home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / src / preproc / pinit.c < prev    next >
C/C++ Source or Header  |  2002-01-18  |  32KB  |  968 lines

  1. /*
  2.  * This file contains functions used to initialize the preprocessor,
  3.  *  particularly those for establishing implementation-dependent standard
  4.  *  macro definitions.
  5.  */
  6. #include "../preproc/preproc.h"
  7. #include "../preproc/ptoken.h"
  8.  
  9. /*
  10.  * The following code is operating-system dependent [@p_init.01].
  11.  *  #includes and #defines.
  12.  */
  13.  
  14. #if PORT
  15.    /* something may be needed */
  16. Deliberate Syntax Error
  17. #endif                    /* PORT */
  18.  
  19. #if AMIGA
  20.    /* nothing is needed */
  21. #endif                    /* AMIGA */
  22.  
  23. #if MACINTOSH
  24.    /* nothing is needed */
  25. #endif                    /* MACINTOSH */
  26.  
  27. #if MSDOS
  28. #if MICROSOFT || HIGHC_386 || INTEL_386 || ZTC_386 || WATCOM
  29.    /* nothing is needed */
  30. #endif                    /* MICROSOFT || HIGHC_386 || ... */
  31. #if TURBO || BORLAND_286 || BORLAND_386
  32. #include <dir.h>
  33. #define Strng(s) #s
  34. #define StrMBody(m) Strng(m)
  35. #define CBufSz 200
  36. #endif                    /* TURBO || BORLAND_286 ... */
  37. #endif                    /* MSDOS */
  38.  
  39. #if UNIX || VMS
  40.    /* nothing is needed */
  41. #endif                    /* UNIX || VMS */
  42.  
  43. /*
  44.  * End of operating-system specific code.
  45.  */
  46.  
  47. #include "../preproc/pproto.h"
  48.  
  49. /*
  50.  * Prototypes for static functions.
  51.  */
  52. static void define_opt   (char *s, int len, struct token *dflt);
  53. static void do_directive (char *s);
  54. static void mac_opts     (char *opt_lst, char **opt_args);
  55. static void undef_opt    (char *s, int len);
  56.  
  57. struct src dummy;
  58.  
  59. /*
  60.  * init_preproc - initialize all parts of the preprocessor, establishing
  61.  *  the primary file as the current source of tokens.
  62.  */
  63. void init_preproc(fname, opt_lst, opt_args)
  64. char *fname;
  65. char *opt_lst;
  66. char **opt_args;
  67.    {
  68.  
  69.    init_str();                      /* initialize string table */
  70.    init_tok();                      /* initialize tokenizer */
  71.    init_macro();                    /* initialize macro table */
  72.    init_files(opt_lst, opt_args);   /* initialize standard header locations */
  73.    dummy.flag = DummySrc;           /* marker at bottom of source stack */
  74.    dummy.ntoks = 0;
  75.    src_stack = &dummy;
  76.    mac_opts(opt_lst, opt_args);     /* process options for predefined macros */
  77.    source(fname);                   /* establish primary source file */
  78.    }
  79.  
  80. /*
  81.  * mac_opts - handle options which affect what predefined macros are in
  82.  *  effect when preprocessing starts. Some of these options may be system
  83.  *  specific. The options may be on the command line. On some systems they
  84.  *  may also be in environment variables or configurations files. Most
  85.  *  systems will have some predefined macros which are not dependent on
  86.  *  options; establish them also.
  87.  */
  88. static void mac_opts(opt_lst, opt_args)
  89. char *opt_lst;
  90. char **opt_args;
  91.    {
  92.    int i;
  93.  
  94. /*
  95.  * The following code is operating-system dependent [@p_init.02].
  96.  *  Establish predefined macros and look for options in environment
  97.  *  variables and/or configuration files that affect predefined macros.
  98.  */
  99.  
  100. #if PORT
  101.    /* something may be needed */
  102. Deliberate Syntax Error
  103. #endif                    /* PORT */
  104.  
  105. #if AMIGA
  106.    do_directive("#define AMIGA 1\n");
  107. #if __SASC
  108.    do_directive("#define __SASC 1\n");
  109.    do_directive("#define LATTICE 0\n");
  110. #endif                                  /* __SASC */
  111. #endif                    /* AMIGA */
  112.  
  113. #if MACINTOSH
  114.    /* nothing is needed */
  115. #endif                    /* MACINTOSH */
  116.  
  117. #if MSDOS
  118. #if MICROSOFT
  119.    char *undef_model = "#undef M_I86SM\n#undef M_I86CM\n#undef M_I86MM\n"
  120.        "#undef M_I86LM\n#undef M_I86HM\n";
  121.    char *cl_var;
  122.  
  123.    do_directive("#define MSDOS 1\n");
  124.    do_directive("#define M_I86 1\n");
  125.    do_directive("#define M_I86SM 1\n");  /* small memory model */
  126.  
  127.    /*
  128.     * Process all applicable options from the CL environment variable.
  129.     */
  130.    cl_var = getenv("CL");
  131.    if (cl_var != NULL)
  132.       while (*cl_var != '\0') {
  133.          if (*cl_var == '/' || *cl_var == '-') {
  134.             ++cl_var;
  135.             switch (*cl_var) {
  136.                case 'U':
  137.                   /*
  138.                    * Undefine a specific identifier. Find the identifier
  139.                    *  by skipping white space then locating its end.
  140.                    */
  141.                   ++cl_var;
  142.                   while (*cl_var == ' ' || *cl_var == '\t')
  143.                      ++cl_var;
  144.                   i = 0;
  145.                   while (cl_var[i] != ' ' && cl_var[i] != '\t' &&
  146.                     cl_var[i] != '\0')
  147.                      ++i;
  148.                   undef_opt(cl_var, i); /* undefine the identifier */
  149.                   cl_var += i;
  150.                   break;
  151.                case 'u':
  152.                   do_directive("#undef MSDOS\n");
  153.                   do_directive("#undef M_I86\n");
  154.                   do_directive("#undef NO_EXT_KEYS\n");
  155.                   do_directive("#undef _CHAR_UNSIGED\n");
  156.                   break;
  157.                case 'D':
  158.                   /*
  159.                    * Define an identifier. If no defining string is given
  160.                    *  define it to "1".
  161.                    */
  162.                   ++cl_var;
  163.                   while (*cl_var == ' ' || *cl_var == '\t')
  164.                      ++cl_var;
  165.                   i = 0;
  166.                   while (cl_var[i] != ' ' && cl_var[i] != '\t' &&
  167.                     cl_var[i] != '\0')
  168.                      ++i;
  169.                   define_opt(cl_var, i, one_tok); /* define the identifier */
  170.                   cl_var += i;
  171.                   break;
  172.                case 'A':
  173.                   /*
  174.                    * Memory model. Define corresponding identifiers after
  175.                    *  after making sure all others are undefined.
  176.                    */
  177.                   ++cl_var;
  178.                   switch (*cl_var) {
  179.                      case 'S':
  180.                         /*
  181.                          * -AS - small memory model.
  182.                          */
  183.                         do_directive(undef_model);
  184.                         do_directive("#define M_I86SM 1\n");
  185.                         break;
  186.                      case 'C':
  187.                         /*
  188.                          * -AC - compact memory model.
  189.                          */
  190.                         do_directive(undef_model);
  191.                         do_directive("#define M_I86CM 1\n");
  192.                        break;
  193.                      case 'M':
  194.                         /*
  195.                          * -AM - medium memory model.
  196.                          */
  197.                         do_directive(undef_model);
  198.                         do_directive("#define M_I86MM 1\n");
  199.                         break;
  200.                      case 'L':
  201.                         /*
  202.                          * -AL - large memory model.
  203.                          */
  204.                         do_directive(undef_model);
  205.                         do_directive("#define M_I86LM 1\n");
  206.                         break;
  207.                      case 'H':
  208.                         /*
  209.                          * -AH - huge memory model.
  210.                          */
  211.                         do_directive(undef_model);
  212.                         do_directive("#define M_I86LM 1\n");
  213.                         do_directive("#define M_I86HM 1\n");
  214.                         break;
  215.                      }
  216.                   break;
  217.                case 'Z':
  218.                   ++cl_var;
  219.                   if (*cl_var == 'a') {
  220.                      /*
  221.                       * -Za
  222.                       */
  223.                      do_directive("#undef NO_EXT_KEYS\n");
  224.                      do_directive("#define NO_EXT_KEYS 1\n");
  225.                      }
  226.                   break;
  227.                case 'J':
  228.                    do_directive("#undef _CHAR_UNSIGED\n");
  229.                    do_directive("#define _CHAR_UNSIGNED 1\n");
  230.                    break;
  231.                }
  232.             }
  233.          if (*cl_var != '\0')
  234.             ++cl_var;
  235.          }
  236. #endif                    /* MICROSOFT */
  237.  
  238. #if ZTC_386
  239.    char *undef_model = "#undef M_I86SM\n#undef M_I86CM\n#undef M_I86MM\n"
  240.       "#undef M_I86LM\n#undef M_I86VM\n";
  241.    char *undef_model2 =
  242.       "#undef __SMALL__\n#undef __MEDIUM__\n"
  243.       "#undef __COMPACT__\n#undef __LARGE__\n#undef __VCM__\n";
  244.    char *undef_machine =
  245.       "#undef M_I8086\n#undef M_I286\n#undef M_I386\n#undef M_I486\n";
  246.    char *cl_var;
  247.    int ms_syms = 1;            /* allow Microsoft memory and machine symbols    */
  248.  
  249.    do_directive("#define __ZTC__ 0x304\n");
  250.  
  251.    do_directive("#define M_I86SM 1\n");
  252.    do_directive("#define __SMALL__ 1\n");
  253.  
  254.    do_directive("#define M_I86 1\n");
  255.    do_directive("#define M_I8086 1\n");
  256.    do_directive("#define __I86__ 0\n");
  257.  
  258.    do_directive("#define __FPCE__ 1\n");
  259.    do_directive("#define __FPCE_IEEE__ 1\n");
  260.  
  261.    /*
  262.     * Process all applicable options from the CFLAGS environment variable.
  263.     */
  264.    cl_var = getenv("CFLAGS");
  265.    if (cl_var != NULL)
  266.       while (*cl_var != '\0') {
  267.          if (*cl_var == '/' || *cl_var == '-') {
  268.             ++cl_var;
  269.             switch (*cl_var) {
  270.                case 'D':
  271.                   /*
  272.                    * Define an identifier. If no defining string is given
  273.                    *  define it to "1".
  274.                    */
  275.                   ++cl_var;
  276.                   while (*cl_var == ' ' || *cl_var == '\t')
  277.                      ++cl_var;
  278.                   i = 0;
  279.                   while (cl_var[i] != ' ' && cl_var[i] != '\t' &&
  280.                     cl_var[i] != '\0')
  281.                      ++i;
  282.                   define_opt(cl_var, i, one_tok); /* define the identifier */
  283.                   cl_var += i;
  284.                   break;
  285.              case 'W':
  286.                  do_directive("#undef _WINDOWS\n");
  287.                      do_directive("#define _WINDOWS 1\n");
  288.                      break;
  289.              case 'J':
  290.                      do_directive("#undef _CHAR_UNSIGNED\n");
  291.                  do_directive("#define _CHAR_UNSIGNED 1\n");
  292.                  break;
  293.              case 'A':
  294.                  do_directive(undef_model);
  295.                      do_directive(undef_machine);
  296.                      do_directive("#undef M_I86\n");
  297.                  do_directive("#undef __STDC__\n");
  298.                      do_directive("#define __STDC__ 1\n");
  299.                      ms_syms = 0;
  300.                      break;
  301.              case 'm':
  302.                 switch (*opt_args[i]) {
  303.                    case 'p':
  304.                    case 'x':
  305.                       do_directive("#undef DOS386\n");
  306.                       do_directive("#define DOS386 1\n");
  307.                       do_directive(undef_machine);
  308.                       do_directive("#undef __I86__\n");
  309.                       do_directive("#define __I86__ 3\n");
  310.                       if (ms_syms)
  311.                          do_directive("#define M_I386 1\n");
  312.                       /* fall through    */
  313.                    case 't':
  314.                    case 's':
  315.                       do_directive(undef_model);
  316.                       do_directive(undef_model2);
  317.                       if (ms_syms)
  318.                          do_directive("#define M_I86SM 1\n");
  319.                       do_directive("#define __SMALL__ 1\n");
  320.                       break;
  321.                    case 'c':
  322.                       do_directive(undef_model);
  323.                       do_directive(undef_model2);
  324.                       if (ms_syms)
  325.                          do_directive("#define M_I86CM 1\n");
  326.                       do_directive("#define __COMPACT__ 1\n");
  327.                       break;
  328.                    case 'm':
  329.                       do_directive(undef_model);
  330.                       do_directive(undef_model2);
  331.                       if (ms_syms)
  332.                          do_directive("#define M_I86MM 1\n");
  333.                       do_directive("#define __MEDIUM__ 1\n");
  334.                       break;
  335.                    case 'r':
  336.                    case 'z':
  337.                       do_directive("#undef DOS16RM\n");
  338.                       do_directive("#define DOS16RM 1\n");
  339.                       do_directive(undef_machine);
  340.                       do_directive("#undef __I86__\n");
  341.                       do_directive("#define __I86__ 2\n");
  342.                       if (ms_syms)
  343.                          do_directive("#define M_I286 1\n");
  344.                       /* fall through */
  345.                    case 'l':
  346.                       do_directive(undef_model);
  347.                       do_directive(undef_model2);
  348.                       if (ms_syms)
  349.                          do_directive("#define M_I86LM 1\n");
  350.                       do_directive("#define __LARGE__ 1\n");
  351.                       break;
  352.                    case 'v':
  353.                       do_directive(undef_model);
  354.                       do_directive(undef_model2);
  355.                       if (ms_syms)
  356.                          do_directive("#define M_I86VM 1\n");
  357.                       do_directive("#define __VCM__ 1\n");
  358.                       break;
  359.                    }
  360.                     break;
  361.              case '2':
  362.                  do_directive(undef_machine);
  363.                  do_directive("#undef __I86__\n");
  364.                  do_directive("#define __I86__ 2\n");
  365.                  if (ms_syms)
  366.                     do_directive("#define M_I286 1\n");
  367.                  break;
  368.              case '3':
  369.                  do_directive("#undef DOS386\n");
  370.                  do_directive("#define DOS386 1\n");
  371.                  do_directive(undef_machine);
  372.                  do_directive("#undef __I86__\n");
  373.                  do_directive("#define __I86__ 3\n");
  374.                  if (ms_syms)
  375.                     do_directive("#define M_I386 1\n");
  376.                  break;
  377.              case '4':
  378.                  do_directive("#undef DOS386\n");
  379.                  do_directive("#define DOS386 1\n");
  380.                  do_directive(undef_machine);
  381.                  do_directive("#undef __I86__\n");
  382.                  do_directive("#define __I86__ 4\n");
  383.                  if (ms_syms)
  384.                     do_directive("#define M_I486 1\n");
  385.                  /* fall through */
  386.              case 'f':
  387.                  do_directive("#define __INLINE_8087 1\n");
  388.                  break;
  389.              case 'u':
  390.                  do_directive(undef_model);
  391.                  do_directive("#undef M_I86\n");
  392.                  do_directive("#undef __ZTC__\n");
  393.                  ms_syms = 0;
  394.                  break;
  395.                }
  396.             }
  397.          if (*cl_var != '\0')
  398.             ++cl_var;
  399.          }
  400. #endif                    /* ZTC_386 */
  401.  
  402. #if TURBO || BORLAND_286 ||  BORLAND_386
  403.    char *undef_models = "#undef __TINY__\n#undef __SMALL__\n#undef __MEDIUM__\n\
  404. #undef __COMPACT__\n#undef __LARGE__\n#undef __HUGE__\n";
  405.    char dir_buf[60];
  406.    char *cfg_fname;
  407.    FILE *cfg_file;
  408.    char cbuf[CBufSz];
  409.    int c;
  410.  
  411.    do_directive("#define __MSDOS__ 1\n");
  412.    do_directive("#define __SMALL__ 1\n");
  413.    do_directive("#define __CDECL__ 1\n");
  414.    sprintf(dir_buf, "#define __TURBOC__ %s\n", StrMBody(__TURBOC__));
  415.    do_directive(dir_buf);
  416.  
  417.    /*
  418.     * Process all applicable options from the configuration file.
  419.     */
  420.    cfg_fname = searchpath("turboc.cfg");
  421.    if (cfg_fname != NULL && (cfg_file = fopen(cfg_fname, "r")) != NULL) {
  422.       c = getc(cfg_file);
  423.       while (c != EOF) {
  424.          if (c == '-') {
  425.             c = getc(cfg_file);
  426.             switch (c) {
  427.                 case 'U':
  428.                   /*
  429.                    * Undefine a specific identifier. Locate the identifier's
  430.                    *  end.
  431.                    */
  432.                    i = 0;
  433.                    c = getc(cfg_file);
  434.                    while (c != ' ' && c != '\t' && c != '\n' && c != EOF) {
  435.                       if (i >= CBufSz) {
  436.                          cbuf[CBufSz - 1] = '\0';
  437.                          err2("-U argument too big: ", cbuf);
  438.                          }
  439.                       cbuf[i++] = c;
  440.                       c = getc(cfg_file);
  441.                       }
  442.                    undef_opt(cbuf, i); /* undefine identifier */
  443.                    break;
  444.                 case 'D':
  445.                   /*
  446.                    * Define an identifier. If no defining string is given,
  447.                    *  the definition is empty.
  448.                    */
  449.                    i = 0;
  450.                    c = getc(cfg_file);
  451.                    while (c != ' ' && c != '\t' && c != '\n' && c != EOF) {
  452.                       if (i >= CBufSz) {
  453.                          cbuf[CBufSz - 1] = '\0';
  454.                          err2("-D argument too big: ", cbuf);
  455.                          }
  456.                       cbuf[i++] = c;
  457.                       c = getc(cfg_file);
  458.                       }
  459.                    define_opt(cbuf, i, NULL); /* define the identifier */
  460.                    break;
  461.                 case 'm':
  462.                    /*
  463.                     * Memory model. Define the appropriate macro after
  464.                     *  insuring that all other memory model macros are
  465.                     *  undefined.
  466.                     */
  467.                    switch (c = getc(cfg_file)) {
  468.                       case 't':
  469.                          do_directive(undef_models);
  470.                          do_directive("#define __TINY__ 1\n");
  471.                          break;
  472.                       case 's':
  473.                          do_directive(undef_models);
  474.                          do_directive("#define __SMALL__ 1\n");
  475.                          break;
  476.                       case 'm':
  477.                          do_directive(undef_models);
  478.                          do_directive("#define __MEDIUM__ 1\n");
  479.                          break;
  480.                       case 'c':
  481.                          do_directive(undef_models);
  482.                          do_directive("#define __COMPACT__ 1\n");
  483.                          break;
  484.                       case 'l':
  485.                          do_directive(undef_models);
  486.                          do_directive("#define __LARGE__ 1\n");
  487.                          break;
  488.                       case 'h':
  489.                          do_directive(undef_models);
  490.                          do_directive("#define __HUGE__ 1\n");
  491.                          break;
  492.                       }
  493.                    break;
  494.                 case 'p':
  495.                    do_directive("#undef __PASCAL__\n#undef __CDECL__\n");
  496.                    do_directive("#define __PASCAL__ 1\n");
  497.                    break;
  498.                 }
  499.              }
  500.           if (c != EOF)
  501.              c = getc(cfg_file);
  502.           }
  503.        fclose(cfg_file);
  504.        }
  505. #endif                    /* TURBO || BORLAND_286 ... */
  506.  
  507. #if HIGHC_386 || INTEL_386 || WATCOM
  508.    /* something may be needed */
  509. #endif                    /* HIGHC_386 || INTEL_386 || ... */
  510. #endif                    /* MSDOS */
  511.  
  512. #if UNIX
  513.    do_directive("#define unix 1\n");
  514.    do_directive(PPInit);   /* defines that vary between Unix systems */
  515. #endif                    /* UNIX */
  516.  
  517. #if VMS
  518.    /* nothing is needed */
  519. #endif                    /* VMS */
  520.  
  521. /*
  522.  * End of operating-system specific code.
  523.  */
  524.  
  525.    /*
  526.     * look for options that affect macro definitions (-U, -D, etc).
  527.     */
  528.    for (i = 0; opt_lst[i] != '\0'; ++i)
  529.       switch(opt_lst[i]) {
  530.          case 'U':
  531.             /*
  532.              * Undefine and predefined identifier.
  533.              */
  534.             undef_opt(opt_args[i], (int)strlen(opt_args[i]));
  535.             break;
  536.  
  537.          case 'D':
  538.             /*
  539.              * Define an identifier. Use "1" if no defining string is given.
  540.              */
  541.             define_opt(opt_args[i], (int)strlen(opt_args[i]), one_tok);
  542.             break;
  543.  
  544. /*
  545.  * The following code is operating-system dependent [@p_init.03]. Check for
  546.  *  system specific options from command line.
  547.  */
  548.  
  549. #if PORT
  550.    /* something may be needed */
  551. Deliberate Syntax Error
  552. #endif                    /* PORT */
  553.  
  554. #if AMIGA
  555.    /* nothing is needed */
  556. #endif                    /* AMIGA */
  557.  
  558. #if MACINTOSH
  559.    /* nothing is needed */
  560. #endif                    /* MACINTOSH */
  561.  
  562. #if MSDOS
  563. #if MICROSOFT
  564.          case 'A':
  565.             /*
  566.              * Memory model. Define corresponding identifiers after
  567.              *  after making sure all others are undefined.
  568.              */
  569.             switch (*opt_args[i]) {
  570.                case 'S':
  571.                   /*
  572.                    * -AS - small memory model.
  573.                    */
  574.                   do_directive(undef_model);
  575.                   do_directive("#define M_I86SM 1\n");
  576.                   break;
  577.                case 'C':
  578.                   /*
  579.                    * -AC - compact memory model.
  580.                    */
  581.                   do_directive(undef_model);
  582.                   do_directive("#define M_I86CM 1\n");
  583.                   break;
  584.                case 'M':
  585.                   /*
  586.                    * -AM - medium memory model.
  587.                    */
  588.                   do_directive(undef_model);
  589.                   do_directive("#define M_I86MM 1\n");
  590.                   break;
  591.                case 'L':
  592.                   /*
  593.                    * -AL - large memory model.
  594.                    */
  595.                   do_directive(undef_model);
  596.                   do_directive("#define M_I86LM 1\n");
  597.                   break;
  598.                case 'H':
  599.                   /*
  600.                    * -AH - huge memory model.
  601.                    */
  602.                   do_directive(undef_model);
  603.                   do_directive("#define M_I86LM 1\n");
  604.                   do_directive("#define M_I86HM 1\n");
  605.                   break;
  606.                default:
  607.                   fprintf(stderr, "invalid argument to -A option: %s\n",
  608.                      opt_args[i]);
  609.                   show_usage();
  610.                }
  611.             break;
  612.          case 'Z':
  613.             if (*opt_args[i] == 'a') {
  614.                do_directive("#undef NO_EXT_KEYS\n");
  615.                do_directive("#define NO_EXT_KEYS 1\n");
  616.                }
  617.             else {
  618.                fprintf(stderr, "invalid argument to -Z option: %s\n",
  619.                   opt_args[i]);
  620.                show_usage();
  621.             }
  622.             break;
  623.          case 'J':
  624.              do_directive("#undef _CHAR_UNSIGED\n");
  625.              do_directive("#define _CHAR_UNSIGNED 1\n");
  626.              break;
  627. #endif                    /* MICROSOFT */
  628.  
  629. #if ZTC_386
  630.          case 'W':
  631.              do_directive("#undef _WINDOWS\n");
  632.              do_directive("#define _WINDOWS 1\n");
  633.              break;
  634.          case 'J':
  635.              do_directive("#undef _CHAR_UNSIGNED\n");
  636.              do_directive("#define _CHAR_UNSIGNED 1\n");
  637.              break;
  638.          case 'A':
  639.              do_directive(undef_model);
  640.              do_directive(undef_machine);
  641.              do_directive("#undef M_I86\n");
  642.              do_directive("#undef __STDC__\n");
  643.              do_directive("#define __STDC__ 1\n");
  644.              ms_syms = 0;
  645.              break;
  646.          case 'm':
  647.             switch (*opt_args[i]) {
  648.                case 'p':
  649.                case 'x':
  650.                   do_directive("#undef DOS386\n");
  651.                   do_directive("#define DOS386 1\n");
  652.                   do_directive(undef_machine);
  653.                   do_directive("#undef __I86__\n");
  654.                   do_directive("#define __I86__ 3\n");
  655.                   if (ms_syms)
  656.                      do_directive("#define M_I386 1\n");
  657.                   /* fall through */
  658.                case 't':
  659.                case 's':
  660.                   do_directive(undef_model);
  661.                   do_directive(undef_model2);
  662.                   if (ms_syms)
  663.                      do_directive("#define M_I86SM 1\n");
  664.                   do_directive("#define __SMALL__ 1\n");
  665.                   break;
  666.                case 'c':
  667.                   do_directive(undef_model);
  668.                   do_directive(undef_model2);
  669.                   if (ms_syms)
  670.                      do_directive("#define M_I86CM 1\n");
  671.                   do_directive("#define __COMPACT__ 1\n");
  672.                   break;
  673.                case 'm':
  674.                   do_directive(undef_model);
  675.                   do_directive(undef_model2);
  676.                   if (ms_syms)
  677.                      do_directive("#define M_I86MM 1\n");
  678.                   do_directive("#define __MEDIUM__ 1\n");
  679.                   break;
  680.                case 'r':
  681.                case 'z':
  682.                   do_directive("#undef DOS16RM\n");
  683.                   do_directive("#define DOS16RM 1\n");
  684.                   do_directive(undef_machine);
  685.                   do_directive("#undef __I86__\n");
  686.                   do_directive("#define __I86__ 2\n");
  687.                   if (ms_syms)
  688.                      do_directive("#define M_I286 1\n");
  689.                   /* fall through */
  690.                case 'l':
  691.                   do_directive(undef_model);
  692.                   do_directive(undef_model2);
  693.                   if (ms_syms)
  694.                      do_directive("#define M_I86LM 1\n");
  695.                   do_directive("#define __LARGE__ 1\n");
  696.                   break;
  697.                case 'v':
  698.                   do_directive(undef_model);
  699.                   do_directive(undef_model2);
  700.                   if (ms_syms)
  701.                      do_directive("#define M_I86VM 1\n");
  702.                   do_directive("#define __VCM__ 1\n");
  703.                   break;
  704.                }
  705.             break;
  706.          case '2':
  707.              do_directive(undef_machine);
  708.              do_directive("#undef __I86__\n");
  709.              do_directive("#define __I86__ 2\n");
  710.              if (ms_syms)
  711.                 do_directive("#define M_I286 1\n");
  712.              break;
  713.          case '3':
  714.              do_directive("#undef DOS386\n");
  715.              do_directive("#define DOS386 1\n");
  716.              do_directive(undef_machine);
  717.              do_directive("#undef __I86__\n");
  718.              do_directive("#define __I86__ 3\n");
  719.              if (ms_syms)
  720.                 do_directive("#define M_I386 1\n");
  721.              break;
  722.          case '4':
  723.              do_directive("#undef DOS386\n");
  724.              do_directive("#define DOS386 1\n");
  725.              do_directive(undef_machine);
  726.              do_directive("#undef __I86__\n");
  727.              do_directive("#define __I86__ 4\n");
  728.              if (ms_syms)
  729.                 do_directive("#define M_I486 1\n");
  730.              /* fall through */
  731.          case 'f':
  732.              do_directive("#define __INLINE_8087 1\n");
  733.              break;
  734.          case 'u':
  735.              do_directive(undef_model);
  736.              do_directive(undef_machine);
  737.              do_directive("#undef M_I86\n");
  738.              do_directive("#undef __ZTC__\n");
  739.              ms_syms = 0;
  740.              break;
  741. #endif                    /* ZTC_386 */
  742.  
  743. #if TURBO || BORLAND_286 || BORLAND_386
  744.          case 'm':
  745.             /*
  746.              * Memory model. Define the appropriate macro after
  747.              *  insuring that all other memory model macros are
  748.              *  undefined.
  749.              */
  750.             switch (*opt_args[i]) {
  751.                case 't':
  752.                   do_directive(undef_models);
  753.                   do_directive("#define __TINY__ 1\n");
  754.                   break;
  755.                case 's':
  756.                   do_directive(undef_models);
  757.                   do_directive("#define __SMALL__ 1\n");
  758.                   break;
  759.                case 'm':
  760.                   do_directive(undef_models);
  761.                   do_directive("#define __MEDIUM__ 1\n");
  762.                   break;
  763.                case 'c':
  764.                   do_directive(undef_models);
  765.                   do_directive("#define __COMPACT__ 1\n");
  766.                   break;
  767.                case 'l':
  768.                   do_directive(undef_models);
  769.                   do_directive("#define __LARGE__ 1\n");
  770.                   break;
  771.                case 'h':
  772.                   do_directive(undef_models);
  773.                   do_directive("#define __HUGE__ 1\n");
  774.                   break;
  775.                default:
  776.                   fprintf(stderr, "invalid argument to -m option: %s\n",
  777.                      opt_args[i]);
  778.                   show_usage();
  779.                }
  780.             break;
  781.          case 'p':
  782.             do_directive("#undef __PASCAL__\n#undef __CDECL__\n");
  783.             do_directive("#define __PASCAL__ 1\n");
  784.             break;
  785. #endif                    /* TURBO || BORLAND_286 ... */
  786.  
  787. #if HIGHC_386 || INTEL_386
  788.    /* something may be needed */
  789. #endif                    /* HIGHC_386 || INTEL_386 || ZTC_386 */
  790. #endif                    /* MSDOS */
  791.  
  792. #if UNIX || VMS
  793.    /* nothing is needed */
  794. #endif                    /* UNIX || VMS */
  795.  
  796. /*
  797.  * End of operating-system specific code.
  798.  */
  799.          }
  800.    }
  801.  
  802. /*
  803.  * str_src - establish a string, given by a character pointer and a length,
  804.  *  as the current source of tokens.
  805.  */
  806. void str_src(src_name, s, len)
  807. char *src_name;
  808. char *s;
  809. int len;
  810.    {
  811.    union src_ref ref;
  812.    int *ip1, *ip2;
  813.  
  814.    /*
  815.     * Create a character source with a large enought buffer for the string.
  816.     */
  817.    ref.cs = new_cs(src_name, NULL, len + 1);
  818.    push_src(CharSrc, &ref);
  819.    ip1 = ref.cs->char_buf;
  820.    ip2 = ref.cs->line_buf;
  821.    while (len-- > 0) {
  822.      *ip1++ = *s++;    /* copy string to source buffer */
  823.      *ip2++ = 0;       /* characters are from "line 0" */
  824.      }
  825.    *ip1 = EOF;
  826.    *ip2 = 0;
  827.    ref.cs->next_char = ref.cs->char_buf;
  828.    ref.cs->last_char = ip1;
  829.    first_char = ref.cs->char_buf;
  830.    next_char = first_char;
  831.    last_char = ref.cs->last_char;
  832.    }
  833.  
  834. /*
  835.  * do_directive - take a character string containing preprocessor
  836.  *  directives separated by new-lines and execute them. This done
  837.  *  by preprocessing the string.
  838.  */
  839. static void do_directive(s)
  840. char *s;
  841.    {
  842.    str_src("<initialization>", s, (int)strlen(s));
  843.    while (interp_dir() != NULL)
  844.       ;
  845.    }
  846.  
  847. /*
  848.  * undef_opt - take the argument to a -U option and, if it is valid,
  849.  *  undefine it.
  850.  */
  851. static void undef_opt(s, len)
  852. char *s;
  853. int len;
  854.    {
  855.    struct token *mname;
  856.    int i;
  857.  
  858.    /*
  859.     * The name is needed in the form of a token. Use the preprocessor
  860.     *  to tokenize it.
  861.     */
  862.    str_src("<options>", s, len);
  863.    mname = next_tok();
  864.    if (mname == NULL || mname->tok_id != Identifier ||
  865.      next_tok() != NULL) {
  866.       fprintf(stderr, "invalid argument to -U option: ");
  867.       for (i = 0; i < len; ++i)
  868.          putc(s[i], stderr);    /* show offending argument */
  869.       putc('\n', stderr);
  870.       show_usage();
  871.       }
  872.    m_delete(mname);
  873.    }
  874.  
  875. /*
  876.  * define_opt - take an argument to a -D option and, if it is valid, perform
  877.  *  the requested definition.
  878.  */
  879. static void define_opt(s, len, dflt)
  880. char *s;
  881. int len;
  882. struct token *dflt;
  883.    {
  884.    struct token *mname;
  885.    struct token *t;
  886.    struct tok_lst *body;
  887.    struct tok_lst **ptlst, **trail_whsp;
  888.    int i;
  889.  
  890.    /*
  891.     * The argument to -D must be tokenized.
  892.     */
  893.    str_src("<options>", s, len);
  894.  
  895.    /*
  896.     * Find the macro name.
  897.     */
  898.    mname = next_tok();
  899.    if (mname == NULL || mname->tok_id != Identifier) {
  900.       fprintf(stderr, "invalid argument to -D option: ");
  901.       for (i = 0; i < len; ++i)
  902.          putc(s[i], stderr);
  903.       putc('\n', stderr);
  904.       show_usage();
  905.       }
  906.  
  907.    /*
  908.     * Determine if the name is followed by '='.
  909.     */
  910.    if (chk_eq_sign()) {
  911.       /*
  912.        * Macro body is given, strip leading white space
  913.        */
  914.       t = next_tok();
  915.       if (t != NULL && t->tok_id == WhiteSpace) {
  916.          free_t(t);
  917.          t = next_tok();
  918.          }
  919.  
  920.  
  921.       /*
  922.        * Construct the token list for body of macro. Keep track of trailing
  923.        *  white space so it can be deleted.
  924.        */
  925.       body = NULL;
  926.       ptlst = &body;
  927.       trail_whsp = NULL;
  928.       while (t != NULL) {
  929.          t->flag &= ~LineChk;
  930.          (*ptlst) = new_t_lst(t);
  931.          if (t->tok_id == WhiteSpace)
  932.             trail_whsp = ptlst;
  933.          else
  934.             trail_whsp = NULL;
  935.          ptlst = &(*ptlst)->next;
  936.          t = next_tok();
  937.          }
  938.  
  939.       /*
  940.        * strip trailing white space
  941.        */
  942.       if (trail_whsp != NULL) {
  943.          free_t_lst(*trail_whsp);
  944.          *trail_whsp = NULL;
  945.          }
  946.       }
  947.    else {
  948.       /*
  949.        * There is no '=' after the macro name; use the supplied
  950.        *  default value for the macro definition.
  951.        */
  952.       if (next_tok() == NULL)
  953.          if (dflt == NULL)
  954.             body = NULL;
  955.          else
  956.             body = new_t_lst(copy_t(dflt));
  957.       else {
  958.          fprintf(stderr, "invalid argument to -D option: ");
  959.          for (i = 0; i < len; ++i)
  960.             putc(s[i], stderr);
  961.          putc('\n', stderr);
  962.          show_usage();
  963.          }
  964.       }
  965.  
  966.    m_install(mname, NoArgs, 0, NULL, body); /* install macro definition */
  967.    }
  968.