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 */ 221ee2e5faSnakanon 231ee2e5faSnakanon /* 241ee2e5faSnakanon * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 251ee2e5faSnakanon * Use is subject to license terms. 261ee2e5faSnakanon */ 271ee2e5faSnakanon 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 311ee2e5faSnakanon #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 371ee2e5faSnakanon uchar *recdata; 381ee2e5faSnakanon uchar *record; 391ee2e5faSnakanon 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 441ee2e5faSnakanon static struct fldtab_chunk { 451ee2e5faSnakanon struct fldtab_chunk *next; 461ee2e5faSnakanon Cell fields[FLD_INCR]; 471ee2e5faSnakanon } *fldtab_head, *fldtab_tail; 487c478bd9Sstevel@tonic-gate 491ee2e5faSnakanon static size_t fldtab_maxidx; 507c478bd9Sstevel@tonic-gate 511ee2e5faSnakanon static FILE *infile = NULL; 521ee2e5faSnakanon static uchar *file = (uchar*) ""; 531ee2e5faSnakanon static uchar *fields; 541ee2e5faSnakanon static size_t fields_size = LINE_INCR; 551ee2e5faSnakanon 561ee2e5faSnakanon static int maxfld = 0; /* last used field */ 571ee2e5faSnakanon static int argno = 1; /* current input argument number */ 581ee2e5faSnakanon 591ee2e5faSnakanon static uchar *getargv(int); 601ee2e5faSnakanon static void cleanfld(int, int); 611ee2e5faSnakanon static int refldbld(uchar *, uchar *); 621ee2e5faSnakanon static void bcheck2(int, int, int); 631ee2e5faSnakanon static void eprint(void); 641ee2e5faSnakanon static void bclass(int); 651ee2e5faSnakanon 661ee2e5faSnakanon static void 671ee2e5faSnakanon 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 821ee2e5faSnakanon int 831ee2e5faSnakanon getrec(uchar **bufp, size_t *bufsizep) 847c478bd9Sstevel@tonic-gate { 857c478bd9Sstevel@tonic-gate int c; 867c478bd9Sstevel@tonic-gate static int firsttime = 1; 871ee2e5faSnakanon uchar_t *buf, *nbuf; 881ee2e5faSnakanon 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; 1171ee2e5faSnakanon (void) setfval(fnrloc, 0.0); 1187c478bd9Sstevel@tonic-gate } 1191ee2e5faSnakanon c = readrec(&nbuf, &len, infile); 1201ee2e5faSnakanon expand_buf(bufp, bufsizep, len); 1211ee2e5faSnakanon buf = *bufp; 1221ee2e5faSnakanon (void) memcpy(buf, nbuf, len); 1231ee2e5faSnakanon buf[len] = '\0'; 1241ee2e5faSnakanon free(nbuf); 1251ee2e5faSnakanon 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; 1321ee2e5faSnakanon if (is_number(recloc->sval)) { 1331ee2e5faSnakanon recloc->fval = 1341ee2e5faSnakanon atof((const char *)recloc->sval); 1357c478bd9Sstevel@tonic-gate recloc->tval |= NUM; 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate } 1381ee2e5faSnakanon (void) setfval(nrloc, nrloc->fval+1); 1391ee2e5faSnakanon (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) 1441ee2e5faSnakanon (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 1511ee2e5faSnakanon int 1521ee2e5faSnakanon readrec(uchar **bufp, size_t *sizep, FILE *inf) /* read one record into buf */ 1537c478bd9Sstevel@tonic-gate { 154*cb4658fbSceastha int sep, c; 1551ee2e5faSnakanon uchar *buf; 1567c478bd9Sstevel@tonic-gate int count; 1571ee2e5faSnakanon size_t bufsize; 1587c478bd9Sstevel@tonic-gate 1591ee2e5faSnakanon 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) 1661ee2e5faSnakanon (void) ungetc(c, inf); 1677c478bd9Sstevel@tonic-gate } 1681ee2e5faSnakanon count = 0; 1691ee2e5faSnakanon for (;;) { 1707c478bd9Sstevel@tonic-gate while ((c = getc(inf)) != sep && c != EOF) { 1711ee2e5faSnakanon expand_buf(&buf, &bufsize, count); 1721ee2e5faSnakanon 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; 1781ee2e5faSnakanon expand_buf(&buf, &bufsize, count + 1); 1791ee2e5faSnakanon buf[count++] = '\n'; 1801ee2e5faSnakanon buf[count++] = c; 1817c478bd9Sstevel@tonic-gate } 1821ee2e5faSnakanon buf[count] = '\0'; 1837c478bd9Sstevel@tonic-gate dprintf(("readrec saw <%s>, returns %d\n", 1841ee2e5faSnakanon buf, c == EOF && count == 0 ? 0 : 1)); 1851ee2e5faSnakanon *bufp = buf; 1861ee2e5faSnakanon *sizep = count; 1871ee2e5faSnakanon return (c == EOF && count == 0 ? 0 : 1); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate /* get ARGV[n] */ 1911ee2e5faSnakanon static uchar * 1921ee2e5faSnakanon getargv(int n) 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate Cell *x; 1951ee2e5faSnakanon uchar *s, temp[11]; 1967c478bd9Sstevel@tonic-gate extern Array *ARGVtab; 1977c478bd9Sstevel@tonic-gate 1981ee2e5faSnakanon (void) sprintf((char *)temp, "%d", n); 1991ee2e5faSnakanon 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 2051ee2e5faSnakanon void 2061ee2e5faSnakanon 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); 2161ee2e5faSnakanon (void) setsval(q, p); 2171ee2e5faSnakanon if (is_number(q->sval)) { 2181ee2e5faSnakanon 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)); 2221ee2e5faSnakanon free(p); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2251ee2e5faSnakanon void 2261ee2e5faSnakanon fldbld(void) 2277c478bd9Sstevel@tonic-gate { 228*cb4658fbSceastha uchar *r, *fr, sep; 2297c478bd9Sstevel@tonic-gate Cell *p; 2307c478bd9Sstevel@tonic-gate int i; 2311ee2e5faSnakanon size_t len; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate if (donefld) 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate if (!(recloc->tval & STR)) 2361ee2e5faSnakanon (void) getsval(recloc); 2377c478bd9Sstevel@tonic-gate r = recloc->sval; /* was record! */ 2381ee2e5faSnakanon 2391ee2e5faSnakanon /* make sure fields is always allocated */ 2401ee2e5faSnakanon adjust_buf(&fields, fields_size); 2411ee2e5faSnakanon 2421ee2e5faSnakanon /* 2431ee2e5faSnakanon * make sure fields has enough size. We don't expand the buffer 2441ee2e5faSnakanon * in the middle of the loop, since p->sval has already pointed 2451ee2e5faSnakanon * the address in the fields. 2461ee2e5faSnakanon */ 2471ee2e5faSnakanon len = strlen((char *)r) + 1; 2481ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 2497c478bd9Sstevel@tonic-gate fr = fields; 2501ee2e5faSnakanon 2517c478bd9Sstevel@tonic-gate i = 0; /* number of fields accumulated here */ 2521ee2e5faSnakanon 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++; 2611ee2e5faSnakanon p = getfld(i); 2621ee2e5faSnakanon if (!(p->tval & DONTFREE)) 2631ee2e5faSnakanon xfree(p->sval); 2641ee2e5faSnakanon p->sval = fr; 2651ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 2667c478bd9Sstevel@tonic-gate do 2677c478bd9Sstevel@tonic-gate *fr++ = *r++; 2687c478bd9Sstevel@tonic-gate while (*r != ' ' && *r != '\t' && *r != '\n' && 2691ee2e5faSnakanon *r != '\0') 2701ee2e5faSnakanon ; 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++; 2771ee2e5faSnakanon p = getfld(i); 2781ee2e5faSnakanon if (!(p->tval & DONTFREE)) 2791ee2e5faSnakanon xfree(p->sval); 2801ee2e5faSnakanon p->sval = fr; 2811ee2e5faSnakanon 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; 2951ee2e5faSnakanon for (i = 1; i <= maxfld; i++) { 2961ee2e5faSnakanon p = getfld(i); 2971ee2e5faSnakanon if (is_number(p->sval)) { 2981ee2e5faSnakanon p->fval = atof((const char *)p->sval); 2997c478bd9Sstevel@tonic-gate p->tval |= NUM; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate } 3021ee2e5faSnakanon 3031ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) maxfld); 3041ee2e5faSnakanon if (dbg) { 3051ee2e5faSnakanon for (i = 0; i <= maxfld; i++) { 3061ee2e5faSnakanon p = getfld(i); 3071ee2e5faSnakanon (void) printf("field %d: |%s|\n", i, p->sval); 3081ee2e5faSnakanon } 3091ee2e5faSnakanon } 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3121ee2e5faSnakanon static void 3131ee2e5faSnakanon cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */ 3147c478bd9Sstevel@tonic-gate { 3157c478bd9Sstevel@tonic-gate static uchar *nullstat = (uchar *) ""; 316*cb4658fbSceastha Cell *p; 3171ee2e5faSnakanon int i; 3187c478bd9Sstevel@tonic-gate 3191ee2e5faSnakanon for (i = n2; i > n1; i--) { 3201ee2e5faSnakanon 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 3281ee2e5faSnakanon void 3291ee2e5faSnakanon newfld(int n) /* add field n (after end) */ 3307c478bd9Sstevel@tonic-gate { 3311ee2e5faSnakanon if (n < 0) 3321ee2e5faSnakanon ERROR "accessing invalid field", record FATAL; 3331ee2e5faSnakanon (void) getfld(n); 3347c478bd9Sstevel@tonic-gate cleanfld(maxfld, n); 3357c478bd9Sstevel@tonic-gate maxfld = n; 3361ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) n); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3391ee2e5faSnakanon /* 3401ee2e5faSnakanon * allocate field table. We don't reallocate the table since there 3411ee2e5faSnakanon * might be somewhere recording the address of the table. 3421ee2e5faSnakanon */ 3431ee2e5faSnakanon static void 3441ee2e5faSnakanon morefld(void) 3457c478bd9Sstevel@tonic-gate { 3461ee2e5faSnakanon int i; 3471ee2e5faSnakanon struct fldtab_chunk *fldcp; 3481ee2e5faSnakanon Cell *newfld; 3491ee2e5faSnakanon 3501ee2e5faSnakanon if ((fldcp = calloc(sizeof (struct fldtab_chunk), 1)) == NULL) 3511ee2e5faSnakanon ERROR "out of space in morefld" FATAL; 3521ee2e5faSnakanon 3531ee2e5faSnakanon newfld = &fldcp->fields[0]; 3541ee2e5faSnakanon for (i = 0; i < FLD_INCR; i++) { 3551ee2e5faSnakanon newfld[i].ctype = OCELL; 3561ee2e5faSnakanon newfld[i].csub = CFLD; 3571ee2e5faSnakanon newfld[i].nval = NULL; 3581ee2e5faSnakanon newfld[i].sval = (uchar *)""; 3591ee2e5faSnakanon newfld[i].fval = 0.0; 3601ee2e5faSnakanon newfld[i].tval = FLD|STR|DONTFREE; 3611ee2e5faSnakanon newfld[i].cnext = NULL; 3621ee2e5faSnakanon } 3631ee2e5faSnakanon /* 3641ee2e5faSnakanon * link this field chunk 3651ee2e5faSnakanon */ 3661ee2e5faSnakanon if (fldtab_head == NULL) 3671ee2e5faSnakanon fldtab_head = fldcp; 3681ee2e5faSnakanon else 3691ee2e5faSnakanon fldtab_tail->next = fldcp; 3701ee2e5faSnakanon fldtab_tail = fldcp; 3711ee2e5faSnakanon fldcp->next = NULL; 3721ee2e5faSnakanon 3731ee2e5faSnakanon fldtab_maxidx += FLD_INCR; 3741ee2e5faSnakanon } 3751ee2e5faSnakanon 3761ee2e5faSnakanon Cell * 3771ee2e5faSnakanon getfld(int idx) 3781ee2e5faSnakanon { 3791ee2e5faSnakanon struct fldtab_chunk *fldcp; 3801ee2e5faSnakanon int cbase; 3811ee2e5faSnakanon 3821ee2e5faSnakanon if (idx < 0) 3831ee2e5faSnakanon ERROR "trying to access field %d", idx FATAL; 3841ee2e5faSnakanon while (idx >= fldtab_maxidx) 3851ee2e5faSnakanon morefld(); 3861ee2e5faSnakanon cbase = 0; 3871ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 3881ee2e5faSnakanon if (idx < (cbase + FLD_INCR)) 3891ee2e5faSnakanon return (&fldcp->fields[idx - cbase]); 3901ee2e5faSnakanon cbase += FLD_INCR; 3911ee2e5faSnakanon } 3921ee2e5faSnakanon /* should never happen */ 3931ee2e5faSnakanon ERROR "trying to access invalid field %d", idx FATAL; 3941ee2e5faSnakanon return (NULL); 3951ee2e5faSnakanon } 3961ee2e5faSnakanon 3971ee2e5faSnakanon int 3981ee2e5faSnakanon fldidx(Cell *vp) 3991ee2e5faSnakanon { 4001ee2e5faSnakanon struct fldtab_chunk *fldcp; 4011ee2e5faSnakanon Cell *tbl; 4021ee2e5faSnakanon int cbase; 4031ee2e5faSnakanon 4041ee2e5faSnakanon cbase = 0; 4051ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 4061ee2e5faSnakanon tbl = &fldcp->fields[0]; 4071ee2e5faSnakanon if (vp >= tbl && vp < (tbl + FLD_INCR)) 4081ee2e5faSnakanon return (cbase + (vp - tbl)); 4091ee2e5faSnakanon cbase += FLD_INCR; 4101ee2e5faSnakanon } 4111ee2e5faSnakanon /* should never happen */ 4121ee2e5faSnakanon ERROR "trying to access unknown field" FATAL; 4131ee2e5faSnakanon return (0); 4141ee2e5faSnakanon } 4151ee2e5faSnakanon 4161ee2e5faSnakanon static int 4171ee2e5faSnakanon refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */ 4181ee2e5faSnakanon { 4197c478bd9Sstevel@tonic-gate uchar *fr; 4207c478bd9Sstevel@tonic-gate int i, tempstat; 4217c478bd9Sstevel@tonic-gate fa *pfa; 4221ee2e5faSnakanon Cell *p; 4231ee2e5faSnakanon size_t len; 4247c478bd9Sstevel@tonic-gate 4251ee2e5faSnakanon /* make sure fields is allocated */ 4261ee2e5faSnakanon 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); 4311ee2e5faSnakanon 4321ee2e5faSnakanon len = strlen((char *)rec) + 1; 4331ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 4341ee2e5faSnakanon fr = fields; 4351ee2e5faSnakanon 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; 4391ee2e5faSnakanon for (i = 1; ; i++) { 4401ee2e5faSnakanon p = getfld(i); 4411ee2e5faSnakanon if (!(p->tval & DONTFREE)) 4421ee2e5faSnakanon xfree(p->sval); 4431ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 4441ee2e5faSnakanon 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)); 4491ee2e5faSnakanon (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)); 4551ee2e5faSnakanon (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 4631ee2e5faSnakanon void 4641ee2e5faSnakanon recbld(void) 4657c478bd9Sstevel@tonic-gate { 4667c478bd9Sstevel@tonic-gate int i; 467*cb4658fbSceastha uchar *p; 4681ee2e5faSnakanon size_t cnt, len, olen; 4691ee2e5faSnakanon static uchar *rec; 4701ee2e5faSnakanon size_t osize, nsize; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate if (donerec == 1) 4737c478bd9Sstevel@tonic-gate return; 4741ee2e5faSnakanon /* sync up rec size */ 4751ee2e5faSnakanon adjust_buf(&rec, record_size); 4761ee2e5faSnakanon cnt = 0; 4771ee2e5faSnakanon olen = strlen((char *)*OFS); 4787c478bd9Sstevel@tonic-gate for (i = 1; i <= *NF; i++) { 4791ee2e5faSnakanon p = getsval(getfld(i)); 4801ee2e5faSnakanon len = strlen((char *)p); 4811ee2e5faSnakanon osize = record_size; 4821ee2e5faSnakanon nsize = cnt + len + olen; 4831ee2e5faSnakanon expand_buf(&rec, &record_size, nsize); 4841ee2e5faSnakanon if (osize != record_size) 4851ee2e5faSnakanon adjust_buf(&recdata, record_size); 4861ee2e5faSnakanon (void) memcpy(&rec[cnt], p, len); 4871ee2e5faSnakanon cnt += len; 4881ee2e5faSnakanon if (i < *NF) { 4891ee2e5faSnakanon (void) memcpy(&rec[cnt], *OFS, olen); 4901ee2e5faSnakanon cnt += olen; 4917c478bd9Sstevel@tonic-gate } 4921ee2e5faSnakanon } 4931ee2e5faSnakanon rec[cnt] = '\0'; 4941ee2e5faSnakanon 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; 4971ee2e5faSnakanon 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 * 5031ee2e5faSnakanon fieldadr(int n) 5047c478bd9Sstevel@tonic-gate { 5051ee2e5faSnakanon if (n < 0) 5067c478bd9Sstevel@tonic-gate ERROR "trying to access field %d", n FATAL; 5071ee2e5faSnakanon return (getfld(n)); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate int errorflag = 0; 5117c478bd9Sstevel@tonic-gate char errbuf[200]; 5127c478bd9Sstevel@tonic-gate 5131ee2e5faSnakanon void 5141ee2e5faSnakanon 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; 5211ee2e5faSnakanon (void) fprintf(stderr, "%s: %s", cmdname, s); 5221ee2e5faSnakanon (void) fprintf(stderr, gettext(" at source line %lld"), lineno); 5237c478bd9Sstevel@tonic-gate if (curfname != NULL) 5241ee2e5faSnakanon (void) fprintf(stderr, gettext(" in function %s"), curfname); 5251ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5267c478bd9Sstevel@tonic-gate errorflag = 2; 5277c478bd9Sstevel@tonic-gate eprint(); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5301ee2e5faSnakanon /*ARGSUSED*/ 5311ee2e5faSnakanon void 5321ee2e5faSnakanon 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 5391ee2e5faSnakanon void 5401ee2e5faSnakanon 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 5541ee2e5faSnakanon /*ARGSUSED*/ 5551ee2e5faSnakanon static void 5561ee2e5faSnakanon bcheck2(int n, int c1, int c2) 5577c478bd9Sstevel@tonic-gate { 5587c478bd9Sstevel@tonic-gate if (n == 1) 5591ee2e5faSnakanon (void) fprintf(stderr, gettext("\tmissing %c\n"), c2); 5607c478bd9Sstevel@tonic-gate else if (n > 1) 5611ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d missing %c's\n"), n, c2); 5627c478bd9Sstevel@tonic-gate else if (n == -1) 5631ee2e5faSnakanon (void) fprintf(stderr, gettext("\textra %c\n"), c2); 5647c478bd9Sstevel@tonic-gate else if (n < -1) 5651ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate 5681ee2e5faSnakanon void 5691ee2e5faSnakanon error(int f, char *s) 5707c478bd9Sstevel@tonic-gate { 5717c478bd9Sstevel@tonic-gate extern Node *curnode; 5727c478bd9Sstevel@tonic-gate extern uchar *cmdname; 5737c478bd9Sstevel@tonic-gate 5741ee2e5faSnakanon (void) fflush(stdout); 5751ee2e5faSnakanon (void) fprintf(stderr, "%s: ", cmdname); 5761ee2e5faSnakanon (void) fprintf(stderr, "%s", s); 5771ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5787c478bd9Sstevel@tonic-gate if (compile_time != 2 && NR && *NR > 0) { 5791ee2e5faSnakanon (void) fprintf(stderr, 5801ee2e5faSnakanon gettext(" input record number %g"), *FNR); 5811ee2e5faSnakanon if (strcmp((char *)*FILENAME, "-") != 0) 5821ee2e5faSnakanon (void) fprintf(stderr, gettext(", file %s"), *FILENAME); 5831ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate if (compile_time != 2 && curnode) 5861ee2e5faSnakanon (void) fprintf(stderr, gettext(" source line number %lld\n"), 5877c478bd9Sstevel@tonic-gate curnode->lineno); 5881ee2e5faSnakanon else if (compile_time != 2 && lineno) { 5891ee2e5faSnakanon (void) fprintf(stderr, 5901ee2e5faSnakanon gettext(" source line number %lld\n"), lineno); 5911ee2e5faSnakanon } 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 6001ee2e5faSnakanon static void 6011ee2e5faSnakanon 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++; 6171ee2e5faSnakanon (void) fprintf(stderr, gettext(" context is\n\t")); 6181ee2e5faSnakanon 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) 6221ee2e5faSnakanon (void) putc(*p, stderr); 6231ee2e5faSnakanon (void) fprintf(stderr, " >>> "); 6247c478bd9Sstevel@tonic-gate for (; p < ep; p++) 6257c478bd9Sstevel@tonic-gate if (*p) 6261ee2e5faSnakanon (void) putc(*p, stderr); 6271ee2e5faSnakanon (void) fprintf(stderr, " <<< "); 6287c478bd9Sstevel@tonic-gate if (*ep) 6297c478bd9Sstevel@tonic-gate while ((c = input()) != '\n' && c != '\0' && c != EOF) { 6301ee2e5faSnakanon (void) putc(c, stderr); 6317c478bd9Sstevel@tonic-gate bclass(c); 6327c478bd9Sstevel@tonic-gate } 6331ee2e5faSnakanon (void) putc('\n', stderr); 6347c478bd9Sstevel@tonic-gate ep = ebuf; 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate 6371ee2e5faSnakanon static void 6381ee2e5faSnakanon 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 6511ee2e5faSnakanon 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 6671ee2e5faSnakanon void 6681ee2e5faSnakanon PUTS(uchar *s) 6691ee2e5faSnakanon { 6707c478bd9Sstevel@tonic-gate dprintf(("%s\n", s)); 6717c478bd9Sstevel@tonic-gate } 6727c478bd9Sstevel@tonic-gate 6731ee2e5faSnakanon int 6741ee2e5faSnakanon isclvar(uchar *s) /* is s of form var=something? */ 6757c478bd9Sstevel@tonic-gate { 676*cb4658fbSceastha if (s != NULL) { 6777c478bd9Sstevel@tonic-gate 678*cb4658fbSceastha /* Must begin with an underscore or alphabetic character */ 679*cb4658fbSceastha if (isalpha(*s) || (*s == '_')) { 680*cb4658fbSceastha 681*cb4658fbSceastha for (s++; *s; s++) { 682*cb4658fbSceastha /* 683*cb4658fbSceastha * followed by a sequence of underscores, 684*cb4658fbSceastha * digits, and alphabetics 685*cb4658fbSceastha */ 686*cb4658fbSceastha if (!(isalnum(*s) || *s == '_')) { 6877c478bd9Sstevel@tonic-gate break; 688*cb4658fbSceastha } 689*cb4658fbSceastha } 690*cb4658fbSceastha return (*s == '=' && *(s + 1) != '='); 691*cb4658fbSceastha } 692*cb4658fbSceastha } 693*cb4658fbSceastha 694*cb4658fbSceastha return (0); 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate #define MAXEXPON 38 /* maximum exponent for fp number */ 6987c478bd9Sstevel@tonic-gate 6991ee2e5faSnakanon int 7001ee2e5faSnakanon is_number(uchar *s) 7017c478bd9Sstevel@tonic-gate { 702*cb4658fbSceastha int d1, d2; 7037c478bd9Sstevel@tonic-gate int point; 7047c478bd9Sstevel@tonic-gate uchar *es; 7057c478bd9Sstevel@tonic-gate extern char radixpoint; 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate d1 = d2 = point = 0; 7087c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 7097c478bd9Sstevel@tonic-gate s++; 7107c478bd9Sstevel@tonic-gate if (*s == '\0') 7117c478bd9Sstevel@tonic-gate return (0); /* empty stuff isn't number */ 7127c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7137c478bd9Sstevel@tonic-gate s++; 7147c478bd9Sstevel@tonic-gate if (!isdigit(*s) && *s != radixpoint) 7157c478bd9Sstevel@tonic-gate return (0); 7167c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7177c478bd9Sstevel@tonic-gate do { 7187c478bd9Sstevel@tonic-gate d1++; 7197c478bd9Sstevel@tonic-gate s++; 7207c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate if (d1 >= MAXEXPON) 7237c478bd9Sstevel@tonic-gate return (0); /* too many digits to convert */ 7247c478bd9Sstevel@tonic-gate if (*s == radixpoint) { 7257c478bd9Sstevel@tonic-gate point++; 7267c478bd9Sstevel@tonic-gate s++; 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7297c478bd9Sstevel@tonic-gate d2++; 7307c478bd9Sstevel@tonic-gate do { 7317c478bd9Sstevel@tonic-gate s++; 7327c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7337c478bd9Sstevel@tonic-gate } 7347c478bd9Sstevel@tonic-gate if (!(d1 || point && d2)) 7357c478bd9Sstevel@tonic-gate return (0); 7367c478bd9Sstevel@tonic-gate if (*s == 'e' || *s == 'E') { 7377c478bd9Sstevel@tonic-gate s++; 7387c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7397c478bd9Sstevel@tonic-gate s++; 7407c478bd9Sstevel@tonic-gate if (!isdigit(*s)) 7417c478bd9Sstevel@tonic-gate return (0); 7427c478bd9Sstevel@tonic-gate es = s; 7437c478bd9Sstevel@tonic-gate do { 7447c478bd9Sstevel@tonic-gate s++; 7457c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7461ee2e5faSnakanon if (s - es > 2) { 7477c478bd9Sstevel@tonic-gate return (0); 7481ee2e5faSnakanon } else if (s - es == 2 && 7491ee2e5faSnakanon (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) { 7507c478bd9Sstevel@tonic-gate return (0); 7517c478bd9Sstevel@tonic-gate } 7521ee2e5faSnakanon } 7537c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 7547c478bd9Sstevel@tonic-gate s++; 7557c478bd9Sstevel@tonic-gate if (*s == '\0') 7567c478bd9Sstevel@tonic-gate return (1); 7577c478bd9Sstevel@tonic-gate else 7587c478bd9Sstevel@tonic-gate return (0); 7597c478bd9Sstevel@tonic-gate } 7601ee2e5faSnakanon 7611ee2e5faSnakanon void 7621ee2e5faSnakanon init_buf(uchar **optr, size_t *sizep, size_t amt) 7631ee2e5faSnakanon { 7641ee2e5faSnakanon uchar *nptr = NULL; 7651ee2e5faSnakanon 7661ee2e5faSnakanon if ((nptr = malloc(amt)) == NULL) 7671ee2e5faSnakanon ERROR "out of space in init_buf" FATAL; 7681ee2e5faSnakanon /* initial buffer should have NULL terminated */ 7691ee2e5faSnakanon *nptr = '\0'; 7701ee2e5faSnakanon if (sizep != NULL) 7711ee2e5faSnakanon *sizep = amt; 7721ee2e5faSnakanon *optr = nptr; 7731ee2e5faSnakanon } 7741ee2e5faSnakanon 7751ee2e5faSnakanon void 7761ee2e5faSnakanon r_expand_buf(uchar **optr, size_t *sizep, size_t req) 7771ee2e5faSnakanon { 7781ee2e5faSnakanon uchar *nptr; 7791ee2e5faSnakanon size_t amt, size = *sizep; 7801ee2e5faSnakanon 7811ee2e5faSnakanon if (size != 0 && req < (size - 1)) 7821ee2e5faSnakanon return; 7831ee2e5faSnakanon amt = req + 1 - size; 7841ee2e5faSnakanon amt = (amt / LINE_INCR + 1) * LINE_INCR; 7851ee2e5faSnakanon 7861ee2e5faSnakanon if ((nptr = realloc(*optr, size + amt)) == NULL) 7871ee2e5faSnakanon ERROR "out of space in expand_buf" FATAL; 7881ee2e5faSnakanon /* initial buffer should have NULL terminated */ 7891ee2e5faSnakanon if (size == 0) 7901ee2e5faSnakanon *nptr = '\0'; 7911ee2e5faSnakanon *sizep += amt; 7921ee2e5faSnakanon *optr = nptr; 7931ee2e5faSnakanon } 7941ee2e5faSnakanon 7951ee2e5faSnakanon void 7961ee2e5faSnakanon adjust_buf(uchar **optr, size_t size) 7971ee2e5faSnakanon { 7981ee2e5faSnakanon uchar *nptr; 7991ee2e5faSnakanon 8001ee2e5faSnakanon if ((nptr = realloc(*optr, size)) == NULL) 8011ee2e5faSnakanon ERROR "out of space in adjust_buf" FATAL; 8021ee2e5faSnakanon *optr = nptr; 8031ee2e5faSnakanon } 804