Initial Import from SVN
This commit is contained in:
28
src/cmd/m4/Makefile
Normal file
28
src/cmd/m4/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
# @(#)Makefile 1.0 (2.11BSD GTE) 4/5/94
|
||||
|
||||
DEFS= -DEXTENDED -I.
|
||||
CFLAGS= -O ${DEFS}
|
||||
DESTDIR=
|
||||
SEPFLAG= -i
|
||||
SRCS= eval.c expr.c look.c main.c misc.c
|
||||
OBJS= eval.o expr.o look.o main.o misc.o
|
||||
|
||||
all: m4 tags
|
||||
|
||||
m4: ${OBJS}
|
||||
cc ${SEPFLAG} -o m4 ${OBJS}
|
||||
|
||||
install: all
|
||||
install -s -m 755 m4 ${DESTDIR}/usr/bin/m4
|
||||
|
||||
lint:
|
||||
lint -hax ${DEFS} ${SRCS}
|
||||
|
||||
tags:
|
||||
ctags -t *.h ${SRCS}
|
||||
|
||||
clean:
|
||||
-rm -f *.o m4 core
|
||||
|
||||
depend: ${SRCS}
|
||||
mkdep -p ${CFLAGS} ${SRCS}
|
||||
64
src/cmd/m4/NOTES
Normal file
64
src/cmd/m4/NOTES
Normal file
@@ -0,0 +1,64 @@
|
||||
m4 - macro processor
|
||||
|
||||
PD m4 is based on the macro tool distributed with the software
|
||||
tools (VOS) package, and described in the "SOFTWARE TOOLS" and
|
||||
"SOFTWARE TOOLS IN PASCAL" books. It has been expanded to include
|
||||
most of the command set of SysV m4, the standard UN*X macro processor.
|
||||
|
||||
Since both PD m4 and UN*X m4 are based on SOFTWARE TOOLS macro,
|
||||
there may be certain implementation similarities between
|
||||
the two. The PD m4 was produced without ANY references to m4
|
||||
sources.
|
||||
|
||||
written by: Ozan S. Yigit
|
||||
|
||||
References:
|
||||
|
||||
Software Tools distribution: macro
|
||||
|
||||
Kernighan, Brian W. and P. J. Plauger, SOFTWARE
|
||||
TOOLS IN PASCAL, Addison-Wesley, Mass. 1981
|
||||
|
||||
Kernighan, Brian W. and P. J. Plauger, SOFTWARE
|
||||
TOOLS, Addison-Wesley, Mass. 1976
|
||||
|
||||
Kernighan, Brian W. and Dennis M. Ritchie,
|
||||
THE M4 MACRO PROCESSOR, Unix Programmer's Manual,
|
||||
Seventh Edition, Vol. 2, Bell Telephone Labs, 1979
|
||||
|
||||
System V man page for M4
|
||||
|
||||
|
||||
Implementation Notes:
|
||||
|
||||
[1] PD m4 uses a different (and simpler) stack mechanism than the one
|
||||
described in Software Tools and Software Tools in Pascal books.
|
||||
The triple stack thing is replaced with a single stack containing
|
||||
the call frames and the arguments. Each frame is back-linked to a
|
||||
previous stack frame, which enables us to rewind the stack after
|
||||
each nested call is completed. Each argument is a character pointer
|
||||
to the beginning of the argument string within the string space.
|
||||
The only exceptions to this are (*) arg 0 and arg 1, which are
|
||||
the macro definition and macro name strings, stored dynamically
|
||||
for the hash table.
|
||||
|
||||
. .
|
||||
| . | <-- sp | . |
|
||||
+-------+ +-----+
|
||||
| arg 3 ------------------------------->| str |
|
||||
+-------+ | . |
|
||||
| arg 2 --------------+ .
|
||||
+-------+ |
|
||||
* | | |
|
||||
+-------+ | +-----+
|
||||
| plev | <-- fp +---------------->| str |
|
||||
+-------+ | . |
|
||||
| type | .
|
||||
+-------+
|
||||
| prcf -----------+ plev: paren level
|
||||
+-------+ | type: call type
|
||||
| . | | prcf: prev. call frame
|
||||
. |
|
||||
+-------+ |
|
||||
| <----------+
|
||||
+-------+
|
||||
40
src/cmd/m4/TEST/ack.m4
Normal file
40
src/cmd/m4/TEST/ack.m4
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)ack.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
define(ack, `ifelse($1,0,incr($2),$2,0,`ack(DECR($1),1)',
|
||||
`ack(DECR($1), ack($1,DECR($2)))')')
|
||||
45
src/cmd/m4/TEST/hanoi.m4
Normal file
45
src/cmd/m4/TEST/hanoi.m4
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)hanoi.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
define(hanoi, `trans(A, B, C, $1)')
|
||||
|
||||
define(moved,`move disk from $1 to $2
|
||||
')
|
||||
|
||||
define(trans, `ifelse($4,1,`moved($1,$2)',
|
||||
`trans($1,$3,$2,DECR($4))moved($1,$2)trans($3,$2,$1,DECR($4))')')
|
||||
55
src/cmd/m4/TEST/hash.m4
Normal file
55
src/cmd/m4/TEST/hash.m4
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)hash.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
dnl This probably will not run on any m4 that cannot
|
||||
dnl handle char constants in eval.
|
||||
dnl
|
||||
changequote(<,>) define(HASHVAL,99) dnl
|
||||
define(hash,<eval(str(substr($1,1),0)%HASHVAL)>) dnl
|
||||
define(str,
|
||||
<ifelse($1,",$2,
|
||||
<str(substr(<$1>,1),<eval($2+'substr($1,0,1)')>)>)
|
||||
>) dnl
|
||||
define(KEYWORD,<$1,hash($1),>) dnl
|
||||
define(TSTART,
|
||||
<struct prehash {
|
||||
char *keyword;
|
||||
int hashval;
|
||||
} keytab[] = {>) dnl
|
||||
define(TEND,< "",0
|
||||
};>) dnl
|
||||
45
src/cmd/m4/TEST/sqroot.m4
Normal file
45
src/cmd/m4/TEST/sqroot.m4
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)sqroot.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
define(square_root,
|
||||
`ifelse(eval($1<0),1,negative-square-root,
|
||||
`square_root_aux($1, 1, eval(($1+1)/2))')')
|
||||
define(square_root_aux,
|
||||
`ifelse($3, $2, $3,
|
||||
$3, eval($1/$2), $3,
|
||||
`square_root_aux($1, $3, eval(($3+($1/$3))/2))')')
|
||||
45
src/cmd/m4/TEST/string.m4
Normal file
45
src/cmd/m4/TEST/string.m4
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)string.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
define(string,`integer $1(len(substr($2,1)))
|
||||
str($1,substr($2,1),0)
|
||||
data $1(len(substr($2,1)))/EOS/
|
||||
')
|
||||
|
||||
define(str,`ifelse($2,",,data $1(incr($3))/`LET'substr($2,0,1)/
|
||||
`str($1,substr($2,1),incr($3))')')
|
||||
243
src/cmd/m4/TEST/test.m4
Normal file
243
src/cmd/m4/TEST/test.m4
Normal file
@@ -0,0 +1,243 @@
|
||||
#
|
||||
# Copyright (c) 1989, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to Berkeley by
|
||||
# Ozan Yigit.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)test.m4 8.1 (Berkeley) 6/6/93
|
||||
#
|
||||
|
||||
# test file for mp (not comprehensive)
|
||||
#
|
||||
# v7 m4 does not have `decr'.
|
||||
#
|
||||
define(DECR,`eval($1-1)')
|
||||
#
|
||||
# include string macros
|
||||
#
|
||||
include(string.m4)
|
||||
#
|
||||
# create some fortrash strings for an even uglier language
|
||||
#
|
||||
string(TEXT, "text")
|
||||
string(DATA, "data")
|
||||
string(BEGIN, "begin")
|
||||
string(END, "end")
|
||||
string(IF, "if")
|
||||
string(THEN, "then")
|
||||
string(ELSE, "else")
|
||||
string(CASE, "case")
|
||||
string(REPEAT, "repeat")
|
||||
string(WHILE, "while")
|
||||
string(DEFAULT, "default")
|
||||
string(UNTIL, "until")
|
||||
string(FUNCTION, "function")
|
||||
string(PROCEDURE, "procedure")
|
||||
string(EXTERNAL, "external")
|
||||
string(FORWARD, "forward")
|
||||
string(TYPE, "type")
|
||||
string(VAR, "var")
|
||||
string(CONST, "const")
|
||||
string(PROGRAM, "program")
|
||||
string(INPUT, "input")
|
||||
string(OUTPUT, "output")
|
||||
#
|
||||
divert(2)
|
||||
diversion #1
|
||||
divert(3)
|
||||
diversion #2
|
||||
divert(4)
|
||||
diversion #3
|
||||
divert(5)
|
||||
diversion #4
|
||||
divert(0)
|
||||
define(abc,xxx)
|
||||
ifdef(`abc',defined,undefined)
|
||||
#
|
||||
# v7 m4 does this wrong. The right output is
|
||||
# this is A vEry lon sEntEnCE
|
||||
# see m4 documentation for translit.
|
||||
#
|
||||
translit(`this is a very long sentence', abcdefg, ABCDEF)
|
||||
#
|
||||
# include towers-of-hanoi
|
||||
#
|
||||
include(hanoi.m4)
|
||||
#
|
||||
# some reasonable set of disks
|
||||
#
|
||||
hanoi(6)
|
||||
#
|
||||
# include ackermann's function
|
||||
#
|
||||
include(ack.m4)
|
||||
#
|
||||
# something like (3,3) will blow away un*x m4.
|
||||
#
|
||||
ack(2,3)
|
||||
#
|
||||
# include a square_root function for fixed nums
|
||||
#
|
||||
include(sqroot.m4)
|
||||
#
|
||||
# some square roots.
|
||||
#
|
||||
square_root(15)
|
||||
square_root(100)
|
||||
square_root(-4)
|
||||
square_root(21372)
|
||||
#
|
||||
# some textual material for enjoyment.
|
||||
#
|
||||
[taken from the 'Clemson University Computer Newsletter',
|
||||
September 1981, pp. 6-7]
|
||||
|
||||
I am a wizard in the magical Kingdom of Transformation and I
|
||||
slay dragons for a living. Actually, I am a systems programmer.
|
||||
One of the problems with systems programming is explaining to
|
||||
non-computer enthusiasts what that is. All of the terms I use to
|
||||
describe my job are totally meaningless to them. Usually my response
|
||||
to questions about my work is to say as little as possible. For
|
||||
instance, if someone asks what happened at work this week, I say
|
||||
"Nothing much" and then I change the subject.
|
||||
|
||||
With the assistance of my brother, a mechanical engineer, I have devised
|
||||
an analogy that everyone can understand. The analogy describes the
|
||||
"Kingdom of Transformation" where travelers wander and are magically
|
||||
transformed. This kingdom is the computer and the travelers are information.
|
||||
The purpose of the computer is to change information to a more meaningful
|
||||
forma. The law of conservation applies here: The computer never creates
|
||||
and never intentionally destroys data. With no further ado, let us travel
|
||||
to the Kingdom of Transformation:
|
||||
|
||||
In a land far, far away, there is a magical kingdom called the Kingdom of
|
||||
Transformation. A king rules over this land and employs a Council of
|
||||
Wizardry. The main purpose of this kingdom is to provide a way for
|
||||
neighboring kingdoms to transform citizens into more useful citizens. This
|
||||
is done by allowing the citizens to enter the kingdom at one of its ports
|
||||
and to travel any of the many routes in the kingdom. They are magically
|
||||
transformed along the way. The income of the Kingdom of Transformation
|
||||
comes from the many toll roads within its boundaries.
|
||||
|
||||
The Kingdom of Transformation was created when several kingdoms got
|
||||
together and discovered a mutual need for new talents and abilities for
|
||||
citizens. They employed CTK, Inc. (Creators of Transformation, Inc.) to
|
||||
create this kingdom. CTK designed the country, its transportation routes,
|
||||
and its laws of transformation, and created the major highway system.
|
||||
|
||||
Hazards
|
||||
=======
|
||||
|
||||
Because magic is not truly controllable, CTK invariably, but unknowingly,
|
||||
creates dragons. Dragons are huge fire-breathing beasts which sometimes
|
||||
injure or kill travelers. Fortunately, they do not travel, but always
|
||||
remain near their den.
|
||||
|
||||
Other hazards also exist which are potentially harmful. As the roads
|
||||
become older and more weatherbeaten, pot-holes will develop, trees will
|
||||
fall on travelers, etc. CTK maintenance men are called to fix these
|
||||
problems.
|
||||
|
||||
Wizards
|
||||
=======
|
||||
|
||||
The wizards play a major role in creating and maintaining the kingdom but
|
||||
get little credit for their work because it is performed secretly. The
|
||||
wizards do not wan the workers or travelers to learn their incantations
|
||||
because many laws would be broken and chaos would result.
|
||||
|
||||
CTK's grand design is always general enough to be applicable in many
|
||||
different situations. As a result, it is often difficult to use. The
|
||||
first duty of the wizards is to tailor the transformation laws so as to be
|
||||
more beneficial and easier to use in their particular environment.
|
||||
|
||||
After creation of the kingdom, a major duty of the wizards is to search for
|
||||
and kill dragons. If travelers do not return on time or if they return
|
||||
injured, the ruler of the country contacts the wizards. If the wizards
|
||||
determine that the injury or death occurred due to the traveler's
|
||||
negligence, they provide the traveler's country with additional warnings.
|
||||
If not, they must determine if the cause was a road hazard or a dragon. If
|
||||
the suspect a road hazard, they call in a CTK maintenance man to locate the
|
||||
hazard and to eliminate it, as in repairing the pothole in the road. If
|
||||
they think that cause was a dragon, then they must find and slay it.
|
||||
|
||||
The most difficult part of eliminating a dragon is finding it. Sometimes
|
||||
the wizard magically knows where the dragon's lair it, but often the wizard
|
||||
must send another traveler along the same route and watch to see where he
|
||||
disappears. This sounds like a failsafe method for finding dragons (and a
|
||||
suicide mission for thr traveler) but the second traveler does not always
|
||||
disappear. Some dragons eat any traveler who comes too close; others are
|
||||
very picky.
|
||||
|
||||
The wizards may call in CTK who designed the highway system and
|
||||
transformation laws to help devise a way to locate the dragon. CTK also
|
||||
helps provide the right spell or incantation to slay the dragon. (There is
|
||||
no general spell to slay dragons; each dragon must be eliminated with a
|
||||
different spell.)
|
||||
|
||||
Because neither CTK nor wizards are perfect, spells to not always work
|
||||
correctly. At best, nothing happens when the wrong spell is uttered. At
|
||||
worst, the dragon becomes a much larger dragon or multiplies into several
|
||||
smaller ones. In either case, new spells must be found.
|
||||
|
||||
If all existing dragons are quiet (i.e. have eaten sufficiently), wizards
|
||||
have time to do other things. They hide in castles and practice spells and
|
||||
incatations. They also devise shortcuts for travelers and new laws of
|
||||
transformation.
|
||||
|
||||
Changes in the Kingdom
|
||||
======================
|
||||
|
||||
As new transformation kingdoms are created and old ones are maintained,
|
||||
CTK, Inc. is constantly learning new things. It learns ways to avoid
|
||||
creating some of the dragons that they have previously created. It also
|
||||
discovers new and better laws of transformation. As a result, CTK will
|
||||
periodically create a new grand design which is far better than the old.
|
||||
The wizards determine when is a good time to implement this new design.
|
||||
This is when the tourist season is slow or when no important travelers
|
||||
(VIPs) are to arrive. The kingdom must be closed for the actual
|
||||
implementation and is leter reopened as a new and better place to go.
|
||||
|
||||
A final question you might ask is what happens when the number of tourists
|
||||
becomes too great for the kingdom to handle in a reasonable period of time
|
||||
(i.e., the tourist lines at the ports are too long). The Kingdom of
|
||||
Transformation has three options: (1) shorten the paths that a tourist must
|
||||
travel, or (2) convince CTK to develop a faster breed of horses so that the
|
||||
travelers can finish sooner, or (3) annex more territories so that the
|
||||
kingdom can handle more travelers.
|
||||
|
||||
Thus ends the story of the Kingdom of Transformation. I hope this has
|
||||
explained my job to you: I slay dragons for a living.
|
||||
|
||||
#
|
||||
#should do an automatic undivert..
|
||||
#
|
||||
787
src/cmd/m4/eval.c
Normal file
787
src/cmd/m4/eval.c
Normal file
@@ -0,0 +1,787 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && defined(DOSCCS)
|
||||
static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* eval.c
|
||||
* Facility: m4 macro processor
|
||||
* by: oz
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mdef.h"
|
||||
#include "stdd.h"
|
||||
#include "extern.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/*
|
||||
* eval - evaluate built-in macros.
|
||||
* argc - number of elements in argv.
|
||||
* argv - element vector :
|
||||
* argv[0] = definition of a user
|
||||
* macro or nil if built-in.
|
||||
* argv[1] = name of the macro or
|
||||
* built-in.
|
||||
* argv[2] = parameters to user-defined
|
||||
* . macro or built-in.
|
||||
* .
|
||||
*
|
||||
* Note that the minimum value for argc is 3. A call in the form
|
||||
* of macro-or-builtin() will result in:
|
||||
* argv[0] = nullstr
|
||||
* argv[1] = macro-or-builtin
|
||||
* argv[2] = nullstr
|
||||
*/
|
||||
|
||||
void
|
||||
eval(argv, argc, td)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
register int td;
|
||||
{
|
||||
register int c, n;
|
||||
static int sysval = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("argc = %d\n", argc);
|
||||
for (n = 0; n < argc; n++)
|
||||
printf("argv[%d] = %s\n", n, argv[n]);
|
||||
#endif
|
||||
/*
|
||||
* if argc == 3 and argv[2] is null, then we
|
||||
* have macro-or-builtin() type call. We adjust
|
||||
* argc to avoid further checking..
|
||||
*/
|
||||
if (argc == 3 && !*(argv[2]))
|
||||
argc--;
|
||||
|
||||
switch (td & ~STATIC) {
|
||||
|
||||
case DEFITYPE:
|
||||
if (argc > 2)
|
||||
dodefine(argv[2], (argc > 3) ? argv[3] : null);
|
||||
break;
|
||||
|
||||
case PUSDTYPE:
|
||||
if (argc > 2)
|
||||
dopushdef(argv[2], (argc > 3) ? argv[3] : null);
|
||||
break;
|
||||
|
||||
case DUMPTYPE:
|
||||
dodump(argv, argc);
|
||||
break;
|
||||
|
||||
case EXPRTYPE:
|
||||
/*
|
||||
* doexpr - evaluate arithmetic
|
||||
* expression
|
||||
*/
|
||||
if (argc > 2)
|
||||
pbnum(expr(argv[2]));
|
||||
break;
|
||||
|
||||
case IFELTYPE:
|
||||
if (argc > 4)
|
||||
doifelse(argv, argc);
|
||||
break;
|
||||
|
||||
case IFDFTYPE:
|
||||
/*
|
||||
* doifdef - select one of two
|
||||
* alternatives based on the existence of
|
||||
* another definition
|
||||
*/
|
||||
if (argc > 3) {
|
||||
if (lookup(argv[2]) != nil)
|
||||
pbstr(argv[3]);
|
||||
else if (argc > 4)
|
||||
pbstr(argv[4]);
|
||||
}
|
||||
break;
|
||||
|
||||
case LENGTYPE:
|
||||
/*
|
||||
* dolen - find the length of the
|
||||
* argument
|
||||
*/
|
||||
if (argc > 2)
|
||||
pbnum((argc > 2) ? strlen(argv[2]) : 0);
|
||||
break;
|
||||
|
||||
case INCRTYPE:
|
||||
/*
|
||||
* doincr - increment the value of the
|
||||
* argument
|
||||
*/
|
||||
if (argc > 2)
|
||||
pbnum(atoi(argv[2]) + 1);
|
||||
break;
|
||||
|
||||
case DECRTYPE:
|
||||
/*
|
||||
* dodecr - decrement the value of the
|
||||
* argument
|
||||
*/
|
||||
if (argc > 2)
|
||||
pbnum(atoi(argv[2]) - 1);
|
||||
break;
|
||||
|
||||
case SYSCTYPE:
|
||||
/*
|
||||
* dosys - execute system command
|
||||
*/
|
||||
if (argc > 2)
|
||||
sysval = system(argv[2]);
|
||||
break;
|
||||
|
||||
case SYSVTYPE:
|
||||
/*
|
||||
* dosysval - return value of the last
|
||||
* system call.
|
||||
*
|
||||
*/
|
||||
pbnum(sysval);
|
||||
break;
|
||||
|
||||
case INCLTYPE:
|
||||
if (argc > 2)
|
||||
if (!doincl(argv[2]))
|
||||
oops("%s: %s", argv[2], strerror(errno));
|
||||
break;
|
||||
|
||||
case SINCTYPE:
|
||||
if (argc > 2)
|
||||
(void) doincl(argv[2]);
|
||||
break;
|
||||
#ifdef EXTENDED
|
||||
case PASTTYPE:
|
||||
if (argc > 2)
|
||||
if (!dopaste(argv[2]))
|
||||
oops("%s: %s", argv[2], strerror(errno));
|
||||
break;
|
||||
|
||||
case SPASTYPE:
|
||||
if (argc > 2)
|
||||
(void) dopaste(argv[2]);
|
||||
break;
|
||||
#endif
|
||||
case CHNQTYPE:
|
||||
dochq(argv, argc);
|
||||
break;
|
||||
|
||||
case CHNCTYPE:
|
||||
dochc(argv, argc);
|
||||
break;
|
||||
|
||||
case SUBSTYPE:
|
||||
/*
|
||||
* dosub - select substring
|
||||
*
|
||||
*/
|
||||
if (argc > 3)
|
||||
dosub(argv, argc);
|
||||
break;
|
||||
|
||||
case SHIFTYPE:
|
||||
/*
|
||||
* doshift - push back all arguments
|
||||
* except the first one (i.e. skip
|
||||
* argv[2])
|
||||
*/
|
||||
if (argc > 3) {
|
||||
for (n = argc - 1; n > 3; n--) {
|
||||
putback(rquote);
|
||||
pbstr(argv[n]);
|
||||
putback(lquote);
|
||||
putback(',');
|
||||
}
|
||||
putback(rquote);
|
||||
pbstr(argv[3]);
|
||||
putback(lquote);
|
||||
}
|
||||
break;
|
||||
|
||||
case DIVRTYPE:
|
||||
if (argc > 2 && (n = atoi(argv[2])) != 0)
|
||||
dodiv(n);
|
||||
else {
|
||||
active = stdout;
|
||||
oindex = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case UNDVTYPE:
|
||||
doundiv(argv, argc);
|
||||
break;
|
||||
|
||||
case DIVNTYPE:
|
||||
/*
|
||||
* dodivnum - return the number of
|
||||
* current output diversion
|
||||
*/
|
||||
pbnum(oindex);
|
||||
break;
|
||||
|
||||
case UNDFTYPE:
|
||||
/*
|
||||
* doundefine - undefine a previously
|
||||
* defined macro(s) or m4 keyword(s).
|
||||
*/
|
||||
if (argc > 2)
|
||||
for (n = 2; n < argc; n++)
|
||||
remhash(argv[n], ALL);
|
||||
break;
|
||||
|
||||
case POPDTYPE:
|
||||
/*
|
||||
* dopopdef - remove the topmost
|
||||
* definitions of macro(s) or m4
|
||||
* keyword(s).
|
||||
*/
|
||||
if (argc > 2)
|
||||
for (n = 2; n < argc; n++)
|
||||
remhash(argv[n], TOP);
|
||||
break;
|
||||
|
||||
case MKTMTYPE:
|
||||
/*
|
||||
* dotemp - create a temporary file
|
||||
*/
|
||||
if (argc > 2)
|
||||
pbstr(mktemp(argv[2]));
|
||||
break;
|
||||
|
||||
case TRNLTYPE:
|
||||
/*
|
||||
* dotranslit - replace all characters in
|
||||
* the source string that appears in the
|
||||
* "from" string with the corresponding
|
||||
* characters in the "to" string.
|
||||
*/
|
||||
if (argc > 3) {
|
||||
char temp[MAXTOK];
|
||||
if (argc > 4)
|
||||
map(temp, argv[2], argv[3], argv[4]);
|
||||
else
|
||||
map(temp, argv[2], argv[3], null);
|
||||
pbstr(temp);
|
||||
}
|
||||
else if (argc > 2)
|
||||
pbstr(argv[2]);
|
||||
break;
|
||||
|
||||
case INDXTYPE:
|
||||
/*
|
||||
* doindex - find the index of the second
|
||||
* argument string in the first argument
|
||||
* string. -1 if not present.
|
||||
*/
|
||||
pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
|
||||
break;
|
||||
|
||||
case ERRPTYPE:
|
||||
/*
|
||||
* doerrp - print the arguments to stderr
|
||||
* file
|
||||
*/
|
||||
if (argc > 2) {
|
||||
for (n = 2; n < argc; n++)
|
||||
fprintf(stderr, "%s ", argv[n]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DNLNTYPE:
|
||||
/*
|
||||
* dodnl - eat-up-to and including
|
||||
* newline
|
||||
*/
|
||||
while ((c = gpbc()) != '\n' && c != EOF)
|
||||
;
|
||||
break;
|
||||
|
||||
case M4WRTYPE:
|
||||
/*
|
||||
* dom4wrap - set up for
|
||||
* wrap-up/wind-down activity
|
||||
*/
|
||||
m4wraps = (argc > 2) ? xstrdup(argv[2]) : null;
|
||||
break;
|
||||
|
||||
case EXITTYPE:
|
||||
/*
|
||||
* doexit - immediate exit from m4.
|
||||
*/
|
||||
exit((argc > 2) ? atoi(argv[2]) : 0);
|
||||
break;
|
||||
|
||||
case DEFNTYPE:
|
||||
if (argc > 2)
|
||||
for (n = 2; n < argc; n++)
|
||||
dodefn(argv[n]);
|
||||
break;
|
||||
|
||||
default:
|
||||
oops("%s: major botch.", "eval");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *dumpfmt = "`%s'\t`%s'\n"; /* format string for dumpdef */
|
||||
|
||||
/*
|
||||
* expand - user-defined macro expansion
|
||||
*/
|
||||
void
|
||||
expand(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
register char *t;
|
||||
register char *p;
|
||||
register int n;
|
||||
register int argno;
|
||||
|
||||
t = argv[0]; /* defn string as a whole */
|
||||
p = t;
|
||||
while (*p)
|
||||
p++;
|
||||
p--; /* last character of defn */
|
||||
while (p > t) {
|
||||
if (*(p - 1) != ARGFLAG)
|
||||
putback(*p);
|
||||
else {
|
||||
switch (*p) {
|
||||
|
||||
case '#':
|
||||
pbnum(argc - 2);
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if ((argno = *p - '0') < argc - 1)
|
||||
pbstr(argv[argno + 1]);
|
||||
break;
|
||||
case '*':
|
||||
for (n = argc - 1; n > 2; n--) {
|
||||
pbstr(argv[n]);
|
||||
putback(',');
|
||||
}
|
||||
pbstr(argv[2]);
|
||||
break;
|
||||
default:
|
||||
putback(*p);
|
||||
putback('$');
|
||||
break;
|
||||
}
|
||||
p--;
|
||||
}
|
||||
p--;
|
||||
}
|
||||
if (p == t) /* do last character */
|
||||
putback(*p);
|
||||
}
|
||||
|
||||
/*
|
||||
* dodefine - install definition in the table
|
||||
*/
|
||||
void
|
||||
dodefine(name, defn)
|
||||
register char *name;
|
||||
register char *defn;
|
||||
{
|
||||
register ndptr p;
|
||||
|
||||
if (!*name)
|
||||
oops("null definition.");
|
||||
if (STREQ(name, defn))
|
||||
oops("%s: recursive definition.", name);
|
||||
if ((p = lookup(name)) == nil)
|
||||
p = addent(name);
|
||||
else if (p->defn != null)
|
||||
free((char *) p->defn);
|
||||
if (!*defn)
|
||||
p->defn = null;
|
||||
else
|
||||
p->defn = xstrdup(defn);
|
||||
p->type = MACRTYPE;
|
||||
}
|
||||
|
||||
/*
|
||||
* dodefn - push back a quoted definition of
|
||||
* the given name.
|
||||
*/
|
||||
void
|
||||
dodefn(name)
|
||||
char *name;
|
||||
{
|
||||
register ndptr p;
|
||||
|
||||
if ((p = lookup(name)) != nil && p->defn != null) {
|
||||
putback(rquote);
|
||||
pbstr(p->defn);
|
||||
putback(lquote);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dopushdef - install a definition in the hash table
|
||||
* without removing a previous definition. Since
|
||||
* each new entry is entered in *front* of the
|
||||
* hash bucket, it hides a previous definition from
|
||||
* lookup.
|
||||
*/
|
||||
void
|
||||
dopushdef(name, defn)
|
||||
register char *name;
|
||||
register char *defn;
|
||||
{
|
||||
register ndptr p;
|
||||
|
||||
if (!*name)
|
||||
oops("null definition");
|
||||
if (STREQ(name, defn))
|
||||
oops("%s: recursive definition.", name);
|
||||
p = addent(name);
|
||||
if (!*defn)
|
||||
p->defn = null;
|
||||
else
|
||||
p->defn = xstrdup(defn);
|
||||
p->type = MACRTYPE;
|
||||
}
|
||||
|
||||
/*
|
||||
* dodumpdef - dump the specified definitions in the hash
|
||||
* table to stderr. If nothing is specified, the entire
|
||||
* hash table is dumped.
|
||||
*/
|
||||
void
|
||||
dodump(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
register int n;
|
||||
ndptr p;
|
||||
|
||||
if (argc > 2) {
|
||||
for (n = 2; n < argc; n++)
|
||||
if ((p = lookup(argv[n])) != nil)
|
||||
fprintf(stderr, dumpfmt, p->name,
|
||||
p->defn);
|
||||
}
|
||||
else {
|
||||
for (n = 0; n < HASHSIZE; n++)
|
||||
for (p = hashtab[n]; p != nil; p = p->nxtptr)
|
||||
fprintf(stderr, dumpfmt, p->name,
|
||||
p->defn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* doifelse - select one of two alternatives - loop.
|
||||
*/
|
||||
void
|
||||
doifelse(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
cycle {
|
||||
if (STREQ(argv[2], argv[3]))
|
||||
pbstr(argv[4]);
|
||||
else if (argc == 6)
|
||||
pbstr(argv[5]);
|
||||
else if (argc > 6) {
|
||||
argv += 3;
|
||||
argc -= 3;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* doinclude - include a given file.
|
||||
*/
|
||||
int
|
||||
doincl(ifile)
|
||||
char *ifile;
|
||||
{
|
||||
if (ilevel + 1 == MAXINP)
|
||||
oops("too many include files.");
|
||||
if ((infile[ilevel + 1] = fopen(ifile, "r")) != NULL) {
|
||||
ilevel++;
|
||||
bbase[ilevel] = bufbase = bp;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef EXTENDED
|
||||
/*
|
||||
* dopaste - include a given file without any
|
||||
* macro processing.
|
||||
*/
|
||||
int
|
||||
dopaste(pfile)
|
||||
char *pfile;
|
||||
{
|
||||
FILE *pf;
|
||||
register int c;
|
||||
|
||||
if ((pf = fopen(pfile, "r")) != NULL) {
|
||||
while ((c = getc(pf)) != EOF)
|
||||
putc(c, active);
|
||||
(void) fclose(pf);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dochq - change quote characters
|
||||
*/
|
||||
void
|
||||
dochq(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
if (argc > 2) {
|
||||
if (*argv[2])
|
||||
lquote = *argv[2];
|
||||
if (argc > 3) {
|
||||
if (*argv[3])
|
||||
rquote = *argv[3];
|
||||
}
|
||||
else
|
||||
rquote = lquote;
|
||||
}
|
||||
else {
|
||||
lquote = LQUOTE;
|
||||
rquote = RQUOTE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dochc - change comment characters
|
||||
*/
|
||||
void
|
||||
dochc(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
if (argc > 2) {
|
||||
if (*argv[2])
|
||||
scommt = *argv[2];
|
||||
if (argc > 3) {
|
||||
if (*argv[3])
|
||||
ecommt = *argv[3];
|
||||
}
|
||||
else
|
||||
ecommt = ECOMMT;
|
||||
}
|
||||
else {
|
||||
scommt = SCOMMT;
|
||||
ecommt = ECOMMT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dodivert - divert the output to a temporary file
|
||||
*/
|
||||
void
|
||||
dodiv(n)
|
||||
register int n;
|
||||
{
|
||||
if (n < 0 || n >= MAXOUT)
|
||||
n = 0; /* bitbucket */
|
||||
if (outfile[n] == NULL) {
|
||||
m4temp[UNIQUE] = n + '0';
|
||||
if ((outfile[n] = fopen(m4temp, "w")) == NULL)
|
||||
oops("%s: cannot divert.", m4temp);
|
||||
}
|
||||
oindex = n;
|
||||
active = outfile[n];
|
||||
}
|
||||
|
||||
/*
|
||||
* doundivert - undivert a specified output, or all
|
||||
* other outputs, in numerical order.
|
||||
*/
|
||||
void
|
||||
doundiv(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
register int ind;
|
||||
register int n;
|
||||
|
||||
if (argc > 2) {
|
||||
for (ind = 2; ind < argc; ind++) {
|
||||
n = atoi(argv[ind]);
|
||||
if (n > 0 && n < MAXOUT && outfile[n] != NULL)
|
||||
getdiv(n);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
for (n = 1; n < MAXOUT; n++)
|
||||
if (outfile[n] != NULL)
|
||||
getdiv(n);
|
||||
}
|
||||
|
||||
/*
|
||||
* dosub - select substring
|
||||
*/
|
||||
void
|
||||
dosub(argv, argc)
|
||||
register char *argv[];
|
||||
register int argc;
|
||||
{
|
||||
register char *ap, *fc, *k;
|
||||
register int nc;
|
||||
|
||||
if (argc < 5)
|
||||
nc = MAXTOK;
|
||||
else
|
||||
#ifdef EXPR
|
||||
nc = expr(argv[4]);
|
||||
#else
|
||||
nc = atoi(argv[4]);
|
||||
#endif
|
||||
ap = argv[2]; /* target string */
|
||||
#ifdef EXPR
|
||||
fc = ap + expr(argv[3]); /* first char */
|
||||
#else
|
||||
fc = ap + atoi(argv[3]); /* first char */
|
||||
#endif
|
||||
if (fc >= ap && fc < ap + strlen(ap))
|
||||
for (k = fc + min(nc, strlen(fc)) - 1; k >= fc; k--)
|
||||
putback(*k);
|
||||
}
|
||||
|
||||
/*
|
||||
* map:
|
||||
* map every character of s1 that is specified in from
|
||||
* into s3 and replace in s. (source s1 remains untouched)
|
||||
*
|
||||
* This is a standard implementation of map(s,from,to) function of ICON
|
||||
* language. Within mapvec, we replace every character of "from" with
|
||||
* the corresponding character in "to". If "to" is shorter than "from",
|
||||
* than the corresponding entries are null, which means that those
|
||||
* characters dissapear altogether. Furthermore, imagine
|
||||
* map(dest, "sourcestring", "srtin", "rn..*") type call. In this case,
|
||||
* `s' maps to `r', `r' maps to `n' and `n' maps to `*'. Thus, `s'
|
||||
* ultimately maps to `*'. In order to achieve this effect in an efficient
|
||||
* manner (i.e. without multiple passes over the destination string), we
|
||||
* loop over mapvec, starting with the initial source character. if the
|
||||
* character value (dch) in this location is different than the source
|
||||
* character (sch), sch becomes dch, once again to index into mapvec, until
|
||||
* the character value stabilizes (i.e. sch = dch, in other words
|
||||
* mapvec[n] == n). Even if the entry in the mapvec is null for an ordinary
|
||||
* character, it will stabilize, since mapvec[0] == 0 at all times. At the
|
||||
* end, we restore mapvec* back to normal where mapvec[n] == n for
|
||||
* 0 <= n <= 127. This strategy, along with the restoration of mapvec, is
|
||||
* about 5 times faster than any algorithm that makes multiple passes over
|
||||
* destination string.
|
||||
*/
|
||||
void
|
||||
map(dest, src, from, to)
|
||||
register char *dest;
|
||||
register char *src;
|
||||
register char *from;
|
||||
register char *to;
|
||||
{
|
||||
register char *tmp;
|
||||
register char sch, dch;
|
||||
static char mapvec[128] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
|
||||
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 124, 125, 126, 127
|
||||
};
|
||||
|
||||
if (*src) {
|
||||
tmp = from;
|
||||
/*
|
||||
* create a mapping between "from" and
|
||||
* "to"
|
||||
*/
|
||||
while (*from)
|
||||
mapvec[*from++] = (*to) ? *to++ : (char) 0;
|
||||
|
||||
while (*src) {
|
||||
sch = *src++;
|
||||
dch = mapvec[sch];
|
||||
while (dch != sch) {
|
||||
sch = dch;
|
||||
dch = mapvec[sch];
|
||||
}
|
||||
if (*dest = dch)
|
||||
dest++;
|
||||
}
|
||||
/*
|
||||
* restore all the changed characters
|
||||
*/
|
||||
while (*tmp) {
|
||||
mapvec[*tmp] = *tmp;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
*dest = (char) 0;
|
||||
}
|
||||
626
src/cmd/m4/expr.c
Normal file
626
src/cmd/m4/expr.c
Normal file
@@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && defined(DOSCCS)
|
||||
static char sccsid[] = "@(#)expr.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "stdd.h"
|
||||
|
||||
/*
|
||||
* expression evaluator: performs a standard recursive
|
||||
* descent parse to evaluate any expression permissible
|
||||
* within the following grammar:
|
||||
*
|
||||
* expr : query EOS
|
||||
* query : lor
|
||||
* | lor "?" query ":" query
|
||||
* lor : land { "||" land }
|
||||
* land : bor { "&&" bor }
|
||||
* bor : bxor { "|" bxor }
|
||||
* bxor : band { "^" band }
|
||||
* band : eql { "&" eql }
|
||||
* eql : relat { eqrel relat }
|
||||
* relat : shift { rel shift }
|
||||
* shift : primary { shop primary }
|
||||
* primary : term { addop term }
|
||||
* term : unary { mulop unary }
|
||||
* unary : factor
|
||||
* | unop unary
|
||||
* factor : constant
|
||||
* | "(" query ")"
|
||||
* constant: num
|
||||
* | "'" CHAR "'"
|
||||
* num : DIGIT
|
||||
* | DIGIT num
|
||||
* shop : "<<"
|
||||
* | ">>"
|
||||
* eqlrel : "="
|
||||
* | "=="
|
||||
* | "!="
|
||||
* rel : "<"
|
||||
* | ">"
|
||||
* | "<="
|
||||
* | ">="
|
||||
*
|
||||
*
|
||||
* This expression evaluator is lifted from a public-domain
|
||||
* C Pre-Processor included with the DECUS C Compiler distribution.
|
||||
* It is hacked somewhat to be suitable for m4.
|
||||
*
|
||||
* Originally by: Mike Lutz
|
||||
* Bob Harper
|
||||
*/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define EOS (char) 0
|
||||
#define EQL 0
|
||||
#define NEQ 1
|
||||
#define LSS 2
|
||||
#define LEQ 3
|
||||
#define GTR 4
|
||||
#define GEQ 5
|
||||
#define OCTAL 8
|
||||
#define DECIMAL 10
|
||||
|
||||
static char *nxtch; /* Parser scan pointer */
|
||||
|
||||
static int query __P((void));
|
||||
static int lor __P((void));
|
||||
static int land __P((void));
|
||||
static int bor __P((void));
|
||||
static int bxor __P((void));
|
||||
static int band __P((void));
|
||||
static int eql __P((void));
|
||||
static int relat __P((void));
|
||||
static int shift __P((void));
|
||||
static int primary __P((void));
|
||||
static int term __P((void));
|
||||
static int unary __P((void));
|
||||
static int factor __P((void));
|
||||
static int constant __P((void));
|
||||
static int num __P((void));
|
||||
static int geteql __P((void));
|
||||
static int getrel __P((void));
|
||||
static int skipws __P((void));
|
||||
static void experr __P((char *));
|
||||
|
||||
/*
|
||||
* For longjmp
|
||||
*/
|
||||
#include <setjmp.h>
|
||||
static jmp_buf expjump;
|
||||
|
||||
/*
|
||||
* macros:
|
||||
* ungetch - Put back the last character examined.
|
||||
* getch - return the next character from expr string.
|
||||
*/
|
||||
#define ungetch() nxtch--
|
||||
#define getch() *nxtch++
|
||||
|
||||
int
|
||||
expr(expbuf)
|
||||
char *expbuf;
|
||||
{
|
||||
register int rval;
|
||||
|
||||
nxtch = expbuf;
|
||||
if (setjmp(expjump) != 0)
|
||||
return FALSE;
|
||||
|
||||
rval = query();
|
||||
if (skipws() == EOS)
|
||||
return rval;
|
||||
|
||||
printf("m4: ill-formed expression.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* query : lor | lor '?' query ':' query
|
||||
*/
|
||||
static int
|
||||
query()
|
||||
{
|
||||
register int bool, true_val, false_val;
|
||||
|
||||
bool = lor();
|
||||
if (skipws() != '?') {
|
||||
ungetch();
|
||||
return bool;
|
||||
}
|
||||
|
||||
true_val = query();
|
||||
if (skipws() != ':')
|
||||
experr("bad query");
|
||||
|
||||
false_val = query();
|
||||
return bool ? true_val : false_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* lor : land { '||' land }
|
||||
*/
|
||||
static int
|
||||
lor()
|
||||
{
|
||||
register int c, vl, vr;
|
||||
|
||||
vl = land();
|
||||
while ((c = skipws()) == '|' && getch() == '|') {
|
||||
vr = land();
|
||||
vl = vl || vr;
|
||||
}
|
||||
|
||||
if (c == '|')
|
||||
ungetch();
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* land : bor { '&&' bor }
|
||||
*/
|
||||
static int
|
||||
land()
|
||||
{
|
||||
register int c, vl, vr;
|
||||
|
||||
vl = bor();
|
||||
while ((c = skipws()) == '&' && getch() == '&') {
|
||||
vr = bor();
|
||||
vl = vl && vr;
|
||||
}
|
||||
|
||||
if (c == '&')
|
||||
ungetch();
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* bor : bxor { '|' bxor }
|
||||
*/
|
||||
static int
|
||||
bor()
|
||||
{
|
||||
register int vl, vr, c;
|
||||
|
||||
vl = bxor();
|
||||
while ((c = skipws()) == '|' && getch() != '|') {
|
||||
ungetch();
|
||||
vr = bxor();
|
||||
vl |= vr;
|
||||
}
|
||||
|
||||
if (c == '|')
|
||||
ungetch();
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* bxor : band { '^' band }
|
||||
*/
|
||||
static int
|
||||
bxor()
|
||||
{
|
||||
register int vl, vr;
|
||||
|
||||
vl = band();
|
||||
while (skipws() == '^') {
|
||||
vr = band();
|
||||
vl ^= vr;
|
||||
}
|
||||
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* band : eql { '&' eql }
|
||||
*/
|
||||
static int
|
||||
band()
|
||||
{
|
||||
register int vl, vr, c;
|
||||
|
||||
vl = eql();
|
||||
while ((c = skipws()) == '&' && getch() != '&') {
|
||||
ungetch();
|
||||
vr = eql();
|
||||
vl &= vr;
|
||||
}
|
||||
|
||||
if (c == '&')
|
||||
ungetch();
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* eql : relat { eqrel relat }
|
||||
*/
|
||||
static int
|
||||
eql()
|
||||
{
|
||||
register int vl, vr, rel;
|
||||
|
||||
vl = relat();
|
||||
while ((rel = geteql()) != -1) {
|
||||
vr = relat();
|
||||
|
||||
switch (rel) {
|
||||
|
||||
case EQL:
|
||||
vl = (vl == vr);
|
||||
break;
|
||||
case NEQ:
|
||||
vl = (vl != vr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* relat : shift { rel shift }
|
||||
*/
|
||||
static int
|
||||
relat()
|
||||
{
|
||||
register int vl, vr, rel;
|
||||
|
||||
vl = shift();
|
||||
while ((rel = getrel()) != -1) {
|
||||
|
||||
vr = shift();
|
||||
switch (rel) {
|
||||
|
||||
case LEQ:
|
||||
vl = (vl <= vr);
|
||||
break;
|
||||
case LSS:
|
||||
vl = (vl < vr);
|
||||
break;
|
||||
case GTR:
|
||||
vl = (vl > vr);
|
||||
break;
|
||||
case GEQ:
|
||||
vl = (vl >= vr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift : primary { shop primary }
|
||||
*/
|
||||
static int
|
||||
shift()
|
||||
{
|
||||
register int vl, vr, c;
|
||||
|
||||
vl = primary();
|
||||
while (((c = skipws()) == '<' || c == '>') && c == getch()) {
|
||||
vr = primary();
|
||||
|
||||
if (c == '<')
|
||||
vl <<= vr;
|
||||
else
|
||||
vl >>= vr;
|
||||
}
|
||||
|
||||
if (c == '<' || c == '>')
|
||||
ungetch();
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* primary : term { addop term }
|
||||
*/
|
||||
static int
|
||||
primary()
|
||||
{
|
||||
register int c, vl, vr;
|
||||
|
||||
vl = term();
|
||||
while ((c = skipws()) == '+' || c == '-') {
|
||||
vr = term();
|
||||
if (c == '+')
|
||||
vl += vr;
|
||||
else
|
||||
vl -= vr;
|
||||
}
|
||||
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* <term> := <unary> { <mulop> <unary> }
|
||||
*/
|
||||
static int
|
||||
term()
|
||||
{
|
||||
register int c, vl, vr;
|
||||
|
||||
vl = unary();
|
||||
while ((c = skipws()) == '*' || c == '/' || c == '%') {
|
||||
vr = unary();
|
||||
|
||||
switch (c) {
|
||||
case '*':
|
||||
vl *= vr;
|
||||
break;
|
||||
case '/':
|
||||
vl /= vr;
|
||||
break;
|
||||
case '%':
|
||||
vl %= vr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ungetch();
|
||||
return vl;
|
||||
}
|
||||
|
||||
/*
|
||||
* unary : factor | unop unary
|
||||
*/
|
||||
static int
|
||||
unary()
|
||||
{
|
||||
register int val, c;
|
||||
|
||||
if ((c = skipws()) == '!' || c == '~' || c == '-') {
|
||||
val = unary();
|
||||
|
||||
switch (c) {
|
||||
case '!':
|
||||
return !val;
|
||||
case '~':
|
||||
return ~val;
|
||||
case '-':
|
||||
return -val;
|
||||
}
|
||||
}
|
||||
|
||||
ungetch();
|
||||
return factor();
|
||||
}
|
||||
|
||||
/*
|
||||
* factor : constant | '(' query ')'
|
||||
*/
|
||||
static int
|
||||
factor()
|
||||
{
|
||||
register int val;
|
||||
|
||||
if (skipws() == '(') {
|
||||
val = query();
|
||||
if (skipws() != ')')
|
||||
experr("bad factor");
|
||||
return val;
|
||||
}
|
||||
|
||||
ungetch();
|
||||
return constant();
|
||||
}
|
||||
|
||||
/*
|
||||
* constant: num | 'char'
|
||||
* Note: constant() handles multi-byte constants
|
||||
*/
|
||||
static int
|
||||
constant()
|
||||
{
|
||||
register int i;
|
||||
register int value;
|
||||
register char c;
|
||||
int v[sizeof(int)];
|
||||
|
||||
if (skipws() != '\'') {
|
||||
ungetch();
|
||||
return num();
|
||||
}
|
||||
for (i = 0; i < sizeof(int); i++) {
|
||||
if ((c = getch()) == '\'') {
|
||||
ungetch();
|
||||
break;
|
||||
}
|
||||
if (c == '\\') {
|
||||
switch (c = getch()) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
ungetch();
|
||||
c = num();
|
||||
break;
|
||||
case 'n':
|
||||
c = 012;
|
||||
break;
|
||||
case 'r':
|
||||
c = 015;
|
||||
break;
|
||||
case 't':
|
||||
c = 011;
|
||||
break;
|
||||
case 'b':
|
||||
c = 010;
|
||||
break;
|
||||
case 'f':
|
||||
c = 014;
|
||||
break;
|
||||
}
|
||||
}
|
||||
v[i] = c;
|
||||
}
|
||||
if (i == 0 || getch() != '\'')
|
||||
experr("illegal character constant");
|
||||
for (value = 0; --i >= 0;) {
|
||||
value <<= 8;
|
||||
value += v[i];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* num : digit | num digit
|
||||
*/
|
||||
static int
|
||||
num()
|
||||
{
|
||||
register int rval, c, base;
|
||||
int ndig;
|
||||
|
||||
base = ((c = skipws()) == '0') ? OCTAL : DECIMAL;
|
||||
rval = 0;
|
||||
ndig = 0;
|
||||
while (c >= '0' && c <= (base == OCTAL ? '7' : '9')) {
|
||||
rval *= base;
|
||||
rval += (c - '0');
|
||||
c = getch();
|
||||
ndig++;
|
||||
}
|
||||
ungetch();
|
||||
|
||||
if (ndig == 0)
|
||||
experr("bad constant");
|
||||
|
||||
return rval;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* eqlrel : '=' | '==' | '!='
|
||||
*/
|
||||
static int
|
||||
geteql()
|
||||
{
|
||||
register int c1, c2;
|
||||
|
||||
c1 = skipws();
|
||||
c2 = getch();
|
||||
|
||||
switch (c1) {
|
||||
|
||||
case '=':
|
||||
if (c2 != '=')
|
||||
ungetch();
|
||||
return EQL;
|
||||
|
||||
case '!':
|
||||
if (c2 == '=')
|
||||
return NEQ;
|
||||
ungetch();
|
||||
ungetch();
|
||||
return -1;
|
||||
|
||||
default:
|
||||
ungetch();
|
||||
ungetch();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rel : '<' | '>' | '<=' | '>='
|
||||
*/
|
||||
static int
|
||||
getrel()
|
||||
{
|
||||
register int c1, c2;
|
||||
|
||||
c1 = skipws();
|
||||
c2 = getch();
|
||||
|
||||
switch (c1) {
|
||||
|
||||
case '<':
|
||||
if (c2 == '=')
|
||||
return LEQ;
|
||||
ungetch();
|
||||
return LSS;
|
||||
|
||||
case '>':
|
||||
if (c2 == '=')
|
||||
return GEQ;
|
||||
ungetch();
|
||||
return GTR;
|
||||
|
||||
default:
|
||||
ungetch();
|
||||
ungetch();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over any white space and return terminating char.
|
||||
*/
|
||||
static int
|
||||
skipws()
|
||||
{
|
||||
register char c;
|
||||
|
||||
while ((c = getch()) <= ' ' && c > EOS)
|
||||
;
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* resets environment to eval(), prints an error
|
||||
* and forces eval to return FALSE.
|
||||
*/
|
||||
static void
|
||||
experr(msg)
|
||||
char *msg;
|
||||
{
|
||||
printf("m4: %s in expr.\n", msg);
|
||||
longjmp(expjump, -1);
|
||||
}
|
||||
98
src/cmd/m4/extern.h
Normal file
98
src/cmd/m4/extern.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
char *basename __P((char *));
|
||||
char *xalloc __P((unsigned int));
|
||||
int expr __P((char *));
|
||||
ndptr addent __P((char *));
|
||||
void chrsave __P((int));
|
||||
void dochc __P((char *[], int));
|
||||
void dochq __P((char *[], int));
|
||||
void dodefine __P((char *, char *));
|
||||
void dodefn __P((char *));
|
||||
void dodiv __P((int));
|
||||
void dodump __P((char *[], int));
|
||||
void doifelse __P((char *[], int));
|
||||
int doincl __P((char *));
|
||||
int dopaste __P((char *));
|
||||
void dopushdef __P((char *, char *));
|
||||
void dosub __P((char *[], int));
|
||||
void doundiv __P((char *[], int));
|
||||
void eval __P((char *[], int, int));
|
||||
void expand __P((char *[], int));
|
||||
void getdiv __P((int));
|
||||
char *xstrdup __P((const char *));
|
||||
int hash __P((char *));
|
||||
int indx __P((char *, char *));
|
||||
ndptr lookup __P((char *));
|
||||
void map __P((char *, char *, char *, char *));
|
||||
int onintr __P((int));
|
||||
void oops __P((const char *, ...));
|
||||
void pbnum __P((int));
|
||||
void pbstr __P((char *));
|
||||
void putback __P((int));
|
||||
void remhash __P((char *, int));
|
||||
void usage __P((void));
|
||||
|
||||
extern ndptr hashtab[]; /* hash table for macros etc. */
|
||||
extern stae mstack[]; /* stack of m4 machine */
|
||||
extern FILE *active; /* active output file pointer */
|
||||
extern FILE *infile[]; /* input file stack (0=stdin) */
|
||||
extern FILE *outfile[]; /* diversion array(0=bitbucket) */
|
||||
extern int fp; /* m4 call frame pointer */
|
||||
extern int ilevel; /* input file stack pointer */
|
||||
extern int oindex; /* diversion index. */
|
||||
extern int sp; /* current m4 stack pointer */
|
||||
extern char *bp; /* first available character */
|
||||
extern char buf[]; /* push-back buffer */
|
||||
extern char *bufbase; /* buffer base for this ilevel */
|
||||
extern char *bbase[]; /* buffer base per ilevel */
|
||||
extern char ecommt; /* end character for comment */
|
||||
extern char *endest; /* end of string space */
|
||||
extern char *endpbb; /* end of push-back buffer */
|
||||
extern char *ep; /* first free char in strspace */
|
||||
extern char lquote; /* left quote character (`) */
|
||||
extern char *m4temp; /* filename for diversions */
|
||||
extern char *m4wraps; /* m4wrap string default. */
|
||||
extern char *null; /* as it says.. just a null. */
|
||||
extern char *progname; /* program name */
|
||||
extern char rquote; /* right quote character (') */
|
||||
extern char scommt; /* start character for comment */
|
||||
|
||||
extern char *mktemp();
|
||||
extern char *malloc();
|
||||
144
src/cmd/m4/look.c
Normal file
144
src/cmd/m4/look.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && defined(DOSCCS)
|
||||
static char sccsid[] = "@(#)look.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* look.c
|
||||
* Facility: m4 macro processor
|
||||
* by: oz
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mdef.h"
|
||||
#include "stdd.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
hash(name)
|
||||
register char *name;
|
||||
{
|
||||
register unsigned long h = 0;
|
||||
while (*name)
|
||||
h = (h << 5) + h + *name++;
|
||||
return (h % HASHSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* find name in the hash table
|
||||
*/
|
||||
ndptr
|
||||
lookup(name)
|
||||
char *name;
|
||||
{
|
||||
register ndptr p;
|
||||
|
||||
for (p = hashtab[hash(name)]; p != nil; p = p->nxtptr)
|
||||
if (STREQ(name, p->name))
|
||||
break;
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash and create an entry in the hash table.
|
||||
* The new entry is added in front of a hash bucket.
|
||||
*/
|
||||
ndptr
|
||||
addent(name)
|
||||
char *name;
|
||||
{
|
||||
register int h;
|
||||
ndptr p;
|
||||
|
||||
h = hash(name);
|
||||
p = (ndptr) xalloc(sizeof(struct ndblock));
|
||||
p->nxtptr = hashtab[h];
|
||||
hashtab[h] = p;
|
||||
p->name = xstrdup(name);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
freent(p)
|
||||
ndptr p;
|
||||
{
|
||||
if (!(p->type & STATIC)) {
|
||||
free((char *) p->name);
|
||||
if (p->defn != null)
|
||||
free((char *) p->defn);
|
||||
}
|
||||
free((char *) p);
|
||||
}
|
||||
|
||||
/*
|
||||
* remove an entry from the hashtable
|
||||
*/
|
||||
void
|
||||
remhash(name, all)
|
||||
char *name;
|
||||
int all;
|
||||
{
|
||||
register int h;
|
||||
register ndptr xp, tp, mp;
|
||||
|
||||
h = hash(name);
|
||||
mp = hashtab[h];
|
||||
tp = nil;
|
||||
while (mp != nil) {
|
||||
if (STREQ(mp->name, name)) {
|
||||
mp = mp->nxtptr;
|
||||
if (tp == nil) {
|
||||
freent(hashtab[h]);
|
||||
hashtab[h] = mp;
|
||||
}
|
||||
else {
|
||||
xp = tp->nxtptr;
|
||||
tp->nxtptr = mp;
|
||||
freent(xp);
|
||||
}
|
||||
if (!all)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
tp = mp;
|
||||
mp = mp->nxtptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
422
src/cmd/m4/main.c
Normal file
422
src/cmd/m4/main.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/*-
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && defined(DOSCCS)
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
|
||||
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main.c
|
||||
* Facility: m4 macro processor
|
||||
* by: oz
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "mdef.h"
|
||||
#include "stdd.h"
|
||||
#include "extern.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
ndptr hashtab[HASHSIZE]; /* hash table for macros etc. */
|
||||
char buf[BUFSIZE]; /* push-back buffer */
|
||||
char *bufbase = buf; /* the base for current ilevel */
|
||||
char *bbase[MAXINP]; /* the base for each ilevel */
|
||||
char *bp = buf; /* first available character */
|
||||
char *endpbb = buf+BUFSIZE; /* end of push-back buffer */
|
||||
stae mstack[STACKMAX+1]; /* stack of m4 machine */
|
||||
char strspace[STRSPMAX+1]; /* string space for evaluation */
|
||||
char *ep = strspace; /* first free char in strspace */
|
||||
char *endest= strspace+STRSPMAX;/* end of string space */
|
||||
int sp; /* current m4 stack pointer */
|
||||
int fp; /* m4 call frame pointer */
|
||||
FILE *infile[MAXINP]; /* input file stack (0=stdin) */
|
||||
FILE *outfile[MAXOUT]; /* diversion array(0=bitbucket)*/
|
||||
FILE *active; /* active output file pointer */
|
||||
char *m4temp; /* filename for diversions */
|
||||
int ilevel = 0; /* input file stack pointer */
|
||||
int oindex = 0; /* diversion index.. */
|
||||
char *null = ""; /* as it says.. just a null.. */
|
||||
char *m4wraps = ""; /* m4wrap string default.. */
|
||||
char *progname; /* name of this program */
|
||||
char lquote = LQUOTE; /* left quote character (`) */
|
||||
char rquote = RQUOTE; /* right quote character (') */
|
||||
char scommt = SCOMMT; /* start character for comment */
|
||||
char ecommt = ECOMMT; /* end character for comment */
|
||||
|
||||
struct keyblk keywrds[] = { /* m4 keywords to be installed */
|
||||
"include", INCLTYPE,
|
||||
"sinclude", SINCTYPE,
|
||||
"define", DEFITYPE,
|
||||
"defn", DEFNTYPE,
|
||||
"divert", DIVRTYPE,
|
||||
"expr", EXPRTYPE,
|
||||
"eval", EXPRTYPE,
|
||||
"substr", SUBSTYPE,
|
||||
"ifelse", IFELTYPE,
|
||||
"ifdef", IFDFTYPE,
|
||||
"len", LENGTYPE,
|
||||
"incr", INCRTYPE,
|
||||
"decr", DECRTYPE,
|
||||
"dnl", DNLNTYPE,
|
||||
"changequote", CHNQTYPE,
|
||||
"changecom", CHNCTYPE,
|
||||
"index", INDXTYPE,
|
||||
#ifdef EXTENDED
|
||||
"paste", PASTTYPE,
|
||||
"spaste", SPASTYPE,
|
||||
#endif
|
||||
"popdef", POPDTYPE,
|
||||
"pushdef", PUSDTYPE,
|
||||
"dumpdef", DUMPTYPE,
|
||||
"shift", SHIFTYPE,
|
||||
"translit", TRNLTYPE,
|
||||
"undefine", UNDFTYPE,
|
||||
"undivert", UNDVTYPE,
|
||||
"divnum", DIVNTYPE,
|
||||
"maketemp", MKTMTYPE,
|
||||
"errprint", ERRPTYPE,
|
||||
"m4wrap", M4WRTYPE,
|
||||
"m4exit", EXITTYPE,
|
||||
"syscmd", SYSCTYPE,
|
||||
"sysval", SYSVTYPE,
|
||||
|
||||
#ifdef unix
|
||||
"unix", MACRTYPE,
|
||||
#else
|
||||
#ifdef vms
|
||||
"vms", MACRTYPE,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MAXKEYS (sizeof(keywrds)/sizeof(struct keyblk))
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
void macro();
|
||||
void initkwds();
|
||||
extern int getopt();
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register int c;
|
||||
register int n;
|
||||
char *p;
|
||||
register FILE *ifp;
|
||||
|
||||
progname = basename(argv[0]);
|
||||
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
||||
signal(SIGINT, onintr);
|
||||
|
||||
initkwds();
|
||||
|
||||
while ((c = getopt(argc, argv, "tD:U:o:")) != EOF)
|
||||
switch(c) {
|
||||
|
||||
case 'D': /* define something..*/
|
||||
for (p = optarg; *p; p++)
|
||||
if (*p == '=')
|
||||
break;
|
||||
if (*p)
|
||||
*p++ = EOS;
|
||||
dodefine(optarg, p);
|
||||
break;
|
||||
case 'U': /* undefine... */
|
||||
remhash(optarg, TOP);
|
||||
break;
|
||||
case 'o': /* specific output */
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
active = stdout; /* default active output */
|
||||
/* filename for diversions */
|
||||
m4temp = mktemp(xstrdup(_PATH_DIVNAME));
|
||||
|
||||
bbase[0] = bufbase;
|
||||
if (!argc) {
|
||||
sp = -1; /* stack pointer initialized */
|
||||
fp = 0; /* frame pointer initialized */
|
||||
infile[0] = stdin; /* default input (naturally) */
|
||||
macro();
|
||||
} else
|
||||
for (; argc--; ++argv) {
|
||||
p = *argv;
|
||||
if (p[0] == '-' && p[1] == '\0')
|
||||
ifp = stdin;
|
||||
else if ((ifp = fopen(p, "r")) == NULL)
|
||||
oops("%s: %s", p, strerror(errno));
|
||||
sp = -1;
|
||||
fp = 0;
|
||||
infile[0] = ifp;
|
||||
macro();
|
||||
if (ifp != stdin)
|
||||
(void)fclose(ifp);
|
||||
}
|
||||
|
||||
if (*m4wraps) { /* anything for rundown ?? */
|
||||
ilevel = 0; /* in case m4wrap includes.. */
|
||||
bufbase = bp = buf; /* use the entire buffer */
|
||||
putback(EOF); /* eof is a must !! */
|
||||
pbstr(m4wraps); /* user-defined wrapup act */
|
||||
macro(); /* last will and testament */
|
||||
}
|
||||
|
||||
if (active != stdout)
|
||||
active = stdout; /* reset output just in case */
|
||||
for (n = 1; n < MAXOUT; n++) /* default wrap-up: undivert */
|
||||
if (outfile[n] != NULL)
|
||||
getdiv(n);
|
||||
/* remove bitbucket if used */
|
||||
if (outfile[0] != NULL) {
|
||||
(void) fclose(outfile[0]);
|
||||
m4temp[UNIQUE] = '0';
|
||||
#ifdef vms
|
||||
(void) remove(m4temp);
|
||||
#else
|
||||
(void) unlink(m4temp);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ndptr inspect();
|
||||
|
||||
/*
|
||||
* macro - the work horse..
|
||||
*/
|
||||
void
|
||||
macro() {
|
||||
char token[MAXTOK];
|
||||
register char *s;
|
||||
register int t, l;
|
||||
register ndptr p;
|
||||
register int nlpar;
|
||||
|
||||
cycle {
|
||||
if ((t = gpbc()) == '_' || isalpha(t)) {
|
||||
putback(t);
|
||||
if ((p = inspect(s = token)) == nil) {
|
||||
if (sp < 0)
|
||||
while (*s)
|
||||
putc(*s++, active);
|
||||
else
|
||||
while (*s)
|
||||
chrsave(*s++);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* real thing.. First build a call frame:
|
||||
*/
|
||||
pushf(fp); /* previous call frm */
|
||||
pushf(p->type); /* type of the call */
|
||||
pushf(0); /* parenthesis level */
|
||||
fp = sp; /* new frame pointer */
|
||||
/*
|
||||
* now push the string arguments:
|
||||
*/
|
||||
pushs(p->defn); /* defn string */
|
||||
pushs(p->name); /* macro name */
|
||||
pushs(ep); /* start next..*/
|
||||
|
||||
putback(l = gpbc());
|
||||
if (l != LPAREN) { /* add bracks */
|
||||
putback(RPAREN);
|
||||
putback(LPAREN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t == EOF) {
|
||||
if (sp > -1)
|
||||
oops("unexpected end of input", "");
|
||||
if (ilevel <= 0)
|
||||
break; /* all done thanks.. */
|
||||
--ilevel;
|
||||
(void) fclose(infile[ilevel+1]);
|
||||
bufbase = bbase[ilevel];
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* non-alpha single-char token seen..
|
||||
* [the order of else if .. stmts is important.]
|
||||
*/
|
||||
else if (t == lquote) { /* strip quotes */
|
||||
nlpar = 1;
|
||||
do {
|
||||
if ((l = gpbc()) == rquote)
|
||||
nlpar--;
|
||||
else if (l == lquote)
|
||||
nlpar++;
|
||||
else if (l == EOF)
|
||||
oops("missing right quote", "");
|
||||
if (nlpar > 0) {
|
||||
if (sp < 0)
|
||||
putc(l, active);
|
||||
else
|
||||
chrsave(l);
|
||||
}
|
||||
}
|
||||
while (nlpar != 0);
|
||||
}
|
||||
|
||||
else if (sp < 0) { /* not in a macro at all */
|
||||
if (t == scommt) { /* comment handling here */
|
||||
putc(t, active);
|
||||
while ((t = gpbc()) != ecommt)
|
||||
putc(t, active);
|
||||
}
|
||||
putc(t, active); /* output directly.. */
|
||||
}
|
||||
|
||||
else switch(t) {
|
||||
|
||||
case LPAREN:
|
||||
if (PARLEV > 0)
|
||||
chrsave(t);
|
||||
while (isspace(l = gpbc()))
|
||||
; /* skip blank, tab, nl.. */
|
||||
putback(l);
|
||||
PARLEV++;
|
||||
break;
|
||||
|
||||
case RPAREN:
|
||||
if (--PARLEV > 0)
|
||||
chrsave(t);
|
||||
else { /* end of argument list */
|
||||
chrsave(EOS);
|
||||
|
||||
if (sp == STACKMAX)
|
||||
oops("internal stack overflow", "");
|
||||
|
||||
if (CALTYP == MACRTYPE)
|
||||
expand((char **) mstack+fp+1, sp-fp);
|
||||
else
|
||||
eval((char **) mstack+fp+1, sp-fp, CALTYP);
|
||||
|
||||
ep = PREVEP; /* flush strspace */
|
||||
sp = PREVSP; /* previous sp.. */
|
||||
fp = PREVFP; /* rewind stack...*/
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMA:
|
||||
if (PARLEV == 1) {
|
||||
chrsave(EOS); /* new argument */
|
||||
while (isspace(l = gpbc()))
|
||||
;
|
||||
putback(l);
|
||||
pushs(ep);
|
||||
} else
|
||||
chrsave(t);
|
||||
break;
|
||||
|
||||
default:
|
||||
chrsave(t); /* stack the char */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* build an input token..
|
||||
* consider only those starting with _ or A-Za-z. This is a
|
||||
* combo with lookup to speed things up.
|
||||
*/
|
||||
ndptr
|
||||
inspect(tp)
|
||||
register char *tp;
|
||||
{
|
||||
register char c;
|
||||
register char *name = tp;
|
||||
register char *etp = tp+MAXTOK;
|
||||
register ndptr p;
|
||||
register unsigned long h = 0;
|
||||
|
||||
while ((isalnum(c = gpbc()) || c == '_') && tp < etp)
|
||||
h = (h << 5) + h + (*tp++ = c);
|
||||
putback(c);
|
||||
if (tp == etp)
|
||||
oops("token too long", "");
|
||||
|
||||
*tp = EOS;
|
||||
|
||||
for (p = hashtab[h%HASHSIZE]; p != nil; p = p->nxtptr)
|
||||
if (STREQ(name, p->name))
|
||||
break;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* initkwds - initialise m4 keywords as fast as possible.
|
||||
* This very similar to install, but without certain overheads,
|
||||
* such as calling lookup. Malloc is not used for storing the
|
||||
* keyword strings, since we simply use the static pointers
|
||||
* within keywrds block.
|
||||
*/
|
||||
void
|
||||
initkwds() {
|
||||
register int i;
|
||||
register int h;
|
||||
register ndptr p;
|
||||
|
||||
for (i = 0; i < MAXKEYS; i++) {
|
||||
h = hash(keywrds[i].knam);
|
||||
p = (ndptr) xalloc(sizeof(struct ndblock));
|
||||
p->nxtptr = hashtab[h];
|
||||
hashtab[h] = p;
|
||||
p->name = keywrds[i].knam;
|
||||
p->defn = null;
|
||||
p->type = keywrds[i].ktyp | STATIC;
|
||||
}
|
||||
}
|
||||
176
src/cmd/m4/mdef.h
Normal file
176
src/cmd/m4/mdef.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mdef.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#define MACRTYPE 1
|
||||
#define DEFITYPE 2
|
||||
#define EXPRTYPE 3
|
||||
#define SUBSTYPE 4
|
||||
#define IFELTYPE 5
|
||||
#define LENGTYPE 6
|
||||
#define CHNQTYPE 7
|
||||
#define SYSCTYPE 8
|
||||
#define UNDFTYPE 9
|
||||
#define INCLTYPE 10
|
||||
#define SINCTYPE 11
|
||||
#define PASTTYPE 12
|
||||
#define SPASTYPE 13
|
||||
#define INCRTYPE 14
|
||||
#define IFDFTYPE 15
|
||||
#define PUSDTYPE 16
|
||||
#define POPDTYPE 17
|
||||
#define SHIFTYPE 18
|
||||
#define DECRTYPE 19
|
||||
#define DIVRTYPE 20
|
||||
#define UNDVTYPE 21
|
||||
#define DIVNTYPE 22
|
||||
#define MKTMTYPE 23
|
||||
#define ERRPTYPE 24
|
||||
#define M4WRTYPE 25
|
||||
#define TRNLTYPE 26
|
||||
#define DNLNTYPE 27
|
||||
#define DUMPTYPE 28
|
||||
#define CHNCTYPE 29
|
||||
#define INDXTYPE 30
|
||||
#define SYSVTYPE 31
|
||||
#define EXITTYPE 32
|
||||
#define DEFNTYPE 33
|
||||
|
||||
#define STATIC 128
|
||||
|
||||
/*
|
||||
* m4 special characters
|
||||
*/
|
||||
|
||||
#define ARGFLAG '$'
|
||||
#define LPAREN '('
|
||||
#define RPAREN ')'
|
||||
#define LQUOTE '`'
|
||||
#define RQUOTE '\''
|
||||
#define COMMA ','
|
||||
#define SCOMMT '#'
|
||||
#define ECOMMT '\n'
|
||||
|
||||
#ifdef msdos
|
||||
#define system(str) (-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* other important constants
|
||||
*/
|
||||
|
||||
#define EOS (char) 0
|
||||
#define MAXINP 10 /* maximum include files */
|
||||
#define MAXOUT 10 /* maximum # of diversions */
|
||||
#define MAXSTR 512 /* maximum size of string */
|
||||
#define BUFSIZE 4096 /* size of pushback buffer */
|
||||
#define STACKMAX 1024 /* size of call stack */
|
||||
#define STRSPMAX 4096 /* size of string space */
|
||||
#define MAXTOK MAXSTR /* maximum chars in a tokn */
|
||||
#define HASHSIZE 199 /* maximum size of hashtab */
|
||||
|
||||
#define ALL 1
|
||||
#define TOP 0
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define cycle for(;;)
|
||||
|
||||
/*
|
||||
* m4 data structures
|
||||
*/
|
||||
|
||||
typedef struct ndblock *ndptr;
|
||||
|
||||
struct ndblock { /* hastable structure */
|
||||
char *name; /* entry name.. */
|
||||
char *defn; /* definition.. */
|
||||
int type; /* type of the entry.. */
|
||||
ndptr nxtptr; /* link to next entry.. */
|
||||
};
|
||||
|
||||
#define nil ((ndptr) 0)
|
||||
|
||||
struct keyblk {
|
||||
char *knam; /* keyword name */
|
||||
int ktyp; /* keyword type */
|
||||
};
|
||||
|
||||
typedef union { /* stack structure */
|
||||
int sfra; /* frame entry */
|
||||
char *sstr; /* string entry */
|
||||
} stae;
|
||||
|
||||
/*
|
||||
* macros for readibility and/or speed
|
||||
*
|
||||
* gpbc() - get a possibly pushed-back character
|
||||
* pushf() - push a call frame entry onto stack
|
||||
* pushs() - push a string pointer onto stack
|
||||
*/
|
||||
#define gpbc() (bp > bufbase) ? *--bp : getc(infile[ilevel])
|
||||
#define pushf(x) if (sp < STACKMAX) mstack[++sp].sfra = (x)
|
||||
#define pushs(x) if (sp < STACKMAX) mstack[++sp].sstr = (x)
|
||||
|
||||
/*
|
||||
* . .
|
||||
* | . | <-- sp | . |
|
||||
* +-------+ +-----+
|
||||
* | arg 3 ----------------------->| str |
|
||||
* +-------+ | . |
|
||||
* | arg 2 ---PREVEP-----+ .
|
||||
* +-------+ |
|
||||
* . | | |
|
||||
* +-------+ | +-----+
|
||||
* | plev | PARLEV +-------->| str |
|
||||
* +-------+ | . |
|
||||
* | type | CALTYP .
|
||||
* +-------+
|
||||
* | prcf ---PREVFP--+
|
||||
* +-------+ |
|
||||
* | . | PREVSP |
|
||||
* . |
|
||||
* +-------+ |
|
||||
* | <----------+
|
||||
* +-------+
|
||||
*
|
||||
*/
|
||||
#define PARLEV (mstack[fp].sfra)
|
||||
#define CALTYP (mstack[fp-1].sfra)
|
||||
#define PREVEP (mstack[fp+3].sstr)
|
||||
#define PREVSP (fp-3)
|
||||
#define PREVFP (mstack[fp-2].sfra)
|
||||
244
src/cmd/m4/misc.c
Normal file
244
src/cmd/m4/misc.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && defined(DOSCCS)
|
||||
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mdef.h"
|
||||
#include "stdd.h"
|
||||
#include "extern.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/*
|
||||
* find the index of second str in the first str.
|
||||
*/
|
||||
int
|
||||
indx(s1, s2)
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
register char *t;
|
||||
register char *p;
|
||||
register char *m;
|
||||
|
||||
for (p = s1; *p; p++) {
|
||||
for (t = p, m = s2; *m && *m == *t; m++, t++);
|
||||
if (!*m)
|
||||
return (p - s1);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* putback - push character back onto input
|
||||
*/
|
||||
void
|
||||
putback(c)
|
||||
char c;
|
||||
{
|
||||
if (bp < endpbb)
|
||||
*bp++ = c;
|
||||
else
|
||||
oops("too many characters pushed back");
|
||||
}
|
||||
|
||||
/*
|
||||
* pbstr - push string back onto input
|
||||
* putback is replicated to improve
|
||||
* performance.
|
||||
*/
|
||||
void
|
||||
pbstr(s)
|
||||
register char *s;
|
||||
{
|
||||
register char *es;
|
||||
register char *zp;
|
||||
|
||||
es = s;
|
||||
zp = bp;
|
||||
|
||||
while (*es)
|
||||
es++;
|
||||
es--;
|
||||
while (es >= s)
|
||||
if (zp < endpbb)
|
||||
*zp++ = *es--;
|
||||
if ((bp = zp) == endpbb)
|
||||
oops("too many characters pushed back");
|
||||
}
|
||||
|
||||
/*
|
||||
* pbnum - convert number to string, push back on input.
|
||||
*/
|
||||
void
|
||||
pbnum(n)
|
||||
int n;
|
||||
{
|
||||
register int num;
|
||||
|
||||
num = (n < 0) ? -n : n;
|
||||
do {
|
||||
putback(num % 10 + '0');
|
||||
}
|
||||
while ((num /= 10) > 0);
|
||||
|
||||
if (n < 0)
|
||||
putback('-');
|
||||
}
|
||||
|
||||
/*
|
||||
* chrsave - put single char on string space
|
||||
*/
|
||||
void
|
||||
chrsave(c)
|
||||
char c;
|
||||
{
|
||||
if (ep < endest)
|
||||
*ep++ = c;
|
||||
else
|
||||
oops("string space overflow");
|
||||
}
|
||||
|
||||
/*
|
||||
* read in a diversion file, and dispose it.
|
||||
*/
|
||||
void
|
||||
getdiv(n)
|
||||
int n;
|
||||
{
|
||||
register int c;
|
||||
register FILE *dfil;
|
||||
|
||||
if (active == outfile[n])
|
||||
oops("%s: diversion still active.", "undivert");
|
||||
(void) fclose(outfile[n]);
|
||||
outfile[n] = NULL;
|
||||
m4temp[UNIQUE] = n + '0';
|
||||
if ((dfil = fopen(m4temp, "r")) == NULL)
|
||||
oops("%s: cannot undivert.", m4temp);
|
||||
else
|
||||
while ((c = getc(dfil)) != EOF)
|
||||
putc(c, active);
|
||||
(void) fclose(dfil);
|
||||
|
||||
#ifdef vms
|
||||
if (remove(m4temp))
|
||||
#else
|
||||
if (unlink(m4temp) == -1)
|
||||
#endif
|
||||
oops("%s: cannot unlink.", m4temp);
|
||||
}
|
||||
|
||||
int
|
||||
onintr()
|
||||
{
|
||||
oops("interrupted.");
|
||||
}
|
||||
|
||||
char *
|
||||
xalloc(n)
|
||||
unsigned n;
|
||||
{
|
||||
register char *p = malloc(n);
|
||||
|
||||
if (p == NULL)
|
||||
oops("malloc: %s", strerror(errno));
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
xstrdup(s)
|
||||
char *s;
|
||||
{
|
||||
register char *p = strdup(s);
|
||||
if (p == NULL)
|
||||
oops("strdup: %s", strerror(errno));
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
basename(s)
|
||||
register char *s;
|
||||
{
|
||||
register char *p;
|
||||
extern char *strrchr();
|
||||
|
||||
if ((p = strrchr(s, '/')) == NULL)
|
||||
return s;
|
||||
|
||||
return ++p;
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
oops(const char *fmt, ...)
|
||||
#else
|
||||
/* VARARGS1 */
|
||||
oops(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "%s: ", progname);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
57
src/cmd/m4/pathnames.h
Normal file
57
src/cmd/m4/pathnames.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions of diversion files. If the name of the file is changed,
|
||||
* adjust UNIQUE to point to the wildcard (*) character in the filename.
|
||||
*/
|
||||
|
||||
#ifdef msdos
|
||||
#define _PATH_DIVNAME "\\M4*XXXXXX" /* msdos diversion files */
|
||||
#define UNIQUE 3 /* unique char location */
|
||||
#endif
|
||||
|
||||
#ifdef unix
|
||||
#define _PATH_DIVNAME "/tmp/m4.0XXXXXX" /* unix diversion files */
|
||||
#define UNIQUE 8 /* unique char location */
|
||||
#endif
|
||||
|
||||
#ifdef vms
|
||||
#define _PATH_DIVNAME "sys$login:m4*XXXXXX" /* vms diversion files */
|
||||
#define UNIQUE 12 /* unique char location */
|
||||
#endif
|
||||
60
src/cmd/m4/stdd.h
Normal file
60
src/cmd/m4/stdd.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ozan Yigit at York University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)stdd.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* standard defines
|
||||
*/
|
||||
|
||||
#define max(a,b) ((a) > (b)? (a): (b))
|
||||
#define min(a,b) ((a) < (b)? (a): (b))
|
||||
|
||||
#define iswhite(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
/*
|
||||
* STREQ is an optimised strcmp(a,b)==0
|
||||
* STREQN is an optimised strncmp(a,b,n)==0; assumes n > 0
|
||||
*/
|
||||
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
|
||||
#define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define __P(protos) ()
|
||||
|
||||
extern int errno;
|
||||
70
src/cmd/m4/tags
Normal file
70
src/cmd/m4/tags
Normal file
@@ -0,0 +1,70 @@
|
||||
Mmain main.c /^main(argc,argv)$/
|
||||
STREQ stdd.h /^#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a,/
|
||||
STREQN stdd.h /^#define STREQN(a, b, n) ((a)[0] == (b)[0] && strnc/
|
||||
__P stdd.h /^#define __P(protos) ()$/
|
||||
addent look.c /^ndptr $/
|
||||
band expr.c /^band()$/
|
||||
basename misc.c /^basename(s)$/
|
||||
bor expr.c /^bor()$/
|
||||
bxor expr.c /^bxor()$/
|
||||
chrsave misc.c /^chrsave(c)$/
|
||||
constant expr.c /^constant()$/
|
||||
dochc eval.c /^dochc(argv, argc)$/
|
||||
dochq eval.c /^dochq(argv, argc)$/
|
||||
dodefine eval.c /^dodefine(name, defn)$/
|
||||
dodefn eval.c /^dodefn(name)$/
|
||||
dodiv eval.c /^dodiv(n)$/
|
||||
dodump eval.c /^dodump(argv, argc)$/
|
||||
doifelse eval.c /^doifelse(argv, argc)$/
|
||||
doincl eval.c /^doincl(ifile)$/
|
||||
dopaste eval.c /^dopaste(pfile)$/
|
||||
dopushdef eval.c /^dopushdef(name, defn)$/
|
||||
dosub eval.c /^dosub(argv, argc)$/
|
||||
doundiv eval.c /^doundiv(argv, argc)$/
|
||||
eql expr.c /^eql()$/
|
||||
eval eval.c /^eval(argv, argc, td)$/
|
||||
expand eval.c /^expand(argv, argc)$/
|
||||
experr expr.c /^experr(msg)$/
|
||||
expr expr.c /^expr(expbuf)$/
|
||||
factor expr.c /^factor()$/
|
||||
freent look.c /^freent(p)$/
|
||||
getch expr.c /^#define getch() *nxtch++$/
|
||||
getdiv misc.c /^getdiv(n)$/
|
||||
geteql expr.c /^geteql()$/
|
||||
getrel expr.c /^getrel()$/
|
||||
gpbc mdef.h /^#define gpbc() (bp > bufbase) ? *--bp : getc(inf/
|
||||
hash look.c /^hash(name)$/
|
||||
indx misc.c /^indx(s1, s2)$/
|
||||
initkwds main.c /^initkwds() {$/
|
||||
inspect main.c /^inspect(tp) $/
|
||||
iswhite stdd.h /^#define iswhite(c) ((c) == ' ' || (c) == '\\t')$/
|
||||
land expr.c /^land()$/
|
||||
lookup look.c /^ndptr $/
|
||||
lor expr.c /^lor()$/
|
||||
macro main.c /^macro() {$/
|
||||
map eval.c /^map(dest, src, from, to)$/
|
||||
max stdd.h /^#define max(a,b) ((a) > (b)? (a): (b))$/
|
||||
min stdd.h /^#define min(a,b) ((a) < (b)? (a): (b))$/
|
||||
ndptr mdef.h 117
|
||||
num expr.c /^num()$/
|
||||
onintr misc.c /^onintr()$/
|
||||
oops misc.c /^oops(const char *fmt, ...)$/
|
||||
pbnum misc.c /^pbnum(n)$/
|
||||
pbstr misc.c /^pbstr(s)$/
|
||||
primary expr.c /^primary()$/
|
||||
pushf mdef.h /^#define pushf(x) if (sp < STACKMAX) mstack[++sp].s/
|
||||
pushs mdef.h /^#define pushs(x) if (sp < STACKMAX) mstack[++sp].s/
|
||||
putback misc.c /^putback(c)$/
|
||||
query expr.c /^query()$/
|
||||
relat expr.c /^relat()$/
|
||||
remhash look.c /^remhash(name, all)$/
|
||||
shift expr.c /^shift()$/
|
||||
skipws expr.c /^skipws()$/
|
||||
stae mdef.h 136
|
||||
system mdef.h /^#define system(str) (-1)$/
|
||||
term expr.c /^term()$/
|
||||
unary expr.c /^unary()$/
|
||||
ungetch expr.c /^#define ungetch() nxtch--$/
|
||||
usage misc.c /^usage()$/
|
||||
xalloc misc.c /^xalloc(n)$/
|
||||
xstrdup misc.c /^xstrdup(s)$/
|
||||
Reference in New Issue
Block a user