m4.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
* Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include "m4.h"
static int mb_cur_max;
static void getflags(int *, char ***, int *);
static void initalloc(void);
static void error3(void);
static void chkspace(char **, int *, char ***);
static void catchsig(int);
static void showwrap(void);
static int myfeof(int);
int argc;
char **argv;
{
wchar_t t;
int i, opt_end = 0;
for (i = 0; sigs[i]; ++i) {
}
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
wide = 1;
initalloc();
setfname("-");
if (argc > 1) {
--argc;
++argv;
}
}
for (;;) {
if (t == WEOF) {
if (ifx > 0) {
continue;
}
if (argc <= 1)
/*
* If dowrap() has been called, the m4wrap
* macro has been processed, and a linked
* list of m4wrap strings has been created.
* The list starts at wrapstart.
*/
if (wrapstart) {
/*
* Now that EOF has been processed,
* display the m4wrap strings.
*/
showwrap();
continue;
} else
break;
--argc;
++argv;
else
continue;
}
if (is_alpha(t) || t == '_') {
tp++;
if (--tlim <= 0)
"more than %d chars in word"),
toksize);
}
--Ap;
"more than %d items on argument stack"),
stksize);
}
t = getchr();
putbak(t);
if (t != '(')
pbstr(L"()");
else /* try to fix arg count */
} else {
}
register qlev = 1;
for (;;) {
if (--qlev > 0)
else
break;
++qlev;
} else {
if (t == WEOF)
"EOF in quote"));
putchr(t);
}
}
prev_char != '$')) {
/*
* Don't expand commented macro (between lcom and
* rcom).
* What we know so far is that we have found the
* left comment char (lcom).
* Make sure we haven't found '#' (lcom) immediately
* preceded by '$' because we want to expand "$#".
*/
for (;;) {
break;
} else {
if (t == WEOF)
"EOF in comment"));
putchr(t);
}
}
putchr(t);
} else if (t == '(') {
stkchr(t);
else {
/* skip white before arg */
;
putbak(t);
}
} else if (t == ')') {
} else
stkchr(t);
--Ap;
"more than %d items on argument stack"),
stksize);
}
;
putbak(t);
} else {
stkchr(t);
}
}
"EOF in argument list"));
return (0);
}
static wchar_t *
{
while (*s) {
if (*tp++ != *s++) {
return (0);
}
}
return (token);
}
static void
{
char *arg;
char *t;
wchar_t *s[3];
while (*xargc > 1) {
/*
* This argument is not an option if it equals "-" or if
* "--" has already been parsed.
*/
break;
*option_end = 1;
} else {
switch (arg[1]) {
case 'B':
break;
case 'D':
initalloc();
for (t = &arg[2]; *t; t++) {
if (*t == '=') {
*t++ = EOS;
break;
}
}
dodef(&s[0], 2);
free(s[1]);
free(s[2]);
break;
case 'H':
break;
case 'S':
break;
case 'T':
break;
case 'U':
initalloc();
doundef(&s[0], 1);
free(s[1]);
break;
case 'e':
break;
case 's':
/* turn on line sync */
sflag = 1;
break;
default:
gettext("%s: bad option: %s\n"),
}
} /* end else not "--" */
(*xargv)++;
--(*xargc);
} /* end while options to process */
}
/*
* Function: chkspace
*
* If there is a space between the option and its argument,
* adjust argptr so that &arg[2] will point to beginning of the option argument.
* This will ensure that processing in getflags() will work, because &arg[2]
* will point to the beginning of the option argument whether or not we have
* a space between the option and its argument. If there is a space between
* the option and its argument, also adjust xargv and xargc because we are
* processing the next argument.
*/
static void
{
/* there is a space between the option and its argument */
(*xargv)++; /* look at the next argument */
--(*xargc);
/*
* Adjust argptr if the option is followed by an
* option argument.
*/
if (*xargc > 1) {
/* point &arg[2] to beginning of option argument */
*argptr -= 2;
}
}
}
static void
{
static done = 0;
register t;
if (done++)
return;
p[0] = builtin(t);
}
}
void
{
int l;
else
;
while (*val)
}
struct nlist *
{
return (np);
}
return (&nodef);
}
static void
{
int i;
if (c > 0) {
for (i = 2; i <= c; ++i)
}
}
if (is_builtin(*dp)) {
register n;
if ((n = *dp-'0') <= c)
++dp;
} else if (*dp == '#') {
pbnum((long)c);
++dp;
register i = c;
if (i > 0)
for (;;) {
if (*dp == '@')
pbstr(a[i--]);
if (*dp == '@')
if (i <= 0)
break;
pbstr(L",");
}
++dp;
} else
} else
}
}
void
setfname(char *s)
{
nflag = 1;
}
static void
{
static int cline = 0;
static int cfile = 0;
return;
nflag = 0;
}
static void
{
register i;
return;
for (i = 1; i <= ifx; ++i)
}
/* ARGSUSED */
static void
catchsig(int i)
{
}
void
{
register i;
/*
* if (ofx != 0) {
* ofx = 0;
* code = NOT_OK;
* }
*/
ofx = 0; /* ensure that everything comes out */
for (i = 1; i < 10; i++)
/* flush standard I/O buffers, ie: call exit() not _exit() */
if (flushio)
}
static void
{
if (Cp) {
while (*tp)
} else if (cf) {
while (*tp) {
}
}
}
void
{
wchar_t *p;
putbak(*p);
}
void
{
wint_t c;
return;
if (wide) {
} else {
}
}
}
void
{
}
void
{
register neg = 0;
if (base <= 0)
return;
if (nbr < 0)
neg = 1;
else
while (nbr < 0) {
register int i;
if (base > 1) {
#if (-3 % 2) != -1
while (i > 0) {
i -= base;
++nbr;
}
#endif
i = -i;
} else {
i = 1;
++nbr;
}
--len;
}
while (--len >= 0)
putbak('0');
if (neg)
putbak('-');
}
static wchar_t
itochr(int i)
{
if (i > 9)
else
return ((wchar_t)(i+'0'));
}
long
{
register sign;
long num;
++str;
num = 0;
if (*str == '-') {
sign = -1;
++str;
} else
sign = 1;
}
int
min(int a, int b)
{
if (a > b)
return (b);
return (a);
}
FILE *
{
return (fp);
}
/*
* m4open
*
* Continue processing files when unable to open the given file argument.
*/
FILE *
{
char *arg;
while (*argcnt > 0) {
return (stdin);
else {
"m4: cannot open %s: "), arg);
perror("");
if (*argcnt == 1) {
/* last arg therefore exit */
error3();
} else {
exitstat = 1;
(*argvec)++; /* try next arg */
(*argcnt)--;
}
} else
break;
}
}
return (fp);
}
void *
{
void *ptr;
return (ptr);
}
static void *
{
register void *ptr;
return (ptr);
}
void
{
char buf[500];
}
void
{
error3();
}
static void
error3()
{
if (Cp) {
/* fix limit */
++aptr;
for (;;) {
break;
}
}
}
}
static wchar_t *
{
if (is_builtin(*s)) {
return (buf);
}
return (s);
}
getchr()
{
static wchar_t C;
prev_char = C;
return (*--ip);
if (wide) {
} else {
}
if (C == '\n')
return (C);
}
/*
* showwrap
*
* Loop through the list of m4wrap strings. Call pbstr() so that the
* string will be displayed, then delete the list entry and free the memory
* allocated for it.
*/
static void
showwrap()
{
while (wrapstart) {
}
}
static void
{
if (is_builtin(c))
return;
if (wide)
else
if (ret == '\n')
lnsync(f);
}
static void
{
if (Cp)
stkchr(c);
else if (cf) {
if (sflag)
else {
if (is_builtin(c))
return;
if (wide)
else
}
}
}
}
wchar_t *
{
return (ret);
}
int
{
}
char *
{
static char *retbuf;
char *p, *ret;
if (alloc) {
} else {
bsiz += 256;
retbuf = p;
}
}
if (wide) {
while (*from) {
int len;
if (*from & INVALID_CHAR) {
*p = (char)(*from & ~INVALID_CHAR);
len = 1;
} else {
*p = (char)*from;
len = 1;
}
}
p += len;
from++;
}
} else {
while (*from)
*p++ = (char)*from++;
}
*p = '\0';
return (ret);
}
wchar_t *
{
if (alloc) {
} else {
}
bsiz += 256;
retbuf = p;
}
}
if (wide) {
while (*from) {
int len;
len = 1;
}
*p++ = wc;
}
} else {
while (*from)
*p++ = (unsigned char) *from++;
}
*p = 0;
return (ret);
}
static wint_t
{
unsigned char *buf;
else
len = 0;
for (i = 1; i <= mb_cur_max; i++) {
if (nb < i) {
if (c == EOF) {
if (nb == 0)
return (WEOF);
else
break;
}
}
break;
}
if (len <= 0) {
len = 1;
}
if (nb > 0) {
for (i = 0; i < nb; i++)
}
return (wc);
}
static wint_t
{
if (wc & INVALID_CHAR) {
wc &= ~INVALID_CHAR;
}
}
static int
{
}