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 5*8ef4c21aSnakanon * Common Development and Distribution License (the "License"). 6*8ef4c21aSnakanon * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 211ee2e5faSnakanon 221ee2e5faSnakanon /* 23*8ef4c21aSnakanon * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 241ee2e5faSnakanon * Use is subject to license terms. 251ee2e5faSnakanon */ 261ee2e5faSnakanon 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 301ee2e5faSnakanon #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include "awk.h" 347c478bd9Sstevel@tonic-gate #include "y.tab.h" 357c478bd9Sstevel@tonic-gate 361ee2e5faSnakanon uchar *record; 371ee2e5faSnakanon size_t record_size; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate int donefld; /* 1 = implies rec broken into fields */ 407c478bd9Sstevel@tonic-gate int donerec; /* 1 = record is valid (no flds have changed) */ 417c478bd9Sstevel@tonic-gate 421ee2e5faSnakanon static struct fldtab_chunk { 431ee2e5faSnakanon struct fldtab_chunk *next; 441ee2e5faSnakanon Cell fields[FLD_INCR]; 451ee2e5faSnakanon } *fldtab_head, *fldtab_tail; 467c478bd9Sstevel@tonic-gate 471ee2e5faSnakanon static size_t fldtab_maxidx; 487c478bd9Sstevel@tonic-gate 491ee2e5faSnakanon static FILE *infile = NULL; 501ee2e5faSnakanon static uchar *file = (uchar*) ""; 511ee2e5faSnakanon static uchar *fields; 521ee2e5faSnakanon static size_t fields_size = LINE_INCR; 531ee2e5faSnakanon 541ee2e5faSnakanon static int maxfld = 0; /* last used field */ 551ee2e5faSnakanon static int argno = 1; /* current input argument number */ 561ee2e5faSnakanon 571ee2e5faSnakanon static uchar *getargv(int); 581ee2e5faSnakanon static void cleanfld(int, int); 591ee2e5faSnakanon static int refldbld(uchar *, uchar *); 601ee2e5faSnakanon static void bcheck2(int, int, int); 611ee2e5faSnakanon static void eprint(void); 621ee2e5faSnakanon static void bclass(int); 631ee2e5faSnakanon 641ee2e5faSnakanon static void 651ee2e5faSnakanon initgetrec(void) 667c478bd9Sstevel@tonic-gate { 677c478bd9Sstevel@tonic-gate int i; 687c478bd9Sstevel@tonic-gate uchar *p; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate for (i = 1; i < *ARGC; i++) { 717c478bd9Sstevel@tonic-gate if (!isclvar(p = getargv(i))) /* find 1st real filename */ 727c478bd9Sstevel@tonic-gate return; 737c478bd9Sstevel@tonic-gate setclvar(p); /* a commandline assignment before filename */ 747c478bd9Sstevel@tonic-gate argno++; 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate infile = stdin; /* no filenames, so use stdin */ 777c478bd9Sstevel@tonic-gate /* *FILENAME = file = (uchar*) "-"; */ 787c478bd9Sstevel@tonic-gate } 797c478bd9Sstevel@tonic-gate 801ee2e5faSnakanon int 811ee2e5faSnakanon getrec(uchar **bufp, size_t *bufsizep) 827c478bd9Sstevel@tonic-gate { 837c478bd9Sstevel@tonic-gate int c; 847c478bd9Sstevel@tonic-gate static int firsttime = 1; 851ee2e5faSnakanon uchar_t *buf, *nbuf; 861ee2e5faSnakanon size_t len; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate if (firsttime) { 897c478bd9Sstevel@tonic-gate firsttime = 0; 907c478bd9Sstevel@tonic-gate initgetrec(); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate dprintf(("RS=<%s>, FS=<%s>, ARGC=%f, FILENAME=%s\n", 937c478bd9Sstevel@tonic-gate *RS, *FS, *ARGC, *FILENAME)); 947c478bd9Sstevel@tonic-gate donefld = 0; 957c478bd9Sstevel@tonic-gate donerec = 1; 967c478bd9Sstevel@tonic-gate while (argno < *ARGC || infile == stdin) { 977c478bd9Sstevel@tonic-gate dprintf(("argno=%d, file=|%s|\n", argno, file)); 987c478bd9Sstevel@tonic-gate if (infile == NULL) { /* have to open a new file */ 997c478bd9Sstevel@tonic-gate file = getargv(argno); 1007c478bd9Sstevel@tonic-gate if (*file == '\0') { /* it's been zapped */ 1017c478bd9Sstevel@tonic-gate argno++; 1027c478bd9Sstevel@tonic-gate continue; 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate if (isclvar(file)) { /* a var=value arg */ 1057c478bd9Sstevel@tonic-gate setclvar(file); 1067c478bd9Sstevel@tonic-gate argno++; 1077c478bd9Sstevel@tonic-gate continue; 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate *FILENAME = file; 1107c478bd9Sstevel@tonic-gate dprintf(("opening file %s\n", file)); 1117c478bd9Sstevel@tonic-gate if (*file == '-' && *(file+1) == '\0') 1127c478bd9Sstevel@tonic-gate infile = stdin; 1137c478bd9Sstevel@tonic-gate else if ((infile = fopen((char *)file, "r")) == NULL) 1147c478bd9Sstevel@tonic-gate ERROR "can't open file %s", file FATAL; 1151ee2e5faSnakanon (void) setfval(fnrloc, 0.0); 1167c478bd9Sstevel@tonic-gate } 1171ee2e5faSnakanon c = readrec(&nbuf, &len, infile); 1181ee2e5faSnakanon expand_buf(bufp, bufsizep, len); 1191ee2e5faSnakanon buf = *bufp; 1201ee2e5faSnakanon (void) memcpy(buf, nbuf, len); 1211ee2e5faSnakanon buf[len] = '\0'; 1221ee2e5faSnakanon free(nbuf); 1231ee2e5faSnakanon 1247c478bd9Sstevel@tonic-gate if (c != 0 || buf[0] != '\0') { /* normal record */ 125*8ef4c21aSnakanon if (bufp == &record) { 1267c478bd9Sstevel@tonic-gate if (!(recloc->tval & DONTFREE)) 1277c478bd9Sstevel@tonic-gate xfree(recloc->sval); 1287c478bd9Sstevel@tonic-gate recloc->sval = record; 1297c478bd9Sstevel@tonic-gate recloc->tval = REC | STR | DONTFREE; 1301ee2e5faSnakanon if (is_number(recloc->sval)) { 1311ee2e5faSnakanon recloc->fval = 1321ee2e5faSnakanon atof((const char *)recloc->sval); 1337c478bd9Sstevel@tonic-gate recloc->tval |= NUM; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate } 1361ee2e5faSnakanon (void) setfval(nrloc, nrloc->fval+1); 1371ee2e5faSnakanon (void) setfval(fnrloc, fnrloc->fval+1); 1387c478bd9Sstevel@tonic-gate return (1); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate /* EOF arrived on this file; set up next */ 1417c478bd9Sstevel@tonic-gate if (infile != stdin) 1421ee2e5faSnakanon (void) fclose(infile); 1437c478bd9Sstevel@tonic-gate infile = NULL; 1447c478bd9Sstevel@tonic-gate argno++; 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate return (0); /* true end of file */ 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1491ee2e5faSnakanon int 1501ee2e5faSnakanon readrec(uchar **bufp, size_t *sizep, FILE *inf) /* read one record into buf */ 1517c478bd9Sstevel@tonic-gate { 152cb4658fbSceastha int sep, c; 1531ee2e5faSnakanon uchar *buf; 1547c478bd9Sstevel@tonic-gate int count; 1551ee2e5faSnakanon size_t bufsize; 1567c478bd9Sstevel@tonic-gate 1571ee2e5faSnakanon init_buf(&buf, &bufsize, LINE_INCR); 1587c478bd9Sstevel@tonic-gate if ((sep = **RS) == 0) { 1597c478bd9Sstevel@tonic-gate sep = '\n'; 1607c478bd9Sstevel@tonic-gate /* skip leading \n's */ 1617c478bd9Sstevel@tonic-gate while ((c = getc(inf)) == '\n' && c != EOF) 1627c478bd9Sstevel@tonic-gate ; 1637c478bd9Sstevel@tonic-gate if (c != EOF) 1641ee2e5faSnakanon (void) ungetc(c, inf); 1657c478bd9Sstevel@tonic-gate } 1661ee2e5faSnakanon count = 0; 1671ee2e5faSnakanon for (;;) { 1687c478bd9Sstevel@tonic-gate while ((c = getc(inf)) != sep && c != EOF) { 1691ee2e5faSnakanon expand_buf(&buf, &bufsize, count); 1701ee2e5faSnakanon buf[count++] = c; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate if (**RS == sep || c == EOF) 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */ 1757c478bd9Sstevel@tonic-gate break; 1761ee2e5faSnakanon expand_buf(&buf, &bufsize, count + 1); 1771ee2e5faSnakanon buf[count++] = '\n'; 1781ee2e5faSnakanon buf[count++] = c; 1797c478bd9Sstevel@tonic-gate } 1801ee2e5faSnakanon buf[count] = '\0'; 1817c478bd9Sstevel@tonic-gate dprintf(("readrec saw <%s>, returns %d\n", 1821ee2e5faSnakanon buf, c == EOF && count == 0 ? 0 : 1)); 1831ee2e5faSnakanon *bufp = buf; 1841ee2e5faSnakanon *sizep = count; 1851ee2e5faSnakanon return (c == EOF && count == 0 ? 0 : 1); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* get ARGV[n] */ 1891ee2e5faSnakanon static uchar * 1901ee2e5faSnakanon getargv(int n) 1917c478bd9Sstevel@tonic-gate { 1927c478bd9Sstevel@tonic-gate Cell *x; 1931ee2e5faSnakanon uchar *s, temp[11]; 1947c478bd9Sstevel@tonic-gate extern Array *ARGVtab; 1957c478bd9Sstevel@tonic-gate 1961ee2e5faSnakanon (void) sprintf((char *)temp, "%d", n); 1971ee2e5faSnakanon x = setsymtab(temp, (uchar *)"", 0.0, STR, ARGVtab); 1987c478bd9Sstevel@tonic-gate s = getsval(x); 1997c478bd9Sstevel@tonic-gate dprintf(("getargv(%d) returns |%s|\n", n, s)); 2007c478bd9Sstevel@tonic-gate return (s); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2031ee2e5faSnakanon void 2041ee2e5faSnakanon setclvar(uchar *s) /* set var=value from s */ 2057c478bd9Sstevel@tonic-gate { 2067c478bd9Sstevel@tonic-gate uchar *p; 2077c478bd9Sstevel@tonic-gate Cell *q; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate for (p = s; *p != '='; p++) 2107c478bd9Sstevel@tonic-gate ; 2117c478bd9Sstevel@tonic-gate *p++ = 0; 2127c478bd9Sstevel@tonic-gate p = qstring(p, '\0'); 2137c478bd9Sstevel@tonic-gate q = setsymtab(s, p, 0.0, STR, symtab); 2141ee2e5faSnakanon (void) setsval(q, p); 2151ee2e5faSnakanon if (is_number(q->sval)) { 2161ee2e5faSnakanon q->fval = atof((const char *)q->sval); 2177c478bd9Sstevel@tonic-gate q->tval |= NUM; 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate dprintf(("command line set %s to |%s|\n", s, p)); 2201ee2e5faSnakanon free(p); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2231ee2e5faSnakanon void 2241ee2e5faSnakanon fldbld(void) 2257c478bd9Sstevel@tonic-gate { 226cb4658fbSceastha uchar *r, *fr, sep; 2277c478bd9Sstevel@tonic-gate Cell *p; 2287c478bd9Sstevel@tonic-gate int i; 2291ee2e5faSnakanon size_t len; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (donefld) 2327c478bd9Sstevel@tonic-gate return; 2337c478bd9Sstevel@tonic-gate if (!(recloc->tval & STR)) 2341ee2e5faSnakanon (void) getsval(recloc); 2357c478bd9Sstevel@tonic-gate r = recloc->sval; /* was record! */ 2361ee2e5faSnakanon 2371ee2e5faSnakanon /* make sure fields is always allocated */ 2381ee2e5faSnakanon adjust_buf(&fields, fields_size); 2391ee2e5faSnakanon 2401ee2e5faSnakanon /* 2411ee2e5faSnakanon * make sure fields has enough size. We don't expand the buffer 2421ee2e5faSnakanon * in the middle of the loop, since p->sval has already pointed 2431ee2e5faSnakanon * the address in the fields. 2441ee2e5faSnakanon */ 2451ee2e5faSnakanon len = strlen((char *)r) + 1; 2461ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 2477c478bd9Sstevel@tonic-gate fr = fields; 2481ee2e5faSnakanon 2497c478bd9Sstevel@tonic-gate i = 0; /* number of fields accumulated here */ 2501ee2e5faSnakanon if (strlen((char *)*FS) > 1) { /* it's a regular expression */ 2517c478bd9Sstevel@tonic-gate i = refldbld(r, *FS); 2527c478bd9Sstevel@tonic-gate } else if ((sep = **FS) == ' ') { 2537c478bd9Sstevel@tonic-gate for (i = 0; ; ) { 2547c478bd9Sstevel@tonic-gate while (*r == ' ' || *r == '\t' || *r == '\n') 2557c478bd9Sstevel@tonic-gate r++; 2567c478bd9Sstevel@tonic-gate if (*r == 0) 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate i++; 2591ee2e5faSnakanon p = getfld(i); 2601ee2e5faSnakanon if (!(p->tval & DONTFREE)) 2611ee2e5faSnakanon xfree(p->sval); 2621ee2e5faSnakanon p->sval = fr; 2631ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 2647c478bd9Sstevel@tonic-gate do 2657c478bd9Sstevel@tonic-gate *fr++ = *r++; 2667c478bd9Sstevel@tonic-gate while (*r != ' ' && *r != '\t' && *r != '\n' && 2671ee2e5faSnakanon *r != '\0') 2681ee2e5faSnakanon ; 2697c478bd9Sstevel@tonic-gate *fr++ = 0; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate *fr = 0; 2727c478bd9Sstevel@tonic-gate } else if (*r != 0) { /* if 0, it's a null field */ 2737c478bd9Sstevel@tonic-gate for (;;) { 2747c478bd9Sstevel@tonic-gate i++; 2751ee2e5faSnakanon p = getfld(i); 2761ee2e5faSnakanon if (!(p->tval & DONTFREE)) 2771ee2e5faSnakanon xfree(p->sval); 2781ee2e5faSnakanon p->sval = fr; 2791ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 2807c478bd9Sstevel@tonic-gate /* \n always a separator */ 2817c478bd9Sstevel@tonic-gate while (*r != sep && *r != '\n' && *r != '\0') 2827c478bd9Sstevel@tonic-gate *fr++ = *r++; 2837c478bd9Sstevel@tonic-gate *fr++ = 0; 2847c478bd9Sstevel@tonic-gate if (*r++ == 0) 2857c478bd9Sstevel@tonic-gate break; 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate *fr = 0; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate /* clean out junk from previous record */ 2907c478bd9Sstevel@tonic-gate cleanfld(i, maxfld); 2917c478bd9Sstevel@tonic-gate maxfld = i; 2927c478bd9Sstevel@tonic-gate donefld = 1; 2931ee2e5faSnakanon for (i = 1; i <= maxfld; i++) { 2941ee2e5faSnakanon p = getfld(i); 2951ee2e5faSnakanon if (is_number(p->sval)) { 2961ee2e5faSnakanon p->fval = atof((const char *)p->sval); 2977c478bd9Sstevel@tonic-gate p->tval |= NUM; 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate } 3001ee2e5faSnakanon 3011ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) maxfld); 3021ee2e5faSnakanon if (dbg) { 3031ee2e5faSnakanon for (i = 0; i <= maxfld; i++) { 3041ee2e5faSnakanon p = getfld(i); 3051ee2e5faSnakanon (void) printf("field %d: |%s|\n", i, p->sval); 3061ee2e5faSnakanon } 3071ee2e5faSnakanon } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3101ee2e5faSnakanon static void 3111ee2e5faSnakanon cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */ 3127c478bd9Sstevel@tonic-gate { 3137c478bd9Sstevel@tonic-gate static uchar *nullstat = (uchar *) ""; 314cb4658fbSceastha Cell *p; 3151ee2e5faSnakanon int i; 3167c478bd9Sstevel@tonic-gate 3171ee2e5faSnakanon for (i = n2; i > n1; i--) { 3181ee2e5faSnakanon p = getfld(i); 3197c478bd9Sstevel@tonic-gate if (!(p->tval & DONTFREE)) 3207c478bd9Sstevel@tonic-gate xfree(p->sval); 3217c478bd9Sstevel@tonic-gate p->tval = FLD | STR | DONTFREE; 3227c478bd9Sstevel@tonic-gate p->sval = nullstat; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3261ee2e5faSnakanon void 3271ee2e5faSnakanon newfld(int n) /* add field n (after end) */ 3287c478bd9Sstevel@tonic-gate { 3291ee2e5faSnakanon if (n < 0) 3301ee2e5faSnakanon ERROR "accessing invalid field", record FATAL; 3311ee2e5faSnakanon (void) getfld(n); 3327c478bd9Sstevel@tonic-gate cleanfld(maxfld, n); 3337c478bd9Sstevel@tonic-gate maxfld = n; 3341ee2e5faSnakanon (void) setfval(nfloc, (Awkfloat) n); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate 3371ee2e5faSnakanon /* 3381ee2e5faSnakanon * allocate field table. We don't reallocate the table since there 3391ee2e5faSnakanon * might be somewhere recording the address of the table. 3401ee2e5faSnakanon */ 3411ee2e5faSnakanon static void 3421ee2e5faSnakanon morefld(void) 3437c478bd9Sstevel@tonic-gate { 3441ee2e5faSnakanon int i; 3451ee2e5faSnakanon struct fldtab_chunk *fldcp; 3461ee2e5faSnakanon Cell *newfld; 3471ee2e5faSnakanon 3481ee2e5faSnakanon if ((fldcp = calloc(sizeof (struct fldtab_chunk), 1)) == NULL) 3491ee2e5faSnakanon ERROR "out of space in morefld" FATAL; 3501ee2e5faSnakanon 3511ee2e5faSnakanon newfld = &fldcp->fields[0]; 3521ee2e5faSnakanon for (i = 0; i < FLD_INCR; i++) { 3531ee2e5faSnakanon newfld[i].ctype = OCELL; 3541ee2e5faSnakanon newfld[i].csub = CFLD; 3551ee2e5faSnakanon newfld[i].nval = NULL; 3561ee2e5faSnakanon newfld[i].sval = (uchar *)""; 3571ee2e5faSnakanon newfld[i].fval = 0.0; 3581ee2e5faSnakanon newfld[i].tval = FLD|STR|DONTFREE; 3591ee2e5faSnakanon newfld[i].cnext = NULL; 3601ee2e5faSnakanon } 3611ee2e5faSnakanon /* 3621ee2e5faSnakanon * link this field chunk 3631ee2e5faSnakanon */ 3641ee2e5faSnakanon if (fldtab_head == NULL) 3651ee2e5faSnakanon fldtab_head = fldcp; 3661ee2e5faSnakanon else 3671ee2e5faSnakanon fldtab_tail->next = fldcp; 3681ee2e5faSnakanon fldtab_tail = fldcp; 3691ee2e5faSnakanon fldcp->next = NULL; 3701ee2e5faSnakanon 3711ee2e5faSnakanon fldtab_maxidx += FLD_INCR; 3721ee2e5faSnakanon } 3731ee2e5faSnakanon 3741ee2e5faSnakanon Cell * 3751ee2e5faSnakanon getfld(int idx) 3761ee2e5faSnakanon { 3771ee2e5faSnakanon struct fldtab_chunk *fldcp; 3781ee2e5faSnakanon int cbase; 3791ee2e5faSnakanon 3801ee2e5faSnakanon if (idx < 0) 3811ee2e5faSnakanon ERROR "trying to access field %d", idx FATAL; 3821ee2e5faSnakanon while (idx >= fldtab_maxidx) 3831ee2e5faSnakanon morefld(); 3841ee2e5faSnakanon cbase = 0; 3851ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 3861ee2e5faSnakanon if (idx < (cbase + FLD_INCR)) 3871ee2e5faSnakanon return (&fldcp->fields[idx - cbase]); 3881ee2e5faSnakanon cbase += FLD_INCR; 3891ee2e5faSnakanon } 3901ee2e5faSnakanon /* should never happen */ 3911ee2e5faSnakanon ERROR "trying to access invalid field %d", idx FATAL; 3921ee2e5faSnakanon return (NULL); 3931ee2e5faSnakanon } 3941ee2e5faSnakanon 3951ee2e5faSnakanon int 3961ee2e5faSnakanon fldidx(Cell *vp) 3971ee2e5faSnakanon { 3981ee2e5faSnakanon struct fldtab_chunk *fldcp; 3991ee2e5faSnakanon Cell *tbl; 4001ee2e5faSnakanon int cbase; 4011ee2e5faSnakanon 4021ee2e5faSnakanon cbase = 0; 4031ee2e5faSnakanon for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { 4041ee2e5faSnakanon tbl = &fldcp->fields[0]; 4051ee2e5faSnakanon if (vp >= tbl && vp < (tbl + FLD_INCR)) 4061ee2e5faSnakanon return (cbase + (vp - tbl)); 4071ee2e5faSnakanon cbase += FLD_INCR; 4081ee2e5faSnakanon } 4091ee2e5faSnakanon /* should never happen */ 4101ee2e5faSnakanon ERROR "trying to access unknown field" FATAL; 4111ee2e5faSnakanon return (0); 4121ee2e5faSnakanon } 4131ee2e5faSnakanon 4141ee2e5faSnakanon static int 4151ee2e5faSnakanon refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */ 4161ee2e5faSnakanon { 4177c478bd9Sstevel@tonic-gate uchar *fr; 4187c478bd9Sstevel@tonic-gate int i, tempstat; 4197c478bd9Sstevel@tonic-gate fa *pfa; 4201ee2e5faSnakanon Cell *p; 4211ee2e5faSnakanon size_t len; 4227c478bd9Sstevel@tonic-gate 4231ee2e5faSnakanon /* make sure fields is allocated */ 4241ee2e5faSnakanon adjust_buf(&fields, fields_size); 4257c478bd9Sstevel@tonic-gate fr = fields; 4267c478bd9Sstevel@tonic-gate *fr = '\0'; 4277c478bd9Sstevel@tonic-gate if (*rec == '\0') 4287c478bd9Sstevel@tonic-gate return (0); 4291ee2e5faSnakanon 4301ee2e5faSnakanon len = strlen((char *)rec) + 1; 4311ee2e5faSnakanon expand_buf(&fields, &fields_size, len); 4321ee2e5faSnakanon fr = fields; 4331ee2e5faSnakanon 4347c478bd9Sstevel@tonic-gate pfa = makedfa(fs, 1); 4357c478bd9Sstevel@tonic-gate dprintf(("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs)); 4367c478bd9Sstevel@tonic-gate tempstat = pfa->initstat; 4371ee2e5faSnakanon for (i = 1; ; i++) { 4381ee2e5faSnakanon p = getfld(i); 4391ee2e5faSnakanon if (!(p->tval & DONTFREE)) 4401ee2e5faSnakanon xfree(p->sval); 4411ee2e5faSnakanon p->tval = FLD | STR | DONTFREE; 4421ee2e5faSnakanon p->sval = fr; 4437c478bd9Sstevel@tonic-gate dprintf(("refldbld: i=%d\n", i)); 4447c478bd9Sstevel@tonic-gate if (nematch(pfa, rec)) { 4457c478bd9Sstevel@tonic-gate pfa->initstat = 2; 4467c478bd9Sstevel@tonic-gate dprintf(("match %s (%d chars)\n", patbeg, patlen)); 4471ee2e5faSnakanon (void) strncpy((char *)fr, (char *)rec, patbeg-rec); 4487c478bd9Sstevel@tonic-gate fr += patbeg - rec + 1; 4497c478bd9Sstevel@tonic-gate *(fr-1) = '\0'; 4507c478bd9Sstevel@tonic-gate rec = patbeg + patlen; 4517c478bd9Sstevel@tonic-gate } else { 4527c478bd9Sstevel@tonic-gate dprintf(("no match %s\n", rec)); 4531ee2e5faSnakanon (void) strcpy((char *)fr, (char *)rec); 4547c478bd9Sstevel@tonic-gate pfa->initstat = tempstat; 4557c478bd9Sstevel@tonic-gate break; 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate return (i); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4611ee2e5faSnakanon void 4621ee2e5faSnakanon recbld(void) 4637c478bd9Sstevel@tonic-gate { 4647c478bd9Sstevel@tonic-gate int i; 465cb4658fbSceastha uchar *p; 4661ee2e5faSnakanon size_t cnt, len, olen; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate if (donerec == 1) 4697c478bd9Sstevel@tonic-gate return; 4701ee2e5faSnakanon cnt = 0; 4711ee2e5faSnakanon olen = strlen((char *)*OFS); 4727c478bd9Sstevel@tonic-gate for (i = 1; i <= *NF; i++) { 4731ee2e5faSnakanon p = getsval(getfld(i)); 4741ee2e5faSnakanon len = strlen((char *)p); 475*8ef4c21aSnakanon expand_buf(&record, &record_size, cnt + len + olen); 476*8ef4c21aSnakanon (void) memcpy(&record[cnt], p, len); 4771ee2e5faSnakanon cnt += len; 4781ee2e5faSnakanon if (i < *NF) { 479*8ef4c21aSnakanon (void) memcpy(&record[cnt], *OFS, olen); 4801ee2e5faSnakanon cnt += olen; 4817c478bd9Sstevel@tonic-gate } 4821ee2e5faSnakanon } 483*8ef4c21aSnakanon record[cnt] = '\0'; 4841ee2e5faSnakanon dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); 485*8ef4c21aSnakanon if (!(recloc->tval & DONTFREE)) 486*8ef4c21aSnakanon xfree(recloc->sval); 4877c478bd9Sstevel@tonic-gate recloc->tval = REC | STR | DONTFREE; 488*8ef4c21aSnakanon recloc->sval = record; 4891ee2e5faSnakanon dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); 4907c478bd9Sstevel@tonic-gate dprintf(("recbld = |%s|\n", record)); 4917c478bd9Sstevel@tonic-gate donerec = 1; 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate Cell * 4951ee2e5faSnakanon fieldadr(int n) 4967c478bd9Sstevel@tonic-gate { 4971ee2e5faSnakanon if (n < 0) 4987c478bd9Sstevel@tonic-gate ERROR "trying to access field %d", n FATAL; 4991ee2e5faSnakanon return (getfld(n)); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate int errorflag = 0; 5037c478bd9Sstevel@tonic-gate char errbuf[200]; 5047c478bd9Sstevel@tonic-gate 5051ee2e5faSnakanon void 5061ee2e5faSnakanon yyerror(char *s) 5077c478bd9Sstevel@tonic-gate { 5087c478bd9Sstevel@tonic-gate extern uchar *cmdname, *curfname; 5097c478bd9Sstevel@tonic-gate static int been_here = 0; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate if (been_here++ > 2) 5127c478bd9Sstevel@tonic-gate return; 5131ee2e5faSnakanon (void) fprintf(stderr, "%s: %s", cmdname, s); 5141ee2e5faSnakanon (void) fprintf(stderr, gettext(" at source line %lld"), lineno); 5157c478bd9Sstevel@tonic-gate if (curfname != NULL) 5161ee2e5faSnakanon (void) fprintf(stderr, gettext(" in function %s"), curfname); 5171ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5187c478bd9Sstevel@tonic-gate errorflag = 2; 5197c478bd9Sstevel@tonic-gate eprint(); 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5221ee2e5faSnakanon /*ARGSUSED*/ 5231ee2e5faSnakanon void 5241ee2e5faSnakanon fpecatch(int sig) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate ERROR "floating point exception" FATAL; 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate extern int bracecnt, brackcnt, parencnt; 5307c478bd9Sstevel@tonic-gate 5311ee2e5faSnakanon void 5321ee2e5faSnakanon bracecheck(void) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate int c; 5357c478bd9Sstevel@tonic-gate static int beenhere = 0; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate if (beenhere++) 5387c478bd9Sstevel@tonic-gate return; 5397c478bd9Sstevel@tonic-gate while ((c = input()) != EOF && c != '\0') 5407c478bd9Sstevel@tonic-gate bclass(c); 5417c478bd9Sstevel@tonic-gate bcheck2(bracecnt, '{', '}'); 5427c478bd9Sstevel@tonic-gate bcheck2(brackcnt, '[', ']'); 5437c478bd9Sstevel@tonic-gate bcheck2(parencnt, '(', ')'); 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate 5461ee2e5faSnakanon /*ARGSUSED*/ 5471ee2e5faSnakanon static void 5481ee2e5faSnakanon bcheck2(int n, int c1, int c2) 5497c478bd9Sstevel@tonic-gate { 5507c478bd9Sstevel@tonic-gate if (n == 1) 5511ee2e5faSnakanon (void) fprintf(stderr, gettext("\tmissing %c\n"), c2); 5527c478bd9Sstevel@tonic-gate else if (n > 1) 5531ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d missing %c's\n"), n, c2); 5547c478bd9Sstevel@tonic-gate else if (n == -1) 5551ee2e5faSnakanon (void) fprintf(stderr, gettext("\textra %c\n"), c2); 5567c478bd9Sstevel@tonic-gate else if (n < -1) 5571ee2e5faSnakanon (void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2); 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 5601ee2e5faSnakanon void 5611ee2e5faSnakanon error(int f, char *s) 5627c478bd9Sstevel@tonic-gate { 5637c478bd9Sstevel@tonic-gate extern Node *curnode; 5647c478bd9Sstevel@tonic-gate extern uchar *cmdname; 5657c478bd9Sstevel@tonic-gate 5661ee2e5faSnakanon (void) fflush(stdout); 5671ee2e5faSnakanon (void) fprintf(stderr, "%s: ", cmdname); 5681ee2e5faSnakanon (void) fprintf(stderr, "%s", s); 5691ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5707c478bd9Sstevel@tonic-gate if (compile_time != 2 && NR && *NR > 0) { 5711ee2e5faSnakanon (void) fprintf(stderr, 5721ee2e5faSnakanon gettext(" input record number %g"), *FNR); 5731ee2e5faSnakanon if (strcmp((char *)*FILENAME, "-") != 0) 5741ee2e5faSnakanon (void) fprintf(stderr, gettext(", file %s"), *FILENAME); 5751ee2e5faSnakanon (void) fprintf(stderr, "\n"); 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate if (compile_time != 2 && curnode) 5781ee2e5faSnakanon (void) fprintf(stderr, gettext(" source line number %lld\n"), 5797c478bd9Sstevel@tonic-gate curnode->lineno); 5801ee2e5faSnakanon else if (compile_time != 2 && lineno) { 5811ee2e5faSnakanon (void) fprintf(stderr, 5821ee2e5faSnakanon gettext(" source line number %lld\n"), lineno); 5831ee2e5faSnakanon } 5847c478bd9Sstevel@tonic-gate eprint(); 5857c478bd9Sstevel@tonic-gate if (f) { 5867c478bd9Sstevel@tonic-gate if (dbg) 5877c478bd9Sstevel@tonic-gate abort(); 5887c478bd9Sstevel@tonic-gate exit(2); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate 5921ee2e5faSnakanon static void 5931ee2e5faSnakanon eprint(void) /* try to print context around error */ 5947c478bd9Sstevel@tonic-gate { 5957c478bd9Sstevel@tonic-gate uchar *p, *q; 5967c478bd9Sstevel@tonic-gate int c; 5977c478bd9Sstevel@tonic-gate static int been_here = 0; 5987c478bd9Sstevel@tonic-gate extern uchar ebuf[300], *ep; 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate if (compile_time == 2 || compile_time == 0 || been_here++ > 0) 6017c478bd9Sstevel@tonic-gate return; 6027c478bd9Sstevel@tonic-gate p = ep - 1; 6037c478bd9Sstevel@tonic-gate if (p > ebuf && *p == '\n') 6047c478bd9Sstevel@tonic-gate p--; 6057c478bd9Sstevel@tonic-gate for (; p > ebuf && *p != '\n' && *p != '\0'; p--) 6067c478bd9Sstevel@tonic-gate ; 6077c478bd9Sstevel@tonic-gate while (*p == '\n') 6087c478bd9Sstevel@tonic-gate p++; 6091ee2e5faSnakanon (void) fprintf(stderr, gettext(" context is\n\t")); 6101ee2e5faSnakanon for (q = ep-1; q >= p && *q != ' ' && *q != '\t' && *q != '\n'; q--) 6117c478bd9Sstevel@tonic-gate ; 6127c478bd9Sstevel@tonic-gate for (; p < q; p++) 6137c478bd9Sstevel@tonic-gate if (*p) 6141ee2e5faSnakanon (void) putc(*p, stderr); 6151ee2e5faSnakanon (void) fprintf(stderr, " >>> "); 6167c478bd9Sstevel@tonic-gate for (; p < ep; p++) 6177c478bd9Sstevel@tonic-gate if (*p) 6181ee2e5faSnakanon (void) putc(*p, stderr); 6191ee2e5faSnakanon (void) fprintf(stderr, " <<< "); 6207c478bd9Sstevel@tonic-gate if (*ep) 6217c478bd9Sstevel@tonic-gate while ((c = input()) != '\n' && c != '\0' && c != EOF) { 6221ee2e5faSnakanon (void) putc(c, stderr); 6237c478bd9Sstevel@tonic-gate bclass(c); 6247c478bd9Sstevel@tonic-gate } 6251ee2e5faSnakanon (void) putc('\n', stderr); 6267c478bd9Sstevel@tonic-gate ep = ebuf; 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6291ee2e5faSnakanon static void 6301ee2e5faSnakanon bclass(int c) 6317c478bd9Sstevel@tonic-gate { 6327c478bd9Sstevel@tonic-gate switch (c) { 6337c478bd9Sstevel@tonic-gate case '{': bracecnt++; break; 6347c478bd9Sstevel@tonic-gate case '}': bracecnt--; break; 6357c478bd9Sstevel@tonic-gate case '[': brackcnt++; break; 6367c478bd9Sstevel@tonic-gate case ']': brackcnt--; break; 6377c478bd9Sstevel@tonic-gate case '(': parencnt++; break; 6387c478bd9Sstevel@tonic-gate case ')': parencnt--; break; 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate double 6431ee2e5faSnakanon errcheck(double x, char *s) 6447c478bd9Sstevel@tonic-gate { 6457c478bd9Sstevel@tonic-gate extern int errno; 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate if (errno == EDOM) { 6487c478bd9Sstevel@tonic-gate errno = 0; 6497c478bd9Sstevel@tonic-gate ERROR "%s argument out of domain", s WARNING; 6507c478bd9Sstevel@tonic-gate x = 1; 6517c478bd9Sstevel@tonic-gate } else if (errno == ERANGE) { 6527c478bd9Sstevel@tonic-gate errno = 0; 6537c478bd9Sstevel@tonic-gate ERROR "%s result out of range", s WARNING; 6547c478bd9Sstevel@tonic-gate x = 1; 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate return (x); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate 6591ee2e5faSnakanon void 6601ee2e5faSnakanon PUTS(uchar *s) 6611ee2e5faSnakanon { 6627c478bd9Sstevel@tonic-gate dprintf(("%s\n", s)); 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6651ee2e5faSnakanon int 6661ee2e5faSnakanon isclvar(uchar *s) /* is s of form var=something? */ 6677c478bd9Sstevel@tonic-gate { 668cb4658fbSceastha if (s != NULL) { 6697c478bd9Sstevel@tonic-gate 670cb4658fbSceastha /* Must begin with an underscore or alphabetic character */ 671cb4658fbSceastha if (isalpha(*s) || (*s == '_')) { 672cb4658fbSceastha 673cb4658fbSceastha for (s++; *s; s++) { 674cb4658fbSceastha /* 675cb4658fbSceastha * followed by a sequence of underscores, 676cb4658fbSceastha * digits, and alphabetics 677cb4658fbSceastha */ 678cb4658fbSceastha if (!(isalnum(*s) || *s == '_')) { 6797c478bd9Sstevel@tonic-gate break; 680cb4658fbSceastha } 681cb4658fbSceastha } 682cb4658fbSceastha return (*s == '=' && *(s + 1) != '='); 683cb4658fbSceastha } 684cb4658fbSceastha } 685cb4658fbSceastha 686cb4658fbSceastha return (0); 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate #define MAXEXPON 38 /* maximum exponent for fp number */ 6907c478bd9Sstevel@tonic-gate 6911ee2e5faSnakanon int 6921ee2e5faSnakanon is_number(uchar *s) 6937c478bd9Sstevel@tonic-gate { 694cb4658fbSceastha int d1, d2; 6957c478bd9Sstevel@tonic-gate int point; 6967c478bd9Sstevel@tonic-gate uchar *es; 6977c478bd9Sstevel@tonic-gate extern char radixpoint; 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate d1 = d2 = point = 0; 7007c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 7017c478bd9Sstevel@tonic-gate s++; 7027c478bd9Sstevel@tonic-gate if (*s == '\0') 7037c478bd9Sstevel@tonic-gate return (0); /* empty stuff isn't number */ 7047c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7057c478bd9Sstevel@tonic-gate s++; 7067c478bd9Sstevel@tonic-gate if (!isdigit(*s) && *s != radixpoint) 7077c478bd9Sstevel@tonic-gate return (0); 7087c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7097c478bd9Sstevel@tonic-gate do { 7107c478bd9Sstevel@tonic-gate d1++; 7117c478bd9Sstevel@tonic-gate s++; 7127c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate if (d1 >= MAXEXPON) 7157c478bd9Sstevel@tonic-gate return (0); /* too many digits to convert */ 7167c478bd9Sstevel@tonic-gate if (*s == radixpoint) { 7177c478bd9Sstevel@tonic-gate point++; 7187c478bd9Sstevel@tonic-gate s++; 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate if (isdigit(*s)) { 7217c478bd9Sstevel@tonic-gate d2++; 7227c478bd9Sstevel@tonic-gate do { 7237c478bd9Sstevel@tonic-gate s++; 7247c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate if (!(d1 || point && d2)) 7277c478bd9Sstevel@tonic-gate return (0); 7287c478bd9Sstevel@tonic-gate if (*s == 'e' || *s == 'E') { 7297c478bd9Sstevel@tonic-gate s++; 7307c478bd9Sstevel@tonic-gate if (*s == '+' || *s == '-') 7317c478bd9Sstevel@tonic-gate s++; 7327c478bd9Sstevel@tonic-gate if (!isdigit(*s)) 7337c478bd9Sstevel@tonic-gate return (0); 7347c478bd9Sstevel@tonic-gate es = s; 7357c478bd9Sstevel@tonic-gate do { 7367c478bd9Sstevel@tonic-gate s++; 7377c478bd9Sstevel@tonic-gate } while (isdigit(*s)); 7381ee2e5faSnakanon if (s - es > 2) { 7397c478bd9Sstevel@tonic-gate return (0); 7401ee2e5faSnakanon } else if (s - es == 2 && 7411ee2e5faSnakanon (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) { 7427c478bd9Sstevel@tonic-gate return (0); 7437c478bd9Sstevel@tonic-gate } 7441ee2e5faSnakanon } 7457c478bd9Sstevel@tonic-gate while (*s == ' ' || *s == '\t' || *s == '\n') 7467c478bd9Sstevel@tonic-gate s++; 7477c478bd9Sstevel@tonic-gate if (*s == '\0') 7487c478bd9Sstevel@tonic-gate return (1); 7497c478bd9Sstevel@tonic-gate else 7507c478bd9Sstevel@tonic-gate return (0); 7517c478bd9Sstevel@tonic-gate } 7521ee2e5faSnakanon 7531ee2e5faSnakanon void 7541ee2e5faSnakanon init_buf(uchar **optr, size_t *sizep, size_t amt) 7551ee2e5faSnakanon { 7561ee2e5faSnakanon uchar *nptr = NULL; 7571ee2e5faSnakanon 7581ee2e5faSnakanon if ((nptr = malloc(amt)) == NULL) 7591ee2e5faSnakanon ERROR "out of space in init_buf" FATAL; 7601ee2e5faSnakanon /* initial buffer should have NULL terminated */ 7611ee2e5faSnakanon *nptr = '\0'; 7621ee2e5faSnakanon if (sizep != NULL) 7631ee2e5faSnakanon *sizep = amt; 7641ee2e5faSnakanon *optr = nptr; 7651ee2e5faSnakanon } 7661ee2e5faSnakanon 7671ee2e5faSnakanon void 7681ee2e5faSnakanon r_expand_buf(uchar **optr, size_t *sizep, size_t req) 7691ee2e5faSnakanon { 7701ee2e5faSnakanon uchar *nptr; 7711ee2e5faSnakanon size_t amt, size = *sizep; 7721ee2e5faSnakanon 7731ee2e5faSnakanon if (size != 0 && req < (size - 1)) 7741ee2e5faSnakanon return; 7751ee2e5faSnakanon amt = req + 1 - size; 7761ee2e5faSnakanon amt = (amt / LINE_INCR + 1) * LINE_INCR; 7771ee2e5faSnakanon 7781ee2e5faSnakanon if ((nptr = realloc(*optr, size + amt)) == NULL) 7791ee2e5faSnakanon ERROR "out of space in expand_buf" FATAL; 7801ee2e5faSnakanon /* initial buffer should have NULL terminated */ 7811ee2e5faSnakanon if (size == 0) 7821ee2e5faSnakanon *nptr = '\0'; 7831ee2e5faSnakanon *sizep += amt; 7841ee2e5faSnakanon *optr = nptr; 7851ee2e5faSnakanon } 7861ee2e5faSnakanon 7871ee2e5faSnakanon void 7881ee2e5faSnakanon adjust_buf(uchar **optr, size_t size) 7891ee2e5faSnakanon { 7901ee2e5faSnakanon uchar *nptr; 7911ee2e5faSnakanon 7921ee2e5faSnakanon if ((nptr = realloc(*optr, size)) == NULL) 7931ee2e5faSnakanon ERROR "out of space in adjust_buf" FATAL; 7941ee2e5faSnakanon *optr = nptr; 7951ee2e5faSnakanon } 796