home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / CMTEX330 / SOURCE / COND.C < prev    next >
C/C++ Source or Header  |  1992-02-19  |  6KB  |  366 lines

  1.  
  2. /*
  3.  * %Y%:%M%:%I%:%Q%
  4.  *
  5.  * Copyright 1987,1988,1991,1992 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  *
  11.  */
  12.  
  13. #ifndef lint
  14. static char *sccsid = "%A%";
  15. #endif
  16.  
  17. #include "tex.h"
  18.  
  19. ptr    cond_ptr;
  20.  
  21. int    cur_if;
  22. int    if_limit;
  23. int    if_line;
  24. int    skip_line;
  25.  
  26. void
  27. conditional ()
  28. {
  29.     bool    b;
  30.     sym    s;
  31.     int    m, n;
  32.     ptr    p, q, r;
  33.     int    this_if;
  34.     ptr    save_cond_ptr;
  35.     int    save_scanner_status;
  36.  
  37.     static void get_x_token_or_active_char();
  38.  
  39.     push_cond();
  40.     save_cond_ptr = cond_ptr;
  41.     this_if = cur_chr;
  42.     switch (this_if)
  43.     {
  44.     case IF_CHAR_CODE:
  45.     case IF_CAT_CODE:
  46.         get_x_token_or_active_char();
  47.         if (cur_cmd > ACTIVE_CHAR || cur_chr > 255) {
  48.             m = RELAX;
  49.             n = 256;
  50.         } else {
  51.             m = cur_cmd;
  52.             n = cur_chr;
  53.         }
  54.         get_x_token_or_active_char();
  55.         if (cur_cmd > ACTIVE_CHAR || cur_chr > 255) {
  56.             cur_cmd = RELAX;
  57.             cur_chr = 256;
  58.         }
  59.         if (this_if == IF_CHAR_CODE) {
  60.             b = n == cur_chr;
  61.         } else {
  62.             b = m == cur_cmd;
  63.         }
  64.         break;
  65.  
  66.     case IF_INT_CODE:
  67.     case IF_DIM_CODE:
  68.         if (this_if == IF_INT_CODE) {
  69.             scan_int();
  70.         } else {
  71.             scan_normal_dimen();
  72.         }
  73.         n = cur_val;
  74.         get_nbx_token(); 
  75.         if (cur_tok >= OTHER_TOKEN + '<'
  76.         && cur_tok <= OTHER_TOKEN + '>') {
  77.             r = cur_tok - OTHER_TOKEN;
  78.         } else {
  79.             print_err("Missing = inserted for ");
  80.             print_cmd_chr(IF_TEST, this_if);
  81.             help_relation();
  82.             back_error();
  83.             r = '=';
  84.         }
  85.         if (this_if == IF_INT_CODE) {
  86.             scan_int();
  87.         } else {
  88.             scan_normal_dimen();
  89.         }
  90.         switch (r) {
  91.         case '<': b = n < cur_val; break;
  92.         case '=': b = n == cur_val; break; 
  93.         case '>': b = n > cur_val; break;
  94.         }
  95.         break;
  96.     
  97.     case IF_ODD_CODE:
  98.         scan_int();
  99.         b = odd(cur_val);
  100.         break;
  101.     
  102.     case IF_VMODE_CODE:
  103.         b = abs(mode) == VMODE;
  104.         break;
  105.  
  106.     case IF_HMODE_CODE:
  107.         b = abs(mode) == HMODE;
  108.         break;
  109.  
  110.     case IF_MMODE_CODE:
  111.         b = abs(mode) == MMODE;
  112.         break;
  113.     
  114.     case IF_INNER_CODE:
  115.         b = mode < 0;
  116.         break;
  117.     
  118.     case IF_VOID_CODE:
  119.     case IF_HBOX_CODE:
  120.     case IF_VBOX_CODE:
  121.         scan_eight_bit_int();
  122.         p = box(cur_val);
  123.         if (this_if == IF_VOID_CODE) {
  124.             b = p == null;
  125.         } else if (p == null) {
  126.             b = FALSE;
  127.         } else if (this_if == IF_HBOX_CODE) {
  128.             b = type(p) == HLIST_NODE;
  129.         } else {
  130.             b = type(p) == VLIST_NODE;
  131.         }
  132.         break;
  133.  
  134.     case IFX_CODE:
  135.         save_scanner_status = scanner_status;
  136.         scanner_status = NORMAL;
  137.         get_next();
  138.         s = cur_cs;
  139.         p = cur_cmd;
  140.         q = cur_chr;
  141.         get_next(); 
  142.         if (cur_cmd != p) {
  143.             b = FALSE;
  144.         } else if (cur_cmd < CALL) {
  145.             b = cur_chr == q;
  146.         } else {
  147.             p = token_link(cur_chr);
  148.             q = token_link(equiv(s));
  149.             if (p == q) {
  150.                 b = TRUE;
  151.             } else {
  152.                 while (p != null && q != null) {
  153.                     if (token(p) != token(q)) {
  154.                         p = null;
  155.                     } else {
  156.                         p = token_link(p);
  157.                         q = token_link(q);
  158.                     }
  159.                 }
  160.                 b = (p == null) && (q == null);
  161.             }
  162.         }
  163.         scanner_status = save_scanner_status;
  164.         break;
  165.  
  166.     case IF_EOF_CODE:
  167.         scan_four_bit_int();
  168.         b = read_open[cur_val] == CLOSED;
  169.         break;
  170.     
  171.     case IF_TRUE_CODE:
  172.         b = TRUE;
  173.         break;
  174.  
  175.     case IF_FALSE_CODE:
  176.         b = FALSE;
  177.         break;
  178.  
  179.     case IF_CASE_CODE: 
  180.         scan_int();
  181.         n = cur_val;
  182.         if (tracing_commands > 1) {
  183.             begin_diagnostic();
  184.             print("{case ");
  185.             print_int(n);
  186.             print("}");
  187.             end_diagnostic(FALSE);
  188.         }
  189.         while (n != 0) {
  190.             pass_text();
  191.             if (cond_ptr == save_cond_ptr) {
  192.                 if (cur_chr == OR_CODE) {
  193.                     decr(n);
  194.                 } else {
  195.                     goto common_end;
  196.                 }
  197.             } else if (cur_chr == FI_CODE) {
  198.                 pop_cond();
  199.             }
  200.         }
  201.         change_if_limit(OR_CODE, save_cond_ptr);
  202.         return;
  203.     
  204.     default:
  205.         break;
  206.     }
  207.  
  208.     if (tracing_commands > 1) {
  209.         begin_diagnostic();
  210.         print(b ? "{true}" : "{false}");
  211.         end_diagnostic(FALSE);
  212.     }
  213.  
  214.     if (b) {
  215.         change_if_limit(ELSE_CODE, save_cond_ptr);
  216.         return;
  217.     }
  218.  
  219.     loop {
  220.         pass_text(); 
  221.         if (cond_ptr == save_cond_ptr) {
  222.             if (cur_chr != OR_CODE) {
  223.                 goto common_end;
  224.             }
  225.             print_err("Extra ");
  226.             print_esc("or");
  227.             help_or();
  228.             error();
  229.         } else if (cur_chr == FI_CODE) {
  230.             pop_cond();
  231.         }
  232.     }
  233.  
  234. common_end:
  235.     if (cur_chr == FI_CODE) {
  236.         pop_cond();
  237.     } else {
  238.         if_limit = FI_CODE;
  239.     }
  240. }
  241.  
  242. static void
  243. get_x_token_or_active_char()
  244. {
  245.     get_x_token();
  246.     if (cur_cmd == RELAX && cur_chr == NO_EXPAND_FLAG) {
  247.         cur_cmd = ACTIVE_CHAR;
  248.         if (is_sym(cur_tok)) {
  249.             if (isactive(tok2sym(cur_tok))) {
  250.                 cur_chr = tok2sym(cur_tok) - active_base[0];
  251.             } else if (issingle(tok2sym(cur_tok))) {
  252.                 cur_chr = tok2sym(cur_tok) - single_base[0];
  253.             } else {
  254.                 cur_chr = 256;
  255.             }
  256.         }
  257.     }
  258. }
  259.  
  260. void
  261. push_cond ()
  262. {
  263.     ptr    p;
  264.  
  265.     p = new_node(IF_NODE_SIZE);
  266.     link(p) = cond_ptr;
  267.     type(p) = if_limit;
  268.     subtype(p) = cur_if;
  269.     if_line_field(p) = if_line;
  270.     cond_ptr = p;
  271.     cur_if = cur_chr;
  272.     if_limit = IF_CODE;
  273.     if_line = line;
  274. }
  275.  
  276. void
  277. pop_cond ()
  278. {
  279.     ptr    p;
  280.  
  281.     p = cond_ptr;
  282.     if_line = if_line_field(p);
  283.     cur_if = subtype(p);
  284.     if_limit = type(p);
  285.     cond_ptr = link(p);
  286.     free_node(p, IF_NODE_SIZE);
  287. }
  288.  
  289. void
  290. pass_text ()
  291. {
  292.     int    l;
  293.     int    save_scanner_status;
  294.  
  295.     l = 0;
  296.     save_scanner_status = scanner_status;
  297.     scanner_status = SKIPPING;
  298.     skip_line = line;
  299.     loop {
  300.         get_next();
  301.         if (cur_cmd == FI_OR_ELSE) {
  302.             if (l == 0) {
  303.                 break;
  304.             }
  305.             if (cur_chr == FI_CODE) {
  306.                 decr(l);
  307.             }
  308.         } else if (cur_cmd == IF_TEST) {
  309.             incr(l);
  310.         }
  311.     }
  312.     scanner_status = save_scanner_status;
  313. }
  314.  
  315. void
  316. change_if_limit (l, p)
  317.     int    l;
  318.     ptr    p;
  319. {
  320.     ptr    q;
  321.  
  322.     if (p == cond_ptr) {
  323.         if_limit = l;
  324.     } else {
  325.         q = cond_ptr; 
  326.         loop {
  327.             if (q == null) {
  328.                 confusion("if");
  329.             }
  330.             if (link(q) == p) {
  331.                 type(q) = l;
  332.                 return;
  333.             }
  334.             q = link(q);
  335.         }
  336.     }
  337. }
  338.  
  339. void
  340. _cond_init ()
  341. {
  342.     cond_ptr = null;
  343.     if_limit = NORMAL;
  344.     if_line = 0;
  345.     cur_if = 0;
  346. }
  347.  
  348. void
  349. _cond_init_once ()
  350. {
  351. }
  352.  
  353. /*
  354. **    Help text
  355. */
  356.  
  357. help_or ()
  358. {
  359.     help1("I'm ignoring this; it doesn't match any \\if.");
  360. }
  361.  
  362. help_relation ()
  363. {
  364.     help1("I was expecting to see `<', `=', or `>'. Didn't.");
  365. }
  366.