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.3 by greg, Sun Apr 27 06:08:03 2003 UTC vs.
Revision 1.20 by greg, Sat Dec 23 17:27:45 2006 UTC

# 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  bocols = 0;                /* produce binary output 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 88 | 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  
# Line 101 | Line 116 | char  *argv[];
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 110 | 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 128 | Line 147 | char  *argv[];
147                  case 'i':
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);
175 >                                        nbicols = atoi(argv[i]+3);
176                                  else
177 <                                        nbicols = -1;
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;
# Line 153 | Line 188 | char  *argv[];
188                  case 'o':
189                          switch (argv[i][2]) {
190                          case '\0':
191 <                                bocols = 0;
191 >                                otype = 'a';
192                                  readfmt(argv[++i], 1);
193                                  break;
194                          case 'a':
195 <                                bocols = 0;
195 >                                otype = 'a';
196                                  break;
197                          case 'd':
198 <                                bocols = 1;
164 <                                break;
198 >                        case 'D':
199                          case 'f':
200 <                                bocols = -1;
200 >                        case 'F':
201 >                                otype = argv[i][2];
202                                  break;
203 +                        default:
204 +                                goto userr;
205                          }
206                          break;
207                  case 'w':
# Line 177 | Line 214 | char  *argv[];
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 197 | 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 211 | Line 258 | nbsynch()               /* non-blank starting synch ch
258   }
259  
260  
261 < int
262 < getinputrec(fp)         /* get next input record */
263 < FILE  *fp;
261 > static int
262 > getinputrec(            /* get next input record */
263 > FILE  *fp
264 > )
265   {
266          if (inpfmt != NULL)
267                  return(getrec());
268 <        if (nbicols > 0)
269 <                return(fread(inpbuf, sizeof(double),
270 <                                        nbicols, fp) == nbicols);
271 <        if (nbicols < 0)
272 <                return(fread(inpbuf, sizeof(float),
273 <                                        -nbicols, fp) == -nbicols);
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 < execute(file)           /* process a file */
287 < char  *file;
286 > static void
287 > execute(           /* process a file */
288 > char  *file
289 > )
290   {
291          int  conditional = vardefined("cond");
292          long  nrecs = 0;
# Line 258 | Line 316 | char  *file;
316   }
317  
318  
319 < putout()                /* produce an output record */
319 > static void
320 > putout(void)                /* produce an output record */
321   {
263        extern void  chanset(), bchanset();
322  
323          colpos = 0;
324          if (outfmt != NULL)
325                  putrec();
326 <        else if (bocols)
269 <                chanout(bchanset);
270 <        else
326 >        else if (otype == 'a')
327                  chanout(chanset);
328 <        if (colpos && !bchanset)
328 >        else
329 >                chanout(bchanset);
330 >        if (colpos && otype == 'a')
331                  putchar('\n');
332          if (unbuff)
333                  fflush(stdout);
334   }
335  
336  
337 + static double
338 + l_in(char *funame)      /* function call for $channel */
339 + {
340 +        int  n;
341 +        register char  *cp;
342 +                        /* get argument as integer */
343 +        n = (int)(argument(1) + .5);
344 +        if (n != 0)     /* return channel value */
345 +                return(chanvalue(n));
346 +                        /* determine number of channels */
347 +        if (noinput || inpfmt != NULL)
348 +                return(0);
349 +        if (nbicols)
350 +                return(nbicols);
351 +        cp = inpbuf;    /* need to count */
352 +        for (n = 0; *cp; )
353 +                if (blnkeq && isspace(sepchar)) {
354 +                        while (isspace(*cp))
355 +                                cp++;
356 +                        n += *cp != '\0';
357 +                        while (*cp && !isspace(*cp))
358 +                                cp++;
359 +                } else {
360 +                        n += *cp != '\n';
361 +                        while (*cp && *cp++ != sepchar)
362 +                                ;
363 +                }
364 +        return(n);
365 + }
366 +
367   double
368 < chanvalue(n)            /* return value for column n */
369 < int  n;
368 > chanvalue(            /* return value for column n */
369 > int  n
370 > )
371   {
372          int  i;
373          register char  *cp;
# Line 291 | Line 380 | int  n;
380                  eputs("illegal channel number\n");
381                  quit(1);
382          }
383 <        if (nbicols > 0) {
383 >        if (nbicols) {
384                  if (n > nbicols)
385                          return(0.0);
386 <                cp = inpbuf + (n-1)*sizeof(double);
387 <                return(*(double *)cp);
388 <        }
389 <        if (nbicols < 0) {
301 <                if (n > -nbicols)
302 <                        return(0.0);
386 >                if (tolower(itype) == 'd') {
387 >                        cp = inpbuf + (n-1)*sizeof(double);
388 >                        return(*(double *)cp);
389 >                }
390                  cp = inpbuf + (n-1)*sizeof(float);
391                  return(*(float *)cp);
392          }
# Line 329 | Line 416 | int  n;
416  
417  
418   void
419 < chanset(n, v)                   /* output column n */
420 < int  n;
421 < double  v;
419 > chanset(                   /* output column n */
420 > int  n,
421 > double  v
422 > )
423   {
424          if (colpos == 0)                /* no leading separator */
425                  colpos = 1;
# Line 344 | Line 432 | double  v;
432  
433  
434   void
435 < bchanset(n, v)                   /* output binary channel n */
436 < int  n;
437 < double  v;
435 > bchanset(                   /* output binary channel n */
436 > int  n,
437 > double  v
438 > )
439   {
440          static char     zerobuf[sizeof(double)];
441 +        float   fval = v;
442  
443          while (++colpos < n)
444                  fwrite(zerobuf,
445 <                        bocols>0 ? sizeof(double) : sizeof(float),
445 >                        tolower(otype)=='d' ? sizeof(double) : sizeof(float),
446                          1, stdout);
447 <        if (bocols > 0)
447 >        switch (otype) {
448 >        case 'D':
449 >                swap64((char *)&v, 1);
450 >                /* fall through */
451 >        case 'd':
452                  fwrite(&v, sizeof(double), 1, stdout);
453 <        else {
454 <                float   fval = v;
453 >                break;
454 >        case 'F':
455 >                swap32((char *)&fval, 1);
456 >                /* fall through */
457 >        case 'f':
458                  fwrite(&fval, sizeof(float), 1, stdout);
459 +                break;
460          }
461   }
462  
463  
464 < readfmt(spec, output)                   /* read record format */
465 < char  *spec;
466 < int  output;
464 > static void
465 > readfmt(                   /* read record format */
466 > char  *spec,
467 > int  output
468 > )
469   {
470          int  fd;
471          char  *inptr;
# Line 384 | Line 484 | int  output;
484                          eputs(": cannot open\n");
485                          quit(1);
486                  }
487 <                res = read(fd, inpbuf+1, INBSIZ-1);
487 >                res = read(fd, inpbuf+2, INBSIZ-2);
488                  if (res <= 0 || res >= INBSIZ-1) {
489                          eputs(spec);
490                          if (res < 0)
# Line 396 | Line 496 | int  output;
496                          quit(1);
497                  }
498                  close(fd);
499 <                (inptr=inpbuf+1)[res] = '\0';
499 >                (inptr=inpbuf+2)[res] = '\0';
500          }
501          f = &fmt;                               /* get fields */
502          while ((res = readfield(&inptr)) != F_NUL) {
# Line 429 | Line 529 | int  output;
529   }
530  
531  
532 < int
533 < readfield(pp)                   /* get next field in format */
534 < register char  **pp;
532 > static int
533 > readfield(                   /* get next field in format */
534 > register char  **pp
535 > )
536   {
537          int  type = F_NUL;
538          int  width = 0;
# Line 496 | Line 597 | register char  **pp;
597  
598  
599   struct strvar *
600 < getsvar(svname)                         /* get string variable */
601 < char  *svname;
600 > getsvar(                         /* get string variable */
601 > char  *svname
602 > )
603   {
604          register struct strvar  *sv;
605          
# Line 513 | Line 615 | char  *svname;
615   }
616  
617  
618 < svpreset(eqn)                    /* preset a string variable */
619 < char  *eqn;
618 > static void
619 > svpreset(                    /* preset a string variable */
620 > char  *eqn
621 > )
622   {
623          register struct strvar  *sv;
624          register char  *val;
# Line 533 | Line 637 | char  *eqn;
637   }
638  
639  
640 < clearrec()                      /* clear input record variables */
640 > static void
641 > clearrec(void)                  /* clear input record variables */
642   {
643          register struct field  *f;
644  
# Line 552 | Line 657 | clearrec()                     /* clear input record variables */
657   }
658  
659  
660 < getrec()                                /* get next record from file */
660 > static int
661 > getrec(void)                            /* get next record from file */
662   {
663          int  eatline;
664          register struct field  *f;
665 <        
665 >
666          while (ipb.chr != EOF) {
667 <                eatline = !igneol && ipb.chr != '\n';
562 <                if (blnkeq)             /* beware of nbsynch() */
667 >                if (blnkeq) {           /* beware of nbsynch() */
668                          while (isblnk(ipb.chr))
669 <                                scaninp();
669 >                                resetinp();
670 >                        if (ipb.chr == EOF)
671 >                                return(0);
672 >                }
673 >                eatline = (!igneol && ipb.chr != '\n');
674                  clearrec();             /* start with fresh record */
675                  for (f = inpfmt; f != NULL; f = f->next)
676                          if (getfield(f) == -1)
677                                  break;
678                  if (f == NULL) {
679 <                        advinp();
679 >                        advinp();       /* got one! */
680                          return(1);
681                  }
682 <                resetinp();
682 >                resetinp();             /* eat false start */
683                  if (eatline) {          /* eat rest of line */
684                          while (ipb.chr != '\n') {
685                                  if (ipb.chr == EOF)
686                                          return(0);
687 <                                scaninp();
687 >                                resetinp();
688                          }
689 <                        scaninp();
581 <                        advinp();
689 >                        resetinp();
690                  }
691          }
692          return(0);
693   }
694  
695  
696 < getfield(f)                             /* get next field */
697 < register struct field  *f;
696 > static int
697 > getfield(                             /* get next field */
698 > register struct field  *f
699 > )
700   {
701 <        static char  buf[MAXWORD+1];            /* no recursion! */
701 >        static char  buf[RMAXWORD+1];            /* no recursion! */
702          int  delim, inword;
703          double  d;
704          char  *np;
# Line 621 | Line 731 | register struct field  *f;
731                          delim = f->next->f.sl[0];
732                  cp = buf;
733                  do {
734 <                        if (ipb.chr == EOF)
734 >                        if (ipb.chr == EOF || ipb.chr == '\n')
735                                  inword = 0;
736                          else if (blnkeq && delim != EOF)
737                                  inword = isblnk(delim) ?
# Line 633 | Line 743 | register struct field  *f;
743                                  *cp++ = ipb.chr;
744                                  scaninp();
745                          }
746 <                } while (inword && cp < &buf[MAXWORD]);
746 >                } while (inword && cp < &buf[RMAXWORD]);
747                  *cp = '\0';
748                  if (f->f.sv->val == NULL)
749                          f->f.sv->val = savqstr(buf);    /* first setting */
# Line 662 | Line 772 | register struct field  *f;
772                                  *cp++ = ipb.chr;
773                                  scaninp();
774                          }
775 <                } while (inword && cp < &buf[MAXWORD]);
775 >                } while (inword && cp < &buf[RMAXWORD]);
776                  *cp = '\0';
777                  d = np==NULL ? 0. : atof(np);
778                  if (!vardefined(f->f.nv))
# Line 672 | Line 782 | register struct field  *f;
782                          return(-1);                     /* doesn't match! */
783                  return(0);
784          }
785 +        return -1; /* pro forma return */
786   }
787  
788  
789 < putrec()                                /* output a record */
789 > static void
790 > putrec(void)                                /* output a record */
791   {
792          char  fmt[32];
793          register int  n;
# Line 725 | Line 837 | putrec()                                /* output a re
837   }
838  
839  
840 < initinp(fp)                     /* prepare lookahead buffer */
841 < FILE  *fp;
840 > static void
841 > initinp(FILE  *fp)                     /* prepare lookahead buffer */
842 >
843   {
844          ipb.fin = fp;
845          ipb.beg = ipb.end = inpbuf;
# Line 736 | Line 849 | FILE  *fp;
849   }
850  
851  
852 < scaninp()                       /* scan next character */
852 > static void
853 > scaninp(void)                       /* scan next character */
854   {
855          if (ipb.chr == EOF)
856                  return;
# Line 755 | Line 869 | scaninp()                       /* scan next character
869   }
870  
871  
872 < advinp()                        /* move home to current position */
872 > static void
873 > advinp(void)                        /* move home to current position */
874   {
875          ipb.beg = ipb.pos;
876   }
877  
878  
879 < resetinp()                      /* rewind position and advance 1 */
879 > static void
880 > resetinp(void)                      /* rewind position and advance 1 */
881   {
882          if (ipb.beg == NULL)            /* full */
883                  ipb.beg = ipb.end;
884          ipb.pos = ipb.beg;
885          ipb.chr = *ipb.pos;
886 +        if (passive)                    /* transmit unmatched character? */
887 +                fputc(ipb.chr, stdout);
888          if (++ipb.beg >= &inpbuf[INBSIZ])
889                  ipb.beg = inpbuf;
890          scaninp();
# Line 774 | Line 892 | resetinp()                      /* rewind position and
892  
893  
894   void
895 < eputs(msg)
778 < char  *msg;
895 > eputs(char  *msg)
896   {
897          fputs(msg, stderr);
898   }
899  
900  
901   void
902 < wputs(msg)
786 < char  *msg;
902 > wputs(char  *msg)
903   {
904          if (!nowarn)
905                  eputs(msg);
# Line 791 | Line 907 | char  *msg;
907  
908  
909   void
910 < quit(code)
795 < int  code;
910 > quit(int  code)
911   {
912          exit(code);
913   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines