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
initgetrec(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
getrec(uchar ** bufp,size_t * bufsizep)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
readrec(uchar ** bufp,size_t * sizep,FILE * inf)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 *
getargv(int n)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
setclvar(uchar * s)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
fldbld(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
cleanfld(int n1,int n2)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
newfld(int n)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
morefld(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 *
getfld(int idx)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
fldidx(Cell * vp)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
refldbld(uchar * rec,uchar * fs)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
recbld(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 *
fieldadr(int n)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
yyerror(char * s)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
fpecatch(int sig)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
bracecheck(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
bcheck2(int n,int c1,int c2)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
error(int f,char * s)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
eprint(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
bclass(int c)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
errcheck(double x,char * s)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
PUTS(uchar * s)6601ee2e5faSnakanon PUTS(uchar *s)
6611ee2e5faSnakanon {
6627c478bd9Sstevel@tonic-gate dprintf(("%s\n", s));
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate
6651ee2e5faSnakanon int
isclvar(uchar * s)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
is_number(uchar * s)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
init_buf(uchar ** optr,size_t * sizep,size_t amt)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
r_expand_buf(uchar ** optr,size_t * sizep,size_t req)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
adjust_buf(uchar ** optr,size_t size)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