ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rcalc.c
(Generate patch)

Comparing ray/src/cal/rcalc.c (file contents):
Revision 1.1 by greg, Sat Feb 22 02:07:20 2003 UTC vs.
Revision 1.17 by greg, Wed Feb 16 17:20:22 2005 UTC

# Line 1 | Line 1
1   #ifndef lint
2 < static const char       RCSid[] = "$Id$";
2 > static const char RCSid[] = "$Id$";
3   #endif
4   /*
5   *  rcalc.c - record calculator program.
# Line 7 | Line 7 | static const char      RCSid[] = "$Id$";
7   *     9/11/87
8   */
9  
10 #include  <stdio.h>
11
10   #include  <stdlib.h>
11 <
11 > #include  <fcntl.h>
12 > #include  <stdio.h>
13 > #include  <string.h>
14   #include  <math.h>
15
15   #include  <ctype.h>
16  
17 + #include  "platform.h"
18 + #include  "rterror.h"
19 + #include  "rtmisc.h"
20 + #include  "rtio.h"
21   #include  "calcomp.h"
22  
20 #ifdef  CPM
21 #define  getc           agetc   /* text files only, right? */
22 #endif
23
23   #define  isnum(c)       (isdigit(c) || (c)=='-' || (c)=='.' \
24                                  || (c)=='+' || (c)=='e' || (c)=='E')
25  
26   #define  isblnk(c)      (igneol ? isspace(c) : (c)==' '||(c)=='\t')
27  
28 < #define  INBSIZ         4096    /* longest record */
28 > #define  INBSIZ         16384   /* longest record */
29   #define  MAXCOL         32      /* number of columns recorded */
30  
31                                  /* field type specifications */
# Line 58 | Line 57 | struct field {                  /* record format struc
57   #define  savqstr(s)     strcpy(emalloc(strlen(s)+1),s)
58   #define  freqstr(s)     efree(s)
59  
60 < extern char  *strcpy(), *emalloc(), *savestr();
61 < struct strvar  *getsvar();
60 > static int getinputrec(FILE *fp);
61 > static void scaninp(void), advinp(void), resetinp(void);
62 > static void putrec(void), putout(void), nbsynch(void);
63 > static int getrec(void);
64 > static void execute(char *file);
65 > static void initinp(FILE *fp);
66 > static void svpreset(char *eqn);
67 > static void readfmt(char *spec, int output);
68 > static int readfield(char **pp);
69 > static int getfield(struct field *f);
70 > static void chanset(int n, double v);
71 > static void bchanset(int n, double v);
72 > static struct strvar* getsvar(char *svname);
73 > static double l_in(char *);
74  
75   struct field  *inpfmt = NULL;   /* input record format */
76   struct field  *outfmt = NULL;   /* output record structure */
# Line 67 | Line 78 | struct strvar  *svhead = NULL;  /* string variables */
78  
79   int  blnkeq = 1;                /* blanks compare equal? */
80   int  igneol = 0;                /* ignore end of line? */
81 + int  passive = 0;               /* passive mode (transmit unmatched input) */
82   char  sepchar = '\t';           /* input/output separator */
83   int  noinput = 0;               /* no input records? */
84 + int  nbicols = 0;               /* number of binary input columns */
85 + int  bocols = 0;                /* produce binary output columns */
86   char  inpbuf[INBSIZ];           /* input buffer */
87   double  colval[MAXCOL];         /* input column values */
88   unsigned long  colflg = 0;      /* column retrieved flags */
# Line 86 | Line 100 | struct {
100   } ipb;                          /* circular lookahead buffer */
101  
102  
103 < main(argc, argv)
104 < int  argc;
105 < char  *argv[];
103 > int
104 > main(
105 > int  argc,
106 > char  *argv[]
107 > )
108   {
109          int  i;
110  
111 <        esupport |= (E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST);
111 >        esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST;
112 >        esupport &= ~(E_REDEFW);
113  
114   #ifdef  BIGGERLIB
115          biggerlib();
116   #endif
117          varset("PI", ':', 3.14159265358979323846);
118 +        funset("in", 1, '=', &l_in);
119  
120          for (i = 1; i < argc && argv[i][0] == '-'; i++)
121                  switch (argv[i][1]) {
# Line 107 | Line 125 | char  *argv[];
125                  case 'l':
126                          igneol = !igneol;
127                          break;
128 +                case 'p':
129 +                        passive = !passive;
130 +                        break;
131                  case 't':
132                          sepchar = argv[i][2];
133                          break;
# Line 123 | Line 144 | char  *argv[];
144                          noinput = 1;
145                          break;
146                  case 'i':
147 <                        readfmt(argv[++i], 0);
147 >                        switch (argv[i][2]) {
148 >                        case '\0':
149 >                                nbicols = 0;
150 >                                readfmt(argv[++i], 0);
151 >                                break;
152 >                        case 'a':
153 >                                nbicols = 0;
154 >                                break;
155 >                        case 'd':
156 >                                if (isdigit(argv[i][3]))
157 >                                        nbicols = atoi(argv[i]+3);
158 >                                else
159 >                                        nbicols = 1;
160 >                                if (nbicols*sizeof(double) > INBSIZ) {
161 >                                        eputs(argv[0]);
162 >                                        eputs(": too many input columns\n");
163 >                                        quit(1);
164 >                                }
165 >                                break;
166 >                        case 'f':
167 >                                if (isdigit(argv[i][3]))
168 >                                        nbicols = -atoi(argv[i]+3);
169 >                                else
170 >                                        nbicols = -1;
171 >                                if (-nbicols*sizeof(float) > INBSIZ) {
172 >                                        eputs(argv[0]);
173 >                                        eputs(": too many input columns\n");
174 >                                        quit(1);
175 >                                }
176 >                                break;
177 >                        default:
178 >                                goto userr;
179 >                        }
180                          break;
181                  case 'o':
182 <                        readfmt(argv[++i], 1);
182 >                        switch (argv[i][2]) {
183 >                        case '\0':
184 >                                bocols = 0;
185 >                                readfmt(argv[++i], 1);
186 >                                break;
187 >                        case 'a':
188 >                                bocols = 0;
189 >                                break;
190 >                        case 'd':
191 >                                bocols = 1;
192 >                                break;
193 >                        case 'f':
194 >                                bocols = -1;
195 >                                break;
196 >                        }
197                          break;
198                  case 'w':
199                          nowarn = !nowarn;
# Line 134 | Line 201 | char  *argv[];
201                  case 'u':
202                          unbuff = !unbuff;
203                          break;
204 <                default:
204 >                default:;
205 >                userr:
206                          eputs("Usage: ");
207                          eputs(argv[0]);
208 < eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
208 > eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
209                          quit(1);
210                  }
211  
212          if (noinput) {          /* produce a single output record */
213 +                if (i < argc) {
214 +                        eputs(argv[0]);
215 +                        eputs(": file argument(s) incompatible with -n\n");
216 +                        quit(1);
217 +                }
218                  eclock++;
219                  putout();
220                  quit(0);
# Line 157 | Line 230 | eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e exp
230                          execute(argv[i]);
231          
232          quit(0);
233 +        return 0; /* pro forma return */
234   }
235  
236  
237 < nbsynch()               /* non-blank starting synch character */
237 > static void
238 > nbsynch(void)               /* non-blank starting synch character */
239   {
240          if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT)
241                  return;
# Line 171 | Line 246 | nbsynch()               /* non-blank starting synch ch
246   }
247  
248  
249 < execute(file)           /* process a file */
250 < char  *file;
249 > static int
250 > getinputrec(            /* get next input record */
251 > FILE  *fp
252 > )
253   {
254 +        if (inpfmt != NULL)
255 +                return(getrec());
256 +        if (nbicols > 0)
257 +                return(fread(inpbuf, sizeof(double),
258 +                                        nbicols, fp) == nbicols);
259 +        if (nbicols < 0)
260 +                return(fread(inpbuf, sizeof(float),
261 +                                        -nbicols, fp) == -nbicols);
262 +        return(fgets(inpbuf, INBSIZ, fp) != NULL);
263 + }
264 +
265 +
266 + static void
267 + execute(           /* process a file */
268 + char  *file
269 + )
270 + {
271          int  conditional = vardefined("cond");
272          long  nrecs = 0;
273          long  nout = 0;
# Line 188 | Line 282 | char  *file;
282          }
283          if (inpfmt != NULL)
284                  initinp(fp);
285 <                
286 <        while (inpfmt != NULL ? getrec() : fgets(inpbuf, INBSIZ, fp) != NULL) {
285 >        
286 >        while (getinputrec(fp)) {
287                  varset("recno", '=', (double)++nrecs);
288                  colflg = 0;
289                  eclock++;
# Line 202 | Line 296 | char  *file;
296   }
297  
298  
299 < putout()                /* produce an output record */
299 > static void
300 > putout(void)                /* produce an output record */
301   {
207        extern int  chanset();
302  
303          colpos = 0;
304          if (outfmt != NULL)
305                  putrec();
306 +        else if (bocols)
307 +                chanout(bchanset);
308          else
309                  chanout(chanset);
310 <        if (colpos)
310 >        if (colpos && !bocols)
311                  putchar('\n');
312          if (unbuff)
313                  fflush(stdout);
314   }
315  
316  
317 + static double
318 + l_in(char *funame)      /* function call for $channel */
319 + {
320 +        int  n;
321 +        register char  *cp;
322 +                        /* get argument as integer */
323 +        n = (int)(argument(1) + .5);
324 +        if (n != 0)     /* return channel value */
325 +                return(chanvalue(n));
326 +                        /* determine number of channels */
327 +        if (noinput || inpfmt != NULL)
328 +                return(0);
329 +        if (nbicols > 0)
330 +                return(nbicols);
331 +        if (nbicols < 0)
332 +                return(-nbicols);
333 +        cp = inpbuf;    /* need to count */
334 +        for (n = 0; *cp; )
335 +                if (blnkeq && isspace(sepchar)) {
336 +                        while (isspace(*cp))
337 +                                cp++;
338 +                        n += *cp != '\0';
339 +                        while (*cp && !isspace(*cp))
340 +                                cp++;
341 +                } else {
342 +                        n += *cp != '\n';
343 +                        while (*cp && *cp++ != sepchar)
344 +                                ;
345 +                }
346 +        return(n);
347 + }
348 +
349   double
350 < chanvalue(n)            /* return value for column n */
351 < int  n;
350 > chanvalue(            /* return value for column n */
351 > int  n
352 > )
353   {
354          int  i;
355          register char  *cp;
# Line 233 | Line 362 | int  n;
362                  eputs("illegal channel number\n");
363                  quit(1);
364          }
365 +        if (nbicols > 0) {
366 +                if (n > nbicols)
367 +                        return(0.0);
368 +                cp = inpbuf + (n-1)*sizeof(double);
369 +                return(*(double *)cp);
370 +        }
371 +        if (nbicols < 0) {
372 +                if (n > -nbicols)
373 +                        return(0.0);
374 +                cp = inpbuf + (n-1)*sizeof(float);
375 +                return(*(float *)cp);
376 +        }
377          if (n <= MAXCOL && colflg & 1L<<(n-1))
378                  return(colval[n-1]);
379  
# Line 258 | Line 399 | int  n;
399   }
400  
401  
402 < chanset(n, v)                   /* output column n */
403 < int  n;
404 < double  v;
402 > void
403 > chanset(                   /* output column n */
404 > int  n,
405 > double  v
406 > )
407   {
408          if (colpos == 0)                /* no leading separator */
409                  colpos = 1;
# Line 272 | Line 415 | double  v;
415   }
416  
417  
418 < readfmt(spec, output)                   /* read record format */
419 < char  *spec;
420 < int  output;
418 > void
419 > bchanset(                   /* output binary channel n */
420 > int  n,
421 > double  v
422 > )
423   {
424 +        static char     zerobuf[sizeof(double)];
425 +
426 +        while (++colpos < n)
427 +                fwrite(zerobuf,
428 +                        bocols>0 ? sizeof(double) : sizeof(float),
429 +                        1, stdout);
430 +        if (bocols > 0)
431 +                fwrite(&v, sizeof(double), 1, stdout);
432 +        else {
433 +                float   fval = v;
434 +                fwrite(&fval, sizeof(float), 1, stdout);
435 +        }
436 + }
437 +
438 +
439 + static void
440 + readfmt(                   /* read record format */
441 + char  *spec,
442 + int  output
443 + )
444 + {
445          int  fd;
446          char  *inptr;
447          struct field  fmt;
# Line 293 | Line 459 | int  output;
459                          eputs(": cannot open\n");
460                          quit(1);
461                  }
462 <                res = read(fd, inpbuf+1, INBSIZ-1);
462 >                res = read(fd, inpbuf+2, INBSIZ-2);
463                  if (res <= 0 || res >= INBSIZ-1) {
464                          eputs(spec);
465                          if (res < 0)
# Line 305 | Line 471 | int  output;
471                          quit(1);
472                  }
473                  close(fd);
474 <                (inptr=inpbuf+1)[res] = '\0';
474 >                (inptr=inpbuf+2)[res] = '\0';
475          }
476          f = &fmt;                               /* get fields */
477          while ((res = readfield(&inptr)) != F_NUL) {
# Line 338 | Line 504 | int  output;
504   }
505  
506  
507 < int
508 < readfield(pp)                   /* get next field in format */
509 < register char  **pp;
507 > static int
508 > readfield(                   /* get next field in format */
509 > register char  **pp
510 > )
511   {
512          int  type = F_NUL;
513          int  width = 0;
# Line 405 | Line 572 | register char  **pp;
572  
573  
574   struct strvar *
575 < getsvar(svname)                         /* get string variable */
576 < char  *svname;
575 > getsvar(                         /* get string variable */
576 > char  *svname
577 > )
578   {
579          register struct strvar  *sv;
580          
# Line 422 | Line 590 | char  *svname;
590   }
591  
592  
593 < svpreset(eqn)                    /* preset a string variable */
594 < char  *eqn;
593 > static void
594 > svpreset(                    /* preset a string variable */
595 > char  *eqn
596 > )
597   {
598          register struct strvar  *sv;
599          register char  *val;
# Line 442 | Line 612 | char  *eqn;
612   }
613  
614  
615 < clearrec()                      /* clear input record variables */
615 > static void
616 > clearrec(void)                  /* clear input record variables */
617   {
618          register struct field  *f;
619  
# Line 461 | Line 632 | clearrec()                     /* clear input record variables */
632   }
633  
634  
635 < getrec()                                /* get next record from file */
635 > static int
636 > getrec(void)                            /* get next record from file */
637   {
638          int  eatline;
639          register struct field  *f;
640 <        
640 >
641          while (ipb.chr != EOF) {
470                eatline = !igneol && ipb.chr != '\n';
642                  if (blnkeq)             /* beware of nbsynch() */
643                          while (isblnk(ipb.chr))
644 <                                scaninp();
644 >                                resetinp();
645 >                eatline = (!igneol && ipb.chr != '\n');
646                  clearrec();             /* start with fresh record */
647                  for (f = inpfmt; f != NULL; f = f->next)
648                          if (getfield(f) == -1)
649                                  break;
650                  if (f == NULL) {
651 <                        advinp();
651 >                        advinp();       /* got one! */
652                          return(1);
653                  }
654 <                resetinp();
654 >                resetinp();             /* eat false start */
655                  if (eatline) {          /* eat rest of line */
656                          while (ipb.chr != '\n') {
657                                  if (ipb.chr == EOF)
658                                          return(0);
659 <                                scaninp();
659 >                                resetinp();
660                          }
661 <                        scaninp();
490 <                        advinp();
661 >                        resetinp();
662                  }
663          }
664          return(0);
665   }
666  
667  
668 < getfield(f)                             /* get next field */
669 < register struct field  *f;
668 > static int
669 > getfield(                             /* get next field */
670 > register struct field  *f
671 > )
672   {
673 <        static char  buf[MAXWORD+1];            /* no recursion! */
673 >        static char  buf[RMAXWORD+1];            /* no recursion! */
674          int  delim, inword;
675          double  d;
676          char  *np;
# Line 530 | Line 703 | register struct field  *f;
703                          delim = f->next->f.sl[0];
704                  cp = buf;
705                  do {
706 <                        if (ipb.chr == EOF)
706 >                        if (ipb.chr == EOF || ipb.chr == '\n')
707                                  inword = 0;
708                          else if (blnkeq && delim != EOF)
709                                  inword = isblnk(delim) ?
# Line 542 | Line 715 | register struct field  *f;
715                                  *cp++ = ipb.chr;
716                                  scaninp();
717                          }
718 <                } while (inword && cp < &buf[MAXWORD]);
718 >                } while (inword && cp < &buf[RMAXWORD]);
719                  *cp = '\0';
720                  if (f->f.sv->val == NULL)
721                          f->f.sv->val = savqstr(buf);    /* first setting */
# Line 571 | Line 744 | register struct field  *f;
744                                  *cp++ = ipb.chr;
745                                  scaninp();
746                          }
747 <                } while (inword && cp < &buf[MAXWORD]);
747 >                } while (inword && cp < &buf[RMAXWORD]);
748                  *cp = '\0';
749                  d = np==NULL ? 0. : atof(np);
750                  if (!vardefined(f->f.nv))
# Line 581 | Line 754 | register struct field  *f;
754                          return(-1);                     /* doesn't match! */
755                  return(0);
756          }
757 +        return -1; /* pro forma return */
758   }
759  
760  
761 < putrec()                                /* output a record */
761 > static void
762 > putrec(void)                                /* output a record */
763   {
764          char  fmt[32];
765          register int  n;
# Line 634 | Line 809 | putrec()                                /* output a re
809   }
810  
811  
812 < initinp(fp)                     /* prepare lookahead buffer */
813 < FILE  *fp;
812 > static void
813 > initinp(FILE  *fp)                     /* prepare lookahead buffer */
814 >
815   {
816          ipb.fin = fp;
817          ipb.beg = ipb.end = inpbuf;
# Line 645 | Line 821 | FILE  *fp;
821   }
822  
823  
824 < scaninp()                       /* scan next character */
824 > static void
825 > scaninp(void)                       /* scan next character */
826   {
827          if (ipb.chr == EOF)
828                  return;
# Line 664 | Line 841 | scaninp()                       /* scan next character
841   }
842  
843  
844 < advinp()                        /* move home to current position */
844 > static void
845 > advinp(void)                        /* move home to current position */
846   {
847          ipb.beg = ipb.pos;
848   }
849  
850  
851 < resetinp()                      /* rewind position and advance 1 */
851 > static void
852 > resetinp(void)                      /* rewind position and advance 1 */
853   {
854          if (ipb.beg == NULL)            /* full */
855                  ipb.beg = ipb.end;
856          ipb.pos = ipb.beg;
857          ipb.chr = *ipb.pos;
858 +        if (passive)                    /* transmit unmatched character? */
859 +                fputc(ipb.chr, stdout);
860          if (++ipb.beg >= &inpbuf[INBSIZ])
861                  ipb.beg = inpbuf;
862          scaninp();
# Line 683 | Line 864 | resetinp()                      /* rewind position and
864  
865  
866   void
867 < eputs(msg)
687 < char  *msg;
867 > eputs(char  *msg)
868   {
869          fputs(msg, stderr);
870   }
871  
872  
873   void
874 < wputs(msg)
695 < char  *msg;
874 > wputs(char  *msg)
875   {
876          if (!nowarn)
877                  eputs(msg);
# Line 700 | Line 879 | char  *msg;
879  
880  
881   void
882 < quit(code)
704 < int  code;
882 > quit(int  code)
883   {
884          exit(code);
885   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines