home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 243_01 / cpp3.c < prev    next >
C/C++ Source or Header  |  1990-05-14  |  22KB  |  666 lines

  1. /*
  2. **    name:        cpp3.c
  3. */
  4.  
  5. /*
  6.  *                              C P P 3 . C
  7.  *
  8.  *                  File open and command line options
  9.  *
  10.  * Edit history
  11.  * 13-Nov-84    MM      Split from cpp1.c
  12.  * 29-Apr-85    MM      Make -N work again.
  13.  * 03-Oct-85    CG      Change default loc. of <files> for P/OS.
  14.  * 08-Nov-85    ado     Prevent wierd -D arguments
  15.  * 24-Jun-88    BM    taught cpp about multiple include directoried in
  16.  *                      INCLUDE environment variable (Blake McBride)
  17.  * 15-Dec-88    RA      Duplicated logic above for the included directories
  18.  *                      in the DPATH environment variable for OS/2 E 1.1
  19.  *                      (Roberto Artigas Jr) since the headers from the
  20.  *            data base manager and communications manager are
  21.  *            picked up from their own specific directories.
  22.  */
  23.  
  24. #include        "cppdef.h"
  25. #include        "cpp.h"
  26.  
  27. FILE_LOCAL void    unpredefine();
  28.  
  29.  
  30.  
  31. #if DEBUG && (HOST == SYS_VMS || HOST == SYS_UNIX)
  32. #include        <signal.h>
  33. extern int      abort();                /* For debugging                */
  34. #endif
  35.  
  36. int
  37. openfile(filename)
  38. char            *filename;
  39. /*
  40.  * Open a file, add it to the linked list of open files.
  41.  * This is called only from openfile() above.
  42.  */
  43. {
  44.         register FILE           *fp;
  45.  
  46.         if ((fp = fopen(filename, "r")) == NULL) {
  47. #if DEBUG
  48.             perror(filename);
  49. #endif
  50.             return (FALSE);
  51.         }
  52. #if DEBUG
  53.         if (debug)
  54.             fprintf(stderr, "Reading from \"%s\"\n", filename);
  55. #endif
  56.         addfile(fp, filename);
  57.         return (TRUE);
  58. }
  59.  
  60. void
  61. addfile(fp, filename)
  62. FILE            *fp;                    /* Open file pointer            */
  63. char            *filename;              /* Name of the file             */
  64. /*
  65.  * Initialize tables for this open file.  This is called from openfile()
  66.  * above (for #include files), and from the entry to cpp to open the main
  67.  * input file.  It calls a common routine, getfile() to build the FILEINFO
  68.  * structure which is used to read characters.  (getfile() is also called
  69.  * to setup a macro replacement.)
  70.  */
  71. {
  72.         register FILEINFO       *file;
  73.         extern FILEINFO         *getfile();
  74.  
  75.         file = getfile(NBUFF, filename);
  76.         file->fp = fp;                  /* Better remember FILE *       */
  77.         file->buffer[0] = EOS;          /* Initialize for first read    */
  78.         line = 1;                       /* Working on line 1 now        */
  79.         wrongline = TRUE;               /* Force out initial #line      */
  80. }
  81.  
  82.  
  83. void
  84. setincdirs()
  85. /*
  86.  * Append system-specific directories to the include directory list.
  87.  * Called only when cpp is started.
  88.  */
  89. {
  90.  
  91. #ifdef  CPP_INCLUDE
  92.         *incend++ = CPP_INCLUDE;
  93. #define IS_INCLUDE      1
  94. #else
  95. #define IS_INCLUDE      0
  96. #endif
  97.  
  98. #if HOST == SYS_UNIX
  99.         *incend++ = "/usr/include";
  100. #define MAXINCLUDE      (NINCLUDE - 1 - IS_INCLUDE)
  101. #endif
  102.  
  103. #if HOST == SYS_VMS
  104.         extern char     *getenv();
  105.  
  106.         if (getenv("C$LIBRARY") != NULL)
  107.             *incend++ = "C$LIBRARY:";
  108.         *incend++ = "SYS$LIBRARY:";
  109. #define MAXINCLUDE      (NINCLUDE - 2 - IS_INCLUDE)
  110. #endif
  111.  
  112. #if HOST == SYS_RSX
  113.         extern int      $$rsts;                 /* TRUE on RSTS/E       */
  114.         extern int      $$pos;                  /* TRUE on PRO-350 P/OS */
  115.         extern int      $$vms;                  /* TRUE on VMS compat.  */
  116.  
  117.         if ($$pos) {                            /* P/OS?                */
  118.             *incend++ = "LB:[ZZDECUSC]";        /* C #includes          */
  119.             *incend++ = "LB:[1,5]";             /* RSX library          */
  120.         }
  121.         else if ($$rsts) {                      /* RSTS/E?              */
  122.             *incend++ = "SY:@";                 /* User-defined account */
  123.             *incend++ = "C:";                   /* Decus-C library      */
  124.             *incend++ = "LB:[1,1]";             /* RSX library          */
  125.         }
  126.         else if ($$vms) {                       /* VMS compatibility?   */
  127.             *incend++ = "C:";
  128.         }
  129.         else {                                  /* Plain old RSX/IAS    */
  130.             *incend++ = "LB:[1,1]";
  131.         }
  132. #define MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
  133. #endif
  134.  
  135. #if HOST == SYS_RT11
  136.         extern int      $$rsts;                 /* RSTS/E emulation?    */
  137.  
  138.         if ($$rsts)
  139.             *incend++ = "SY:@";                 /* User-defined account */
  140.         *incend++ = "C:";                       /* Decus-C library disk */
  141.         *incend++ = "SY:";                      /* System (boot) disk   */
  142. #define MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
  143. #endif
  144.  
  145. #if HOST == SYS_MSDOS
  146. {
  147.     char incdir[ 100 ];
  148.     char *getenv(), *strsave();
  149.     char *foo;
  150.  
  151.     foo = getenv( "INCLUDE" );
  152.     if ( foo == NULL )
  153.     *incend++ = "\\include\\";
  154.     else {
  155.     while (*foo)  {
  156.         char    *p = incdir;
  157.         while (*foo && *foo != ';' && *foo != ' ' && p-incdir < 98)
  158.             *p++ = *foo++;
  159.         if (p != incdir)  {
  160.             if (*(p-1) != '\\'  &&  *(p-1) != '/')
  161.                 *p++ = '\\';
  162.             *p = '\0';
  163.             *incend++ = strsave(incdir);
  164.         }
  165.         while (*foo && (*foo == ';' || *foo == ' '))
  166.             ++foo;
  167.     }
  168.     } /* End if */
  169.  
  170.     foo = getenv( "DPATH" );
  171.     if ( foo != NULL ) {
  172.     while (*foo)  {
  173.         char    *p = incdir;
  174.         while (*foo && *foo != ';' && *foo != ' ' && p-incdir < 98)
  175.             *p++ = *foo++;
  176.         if (p != incdir)  {
  177.             if (*(p-1) != '\\'  &&  *(p-1) != '/')
  178.                 *p++ = '\\';
  179.             *p = '\0';
  180.             *incend++ = strsave(incdir);
  181.         }
  182.         while (*foo && (*foo == ';' || *foo == ' '))
  183.             ++foo;
  184.     }
  185.     } /* End if */
  186. } /* End hack */
  187. #define    MAXINCLUDE    (NINCLUDE - 1 - IS_INCLUDE)
  188. #endif
  189. }
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. int
  202. dooptions(argc, argv)
  203. int             argc;
  204. char            *argv[];
  205. /*
  206.  * dooptions is called to process command line arguments (-Detc).
  207.  * It is called only at cpp startup.
  208.  */
  209. {
  210.         register char           *ap;
  211.         register DEFBUF         *dp;
  212.         register int            c;
  213.         int                     i, j;
  214.         char                    *arg;
  215.         SIZES                   *sizp;          /* For -S               */
  216.         int                     size;           /* For -S               */
  217.         int                     isdatum;        /* FALSE for -S*        */
  218.         int                     endtest;        /* For -S               */
  219.         char                    *cp;            /* For -D arg test      */
  220.  
  221.         for (i = j = 1; i < argc; i++) {
  222.             arg = ap = argv[i];
  223.             if (*ap++ != '-' || *ap == EOS)
  224.                 argv[j++] = argv[i];
  225.             else {
  226.                 c = *ap++;                      /* Option byte          */
  227.                 if (islower(c))                 /* Normalize case       */
  228.                     c = toupper(c);
  229.                 switch (c) {                    /* Command character    */
  230.                 case 'C':                       /* Keep comments        */
  231.                     cflag = TRUE;
  232.                     keepcomments = TRUE;
  233.                     break;
  234.  
  235.                 case 'D':                       /* Define symbol        */
  236.                     /*
  237.                      * Check for incorrect argument -- don't allow
  238.                      * -Dfoo(bar)=something
  239.                      */
  240.                     if (type[*ap] != LET)
  241.                         cfatal("Argument needed for -D in \"%s\"", arg);
  242.                     for (cp = ap; *cp != EOS && *cp != '='; cp++) {
  243.                         if (type[*cp] != LET && type[*cp] != DIG)
  244.                             cfatal("Incorrect argument for -D in \"%s\"", arg);
  245.                     }
  246. #if HOST != SYS_UNIX         && HOST != SYS_MSDOS
  247.                     zap_uc(ap);                 /* Force define to U.C. */
  248. #endif
  249. #if OK_TRIGRAPH
  250.                     if (tflag)
  251.                         trigraph(ap);
  252. #endif
  253.                     /*
  254.                      * If the option is just "-Dfoo", make it -Dfoo=1
  255.                      */
  256.                     while (*ap != EOS && *ap != '=')
  257.                         ap++;
  258.