10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6951Sab196087 * Common Development and Distribution License (the "License").
6*6951Sab196087 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21291Smike_s
22291Smike_s /*
23*6951Sab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24291Smike_s * Use is subject to license terms.
25291Smike_s */
26291Smike_s
270Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include <limits.h>
330Sstevel@tonic-gate #include <unistd.h>
340Sstevel@tonic-gate #include <sys/types.h>
350Sstevel@tonic-gate #include "m4.h"
360Sstevel@tonic-gate
370Sstevel@tonic-gate #define arg(n) (c < (n) ? nullstr: ap[n])
380Sstevel@tonic-gate static void mkpid(char *);
390Sstevel@tonic-gate static void def(wchar_t **, int, int);
400Sstevel@tonic-gate static void dump(wchar_t *, wchar_t *);
410Sstevel@tonic-gate static void incl(wchar_t **, int, int);
420Sstevel@tonic-gate static int leftmatch(wchar_t *, wchar_t *);
430Sstevel@tonic-gate
440Sstevel@tonic-gate static void
dochcom(wchar_t ** ap,int c)450Sstevel@tonic-gate dochcom(wchar_t **ap, int c)
460Sstevel@tonic-gate {
470Sstevel@tonic-gate wchar_t *l = arg(1);
480Sstevel@tonic-gate wchar_t *r = arg(2);
490Sstevel@tonic-gate
500Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM)
510Sstevel@tonic-gate error2(gettext(
520Sstevel@tonic-gate "comment marker longer than %d chars"), MAXSYM);
530Sstevel@tonic-gate (void) wcscpy(lcom, l);
540Sstevel@tonic-gate (void) wcscpy(rcom, *r ? r : L"\n");
550Sstevel@tonic-gate }
560Sstevel@tonic-gate
570Sstevel@tonic-gate static void
docq(wchar_t ** ap,int c)580Sstevel@tonic-gate docq(wchar_t **ap, int c)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate wchar_t *l = arg(1);
610Sstevel@tonic-gate wchar_t *r = arg(2);
620Sstevel@tonic-gate
630Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM)
640Sstevel@tonic-gate error2(gettext(
650Sstevel@tonic-gate "quote marker longer than %d chars"), MAXSYM);
660Sstevel@tonic-gate
670Sstevel@tonic-gate if (c <= 1 && !*l) {
680Sstevel@tonic-gate l = L"`";
690Sstevel@tonic-gate r = L"'";
700Sstevel@tonic-gate } else if (c == 1) {
710Sstevel@tonic-gate r = l;
720Sstevel@tonic-gate }
730Sstevel@tonic-gate
740Sstevel@tonic-gate (void) wcscpy(lquote, l);
750Sstevel@tonic-gate (void) wcscpy(rquote, r);
760Sstevel@tonic-gate }
770Sstevel@tonic-gate
780Sstevel@tonic-gate static void
dodecr(wchar_t ** ap,int c)790Sstevel@tonic-gate dodecr(wchar_t **ap, int c)
800Sstevel@tonic-gate {
810Sstevel@tonic-gate pbnum(ctol(arg(1))-1);
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
840Sstevel@tonic-gate void
dodef(wchar_t ** ap,int c)850Sstevel@tonic-gate dodef(wchar_t **ap, int c)
860Sstevel@tonic-gate {
870Sstevel@tonic-gate def(ap, c, NOPUSH);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate static void
def(wchar_t ** ap,int c,int mode)910Sstevel@tonic-gate def(wchar_t **ap, int c, int mode)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate wchar_t *s;
940Sstevel@tonic-gate
950Sstevel@tonic-gate if (c < 1)
960Sstevel@tonic-gate return;
970Sstevel@tonic-gate
980Sstevel@tonic-gate s = ap[1];
990Sstevel@tonic-gate if (is_alpha(*s) || *s == '_') {
1000Sstevel@tonic-gate s++;
1010Sstevel@tonic-gate while (is_alnum(*s) || *s == '_')
1020Sstevel@tonic-gate s++;
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate if (*s || s == ap[1])
1050Sstevel@tonic-gate error(gettext("bad macro name"));
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate if ((ap[2] != NULL) && (wcscmp(ap[1], ap[2]) == 0))
1080Sstevel@tonic-gate error(gettext("macro defined as itself"));
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate install(ap[1], arg(2), mode);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate static void
dodefn(wchar_t ** ap,int c)1140Sstevel@tonic-gate dodefn(wchar_t **ap, int c)
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate wchar_t *d;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate while (c > 0)
1190Sstevel@tonic-gate if ((d = lookup(ap[c--])->def) != NULL) {
1200Sstevel@tonic-gate putbak(*rquote);
1210Sstevel@tonic-gate while (*d)
1220Sstevel@tonic-gate putbak(*d++);
1230Sstevel@tonic-gate putbak(*lquote);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate static void
dodiv(wchar_t ** ap,int c)1280Sstevel@tonic-gate dodiv(wchar_t **ap, int c)
1290Sstevel@tonic-gate {
130291Smike_s int f;
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate f = wstoi(arg(1));
1330Sstevel@tonic-gate if (f >= 10 || f < 0) {
1340Sstevel@tonic-gate cf = NULL;
1350Sstevel@tonic-gate ofx = f;
1360Sstevel@tonic-gate return;
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate tempfile[7] = 'a'+f;
1390Sstevel@tonic-gate if (ofile[f] || (ofile[f] = xfopen(tempfile, "w"))) {
1400Sstevel@tonic-gate ofx = f;
1410Sstevel@tonic-gate cf = ofile[f];
1420Sstevel@tonic-gate }
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate /* ARGSUSED */
1460Sstevel@tonic-gate static void
dodivnum(wchar_t ** ap,int c)1470Sstevel@tonic-gate dodivnum(wchar_t **ap, int c)
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate pbnum((long)ofx);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate /* ARGSUSED */
1530Sstevel@tonic-gate static void
dodnl(wchar_t ** ap,int c)1540Sstevel@tonic-gate dodnl(wchar_t **ap, int c)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate wchar_t t;
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate while ((t = getchr()) != '\n' && t != WEOF)
1590Sstevel@tonic-gate ;
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate static void
dodump(wchar_t ** ap,int c)1630Sstevel@tonic-gate dodump(wchar_t **ap, int c)
1640Sstevel@tonic-gate {
165291Smike_s struct nlist *np;
166291Smike_s int i;
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate if (c > 0)
1690Sstevel@tonic-gate while (c--) {
1700Sstevel@tonic-gate if ((np = lookup(*++ap))->name != NULL)
1710Sstevel@tonic-gate dump(np->name, np->def);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate else
1740Sstevel@tonic-gate for (i = 0; i < hshsize; i++)
1750Sstevel@tonic-gate for (np = hshtab[i]; np != NULL; np = np->next)
1760Sstevel@tonic-gate dump(np->name, np->def);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate
179*6951Sab196087 /*ARGSUSED*/
1800Sstevel@tonic-gate static void
dump(wchar_t * name,wchar_t * defnn)1810Sstevel@tonic-gate dump(wchar_t *name, wchar_t *defnn)
1820Sstevel@tonic-gate {
1830Sstevel@tonic-gate wchar_t *s = defnn;
1840Sstevel@tonic-gate
185*6951Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
1860Sstevel@tonic-gate (void) fprintf(stderr, "%ws:\t", name);
187*6951Sab196087 #endif
1880Sstevel@tonic-gate
189*6951Sab196087 while (*s++)
190*6951Sab196087 ;
1910Sstevel@tonic-gate --s;
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate while (s > defnn) {
1940Sstevel@tonic-gate --s;
195*6951Sab196087 if (is_builtin(*s)) {
196*6951Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
1970Sstevel@tonic-gate (void) fprintf(stderr, "<%ws>",
198*6951Sab196087 barray[builtin_idx(*s)].bname);
199*6951Sab196087 } else {
200*6951Sab196087 #endif
2010Sstevel@tonic-gate (void) fputwc(*s, stderr);
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate (void) fputc('\n', stderr);
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate
207*6951Sab196087 /*ARGSUSED*/
2080Sstevel@tonic-gate static void
doerrp(wchar_t ** ap,int c)2090Sstevel@tonic-gate doerrp(wchar_t **ap, int c)
2100Sstevel@tonic-gate {
211*6951Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
2120Sstevel@tonic-gate if (c > 0)
2130Sstevel@tonic-gate (void) fprintf(stderr, "%ws", ap[1]);
214*6951Sab196087 #endif
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate long evalval; /* return value from yacc stuff */
2180Sstevel@tonic-gate wchar_t *pe; /* used by grammar */
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate static void
doeval(wchar_t ** ap,int c)2210Sstevel@tonic-gate doeval(wchar_t **ap, int c)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate int base = wstoi(arg(2));
2240Sstevel@tonic-gate int pad = wstoi(arg(3));
2250Sstevel@tonic-gate extern int yyparse(void);
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate evalval = 0;
2280Sstevel@tonic-gate if (c > 0) {
2290Sstevel@tonic-gate pe = ap[1];
2300Sstevel@tonic-gate if (yyparse() != 0)
2310Sstevel@tonic-gate error(gettext(
2320Sstevel@tonic-gate "invalid expression"));
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate pbnbr(evalval, base > 0 ? base:10, pad > 0 ? pad : 1);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate * doexit
2390Sstevel@tonic-gate *
2400Sstevel@tonic-gate * Process m4exit macro.
2410Sstevel@tonic-gate */
2420Sstevel@tonic-gate static void
doexit(wchar_t ** ap,int c)2430Sstevel@tonic-gate doexit(wchar_t **ap, int c)
2440Sstevel@tonic-gate {
2450Sstevel@tonic-gate delexit(wstoi(arg(1)), 1);
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate static void
doif(wchar_t ** ap,int c)2490Sstevel@tonic-gate doif(wchar_t **ap, int c)
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate if (c < 3)
2520Sstevel@tonic-gate return;
2530Sstevel@tonic-gate while (c >= 3) {
2540Sstevel@tonic-gate if (wcscmp(ap[1], ap[2]) == 0) {
2550Sstevel@tonic-gate pbstr(ap[3]);
2560Sstevel@tonic-gate return;
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate c -= 3;
2590Sstevel@tonic-gate ap += 3;
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate if (c > 0)
2620Sstevel@tonic-gate pbstr(ap[1]);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate static void
doifdef(wchar_t ** ap,int c)2660Sstevel@tonic-gate doifdef(wchar_t **ap, int c)
2670Sstevel@tonic-gate {
2680Sstevel@tonic-gate if (c < 2)
2690Sstevel@tonic-gate return;
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate while (c >= 2) {
2720Sstevel@tonic-gate if (lookup(ap[1])->name != NULL) {
2730Sstevel@tonic-gate pbstr(ap[2]);
2740Sstevel@tonic-gate return;
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate c -= 2;
2770Sstevel@tonic-gate ap += 2;
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate if (c > 0)
2810Sstevel@tonic-gate pbstr(ap[1]);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate static void
doincl(wchar_t ** ap,int c)2850Sstevel@tonic-gate doincl(wchar_t **ap, int c)
2860Sstevel@tonic-gate {
2870Sstevel@tonic-gate incl(ap, c, 1);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate static void
incl(wchar_t ** ap,int c,int noisy)2910Sstevel@tonic-gate incl(wchar_t **ap, int c, int noisy)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate if (c > 0 && wcslen(ap[1]) > 0) {
2940Sstevel@tonic-gate if (ifx >= 9)
2950Sstevel@tonic-gate error(gettext(
2960Sstevel@tonic-gate "input file nesting too deep (9)"));
2970Sstevel@tonic-gate if ((ifile[++ifx] = fopen(wstr2str(ap[1], 0), "r")) == NULL) {
2980Sstevel@tonic-gate --ifx;
2990Sstevel@tonic-gate if (noisy)
3000Sstevel@tonic-gate error(gettext(
3010Sstevel@tonic-gate "can't open file"));
3020Sstevel@tonic-gate } else {
3030Sstevel@tonic-gate ipstk[ifx] = ipflr = ip;
3040Sstevel@tonic-gate setfname(wstr2str(ap[1], 0));
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate }
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate static void
doincr(wchar_t ** ap,int c)3100Sstevel@tonic-gate doincr(wchar_t **ap, int c)
3110Sstevel@tonic-gate {
3120Sstevel@tonic-gate pbnum(ctol(arg(1))+1);
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate static void
doindex(wchar_t ** ap,int c)3160Sstevel@tonic-gate doindex(wchar_t **ap, int c)
3170Sstevel@tonic-gate {
3180Sstevel@tonic-gate wchar_t *subj = arg(1);
3190Sstevel@tonic-gate wchar_t *obj = arg(2);
320291Smike_s int i;
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate for (i = 0; *subj; ++i)
3230Sstevel@tonic-gate if (leftmatch(subj++, obj)) {
3240Sstevel@tonic-gate pbnum((long)i);
3250Sstevel@tonic-gate return;
3260Sstevel@tonic-gate }
3270Sstevel@tonic-gate
3280Sstevel@tonic-gate pbnum((long)-1);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate static int
leftmatch(wchar_t * str,wchar_t * substr)3320Sstevel@tonic-gate leftmatch(wchar_t *str, wchar_t *substr)
3330Sstevel@tonic-gate {
3340Sstevel@tonic-gate while (*substr)
3350Sstevel@tonic-gate if (*str++ != *substr++)
3360Sstevel@tonic-gate return (0);
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate return (1);
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate static void
dolen(wchar_t ** ap,int c)3420Sstevel@tonic-gate dolen(wchar_t **ap, int c)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate pbnum((long)wcslen(arg(1)));
3450Sstevel@tonic-gate }
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate static void
domake(wchar_t ** ap,int c)3480Sstevel@tonic-gate domake(wchar_t **ap, int c)
3490Sstevel@tonic-gate {
3500Sstevel@tonic-gate char *path;
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate if (c > 0) {
3530Sstevel@tonic-gate path = wstr2str(ap[1], 1);
3540Sstevel@tonic-gate mkpid(path);
3550Sstevel@tonic-gate pbstr(str2wstr(path, 0));
3560Sstevel@tonic-gate free(path);
3570Sstevel@tonic-gate }
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate static void
dopopdef(wchar_t ** ap,int c)3610Sstevel@tonic-gate dopopdef(wchar_t **ap, int c)
3620Sstevel@tonic-gate {
363291Smike_s int i;
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate for (i = 1; i <= c; ++i)
3660Sstevel@tonic-gate (void) undef(ap[i]);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate static void
dopushdef(wchar_t ** ap,int c)3700Sstevel@tonic-gate dopushdef(wchar_t **ap, int c)
3710Sstevel@tonic-gate {
3720Sstevel@tonic-gate def(ap, c, PUSH);
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate static void
doshift(wchar_t ** ap,int c)3760Sstevel@tonic-gate doshift(wchar_t **ap, int c)
3770Sstevel@tonic-gate {
3780Sstevel@tonic-gate if (c <= 1)
3790Sstevel@tonic-gate return;
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate for (;;) {
3820Sstevel@tonic-gate pbstr(rquote);
3830Sstevel@tonic-gate pbstr(ap[c--]);
3840Sstevel@tonic-gate pbstr(lquote);
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate if (c <= 1)
3870Sstevel@tonic-gate break;
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate pbstr(L",");
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate static void
dosincl(wchar_t ** ap,int c)3940Sstevel@tonic-gate dosincl(wchar_t **ap, int c)
3950Sstevel@tonic-gate {
3960Sstevel@tonic-gate incl(ap, c, 0);
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate
3990Sstevel@tonic-gate static void
dosubstr(wchar_t ** ap,int c)4000Sstevel@tonic-gate dosubstr(wchar_t **ap, int c)
4010Sstevel@tonic-gate {
4020Sstevel@tonic-gate wchar_t *str;
4030Sstevel@tonic-gate int inlen, outlen;
4040Sstevel@tonic-gate int offset, ix;
4050Sstevel@tonic-gate
4060Sstevel@tonic-gate inlen = wcslen(str = arg(1));
4070Sstevel@tonic-gate offset = wstoi(arg(2));
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate if (offset < 0 || offset >= inlen)
4100Sstevel@tonic-gate return;
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate outlen = c >= 3 ? wstoi(ap[3]) : inlen;
4130Sstevel@tonic-gate ix = min(offset+outlen, inlen);
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate while (ix > offset)
4160Sstevel@tonic-gate putbak(str[--ix]);
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate static void
dosyscmd(wchar_t ** ap,int c)4200Sstevel@tonic-gate dosyscmd(wchar_t **ap, int c)
4210Sstevel@tonic-gate {
4220Sstevel@tonic-gate sysrval = 0;
4230Sstevel@tonic-gate if (c > 0) {
4240Sstevel@tonic-gate (void) fflush(stdout);
4250Sstevel@tonic-gate sysrval = system(wstr2str(ap[1], 0));
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate }
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate /* ARGSUSED */
4300Sstevel@tonic-gate static void
dosysval(wchar_t ** ap,int c)4310Sstevel@tonic-gate dosysval(wchar_t **ap, int c)
4320Sstevel@tonic-gate {
4330Sstevel@tonic-gate pbnum((long)(sysrval < 0 ? sysrval :
434*6951Sab196087 (sysrval >> 8) & ((1 << 8) - 1)) |
435*6951Sab196087 ((sysrval & ((1 << 8) - 1)) << 8));
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate static void
dotransl(wchar_t ** ap,int c)4390Sstevel@tonic-gate dotransl(wchar_t **ap, int c)
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate wchar_t *sink, *fr, *sto;
4420Sstevel@tonic-gate wchar_t *source, *to;
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate if (c < 1)
4450Sstevel@tonic-gate return;
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate sink = ap[1];
4480Sstevel@tonic-gate fr = arg(2);
4490Sstevel@tonic-gate sto = arg(3);
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate for (source = ap[1]; *source; source++) {
4520Sstevel@tonic-gate wchar_t *i;
4530Sstevel@tonic-gate to = sto;
4540Sstevel@tonic-gate for (i = fr; *i; ++i) {
4550Sstevel@tonic-gate if (*source == *i)
4560Sstevel@tonic-gate break;
4570Sstevel@tonic-gate if (*to)
4580Sstevel@tonic-gate ++to;
4590Sstevel@tonic-gate }
4600Sstevel@tonic-gate if (*i) {
4610Sstevel@tonic-gate if (*to)
4620Sstevel@tonic-gate *sink++ = *to;
4630Sstevel@tonic-gate } else
4640Sstevel@tonic-gate *sink++ = *source;
4650Sstevel@tonic-gate }
4660Sstevel@tonic-gate *sink = EOS;
4670Sstevel@tonic-gate pbstr(ap[1]);
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate static void
dotroff(wchar_t ** ap,int c)4710Sstevel@tonic-gate dotroff(wchar_t **ap, int c)
4720Sstevel@tonic-gate {
473291Smike_s struct nlist *np;
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate trace = 0;
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate while (c > 0)
4780Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name)
4790Sstevel@tonic-gate np->tflag = 0;
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate static void
dotron(wchar_t ** ap,int c)4830Sstevel@tonic-gate dotron(wchar_t **ap, int c)
4840Sstevel@tonic-gate {
485291Smike_s struct nlist *np;
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate trace = !*arg(1);
4880Sstevel@tonic-gate
4890Sstevel@tonic-gate while (c > 0)
4900Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name)
4910Sstevel@tonic-gate np->tflag = 1;
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate void
doundef(wchar_t ** ap,int c)4950Sstevel@tonic-gate doundef(wchar_t **ap, int c)
4960Sstevel@tonic-gate {
497291Smike_s int i;
4980Sstevel@tonic-gate
4990Sstevel@tonic-gate for (i = 1; i <= c; ++i)
5000Sstevel@tonic-gate while (undef(ap[i]))
5010Sstevel@tonic-gate ;
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate int
undef(wchar_t * nam)5050Sstevel@tonic-gate undef(wchar_t *nam)
5060Sstevel@tonic-gate {
507291Smike_s struct nlist *np, *tnp;
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate if ((np = lookup(nam))->name == NULL)
5100Sstevel@tonic-gate return (0);
5110Sstevel@tonic-gate tnp = hshtab[hshval]; /* lookup sets hshval */
5120Sstevel@tonic-gate if (tnp == np) /* it's in first place */
5130Sstevel@tonic-gate hshtab[hshval] = tnp->next;
5140Sstevel@tonic-gate else {
5150Sstevel@tonic-gate while (tnp->next != np)
5160Sstevel@tonic-gate tnp = tnp->next;
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate tnp->next = np->next;
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate free(np->name);
5210Sstevel@tonic-gate free(np->def);
5220Sstevel@tonic-gate free(np);
5230Sstevel@tonic-gate return (1);
5240Sstevel@tonic-gate }
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate static void
doundiv(wchar_t ** ap,int c)5270Sstevel@tonic-gate doundiv(wchar_t **ap, int c)
5280Sstevel@tonic-gate {
529291Smike_s int i;
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate if (c <= 0)
5320Sstevel@tonic-gate for (i = 1; i < 10; i++)
5330Sstevel@tonic-gate undiv(i, OK);
5340Sstevel@tonic-gate else
5350Sstevel@tonic-gate while (--c >= 0)
5360Sstevel@tonic-gate undiv(wstoi(*++ap), OK);
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate /*
5400Sstevel@tonic-gate * dowrap
5410Sstevel@tonic-gate *
5420Sstevel@tonic-gate * Process m4wrap macro.
5430Sstevel@tonic-gate */
5440Sstevel@tonic-gate static void
dowrap(wchar_t ** ap,int c)5450Sstevel@tonic-gate dowrap(wchar_t **ap, int c)
5460Sstevel@tonic-gate {
5470Sstevel@tonic-gate wchar_t *a = arg(1);
5480Sstevel@tonic-gate struct Wrap *wrapentry; /* entry for list of "m4wrap" strings */
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate wrapentry = xmalloc(sizeof (struct Wrap));
5510Sstevel@tonic-gate /* store m4wrap string */
5520Sstevel@tonic-gate wrapentry->wrapstr = wstrdup(a);
5530Sstevel@tonic-gate /* add this entry to the front of the list of Wrap entries */
5540Sstevel@tonic-gate wrapentry->nxt = wrapstart;
5550Sstevel@tonic-gate wrapstart = wrapentry;
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate static void
mkpid(char * as)5590Sstevel@tonic-gate mkpid(char *as)
5600Sstevel@tonic-gate {
5610Sstevel@tonic-gate char *s = as;
5620Sstevel@tonic-gate char *l;
5630Sstevel@tonic-gate char *first_X;
5640Sstevel@tonic-gate unsigned xcnt = 0;
5650Sstevel@tonic-gate char my_pid[32];
5660Sstevel@tonic-gate int pid_len;
5670Sstevel@tonic-gate int i = 0;
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate /*
5700Sstevel@tonic-gate * Count number of X.
5710Sstevel@tonic-gate */
5720Sstevel@tonic-gate l = &s[strlen(s)-1];
5730Sstevel@tonic-gate while (l != as) {
5740Sstevel@tonic-gate if (*l == 'X') {
5750Sstevel@tonic-gate first_X = l;
5760Sstevel@tonic-gate l--;
5770Sstevel@tonic-gate xcnt++;
5780Sstevel@tonic-gate } else if (xcnt == 0)
5790Sstevel@tonic-gate l--;
5800Sstevel@tonic-gate else {
5810Sstevel@tonic-gate break;
5820Sstevel@tonic-gate }
5830Sstevel@tonic-gate }
5840Sstevel@tonic-gate
5850Sstevel@tonic-gate /*
5860Sstevel@tonic-gate * 1) If there is no X in the passed string,
5870Sstevel@tonic-gate * then it just return the passed string.
5880Sstevel@tonic-gate * 2) If the length of the continuous right most X's of
5890Sstevel@tonic-gate * the string is shorter than the length of pid,
5900Sstevel@tonic-gate * then right most X's will be substitued with
5910Sstevel@tonic-gate * upper digits of pid.
5920Sstevel@tonic-gate * 3) If the length of the continuous right most X's of
5930Sstevel@tonic-gate * the string is equat to the length of pid,
5940Sstevel@tonic-gate * then X's will be replaced with pid.
5950Sstevel@tonic-gate * 4) If the lenght of the continuous right most X's of
5960Sstevel@tonic-gate * the string is longer than the length of pid,
5970Sstevel@tonic-gate * then X's will have leading 0 followed by
5980Sstevel@tonic-gate * pid.
5990Sstevel@tonic-gate */
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate /*
6020Sstevel@tonic-gate * If there were no X, don't do anything.
6030Sstevel@tonic-gate */
6040Sstevel@tonic-gate if (xcnt == 0)
6050Sstevel@tonic-gate return;
6060Sstevel@tonic-gate
6070Sstevel@tonic-gate /*
6080Sstevel@tonic-gate * Get pid
6090Sstevel@tonic-gate */
6100Sstevel@tonic-gate (void) snprintf(my_pid, sizeof (my_pid), "%d", (int)getpid());
6110Sstevel@tonic-gate pid_len = strlen(my_pid);
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate if (pid_len > xcnt)
6140Sstevel@tonic-gate my_pid[xcnt] = 0;
6150Sstevel@tonic-gate else if (pid_len < xcnt) {
6160Sstevel@tonic-gate while (xcnt != pid_len) {
6170Sstevel@tonic-gate *first_X++ = '0';
6180Sstevel@tonic-gate xcnt--;
6190Sstevel@tonic-gate }
6200Sstevel@tonic-gate }
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate /*
6230Sstevel@tonic-gate * Copy pid
6240Sstevel@tonic-gate */
6250Sstevel@tonic-gate while (i != xcnt)
6260Sstevel@tonic-gate *first_X++ = my_pid[i++];
6270Sstevel@tonic-gate }
6280Sstevel@tonic-gate
6290Sstevel@tonic-gate struct bs barray[] = {
6300Sstevel@tonic-gate dochcom, L"changecom",
6310Sstevel@tonic-gate docq, L"changequote",
6320Sstevel@tonic-gate dodecr, L"decr",
6330Sstevel@tonic-gate dodef, L"define",
6340Sstevel@tonic-gate dodefn, L"defn",
6350Sstevel@tonic-gate dodiv, L"divert",
6360Sstevel@tonic-gate dodivnum, L"divnum",
6370Sstevel@tonic-gate dodnl, L"dnl",
6380Sstevel@tonic-gate dodump, L"dumpdef",
6390Sstevel@tonic-gate doerrp, L"errprint",
6400Sstevel@tonic-gate doeval, L"eval",
6410Sstevel@tonic-gate doexit, L"m4exit",
6420Sstevel@tonic-gate doif, L"ifelse",
6430Sstevel@tonic-gate doifdef, L"ifdef",
6440Sstevel@tonic-gate doincl, L"include",
6450Sstevel@tonic-gate doincr, L"incr",
6460Sstevel@tonic-gate doindex, L"index",
6470Sstevel@tonic-gate dolen, L"len",
6480Sstevel@tonic-gate domake, L"maketemp",
6490Sstevel@tonic-gate dopopdef, L"popdef",
6500Sstevel@tonic-gate dopushdef, L"pushdef",
6510Sstevel@tonic-gate doshift, L"shift",
6520Sstevel@tonic-gate dosincl, L"sinclude",
6530Sstevel@tonic-gate dosubstr, L"substr",
6540Sstevel@tonic-gate dosyscmd, L"syscmd",
6550Sstevel@tonic-gate dosysval, L"sysval",
6560Sstevel@tonic-gate dotransl, L"translit",
6570Sstevel@tonic-gate dotroff, L"traceoff",
6580Sstevel@tonic-gate dotron, L"traceon",
6590Sstevel@tonic-gate doundef, L"undefine",
6600Sstevel@tonic-gate doundiv, L"undivert",
6610Sstevel@tonic-gate dowrap, L"m4wrap",
6620Sstevel@tonic-gate 0, 0
6630Sstevel@tonic-gate };
664