1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 23*0Sstevel@tonic-gate /* All Rights Reserved */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28*0Sstevel@tonic-gate * Use is subject to license terms. 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <limits.h> 34*0Sstevel@tonic-gate #include <unistd.h> 35*0Sstevel@tonic-gate #include <sys/types.h> 36*0Sstevel@tonic-gate #include "m4.h" 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #define arg(n) (c < (n) ? nullstr: ap[n]) 39*0Sstevel@tonic-gate static void mkpid(char *); 40*0Sstevel@tonic-gate static void def(wchar_t **, int, int); 41*0Sstevel@tonic-gate static void dump(wchar_t *, wchar_t *); 42*0Sstevel@tonic-gate static void incl(wchar_t **, int, int); 43*0Sstevel@tonic-gate static int leftmatch(wchar_t *, wchar_t *); 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate static void 46*0Sstevel@tonic-gate dochcom(wchar_t **ap, int c) 47*0Sstevel@tonic-gate { 48*0Sstevel@tonic-gate wchar_t *l = arg(1); 49*0Sstevel@tonic-gate wchar_t *r = arg(2); 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM) 52*0Sstevel@tonic-gate error2(gettext( 53*0Sstevel@tonic-gate "comment marker longer than %d chars"), MAXSYM); 54*0Sstevel@tonic-gate (void) wcscpy(lcom, l); 55*0Sstevel@tonic-gate (void) wcscpy(rcom, *r ? r : L"\n"); 56*0Sstevel@tonic-gate } 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate static void 59*0Sstevel@tonic-gate docq(wchar_t **ap, int c) 60*0Sstevel@tonic-gate { 61*0Sstevel@tonic-gate wchar_t *l = arg(1); 62*0Sstevel@tonic-gate wchar_t *r = arg(2); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate if (wcslen(l) > MAXSYM || wcslen(r) > MAXSYM) 65*0Sstevel@tonic-gate error2(gettext( 66*0Sstevel@tonic-gate "quote marker longer than %d chars"), MAXSYM); 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate if (c <= 1 && !*l) { 69*0Sstevel@tonic-gate l = L"`"; 70*0Sstevel@tonic-gate r = L"'"; 71*0Sstevel@tonic-gate } else if (c == 1) { 72*0Sstevel@tonic-gate r = l; 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate (void) wcscpy(lquote, l); 76*0Sstevel@tonic-gate (void) wcscpy(rquote, r); 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate static void 80*0Sstevel@tonic-gate dodecr(wchar_t **ap, int c) 81*0Sstevel@tonic-gate { 82*0Sstevel@tonic-gate pbnum(ctol(arg(1))-1); 83*0Sstevel@tonic-gate } 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate void 86*0Sstevel@tonic-gate dodef(wchar_t **ap, int c) 87*0Sstevel@tonic-gate { 88*0Sstevel@tonic-gate def(ap, c, NOPUSH); 89*0Sstevel@tonic-gate } 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate static void 92*0Sstevel@tonic-gate def(wchar_t **ap, int c, int mode) 93*0Sstevel@tonic-gate { 94*0Sstevel@tonic-gate wchar_t *s; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate if (c < 1) 97*0Sstevel@tonic-gate return; 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate s = ap[1]; 100*0Sstevel@tonic-gate if (is_alpha(*s) || *s == '_') { 101*0Sstevel@tonic-gate s++; 102*0Sstevel@tonic-gate while (is_alnum(*s) || *s == '_') 103*0Sstevel@tonic-gate s++; 104*0Sstevel@tonic-gate } 105*0Sstevel@tonic-gate if (*s || s == ap[1]) 106*0Sstevel@tonic-gate error(gettext("bad macro name")); 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate if ((ap[2] != NULL) && (wcscmp(ap[1], ap[2]) == 0)) 109*0Sstevel@tonic-gate error(gettext("macro defined as itself")); 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate install(ap[1], arg(2), mode); 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate static void 115*0Sstevel@tonic-gate dodefn(wchar_t **ap, int c) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate wchar_t *d; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate while (c > 0) 120*0Sstevel@tonic-gate if ((d = lookup(ap[c--])->def) != NULL) { 121*0Sstevel@tonic-gate putbak(*rquote); 122*0Sstevel@tonic-gate while (*d) 123*0Sstevel@tonic-gate putbak(*d++); 124*0Sstevel@tonic-gate putbak(*lquote); 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate static void 129*0Sstevel@tonic-gate dodiv(wchar_t **ap, int c) 130*0Sstevel@tonic-gate { 131*0Sstevel@tonic-gate register int f; 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate f = wstoi(arg(1)); 134*0Sstevel@tonic-gate if (f >= 10 || f < 0) { 135*0Sstevel@tonic-gate cf = NULL; 136*0Sstevel@tonic-gate ofx = f; 137*0Sstevel@tonic-gate return; 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate tempfile[7] = 'a'+f; 140*0Sstevel@tonic-gate if (ofile[f] || (ofile[f] = xfopen(tempfile, "w"))) { 141*0Sstevel@tonic-gate ofx = f; 142*0Sstevel@tonic-gate cf = ofile[f]; 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate /* ARGSUSED */ 147*0Sstevel@tonic-gate static void 148*0Sstevel@tonic-gate dodivnum(wchar_t **ap, int c) 149*0Sstevel@tonic-gate { 150*0Sstevel@tonic-gate pbnum((long)ofx); 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate /* ARGSUSED */ 154*0Sstevel@tonic-gate static void 155*0Sstevel@tonic-gate dodnl(wchar_t **ap, int c) 156*0Sstevel@tonic-gate { 157*0Sstevel@tonic-gate wchar_t t; 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate while ((t = getchr()) != '\n' && t != WEOF) 160*0Sstevel@tonic-gate ; 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate static void 164*0Sstevel@tonic-gate dodump(wchar_t **ap, int c) 165*0Sstevel@tonic-gate { 166*0Sstevel@tonic-gate register struct nlist *np; 167*0Sstevel@tonic-gate register i; 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate if (c > 0) 170*0Sstevel@tonic-gate while (c--) { 171*0Sstevel@tonic-gate if ((np = lookup(*++ap))->name != NULL) 172*0Sstevel@tonic-gate dump(np->name, np->def); 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate else 175*0Sstevel@tonic-gate for (i = 0; i < hshsize; i++) 176*0Sstevel@tonic-gate for (np = hshtab[i]; np != NULL; np = np->next) 177*0Sstevel@tonic-gate dump(np->name, np->def); 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate static void 181*0Sstevel@tonic-gate dump(wchar_t *name, wchar_t *defnn) 182*0Sstevel@tonic-gate { 183*0Sstevel@tonic-gate wchar_t *s = defnn; 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate (void) fprintf(stderr, "%ws:\t", name); 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate while (*s++); 188*0Sstevel@tonic-gate --s; 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate while (s > defnn) { 191*0Sstevel@tonic-gate --s; 192*0Sstevel@tonic-gate if (is_builtin(*s)) 193*0Sstevel@tonic-gate (void) fprintf(stderr, "<%ws>", 194*0Sstevel@tonic-gate barray[builtin_idx(*s)].bname); 195*0Sstevel@tonic-gate else { 196*0Sstevel@tonic-gate (void) fputwc(*s, stderr); 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate (void) fputc('\n', stderr); 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate static void 203*0Sstevel@tonic-gate doerrp(wchar_t **ap, int c) 204*0Sstevel@tonic-gate { 205*0Sstevel@tonic-gate if (c > 0) 206*0Sstevel@tonic-gate (void) fprintf(stderr, "%ws", ap[1]); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate long evalval; /* return value from yacc stuff */ 210*0Sstevel@tonic-gate wchar_t *pe; /* used by grammar */ 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate static void 213*0Sstevel@tonic-gate doeval(wchar_t **ap, int c) 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate int base = wstoi(arg(2)); 216*0Sstevel@tonic-gate int pad = wstoi(arg(3)); 217*0Sstevel@tonic-gate extern int yyparse(void); 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate evalval = 0; 220*0Sstevel@tonic-gate if (c > 0) { 221*0Sstevel@tonic-gate pe = ap[1]; 222*0Sstevel@tonic-gate if (yyparse() != 0) 223*0Sstevel@tonic-gate error(gettext( 224*0Sstevel@tonic-gate "invalid expression")); 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate pbnbr(evalval, base > 0 ? base:10, pad > 0 ? pad : 1); 227*0Sstevel@tonic-gate } 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate /* 230*0Sstevel@tonic-gate * doexit 231*0Sstevel@tonic-gate * 232*0Sstevel@tonic-gate * Process m4exit macro. 233*0Sstevel@tonic-gate */ 234*0Sstevel@tonic-gate static void 235*0Sstevel@tonic-gate doexit(wchar_t **ap, int c) 236*0Sstevel@tonic-gate { 237*0Sstevel@tonic-gate delexit(wstoi(arg(1)), 1); 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate static void 241*0Sstevel@tonic-gate doif(wchar_t **ap, int c) 242*0Sstevel@tonic-gate { 243*0Sstevel@tonic-gate if (c < 3) 244*0Sstevel@tonic-gate return; 245*0Sstevel@tonic-gate while (c >= 3) { 246*0Sstevel@tonic-gate if (wcscmp(ap[1], ap[2]) == 0) { 247*0Sstevel@tonic-gate pbstr(ap[3]); 248*0Sstevel@tonic-gate return; 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate c -= 3; 251*0Sstevel@tonic-gate ap += 3; 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate if (c > 0) 254*0Sstevel@tonic-gate pbstr(ap[1]); 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate static void 258*0Sstevel@tonic-gate doifdef(wchar_t **ap, int c) 259*0Sstevel@tonic-gate { 260*0Sstevel@tonic-gate if (c < 2) 261*0Sstevel@tonic-gate return; 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate while (c >= 2) { 264*0Sstevel@tonic-gate if (lookup(ap[1])->name != NULL) { 265*0Sstevel@tonic-gate pbstr(ap[2]); 266*0Sstevel@tonic-gate return; 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate c -= 2; 269*0Sstevel@tonic-gate ap += 2; 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate if (c > 0) 273*0Sstevel@tonic-gate pbstr(ap[1]); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate static void 277*0Sstevel@tonic-gate doincl(wchar_t **ap, int c) 278*0Sstevel@tonic-gate { 279*0Sstevel@tonic-gate incl(ap, c, 1); 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate static void 283*0Sstevel@tonic-gate incl(wchar_t **ap, int c, int noisy) 284*0Sstevel@tonic-gate { 285*0Sstevel@tonic-gate if (c > 0 && wcslen(ap[1]) > 0) { 286*0Sstevel@tonic-gate if (ifx >= 9) 287*0Sstevel@tonic-gate error(gettext( 288*0Sstevel@tonic-gate "input file nesting too deep (9)")); 289*0Sstevel@tonic-gate if ((ifile[++ifx] = fopen(wstr2str(ap[1], 0), "r")) == NULL) { 290*0Sstevel@tonic-gate --ifx; 291*0Sstevel@tonic-gate if (noisy) 292*0Sstevel@tonic-gate error(gettext( 293*0Sstevel@tonic-gate "can't open file")); 294*0Sstevel@tonic-gate } else { 295*0Sstevel@tonic-gate ipstk[ifx] = ipflr = ip; 296*0Sstevel@tonic-gate setfname(wstr2str(ap[1], 0)); 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate static void 302*0Sstevel@tonic-gate doincr(wchar_t **ap, int c) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate pbnum(ctol(arg(1))+1); 305*0Sstevel@tonic-gate } 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate static void 308*0Sstevel@tonic-gate doindex(wchar_t **ap, int c) 309*0Sstevel@tonic-gate { 310*0Sstevel@tonic-gate wchar_t *subj = arg(1); 311*0Sstevel@tonic-gate wchar_t *obj = arg(2); 312*0Sstevel@tonic-gate register i; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate for (i = 0; *subj; ++i) 315*0Sstevel@tonic-gate if (leftmatch(subj++, obj)) { 316*0Sstevel@tonic-gate pbnum((long)i); 317*0Sstevel@tonic-gate return; 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate pbnum((long)-1); 321*0Sstevel@tonic-gate } 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate static int 324*0Sstevel@tonic-gate leftmatch(wchar_t *str, wchar_t *substr) 325*0Sstevel@tonic-gate { 326*0Sstevel@tonic-gate while (*substr) 327*0Sstevel@tonic-gate if (*str++ != *substr++) 328*0Sstevel@tonic-gate return (0); 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate return (1); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate static void 334*0Sstevel@tonic-gate dolen(wchar_t **ap, int c) 335*0Sstevel@tonic-gate { 336*0Sstevel@tonic-gate pbnum((long)wcslen(arg(1))); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate static void 340*0Sstevel@tonic-gate domake(wchar_t **ap, int c) 341*0Sstevel@tonic-gate { 342*0Sstevel@tonic-gate char *path; 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate if (c > 0) { 345*0Sstevel@tonic-gate path = wstr2str(ap[1], 1); 346*0Sstevel@tonic-gate mkpid(path); 347*0Sstevel@tonic-gate pbstr(str2wstr(path, 0)); 348*0Sstevel@tonic-gate free(path); 349*0Sstevel@tonic-gate } 350*0Sstevel@tonic-gate } 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate static void 353*0Sstevel@tonic-gate dopopdef(wchar_t **ap, int c) 354*0Sstevel@tonic-gate { 355*0Sstevel@tonic-gate register i; 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate for (i = 1; i <= c; ++i) 358*0Sstevel@tonic-gate (void) undef(ap[i]); 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate static void 362*0Sstevel@tonic-gate dopushdef(wchar_t **ap, int c) 363*0Sstevel@tonic-gate { 364*0Sstevel@tonic-gate def(ap, c, PUSH); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate static void 368*0Sstevel@tonic-gate doshift(wchar_t **ap, int c) 369*0Sstevel@tonic-gate { 370*0Sstevel@tonic-gate if (c <= 1) 371*0Sstevel@tonic-gate return; 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate for (;;) { 374*0Sstevel@tonic-gate pbstr(rquote); 375*0Sstevel@tonic-gate pbstr(ap[c--]); 376*0Sstevel@tonic-gate pbstr(lquote); 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate if (c <= 1) 379*0Sstevel@tonic-gate break; 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate pbstr(L","); 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate } 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate static void 386*0Sstevel@tonic-gate dosincl(wchar_t **ap, int c) 387*0Sstevel@tonic-gate { 388*0Sstevel@tonic-gate incl(ap, c, 0); 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate static void 392*0Sstevel@tonic-gate dosubstr(wchar_t **ap, int c) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate wchar_t *str; 395*0Sstevel@tonic-gate int inlen, outlen; 396*0Sstevel@tonic-gate int offset, ix; 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate inlen = wcslen(str = arg(1)); 399*0Sstevel@tonic-gate offset = wstoi(arg(2)); 400*0Sstevel@tonic-gate 401*0Sstevel@tonic-gate if (offset < 0 || offset >= inlen) 402*0Sstevel@tonic-gate return; 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate outlen = c >= 3 ? wstoi(ap[3]) : inlen; 405*0Sstevel@tonic-gate ix = min(offset+outlen, inlen); 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate while (ix > offset) 408*0Sstevel@tonic-gate putbak(str[--ix]); 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate static void 412*0Sstevel@tonic-gate dosyscmd(wchar_t **ap, int c) 413*0Sstevel@tonic-gate { 414*0Sstevel@tonic-gate sysrval = 0; 415*0Sstevel@tonic-gate if (c > 0) { 416*0Sstevel@tonic-gate (void) fflush(stdout); 417*0Sstevel@tonic-gate sysrval = system(wstr2str(ap[1], 0)); 418*0Sstevel@tonic-gate } 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate /* ARGSUSED */ 422*0Sstevel@tonic-gate static void 423*0Sstevel@tonic-gate dosysval(wchar_t **ap, int c) 424*0Sstevel@tonic-gate { 425*0Sstevel@tonic-gate pbnum((long)(sysrval < 0 ? sysrval : 426*0Sstevel@tonic-gate (sysrval >> 8) & ((1 << 8) - 1)) | 427*0Sstevel@tonic-gate ((sysrval & ((1 << 8) - 1)) << 8)); 428*0Sstevel@tonic-gate } 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate static void 431*0Sstevel@tonic-gate dotransl(wchar_t **ap, int c) 432*0Sstevel@tonic-gate { 433*0Sstevel@tonic-gate wchar_t *sink, *fr, *sto; 434*0Sstevel@tonic-gate wchar_t *source, *to; 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate if (c < 1) 437*0Sstevel@tonic-gate return; 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate sink = ap[1]; 440*0Sstevel@tonic-gate fr = arg(2); 441*0Sstevel@tonic-gate sto = arg(3); 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate for (source = ap[1]; *source; source++) { 444*0Sstevel@tonic-gate wchar_t *i; 445*0Sstevel@tonic-gate to = sto; 446*0Sstevel@tonic-gate for (i = fr; *i; ++i) { 447*0Sstevel@tonic-gate if (*source == *i) 448*0Sstevel@tonic-gate break; 449*0Sstevel@tonic-gate if (*to) 450*0Sstevel@tonic-gate ++to; 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate if (*i) { 453*0Sstevel@tonic-gate if (*to) 454*0Sstevel@tonic-gate *sink++ = *to; 455*0Sstevel@tonic-gate } else 456*0Sstevel@tonic-gate *sink++ = *source; 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate *sink = EOS; 459*0Sstevel@tonic-gate pbstr(ap[1]); 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate static void 463*0Sstevel@tonic-gate dotroff(wchar_t **ap, int c) 464*0Sstevel@tonic-gate { 465*0Sstevel@tonic-gate register struct nlist *np; 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gate trace = 0; 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate while (c > 0) 470*0Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name) 471*0Sstevel@tonic-gate np->tflag = 0; 472*0Sstevel@tonic-gate } 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate static void 475*0Sstevel@tonic-gate dotron(wchar_t **ap, int c) 476*0Sstevel@tonic-gate { 477*0Sstevel@tonic-gate register struct nlist *np; 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate trace = !*arg(1); 480*0Sstevel@tonic-gate 481*0Sstevel@tonic-gate while (c > 0) 482*0Sstevel@tonic-gate if ((np = lookup(ap[c--]))->name) 483*0Sstevel@tonic-gate np->tflag = 1; 484*0Sstevel@tonic-gate } 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate void 487*0Sstevel@tonic-gate doundef(wchar_t **ap, int c) 488*0Sstevel@tonic-gate { 489*0Sstevel@tonic-gate register i; 490*0Sstevel@tonic-gate 491*0Sstevel@tonic-gate for (i = 1; i <= c; ++i) 492*0Sstevel@tonic-gate while (undef(ap[i])) 493*0Sstevel@tonic-gate ; 494*0Sstevel@tonic-gate } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate int 497*0Sstevel@tonic-gate undef(wchar_t *nam) 498*0Sstevel@tonic-gate { 499*0Sstevel@tonic-gate register struct nlist *np, *tnp; 500*0Sstevel@tonic-gate 501*0Sstevel@tonic-gate if ((np = lookup(nam))->name == NULL) 502*0Sstevel@tonic-gate return (0); 503*0Sstevel@tonic-gate tnp = hshtab[hshval]; /* lookup sets hshval */ 504*0Sstevel@tonic-gate if (tnp == np) /* it's in first place */ 505*0Sstevel@tonic-gate hshtab[hshval] = tnp->next; 506*0Sstevel@tonic-gate else { 507*0Sstevel@tonic-gate while (tnp->next != np) 508*0Sstevel@tonic-gate tnp = tnp->next; 509*0Sstevel@tonic-gate 510*0Sstevel@tonic-gate tnp->next = np->next; 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate free(np->name); 513*0Sstevel@tonic-gate free(np->def); 514*0Sstevel@tonic-gate free(np); 515*0Sstevel@tonic-gate return (1); 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate static void 519*0Sstevel@tonic-gate doundiv(wchar_t **ap, int c) 520*0Sstevel@tonic-gate { 521*0Sstevel@tonic-gate register int i; 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate if (c <= 0) 524*0Sstevel@tonic-gate for (i = 1; i < 10; i++) 525*0Sstevel@tonic-gate undiv(i, OK); 526*0Sstevel@tonic-gate else 527*0Sstevel@tonic-gate while (--c >= 0) 528*0Sstevel@tonic-gate undiv(wstoi(*++ap), OK); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate /* 532*0Sstevel@tonic-gate * dowrap 533*0Sstevel@tonic-gate * 534*0Sstevel@tonic-gate * Process m4wrap macro. 535*0Sstevel@tonic-gate */ 536*0Sstevel@tonic-gate static void 537*0Sstevel@tonic-gate dowrap(wchar_t **ap, int c) 538*0Sstevel@tonic-gate { 539*0Sstevel@tonic-gate wchar_t *a = arg(1); 540*0Sstevel@tonic-gate struct Wrap *wrapentry; /* entry for list of "m4wrap" strings */ 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate wrapentry = xmalloc(sizeof (struct Wrap)); 543*0Sstevel@tonic-gate /* store m4wrap string */ 544*0Sstevel@tonic-gate wrapentry->wrapstr = wstrdup(a); 545*0Sstevel@tonic-gate /* add this entry to the front of the list of Wrap entries */ 546*0Sstevel@tonic-gate wrapentry->nxt = wrapstart; 547*0Sstevel@tonic-gate wrapstart = wrapentry; 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate static void 551*0Sstevel@tonic-gate mkpid(char *as) 552*0Sstevel@tonic-gate { 553*0Sstevel@tonic-gate char *s = as; 554*0Sstevel@tonic-gate char *l; 555*0Sstevel@tonic-gate char *first_X; 556*0Sstevel@tonic-gate unsigned xcnt = 0; 557*0Sstevel@tonic-gate char my_pid[32]; 558*0Sstevel@tonic-gate int pid_len; 559*0Sstevel@tonic-gate int i = 0; 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate /* 562*0Sstevel@tonic-gate * Count number of X. 563*0Sstevel@tonic-gate */ 564*0Sstevel@tonic-gate l = &s[strlen(s)-1]; 565*0Sstevel@tonic-gate while (l != as) { 566*0Sstevel@tonic-gate if (*l == 'X') { 567*0Sstevel@tonic-gate first_X = l; 568*0Sstevel@tonic-gate l--; 569*0Sstevel@tonic-gate xcnt++; 570*0Sstevel@tonic-gate } else if (xcnt == 0) 571*0Sstevel@tonic-gate l--; 572*0Sstevel@tonic-gate else { 573*0Sstevel@tonic-gate break; 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate } 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate /* 578*0Sstevel@tonic-gate * 1) If there is no X in the passed string, 579*0Sstevel@tonic-gate * then it just return the passed string. 580*0Sstevel@tonic-gate * 2) If the length of the continuous right most X's of 581*0Sstevel@tonic-gate * the string is shorter than the length of pid, 582*0Sstevel@tonic-gate * then right most X's will be substitued with 583*0Sstevel@tonic-gate * upper digits of pid. 584*0Sstevel@tonic-gate * 3) If the length of the continuous right most X's of 585*0Sstevel@tonic-gate * the string is equat to the length of pid, 586*0Sstevel@tonic-gate * then X's will be replaced with pid. 587*0Sstevel@tonic-gate * 4) If the lenght of the continuous right most X's of 588*0Sstevel@tonic-gate * the string is longer than the length of pid, 589*0Sstevel@tonic-gate * then X's will have leading 0 followed by 590*0Sstevel@tonic-gate * pid. 591*0Sstevel@tonic-gate */ 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate /* 594*0Sstevel@tonic-gate * If there were no X, don't do anything. 595*0Sstevel@tonic-gate */ 596*0Sstevel@tonic-gate if (xcnt == 0) 597*0Sstevel@tonic-gate return; 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate /* 600*0Sstevel@tonic-gate * Get pid 601*0Sstevel@tonic-gate */ 602*0Sstevel@tonic-gate (void) snprintf(my_pid, sizeof (my_pid), "%d", (int)getpid()); 603*0Sstevel@tonic-gate pid_len = strlen(my_pid); 604*0Sstevel@tonic-gate 605*0Sstevel@tonic-gate if (pid_len > xcnt) 606*0Sstevel@tonic-gate my_pid[xcnt] = 0; 607*0Sstevel@tonic-gate else if (pid_len < xcnt) { 608*0Sstevel@tonic-gate while (xcnt != pid_len) { 609*0Sstevel@tonic-gate *first_X++ = '0'; 610*0Sstevel@tonic-gate xcnt--; 611*0Sstevel@tonic-gate } 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate /* 615*0Sstevel@tonic-gate * Copy pid 616*0Sstevel@tonic-gate */ 617*0Sstevel@tonic-gate while (i != xcnt) 618*0Sstevel@tonic-gate *first_X++ = my_pid[i++]; 619*0Sstevel@tonic-gate } 620*0Sstevel@tonic-gate 621*0Sstevel@tonic-gate struct bs barray[] = { 622*0Sstevel@tonic-gate dochcom, L"changecom", 623*0Sstevel@tonic-gate docq, L"changequote", 624*0Sstevel@tonic-gate dodecr, L"decr", 625*0Sstevel@tonic-gate dodef, L"define", 626*0Sstevel@tonic-gate dodefn, L"defn", 627*0Sstevel@tonic-gate dodiv, L"divert", 628*0Sstevel@tonic-gate dodivnum, L"divnum", 629*0Sstevel@tonic-gate dodnl, L"dnl", 630*0Sstevel@tonic-gate dodump, L"dumpdef", 631*0Sstevel@tonic-gate doerrp, L"errprint", 632*0Sstevel@tonic-gate doeval, L"eval", 633*0Sstevel@tonic-gate doexit, L"m4exit", 634*0Sstevel@tonic-gate doif, L"ifelse", 635*0Sstevel@tonic-gate doifdef, L"ifdef", 636*0Sstevel@tonic-gate doincl, L"include", 637*0Sstevel@tonic-gate doincr, L"incr", 638*0Sstevel@tonic-gate doindex, L"index", 639*0Sstevel@tonic-gate dolen, L"len", 640*0Sstevel@tonic-gate domake, L"maketemp", 641*0Sstevel@tonic-gate dopopdef, L"popdef", 642*0Sstevel@tonic-gate dopushdef, L"pushdef", 643*0Sstevel@tonic-gate doshift, L"shift", 644*0Sstevel@tonic-gate dosincl, L"sinclude", 645*0Sstevel@tonic-gate dosubstr, L"substr", 646*0Sstevel@tonic-gate dosyscmd, L"syscmd", 647*0Sstevel@tonic-gate dosysval, L"sysval", 648*0Sstevel@tonic-gate dotransl, L"translit", 649*0Sstevel@tonic-gate dotroff, L"traceoff", 650*0Sstevel@tonic-gate dotron, L"traceon", 651*0Sstevel@tonic-gate doundef, L"undefine", 652*0Sstevel@tonic-gate doundiv, L"undivert", 653*0Sstevel@tonic-gate dowrap, L"m4wrap", 654*0Sstevel@tonic-gate 0, 0 655*0Sstevel@tonic-gate }; 656