baseline of new version of m4 supplied by Ozan Yigit, original author

of the broken m4 we had.  This is his stuff virgin + our Makefile.
This commit is contained in:
glass 1993-06-18 21:50:26 +00:00
parent e66e5354ca
commit 0d66213fcd
17 changed files with 2264 additions and 1620 deletions

View File

@ -5,7 +5,7 @@
PROG= m4
CFLAGS+=-DEXTENDED
SRCS = main.c eval.c serv.c look.c misc.c expr.c
NOMAN= noman
SRCS = expr.c int2str.c look.c main.c misc.c serv.c
MAN1 = m4.0
.include <bsd.prog.mk>

View File

@ -1,40 +1,2 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
define(ack, `ifelse($1,0,incr($2),$2,0,`ack(DECR($1),1)',
`ack(DECR($1), ack($1,DECR($2)))')')

View File

@ -1,41 +1,3 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
define(hanoi, `trans(A, B, C, $1)')
define(moved,`move disk from $1 to $2

View File

@ -1,41 +1,3 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
dnl This probably will not run on any m4 that cannot
dnl handle char constants in eval.
dnl

View File

@ -1,41 +1,3 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
define(square_root,
`ifelse(eval($1<0),1,negative-square-root,
`square_root_aux($1, 1, eval(($1+1)/2))')')

View File

@ -1,40 +1,3 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
define(string,`integer $1(len(substr($2,1)))
str($1,substr($2,1),0)

View File

@ -1,41 +1,4 @@
#
# Copyright (c) 1989 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 5.2 (Berkeley) 4/12/91
#
# test file for mp (not comprehensive)
#
# v7 m4 does not have `decr'.

File diff suppressed because it is too large Load Diff

View File

@ -1,59 +1,160 @@
/*
* Copyright (c) 1989 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.
*
* @(#)extr.h 5.2 (Berkeley) 6/1/90
*/
/* Header : extr.h
Author : Ozan Yigit
Updated: %G%
*/
#ifndef putback
extern ndptr hashtab[]; /* hash table for macros etc. */
extern char buf[]; /* push-back buffer */
extern char buf[]; /* push-back buffer */
extern char *bp; /* first available character */
extern char *bb; /* current beginning of bp */
extern char *endpbb; /* end of push-back buffer */
extern stae mstack[]; /* stack of m4 machine */
extern stae mstack[]; /* stack of m4 machine */
extern char *ep; /* first free char in strspace */
extern char *endest; /* end of string space */
int sp; /* current m4 stack pointer */
int fp; /* m4 call frame pointer */
extern int sp; /* current m4 stack pointer */
extern int fp; /* m4 call frame pointer */
extern char *bbstack[];
extern FILE *infile[]; /* input file stack (0=stdin) */
extern FILE *outfile[]; /* diversion array(0=bitbucket)*/
extern FILE *active; /* active output file pointer */
extern char *m4temp; /* filename for diversions */
extern int ilevel; /* input file stack pointer */
extern int oindex; /* diversion index.. */
extern int UNIQUE; /* where to change m4temp */
extern int ilevel; /* input file stack pointer */
extern int oindex; /* diversion index.. */
extern char *null; /* as it says.. just a null.. */
extern char *m4wraps; /* m4wrap string default.. */
extern char lquote; /* left quote character (`) */
extern char rquote; /* right quote character (') */
extern char scommt; /* start character for comment */
extern char ecommt; /* end character for comment */
extern char lquote; /* left quote character (`) */
extern char rquote; /* right quote character (') */
extern char vquote; /* verbatim quote character ^V */
extern char scommt; /* start character for comment */
extern char ecommt; /* end character for comment */
/* inlined versions of chrsave() and putback() */
extern char pbmsg[]; /* error message for putback */
extern char csmsg[]; /* error message for chrsave */
#define putback(c) do { if (bp >= endpbb) error(pbmsg); *bp++ = c; } while (0)
#define chrsave(c) do { if (ep >= endest) error(csmsg); *ep++ = c; } while (0)
/* getopt() interface */
extern char * optarg;
extern int optind;
#ifdef __STDC__
extern int getopt(int, char **, char *);
#else
extern int getopt();
#endif
#ifdef __STDC__
#include <stdlib.h>
/* functions from misc.c */
extern char * strsave(char *);
extern int indx(char *, char *);
extern void pbstr(char *);
extern void pbqtd(char *);
extern void pbnum(int);
extern void pbrad(long int, int, int);
extern void getdiv(int);
extern void killdiv();
extern void error(char *);
extern void onintr(int);
extern void usage();
/* functions from look.c */
extern ndptr lookup(char *);
extern ndptr addent(char *);
extern void remhash(char *, int);
extern void addkywd(char *, int);
/* functions from int2str.c */
extern char* int2str(/* char*, int, long */);
/* functions from serv.c */
extern void expand(char **, int);
extern void dodefine(char *, char *);
extern void dopushdef(char *, char *);
extern void dodefn(char *);
extern void dodump(char **, int);
extern void doifelse(char **, int);
extern int doincl(char *);
extern void dochq(char **, int);
extern void dochc(char **, int);
extern void dodiv(int);
extern void doundiv(char **, int);
extern void dosub(char **, int);
extern void map(char *, char *, char *, char *);
#ifdef EXTENDED
extern int dopaste(char *);
extern void m4trim(char **, int);
extern void dodefqt(char **, int);
extern void doqutr(char **, int);
#endif
/* functions from expr.c */
extern long expr(char *);
#else
/* functions from misc.c */
extern char * malloc();
extern char * strsave();
extern int indx();
extern void pbstr();
extern void pbqtd();
extern void pbnum();
extern void pbrad();
extern void getdiv();
extern void killdiv();
extern void error();
extern int onintr();
extern void usage();
/* functions from look.c */
extern ndptr lookup();
extern ndptr addent();
extern void remhash();
extern void addkywd();
/* functions from int2str.c */
extern char* int2str(/* char*, int, long */);
/* functions from serv.c */
extern void expand();
extern void dodefine();
extern void dopushdef();
extern void dodefn();
extern void dodump();
extern void doifelse();
extern int doincl();
extern void dochq();
extern void dochc();
extern void dodiv();
extern void doundiv();
extern void dosub();
extern void map();
#ifdef EXTENDED
extern int dopaste();
extern void m4trim();
extern void dodefqt();
extern void doqutr();
#endif
/* functions from expr.c */
extern long expr();
#endif
#endif

58
usr.bin/m4/int2str.c Normal file
View File

@ -0,0 +1,58 @@
/* File : int2str.c
Author : Richard A. O'Keefe
Updated: 6 February 1993
Defines: int2str()
int2str(dst, radix, val)
converts the (long) integer "val" to character form and moves it to
the destination string "dst" followed by a terminating NUL. The
result is normally a pointer to this NUL character, but if the radix
is dud the result will be NullS and nothing will be changed.
If radix is -2..-36, val is taken to be SIGNED.
If radix is 2.. 36, val is taken to be UNSIGNED.
That is, val is signed if and only if radix is. You will normally
use radix -10 only through itoa and ltoa, for radix 2, 8, or 16
unsigned is what you generally want.
*/
static char dig_vec[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *int2str(dst, radix, val)
register char *dst;
register int radix;
register long val;
{
char buffer[65]; /* Ready for 64-bit machines */
register char *p;
if (radix < 2 || radix > 36) { /* Not 2..36 */
if (radix > -2 || radix < -36) return (char *)0;
if (val < 0) {
*dst++ = '-';
val = -val;
}
radix = -radix;
}
/* The slightly contorted code which follows is due to the
fact that few machines directly support unsigned long / and %.
Certainly the VAX C compiler generates a subroutine call. In
the interests of efficiency (hollow laugh) I let this happen
for the first digit only; after that "val" will be in range so
that signed integer division will do. Sorry 'bout that.
CHECK THE CODE PRODUCED BY YOUR C COMPILER. The first % and /
should be unsigned, the second % and / signed, but C compilers
tend to be extraordinarily sensitive to minor details of style.
This works on a VAX, that's all I claim for it.
*/
p = &buffer[sizeof buffer];
*--p = '\0';
*--p = dig_vec[(unsigned long)val%(unsigned long)radix];
val = (unsigned long)val/(unsigned long)radix;
while (val != 0) *--p = dig_vec[val%radix], val /= radix;
while (*dst++ = *p++) ;
return dst-1;
}

View File

@ -1,153 +1,107 @@
/*
* Copyright (c) 1989 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.
*/
/* File : look.c
Author : Ozan Yigit
Updated: 4 May 1992
Purpose: Hash table for M4
*/
#ifndef lint
static char sccsid[] = "@(#)look.c 5.3 (Berkeley) 2/26/91";
#endif /* not lint */
/*
* look.c
* Facility: m4 macro processor
* by: oz
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mdef.h"
#include "extr.h"
/*
* hash - compute hash value using the proverbial
* hashing function. Taken from K&R.
*/
hash (name)
register char *name;
{
register int h = 0;
while (*name)
h += *name++;
return (h % HASHSIZE);
}
ndptr hashtab[HASHSIZE];
/*
* lookup - find name in the hash table
*
* hash - get a hash value for string s
*/
ndptr lookup(name)
int
hash(name)
char *name;
{
register unsigned long h = 0;
while (*name)
h = (h << 5) + h + *name++;
return h % HASHSIZE;
}
/*
* lookup(name) - 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 (strcmp(name, p->name) == 0)
break;
return (p);
}
if (strcmp(name, p->name) == 0)
break;
return p;
}
/*
* addent - hash and create an entry in the hash
* table. The new entry is added in front
* of a hash bucket.
/*
* addent(name) - hash and create an entry in the hash table.
* The new entry is added at the front of a hash bucket.
* BEWARE: the type and defn fields are UNDEFINED.
*/
ndptr addent(name)
char *name;
{
register int h;
ndptr p;
char *name;
{
register ndptr p, *h;
h = hash(name);
if ((p = (ndptr) malloc(sizeof(struct ndblock))) != NULL) {
p->nxtptr = hashtab[h];
hashtab[h] = p;
p->name = strdup(name);
}
else
error("m4: no more memory.");
p = (ndptr)malloc(sizeof *p);
if (p == NULL) error("m4: no more memory.");
h = &hashtab[hash(name)];
p->name = strsave(name);
p->defn = null;
p->nxtptr = *h;
*h = p;
return p;
}
}
/*
* remhash - remove an entry from the hashtable
*
/*
* addkywd(name, type) - stores a keyword in the hash table.
*/
remhash(name, all)
char *name;
int all;
{
register int h;
register ndptr xp, tp, mp;
void addkywd(name, type)
char *name;
int type;
{
register ndptr p = addent(name);
p->type = type | STATIC;
}
h = hash(name);
mp = hashtab[h];
tp = nil;
while (mp != nil) {
if (strcmp(mp->name, name) == 0) {
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;
}
}
}
/*
* freent - free a hashtable information block
*
/*
* remhash(name, all)
* remove one entry (all==0) or all entries (all!=0) for a given name
* from the hash table. All hash table entries must have been obtained
* from malloc(), so it is safe to free the records themselves.
* However, the ->name and ->defn fields might point to storage which
* was obtained from strsave() -- in which case they may be freed -- or
* to static storage -- in which case they must not be freed. If the
* STATIC bit is set, the fields are not to be freed.
*/
freent(p)
ndptr p;
{
if (!(p->type & STATIC)) {
free(p->name);
if (p->defn != null)
free(p->defn);
}
free(p);
}
void remhash(name, all)
char *name;
int all;
{
register ndptr p, *h;
/* h always points to the pointer to p */
h = &hashtab[hash(name)];
while ((p = *h) != nil) {
if (strcmp(p->name, name) == 0) {
*h = p->nxtptr; /* delink this record */
if (!(p->type & STATIC)) { /* free the name and defn */
free(p->name); /* if they came from strsave */
if (p->defn != null) free(p->defn);
} /* otherwise leave them */
free(p); /* free the record itself */
if (!all) return; /* first occurrence has gone */
} else {
h = &(p->nxtptr);
}
}
}

179
usr.bin/m4/m4.1 Normal file
View File

@ -0,0 +1,179 @@
.\"
.\" @(#) $Id: m4.1,v 1.1 1993/06/18 21:50:31 glass Exp $
.\"
.Dd January 26, 1993
.Dt m4 1
.Os
.Sh NAME
.Nm m4
.Nd macro language processor
.Sh SYNOPSIS
.Nm m4
.Oo
.Fl D Ns Ar name Ns Op Ar =value
.Oc
.Op Fl U Ns Ar name
.Sh DESCRIPTION
The
.Nm m4
utility is a macro processor that can be used as a front end to any
language (e.g., C, ratfor, fortran, lex, and yacc).
.Nm m4
reads from the standard input and writes
the processed text to the standard output.
.Pp
Macro calls have the form name(argument1[, argument2, ...,] argumentN).
.Pp
There cannot be any space following the macro name and the open
parentheses '('. If the macro name is not followed by an open
parentheses it is processed with no arguments.
.Pp
Macro names consist of a leading alphabetic or underscore
possibly followed by alphanumeric or underscore characters, therefore
valid macro names match this pattern [a-zA-Z_][a-zA-Z0-9_]*.
.Pp
In arguments to macros, leading unquoted space, tab and newline
characters are ignored. To quote strings use left and right single
quotes (e.g., ` this is a string with a leading space'). You can change
the quote characters with the changequote built-in macro.
.Pp
The options are as follows:
.Bl -tag -width "-Dname[=value]xxx"
.It Fl D Ns Ar name Ns Oo
.Ar =value
.Oc
Define the symbol
.Ar name
to have some value (or NULL).
.It Fl "U" Ns Ar "name"
Undefine the symbol
.Ar name .
.El
.Sh SYNTAX
.Nm m4
provides the following built-in macros. They may be
redefined, loosing their original meaning.
Return values are NULL unless otherwise stated.
.Bl -tag -width changequotexxx
.It changecom
Change the start and end comment sequences. The default is
the pound sign `#' and the newline character. With no arguments
comments are turned off. The maximum length for a comment marker is
five characters.
.It changequote
Defines the quote symbols to be the first and second arguments.
The symbols may be up to five characters long. If no arguments are
given it restores the default open and close single quotes.
.It decr
Decrements the argument by 1. The argument must be a valid numeric string.
.It define
Define a new macro named by the first argument to have the
value of the second argument. Each occurrence of $n (where n
is 0 through 9) is replaced by the n'th argument. $0 is the name
of the calling macro. Undefined arguments are replaced by a
NULL string. $# is replaced by the number of arguments; $*
is replaced by all arguments comma separated; $@ is the same
as $* but all arguments are quoted against further expansion.
.It defn
Returns the quoted definition for each argument. This can be used to rename
macro definitions (even for built-in macros).
.It divert
There are 10 output queues (numbered 0-9).
At the end of processing
.Nm m4
concatenates all the queues in numerical order to produce the
final output. Initially the output queue is 0. The divert
macro allows you to select a new output queue (an invalid argument
passed to divert causes output to be discarded).
.It divnum
Returns the current output queue number.
.It dnl
Discard input characters up to and including the next newline.
.It dumpdef
Prints the names and definitions for the named items, or for everything
if no arguments are passed.
.It errprint
Prints the first argument on the standard error output stream.
.It eval
Computes the first argument as an arithmetic expression using 32-bit
arithmetic. Operators are the standard C ternary, arithmetic, logical,
shift, relational, bitwise, and parentheses operators. You can specify
octal, decimal, and hexadecimal numbers as in C. The second argument (if
any) specifies the radix for the result and the third argument (if
any) specifies the minimum number of digits in the result.
.It expr
This is an alias for eval.
.It ifdef
If the macro named by the first argument is defined then return the second
argument, otherwise the third. If there is no third argument,
the value is NULL. The word `unix' is predefined.
.It ifelse
If the first argument matches the second argument then ifelse returns
the third argument. If the match fails the three arguments are
discarded and the next three arguments are used until there is
zero or one arguments left, either this last argument or NULL is
returned if no other matches were found.
.It include
Returns the contents of the file specified in the first argument.
Include aborts with an error message if the file cannot be included.
.It incr
Increments the argument by 1. The argument must be a valid numeric string.
.It index
Returns the index of the second argument in the first argument (e.g.,
index(the quick brown fox jumped, fox) returns 16). If the second
argument is not found index returns -1.
.It len
Returns the number of characters in the first argument. Extra arguments
are ignored.
.It m4exit
Immediately exits with the return value specified by the first argument,
0 if none.
.It m4wrap
Allows you to define what happens at the final EOF, usually for cleanup
purposes (e.g., m4wrap("cleanup(tempfile)") causes the macro cleanup to
invoked after all other processing is done.)
.It maketemp
Translates the string XXXXX in the first argument with the current process
ID leaving other characters alone. This can be used to create unique
temporary file names.
.It paste
Includes the contents of the file specified by the first argument without
any macro processing. Aborts with an error message if the file cannot be
included.
.It popdef
Restores the pushdef'ed definition for each argument.
.It pushdef
Takes the same arguments as define, but it saves the definition on a
stack for later retrieval by popdef.
.It shift
Returns all but the first argument, the remaining arguments are
quoted and pushed back with commas in between. The quoting
nullifies the effect of the extra scan that will subsequently be
performed.
.It sinclude
Similar to include, except it ignores any errors.
.It spaste
Similar to spaste, except it ignores any errors.
.It substr
Returns a substring of the first argument starting at the offset specified
by the second argument and the length specified by the third argument.
If no third argument is present it returns the rest of the string.
.It syscmd
Passes the first argument to the shell. Nothing is returned.
.It sysval
Returns the return value from the last syscmd.
.It translit
Transliterate the characters in the first argument from the set
given by the second argument to the set given by the third. You cannot
use
.Xr tr 1
style abbreviations.
.It undefine
Removes the definition for the macro specified by the first argument.
.It undivert
Flushes the named output queues (or all queues if no arguments).
.It unix
A pre-defined macro for testing the OS platform.
.El
.Sh AUTHOR
Ozan Yigit <oz@sis.yorku.ca> and Richard A. O'Keefe (ok@goanna.cs.rmit.OZ.AU)

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +1,32 @@
/*
* Copyright (c) 1989 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.
*
* @(#)mdef.h 5.6 (Berkeley) 2/26/91
*/
/* Header : mdef.h
Author : Ozan Yigit
Updated: 4 May 1992
*/
#ifndef MACRTYPE
/*
* mdef.h
* Facility: m4 macro processor
* by: oz
*/
#ifndef unix
#define unix 0
#endif
/*
*
* m4 constants..
*
*/
#ifndef vms
#define vms 0
#endif
#include <stdio.h>
#include <signal.h>
#ifdef __STDC__
#include <string.h>
#else
#ifdef VOID
#define void int
#endif
extern int strlen();
extern int strcmp();
extern void memcpy();
#endif
/* m4 constants */
#define MACRTYPE 1
#define DEFITYPE 2
@ -81,18 +61,22 @@
#define SYSVTYPE 31
#define EXITTYPE 32
#define DEFNTYPE 33
#define LINETYPE 34
#define TRIMTYPE 35
#define TLITTYPE 36
#define DEFQTYPE 37 /* defquote */
#define QUTRTYPE 38 /* quoter thus defined */
#define STATIC 128
/*
* m4 special characters
*/
/* m4 special characters */
#define ARGFLAG '$'
#define LPAREN '('
#define RPAREN ')'
#define LQUOTE '`'
#define RQUOTE '\''
#define VQUOTE ('V'&(' '- 1))
#define COMMA ','
#define SCOMMT '#'
#define ECOMMT '\n'
@ -104,44 +88,45 @@
#define EOS (char) 0
#define MAXINP 10 /* maximum include files */
#define MAXOUT 10 /* maximum # of diversions */
#define MAXSTR 512 /* maximum size of string */
#ifdef SMALL
#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 HASHSIZE 199 /* maximum size of hashtab */
#else
#define MAXSTR 1024 /* maximum size of string */
#define BUFSIZE 8192 /* size of pushback buffer */
#define STACKMAX 2048 /* size of call stack */
#define STRSPMAX 8192 /* size of string space */
#define HASHSIZE 509 /* maximum size of hashtab */
#endif
#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
*/
/* m4 data structures */
typedef struct ndblock *ndptr;
struct ndblock { /* hastable structure */
struct ndblock /* hashtable 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 */
typedef union /* stack structure */
{ int sfra; /* frame entry */
char *sstr; /* string entry */
} stae;
} stae;
/*
* macros for readibility and/or speed
@ -151,7 +136,7 @@ typedef union { /* stack structure */
* pushf() - push a call frame entry onto stack
* pushs() - push a string pointer onto stack
*/
#define gpbc() (bp > buf) ? *--bp : getc(infile[ilevel])
#define gpbc() bp == bb ? getc(infile[ilevel]) : *--bp
#define min(x,y) ((x > y) ? y : x)
#define pushf(x) if (sp < STACKMAX) mstack[++sp].sfra = (x)
#define pushs(x) if (sp < STACKMAX) mstack[++sp].sstr = (x)
@ -184,3 +169,5 @@ typedef union { /* stack structure */
#define PREVEP (mstack[fp+3].sstr)
#define PREVSP (fp-3)
#define PREVFP (mstack[fp-2].sfra)
#endif

View File

@ -1,211 +1,357 @@
/*
* Copyright (c) 1989 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.
*/
/* File : misc.c
Author : Ozan Yigit
Updated: 26-Mar-1993
Purpose: Miscellaneous support code for PD M4.
*/
#ifndef lint
static char sccsid[] = "@(#)misc.c 5.6 (Berkeley) 2/26/91";
#endif /* not lint */
/*
* misc.c
* Facility: m4 macro processor
* by: oz
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mdef.h"
#include "extr.h"
#include "pathnames.h"
/*
* indx - find the index of second str in the
* first str.
*/
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
*
*/
putback (c)
char c;
{
if (bp < endpbb)
*bp++ = c;
else
error("m4: too many characters pushed back");
}
/*
* pbstr - push string back onto input
* putback is replicated to improve
* performance.
*
*/
pbstr(s)
register char *s;
{
register char *es;
#include "extr.h"
#include "ourlims.h"
#ifdef DUFFCP
/* This version of the ANSI standard function memcpy()
uses Duff's Device (tm Tom Duff) to unroll the copying loop:
while (count-- > 0) *to++ = *from++;
*/
void memcpy(to, from, count)
register char *from, *to;
register int count;
{
if (count > 0) {
register int loops = (count+8-1) >> 3; /* div 8 round up */
switch (count & (8-1)) { /* mod 8 */
case 0: do { *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
} while (--loops > 0);
}
}
}
#endif
/* strsave(s)
return a new malloc()ed copy of s -- same as V.3's strdup().
*/
char *strsave(s)
char *s;
{
register int n = strlen(s)+1;
char *p = malloc(n);
if (p) memcpy(p, s, n);
return p;
}
/* indx(s1, s2)
if s1 can be decomposed as alpha || s2 || omega, return the length
of the shortest such alpha, otherwise return -1.
*/
int indx(s1, s2)
char *s1;
char *s2;
{
register char *t;
register char *m;
register char *p;
for (p = s1; *p; p++) {
for (t = p, m = s2; *m && *m == *t; m++, t++);
if (!*m) return p-s1;
}
return -1;
}
char pbmsg[] = "m4: too many characters pushed back";
/* Xputback(c)
push character c back onto the input stream.
This is now macro putback() in misc.h
*/
void Xputback(c)
char c;
{
if (bp < endpbb) *bp++ = c; else error(pbmsg);
}
/* pbstr(s)
push string s back onto the input stream.
putback() has been unfolded here to improve performance.
Example:
s = <ABC>
bp = <more stuff>
After the call:
bp = <more stuffCBA>
It would be more efficient if we ran the pushback buffer in the
opposite direction
*/
void pbstr(s)
register char *s;
{
register char *es;
register char *zp;
es = s;
zp = bp;
for (es = s; *es; ) es++; /* now es points to terminating NUL */
bp += es-s; /* advance bp as far as it should go */
if (bp >= endpbb) error("m4: too many characters to push back");
while (es > s) *zp++ = *--es;
}
while (*es)
es++;
es--;
while (es >= s)
if (zp < endpbb)
*zp++ = *es--;
if ((bp = zp) == endpbb)
error("m4: too many characters pushed back");
}
/*
* pbnum - convert number to string, push back on input.
*
*/
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
*
*/
chrsave (c)
char c;
{
/*** if (sp < 0)
putc(c, active);
else ***/ if (ep < endest)
*ep++ = c;
else
error("m4: string space overflow");
}
/*
* getdiv - read in a diversion file, and
* trash it.
*/
getdiv(ind) {
register int c;
register FILE *dfil;
if (active == outfile[ind])
error("m4: undivert: diversion still active.");
(void) fclose(outfile[ind]);
outfile[ind] = NULL;
m4temp[UNIQUE] = ind + '0';
if ((dfil = fopen(m4temp, "r")) == NULL)
error("m4: cannot undivert.");
else
while((c = getc(dfil)) != EOF)
putc(c, active);
(void) fclose(dfil);
/* pbqtd(s)
pushes string s back "quoted", doing whatever has to be done to it to
make sure that the result will evaluate to the original value. As it
happens, we have only to add lquote and rquote.
*/
void pbqtd(s)
register char *s;
{
register char *es;
register char *zp;
if (unlink(m4temp) == -1)
error("m4: cannot unlink.");
}
/*
* Very fatal error. Close all files
* and die hard.
*/
error(s)
char *s;
{
killdiv();
fprintf(stderr,"%s\n",s);
exit(1);
}
/*
* Interrupt handling
*/
zp = bp;
for (es = s; *es; ) es++; /* now es points to terminating NUL */
bp += 2+es-s; /* advance bp as far as it should go */
if (bp >= endpbb) error("m4: too many characters to push back");
*zp++ = rquote;
while (es > s) *zp++ = *--es;
*zp++ = lquote;
}
/* pbnum(n)
convert a number to a (decimal) string and push it back.
The original definition did not work for MININT; this does.
*/
void pbnum(n)
int n;
{
register int num;
num = n > 0 ? -n : n; /* MININT <= num <= 0 */
do {
putback('0' - (num % 10));
} while ((num /= 10) < 0);
if (n < 0) putback('-');
}
/* pbrad(n, r, m)
converts a number n to base r ([-36..-2] U [2..36]), with at least
m digits. If r == 10 and m == 1, this is exactly the same as pbnum.
However, this uses the function int2str() from R.A.O'Keefe's public
domain string library, and puts the results of that back.
The Unix System V Release 3 version of m4 accepts radix 1;
THIS VERSION OF M4 DOES NOT ACCEPT RADIX 1 OR -1,
nor do we accept radix < -36 or radix > 36. At the moment such bad
radices quietly produce nothing. The V.3 treatment of radix 1 is
push back abs(n) "1"s, then
if n < 0, push back one "-".
Until I come across something which uses it, I can't bring myself to
implement this.
I have, however, found a use for radix 0. Unsurprisingly, it is
related to radix 0 in Edinburgh Prolog.
eval('c1c2...cn', 0, m)
pushes back max(m-n,0) blanks and the characters c1...cn. This can
adjust to any byte size as long as UCHAR_MAX = (1 << CHAR_BIT) - 1.
In particular, eval(c, 0) where 0 < c <= UCHAR_MAX, pushes back the
character with code c. Note that this has to agree with eval(); so
both of them have to use the same byte ordering.
*/
void pbrad(n, r, m)
long int n;
int r, m;
{
char buffer[34];
char *p;
int L;
if (r == 0) {
unsigned long int x = (unsigned long)n;
int n;
for (n = 0; x; x >>= CHAR_BIT, n++) buffer[n] = x & UCHAR_MAX;
for (L = n; --L >= 0; ) putback(buffer[L]);
for (L = m-n; --L >= 0; ) putback(' ');
return;
}
L = m - (int2str(p = buffer, -r, n)-buffer);
if (buffer[0] == '-') L++, p++;
if (L > 0) {
pbstr(p);
while (--L >= 0) putback('0');
if (p != buffer) putback('-');
} else {
pbstr(buffer);
}
}
char csmsg[] = "m4: string space overflow";
/* chrsave(c)
put the character c in the string space.
*/
void Xchrsave(c)
char c;
{
#if 0
if (sp < 0) putc(c, active); else
#endif
if (ep < endest) *ep++ = c; else
error(csmsg);
}
/* getdiv(ind)
read in a diversion file and then delete it.
*/
void getdiv(ind)
int ind;
{
register int c;
register FILE *dfil;
register FILE *afil;
afil = active;
if (outfile[ind] == afil)
error("m4: undivert: diversion still active.");
(void) fclose(outfile[ind]);
outfile[ind] = NULL;
m4temp[UNIQUE] = '0' + ind;
if ((dfil = fopen(m4temp, "r")) == NULL)
error("m4: cannot undivert.");
while ((c = getc(dfil)) != EOF) putc(c, afil);
(void) fclose(dfil);
#if vms
if (remove(m4temp)) error("m4: cannot unlink.");
#else
if (unlink(m4temp) == -1) error("m4: cannot unlink.");
#endif
}
/* killdiv()
delete all the diversion files which have been created.
*/
void killdiv()
{
register int n;
for (n = 0; n < MAXOUT; n++) {
if (outfile[n] != NULL) {
(void) fclose(outfile[n]);
m4temp[UNIQUE] = '0' + n;
#if unix
(void) unlink(m4temp);
#else
(void) remove(m4temp);
#endif
}
}
}
/* error(s)
close all files, report a fatal error, and quit, letting the caller know.
*/
void error(s)
char *s;
{
killdiv();
fprintf(stderr, "%s\n", s);
exit(1);
}
/* Interrupt handling
*/
static char *msg = "\ninterrupted.";
void
onintr() {
error(msg);
}
/*
* killdiv - get rid of the diversion files
*
*/
killdiv() {
register int n;
for (n = 0; n < MAXOUT; n++)
if (outfile[n] != NULL) {
(void) fclose (outfile[n]);
m4temp[UNIQUE] = n + '0';
(void) unlink (m4temp);
}
}
usage() {
fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
exit(1);
}
#ifdef __STDC__
void onintr(int signo)
#else
onintr()
#endif
{
error(msg);
}
void usage()
{
fprintf(stderr, "Usage: m4 [-e] [-[BHST]int] [-Dname[=val]] [-Uname]\n");
exit(1);
}
#ifdef GETOPT
/* Henry Spencer's getopt() - get option letter from argv */
char *optarg; /* Global argument pointer. */
int optind = 0; /* Global argv index. */
static char *scan = NULL; /* Private scan pointer. */
#ifndef __STDC__
extern char *index();
#define strchr index
#endif
int getopt(argc, argv, optstring)
int argc;
char **argv;
char *optstring;
{
register char c;
register char *place;
optarg = NULL;
if (scan == NULL || *scan == '\0') {
if (optind == 0) optind++;
if (optind >= argc
|| argv[optind][0] != '-'
|| argv[optind][1] == '\0')
return EOF;
if (strcmp(argv[optind], "--") == 0) {
optind++;
return EOF;
}
scan = argv[optind]+1;
optind++;
}
c = *scan++;
place = strchr(optstring, c);
if (place == NULL || c == ':') {
fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
return '?';
}
place++;
if (*place == ':') {
if (*scan != '\0') {
optarg = scan;
scan = NULL;
} else {
optarg = argv[optind];
optind++;
}
}
return c;
}
#endif

16
usr.bin/m4/ourlims.h Normal file
View File

@ -0,0 +1,16 @@
/* File : ourlims.h
Author : Richard A. O'Keefe
Defines: UCHAR_MAX, CHAR_BIT, LONG_BIT
*/
/* If <limits.h> is available, use that.
Otherwise, use 8-bit byte as the default.
If the number of characters is a power of 2, you might be able
to use (unsigned char)(~0), but why get fancy?
*/
#ifdef __STDC__
#include <limits.h>
#else
#define UCHAR_MAX 255
#define CHAR_BIT 8
#endif
#define LONG_BIT 32

View File

@ -1 +1 @@
revision 1.1.1.1 intentionally removed
revision 1.2 intentionally removed