1
0
Files
2022-09-29 17:59:04 +03:00

568 lines
8.1 KiB
C

/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)m4:m4macs.c 1.7"
#include <stdio.h>
#include <sys/param.h>
#include <signal.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "m4.h"
#define arg(n) (c<(n)? nullstr: ap[n])
dochcom(ap,c)
char **ap;
{
register char *l = arg(1);
register char *r = arg(2);
if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
error2("comment marker longer than %d chars",MAXSYM);
strcpy(lcom,l);
strcpy(rcom,*r?r:"\n");
}
docq(ap,c)
register char **ap;
{
register char *l = arg(1);
register char *r = arg(2);
if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
error2("quote marker longer than %d chars", MAXSYM);
if (c<=1 && !*l) {
l = "`";
r = "'";
} else if (c==1) {
r = l;
}
strcpy(lquote,l);
strcpy(rquote,r);
}
dodecr(ap,c)
char **ap;
{
pbnum(ctol(arg(1))-1);
}
dodef(ap,c)
char **ap;
{
def(ap,c,NOPUSH);
}
def(ap,c,mode)
register char **ap;
{
register char *s;
if (c<1)
return;
s = ap[1];
if (isalpha(*s) || ( *s == '_' ) )
while ( isalnum(*++s) || ( *s == '_' ) )
;
if (*s || s==ap[1])
error("bad macro name", NULL);
if (strcmp(ap[1],ap[2])==0)
error("macro defined as itself", ap[1]);
install(ap[1],arg(2),mode);
}
dodefn(ap,c)
register char **ap;
register c;
{
register char *d;
while (c > 0)
if ((d = lookup(ap[c--])->def) != NULL) {
putbak(*rquote);
while (*d)
putbak(*d++);
putbak(*lquote);
}
}
dodiv(ap,c)
register char **ap;
{
register int f;
f = atoi(arg(1));
if (f>=10 || f<0) {
cf = NULL;
ofx = f;
return;
}
tempfile[7] = 'a'+f;
if (ofile[f] || (ofile[f]=xfopen(tempfile,"w"))) {
ofx = f;
cf = ofile[f];
}
}
/* ARGSUSED */
dodivnum(ap,c)
{
pbnum((long) ofx);
}
/* ARGSUSED */
dodnl(ap,c)
char *ap;
{
register t;
while ((t=getchr())!='\n' && t!=EOF)
;
}
dodump(ap,c)
char **ap;
{
register struct nlist *np;
register i;
if (c > 0)
while (c--) {
if ((np = lookup(*++ap))->name != NULL)
dump(np->name,np->def);
}
else
for (i=0; i<hshsize; i++)
for (np=hshtab[i]; np!=NULL; np=np->next)
dump(np->name,np->def);
}
dump(name,defnn)
register char *name,
*defnn;
{
register char *s = defnn;
fprintf(stderr,"%s:\t",name);
while (*s++)
;
--s;
while (s>defnn)
if (*--s&~LOW7)
fprintf(stderr,"<%s>",barray[*s&LOW7].bname);
else
fputc(*s,stderr);
fputc('\n',stderr);
}
doerrp(ap,c)
char **ap;
{
if (c > 0)
fprintf(stderr,"%s",ap[1]);
}
long evalval; /* return value from yacc stuff */
char *pe; /* used by grammar */
doeval(ap,c)
char **ap;
{
register base = atoi(arg(2));
register pad = atoi(arg(3));
evalval = 0;
if (c > 0) {
pe = ap[1];
if (yyparse()!=0)
error("invalid expression", NULL);
}
pbnbr(evalval, base>0?base:10, pad>0?pad:1);
}
doexit(ap,c)
char **ap;
{
delexit(atoi(arg(1)));
}
doif(ap,c)
register char **ap;
{
if (c < 3)
return;
while (c >= 3) {
if (strcmp(ap[1],ap[2])==0) {
pbstr(ap[3]);
return;
}
c -= 3;
ap += 3;
}
if (c > 0)
pbstr(ap[1]);
}
doifdef(ap,c)
char **ap;
{
struct nlist *arg1;
if (c < 2)
return;
while (c >= 2) {
arg1 = lookup(ap[1]) ;
if (arg1->name != NULL) {
if (strcmp(arg1->def,"0") == 0) {
pbstr(ap[3]);
return;
} else {
pbstr(ap[2]);
return;
}
}
c -= 2;
ap += 2;
}
if (c > 0)
pbstr(ap[1]);
}
doincl(ap,c)
char **ap;
{
incl(ap,c,1);
}
FILE *
srchincl(char *fn)
{
int i;
FILE *f;
char path[PATH_MAX];
if ((f = fopen(fn, "r")) != NULL)
return f;
for (i = 0; i < nincls; i++) {
strcpy(path, incls[i]);
strcat(path, "/");
strcat(path, fn);
if ((f = fopen(path, "r")) != NULL)
return f;
}
return NULL;
}
incl(ap,c,noisy)
register char **ap;
{
if (c>0 && strlen(ap[1])>0) {
if (ifx >= 9)
error("input file nesting too deep (9)", NULL);
if ((ifile[++ifx]=srchincl(ap[1]))==NULL){
--ifx;
if (noisy)
error(badfile, ap[1]);
} else {
ipstk[ifx] = ipflr = ip;
setfname(ap[1]);
}
}
}
doincr(ap,c)
char **ap;
{
pbnum(ctol(arg(1))+1);
}
doindex(ap,c)
char **ap;
{
register char *subj = arg(1);
register char *obj = arg(2);
register i;
for (i=0; *subj; ++i)
if (leftmatch(subj++,obj)) {
pbnum( (long) i );
return;
}
pbnum( (long) -1 );
}
leftmatch(str,substr)
register char *str;
register char *substr;
{
while (*substr)
if (*str++ != *substr++)
return (0);
return (1);
}
dolen(ap,c)
char **ap;
{
pbnum((long) strlen(arg(1)));
}
domake(ap,c)
char **ap;
{
if (c > 0)
pbstr(mktemp(ap[1]));
}
dopopdef(ap,c)
char **ap;
{
register i;
for (i=1; i<=c; ++i)
undef(ap[i]);
}
dopushdef(ap,c)
char **ap;
{
def(ap,c,PUSH);
}
doshift(ap,c)
register char **ap;
register c;
{
if (c <= 1)
return;
for (;;) {
pbstr(rquote);
pbstr(ap[c--]);
pbstr(lquote);
if (c <= 1)
break;
pbstr(",");
}
}
dosincl(ap,c)
char **ap;
{
incl(ap,c,0);
}
dosubstr(ap,c)
register char **ap;
{
char *str;
int inlen, outlen;
register offset, ix;
inlen = strlen(str=arg(1));
offset = atoi(arg(2));
if (offset<0 || offset>=inlen)
return;
outlen = c>=3? atoi(ap[3]): inlen;
ix = min(offset+outlen,inlen);
while (ix > offset)
putbak(str[--ix]);
}
dosyscmd(ap,c)
char **ap;
{
sysrval = 0;
if (c > 0) {
fflush(stdout);
sysrval = system(ap[1]);
}
}
/* ARGSUSED */
dosysval(ap,c)
char **ap;
{
pbnum((long) (sysrval < 0 ? sysrval :
(sysrval >> 8) & ((1 << 8) - 1)) |
((sysrval & ((1 << 8) - 1)) << 8));
}
dotransl(ap,c)
char **ap;
{
char *sink, *fr, *sto;
register char *source, *to;
if (c<1)
return;
sink = ap[1];
fr = arg(2);
sto = arg(3);
for (source = ap[1]; *source; source++) {
register char *i;
to = sto;
for (i = fr; *i; ++i) {
if (*source==*i)
break;
if (*to)
++to;
}
if (*i) {
if (*to)
*sink++ = *to;
} else
*sink++ = *source;
}
*sink = EOS;
pbstr(ap[1]);
}
dotroff(ap,c)
register char **ap;
{
register struct nlist *np;
trace = 0;
while (c > 0)
if ((np=lookup(ap[c--]))->name)
np->tflag = 0;
}
dotron(ap,c)
register char **ap;
{
register struct nlist *np;
trace = !*arg(1);
while (c > 0)
if ((np=lookup(ap[c--]))->name)
np->tflag = 1;
}
doundef(ap,c)
char **ap;
{
register i;
for (i=1; i<=c; ++i)
while (undef(ap[i]))
;
}
undef(nam)
char *nam;
{
register struct nlist *np, *tnp;
if ((np=lookup(nam))->name==NULL)
return 0;
tnp = hshtab[hshval]; /* lookup sets hshval */
if (tnp==np) /* it's in first place */
hshtab[hshval] = tnp->next;
else {
while (tnp->next != np)
tnp = tnp->next;
tnp->next = np->next;
}
cfree(np->name);
cfree(np->def);
cfree((char *) np);
return 1;
}
doundiv(ap,c)
register char **ap;
{
register int i;
if (c<=0)
for (i=1; i<10; i++)
undiv(i,OK);
else
while (--c >= 0)
undiv(atoi(*++ap),OK);
}
dowrap(ap,c)
char **ap;
{
register char *a = arg(1);
if (!Wrapstr) {
Wrapstr = (struct wrap_info *)malloc (sizeof(struct wrap_info));
Wrapstr->str = xcalloc(strlen(a)+1,sizeof(char));
strcpy(Wrapstr->str, a);
Wrapstr->previous = NULL;
} else {
Curr_str = (struct wrap_info *)malloc (sizeof(struct wrap_info));
Curr_str->previous = Wrapstr;
Curr_str->str = xcalloc(strlen(a)+1,sizeof(char));
strcpy(Curr_str->str, a);
Wrapstr = Curr_str;
}
}
struct bs barray[] = {
dochcom, "changecom",
docq, "changequote",
dodecr, "decr",
dodef, "define",
dodefn, "defn",
dodiv, "divert",
dodivnum, "divnum",
dodnl, "dnl",
dodump, "dumpdef",
doerrp, "errprint",
doeval, "eval",
doexit, "m4exit",
doif, "ifelse",
doifdef, "ifdef",
doincl, "include",
doincr, "incr",
doindex, "index",
dolen, "len",
domake, "maketemp",
dopopdef, "popdef",
dopushdef, "pushdef",
doshift, "shift",
dosincl, "sinclude",
dosubstr, "substr",
dosyscmd, "syscmd",
dosysval, "sysval",
dotransl, "translit",
dotroff, "traceoff",
dotron, "traceon",
doundef, "undefine",
doundiv, "undivert",
dowrap, "m4wrap",
0, 0
};