| 1 | < | /* Copyright (c) 1991 Regents of the University of California */ | 
| 1 | > | /* Copyright (c) 1996 Regents of the University of California */ | 
| 2 |  |  | 
| 3 |  | #ifndef lint | 
| 4 |  | static char SCCSid[] = "$SunId$ LBL"; | 
| 14 |  |  | 
| 15 |  | #include  "standard.h" | 
| 16 |  |  | 
| 17 | + | #include  "paths.h" | 
| 18 | + |  | 
| 19 |  | #include  <ctype.h> | 
| 20 |  |  | 
| 21 |  | #include  "object.h" | 
| 31 |  |  | 
| 32 |  | int  invert = 0;                        /* boolean true to invert surfaces */ | 
| 33 |  |  | 
| 34 | < | int  expand = 0;                        /* boolean true to expand commands */ | 
| 34 | > | int  expand = 1;                        /* 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 */ | 
| 40 | > | #define  ALIAS          NUMOTYPE        /* put alias at end of array */ | 
| 41 |  |  | 
| 42 | < | #define  NUMTYPES       (NUMOTYPE+1)    /* total number of object types */ | 
| 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 | < | #define  progname  (xav[0]) | 
| 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 | < | FILE  *fopen(); | 
| 56 | < | FILE  *fp; | 
| 62 | > | char  *fname; | 
| 63 |  | int  a; | 
| 64 |  | /* check for array */ | 
| 65 |  | for (a = 1; a < argc; a++) | 
| 81 |  | break; | 
| 82 |  | idprefix = argv[++a]; | 
| 83 |  | continue; | 
| 84 | + | case 'c': | 
| 85 | + | if (argv[a][2]) | 
| 86 | + | break; | 
| 87 | + | expand = 0; | 
| 88 | + | continue; | 
| 89 |  | case 'e': | 
| 90 |  | if (argv[a][2]) | 
| 91 |  | break; | 
| 123 |  | printf(" %s", xav[a]); | 
| 124 |  | putchar('\n'); | 
| 125 |  | /* transform input */ | 
| 126 | < | if (xac == argc) | 
| 127 | < | xform("standard input", stdin); | 
| 128 | < | else | 
| 126 | > | if (xac == argc) { | 
| 127 | > | openmain(NULL); | 
| 128 | > | xform(mainfn, mainfp); | 
| 129 | > | } else | 
| 130 |  | for (a = xac; a < argc; a++) { | 
| 131 | < | if ((fp = fopen(argv[a], "r")) == NULL) { | 
| 132 | < | fprintf(stderr, "%s: cannot open \"%s\"\n", | 
| 121 | < | progname, argv[a]); | 
| 122 | < | exit(1); | 
| 123 | < | } | 
| 124 | < | xform(argv[a], fp); | 
| 125 | < | fclose(fp); | 
| 131 | > | openmain(argv[a]); | 
| 132 | > | xform(mainfn, mainfp); | 
| 133 |  | } | 
| 134 |  |  | 
| 135 |  | return(0); | 
| 143 |  | char  *newav[256], **avp; | 
| 144 |  | char  newid[128], repts[32]; | 
| 145 |  | char  *oldid = NULL; | 
| 146 | < | int  i, err; | 
| 146 | > | int  n, i, err; | 
| 147 |  |  | 
| 148 |  | avp = newav+2; | 
| 149 |  | avp[0] = av[0]; | 
| 163 |  | avp = newav; | 
| 164 |  | ac += 2; | 
| 165 |  | } | 
| 166 | + | nrept *= n = atoi(av[ai+1]); | 
| 167 |  | err = 0; | 
| 168 | < | for (i = 0; i < atoi(av[ai+1]); i++) { | 
| 168 | > | for (i = 0; i < n; i++) { | 
| 169 |  | if (oldid == NULL) | 
| 170 |  | sprintf(newid, "a%d", i); | 
| 171 |  | else | 
| 181 |  | char  *name; | 
| 182 |  | register FILE  *fin; | 
| 183 |  | { | 
| 184 | + | int  nobjs = 0; | 
| 185 |  | register int  c; | 
| 186 |  |  | 
| 187 |  | while ((c = getc(fin)) != EOF) { | 
| 197 |  | } else if (c == '!') {                  /* command */ | 
| 198 |  | ungetc(c, fin); | 
| 199 |  | xfcomm(name, fin); | 
| 200 | + | nobjs++; | 
| 201 |  | } else {                                /* object */ | 
| 202 |  | ungetc(c, fin); | 
| 203 |  | xfobject(name, fin); | 
| 204 | + | nobjs++; | 
| 205 |  | } | 
| 206 |  | } | 
| 207 | + | if (nobjs == 0) | 
| 208 | + | fprintf(stderr, "%s: (%s): warning - empty file\n", | 
| 209 | + | progname, name); | 
| 210 |  | } | 
| 211 |  |  | 
| 212 |  |  | 
| 213 |  | xfcomm(fname, fin)                      /* transform a command */ | 
| 214 | + | char  *fname; | 
| 215 |  | FILE  *fin; | 
| 216 |  | { | 
| 217 | < | FILE  *popen(); | 
| 218 | < | char  *fgetline(); | 
| 217 | > | extern FILE  *popen(); | 
| 218 | > | extern char  *fgetline(); | 
| 219 |  | FILE  *pin; | 
| 220 |  | char  buf[512]; | 
| 221 |  | int  i; | 
| 222 |  |  | 
| 223 |  | fgetline(buf, sizeof(buf), fin); | 
| 224 |  | if (expand) { | 
| 225 | < | if (xac > 2) { | 
| 226 | < | if ((pin = popen(buf+1, "r")) == NULL) { | 
| 227 | < | fprintf(stderr, | 
| 228 | < | "%s: (%s): cannot execute \"%s\"\n", | 
| 214 | < | progname, fname, buf); | 
| 215 | < | exit(1); | 
| 216 | < | } | 
| 217 | < | xform(buf, pin); | 
| 218 | < | pclose(pin); | 
| 219 | < | } else { | 
| 220 | < | fflush(stdout); | 
| 221 | < | system(buf+1); | 
| 225 | > | if ((pin = popen(buf+1, "r")) == NULL) { | 
| 226 | > | fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n", | 
| 227 | > | progname, fname, buf); | 
| 228 | > | exit(1); | 
| 229 |  | } | 
| 230 | + | xform(buf, pin); | 
| 231 | + | pclose(pin); | 
| 232 |  | } else { | 
| 233 |  | printf("\n%s", buf); | 
| 234 |  | if (xac > 1) { | 
| 235 | < | printf(" | %s -e", xav[0]); | 
| 235 | > | printf(" | %s", xav[0]); | 
| 236 |  | for (i = 1; i < xac; i++) | 
| 237 |  | printf(" %s", xav[i]); | 
| 238 |  | } | 
| 257 |  | progname, fname, typ); | 
| 258 |  | exit(1); | 
| 259 |  | } | 
| 260 | < | if (issurface(fn)) | 
| 260 | > | if (ismodifier(fn)) | 
| 261 | > | printf("\n%s %s ", nam, typ); | 
| 262 | > | else | 
| 263 |  | printf("\n%s %s ", newmod != NULL ? newmod : nam, | 
| 264 |  | invert ? ofun[tinvers[fn]].funame : typ); | 
| 254 | – | else | 
| 255 | – | printf("\n%s %s ", nam, typ); | 
| 265 |  | /* object name */ | 
| 266 |  | fgetword(nam, sizeof(nam), fin); | 
| 267 | < | if (idprefix != NULL && issurface(fn)) | 
| 259 | < | printf("%s.%s\n", idprefix, nam); | 
| 260 | < | else | 
| 267 | > | if (idprefix == NULL || ismodifier(fn)) | 
| 268 |  | printf("%s\n", nam); | 
| 269 | + | else | 
| 270 | + | printf("%s.%s\n", idprefix, nam); | 
| 271 |  | /* transform arguments */ | 
| 272 |  | if ((*ofun[fn].funp)(fin) < 0) { | 
| 273 |  | fprintf(stderr, "%s: (%s): bad %s \"%s\"\n", | 
| 281 |  | FILE  *fin; | 
| 282 |  | { | 
| 283 |  | register int  i; | 
| 284 | < | FUNARGS  fa; | 
| 284 | > | FUNARGS  fa; | 
| 285 |  |  | 
| 286 |  | if (readfargs(&fa, fin) != 1) | 
| 287 |  | return(-1); | 
| 290 |  | for (i = 0; i < fa.nsargs; i++) | 
| 291 |  | printf(" %s", fa.sarg[i]); | 
| 292 |  | printf("\n"); | 
| 293 | < | #ifdef  IARGS | 
| 293 | > | #ifdef  IARGS | 
| 294 |  | /* integer arguments */ | 
| 295 |  | printf("%d", fa.niargs); | 
| 296 |  | for (i = 0; i < fa.niargs; i++) | 
| 314 |  | { | 
| 315 |  | register int  i; | 
| 316 |  | int  resetarr = 0; | 
| 317 | < | FUNARGS  fa; | 
| 317 | > | FUNARGS  fa; | 
| 318 |  |  | 
| 319 |  | if (readfargs(&fa, fin) != 1) | 
| 320 |  | return(-1); | 
| 329 |  | for (i = xfa; i < xac; i++)     /* add xf arguments */ | 
| 330 |  | printf(" %s", xav[i]); | 
| 331 |  | printf("\n"); | 
| 332 | < | #ifdef  IARGS | 
| 332 | > | #ifdef  IARGS | 
| 333 |  | /* integer arguments */ | 
| 334 |  | printf("%d", fa.niargs); | 
| 335 |  | for (i = 0; i < fa.niargs; i++) | 
| 377 |  | m_glow(fin)                     /* transform arguments for proximity light */ | 
| 378 |  | FILE  *fin; | 
| 379 |  | { | 
| 380 | < | FUNARGS  fa; | 
| 380 | > | FUNARGS  fa; | 
| 381 |  |  | 
| 382 |  | if (readfargs(&fa, fin) != 1) | 
| 383 |  | return(-1); | 
| 396 |  | FILE  *fin; | 
| 397 |  | { | 
| 398 |  | FVECT  v; | 
| 399 | < | FUNARGS  fa; | 
| 399 | > | FUNARGS  fa; | 
| 400 |  |  | 
| 401 |  | if (readfargs(&fa, fin) != 1) | 
| 402 |  | return(-1); | 
| 412 |  | } | 
| 413 |  |  | 
| 414 |  |  | 
| 415 | + | m_mist(fin)             /* transform arguments for mist */ | 
| 416 | + | FILE  *fin; | 
| 417 | + | { | 
| 418 | + | FUNARGS  fa; | 
| 419 | + | int     i; | 
| 420 | + |  | 
| 421 | + | if (readfargs(&fa, fin) != 1) | 
| 422 | + | return(-1); | 
| 423 | + | if (fa.nfargs > 5) | 
| 424 | + | return(-1); | 
| 425 | + | printf("%d", fa.nsargs); | 
| 426 | + | if (idprefix == NULL) | 
| 427 | + | for (i = 0; i < fa.nsargs; i++) | 
| 428 | + | printf(" %s", fa.sarg[i]); | 
| 429 | + | else | 
| 430 | + | for (i = 0; i < fa.nsargs; i++) { | 
| 431 | + | char    sname[256], *sp; | 
| 432 | + | register char   *cp1, *cp2 = sname; | 
| 433 | + | /* add idprefix */ | 
| 434 | + | for (sp = fa.sarg[i]; *sp; sp = cp1) { | 
| 435 | + | for (cp1 = idprefix; *cp1; ) | 
| 436 | + | *cp2++ = *cp1++; | 
| 437 | + | *cp2++ = '.'; | 
| 438 | + | for (cp1 = sp; *cp1 && | 
| 439 | + | (*cp2++ = *cp1++) != '>'; ) | 
| 440 | + | ; | 
| 441 | + | } | 
| 442 | + | *cp2 = '\0'; | 
| 443 | + | printf(" %s", sname); | 
| 444 | + | } | 
| 445 | + | printf("\n0\n%d", fa.nfargs); | 
| 446 | + | if (fa.nfargs > 2) | 
| 447 | + | printf(" %12.6g %12.6g %12.6g", fa.farg[0]/tot.sca, | 
| 448 | + | fa.farg[1]/tot.sca, fa.farg[2]/tot.sca); | 
| 449 | + | if (fa.nfargs > 3) | 
| 450 | + | printf(" %12.6g", fa.farg[3]); | 
| 451 | + | if (fa.nfargs > 4) | 
| 452 | + | printf(" %12.6g", fa.farg[4]); | 
| 453 | + | printf("\n"); | 
| 454 | + | freefargs(&fa); | 
| 455 | + | return(0); | 
| 456 | + | } | 
| 457 | + |  | 
| 458 | + |  | 
| 459 |  | m_dielectric(fin)               /* transform arguments for dielectric */ | 
| 460 |  | FILE  *fin; | 
| 461 |  | { | 
| 462 | < | double  pow(); | 
| 410 | < | FUNARGS  fa; | 
| 462 | > | FUNARGS  fa; | 
| 463 |  |  | 
| 464 |  | if (readfargs(&fa, fin) != 1) | 
| 465 |  | return(-1); | 
| 466 |  | if (fa.nsargs != 0  || fa.nfargs != 5) | 
| 467 |  | return(-1); | 
| 468 |  | printf("0\n0\n5"); | 
| 469 | < | printf(" %18.12g %18.12g %18.12g", | 
| 469 | > | printf(" %12.6g %12.6g %12.6g", | 
| 470 |  | pow(fa.farg[0], 1.0/tot.sca), | 
| 471 |  | pow(fa.farg[1], 1.0/tot.sca), | 
| 472 |  | pow(fa.farg[2], 1.0/tot.sca)); | 
| 473 | < | printf(" %18.12g %18.12g\n", fa.farg[3], fa.farg[4]); | 
| 473 | > | printf(" %12.6g %12.6g\n", fa.farg[3], fa.farg[4]); | 
| 474 |  | freefargs(&fa); | 
| 475 |  | return(0); | 
| 476 |  | } | 
| 479 |  | m_interface(fin)                /* transform arguments for interface */ | 
| 480 |  | FILE  *fin; | 
| 481 |  | { | 
| 482 | < | double  pow(); | 
| 431 | < | FUNARGS  fa; | 
| 482 | > | FUNARGS  fa; | 
| 483 |  |  | 
| 484 |  | if (readfargs(&fa, fin) != 1) | 
| 485 |  | return(-1); | 
| 486 |  | if (fa.nsargs != 0  || fa.nfargs != 8) | 
| 487 |  | return(-1); | 
| 488 |  | printf("0\n0\n8\n"); | 
| 489 | < | printf("%18.12g %18.12g %18.12g", | 
| 489 | > | printf("%12.6g %12.6g %12.6g", | 
| 490 |  | pow(fa.farg[0], 1.0/tot.sca), | 
| 491 |  | pow(fa.farg[1], 1.0/tot.sca), | 
| 492 |  | pow(fa.farg[2], 1.0/tot.sca)); | 
| 493 | < | printf(" %18.12g\n", fa.farg[3]); | 
| 494 | < | printf("%18.12g %18.12g %18.12g", | 
| 493 | > | printf(" %12.6g\n", fa.farg[3]); | 
| 494 | > | printf("%12.6g %12.6g %12.6g", | 
| 495 |  | pow(fa.farg[4], 1.0/tot.sca), | 
| 496 |  | pow(fa.farg[5], 1.0/tot.sca), | 
| 497 |  | pow(fa.farg[6], 1.0/tot.sca)); | 
| 498 | < | printf(" %18.12g\n", fa.farg[7]); | 
| 498 | > | printf(" %12.6g\n", fa.farg[7]); | 
| 499 |  | freefargs(&fa); | 
| 500 |  | return(0); | 
| 501 |  | } | 
| 506 |  | { | 
| 507 |  | int  i; | 
| 508 |  | FVECT  v; | 
| 509 | < | FUNARGS  fa; | 
| 509 | > | FUNARGS  fa; | 
| 510 |  |  | 
| 511 |  | if (readfargs(&fa, fin) != 1) | 
| 512 |  | return(-1); | 
| 513 | < | if (fa.nfargs != 9 && fa.nfargs != 11 && fa.nfargs != 15) | 
| 513 | > | if (fa.nfargs < 9) | 
| 514 |  | return(-1); | 
| 515 |  | /* string arguments */ | 
| 516 |  | printf("%d", fa.nsargs); | 
| 525 |  | printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]); | 
| 526 |  | /* down vector */ | 
| 527 |  | multv3(v, fa.farg+6, tot.xfm); | 
| 528 | < | printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]); | 
| 529 | < | /* forground and background */ | 
| 530 | < | if (fa.nfargs == 11) | 
| 531 | < | printf(" %18.12g %18.12g\n", fa.farg[9], fa.farg[10]); | 
| 532 | < | else if (fa.nfargs == 15) { | 
| 533 | < | printf(" %18.12g %18.12g %18.12g\n", | 
| 483 | < | fa.farg[9], fa.farg[10], fa.farg[11]); | 
| 484 | < | printf(" %18.12g %18.12g %18.12g\n", | 
| 485 | < | fa.farg[12], fa.farg[13], fa.farg[14]); | 
| 528 | > | printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]); | 
| 529 | > | /* remaining arguments */ | 
| 530 | > | for (i = 9; i < fa.nfargs; i++) { | 
| 531 | > | if (i%3 == 0) | 
| 532 | > | putchar('\n'); | 
| 533 | > | printf(" %18.12g", fa.farg[i]); | 
| 534 |  | } | 
| 535 | + | putchar('\n'); | 
| 536 |  | freefargs(&fa); | 
| 537 |  | return(0); | 
| 538 |  | } | 
| 542 |  | FILE  *fin; | 
| 543 |  | { | 
| 544 |  | FVECT  dv; | 
| 545 | < | FUNARGS  fa; | 
| 545 | > | FUNARGS  fa; | 
| 546 |  |  | 
| 547 |  | if (readfargs(&fa, fin) != 1) | 
| 548 |  | return(-1); | 
| 563 |  | FILE  *fin; | 
| 564 |  | { | 
| 565 |  | FVECT  cent; | 
| 566 | < | double  rad; | 
| 567 | < | FUNARGS  fa; | 
| 566 | > | double  rad; | 
| 567 | > | FUNARGS  fa; | 
| 568 |  |  | 
| 569 |  | if (readfargs(&fa, fin) != 1) | 
| 570 |  | return(-1); | 
| 571 |  | if (fa.nsargs != 0  || fa.nfargs != 4) | 
| 572 |  | return(-1); | 
| 573 |  |  | 
| 574 | < | multp3(cent, fa.farg, tot.xfm); /* transform center */ | 
| 574 | > | multp3(cent, fa.farg, tot.xfm); /* transform center */ | 
| 575 |  |  | 
| 576 |  | rad = fa.farg[3] * tot.sca;             /* scale radius */ | 
| 577 |  |  | 
| 588 |  | { | 
| 589 |  | FVECT  p; | 
| 590 |  | register int  i; | 
| 591 | < | FUNARGS  fa; | 
| 591 | > | FUNARGS  fa; | 
| 592 |  |  | 
| 593 |  | if (readfargs(&fa, fin) != 1) | 
| 594 |  | return(-1); | 
| 613 |  | FILE  *fin; | 
| 614 |  | { | 
| 615 |  | FVECT  p0, p1; | 
| 616 | < | double  r0, r1; | 
| 617 | < | FUNARGS  fa; | 
| 616 | > | double  r0, r1; | 
| 617 | > | FUNARGS  fa; | 
| 618 |  |  | 
| 619 |  | if (readfargs(&fa, fin) != 1) | 
| 620 |  | return(-1); | 
| 640 |  | FILE  *fin; | 
| 641 |  | { | 
| 642 |  | FVECT  p0, p1; | 
| 643 | < | double  rad; | 
| 644 | < | FUNARGS  fa; | 
| 643 | > | double  rad; | 
| 644 | > | FUNARGS  fa; | 
| 645 |  |  | 
| 646 |  | if (readfargs(&fa, fin) != 1) | 
| 647 |  | return(-1); | 
| 665 |  | FILE  *fin; | 
| 666 |  | { | 
| 667 |  | FVECT  p0, pd; | 
| 668 | < | double  r0, r1; | 
| 669 | < | FUNARGS  fa; | 
| 668 | > | double  r0, r1; | 
| 669 | > | FUNARGS  fa; | 
| 670 |  |  | 
| 671 |  | if (readfargs(&fa, fin) != 1) | 
| 672 |  | return(-1); | 
| 694 |  |  | 
| 695 |  | initotypes()                    /* initialize ofun[] array */ | 
| 696 |  | { | 
| 648 | – | extern int  o_source(); | 
| 649 | – | extern int  o_sphere(); | 
| 650 | – | extern int  o_face(); | 
| 651 | – | extern int  o_cone(); | 
| 652 | – | extern int  o_cylinder(); | 
| 653 | – | extern int  o_ring(); | 
| 654 | – | extern int  m_glow(); | 
| 655 | – | extern int  m_spot(); | 
| 656 | – | extern int  m_dielectric(); | 
| 657 | – | extern int  m_interface(); | 
| 658 | – | extern int  text(); | 
| 659 | – | extern int  alias(); | 
| 660 | – | extern int  passargs(); | 
| 661 | – | extern int  addxform(); | 
| 697 |  | register int  i; | 
| 698 |  |  | 
| 699 |  | if (ofun[OBJ_SOURCE].funp == o_source) | 
| 720 |  | ofun[MAT_SPOT].funp = m_spot; | 
| 721 |  | ofun[MAT_DIELECTRIC].funp = m_dielectric; | 
| 722 |  | ofun[MAT_INTERFACE].funp = m_interface; | 
| 723 | + | ofun[MAT_MIST].funp = m_mist; | 
| 724 |  | ofun[PAT_CTEXT].funp = | 
| 725 |  | ofun[PAT_BTEXT].funp = | 
| 726 |  | ofun[MIX_TEXT].funp = text; | 
| 727 |  | ofun[ALIAS].funp = alias; | 
| 728 |  | /* surface inverses */ | 
| 729 | + | tinvers[OBJ_FACE] = OBJ_FACE; | 
| 730 |  | tinvers[OBJ_SOURCE] = OBJ_SOURCE; | 
| 731 |  | tinvers[OBJ_CONE] = OBJ_CUP; | 
| 732 |  | tinvers[OBJ_CUP] = OBJ_CONE; | 
| 737 |  | tinvers[OBJ_TUBE] = OBJ_CYLINDER; | 
| 738 |  | tinvers[OBJ_INSTANCE] = OBJ_INSTANCE;   /* oh, well */ | 
| 739 |  | } | 
| 740 | + |  | 
| 741 | + |  | 
| 742 | + | #ifdef  OLDXFORM | 
| 743 | + | openmain(fname) | 
| 744 | + | char  *fname; | 
| 745 | + | { | 
| 746 | + | if (fname == NULL) { | 
| 747 | + | strcpy(mainfn, "standard input"); | 
| 748 | + | mainfp = stdin; | 
| 749 | + | return; | 
| 750 | + | } | 
| 751 | + | if (mainfp != NULL) { | 
| 752 | + | if (!strcmp(fname, mainfn)) { | 
| 753 | + | rewind(mainfp); | 
| 754 | + | return; | 
| 755 | + | } | 
| 756 | + | fclose(mainfp); | 
| 757 | + | } | 
| 758 | + | if ((mainfp = fopen(fname, "r")) == NULL) { | 
| 759 | + | fprintf(stderr, "%s: cannot open file \"%s\"\n", | 
| 760 | + | progname, fname); | 
| 761 | + | exit(1); | 
| 762 | + | } | 
| 763 | + | strcpy(mainfn, fname); | 
| 764 | + | } | 
| 765 | + | #else | 
| 766 | + | openmain(fname)         /* open fname for input, changing to its directory */ | 
| 767 | + | char  *fname; | 
| 768 | + | { | 
| 769 | + | extern FILE  *tmpfile(); | 
| 770 | + | extern char  *getlibpath(), *getpath(); | 
| 771 | + | static char  origdir[MAXPATH]; | 
| 772 | + | static char  curfn[MAXPATH]; | 
| 773 | + | static int  diffdir; | 
| 774 | + | register char  *fpath; | 
| 775 | + |  | 
| 776 | + | if (fname == NULL) {                    /* standard input */ | 
| 777 | + | if (mainfp == NULL) { | 
| 778 | + | register int  c; | 
| 779 | + | strcpy(mainfn, "standard input"); | 
| 780 | + | if (nrept <= 1) { | 
| 781 | + | mainfp = stdin; | 
| 782 | + | return;                 /* just read once */ | 
| 783 | + | } | 
| 784 | + | /* else copy */ | 
| 785 | + | if ((mainfp = tmpfile()) == NULL) { | 
| 786 | + | fprintf(stderr, | 
| 787 | + | "%s: cannot create temporary file\n", | 
| 788 | + | progname); | 
| 789 | + | exit(1); | 
| 790 | + | } | 
| 791 | + | while ((c = getc(stdin)) != EOF) | 
| 792 | + | putc(c, mainfp); | 
| 793 | + | fclose(stdin); | 
| 794 | + | } | 
| 795 | + | rewind(mainfp);                 /* rewind copy */ | 
| 796 | + | return; | 
| 797 | + | } | 
| 798 | + | if (mainfp == NULL) {                   /* first call, initialize */ | 
| 799 | + | getwd(origdir); | 
| 800 | + | } else if (!strcmp(fname, curfn)) {     /* just need to rewind? */ | 
| 801 | + | rewind(mainfp); | 
| 802 | + | return; | 
| 803 | + | } else {                                /* else close old stream */ | 
| 804 | + | fclose(mainfp); | 
| 805 | + | if (diffdir) { | 
| 806 | + | chdir(origdir); | 
| 807 | + | diffdir = 0; | 
| 808 | + | } | 
| 809 | + | } | 
| 810 | + | strcpy(curfn, fname);                   /* remember file name */ | 
| 811 | + | /* get full path */ | 
| 812 | + | if ((fpath = getpath(fname, getlibpath(), R_OK)) == NULL) { | 
| 813 | + | fprintf(stderr, "%s: cannot find file \"%s\"\n", | 
| 814 | + | progname, fname); | 
| 815 | + | exit(1); | 
| 816 | + | } | 
| 817 | + | if (fpath[0] == '.' && ISDIRSEP(fpath[1]))      /* remove leading ./ */ | 
| 818 | + | fpath += 2; | 
| 819 | + | /* record path name */ | 
| 820 | + | strcpy(mainfn, fpath); | 
| 821 | + | if (expand) {                           /* change to local directory */ | 
| 822 | + | register char  *cp = fpath + strlen(fpath);     /* get dir. */ | 
| 823 | + | while (cp > fpath) { | 
| 824 | + | cp--; | 
| 825 | + | if (ISDIRSEP(*cp)) { | 
| 826 | + | if (cp == fpath) | 
| 827 | + | cp++;   /* root special case */ | 
| 828 | + | break; | 
| 829 | + | } | 
| 830 | + | } | 
| 831 | + | *cp = '\0'; | 
| 832 | + | if (fpath[0]) {                 /* change to new directory? */ | 
| 833 | + | if (chdir(fpath) < 0) { | 
| 834 | + | fprintf(stderr, | 
| 835 | + | "%s: cannot change directory to \"%s\"\n", | 
| 836 | + | progname, fpath); | 
| 837 | + | exit(1); | 
| 838 | + | } | 
| 839 | + | diffdir++; | 
| 840 | + | } | 
| 841 | + | /* get final path component */ | 
| 842 | + | for (fpath = fname+strlen(fname); | 
| 843 | + | fpath > fname && !ISDIRSEP(fpath[-1]); fpath--) | 
| 844 | + | ; | 
| 845 | + | } | 
| 846 | + | /* open the file */ | 
| 847 | + | if ((mainfp = fopen(fpath, "r")) == NULL) { | 
| 848 | + | fprintf(stderr, "%s: cannot open file \"%s\"\n", | 
| 849 | + | progname, mainfn); | 
| 850 | + | exit(1); | 
| 851 | + | } | 
| 852 | + | } | 
| 853 | + | #endif |