1% omtrans.ch: Characters sets for input and output 2% 3% This file is part of the Omega project, which 4% is based on the web2c distribution of TeX. 5% 6% Copyright (c) 1994--2000 John Plaice and Yannis Haralambous 7% 8% This library is free software; you can redistribute it and/or 9% modify it under the terms of the GNU Library General Public 10% License as published by the Free Software Foundation; either 11% version 2 of the License, or (at your option) any later version. 12% 13% This library is distributed in the hope that it will be useful, 14% but WITHOUT ANY WARRANTY; without even the implied warranty of 15% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16% Library General Public License for more details. 17% 18% You should have received a copy of the GNU Library General Public 19% License along with this library; if not, write to the Free Software 20% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21% 22%--------------------------------------- 23@x [3] m.25 l.767 - Omega Translation 24initialization. We shall define a word file later; but it will be possible 25for us to specify simple operations on word files before they are defined. 26@y 27initialization. We shall define a word file later; but it will be possible 28for us to specify simple operations on word files before they are defined. 29 30@d no_mode=0 31@d onebyte_mode=1 32@d ebcdic_mode=2 33@d twobyte_mode=3 34@d twobyteLE_mode=4 35 36@d trans_input=0 37@d trans_output=1 38@d trans_default_input=2 39@d trans_default_output=3 40@d trans_no_input=4 41@d trans_no_output=5 42@d trans_no_default_input=6 43@d trans_no_default_output=7 44 45@d mode_input=0 46@d mode_output=1 47@d mode_default_input=2 48@d mode_default_output=3 49@d mode_no_input=4 50@d mode_no_output=5 51@d mode_no_default_input=6 52@d mode_no_default_output=7 53@z 54%--------------------------------------- 55@x [3] m.30 l.890 - Omega Translation 56@!max_buf_stack:0..buf_size; {largest index used in |buffer|} 57@y 58@!max_buf_stack:0..buf_size; {largest index used in |buffer|} 59@!term_in_mode:halfword; 60@!term_in_translation:halfword; 61@z 62%--------------------------------------- 63@x [3] m.37 l.1065 - Omega Translation 64 if not input_ln(term_in,true) then {this shouldn't happen} 65@y 66 if not new_input_ln(term_in,term_in_mode,term_in_translation,true) 67then {this shouldn't happen} 68@z 69%--------------------------------------- 70@x [5] m.54 l. - Omega Translation 71@!log_file : alpha_file; {transcript of \TeX\ session} 72@y 73@!log_file : alpha_file; {transcript of \TeX\ session} 74@!term_out_mode:halfword; 75@!term_out_translation:halfword; 76@z 77%--------------------------------------- 78@x [5] m.59 l. - Omega Translation 79@<Basic printing...@>= 80procedure print_char(@!s:ASCII_code); {prints a single character} 81label exit; 82begin if @<Character |s| is the current new-line character@> then 83 if selector<pseudo then 84 begin print_ln; return; 85 end; 86case selector of 87term_and_log: begin wterm(xchr[s]); wlog(xchr[s]); 88 incr(term_offset); incr(file_offset); 89 if term_offset=max_print_line then 90 begin wterm_cr; term_offset:=0; 91 end; 92 if file_offset=max_print_line then 93 begin wlog_cr; file_offset:=0; 94 end; 95 end; 96log_only: begin wlog(xchr[s]); incr(file_offset); 97 if file_offset=max_print_line then print_ln; 98 end; 99term_only: begin wterm(xchr[s]); incr(term_offset); 100 if term_offset=max_print_line then print_ln; 101 end; 102no_print: do_nothing; 103pseudo: if tally<trick_count then trick_buf[tally mod error_line]:=s; 104new_string: begin if pool_ptr<pool_size then append_char(s); 105 end; {we drop characters if the string space is full} 106othercases write(write_file[selector],xchr[s]) 107endcases;@/ 108incr(tally); 109exit:end; 110@y 111@d omega_write(#)==case term_out_mode of 112 no_mode: write(#,xchr[s]); 113 onebyte_mode,ebcdic_mode: write(#,xchr[s]); 114 twobyte_mode: begin write(#,xchr[s div @"100]); 115 write(#,xchr[s mod @"100]); 116 end; 117 twobyteLE_mode: begin write(#,xchr[s mod @"100]); 118 write(#,xchr[s div @"100]); 119 end; 120 end 121 122@d omega_file_write(#)==case write_file_mode[#] of 123 no_mode: write(write_file[#],xchr[s]); 124 onebyte_mode,ebcdic_mode: write(write_file[#],xchr[s]); 125 twobyte_mode: begin write(write_file[#],xchr[s div @"100]); 126 write(write_file[#],xchr[s mod @"100]); 127 end; 128 twobyteLE_mode: begin write(write_file[#],xchr[s mod @"100]); 129 write(write_file[#],xchr[s div @"100]); 130 end; 131 end 132 133@<Basic printing...@>= 134procedure print_char(@!s:ASCII_code); {prints a single character} 135label exit; 136begin if @<Character |s| is the current new-line character@> then 137 if selector<pseudo then 138 begin print_ln; return; 139 end; 140case selector of 141term_and_log: begin omega_write(term_out); omega_write(log_file); 142 incr(term_offset); incr(file_offset); 143 if term_offset=max_print_line then 144 begin wterm_cr; term_offset:=0; 145 end; 146 if file_offset=max_print_line then 147 begin wlog_cr; file_offset:=0; 148 end; 149 end; 150log_only: begin omega_write(log_file); incr(file_offset); 151 if file_offset=max_print_line then print_ln; 152 end; 153term_only: begin omega_write(term_out); incr(term_offset); 154 if term_offset=max_print_line then print_ln; 155 end; 156no_print: do_nothing; 157pseudo: if tally<trick_count then trick_buf[tally mod error_line]:=s; 158new_string: begin if pool_ptr<pool_size then append_char(s); 159 end; {we drop characters if the string space is full} 160othercases omega_file_write(selector) 161endcases;@/ 162incr(tally); 163exit:end; 164@z 165%--------------------------------------- 166@x [5] m.59 l. - Omega Translation 167procedure print(@!s:integer); {prints string |s|} 168label exit; 169var j:pool_pointer; {current character code position} 170@!nl:integer; {new-line character to restore} 171@!l:integer; {for printing 16-bit characters} 172begin if s>=str_ptr then s:="???" {this can't happen} 173@.???@> 174else if s<biggest_char then 175 if s<0 then s:="???" {can't happen} 176 else begin if selector>pseudo then 177 begin print_char(s); return; {internal strings are not expanded} 178 end; 179 if (@<Character |s| is the current new-line character@>) then 180 if selector<pseudo then 181 begin print_ln; return; 182 end; 183 nl:=new_line_char; 184 @<Set newline character to -1@>; 185 if s<@"20 then begin 186 print_char(@"5E); print_char(@"5E); print_char(s+@'100); 187 end 188 else if s<@"7F then 189 print_char(s) 190 else if s=@"7F then begin 191 print_char(@"5E); print_char(@"5E); print_char(s-@'100); 192 end 193 else if s<@"100 then begin 194 print_char(@"5E); print_char(@"5E); 195 print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10); 196 end 197 else begin {Here is where we generate the strings on the fly.} 198 print_char(@"5E); print_char(@"5E); 199 print_char(@"5E); print_char(@"5E); 200 print_lc_hex(s div @"1000); print_lc_hex((s mod @"1000) div @"100); 201 print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10); 202 end; 203 @<Set newline character to nl@>; 204 return; 205 end; 206j:=str_start(s); 207while j<str_start(s+1) do 208 begin print_char(so(str_pool[j])); incr(j); 209 end; 210exit:end; 211 212@ Control sequence names, file names, and strings constructed with 213\.{\\string} might contain |ASCII_code| values that can't 214be printed using |print_char|. Therefore we use |slow_print| for them: 215 216@<Basic print...@>= 217procedure slow_print(@!s:integer); {prints string |s|} 218var j:pool_pointer; {current character code position} 219begin if (s>=str_ptr) or (s<=biggest_char) then print(s) 220else begin j:=str_start(s); 221 while j<str_start(s+1) do 222 begin print(so(str_pool[j])); incr(j); 223 end; 224 end; 225end; 226@y 227procedure print(@!s:integer); {prints string |s|} 228label exit; 229var j:pool_pointer; {current character code position} 230@!nl:integer; {new-line character to restore} 231@!l:integer; {for printing 16-bit characters} 232begin if s>=str_ptr then s:="???" {this can't happen} 233@.???@> 234else if s<biggest_char then 235 if s<0 then s:="???" {can't happen} 236 else begin if selector>pseudo then 237 begin print_char(s); return; {internal strings are not expanded} 238 end; 239 if (@<Character |s| is the current new-line character@>) then 240 if selector<pseudo then 241 begin print_ln; return; 242 end; 243 nl:=new_line_char; 244 @<Set newline character to -1@>; 245 if s<@"20 then begin 246 print_char(@"5E); print_char(@"5E); print_char(s+@'100); 247 end 248 else if s<@"7F then 249 print_char(s) 250 else if s=@"7F then begin 251 print_char(@"5E); print_char(@"5E); print_char(s-@'100); 252 end 253 else if s<@"100 then begin 254 print_char(@"5E); print_char(@"5E); 255 print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10); 256 end 257 else begin {Here is where we generate the strings on the fly.} 258 print_char(@"5E); print_char(@"5E); 259 print_char(@"5E); print_char(@"5E); 260 print_lc_hex(s div @"1000); print_lc_hex((s mod @"1000) div @"100); 261 print_lc_hex((s mod @"100) div @"10); print_lc_hex(s mod @"10); 262 end; 263 @<Set newline character to nl@>; 264 return; 265 end; 266j:=str_start(s); 267while j<str_start(s+1) do 268 begin print_char(so(str_pool[j])); incr(j); 269 end; 270exit:end; 271 272procedure print_nl(@!s:str_number); {prints string |s| at beginning of line} 273begin if ((term_offset>0)and(odd(selector)))or@| 274 ((file_offset>0)and(selector>=log_only)) then print_ln; 275print(s); 276end; 277 278procedure overflow_ocp_buf_size; forward; 279procedure overflow_ocp_stack_size; forward; 280 281procedure omega_print(s:str_number); 282var new_s:str_number; 283 om_mode,om_translation:integer; 284 j:integer; 285begin 286om_mode:=no_mode; 287om_translation:=0; 288case selector of 289term_and_log,log_only,term_only: begin 290 om_mode:=term_out_mode; 291 if om_mode<>no_mode then om_translation:=term_out_translation; 292 end; 293no_print,pseudo,new_string: do_nothing; 294othercases begin 295 om_mode:=write_file_mode[selector]; 296 if om_mode<>no_mode then om_translation:=write_file_translation[selector]; 297 end 298endcases; 299 300if (om_mode=no_mode) or 301 ((om_mode=onebyte_mode) and (om_translation=0)) then 302 begin 303 j:=str_start(s); 304 while j<str_start(s+1) do begin 305 new_s:=so(str_pool[j]); 306 if new_s<@"20 then begin 307 print_char(@"5E); print_char(@"5E); print_char(new_s+@'100); 308 end 309 else if new_s<@"7F then 310 print_char(new_s) 311 else if new_s=@"7F then begin 312 print_char(@"5E); print_char(@"5E); print_char(new_s-@'100); 313 end 314 else if new_s<@"100 then begin 315 print_char(@"5E); print_char(@"5E); 316 print_lc_hex((new_s mod @"100) div @"10); print_lc_hex(new_s mod @"10); 317 end 318 else begin {Here is where we generate the strings on the fly.} 319 print_char(@"5E); print_char(@"5E); 320 print_char(@"5E); print_char(@"5E); 321 print_lc_hex(new_s div @"1000); 322 print_lc_hex((new_s mod @"1000) div @"100); 323 print_lc_hex((new_s mod @"100) div @"10); 324 print_lc_hex(new_s mod @"10); 325 end; 326 incr(j); 327 end; 328 end 329else begin 330 if om_translation=0 then begin 331 j:=str_start(s); 332 otp_counter:=1; 333 while j<str_start(s+1) do begin 334 otp_output_buf[otp_counter]:=so(str_pool[j]); 335 incr(otp_counter); 336 incr(j); 337 end; 338 otp_output_end:=otp_counter; 339 end 340 else begin 341 otp_input_start:=0; 342 otp_input_last:=0; 343 otp_stack_used:=0; 344 otp_stack_last:=0; 345 otp_stack_new:=0; 346 otp_output_end:=0; 347 otp_pc:=0; 348 otp_finished:=false; 349 otp_calc_ptr:=0; 350 otp_calcs[otp_calc_ptr]:=0; 351 otp_state_ptr:=0; 352 otp_states[otp_state_ptr]:=0; 353 otp_input_ocp:=om_translation; 354 j:=str_start(s); 355 otp_counter:=1; 356 while j<str_start(s+1) do begin 357 otp_input_buf[otp_counter]:=so(str_pool[j]); 358 incr(otp_counter); 359 incr(j); 360 end; 361 otp_input_end:=otp_counter; 362 while not otp_finished do 363 @<Run the OTP program@>; 364 end; 365 for otp_counter:=1 to (otp_output_end-1) do begin 366 new_s:=otp_output_buf[otp_counter]; 367 if (om_mode<twobyte_mode) and (new_s>255) then 368 begin 369 print_char(@"5E); print_char(@"5E); 370 print_char(@"5E); print_char(@"5E); 371 print_lc_hex(new_s div @"1000); 372 print_lc_hex((new_s mod @"1000) div @"100); 373 print_lc_hex((new_s mod @"100) div @"10); 374 print_lc_hex(new_s mod @"10); 375 end 376 else 377 print_char(new_s); 378 end; 379 end; 380end; 381 382@ Control sequence names, file names, and strings constructed with 383\.{\\string} might contain |ASCII_code| values that can't 384be printed using |print_char|. Therefore we use |slow_print| for them: 385 386@<Basic print...@>= 387procedure slow_print(@!s:integer); {prints string |s|} 388begin if (s>=str_ptr) or (s<=biggest_char) then print(s) 389else omega_print(s); 390end; 391@z 392%--------------------------------------- 393@x [5] - Omega Translation 394procedure print_nl(@!s:str_number); {prints string |s| at beginning of line} 395begin if ((term_offset>0)and(odd(selector)))or@| 396 ((file_offset>0)and(selector>=log_only)) then print_ln; 397print(s); 398end; 399@y 400@z 401%--------------------------------------- 402@x [5] m.71 l.1694 - Omega Translation 403if not input_ln(term_in,true) then fatal_error("End of file on the terminal!"); 404@y 405if not new_input_ln(term_in,term_in_mode,term_in_translation,true) 406then fatal_error("End of file on the terminal!"); 407@z 408%--------------------------------------- 409@x [15] m.209 l.4170 - Omega Translation 410@d max_command=ocp_trace_level 411 {the largest command code seen at |big_switch|} 412@y 413@d char_trans=ocp_trace_level+1 414@d char_mode=char_trans+1 415@d max_command=char_mode 416 {the largest command code seen at |big_switch|} 417@z 418%--------------------------------------- 419@x [17] m.230 l.4722 - Omega Translation 420@d toks_base=ocp_active_base+max_active_ocp_lists 421 {table of |number_regs| token list registers} 422@y 423@d ocp_input_mode_base=ocp_active_base+max_active_ocp_lists 424@d ocp_input_onebyte_translation_base =ocp_input_mode_base+ 1 425@d ocp_input_ebcdic_translation_base =ocp_input_mode_base+ 2 426@d ocp_input_twobyte_translation_base =ocp_input_mode_base+ 3 427@d ocp_input_twobyteLE_translation_base =ocp_input_mode_base+ 4 428 429@d ocp_output_mode_base =ocp_input_mode_base+ 5 430@d ocp_output_onebyte_translation_base =ocp_input_mode_base+ 6 431@d ocp_output_ebcdic_translation_base =ocp_input_mode_base+ 7 432@d ocp_output_twobyte_translation_base =ocp_input_mode_base+ 8 433@d ocp_output_twobyteLE_translation_base =ocp_input_mode_base+ 9 434 435@d toks_base =ocp_input_mode_base+10 436@z 437%--------------------------------------- 438@x [22] m.304 l.6535 - Omega Translation 439@!input_file : array[1..max_in_open] of alpha_file; 440@y 441@!input_file : array[1..max_in_open] of alpha_file; 442@!input_file_mode : array[1..max_in_open] of halfword; 443@!input_file_translation : array[1..max_in_open] of halfword; 444@z 445%--------------------------------------- 446@x [23] m.331 l.7066 - Omega Translation 447param_ptr:=0; max_param_stack:=0; 448@y 449param_ptr:=0; max_param_stack:=0; 450geq_define(ocp_input_mode_base,data,1); 451term_in_mode:=equiv(ocp_input_mode_base); 452term_out_mode:=equiv(ocp_input_mode_base); 453if term_in_mode>0 454then term_in_translation:= 455 equiv(ocp_input_onebyte_translation_base+term_in_mode-1); 456if term_out_mode>0 457then term_out_translation:= 458 equiv(ocp_output_onebyte_translation_base+term_in_mode-1); 459@z 460%--------------------------------------- 461@x [24] m.362 l.7066 - Omega Translation 462 begin if input_ln(cur_file,true) then {not end of file} 463@y 464 begin if new_input_ln(cur_file,input_file_mode[index], 465 input_file_translation[index],true) then {not end of file} 466@z 467%--------------------------------------- 468@x [27] m.480 l.9411 - Omega Translation 469@!read_file:array[0..15] of alpha_file; {used for \.{\\read}} 470@y 471@!read_file:array[0..15] of alpha_file; {used for \.{\\read}} 472@!read_file_mode:array[0..15] of halfword; 473@!read_file_translation:array[0..15] of halfword; 474@z 475%--------------------------------------- 476@x [27] m.485 l.9475 - Omega Translation 477@<Input the first line of |read_file[m]|@>= 478if input_ln(read_file[m],false) then read_open[m]:=normal 479else begin a_close(read_file[m]); read_open[m]:=closed; 480 end 481@y 482@<Input the first line of |read_file[m]|@>= 483begin read_file_mode[m]:= 484 get_file_mode(read_file[m], equiv(ocp_input_mode_base)); 485if read_file_mode[m]>0 486then read_file_translation[m]:= 487 equiv(ocp_input_onebyte_translation_base+read_file_mode[m]-1); 488if new_input_ln(read_file[m],read_file_mode[m], 489 read_file_translation[m],false) then read_open[m]:=normal 490else begin a_close(read_file[m]); read_open[m]:=closed; 491 end 492end 493@z 494%--------------------------------------- 495@x [27] m.486 l.9484 - Omega Translation 496begin if not input_ln(read_file[m],true) then 497 begin a_close(read_file[m]); read_open[m]:=closed; 498@y 499begin if not new_input_ln(read_file[m], 500read_file_mode[m],read_file_translation[m],true) then 501 begin a_close(read_file[m]); read_open[m]:=closed; 502@z 503%--------------------------------------- 504@x [29] m.538 l.10371 - Omega Translation 505begin line:=1; 506if input_ln(cur_file,false) then do_nothing; 507@y 508begin line:=1; 509input_file_mode[index]:= 510 get_file_mode(cur_file, equiv(ocp_input_mode_base)); 511if input_file_mode[index]>0 512then input_file_translation[index]:= 513 equiv(ocp_input_onebyte_translation_base+input_file_mode[index]-1); 514if new_input_ln(cur_file,input_file_mode[index], 515 input_file_translation[index],false) then do_nothing; 516@z 517%--------------------------------------- 518@x [49] m.1210 l.22629 - Omega Translation 519any_mode(ocp_trace_level) : prefixed_command; 520@y 521any_mode(ocp_trace_level) : prefixed_command; 522any_mode(char_mode) : do_char_mode; 523any_mode(char_trans) : do_char_translation; 524@z 525%--------------------------------------- 526@x [49] m.1343 l.24928 - Omega Translation 527@!write_file:array[0..15] of alpha_file; 528@y 529@!write_file:array[0..15] of alpha_file; 530@!write_file_mode:array[0..15] of halfword; 531@!write_file_translation:array[0..15] of halfword; 532@z 533%--------------------------------------- 534@x 535@* \[54] $\Omega$ changes. 536 537@y 538@* \[54] $\Omega$ changes. 539 540@ Here we do the main work required for reading and interpreting 541 $\Omega$ Input Translation Processes. 542 543@ @<Put each...@>= 544primitive("InputTranslation", char_trans, trans_input); 545primitive("OutputTranslation", char_trans, trans_output); 546primitive("DefaultInputTranslation", char_trans, trans_default_input); 547primitive("DefaultOutputTranslation", char_trans, trans_default_output); 548primitive("noInputTranslation", char_trans, trans_no_input); 549primitive("noOutputTranslation", char_trans, trans_no_output); 550primitive("noDefaultInputTranslation", char_trans, trans_no_default_input); 551primitive("noDefaultOutputTranslation", char_trans, trans_no_default_output); 552primitive("InputMode", char_mode, mode_input); 553primitive("OutputMode", char_mode, mode_output); 554primitive("DefaultInputMode", char_mode, mode_default_input); 555primitive("DefaultOutputMode", char_mode, mode_default_output); 556primitive("noInputMode", char_mode, mode_no_input); 557primitive("noOutputMode", char_mode, mode_no_output); 558primitive("noDefaultInputMode", char_mode, mode_no_default_input); 559primitive("noDefaultOutputMode", char_mode, mode_no_default_output); 560 561geq_define(ocp_input_onebyte_translation_base, data, 0); 562geq_define(ocp_input_ebcdic_translation_base, data, 0); 563geq_define(ocp_input_twobyte_translation_base, data, 0); 564geq_define(ocp_input_twobyteLE_translation_base, data, 0); 565geq_define(ocp_input_mode_base, data, 0); 566 567geq_define(ocp_output_onebyte_translation_base, data, 0); 568geq_define(ocp_output_ebcdic_translation_base, data, 0); 569geq_define(ocp_output_twobyte_translation_base, data, 0); 570geq_define(ocp_output_twobyteLE_translation_base, data, 0); 571geq_define(ocp_output_mode_base, data, 0); 572 573@ @<Cases of |print_cmd_chr|...@>= 574char_trans: 575 case chr_code of 576 trans_input: print_esc("InputTranslation"); 577 trans_output: print_esc("OutputTranslation"); 578 trans_default_input: print_esc("DefaultInputTranslation"); 579 trans_default_output: print_esc("DefaultOutputTranslation"); 580 trans_no_input: print_esc("noInputTranslation"); 581 trans_no_output: print_esc("noOutputTranslation"); 582 trans_no_default_input: print_esc("noDefaultInputTranslation"); 583 trans_no_default_output: print_esc("noDefaultOutputTranslation"); 584 end; 585char_mode: 586 case chr_code of 587 mode_input: print_esc("InputMode"); 588 mode_output: print_esc("OutputMode"); 589 mode_default_input: print_esc("DefaultInputMode"); 590 mode_default_output: print_esc("DefaultOutputMode"); 591 mode_no_input: print_esc("noInputMode"); 592 mode_no_output: print_esc("noOutputMode"); 593 mode_no_default_input: print_esc("noDefaultInputMode"); 594 mode_no_default_output: print_esc("noDefaultOutputMode"); 595 end; 596 597@ @<Declare subprocedures for |prefixed_command|@>= 598procedure scan_file_referrent; 599begin 600if scan_keyword("currentfile") then cur_val:=max_halfword 601else scan_int; 602end; 603 604procedure scan_mode; 605begin 606if scan_keyword("onebyte") then cur_val:=onebyte_mode 607else if scan_keyword("ebcdic") then cur_val:=ebcdic_mode 608else if scan_keyword("twobyte") then cur_val:=twobyte_mode 609else if scan_keyword("twobyteLE") then cur_val:=twobyteLE_mode 610else begin print_err("Invalid input mode"); cur_val:=0; end; 611end; 612 613procedure do_char_translation; 614var kind:halfword; 615 fileref:halfword; 616 moderef:halfword; 617 ocpref:halfword; 618begin 619fileref:=0; 620moderef:=0; 621ocpref:=0; 622kind:=cur_chr; 623if (kind mod 4) <= 1 then begin 624 scan_file_referrent; 625 fileref:=cur_val; 626 end 627else begin 628 scan_mode; 629 moderef:=cur_val; 630 end; 631if kind < 4 then begin 632 scan_ocp_ident; 633 ocpref:=cur_val; 634 end; 635case (kind mod 4) of 636 trans_input: begin 637 if (fileref>=0) and (fileref<=15) then begin 638 read_file_translation[fileref]:=ocpref; 639 end 640 else if fileref<>max_halfword then begin 641 term_in_translation:=ocpref; 642 end 643 else begin 644 base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input; 645 while state = token_list do 646 begin 647 decr(base_ptr); 648 cur_input:=input_stack[base_ptr]; 649 end; 650 if name>17 then input_file_translation[index]:=ocpref; 651 cur_input:=input_stack[input_ptr]; 652 end; 653 end; 654 trans_output: begin 655 if (fileref>=0) and (fileref<=15) then begin 656 write_file_translation[fileref]:=ocpref; 657 end 658 else begin 659 term_out_translation:=ocpref; 660 end; 661 end; 662 trans_default_input: begin 663 geq_define(ocp_input_mode_base+moderef,data,ocpref); 664 end; 665 trans_default_output: begin 666 geq_define(ocp_output_mode_base+moderef,data,ocpref); 667 end; 668 end; 669end; 670 671procedure do_char_mode; 672var kind:halfword; 673 fileref:halfword; 674 moderef:halfword; 675begin 676fileref:=0; 677moderef:=0; 678kind:=cur_chr; 679if (kind mod 4) <= 1 then begin 680 scan_file_referrent; 681 fileref:=cur_val; 682 end; 683if kind < 4 then begin 684 scan_mode; 685 moderef:=cur_val; 686 end; 687case (kind mod 4) of 688 trans_input: begin 689 if (fileref>=0) and (fileref<=15) then begin 690 read_file_mode[fileref]:=moderef; 691 end 692 else if fileref<>max_halfword then begin 693 term_in_mode:=moderef; 694 end 695 else begin 696 base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input; 697 while state = token_list do 698 begin 699 decr(base_ptr); 700 cur_input:=input_stack[base_ptr]; 701 end; 702 if name>17 then input_file_mode[index]:=moderef; 703 cur_input:=input_stack[input_ptr]; 704 end; 705 end; 706 trans_output: begin 707 if (fileref>=0) and (fileref<=15) then begin 708 write_file_mode[fileref]:=moderef; 709 end 710 else begin 711 term_out_mode:=moderef; 712 end; 713 end; 714 trans_default_input: begin 715 geq_define(ocp_input_mode_base,data,moderef); 716 end; 717 trans_default_output: begin 718 geq_define(ocp_output_mode_base,data,moderef); 719 end; 720 end; 721end; 722 723function p_new_input_ln(f:alpha_file; 724the_mode,translation:halfword; 725bypass_eoln:boolean):boolean; 726begin 727if (the_mode=no_mode) or ((the_mode=onebyte_mode) and (translation=0)) 728then p_new_input_ln:=input_ln(f,bypass_eoln) 729else if not newinputline(f,the_mode,bypass_eoln) 730then p_new_input_ln:=false 731else if translation=0 then 732begin 733 if (first+otp_input_end)>=buf_size then overflow("buffer size", buf_size); 734 state:=new_line; 735 start:=first; 736 last:=start; 737 loc:=start; 738 for otp_counter:=1 to otp_input_end do 739 begin 740 buffer[last]:=otp_input_buf[otp_counter]; 741 incr(last); 742 end; 743 while buffer[last-1]=' ' do decr(last); 744 limit:=last-1; 745 p_new_input_ln:=true 746end 747else 748begin 749 otp_input_start:=0; 750 otp_input_last:=0; 751 otp_stack_used:=0; 752 otp_stack_last:=0; 753 otp_stack_new:=0; 754 otp_output_end:=0; 755 otp_pc:=0; 756 otp_finished:=false; 757 otp_calc_ptr:=0; 758 otp_calcs[otp_calc_ptr]:=0; 759 otp_state_ptr:=0; 760 otp_states[otp_state_ptr]:=0; 761 otp_input_ocp:=translation; 762 while not otp_finished do 763 @<Run the OTP program@>; 764 if (first+otp_output_end)>=buf_size then overflow("buffer size", buf_size); 765 state:=new_line; 766 start:=first; 767 last:=start; 768 loc:=start; 769 for otp_counter:=1 to otp_output_end do 770 begin 771 buffer[last]:=otp_output_buf[otp_counter]; 772 incr(last); 773 end; 774 while buffer[last-1]=' ' do decr(last); 775 limit:=last-1; 776 p_new_input_ln:=true 777end 778end; 779 780 781@z 782%--------------------------------------- 783