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