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 /* 234c56998aSRich Burridge * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 26*447603b5SGary Mills /* 27*447603b5SGary Mills * Copyright (c) 2011 Gary Mills 28*447603b5SGary Mills */ 29*447603b5SGary Mills 309fb11590Smike_s /* Copyright (c) 1988 AT&T */ 319fb11590Smike_s /* All Rights Reserved */ 329fb11590Smike_s 337c478bd9Sstevel@tonic-gate #include <signal.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <fcntl.h> 367c478bd9Sstevel@tonic-gate #include "m4.h" 377c478bd9Sstevel@tonic-gate 381dd08564Sab196087 #if defined(__lint) 391dd08564Sab196087 extern int yydebug; 401dd08564Sab196087 #endif 411dd08564Sab196087 427c478bd9Sstevel@tonic-gate #define match(c, s) (c == *s && (!s[1] || inpmatch(s+1))) 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate static char tmp_name[] = "/tmp/m4aXXXXX"; 457c478bd9Sstevel@tonic-gate static wchar_t prev_char; 467c478bd9Sstevel@tonic-gate static int mb_cur_max; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate static void getflags(int *, char ***, int *); 497c478bd9Sstevel@tonic-gate static void initalloc(void); 507c478bd9Sstevel@tonic-gate static void expand(wchar_t **, int); 517c478bd9Sstevel@tonic-gate static void lnsync(FILE *); 527c478bd9Sstevel@tonic-gate static void fpath(FILE *); 537c478bd9Sstevel@tonic-gate static void puttok(wchar_t *); 547c478bd9Sstevel@tonic-gate static void error3(void); 557c478bd9Sstevel@tonic-gate static wchar_t itochr(int); 561dd08564Sab196087 /*LINTED: E_STATIC_UNUSED*/ 577c478bd9Sstevel@tonic-gate static wchar_t *chkbltin(wchar_t *); 587c478bd9Sstevel@tonic-gate static wchar_t *inpmatch(wchar_t *); 597c478bd9Sstevel@tonic-gate static void chkspace(char **, int *, char ***); 607c478bd9Sstevel@tonic-gate static void catchsig(int); 617c478bd9Sstevel@tonic-gate static FILE *m4open(char ***, char *, int *); 627c478bd9Sstevel@tonic-gate static void showwrap(void); 637c478bd9Sstevel@tonic-gate static void sputchr(wchar_t, FILE *); 647c478bd9Sstevel@tonic-gate static void putchr(wchar_t); 657c478bd9Sstevel@tonic-gate static void *xcalloc(size_t, size_t); 667c478bd9Sstevel@tonic-gate static wint_t myfgetwc(FILE *, int); 677c478bd9Sstevel@tonic-gate static wint_t myfputwc(wchar_t, FILE *); 687c478bd9Sstevel@tonic-gate static int myfeof(int); 697c478bd9Sstevel@tonic-gate 709fb11590Smike_s int 719fb11590Smike_s main(int argc, char **argv) 727c478bd9Sstevel@tonic-gate { 737c478bd9Sstevel@tonic-gate wchar_t t; 747c478bd9Sstevel@tonic-gate int i, opt_end = 0; 757c478bd9Sstevel@tonic-gate int sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0}; 767c478bd9Sstevel@tonic-gate 771dd08564Sab196087 #if defined(__lint) 781dd08564Sab196087 yydebug = 0; 791dd08564Sab196087 #endif 801dd08564Sab196087 817c478bd9Sstevel@tonic-gate for (i = 0; sigs[i]; ++i) { 827c478bd9Sstevel@tonic-gate if (signal(sigs[i], SIG_IGN) != SIG_IGN) 837c478bd9Sstevel@tonic-gate (void) signal(sigs[i], catchsig); 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate tempfile = mktemp(tmp_name); 867c478bd9Sstevel@tonic-gate (void) close(creat(tempfile, 0)); 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 917c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 927c478bd9Sstevel@tonic-gate #endif 937c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if ((mb_cur_max = MB_CUR_MAX) > 1) 967c478bd9Sstevel@tonic-gate wide = 1; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate procnam = argv[0]; 997c478bd9Sstevel@tonic-gate getflags(&argc, &argv, &opt_end); 1007c478bd9Sstevel@tonic-gate initalloc(); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate setfname("-"); 1037c478bd9Sstevel@tonic-gate if (argc > 1) { 1047c478bd9Sstevel@tonic-gate --argc; 1057c478bd9Sstevel@tonic-gate ++argv; 1067c478bd9Sstevel@tonic-gate if (strcmp(argv[0], "-")) { 1077c478bd9Sstevel@tonic-gate ifile[ifx] = m4open(&argv, "r", &argc); 1087c478bd9Sstevel@tonic-gate setfname(argv[0]); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate for (;;) { 1137c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 1147c478bd9Sstevel@tonic-gate token[1] = EOS; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if (t == WEOF) { 1177c478bd9Sstevel@tonic-gate if (ifx > 0) { 1187c478bd9Sstevel@tonic-gate (void) fclose(ifile[ifx]); 1197c478bd9Sstevel@tonic-gate ipflr = ipstk[--ifx]; 1207c478bd9Sstevel@tonic-gate continue; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate getflags(&argc, &argv, &opt_end); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate if (argc <= 1) 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * If dowrap() has been called, the m4wrap 1287c478bd9Sstevel@tonic-gate * macro has been processed, and a linked 1297c478bd9Sstevel@tonic-gate * list of m4wrap strings has been created. 1307c478bd9Sstevel@tonic-gate * The list starts at wrapstart. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate if (wrapstart) { 1337c478bd9Sstevel@tonic-gate /* 1347c478bd9Sstevel@tonic-gate * Now that EOF has been processed, 1357c478bd9Sstevel@tonic-gate * display the m4wrap strings. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate showwrap(); 1387c478bd9Sstevel@tonic-gate continue; 1397c478bd9Sstevel@tonic-gate } else 1407c478bd9Sstevel@tonic-gate break; 1417c478bd9Sstevel@tonic-gate --argc; 1427c478bd9Sstevel@tonic-gate ++argv; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if (ifile[ifx] != stdin) 1457c478bd9Sstevel@tonic-gate (void) fclose(ifile[ifx]); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (strcmp(argv[0], "-")) 1487c478bd9Sstevel@tonic-gate ifile[ifx] = m4open(&argv, "r", &argc); 1497c478bd9Sstevel@tonic-gate else 1507c478bd9Sstevel@tonic-gate ifile[ifx] = stdin; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate setfname(argv[0]); 1537c478bd9Sstevel@tonic-gate continue; 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if (is_alpha(t) || t == '_') { 1577c478bd9Sstevel@tonic-gate wchar_t *tp = token+1; 1587c478bd9Sstevel@tonic-gate int tlim = toksize; 1597c478bd9Sstevel@tonic-gate struct nlist *macadd; /* temp variable */ 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate while ((*tp = getchr()) != WEOF && 1627c478bd9Sstevel@tonic-gate (is_alnum(*tp) || *tp == '_')) { 1637c478bd9Sstevel@tonic-gate tp++; 1647c478bd9Sstevel@tonic-gate if (--tlim <= 0) 1657c478bd9Sstevel@tonic-gate error2(gettext( 1667c478bd9Sstevel@tonic-gate "more than %d chars in word"), 1677c478bd9Sstevel@tonic-gate toksize); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate putbak(*tp); 1707c478bd9Sstevel@tonic-gate *tp = EOS; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate macadd = lookup(token); 1737c478bd9Sstevel@tonic-gate *Ap = (wchar_t *)macadd; 1747c478bd9Sstevel@tonic-gate if (macadd->def) { 1757c478bd9Sstevel@tonic-gate if ((wchar_t *)(++Ap) >= astklm) { 1767c478bd9Sstevel@tonic-gate --Ap; 1777c478bd9Sstevel@tonic-gate error2(gettext( 1781dd08564Sab196087 "more than %d items on " 1791dd08564Sab196087 "argument stack"), 1807c478bd9Sstevel@tonic-gate stksize); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate if (Cp++ == NULL) 1847c478bd9Sstevel@tonic-gate Cp = callst; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate Cp->argp = Ap; 1877c478bd9Sstevel@tonic-gate *Ap++ = op; 1887c478bd9Sstevel@tonic-gate puttok(token); 1897c478bd9Sstevel@tonic-gate stkchr(EOS); 1907c478bd9Sstevel@tonic-gate t = getchr(); 1917c478bd9Sstevel@tonic-gate putbak(t); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate if (t != '(') 1947c478bd9Sstevel@tonic-gate pbstr(L"()"); 1957c478bd9Sstevel@tonic-gate else /* try to fix arg count */ 1967c478bd9Sstevel@tonic-gate *Ap++ = op; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate Cp->plev = 0; 1997c478bd9Sstevel@tonic-gate } else { 2007c478bd9Sstevel@tonic-gate puttok(token); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate } else if (match(t, lquote)) { 2039fb11590Smike_s int qlev = 1; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate for (;;) { 2067c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 2077c478bd9Sstevel@tonic-gate token[1] = EOS; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (match(t, rquote)) { 2107c478bd9Sstevel@tonic-gate if (--qlev > 0) 2117c478bd9Sstevel@tonic-gate puttok(token); 2127c478bd9Sstevel@tonic-gate else 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate } else if (match(t, lquote)) { 2157c478bd9Sstevel@tonic-gate ++qlev; 2167c478bd9Sstevel@tonic-gate puttok(token); 2177c478bd9Sstevel@tonic-gate } else { 2187c478bd9Sstevel@tonic-gate if (t == WEOF) 2197c478bd9Sstevel@tonic-gate error(gettext( 2207c478bd9Sstevel@tonic-gate "EOF in quote")); 2217c478bd9Sstevel@tonic-gate putchr(t); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate } else if (match(t, lcom) && 2257c478bd9Sstevel@tonic-gate ((lcom[0] != L'#' || lcom[1] != L'\0') || 2267c478bd9Sstevel@tonic-gate prev_char != '$')) { 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * Don't expand commented macro (between lcom and 2307c478bd9Sstevel@tonic-gate * rcom). 2317c478bd9Sstevel@tonic-gate * What we know so far is that we have found the 2327c478bd9Sstevel@tonic-gate * left comment char (lcom). 2337c478bd9Sstevel@tonic-gate * Make sure we haven't found '#' (lcom) immediately 2347c478bd9Sstevel@tonic-gate * preceded by '$' because we want to expand "$#". 2357c478bd9Sstevel@tonic-gate */ 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate puttok(token); 2387c478bd9Sstevel@tonic-gate for (;;) { 2397c478bd9Sstevel@tonic-gate token[0] = t = getchr(); 2407c478bd9Sstevel@tonic-gate token[1] = EOS; 2417c478bd9Sstevel@tonic-gate if (match(t, rcom)) { 2427c478bd9Sstevel@tonic-gate puttok(token); 2437c478bd9Sstevel@tonic-gate break; 2447c478bd9Sstevel@tonic-gate } else { 2457c478bd9Sstevel@tonic-gate if (t == WEOF) 2467c478bd9Sstevel@tonic-gate error(gettext( 2477c478bd9Sstevel@tonic-gate "EOF in comment")); 2487c478bd9Sstevel@tonic-gate putchr(t); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate } else if (Cp == NULL) { 2527c478bd9Sstevel@tonic-gate putchr(t); 2537c478bd9Sstevel@tonic-gate } else if (t == '(') { 2547c478bd9Sstevel@tonic-gate if (Cp->plev) 2557c478bd9Sstevel@tonic-gate stkchr(t); 2567c478bd9Sstevel@tonic-gate else { 2577c478bd9Sstevel@tonic-gate /* skip white before arg */ 2587c478bd9Sstevel@tonic-gate while ((t = getchr()) != WEOF && is_space(t)) 2597c478bd9Sstevel@tonic-gate ; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate putbak(t); 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate ++Cp->plev; 2657c478bd9Sstevel@tonic-gate } else if (t == ')') { 2667c478bd9Sstevel@tonic-gate --Cp->plev; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if (Cp->plev == 0) { 2697c478bd9Sstevel@tonic-gate stkchr(EOS); 2707c478bd9Sstevel@tonic-gate expand(Cp->argp, Ap-Cp->argp-1); 2717c478bd9Sstevel@tonic-gate op = *Cp->argp; 2727c478bd9Sstevel@tonic-gate Ap = Cp->argp-1; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (--Cp < callst) 2757c478bd9Sstevel@tonic-gate Cp = NULL; 2767c478bd9Sstevel@tonic-gate } else 2777c478bd9Sstevel@tonic-gate stkchr(t); 2787c478bd9Sstevel@tonic-gate } else if (t == ',' && Cp->plev <= 1) { 2797c478bd9Sstevel@tonic-gate stkchr(EOS); 2807c478bd9Sstevel@tonic-gate *Ap = op; 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate if ((wchar_t *)(++Ap) >= astklm) { 2837c478bd9Sstevel@tonic-gate --Ap; 2847c478bd9Sstevel@tonic-gate error2(gettext( 2857c478bd9Sstevel@tonic-gate "more than %d items on argument stack"), 2867c478bd9Sstevel@tonic-gate stksize); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate while ((t = getchr()) != WEOF && is_space(t)) 2907c478bd9Sstevel@tonic-gate ; 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate putbak(t); 2937c478bd9Sstevel@tonic-gate } else { 2947c478bd9Sstevel@tonic-gate stkchr(t); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate if (Cp != NULL) 2997c478bd9Sstevel@tonic-gate error(gettext( 3007c478bd9Sstevel@tonic-gate "EOF in argument list")); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate delexit(exitstat, 1); 3037c478bd9Sstevel@tonic-gate return (0); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate static wchar_t * 3077c478bd9Sstevel@tonic-gate inpmatch(wchar_t *s) 3087c478bd9Sstevel@tonic-gate { 3097c478bd9Sstevel@tonic-gate wchar_t *tp = token+1; 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate while (*s) { 3127c478bd9Sstevel@tonic-gate *tp = getchr(); 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate if (*tp++ != *s++) { 3157c478bd9Sstevel@tonic-gate *tp = EOS; 3167c478bd9Sstevel@tonic-gate pbstr(token+1); 3177c478bd9Sstevel@tonic-gate return (0); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate *tp = EOS; 3227c478bd9Sstevel@tonic-gate return (token); 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate static void 3267c478bd9Sstevel@tonic-gate getflags(int *xargc, char ***xargv, int *option_end) 3277c478bd9Sstevel@tonic-gate { 3287c478bd9Sstevel@tonic-gate char *arg; 3297c478bd9Sstevel@tonic-gate char *t; 3307c478bd9Sstevel@tonic-gate wchar_t *s[3]; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate while (*xargc > 1) { 3337c478bd9Sstevel@tonic-gate arg = (*xargv)[1]; /* point arg to current argument */ 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * This argument is not an option if it equals "-" or if 3377c478bd9Sstevel@tonic-gate * "--" has already been parsed. 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate if (arg[0] != '-' || arg[1] == EOS || *option_end) 3407c478bd9Sstevel@tonic-gate break; 3417c478bd9Sstevel@tonic-gate if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0') { 3427c478bd9Sstevel@tonic-gate *option_end = 1; 3437c478bd9Sstevel@tonic-gate } else { 3447c478bd9Sstevel@tonic-gate switch (arg[1]) { 3457c478bd9Sstevel@tonic-gate case 'B': 3467c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3477c478bd9Sstevel@tonic-gate bufsize = atoi(&arg[2]); 3484c56998aSRich Burridge if (bufsize <= 0) { 3494c56998aSRich Burridge bufsize = DEF_BUFSIZE; 3504c56998aSRich Burridge } 3517c478bd9Sstevel@tonic-gate break; 3527c478bd9Sstevel@tonic-gate case 'D': 3537c478bd9Sstevel@tonic-gate initalloc(); 3547c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3557c478bd9Sstevel@tonic-gate for (t = &arg[2]; *t; t++) { 3567c478bd9Sstevel@tonic-gate if (*t == '=') { 3577c478bd9Sstevel@tonic-gate *t++ = EOS; 3587c478bd9Sstevel@tonic-gate break; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate s[1] = str2wstr(&arg[2], 1); 3627c478bd9Sstevel@tonic-gate s[2] = str2wstr(t, 1); 3637c478bd9Sstevel@tonic-gate dodef(&s[0], 2); 3647c478bd9Sstevel@tonic-gate free(s[1]); 3657c478bd9Sstevel@tonic-gate free(s[2]); 3667c478bd9Sstevel@tonic-gate break; 3677c478bd9Sstevel@tonic-gate case 'H': 3687c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3697c478bd9Sstevel@tonic-gate hshsize = atoi(&arg[2]); 3704c56998aSRich Burridge if (hshsize <= 0) { 3714c56998aSRich Burridge hshsize = DEF_HSHSIZE; 3724c56998aSRich Burridge } 3737c478bd9Sstevel@tonic-gate break; 3747c478bd9Sstevel@tonic-gate case 'S': 3757c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3767c478bd9Sstevel@tonic-gate stksize = atoi(&arg[2]); 3774c56998aSRich Burridge if (stksize <= 0) { 3784c56998aSRich Burridge stksize = DEF_STKSIZE; 3794c56998aSRich Burridge } 3807c478bd9Sstevel@tonic-gate break; 3817c478bd9Sstevel@tonic-gate case 'T': 3827c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3837c478bd9Sstevel@tonic-gate toksize = atoi(&arg[2]); 3844c56998aSRich Burridge if (toksize <= 0) { 3854c56998aSRich Burridge toksize = DEF_TOKSIZE; 3864c56998aSRich Burridge } 3877c478bd9Sstevel@tonic-gate break; 3887c478bd9Sstevel@tonic-gate case 'U': 3897c478bd9Sstevel@tonic-gate initalloc(); 3907c478bd9Sstevel@tonic-gate chkspace(&arg, xargc, xargv); 3917c478bd9Sstevel@tonic-gate s[1] = str2wstr(&arg[2], 1); 3927c478bd9Sstevel@tonic-gate doundef(&s[0], 1); 3937c478bd9Sstevel@tonic-gate free(s[1]); 3947c478bd9Sstevel@tonic-gate break; 3957c478bd9Sstevel@tonic-gate case 'e': 3967c478bd9Sstevel@tonic-gate setbuf(stdout, NULL); 3977c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 3987c478bd9Sstevel@tonic-gate break; 3997c478bd9Sstevel@tonic-gate case 's': 4007c478bd9Sstevel@tonic-gate /* turn on line sync */ 4017c478bd9Sstevel@tonic-gate sflag = 1; 4027c478bd9Sstevel@tonic-gate break; 4037c478bd9Sstevel@tonic-gate default: 4047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4057c478bd9Sstevel@tonic-gate gettext("%s: bad option: %s\n"), 4067c478bd9Sstevel@tonic-gate procnam, arg); 4077c478bd9Sstevel@tonic-gate delexit(NOT_OK, 0); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate } /* end else not "--" */ 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate (*xargv)++; 4127c478bd9Sstevel@tonic-gate --(*xargc); 4137c478bd9Sstevel@tonic-gate } /* end while options to process */ 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * Function: chkspace 4187c478bd9Sstevel@tonic-gate * 4197c478bd9Sstevel@tonic-gate * If there is a space between the option and its argument, 4207c478bd9Sstevel@tonic-gate * adjust argptr so that &arg[2] will point to beginning of the option argument. 4217c478bd9Sstevel@tonic-gate * This will ensure that processing in getflags() will work, because &arg[2] 4227c478bd9Sstevel@tonic-gate * will point to the beginning of the option argument whether or not we have 4237c478bd9Sstevel@tonic-gate * a space between the option and its argument. If there is a space between 4247c478bd9Sstevel@tonic-gate * the option and its argument, also adjust xargv and xargc because we are 4257c478bd9Sstevel@tonic-gate * processing the next argument. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate static void 4287c478bd9Sstevel@tonic-gate chkspace(char **argptr, int *xargc, char ***xargv) 4297c478bd9Sstevel@tonic-gate { 4307c478bd9Sstevel@tonic-gate if ((*argptr)[2] == EOS) { 4317c478bd9Sstevel@tonic-gate /* there is a space between the option and its argument */ 4327c478bd9Sstevel@tonic-gate (*xargv)++; /* look at the next argument */ 4337c478bd9Sstevel@tonic-gate --(*xargc); 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * Adjust argptr if the option is followed by an 4367c478bd9Sstevel@tonic-gate * option argument. 4377c478bd9Sstevel@tonic-gate */ 4387c478bd9Sstevel@tonic-gate if (*xargc > 1) { 4397c478bd9Sstevel@tonic-gate *argptr = (*xargv)[1]; 4407c478bd9Sstevel@tonic-gate /* point &arg[2] to beginning of option argument */ 4417c478bd9Sstevel@tonic-gate *argptr -= 2; 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate static void 4479fb11590Smike_s initalloc(void) 4487c478bd9Sstevel@tonic-gate { 4499fb11590Smike_s static int done = 0; 4509fb11590Smike_s int t; 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if (done++) 4537c478bd9Sstevel@tonic-gate return; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate hshtab = xcalloc(hshsize, sizeof (struct nlist *)); 4567c478bd9Sstevel@tonic-gate callst = xcalloc(stksize/3+1, sizeof (struct call)); 4577c478bd9Sstevel@tonic-gate Ap = argstk = xcalloc(stksize+3, sizeof (wchar_t *)); 4587c478bd9Sstevel@tonic-gate ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1, sizeof (wchar_t)); 4597c478bd9Sstevel@tonic-gate op = obuf = xcalloc(bufsize+1, sizeof (wchar_t)); 4607c478bd9Sstevel@tonic-gate token = xcalloc(toksize+1, sizeof (wchar_t)); 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate astklm = (wchar_t *)(&argstk[stksize]); 4637c478bd9Sstevel@tonic-gate ibuflm = &ibuf[bufsize]; 4647c478bd9Sstevel@tonic-gate obuflm = &obuf[bufsize]; 4657c478bd9Sstevel@tonic-gate toklm = &token[toksize]; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate for (t = 0; barray[t].bname; ++t) { 4687c478bd9Sstevel@tonic-gate wchar_t p[2] = {0, EOS}; 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate p[0] = builtin(t); 4717c478bd9Sstevel@tonic-gate install(barray[t].bname, p, NOPUSH); 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate install(L"unix", nullstr, NOPUSH); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate void 4777c478bd9Sstevel@tonic-gate install(wchar_t *nam, wchar_t *val, int mode) 4787c478bd9Sstevel@tonic-gate { 4799fb11590Smike_s struct nlist *np; 4807c478bd9Sstevel@tonic-gate wchar_t *cp; 4817c478bd9Sstevel@tonic-gate int l; 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate if (mode == PUSH) 4847c478bd9Sstevel@tonic-gate (void) lookup(nam); /* lookup sets hshval */ 4857c478bd9Sstevel@tonic-gate else 4867c478bd9Sstevel@tonic-gate while (undef(nam)) /* undef calls lookup */ 4877c478bd9Sstevel@tonic-gate ; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate np = xcalloc(1, sizeof (*np)); 4907c478bd9Sstevel@tonic-gate np->name = wstrdup(nam); 4917c478bd9Sstevel@tonic-gate np->next = hshtab[hshval]; 4927c478bd9Sstevel@tonic-gate hshtab[hshval] = np; 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate cp = xcalloc((l = wcslen(val))+1, sizeof (*val)); 4957c478bd9Sstevel@tonic-gate np->def = cp; 4967c478bd9Sstevel@tonic-gate cp = &cp[l]; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate while (*val) 4997c478bd9Sstevel@tonic-gate *--cp = *val++; 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate struct nlist * 5037c478bd9Sstevel@tonic-gate lookup(wchar_t *str) 5047c478bd9Sstevel@tonic-gate { 5057c478bd9Sstevel@tonic-gate wchar_t *s1; 5069fb11590Smike_s struct nlist *np; 5077c478bd9Sstevel@tonic-gate static struct nlist nodef; 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate s1 = str; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate for (hshval = 0; *s1; ) 5127c478bd9Sstevel@tonic-gate hshval += *s1++; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate hshval %= hshsize; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate for (np = hshtab[hshval]; np != NULL; np = np->next) { 5177c478bd9Sstevel@tonic-gate if (*str == *np->name && wcscmp(str, np->name) == 0) 5187c478bd9Sstevel@tonic-gate return (np); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate return (&nodef); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate static void 5247c478bd9Sstevel@tonic-gate expand(wchar_t **a1, int c) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate wchar_t *dp; 5279fb11590Smike_s struct nlist *sp; 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate sp = (struct nlist *)a1[-1]; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (sp->tflag || trace) { 5321dd08564Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */ 5337c478bd9Sstevel@tonic-gate int i; 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5367c478bd9Sstevel@tonic-gate "Trace(%d): %ws", Cp-callst, a1[0]); 5371dd08564Sab196087 #endif 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate if (c > 0) { 5401dd08564Sab196087 #if !defined(__lint) /* lint doesn't grok "%ws" */ 5417c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "(%ws", chkbltin(a1[1])); 5427c478bd9Sstevel@tonic-gate for (i = 2; i <= c; ++i) 5437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ",%ws", chkbltin(a1[i])); 5441dd08564Sab196087 #endif 5457c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ")"); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate dp = sp->def; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate for (; *dp; ++dp) { 5537c478bd9Sstevel@tonic-gate if (is_builtin(*dp)) { 5547c478bd9Sstevel@tonic-gate (*barray[builtin_idx(*dp)].bfunc)(a1, c); 5557c478bd9Sstevel@tonic-gate } else if (dp[1] == '$') { 5567c478bd9Sstevel@tonic-gate if (is_digit(*dp)) { 5579fb11590Smike_s int n; 5587c478bd9Sstevel@tonic-gate if ((n = *dp-'0') <= c) 5597c478bd9Sstevel@tonic-gate pbstr(a1[n]); 5607c478bd9Sstevel@tonic-gate ++dp; 5617c478bd9Sstevel@tonic-gate } else if (*dp == '#') { 5627c478bd9Sstevel@tonic-gate pbnum((long)c); 5637c478bd9Sstevel@tonic-gate ++dp; 5647c478bd9Sstevel@tonic-gate } else if (*dp == '*' || *dp == '@') { 5659fb11590Smike_s int i = c; 5667c478bd9Sstevel@tonic-gate wchar_t **a = a1; 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate if (i > 0) 5697c478bd9Sstevel@tonic-gate for (;;) { 5707c478bd9Sstevel@tonic-gate if (*dp == '@') 5717c478bd9Sstevel@tonic-gate pbstr(rquote); 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate pbstr(a[i--]); 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate if (*dp == '@') 5767c478bd9Sstevel@tonic-gate pbstr(lquote); 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate if (i <= 0) 5797c478bd9Sstevel@tonic-gate break; 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate pbstr(L","); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate ++dp; 5847c478bd9Sstevel@tonic-gate } else 5857c478bd9Sstevel@tonic-gate putbak(*dp); 5867c478bd9Sstevel@tonic-gate } else 5877c478bd9Sstevel@tonic-gate putbak(*dp); 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate void 5927c478bd9Sstevel@tonic-gate setfname(char *s) 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate if (fname[ifx]) 5957c478bd9Sstevel@tonic-gate free(fname[ifx]); 5967c478bd9Sstevel@tonic-gate if ((fname[ifx] = strdup(s)) == NULL) 5977c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 5987c478bd9Sstevel@tonic-gate fline[ifx] = 1; 5997c478bd9Sstevel@tonic-gate nflag = 1; 6007c478bd9Sstevel@tonic-gate lnsync(stdout); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate static void 6047c478bd9Sstevel@tonic-gate lnsync(FILE *iop) 6057c478bd9Sstevel@tonic-gate { 6067c478bd9Sstevel@tonic-gate static int cline = 0; 6077c478bd9Sstevel@tonic-gate static int cfile = 0; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if (!sflag || iop != stdout) 6107c478bd9Sstevel@tonic-gate return; 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate if (nflag || ifx != cfile) { 6137c478bd9Sstevel@tonic-gate nflag = 0; 6147c478bd9Sstevel@tonic-gate cfile = ifx; 6157c478bd9Sstevel@tonic-gate (void) fprintf(iop, "#line %d \"", cline = fline[ifx]); 6167c478bd9Sstevel@tonic-gate fpath(iop); 6177c478bd9Sstevel@tonic-gate (void) fprintf(iop, "\"\n"); 6187c478bd9Sstevel@tonic-gate } else if (++cline != fline[ifx]) 6197c478bd9Sstevel@tonic-gate (void) fprintf(iop, "#line %d\n", cline = fline[ifx]); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate static void 6237c478bd9Sstevel@tonic-gate fpath(FILE *iop) 6247c478bd9Sstevel@tonic-gate { 6259fb11590Smike_s int i; 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate if (fname[0] == NULL) 6287c478bd9Sstevel@tonic-gate return; 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate (void) fprintf(iop, "%s", fname[0]); 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate for (i = 1; i <= ifx; ++i) 6337c478bd9Sstevel@tonic-gate (void) fprintf(iop, ":%s", fname[i]); 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate /* ARGSUSED */ 6377c478bd9Sstevel@tonic-gate static void 6387c478bd9Sstevel@tonic-gate catchsig(int i) 6397c478bd9Sstevel@tonic-gate { 6407c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN); 6417c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 6427c478bd9Sstevel@tonic-gate delexit(NOT_OK, 0); 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate void 6467c478bd9Sstevel@tonic-gate delexit(int code, int flushio) 6477c478bd9Sstevel@tonic-gate { 6489fb11590Smike_s int i; 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate cf = stdout; 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate /* 6537c478bd9Sstevel@tonic-gate * if (ofx != 0) { 6547c478bd9Sstevel@tonic-gate * ofx = 0; 6557c478bd9Sstevel@tonic-gate * code = NOT_OK; 6567c478bd9Sstevel@tonic-gate * } 6577c478bd9Sstevel@tonic-gate */ 6587c478bd9Sstevel@tonic-gate ofx = 0; /* ensure that everything comes out */ 6597c478bd9Sstevel@tonic-gate for (i = 1; i < 10; i++) 6607c478bd9Sstevel@tonic-gate undiv(i, code); 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate tempfile[7] = 'a'; 6637c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate /* flush standard I/O buffers, ie: call exit() not _exit() */ 6667c478bd9Sstevel@tonic-gate if (flushio) 6677c478bd9Sstevel@tonic-gate exit(code); 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate _exit(code); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate static void 6737c478bd9Sstevel@tonic-gate puttok(wchar_t *tp) 6747c478bd9Sstevel@tonic-gate { 6757c478bd9Sstevel@tonic-gate if (Cp) { 6767c478bd9Sstevel@tonic-gate while (*tp) 6777c478bd9Sstevel@tonic-gate stkchr(*tp++); 6787c478bd9Sstevel@tonic-gate } else if (cf) { 6797c478bd9Sstevel@tonic-gate while (*tp) { 6807c478bd9Sstevel@tonic-gate sputchr(*tp++, cf); 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate void 6867c478bd9Sstevel@tonic-gate pbstr(wchar_t *str) 6877c478bd9Sstevel@tonic-gate { 6887c478bd9Sstevel@tonic-gate wchar_t *p; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate for (p = str + wcslen(str); --p >= str; ) 6917c478bd9Sstevel@tonic-gate putbak(*p); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate void 6957c478bd9Sstevel@tonic-gate undiv(int i, int code) 6967c478bd9Sstevel@tonic-gate { 6979fb11590Smike_s FILE *fp; 6987c478bd9Sstevel@tonic-gate wint_t c; 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate if (i < 1 || i > 9 || i == ofx || !ofile[i]) 7017c478bd9Sstevel@tonic-gate return; 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate (void) fclose(ofile[i]); 7047c478bd9Sstevel@tonic-gate tempfile[7] = 'a'+i; 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate if (code == OK && cf) { 7077c478bd9Sstevel@tonic-gate fp = xfopen(tempfile, "r"); 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate if (wide) { 7107c478bd9Sstevel@tonic-gate while ((c = myfgetwc(fp, -1)) != WEOF) 7117c478bd9Sstevel@tonic-gate sputchr((wchar_t)c, cf); 7127c478bd9Sstevel@tonic-gate } else { 7137c478bd9Sstevel@tonic-gate while ((c = (wint_t)getc(fp)) != WEOF) 7147c478bd9Sstevel@tonic-gate sputchr((wchar_t)c, cf); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate (void) fclose(fp); 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate (void) unlink(tempfile); 7217c478bd9Sstevel@tonic-gate ofile[i] = NULL; 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate void 7257c478bd9Sstevel@tonic-gate pbnum(long num) 7267c478bd9Sstevel@tonic-gate { 7277c478bd9Sstevel@tonic-gate pbnbr(num, 10, 1); 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate void 7317c478bd9Sstevel@tonic-gate pbnbr(long nbr, int base, int len) 7327c478bd9Sstevel@tonic-gate { 7339fb11590Smike_s int neg = 0; 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate if (base <= 0) 7367c478bd9Sstevel@tonic-gate return; 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate if (nbr < 0) 7397c478bd9Sstevel@tonic-gate neg = 1; 7407c478bd9Sstevel@tonic-gate else 7417c478bd9Sstevel@tonic-gate nbr = -nbr; 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate while (nbr < 0) { 7449fb11590Smike_s int i; 7457c478bd9Sstevel@tonic-gate if (base > 1) { 7467c478bd9Sstevel@tonic-gate i = nbr%base; 7477c478bd9Sstevel@tonic-gate nbr /= base; 7487c478bd9Sstevel@tonic-gate #if (-3 % 2) != -1 7497c478bd9Sstevel@tonic-gate while (i > 0) { 7507c478bd9Sstevel@tonic-gate i -= base; 7517c478bd9Sstevel@tonic-gate ++nbr; 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate #endif 7547c478bd9Sstevel@tonic-gate i = -i; 7557c478bd9Sstevel@tonic-gate } else { 7567c478bd9Sstevel@tonic-gate i = 1; 7577c478bd9Sstevel@tonic-gate ++nbr; 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate putbak(itochr(i)); 7607c478bd9Sstevel@tonic-gate --len; 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate while (--len >= 0) 7647c478bd9Sstevel@tonic-gate putbak('0'); 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate if (neg) 7677c478bd9Sstevel@tonic-gate putbak('-'); 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate static wchar_t 7717c478bd9Sstevel@tonic-gate itochr(int i) 7727c478bd9Sstevel@tonic-gate { 7737c478bd9Sstevel@tonic-gate if (i > 9) 7747c478bd9Sstevel@tonic-gate return ((wchar_t)(i-10+'A')); 7757c478bd9Sstevel@tonic-gate else 7767c478bd9Sstevel@tonic-gate return ((wchar_t)(i+'0')); 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate long 7807c478bd9Sstevel@tonic-gate ctol(wchar_t *str) 7817c478bd9Sstevel@tonic-gate { 7829fb11590Smike_s int sign; 7837c478bd9Sstevel@tonic-gate long num; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate while (is_space(*str)) 7867c478bd9Sstevel@tonic-gate ++str; 7877c478bd9Sstevel@tonic-gate num = 0; 7887c478bd9Sstevel@tonic-gate if (*str == '-') { 7897c478bd9Sstevel@tonic-gate sign = -1; 7907c478bd9Sstevel@tonic-gate ++str; 7917c478bd9Sstevel@tonic-gate } else 7927c478bd9Sstevel@tonic-gate sign = 1; 7937c478bd9Sstevel@tonic-gate while (is_digit(*str)) 7947c478bd9Sstevel@tonic-gate num = num*10 + *str++ - '0'; 7957c478bd9Sstevel@tonic-gate return (sign * num); 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate int 7997c478bd9Sstevel@tonic-gate min(int a, int b) 8007c478bd9Sstevel@tonic-gate { 8017c478bd9Sstevel@tonic-gate if (a > b) 8027c478bd9Sstevel@tonic-gate return (b); 8037c478bd9Sstevel@tonic-gate return (a); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate FILE * 8077c478bd9Sstevel@tonic-gate xfopen(char *name, char *mode) 8087c478bd9Sstevel@tonic-gate { 8097c478bd9Sstevel@tonic-gate FILE *fp; 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate if ((fp = fopen(name, mode)) == NULL) 812*447603b5SGary Mills errorf(gettext("cannot open file: %s"), 813*447603b5SGary Mills strerror(errno)); 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate return (fp); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* 8197c478bd9Sstevel@tonic-gate * m4open 8207c478bd9Sstevel@tonic-gate * 8217c478bd9Sstevel@tonic-gate * Continue processing files when unable to open the given file argument. 8227c478bd9Sstevel@tonic-gate */ 8237c478bd9Sstevel@tonic-gate FILE * 8247c478bd9Sstevel@tonic-gate m4open(char ***argvec, char *mode, int *argcnt) 8257c478bd9Sstevel@tonic-gate { 8267c478bd9Sstevel@tonic-gate FILE *fp; 8277c478bd9Sstevel@tonic-gate char *arg; 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate while (*argcnt > 0) { 8307c478bd9Sstevel@tonic-gate arg = (*argvec)[0]; /* point arg to current file name */ 8317c478bd9Sstevel@tonic-gate if (arg[0] == '-' && arg[1] == EOS) 8327c478bd9Sstevel@tonic-gate return (stdin); 8337c478bd9Sstevel@tonic-gate else { 8347c478bd9Sstevel@tonic-gate if ((fp = fopen(arg, mode)) == NULL) { 8357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 8367c478bd9Sstevel@tonic-gate "m4: cannot open %s: "), arg); 8377c478bd9Sstevel@tonic-gate perror(""); 8387c478bd9Sstevel@tonic-gate if (*argcnt == 1) { 8397c478bd9Sstevel@tonic-gate /* last arg therefore exit */ 8407c478bd9Sstevel@tonic-gate error3(); 8417c478bd9Sstevel@tonic-gate } else { 8427c478bd9Sstevel@tonic-gate exitstat = 1; 8437c478bd9Sstevel@tonic-gate (*argvec)++; /* try next arg */ 8447c478bd9Sstevel@tonic-gate (*argcnt)--; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate } else 8477c478bd9Sstevel@tonic-gate break; 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate return (fp); 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate void * 8547c478bd9Sstevel@tonic-gate xmalloc(size_t size) 8557c478bd9Sstevel@tonic-gate { 8567c478bd9Sstevel@tonic-gate void *ptr; 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate if ((ptr = malloc(size)) == NULL) 8597c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 8607c478bd9Sstevel@tonic-gate return (ptr); 8617c478bd9Sstevel@tonic-gate } 8627c478bd9Sstevel@tonic-gate 8637c478bd9Sstevel@tonic-gate static void * 8647c478bd9Sstevel@tonic-gate xcalloc(size_t nbr, size_t size) 8657c478bd9Sstevel@tonic-gate { 8669fb11590Smike_s void *ptr; 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate ptr = xmalloc(nbr * size); 8697c478bd9Sstevel@tonic-gate (void) memset(ptr, '\0', nbr * size); 8707c478bd9Sstevel@tonic-gate return (ptr); 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate 873*447603b5SGary Mills /* Typical format: "cannot open file: %s" */ 874*447603b5SGary Mills /* PRINTFLIKE1 */ 875*447603b5SGary Mills void 876*447603b5SGary Mills errorf(char *str, char *serr) 877*447603b5SGary Mills { 878*447603b5SGary Mills char buf[500]; 879*447603b5SGary Mills 880*447603b5SGary Mills (void) snprintf(buf, sizeof (buf), str, serr); 881*447603b5SGary Mills error(buf); 882*447603b5SGary Mills } 883*447603b5SGary Mills 8849fb11590Smike_s /* PRINTFLIKE1 */ 8857c478bd9Sstevel@tonic-gate void 8867c478bd9Sstevel@tonic-gate error2(char *str, int num) 8877c478bd9Sstevel@tonic-gate { 8887c478bd9Sstevel@tonic-gate char buf[500]; 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), str, num); 8917c478bd9Sstevel@tonic-gate error(buf); 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate void 8957c478bd9Sstevel@tonic-gate error(char *str) 8967c478bd9Sstevel@tonic-gate { 8977c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n%s:", procnam); 8987c478bd9Sstevel@tonic-gate fpath(stderr); 8997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, ":%d %s\n", fline[ifx], str); 9007c478bd9Sstevel@tonic-gate error3(); 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate static void 9047c478bd9Sstevel@tonic-gate error3() 9057c478bd9Sstevel@tonic-gate { 9067c478bd9Sstevel@tonic-gate if (Cp) { 9079fb11590Smike_s struct call *mptr; 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate /* fix limit */ 9107c478bd9Sstevel@tonic-gate *op = EOS; 9117c478bd9Sstevel@tonic-gate (Cp+1)->argp = Ap+1; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate for (mptr = callst; mptr <= Cp; ++mptr) { 9147c478bd9Sstevel@tonic-gate wchar_t **aptr, **lim; 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate aptr = mptr->argp; 9177c478bd9Sstevel@tonic-gate lim = (mptr+1)->argp-1; 9187c478bd9Sstevel@tonic-gate if (mptr == callst) 9197c478bd9Sstevel@tonic-gate (void) fputws(*aptr, stderr); 9207c478bd9Sstevel@tonic-gate ++aptr; 9217c478bd9Sstevel@tonic-gate (void) fputs("(", stderr); 9227c478bd9Sstevel@tonic-gate if (aptr < lim) 9237c478bd9Sstevel@tonic-gate for (;;) { 9247c478bd9Sstevel@tonic-gate (void) fputws(*aptr++, stderr); 9257c478bd9Sstevel@tonic-gate if (aptr >= lim) 9267c478bd9Sstevel@tonic-gate break; 9277c478bd9Sstevel@tonic-gate (void) fputs(",", stderr); 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate while (--mptr >= callst) 9317c478bd9Sstevel@tonic-gate (void) fputs(")", stderr); 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate (void) fputs("\n", stderr); 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate delexit(NOT_OK, 1); 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate static wchar_t * 9397c478bd9Sstevel@tonic-gate chkbltin(wchar_t *s) 9407c478bd9Sstevel@tonic-gate { 9417c478bd9Sstevel@tonic-gate static wchar_t buf[24]; 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate if (is_builtin(*s)) { 9447c478bd9Sstevel@tonic-gate (void) swprintf(buf, sizeof (buf)/sizeof (wchar_t), L"<%ls>", 9457c478bd9Sstevel@tonic-gate barray[builtin_idx(*s)].bname); 9467c478bd9Sstevel@tonic-gate return (buf); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate return (s); 9497c478bd9Sstevel@tonic-gate } 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate wchar_t 9527c478bd9Sstevel@tonic-gate getchr() 9537c478bd9Sstevel@tonic-gate { 9547c478bd9Sstevel@tonic-gate static wchar_t C; 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate prev_char = C; 9577c478bd9Sstevel@tonic-gate if (ip > ipflr) 9587c478bd9Sstevel@tonic-gate return (*--ip); 9597c478bd9Sstevel@tonic-gate if (wide) { 9607c478bd9Sstevel@tonic-gate C = (wchar_t)(myfeof(ifx) ? WEOF : myfgetwc(NULL, ifx)); 9617c478bd9Sstevel@tonic-gate } else { 9627c478bd9Sstevel@tonic-gate C = (wchar_t)(feof(ifile[ifx]) ? 9637c478bd9Sstevel@tonic-gate WEOF : (wint_t)getc(ifile[ifx])); 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate if (C == '\n') 9667c478bd9Sstevel@tonic-gate fline[ifx]++; 9677c478bd9Sstevel@tonic-gate return (C); 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate /* 9717c478bd9Sstevel@tonic-gate * showwrap 9727c478bd9Sstevel@tonic-gate * 9737c478bd9Sstevel@tonic-gate * Loop through the list of m4wrap strings. Call pbstr() so that the 9747c478bd9Sstevel@tonic-gate * string will be displayed, then delete the list entry and free the memory 9757c478bd9Sstevel@tonic-gate * allocated for it. 9767c478bd9Sstevel@tonic-gate */ 9777c478bd9Sstevel@tonic-gate static void 9787c478bd9Sstevel@tonic-gate showwrap() 9797c478bd9Sstevel@tonic-gate { 9807c478bd9Sstevel@tonic-gate struct Wrap *prev; 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate while (wrapstart) { 9837c478bd9Sstevel@tonic-gate pbstr(wrapstart->wrapstr); 9847c478bd9Sstevel@tonic-gate free(wrapstart->wrapstr); 9857c478bd9Sstevel@tonic-gate prev = wrapstart; 9867c478bd9Sstevel@tonic-gate wrapstart = wrapstart->nxt; 9877c478bd9Sstevel@tonic-gate free(prev); 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate static void 9927c478bd9Sstevel@tonic-gate sputchr(wchar_t c, FILE *f) 9937c478bd9Sstevel@tonic-gate { 9947c478bd9Sstevel@tonic-gate wint_t ret; 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate if (is_builtin(c)) 9977c478bd9Sstevel@tonic-gate return; 9987c478bd9Sstevel@tonic-gate if (wide) 9997c478bd9Sstevel@tonic-gate ret = myfputwc(c, f); 10007c478bd9Sstevel@tonic-gate else 10017c478bd9Sstevel@tonic-gate ret = (wint_t)putc((int)c, f); 10027c478bd9Sstevel@tonic-gate if (ret == WEOF) 10037c478bd9Sstevel@tonic-gate error(gettext("output error")); 10047c478bd9Sstevel@tonic-gate if (ret == '\n') 10057c478bd9Sstevel@tonic-gate lnsync(f); 10067c478bd9Sstevel@tonic-gate } 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate static void 10097c478bd9Sstevel@tonic-gate putchr(wchar_t c) 10107c478bd9Sstevel@tonic-gate { 10117c478bd9Sstevel@tonic-gate wint_t ret; 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate if (Cp) 10147c478bd9Sstevel@tonic-gate stkchr(c); 10157c478bd9Sstevel@tonic-gate else if (cf) { 10167c478bd9Sstevel@tonic-gate if (sflag) 10177c478bd9Sstevel@tonic-gate sputchr(c, cf); 10187c478bd9Sstevel@tonic-gate else { 10197c478bd9Sstevel@tonic-gate if (is_builtin(c)) 10207c478bd9Sstevel@tonic-gate return; 10217c478bd9Sstevel@tonic-gate if (wide) 10227c478bd9Sstevel@tonic-gate ret = myfputwc(c, cf); 10237c478bd9Sstevel@tonic-gate else 10247c478bd9Sstevel@tonic-gate ret = (wint_t)putc((int)c, cf); 10257c478bd9Sstevel@tonic-gate if (ret == WEOF) { 10267c478bd9Sstevel@tonic-gate error(gettext("output error")); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate } 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate wchar_t * 10337c478bd9Sstevel@tonic-gate wstrdup(wchar_t *p) 10347c478bd9Sstevel@tonic-gate { 10357c478bd9Sstevel@tonic-gate size_t len = wcslen(p); 10367c478bd9Sstevel@tonic-gate wchar_t *ret; 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate ret = xmalloc((len + 1) * sizeof (wchar_t)); 10397c478bd9Sstevel@tonic-gate (void) wcscpy(ret, p); 10407c478bd9Sstevel@tonic-gate return (ret); 10417c478bd9Sstevel@tonic-gate } 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate int 10447c478bd9Sstevel@tonic-gate wstoi(wchar_t *p) 10457c478bd9Sstevel@tonic-gate { 10467c478bd9Sstevel@tonic-gate return ((int)wcstol(p, NULL, 10)); 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate char * 10507c478bd9Sstevel@tonic-gate wstr2str(wchar_t *from, int alloc) 10517c478bd9Sstevel@tonic-gate { 10527c478bd9Sstevel@tonic-gate static char *retbuf; 10537c478bd9Sstevel@tonic-gate static size_t bsiz; 10547c478bd9Sstevel@tonic-gate char *p, *ret; 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate if (alloc) { 10577c478bd9Sstevel@tonic-gate ret = p = xmalloc(wcslen(from) * mb_cur_max + 1); 10587c478bd9Sstevel@tonic-gate } else { 10597c478bd9Sstevel@tonic-gate while (bsiz < (wcslen(from) * mb_cur_max + 1)) { 10607c478bd9Sstevel@tonic-gate if ((p = realloc(retbuf, bsiz + 256)) == NULL) 10617c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 10627c478bd9Sstevel@tonic-gate bsiz += 256; 10637c478bd9Sstevel@tonic-gate retbuf = p; 10647c478bd9Sstevel@tonic-gate } 10657c478bd9Sstevel@tonic-gate ret = p = retbuf; 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate if (wide) { 10697c478bd9Sstevel@tonic-gate while (*from) { 10707c478bd9Sstevel@tonic-gate int len; 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate if (*from & INVALID_CHAR) { 10737c478bd9Sstevel@tonic-gate *p = (char)(*from & ~INVALID_CHAR); 10747c478bd9Sstevel@tonic-gate len = 1; 10757c478bd9Sstevel@tonic-gate } else { 10767c478bd9Sstevel@tonic-gate if ((len = wctomb(p, *from)) == -1) { 10777c478bd9Sstevel@tonic-gate *p = (char)*from; 10787c478bd9Sstevel@tonic-gate len = 1; 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate } 10817c478bd9Sstevel@tonic-gate p += len; 10827c478bd9Sstevel@tonic-gate from++; 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate } else { 10857c478bd9Sstevel@tonic-gate while (*from) 10867c478bd9Sstevel@tonic-gate *p++ = (char)*from++; 10877c478bd9Sstevel@tonic-gate } 10887c478bd9Sstevel@tonic-gate *p = '\0'; 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate return (ret); 10917c478bd9Sstevel@tonic-gate } 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate wchar_t * 10947c478bd9Sstevel@tonic-gate str2wstr(char *from, int alloc) 10957c478bd9Sstevel@tonic-gate { 10967c478bd9Sstevel@tonic-gate static wchar_t *retbuf; 10977c478bd9Sstevel@tonic-gate static size_t bsiz; 10987c478bd9Sstevel@tonic-gate wchar_t *p, *ret; 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate if (alloc) { 11017c478bd9Sstevel@tonic-gate ret = p = xmalloc((strlen(from) + 1) * sizeof (wchar_t)); 11027c478bd9Sstevel@tonic-gate } else { 11037c478bd9Sstevel@tonic-gate while (bsiz < (strlen(from) + 1)) { 11047c478bd9Sstevel@tonic-gate if ((p = realloc(retbuf, 11057c478bd9Sstevel@tonic-gate (bsiz + 256) * sizeof (wchar_t))) == NULL) { 11067c478bd9Sstevel@tonic-gate error(gettext("out of storage")); 11077c478bd9Sstevel@tonic-gate } 11087c478bd9Sstevel@tonic-gate bsiz += 256; 11097c478bd9Sstevel@tonic-gate retbuf = p; 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate ret = p = retbuf; 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate if (wide) { 11157c478bd9Sstevel@tonic-gate while (*from) { 11167c478bd9Sstevel@tonic-gate int len; 11177c478bd9Sstevel@tonic-gate wchar_t wc; 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate if ((len = mbtowc(&wc, from, mb_cur_max)) <= 0) { 11207c478bd9Sstevel@tonic-gate wc = *from | INVALID_CHAR; 11217c478bd9Sstevel@tonic-gate len = 1; 11227c478bd9Sstevel@tonic-gate } 11237c478bd9Sstevel@tonic-gate *p++ = wc; 11247c478bd9Sstevel@tonic-gate from += len; 11257c478bd9Sstevel@tonic-gate } 11267c478bd9Sstevel@tonic-gate } else { 11277c478bd9Sstevel@tonic-gate while (*from) 11287c478bd9Sstevel@tonic-gate *p++ = (unsigned char) *from++; 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate *p = 0; 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate return (ret); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate static wint_t 11367c478bd9Sstevel@tonic-gate myfgetwc(FILE *fp, int idx) 11377c478bd9Sstevel@tonic-gate { 11387c478bd9Sstevel@tonic-gate int i, c, len, nb; 11397c478bd9Sstevel@tonic-gate wchar_t wc; 11407c478bd9Sstevel@tonic-gate unsigned char *buf; 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate if (fp == NULL) 11437c478bd9Sstevel@tonic-gate fp = ifile[idx]; 11447c478bd9Sstevel@tonic-gate else 11457c478bd9Sstevel@tonic-gate idx = 10; /* extra slot */ 11467c478bd9Sstevel@tonic-gate buf = ibuffer[idx].buffer; 11477c478bd9Sstevel@tonic-gate nb = ibuffer[idx].nbytes; 11487c478bd9Sstevel@tonic-gate len = 0; 11497c478bd9Sstevel@tonic-gate for (i = 1; i <= mb_cur_max; i++) { 11507c478bd9Sstevel@tonic-gate if (nb < i) { 11517c478bd9Sstevel@tonic-gate c = getc(fp); 11527c478bd9Sstevel@tonic-gate if (c == EOF) { 11537c478bd9Sstevel@tonic-gate if (nb == 0) 11547c478bd9Sstevel@tonic-gate return (WEOF); 11557c478bd9Sstevel@tonic-gate else 11567c478bd9Sstevel@tonic-gate break; 11577c478bd9Sstevel@tonic-gate } 11587c478bd9Sstevel@tonic-gate buf[nb++] = (unsigned char)c; 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate if ((len = mbtowc(&wc, (char *)buf, i)) >= 0) 11617c478bd9Sstevel@tonic-gate break; 11627c478bd9Sstevel@tonic-gate } 11637c478bd9Sstevel@tonic-gate if (len <= 0) { 11647c478bd9Sstevel@tonic-gate wc = buf[0] | INVALID_CHAR; 11657c478bd9Sstevel@tonic-gate len = 1; 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate nb -= len; 11687c478bd9Sstevel@tonic-gate if (nb > 0) { 11697c478bd9Sstevel@tonic-gate for (i = 0; i < nb; i++) 11707c478bd9Sstevel@tonic-gate buf[i] = buf[i + len]; 11717c478bd9Sstevel@tonic-gate } 11727c478bd9Sstevel@tonic-gate ibuffer[idx].nbytes = nb; 11737c478bd9Sstevel@tonic-gate return (wc); 11747c478bd9Sstevel@tonic-gate } 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate static wint_t 11777c478bd9Sstevel@tonic-gate myfputwc(wchar_t wc, FILE *fp) 11787c478bd9Sstevel@tonic-gate { 11797c478bd9Sstevel@tonic-gate if (wc & INVALID_CHAR) { 11807c478bd9Sstevel@tonic-gate wc &= ~INVALID_CHAR; 11817c478bd9Sstevel@tonic-gate return (fputc((int)wc, fp)); 11827c478bd9Sstevel@tonic-gate } 11837c478bd9Sstevel@tonic-gate return (fputwc(wc, fp)); 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate static int 11877c478bd9Sstevel@tonic-gate myfeof(int idx) 11887c478bd9Sstevel@tonic-gate { 11897c478bd9Sstevel@tonic-gate return (ibuffer[idx].nbytes == 0 && feof(ifile[idx])); 11907c478bd9Sstevel@tonic-gate } 1191