ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rcalc.c
Revision: 1.11
Committed: Fri Nov 14 17:31:24 2003 UTC (20 years, 4 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.10: +3 -1 lines
Log Message:
Reduced compile warnings.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.11 static const char RCSid[] = "$Id: rcalc.c,v 1.10 2003/11/06 05:39:33 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * rcalc.c - record calculator program.
6     *
7     * 9/11/87
8     */
9    
10 schorsch 1.5 #include <stdlib.h>
11 schorsch 1.11 #include <fcntl.h>
12 greg 1.1 #include <stdio.h>
13 schorsch 1.5 #include <string.h>
14 greg 1.1 #include <math.h>
15     #include <ctype.h>
16    
17 schorsch 1.5 #include "platform.h"
18 greg 1.1 #include "calcomp.h"
19 schorsch 1.7 #include "rterror.h"
20 greg 1.1
21     #define isnum(c) (isdigit(c) || (c)=='-' || (c)=='.' \
22     || (c)=='+' || (c)=='e' || (c)=='E')
23    
24     #define isblnk(c) (igneol ? isspace(c) : (c)==' '||(c)=='\t')
25    
26     #define INBSIZ 4096 /* longest record */
27     #define MAXCOL 32 /* number of columns recorded */
28    
29     /* field type specifications */
30     #define F_NUL 0 /* empty */
31     #define F_TYP 0x7000 /* mask for type */
32     #define F_WID 0x0fff /* mask for width */
33     #define T_LIT 0x1000 /* string literal */
34     #define T_STR 0x2000 /* string variable */
35     #define T_NUM 0x3000 /* numeric value */
36    
37     struct strvar { /* string variable */
38     char *name;
39     char *val;
40     char *preset;
41     struct strvar *next;
42     };
43    
44     struct field { /* record format structure */
45     int type; /* type of field (& width) */
46     union {
47     char *sl; /* string literal */
48     struct strvar *sv; /* string variable */
49     char *nv; /* numeric variable */
50     EPNODE *ne; /* numeric expression */
51     } f; /* field contents */
52     struct field *next; /* next field in record */
53     };
54    
55     #define savqstr(s) strcpy(emalloc(strlen(s)+1),s)
56     #define freqstr(s) efree(s)
57    
58 greg 1.10 static int getinputrec(FILE *fp);
59 schorsch 1.5 static void scaninp(void), advinp(void), resetinp(void);
60     static void putrec(void), putout(void), nbsynch(void);
61     static int getrec(void);
62     static void execute(char *file);
63     static void initinp(FILE *fp);
64     static void svpreset(char *eqn);
65     static void readfmt(char *spec, int output);
66     static int readfield(char **pp);
67     static int getfield(struct field *f);
68     static void chanset(int n, double v);
69     static void bchanset(int n, double v);
70     static struct strvar* getsvar(char *svname);
71 greg 1.10 static double l_in(char *);
72 greg 1.1
73     struct field *inpfmt = NULL; /* input record format */
74     struct field *outfmt = NULL; /* output record structure */
75     struct strvar *svhead = NULL; /* string variables */
76    
77     int blnkeq = 1; /* blanks compare equal? */
78     int igneol = 0; /* ignore end of line? */
79     char sepchar = '\t'; /* input/output separator */
80     int noinput = 0; /* no input records? */
81 greg 1.3 int nbicols = 0; /* number of binary input columns */
82     int bocols = 0; /* produce binary output columns */
83 greg 1.1 char inpbuf[INBSIZ]; /* input buffer */
84     double colval[MAXCOL]; /* input column values */
85     unsigned long colflg = 0; /* column retrieved flags */
86     int colpos; /* output column position */
87    
88     int nowarn = 0; /* non-fatal diagnostic output */
89     int unbuff = 0; /* unbuffered output (flush each record) */
90    
91     struct {
92     FILE *fin; /* input file */
93     int chr; /* next character */
94     char *beg; /* home position */
95     char *pos; /* scan position */
96     char *end; /* read position */
97     } ipb; /* circular lookahead buffer */
98    
99    
100 schorsch 1.5 int
101     main(
102     int argc,
103     char *argv[]
104     )
105 greg 1.1 {
106     int i;
107    
108 greg 1.2 esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST;
109     esupport &= ~(E_REDEFW);
110 greg 1.1
111     #ifdef BIGGERLIB
112     biggerlib();
113     #endif
114     varset("PI", ':', 3.14159265358979323846);
115 greg 1.10 funset("in", 1, '=', &l_in);
116 greg 1.1
117     for (i = 1; i < argc && argv[i][0] == '-'; i++)
118     switch (argv[i][1]) {
119     case 'b':
120     blnkeq = !blnkeq;
121     break;
122     case 'l':
123     igneol = !igneol;
124     break;
125     case 't':
126     sepchar = argv[i][2];
127     break;
128     case 's':
129     svpreset(argv[++i]);
130     break;
131     case 'f':
132     fcompile(argv[++i]);
133     break;
134     case 'e':
135     scompile(argv[++i], NULL, 0);
136     break;
137     case 'n':
138     noinput = 1;
139     break;
140     case 'i':
141 greg 1.3 switch (argv[i][2]) {
142     case '\0':
143     nbicols = 0;
144     readfmt(argv[++i], 0);
145     break;
146     case 'a':
147     nbicols = 0;
148     break;
149     case 'd':
150     if (isdigit(argv[i][3]))
151     nbicols = atoi(argv[i]+3);
152     else
153     nbicols = 1;
154 greg 1.9 if (nbicols*sizeof(double) > INBSIZ) {
155     eputs(argv[0]);
156     eputs(": too many input columns\n");
157     quit(1);
158     }
159 greg 1.3 break;
160     case 'f':
161     if (isdigit(argv[i][3]))
162     nbicols = -atoi(argv[i]+3);
163     else
164     nbicols = -1;
165 greg 1.9 if (-nbicols*sizeof(float) > INBSIZ) {
166     eputs(argv[0]);
167     eputs(": too many input columns\n");
168     quit(1);
169     }
170 greg 1.3 break;
171     default:
172     goto userr;
173     }
174 greg 1.1 break;
175     case 'o':
176 greg 1.3 switch (argv[i][2]) {
177     case '\0':
178     bocols = 0;
179     readfmt(argv[++i], 1);
180     break;
181     case 'a':
182     bocols = 0;
183     break;
184     case 'd':
185     bocols = 1;
186     break;
187     case 'f':
188     bocols = -1;
189     break;
190     }
191 greg 1.1 break;
192     case 'w':
193     nowarn = !nowarn;
194     break;
195     case 'u':
196     unbuff = !unbuff;
197     break;
198 greg 1.3 default:;
199     userr:
200 greg 1.1 eputs("Usage: ");
201     eputs(argv[0]);
202     eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
203     quit(1);
204     }
205    
206     if (noinput) { /* produce a single output record */
207     eclock++;
208     putout();
209     quit(0);
210     }
211    
212     if (blnkeq) /* for efficiency */
213     nbsynch();
214    
215     if (i == argc) /* from stdin */
216     execute(NULL);
217     else /* from one or more files */
218     for ( ; i < argc; i++)
219     execute(argv[i]);
220    
221     quit(0);
222 schorsch 1.11 return 0; /* pro forma return */
223 greg 1.1 }
224    
225    
226 schorsch 1.5 static void
227     nbsynch(void) /* non-blank starting synch character */
228 greg 1.1 {
229     if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT)
230     return;
231     while (isblnk(*inpfmt->f.sl))
232     inpfmt->f.sl++;
233     if (!*inpfmt->f.sl)
234     inpfmt = inpfmt->next;
235     }
236    
237    
238 greg 1.10 static int
239 schorsch 1.5 getinputrec( /* get next input record */
240     FILE *fp
241     )
242 greg 1.3 {
243     if (inpfmt != NULL)
244     return(getrec());
245     if (nbicols > 0)
246     return(fread(inpbuf, sizeof(double),
247     nbicols, fp) == nbicols);
248     if (nbicols < 0)
249     return(fread(inpbuf, sizeof(float),
250     -nbicols, fp) == -nbicols);
251     return(fgets(inpbuf, INBSIZ, fp) != NULL);
252     }
253    
254    
255 schorsch 1.5 static void
256     execute( /* process a file */
257     char *file
258     )
259 greg 1.1 {
260     int conditional = vardefined("cond");
261     long nrecs = 0;
262     long nout = 0;
263     FILE *fp;
264    
265     if (file == NULL)
266     fp = stdin;
267     else if ((fp = fopen(file, "r")) == NULL) {
268     eputs(file);
269     eputs(": cannot open\n");
270     quit(1);
271     }
272     if (inpfmt != NULL)
273     initinp(fp);
274 greg 1.3
275     while (getinputrec(fp)) {
276 greg 1.1 varset("recno", '=', (double)++nrecs);
277     colflg = 0;
278     eclock++;
279     if (!conditional || varvalue("cond") > 0.0) {
280     varset("outno", '=', (double)++nout);
281     putout();
282     }
283     }
284     fclose(fp);
285     }
286    
287    
288 schorsch 1.5 static void
289     putout(void) /* produce an output record */
290 greg 1.1 {
291    
292     colpos = 0;
293     if (outfmt != NULL)
294     putrec();
295 greg 1.3 else if (bocols)
296     chanout(bchanset);
297 greg 1.1 else
298     chanout(chanset);
299 greg 1.4 if (colpos && !bocols)
300 greg 1.1 putchar('\n');
301     if (unbuff)
302     fflush(stdout);
303     }
304    
305 greg 1.10
306     static double
307     l_in(char *funame) /* function call for $channel */
308     {
309     int n;
310     register char *cp;
311     /* get argument as integer */
312     n = (int)(argument(1) + .5);
313     if (n != 0) /* return channel value */
314     return(chanvalue(n));
315     /* determine number of channels */
316     if (noinput || inpfmt != NULL)
317     return(0);
318     if (nbicols > 0)
319     return(nbicols);
320     if (nbicols < 0)
321     return(-nbicols);
322     cp = inpbuf; /* need to count */
323     for (n = 0; *cp; )
324     if (blnkeq && isspace(sepchar)) {
325     while (isspace(*cp))
326     cp++;
327     n += *cp != '\0';
328     while (*cp && !isspace(*cp))
329     cp++;
330     } else {
331     n += *cp != '\n';
332     while (*cp && *cp++ != sepchar)
333     ;
334     }
335     return(n);
336     }
337 greg 1.1
338     double
339 schorsch 1.5 chanvalue( /* return value for column n */
340     int n
341     )
342 greg 1.1 {
343     int i;
344     register char *cp;
345    
346     if (noinput || inpfmt != NULL) {
347     eputs("no column input\n");
348     quit(1);
349     }
350     if (n < 1) {
351     eputs("illegal channel number\n");
352     quit(1);
353     }
354 greg 1.3 if (nbicols > 0) {
355     if (n > nbicols)
356     return(0.0);
357     cp = inpbuf + (n-1)*sizeof(double);
358     return(*(double *)cp);
359     }
360     if (nbicols < 0) {
361     if (n > -nbicols)
362     return(0.0);
363     cp = inpbuf + (n-1)*sizeof(float);
364     return(*(float *)cp);
365     }
366 greg 1.1 if (n <= MAXCOL && colflg & 1L<<(n-1))
367     return(colval[n-1]);
368    
369     cp = inpbuf;
370     for (i = 1; i < n; i++)
371     if (blnkeq && isspace(sepchar)) {
372     while (isspace(*cp))
373     cp++;
374     while (*cp && !isspace(*cp))
375     cp++;
376     } else
377     while (*cp && *cp++ != sepchar)
378     ;
379    
380     while (isspace(*cp)) /* some atof()'s don't like tabs */
381     cp++;
382    
383     if (n <= MAXCOL) {
384     colflg |= 1L<<(n-1);
385     return(colval[n-1] = atof(cp));
386     } else
387     return(atof(cp));
388     }
389    
390    
391 greg 1.3 void
392 schorsch 1.5 chanset( /* output column n */
393     int n,
394     double v
395     )
396 greg 1.1 {
397     if (colpos == 0) /* no leading separator */
398     colpos = 1;
399     while (colpos < n) {
400     putchar(sepchar);
401     colpos++;
402     }
403     printf("%.9g", v);
404 greg 1.3 }
405    
406    
407     void
408 schorsch 1.5 bchanset( /* output binary channel n */
409     int n,
410     double v
411     )
412 greg 1.3 {
413     static char zerobuf[sizeof(double)];
414    
415     while (++colpos < n)
416     fwrite(zerobuf,
417     bocols>0 ? sizeof(double) : sizeof(float),
418     1, stdout);
419     if (bocols > 0)
420     fwrite(&v, sizeof(double), 1, stdout);
421     else {
422     float fval = v;
423     fwrite(&fval, sizeof(float), 1, stdout);
424     }
425 greg 1.1 }
426    
427    
428 schorsch 1.5 static void
429     readfmt( /* read record format */
430     char *spec,
431     int output
432     )
433 greg 1.1 {
434     int fd;
435     char *inptr;
436     struct field fmt;
437     int res;
438     register struct field *f;
439     /* check for inline format */
440     for (inptr = spec; *inptr; inptr++)
441     if (*inptr == '$')
442     break;
443     if (*inptr) /* inline */
444     inptr = spec;
445     else { /* from file */
446     if ((fd = open(spec, 0)) == -1) {
447     eputs(spec);
448     eputs(": cannot open\n");
449     quit(1);
450     }
451     res = read(fd, inpbuf+1, INBSIZ-1);
452     if (res <= 0 || res >= INBSIZ-1) {
453     eputs(spec);
454     if (res < 0)
455     eputs(": read error\n");
456     else if (res == 0)
457     eputs(": empty file\n");
458     else if (res >= INBSIZ-1)
459     eputs(": format too long\n");
460     quit(1);
461     }
462     close(fd);
463     (inptr=inpbuf+1)[res] = '\0';
464     }
465     f = &fmt; /* get fields */
466     while ((res = readfield(&inptr)) != F_NUL) {
467     f->next = (struct field *)emalloc(sizeof(struct field));
468     f = f->next;
469     f->type = res;
470     switch (res & F_TYP) {
471     case T_LIT:
472     f->f.sl = savqstr(inpbuf);
473     break;
474     case T_STR:
475     f->f.sv = getsvar(inpbuf);
476     break;
477     case T_NUM:
478     if (output)
479     f->f.ne = eparse(inpbuf);
480     else
481     f->f.nv = savestr(inpbuf);
482     break;
483     }
484     /* add final newline if necessary */
485     if (!igneol && *inptr == '\0' && inptr[-1] != '\n')
486     inptr = "\n";
487     }
488     f->next = NULL;
489     if (output)
490     outfmt = fmt.next;
491     else
492     inpfmt = fmt.next;
493     }
494    
495    
496 schorsch 1.5 static int
497     readfield( /* get next field in format */
498     register char **pp
499     )
500 greg 1.1 {
501     int type = F_NUL;
502     int width = 0;
503     register char *cp;
504    
505     cp = inpbuf;
506     while (cp < &inpbuf[INBSIZ-1] && **pp != '\0') {
507     width++;
508     switch (type) {
509     case F_NUL:
510     if (**pp == '$') {
511     (*pp)++;
512     width++;
513     if (**pp == '{') {
514     type = T_NUM;
515     (*pp)++;
516     continue;
517     } else if (**pp == '(') {
518     type = T_STR;
519     (*pp)++;
520     continue;
521     } else if (**pp != '$') {
522     eputs("format error\n");
523     quit(1);
524     }
525     width--;
526     }
527     type = T_LIT;
528     *cp++ = *(*pp)++;
529     continue;
530     case T_LIT:
531     if (**pp == '$') {
532     width--;
533     break;
534     }
535     *cp++ = *(*pp)++;
536     continue;
537     case T_NUM:
538     if (**pp == '}') {
539     (*pp)++;
540     break;
541     }
542     if (!isspace(**pp))
543     *cp++ = **pp;
544     (*pp)++;
545     continue;
546     case T_STR:
547     if (**pp == ')') {
548     (*pp)++;
549     break;
550     }
551     if (!isspace(**pp))
552     *cp++ = **pp;
553     (*pp)++;
554     continue;
555     }
556     break;
557     }
558     *cp = '\0';
559     return(type | width);
560     }
561    
562    
563     struct strvar *
564 schorsch 1.5 getsvar( /* get string variable */
565     char *svname
566     )
567 greg 1.1 {
568     register struct strvar *sv;
569    
570     for (sv = svhead; sv != NULL; sv = sv->next)
571     if (!strcmp(sv->name, svname))
572     return(sv);
573     sv = (struct strvar *)emalloc(sizeof(struct strvar));
574     sv->name = savqstr(svname);
575     sv->val = sv->preset = NULL;
576     sv->next = svhead;
577     svhead = sv;
578     return(sv);
579     }
580    
581    
582 schorsch 1.5 static void
583     svpreset( /* preset a string variable */
584     char *eqn
585     )
586 greg 1.1 {
587     register struct strvar *sv;
588     register char *val;
589    
590     for (val = eqn; *val != '='; val++)
591     if (!*val)
592     return;
593     *val++ = '\0';
594     sv = getsvar(eqn);
595     if (sv->preset != NULL)
596     freqstr(sv->preset);
597     if (sv->val != NULL)
598     freqstr(sv->val);
599     sv->val = sv->preset = savqstr(val);
600     *--val = '=';
601     }
602    
603    
604 schorsch 1.5 static void
605     clearrec(void) /* clear input record variables */
606 greg 1.1 {
607     register struct field *f;
608    
609     for (f = inpfmt; f != NULL; f = f->next)
610     switch (f->type & F_TYP) {
611     case T_NUM:
612     dremove(f->f.nv);
613     break;
614     case T_STR:
615     if (f->f.sv->val != f->f.sv->preset) {
616     freqstr(f->f.sv->val);
617     f->f.sv->val = f->f.sv->preset;
618     }
619     break;
620     }
621     }
622    
623    
624 schorsch 1.5 static int
625     getrec(void) /* get next record from file */
626 greg 1.1 {
627     int eatline;
628     register struct field *f;
629    
630     while (ipb.chr != EOF) {
631     eatline = !igneol && ipb.chr != '\n';
632     if (blnkeq) /* beware of nbsynch() */
633     while (isblnk(ipb.chr))
634     scaninp();
635     clearrec(); /* start with fresh record */
636     for (f = inpfmt; f != NULL; f = f->next)
637     if (getfield(f) == -1)
638     break;
639     if (f == NULL) {
640     advinp();
641     return(1);
642     }
643     resetinp();
644     if (eatline) { /* eat rest of line */
645     while (ipb.chr != '\n') {
646     if (ipb.chr == EOF)
647     return(0);
648     scaninp();
649     }
650     scaninp();
651     advinp();
652     }
653     }
654     return(0);
655     }
656    
657    
658 schorsch 1.5 static int
659     getfield( /* get next field */
660     register struct field *f
661     )
662 greg 1.1 {
663 schorsch 1.6 static char buf[RMAXWORD+1]; /* no recursion! */
664 greg 1.1 int delim, inword;
665     double d;
666     char *np;
667     register char *cp;
668    
669     switch (f->type & F_TYP) {
670     case T_LIT:
671     cp = f->f.sl;
672     do {
673     if (blnkeq && isblnk(*cp)) {
674     if (!isblnk(ipb.chr))
675     return(-1);
676     do
677     cp++;
678     while (isblnk(*cp));
679     do
680     scaninp();
681     while (isblnk(ipb.chr));
682     } else if (*cp == ipb.chr) {
683     cp++;
684     scaninp();
685     } else
686     return(-1);
687     } while (*cp);
688     return(0);
689     case T_STR:
690     if (f->next == NULL || (f->next->type & F_TYP) != T_LIT)
691     delim = EOF;
692     else
693     delim = f->next->f.sl[0];
694     cp = buf;
695     do {
696 greg 1.9 if (ipb.chr == EOF || ipb.chr == '\n')
697 greg 1.1 inword = 0;
698     else if (blnkeq && delim != EOF)
699     inword = isblnk(delim) ?
700     !isblnk(ipb.chr)
701     : ipb.chr != delim;
702     else
703     inword = cp-buf < (f->type & F_WID);
704     if (inword) {
705     *cp++ = ipb.chr;
706     scaninp();
707     }
708 schorsch 1.6 } while (inword && cp < &buf[RMAXWORD]);
709 greg 1.1 *cp = '\0';
710     if (f->f.sv->val == NULL)
711     f->f.sv->val = savqstr(buf); /* first setting */
712     else if (strcmp(f->f.sv->val, buf))
713     return(-1); /* doesn't match! */
714     return(0);
715     case T_NUM:
716     if (f->next == NULL || (f->next->type & F_TYP) != T_LIT)
717     delim = EOF;
718     else
719     delim = f->next->f.sl[0];
720     np = NULL;
721     cp = buf;
722     do {
723     if (!((np==NULL&&isblnk(ipb.chr)) || isnum(ipb.chr)))
724     inword = 0;
725     else if (blnkeq && delim != EOF)
726     inword = isblnk(delim) ?
727     !isblnk(ipb.chr)
728     : ipb.chr != delim;
729     else
730     inword = cp-buf < (f->type & F_WID);
731     if (inword) {
732     if (np==NULL && !isblnk(ipb.chr))
733     np = cp;
734     *cp++ = ipb.chr;
735     scaninp();
736     }
737 schorsch 1.6 } while (inword && cp < &buf[RMAXWORD]);
738 greg 1.1 *cp = '\0';
739     d = np==NULL ? 0. : atof(np);
740     if (!vardefined(f->f.nv))
741     varset(f->f.nv, '=', d); /* first setting */
742     else if ((d = (varvalue(f->f.nv)-d)/(d==0.?1.:d)) > .001
743     || d < -.001)
744     return(-1); /* doesn't match! */
745     return(0);
746     }
747 schorsch 1.5 return -1; /* pro forma return */
748 greg 1.1 }
749    
750    
751 schorsch 1.5 static void
752     putrec(void) /* output a record */
753 greg 1.1 {
754     char fmt[32];
755     register int n;
756     register struct field *f;
757     int adlast, adnext;
758    
759     adlast = 0;
760     for (f = outfmt; f != NULL; f = f->next) {
761     adnext = blnkeq &&
762     f->next != NULL &&
763     !( (f->next->type&F_TYP) == T_LIT &&
764     f->next->f.sl[0] == ' ' );
765     switch (f->type & F_TYP) {
766     case T_LIT:
767     fputs(f->f.sl, stdout);
768     adlast = f->f.sl[(f->type&F_WID)-1] != ' ';
769     break;
770     case T_STR:
771     if (f->f.sv->val == NULL) {
772     eputs(f->f.sv->name);
773     eputs(": undefined string\n");
774     quit(1);
775     }
776     n = (int)(f->type & F_WID) - strlen(f->f.sv->val);
777     if (adlast)
778     fputs(f->f.sv->val, stdout);
779     if (!(adlast && adnext))
780     while (n-- > 0)
781     putchar(' ');
782     if (!adlast)
783     fputs(f->f.sv->val, stdout);
784     adlast = 1;
785     break;
786     case T_NUM:
787     n = f->type & F_WID;
788     if (adlast && adnext)
789     strcpy(fmt, "%g");
790     else if (adlast)
791     sprintf(fmt, "%%-%dg", n);
792     else
793     sprintf(fmt, "%%%dg", n);
794     printf(fmt, evalue(f->f.ne));
795     adlast = 1;
796     break;
797     }
798     }
799     }
800    
801    
802 schorsch 1.5 static void
803     initinp(FILE *fp) /* prepare lookahead buffer */
804    
805 greg 1.1 {
806     ipb.fin = fp;
807     ipb.beg = ipb.end = inpbuf;
808     ipb.pos = inpbuf-1; /* position before beginning */
809     ipb.chr = '\0';
810     scaninp();
811     }
812    
813    
814 schorsch 1.5 static void
815     scaninp(void) /* scan next character */
816 greg 1.1 {
817     if (ipb.chr == EOF)
818     return;
819     if (++ipb.pos >= &inpbuf[INBSIZ])
820     ipb.pos = inpbuf;
821     if (ipb.pos == ipb.end) { /* new character */
822     if ((ipb.chr = getc(ipb.fin)) != EOF) {
823     *ipb.end = ipb.chr;
824     if (++ipb.end >= &inpbuf[INBSIZ])
825     ipb.end = inpbuf;
826     if (ipb.end == ipb.beg)
827     ipb.beg = NULL;
828     }
829     } else
830     ipb.chr = *ipb.pos;
831     }
832    
833    
834 schorsch 1.5 static void
835     advinp(void) /* move home to current position */
836 greg 1.1 {
837     ipb.beg = ipb.pos;
838     }
839    
840    
841 schorsch 1.5 static void
842     resetinp(void) /* rewind position and advance 1 */
843 greg 1.1 {
844     if (ipb.beg == NULL) /* full */
845     ipb.beg = ipb.end;
846     ipb.pos = ipb.beg;
847     ipb.chr = *ipb.pos;
848     if (++ipb.beg >= &inpbuf[INBSIZ])
849     ipb.beg = inpbuf;
850     scaninp();
851     }
852    
853    
854     void
855 schorsch 1.5 eputs(char *msg)
856 greg 1.1 {
857     fputs(msg, stderr);
858     }
859    
860    
861     void
862 schorsch 1.5 wputs(char *msg)
863 greg 1.1 {
864     if (!nowarn)
865     eputs(msg);
866     }
867    
868    
869     void
870 schorsch 1.5 quit(int code)
871 greg 1.1 {
872     exit(code);
873     }