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.21 by greg, Sun Jun 14 00:33:16 2009 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  itype = 'a';               /* input type (a/f/F/d/D) */
85 + int  nbicols = 0;               /* number of binary input columns */
86 + int  otype = 'a';               /* output format (a/f/F/d/D) */
87   char  inpbuf[INBSIZ];           /* input buffer */
88   double  colval[MAXCOL];         /* input column values */
89   unsigned long  colflg = 0;      /* column retrieved flags */
# Line 86 | Line 101 | struct {
101   } ipb;                          /* circular lookahead buffer */
102  
103  
104 < main(argc, argv)
105 < int  argc;
106 < char  *argv[];
104 > int
105 > main(
106 > int  argc,
107 > char  *argv[]
108 > )
109   {
110          int  i;
111  
112 <        esupport |= (E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST);
112 >        esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST;
113 >        esupport &= ~(E_REDEFW);
114  
115   #ifdef  BIGGERLIB
116          biggerlib();
117   #endif
118          varset("PI", ':', 3.14159265358979323846);
119 +        funset("in", 1, '=', &l_in);
120  
121          for (i = 1; i < argc && argv[i][0] == '-'; i++)
122                  switch (argv[i][1]) {
# Line 107 | Line 126 | char  *argv[];
126                  case 'l':
127                          igneol = !igneol;
128                          break;
129 +                case 'p':
130 +                        passive = !passive;
131 +                        break;
132                  case 't':
133                          sepchar = argv[i][2];
134                          break;
# Line 123 | Line 145 | char  *argv[];
145                          noinput = 1;
146                          break;
147                  case 'i':
148 <                        readfmt(argv[++i], 0);
148 >                        switch (argv[i][2]) {
149 >                        case '\0':
150 >                                itype = 'a';
151 >                                nbicols = 0;
152 >                                readfmt(argv[++i], 0);
153 >                                break;
154 >                        case 'a':
155 >                                itype = 'a';
156 >                                nbicols = 0;
157 >                                break;
158 >                        case 'd':
159 >                        case 'D':
160 >                                itype = argv[i][2];
161 >                                if (isdigit(argv[i][3]))
162 >                                        nbicols = atoi(argv[i]+3);
163 >                                else
164 >                                        nbicols = 1;
165 >                                if (nbicols*sizeof(double) > INBSIZ) {
166 >                                        eputs(argv[0]);
167 >                                        eputs(": too many input columns\n");
168 >                                        quit(1);
169 >                                }
170 >                                break;
171 >                        case 'f':
172 >                        case 'F':
173 >                                itype = argv[i][2];
174 >                                if (isdigit(argv[i][3]))
175 >                                        nbicols = atoi(argv[i]+3);
176 >                                else
177 >                                        nbicols = 1;
178 >                                if (nbicols*sizeof(float) > INBSIZ) {
179 >                                        eputs(argv[0]);
180 >                                        eputs(": too many input columns\n");
181 >                                        quit(1);
182 >                                }
183 >                                break;
184 >                        default:
185 >                                goto userr;
186 >                        }
187                          break;
188                  case 'o':
189 <                        readfmt(argv[++i], 1);
189 >                        switch (argv[i][2]) {
190 >                        case '\0':
191 >                                otype = 'a';
192 >                                readfmt(argv[++i], 1);
193 >                                break;
194 >                        case 'a':
195 >                                otype = 'a';
196 >                                break;
197 >                        case 'd':
198 >                        case 'D':
199 >                        case 'f':
200 >                        case 'F':
201 >                                otype = argv[i][2];
202 >                                break;
203 >                        default:
204 >                                goto userr;
205 >                        }
206                          break;
207                  case 'w':
208                          nowarn = !nowarn;
# Line 134 | Line 210 | char  *argv[];
210                  case 'u':
211                          unbuff = !unbuff;
212                          break;
213 <                default:
213 >                default:;
214 >                userr:
215                          eputs("Usage: ");
216                          eputs(argv[0]);
217 < eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
217 > eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n");
218                          quit(1);
219                  }
220 <
220 >        if (otype != 'a')
221 >                SET_FILE_BINARY(stdout);
222          if (noinput) {          /* produce a single output record */
223 +                if (i < argc) {
224 +                        eputs(argv[0]);
225 +                        eputs(": file argument(s) incompatible with -n\n");
226 +                        quit(1);
227 +                }
228                  eclock++;
229                  putout();
230                  quit(0);
231          }
232 +        if (itype != 'a')
233 +                SET_FILE_BINARY(stdin);
234  
235          if (blnkeq)             /* for efficiency */
236                  nbsynch();
# Line 157 | Line 242 | eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e exp
242                          execute(argv[i]);
243          
244          quit(0);
245 +        return 0; /* pro forma return */
246   }
247  
248  
249 < nbsynch()               /* non-blank starting synch character */
249 > static void
250 > nbsynch(void)               /* non-blank starting synch character */
251   {
252          if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT)
253                  return;
# Line 171 | Line 258 | nbsynch()               /* non-blank starting synch ch
258   }
259  
260  
261 < execute(file)           /* process a file */
262 < char  *file;
261 > static int
262 > getinputrec(            /* get next input record */
263 > FILE  *fp
264 > )
265   {
266 +        if (inpfmt != NULL)
267 +                return(getrec());
268 +        if (tolower(itype) == 'd') {
269 +                if (fread(inpbuf, sizeof(double), nbicols, fp) != nbicols)
270 +                        return(0);
271 +                if (itype == 'D')
272 +                        swap64(inpbuf, nbicols);
273 +                return(1);
274 +        }
275 +        if (tolower(itype) == 'f') {
276 +                if (fread(inpbuf, sizeof(float), nbicols, fp) != nbicols)
277 +                        return(0);
278 +                if (itype == 'F')
279 +                        swap32(inpbuf, nbicols);
280 +                return(1);
281 +        }
282 +        return(fgets(inpbuf, INBSIZ, fp) != NULL);
283 + }
284 +
285 +
286 + static void
287 + execute(           /* process a file */
288 + char  *file
289 + )
290 + {
291          int  conditional = vardefined("cond");
292          long  nrecs = 0;
293          long  nout = 0;
# Line 188 | Line 302 | char  *file;
302          }
303          if (inpfmt != NULL)
304                  initinp(fp);
305 <                
306 <        while (inpfmt != NULL ? getrec() : fgets(inpbuf, INBSIZ, fp) != NULL) {
305 >        
306 >        while (getinputrec(fp)) {
307                  varset("recno", '=', (double)++nrecs);
308 +                varset("outno", '=', (double)(nout+1));
309                  colflg = 0;
310                  eclock++;
311                  if (!conditional || varvalue("cond") > 0.0) {
197                        varset("outno", '=', (double)++nout);
312                          putout();
313 +                        ++nout;
314                  }
315          }
316          fclose(fp);
317   }
318  
319  
320 < putout()                /* produce an output record */
320 > static void
321 > putout(void)                /* produce an output record */
322   {
207        extern int  chanset();
323  
324          colpos = 0;
325          if (outfmt != NULL)
326                  putrec();
327 <        else
327 >        else if (otype == 'a')
328                  chanout(chanset);
329 <        if (colpos)
329 >        else
330 >                chanout(bchanset);
331 >        if (colpos && otype == 'a')
332                  putchar('\n');
333          if (unbuff)
334                  fflush(stdout);
335   }
336  
337  
338 + static double
339 + l_in(char *funame)      /* function call for $channel */
340 + {
341 +        int  n;
342 +        register char  *cp;
343 +                        /* get argument as integer */
344 +        n = (int)(argument(1) + .5);
345 +        if (n != 0)     /* return channel value */
346 +                return(chanvalue(n));
347 +                        /* determine number of channels */
348 +        if (noinput || inpfmt != NULL)
349 +                return(0);
350 +        if (nbicols)
351 +                return(nbicols);
352 +        cp = inpbuf;    /* need to count */
353 +        for (n = 0; *cp; )
354 +                if (blnkeq && isspace(sepchar)) {
355 +                        while (isspace(*cp))
356 +                                cp++;
357 +                        n += *cp != '\0';
358 +                        while (*cp && !isspace(*cp))
359 +                                cp++;
360 +                } else {
361 +                        n += *cp != '\n';
362 +                        while (*cp && *cp++ != sepchar)
363 +                                ;
364 +                }
365 +        return(n);
366 + }
367 +
368   double
369 < chanvalue(n)            /* return value for column n */
370 < int  n;
369 > chanvalue(            /* return value for column n */
370 > int  n
371 > )
372   {
373          int  i;
374          register char  *cp;
# Line 233 | Line 381 | int  n;
381                  eputs("illegal channel number\n");
382                  quit(1);
383          }
384 +        if (nbicols) {
385 +                if (n > nbicols)
386 +                        return(0.0);
387 +                if (tolower(itype) == 'd') {
388 +                        cp = inpbuf + (n-1)*sizeof(double);
389 +                        return(*(double *)cp);
390 +                }
391 +                cp = inpbuf + (n-1)*sizeof(float);
392 +                return(*(float *)cp);
393 +        }
394          if (n <= MAXCOL && colflg & 1L<<(n-1))
395                  return(colval[n-1]);
396  
# Line 258 | Line 416 | int  n;
416   }
417  
418  
419 < chanset(n, v)                   /* output column n */
420 < int  n;
421 < double  v;
419 > void
420 > chanset(                   /* output column n */
421 > int  n,
422 > double  v
423 > )
424   {
425          if (colpos == 0)                /* no leading separator */
426                  colpos = 1;
# Line 272 | Line 432 | double  v;
432   }
433  
434  
435 < readfmt(spec, output)                   /* read record format */
436 < char  *spec;
437 < int  output;
435 > void
436 > bchanset(                   /* output binary channel n */
437 > int  n,
438 > double  v
439 > )
440   {
441 +        static char     zerobuf[sizeof(double)];
442 +        float   fval = v;
443 +
444 +        while (++colpos < n)
445 +                fwrite(zerobuf,
446 +                        tolower(otype)=='d' ? sizeof(double) : sizeof(float),
447 +                        1, stdout);
448 +        switch (otype) {
449 +        case 'D':
450 +                swap64((char *)&v, 1);
451 +                /* fall through */
452 +        case 'd':
453 +                fwrite(&v, sizeof(double), 1, stdout);
454 +                break;
455 +        case 'F':
456 +                swap32((char *)&fval, 1);
457 +                /* fall through */
458 +        case 'f':
459 +                fwrite(&fval, sizeof(float), 1, stdout);
460 +                break;
461 +        }
462 + }
463 +
464 +
465 + static void
466 + readfmt(                   /* read record format */
467 + char  *spec,
468 + int  output
469 + )
470 + {
471          int  fd;
472          char  *inptr;
473          struct field  fmt;
# Line 293 | Line 485 | int  output;
485                          eputs(": cannot open\n");
486                          quit(1);
487                  }
488 <                res = read(fd, inpbuf+1, INBSIZ-1);
488 >                res = read(fd, inpbuf+2, INBSIZ-2);
489                  if (res <= 0 || res >= INBSIZ-1) {
490                          eputs(spec);
491                          if (res < 0)
# Line 305 | Line 497 | int  output;
497                          quit(1);
498                  }
499                  close(fd);
500 <                (inptr=inpbuf+1)[res] = '\0';
500 >                (inptr=inpbuf+2)[res] = '\0';
501          }
502          f = &fmt;                               /* get fields */
503          while ((res = readfield(&inptr)) != F_NUL) {
# Line 338 | Line 530 | int  output;
530   }
531  
532  
533 < int
534 < readfield(pp)                   /* get next field in format */
535 < register char  **pp;
533 > static int
534 > readfield(                   /* get next field in format */
535 > register char  **pp
536 > )
537   {
538          int  type = F_NUL;
539          int  width = 0;
# Line 405 | Line 598 | register char  **pp;
598  
599  
600   struct strvar *
601 < getsvar(svname)                         /* get string variable */
602 < char  *svname;
601 > getsvar(                         /* get string variable */
602 > char  *svname
603 > )
604   {
605          register struct strvar  *sv;
606          
# Line 422 | Line 616 | char  *svname;
616   }
617  
618  
619 < svpreset(eqn)                    /* preset a string variable */
620 < char  *eqn;
619 > static void
620 > svpreset(                    /* preset a string variable */
621 > char  *eqn
622 > )
623   {
624          register struct strvar  *sv;
625          register char  *val;
# Line 442 | Line 638 | char  *eqn;
638   }
639  
640  
641 < clearrec()                      /* clear input record variables */
641 > static void
642 > clearrec(void)                  /* clear input record variables */
643   {
644          register struct field  *f;
645  
# Line 461 | Line 658 | clearrec()                     /* clear input record variables */
658   }
659  
660  
661 < getrec()                                /* get next record from file */
661 > static int
662 > getrec(void)                            /* get next record from file */
663   {
664          int  eatline;
665          register struct field  *f;
666 <        
666 >
667          while (ipb.chr != EOF) {
668 <                eatline = !igneol && ipb.chr != '\n';
471 <                if (blnkeq)             /* beware of nbsynch() */
668 >                if (blnkeq) {           /* beware of nbsynch() */
669                          while (isblnk(ipb.chr))
670 <                                scaninp();
670 >                                resetinp();
671 >                        if (ipb.chr == EOF)
672 >                                return(0);
673 >                }
674 >                eatline = (!igneol && ipb.chr != '\n');
675                  clearrec();             /* start with fresh record */
676                  for (f = inpfmt; f != NULL; f = f->next)
677                          if (getfield(f) == -1)
678                                  break;
679                  if (f == NULL) {
680 <                        advinp();
680 >                        advinp();       /* got one! */
681                          return(1);
682                  }
683 <                resetinp();
683 >                resetinp();             /* eat false start */
684                  if (eatline) {          /* eat rest of line */
685                          while (ipb.chr != '\n') {
686                                  if (ipb.chr == EOF)
687                                          return(0);
688 <                                scaninp();
688 >                                resetinp();
689                          }
690 <                        scaninp();
490 <                        advinp();
690 >                        resetinp();
691                  }
692          }
693          return(0);
694   }
695  
696  
697 < getfield(f)                             /* get next field */
698 < register struct field  *f;
697 > static int
698 > getfield(                             /* get next field */
699 > register struct field  *f
700 > )
701   {
702 <        static char  buf[MAXWORD+1];            /* no recursion! */
702 >        static char  buf[RMAXWORD+1];            /* no recursion! */
703          int  delim, inword;
704          double  d;
705          char  *np;
# Line 530 | Line 732 | register struct field  *f;
732                          delim = f->next->f.sl[0];
733                  cp = buf;
734                  do {
735 <                        if (ipb.chr == EOF)
735 >                        if (ipb.chr == EOF || ipb.chr == '\n')
736                                  inword = 0;
737                          else if (blnkeq && delim != EOF)
738                                  inword = isblnk(delim) ?
# Line 542 | 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                  if (f->f.sv->val == NULL)
750                          f->f.sv->val = savqstr(buf);    /* first setting */
# Line 571 | Line 773 | register struct field  *f;
773                                  *cp++ = ipb.chr;
774                                  scaninp();
775                          }
776 <                } while (inword && cp < &buf[MAXWORD]);
776 >                } while (inword && cp < &buf[RMAXWORD]);
777                  *cp = '\0';
778                  d = np==NULL ? 0. : atof(np);
779                  if (!vardefined(f->f.nv))
# Line 581 | Line 783 | register struct field  *f;
783                          return(-1);                     /* doesn't match! */
784                  return(0);
785          }
786 +        return -1; /* pro forma return */
787   }
788  
789  
790 < putrec()                                /* output a record */
790 > static void
791 > putrec(void)                                /* output a record */
792   {
793          char  fmt[32];
794          register int  n;
# Line 634 | Line 838 | putrec()                                /* output a re
838   }
839  
840  
841 < initinp(fp)                     /* prepare lookahead buffer */
842 < FILE  *fp;
841 > static void
842 > initinp(FILE  *fp)                     /* prepare lookahead buffer */
843 >
844   {
845          ipb.fin = fp;
846          ipb.beg = ipb.end = inpbuf;
# Line 645 | Line 850 | FILE  *fp;
850   }
851  
852  
853 < scaninp()                       /* scan next character */
853 > static void
854 > scaninp(void)                       /* scan next character */
855   {
856          if (ipb.chr == EOF)
857                  return;
# Line 664 | Line 870 | scaninp()                       /* scan next character
870   }
871  
872  
873 < advinp()                        /* move home to current position */
873 > static void
874 > advinp(void)                        /* move home to current position */
875   {
876          ipb.beg = ipb.pos;
877   }
878  
879  
880 < resetinp()                      /* rewind position and advance 1 */
880 > static void
881 > resetinp(void)                      /* rewind position and advance 1 */
882   {
883          if (ipb.beg == NULL)            /* full */
884                  ipb.beg = ipb.end;
885          ipb.pos = ipb.beg;
886          ipb.chr = *ipb.pos;
887 +        if (passive)                    /* transmit unmatched character? */
888 +                fputc(ipb.chr, stdout);
889          if (++ipb.beg >= &inpbuf[INBSIZ])
890                  ipb.beg = inpbuf;
891          scaninp();
# Line 683 | Line 893 | resetinp()                      /* rewind position and
893  
894  
895   void
896 < eputs(msg)
687 < char  *msg;
896 > eputs(char  *msg)
897   {
898          fputs(msg, stderr);
899   }
900  
901  
902   void
903 < wputs(msg)
695 < char  *msg;
903 > wputs(char  *msg)
904   {
905          if (!nowarn)
906                  eputs(msg);
# Line 700 | Line 908 | char  *msg;
908  
909  
910   void
911 < quit(code)
704 < int  code;
911 > quit(int  code)
912   {
913          exit(code);
914   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines