ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/xform.c
Revision: 2.12
Committed: Wed Jun 12 11:55:27 1996 UTC (27 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +125 -17 lines
Log Message:
greatly improved file handling -- lib search and directory change

File Contents

# Content
1 /* Copyright (c) 1996 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * xform.c - program to transform object files.
9 * Transformations must preserve aspect ratio.
10 *
11 * 10/19/85
12 * 11/6/86 Finally added error checking!
13 */
14
15 #include "standard.h"
16
17 #include "paths.h"
18
19 #include <ctype.h>
20
21 #include "object.h"
22
23 #include "otypes.h"
24
25 int xac; /* global xform argument count */
26 char **xav; /* global xform argument pointer */
27 int xfa; /* start of xf arguments */
28
29 XF tot; /* total transformation */
30 int reverse; /* boolean true if scene mirrored */
31
32 int invert = 0; /* boolean true to invert surfaces */
33
34 int expand = 0; /* boolean true to expand commands */
35
36 char *newmod = NULL; /* new modifier for surfaces */
37
38 char *idprefix = NULL; /* prefix for object identifiers */
39
40 #define ALIAS NUMOTYPE /* put alias at end of array */
41
42 #define NUMTYPES (NUMOTYPE+1) /* total number of object types */
43
44 FUN ofun[NUMTYPES] = INIT_OTYPE; /* default types and actions */
45
46 short tinvers[NUMOTYPE]; /* inverse types for surfaces */
47
48 int nrept = 1; /* number of array repetitions */
49
50 extern char *malloc(), *fgetword();
51
52 char *mainfn[MAXPATH]; /* main file name */
53 FILE *mainfp = NULL; /* main file pointer */
54
55 #define progname (xav[0])
56
57
58 main(argc, argv) /* get transform options and transform file */
59 int argc;
60 char *argv[];
61 {
62 char *fname;
63 int a;
64 /* check for array */
65 for (a = 1; a < argc; a++)
66 if (!strcmp(argv[a], "-a"))
67 return(doarray(argc, argv, a));
68
69 initotypes();
70
71 for (a = 1; a < argc; a++) {
72 if (argv[a][0] == '-')
73 switch (argv[a][1]) {
74 case 'm':
75 if (argv[a][2] || a+1 >= argc)
76 break;
77 newmod = argv[++a];
78 continue;
79 case 'n':
80 if (argv[a][2] || a+1 >= argc)
81 break;
82 idprefix = argv[++a];
83 continue;
84 case 'e':
85 if (argv[a][2])
86 break;
87 expand = 1;
88 continue;
89 case 'I':
90 if (argv[a][2])
91 break;
92 invert = 1;
93 continue;
94 }
95 break;
96 }
97
98 xav = argv;
99 xfa = a;
100
101 a += xf(&tot, argc-a, argv+a);
102
103 if (reverse = tot.sca < 0.0)
104 tot.sca = -tot.sca;
105 if (invert)
106 reverse = !reverse;
107
108 if (a < argc && argv[a][0] == '-') {
109 fprintf(stderr, "%s: command line error at '%s'\n",
110 argv[0], argv[a]);
111 exit(1);
112 }
113
114 xac = a;
115 /* simple header */
116 putchar('#');
117 for (a = 0; a < xac; a++)
118 printf(" %s", xav[a]);
119 putchar('\n');
120 /* transform input */
121 if (xac == argc) {
122 openmain(NULL);
123 xform(mainfn, mainfp);
124 } else
125 for (a = xac; a < argc; a++) {
126 openmain(argv[a]);
127 xform(mainfn, mainfp);
128 }
129
130 return(0);
131 }
132
133
134 doarray(ac, av, ai) /* make array */
135 char **av;
136 int ac, ai;
137 {
138 char *newav[256], **avp;
139 char newid[128], repts[32];
140 char *oldid = NULL;
141 int n, i, err;
142
143 avp = newav+2;
144 avp[0] = av[0];
145 for (i = 1; i < ac; i++)
146 if (!strcmp(av[i-1], "-n")) {
147 oldid = av[i];
148 avp[i] = newid;
149 } else
150 avp[i] = av[i];
151 avp[ai] = "-i";
152 avp[ai+1] = repts;
153 avp[i] = NULL;
154 if (oldid == NULL) {
155 newav[0] = av[0];
156 newav[1] = "-n";
157 newav[2] = newid;
158 avp = newav;
159 ac += 2;
160 }
161 nrept *= n = atoi(av[ai+1]);
162 err = 0;
163 for (i = 0; i < n; i++) {
164 if (oldid == NULL)
165 sprintf(newid, "a%d", i);
166 else
167 sprintf(newid, "%s.%d", oldid, i);
168 sprintf(repts, "%d", i);
169 err |= main(ac, avp);
170 }
171 return(err);
172 }
173
174
175 xform(name, fin) /* transform stream by tot.xfm */
176 char *name;
177 register FILE *fin;
178 {
179 int nobjs = 0;
180 register int c;
181
182 while ((c = getc(fin)) != EOF) {
183 if (isspace(c)) /* blank */
184 continue;
185 if (c == '#') { /* comment */
186 putchar(c);
187 do {
188 if ((c = getc(fin)) == EOF)
189 return;
190 putchar(c);
191 } while (c != '\n');
192 } else if (c == '!') { /* command */
193 ungetc(c, fin);
194 xfcomm(name, fin);
195 nobjs++;
196 } else { /* object */
197 ungetc(c, fin);
198 xfobject(name, fin);
199 nobjs++;
200 }
201 }
202 if (nobjs == 0)
203 fprintf(stderr, "%s: (%s): warning - empty file\n",
204 progname, name);
205 }
206
207
208 xfcomm(fname, fin) /* transform a command */
209 char *fname;
210 FILE *fin;
211 {
212 extern FILE *popen();
213 extern char *fgetline();
214 FILE *pin;
215 char buf[512];
216 int i;
217
218 fgetline(buf, sizeof(buf), fin);
219 if (expand) {
220 if ((pin = popen(buf+1, "r")) == NULL) {
221 fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n",
222 progname, fname, buf);
223 exit(1);
224 }
225 xform(buf, pin);
226 pclose(pin);
227 } else {
228 printf("\n%s", buf);
229 if (xac > 1) {
230 printf(" | %s -e", xav[0]);
231 for (i = 1; i < xac; i++)
232 printf(" %s", xav[i]);
233 }
234 putchar('\n');
235 }
236 }
237
238
239 xfobject(fname, fin) /* transform an object */
240 char *fname;
241 FILE *fin;
242 {
243 extern char *strcpy();
244 char typ[16], nam[MAXSTR];
245 int fn;
246 /* modifier and type */
247 strcpy(typ, "EOF");
248 fgetword(nam, sizeof(nam), fin);
249 fgetword(typ, sizeof(typ), fin);
250 if ((fn = otype(typ)) < 0) {
251 fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
252 progname, fname, typ);
253 exit(1);
254 }
255 if (ismodifier(fn))
256 printf("\n%s %s ", nam, typ);
257 else
258 printf("\n%s %s ", newmod != NULL ? newmod : nam,
259 invert ? ofun[tinvers[fn]].funame : typ);
260 /* object name */
261 fgetword(nam, sizeof(nam), fin);
262 if (idprefix == NULL || ismodifier(fn))
263 printf("%s\n", nam);
264 else
265 printf("%s.%s\n", idprefix, nam);
266 /* transform arguments */
267 if ((*ofun[fn].funp)(fin) < 0) {
268 fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
269 progname, fname, ofun[fn].funame, nam);
270 exit(1);
271 }
272 }
273
274
275 o_default(fin) /* pass on arguments unchanged */
276 FILE *fin;
277 {
278 register int i;
279 FUNARGS fa;
280
281 if (readfargs(&fa, fin) != 1)
282 return(-1);
283 /* string arguments */
284 printf("%d", fa.nsargs);
285 for (i = 0; i < fa.nsargs; i++)
286 printf(" %s", fa.sarg[i]);
287 printf("\n");
288 #ifdef IARGS
289 /* integer arguments */
290 printf("%d", fa.niargs);
291 for (i = 0; i < fa.niargs; i++)
292 printf(" %d", fa.iarg[i]);
293 printf("\n");
294 #else
295 printf("0\n");
296 #endif
297 /* float arguments */
298 printf("%d", fa.nfargs);
299 for (i = 0; i < fa.nfargs; i++)
300 printf(" %18.12g", fa.farg[i]);
301 printf("\n");
302 freefargs(&fa);
303 return(0);
304 }
305
306
307 addxform(fin) /* add xf arguments to strings */
308 FILE *fin;
309 {
310 register int i;
311 int resetarr = 0;
312 FUNARGS fa;
313
314 if (readfargs(&fa, fin) != 1)
315 return(-1);
316 /* string arguments */
317 if (xac > xfa && strcmp(xav[xfa], "-i"))
318 resetarr = 2;
319 printf("%d", fa.nsargs + resetarr + xac-xfa);
320 for (i = 0; i < fa.nsargs; i++)
321 printf(" %s", fa.sarg[i]);
322 if (resetarr)
323 printf(" -i 1");
324 for (i = xfa; i < xac; i++) /* add xf arguments */
325 printf(" %s", xav[i]);
326 printf("\n");
327 #ifdef IARGS
328 /* integer arguments */
329 printf("%d", fa.niargs);
330 for (i = 0; i < fa.niargs; i++)
331 printf(" %d", fa.iarg[i]);
332 printf("\n");
333 #else
334 printf("0\n");
335 #endif
336 /* float arguments */
337 printf("%d", fa.nfargs);
338 for (i = 0; i < fa.nfargs; i++)
339 printf(" %18.12g", fa.farg[i]);
340 printf("\n");
341 freefargs(&fa);
342 return(0);
343 }
344
345
346 int
347 otype(ofname) /* get object function number from its name */
348 register char *ofname;
349 {
350 register int i;
351
352 for (i = 0; i < NUMTYPES; i++)
353 if (!strcmp(ofun[i].funame, ofname))
354 return(i);
355
356 return(-1); /* not found */
357 }
358
359
360 alias(fin) /* transfer alias */
361 FILE *fin;
362 {
363 char aliasnm[MAXSTR];
364
365 if (fgetword(aliasnm, MAXSTR, fin) == NULL)
366 return(-1);
367 printf("\t%s\n", aliasnm);
368 return(0);
369 }
370
371
372 m_glow(fin) /* transform arguments for proximity light */
373 FILE *fin;
374 {
375 FUNARGS fa;
376
377 if (readfargs(&fa, fin) != 1)
378 return(-1);
379 if (fa.nsargs != 0 || fa.nfargs != 4)
380 return(-1);
381 printf("0\n0\n4");
382 printf(" %18.12g %18.12g %18.12g",
383 fa.farg[0], fa.farg[1], fa.farg[2]);
384 printf(" %18.12g\n", fa.farg[3] * tot.sca);
385 freefargs(&fa);
386 return(0);
387 }
388
389
390 m_spot(fin) /* transform arguments for spotlight */
391 FILE *fin;
392 {
393 FVECT v;
394 FUNARGS fa;
395
396 if (readfargs(&fa, fin) != 1)
397 return(-1);
398 if (fa.nsargs != 0 || fa.nfargs != 7)
399 return(-1);
400 printf("0\n0\n7");
401 printf(" %18.12g %18.12g %18.12g %18.12g\n",
402 fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
403 multv3(v, fa.farg+4, tot.xfm);
404 printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
405 freefargs(&fa);
406 return(0);
407 }
408
409
410 m_mist(fin) /* transform arguments for mist */
411 FILE *fin;
412 {
413 FUNARGS fa;
414 int i;
415
416 if (readfargs(&fa, fin) != 1)
417 return(-1);
418 if (fa.nfargs > 5)
419 return(-1);
420 printf("%d", fa.nsargs);
421 if (idprefix == NULL)
422 for (i = 0; i < fa.nsargs; i++)
423 printf(" %s", fa.sarg[i]);
424 else
425 for (i = 0; i < fa.nsargs; i++) {
426 char sname[256], *sp;
427 register char *cp1, *cp2 = sname;
428 /* add idprefix */
429 for (sp = fa.sarg[i]; *sp; sp = cp1) {
430 for (cp1 = idprefix; *cp1; )
431 *cp2++ = *cp1++;
432 *cp2++ = '.';
433 for (cp1 = sp; *cp1 &&
434 (*cp2++ = *cp1++) != '>'; )
435 ;
436 }
437 *cp2 = '\0';
438 printf(" %s", sname);
439 }
440 printf("\n0\n%d", fa.nfargs);
441 if (fa.nfargs > 2)
442 printf(" %12.6g %12.6g %12.6g", fa.farg[0]/tot.sca,
443 fa.farg[1]/tot.sca, fa.farg[2]/tot.sca);
444 if (fa.nfargs > 3)
445 printf(" %12.6g", fa.farg[3]);
446 if (fa.nfargs > 4)
447 printf(" %12.6g", fa.farg[4]);
448 printf("\n");
449 freefargs(&fa);
450 return(0);
451 }
452
453
454 m_dielectric(fin) /* transform arguments for dielectric */
455 FILE *fin;
456 {
457 FUNARGS fa;
458
459 if (readfargs(&fa, fin) != 1)
460 return(-1);
461 if (fa.nsargs != 0 || fa.nfargs != 5)
462 return(-1);
463 printf("0\n0\n5");
464 printf(" %12.6g %12.6g %12.6g",
465 pow(fa.farg[0], 1.0/tot.sca),
466 pow(fa.farg[1], 1.0/tot.sca),
467 pow(fa.farg[2], 1.0/tot.sca));
468 printf(" %12.6g %12.6g\n", fa.farg[3], fa.farg[4]);
469 freefargs(&fa);
470 return(0);
471 }
472
473
474 m_interface(fin) /* transform arguments for interface */
475 FILE *fin;
476 {
477 FUNARGS fa;
478
479 if (readfargs(&fa, fin) != 1)
480 return(-1);
481 if (fa.nsargs != 0 || fa.nfargs != 8)
482 return(-1);
483 printf("0\n0\n8\n");
484 printf("%12.6g %12.6g %12.6g",
485 pow(fa.farg[0], 1.0/tot.sca),
486 pow(fa.farg[1], 1.0/tot.sca),
487 pow(fa.farg[2], 1.0/tot.sca));
488 printf(" %12.6g\n", fa.farg[3]);
489 printf("%12.6g %12.6g %12.6g",
490 pow(fa.farg[4], 1.0/tot.sca),
491 pow(fa.farg[5], 1.0/tot.sca),
492 pow(fa.farg[6], 1.0/tot.sca));
493 printf(" %12.6g\n", fa.farg[7]);
494 freefargs(&fa);
495 return(0);
496 }
497
498
499 text(fin) /* transform text arguments */
500 FILE *fin;
501 {
502 int i;
503 FVECT v;
504 FUNARGS fa;
505
506 if (readfargs(&fa, fin) != 1)
507 return(-1);
508 if (fa.nfargs < 9)
509 return(-1);
510 /* string arguments */
511 printf("%d", fa.nsargs);
512 for (i = 0; i < fa.nsargs; i++)
513 printf(" %s", fa.sarg[i]);
514 printf("\n0\n%d\n", fa.nfargs);
515 /* anchor point */
516 multp3(v, fa.farg, tot.xfm);
517 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
518 /* right vector */
519 multv3(v, fa.farg+3, tot.xfm);
520 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
521 /* down vector */
522 multv3(v, fa.farg+6, tot.xfm);
523 printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
524 /* remaining arguments */
525 for (i = 9; i < fa.nfargs; i++) {
526 if (i%3 == 0)
527 putchar('\n');
528 printf(" %18.12g", fa.farg[i]);
529 }
530 putchar('\n');
531 freefargs(&fa);
532 return(0);
533 }
534
535
536 o_source(fin) /* transform source arguments */
537 FILE *fin;
538 {
539 FVECT dv;
540 FUNARGS fa;
541
542 if (readfargs(&fa, fin) != 1)
543 return(-1);
544 if (fa.nsargs != 0 || fa.nfargs != 4)
545 return(-1);
546 /* transform direction vector */
547 multv3(dv, fa.farg, tot.xfm);
548 /* output */
549 printf("0\n0\n4");
550 printf(" %18.12g %18.12g %18.12g %18.12g\n",
551 dv[0], dv[1], dv[2], fa.farg[3]);
552 freefargs(&fa);
553 return(0);
554 }
555
556
557 o_sphere(fin) /* transform sphere arguments */
558 FILE *fin;
559 {
560 FVECT cent;
561 double rad;
562 FUNARGS fa;
563
564 if (readfargs(&fa, fin) != 1)
565 return(-1);
566 if (fa.nsargs != 0 || fa.nfargs != 4)
567 return(-1);
568
569 multp3(cent, fa.farg, tot.xfm); /* transform center */
570
571 rad = fa.farg[3] * tot.sca; /* scale radius */
572
573 printf("0\n0\n4");
574 printf(" %18.12g %18.12g %18.12g %18.12g\n",
575 cent[0], cent[1], cent[2], rad);
576 freefargs(&fa);
577 return(0);
578 }
579
580
581 o_face(fin) /* transform face arguments */
582 FILE *fin;
583 {
584 FVECT p;
585 register int i;
586 FUNARGS fa;
587
588 if (readfargs(&fa, fin) != 1)
589 return(-1);
590 if (fa.nsargs != 0 || fa.nfargs % 3)
591 return(-1);
592
593 printf("0\n0\n%d\n", fa.nfargs);
594
595 for (i = 0; i < fa.nfargs; i += 3) {
596 if (reverse)
597 multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
598 else
599 multp3(p, fa.farg+i, tot.xfm);
600 printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
601 }
602 freefargs(&fa);
603 return(0);
604 }
605
606
607 o_cone(fin) /* transform cone and cup arguments */
608 FILE *fin;
609 {
610 FVECT p0, p1;
611 double r0, r1;
612 FUNARGS fa;
613
614 if (readfargs(&fa, fin) != 1)
615 return(-1);
616 if (fa.nsargs != 0 || fa.nfargs != 8)
617 return(-1);
618
619 printf("0\n0\n8\n");
620
621 multp3(p0, fa.farg, tot.xfm);
622 multp3(p1, fa.farg+3, tot.xfm);
623 r0 = fa.farg[6] * tot.sca;
624 r1 = fa.farg[7] * tot.sca;
625 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
626 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
627 printf(" %18.12g %18.12g\n", r0, r1);
628
629 freefargs(&fa);
630 return(0);
631 }
632
633
634 o_cylinder(fin) /* transform cylinder and tube arguments */
635 FILE *fin;
636 {
637 FVECT p0, p1;
638 double rad;
639 FUNARGS fa;
640
641 if (readfargs(&fa, fin) != 1)
642 return(-1);
643 if (fa.nsargs != 0 || fa.nfargs != 7)
644 return(-1);
645
646 printf("0\n0\n7\n");
647
648 multp3(p0, fa.farg, tot.xfm);
649 multp3(p1, fa.farg+3, tot.xfm);
650 rad = fa.farg[6] * tot.sca;
651 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
652 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
653 printf(" %18.12g\n", rad);
654 freefargs(&fa);
655 return(0);
656 }
657
658
659 o_ring(fin) /* transform ring arguments */
660 FILE *fin;
661 {
662 FVECT p0, pd;
663 double r0, r1;
664 FUNARGS fa;
665
666 if (readfargs(&fa, fin) != 1)
667 return(-1);
668 if (fa.nsargs != 0 || fa.nfargs != 8)
669 return(-1);
670
671 printf("0\n0\n8\n");
672
673 multp3(p0, fa.farg, tot.xfm);
674 multv3(pd, fa.farg+3, tot.xfm);
675 if (invert) {
676 pd[0] = -pd[0];
677 pd[1] = -pd[1];
678 pd[2] = -pd[2];
679 }
680 r0 = fa.farg[6] * tot.sca;
681 r1 = fa.farg[7] * tot.sca;
682 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
683 printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
684 printf(" %18.12g %18.12g\n", r0, r1);
685 freefargs(&fa);
686 return(0);
687 }
688
689
690 initotypes() /* initialize ofun[] array */
691 {
692 register int i;
693
694 if (ofun[OBJ_SOURCE].funp == o_source)
695 return; /* done already */
696 /* alias is additional */
697 ofun[ALIAS].funame = ALIASID;
698 ofun[ALIAS].flags = 0;
699 /* functions get new transform */
700 for (i = 0; i < NUMTYPES; i++)
701 if (hasfunc(i))
702 ofun[i].funp = addxform;
703 /* special cases */
704 ofun[OBJ_SOURCE].funp = o_source;
705 ofun[OBJ_SPHERE].funp =
706 ofun[OBJ_BUBBLE].funp = o_sphere;
707 ofun[OBJ_FACE].funp = o_face;
708 ofun[OBJ_CONE].funp =
709 ofun[OBJ_CUP].funp = o_cone;
710 ofun[OBJ_CYLINDER].funp =
711 ofun[OBJ_TUBE].funp = o_cylinder;
712 ofun[OBJ_RING].funp = o_ring;
713 ofun[OBJ_INSTANCE].funp = addxform;
714 ofun[MAT_GLOW].funp = m_glow;
715 ofun[MAT_SPOT].funp = m_spot;
716 ofun[MAT_DIELECTRIC].funp = m_dielectric;
717 ofun[MAT_INTERFACE].funp = m_interface;
718 ofun[MAT_MIST].funp = m_mist;
719 ofun[PAT_CTEXT].funp =
720 ofun[PAT_BTEXT].funp =
721 ofun[MIX_TEXT].funp = text;
722 ofun[ALIAS].funp = alias;
723 /* surface inverses */
724 tinvers[OBJ_FACE] = OBJ_FACE;
725 tinvers[OBJ_SOURCE] = OBJ_SOURCE;
726 tinvers[OBJ_CONE] = OBJ_CUP;
727 tinvers[OBJ_CUP] = OBJ_CONE;
728 tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
729 tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
730 tinvers[OBJ_RING] = OBJ_RING;
731 tinvers[OBJ_CYLINDER] = OBJ_TUBE;
732 tinvers[OBJ_TUBE] = OBJ_CYLINDER;
733 tinvers[OBJ_INSTANCE] = OBJ_INSTANCE; /* oh, well */
734 }
735
736
737 #ifdef OLDXFORM
738 openmain(fname)
739 char *fname;
740 {
741 if (fname == NULL) {
742 strcpy(mainfn, "standard input");
743 mainfp = stdin;
744 return;
745 }
746 if (mainfp != NULL) {
747 if (!strcmp(fname, mainfn)) {
748 rewind(mainfp);
749 return;
750 }
751 fclose(mainfp);
752 }
753 if ((mainfp = fopen(fname, "r")) == NULL) {
754 fprintf(stderr, "%s: cannot open file \"%s\"\n",
755 progname, fname);
756 exit(1);
757 }
758 strcpy(mainfn, fname);
759 }
760 #else
761 openmain(fname) /* open fname for input, changing to its directory */
762 char *fname;
763 {
764 extern FILE *tmpfile();
765 extern char *getlibpath(), *getpath();
766 static char origdir[MAXPATH];
767 static char curdir[MAXPATH];
768 char newdir[MAXPATH], *cp;
769
770 if (fname == NULL) { /* standard input */
771 if (mainfp == NULL) {
772 register int c;
773 strcpy(mainfn, "standard input");
774 if (nrept <= 1) {
775 mainfp = stdin;
776 return; /* just read once */
777 }
778 /* else copy */
779 if ((mainfp = tmpfile()) == NULL) {
780 fprintf(stderr,
781 "%s: cannot create temporary file\n",
782 progname);
783 exit(1);
784 }
785 while ((c = getc(stdin)) != EOF)
786 putc(c, mainfp);
787 fclose(stdin);
788 }
789 rewind(mainfp); /* rewind copy */
790 return;
791 }
792 /* get full path */
793 if ((cp = getpath(fname, getlibpath(), R_OK)) == NULL) {
794 fprintf(stderr, "%s: cannot find file \"%s\"\n",
795 progname, fname);
796 exit(1);
797 }
798 if (cp[0] == '.' && ISDIRSEP(cp[1])) /* remove leading ./ */
799 cp += 2;
800 if (mainfp == NULL) { /* first call, initialize */
801 getwd(origdir);
802 strcpy(curdir, origdir);
803 } else if (!strcmp(cp, mainfn)) { /* just need to rewind? */
804 rewind(mainfp);
805 return;
806 } else /* else close old stream */
807 fclose(mainfp);
808 /* record path name */
809 strcpy(mainfn, cp);
810 if (expand) { /* get directory component */
811 if (ISDIRSEP(cp[0]))
812 strcpy(newdir, cp);
813 else
814 sprintf(newdir, "%s%c%s", origdir, DIRSEP, cp);
815 for (cp = newdir+strlen(newdir); !ISDIRSEP(cp[-1]); cp--)
816 ;
817 *cp = '\0';
818 if (strcmp(newdir, curdir)) { /* change to new directory? */
819 if (chdir(newdir) < 0) {
820 fprintf(stderr,
821 "%s: cannot change directory to \"%s\"\n",
822 progname, newdir);
823 exit(1);
824 }
825 strcpy(curdir, newdir);
826 }
827 /* get final path component */
828 for (cp = fname+strlen(fname);
829 cp > fname && !ISDIRSEP(cp[-1]); cp--)
830 ;
831 }
832 /* open the file */
833 if ((mainfp = fopen(cp, "r")) == NULL) {
834 fprintf(stderr, "%s: cannot open file \"%s\"\n",
835 progname, mainfn);
836 exit(1);
837 }
838 }
839 #endif