1*2e8d1edaSArun Thomas /* $OpenBSD: misc.c,v 1.41 2009/10/14 17:19:47 sthen Exp $ */ 2*2e8d1edaSArun Thomas /* $NetBSD: misc.c,v 1.20 2009/11/06 15:13:27 joerg Exp $ */ 3*2e8d1edaSArun Thomas 4*2e8d1edaSArun Thomas /* 5*2e8d1edaSArun Thomas * Copyright (c) 1989, 1993 6*2e8d1edaSArun Thomas * The Regents of the University of California. All rights reserved. 7*2e8d1edaSArun Thomas * 8*2e8d1edaSArun Thomas * This code is derived from software contributed to Berkeley by 9*2e8d1edaSArun Thomas * Ozan Yigit at York University. 10*2e8d1edaSArun Thomas * 11*2e8d1edaSArun Thomas * Redistribution and use in source and binary forms, with or without 12*2e8d1edaSArun Thomas * modification, are permitted provided that the following conditions 13*2e8d1edaSArun Thomas * are met: 14*2e8d1edaSArun Thomas * 1. Redistributions of source code must retain the above copyright 15*2e8d1edaSArun Thomas * notice, this list of conditions and the following disclaimer. 16*2e8d1edaSArun Thomas * 2. Redistributions in binary form must reproduce the above copyright 17*2e8d1edaSArun Thomas * notice, this list of conditions and the following disclaimer in the 18*2e8d1edaSArun Thomas * documentation and/or other materials provided with the distribution. 19*2e8d1edaSArun Thomas * 3. Neither the name of the University nor the names of its contributors 20*2e8d1edaSArun Thomas * may be used to endorse or promote products derived from this software 21*2e8d1edaSArun Thomas * without specific prior written permission. 22*2e8d1edaSArun Thomas * 23*2e8d1edaSArun Thomas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24*2e8d1edaSArun Thomas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25*2e8d1edaSArun Thomas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26*2e8d1edaSArun Thomas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27*2e8d1edaSArun Thomas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28*2e8d1edaSArun Thomas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29*2e8d1edaSArun Thomas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30*2e8d1edaSArun Thomas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31*2e8d1edaSArun Thomas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32*2e8d1edaSArun Thomas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33*2e8d1edaSArun Thomas * SUCH DAMAGE. 34*2e8d1edaSArun Thomas */ 35*2e8d1edaSArun Thomas #if HAVE_NBTOOL_CONFIG_H 36*2e8d1edaSArun Thomas #include "nbtool_config.h" 37*2e8d1edaSArun Thomas #endif 38*2e8d1edaSArun Thomas #include <sys/cdefs.h> 39*2e8d1edaSArun Thomas __RCSID("$NetBSD: misc.c,v 1.20 2009/11/06 15:13:27 joerg Exp $"); 40*2e8d1edaSArun Thomas #include <sys/types.h> 41*2e8d1edaSArun Thomas #include <errno.h> 42*2e8d1edaSArun Thomas #include <unistd.h> 43*2e8d1edaSArun Thomas #include <stdarg.h> 44*2e8d1edaSArun Thomas #include <stdio.h> 45*2e8d1edaSArun Thomas #include <stdlib.h> 46*2e8d1edaSArun Thomas #include <stddef.h> 47*2e8d1edaSArun Thomas #include <string.h> 48*2e8d1edaSArun Thomas #include <err.h> 49*2e8d1edaSArun Thomas #include "mdef.h" 50*2e8d1edaSArun Thomas #include "stdd.h" 51*2e8d1edaSArun Thomas #include "extern.h" 52*2e8d1edaSArun Thomas #include "pathnames.h" 53*2e8d1edaSArun Thomas 54*2e8d1edaSArun Thomas 55*2e8d1edaSArun Thomas char *ep; /* first free char in strspace */ 56*2e8d1edaSArun Thomas static char *strspace; /* string space for evaluation */ 57*2e8d1edaSArun Thomas char *endest; /* end of string space */ 58*2e8d1edaSArun Thomas static size_t strsize = STRSPMAX; 59*2e8d1edaSArun Thomas static size_t bufsize = BUFSIZE; 60*2e8d1edaSArun Thomas 61*2e8d1edaSArun Thomas unsigned char *buf; /* push-back buffer */ 62*2e8d1edaSArun Thomas unsigned char *bufbase; /* the base for current ilevel */ 63*2e8d1edaSArun Thomas unsigned char *bbase[MAXINP]; /* the base for each ilevel */ 64*2e8d1edaSArun Thomas unsigned char *bp; /* first available character */ 65*2e8d1edaSArun Thomas unsigned char *endpbb; /* end of push-back buffer */ 66*2e8d1edaSArun Thomas 67*2e8d1edaSArun Thomas 68*2e8d1edaSArun Thomas /* 69*2e8d1edaSArun Thomas * find the index of second str in the first str. 70*2e8d1edaSArun Thomas */ 71*2e8d1edaSArun Thomas ptrdiff_t 72*2e8d1edaSArun Thomas indx(const char *s1, const char *s2) 73*2e8d1edaSArun Thomas { 74*2e8d1edaSArun Thomas char *t; 75*2e8d1edaSArun Thomas 76*2e8d1edaSArun Thomas t = strstr(s1, s2); 77*2e8d1edaSArun Thomas if (t == NULL) 78*2e8d1edaSArun Thomas return (-1); 79*2e8d1edaSArun Thomas else 80*2e8d1edaSArun Thomas return (t - s1); 81*2e8d1edaSArun Thomas } 82*2e8d1edaSArun Thomas /* 83*2e8d1edaSArun Thomas * pushback - push character back onto input 84*2e8d1edaSArun Thomas */ 85*2e8d1edaSArun Thomas void 86*2e8d1edaSArun Thomas pushback(int c) 87*2e8d1edaSArun Thomas { 88*2e8d1edaSArun Thomas if (c == EOF) 89*2e8d1edaSArun Thomas return; 90*2e8d1edaSArun Thomas if (bp >= endpbb) 91*2e8d1edaSArun Thomas enlarge_bufspace(); 92*2e8d1edaSArun Thomas *bp++ = c; 93*2e8d1edaSArun Thomas } 94*2e8d1edaSArun Thomas 95*2e8d1edaSArun Thomas /* 96*2e8d1edaSArun Thomas * pbstr - push string back onto input 97*2e8d1edaSArun Thomas * pushback is replicated to improve 98*2e8d1edaSArun Thomas * performance. 99*2e8d1edaSArun Thomas */ 100*2e8d1edaSArun Thomas void 101*2e8d1edaSArun Thomas pbstr(const char *s) 102*2e8d1edaSArun Thomas { 103*2e8d1edaSArun Thomas size_t n; 104*2e8d1edaSArun Thomas 105*2e8d1edaSArun Thomas n = strlen(s); 106*2e8d1edaSArun Thomas while ((size_t)(endpbb - bp) <= n) 107*2e8d1edaSArun Thomas enlarge_bufspace(); 108*2e8d1edaSArun Thomas while (n > 0) 109*2e8d1edaSArun Thomas *bp++ = s[--n]; 110*2e8d1edaSArun Thomas } 111*2e8d1edaSArun Thomas 112*2e8d1edaSArun Thomas /* 113*2e8d1edaSArun Thomas * pbnum - convert number to string, push back on input. 114*2e8d1edaSArun Thomas */ 115*2e8d1edaSArun Thomas void 116*2e8d1edaSArun Thomas pbnum(int n) 117*2e8d1edaSArun Thomas { 118*2e8d1edaSArun Thomas pbnumbase(n, 10, 0); 119*2e8d1edaSArun Thomas } 120*2e8d1edaSArun Thomas 121*2e8d1edaSArun Thomas void 122*2e8d1edaSArun Thomas pbnumbase(int n, int base, int d) 123*2e8d1edaSArun Thomas { 124*2e8d1edaSArun Thomas static char digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz"; 125*2e8d1edaSArun Thomas int num; 126*2e8d1edaSArun Thomas int printed = 0; 127*2e8d1edaSArun Thomas 128*2e8d1edaSArun Thomas if (base > 36) 129*2e8d1edaSArun Thomas m4errx(1, "base %d > 36: not supported.", base); 130*2e8d1edaSArun Thomas 131*2e8d1edaSArun Thomas if (base < 2) 132*2e8d1edaSArun Thomas m4errx(1, "bad base %d for conversion.", base); 133*2e8d1edaSArun Thomas 134*2e8d1edaSArun Thomas num = (n < 0) ? -n : n; 135*2e8d1edaSArun Thomas do { 136*2e8d1edaSArun Thomas pushback(digits[num % base]); 137*2e8d1edaSArun Thomas printed++; 138*2e8d1edaSArun Thomas } 139*2e8d1edaSArun Thomas while ((num /= base) > 0); 140*2e8d1edaSArun Thomas 141*2e8d1edaSArun Thomas if (n < 0) 142*2e8d1edaSArun Thomas printed++; 143*2e8d1edaSArun Thomas while (printed++ < d) 144*2e8d1edaSArun Thomas pushback('0'); 145*2e8d1edaSArun Thomas 146*2e8d1edaSArun Thomas if (n < 0) 147*2e8d1edaSArun Thomas pushback('-'); 148*2e8d1edaSArun Thomas } 149*2e8d1edaSArun Thomas 150*2e8d1edaSArun Thomas /* 151*2e8d1edaSArun Thomas * pbunsigned - convert unsigned long to string, push back on input. 152*2e8d1edaSArun Thomas */ 153*2e8d1edaSArun Thomas void 154*2e8d1edaSArun Thomas pbunsigned(unsigned long n) 155*2e8d1edaSArun Thomas { 156*2e8d1edaSArun Thomas do { 157*2e8d1edaSArun Thomas pushback(n % 10 + '0'); 158*2e8d1edaSArun Thomas } 159*2e8d1edaSArun Thomas while ((n /= 10) > 0); 160*2e8d1edaSArun Thomas } 161*2e8d1edaSArun Thomas 162*2e8d1edaSArun Thomas void 163*2e8d1edaSArun Thomas initspaces() 164*2e8d1edaSArun Thomas { 165*2e8d1edaSArun Thomas int i; 166*2e8d1edaSArun Thomas 167*2e8d1edaSArun Thomas strspace = xalloc(strsize+1, NULL); 168*2e8d1edaSArun Thomas ep = strspace; 169*2e8d1edaSArun Thomas endest = strspace+strsize; 170*2e8d1edaSArun Thomas buf = (unsigned char *)xalloc(bufsize, NULL); 171*2e8d1edaSArun Thomas bufbase = buf; 172*2e8d1edaSArun Thomas bp = buf; 173*2e8d1edaSArun Thomas endpbb = buf + bufsize; 174*2e8d1edaSArun Thomas for (i = 0; i < MAXINP; i++) 175*2e8d1edaSArun Thomas bbase[i] = buf; 176*2e8d1edaSArun Thomas } 177*2e8d1edaSArun Thomas 178*2e8d1edaSArun Thomas void 179*2e8d1edaSArun Thomas enlarge_strspace() 180*2e8d1edaSArun Thomas { 181*2e8d1edaSArun Thomas char *newstrspace; 182*2e8d1edaSArun Thomas int i; 183*2e8d1edaSArun Thomas 184*2e8d1edaSArun Thomas strsize *= 2; 185*2e8d1edaSArun Thomas newstrspace = malloc(strsize + 1); 186*2e8d1edaSArun Thomas if (!newstrspace) 187*2e8d1edaSArun Thomas errx(1, "string space overflow"); 188*2e8d1edaSArun Thomas memcpy(newstrspace, strspace, strsize/2); 189*2e8d1edaSArun Thomas for (i = 0; i <= sp; i++) 190*2e8d1edaSArun Thomas if (sstack[i]) 191*2e8d1edaSArun Thomas mstack[i].sstr = (mstack[i].sstr - strspace) 192*2e8d1edaSArun Thomas + newstrspace; 193*2e8d1edaSArun Thomas ep = (ep-strspace) + newstrspace; 194*2e8d1edaSArun Thomas free(strspace); 195*2e8d1edaSArun Thomas strspace = newstrspace; 196*2e8d1edaSArun Thomas endest = strspace + strsize; 197*2e8d1edaSArun Thomas } 198*2e8d1edaSArun Thomas 199*2e8d1edaSArun Thomas void 200*2e8d1edaSArun Thomas enlarge_bufspace() 201*2e8d1edaSArun Thomas { 202*2e8d1edaSArun Thomas unsigned char *newbuf; 203*2e8d1edaSArun Thomas int i; 204*2e8d1edaSArun Thomas 205*2e8d1edaSArun Thomas bufsize += bufsize/2; 206*2e8d1edaSArun Thomas newbuf = xrealloc(buf, bufsize, "too many characters pushed back"); 207*2e8d1edaSArun Thomas for (i = 0; i < MAXINP; i++) 208*2e8d1edaSArun Thomas bbase[i] = (bbase[i]-buf)+newbuf; 209*2e8d1edaSArun Thomas bp = (bp-buf)+newbuf; 210*2e8d1edaSArun Thomas bufbase = (bufbase-buf)+newbuf; 211*2e8d1edaSArun Thomas buf = newbuf; 212*2e8d1edaSArun Thomas endpbb = buf+bufsize; 213*2e8d1edaSArun Thomas } 214*2e8d1edaSArun Thomas 215*2e8d1edaSArun Thomas /* 216*2e8d1edaSArun Thomas * chrsave - put single char on string space 217*2e8d1edaSArun Thomas */ 218*2e8d1edaSArun Thomas void 219*2e8d1edaSArun Thomas chrsave(int c) 220*2e8d1edaSArun Thomas { 221*2e8d1edaSArun Thomas if (ep >= endest) 222*2e8d1edaSArun Thomas enlarge_strspace(); 223*2e8d1edaSArun Thomas *ep++ = c; 224*2e8d1edaSArun Thomas } 225*2e8d1edaSArun Thomas 226*2e8d1edaSArun Thomas /* 227*2e8d1edaSArun Thomas * read in a diversion file, and dispose it. 228*2e8d1edaSArun Thomas */ 229*2e8d1edaSArun Thomas void 230*2e8d1edaSArun Thomas getdiv(int n) 231*2e8d1edaSArun Thomas { 232*2e8d1edaSArun Thomas int c; 233*2e8d1edaSArun Thomas 234*2e8d1edaSArun Thomas if (active == outfile[n]) 235*2e8d1edaSArun Thomas m4errx(1, "undivert: diversion still active."); 236*2e8d1edaSArun Thomas rewind(outfile[n]); 237*2e8d1edaSArun Thomas while ((c = getc(outfile[n])) != EOF) 238*2e8d1edaSArun Thomas putc(c, active); 239*2e8d1edaSArun Thomas (void) fclose(outfile[n]); 240*2e8d1edaSArun Thomas outfile[n] = NULL; 241*2e8d1edaSArun Thomas } 242*2e8d1edaSArun Thomas 243*2e8d1edaSArun Thomas void 244*2e8d1edaSArun Thomas onintr(int signo) 245*2e8d1edaSArun Thomas { 246*2e8d1edaSArun Thomas #define intrmessage "m4: interrupted.\n" 247*2e8d1edaSArun Thomas write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1); 248*2e8d1edaSArun Thomas _exit(1); 249*2e8d1edaSArun Thomas } 250*2e8d1edaSArun Thomas 251*2e8d1edaSArun Thomas /* 252*2e8d1edaSArun Thomas * killdiv - get rid of the diversion files 253*2e8d1edaSArun Thomas */ 254*2e8d1edaSArun Thomas void 255*2e8d1edaSArun Thomas killdiv() 256*2e8d1edaSArun Thomas { 257*2e8d1edaSArun Thomas int n; 258*2e8d1edaSArun Thomas 259*2e8d1edaSArun Thomas for (n = 0; n < maxout; n++) 260*2e8d1edaSArun Thomas if (outfile[n] != NULL) { 261*2e8d1edaSArun Thomas (void) fclose(outfile[n]); 262*2e8d1edaSArun Thomas } 263*2e8d1edaSArun Thomas } 264*2e8d1edaSArun Thomas 265*2e8d1edaSArun Thomas void 266*2e8d1edaSArun Thomas m4errx(int exval, const char *fmt, ...) 267*2e8d1edaSArun Thomas { 268*2e8d1edaSArun Thomas fprintf(stderr, "%s: ", getprogname()); 269*2e8d1edaSArun Thomas fprintf(stderr, "%s at line %lu: ", CURRENT_NAME, CURRENT_LINE); 270*2e8d1edaSArun Thomas if (fmt != NULL) { 271*2e8d1edaSArun Thomas va_list ap; 272*2e8d1edaSArun Thomas 273*2e8d1edaSArun Thomas va_start(ap, fmt); 274*2e8d1edaSArun Thomas vfprintf(stderr, fmt, ap); 275*2e8d1edaSArun Thomas va_end(ap); 276*2e8d1edaSArun Thomas } 277*2e8d1edaSArun Thomas fprintf(stderr, "\n"); 278*2e8d1edaSArun Thomas exit(exval); 279*2e8d1edaSArun Thomas } 280*2e8d1edaSArun Thomas 281*2e8d1edaSArun Thomas /* 282*2e8d1edaSArun Thomas * resizedivs: allocate more diversion files */ 283*2e8d1edaSArun Thomas void 284*2e8d1edaSArun Thomas resizedivs(int n) 285*2e8d1edaSArun Thomas { 286*2e8d1edaSArun Thomas int i; 287*2e8d1edaSArun Thomas 288*2e8d1edaSArun Thomas outfile = (FILE **)xrealloc(outfile, sizeof(FILE *) * n, 289*2e8d1edaSArun Thomas "too many diverts %d", n); 290*2e8d1edaSArun Thomas for (i = maxout; i < n; i++) 291*2e8d1edaSArun Thomas outfile[i] = NULL; 292*2e8d1edaSArun Thomas maxout = n; 293*2e8d1edaSArun Thomas } 294*2e8d1edaSArun Thomas 295*2e8d1edaSArun Thomas void * 296*2e8d1edaSArun Thomas xalloc(size_t n, const char *fmt, ...) 297*2e8d1edaSArun Thomas { 298*2e8d1edaSArun Thomas void *p = malloc(n); 299*2e8d1edaSArun Thomas 300*2e8d1edaSArun Thomas if (p == NULL) { 301*2e8d1edaSArun Thomas if (fmt == NULL) 302*2e8d1edaSArun Thomas err(1, "malloc"); 303*2e8d1edaSArun Thomas else { 304*2e8d1edaSArun Thomas va_list va; 305*2e8d1edaSArun Thomas 306*2e8d1edaSArun Thomas va_start(va, fmt); 307*2e8d1edaSArun Thomas verr(1, fmt, va); 308*2e8d1edaSArun Thomas va_end(va); 309*2e8d1edaSArun Thomas } 310*2e8d1edaSArun Thomas } 311*2e8d1edaSArun Thomas return p; 312*2e8d1edaSArun Thomas } 313*2e8d1edaSArun Thomas 314*2e8d1edaSArun Thomas void * 315*2e8d1edaSArun Thomas xrealloc(void *old, size_t n, const char *fmt, ...) 316*2e8d1edaSArun Thomas { 317*2e8d1edaSArun Thomas char *p = realloc(old, n); 318*2e8d1edaSArun Thomas 319*2e8d1edaSArun Thomas if (p == NULL) { 320*2e8d1edaSArun Thomas free(old); 321*2e8d1edaSArun Thomas if (fmt == NULL) 322*2e8d1edaSArun Thomas err(1, "realloc"); 323*2e8d1edaSArun Thomas else { 324*2e8d1edaSArun Thomas va_list va; 325*2e8d1edaSArun Thomas 326*2e8d1edaSArun Thomas va_start(va, fmt); 327*2e8d1edaSArun Thomas verr(1, fmt, va); 328*2e8d1edaSArun Thomas va_end(va); 329*2e8d1edaSArun Thomas } 330*2e8d1edaSArun Thomas } 331*2e8d1edaSArun Thomas return p; 332*2e8d1edaSArun Thomas } 333*2e8d1edaSArun Thomas 334*2e8d1edaSArun Thomas char * 335*2e8d1edaSArun Thomas xstrdup(const char *s) 336*2e8d1edaSArun Thomas { 337*2e8d1edaSArun Thomas char *p = strdup(s); 338*2e8d1edaSArun Thomas if (p == NULL) 339*2e8d1edaSArun Thomas err(1, "strdup"); 340*2e8d1edaSArun Thomas return p; 341*2e8d1edaSArun Thomas } 342*2e8d1edaSArun Thomas 343*2e8d1edaSArun Thomas void 344*2e8d1edaSArun Thomas usage(void) 345*2e8d1edaSArun Thomas { 346*2e8d1edaSArun Thomas fprintf(stderr, "usage: %s [-gPs] [-Dname[=value]] [-d flags] " 347*2e8d1edaSArun Thomas "[-I dirname] [-o filename]\n" 348*2e8d1edaSArun Thomas "\t[-t macro] [-Uname] [file ...]\n", getprogname()); 349*2e8d1edaSArun Thomas exit(1); 350*2e8d1edaSArun Thomas } 351*2e8d1edaSArun Thomas 352*2e8d1edaSArun Thomas int 353*2e8d1edaSArun Thomas obtain_char(struct input_file *f) 354*2e8d1edaSArun Thomas { 355*2e8d1edaSArun Thomas if (f->c == EOF) 356*2e8d1edaSArun Thomas return EOF; 357*2e8d1edaSArun Thomas 358*2e8d1edaSArun Thomas f->c = fgetc(f->file); 359*2e8d1edaSArun Thomas if (f->c == '\n') 360*2e8d1edaSArun Thomas f->lineno++; 361*2e8d1edaSArun Thomas 362*2e8d1edaSArun Thomas return f->c; 363*2e8d1edaSArun Thomas } 364*2e8d1edaSArun Thomas 365*2e8d1edaSArun Thomas void 366*2e8d1edaSArun Thomas set_input(struct input_file *f, FILE *real, const char *name) 367*2e8d1edaSArun Thomas { 368*2e8d1edaSArun Thomas f->file = real; 369*2e8d1edaSArun Thomas f->lineno = 1; 370*2e8d1edaSArun Thomas f->c = 0; 371*2e8d1edaSArun Thomas f->name = xstrdup(name); 372*2e8d1edaSArun Thomas emit_synchline(); 373*2e8d1edaSArun Thomas } 374*2e8d1edaSArun Thomas 375*2e8d1edaSArun Thomas void 376*2e8d1edaSArun Thomas do_emit_synchline() 377*2e8d1edaSArun Thomas { 378*2e8d1edaSArun Thomas fprintf(active, "#line %lu \"%s\"\n", 379*2e8d1edaSArun Thomas infile[ilevel].lineno, infile[ilevel].name); 380*2e8d1edaSArun Thomas infile[ilevel].synch_lineno = infile[ilevel].lineno; 381*2e8d1edaSArun Thomas } 382*2e8d1edaSArun Thomas 383*2e8d1edaSArun Thomas void 384*2e8d1edaSArun Thomas release_input(struct input_file *f) 385*2e8d1edaSArun Thomas { 386*2e8d1edaSArun Thomas if (f->file != stdin) 387*2e8d1edaSArun Thomas fclose(f->file); 388*2e8d1edaSArun Thomas f->c = EOF; 389*2e8d1edaSArun Thomas /* 390*2e8d1edaSArun Thomas * XXX can't free filename, as there might still be 391*2e8d1edaSArun Thomas * error information pointing to it. 392*2e8d1edaSArun Thomas */ 393*2e8d1edaSArun Thomas } 394*2e8d1edaSArun Thomas 395*2e8d1edaSArun Thomas void 396*2e8d1edaSArun Thomas doprintlineno(struct input_file *f) 397*2e8d1edaSArun Thomas { 398*2e8d1edaSArun Thomas pbunsigned(f->lineno); 399*2e8d1edaSArun Thomas } 400*2e8d1edaSArun Thomas 401*2e8d1edaSArun Thomas void 402*2e8d1edaSArun Thomas doprintfilename(struct input_file *f) 403*2e8d1edaSArun Thomas { 404*2e8d1edaSArun Thomas pbstr(rquote); 405*2e8d1edaSArun Thomas pbstr(f->name); 406*2e8d1edaSArun Thomas pbstr(lquote); 407*2e8d1edaSArun Thomas } 408*2e8d1edaSArun Thomas 409*2e8d1edaSArun Thomas /* 410*2e8d1edaSArun Thomas * buffer_mark/dump_buffer: allows one to save a mark in a buffer, 411*2e8d1edaSArun Thomas * and later dump everything that was added since then to a file. 412*2e8d1edaSArun Thomas */ 413*2e8d1edaSArun Thomas size_t 414*2e8d1edaSArun Thomas buffer_mark() 415*2e8d1edaSArun Thomas { 416*2e8d1edaSArun Thomas return bp - buf; 417*2e8d1edaSArun Thomas } 418*2e8d1edaSArun Thomas 419*2e8d1edaSArun Thomas 420*2e8d1edaSArun Thomas void 421*2e8d1edaSArun Thomas dump_buffer(FILE *f, size_t m) 422*2e8d1edaSArun Thomas { 423*2e8d1edaSArun Thomas unsigned char *s; 424*2e8d1edaSArun Thomas 425*2e8d1edaSArun Thomas for (s = bp; (size_t)(s - buf) > m;) 426*2e8d1edaSArun Thomas fputc(*--s, f); 427*2e8d1edaSArun Thomas } 428