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 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 22*1ee2e5faSnakanon 23*1ee2e5faSnakanon /* 24*1ee2e5faSnakanon * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*1ee2e5faSnakanon * Use is subject to license terms. 26*1ee2e5faSnakanon */ 27*1ee2e5faSnakanon 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 31*1ee2e5faSnakanon #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <errno.h> 347c478bd9Sstevel@tonic-gate #include "awk.h" 357c478bd9Sstevel@tonic-gate #include "y.tab.h" 367c478bd9Sstevel@tonic-gate 37*1ee2e5faSnakanon uchar *recdata; 38*1ee2e5faSnakanon uchar *record; 39*1ee2e5faSnakanon size_t record_size; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate int donefld; /* 1 = implies rec broken into fields */ 427c478bd9Sstevel@tonic-gate int donerec; /* 1 = record is valid (no flds have changed) */ 437c478bd9Sstevel@tonic-gate 44*1ee2e5faSnakanon static struct fldtab_chunk { 45*1ee2e5faSnakanon struct fldtab_chunk *next; 46*1ee2e5faSnakanon Cell fields[FLD_INCR]; 47*1ee2e5faSnakanon } *fldtab_head, *fldtab_tail; 487c478bd9Sstevel@tonic-gate 49*1ee2e5faSnakanon static size_t fldtab_maxidx; 507c478bd9Sstevel@tonic-gate 51*1ee2e5faSnakanon static FILE *infile = NULL; 52*1ee2e5faSnakanon static uchar *file = (uchar*) ""; 53*1ee2e5faSnakanon static uchar *fields; 54*1ee2e5faSnakanon static size_t fields_size = LINE_INCR; 55*1ee2e5faSnakanon 56*1ee2e5faSnakanon static int maxfld = 0; /* last used field */ 57*1ee2e5faSnakanon static int argno = 1; /* current input argument number */ 58*1ee2e5faSnakanon 59*1ee2e5faSnakanon static uchar *getargv(int); 60*1ee2e5faSnakanon static void cleanfld(int, int); 61*1ee2e5faSnakanon static int refldbld(uchar *, uchar *); 62*1ee2e5faSnakanon static void bcheck2(int, int, int); 63*1ee2e5faSnakanon static void eprint(void); 64*1ee2e5faSnakanon static void bclass(int); 65*1ee2e5faSnakanon 66*1ee2e5faSnakanon static void 67*1ee2e5faSnakanon initgetrec(void) 687c478bd9Sstevel@tonic-gate { 697c478bd9Sstevel@tonic-gate int i; 707c478bd9Sstevel@tonic-gate uchar *p; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate for (i = 1; i < *ARGC; i++) { 737c478bd9Sstevel@tonic-gate if (!isclvar(p = getargv(i))) /* find 1st real filename */ 747c478bd9Sstevel@tonic-gate return; 757c478bd9Sstevel@tonic-gate setclvar(p); /* a commandline assignment before filename */ 767c478bd9Sstevel@tonic-gate argno++; 777c478bd9Sstevel@tonic-gate } 787c478bd9Sstevel@tonic-gate infile = stdin; /* no filenames, so use stdin */ 797c478bd9Sstevel@tonic-gate /* *FILENAME = file = (uchar*) "-"; */ 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 82*1ee2e5faSnakanon int 83*1ee2e5faSnakanon getrec(uchar **bufp, size_t *bufsizep) 847c478bd9Sstevel@tonic-gate { 857c478bd9Sstevel@tonic-gate int c; 867c478bd9Sstevel@tonic-gate static int firsttime = 1; 87*1ee2e5faSnakanon uchar_t *buf, *nbuf; 88*1ee2e5faSnakanon size_t len; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate if (firsttime) { 917c478bd9Sstevel@tonic-gate firsttime = 0; 927c478bd9Sstevel@tonic-gate initgetrec(); 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate dprintf(("RS=<%s>, FS=<%s>, ARGC=%f, FILENAME=%s\n", 957c478bd9Sstevel@tonic-gate *RS, *FS, *ARGC, *FILENAME)); 967c478bd9Sstevel@tonic-gate donefld = 0; 977c478bd9Sstevel@tonic-gate donerec = 1; 987c478bd9Sstevel@tonic-gate while (argno < *ARGC || infile == stdin) { 997c478bd9Sstevel@tonic-gate dprintf(("argno=%d, file=|%s|\n", argno, file)); 1007c478bd9Sstevel@tonic-gate if (infile == NULL) { /* have to open a new file */ 1017c478bd9Sstevel@tonic-gate file = getargv(argno); 1027c478bd9Sstevel@tonic-gate if (*file == '\0') { /* it's been zapped */ 1037c478bd9Sstevel@tonic-gate argno++; 1047c478bd9Sstevel@tonic-gate continue; 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate if (isclvar(file)) { /* a var=value arg */ 1077c478bd9Sstevel@tonic-gate setclvar(file); 1087c478bd9Sstevel@tonic-gate argno++; 1097c478bd9Sstevel@tonic-gate continue; 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate *FILENAME = file; 1127c478bd9Sstevel@tonic-gate dprintf(("opening file %s\n", file)); 1137c478bd9Sstevel@tonic-gate if (*file == '-' && *(file+1) == '\0') 1147c478bd9Sstevel@tonic-gate infile = stdin; 1157c478bd9Sstevel@tonic-gate else if ((infile = fopen((char *)file, "r")) == NULL) 1167c478bd9Sstevel@tonic-gate ERROR "can't open file %s", file FATAL; 117*1ee2e5faSnakanon (void) setfval(fnrloc, 0.0); 1187c478bd9Sstevel@tonic-gate } 119*1ee2e5faSnakanon c = readrec(&nbuf, &len, infile); 120*1ee2e5faSnakanon expand_buf(bufp, bufsizep, len); 121*1ee2e5faSnakanon buf = *bufp; 122*1ee2e5faSnakanon (void) memcpy(buf, nbuf, len); 123*1ee2e5faSnakanon buf[len] = '\0'; 124*1ee2e5faSnakanon free(nbuf); 125*1ee2e5faSnakanon 1267c478bd9Sstevel@tonic-gate if (c != 0 || buf[0] != '\0') { /* normal record */ 1277c478bd9Sstevel@tonic-gate if (buf == record) { 1287c478bd9Sstevel@tonic-gate if (!(recloc->tval & DONTFREE)) 1297c478bd9Sstevel@tonic-gate xfree(recloc->sval); 1307c478bd9Sstevel@tonic-gate recloc->sval = record; 1317c478bd9Sstevel@tonic-gate recloc->tval = REC | STR | DONTFREE; 132*1ee2e5faSnakanon if (is_number(recloc->sval)) { 133*1ee2e5faSnakanon recloc->fval = 134*1ee2e5faSnakanon atof((const char *)recloc->sval); 1357c478bd9Sstevel@tonic-gate recloc->tval |= NUM; 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate } 138*1ee2e5faSnakanon (void) setfval(nrloc, nrloc->fval+1); 139*1ee2e5faSnakanon (void) setfval(fnrloc, fnrloc->fval+1); 1407c478bd9Sstevel@tonic-gate return (1); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate /* EOF arrived on this file; set up next */ 1437c478bd9Sstevel@tonic-gate if (infile != stdin) 144*1ee2e5faSnakanon (void) fclose(infile); 1457c478bd9Sstevel@tonic-gate infile = NULL; 1467c478bd9Sstevel@tonic-gate argno++; 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate return (0); /* true end of file */ 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 151*1ee2e5faSnakanon int 152*1ee2e5faSnakanon readrec(uchar **bufp, size_t *sizep, FILE *inf) /* read one record into buf */ 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate register int sep, c; 155*1ee2e5faSnakanon uchar *buf; 1567c478bd9Sstevel@tonic-gate int count; 157*1ee2e5faSnakanon size_t bufsize; 1587c478bd9Sstevel@tonic-gate 159*1ee2e5faSnakanon init_buf(&buf, &bufsize, LINE_INCR); 1607c478bd9Sstevel@tonic-gate if ((sep = **RS) == 0) { 1617c478bd9Sstevel@tonic-gate sep = '\n'; 1627c478bd9Sstevel@tonic-gate /* skip leading \n's */ 1637c478bd9Sstevel@tonic-gate while ((c = getc(inf)) == '\n' && c != EOF) 1647c478bd9Sstevel@tonic-gate ; 1657c478bd9Sstevel@tonic-gate if (c != EOF) 166*1ee2e5faSnakanon (void) ungetc(c, inf); 1677c478bd9Sstevel@tonic-gate } 168*1ee2e5faSnakanon count = 0; 169*1ee2e5faSnakanon for (;;) { 1707c478bd9Sstevel@tonic-gate while ((c = getc(inf)) != sep && c != EOF) { 171*1ee2e5faSnakanon expand_buf(&buf, &bufsize, count); 172*1ee2e5faSnakanon buf[count++] = c; 1737c478bd9Sstevel@tonic-gate } 1747c478bd9Sstevel@tonic-gate if (**RS == sep || c == EOF) 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */ 1777c478bd9Sstevel@tonic-gate break; 178*1ee2e5faSnakanon expand_buf(&buf, &bufsize, count + 1); 179*1ee2e5faSnakanon buf[count++] = '\n'; 180*1ee2e5faSnakanon buf[count++] = c; 1817c478bd9Sstevel@tonic-gate } 182*1ee2e5faSnakanon buf[count] = '\0'; 1837c478bd9Sstevel@tonic-gate dprintf(("readrec saw <%s>, returns %d\n", 184*1ee2e5faSnakanon buf, c == EOF && count == 0 ? 0 : 1)); 185*1ee2e5faSnakanon *bufp = buf; 186*1ee2e5faSnakanon *sizep = count; 187*1ee2e5faSnakanon return (c == EOF && count == 0 ? 0 : 1); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate /* get ARGV[n] */ 191*1ee2e5faSnakanon static uchar * 192*1ee2e5faSnakanon getargv(int n) 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate Cell *x; 195*1ee2e5faSnakanon uchar *s, temp[11]; 1967c478bd9Sstevel@tonic-gate extern Array *ARGVtab; 1977c478bd9Sstevel@tonic-gate 198*1ee2e5faSnakanon (void) sprintf((char *)temp, "%d", n); 199*1ee2e5faSnakanon x = setsymtab(temp, (uchar *)"", 0.0, STR, ARGVtab); 2007c478bd9Sstevel@tonic-gate s = getsval(x); 2017c478bd9Sstevel@tonic-gate dprintf(("getargv(%d) returns |%s|\n", n, s)); 2027c478bd9Sstevel@tonic-gate return (s); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 205*1ee2e5faSnakanon void 206*1ee2e5faSnakanon setclvar(uchar *s) /* set var=value from s */ 2077c478bd9Sstevel@tonic-gate { 2087c478bd9Sstevel@tonic-gate uchar *p; 2097c478bd9Sstevel@tonic-gate Cell *q; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate for (p = s; *p != '='; p++) 2127c478bd9Sstevel@tonic-gate ; 2137c478bd9Sstevel@tonic-gate *p++ = 0; 2147c478bd9Sstevel@tonic-gate p = qstring(p, '\0'); 2157c478bd9Sstevel@tonic-gate q = setsymtab(s, p, 0.0, STR, symtab); 216*1ee2e5faSnakanon (void) setsval(q, p); 217*1ee2e5faSnakanon if (is_number(q->sval)) { 218*1ee2e5faSnakanon q->fval = atof((const char *)q->sval); 2197c478bd9Sstevel@tonic-gate q->tval |= NUM; 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate dprintf(("command line set %s to |%s|\n", s, p)); 222*1ee2e5faSnakanon free(p); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 225*1ee2e5faSnakanon void 226*1ee2e5faSnakanon fldbld(void) 2277c478bd9Sstevel@tonic-gate { 2287c478bd9Sstevel@tonic-gate register uchar *r, *fr, sep; 2297c478bd9Sstevel@tonic-gate Cell *p; 2307c478bd9Sstevel@tonic-gate int i; 231*1ee2e5faSnakanon size_t len; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate if (donefld) 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate if (!(recloc->tval & STR)) 236*1ee2e5faSnakanon (void) getsval(recloc); 2377c478bd9Sstevel@tonic-gate r = recloc->sval; /* was record! */ 238*1ee2e5faSnakanon 239*1ee2e5faSnakanon /* make sure fields is always allocated */ 240*1ee2e5faSnakanon adjust_buf(&fields, fields_size); 241*1ee2e5faSnakanon 242*1ee2e5faSnakanon /* 243*1ee2e5faSnakanon * make sure fields has enough size. We don't expand the buffer 244*1ee2e5faSnakanon * in the middle of the loop, since p->sval has already pointed 245*1ee2e5faSnakanon * the address in the fields. 246*1ee2e5faSnakanon */ 247*1ee2e5faSnakanon len = strlen((char *)r) + 1; 248*1ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 2497c478bd9Sstevel@tonic-gate fr = fields; 250*1ee2e5faSnakanon 2517c478bd9Sstevel@tonic-gate i = 0; /* number of fields accumulated here */ 252*1ee2e5faSnakanon if (strlen((char *)*FS) > 1) { /* it's a regular expression */ 2537c478bd9Sstevel@tonic-gate i = refldbld(r, *FS); 2547c478bd9Sstevel@tonic-gate } else if ((sep = **FS) == ' ') { 2557c478bd9Sstevel@tonic-gate for (i = 0; ; ) { 2567c478bd9Sstevel@tonic-gate while (*r == ' ' || *r == '\t' || *r == '\n') 2577c478bd9Sstevel@tonic-gate r++; 2587c478bd9Sstevel@tonic-gate if (*r == 0) 2597c478bd9Sstevel@tonic-gate break; 2607c478bd9Sstevel@tonic-gate i++; 261*1ee2e5faSnakanon p = getfld(i); 262*1ee2e5faSnakanon if (!(p->tval & DONTFREE)) 263*1ee2e5faSnakanon xfree(p->sval); 264*1ee2e5faSnakanon p->sval = fr; 265*1ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 2667c478bd9Sstevel@tonic-gate do 2677c478bd9Sstevel@tonic-gate *fr++ = *r++; 2687c478bd9Sstevel@tonic-gate while (*r != ' ' && *r != '\t' && *r != '\n' && 269*1ee2e5faSnakanon *r != '\0') 270*1ee2e5faSnakanon ; 2717c478bd9Sstevel@tonic-gate *fr++ = 0; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate *fr = 0; 2747c478bd9Sstevel@tonic-gate } else if (*r != 0) { /* if 0, it's a null field */ 2757c478bd9Sstevel@tonic-gate for (;;) { 2767c478bd9Sstevel@tonic-gate i++; 277*1ee2e5faSnakanon p = getfld(i); 278*1ee2e5faSnakanon if (!(p->tval & DONTFREE)) 279*1ee2e5faSnakanon xfree(p->sval); 280*1ee2e5faSnakanon p->sval = fr; 281*1ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 2827c478bd9Sstevel@tonic-gate /* \n always a separator */ 2837c478bd9Sstevel@tonic-gate while (*r != sep && *r != '\n' && *r != '\0') 2847c478bd9Sstevel@tonic-gate *fr++ = *r++; 2857c478bd9Sstevel@tonic-gate *fr++ = 0; 2867c478bd9Sstevel@tonic-gate if (*r++ == 0) 2877c478bd9Sstevel@tonic-gate break; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate *fr = 0; 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate /* clean out junk from previous record */ 2927c478bd9Sstevel@tonic-gate cleanfld(i, maxfld); 2937c478bd9Sstevel@tonic-gate maxfld = i; 2947c478bd9Sstevel@tonic-gate donefld = 1; 295*1ee2e5faSnakanon for (i = 1; i <= maxfld; i++) { 296*1ee2e5faSnakanon p = getfld(i); 297*1ee2e5faSnakanon if (is_number(p->sval)) { 298*1ee2e5faSnakanon p->fval = atof((const char *)p->sval); 2997c478bd9Sstevel@tonic-gate p->tval |= NUM; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate } 302*1ee2e5faSnakanon 303*1ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) maxfld); 304*1ee2e5faSnakanon if (dbg) { 305*1ee2e5faSnakanon for (i = 0; i <= maxfld; i++) { 306*1ee2e5faSnakanon p = getfld(i); 307*1ee2e5faSnakanon (void) printf("field %d: |%s|\n", i, p->sval); 308*1ee2e5faSnakanon } 309*1ee2e5faSnakanon } 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 312*1ee2e5faSnakanon static void 313*1ee2e5faSnakanon cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */ 3147c478bd9Sstevel@tonic-gate { 3157c478bd9Sstevel@tonic-gate static uchar *nullstat = (uchar *) ""; 316*1ee2e5faSnakanon register Cell *p; 317*1ee2e5faSnakanon int i; 3187c478bd9Sstevel@tonic-gate 319*1ee2e5faSnakanon for (i = n2; i > n1; i--) { 320*1ee2e5faSnakanon p = getfld(i); 3217c478bd9Sstevel@tonic-gate if (!(p->tval & DONTFREE)) 3227c478bd9Sstevel@tonic-gate xfree(p->sval); 3237c478bd9Sstevel@tonic-gate p->tval = FLD | STR | DONTFREE; 3247c478bd9Sstevel@tonic-gate p->sval = nullstat; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 328*1ee2e5faSnakanon void 329*1ee2e5faSnakanon newfld(int n) /* add field n (after end) */ 3307c478bd9Sstevel@tonic-gate { 331*1ee2e5faSnakanon if (n < 0) 332*1ee2e5faSnakanon ERROR "accessing invalid field", record FATAL; 333*1ee2e5faSnakanon (void) getfld(n); 3347c478bd9Sstevel@tonic-gate cleanfld(maxfld, n); 3357c478bd9Sstevel@tonic-gate maxfld = n; 336*1ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) n); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 339*1ee2e5faSnakanon /* 340*1ee2e5faSnakanon * allocate field table. We don't reallocate the table since there 341*1ee2e5faSnakanon * might be somewhere recording the address of the table. 342*1ee2e5faSnakanon */ 343*1ee2e5faSnakanon static void 344*1ee2e5faSnakanon morefld(void) 3457c478bd9Sstevel@tonic-gate { 346*1ee2e5faSnakanon int i; 347*1ee2e5faSnakanon struct fldtab_chunk *fldcp; 348*1ee2e5faSnakanon Cell *newfld; 349*1ee2e5faSnakanon 350*1ee2e5faSnakanon if ((fldcp = calloc(sizeof (struct fldtab_chunk), 1)) == NULL) 351*1ee2e5faSnakanon ERROR "out of space in morefld" FATAL; 352*1ee2e5faSnakanon 353*1ee2e5faSnakanon newfld = &fldcp->fields[0]; 354*1ee2e5faSnakanon for (i = 0; i < FLD_INCR; i++) { 355*1ee2e5faSnakanon newfld[i].ctype = OCELL; 356*1ee2e5faSnakanon newfld[i].csub = CFLD; 357*1ee2e5faSnakanon newfld[i].nval = NULL; 358*1ee2e5faSnakanon newfld[i].sval = (uchar *)""; 359*1ee2e5faSnakanon newfld[i].fval = 0.0; 360*1ee2e5faSnakanon newfld[i].tval = FLD|STR|DONTFREE; 361*1ee2e5faSnakanon newfld[i].cnext = NULL; 362*1ee2e5faSnakanon } 363*1ee2e5faSnakanon /* 364*1ee2e5faSnakanon * link this field chunk 365*1ee2e5faSnakanon */ 366*1ee2e5faSnakanon if (fldtab_head == NULL) 367*1ee2e5faSnakanon fldtab_head = fldcp; 368*1ee2e5faSnakanon else 369*1ee2e5faSnakanon fldtab_tail->next = fldcp; 370*1ee2e5faSnakanon fldtab_tail = fldcp; 371*1ee2e5faSnakanon fldcp->next = NULL; 372*1ee2e5faSnakanon 373*1ee2e5faSnakanon fldtab_maxidx += FLD_INCR; 374*1ee2e5faSnakanon } 375*1ee2e5faSnakanon 376*1ee2e5faSnakanon Cell * 377*1ee2e5faSnakanon getfld(int idx) 378*1ee2e5faSnakanon { 379*1ee2e5faSnakanon struct fldtab_chunk *fldcp; 380*1ee2e5faSnakanon int cbase; 381*1ee2e5faSnakanon 382*1ee2e5faSnakanon if (idx < 0) 383*1ee2e5faSnakanon ERROR "trying to access field %d", idx FATAL; 384*1ee2e5faSnakanon while (idx >= fldtab_maxidx) 385*1ee2e5faSnakanon morefld(); 386*1ee2e5faSnakanon cbase = 0; 387*1ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 388*1ee2e5faSnakanon if (idx < (cbase + FLD_INCR)) 389*1ee2e5faSnakanon return (&fldcp->fields[idx - cbase]); 390*1ee2e5faSnakanon cbase += FLD_INCR; 391*1ee2e5faSnakanon } 392*1ee2e5faSnakanon /* should never happen */ 393*1ee2e5faSnakanon ERROR "trying to access invalid field %d", idx FATAL; 394*1ee2e5faSnakanon return (NULL); 395*1ee2e5faSnakanon } 396*1ee2e5faSnakanon 397*1ee2e5faSnakanon int 398*1ee2e5faSnakanon fldidx(Cell *vp) 399*1ee2e5faSnakanon { 400*1ee2e5faSnakanon struct fldtab_chunk *fldcp; 401*1ee2e5faSnakanon Cell *tbl; 402*1ee2e5faSnakanon int cbase; 403*1ee2e5faSnakanon 404*1ee2e5faSnakanon cbase = 0; 405*1ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 406*1ee2e5faSnakanon tbl = &fldcp->fields[0]; 407*1ee2e5faSnakanon if (vp >= tbl && vp < (tbl + FLD_INCR)) 408*1ee2e5faSnakanon return (cbase + (vp - tbl)); 409*1ee2e5faSnakanon cbase += FLD_INCR; 410*1ee2e5faSnakanon } 411*1ee2e5faSnakanon /* should never happen */ 412*1ee2e5faSnakanon ERROR "trying to access unknown field" FATAL; 413*1ee2e5faSnakanon return (0); 414*1ee2e5faSnakanon } 415*1ee2e5faSnakanon 416*1ee2e5faSnakanon static int 417*1ee2e5faSnakanon refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */ 418*1ee2e5faSnakanon { 4197c478bd9Sstevel@tonic-gate uchar *fr; 4207c478bd9Sstevel@tonic-gate int i, tempstat; 4217c478bd9Sstevel@tonic-gate fa *pfa; 422*1ee2e5faSnakanon Cell *p; 423*1ee2e5faSnakanon size_t len; 4247c478bd9Sstevel@tonic-gate 425*1ee2e5faSnakanon /* make sure fields is allocated */ 426*1ee2e5faSnakanon adjust_buf(&fields, fields_size); 4277c478bd9Sstevel@tonic-gate fr = fields; 4287c478bd9Sstevel@tonic-gate *fr = '\0'; 4297c478bd9Sstevel@tonic-gate if (*rec == '\0') 4307c478bd9Sstevel@tonic-gate return (0); 431*1ee2e5faSnakanon 432*1ee2e5faSnakanon len = strlen((char *)rec) + 1; 433*1ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 434*1ee2e5faSnakanon fr = fields; 435*1ee2e5faSnakanon 4367c478bd9Sstevel@tonic-gate pfa = makedfa(fs, 1); 4377c478bd9Sstevel@tonic-gate dprintf(("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs)); 4387c478bd9Sstevel@tonic-gate tempstat = pfa->initstat; 439*1ee2e5faSnakanon for (i = 1; ; i++) { 440*1ee2e5faSnakanon p = getfld(i); 441*1ee2e5faSnakanon if (!(p->tval & DONTFREE)) 442*1ee2e5faSnakanon xfree(p->sval); 443*1ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 444*1ee2e5faSnakanon p->sval = fr; 4457c478bd9Sstevel@tonic-gate dprintf(("refldbld: i=%d\n", i)); 4467c478bd9Sstevel@tonic-gate if (nematch(pfa, rec)) { 4477c478bd9Sstevel@tonic-gate pfa->initstat = 2; 4487c478bd9Sstevel@tonic-gate dprintf(("match %s (%d chars)\n", patbeg, patlen)); 449*1ee2e5faSnakanon (void) strncpy((char *)fr, (char *)rec, patbeg-rec); 4507c478bd9Sstevel@tonic-gate fr += patbeg - rec + 1; 4517c478bd9Sstevel@tonic-gate *(fr-1) = '\0'; 4527c478bd9Sstevel@tonic-gate rec = patbeg + patlen; 4537c478bd9Sstevel@tonic-gate } else { 4547c478bd9Sstevel@tonic-gate dprintf(("no match %s\n", rec)); 455*1ee2e5faSnakanon (void) strcpy((char *)fr, (char *)rec); 4567c478bd9Sstevel@tonic-gate pfa->initstat = tempstat; 4577c478bd9Sstevel@tonic-gate break; 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate return (i); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 463*1ee2e5faSnakanon void 464*1ee2e5faSnakanon recbld(void) 4657c478bd9Sstevel@tonic-gate { 4667c478bd9Sstevel@tonic-gate int i; 467*1ee2e5faSnakanon register uchar *p; 468*1ee2e5faSnakanon size_t cnt, len, olen; 469*1ee2e5faSnakanon static uchar *rec; 470*1ee2e5faSnakanon size_t osize, nsize; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate if (donerec == 1) 4737c478bd9Sstevel@tonic-gate return; 474*1ee2e5faSnakanon /* sync up rec size */ 475*1ee2e5faSnakanon adjust_buf(&rec, record_size); 476*1ee2e5faSnakanon cnt = 0; 477*1ee2e5faSnakanon olen = strlen((char *)*OFS); 4787c478bd9Sstevel@tonic-gate for (i = 1; i <= *NF; i++) { 479*1ee2e5faSnakanon p = getsval(getfld(i)); 480*1ee2e5faSnakanon len = strlen((char *)p); 481*1ee2e5faSnakanon osize = record_size; 482*1ee2e5faSnakanon nsize = cnt + len + olen; 483*1ee2e5faSnakanon expand_buf(&rec, &record_size, nsize); 484*1ee2e5faSnakanon if (osize != record_size) 485*1ee2e5faSnakanon adjust_buf(&recdata, record_size); 486*1ee2e5faSnakanon (void) memcpy(&rec[cnt], p, len); 487*1ee2e5faSnakanon cnt += len; 488*1ee2e5faSnakanon if (i < *NF) { 489*1ee2e5faSnakanon (void) memcpy(&rec[cnt], *OFS, olen); 490*1ee2e5faSnakanon cnt += olen; 4917c478bd9Sstevel@tonic-gate } 492*1ee2e5faSnakanon } 493*1ee2e5faSnakanon rec[cnt] = '\0'; 494*1ee2e5faSnakanon dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); 4957c478bd9Sstevel@tonic-gate recloc->tval = REC | STR | DONTFREE; 4967c478bd9Sstevel@tonic-gate recloc->sval = record = rec; 497*1ee2e5faSnakanon dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); 4987c478bd9Sstevel@tonic-gate dprintf(("recbld = |%s|\n", record)); 4997c478bd9Sstevel@tonic-gate donerec = 1; 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate Cell * 503*1ee2e5faSnakanon fieldadr(int n) 5047c478bd9Sstevel@tonic-gate { 505*1ee2e5faSnakanon if (n < 0) 5067c478bd9Sstevel@tonic-gate ERROR "trying to access field %d", n FATAL; 507*1ee2e5faSnakanon return (getfld(n)); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate int errorflag = 0; 5117c478bd9Sstevel@tonic-gate char errbuf[200]; 5127c478bd9Sstevel@tonic-gate 513*1ee2e5faSnakanon void 514*1ee2e5faSnakanon yyerror(char *s) 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate extern uchar *cmdname, *curfname; 5177c478bd9Sstevel@tonic-gate static int been_here = 0; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate if (been_here++ > 2) 5207c478bd9Sstevel@tonic-gate return; 521*1ee2e5faSnakanon (void) fprintf(stderr, "%s: %s", cmdname, s); 522*1ee2e5faSnakanon (void) fprintf(stderr, gettext(" at source line %lld"), lineno); 5237c478bd9Sstevel@tonic-gate if (curfname != NULL) 524*1ee2e5faSnakanon (void) fprintf(stderr, gettext(" in function %s"), curfname); 525*1ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5267c478bd9Sstevel@tonic-gate errorflag = 2; 5277c478bd9Sstevel@tonic-gate eprint(); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 530*1ee2e5faSnakanon /*ARGSUSED*/ 531*1ee2e5faSnakanon void 532*1ee2e5faSnakanon fpecatch(int sig) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate ERROR "floating point exception" FATAL; 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate extern int bracecnt, brackcnt, parencnt; 5387c478bd9Sstevel@tonic-gate 539*1ee2e5faSnakanon void 540*1ee2e5faSnakanon bracecheck(void) 5417c478bd9Sstevel@tonic-gate { 5427c478bd9Sstevel@tonic-gate int c; 5437c478bd9Sstevel@tonic-gate static int beenhere = 0; 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate if (beenhere++) 5467c478bd9Sstevel@tonic-gate return; 5477c478bd9Sstevel@tonic-gate while ((c = input()) != EOF && c != '\0') 5487c478bd9Sstevel@tonic-gate bclass(c); 5497c478bd9Sstevel@tonic-gate bcheck2(bracecnt, '{', '}'); 5507c478bd9Sstevel@tonic-gate bcheck2(brackcnt, '[', ']'); 5517c478bd9Sstevel@tonic-gate bcheck2(parencnt, '(', ')'); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 554*1ee2e5faSnakanon /*ARGSUSED*/ 555*1ee2e5faSnakanon static void 556*1ee2e5faSnakanon bcheck2(int n, int c1, int c2) 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate if (n == 1) 559*1ee2e5faSnakanon (void) fprintf(stderr, gettext("\tmissing %c\n"), c2); 5607c478bd9Sstevel@tonic-gate else if (n > 1) 561*1ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d missing %c's\n"), n, c2); 5627c478bd9Sstevel@tonic-gate else if (n == -1) 563*1ee2e5faSnakanon (void) fprintf(stderr, gettext("\textra %c\n"), c2); 5647c478bd9Sstevel@tonic-gate else if (n < -1) 565*1ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate 568*1ee2e5faSnakanon void 569*1ee2e5faSnakanon error(int f, char *s) 5707c478bd9Sstevel@tonic-gate { 5717c478bd9Sstevel@tonic-gate extern Node *curnode; 5727c478bd9Sstevel@tonic-gate extern uchar *cmdname; 5737c478bd9Sstevel@tonic-gate 574*1ee2e5faSnakanon (void) fflush(stdout); 575*1ee2e5faSnakanon (void) fprintf(stderr, "%s: ", cmdname); 576*1ee2e5faSnakanon (void) fprintf(stderr, "%s", s); 577*1ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5787c478bd9Sstevel@tonic-gate if (compile_time != 2 && NR && *NR > 0) { 579*1ee2e5faSnakanon (void) fprintf(stderr, 580*1ee2e5faSnakanon gettext(" input record number %g"), *FNR); 581*1ee2e5faSnakanon if (strcmp((char *)*FILENAME, "-") != 0) 582*1ee2e5faSnakanon (void) fprintf(stderr, gettext(", file %s"), *FILENAME); 583*1ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate if (compile_time != 2 && curnode) 586*1ee2e5faSnakanon (void) fprintf(stderr, gettext(" source line number %lld\n"), 5877c478bd9Sstevel@tonic-gate curnode->lineno); 588*1ee2e5faSnakanon else if (compile_time != 2 && lineno) { 589*1ee2e5faSnakanon (void) fprintf(stderr, 590*1ee2e5faSnakanon gettext(" source line number %lld\n"), lineno); 591*1ee2e5faSnakanon } 5927c478bd9Sstevel@tonic-gate eprint(); 5937c478bd9Sstevel@tonic-gate if (f) { 5947c478bd9Sstevel@tonic-gate if (dbg) 5957c478bd9Sstevel@tonic-gate abort(); 5967c478bd9Sstevel@tonic-gate exit(2); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate 600*1ee2e5faSnakanon static void 601*1ee2e5faSnakanon eprint(void) /* try to print context around error */ 6027c478bd9Sstevel@tonic-gate { 6037c478bd9Sstevel@tonic-gate uchar *p, *q; 6047c478bd9Sstevel@tonic-gate int c; 6057c478bd9Sstevel@tonic-gate static int been_here = 0; 6067c478bd9Sstevel@tonic-gate extern uchar ebuf[300], *ep; 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate if (compile_time == 2 || compile_time == 0 || been_here++ > 0) 6097c478bd9Sstevel@tonic-gate return; 6107c478bd9Sstevel@tonic-gate p = ep - 1; 6117c478bd9Sstevel@tonic-gate if (p > ebuf && *p == '\n') 6127c478bd9Sstevel@tonic-gate p--; 6137c478bd9Sstevel@tonic-gate for (; p > ebuf && *p != '\n' && *p != '\0'; p--) 6147c478bd9Sstevel@tonic-gate ; 6157c478bd9Sstevel@tonic-gate while (*p == '\n') 6167c478bd9Sstevel@tonic-gate p++; 617*1ee2e5faSnakanon (void) fprintf(stderr, gettext(" context is\n\t")); 618*1ee2e5faSnakanon for (q = ep-1; q >= p && *q != ' ' && *q != '\t' && *q != '\n'; q--) 6197c478bd9Sstevel@tonic-gate ; 6207c478bd9Sstevel@tonic-gate for (; p < q; p++) 6217c478bd9Sstevel@tonic-gate if (*p) 622*1ee2e5faSnakanon (void) putc(*p, stderr); 623*1ee2e5faSnakanon (void) fprintf(stderr, " >>> "); 6247c478bd9Sstevel@tonic-gate for (; p < ep; p++) 6257c478bd9Sstevel@tonic-gate if (*p) 626*1ee2e5faSnakanon (void) putc(*p, stderr); 627*1ee2e5faSnakanon (void) fprintf(stderr, " <<< "); 6287c478bd9Sstevel@tonic-gate if (*ep) 6297c478bd9Sstevel@tonic-gate while ((c = input()) != '\n' && c != '\0' && c != EOF) { 630*1ee2e5faSnakanon (void) putc(c, stderr); 6317c478bd9Sstevel@tonic-gate bclass(c); 6327c478bd9Sstevel@tonic-gate } 633*1ee2e5faSnakanon (void) putc('\n', stderr); 6347c478bd9Sstevel@tonic-gate ep = ebuf; 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate 637*1ee2e5faSnakanon static void 638*1ee2e5faSnakanon bclass(int c) 6397c478bd9Sstevel@tonic-gate { 6407c478bd9Sstevel@tonic-gate switch (c) { 6417c478bd9Sstevel@tonic-gate case '{': bracecnt++; break; 6427c478bd9Sstevel@tonic-gate case '}': bracecnt--; break; 6437c478bd9Sstevel@tonic-gate case '[': brackcnt++; break; 6447c478bd9Sstevel@tonic-gate case ']': brackcnt--; break; 6457c478bd9Sstevel@tonic-gate case '(': parencnt++; break; 6467c478bd9Sstevel@tonic-gate case ')': parencnt--; break; 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate double 651*1ee2e5faSnakanon errcheck(double x, char *s) 6527c478bd9Sstevel@tonic-gate { 6537c478bd9Sstevel@tonic-gate extern int errno; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate if (errno == EDOM) { 6567c478bd9Sstevel@tonic-gate errno = 0; 6577c478bd9Sstevel@tonic-gate ERROR "%s argument out of domain", s WARNING; 6587c478bd9Sstevel@tonic-gate x = 1; 6597c478bd9Sstevel@tonic-gate } else if (errno == ERANGE) { 6607c478bd9Sstevel@tonic-gate errno = 0; 6617c478bd9Sstevel@tonic-gate ERROR "%s result out of range", s WARNING; 6627c478bd9Sstevel@tonic-gate x = 1; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate return (x); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 667*1ee2e5faSnakanon void 668*1ee2e5faSnakanon PUTS(uchar *s) 669*1ee2e5faSnakanon { 6707c478bd9Sstevel@tonic-gate dprintf(("%s\n", s)); 6717c478bd9Sstevel@tonic-gate } 6727c478bd9Sstevel@tonic-gate 673*1ee2e5faSnakanon int 674*1ee2e5faSnakanon isclvar(uchar *s) /* is s of form var=something? */ 6757c478bd9Sstevel@tonic-gate { 676*1ee2e5faSnakanon uchar *os = s; 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate for (; *s; s++) 6797c478bd9Sstevel@tonic-gate if (!(isalnum(*s) || *s == '_')) 6807c478bd9Sstevel@tonic-gate break; 6817c478bd9Sstevel@tonic-gate return (*s == '=' && s > os && *(s + 1) != '='); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate #define MAXEXPON 38 /* maximum exponent for fp number */ 6857c478bd9Sstevel@tonic-gate 686*1ee2e5faSnakanon int 687*1ee2e5faSnakanon is_number(uchar *s) 6887c478bd9Sstevel@tonic-gate { 6897c478bd9Sstevel@tonic-gate register int d1, d2; 6907c478bd9Sstevel@tonic-gate int point; 6917c478bd9Sstevel@tonic-gate uchar *es; 6927c478bd9Sstevel@tonic-gate extern char radixpoint; 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate d1 = d2 = point = 0; 6957c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 6967c478bd9Sstevel@tonic-gate s++; 6977c478bd9Sstevel@tonic-gate if (*s == '\0') 6987c478bd9Sstevel@tonic-gate return (0); /* empty stuff isn't number */ 6997c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7007c478bd9Sstevel@tonic-gate s++; 7017c478bd9Sstevel@tonic-gate if (!isdigit(*s) && *s != radixpoint) 7027c478bd9Sstevel@tonic-gate return (0); 7037c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7047c478bd9Sstevel@tonic-gate do { 7057c478bd9Sstevel@tonic-gate d1++; 7067c478bd9Sstevel@tonic-gate s++; 7077c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate if (d1 >= MAXEXPON) 7107c478bd9Sstevel@tonic-gate return (0); /* too many digits to convert */ 7117c478bd9Sstevel@tonic-gate if (*s == radixpoint) { 7127c478bd9Sstevel@tonic-gate point++; 7137c478bd9Sstevel@tonic-gate s++; 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7167c478bd9Sstevel@tonic-gate d2++; 7177c478bd9Sstevel@tonic-gate do { 7187c478bd9Sstevel@tonic-gate s++; 7197c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7207c478bd9Sstevel@tonic-gate } 7217c478bd9Sstevel@tonic-gate if (!(d1 || point && d2)) 7227c478bd9Sstevel@tonic-gate return (0); 7237c478bd9Sstevel@tonic-gate if (*s == 'e' || *s == 'E') { 7247c478bd9Sstevel@tonic-gate s++; 7257c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7267c478bd9Sstevel@tonic-gate s++; 7277c478bd9Sstevel@tonic-gate if (!isdigit(*s)) 7287c478bd9Sstevel@tonic-gate return (0); 7297c478bd9Sstevel@tonic-gate es = s; 7307c478bd9Sstevel@tonic-gate do { 7317c478bd9Sstevel@tonic-gate s++; 7327c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 733*1ee2e5faSnakanon if (s - es > 2) { 7347c478bd9Sstevel@tonic-gate return (0); 735*1ee2e5faSnakanon } else if (s - es == 2 && 736*1ee2e5faSnakanon (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) { 7377c478bd9Sstevel@tonic-gate return (0); 7387c478bd9Sstevel@tonic-gate } 739*1ee2e5faSnakanon } 7407c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 7417c478bd9Sstevel@tonic-gate s++; 7427c478bd9Sstevel@tonic-gate if (*s == '\0') 7437c478bd9Sstevel@tonic-gate return (1); 7447c478bd9Sstevel@tonic-gate else 7457c478bd9Sstevel@tonic-gate return (0); 7467c478bd9Sstevel@tonic-gate } 747*1ee2e5faSnakanon 748*1ee2e5faSnakanon void 749*1ee2e5faSnakanon init_buf(uchar **optr, size_t *sizep, size_t amt) 750*1ee2e5faSnakanon { 751*1ee2e5faSnakanon uchar *nptr = NULL; 752*1ee2e5faSnakanon 753*1ee2e5faSnakanon if ((nptr = malloc(amt)) == NULL) 754*1ee2e5faSnakanon ERROR "out of space in init_buf" FATAL; 755*1ee2e5faSnakanon /* initial buffer should have NULL terminated */ 756*1ee2e5faSnakanon *nptr = '\0'; 757*1ee2e5faSnakanon if (sizep != NULL) 758*1ee2e5faSnakanon *sizep = amt; 759*1ee2e5faSnakanon *optr = nptr; 760*1ee2e5faSnakanon } 761*1ee2e5faSnakanon 762*1ee2e5faSnakanon void 763*1ee2e5faSnakanon r_expand_buf(uchar **optr, size_t *sizep, size_t req) 764*1ee2e5faSnakanon { 765*1ee2e5faSnakanon uchar *nptr; 766*1ee2e5faSnakanon size_t amt, size = *sizep; 767*1ee2e5faSnakanon 768*1ee2e5faSnakanon if (size != 0 && req < (size - 1)) 769*1ee2e5faSnakanon return; 770*1ee2e5faSnakanon amt = req + 1 - size; 771*1ee2e5faSnakanon amt = (amt / LINE_INCR + 1) * LINE_INCR; 772*1ee2e5faSnakanon 773*1ee2e5faSnakanon if ((nptr = realloc(*optr, size + amt)) == NULL) 774*1ee2e5faSnakanon ERROR "out of space in expand_buf" FATAL; 775*1ee2e5faSnakanon /* initial buffer should have NULL terminated */ 776*1ee2e5faSnakanon if (size == 0) 777*1ee2e5faSnakanon *nptr = '\0'; 778*1ee2e5faSnakanon *sizep += amt; 779*1ee2e5faSnakanon *optr = nptr; 780*1ee2e5faSnakanon } 781*1ee2e5faSnakanon 782*1ee2e5faSnakanon void 783*1ee2e5faSnakanon adjust_buf(uchar **optr, size_t size) 784*1ee2e5faSnakanon { 785*1ee2e5faSnakanon uchar *nptr; 786*1ee2e5faSnakanon 787*1ee2e5faSnakanon if ((nptr = realloc(*optr, size)) == NULL) 788*1ee2e5faSnakanon ERROR "out of space in adjust_buf" FATAL; 789*1ee2e5faSnakanon *optr = nptr; 790*1ee2e5faSnakanon } 791