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

  1.  
  2. /*
  3.  * %Y%:%M%:%I%:%Q%
  4.  *
  5.  * Copyright 1987,1988,1991 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. tok    cur_tok;
  20. tok    par_tok;
  21.  
  22. int    cur_cmd;
  23. int    cur_chr;
  24.  
  25. ptr    def_ref;
  26. ptr    match_toks;
  27. ptr    align_toks;
  28. ptr    omit_template;
  29. ptr    null_list;
  30.  
  31. int    scanner_status;
  32. int    align_state;
  33.  
  34. str    name;
  35. int    line;
  36. bool    force_eof;
  37. int    open_parens;
  38.  
  39. input    cur_input;
  40.  
  41. int    ninputs;
  42. input    *input_stack;
  43. input    *input_end;
  44. input     *input_ptr;
  45. input     *max_in_stack;
  46. input    *base_ptr;
  47.  
  48. #define STACK_SIZE    200
  49.  
  50. int    nfiles;
  51. infile    *file_stack;
  52. infile    *file_end;
  53. infile    *file_ptr;
  54. infile    *max_file_stack;
  55.  
  56. #define INFILE_SIZE    45
  57.  
  58. int    nparams;
  59. ptr    *param_stack;
  60. ptr    *param_end;
  61. ptr    *param_ptr;
  62. ptr    *max_param_stack;
  63.  
  64. #define PARAM_SIZE    100
  65.  
  66. void
  67. get_token ()
  68. {
  69.     no_new_control_sequence = FALSE;
  70.     get_next();
  71.     no_new_control_sequence = TRUE;
  72.     if (cur_cs == null_sym) {
  73.         cur_tok = cur_cmd * 0400 + cur_chr;
  74.     } else {
  75.         cur_tok = sym2tok(cur_cs);
  76.     }
  77. }
  78.  
  79. #define any_state(CAT) \
  80.     case MID_LINE + CAT: \
  81.     case SKIP_BLANKS + CAT: \
  82.     case NEW_LINE + CAT
  83.  
  84. #define delims(STATE) \
  85.     case STATE + MATH_SHIFT: \
  86.     case STATE + TAB_MARK: \
  87.     case STATE + MAC_PARAM: \
  88.     case STATE + SUB_MARK: \
  89.     case STATE + LETTER: \
  90.     case STATE + OTHER_CHAR 
  91.  
  92. #define mid_line(CAT) \
  93.     case MID_LINE + CAT
  94.  
  95. #define new_line(CAT) \
  96.     case NEW_LINE + CAT
  97.  
  98. #define skip_blanks(CAT) \
  99.     case SKIP_BLANKS + CAT
  100.  
  101. #define is_hex(C) \
  102.     ((C) >= '0' && (C) <= '9' || (C) >= 'a' && (C) <= 'f')
  103.  
  104. #define hex_to_cur_chr(C, CC) \
  105. {    cur_chr = 16 * ((C <= '9') ? C - '0' : C - 'a' + 10); \
  106.     cur_chr += (CC <= '9') ? CC - '0' : CC - 'a' + 10; \
  107. }
  108.  
  109. #define    relax() cur_cmd = RELAX; cur_chr = NO_EXPAND_FLAG;
  110.  
  111. void
  112. get_next ()
  113. {
  114.     tok    t;
  115.     int    c, cc;
  116.  
  117. #define JOB_ABORT "*** (job aborted, no legal \\end found)"
  118. #define USER_CMD "(Please type a command or say `\\end')"
  119. #define INVAL_CHAR "Text line contains an invalid character"
  120. #define WOVEN_ALIGNS "(interwoven alignment preambles are not allowed)"
  121.  
  122. restart:
  123.     cur_cs = null_sym;
  124.     if (file_state) {
  125. reread:
  126.         if (next <= limit) {
  127.             cur_chr = *next++;
  128. reswitch:
  129.             cur_cmd = cat_code(cur_chr);
  130.             switch (state + cur_cmd)
  131.             {
  132.             any_state(IGNORE):
  133.             skip_blanks(SPACER):
  134.             new_line(SPACER):
  135.                 goto reread;
  136.  
  137.             any_state(ESCAPE):
  138.                 get_cs();
  139.                 cur_cmd = eq_type(cur_cs);
  140.                 cur_chr = equiv(cur_cs);
  141.                 if (cur_cmd >= OUTER_CALL) {
  142.                     check_outer_validity();
  143.                 }
  144.                 break;
  145.  
  146.             any_state(ACTIVE_CHAR):
  147.                 cur_cs = active_base[cur_chr];
  148.                 cur_cmd = eq_type(cur_cs);
  149.                 cur_chr = equiv(cur_cs);
  150.                 state = MID_LINE;
  151.                 if (cur_cmd >= OUTER_CALL) {
  152.                     check_outer_validity();
  153.                 }
  154.                 break;
  155.  
  156.             any_state(SUP_MARK):
  157.                 if (cur_chr != *next
  158.                 || next >= limit
  159.                 || (c = next[1]) >= 0200) {
  160.                     state = MID_LINE;
  161.                     break;
  162.                 }
  163.                 next += 2;
  164.                 if (is_hex(c) && next <= limit) {
  165.                     cc = *next;
  166.                     if (is_hex(cc)) {
  167.                         next++;
  168.                         hex_to_cur_chr(c, cc);
  169.                         goto reswitch;
  170.                     }
  171.                 }
  172.                 if (c < 0100) {
  173.                     cur_chr = c + 0100;
  174.                 } else {
  175.                     cur_chr = c - 0100;
  176.                 }
  177.                 goto reswitch;
  178.  
  179.             any_state(INVALID_CHAR):
  180.                 print_err(INVAL_CHAR);
  181.                 help_funny();
  182.                 deletions_allowed = FALSE;
  183.                 error();
  184.                 deletions_allowed = TRUE;
  185.                 goto restart;
  186.  
  187.             mid_line(SPACER):
  188.                 state = SKIP_BLANKS;
  189.                 cur_chr = ' ';
  190.                 break;
  191.  
  192.             mid_line(CAR_RET):
  193.                 next = limit + 1;
  194.                 cur_cmd = SPACER;
  195.                 cur_chr = ' ';
  196.                 break;
  197.  
  198.             skip_blanks(CAR_RET):
  199.             any_state(COMMENT):
  200.                 next = limit + 1;
  201.                 goto reread;
  202.  
  203.             new_line(CAR_RET):
  204.                 next = limit + 1;
  205.                 cur_cs = par_cs;
  206.                 cur_cmd = eq_type(cur_cs);
  207.                 cur_chr = equiv(cur_cs);
  208.                 if (cur_cmd >= OUTER_CALL) {
  209.                     check_outer_validity();
  210.                 }
  211.                 break;
  212.  
  213.             mid_line(LEFT_BRACE):
  214.                 incr(align_state);
  215.                 break;
  216.  
  217.             skip_blanks(LEFT_BRACE):
  218.             new_line(LEFT_BRACE):
  219.                 state = MID_LINE;
  220.                 incr(align_state);
  221.                 break;
  222.  
  223.             mid_line(RIGHT_BRACE):
  224.                 decr(align_state);
  225.                 break;
  226.  
  227.             skip_blanks(RIGHT_BRACE):
  228.             new_line(RIGHT_BRACE):
  229.                 state = MID_LINE;
  230.                 decr(align_state);
  231.                 break;
  232.  
  233.             delims(SKIP_BLANKS):
  234.             delims(NEW_LINE):
  235.                 state = MID_LINE;
  236.                 break;
  237.  
  238.             default:
  239.                 break;
  240.             }
  241.         } else {
  242.             state = NEW_LINE; 
  243.             if (index > 17) {
  244.                 incr(line);
  245.                 if (!force_eof) {
  246.                     if (input_ln(cur_file)) {
  247.                         firm_up_the_line();
  248.                     } else {
  249.                         force_eof = TRUE;
  250.                     }
  251.                 }
  252.                 if (force_eof) {
  253.                     print(")");
  254.                     decr(open_parens);
  255.                     force_eof = FALSE;
  256.                     update_terminal();
  257.                     end_file_reading();
  258.                     check_outer_validity();
  259.                     goto restart;
  260.                 }
  261.                 if (end_line_char_active) {
  262.                     *++limit = end_line_char;
  263.                 }
  264.             } else {
  265.                 if (!terminal_input) {
  266.                     cur_cmd = 0;
  267.                     cur_chr = 0;
  268.                     return;
  269.                 }
  270.                 if (input_ptr > input_stack) {
  271.                     end_file_reading();
  272.                     goto restart;
  273.                 }
  274.                 if (selector < LOG_ONLY) {
  275.                     open_log_file();
  276.                 }
  277.                 if (interaction > NONSTOP_MODE) {
  278.                     if (limit <= buffer) {
  279.                         print_nl(USER_CMD);
  280.                     }
  281.                     print_ln();
  282.                     prompt_input("*");
  283.                     memcpy(buffer, cur_str, cur_length());
  284.                     next = buffer;
  285.                     limit = buffer + cur_length() - 1;
  286.                     if (end_line_char_active) {
  287.                         *++limit = end_line_char;
  288.                     }
  289.                     flush_str();
  290.                 } else {
  291.                     fatal_error(JOB_ABORT);
  292.                 }
  293.             }
  294.             check_interrupt();
  295.             goto reread;
  296.         }
  297.     } else {
  298.         if (loc != null) {
  299.             t = token(loc);
  300.             loc = token_link(loc);
  301.             if (is_sym(t)) {
  302.                 cur_cs = tok2sym(t);
  303.                 cur_cmd = eq_type(cur_cs);
  304.                 cur_chr = equiv(cur_cs);
  305.                 if (cur_cmd >= OUTER_CALL) {
  306.                     if (cur_cmd == DONT_EXPAND) {
  307.                         cur_cs = tok2sym(token(loc));
  308.                         loc = null;
  309.                         cur_cmd = eq_type(cur_cs);
  310.                         cur_chr = equiv(cur_cs);
  311.                         if (cur_cmd > MAX_COMMAND) {
  312.                             relax();
  313.                         }
  314.                     } else {
  315.                         check_outer_validity();
  316.                     }
  317.                 }
  318.             } else {
  319.                 cur_cmd = t / 0400;
  320.                 cur_chr = t % 0400;
  321.                 switch (cur_cmd)
  322.                 {
  323.                 case LEFT_BRACE:
  324.                     incr(align_state);
  325.                     break;
  326.  
  327.                 case RIGHT_BRACE:
  328.                     decr(align_state);
  329.                     break;
  330.  
  331.                 case OUT_PARAM:
  332.                     begin_token_list(
  333.                         param_start[cur_chr - 1],
  334.                         PARAMETER
  335.                     );
  336.                     goto restart;
  337.  
  338.                 default:
  339.                     break;
  340.                 }
  341.             }
  342.         } else {
  343.             end_token_list();
  344.             goto restart;
  345.         }
  346.     }
  347.     if (cur_cmd <= CAR_RET && cur_cmd >= TAB_MARK && align_state == 0) {
  348.         if (scanner_status == ALIGNING) {
  349.             fatal_error(WOVEN_ALIGNS);
  350.         }
  351.         cur_cmd = unset_info(cur_align);
  352.         unset_info(cur_align) = cur_chr;
  353.         if (cur_cmd == OMIT) {
  354.             begin_token_list(omit_template, V_TEMPLATE);
  355.         } else {
  356.             begin_token_list(v_part(cur_align), V_TEMPLATE);
  357.         }
  358.         align_state = 1000000;
  359.         goto restart;
  360.     }
  361. }
  362.  
  363. void
  364. get_cs ()
  365. {
  366.     byte    *nxt;
  367.     int    cat;
  368.     int    d, c, cc;
  369.  
  370.     if (next > limit) {
  371.         cur_cs = null_cs;
  372.         return;
  373.     }
  374.  
  375. #define reduce_expanded_cc(CC)                         \
  376. {    if (*CC == cur_chr && cat == SUP_MARK && CC < limit) {         \
  377.         if ((c = CC[1]) < 0200) {                \
  378.             d = 2;                        \
  379.             if (is_hex(c) && CC + 2 <= limit) {        \
  380.                 cc = CC[2];                \
  381.                 if (is_hex(cc))                \
  382.                     incr(d);            \
  383.             }                        \
  384.             if (d > 2) {                    \
  385.                 hex_to_cur_chr(c, cc);            \
  386.                 CC[-1] = cur_chr;            \
  387.             } else if (c < 0100) {                 \
  388.                 CC[-1] = c + 0100;             \
  389.             } else {                    \
  390.                 CC[-1] = c - 0100;             \
  391.             }                        \
  392.             limit -= d;                    \
  393.             while (CC <= limit) {                 \
  394.                 CC[0] = CC[d];                \
  395.                 incr(CC);                \
  396.             }                        \
  397.             goto start_cs;                    \
  398.         }                            \
  399.     }                                \
  400. }
  401.  
  402. start_cs: 
  403.     nxt = next;
  404.     cur_chr = *nxt++;
  405.     cat = cat_code(cur_chr);
  406.     if (cat == LETTER) {
  407.         state = SKIP_BLANKS;
  408.     } else if (cat == SPACER) {
  409.         state = SKIP_BLANKS;
  410.     } else {
  411.         state = MID_LINE;
  412.     }
  413.     if (cat == LETTER && nxt <= limit) {
  414.         do {
  415.             cur_chr = *nxt++;
  416.             cat = cat_code(cur_chr);
  417.         } while (cat == LETTER && nxt <= limit);
  418.         reduce_expanded_cc(nxt);
  419.         if (cat != LETTER) {
  420.             decr(nxt);
  421.         }
  422.         if (nxt > next + 1) {
  423.             cur_cs = id_lookup(next, nxt - next);
  424.             next = nxt;
  425.             return;
  426.         }
  427.     } else {
  428.         reduce_expanded_cc(nxt);
  429.     }
  430.     cur_cs = single_base[*next++];
  431. }
  432.  
  433. void
  434. check_outer_validity ()
  435. {
  436.     ptr    p, q;
  437.  
  438.     if (scanner_status != NORMAL) {
  439.         deletions_allowed = FALSE;
  440.         if (cur_cs != null_sym) {
  441.             if (state == TOKEN_LIST || index < 1 || index > 17) {
  442.                 p = new_token();
  443.                 token(p) = sym2tok(cur_cs);
  444.                 back_list(p);
  445.             }
  446.             cur_cmd = SPACER;
  447.             cur_chr = ' ';
  448.         }
  449.         if (scanner_status > SKIPPING) {
  450.             runaway();
  451.             if (cur_cs == null_sym) {
  452.                 print_err("File ended");
  453.             } else {
  454.                 cur_cs = null_sym;
  455.                 print_err("Forbidden control sequence found");
  456.             }
  457.             print(" while scanning ");
  458.             p = new_token();
  459.             switch (scanner_status)
  460.             {
  461.             case DEFINING:
  462.                 print("definition");
  463.                 token(p) = RIGHT_BRACE_TOKEN + '}';
  464.                 break;
  465.  
  466.             case MATCHING:
  467.                 print("use");
  468.                 token(p) = par_tok;
  469.                 long_state = OUTER_CALL;
  470.                 break;
  471.  
  472.             case ALIGNING:
  473.                 print("preamble");
  474.                 token(p) = RIGHT_BRACE_TOKEN + '}';
  475.                 q = p;
  476.                 p = new_token();
  477.                 token_link(p) = q;
  478.                 token(p) = sym2tok(FROZEN_CR);
  479.                 align_state = -1000000;
  480.                 break;
  481.  
  482.             case ABSORBING:
  483.                 print("text"); 
  484.                 token(p) = RIGHT_BRACE_TOKEN + '}';
  485.                 break;
  486.             }
  487.             ins_list(p);
  488.             print(" of ");
  489.             sprint_cs(warning_cs);
  490.             help_scanner();
  491.             error();
  492.         } else {
  493.             print_err("Incomplete ");
  494.             print_cmd_chr(IF_TEST, cur_if);
  495.             print("; all text was ignored after line ");
  496.             print_int(skip_line);
  497.             if (cur_cs != null_sym) {
  498.                 cur_cs = null_sym;
  499.                 help_skip();
  500.             } else {
  501.                 help_skif();
  502.             }
  503.             cur_tok = sym2tok(FROZEN_FI);
  504.             ins_error();
  505.         }
  506.         deletions_allowed = TRUE;
  507.     }
  508. }
  509.  
  510. void
  511. firm_up_the_line ()
  512. {
  513.     byte    *s;
  514.  
  515.     if (pausing > 0 && interaction > NONSTOP_MODE) {
  516.         wake_up_terminal();
  517.         print_ln();
  518.         if (next <= limit) {
  519.             for (s = buffer; s <= limit; incr(s)) {
  520.                 print_char(*s);
  521.             }
  522.         }
  523.         prompt_input("=>");
  524.         if (cur_length()) {
  525.             memcpy(buffer, cur_str, cur_length());
  526.             next = buffer;
  527.             limit = buffer + cur_length() - 1;
  528.         }
  529.         flush_str();
  530.     }
  531. }
  532.  
  533. void
  534. push_input()
  535. {
  536.     if (input_ptr > max_in_stack) {
  537.         if (input_ptr == input_end) {
  538.             overflow("input stack size", ninputs);
  539.         }
  540.         max_in_stack = input_ptr;
  541.     }
  542.     if (file_state) {
  543.         if (index == 0 || index > 17) {
  544.             file_name = name;
  545.             file_line = line;
  546.         }
  547.     } else {
  548.         cs_name = name;
  549.     }
  550.     *input_ptr++ = cur_input;
  551. }
  552.  
  553. void
  554. pop_input()
  555. {
  556.     cur_input = *--input_ptr;
  557.     if (file_state) {
  558.         if (index == 0 || index > 17) {
  559.             name = file_name;
  560.             line = file_line;
  561.         }
  562.     } else {
  563.         name = cs_name;
  564.     }
  565. }
  566.  
  567. void
  568. begin_token_list (p, t)
  569.     ptr    p;
  570.     int    t;
  571. {
  572.     push_input();
  573.     state = TOKEN_LIST;
  574.     start = p;
  575.     token_type = t;
  576.     if (t >= MACRO) {
  577.         add_token_ref(p);
  578.         if (t == MACRO) {
  579.             param_start = param_ptr;
  580.         } else {
  581.             loc = token_link(p);
  582.             if (tracing_macros > 1) {
  583.                 begin_diagnostic();
  584.                 print_nl(null_str);
  585.                 switch (t)
  586.                 {
  587.                 case MARK_TEXT:
  588.                     print_esc("mark");
  589.                     break;
  590.  
  591.                 case WRITE_TEXT:
  592.                     print_esc("write");
  593.                     break;
  594.  
  595.                 default:
  596.                     print_toks_param(t - OUTPUT_TEXT);
  597.                     break;
  598.                 }
  599.                 print("->");
  600.                 token_show(p);
  601.                 end_diagnostic(FALSE);
  602.             }
  603.         }
  604.     } else {
  605.         loc = p;
  606.     }
  607. }
  608.  
  609. void
  610. end_token_list ()
  611. {
  612.     if (token_type >= BACKED_UP) {
  613.         if (token_type <= INSERTED) {
  614.             flush_list(start);
  615.         } else {
  616.             delete_token_ref(start);
  617.             if (token_type == MACRO) {
  618.                 while (param_ptr > param_start) {
  619.                     flush_list(*--param_ptr);
  620.                 }
  621.             }
  622.         }
  623.     } else if (token_type == U_TEMPLATE) {
  624.         align_state = 0;
  625.     }
  626.     pop_input();
  627.     check_interrupt();
  628. }
  629.  
  630. void
  631. begin_file_reading ()
  632. {
  633.     push_input();
  634.     if (file_ptr > max_file_stack) {
  635.         if (file_ptr == file_end) {
  636.             overflow("file stack size", nfiles);
  637.         }
  638.         max_file_stack = file_ptr;
  639.     }
  640.     in_file = (ptr)file_ptr++;
  641.     state = MID_LINE;
  642.     index = 0;
  643.     buffer = (byte *)new_str(BUF_SIZE);
  644. }
  645.  
  646. void
  647. end_file_reading ()
  648. {
  649.     if (index > 17) {
  650.         a_close(cur_file);
  651.     }
  652.     free_str(buffer);
  653.     pop_input();
  654.     decr(file_ptr);
  655. }
  656.  
  657. void
  658. back_input ()
  659. {
  660.     ptr    p;
  661.  
  662.     while (state == TOKEN_LIST && loc == null) {
  663.         end_token_list();
  664.     }
  665.     p = new_token();
  666.     token(p) = cur_tok;
  667.     if (cur_tok < RIGHT_BRACE_LIMIT) {
  668.         if (cur_tok < LEFT_BRACE_LIMIT) {
  669.             decr(align_state);
  670.         } else {
  671.             incr(align_state);
  672.         }
  673.     }
  674.     push_input();
  675.     state = TOKEN_LIST;
  676.     loc = start = p;
  677.     token_type = BACKED_UP;
  678. }
  679.  
  680. void
  681. back_error ()
  682. {
  683.     OK_to_interrupt = FALSE;
  684.     back_input();
  685.     OK_to_interrupt = TRUE;
  686.     error();
  687. }
  688.  
  689. void
  690. ins_error ()
  691. {
  692.     OK_to_interrupt = FALSE;
  693.     back_input();
  694.     token_type = INSERTED; 
  695.     OK_to_interrupt = TRUE;
  696.     error();
  697. }
  698.  
  699. void
  700. clear_for_error_prompt ()
  701. {
  702.     while (state != TOKEN_LIST
  703.     && terminal_input
  704.     && input_ptr > input_stack
  705.     && next > limit) {
  706.         end_file_reading();
  707.     }
  708.     print_ln();
  709.     clear_terminal();
  710.     flush_str();
  711. }
  712.  
  713. void
  714. runaway ()
  715. {
  716.     ptr    p;
  717.  
  718.     if (scanner_status > SKIPPING) {
  719.         print_nl("Runaway ");
  720.         switch (scanner_status) 
  721.         {
  722.         case DEFINING:
  723.             print("definition");
  724.             p = def_ref;
  725.             break;
  726.  
  727.         case MATCHING:
  728.             print("argument");
  729.             p = match_toks;
  730.             break;
  731.  
  732.         case ALIGNING:
  733.             print("preamble");
  734.             p = align_toks;
  735.             break;
  736.  
  737.         case ABSORBING:
  738.             print("text");
  739.             p = def_ref;
  740.             break;
  741.         }
  742.         print("?");
  743.         print_ln();
  744.         show_token_list(token_link(p), null, ERROR_LINE - 10);
  745.     }
  746. }
  747.  
  748. void
  749. show_context ()
  750. {
  751.     int    i, j, l, m, n, nn, p, q;
  752.     int    old_setting;
  753.     bool    bottom_line;
  754.  
  755.     base_ptr = input_ptr;
  756.     push_input();
  757.     nn = -1;
  758.     bottom_line = FALSE;
  759.     loop {
  760.         cur_input = *base_ptr;
  761.         if (state != TOKEN_LIST
  762.         && (index > 17 || base_ptr == input_stack)) {
  763.             bottom_line = TRUE;
  764.         }
  765.         if (base_ptr == input_ptr - 1
  766.         || bottom_line
  767.         || nn < error_context_lines) {
  768.             if (base_ptr == input_ptr - 1
  769.             || state != TOKEN_LIST
  770.             || token_type != BACKED_UP
  771.             || loc != null) {
  772.             tally = 0;
  773.             old_setting = selector;
  774.             if (file_state) {
  775.                 if (index <= 17) {
  776.                     if (terminal_input) {
  777.                         if (base_ptr == input_stack) {
  778.                             print_nl("<*>");
  779.                         } else {
  780.                             print_nl("<insert> ");
  781.                         }
  782.                     } else {
  783.                         print_nl("<read ");
  784.                         if (index == 17) {
  785.                             print("*");
  786.                         } else {
  787.                             print_int(index - 1);
  788.                         }
  789.                         print(">");
  790.                     }
  791.                 } else {
  792.                     print_nl("l.");
  793.                     print_int(file_line);
  794.                 }
  795.                 print(" ");
  796.                 l = begin_pseudoprint();
  797.                 j = limit - buffer;
  798.                 if (*limit != end_line_char) {
  799.                     incr(j);
  800.                 }
  801.                 if (j > 0) {
  802.                     for (i = 0; i < j; incr(i)) {
  803.                         if (buffer + i == next) {
  804.                             set_trick_count();
  805.                         }
  806.                         print_ASCII(buffer[i]);
  807.                     }
  808.                 }
  809.             } else {
  810.                 switch (token_type)
  811.                 {
  812.                 case PARAMETER:
  813.                     print_nl("<argument> ");
  814.                     break;
  815.  
  816.                 case U_TEMPLATE:
  817.                 case V_TEMPLATE:
  818.                     print_nl("<template> ");
  819.                     break;
  820.  
  821.                 case BACKED_UP:
  822.                     if (loc == null) {
  823.                         print_nl("<recently read> "); 
  824.                     } else {
  825.                         print_nl("<to be read again> ");
  826.                     }
  827.                     break;
  828.  
  829.                 case INSERTED:
  830.                     print_nl("<inserted text> ");
  831.                     break;
  832.  
  833.                 case MACRO:
  834.                     print_ln();
  835.                     print_cs(in_cs);
  836.                     break;
  837.  
  838.                 case OUTPUT_TEXT:
  839.                     print_nl("<output> ");
  840.                     break;
  841.  
  842.                 case EVERY_PAR_TEXT:
  843.                     print_nl("<everypar> ");
  844.                     break;
  845.  
  846.                 case EVERY_MATH_TEXT:
  847.                     print_nl("<everymath> ");
  848.                     break;
  849.  
  850.                 case EVERY_DISPLAY_TEXT:
  851.                     print_nl("<everydisplay> ");
  852.                     break;
  853.  
  854.                 case EVERY_HBOX_TEXT:
  855.                     print_nl("<everyhbox> ");
  856.                     break;
  857.  
  858.                 case EVERY_VBOX_TEXT:
  859.                     print_nl("<everyvbox> ");
  860.                     break;
  861.  
  862.                 case EVERY_JOB_TEXT:
  863.                     print_nl("<everyjob>");
  864.                     break;
  865.  
  866.                 case EVERY_CR_TEXT:
  867.                     print_nl("<everycr> ");
  868.                     break;
  869.  
  870.                 case MARK_TEXT:
  871.                     print_nl("<mark> ");
  872.                     break;
  873.  
  874.                 case WRITE_TEXT:
  875.                     print_nl("<write> ");
  876.                     break;
  877.  
  878.                 default:
  879.                     print_nl("? ");
  880.                     break;
  881.                 }
  882.                 l = begin_pseudoprint();
  883.                 if (token_type < MACRO) {
  884.                     show_token_list(start, loc, 100000);
  885.                 } else {
  886.                     show_token_list(token_link(start),
  887.                         loc, 100000);
  888.                 }
  889.             }
  890.             selector = old_setting;
  891.             if (trick_count == 1000000) {
  892.                 set_trick_count();
  893.             }
  894.             if (tally < trick_count) {
  895.                 m = tally - first_count;
  896.             } else {
  897.                 m = trick_count - first_count;
  898.             }
  899.             if (l + first_count <= HALF_ERROR_LINE) {
  900.                 p = 0;
  901.                 n = l + first_count;
  902.             } else {
  903.                 print("...");
  904.                 p = l + first_count - HALF_ERROR_LINE + 3;
  905.                 n = HALF_ERROR_LINE;
  906.             }
  907.             for (q = p; q < first_count; incr(q)) {
  908.                 print_char(trick_buf[q % ERROR_LINE]);
  909.             }
  910.             print_ln();
  911.             for (q = 1; q <= n; incr(q)) {
  912.                 print(" ");
  913.             }
  914.             if (m + n <= ERROR_LINE) {
  915.                 p = first_count + m;
  916.             } else {
  917.                 p = first_count + ERROR_LINE - n - 3;
  918.             }
  919.             for (q = first_count; q < p; q++) {
  920.                 print_char(trick_buf[q % ERROR_LINE]);
  921.             }
  922.             if (m + n > ERROR_LINE) {
  923.                 print("...");
  924.             }
  925.             incr(nn);
  926.             }
  927.         } else if (nn == error_context_lines) {
  928.             print_nl("...");
  929.             incr(nn);
  930.         }
  931.         if (bottom_line) {
  932.             break;
  933.         }
  934.         decr(base_ptr);
  935.     }
  936.     pop_input();
  937. }
  938.  
  939. void
  940. _tok_init ()
  941. {
  942.     base_ptr = max_in_stack = input_ptr = input_stack;
  943.     max_file_stack = file_ptr = file_stack;
  944.     max_param_stack = param_ptr = param_stack;
  945.     state = NEW_LINE;
  946.     index = 0;
  947.     in_file = (ptr)file_ptr++;
  948.     cur_file = stdin;
  949.     name = file_name = "tty";
  950.     line = file_line =  0;
  951.     force_eof = FALSE;
  952.     open_parens = 0;
  953.     scanner_status = NORMAL;
  954.     align_state = 1000000;
  955.     buffer = (byte *)new_str(BUF_SIZE);
  956.     next = buffer;
  957.     limit = next - 1;
  958.     token(omit_template) = END_TEMPLATE_TOKEN;
  959.     token(null_list) = null_tok;
  960. }
  961.  
  962. void
  963. _tok_init_once ()
  964. {
  965.     ninputs = STACK_SIZE;
  966.     input_stack = (input *)malloc(ninputs*sizeof(input));
  967.     if (input_stack == (input *) 0) {
  968.         overflow("input stack", ninputs);
  969.     }
  970.     input_end = input_stack + ninputs;
  971.  
  972.     nfiles = INFILE_SIZE;
  973.     file_stack = (infile *)malloc(nfiles * sizeof(infile));
  974.     if (file_stack == (infile *) 0) {
  975.         overflow("infile stack", nfiles);
  976.     }
  977.     file_end = file_stack + nfiles;
  978.  
  979.     nparams = PARAM_SIZE;
  980.     param_stack = (ptr *)malloc(nparams * sizeof(ptr));
  981.     if (param_stack == (ptr *) 0) {
  982.         overflow("param stack", nparams);
  983.     }
  984.     param_end = param_stack + nparams;
  985.     match_toks = new_token();
  986.     align_toks = new_token();
  987.     omit_template = new_token();
  988.     null_list = new_token();
  989. }
  990.  
  991. /*
  992. **    Help text
  993. */
  994.  
  995. help_scanner ()
  996. {
  997.     help4("I suspect you have forgotten a `}', causing me",
  998.     "to read past where you wanted me to stop.",
  999.     "I'll try to recover; but if the error is serious,",
  1000.     "you'd better type `E' or `X' now and fix your file.");
  1001. }
  1002.  
  1003. help_funny ()
  1004. {
  1005.     help2("A funny symbol that I can't read has just been input.",
  1006.     "Continue, and I'll forget that it ever happened.");
  1007. }
  1008.  
  1009. help_skip ()
  1010. {
  1011.     help3("A forbidden control sequence occurred in skipped text.",
  1012.     "This kind of error happens when you say `\\if...' and forget",
  1013.     "the matching `\\fi'. I've inserted a `\\fi'; this might work.");
  1014. }
  1015.  
  1016. help_skif ()
  1017. {
  1018.     help3("The file ended while I was skipping conditional text.",
  1019.     "This kind of error happens when you say `\\if...' and forget",
  1020.     "the matching `\\fi'. I've inserted a `\\fi'; this might work.");
  1021. }
  1022.