home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Tex29 / StTeXsrc.zoo / src / cond.c < prev    next >
C/C++ Source or Header  |  1988-03-13  |  7KB  |  329 lines

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