# 2.11BSD#431 - /usr/src/local/cxref/cxref.c

##### Functions

    catchem           X
    deltemps          X
    filename          X
    floats            X
    idens             X
    integers          X
    main              X
    runprogs          X
    setargs           X
    usage             X

##### Variables

    Fflag             X
    ancestor          X
    cflag             X
    cxrfilt           X
    docxref           X
    fflag             X
    fmtxref           X
    iflag             X
    level             X
    name              X
    pipe1             X
    pipe2             X
    pipe3             X
    sepflag           X
    sflag             X
    sort1             X
    sort2             X
    sort3             X
    width             X
    xargc             X
    xargv             X

##### Macros

    FALSE             X
    TRUE              X
    do_pipe           X

##### typedef's

    PIPE              X

       1: /*
       2: ** cxref.c
       3: **
       4: ** C driver for Cxref program.
       5: ** does argument handling, then builds the right
       6: ** shell commands for passing to the system() routine.
       7: **
       8: ** Set up the argument vectors ourselves, the i/o with a pipe()
       9: ** call, and do all the forking and execing ourselves.
      10: **
      11: ** Arnold Robbins, Information and Computer Science, Georgia Tech
      12: **	gatech!arnold
      13: ** Copyright (c) 1984 by Arnold Robbins
      14: ** All rights reserved
      15: ** This program may not be sold, but may be distributed
      16: ** provided this header is included.
      17: */
      18:
      19: #include <stdio.h>
      20: #include <ctype.h>
      21: #include <signal.h>
      22:
      23: #define TRUE    1
      24: #define FALSE   0
      25:
      26: char name[BUFSIZ];  /* save command name */
      27:
      28: int xargc;      /* make argc and argv available globally */
      29: char **xargv;
      30:
      31: int width = 0;      /* output width */
      32:
      33: int sepflag = FALSE;    /* do each one separately */
      34:
      35: int iflag = TRUE;   /* print out ints */
      36: int fflag = TRUE;   /* print out floats */
      37: int cflag = TRUE;   /* print out chars */
      38: int sflag = TRUE;   /* print out strings */
      39: int Fflag = FALSE;  /* fold case in indentifiers */
      40:
      41: int ancestor;       /* id of this process, used by children */
      42:
      43: char *filename();   /* turns "-" into "stdin" */
      44:
      45: #define do_pipe(x)  if (pipe(x) < 0) { fprintf(stderr, "x: pipe failed\n");\
      46:                 fflush(stderr); exit (1); }
      47:
      48: main(argc, argv)
      49: int argc;
      50: char **argv;
      51: {
      52:     int i;
      53:     int catchem();
      54:
      55:     signal (SIGQUIT, catchem);
      56:     signal (SIGINT, catchem);
      57:
      58:     strcpy (name, filename(argv[0]));
      59:
      60:     ancestor = getpid();
      61:
      62:     for(argv++, argc--; argc > 0; argv++, argc--)
      63:         if (argv[0][0] != '-')
      64:             break;
      65:         else if(argv[0][1] == '\0') /* filename of "-" */
      66:             break;
      67:         else
      68:             for(i = 1; argv[0][i] != '\0'; i++)
      69:             {
      70:                 switch(argv[0][i]) {
      71:                 case 'F':
      72:                     Fflag = TRUE;
      73:                     break;
      74:
      75:                 case 'S':
      76:                     sepflag = TRUE;
      77:                     break;
      78:
      79:                 case 'C':
      80:                     /* leave out all constants */
      81:                     cflag =
      82:                     iflag =
      83:                     fflag =
      84:                     sflag = FALSE;
      85:                     break;
      86:
      87:                 case 'c':
      88:                     cflag = FALSE;
      89:                     break;
      90:
      91:                 case 'i':
      92:                     iflag = FALSE;
      93:                     break;
      94:
      95:                 case 'f':
      96:                     fflag = FALSE;
      97:                     break;
      98:
      99:                 case 's':
     100:                     sflag = FALSE;
     101:                     break;
     102:
     103:                 case 'w':
     104:                     if (isdigit(argv[0][i+1]))
     105:                     {
     106:                         width = 0;
     107:                         for(i++; isdigit(argv[0][i]); i++)
     108:                             width = width * 10 + argv[0][i] - '0';
     109:                         i--;
     110:                     }
     111:                     else
     112:                     {
     113:                         width = atoi(argv[1]);
     114:                         argv++;
     115:                         argc--;
     116:                     }
     117:                     break;
     118:
     119:                 default:
     120:                     usage();
     121:                     break;
     122:                 }
     123:             }
     124:
     125:     if (width != 0)
     126:         if (width < 51)
     127:             width = 80;
     128:         else if (width > 132)
     129:             width = 132;
     130:
     131:     xargc = argc;
     132:     xargv = argv;
     133:
     134:     setargs();      /* set up various argv buffers */
     135:
     136:     runprogs();     /* set up and run pipelines */
     137:
     138:     exit (0);
     139: }
     140:
     141: /* argv vectors for various commands */
     142:
     143: char *docxref[BUFSIZ] = { "docxref" };  /* allows BUFSIZ - 2 files */
     144: char *cxrfilt[] = { "cxrfilt", NULL, NULL, NULL };
     145: char *fmtxref[] = { "fmtxref", NULL, NULL, NULL };
     146: char *sort1[] = { "sort", "-u", "+0b", "-2", "+2n", NULL, NULL };
     147: char *sort2[] = { "sort", "-u", "+0n", "-1", "+1b", "-2", "+2n", NULL };
     148: char *sort3[] = { "sort", "-u", "+0n", "+1n", "-2", "+2b", "-3", "+3n", NULL };
     149:
     150: /* pipes to connect programs */
     151:
     152: typedef int PIPE[2];
     153:
     154: PIPE pipe1, pipe2, pipe3;
     155:
     156: setargs()       /* initialize argv vectors */
     157: {
     158:     static char widthbuf[100];
     159:     static char pidbuf[100];
     160:
     161:     if (width != 0)
     162:     {
     163:         fmtxref[1] = "-w";
     164:         sprintf(widthbuf, "%d", width);
     165:         fmtxref[2] = widthbuf;
     166:         fmtxref[3] = NULL;
     167:     }
     168:
     169:     sprintf(pidbuf, "%d", getpid());
     170:
     171:     if (Fflag)
     172:         sort1[5] = "-f";    /* fold case in identifiers */
     173:
     174:     if (! cflag && sflag)
     175:     {
     176:         cxrfilt[1] = "-c";
     177:         cxrfilt[2] = pidbuf;
     178:         cxrfilt[3] = NULL;
     179:     }
     180:
     181:     else if (cflag && ! sflag)
     182:     {
     183:         cxrfilt[1] = "-s";
     184:         cxrfilt[2] = pidbuf;
     185:         cxrfilt[3] = NULL;
     186:     }
     187:
     188:     else if (! cflag && ! sflag)
     189:     {
     190:         cxrfilt[1] = "-cs";
     191:         cxrfilt[2] = pidbuf;
     192:         cxrfilt[3] = NULL;
     193:     }
     194:
     195:     else
     196:     {
     197:         cxrfilt[1] = pidbuf;
     198:         cxrfilt[2] = NULL;
     199:     }
     200: }
     201:
     202:
     203: /*
     204: flow of control is:
     205:
     206: 	docxref  pipe1 sort1 pipe2 cxrfilt -userargs pipe3 fmtxref -userargs
     207: 	sort2 pipe1 cxrfilt -i pipe2 fmtxref -userargs
     208: 	sort3 pipe1 cxrfilt -f pipe2 fmtxref -userargs
     209: */
     210:
     211: runprogs()      /* run the programs, obeying user's options */
     212: {
     213:     int i;
     214:
     215:     if (sepflag)
     216:     {
     217:         for (i = 0; i < xargc; i++)
     218:         {
     219:             printf("\tC Cross Reference Listing of %s\n\n",
     220:                     filename(xargv[i]));
     221:             fflush(stdout);
     222:
     223:             docxref[1] = xargv[i];
     224:             docxref[2] = NULL;
     225:
     226:             idens();
     227:
     228:             if (iflag)
     229:                 integers();
     230:
     231:             if (fflag)
     232:                 floats();
     233:
     234:             fflush(stdout);
     235:
     236:             if (!isatty(fileno(stdout)))
     237:                 putchar('\f');
     238:         }
     239:     }
     240:     else
     241:     {
     242:         if (xargc == 1)
     243:             printf("\tC Cross Reference Listing of %s\n\n",
     244:                 filename(xargv[0]));
     245:         else
     246:             printf("\tC Cross Reference Listing\n\n");
     247:         fflush(stdout);
     248:
     249:         for (i = 0; xargv[i] != NULL; i++)
     250:             docxref[i+1] = xargv[i];
     251:
     252:         docxref[i+1] = NULL;
     253:
     254:         idens();
     255:
     256:         if (iflag)
     257:             integers();
     258:
     259:         if (fflag)
     260:             floats();
     261:
     262:         fflush(stdout);
     263:
     264:         if (! isatty(fileno(stdout)))
     265:             putchar('\f');
     266:     }
     267:
     268:     deltemps();
     269: }
     270:
     271: deltemps()  /* delete temp files used for ints and floats */
     272: {
     273:     char buf[BUFSIZ];
     274:     int i;
     275:
     276:     for (i = 1; i <= 2; i++)
     277:     {
     278:         sprintf(buf, "/tmp/cxr.%d.%d", getpid(), i);
     279:         unlink(buf);
     280:     }
     281: }
     282:
     283: /*
     284:  * now begins the nitty gritty work of forking and setting up pipes.
     285:  */
     286:
     287: int level;  /* how many children down are we */
     288:
     289: idens()     /* cross reference identifiers */
     290: {
     291:     int status;
     292:     int pid;
     293:     int ischild;
     294:     char buf[BUFSIZ];
     295:
     296:     level = 0;  /* starting off as grandparent */
     297:
     298:     ischild = ((pid = fork()) == 0);
     299:
     300: retest:
     301:     switch (level) {
     302:     case 0:         /* first fork */
     303:         if (ischild)
     304:         {
     305:             level++;
     306:             do_pipe(pipe3);
     307:
     308:             if (ischild = ((pid = fork()) == 0))
     309:                 goto retest;
     310:
     311:             close(pipe3[1]);    /* doesn't need this */
     312:
     313:             close (0);
     314:             dup(pipe3[0]);
     315:             close(pipe3[0]);
     316:             sprintf (buf, "%s/fmtxref", SRCDIR);
     317:             execv (buf, fmtxref);
     318:             fprintf (stderr, "couldn't exec '%s'\n", buf);
     319:             exit (1);
     320:         }
     321:         else
     322:             while (wait(&status) != pid)
     323:                 ;
     324:         break;
     325:
     326:     case 1:         /* second fork */
     327:         level++;
     328:         close (pipe3[0]);
     329:
     330:         close(1);
     331:         dup(pipe3[1]);
     332:         close(pipe3[1]);
     333:
     334:         /* set up i/o for next child */
     335:         do_pipe(pipe2);
     336:
     337:         if (ischild = ((pid = fork()) == 0))
     338:             goto retest;
     339:
     340:         close (pipe2[1]);
     341:         close (0);
     342:         dup(pipe2[0]);
     343:         close (pipe2[0]);
     344:
     345:         sprintf (buf, "%s/cxrfilt", SRCDIR);
     346:         execv (buf, cxrfilt);
     347:         fprintf (stderr, "couldn't exec '%s'\n", buf);
     348:         exit (1);
     349:         break;
     350:
     351:     case 2:
     352:         level++;
     353:         close (pipe2[0]);
     354:
     355:         close(1);
     356:         dup(pipe2[1]);
     357:         close(pipe2[1]);    /* now writes to parent */
     358:
     359:         /* set up to read from next child */
     360:         do_pipe(pipe1);
     361:
     362:         if (ischild = ((pid = fork()) == 0))
     363:             goto retest;
     364:
     365:         close (pipe1[1]);
     366:
     367:         close (0);
     368:         dup(pipe1[0]);
     369:         close (pipe1[0]);
     370:         execv (SORT, sort1);
     371:         fprintf (stderr, "couldn't exec '%s'\n", SORT);
     372:         exit (1);
     373:         break;
     374:
     375:     case 3:
     376:         level++;
     377:         close (pipe1[0]);
     378:
     379:         close(1);
     380:         dup(pipe1[1]);
     381:         close(pipe1[1]);    /* now writes to parent */
     382:
     383:         sprintf(buf, "%s/docxref", SRCDIR);
     384:         execv (buf, docxref);
     385:         fprintf (stderr, "couldn't exec '%s'\n", buf);
     386:         exit (1);
     387:         break;
     388:
     389:     default:
     390:         fprintf(stderr, "in cxref (idens): can't happen\n");
     391:         fflush(stderr);
     392:         break;
     393:     }
     394: }
     395:
     396: #include <sys/types.h>
     397: #include <sys/stat.h>
     398:
     399: integers()
     400: {
     401:     int status;
     402:     int pid;
     403:     int ischild;
     404:     char buf[BUFSIZ];
     405:     struct stat fbuf;
     406:
     407:     sprintf(buf, "/tmp/cxr.%d.1", ancestor);
     408:     if (stat(buf, &fbuf) >= 0 && fbuf.st_size > 0)
     409:         ;   /* file is not empty */
     410:     else
     411:         return;
     412:
     413:     level = 0;  /* starting off as grandparent */
     414:
     415:     ischild = ((pid = fork()) == 0);
     416:
     417: retest:
     418:     switch (level) {
     419:     case 0:         /* first fork */
     420:         if (ischild)
     421:         {
     422:             level++;
     423:             do_pipe(pipe2);
     424:
     425:             if (ischild = ((pid = fork()) == 0))
     426:                 goto retest;
     427:
     428:             close(pipe2[1]);    /* doesn't need this */
     429:
     430:             close (0);
     431:             dup(pipe2[0]);
     432:             close(pipe2[0]);
     433:             sprintf (buf, "%s/fmtxref", SRCDIR);
     434:             execv (buf, fmtxref);
     435:             fprintf (stderr, "couldn't exec '%s'\n", buf);
     436:             exit (1);
     437:         }
     438:         else
     439:             while (wait(&status) != pid)
     440:                 ;
     441:         break;
     442:
     443:     case 1:         /* second fork */
     444:         level++;
     445:         close (pipe2[0]);
     446:
     447:         close(1);
     448:         dup(pipe2[1]);
     449:         close(pipe2[1]);
     450:
     451:         /* set up i/o for next child */
     452:         do_pipe(pipe1);
     453:
     454:         if (ischild = ((pid = fork()) == 0))
     455:             goto retest;
     456:
     457:         close (pipe1[1]);
     458:         close (0);
     459:         dup(pipe1[0]);
     460:         close (pipe1[0]);
     461:
     462:         cxrfilt[1] = "-i";
     463:         cxrfilt[2] = NULL;
     464:
     465:         sprintf (buf, "%s/cxrfilt", SRCDIR);
     466:         execv (buf, cxrfilt);
     467:         fprintf (stderr, "couldn't exec '%s'\n", buf);
     468:         exit (1);
     469:         break;
     470:
     471:     case 2:
     472:         level++;
     473:         close (pipe1[0]);
     474:
     475:         close(1);
     476:         dup(pipe1[1]);
     477:         close(pipe1[1]);    /* now writes to parent */
     478:
     479:         /* read from tempfile */
     480:
     481:         close (0);
     482:         sprintf (buf, "/tmp/cxr.%d.1", ancestor);
     483:         open (buf, 0);      /* will be fd 0 */
     484:
     485:         execv (SORT, sort2);
     486:         fprintf (stderr, "couldn't exec '%s'\n", SORT);
     487:         exit (1);
     488:         break;
     489:
     490:     default:
     491:         fprintf(stderr, "in cxref(integers): can't happen\n");
     492:         fflush(stderr);
     493:         break;
     494:     }
     495: }
     496:
     497: floats()
     498: {
     499:     int status;
     500:     int pid;
     501:     int ischild;
     502:     char buf[BUFSIZ];
     503:     struct stat fbuf;
     504:
     505:     sprintf(buf, "/tmp/cxr.%d.2", ancestor);
     506:     if (stat(buf, &fbuf) >= 0 && fbuf.st_size > 0)
     507:         ;   /* file is not empty */
     508:     else
     509:         return;
     510:
     511:     level = 0;  /* starting off as grandparent */
     512:
     513:     ischild = ((pid = fork()) == 0);
     514:
     515: retest:
     516:     switch (level) {
     517:     case 0:         /* first fork */
     518:         if (ischild)
     519:         {
     520:             level++;
     521:             do_pipe(pipe2);
     522:
     523:             if (ischild = ((pid = fork()) == 0))
     524:                 goto retest;
     525:
     526:             close(pipe2[1]);    /* doesn't need this */
     527:
     528:             close (0);
     529:             dup(pipe2[0]);
     530:             close(pipe2[0]);
     531:             sprintf (buf, "%s/fmtxref", SRCDIR);
     532:             execv (buf, fmtxref);
     533:             fprintf (stderr, "couldn't exec '%s'\n", buf);
     534:             exit (1);
     535:         }
     536:         else
     537:             while (wait(&status) != pid)
     538:                 ;
     539:         break;
     540:
     541:     case 1:         /* second fork */
     542:         level++;
     543:         close (pipe2[0]);
     544:
     545:         close(1);
     546:         dup(pipe2[1]);
     547:         close(pipe2[1]);
     548:
     549:         /* set up i/o for next child */
     550:         do_pipe(pipe1);
     551:
     552:         if (ischild = ((pid = fork()) == 0))
     553:             goto retest;
     554:
     555:         close (pipe1[1]);
     556:         close (0);
     557:         dup(pipe1[0]);
     558:         close (pipe1[0]);
     559:
     560:         cxrfilt[1] = "-f";
     561:         cxrfilt[2] = NULL;
     562:
     563:         sprintf (buf, "%s/cxrfilt", SRCDIR);
     564:         execv (buf, cxrfilt);
     565:         fprintf (stderr, "couldn't exec '%s'\n", buf);
     566:         exit (1);
     567:         break;
     568:
     569:     case 2:
     570:         level++;
     571:         close (pipe1[0]);
     572:
     573:         close(1);
     574:         dup(pipe1[1]);
     575:         close(pipe1[1]);    /* now writes to parent */
     576:
     577:         /* read from tempfile */
     578:
     579:         close (0);
     580:         sprintf (buf, "/tmp/cxr.%d.2", ancestor);
     581:         open (buf, 0);      /* will be fd 0 */
     582:
     583:         execv (SORT, sort3);
     584:         fprintf (stderr, "couldn't exec '%s'\n", SORT);
     585:         exit (1);
     586:         break;
     587:
     588:     default:
     589:         fprintf(stderr, "in cxref(floats): can't happen\n");
     590:         fflush(stderr);
     591:         break;
     592:     }
     593: }
     594:
     595: usage()
     596: {
     597:     fprintf(stderr, "usage: %s [-SCcsif] [-w width] [files]\n", name);
     598:     fflush(stderr);
     599:     exit (1);
     600: }
     601:
     602: char *filename(fname)
     603: char *fname;
     604: {
     605:     char *cp, *basename();
     606:
     607:     cp = basename(fname);
     608:
     609:     return ( strcmp(cp, "-") == 0 ? "stdin" : cp);
     610: }
     611:
     612: catchem()   /* simple signal catcher */
     613: {
     614:     signal(SIGQUIT, SIG_IGN);
     615:     signal(SIGINT, SIG_IGN);
     616:
     617:     deltemps();
     618:
     619:     exit (0);
     620: }
     621:
     622: #include "basename.c"

#### Defined functions

catchem defined in line 612; used 3 times

- in line 53-56(3)

deltemps defined in line 271; used 2 times

- in line 268, 617

filename defined in line 602; used 4 times

- in line 43, 58, 220, 244

floats defined in line 497; used 2 times

- in line 232, 260

idens defined in line 289; used 2 times

- in line 226, 254

integers defined in line 399; used 2 times

- in line 229, 257

main defined in line 48; never used
runprogs defined in line 211; used 1 times

- in line 136

setargs defined in line 156; used 1 times

- in line 134

usage defined in line 595; used 1 times

- in line 120

#### Defined variables

Fflag defined in line 39; used 2 times

- in line 72, 171

ancestor defined in line 41; used 5 times

- in line 60, 407, 482, 505, 580

cflag defined in line 37; used 5 times

- in line 81, 88, 174, 181, 188

cxrfilt defined in line 144; used 18 times

- in line 176-198(11), 346, 462-466(3), 560-564(3)

docxref defined in line 143; used 5 times

- in line 223-224(2), 250-252(2), 384

fflag defined in line 36; used 4 times

- in line 83, 96, 231, 259

fmtxref defined in line 145; used 6 times

- in line 163-166(3), 317, 434, 532

iflag defined in line 35; used 4 times

- in line 82, 92, 228, 256

level defined in line 287; used 16 times

- in line 296-305(3), 327, 352, 376, 413-422(3), 444, 472, 511-520(3), 542, 570

name defined in line 26; used 2 times

- in line 58, 597

pipe1 defined in line 154; used 21 times

- in line 360-369(4), 377-381(3), 452-460(4), 473-477(3), 550-558(4), 571-575(3)

pipe2 defined in line 154; used 21 times

- in line 335-343(4), 353-357(3), 423-432(4), 445-449(3), 521-530(4), 543-547(3)

pipe3 defined in line 154; used 7 times

- in line 306-315(4), 328-332(3)

sepflag defined in line 33; used 2 times

- in line 76, 215

sflag defined in line 38; used 5 times

- in line 84, 100, 174, 181, 188

sort1 defined in line 146; used 2 times

- in line 172, 370

sort2 defined in line 147; used 1 times

- in line 485

sort3 defined in line 148; used 1 times

- in line 583

width defined in line 31; used 11 times

- in line 106-113(4), 125-129(5), 161-164(2)

xargc defined in line 28; used 3 times

- in line 131, 217, 242

xargv defined in line 29; used 6 times

- in line 132, 220-223(2), 244-250(3)

#### Defined typedef's

PIPE defined in line 152; used 1 times

- in line 154

#### Defined macros

FALSE defined in line 24; used 7 times

- in line 33, 39, 84-100(5)

TRUE defined in line 23; used 6 times

- in line 35-38(4), 72-76(2)

do_pipe defined in line 45; used 7 times

- in line 306, 335, 360, 423, 452, 521, 550

Last modified: 1991-11-05 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1960 |