1acc9d408SJuli Mallett /* $OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $ */ 2acc9d408SJuli Mallett /* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */ 3acc9d408SJuli Mallett 49b50d902SRodney W. Grimes /* 59b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 69b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 79b50d902SRodney W. Grimes * 89b50d902SRodney W. Grimes * This code is derived from software contributed to Berkeley by 99b50d902SRodney W. Grimes * Ozan Yigit at York University. 109b50d902SRodney W. Grimes * 119b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 129b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 139b50d902SRodney W. Grimes * are met: 149b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 159b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 169b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 179b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 189b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 199b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 209b50d902SRodney W. Grimes * must display the following acknowledgement: 219b50d902SRodney W. Grimes * This product includes software developed by the University of 229b50d902SRodney W. Grimes * California, Berkeley and its contributors. 239b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 249b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 259b50d902SRodney W. Grimes * without specific prior written permission. 269b50d902SRodney W. Grimes * 279b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 289b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 299b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 309b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 319b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 329b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 339b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 349b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 359b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 369b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 379b50d902SRodney W. Grimes * SUCH DAMAGE. 389b50d902SRodney W. Grimes */ 399b50d902SRodney W. Grimes 40acc9d408SJuli Mallett #include <sys/cdefs.h> 41acc9d408SJuli Mallett __SCCSID("@(#)misc.c 8.1 (Berkeley) 6/6/93"); 42acc9d408SJuli Mallett __RCSID_SOURCE("$OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $"); 43acc9d408SJuli Mallett __FBSDID("$FreeBSD$"); 449b50d902SRodney W. Grimes 459b50d902SRodney W. Grimes #include <sys/types.h> 46acc9d408SJuli Mallett #include <errno.h> 47acc9d408SJuli Mallett #include <unistd.h> 489b50d902SRodney W. Grimes #include <stdio.h> 499b50d902SRodney W. Grimes #include <stdlib.h> 50acc9d408SJuli Mallett #include <stddef.h> 519b50d902SRodney W. Grimes #include <string.h> 52acc9d408SJuli Mallett #include <err.h> 539b50d902SRodney W. Grimes #include "mdef.h" 549b50d902SRodney W. Grimes #include "stdd.h" 559b50d902SRodney W. Grimes #include "extern.h" 569b50d902SRodney W. Grimes #include "pathnames.h" 579b50d902SRodney W. Grimes 58acc9d408SJuli Mallett 59acc9d408SJuli Mallett char *ep; /* first free char in strspace */ 60acc9d408SJuli Mallett static char *strspace; /* string space for evaluation */ 61acc9d408SJuli Mallett char *endest; /* end of string space */ 62acc9d408SJuli Mallett static size_t strsize = STRSPMAX; 63acc9d408SJuli Mallett static size_t bufsize = BUFSIZE; 64acc9d408SJuli Mallett 65acc9d408SJuli Mallett char *buf; /* push-back buffer */ 66acc9d408SJuli Mallett char *bufbase; /* the base for current ilevel */ 67acc9d408SJuli Mallett char *bbase[MAXINP]; /* the base for each ilevel */ 68acc9d408SJuli Mallett char *bp; /* first available character */ 69acc9d408SJuli Mallett char *endpbb; /* end of push-back buffer */ 70acc9d408SJuli Mallett 71acc9d408SJuli Mallett 729b50d902SRodney W. Grimes /* 739b50d902SRodney W. Grimes * find the index of second str in the first str. 749b50d902SRodney W. Grimes */ 75acc9d408SJuli Mallett ptrdiff_t 769b50d902SRodney W. Grimes indx(s1, s2) 77acc9d408SJuli Mallett const char *s1; 78acc9d408SJuli Mallett const char *s2; 799b50d902SRodney W. Grimes { 80acc9d408SJuli Mallett char *t; 819b50d902SRodney W. Grimes 82acc9d408SJuli Mallett t = strstr(s1, s2); 83acc9d408SJuli Mallett if (t == NULL) 849b50d902SRodney W. Grimes return (-1); 85acc9d408SJuli Mallett else 86acc9d408SJuli Mallett return (t - s1); 879b50d902SRodney W. Grimes } 889b50d902SRodney W. Grimes /* 899b50d902SRodney W. Grimes * putback - push character back onto input 909b50d902SRodney W. Grimes */ 919b50d902SRodney W. Grimes void 929b50d902SRodney W. Grimes putback(c) 937c5eeb39SAndrey A. Chernov int c; 949b50d902SRodney W. Grimes { 957c5eeb39SAndrey A. Chernov if (c == EOF) 96b63b4cdbSAndrey A. Chernov return; 97acc9d408SJuli Mallett if (bp >= endpbb) 98acc9d408SJuli Mallett enlarge_bufspace(); 999b50d902SRodney W. Grimes *bp++ = c; 1009b50d902SRodney W. Grimes } 1019b50d902SRodney W. Grimes 1029b50d902SRodney W. Grimes /* 1039b50d902SRodney W. Grimes * pbstr - push string back onto input 1049b50d902SRodney W. Grimes * putback is replicated to improve 1059b50d902SRodney W. Grimes * performance. 1069b50d902SRodney W. Grimes */ 1079b50d902SRodney W. Grimes void 1089b50d902SRodney W. Grimes pbstr(s) 109acc9d408SJuli Mallett const char *s; 1109b50d902SRodney W. Grimes { 111acc9d408SJuli Mallett size_t n; 1129b50d902SRodney W. Grimes 113acc9d408SJuli Mallett n = strlen(s); 114acc9d408SJuli Mallett while (endpbb - bp <= n) 115acc9d408SJuli Mallett enlarge_bufspace(); 116acc9d408SJuli Mallett while (n > 0) 117acc9d408SJuli Mallett *bp++ = s[--n]; 1189b50d902SRodney W. Grimes } 1199b50d902SRodney W. Grimes 1209b50d902SRodney W. Grimes /* 1219b50d902SRodney W. Grimes * pbnum - convert number to string, push back on input. 1229b50d902SRodney W. Grimes */ 1239b50d902SRodney W. Grimes void 1249b50d902SRodney W. Grimes pbnum(n) 1259b50d902SRodney W. Grimes int n; 1269b50d902SRodney W. Grimes { 127acc9d408SJuli Mallett int num; 1289b50d902SRodney W. Grimes 1299b50d902SRodney W. Grimes num = (n < 0) ? -n : n; 1309b50d902SRodney W. Grimes do { 1319b50d902SRodney W. Grimes putback(num % 10 + '0'); 1329b50d902SRodney W. Grimes } 1339b50d902SRodney W. Grimes while ((num /= 10) > 0); 1349b50d902SRodney W. Grimes 1359b50d902SRodney W. Grimes if (n < 0) 1369b50d902SRodney W. Grimes putback('-'); 1379b50d902SRodney W. Grimes } 1389b50d902SRodney W. Grimes 1399b50d902SRodney W. Grimes /* 140acc9d408SJuli Mallett * pbunsigned - convert unsigned long to string, push back on input. 141acc9d408SJuli Mallett */ 142acc9d408SJuli Mallett void 143acc9d408SJuli Mallett pbunsigned(n) 144acc9d408SJuli Mallett unsigned long n; 145acc9d408SJuli Mallett { 146acc9d408SJuli Mallett do { 147acc9d408SJuli Mallett putback(n % 10 + '0'); 148acc9d408SJuli Mallett } 149acc9d408SJuli Mallett while ((n /= 10) > 0); 150acc9d408SJuli Mallett } 151acc9d408SJuli Mallett 152acc9d408SJuli Mallett void 153acc9d408SJuli Mallett initspaces() 154acc9d408SJuli Mallett { 155acc9d408SJuli Mallett int i; 156acc9d408SJuli Mallett 157acc9d408SJuli Mallett strspace = xalloc(strsize+1); 158acc9d408SJuli Mallett ep = strspace; 159acc9d408SJuli Mallett endest = strspace+strsize; 160acc9d408SJuli Mallett buf = (char *)xalloc(bufsize); 161acc9d408SJuli Mallett bufbase = buf; 162acc9d408SJuli Mallett bp = buf; 163acc9d408SJuli Mallett endpbb = buf + bufsize; 164acc9d408SJuli Mallett for (i = 0; i < MAXINP; i++) 165acc9d408SJuli Mallett bbase[i] = buf; 166acc9d408SJuli Mallett } 167acc9d408SJuli Mallett 168acc9d408SJuli Mallett void 169acc9d408SJuli Mallett enlarge_strspace() 170acc9d408SJuli Mallett { 171acc9d408SJuli Mallett char *newstrspace; 172acc9d408SJuli Mallett int i; 173acc9d408SJuli Mallett 174acc9d408SJuli Mallett strsize *= 2; 175acc9d408SJuli Mallett newstrspace = malloc(strsize + 1); 176acc9d408SJuli Mallett if (!newstrspace) 177acc9d408SJuli Mallett errx(1, "string space overflow"); 178acc9d408SJuli Mallett memcpy(newstrspace, strspace, strsize/2); 179acc9d408SJuli Mallett for (i = 0; i <= sp; i++) 180acc9d408SJuli Mallett if (sstack[i]) 181acc9d408SJuli Mallett mstack[i].sstr = (mstack[i].sstr - strspace) 182acc9d408SJuli Mallett + newstrspace; 183acc9d408SJuli Mallett ep = (ep-strspace) + newstrspace; 184acc9d408SJuli Mallett free(strspace); 185acc9d408SJuli Mallett strspace = newstrspace; 186acc9d408SJuli Mallett endest = strspace + strsize; 187acc9d408SJuli Mallett } 188acc9d408SJuli Mallett 189acc9d408SJuli Mallett void 190acc9d408SJuli Mallett enlarge_bufspace() 191acc9d408SJuli Mallett { 192acc9d408SJuli Mallett char *newbuf; 193acc9d408SJuli Mallett int i; 194acc9d408SJuli Mallett 195acc9d408SJuli Mallett bufsize *= 2; 196acc9d408SJuli Mallett newbuf = realloc(buf, bufsize); 197acc9d408SJuli Mallett if (!newbuf) 198acc9d408SJuli Mallett errx(1, "too many characters pushed back"); 199acc9d408SJuli Mallett for (i = 0; i < MAXINP; i++) 200acc9d408SJuli Mallett bbase[i] = (bbase[i]-buf)+newbuf; 201acc9d408SJuli Mallett bp = (bp-buf)+newbuf; 202acc9d408SJuli Mallett bufbase = (bufbase-buf)+newbuf; 203acc9d408SJuli Mallett buf = newbuf; 204acc9d408SJuli Mallett endpbb = buf+bufsize; 205acc9d408SJuli Mallett } 206acc9d408SJuli Mallett 207acc9d408SJuli Mallett /* 2089b50d902SRodney W. Grimes * chrsave - put single char on string space 2099b50d902SRodney W. Grimes */ 2109b50d902SRodney W. Grimes void 2119b50d902SRodney W. Grimes chrsave(c) 212acc9d408SJuli Mallett int c; 2139b50d902SRodney W. Grimes { 214acc9d408SJuli Mallett if (ep >= endest) 215acc9d408SJuli Mallett enlarge_strspace(); 2169b50d902SRodney W. Grimes *ep++ = c; 2179b50d902SRodney W. Grimes } 2189b50d902SRodney W. Grimes 2199b50d902SRodney W. Grimes /* 2209b50d902SRodney W. Grimes * read in a diversion file, and dispose it. 2219b50d902SRodney W. Grimes */ 2229b50d902SRodney W. Grimes void 2239b50d902SRodney W. Grimes getdiv(n) 2249b50d902SRodney W. Grimes int n; 2259b50d902SRodney W. Grimes { 226acc9d408SJuli Mallett int c; 2279b50d902SRodney W. Grimes 2289b50d902SRodney W. Grimes if (active == outfile[n]) 22995105358SPhilippe Charnier errx(1, "undivert: diversion still active"); 230acc9d408SJuli Mallett rewind(outfile[n]); 231acc9d408SJuli Mallett while ((c = getc(outfile[n])) != EOF) 232acc9d408SJuli Mallett putc(c, active); 2339b50d902SRodney W. Grimes (void) fclose(outfile[n]); 2349b50d902SRodney W. Grimes outfile[n] = NULL; 2359b50d902SRodney W. Grimes } 2369b50d902SRodney W. Grimes 2379b50d902SRodney W. Grimes void 2389b50d902SRodney W. Grimes onintr(signo) 2399b50d902SRodney W. Grimes int signo; 2409b50d902SRodney W. Grimes { 241acc9d408SJuli Mallett #define intrmessage "m4: interrupted.\n" 242acc9d408SJuli Mallett write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1); 243acc9d408SJuli Mallett _exit(1); 2449b50d902SRodney W. Grimes } 2459b50d902SRodney W. Grimes 2469b50d902SRodney W. Grimes /* 2479b50d902SRodney W. Grimes * killdiv - get rid of the diversion files 2489b50d902SRodney W. Grimes */ 2499b50d902SRodney W. Grimes void 2509b50d902SRodney W. Grimes killdiv() 2519b50d902SRodney W. Grimes { 252acc9d408SJuli Mallett int n; 2539b50d902SRodney W. Grimes 254acc9d408SJuli Mallett for (n = 0; n < maxout; n++) 2559b50d902SRodney W. Grimes if (outfile[n] != NULL) { 2569b50d902SRodney W. Grimes (void) fclose(outfile[n]); 2579b50d902SRodney W. Grimes } 2589b50d902SRodney W. Grimes } 2599b50d902SRodney W. Grimes 260acc9d408SJuli Mallett /* 261acc9d408SJuli Mallett * resizedivs: allocate more diversion files */ 2629b50d902SRodney W. Grimes void 263acc9d408SJuli Mallett resizedivs(n) 264164c01f0SGregory Neil Shapiro int n; 265164c01f0SGregory Neil Shapiro { 266acc9d408SJuli Mallett int i; 267acc9d408SJuli Mallett 268acc9d408SJuli Mallett outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n); 269acc9d408SJuli Mallett if (outfile == NULL) 270acc9d408SJuli Mallett errx(1, "too many diverts %d", n); 271acc9d408SJuli Mallett for (i = maxout; i < n; i++) 272acc9d408SJuli Mallett outfile[i] = NULL; 273acc9d408SJuli Mallett maxout = n; 274164c01f0SGregory Neil Shapiro } 275acc9d408SJuli Mallett 276acc9d408SJuli Mallett void * 277acc9d408SJuli Mallett xalloc(n) 278acc9d408SJuli Mallett size_t n; 279acc9d408SJuli Mallett { 280acc9d408SJuli Mallett char *p = malloc(n); 281acc9d408SJuli Mallett 282acc9d408SJuli Mallett if (p == NULL) 283acc9d408SJuli Mallett err(1, "malloc"); 284acc9d408SJuli Mallett return p; 285acc9d408SJuli Mallett } 286acc9d408SJuli Mallett 287acc9d408SJuli Mallett char * 288acc9d408SJuli Mallett xstrdup(s) 289acc9d408SJuli Mallett const char *s; 290acc9d408SJuli Mallett { 291acc9d408SJuli Mallett char *p = strdup(s); 292acc9d408SJuli Mallett if (p == NULL) 293acc9d408SJuli Mallett err(1, "strdup"); 294acc9d408SJuli Mallett return p; 295164c01f0SGregory Neil Shapiro } 296164c01f0SGregory Neil Shapiro 297164c01f0SGregory Neil Shapiro void 2989b50d902SRodney W. Grimes usage() 2999b50d902SRodney W. Grimes { 300b1ea3d46SJuli Mallett fprintf(stderr, 301acc9d408SJuli Mallett "usage: m4 [-d flags] [-t name] [-gs] [-D name[=value]]...\n" 302acc9d408SJuli Mallett " [-U name]... [-I dirname]... file...\n"); 3039b50d902SRodney W. Grimes exit(1); 3049b50d902SRodney W. Grimes } 305acc9d408SJuli Mallett 306acc9d408SJuli Mallett int 307acc9d408SJuli Mallett obtain_char(f) 308acc9d408SJuli Mallett struct input_file *f; 309acc9d408SJuli Mallett { 310acc9d408SJuli Mallett if (f->c == EOF) 311acc9d408SJuli Mallett return EOF; 312acc9d408SJuli Mallett else if (f->c == '\n') 313acc9d408SJuli Mallett f->lineno++; 314acc9d408SJuli Mallett 315acc9d408SJuli Mallett f->c = fgetc(f->file); 316acc9d408SJuli Mallett return f->c; 317acc9d408SJuli Mallett } 318acc9d408SJuli Mallett 319acc9d408SJuli Mallett void 320acc9d408SJuli Mallett set_input(f, real, name) 321acc9d408SJuli Mallett struct input_file *f; 322acc9d408SJuli Mallett FILE *real; 323acc9d408SJuli Mallett const char *name; 324acc9d408SJuli Mallett { 325acc9d408SJuli Mallett f->file = real; 326acc9d408SJuli Mallett f->lineno = 1; 327acc9d408SJuli Mallett f->c = 0; 328acc9d408SJuli Mallett f->name = xstrdup(name); 329acc9d408SJuli Mallett } 330acc9d408SJuli Mallett 331acc9d408SJuli Mallett void 332acc9d408SJuli Mallett release_input(f) 333acc9d408SJuli Mallett struct input_file *f; 334acc9d408SJuli Mallett { 335acc9d408SJuli Mallett if (f->file != stdin) 336acc9d408SJuli Mallett fclose(f->file); 337acc9d408SJuli Mallett f->c = EOF; 338acc9d408SJuli Mallett /* 339acc9d408SJuli Mallett * XXX can't free filename, as there might still be 340acc9d408SJuli Mallett * error information pointing to it. 341acc9d408SJuli Mallett */ 342acc9d408SJuli Mallett } 343acc9d408SJuli Mallett 344acc9d408SJuli Mallett void 345acc9d408SJuli Mallett doprintlineno(f) 346acc9d408SJuli Mallett struct input_file *f; 347acc9d408SJuli Mallett { 348acc9d408SJuli Mallett pbunsigned(f->lineno); 349acc9d408SJuli Mallett } 350acc9d408SJuli Mallett 351acc9d408SJuli Mallett void 352acc9d408SJuli Mallett doprintfilename(f) 353acc9d408SJuli Mallett struct input_file *f; 354acc9d408SJuli Mallett { 355acc9d408SJuli Mallett pbstr(rquote); 356acc9d408SJuli Mallett pbstr(f->name); 357acc9d408SJuli Mallett pbstr(lquote); 358acc9d408SJuli Mallett } 359acc9d408SJuli Mallett 360acc9d408SJuli Mallett /* 361acc9d408SJuli Mallett * buffer_mark/dump_buffer: allows one to save a mark in a buffer, 362acc9d408SJuli Mallett * and later dump everything that was added since then to a file. 363acc9d408SJuli Mallett */ 364acc9d408SJuli Mallett size_t 365acc9d408SJuli Mallett buffer_mark() 366acc9d408SJuli Mallett { 367acc9d408SJuli Mallett return bp - buf; 368acc9d408SJuli Mallett } 369acc9d408SJuli Mallett 370acc9d408SJuli Mallett 371acc9d408SJuli Mallett void 372acc9d408SJuli Mallett dump_buffer(f, m) 373acc9d408SJuli Mallett FILE *f; 374acc9d408SJuli Mallett size_t m; 375acc9d408SJuli Mallett { 376acc9d408SJuli Mallett char *s; 377acc9d408SJuli Mallett 378acc9d408SJuli Mallett for (s = bp; s-buf > m;) 379acc9d408SJuli Mallett fputc(*--s, f); 380acc9d408SJuli Mallett } 381