home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / CXREF.ZIP / CXREF.C next >
Encoding:
C/C++ Source or Header  |  1988-06-01  |  16.9 KB  |  784 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. #define NestMax 10
  5.  
  6. char CR = 0x0D;
  7. char IDChar[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_";
  8. char TINCLUDE[] = "#include";
  9. char *Reserved[] = {
  10.    "auto",
  11.    "break",
  12.    "case",
  13.    "char",
  14.    "continue",
  15.    "default",
  16.    "do",
  17.    "double",
  18.    "else",
  19.    "entry",
  20.    "extern",
  21.    "float",
  22.    "for",
  23.    "goto",
  24.    "if",
  25.    "int",
  26.    "long",
  27.    "register",
  28.    "return",
  29.    "short",
  30.    "sizeof",
  31.    "static",
  32.    "struct",
  33.    "switch",
  34.    "typedef",
  35.    "union",
  36.    "unsigned",
  37.    "void",
  38.    "while"
  39. };
  40.  
  41. typedef struct
  42. {
  43.    int AX, BX, CX, DX, SI, DI;
  44. } RegPack;
  45.  
  46. typedef struct
  47. {
  48.    FILE *ID;
  49.    char Name[64];
  50.    int Lnno;
  51.    char InsertChar;
  52.    int EndFile, First, Print;
  53. } FileDef;
  54.  
  55. typedef struct LR
  56. {
  57.    struct LR *Next;
  58.    int Key;
  59.    char Code;
  60. } LineRec;
  61.  
  62. typedef struct
  63. {
  64.    LineRec *First, *Current;
  65. } LineQueueRec;
  66.  
  67. typedef struct
  68. {
  69.    char *Key;
  70.    LineQueueRec *LineList;
  71. } WordRec;
  72.  
  73. typedef struct TR
  74. {
  75.    struct TR *Left, *Right;
  76.    WordRec *Ref;
  77. } TreeRec;
  78.  
  79. int PageNum, PageLn;
  80. TreeRec *Root;
  81. FileDef MainFile, IncludeFile, InFile;
  82. FILE *Output;
  83. int TotalLn, ChIndex;
  84. int Listing, StdFlag, IncludeFlag;
  85. int NestUp, NestDn, NestLvl;
  86. int Tabs;
  87. char Token[30], Path[64], IncludePath[64];
  88. int i;
  89. char *FDate, *FTime;
  90. char Today[30];
  91. char *OutFileName[64];
  92. char Ch;
  93. int UnGetCount = 0;
  94. char UnGot = ' ';
  95. char Line[255];
  96.  
  97. main(argc, argv)
  98. int argc;
  99. char *argv[];
  100. {
  101.    void Init(), GetFileDate(), Header(), GetLiteral(), GetIncludeFile();
  102.    void GetCharLiteral(), GetComment(), GetToken(), PrintLine(), AddQueue();
  103.    void Concordance(), Usage();
  104.    FILE *fopen();
  105.    char GetChar(), *index();
  106.  
  107.    Init();
  108.    if (argc < 2)
  109.       Usage();
  110.    else
  111.    {
  112.       for (i = 1; i < argc; i++)
  113.       {
  114.          strcpy(Token, argv[i]);
  115.          if (Token[0] == '-')
  116.          {
  117.             UpperCase(Token);
  118.             if (strcmp(Token, "-NL") == 0)
  119.                Listing = FALSE;
  120.             else if (strcmp(Token, "-NS") == 0)
  121.                StdFlag = FALSE;
  122.             else if (strcmp(Token, "-NI") == 0)
  123.                IncludeFlag = FALSE;
  124.             else if (Token[1] == 'T')
  125.             {
  126.                if (i + 1 < argc)
  127.                   Tabs = atoi(argv[++i]);
  128.                else
  129.                   fprintf(stderr, "Invalid Tab option\n");
  130.             }
  131.             else if (Token[1] == 'I')
  132.             {
  133.                if (i + 1 < argc)
  134.                {
  135.                   strcpy(IncludePath, argv[++i]);
  136.                   if (IncludePath[strlen(IncludePath) - 1] != "\\")
  137.                      strcat(IncludePath, "\\");
  138.                }
  139.                else
  140.                   fprintf(stderr, "Invalid Include Path option\n");
  141.             }
  142.             else
  143.             {
  144.                fprintf(stderr, "Invalid option: %s\n", argv[i]);
  145.             }
  146.          }
  147.          else if (strlen(InFile.Name) == 0)
  148.             strcpy(InFile.Name, argv[i]);
  149.          else
  150.          if (strlen(OutFileName) == 0)
  151.             strcpy(OutFileName, argv[i]);
  152.          else
  153.          {
  154.             fprintf(stderr, "Invalid parameter or too many file names: %s\n", argv[i]);
  155.             Abort();
  156.          }
  157.       }
  158.    }
  159.    if (strlen(InFile.Name) == 0)
  160.    {
  161.       fprintf(stderr, "I have nothing to do!  No input file specified.\n");
  162.       Abort();
  163.    }
  164.    if (index(InFile.Name, '.') == NULL)
  165.       strcat(InFile.Name, ".C");
  166.    for (i = strlen(InFile.Name); i >= 0; i--)
  167.    {
  168.       if ((InFile.Name[i] == '\\') || (InFile.Name[i] == '/') || (InFile.Name[i] == ':'))
  169.          break;
  170.    }
  171.    if (i < 0)
  172.       strcpy(Path, "");
  173.    else
  174.    {
  175.       strncpy(Path, InFile.Name, i + 1);
  176.       Path[i + 1] = '\0';
  177.    }
  178.    if (strlen(OutFileName) == 0)
  179.    {
  180.       strcpy(OutFileName, InFile.Name);
  181.       *index(OutFileName, '.') = 0x00;
  182.    }
  183.    if (index('.', OutFileName) == NULL)
  184.       strcat(OutFileName, ".LST");
  185.    if ((InFile.ID = fopen(InFile.Name, "r")) == NULL)
  186.    {
  187.       fprintf(stderr, "I can't find input file: %s\n", InFile.Name);
  188.       Abort();
  189.    }
  190.    InFile.Lnno = 0;
  191.    InFile.EndFile = FALSE;
  192.    InFile.Print = TRUE;
  193.    InFile.First = TRUE;
  194.    if ((Output = fopen(OutFileName, "w")) == NULL)
  195.    {
  196.       fprintf(stderr, "I can't create output file: %s\n", OutFileName);
  197.       Abort();
  198.    }
  199.    MainFile = InFile;
  200.    ChIndex = 0;
  201.    GetFileDate(InFile.ID->_file, &FDate, &FTime);
  202.    strcpy(Today, " Date: ");
  203.    strcat(Today, FDate);
  204.    strcat(Today, " @ ");
  205.    strcat(Today, FTime);
  206.  
  207.    if (Listing)
  208.       Header();
  209.    while (!MainFile.EndFile)
  210.    {
  211.       while (!InFile.EndFile)
  212.       {
  213.          Ch = GetChar();
  214.          if (Ch == '"')
  215.             GetLiteral();
  216.          else if ((Ch == '#') && IncludeFlag)
  217.             GetIncludeFile();
  218.          else if (Ch == '\'')
  219.             GetCharLiteral();
  220.          else if (Ch == '/')
  221.             GetComment();
  222.          else if (index(IDChar, Ch) != NULL)
  223.             GetToken();
  224.          else if (Ch == '{')
  225.          {
  226.             if (NestLvl == NestMax)
  227.                fprintf(stderr, "---- Too many levels\n");
  228.             else
  229.             {
  230.                NestLvl++;
  231.                NestUp = TRUE;
  232.             }
  233.          }
  234.          else if (Ch == '}')
  235.          {
  236.             if (NestLvl == 0)
  237.                fprintf(stderr, "---- Nesting Error");
  238.             else
  239.             {
  240.                NestLvl--;
  241.                NestDn = TRUE;
  242.             }
  243.          }
  244.       }
  245.       PrintLine();
  246.       if (InFile.InsertChar != ' ')
  247.       {
  248.          fclose(InFile.ID);
  249.          InFile = MainFile;
  250.          ChIndex = 0;
  251.       }
  252.       else
  253.          MainFile = InFile;
  254.    }
  255.    Header();
  256.    fprintf(stderr, "\n");
  257.    fprintf(stderr, "Writing Cross Reference\n");
  258.    Concordance(Root);
  259.    fclose(Output);
  260.    fprintf(stderr, "    Total Pages= %d\n", PageNum);
  261. }
  262.  
  263. void BackCh(Ch)
  264. char Ch;
  265. {
  266.    UnGot = Ch;
  267.    UnGetCount = 1;
  268. }
  269.  
  270. char GetChar()
  271. {
  272.    char Ch, InLine[255];
  273.    int i, j;
  274.  
  275.    if (UnGetCount)
  276.    {
  277.       UnGetCount = 0;
  278.       return (UnGot);
  279.    }
  280.    if (InFile.First)
  281.    {
  282.       InFile.ID = fopen(InFile.Name, "r");
  283.       InFile.First = FALSE;
  284.    }
  285.    if (ChIndex == 0)
  286.    {
  287.       if (!InFile.EndFile)
  288.       {
  289.          if (InFile.Print)
  290.          {
  291.             InFile.Print = FALSE;
  292.             fprintf(stderr, "\n");
  293.             fprintf(stderr, "Line= %4d%c Total Lines= %4d  ", InFile.Lnno, InFile.InsertChar, TotalLn);
  294.             if (InFile.InsertChar != ' ')
  295.                fprintf(stderr, "%13s", "");
  296.             fprintf(stderr, "%s", InFile.Name);
  297.             fputc(CR, stderr);
  298.          }
  299.          else
  300.             PrintLine();
  301.          fgets(InLine, 255, InFile.ID);
  302.          i = j = 0;
  303.          while (InLine[i])
  304.          {
  305.             if (InLine[i] == '\t')
  306.             {
  307.                do
  308.                   Line[j++] = ' ';
  309.                while (j % Tabs);
  310.             }
  311.             else
  312.                Line[j++] = InLine[i];
  313.             ++i;
  314.          }
  315.          Line[j] = 0x00;
  316.          if (feof(InFile.ID))
  317.             InFile.EndFile = TRUE;
  318.          else
  319.          {
  320.             Line[strlen(Line) - 1] = 0x00;
  321.             InFile.Lnno++;
  322.             TotalLn++;
  323.             GotoXY(6, WhereY());
  324.             fprintf(stderr, "%4d%c", InFile.Lnno, InFile.InsertChar);
  325.             GotoXY(25, WhereY());
  326.             fprintf(stderr, "%4d", TotalLn);
  327.             NestUp = FALSE;
  328.             NestDn = FALSE;
  329.             ChIndex = 1;
  330.          }
  331.       }
  332.    }
  333.    if (!InFile.EndFile)
  334.    {
  335.       if (ChIndex <= strlen(Line))
  336.          Ch = Line[ChIndex++ - 1];
  337.       else
  338.       {
  339.          Ch = ' ';
  340.          ChIndex = 0;
  341.       }
  342.    }
  343.    return (Ch);
  344. }
  345.  
  346. void Init()
  347. {
  348.    printf("C Cross Reference: Version 2.00  June 25, 1986\n\n");
  349.    PageNum = 0;
  350.    Root = NULL;
  351.    InFile.InsertChar = ' ';
  352.    TotalLn = 0;
  353.    IncludeFile.InsertChar = '@';
  354.    Listing = TRUE;
  355.    StdFlag = TRUE;
  356.    IncludeFlag = TRUE;
  357.    NestUp = FALSE;
  358.    NestDn = FALSE;
  359.    NestLvl = 0;
  360.    Tabs = 4;
  361.    IncludePath[0] = 0x00;
  362. }
  363.  
  364. int UpperCase(Str)
  365. char *Str;
  366. {
  367.    int i;
  368.  
  369.    for (i = 0; i < strlen(Str); i++)
  370.       if (islower(Str[i]))
  371.          Str[i] = (char) toupper(Str[i]);
  372. }
  373.  
  374. void GetFileDate(Handle, Date, Time)
  375. int Handle;
  376. char **Date, **Time;
  377. {
  378.    char *malloc();
  379.  
  380.    struct
  381.    {
  382.       int AX, BX, CX, DX, SI, DI;
  383.    } Regs;
  384.  
  385.    Regs.AX = 0x5700;
  386.    Regs.BX = Handle;
  387.    intdos(&Regs, &Regs);
  388.    *Date = malloc(9);
  389.    sprintf(*Date, "%02d-%02d-%02d", ((Regs.DX >> 5) & 0x0F), (Regs.DX & 0x1F),
  390.            (Regs.DX >> 9));
  391.    *Time = malloc(9);
  392.    sprintf(*Time, "%02d:%02d:%02d", (Regs.CX >> 11), ((Regs.CX >> 5) & 0x3F),
  393.            (Regs.CX & 0x1F));
  394. }
  395.  
  396. void Header()
  397. {
  398.    PageNum++;
  399.    fputc(0x0C, Output);                /* Form Feed */
  400.    fprintf(Output, "%-48s", MainFile.Name);
  401.    fprintf(Output, "Block Structure and Cross Reference");
  402.    fprintf(Output, "%29s   Page %3d", Today, PageNum);
  403.    fprintf(Output, "\n\n\n");
  404.    PageLn = 60;
  405. }
  406.  
  407. void GetLiteral()
  408. {
  409.    char Ch;
  410.  
  411.    do
  412.    {
  413.       Ch = GetChar();
  414.       if (Ch == '\\')
  415.       {
  416.          Ch = GetChar();
  417.          Ch = GetChar();
  418.       }
  419.    }
  420.    while ((!InFile.EndFile) && (Ch != '"'));
  421. }
  422.  
  423. void GetIncludeFile()
  424. {
  425.    extern int stricmp();
  426.    void PrintLine(), GetToken();
  427.  
  428.    int i, OK;
  429.    char DeLim;
  430.    char Temp[64];
  431.  
  432.    GetToken();
  433.    if (stricmp(Token, TINCLUDE) == 0)
  434.    {
  435.       OK = TRUE;
  436.       while ((!InFile.EndFile) && (Ch == ' '))
  437.          Ch = GetChar();
  438.       switch (Ch)
  439.       {
  440.       case '"':
  441.          DeLim = Ch;
  442.          break;
  443.       case '<':
  444.          DeLim = '>';
  445.          break;
  446.       default:
  447.          DeLim = ' ';
  448.       }
  449.       for (i = 0; ((!InFile.EndFile) && ((Ch = GetChar()) != DeLim)); i++)
  450.       {
  451.          Temp[i] = Ch;
  452.       }
  453.       Temp[i] = 0x00;
  454.       if (InFile.InsertChar == 'Z')
  455.       {
  456.          fprintf(stderr, "Too many include files\n");
  457.          OK = FALSE;
  458.       }
  459.       else
  460.       {
  461.          if (DeLim == '"')
  462.          {
  463.             strcpy(IncludeFile.Name, Path);
  464.             strcat(IncludeFile.Name, Temp);
  465.          }
  466.          else
  467.          {
  468.             strcpy(IncludeFile.Name, IncludePath);
  469.             strcat(IncludeFile.Name, Temp);
  470.          }
  471.          IncludeFile.InsertChar++;
  472.          IncludeFile.Lnno = 0;
  473.          IncludeFile.EndFile = FALSE;
  474.          IncludeFile.Print = TRUE;
  475.          IncludeFile.First = TRUE;
  476.          if ((IncludeFile.ID = fopen(IncludeFile.Name, "r")) == NULL)
  477.          {
  478.             fprintf(stderr, "\nCan't find include file: %s\n", IncludeFile.Name);
  479.             OK = FALSE;
  480.          }
  481.       }
  482.       PrintLine();
  483.       if (OK)
  484.       {
  485.          MainFile = InFile;
  486.          MainFile.Print = TRUE;
  487.          InFile = IncludeFile;
  488.          ChIndex = 0;
  489.       }
  490.    }
  491. }
  492.  
  493. void PrintLine()
  494. {
  495.    void FillLine();
  496.  
  497.    int Column;
  498.  
  499.    if (Listing)
  500.    {
  501.       fprintf(Output, "%4d%c    ", InFile.Lnno, InFile.InsertChar);
  502.       for (Column = 0; Column < NestLvl - 1; Column++)
  503.          fprintf(Output, "|  ");
  504.       if (NestLvl > 0)
  505.       {
  506.          if (NestUp || NestDn)
  507.          {
  508.             if (NestDn)
  509.             {
  510.                fprintf(Output, "|  ");
  511.                fprintf(Output, "E--");
  512.                for (Column = NestLvl + 1; Column < NestMax; Column++)
  513.                   fprintf(Output, "---");
  514.             }
  515.             else
  516.             {
  517.                fprintf(Output, "B--");
  518.                for (Column = NestLvl; Column < NestMax; Column++)
  519.                   fprintf(Output, "---");
  520.             }
  521.             FillLine(Line);
  522.          }
  523.          else
  524.          {
  525.             fprintf(Output, "|  ");
  526.             for (Column = NestLvl; Column < NestMax; Column++)
  527.                fprintf(Output, "   ");
  528.          }
  529.       }
  530.       else if (NestDn)
  531.       {
  532.          fprintf(Output, "E--");
  533.          for (Column = 1; Column < NestMax; Column++)
  534.             fprintf(Output, "---");
  535.          FillLine(Line);
  536.       }
  537.       else
  538.          for (Column = 0; Column < NestMax; Column++)
  539.             fprintf(Output, "   ");
  540.       fprintf(Output, "%s\n", Line);
  541.       PageLn--;
  542.       if (PageLn <= 0)
  543.          Header();
  544.    }
  545. }
  546.  
  547. void FillLine(Line)
  548. char *Line;
  549. {
  550.    int i;
  551.  
  552.    for (i = 0; i < strlen(Line) && Line[i] == ' '; i++)
  553.       Line[i] = '-';
  554. }
  555.  
  556.  
  557. void GetToken()
  558. {
  559.    TreeRec *BinaryTree();
  560.  
  561.    int j;
  562.  
  563.    j = 0;
  564.    do
  565.    {
  566.       Token[j] = Ch;
  567.       j++;
  568.       Ch = GetChar();
  569.    }
  570.    while ((index(IDChar, Ch) != NULL) && (!InFile.EndFile));
  571.    Token[j] = 0x00;
  572.    if (StdFlag)
  573.       Root = BinaryTree(Root);
  574.    else if (!BinarySearch(Token, Reserved, 29))
  575.       Root = BinaryTree(Root);
  576. }
  577.  
  578. void GetComment()
  579. {
  580.    char Ch;
  581.  
  582.    if (!InFile.EndFile)
  583.       Ch = GetChar();
  584.    if ((!InFile.EndFile) && (Ch == '*'))
  585.    {
  586.       while ((!InFile.EndFile) && (Ch != '/'))
  587.       {
  588.          while ((!InFile.EndFile) && (Ch != '*'))
  589.             Ch = GetChar();
  590.          Ch = GetChar();
  591.       }
  592.    }
  593.    else
  594.       BackCh(Ch);
  595. }
  596.  
  597. void GetCharLiteral()
  598. {
  599.    char Ch;
  600.  
  601.    do
  602.    {
  603.       Ch = GetChar();
  604.       if (Ch == '\\')
  605.       {
  606.          Ch = GetChar();
  607.          Ch = GetChar();
  608.       }
  609.    }
  610.    while ((!InFile.EndFile) && (Ch != '\''));
  611. }
  612.  
  613. int BinarySearch(T, A, Num)
  614. char *T, *A[];
  615. int Num;
  616. {
  617.    extern int stricmp();
  618.    int i, j, k, Result;
  619.  
  620.    i = 0;
  621.    j = Num;
  622.    do
  623.    {
  624.       k = (i + j) / 2;
  625.       Result = stricmp(A[k], T);
  626.       switch (Result)
  627.       {
  628.       case -1:
  629.          i = ++k;
  630.          break;
  631.       case 1:
  632.          j = --k;
  633.          break;
  634.       default:
  635.          break;
  636.       }
  637.    }
  638.    while ((Result != 0) && (i <= j));
  639.    if (Result == 0)
  640.       return (TRUE);
  641.    else
  642.       return (FALSE);
  643. }
  644.  
  645. TreeRec *BinaryTree(wl)
  646. TreeRec *wl;
  647. {
  648.    extern int stricmp();
  649.  
  650.    TreeRec *w;
  651.  
  652.    w = wl;
  653.    if (w == NULL)
  654.    {
  655.       w = (TreeRec *) malloc(sizeof(*w));
  656.       w->Ref = (WordRec *) malloc(sizeof(*(w->Ref)));
  657.       w->Left = w->Right = NULL;
  658.       wl = w;
  659.       w->Ref->Key = malloc(strlen(Token) + 1);
  660.       strcpy(w->Ref->Key, Token);
  661.       w->Ref->LineList = (LineQueueRec *) malloc(sizeof(*(w->Ref->LineList)));
  662.       w->Ref->LineList->First = NULL;
  663.       AddQueue(w->Ref->LineList);
  664.    }
  665.    else
  666.    {
  667.       switch (stricmp(Token, w->Ref->Key))
  668.       {
  669.       case -1:
  670.          w->Left = BinaryTree(w->Left);
  671.          break;
  672.       case 1:
  673.          w->Right = BinaryTree(w->Right);
  674.          break;
  675.       case 0:
  676.          AddQueue(w->Ref->LineList);
  677.          break;
  678.       }
  679.    }
  680.    return (w);
  681. }
  682.  
  683.  
  684. void AddQueue(Queue)
  685. LineQueueRec *Queue;
  686. {
  687.    LineRec *w;
  688.  
  689.    w = (LineRec *) malloc(sizeof(LineRec));
  690.    if (Queue->First == NULL)
  691.       Queue->First = w;
  692.    else
  693.       Queue->Current->Next = w;
  694.    Queue->Current = w;
  695.    w->Next = NULL;
  696.    w->Key = InFile.Lnno;
  697.    w->Code = InFile.InsertChar;
  698. }
  699.  
  700. char *FillString(Str, Size, Char)
  701. char *Str, Char;
  702. int Size;
  703. {
  704.    char Temp[255];
  705.    int l;
  706.  
  707.    strcpy(Temp, Str);
  708.    if (strlen(Temp) < Size)
  709.    {
  710.       strcat(Temp, " ");
  711.       l = strlen(Temp);
  712.       while (l < Size)
  713.          Temp[l++] = Char;
  714.       Temp[l] = 0x00;
  715.    }
  716.    return (Temp);
  717. }
  718.  
  719. void Concordance(T)
  720. TreeRec *T;
  721. {
  722.    char *FillString();
  723.  
  724.    static char OldCh = 'A';
  725.    LineRec *P;
  726.    int i;
  727.  
  728.    if (T != NULL)
  729.    {
  730.       Concordance(T->Left);
  731.       if (toupper(T->Ref->Key[0]) != OldCh)
  732.       {
  733.          fprintf(Output, "\n");
  734.          PageLn--;
  735.          if (PageLn <= 0)
  736.             Header();
  737.          OldCh = toupper(T->Ref->Key[0]);
  738.       }
  739.       fprintf(Output, "%s ", FillString(T->Ref->Key, 26, '.'));
  740.       if (!BinarySearch(T->Ref->Key, Reserved, 29))
  741.          fprintf(Output, "%c", ' ');
  742.       else
  743.          fprintf(Output, "%c", 'R');
  744.       P = T->Ref->LineList->First;
  745.       i = 0;
  746.       while (P != NULL)
  747.       {
  748.          if (i >= 17)
  749.          {
  750.             fprintf(Output, "\n");
  751.             i = 0;
  752.             PageLn--;
  753.             if (PageLn <= 0)
  754.                Header();
  755.             fprintf(Output, "%28s", " ");
  756.          }
  757.          fprintf(Output, "%4d%c", P->Key, P->Code);
  758.          i++;
  759.          if (i < 17)
  760.             fprintf(Output, "%s", " ");
  761.          P = P->Next;
  762.       }
  763.       if (i > 0)
  764.       {
  765.          fprintf(Output, "\n");
  766.          PageLn--;
  767.          if (PageLn <= 0)
  768.             Header();
  769.       }
  770.       Concordance(T->Right);
  771.    }
  772. }
  773.  
  774. void Usage()
  775. {
  776.    fprintf(stderr, "USAGE: cxref input_file_spec [output_file_spec] [options]\n\n");
  777.    fprintf(stderr, "\t-NL\tSuppress production of listing\n");
  778.    fprintf(stderr, "\t-NS\tSuppress cross reference of C key words\n");
  779.    fprintf(stderr, "\t-NI\tSuppress analysis of #include files\n\n");
  780.    fprintf(stderr, "\t-I <path> Provide path for #include <file> files\n");
  781.    fprintf(stderr, "\t-T <n>    Provide the tab stop value for tab expansion\n");
  782.    exit();
  783. }
  784.