17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51dd08564Sab196087 * Common Development and Distribution License (the "License").
61dd08564Sab196087 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate
227c478bd9Sstevel@tonic-gate /*
231dd08564Sab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
27*447603b5SGary Mills /*
28*447603b5SGary Mills * Copyright (c) 2011 Gary Mills
29*447603b5SGary Mills */
30*447603b5SGary Mills
319fb11590Smike_s /* Copyright (c) 1988 AT&T */
329fb11590Smike_s /* All Rights Reserved */
339fb11590Smike_s
347c478bd9Sstevel@tonic-gate #include <limits.h>
357c478bd9Sstevel@tonic-gate #include <unistd.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include "m4.h"
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate #define arg(n) (c < (n) ? nullstr: ap[n])
407c478bd9Sstevel@tonic-gate static void mkpid(char *);
417c478bd9Sstevel@tonic-gate static void def(wchar_t **, int, int);
427c478bd9Sstevel@tonic-gate static void dump(wchar_t *, wchar_t *);
437c478bd9Sstevel@tonic-gate static void incl(wchar_t **, int, int);
447c478bd9Sstevel@tonic-gate static int leftmatch(wchar_t *, wchar_t *);
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate static void
dochcom(wchar_t ** ap,int c)477c478bd9Sstevel@tonic-gate dochcom(wchar_t **ap, int c)
487c478bd9Sstevel@tonic-gate {
497c478bd9Sstevel@tonic-gate wchar_t *l = arg(1);
507c478bd9Sstevel@tonic-gate wchar_t *r = arg(2);
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM)
537c478bd9Sstevel@tonic-gate error2(gettext(
547c478bd9Sstevel@tonic-gate "comment marker longer than %d chars"), MAXSYM);
557c478bd9Sstevel@tonic-gate (void) wcscpy(lcom, l);
567c478bd9Sstevel@tonic-gate (void) wcscpy(rcom, *r ? r : L"\n");
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate static void
docq(wchar_t ** ap,int c)607c478bd9Sstevel@tonic-gate docq(wchar_t **ap, int c)
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate wchar_t *l = arg(1);
637c478bd9Sstevel@tonic-gate wchar_t *r = arg(2);
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM)
667c478bd9Sstevel@tonic-gate error2(gettext(
677c478bd9Sstevel@tonic-gate "quote marker longer than %d chars"), MAXSYM);
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate if (c <= 1 && !*l) {
707c478bd9Sstevel@tonic-gate l = L"`";
717c478bd9Sstevel@tonic-gate r = L"'";
727c478bd9Sstevel@tonic-gate } else if (c == 1) {
737c478bd9Sstevel@tonic-gate r = l;
747c478bd9Sstevel@tonic-gate }
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate (void) wcscpy(lquote, l);
777c478bd9Sstevel@tonic-gate (void) wcscpy(rquote, r);
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate static void
dodecr(wchar_t ** ap,int c)817c478bd9Sstevel@tonic-gate dodecr(wchar_t **ap, int c)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate pbnum(ctol(arg(1))-1);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate void
dodef(wchar_t ** ap,int c)877c478bd9Sstevel@tonic-gate dodef(wchar_t **ap, int c)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate def(ap, c, NOPUSH);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate static void
def(wchar_t ** ap,int c,int mode)937c478bd9Sstevel@tonic-gate def(wchar_t **ap, int c, int mode)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate wchar_t *s;
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate if (c < 1)
987c478bd9Sstevel@tonic-gate return;
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate s = ap[1];
1017c478bd9Sstevel@tonic-gate if (is_alpha(*s) || *s == '_') {
1027c478bd9Sstevel@tonic-gate s++;
1037c478bd9Sstevel@tonic-gate while (is_alnum(*s) || *s == '_')
1047c478bd9Sstevel@tonic-gate s++;
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate if (*s || s == ap[1])
1077c478bd9Sstevel@tonic-gate error(gettext("bad macro name"));
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate if ((ap[2] != NULL) && (wcscmp(ap[1], ap[2]) == 0))
1107c478bd9Sstevel@tonic-gate error(gettext("macro defined as itself"));
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate install(ap[1], arg(2), mode);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate static void
dodefn(wchar_t ** ap,int c)1167c478bd9Sstevel@tonic-gate dodefn(wchar_t **ap, int c)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate wchar_t *d;
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate while (c > 0)
1217c478bd9Sstevel@tonic-gate if ((d = lookup(ap[c--])->def) != NULL) {
1227c478bd9Sstevel@tonic-gate putbak(*rquote);
1237c478bd9Sstevel@tonic-gate while (*d)
1247c478bd9Sstevel@tonic-gate putbak(*d++);
1257c478bd9Sstevel@tonic-gate putbak(*lquote);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate static void
dodiv(wchar_t ** ap,int c)1307c478bd9Sstevel@tonic-gate dodiv(wchar_t **ap, int c)
1317c478bd9Sstevel@tonic-gate {
1329fb11590Smike_s int f;
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate f = wstoi(arg(1));
1357c478bd9Sstevel@tonic-gate if (f >= 10 || f < 0) {
1367c478bd9Sstevel@tonic-gate cf = NULL;
1377c478bd9Sstevel@tonic-gate ofx = f;
1387c478bd9Sstevel@tonic-gate return;
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate tempfile[7] = 'a'+f;
1417c478bd9Sstevel@tonic-gate if (ofile[f] || (ofile[f] = xfopen(tempfile, "w"))) {
1427c478bd9Sstevel@tonic-gate ofx = f;
1437c478bd9Sstevel@tonic-gate cf = ofile[f];
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate /* ARGSUSED */
1487c478bd9Sstevel@tonic-gate static void
dodivnum(wchar_t ** ap,int c)1497c478bd9Sstevel@tonic-gate dodivnum(wchar_t **ap, int c)
1507c478bd9Sstevel@tonic-gate {
1517c478bd9Sstevel@tonic-gate pbnum((long)ofx);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /* ARGSUSED */
1557c478bd9Sstevel@tonic-gate static void
dodnl(wchar_t ** ap,int c)1567c478bd9Sstevel@tonic-gate dodnl(wchar_t **ap, int c)
1577c478bd9Sstevel@tonic-gate {
1587c478bd9Sstevel@tonic-gate wchar_t t;
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate while ((t = getchr()) != '\n' && t != WEOF)
1617c478bd9Sstevel@tonic-gate ;
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate static void
dodump(wchar_t ** ap,int c)1657c478bd9Sstevel@tonic-gate dodump(wchar_t **ap, int c)
1667c478bd9Sstevel@tonic-gate {
1679fb11590Smike_s struct nlist *np;
1689fb11590Smike_s int i;
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate if (c > 0)
1717c478bd9Sstevel@tonic-gate while (c--) {
1727c478bd9Sstevel@tonic-gate if ((np = lookup(*++ap))->name != NULL)
1737c478bd9Sstevel@tonic-gate dump(np->name, np->def);
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate else
1767c478bd9Sstevel@tonic-gate for (i = 0; i < hshsize; i++)
1777c478bd9Sstevel@tonic-gate for (np = hshtab[i]; np != NULL; np = np->next)
1787c478bd9Sstevel@tonic-gate dump(np->name, np->def);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
1811dd08564Sab196087 /*ARGSUSED*/
1827c478bd9Sstevel@tonic-gate static void
dump(wchar_t * name,wchar_t * defnn)1837c478bd9Sstevel@tonic-gate dump(wchar_t *name, wchar_t *defnn)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate wchar_t *s = defnn;
1867c478bd9Sstevel@tonic-gate
1871dd08564Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
1887c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%ws:\t", name);
1891dd08564Sab196087 #endif
1907c478bd9Sstevel@tonic-gate
1911dd08564Sab196087 while (*s++)
1921dd08564Sab196087 ;
1937c478bd9Sstevel@tonic-gate --s;
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate while (s > defnn) {
1967c478bd9Sstevel@tonic-gate --s;
1971dd08564Sab196087 if (is_builtin(*s)) {
1981dd08564Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
1997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "<%ws>",
2007c478bd9Sstevel@tonic-gate barray[builtin_idx(*s)].bname);
2011dd08564Sab196087 } else {
2021dd08564Sab196087 #endif
2037c478bd9Sstevel@tonic-gate (void) fputwc(*s, stderr);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate (void) fputc('\n', stderr);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2091dd08564Sab196087 /*ARGSUSED*/
2107c478bd9Sstevel@tonic-gate static void
doerrp(wchar_t ** ap,int c)2117c478bd9Sstevel@tonic-gate doerrp(wchar_t **ap, int c)
2127c478bd9Sstevel@tonic-gate {
2131dd08564Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */
2147c478bd9Sstevel@tonic-gate if (c > 0)
2157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%ws", ap[1]);
2161dd08564Sab196087 #endif
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate long evalval; /* return value from yacc stuff */
2207c478bd9Sstevel@tonic-gate wchar_t *pe; /* used by grammar */
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate static void
doeval(wchar_t ** ap,int c)2237c478bd9Sstevel@tonic-gate doeval(wchar_t **ap, int c)
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate int base = wstoi(arg(2));
2267c478bd9Sstevel@tonic-gate int pad = wstoi(arg(3));
2277c478bd9Sstevel@tonic-gate extern int yyparse(void);
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate evalval = 0;
2307c478bd9Sstevel@tonic-gate if (c > 0) {
2317c478bd9Sstevel@tonic-gate pe = ap[1];
2327c478bd9Sstevel@tonic-gate if (yyparse() != 0)
2337c478bd9Sstevel@tonic-gate error(gettext(
2347c478bd9Sstevel@tonic-gate "invalid expression"));
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate pbnbr(evalval, base > 0 ? base:10, pad > 0 ? pad : 1);
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate * doexit
2417c478bd9Sstevel@tonic-gate *
2427c478bd9Sstevel@tonic-gate * Process m4exit macro.
2437c478bd9Sstevel@tonic-gate */
2447c478bd9Sstevel@tonic-gate static void
doexit(wchar_t ** ap,int c)2457c478bd9Sstevel@tonic-gate doexit(wchar_t **ap, int c)
2467c478bd9Sstevel@tonic-gate {
2477c478bd9Sstevel@tonic-gate delexit(wstoi(arg(1)), 1);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate static void
doif(wchar_t ** ap,int c)2517c478bd9Sstevel@tonic-gate doif(wchar_t **ap, int c)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate if (c < 3)
2547c478bd9Sstevel@tonic-gate return;
2557c478bd9Sstevel@tonic-gate while (c >= 3) {
2567c478bd9Sstevel@tonic-gate if (wcscmp(ap[1], ap[2]) == 0) {
2577c478bd9Sstevel@tonic-gate pbstr(ap[3]);
2587c478bd9Sstevel@tonic-gate return;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate c -= 3;
2617c478bd9Sstevel@tonic-gate ap += 3;
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate if (c > 0)
2647c478bd9Sstevel@tonic-gate pbstr(ap[1]);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate static void
doifdef(wchar_t ** ap,int c)2687c478bd9Sstevel@tonic-gate doifdef(wchar_t **ap, int c)
2697c478bd9Sstevel@tonic-gate {
2707c478bd9Sstevel@tonic-gate if (c < 2)
2717c478bd9Sstevel@tonic-gate return;
2727c478bd9Sstevel@tonic-gate
2737c478bd9Sstevel@tonic-gate while (c >= 2) {
2747c478bd9Sstevel@tonic-gate if (lookup(ap[1])->name != NULL) {
2757c478bd9Sstevel@tonic-gate pbstr(ap[2]);
2767c478bd9Sstevel@tonic-gate return;
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate c -= 2;
2797c478bd9Sstevel@tonic-gate ap += 2;
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate if (c > 0)
2837c478bd9Sstevel@tonic-gate pbstr(ap[1]);
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate static void
doincl(wchar_t ** ap,int c)2877c478bd9Sstevel@tonic-gate doincl(wchar_t **ap, int c)
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate incl(ap, c, 1);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate static void
incl(wchar_t ** ap,int c,int noisy)2937c478bd9Sstevel@tonic-gate incl(wchar_t **ap, int c, int noisy)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate if (c > 0 && wcslen(ap[1]) > 0) {
2967c478bd9Sstevel@tonic-gate if (ifx >= 9)
2977c478bd9Sstevel@tonic-gate error(gettext(
2987c478bd9Sstevel@tonic-gate "input file nesting too deep (9)"));
2997c478bd9Sstevel@tonic-gate if ((ifile[++ifx] = fopen(wstr2str(ap[1], 0), "r")) == NULL) {
3007c478bd9Sstevel@tonic-gate --ifx;
3017c478bd9Sstevel@tonic-gate if (noisy)
302*447603b5SGary Mills errorf(gettext("cannot open file: %s"),
303*447603b5SGary Mills strerror(errno));
3047c478bd9Sstevel@tonic-gate } else {
3057c478bd9Sstevel@tonic-gate ipstk[ifx] = ipflr = ip;
3067c478bd9Sstevel@tonic-gate setfname(wstr2str(ap[1], 0));
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate static void
doincr(wchar_t ** ap,int c)3127c478bd9Sstevel@tonic-gate doincr(wchar_t **ap, int c)
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate pbnum(ctol(arg(1))+1);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate static void
doindex(wchar_t ** ap,int c)3187c478bd9Sstevel@tonic-gate doindex(wchar_t **ap, int c)
3197c478bd9Sstevel@tonic-gate {
3207c478bd9Sstevel@tonic-gate wchar_t *subj = arg(1);
3217c478bd9Sstevel@tonic-gate wchar_t *obj = arg(2);
3229fb11590Smike_s int i;
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate for (i = 0; *subj; ++i)
3257c478bd9Sstevel@tonic-gate if (leftmatch(subj++, obj)) {
3267c478bd9Sstevel@tonic-gate pbnum((long)i);
3277c478bd9Sstevel@tonic-gate return;
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate pbnum((long)-1);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate static int
leftmatch(wchar_t * str,wchar_t * substr)3347c478bd9Sstevel@tonic-gate leftmatch(wchar_t *str, wchar_t *substr)
3357c478bd9Sstevel@tonic-gate {
3367c478bd9Sstevel@tonic-gate while (*substr)
3377c478bd9Sstevel@tonic-gate if (*str++ != *substr++)
3387c478bd9Sstevel@tonic-gate return (0);
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate return (1);
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate static void
dolen(wchar_t ** ap,int c)3447c478bd9Sstevel@tonic-gate dolen(wchar_t **ap, int c)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate pbnum((long)wcslen(arg(1)));
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate static void
domake(wchar_t ** ap,int c)3507c478bd9Sstevel@tonic-gate domake(wchar_t **ap, int c)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate char *path;
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate if (c > 0) {
3557c478bd9Sstevel@tonic-gate path = wstr2str(ap[1], 1);
3567c478bd9Sstevel@tonic-gate mkpid(path);
3577c478bd9Sstevel@tonic-gate pbstr(str2wstr(path, 0));
3587c478bd9Sstevel@tonic-gate free(path);
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate static void
dopopdef(wchar_t ** ap,int c)3637c478bd9Sstevel@tonic-gate dopopdef(wchar_t **ap, int c)
3647c478bd9Sstevel@tonic-gate {
3659fb11590Smike_s int i;
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate for (i = 1; i <= c; ++i)
3687c478bd9Sstevel@tonic-gate (void) undef(ap[i]);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate static void
dopushdef(wchar_t ** ap,int c)3727c478bd9Sstevel@tonic-gate dopushdef(wchar_t **ap, int c)
3737c478bd9Sstevel@tonic-gate {
3747c478bd9Sstevel@tonic-gate def(ap, c, PUSH);
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate static void
doshift(wchar_t ** ap,int c)3787c478bd9Sstevel@tonic-gate doshift(wchar_t **ap, int c)
3797c478bd9Sstevel@tonic-gate {
3807c478bd9Sstevel@tonic-gate if (c <= 1)
3817c478bd9Sstevel@tonic-gate return;
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate for (;;) {
3847c478bd9Sstevel@tonic-gate pbstr(rquote);
3857c478bd9Sstevel@tonic-gate pbstr(ap[c--]);
3867c478bd9Sstevel@tonic-gate pbstr(lquote);
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate if (c <= 1)
3897c478bd9Sstevel@tonic-gate break;
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate pbstr(L",");
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate static void
dosincl(wchar_t ** ap,int c)3967c478bd9Sstevel@tonic-gate dosincl(wchar_t **ap, int c)
3977c478bd9Sstevel@tonic-gate {
3987c478bd9Sstevel@tonic-gate incl(ap, c, 0);
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate static void
dosubstr(wchar_t ** ap,int c)4027c478bd9Sstevel@tonic-gate dosubstr(wchar_t **ap, int c)
4037c478bd9Sstevel@tonic-gate {
4047c478bd9Sstevel@tonic-gate wchar_t *str;
4057c478bd9Sstevel@tonic-gate int inlen, outlen;
4067c478bd9Sstevel@tonic-gate int offset, ix;
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate inlen = wcslen(str = arg(1));
4097c478bd9Sstevel@tonic-gate offset = wstoi(arg(2));
4107c478bd9Sstevel@tonic-gate
4117c478bd9Sstevel@tonic-gate if (offset < 0 || offset >= inlen)
4127c478bd9Sstevel@tonic-gate return;
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate outlen = c >= 3 ? wstoi(ap[3]) : inlen;
4157c478bd9Sstevel@tonic-gate ix = min(offset+outlen, inlen);
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate while (ix > offset)
4187c478bd9Sstevel@tonic-gate putbak(str[--ix]);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate static void
dosyscmd(wchar_t ** ap,int c)4227c478bd9Sstevel@tonic-gate dosyscmd(wchar_t **ap, int c)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate sysrval = 0;
4257c478bd9Sstevel@tonic-gate if (c > 0) {
4267c478bd9Sstevel@tonic-gate (void) fflush(stdout);
4277c478bd9Sstevel@tonic-gate sysrval = system(wstr2str(ap[1], 0));
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate /* ARGSUSED */
4327c478bd9Sstevel@tonic-gate static void
dosysval(wchar_t ** ap,int c)4337c478bd9Sstevel@tonic-gate dosysval(wchar_t **ap, int c)
4347c478bd9Sstevel@tonic-gate {
4357c478bd9Sstevel@tonic-gate pbnum((long)(sysrval < 0 ? sysrval :
4367c478bd9Sstevel@tonic-gate (sysrval >> 8) & ((1 << 8) - 1)) |
4377c478bd9Sstevel@tonic-gate ((sysrval & ((1 << 8) - 1)) << 8));
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate static void
dotransl(wchar_t ** ap,int c)4417c478bd9Sstevel@tonic-gate dotransl(wchar_t **ap, int c)
4427c478bd9Sstevel@tonic-gate {
4437c478bd9Sstevel@tonic-gate wchar_t *sink, *fr, *sto;
4447c478bd9Sstevel@tonic-gate wchar_t *source, *to;
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate if (c < 1)
4477c478bd9Sstevel@tonic-gate return;
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate sink = ap[1];
4507c478bd9Sstevel@tonic-gate fr = arg(2);
4517c478bd9Sstevel@tonic-gate sto = arg(3);
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate for (source = ap[1]; *source; source++) {
4547c478bd9Sstevel@tonic-gate wchar_t *i;
4557c478bd9Sstevel@tonic-gate to = sto;
4567c478bd9Sstevel@tonic-gate for (i = fr; *i; ++i) {
4577c478bd9Sstevel@tonic-gate if (*source == *i)
4587c478bd9Sstevel@tonic-gate break;
4597c478bd9Sstevel@tonic-gate if (*to)
4607c478bd9Sstevel@tonic-gate ++to;
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate if (*i) {
4637c478bd9Sstevel@tonic-gate if (*to)
4647c478bd9Sstevel@tonic-gate *sink++ = *to;
4657c478bd9Sstevel@tonic-gate } else
4667c478bd9Sstevel@tonic-gate *sink++ = *source;
4677c478bd9Sstevel@tonic-gate }
4687c478bd9Sstevel@tonic-gate *sink = EOS;
4697c478bd9Sstevel@tonic-gate pbstr(ap[1]);
4707c478bd9Sstevel@tonic-gate }
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gate static void
dotroff(wchar_t ** ap,int c)4737c478bd9Sstevel@tonic-gate dotroff(wchar_t **ap, int c)
4747c478bd9Sstevel@tonic-gate {
4759fb11590Smike_s struct nlist *np;
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate trace = 0;
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate while (c > 0)
4807c478bd9Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name)
4817c478bd9Sstevel@tonic-gate np->tflag = 0;
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate static void
dotron(wchar_t ** ap,int c)4857c478bd9Sstevel@tonic-gate dotron(wchar_t **ap, int c)
4867c478bd9Sstevel@tonic-gate {
4879fb11590Smike_s struct nlist *np;
4887c478bd9Sstevel@tonic-gate
4897c478bd9Sstevel@tonic-gate trace = !*arg(1);
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate while (c > 0)
4927c478bd9Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name)
4937c478bd9Sstevel@tonic-gate np->tflag = 1;
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate void
doundef(wchar_t ** ap,int c)4977c478bd9Sstevel@tonic-gate doundef(wchar_t **ap, int c)
4987c478bd9Sstevel@tonic-gate {
4999fb11590Smike_s int i;
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate for (i = 1; i <= c; ++i)
5027c478bd9Sstevel@tonic-gate while (undef(ap[i]))
5037c478bd9Sstevel@tonic-gate ;
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate int
undef(wchar_t * nam)5077c478bd9Sstevel@tonic-gate undef(wchar_t *nam)
5087c478bd9Sstevel@tonic-gate {
5099fb11590Smike_s struct nlist *np, *tnp;
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate if ((np = lookup(nam))->name == NULL)
5127c478bd9Sstevel@tonic-gate return (0);
5137c478bd9Sstevel@tonic-gate tnp = hshtab[hshval]; /* lookup sets hshval */
5147c478bd9Sstevel@tonic-gate if (tnp == np) /* it's in first place */
5157c478bd9Sstevel@tonic-gate hshtab[hshval] = tnp->next;
5167c478bd9Sstevel@tonic-gate else {
5177c478bd9Sstevel@tonic-gate while (tnp->next != np)
5187c478bd9Sstevel@tonic-gate tnp = tnp->next;
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate tnp->next = np->next;
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate free(np->name);
5237c478bd9Sstevel@tonic-gate free(np->def);
5247c478bd9Sstevel@tonic-gate free(np);
5257c478bd9Sstevel@tonic-gate return (1);
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate static void
doundiv(wchar_t ** ap,int c)5297c478bd9Sstevel@tonic-gate doundiv(wchar_t **ap, int c)
5307c478bd9Sstevel@tonic-gate {
5319fb11590Smike_s int i;
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate if (c <= 0)
5347c478bd9Sstevel@tonic-gate for (i = 1; i < 10; i++)
5357c478bd9Sstevel@tonic-gate undiv(i, OK);
5367c478bd9Sstevel@tonic-gate else
5377c478bd9Sstevel@tonic-gate while (--c >= 0)
5387c478bd9Sstevel@tonic-gate undiv(wstoi(*++ap), OK);
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate * dowrap
5437c478bd9Sstevel@tonic-gate *
5447c478bd9Sstevel@tonic-gate * Process m4wrap macro.
5457c478bd9Sstevel@tonic-gate */
5467c478bd9Sstevel@tonic-gate static void
dowrap(wchar_t ** ap,int c)5477c478bd9Sstevel@tonic-gate dowrap(wchar_t **ap, int c)
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate wchar_t *a = arg(1);
5507c478bd9Sstevel@tonic-gate struct Wrap *wrapentry; /* entry for list of "m4wrap" strings */
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate wrapentry = xmalloc(sizeof (struct Wrap));
5537c478bd9Sstevel@tonic-gate /* store m4wrap string */
5547c478bd9Sstevel@tonic-gate wrapentry->wrapstr = wstrdup(a);
5557c478bd9Sstevel@tonic-gate /* add this entry to the front of the list of Wrap entries */
5567c478bd9Sstevel@tonic-gate wrapentry->nxt = wrapstart;
5577c478bd9Sstevel@tonic-gate wrapstart = wrapentry;
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate
5607c478bd9Sstevel@tonic-gate static void
mkpid(char * as)5617c478bd9Sstevel@tonic-gate mkpid(char *as)
5627c478bd9Sstevel@tonic-gate {
5637c478bd9Sstevel@tonic-gate char *s = as;
5647c478bd9Sstevel@tonic-gate char *l;
5657c478bd9Sstevel@tonic-gate char *first_X;
5667c478bd9Sstevel@tonic-gate unsigned xcnt = 0;
5677c478bd9Sstevel@tonic-gate char my_pid[32];
5687c478bd9Sstevel@tonic-gate int pid_len;
5697c478bd9Sstevel@tonic-gate int i = 0;
5707c478bd9Sstevel@tonic-gate
5717c478bd9Sstevel@tonic-gate /*
5727c478bd9Sstevel@tonic-gate * Count number of X.
5737c478bd9Sstevel@tonic-gate */
5747c478bd9Sstevel@tonic-gate l = &s[strlen(s)-1];
5757c478bd9Sstevel@tonic-gate while (l != as) {
5767c478bd9Sstevel@tonic-gate if (*l == 'X') {
5777c478bd9Sstevel@tonic-gate first_X = l;
5787c478bd9Sstevel@tonic-gate l--;
5797c478bd9Sstevel@tonic-gate xcnt++;
5807c478bd9Sstevel@tonic-gate } else if (xcnt == 0)
5817c478bd9Sstevel@tonic-gate l--;
5827c478bd9Sstevel@tonic-gate else {
5837c478bd9Sstevel@tonic-gate break;
5847c478bd9Sstevel@tonic-gate }
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate /*
5887c478bd9Sstevel@tonic-gate * 1) If there is no X in the passed string,
5897c478bd9Sstevel@tonic-gate * then it just return the passed string.
5907c478bd9Sstevel@tonic-gate * 2) If the length of the continuous right most X's of
5917c478bd9Sstevel@tonic-gate * the string is shorter than the length of pid,
5927c478bd9Sstevel@tonic-gate * then right most X's will be substitued with
5937c478bd9Sstevel@tonic-gate * upper digits of pid.
5947c478bd9Sstevel@tonic-gate * 3) If the length of the continuous right most X's of
5957c478bd9Sstevel@tonic-gate * the string is equat to the length of pid,
5967c478bd9Sstevel@tonic-gate * then X's will be replaced with pid.
5977c478bd9Sstevel@tonic-gate * 4) If the lenght of the continuous right most X's of
5987c478bd9Sstevel@tonic-gate * the string is longer than the length of pid,
5997c478bd9Sstevel@tonic-gate * then X's will have leading 0 followed by
6007c478bd9Sstevel@tonic-gate * pid.
6017c478bd9Sstevel@tonic-gate */
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate /*
6047c478bd9Sstevel@tonic-gate * If there were no X, don't do anything.
6057c478bd9Sstevel@tonic-gate */
6067c478bd9Sstevel@tonic-gate if (xcnt == 0)
6077c478bd9Sstevel@tonic-gate return;
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate /*
6107c478bd9Sstevel@tonic-gate * Get pid
6117c478bd9Sstevel@tonic-gate */
6127c478bd9Sstevel@tonic-gate (void) snprintf(my_pid, sizeof (my_pid), "%d", (int)getpid());
6137c478bd9Sstevel@tonic-gate pid_len = strlen(my_pid);
6147c478bd9Sstevel@tonic-gate
6157c478bd9Sstevel@tonic-gate if (pid_len > xcnt)
6167c478bd9Sstevel@tonic-gate my_pid[xcnt] = 0;
6177c478bd9Sstevel@tonic-gate else if (pid_len < xcnt) {
6187c478bd9Sstevel@tonic-gate while (xcnt != pid_len) {
6197c478bd9Sstevel@tonic-gate *first_X++ = '0';
6207c478bd9Sstevel@tonic-gate xcnt--;
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate }
6237c478bd9Sstevel@tonic-gate
6247c478bd9Sstevel@tonic-gate /*
6257c478bd9Sstevel@tonic-gate * Copy pid
6267c478bd9Sstevel@tonic-gate */
6277c478bd9Sstevel@tonic-gate while (i != xcnt)
6287c478bd9Sstevel@tonic-gate *first_X++ = my_pid[i++];
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate struct bs barray[] = {
6327c478bd9Sstevel@tonic-gate dochcom, L"changecom",
6337c478bd9Sstevel@tonic-gate docq, L"changequote",
6347c478bd9Sstevel@tonic-gate dodecr, L"decr",
6357c478bd9Sstevel@tonic-gate dodef, L"define",
6367c478bd9Sstevel@tonic-gate dodefn, L"defn",
6377c478bd9Sstevel@tonic-gate dodiv, L"divert",
6387c478bd9Sstevel@tonic-gate dodivnum, L"divnum",
6397c478bd9Sstevel@tonic-gate dodnl, L"dnl",
6407c478bd9Sstevel@tonic-gate dodump, L"dumpdef",
6417c478bd9Sstevel@tonic-gate doerrp, L"errprint",
6427c478bd9Sstevel@tonic-gate doeval, L"eval",
6437c478bd9Sstevel@tonic-gate doexit, L"m4exit",
6447c478bd9Sstevel@tonic-gate doif, L"ifelse",
6457c478bd9Sstevel@tonic-gate doifdef, L"ifdef",
6467c478bd9Sstevel@tonic-gate doincl, L"include",
6477c478bd9Sstevel@tonic-gate doincr, L"incr",
6487c478bd9Sstevel@tonic-gate doindex, L"index",
6497c478bd9Sstevel@tonic-gate dolen, L"len",
6507c478bd9Sstevel@tonic-gate domake, L"maketemp",
6517c478bd9Sstevel@tonic-gate dopopdef, L"popdef",
6527c478bd9Sstevel@tonic-gate dopushdef, L"pushdef",
6537c478bd9Sstevel@tonic-gate doshift, L"shift",
6547c478bd9Sstevel@tonic-gate dosincl, L"sinclude",
6557c478bd9Sstevel@tonic-gate dosubstr, L"substr",
6567c478bd9Sstevel@tonic-gate dosyscmd, L"syscmd",
6577c478bd9Sstevel@tonic-gate dosysval, L"sysval",
6587c478bd9Sstevel@tonic-gate dotransl, L"translit",
6597c478bd9Sstevel@tonic-gate dotroff, L"traceoff",
6607c478bd9Sstevel@tonic-gate dotron, L"traceon",
6617c478bd9Sstevel@tonic-gate doundef, L"undefine",
6627c478bd9Sstevel@tonic-gate doundiv, L"undivert",
6637c478bd9Sstevel@tonic-gate dowrap, L"m4wrap",
6647c478bd9Sstevel@tonic-gate 0, 0
6657c478bd9Sstevel@tonic-gate };
666