Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

yacpps - another C pre-processor simulator

1 view
Skip to first unread message

ECSC68 S Brown CS

unread,
Oct 7, 1986, 11:59:52 AM10/7/86
to
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# yacpps.1
# yacpps
# This archive created: Tue Oct 7 16:56:10 1986
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'yacpps.1'
then
echo shar: "will not over-write existing file 'yacpps.1'"
else
cat << \SHAR_EOF > 'yacpps.1'

.TH YACPPS 1 "Edinburgh Univ, June 6 1986"
.SH NAME
yacpps - yet another C pre-processor simulator
.SH SYNOPSIS
.B yacpps [-i] [-Dlabel] ... [-Ulabel] ... [source]
.SH DESCRIPTION
.I Yacpps
simulates the C pre-processor in its action of
removing dependant code between
.I #ifdef/#ifndef
and
.I #endif
pairs.
Each pre-processor label it encounters is given one of the
values
.I Defined, Undefined or Unknown.
.PP
A
.I #ifdef
directive will be
.TP
.B 1.
Left complete, with the
.I #ifdef-#endif
labels removed, if the variable is
.I Defined.
.TP
.B 2.
Removed entirely, with its #ifdef-#endif labels,
if it is
.I Undefined.
.TP
.B 3
Left alone, if it is
.I Unknown.
.PP
A
.I #ifndef
directive will be similar, with reversed effects
for
.I Defined
and
.I Undefined
variables.
.PP
A
.I #if
directive is always treated as though its parameter were
.I unknown.
.PP
Options understood are
.TP
.B -i
This causes `implicit'
definition of variables;
if a
.I #define
of a previously
.I unknown
variable
occurs
in the scope of an
.I undefined
.I #ifdef
or
.I #ifndef,
or in comments within a
.I defined
.I #ifdef
or
.I #ifndef,
then it is set as being
.I undefined.
.br
This causes lots of junk to be removed, though its
safety is not totally guarenteed.
.TP
.B -Dlabel
This sets the variable
.I label
to be
.I defined.
.TP
.B -Ulabel
This sets the variable named to be
.I undefined.
.PP
If no source file is given on the command line,
then the standard input file is used instead.
.SH "STATUS RETURNS"
Return status is non-zero if anything went wrong,
otherwise 0.
.SH "SEE ALSO"
cpp(1).
.SH BUGS
It doesn't understand comments very well.
.br
Any Control-G's in the input are converted into
newlines on output.
.br
It fails to remove
.I unknown
#ifdef/#endif pairs with null bodies.
.br
It is implemented as a shell-script.
.SH AUTHOR
Simon Brown
SHAR_EOF
if test 1839 -ne "`wc -c < 'yacpps.1'`"
then
echo shar: "error transmitting 'yacpps.1'" '(should have been 1839 characters)'
fi
fi
if test -f 'yacpps'
then
echo shar: "will not over-write existing file 'yacpps'"
else
cat << \SHAR_EOF > 'yacpps'
#!/bin/sh
# yacpps: yet another C pre-processor simulator
#
# Usage: yacpps [-i] [-D label] ... [-U label] ... [source]
#
# where options are:
# -i: Implicit #define's.
# 1. If a #define of an unknown label occurs in
# a comment, then it is set as being undefined.
# 2. If a #define of an unknown label occurs in
# the scope of an undefined #ifdef, then it is
# set as being undefined.
# -D label: Defines the label.
# -U label: Undefines the label.
#
# All labels which are not Defined or Undefined are treated as
# unknown, and may appear under #ifdef and #unifdef scopes in the
# output.
#
# The labels "pdp11" and "vax" are treated specially, in that
# their definition-states are computed automatically.
#
# When removing #ifdefs from code which was written for many
# different systems, it is necessary to explicitly Define the
# system you are using and to Undefine all other possibilities.
# For example,
# yacpps -D sysV -U BSD -U V7 -U sysIII -U ultrix -U eunice
# Failure to do it like this will cause lots of dependant code
# to be left in, which should have been removed.
#
#
# -----------------------------------------------------------------------
#
# Author: Simon Brown
# Department of Computer Science,
# University of Edinburgh.
# Date: Monday October 6th, 1986
#
# Written on the ERCC/ITS GEC-63/40 "its63b" for the SysV shell.
# Not guarenteed to work under BSD (but it probably will).
#
# THIS SOFTWARE MAY BE DISTRIBUTED TO ANYONE SO LONG AS THESE
# LINES REMAIN UNDISTURBED.
#
# Please mail any bugs to si...@its63b.ed.ac.uk
#
#
# -----------------------------------------------------------------------
#
# KNOWN BUGS: 1. It doesn't understand comments properly.
# 2. Any Control-G's in the input are converted into
# newlines.
# 3. Sometimes it leaves pairs of #ifdef/#endif lines
# with no dependant lines between - it would be tidier
# if it just deleted the whole lot.
#
# -----------------------------------------------------------------------
#

machines="pdp11 vax" # add whatever you are using, too
implicit=false

set -- `getopt D:U:i $*`
if [ $? != 0 ]
then echo "Usage: $0 [-i] [-Dlabel] ... [-Ulabel] ... [source]" 1>&2
exit 1
fi
while [ $# -ge 1 ]
do
case $1 in
-i) implicit=true
shift ;;
-D) eval _$2=true
shift; shift ;;
-U) eval _$2=false
shift; shift ;;
--) shift; break ;;
*) echo "wow.... a getopt error! ($1)" 1>&2;
exit 1
esac
done
if [ $# -ge 1 ]
then exec < $1
fi

#fast shell functions... (delete these if you don't have the System-V shell)
true(){ return 0; }
false(){ return 1; }

def=true
state=true
for engine in $machines
do
if $engine > /dev/null 2>&1
then eval _$engine=true
else eval _$engine=false
fi
done

tr '\\' '\007' | while IFS= read line
do
IFS=" "
case $line in
\#define*)
set $line
var=$2
case $var in
*\(* ) normal=false ;;
* ) normal=true
esac
case $state in
true)
if $normal
then eval _$var=true
fi
echo "$line" ;;
neither)
if $normal
then eval : \${_$var:=neither};
fi
echo "$line" ;;
false)
if $implicit && $normal
then eval _$var=false
fi
esac
;;
\#undef*)
set $line
var=$2
case $state in
true)
eval _$var=false
echo "$line" ;;
neither)
eval : \${_$var:=neither}
echo "$line" ;;
esac
;;
/\*#define*)
if $implicit
then
IFS=" /*"
set $line
var=$2
case $state in
true)
eval _$var=false
echo "$line" ;;
neither)
eval : \${_$var:=neither}
echo "$line"
esac
IFS=" "
else case $state in
true|neither)
echo "$line"
esac
fi
;;
\#ifdef*)
set $line
var=$2
case $state in
false) : ;;
neither) eval state=\${_$var:-neither}
case $state in
true) state=neither
esac ;;
* ) eval state=\${_$var:-neither}
esac
case $state in
true) def="true $def" ;;
false)def="false $def" ;;
*) def="neither $def"
echo "$line"
esac
;;
\#ifndef*)
set $line
var=$2
case $state in
false) state=true ;;
neither) eval state=\${_$var:-neither}
case $state in
true) state=neither ;;
false) state=true
esac ;;
* ) eval state=\${_$var:-neither}
esac
case $state in
true) def="false $def"
state=false ;;
false)def="true $def"
state=true ;;
* ) def="neither $def"
echo "$line"
esac
;;
\#else*)
set $def
state=$1
shift
case $state in
true) def="false $*"
state=false ;;
false)def="true $*"
state=true ;;
*) def="neither $*"
echo "$line"
esac
;;
\#endif*)
case $state in
neither) echo "$line"
esac
set $def
shift
state=$1
def=$*
;;
\#if*)
def="neither $def"
state=neither
echo "$line"
;;
*)
case $state in
true|neither)
echo "$line"
esac
esac
done | tr '\007' '\\'

SHAR_EOF
if test 5200 -ne "`wc -c < 'yacpps'`"
then
echo shar: "error transmitting 'yacpps'" '(should have been 5200 characters)'
fi
chmod +x 'yacpps'
fi
exit 0
# End of shell archive

0 new messages