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.18 by greg, Thu Jun 2 04:47:27 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 >                                SET_FILE_BINARY(stdout);
193 >                                break;
194 >                        case 'f':
195 >                                bocols = -1;
196 >                                SET_FILE_BINARY(stdout);
197 >                                break;
198 >                        default:
199 >                                goto userr;
200 >                        }
201                          break;
202                  case 'w':
203                          nowarn = !nowarn;
# Line 134 | Line 205 | char  *argv[];
205                  case 'u':
206                          unbuff = !unbuff;
207                          break;
208 <                default:
208 >                default:;
209 >                userr:
210                          eputs("Usage: ");
211                          eputs(argv[0]);
212 < eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
212 > eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
213                          quit(1);
214                  }
215 <
215 >        if (bocols)
216 >                SET_FILE_BINARY(stdout);
217          if (noinput) {          /* produce a single output record */
218 +                if (i < argc) {
219 +                        eputs(argv[0]);
220 +                        eputs(": file argument(s) incompatible with -n\n");
221 +                        quit(1);
222 +                }
223                  eclock++;
224                  putout();
225                  quit(0);
226          }
227 +        if (nbicols)
228 +                SET_FILE_BINARY(stdin);
229  
230          if (blnkeq)             /* for efficiency */
231                  nbsynch();
# Line 157 | Line 237 | eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e exp
237                          execute(argv[i]);
238          
239          quit(0);
240 +        return 0; /* pro forma return */
241   }
242  
243  
244 < nbsynch()               /* non-blank starting synch character */
244 > static void
245 > nbsynch(void)               /* non-blank starting synch character */
246   {
247          if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT)
248                  return;
# Line 171 | Line 253 | nbsynch()               /* non-blank starting synch ch
253   }
254  
255  
256 < execute(file)           /* process a file */
257 < char  *file;
256 > static int
257 > getinputrec(            /* get next input record */
258 > FILE  *fp
259 > )
260   {
261 +        if (inpfmt != NULL)
262 +                return(getrec());
263 +        if (nbicols > 0)
264 +                return(fread(inpbuf, sizeof(double),
265 +                                        nbicols, fp) == nbicols);
266 +        if (nbicols < 0)
267 +                return(fread(inpbuf, sizeof(float),
268 +                                        -nbicols, fp) == -nbicols);
269 +        return(fgets(inpbuf, INBSIZ, fp) != NULL);
270 + }
271 +
272 +
273 + static void
274 + execute(           /* process a file */
275 + char  *file
276 + )
277 + {
278          int  conditional = vardefined("cond");
279          long  nrecs = 0;
280          long  nout = 0;
# Line 188 | Line 289 | char  *file;
289          }
290          if (inpfmt != NULL)
291                  initinp(fp);
292 <                
293 <        while (inpfmt != NULL ? getrec() : fgets(inpbuf, INBSIZ, fp) != NULL) {
292 >        
293 >        while (getinputrec(fp)) {
294                  varset("recno", '=', (double)++nrecs);
295                  colflg = 0;
296                  eclock++;
# Line 202 | Line 303 | char  *file;
303   }
304  
305  
306 < putout()                /* produce an output record */
306 > static void
307 > putout(void)                /* produce an output record */
308   {
207        extern int  chanset();
309  
310          colpos = 0;
311          if (outfmt != NULL)
312                  putrec();
313 +        else if (bocols)
314 +                chanout(bchanset);
315          else
316                  chanout(chanset);
317 <        if (colpos)
317 >        if (colpos && !bocols)
318                  putchar('\n');
319          if (unbuff)
320                  fflush(stdout);
321   }
322  
323  
324 + static double
325 + l_in(char *funame)      /* function call for $channel */
326 + {
327 +        int  n;
328 +        register char  *cp;
329 +                        /* get argument as integer */
330 +        n = (int)(argument(1) + .5);
331 +        if (n != 0)     /* return channel value */
332 +                return(chanvalue(n));
333 +                        /* determine number of channels */
334 +        if (noinput || inpfmt != NULL)
335 +                return(0);
336 +        if (nbicols > 0)
337 +                return(nbicols);
338 +        if (nbicols < 0)
339 +                return(-nbicols);
340 +        cp = inpbuf;    /* need to count */
341 +        for (n = 0; *cp; )
342 +                if (blnkeq && isspace(sepchar)) {
343 +                        while (isspace(*cp))
344 +                                cp++;
345 +                        n += *cp != '\0';
346 +                        while (*cp && !isspace(*cp))
347 +                                cp++;
348 +                } else {
349 +                        n += *cp != '\n';
350 +                        while (*cp && *cp++ != sepchar)
351 +                                ;
352 +                }
353 +        return(n);
354 + }
355 +
356   double
357 < chanvalue(n)            /* return value for column n */
358 < int  n;
357 > chanvalue(            /* return value for column n */
358 > int  n
359 > )
360   {
361          int  i;
362          register char  *cp;
# Line 233 | Line 369 | int  n;
369                  eputs("illegal channel number\n");
370                  quit(1);
371          }
372 +        if (nbicols > 0) {
373 +                if (n > nbicols)
374 +                        return(0.0);
375 +                cp = inpbuf + (n-1)*sizeof(double);
376 +                return(*(double *)cp);
377 +        }
378 +        if (nbicols < 0) {
379 +                if (n > -nbicols)
380 +                        return(0.0);
381 +                cp = inpbuf + (n-1)*sizeof(float);
382 +                return(*(float *)cp);
383 +        }
384          if (n <= MAXCOL && colflg & 1L<<(n-1))
385                  return(colval[n-1]);
386  
# Line 258 | Line 406 | int  n;
406   }
407  
408  
409 < chanset(n, v)                   /* output column n */
410 < int  n;
411 < double  v;
409 > void
410 > chanset(                   /* output column n */
411 > int  n,
412 > double  v
413 > )
414   {
415          if (colpos == 0)                /* no leading separator */
416                  colpos = 1;
# Line 272 | Line 422 | double  v;
422   }
423  
424  
425 < readfmt(spec, output)                   /* read record format */
426 < char  *spec;
427 < int  output;
425 > void
426 > bchanset(                   /* output binary channel n */
427 > int  n,
428 > double  v
429 > )
430   {
431 +        static char     zerobuf[sizeof(double)];
432 +
433 +        while (++colpos < n)
434 +                fwrite(zerobuf,
435 +                        bocols>0 ? sizeof(double) : sizeof(float),
436 +                        1, stdout);
437 +        if (bocols > 0)
438 +                fwrite(&v, sizeof(double), 1, stdout);
439 +        else {
440 +                float   fval = v;
441 +                fwrite(&fval, sizeof(float), 1, stdout);
442 +        }
443 + }
444 +
445 +
446 + static void
447 + readfmt(                   /* read record format */
448 + char  *spec,
449 + int  output
450 + )
451 + {
452          int  fd;
453          char  *inptr;
454          struct field  fmt;
# Line 293 | Line 466 | int  output;
466                          eputs(": cannot open\n");
467                          quit(1);
468                  }
469 <                res = read(fd, inpbuf+1, INBSIZ-1);
469 >                res = read(fd, inpbuf+2, INBSIZ-2);
470                  if (res <= 0 || res >= INBSIZ-1) {
471                          eputs(spec);
472                          if (res < 0)
# Line 305 | Line 478 | int  output;
478                          quit(1);
479                  }
480                  close(fd);
481 <                (inptr=inpbuf+1)[res] = '\0';
481 >                (inptr=inpbuf+2)[res] = '\0';
482          }
483          f = &fmt;                               /* get fields */
484          while ((res = readfield(&inptr)) != F_NUL) {
# Line 338 | Line 511 | int  output;
511   }
512  
513  
514 < int
515 < readfield(pp)                   /* get next field in format */
516 < register char  **pp;
514 > static int
515 > readfield(                   /* get next field in format */
516 > register char  **pp
517 > )
518   {
519          int  type = F_NUL;
520          int  width = 0;
# Line 405 | Line 579 | register char  **pp;
579  
580  
581   struct strvar *
582 < getsvar(svname)                         /* get string variable */
583 < char  *svname;
582 > getsvar(                         /* get string variable */
583 > char  *svname
584 > )
585   {
586          register struct strvar  *sv;
587          
# Line 422 | Line 597 | char  *svname;
597   }
598  
599  
600 < svpreset(eqn)                    /* preset a string variable */
601 < char  *eqn;
600 > static void
601 > svpreset(                    /* preset a string variable */
602 > char  *eqn
603 > )
604   {
605          register struct strvar  *sv;
606          register char  *val;
# Line 442 | Line 619 | char  *eqn;
619   }
620  
621  
622 < clearrec()                      /* clear input record variables */
622 > static void
623 > clearrec(void)                  /* clear input record variables */
624   {
625          register struct field  *f;
626  
# Line 461 | Line 639 | clearrec()                     /* clear input record variables */
639   }
640  
641  
642 < getrec()                                /* get next record from file */
642 > static int
643 > getrec(void)                            /* get next record from file */
644   {
645          int  eatline;
646          register struct field  *f;
647 <        
647 >
648          while (ipb.chr != EOF) {
470                eatline = !igneol && ipb.chr != '\n';
649                  if (blnkeq)             /* beware of nbsynch() */
650                          while (isblnk(ipb.chr))
651 <                                scaninp();
651 >                                resetinp();
652 >                eatline = (!igneol && ipb.chr != '\n');
653                  clearrec();             /* start with fresh record */
654                  for (f = inpfmt; f != NULL; f = f->next)
655                          if (getfield(f) == -1)
656                                  break;
657                  if (f == NULL) {
658 <                        advinp();
658 >                        advinp();       /* got one! */
659                          return(1);
660                  }
661 <                resetinp();
661 >                resetinp();             /* eat false start */
662                  if (eatline) {          /* eat rest of line */
663                          while (ipb.chr != '\n') {
664                                  if (ipb.chr == EOF)
665                                          return(0);
666 <                                scaninp();
666 >                                resetinp();
667                          }
668 <                        scaninp();
490 <                        advinp();
668 >                        resetinp();
669                  }
670          }
671          return(0);
672   }
673  
674  
675 < getfield(f)                             /* get next field */
676 < register struct field  *f;
675 > static int
676 > getfield(                             /* get next field */
677 > register struct field  *f
678 > )
679   {
680 <        static char  buf[MAXWORD+1];            /* no recursion! */
680 >        static char  buf[RMAXWORD+1];            /* no recursion! */
681          int  delim, inword;
682          double  d;
683          char  *np;
# Line 530 | Line 710 | register struct field  *f;
710                          delim = f->next->f.sl[0];
711                  cp = buf;
712                  do {
713 <                        if (ipb.chr == EOF)
713 >                        if (ipb.chr == EOF || ipb.chr == '\n')
714                                  inword = 0;
715                          else if (blnkeq && delim != EOF)
716                                  inword = isblnk(delim) ?
# Line 542 | Line 722 | register struct field  *f;
722                                  *cp++ = ipb.chr;
723                                  scaninp();
724                          }
725 <                } while (inword && cp < &buf[MAXWORD]);
725 >                } while (inword && cp < &buf[RMAXWORD]);
726                  *cp = '\0';
727                  if (f->f.sv->val == NULL)
728                          f->f.sv->val = savqstr(buf);    /* first setting */
# Line 571 | Line 751 | register struct field  *f;
751                                  *cp++ = ipb.chr;
752                                  scaninp();
753                          }
754 <                } while (inword && cp < &buf[MAXWORD]);
754 >                } while (inword && cp < &buf[RMAXWORD]);
755                  *cp = '\0';
756                  d = np==NULL ? 0. : atof(np);
757                  if (!vardefined(f->f.nv))
# Line 581 | Line 761 | register struct field  *f;
761                          return(-1);                     /* doesn't match! */
762                  return(0);
763          }
764 +        return -1; /* pro forma return */
765   }
766  
767  
768 < putrec()                                /* output a record */
768 > static void
769 > putrec(void)                                /* output a record */
770   {
771          char  fmt[32];
772          register int  n;
# Line 634 | Line 816 | putrec()                                /* output a re
816   }
817  
818  
819 < initinp(fp)                     /* prepare lookahead buffer */
820 < FILE  *fp;
819 > static void
820 > initinp(FILE  *fp)                     /* prepare lookahead buffer */
821 >
822   {
823          ipb.fin = fp;
824          ipb.beg = ipb.end = inpbuf;
# Line 645 | Line 828 | FILE  *fp;
828   }
829  
830  
831 < scaninp()                       /* scan next character */
831 > static void
832 > scaninp(void)                       /* scan next character */
833   {
834          if (ipb.chr == EOF)
835                  return;
# Line 664 | Line 848 | scaninp()                       /* scan next character
848   }
849  
850  
851 < advinp()                        /* move home to current position */
851 > static void
852 > advinp(void)                        /* move home to current position */
853   {
854          ipb.beg = ipb.pos;
855   }
856  
857  
858 < resetinp()                      /* rewind position and advance 1 */
858 > static void
859 > resetinp(void)                      /* rewind position and advance 1 */
860   {
861          if (ipb.beg == NULL)            /* full */
862                  ipb.beg = ipb.end;
863          ipb.pos = ipb.beg;
864          ipb.chr = *ipb.pos;
865 +        if (passive)                    /* transmit unmatched character? */
866 +                fputc(ipb.chr, stdout);
867          if (++ipb.beg >= &inpbuf[INBSIZ])
868                  ipb.beg = inpbuf;
869          scaninp();
# Line 683 | Line 871 | resetinp()                      /* rewind position and
871  
872  
873   void
874 < eputs(msg)
687 < char  *msg;
874 > eputs(char  *msg)
875   {
876          fputs(msg, stderr);
877   }
878  
879  
880   void
881 < wputs(msg)
695 < char  *msg;
881 > wputs(char  *msg)
882   {
883          if (!nowarn)
884                  eputs(msg);
# Line 700 | Line 886 | char  *msg;
886  
887  
888   void
889 < quit(code)
704 < int  code;
889 > quit(int  code)
890   {
891          exit(code);
892   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines