home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 357_01 / cstar1.exe / BIGLINE.PP < prev    next >
Text File  |  1991-11-15  |  7KB  |  449 lines

  1. /*
  2.     TEST PROGRAM
  3.  
  4.     source:  bigline.pp
  5.     started: February 1, 1986
  6.     version: see below
  7.  
  8.     Copyright (C) 1985, 1986 by Edward K. Ream
  9. */
  10.  
  11. #include "pl68k.h"
  12. #define SIGNON "CPP v3: February 1, 1986"
  13.  
  14. main(argc, argv)
  15. int argc;
  16. char **argv;
  17. {
  18.     char *in, *out, *arg;
  19.  
  20.  
  21.     /* Do rest of initializing AFTER getting the arguments. */
  22.  
  23. #ifdef BUG
  24.     bug_init();        /* Do this FIRST.    */
  25.     mm_init();        /* And SECOND.        */
  26.     ops_init();        /* And THIRD.        */
  27.     sysinit(&argc, &argv);    /* And FOURTH.        */
  28.     TICK("main");
  29.     if (argc < 3) {
  30.         printf("usage: cpp in out <optional tracing names>\n");
  31.         exit();
  32.     }
  33.  
  34.     in = NULL;
  35.     out = NULL;
  36.  
  37.     /* Extra command-line arguments enable tracing. */
  38.     argv++;
  39.     while (--argc) {
  40.         arg = *argv++;
  41.         if (*arg == '+') {
  42.             printf("enabling trace of <%s>\n", arg+1);
  43.             BEGIN_TRACE(arg+1);
  44.         }
  45.         else if (*arg == '-') {
  46.             printf("disabling trace of <%s>\n", arg+1);
  47.             END_TRACE(arg+1);
  48.         }
  49.         else if (in == NULL) {
  50.             in = arg;
  51.         }
  52.         else if (out == NULL) {
  53.             out = arg;
  54.         }
  55.         else {
  56.             printf("extra argument <%s> ignored\n", arg+1);
  57.         }
  58.     }
  59.     if (in == NULL) {
  60.         printf("missing input, output file\n");
  61.         exit();
  62.     }
  63.     if (out == NULL) {
  64.         printf("missing output file name\n");
  65.         exit();
  66.     }
  67.     
  68. #else
  69.     mm_init();        /* Do this FIRST.    */
  70.     ops_init();        /* And SECOND.        */
  71.     sysinit(&argc, &argv);    /* And THIRD.        */
  72.     if (argc != 3) {
  73.         printf("usage: cpp in out\n");
  74.         exit();
  75.     }
  76.  
  77.     argv++;
  78.     in = *argv++;
  79.     out = *argv++;
  80. #endif
  81.  
  82.     /* Put out the sign on message. */
  83.     printf("%s\n", SIGNON);
  84.  
  85.     /* Initialize AFTER getting the args so we can trace. */
  86.     t_init();
  87.     mst_init();
  88.  
  89.     /* Open the input file. */
  90.     sysopen(in);
  91.     if (Z) {
  92.         printf("can not open %s\n", in);
  93.         exit();
  94.     }
  95.  
  96.     /* Open the output file. */
  97.     syscreat(out);
  98.     if (Z) {
  99.         printf("can not open %s\n", out);
  100.         exit();
  101.     }
  102.  
  103.     /* Copy the file completely. */
  104.     get_token();
  105.  
  106.     /* Close the output file. */
  107.     sysoclose();
  108.  
  109.     TRACE("bug_dump", mm_stat());
  110.     TRACE("bug_dump", bug_dump());
  111.  
  112.     sysend();
  113. }
  114.  
  115.  
  116. /*
  117.     Get ready for execution.
  118. */
  119.  
  120. t_init()
  121. {
  122.     TICK("t_init");
  123.  
  124.     BAD124;
  125.     nest_flag = TRUE;
  126.     t_iflevel  = 0;
  127.     t_errcount = 0;
  128. }
  129.  
  130.  
  131. /*
  132.     Copy the input to the output.
  133. */
  134.  
  135. get_token()
  136. {
  137.     int delim;
  138.     register struct mst_node * p;
  139.     struct mst_node * mst_lookup();
  140.  
  141.     TICK("get_token");
  142.  
  143. rescan:    switch (ch) {
  144.  
  145.     TICK("get_token1");
  146.  
  147.     case '\r':
  148.     case ' ':
  149.     case '\t':
  150.         TICK("get_token_ws");
  151.  
  152.         syscput(ch);
  153.         sysnext();
  154.         goto rescan;
  155.  
  156.     case '\n':
  157.         TICK("get_token_nl");
  158.  
  159.         sysnext();
  160.         do_nl();
  161.         begin_line(TRUE);
  162.         goto rescan;
  163.  
  164.     case '#':
  165.         sysnext();
  166.         do_pp();
  167.         goto rescan;
  168.  
  169.     case '\'':
  170.     case '"':
  171.         delim = ch;
  172.         syscput(delim);
  173.         t_string(t_symbol);
  174.         syssput(t_symbol);
  175.         syscput(delim);
  176.         goto rescan;
  177.  
  178.     case 'A': case 'B': case 'C': case 'D':
  179.     case 'E': case 'F': case 'G': case 'H':
  180.     case 'I': case 'J': case 'K': case 'L':
  181.     case 'M': case 'N': case 'O': case 'P':
  182.     case 'Q': case 'R': case 'S': case 'T':
  183.     case 'U': case 'V': case 'W': case 'X':
  184.     case 'Y': case 'Z':
  185.     case 'a': case 'b': case 'c': case 'd':
  186.     case 'e': case 'f': case 'g': case 'h':
  187.     case 'i': case 'j': case 'k': case 'l':
  188.     case 'm': case 'n': case 'o': case 'p':
  189.     case 'q': case 'r': case 's': case 't':
  190.     case 'u': case 'v': case 'w': case 'x':
  191.     case 'y': case 'z':
  192.     case '_':
  193.  
  194.     /*
  195.         The t_id() routine puts the identifier into t_symbol[].
  196.     */
  197.  
  198.         TICK("get_token_id");
  199.  
  200.         t_id(t_symbol);
  201.         p = mst_lookup(t_symbol);
  202.         if (p == NULL) {
  203.             syssput(t_symbol);
  204.         }
  205.         else {
  206.             /* Push back the replacement text. */
  207.             pp_expand(p -> mst_nargs, p -> mst_text);
  208.         }
  209.         goto rescan;
  210.  
  211.     case END_FILE:
  212.  
  213.         /* Switch input streams. */
  214.         sysiclose();
  215.         if (t_inlevel == -1) {
  216.             return;
  217.         }
  218.         else {
  219.             goto rescan;
  220.         }
  221.  
  222.     /* Ignore C style comments. */
  223.     case '/':
  224.         sysnext();
  225.         if (ch == '*') {
  226.             sysnext();
  227.             t_comment();
  228.         }
  229.         else {
  230.             syscput('/');
  231.         }
  232.         goto rescan;
  233.  
  234.     default:
  235.         syscput(ch);
  236.         sysnext();
  237.         goto rescan;
  238.     }
  239. }
  240.  
  241.  
  242. /*
  243.     Return the next token in a constant expression.
  244.     Return NULL on end of expression.
  245.     Return ERROR on mal-formed expression.
  246. */
  247.  
  248. int
  249. con_token()
  250. {
  251.     register struct mst_node * p;
  252.     struct mst_node * mst_lookup();
  253.  
  254.     TICK("con_token");
  255.  
  256.     /*
  257.         If you do not wish macros to be legal in #if statements,
  258.         just replace the following with:
  259.  
  260.             if (isid1(ch)) return ERROR;
  261.     */
  262.  
  263. rescan:
  264.     if (isid1(ch)) {
  265.         t_id(t_symbol);
  266.         p = mst_lookup(t_symbol);
  267.         if (p == NULL) {
  268.             return ID_TOK;
  269.         }
  270.         else {
  271.             pp_expand(p -> mst_nargs, p -> mst_text);
  272.             goto rescan;
  273.         }
  274.     }
  275.  
  276.     switch(ch) {
  277.  
  278.     case '\n':
  279.     case END_FILE:
  280.     case '#':
  281.  
  282.         /* Terminate the expression immediately. */
  283.         return NULL;
  284.  
  285.  
  286.     case ' ':
  287.     case '\t':
  288.     case '\r':
  289.  
  290.         /* Ignore white space except for comments. */
  291.         sysnext();
  292.         goto rescan;
  293.  
  294.  
  295.     case '\\':
  296.  
  297.         /* Allow continuation lines. */
  298.         sysnext();
  299.         if (ch == '\n') {
  300.             sysnext();
  301.             goto rescan;
  302.         }
  303.         else {
  304.             return ERROR;
  305.         }
  306.  
  307.  
  308.     case '/':
  309.  
  310.         /* Do not allow comments. */
  311.         sysnext();
  312.         return (ch == '*') ? ERROR : DIV_TOK;
  313.  
  314.  
  315.     case '0': case '1': case '2': case '3': case '4':
  316.     case '5': case '6': case '7': case '8': case '9':
  317.  
  318.         t_number();
  319.         return INT_TOK;        /* 1/10/86 */
  320.  
  321.  
  322.     case '\'':
  323.  
  324.         t_string();
  325.         t_value = char_val(t_symbol);
  326.         return CHAR_TOK;
  327.  
  328.  
  329.     case '=':    /* == */
  330.  
  331.         sysnext();
  332.         if (ch == '=') {
  333.             sysnext();
  334.             return EQUAL_TOK;
  335.         }
  336.         else {
  337.             return ERROR;
  338.         }
  339.  
  340.  
  341.     case '!':    /* != */
  342.  
  343.         sysnext();
  344.         if (ch == '=') {
  345.             sysnext();
  346.             return NE_TOK;
  347.         }
  348.         else {
  349.             return ERROR;
  350.         }
  351.  
  352.  
  353.     case '>':    /* > or >= or >> */
  354.  
  355.         sysnext();
  356.         if (ch == '>') {
  357.             sysnext();
  358.             return RSHIFT_TOK;
  359.         }
  360.         else if (ch == '=') {
  361.             sysnext();
  362.             return GE_TOK;
  363.         }
  364.         else {
  365.             return GT_TOK;
  366.         }
  367.  
  368.  
  369.     case '<':    /* < or <= or << */
  370.  
  371.         sysnext();
  372.         if (ch == '<') {
  373.             sysnext();
  374.             return LSHIFT_TOK;
  375.         }
  376.         else if (ch == '=') {
  377.             sysnext();
  378.             return LE_TOK;
  379.         }
  380.         else {
  381.             return LT_TOK;
  382.         }
  383.  
  384.  
  385.     case '+':    sysnext();    return PLUS_TOK;
  386.     case '-':    sysnext();    return MINUS_TOK;
  387.     case '*':    sysnext();    return STAR_TOK;
  388.     case '%':    sysnext();    return MOD_TOK;
  389.     case '|':    sysnext();    return OR_TOK;
  390.     case '&':    sysnext();    return AND_TOK;
  391.     case '~':    sysnext();    return TILDE_TOK;
  392.     case '?':    sysnext();    return QUESTION_TOK;
  393.     case ':':    sysnext();    return COLON_TOK;
  394.     case '^':    sysnext();    return XOR_TOK;
  395.  
  396.     default:    return ERROR;
  397.     }
  398. }
  399.  
  400.  
  401. /*
  402.     Do beginning of line processing.
  403.     In PL/68K and CPP the flag is not used, but in MACRO
  404.     the flag would be used to determine if preprocessor directives
  405.     should be processed.
  406. */
  407.  
  408. begin_line(flag)
  409. int flag;
  410. {
  411.     TICK("begin_line");
  412.     TRACE("begin_line", printf("begin_line: t_inlevel %d, ch = %x\n",
  413.         t_inlevel, ch));
  414.  
  415.     /*
  416.         At this point, ch contains the character AFTER the '\n'
  417.         so that we can look ahead to determine what the level of
  418.         the NEXT line will be.
  419.     */
  420.     if (ch == END_FILE) {
  421.         if (t_inlevel > 1) {
  422.             syscput(1);
  423.         }
  424.         return;
  425.     }
  426.     if (t_inlevel > 0  || sysinmac()==TRUE) {
  427.         syscput(1);
  428.     }
  429.     if (ch == '.') {
  430.         skip_1line();
  431.     }
  432. }
  433.  
  434.  
  435. /*
  436.     Do end of line processing.
  437. */
  438.  
  439. do_nl()
  440. {
  441.     TICK("do_nl");
  442.  
  443.     BAD442;
  444.     sysnlput();
  445.     if (sysinmac()==FALSE) {
  446.         t_line++;
  447.     }
  448. }
  449.