1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <signal.h> 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 36*7c478bd9Sstevel@tonic-gate #include "m4.h" 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #define match(c, s) (c == *s && (!s[1] || inpmatch(s+1))) 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate static char tmp_name[] = "/tmp/m4aXXXXX"; 41*7c478bd9Sstevel@tonic-gate static wchar_t prev_char; 42*7c478bd9Sstevel@tonic-gate static int mb_cur_max; 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static void getflags(int *, char ***, int *); 45*7c478bd9Sstevel@tonic-gate static void initalloc(void); 46*7c478bd9Sstevel@tonic-gate static void expand(wchar_t **, int); 47*7c478bd9Sstevel@tonic-gate static void lnsync(FILE *); 48*7c478bd9Sstevel@tonic-gate static void fpath(FILE *); 49*7c478bd9Sstevel@tonic-gate static void puttok(wchar_t *); 50*7c478bd9Sstevel@tonic-gate static void error3(void); 51*7c478bd9Sstevel@tonic-gate static wchar_t itochr(int); 52*7c478bd9Sstevel@tonic-gate static wchar_t *chkbltin(wchar_t *); 53*7c478bd9Sstevel@tonic-gate static wchar_t *inpmatch(wchar_t *); 54*7c478bd9Sstevel@tonic-gate static void chkspace(char **, int *, char ***); 55*7c478bd9Sstevel@tonic-gate static void catchsig(int); 56*7c478bd9Sstevel@tonic-gate static FILE *m4open(char ***, char *, int *); 57*7c478bd9Sstevel@tonic-gate static void showwrap(void); 58*7c478bd9Sstevel@tonic-gate static void sputchr(wchar_t, FILE *); 59*7c478bd9Sstevel@tonic-gate static void putchr(wchar_t); 60*7c478bd9Sstevel@tonic-gate static void *xcalloc(size_t, size_t); 61*7c478bd9Sstevel@tonic-gate static wint_t myfgetwc(FILE *, int); 62*7c478bd9Sstevel@tonic-gate static wint_t myfputwc(wchar_t, FILE *); 63*7c478bd9Sstevel@tonic-gate static int myfeof(int); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate main(argc, argv) 66*7c478bd9Sstevel@tonic-gate int argc; 67*7c478bd9Sstevel@tonic-gate char **argv; 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate wchar_t t; 70*7c478bd9Sstevel@tonic-gate int i, opt_end = 0; 71*7c478bd9Sstevel@tonic-gate int sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0}; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate for (i = 0; sigs[i]; ++i) { 74*7c478bd9Sstevel@tonic-gate if (signal(sigs[i], SIG_IGN) != SIG_IGN) 75*7c478bd9Sstevel@tonic-gate (void) signal(sigs[i], catchsig); 76*7c478bd9Sstevel@tonic-gate } 77*7c478bd9Sstevel@tonic-gate tempfile = mktemp(tmp_name); 78*7c478bd9Sstevel@tonic-gate (void) close(creat(tempfile, 0)); 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 83*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 84*7c478bd9Sstevel@tonic-gate #endif 85*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate if ((mb_cur_max = MB_CUR_MAX) > 1) 88*7c478bd9Sstevel@tonic-gate wide = 1; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate procnam = argv[0]; 91*7c478bd9Sstevel@tonic-gate getflags(&argc, &argv, &opt_end); 92*7c478bd9Sstevel@tonic-gate initalloc(); 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate setfname("-"); 95*7c478bd9Sstevel@tonic-gate if (argc > 1) { 96*7c478bd9Sstevel@tonic-gate --argc; 97*7c478bd9Sstevel@tonic-gate ++argv; 98*7c478bd9Sstevel@tonic-gate if (strcmp(argv[0], "-")) { 99*7c478bd9Sstevel@tonic-gate ifile[ifx] = m4open(&argv, "r", &argc); 100*7c478bd9Sstevel@tonic-gate setfname(argv[0]); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate for (;;) { 105*7c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 106*7c478bd9Sstevel@tonic-gate token[1] = EOS; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if (t == WEOF) { 109*7c478bd9Sstevel@tonic-gate if (ifx > 0) { 110*7c478bd9Sstevel@tonic-gate (void) fclose(ifile[ifx]); 111*7c478bd9Sstevel@tonic-gate ipflr = ipstk[--ifx]; 112*7c478bd9Sstevel@tonic-gate continue; 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate getflags(&argc, &argv, &opt_end); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if (argc <= 1) 118*7c478bd9Sstevel@tonic-gate /* 119*7c478bd9Sstevel@tonic-gate * If dowrap() has been called, the m4wrap 120*7c478bd9Sstevel@tonic-gate * macro has been processed, and a linked 121*7c478bd9Sstevel@tonic-gate * list of m4wrap strings has been created. 122*7c478bd9Sstevel@tonic-gate * The list starts at wrapstart. 123*7c478bd9Sstevel@tonic-gate */ 124*7c478bd9Sstevel@tonic-gate if (wrapstart) { 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * Now that EOF has been processed, 127*7c478bd9Sstevel@tonic-gate * display the m4wrap strings. 128*7c478bd9Sstevel@tonic-gate */ 129*7c478bd9Sstevel@tonic-gate showwrap(); 130*7c478bd9Sstevel@tonic-gate continue; 131*7c478bd9Sstevel@tonic-gate } else 132*7c478bd9Sstevel@tonic-gate break; 133*7c478bd9Sstevel@tonic-gate --argc; 134*7c478bd9Sstevel@tonic-gate ++argv; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate if (ifile[ifx] != stdin) 137*7c478bd9Sstevel@tonic-gate (void) fclose(ifile[ifx]); 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate if (strcmp(argv[0], "-")) 140*7c478bd9Sstevel@tonic-gate ifile[ifx] = m4open(&argv, "r", &argc); 141*7c478bd9Sstevel@tonic-gate else 142*7c478bd9Sstevel@tonic-gate ifile[ifx] = stdin; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate setfname(argv[0]); 145*7c478bd9Sstevel@tonic-gate continue; 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate if (is_alpha(t) || t == '_') { 149*7c478bd9Sstevel@tonic-gate wchar_t *tp = token+1; 150*7c478bd9Sstevel@tonic-gate int tlim = toksize; 151*7c478bd9Sstevel@tonic-gate struct nlist *macadd; /* temp variable */ 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate while ((*tp = getchr()) != WEOF && 154*7c478bd9Sstevel@tonic-gate (is_alnum(*tp) || *tp == '_')) { 155*7c478bd9Sstevel@tonic-gate tp++; 156*7c478bd9Sstevel@tonic-gate if (--tlim <= 0) 157*7c478bd9Sstevel@tonic-gate error2(gettext( 158*7c478bd9Sstevel@tonic-gate "more than %d chars in word"), 159*7c478bd9Sstevel@tonic-gate toksize); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate putbak(*tp); 162*7c478bd9Sstevel@tonic-gate *tp = EOS; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate macadd = lookup(token); 165*7c478bd9Sstevel@tonic-gate *Ap = (wchar_t *)macadd; 166*7c478bd9Sstevel@tonic-gate if (macadd->def) { 167*7c478bd9Sstevel@tonic-gate if ((wchar_t *)(++Ap) >= astklm) { 168*7c478bd9Sstevel@tonic-gate --Ap; 169*7c478bd9Sstevel@tonic-gate error2(gettext( 170*7c478bd9Sstevel@tonic-gate "more than %d items on argument stack"), 171*7c478bd9Sstevel@tonic-gate stksize); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate if (Cp++ == NULL) 175*7c478bd9Sstevel@tonic-gate Cp = callst; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate Cp->argp = Ap; 178*7c478bd9Sstevel@tonic-gate *Ap++ = op; 179*7c478bd9Sstevel@tonic-gate puttok(token); 180*7c478bd9Sstevel@tonic-gate stkchr(EOS); 181*7c478bd9Sstevel@tonic-gate t = getchr(); 182*7c478bd9Sstevel@tonic-gate putbak(t); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate if (t != '(') 185*7c478bd9Sstevel@tonic-gate pbstr(L"()"); 186*7c478bd9Sstevel@tonic-gate else /* try to fix arg count */ 187*7c478bd9Sstevel@tonic-gate *Ap++ = op; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate Cp->plev = 0; 190*7c478bd9Sstevel@tonic-gate } else { 191*7c478bd9Sstevel@tonic-gate puttok(token); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate } else if (match(t, lquote)) { 194*7c478bd9Sstevel@tonic-gate register qlev = 1; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate for (;;) { 197*7c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 198*7c478bd9Sstevel@tonic-gate token[1] = EOS; 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate if (match(t, rquote)) { 201*7c478bd9Sstevel@tonic-gate if (--qlev > 0) 202*7c478bd9Sstevel@tonic-gate puttok(token); 203*7c478bd9Sstevel@tonic-gate else 204*7c478bd9Sstevel@tonic-gate break; 205*7c478bd9Sstevel@tonic-gate } else if (match(t, lquote)) { 206*7c478bd9Sstevel@tonic-gate ++qlev; 207*7c478bd9Sstevel@tonic-gate puttok(token); 208*7c478bd9Sstevel@tonic-gate } else { 209*7c478bd9Sstevel@tonic-gate if (t == WEOF) 210*7c478bd9Sstevel@tonic-gate error(gettext( 211*7c478bd9Sstevel@tonic-gate "EOF in quote")); 212*7c478bd9Sstevel@tonic-gate putchr(t); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate } else if (match(t, lcom) && 216*7c478bd9Sstevel@tonic-gate ((lcom[0] != L'#' || lcom[1] != L'\0') || 217*7c478bd9Sstevel@tonic-gate prev_char != '$')) { 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * Don't expand commented macro (between lcom and 221*7c478bd9Sstevel@tonic-gate * rcom). 222*7c478bd9Sstevel@tonic-gate * What we know so far is that we have found the 223*7c478bd9Sstevel@tonic-gate * left comment char (lcom). 224*7c478bd9Sstevel@tonic-gate * Make sure we haven't found '#' (lcom) immediately 225*7c478bd9Sstevel@tonic-gate * preceded by '$' because we want to expand "$#". 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate puttok(token); 229*7c478bd9Sstevel@tonic-gate for (;;) { 230*7c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 231*7c478bd9Sstevel@tonic-gate token[1] = EOS; 232*7c478bd9Sstevel@tonic-gate if (match(t, rcom)) { 233*7c478bd9Sstevel@tonic-gate puttok(token); 234*7c478bd9Sstevel@tonic-gate break; 235*7c478bd9Sstevel@tonic-gate } else { 236*7c478bd9Sstevel@tonic-gate if (t == WEOF) 237*7c478bd9Sstevel@tonic-gate error(gettext( 238*7c478bd9Sstevel@tonic-gate "EOF in comment")); 239*7c478bd9Sstevel@tonic-gate putchr(t); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate } else if (Cp == NULL) { 243*7c478bd9Sstevel@tonic-gate putchr(t); 244*7c478bd9Sstevel@tonic-gate } else if (t == '(') { 245*7c478bd9Sstevel@tonic-gate if (Cp->plev) 246*7c478bd9Sstevel@tonic-gate stkchr(t); 247*7c478bd9Sstevel@tonic-gate else { 248*7c478bd9Sstevel@tonic-gate /* skip white before arg */ 249*7c478bd9Sstevel@tonic-gate while ((t = getchr()) != WEOF && is_space(t)) 250*7c478bd9Sstevel@tonic-gate ; 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate putbak(t); 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate ++Cp->plev; 256*7c478bd9Sstevel@tonic-gate } else if (t == ')') { 257*7c478bd9Sstevel@tonic-gate --Cp->plev; 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate if (Cp->plev == 0) { 260*7c478bd9Sstevel@tonic-gate stkchr(EOS); 261*7c478bd9Sstevel@tonic-gate expand(Cp->argp, Ap-Cp->argp-1); 262*7c478bd9Sstevel@tonic-gate op = *Cp->argp; 263*7c478bd9Sstevel@tonic-gate Ap = Cp->argp-1; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if (--Cp < callst) 266*7c478bd9Sstevel@tonic-gate Cp = NULL; 267*7c478bd9Sstevel@tonic-gate } else 268*7c478bd9Sstevel@tonic-gate stkchr(t); 269*7c478bd9Sstevel@tonic-gate } else if (t == ',' && Cp->plev <= 1) { 270*7c478bd9Sstevel@tonic-gate stkchr(EOS); 271*7c478bd9Sstevel@tonic-gate *Ap = op; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate if ((wchar_t *)(++Ap) >= astklm) { 274*7c478bd9Sstevel@tonic-gate --Ap; 275*7c478bd9Sstevel@tonic-gate error2(gettext( 276*7c478bd9Sstevel@tonic-gate "more than %d items on argument stack"), 277*7c478bd9Sstevel@tonic-gate stksize); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate while ((t = getchr()) != WEOF && is_space(t)) 281*7c478bd9Sstevel@tonic-gate ; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate putbak(t); 284*7c478bd9Sstevel@tonic-gate } else { 285*7c478bd9Sstevel@tonic-gate stkchr(t); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate if (Cp != NULL) 290*7c478bd9Sstevel@tonic-gate error(gettext( 291*7c478bd9Sstevel@tonic-gate "EOF in argument list")); 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate delexit(exitstat, 1); 294*7c478bd9Sstevel@tonic-gate return (0); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate static wchar_t * 298*7c478bd9Sstevel@tonic-gate inpmatch(wchar_t *s) 299*7c478bd9Sstevel@tonic-gate { 300*7c478bd9Sstevel@tonic-gate wchar_t *tp = token+1; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate while (*s) { 303*7c478bd9Sstevel@tonic-gate *tp = getchr(); 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if (*tp++ != *s++) { 306*7c478bd9Sstevel@tonic-gate *tp = EOS; 307*7c478bd9Sstevel@tonic-gate pbstr(token+1); 308*7c478bd9Sstevel@tonic-gate return (0); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate *tp = EOS; 313*7c478bd9Sstevel@tonic-gate return (token); 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate static void 317*7c478bd9Sstevel@tonic-gate getflags(int *xargc, char ***xargv, int *option_end) 318*7c478bd9Sstevel@tonic-gate { 319*7c478bd9Sstevel@tonic-gate char *arg; 320*7c478bd9Sstevel@tonic-gate char *t; 321*7c478bd9Sstevel@tonic-gate wchar_t *s[3]; 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate while (*xargc > 1) { 324*7c478bd9Sstevel@tonic-gate arg = (*xargv)[1]; /* point arg to current argument */ 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate /* 327*7c478bd9Sstevel@tonic-gate * This argument is not an option if it equals "-" or if 328*7c478bd9Sstevel@tonic-gate * "--" has already been parsed. 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate if (arg[0] != '-' || arg[1] == EOS || *option_end) 331*7c478bd9Sstevel@tonic-gate break; 332*7c478bd9Sstevel@tonic-gate if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0') { 333*7c478bd9Sstevel@tonic-gate *option_end = 1; 334*7c478bd9Sstevel@tonic-gate } else { 335*7c478bd9Sstevel@tonic-gate switch (arg[1]) { 336*7c478bd9Sstevel@tonic-gate case 'B': 337*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 338*7c478bd9Sstevel@tonic-gate bufsize = atoi(&arg[2]); 339*7c478bd9Sstevel@tonic-gate break; 340*7c478bd9Sstevel@tonic-gate case 'D': 341*7c478bd9Sstevel@tonic-gate initalloc(); 342*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 343*7c478bd9Sstevel@tonic-gate for (t = &arg[2]; *t; t++) { 344*7c478bd9Sstevel@tonic-gate if (*t == '=') { 345*7c478bd9Sstevel@tonic-gate *t++ = EOS; 346*7c478bd9Sstevel@tonic-gate break; 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate s[1] = str2wstr(&arg[2], 1); 350*7c478bd9Sstevel@tonic-gate s[2] = str2wstr(t, 1); 351*7c478bd9Sstevel@tonic-gate dodef(&s[0], 2); 352*7c478bd9Sstevel@tonic-gate free(s[1]); 353*7c478bd9Sstevel@tonic-gate free(s[2]); 354*7c478bd9Sstevel@tonic-gate break; 355*7c478bd9Sstevel@tonic-gate case 'H': 356*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 357*7c478bd9Sstevel@tonic-gate hshsize = atoi(&arg[2]); 358*7c478bd9Sstevel@tonic-gate break; 359*7c478bd9Sstevel@tonic-gate case 'S': 360*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 361*7c478bd9Sstevel@tonic-gate stksize = atoi(&arg[2]); 362*7c478bd9Sstevel@tonic-gate break; 363*7c478bd9Sstevel@tonic-gate case 'T': 364*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 365*7c478bd9Sstevel@tonic-gate toksize = atoi(&arg[2]); 366*7c478bd9Sstevel@tonic-gate break; 367*7c478bd9Sstevel@tonic-gate case 'U': 368*7c478bd9Sstevel@tonic-gate initalloc(); 369*7c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 370*7c478bd9Sstevel@tonic-gate s[1] = str2wstr(&arg[2], 1); 371*7c478bd9Sstevel@tonic-gate doundef(&s[0], 1); 372*7c478bd9Sstevel@tonic-gate free(s[1]); 373*7c478bd9Sstevel@tonic-gate break; 374*7c478bd9Sstevel@tonic-gate case 'e': 375*7c478bd9Sstevel@tonic-gate setbuf(stdout, NULL); 376*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 377*7c478bd9Sstevel@tonic-gate break; 378*7c478bd9Sstevel@tonic-gate case 's': 379*7c478bd9Sstevel@tonic-gate /* turn on line sync */ 380*7c478bd9Sstevel@tonic-gate sflag = 1; 381*7c478bd9Sstevel@tonic-gate break; 382*7c478bd9Sstevel@tonic-gate default: 383*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 384*7c478bd9Sstevel@tonic-gate gettext("%s: bad option: %s\n"), 385*7c478bd9Sstevel@tonic-gate procnam, arg); 386*7c478bd9Sstevel@tonic-gate delexit(NOT_OK, 0); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate } /* end else not "--" */ 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate (*xargv)++; 391*7c478bd9Sstevel@tonic-gate --(*xargc); 392*7c478bd9Sstevel@tonic-gate } /* end while options to process */ 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate /* 396*7c478bd9Sstevel@tonic-gate * Function: chkspace 397*7c478bd9Sstevel@tonic-gate * 398*7c478bd9Sstevel@tonic-gate * If there is a space between the option and its argument, 399*7c478bd9Sstevel@tonic-gate * adjust argptr so that &arg[2] will point to beginning of the option argument. 400*7c478bd9Sstevel@tonic-gate * This will ensure that processing in getflags() will work, because &arg[2] 401*7c478bd9Sstevel@tonic-gate * will point to the beginning of the option argument whether or not we have 402*7c478bd9Sstevel@tonic-gate * a space between the option and its argument. If there is a space between 403*7c478bd9Sstevel@tonic-gate * the option and its argument, also adjust xargv and xargc because we are 404*7c478bd9Sstevel@tonic-gate * processing the next argument. 405*7c478bd9Sstevel@tonic-gate */ 406*7c478bd9Sstevel@tonic-gate static void 407*7c478bd9Sstevel@tonic-gate chkspace(char **argptr, int *xargc, char ***xargv) 408*7c478bd9Sstevel@tonic-gate { 409*7c478bd9Sstevel@tonic-gate if ((*argptr)[2] == EOS) { 410*7c478bd9Sstevel@tonic-gate /* there is a space between the option and its argument */ 411*7c478bd9Sstevel@tonic-gate (*xargv)++; /* look at the next argument */ 412*7c478bd9Sstevel@tonic-gate --(*xargc); 413*7c478bd9Sstevel@tonic-gate /* 414*7c478bd9Sstevel@tonic-gate * Adjust argptr if the option is followed by an 415*7c478bd9Sstevel@tonic-gate * option argument. 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate if (*xargc > 1) { 418*7c478bd9Sstevel@tonic-gate *argptr = (*xargv)[1]; 419*7c478bd9Sstevel@tonic-gate /* point &arg[2] to beginning of option argument */ 420*7c478bd9Sstevel@tonic-gate *argptr -= 2; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate static void 426*7c478bd9Sstevel@tonic-gate initalloc() 427*7c478bd9Sstevel@tonic-gate { 428*7c478bd9Sstevel@tonic-gate static done = 0; 429*7c478bd9Sstevel@tonic-gate register t; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate if (done++) 432*7c478bd9Sstevel@tonic-gate return; 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate hshtab = xcalloc(hshsize, sizeof (struct nlist *)); 435*7c478bd9Sstevel@tonic-gate callst = xcalloc(stksize/3+1, sizeof (struct call)); 436*7c478bd9Sstevel@tonic-gate Ap = argstk = xcalloc(stksize+3, sizeof (wchar_t *)); 437*7c478bd9Sstevel@tonic-gate ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1, sizeof (wchar_t)); 438*7c478bd9Sstevel@tonic-gate op = obuf = xcalloc(bufsize+1, sizeof (wchar_t)); 439*7c478bd9Sstevel@tonic-gate token = xcalloc(toksize+1, sizeof (wchar_t)); 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate astklm = (wchar_t *)(&argstk[stksize]); 442*7c478bd9Sstevel@tonic-gate ibuflm = &ibuf[bufsize]; 443*7c478bd9Sstevel@tonic-gate obuflm = &obuf[bufsize]; 444*7c478bd9Sstevel@tonic-gate toklm = &token[toksize]; 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate for (t = 0; barray[t].bname; ++t) { 447*7c478bd9Sstevel@tonic-gate wchar_t p[2] = {0, EOS}; 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate p[0] = builtin(t); 450*7c478bd9Sstevel@tonic-gate install(barray[t].bname, p, NOPUSH); 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate install(L"unix", nullstr, NOPUSH); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate void 456*7c478bd9Sstevel@tonic-gate install(wchar_t *nam, wchar_t *val, int mode) 457*7c478bd9Sstevel@tonic-gate { 458*7c478bd9Sstevel@tonic-gate register struct nlist *np; 459*7c478bd9Sstevel@tonic-gate wchar_t *cp; 460*7c478bd9Sstevel@tonic-gate int l; 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate if (mode == PUSH) 463*7c478bd9Sstevel@tonic-gate (void) lookup(nam); /* lookup sets hshval */ 464*7c478bd9Sstevel@tonic-gate else 465*7c478bd9Sstevel@tonic-gate while (undef(nam)) /* undef calls lookup */ 466*7c478bd9Sstevel@tonic-gate ; 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate np = xcalloc(1, sizeof (*np)); 469*7c478bd9Sstevel@tonic-gate np->name = wstrdup(nam); 470*7c478bd9Sstevel@tonic-gate np->next = hshtab[hshval]; 471*7c478bd9Sstevel@tonic-gate hshtab[hshval] = np; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate cp = xcalloc((l = wcslen(val))+1, sizeof (*val)); 474*7c478bd9Sstevel@tonic-gate np->def = cp; 475*7c478bd9Sstevel@tonic-gate cp = &cp[l]; 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate while (*val) 478*7c478bd9Sstevel@tonic-gate *--cp = *val++; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate struct nlist * 482*7c478bd9Sstevel@tonic-gate lookup(wchar_t *str) 483*7c478bd9Sstevel@tonic-gate { 484*7c478bd9Sstevel@tonic-gate wchar_t *s1; 485*7c478bd9Sstevel@tonic-gate register struct nlist *np; 486*7c478bd9Sstevel@tonic-gate static struct nlist nodef; 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate s1 = str; 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate for (hshval = 0; *s1; ) 491*7c478bd9Sstevel@tonic-gate hshval += *s1++; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate hshval %= hshsize; 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate for (np = hshtab[hshval]; np != NULL; np = np->next) { 496*7c478bd9Sstevel@tonic-gate if (*str == *np->name && wcscmp(str, np->name) == 0) 497*7c478bd9Sstevel@tonic-gate return (np); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate return (&nodef); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate static void 503*7c478bd9Sstevel@tonic-gate expand(wchar_t **a1, int c) 504*7c478bd9Sstevel@tonic-gate { 505*7c478bd9Sstevel@tonic-gate wchar_t *dp; 506*7c478bd9Sstevel@tonic-gate register struct nlist *sp; 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate sp = (struct nlist *)a1[-1]; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate if (sp->tflag || trace) { 511*7c478bd9Sstevel@tonic-gate int i; 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 514*7c478bd9Sstevel@tonic-gate "Trace(%d): %ws", Cp-callst, a1[0]); 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate if (c > 0) { 517*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "(%ws", chkbltin(a1[1])); 518*7c478bd9Sstevel@tonic-gate for (i = 2; i <= c; ++i) 519*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ",%ws", chkbltin(a1[i])); 520*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ")"); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate dp = sp->def; 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate for (; *dp; ++dp) { 528*7c478bd9Sstevel@tonic-gate if (is_builtin(*dp)) { 529*7c478bd9Sstevel@tonic-gate (*barray[builtin_idx(*dp)].bfunc)(a1, c); 530*7c478bd9Sstevel@tonic-gate } else if (dp[1] == '$') { 531*7c478bd9Sstevel@tonic-gate if (is_digit(*dp)) { 532*7c478bd9Sstevel@tonic-gate register n; 533*7c478bd9Sstevel@tonic-gate if ((n = *dp-'0') <= c) 534*7c478bd9Sstevel@tonic-gate pbstr(a1[n]); 535*7c478bd9Sstevel@tonic-gate ++dp; 536*7c478bd9Sstevel@tonic-gate } else if (*dp == '#') { 537*7c478bd9Sstevel@tonic-gate pbnum((long)c); 538*7c478bd9Sstevel@tonic-gate ++dp; 539*7c478bd9Sstevel@tonic-gate } else if (*dp == '*' || *dp == '@') { 540*7c478bd9Sstevel@tonic-gate register i = c; 541*7c478bd9Sstevel@tonic-gate wchar_t **a = a1; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (i > 0) 544*7c478bd9Sstevel@tonic-gate for (;;) { 545*7c478bd9Sstevel@tonic-gate if (*dp == '@') 546*7c478bd9Sstevel@tonic-gate pbstr(rquote); 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate pbstr(a[i--]); 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate if (*dp == '@') 551*7c478bd9Sstevel@tonic-gate pbstr(lquote); 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate if (i <= 0) 554*7c478bd9Sstevel@tonic-gate break; 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate pbstr(L","); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate ++dp; 559*7c478bd9Sstevel@tonic-gate } else 560*7c478bd9Sstevel@tonic-gate putbak(*dp); 561*7c478bd9Sstevel@tonic-gate } else 562*7c478bd9Sstevel@tonic-gate putbak(*dp); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate void 567*7c478bd9Sstevel@tonic-gate setfname(char *s) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate if (fname[ifx]) 570*7c478bd9Sstevel@tonic-gate free(fname[ifx]); 571*7c478bd9Sstevel@tonic-gate if ((fname[ifx] = strdup(s)) == NULL) 572*7c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 573*7c478bd9Sstevel@tonic-gate fline[ifx] = 1; 574*7c478bd9Sstevel@tonic-gate nflag = 1; 575*7c478bd9Sstevel@tonic-gate lnsync(stdout); 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate static void 579*7c478bd9Sstevel@tonic-gate lnsync(FILE *iop) 580*7c478bd9Sstevel@tonic-gate { 581*7c478bd9Sstevel@tonic-gate static int cline = 0; 582*7c478bd9Sstevel@tonic-gate static int cfile = 0; 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate if (!sflag || iop != stdout) 585*7c478bd9Sstevel@tonic-gate return; 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate if (nflag || ifx != cfile) { 588*7c478bd9Sstevel@tonic-gate nflag = 0; 589*7c478bd9Sstevel@tonic-gate cfile = ifx; 590*7c478bd9Sstevel@tonic-gate (void) fprintf(iop, "#line %d \"", cline = fline[ifx]); 591*7c478bd9Sstevel@tonic-gate fpath(iop); 592*7c478bd9Sstevel@tonic-gate (void) fprintf(iop, "\"\n"); 593*7c478bd9Sstevel@tonic-gate } else if (++cline != fline[ifx]) 594*7c478bd9Sstevel@tonic-gate (void) fprintf(iop, "#line %d\n", cline = fline[ifx]); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate static void 598*7c478bd9Sstevel@tonic-gate fpath(FILE *iop) 599*7c478bd9Sstevel@tonic-gate { 600*7c478bd9Sstevel@tonic-gate register i; 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate if (fname[0] == NULL) 603*7c478bd9Sstevel@tonic-gate return; 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate (void) fprintf(iop, "%s", fname[0]); 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate for (i = 1; i <= ifx; ++i) 608*7c478bd9Sstevel@tonic-gate (void) fprintf(iop, ":%s", fname[i]); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 612*7c478bd9Sstevel@tonic-gate static void 613*7c478bd9Sstevel@tonic-gate catchsig(int i) 614*7c478bd9Sstevel@tonic-gate { 615*7c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN); 616*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 617*7c478bd9Sstevel@tonic-gate delexit(NOT_OK, 0); 618*7c478bd9Sstevel@tonic-gate } 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate void 621*7c478bd9Sstevel@tonic-gate delexit(int code, int flushio) 622*7c478bd9Sstevel@tonic-gate { 623*7c478bd9Sstevel@tonic-gate register i; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate cf = stdout; 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate /* 628*7c478bd9Sstevel@tonic-gate * if (ofx != 0) { 629*7c478bd9Sstevel@tonic-gate * ofx = 0; 630*7c478bd9Sstevel@tonic-gate * code = NOT_OK; 631*7c478bd9Sstevel@tonic-gate * } 632*7c478bd9Sstevel@tonic-gate */ 633*7c478bd9Sstevel@tonic-gate ofx = 0; /* ensure that everything comes out */ 634*7c478bd9Sstevel@tonic-gate for (i = 1; i < 10; i++) 635*7c478bd9Sstevel@tonic-gate undiv(i, code); 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate tempfile[7] = 'a'; 638*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate /* flush standard I/O buffers, ie: call exit() not _exit() */ 641*7c478bd9Sstevel@tonic-gate if (flushio) 642*7c478bd9Sstevel@tonic-gate exit(code); 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate _exit(code); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate static void 648*7c478bd9Sstevel@tonic-gate puttok(wchar_t *tp) 649*7c478bd9Sstevel@tonic-gate { 650*7c478bd9Sstevel@tonic-gate if (Cp) { 651*7c478bd9Sstevel@tonic-gate while (*tp) 652*7c478bd9Sstevel@tonic-gate stkchr(*tp++); 653*7c478bd9Sstevel@tonic-gate } else if (cf) { 654*7c478bd9Sstevel@tonic-gate while (*tp) { 655*7c478bd9Sstevel@tonic-gate sputchr(*tp++, cf); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate void 661*7c478bd9Sstevel@tonic-gate pbstr(wchar_t *str) 662*7c478bd9Sstevel@tonic-gate { 663*7c478bd9Sstevel@tonic-gate wchar_t *p; 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate for (p = str + wcslen(str); --p >= str; ) 666*7c478bd9Sstevel@tonic-gate putbak(*p); 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate void 670*7c478bd9Sstevel@tonic-gate undiv(int i, int code) 671*7c478bd9Sstevel@tonic-gate { 672*7c478bd9Sstevel@tonic-gate register FILE *fp; 673*7c478bd9Sstevel@tonic-gate wint_t c; 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate if (i < 1 || i > 9 || i == ofx || !ofile[i]) 676*7c478bd9Sstevel@tonic-gate return; 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate (void) fclose(ofile[i]); 679*7c478bd9Sstevel@tonic-gate tempfile[7] = 'a'+i; 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate if (code == OK && cf) { 682*7c478bd9Sstevel@tonic-gate fp = xfopen(tempfile, "r"); 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate if (wide) { 685*7c478bd9Sstevel@tonic-gate while ((c = myfgetwc(fp, -1)) != WEOF) 686*7c478bd9Sstevel@tonic-gate sputchr((wchar_t)c, cf); 687*7c478bd9Sstevel@tonic-gate } else { 688*7c478bd9Sstevel@tonic-gate while ((c = (wint_t)getc(fp)) != WEOF) 689*7c478bd9Sstevel@tonic-gate sputchr((wchar_t)c, cf); 690*7c478bd9Sstevel@tonic-gate } 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 696*7c478bd9Sstevel@tonic-gate ofile[i] = NULL; 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate void 700*7c478bd9Sstevel@tonic-gate pbnum(long num) 701*7c478bd9Sstevel@tonic-gate { 702*7c478bd9Sstevel@tonic-gate pbnbr(num, 10, 1); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate void 706*7c478bd9Sstevel@tonic-gate pbnbr(long nbr, int base, int len) 707*7c478bd9Sstevel@tonic-gate { 708*7c478bd9Sstevel@tonic-gate register neg = 0; 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate if (base <= 0) 711*7c478bd9Sstevel@tonic-gate return; 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate if (nbr < 0) 714*7c478bd9Sstevel@tonic-gate neg = 1; 715*7c478bd9Sstevel@tonic-gate else 716*7c478bd9Sstevel@tonic-gate nbr = -nbr; 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate while (nbr < 0) { 719*7c478bd9Sstevel@tonic-gate register int i; 720*7c478bd9Sstevel@tonic-gate if (base > 1) { 721*7c478bd9Sstevel@tonic-gate i = nbr%base; 722*7c478bd9Sstevel@tonic-gate nbr /= base; 723*7c478bd9Sstevel@tonic-gate #if (-3 % 2) != -1 724*7c478bd9Sstevel@tonic-gate while (i > 0) { 725*7c478bd9Sstevel@tonic-gate i -= base; 726*7c478bd9Sstevel@tonic-gate ++nbr; 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate #endif 729*7c478bd9Sstevel@tonic-gate i = -i; 730*7c478bd9Sstevel@tonic-gate } else { 731*7c478bd9Sstevel@tonic-gate i = 1; 732*7c478bd9Sstevel@tonic-gate ++nbr; 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate putbak(itochr(i)); 735*7c478bd9Sstevel@tonic-gate --len; 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate while (--len >= 0) 739*7c478bd9Sstevel@tonic-gate putbak('0'); 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate if (neg) 742*7c478bd9Sstevel@tonic-gate putbak('-'); 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate static wchar_t 746*7c478bd9Sstevel@tonic-gate itochr(int i) 747*7c478bd9Sstevel@tonic-gate { 748*7c478bd9Sstevel@tonic-gate if (i > 9) 749*7c478bd9Sstevel@tonic-gate return ((wchar_t)(i-10+'A')); 750*7c478bd9Sstevel@tonic-gate else 751*7c478bd9Sstevel@tonic-gate return ((wchar_t)(i+'0')); 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate long 755*7c478bd9Sstevel@tonic-gate ctol(wchar_t *str) 756*7c478bd9Sstevel@tonic-gate { 757*7c478bd9Sstevel@tonic-gate register sign; 758*7c478bd9Sstevel@tonic-gate long num; 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate while (is_space(*str)) 761*7c478bd9Sstevel@tonic-gate ++str; 762*7c478bd9Sstevel@tonic-gate num = 0; 763*7c478bd9Sstevel@tonic-gate if (*str == '-') { 764*7c478bd9Sstevel@tonic-gate sign = -1; 765*7c478bd9Sstevel@tonic-gate ++str; 766*7c478bd9Sstevel@tonic-gate } else 767*7c478bd9Sstevel@tonic-gate sign = 1; 768*7c478bd9Sstevel@tonic-gate while (is_digit(*str)) 769*7c478bd9Sstevel@tonic-gate num = num*10 + *str++ - '0'; 770*7c478bd9Sstevel@tonic-gate return (sign * num); 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate int 774*7c478bd9Sstevel@tonic-gate min(int a, int b) 775*7c478bd9Sstevel@tonic-gate { 776*7c478bd9Sstevel@tonic-gate if (a > b) 777*7c478bd9Sstevel@tonic-gate return (b); 778*7c478bd9Sstevel@tonic-gate return (a); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate FILE * 782*7c478bd9Sstevel@tonic-gate xfopen(char *name, char *mode) 783*7c478bd9Sstevel@tonic-gate { 784*7c478bd9Sstevel@tonic-gate FILE *fp; 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate if ((fp = fopen(name, mode)) == NULL) 787*7c478bd9Sstevel@tonic-gate error(gettext("can't open file")); 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate return (fp); 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate /* 793*7c478bd9Sstevel@tonic-gate * m4open 794*7c478bd9Sstevel@tonic-gate * 795*7c478bd9Sstevel@tonic-gate * Continue processing files when unable to open the given file argument. 796*7c478bd9Sstevel@tonic-gate */ 797*7c478bd9Sstevel@tonic-gate FILE * 798*7c478bd9Sstevel@tonic-gate m4open(char ***argvec, char *mode, int *argcnt) 799*7c478bd9Sstevel@tonic-gate { 800*7c478bd9Sstevel@tonic-gate FILE *fp; 801*7c478bd9Sstevel@tonic-gate char *arg; 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate while (*argcnt > 0) { 804*7c478bd9Sstevel@tonic-gate arg = (*argvec)[0]; /* point arg to current file name */ 805*7c478bd9Sstevel@tonic-gate if (arg[0] == '-' && arg[1] == EOS) 806*7c478bd9Sstevel@tonic-gate return (stdin); 807*7c478bd9Sstevel@tonic-gate else { 808*7c478bd9Sstevel@tonic-gate if ((fp = fopen(arg, mode)) == NULL) { 809*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 810*7c478bd9Sstevel@tonic-gate "m4: cannot open %s: "), arg); 811*7c478bd9Sstevel@tonic-gate perror(""); 812*7c478bd9Sstevel@tonic-gate if (*argcnt == 1) { 813*7c478bd9Sstevel@tonic-gate /* last arg therefore exit */ 814*7c478bd9Sstevel@tonic-gate error3(); 815*7c478bd9Sstevel@tonic-gate } else { 816*7c478bd9Sstevel@tonic-gate exitstat = 1; 817*7c478bd9Sstevel@tonic-gate (*argvec)++; /* try next arg */ 818*7c478bd9Sstevel@tonic-gate (*argcnt)--; 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } else 821*7c478bd9Sstevel@tonic-gate break; 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate return (fp); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate void * 828*7c478bd9Sstevel@tonic-gate xmalloc(size_t size) 829*7c478bd9Sstevel@tonic-gate { 830*7c478bd9Sstevel@tonic-gate void *ptr; 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate if ((ptr = malloc(size)) == NULL) 833*7c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 834*7c478bd9Sstevel@tonic-gate return (ptr); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate static void * 838*7c478bd9Sstevel@tonic-gate xcalloc(size_t nbr, size_t size) 839*7c478bd9Sstevel@tonic-gate { 840*7c478bd9Sstevel@tonic-gate register void *ptr; 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate ptr = xmalloc(nbr * size); 843*7c478bd9Sstevel@tonic-gate (void) memset(ptr, '\0', nbr * size); 844*7c478bd9Sstevel@tonic-gate return (ptr); 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate void 848*7c478bd9Sstevel@tonic-gate error2(char *str, int num) 849*7c478bd9Sstevel@tonic-gate { 850*7c478bd9Sstevel@tonic-gate char buf[500]; 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), str, num); 853*7c478bd9Sstevel@tonic-gate error(buf); 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate void 857*7c478bd9Sstevel@tonic-gate error(char *str) 858*7c478bd9Sstevel@tonic-gate { 859*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n%s:", procnam); 860*7c478bd9Sstevel@tonic-gate fpath(stderr); 861*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ":%d %s\n", fline[ifx], str); 862*7c478bd9Sstevel@tonic-gate error3(); 863*7c478bd9Sstevel@tonic-gate } 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate static void 866*7c478bd9Sstevel@tonic-gate error3() 867*7c478bd9Sstevel@tonic-gate { 868*7c478bd9Sstevel@tonic-gate if (Cp) { 869*7c478bd9Sstevel@tonic-gate register struct call *mptr; 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate /* fix limit */ 872*7c478bd9Sstevel@tonic-gate *op = EOS; 873*7c478bd9Sstevel@tonic-gate (Cp+1)->argp = Ap+1; 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate for (mptr = callst; mptr <= Cp; ++mptr) { 876*7c478bd9Sstevel@tonic-gate wchar_t **aptr, **lim; 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate aptr = mptr->argp; 879*7c478bd9Sstevel@tonic-gate lim = (mptr+1)->argp-1; 880*7c478bd9Sstevel@tonic-gate if (mptr == callst) 881*7c478bd9Sstevel@tonic-gate (void) fputws(*aptr, stderr); 882*7c478bd9Sstevel@tonic-gate ++aptr; 883*7c478bd9Sstevel@tonic-gate (void) fputs("(", stderr); 884*7c478bd9Sstevel@tonic-gate if (aptr < lim) 885*7c478bd9Sstevel@tonic-gate for (;;) { 886*7c478bd9Sstevel@tonic-gate (void) fputws(*aptr++, stderr); 887*7c478bd9Sstevel@tonic-gate if (aptr >= lim) 888*7c478bd9Sstevel@tonic-gate break; 889*7c478bd9Sstevel@tonic-gate (void) fputs(",", stderr); 890*7c478bd9Sstevel@tonic-gate } 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate while (--mptr >= callst) 893*7c478bd9Sstevel@tonic-gate (void) fputs(")", stderr); 894*7c478bd9Sstevel@tonic-gate 895*7c478bd9Sstevel@tonic-gate (void) fputs("\n", stderr); 896*7c478bd9Sstevel@tonic-gate } 897*7c478bd9Sstevel@tonic-gate delexit(NOT_OK, 1); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate static wchar_t * 901*7c478bd9Sstevel@tonic-gate chkbltin(wchar_t *s) 902*7c478bd9Sstevel@tonic-gate { 903*7c478bd9Sstevel@tonic-gate static wchar_t buf[24]; 904*7c478bd9Sstevel@tonic-gate 905*7c478bd9Sstevel@tonic-gate if (is_builtin(*s)) { 906*7c478bd9Sstevel@tonic-gate (void) swprintf(buf, sizeof (buf)/sizeof (wchar_t), L"<%ls>", 907*7c478bd9Sstevel@tonic-gate barray[builtin_idx(*s)].bname); 908*7c478bd9Sstevel@tonic-gate return (buf); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate return (s); 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate wchar_t 914*7c478bd9Sstevel@tonic-gate getchr() 915*7c478bd9Sstevel@tonic-gate { 916*7c478bd9Sstevel@tonic-gate static wchar_t C; 917*7c478bd9Sstevel@tonic-gate 918*7c478bd9Sstevel@tonic-gate prev_char = C; 919*7c478bd9Sstevel@tonic-gate if (ip > ipflr) 920*7c478bd9Sstevel@tonic-gate return (*--ip); 921*7c478bd9Sstevel@tonic-gate if (wide) { 922*7c478bd9Sstevel@tonic-gate C = (wchar_t)(myfeof(ifx) ? WEOF : myfgetwc(NULL, ifx)); 923*7c478bd9Sstevel@tonic-gate } else { 924*7c478bd9Sstevel@tonic-gate C = (wchar_t)(feof(ifile[ifx]) ? 925*7c478bd9Sstevel@tonic-gate WEOF : (wint_t)getc(ifile[ifx])); 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate if (C == '\n') 928*7c478bd9Sstevel@tonic-gate fline[ifx]++; 929*7c478bd9Sstevel@tonic-gate return (C); 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate /* 933*7c478bd9Sstevel@tonic-gate * showwrap 934*7c478bd9Sstevel@tonic-gate * 935*7c478bd9Sstevel@tonic-gate * Loop through the list of m4wrap strings. Call pbstr() so that the 936*7c478bd9Sstevel@tonic-gate * string will be displayed, then delete the list entry and free the memory 937*7c478bd9Sstevel@tonic-gate * allocated for it. 938*7c478bd9Sstevel@tonic-gate */ 939*7c478bd9Sstevel@tonic-gate static void 940*7c478bd9Sstevel@tonic-gate showwrap() 941*7c478bd9Sstevel@tonic-gate { 942*7c478bd9Sstevel@tonic-gate struct Wrap *prev; 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate while (wrapstart) { 945*7c478bd9Sstevel@tonic-gate pbstr(wrapstart->wrapstr); 946*7c478bd9Sstevel@tonic-gate free(wrapstart->wrapstr); 947*7c478bd9Sstevel@tonic-gate prev = wrapstart; 948*7c478bd9Sstevel@tonic-gate wrapstart = wrapstart->nxt; 949*7c478bd9Sstevel@tonic-gate free(prev); 950*7c478bd9Sstevel@tonic-gate } 951*7c478bd9Sstevel@tonic-gate } 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate static void 954*7c478bd9Sstevel@tonic-gate sputchr(wchar_t c, FILE *f) 955*7c478bd9Sstevel@tonic-gate { 956*7c478bd9Sstevel@tonic-gate wint_t ret; 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate if (is_builtin(c)) 959*7c478bd9Sstevel@tonic-gate return; 960*7c478bd9Sstevel@tonic-gate if (wide) 961*7c478bd9Sstevel@tonic-gate ret = myfputwc(c, f); 962*7c478bd9Sstevel@tonic-gate else 963*7c478bd9Sstevel@tonic-gate ret = (wint_t)putc((int)c, f); 964*7c478bd9Sstevel@tonic-gate if (ret == WEOF) 965*7c478bd9Sstevel@tonic-gate error(gettext("output error")); 966*7c478bd9Sstevel@tonic-gate if (ret == '\n') 967*7c478bd9Sstevel@tonic-gate lnsync(f); 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate static void 971*7c478bd9Sstevel@tonic-gate putchr(wchar_t c) 972*7c478bd9Sstevel@tonic-gate { 973*7c478bd9Sstevel@tonic-gate wint_t ret; 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate if (Cp) 976*7c478bd9Sstevel@tonic-gate stkchr(c); 977*7c478bd9Sstevel@tonic-gate else if (cf) { 978*7c478bd9Sstevel@tonic-gate if (sflag) 979*7c478bd9Sstevel@tonic-gate sputchr(c, cf); 980*7c478bd9Sstevel@tonic-gate else { 981*7c478bd9Sstevel@tonic-gate if (is_builtin(c)) 982*7c478bd9Sstevel@tonic-gate return; 983*7c478bd9Sstevel@tonic-gate if (wide) 984*7c478bd9Sstevel@tonic-gate ret = myfputwc(c, cf); 985*7c478bd9Sstevel@tonic-gate else 986*7c478bd9Sstevel@tonic-gate ret = (wint_t)putc((int)c, cf); 987*7c478bd9Sstevel@tonic-gate if (ret == WEOF) { 988*7c478bd9Sstevel@tonic-gate error(gettext("output error")); 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate } 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate } 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate wchar_t * 995*7c478bd9Sstevel@tonic-gate wstrdup(wchar_t *p) 996*7c478bd9Sstevel@tonic-gate { 997*7c478bd9Sstevel@tonic-gate size_t len = wcslen(p); 998*7c478bd9Sstevel@tonic-gate wchar_t *ret; 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate ret = xmalloc((len + 1) * sizeof (wchar_t)); 1001*7c478bd9Sstevel@tonic-gate (void) wcscpy(ret, p); 1002*7c478bd9Sstevel@tonic-gate return (ret); 1003*7c478bd9Sstevel@tonic-gate } 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate int 1006*7c478bd9Sstevel@tonic-gate wstoi(wchar_t *p) 1007*7c478bd9Sstevel@tonic-gate { 1008*7c478bd9Sstevel@tonic-gate return ((int)wcstol(p, NULL, 10)); 1009*7c478bd9Sstevel@tonic-gate } 1010*7c478bd9Sstevel@tonic-gate 1011*7c478bd9Sstevel@tonic-gate char * 1012*7c478bd9Sstevel@tonic-gate wstr2str(wchar_t *from, int alloc) 1013*7c478bd9Sstevel@tonic-gate { 1014*7c478bd9Sstevel@tonic-gate static char *retbuf; 1015*7c478bd9Sstevel@tonic-gate static size_t bsiz; 1016*7c478bd9Sstevel@tonic-gate char *p, *ret; 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate if (alloc) { 1019*7c478bd9Sstevel@tonic-gate ret = p = xmalloc(wcslen(from) * mb_cur_max + 1); 1020*7c478bd9Sstevel@tonic-gate } else { 1021*7c478bd9Sstevel@tonic-gate while (bsiz < (wcslen(from) * mb_cur_max + 1)) { 1022*7c478bd9Sstevel@tonic-gate if ((p = realloc(retbuf, bsiz + 256)) == NULL) 1023*7c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 1024*7c478bd9Sstevel@tonic-gate bsiz += 256; 1025*7c478bd9Sstevel@tonic-gate retbuf = p; 1026*7c478bd9Sstevel@tonic-gate } 1027*7c478bd9Sstevel@tonic-gate ret = p = retbuf; 1028*7c478bd9Sstevel@tonic-gate } 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate if (wide) { 1031*7c478bd9Sstevel@tonic-gate while (*from) { 1032*7c478bd9Sstevel@tonic-gate int len; 1033*7c478bd9Sstevel@tonic-gate 1034*7c478bd9Sstevel@tonic-gate if (*from & INVALID_CHAR) { 1035*7c478bd9Sstevel@tonic-gate *p = (char)(*from & ~INVALID_CHAR); 1036*7c478bd9Sstevel@tonic-gate len = 1; 1037*7c478bd9Sstevel@tonic-gate } else { 1038*7c478bd9Sstevel@tonic-gate if ((len = wctomb(p, *from)) == -1) { 1039*7c478bd9Sstevel@tonic-gate *p = (char)*from; 1040*7c478bd9Sstevel@tonic-gate len = 1; 1041*7c478bd9Sstevel@tonic-gate } 1042*7c478bd9Sstevel@tonic-gate } 1043*7c478bd9Sstevel@tonic-gate p += len; 1044*7c478bd9Sstevel@tonic-gate from++; 1045*7c478bd9Sstevel@tonic-gate } 1046*7c478bd9Sstevel@tonic-gate } else { 1047*7c478bd9Sstevel@tonic-gate while (*from) 1048*7c478bd9Sstevel@tonic-gate *p++ = (char)*from++; 1049*7c478bd9Sstevel@tonic-gate } 1050*7c478bd9Sstevel@tonic-gate *p = '\0'; 1051*7c478bd9Sstevel@tonic-gate 1052*7c478bd9Sstevel@tonic-gate return (ret); 1053*7c478bd9Sstevel@tonic-gate } 1054*7c478bd9Sstevel@tonic-gate 1055*7c478bd9Sstevel@tonic-gate wchar_t * 1056*7c478bd9Sstevel@tonic-gate str2wstr(char *from, int alloc) 1057*7c478bd9Sstevel@tonic-gate { 1058*7c478bd9Sstevel@tonic-gate static wchar_t *retbuf; 1059*7c478bd9Sstevel@tonic-gate static size_t bsiz; 1060*7c478bd9Sstevel@tonic-gate wchar_t *p, *ret; 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate if (alloc) { 1063*7c478bd9Sstevel@tonic-gate ret = p = xmalloc((strlen(from) + 1) * sizeof (wchar_t)); 1064*7c478bd9Sstevel@tonic-gate } else { 1065*7c478bd9Sstevel@tonic-gate while (bsiz < (strlen(from) + 1)) { 1066*7c478bd9Sstevel@tonic-gate if ((p = realloc(retbuf, 1067*7c478bd9Sstevel@tonic-gate (bsiz + 256) * sizeof (wchar_t))) == NULL) { 1068*7c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 1069*7c478bd9Sstevel@tonic-gate } 1070*7c478bd9Sstevel@tonic-gate bsiz += 256; 1071*7c478bd9Sstevel@tonic-gate retbuf = p; 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate ret = p = retbuf; 1074*7c478bd9Sstevel@tonic-gate } 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate if (wide) { 1077*7c478bd9Sstevel@tonic-gate while (*from) { 1078*7c478bd9Sstevel@tonic-gate int len; 1079*7c478bd9Sstevel@tonic-gate wchar_t wc; 1080*7c478bd9Sstevel@tonic-gate 1081*7c478bd9Sstevel@tonic-gate if ((len = mbtowc(&wc, from, mb_cur_max)) <= 0) { 1082*7c478bd9Sstevel@tonic-gate wc = *from | INVALID_CHAR; 1083*7c478bd9Sstevel@tonic-gate len = 1; 1084*7c478bd9Sstevel@tonic-gate } 1085*7c478bd9Sstevel@tonic-gate *p++ = wc; 1086*7c478bd9Sstevel@tonic-gate from += len; 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate } else { 1089*7c478bd9Sstevel@tonic-gate while (*from) 1090*7c478bd9Sstevel@tonic-gate *p++ = (unsigned char) *from++; 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate *p = 0; 1093*7c478bd9Sstevel@tonic-gate 1094*7c478bd9Sstevel@tonic-gate return (ret); 1095*7c478bd9Sstevel@tonic-gate } 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate static wint_t 1098*7c478bd9Sstevel@tonic-gate myfgetwc(FILE *fp, int idx) 1099*7c478bd9Sstevel@tonic-gate { 1100*7c478bd9Sstevel@tonic-gate int i, c, len, nb; 1101*7c478bd9Sstevel@tonic-gate wchar_t wc; 1102*7c478bd9Sstevel@tonic-gate unsigned char *buf; 1103*7c478bd9Sstevel@tonic-gate 1104*7c478bd9Sstevel@tonic-gate if (fp == NULL) 1105*7c478bd9Sstevel@tonic-gate fp = ifile[idx]; 1106*7c478bd9Sstevel@tonic-gate else 1107*7c478bd9Sstevel@tonic-gate idx = 10; /* extra slot */ 1108*7c478bd9Sstevel@tonic-gate buf = ibuffer[idx].buffer; 1109*7c478bd9Sstevel@tonic-gate nb = ibuffer[idx].nbytes; 1110*7c478bd9Sstevel@tonic-gate len = 0; 1111*7c478bd9Sstevel@tonic-gate for (i = 1; i <= mb_cur_max; i++) { 1112*7c478bd9Sstevel@tonic-gate if (nb < i) { 1113*7c478bd9Sstevel@tonic-gate c = getc(fp); 1114*7c478bd9Sstevel@tonic-gate if (c == EOF) { 1115*7c478bd9Sstevel@tonic-gate if (nb == 0) 1116*7c478bd9Sstevel@tonic-gate return (WEOF); 1117*7c478bd9Sstevel@tonic-gate else 1118*7c478bd9Sstevel@tonic-gate break; 1119*7c478bd9Sstevel@tonic-gate } 1120*7c478bd9Sstevel@tonic-gate buf[nb++] = (unsigned char)c; 1121*7c478bd9Sstevel@tonic-gate } 1122*7c478bd9Sstevel@tonic-gate if ((len = mbtowc(&wc, (char *)buf, i)) >= 0) 1123*7c478bd9Sstevel@tonic-gate break; 1124*7c478bd9Sstevel@tonic-gate } 1125*7c478bd9Sstevel@tonic-gate if (len <= 0) { 1126*7c478bd9Sstevel@tonic-gate wc = buf[0] | INVALID_CHAR; 1127*7c478bd9Sstevel@tonic-gate len = 1; 1128*7c478bd9Sstevel@tonic-gate } 1129*7c478bd9Sstevel@tonic-gate nb -= len; 1130*7c478bd9Sstevel@tonic-gate if (nb > 0) { 1131*7c478bd9Sstevel@tonic-gate for (i = 0; i < nb; i++) 1132*7c478bd9Sstevel@tonic-gate buf[i] = buf[i + len]; 1133*7c478bd9Sstevel@tonic-gate } 1134*7c478bd9Sstevel@tonic-gate ibuffer[idx].nbytes = nb; 1135*7c478bd9Sstevel@tonic-gate return (wc); 1136*7c478bd9Sstevel@tonic-gate } 1137*7c478bd9Sstevel@tonic-gate 1138*7c478bd9Sstevel@tonic-gate static wint_t 1139*7c478bd9Sstevel@tonic-gate myfputwc(wchar_t wc, FILE *fp) 1140*7c478bd9Sstevel@tonic-gate { 1141*7c478bd9Sstevel@tonic-gate if (wc & INVALID_CHAR) { 1142*7c478bd9Sstevel@tonic-gate wc &= ~INVALID_CHAR; 1143*7c478bd9Sstevel@tonic-gate return (fputc((int)wc, fp)); 1144*7c478bd9Sstevel@tonic-gate } 1145*7c478bd9Sstevel@tonic-gate return (fputwc(wc, fp)); 1146*7c478bd9Sstevel@tonic-gate } 1147*7c478bd9Sstevel@tonic-gate 1148*7c478bd9Sstevel@tonic-gate static int 1149*7c478bd9Sstevel@tonic-gate myfeof(int idx) 1150*7c478bd9Sstevel@tonic-gate { 1151*7c478bd9Sstevel@tonic-gate return (ibuffer[idx].nbytes == 0 && feof(ifile[idx])); 1152*7c478bd9Sstevel@tonic-gate } 1153