3
Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
5
This file is part of LuaTeX.
7
LuaTeX is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2 of the License, or (at your
10
option) any later version.
12
LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU General Public License along
18
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
25
static const char _svn_version[] =
26
"$Id: runocp.c 3261 2009-12-18 11:38:21Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/ocp/runocp.c $";
28
memory_word active_info[(active_mem_size + 1)];
29
active_index active_min_ptr = 0; /* first unused word of |active_info| */
30
active_index active_max_ptr = 0; /* last unused word of |active_info| */
31
active_index active_real = 0;
33
static ocp_list_index holding[(active_mem_size + 1)] = { 0 };
35
/* Here we do the main work required for reading and interpreting
36
$\Omega$ Compiled Translation Processes.*/
38
#define ocp_list_id_text(A) cs_text(ocp_list_id_base+(A))
40
#define ocp_active_min_ptr_base (ocp_active_number_base+1)
41
#define ocp_active_max_ptr_base (ocp_active_min_ptr_base+1)
42
#define ocp_active_base (ocp_active_max_ptr_base+1)
45
/* Here are all the instructions in our mini-assembler. */
67
otp_state_change = 20,
80
otp_goto_no_advance = 33,
86
#define check_buffer() do { \
87
if (last==buf_size-2) { \
88
check_buffer_overflow(buf_size+4); \
93
Of course we want to define macros that suppress the detail of how ocp
94
information is actually packed, so that we don't have to write things like
95
$$\hbox{|ocp_info[k+ocp_info[j+ocp_state_base[i]]]|}$$
96
too often. The \.{WEB} definitions here make |ocp_state_entry(i)(j)(k)|
97
(|ocp_table_entry(i)(j)(k)|) the |k|-th word in the |j|-th state (table)
102
#define ocp_state_entry(A,B,C) ocp_tables[(A)][ocp_tables[(A)][ocp_state_base((A))+((B)*2)]+(C)]
104
#define ocp_state_no(A,B) ocp_tables[(A)][ocp_state_base(A)+((B)*2)+1]
106
#define ocp_table_entry(A,B,C) ocp_tables[(A)][ocp_tables[(A)][ocp_table_base((A))+(B)*2]+(C)]
108
#define ocp_table_no(A,B) ocp_tables[(A)][ocp_table_base((A))+((B)*2)+1]
110
#define otp_cur_state otp_states[otp_state_ptr]
112
#define tsuccumb pdftex_fail
114
halfword otp_init_input_start;
115
halfword otp_init_input_last;
116
halfword otp_init_input_end;
117
quarterword *otp_init_input_buf;
119
halfword otp_input_start;
120
halfword otp_input_last;
121
halfword otp_input_end;
122
quarterword *otp_input_buf;
124
halfword otp_output_end;
125
quarterword *otp_output_buf;
127
halfword otp_stack_used;
128
halfword otp_stack_last;
129
halfword otp_stack_new;
130
quarterword *otp_stack_buf;
134
halfword otp_calc_ptr;
136
halfword otp_state_ptr;
137
halfword *otp_states;
139
halfword otp_input_char;
140
halfword otp_calculated_char;
141
halfword otp_no_input_chars;
143
halfword otp_instruction;
146
halfword otp_first_arg;
147
halfword otp_second_arg;
149
halfword otp_input_ocp;
151
boolean otp_finished;
156
#define otp_set_instruction() do { \
157
if (otp_pc>=ocp_state_no(otp_input_ocp,otp_cur_state)) { \
158
tsuccumb("bad OCP program -- PC not valid"); \
160
otp_instruction=ocp_state_entry(otp_input_ocp,otp_cur_state,otp_pc); \
161
otp_instr=otp_instruction / 0x1000000; \
162
otp_arg=otp_instruction % 0x1000000; \
166
#define otp_check_char(A) do { \
167
if ((1>(A)) || ((A)>otp_no_input_chars)) { \
168
tsuccumb("right hand side of OCP expression is bad"); \
173
#define otp_get_char(A) do { \
174
otp_check_char((A)); \
175
if ((A)>otp_stack_last) { \
176
otp_calculated_char=otp_input_buf[otp_input_start+(A)-otp_stack_last]; \
178
otp_calculated_char=otp_stack_buf[(A)]; \
183
void overflow_ocp_buf_size(void)
185
overflow("ocp_buf_size", ocp_buf_size);
188
void overflow_ocp_stack_size(void)
190
overflow("ocp_stack_size", ocp_stack_size);
195
halfword otp_counter;
196
otp_set_instruction();
198
/* Run the |otp_right| instructions */
199
case otp_right_output:
200
incr(otp_output_end);
201
if (otp_output_end > ocp_buf_size)
202
overflow_ocp_buf_size();
203
otp_output_buf[otp_output_end] = otp_calcs[otp_calc_ptr];
208
incr(otp_output_end);
209
if (otp_output_end > ocp_buf_size)
210
overflow_ocp_buf_size();
211
otp_output_buf[otp_output_end] = otp_arg;
215
otp_get_char(otp_arg);
216
incr(otp_output_end);
217
if (otp_output_end > ocp_buf_size)
218
overflow_ocp_buf_size();
219
otp_output_buf[otp_output_end] = otp_calculated_char;
222
case otp_right_lchar:
223
otp_get_char(otp_no_input_chars - otp_arg);
224
incr(otp_output_end);
225
if (otp_output_end > ocp_buf_size)
226
overflow_ocp_buf_size();
227
otp_output_buf[otp_output_end] = otp_calculated_char;
231
otp_first_arg = otp_arg + 1;
233
otp_set_instruction();
234
otp_second_arg = otp_no_input_chars - otp_arg;
235
for (otp_counter = otp_first_arg; otp_counter <= otp_second_arg;
237
otp_get_char(otp_counter);
238
incr(otp_output_end);
239
if (otp_output_end > ocp_buf_size)
240
overflow_ocp_buf_size();
241
otp_output_buf[otp_output_end] = otp_calculated_char;
246
/* Run the |otp_pback| instructions */
247
case otp_pback_output:
249
if (otp_stack_new >= ocp_stack_size)
250
overflow_ocp_stack_size();
251
otp_stack_buf[otp_stack_new] = otp_calcs[otp_calc_ptr];
257
if (otp_stack_new >= ocp_stack_size)
258
overflow_ocp_stack_size();
259
otp_stack_buf[otp_stack_new] = otp_arg;
263
otp_get_char(otp_arg);
265
if (otp_stack_new >= ocp_stack_size)
266
overflow_ocp_stack_size();
267
otp_stack_buf[otp_stack_new] = otp_calculated_char;
270
case otp_pback_lchar:
271
otp_get_char(otp_no_input_chars - otp_arg);
273
if (otp_stack_new >= ocp_stack_size)
274
overflow_ocp_stack_size();
275
otp_stack_buf[otp_stack_new] = otp_calculated_char;
279
otp_first_arg = otp_arg + 1;
281
otp_set_instruction();
282
otp_second_arg = otp_no_input_chars - otp_arg;
283
for (otp_counter = otp_first_arg; otp_counter <= otp_second_arg;
285
otp_get_char(otp_counter);
287
if (otp_stack_new >= ocp_stack_size)
288
overflow_ocp_stack_size();
289
otp_stack_buf[otp_stack_new] = otp_calculated_char;
294
/* Run the arithmetic instructions */
296
otp_calcs[otp_calc_ptr - 1] =
297
otp_calcs[otp_calc_ptr - 1] + otp_calcs[otp_calc_ptr];
302
otp_calcs[otp_calc_ptr - 1] =
303
otp_calcs[otp_calc_ptr - 1] - otp_calcs[otp_calc_ptr];
308
otp_calcs[otp_calc_ptr - 1] =
309
otp_calcs[otp_calc_ptr - 1] * otp_calcs[otp_calc_ptr];
314
otp_calcs[otp_calc_ptr - 1] =
315
otp_calcs[otp_calc_ptr - 1] / otp_calcs[otp_calc_ptr];
320
otp_calcs[otp_calc_ptr - 1] =
321
otp_calcs[otp_calc_ptr - 1] % otp_calcs[otp_calc_ptr];
326
if (otp_calcs[otp_calc_ptr] >=
327
ocp_table_no(otp_input_ocp, otp_calcs[otp_calc_ptr - 1])) {
328
tsuccumb("bad OCP program -- table index not valid");
330
otp_calcs[otp_calc_ptr - 1] =
331
ocp_table_entry(otp_input_ocp, otp_calcs[otp_calc_ptr - 1],
332
otp_calcs[otp_calc_ptr]);
338
if (otp_calc_ptr >= ocp_stack_size)
339
overflow_ocp_stack_size();
340
otp_calcs[otp_calc_ptr] = otp_arg;
344
otp_get_char(otp_arg);
346
if (otp_calc_ptr >= ocp_stack_size)
347
overflow_ocp_stack_size();
348
otp_calcs[otp_calc_ptr] = otp_calculated_char;
352
otp_get_char(otp_no_input_chars - otp_arg);
354
if (otp_calc_ptr >= ocp_stack_size)
355
overflow_ocp_stack_size();
356
otp_calcs[otp_calc_ptr] = otp_calculated_char;
360
/* Run the |otp_state| instructions */
361
case otp_state_change:
362
otp_input_start = otp_input_last;
363
for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
365
otp_stack_buf[otp_counter] =
366
otp_stack_buf[otp_counter + otp_stack_used];
368
otp_stack_new = otp_stack_new - otp_stack_used;
369
otp_stack_last = otp_stack_new;
371
otp_states[otp_state_ptr] = otp_arg;
375
otp_input_start = otp_input_last;
376
for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
378
otp_stack_buf[otp_counter] =
379
otp_stack_buf[otp_counter + otp_stack_used];
381
otp_stack_new = otp_stack_new - otp_stack_used;
382
otp_stack_last = otp_stack_new;
385
if (otp_state_ptr >= ocp_stack_size)
386
overflow_ocp_stack_size();
387
otp_states[otp_state_ptr] = otp_arg;
391
otp_input_start = otp_input_last;
392
for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
394
otp_stack_buf[otp_counter] =
395
otp_stack_buf[otp_counter + otp_stack_used];
397
otp_stack_new = otp_stack_new - otp_stack_used;
398
otp_stack_last = otp_stack_new;
400
if (otp_state_ptr > 0)
405
/* Run the |otp_left| instructions */
407
otp_input_start = otp_input_last;
408
otp_input_last = otp_input_start;
410
if ((otp_stack_last == 0) && (otp_input_last >= otp_input_end)) {
412
} else if ((otp_stack_used < otp_stack_last)) {
413
incr(otp_stack_used); /* no overflow problem */
414
otp_input_char = otp_stack_buf[otp_stack_used];
415
otp_no_input_chars = 1;
418
incr(otp_input_last); /* no overflow problem */
419
otp_input_char = otp_input_buf[otp_input_last];
420
otp_no_input_chars = 1;
424
case otp_left_return:
425
otp_input_last = otp_input_start;
427
if ((otp_stack_used < otp_stack_last)) {
428
incr(otp_stack_used); /* no overflow problem */
429
otp_input_char = otp_stack_buf[otp_stack_used];
430
otp_no_input_chars = 1;
433
incr(otp_input_last); /* no overflow problem */
434
otp_input_char = otp_input_buf[otp_input_last];
435
otp_no_input_chars = 1;
439
case otp_left_backup:
440
if (otp_input_start < otp_input_last) {
441
decr(otp_input_last);
442
otp_input_char = otp_input_buf[otp_input_last];
444
decr(otp_stack_used);
445
otp_input_char = otp_stack_buf[otp_stack_used];
447
decr(otp_no_input_chars);
451
/* Run the |otp_goto| instructions */
456
otp_first_arg = otp_arg;
458
otp_set_instruction();
459
if (otp_input_char != otp_first_arg) {
466
otp_first_arg = otp_arg;
468
otp_set_instruction();
469
if (otp_input_char == otp_first_arg) {
476
otp_first_arg = otp_arg;
478
otp_set_instruction();
479
if (otp_input_char < otp_first_arg) {
486
otp_first_arg = otp_arg;
488
otp_set_instruction();
489
if (otp_input_char <= otp_first_arg) {
496
otp_first_arg = otp_arg;
498
otp_set_instruction();
499
if (otp_input_char > otp_first_arg) {
506
otp_first_arg = otp_arg;
508
otp_set_instruction();
509
if (otp_input_char >= otp_first_arg) {
515
case otp_goto_no_advance:
516
if (otp_stack_used < otp_stack_last) {
517
incr(otp_stack_used); /* no overflow problem */
518
otp_input_char = otp_stack_buf[otp_stack_used];
519
incr(otp_no_input_chars); /* no overflow problem */
521
} else if (otp_input_last >= otp_input_end) {
524
incr(otp_input_last); /* no overflow problem */
525
otp_input_char = otp_input_buf[otp_input_last];
526
incr(otp_no_input_chars); /* no overflow problem */
531
if (otp_input_last == 0) {
538
if (otp_input_last >= otp_input_end) {
545
/* Run the |otp_stop| instruction */
547
otp_input_start = otp_input_last;
548
for (otp_counter = 1; otp_counter <= (otp_stack_new - otp_stack_used);
550
otp_stack_buf[otp_counter] =
551
otp_stack_buf[otp_counter + otp_stack_used];
553
otp_stack_new = otp_stack_new - otp_stack_used;
554
otp_stack_last = otp_stack_new;
560
tsuccumb("bad OCP program -- unknown instruction");
565
void run_external_ocp(char *external_ocp_name)
573
char command_line[400];
580
# define null_string(s) ((s == NULL) || (*s == '\0'))
582
tempenv = getenv("TMPDIR");
583
if (null_string(tempenv))
584
tempenv = getenv("TEMP");
585
if (null_string(tempenv))
586
tempenv = getenv("TMP");
587
if (null_string(tempenv))
588
tempenv = "c:/tmp"; /* "/tmp" is not good if we are on a CD-ROM */
589
in_file_name = concat(tempenv, "/__aleph__in__XXXXXX");
590
mktemp(in_file_name);
591
in_file = fopen(in_file_name, FOPEN_WBIN_MODE);
593
in_file_name = strdup("/tmp/__aleph__in__XXXXXX");
594
in_file_fd = mkstemp(in_file_name);
595
in_file = fdopen(in_file_fd, FOPEN_WBIN_MODE);
599
for (i = 1; i <= otp_input_end; i++) {
600
c = otp_input_buf[i];
602
fprintf(stderr, "Aleph does not currently support 31-bit chars\n");
606
fputc(0xfc | ((c >> 30) & 0x1), in_file);
607
fputc(0x80 | ((c >> 24) & 0x3f), in_file);
608
fputc(0x80 | ((c >> 18) & 0x3f), in_file);
609
fputc(0x80 | ((c >> 12) & 0x3f), in_file);
610
fputc(0x80 | ((c >> 6) & 0x3f), in_file);
611
fputc(0x80 | (c & 0x3f), in_file);
612
} else if (c > 0x200000) {
613
fputc(0xf8 | ((c >> 24) & 0x3), in_file);
614
fputc(0x80 | ((c >> 18) & 0x3f), in_file);
615
fputc(0x80 | ((c >> 12) & 0x3f), in_file);
616
fputc(0x80 | ((c >> 6) & 0x3f), in_file);
617
fputc(0x80 | (c & 0x3f), in_file);
618
} else if (c > 0x10000) {
619
fputc(0xf0 | ((c >> 18) & 0x7), in_file);
620
fputc(0x80 | ((c >> 12) & 0x3f), in_file);
621
fputc(0x80 | ((c >> 6) & 0x3f), in_file);
622
fputc(0x80 | (c & 0x3f), in_file);
623
} else if (c > 0x800) {
624
fputc(0xe0 | ((c >> 12) & 0xf), in_file);
625
fputc(0x80 | ((c >> 6) & 0x3f), in_file);
626
fputc(0x80 | (c & 0x3f), in_file);
627
} else if (c > 0x80) {
628
fputc(0xc0 | ((c >> 6) & 0x1f), in_file);
629
fputc(0x80 | (c & 0x3f), in_file);
631
fputc(c & 0x7f, in_file);
636
#define advance_cin if ((c_in = fgetc(out_file)) == -1) { \
637
fprintf(stderr, "File contains bad char\n"); \
642
out_file_name = concat(tempenv, "/__aleph__out__XXXXXX");
643
mktemp(out_file_name);
644
out_file = fopen(out_file_name, FOPEN_RBIN_MODE);
646
out_file_name = strdup("/tmp/__aleph__out__XXXXXX");
647
out_file_fd = mkstemp(out_file_name);
648
out_file = fdopen(out_file_fd, FOPEN_RBIN_MODE);
651
sprintf(command_line, "%s <%s >%s\n",
652
external_ocp_name + 1, in_file_name, out_file_name);
653
system(command_line);
655
otp_output_buf[otp_output_end] = 0;
656
while ((c_in = fgetc(out_file)) != -1) {
658
c = (c_in & 0x1) << 30;
660
c |= (c_in & 0x3f) << 24;
662
c |= (c_in & 0x3f) << 18;
664
c |= (c_in & 0x3f) << 12;
666
c |= (c_in & 0x3f) << 6;
669
} else if (c_in >= 0xf8) {
670
c = (c_in & 0x3) << 24;
672
c |= (c_in & 0x3f) << 18;
674
c |= (c_in & 0x3f) << 12;
676
c |= (c_in & 0x3f) << 6;
679
} else if (c_in >= 0xf0) {
680
c = (c_in & 0x7) << 18;
682
c |= (c_in & 0x3f) << 12;
684
c |= (c_in & 0x3f) << 6;
687
} else if (c_in >= 0xe0) {
688
c = (c_in & 0xf) << 12;
690
c |= (c_in & 0x3f) << 6;
693
} else if (c_in >= 0x80) {
694
c = (c_in & 0x1f) << 6;
700
otp_output_buf[++otp_output_end] = c;
705
remove(in_file_name);
706
remove(out_file_name);
713
halfword otp_counter;
714
/* The OTP input buffer is an array of 16-bit values.
715
The range |0xD800| \dots |0xDFFF| is used for surrogate pairs,
716
so it cannot be used for simple 16-bit values like it is in
717
Omega, and incompatibility with Aleph is unavoidable.
720
otp_init_input_end = 0;
721
while ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd) ||
722
(cur_cmd == char_given_cmd) || (cur_cmd == spacer_cmd)) {
723
incr(otp_init_input_end);
724
if (otp_init_input_end > ocp_buf_size)
725
overflow_ocp_buf_size();
726
/* |cur_chr| can cover the full range |0..0x10FFFF| */
727
if (cur_chr < 0x10000) {
728
otp_init_input_buf[otp_init_input_end] = cur_chr;
730
otp_init_input_buf[otp_init_input_end] =
731
((cur_chr - 0x10000) / 0x400) + 0xD800;
732
incr(otp_init_input_end);
733
if (otp_init_input_end > ocp_buf_size)
734
overflow_ocp_buf_size();
735
otp_init_input_buf[otp_init_input_end] =
736
((cur_chr - 0x10000) % 0x400) + 0xDC00;
739
if ((cur_cmd != letter_cmd) && (cur_cmd != other_char_cmd) &&
740
(cur_cmd != char_given_cmd)) {
742
if (cur_cmd == char_num_cmd) {
744
cur_cmd = other_char_cmd;
750
otp_input_end = otp_init_input_end;
751
for (otp_i = 0; otp_i <= otp_init_input_end; otp_i++) {
752
otp_input_buf[otp_i] = otp_init_input_buf[otp_i];
755
otp_input_ocp = active_ocp(active_real);
756
if (otp_input_ocp == 0) {
757
tex_error("Null ocp being used: all input lost", NULL);
759
} else if (ocp_external(otp_input_ocp) == 0) {
767
otp_finished = false;
769
otp_calcs[otp_calc_ptr] = 0;
771
otp_states[otp_state_ptr] = 0;
772
while (!otp_finished)
776
char *cmd = makecstring(ocp_external(otp_input_ocp));
777
char *arg = makecstring(ocp_external_arg(otp_input_ocp));
778
char *cmdline = xmalloc(strlen(cmd) + strlen(arg) + 3);
779
strcpy(cmdline, cmd);
780
strcat(cmdline, " ");
781
strcat(cmdline, arg);
784
run_external_ocp(cmdline);
788
/* The OTP output buffer is an array of 16-bit values. To convert back
789
to the |buffer| it has to be re-encoded into UTF-8.
792
if ((first + otp_output_end) >= ocp_buf_size)
793
overflow_ocp_buf_size();
795
current_ocp_lstack = active_lstack_no(active_real);
796
current_ocp_no = active_counter(active_real);
801
line_catcode_table = DEFAULT_CAT_TABLE;
802
line_partial = false;
803
for (otp_counter = 1; otp_counter <= otp_output_end; otp_counter++) {
804
/* convert back to utf-8 */
805
t = otp_output_buf[otp_counter];
806
if (otp_counter < otp_output_end) {
807
if ((t >= 0xD800) && (t < 0xDC00)) {
808
if ((otp_output_buf[otp_counter + 1] >= 0xDC00)
809
&& (otp_output_buf[otp_counter + 1] < 0xE000)) {
811
t = (t - 0xD800) * 0x400 + (otp_output_buf[otp_counter] -
814
} else if ((t >= 0xDC00) && (t < 0xE000)) {
815
if ((otp_output_buf[otp_counter + 1] >= 0xD800)
816
&& (otp_output_buf[otp_counter + 1] < 0xDC00)) {
818
t = (otp_output_buf[otp_counter] - 0xD800) * 0x400 + (t -
826
} else if (t <= 0x7FF) {
827
buffer[last] = 0xC0 + t / 0x40;
830
buffer[last] = 0x80 + t % 0x40;
831
} else if (t <= 0xFFFF) {
832
buffer[last] = 0xE0 + t / 0x1000;
835
buffer[last] = 0x80 + (t % 0x1000) / 0x40;
838
buffer[last] = 0x80 + (t % 0x1000) % 0x40;
840
buffer[last] = 0xF0 + t / 0x40000;
843
buffer[last] = 0x80 + (t % 0x40000) / 0x1000;
846
buffer[last] = 0x80 + ((t % 0x40000) % 0x1000) / 0x40;
849
buffer[last] = 0x80 + ((t % 0x40000) % 0x1000) % 0x40;
866
void initialize_ocp_buffers(int ocp_buf_size, int ocp_stack_size)
868
otp_init_input_buf = xmallocarray(quarterword, ocp_buf_size);
869
otp_input_buf = xmallocarray(quarterword, ocp_buf_size);
870
otp_output_buf = xmallocarray(quarterword, ocp_buf_size);
871
otp_stack_buf = xmallocarray(quarterword, ocp_stack_size);
872
otp_calcs = xmallocarray(halfword, ocp_stack_size);
873
otp_states = xmallocarray(halfword, ocp_stack_size);
876
boolean is_last_ocp(scaled llstack_no, int counter)
878
active_min_ptr = equiv(ocp_active_min_ptr_base);
879
active_max_ptr = equiv(ocp_active_max_ptr_base);
880
active_real = active_min_ptr;
881
while ((active_real < active_max_ptr) &&
882
(active_lstack_no(active_real) < llstack_no)) {
883
active_real = active_real + 2;
885
while ((active_real < active_max_ptr) &&
886
(active_lstack_no(active_real) == llstack_no) &&
887
(active_counter(active_real) <= counter)) {
888
active_real = active_real + 2;
890
return (active_real == active_max_ptr);
893
void print_active_ocps(void)
896
tprint_nl("Active ocps: [");
898
while (i < active_max_ptr) {
900
print_scaled(active_lstack_no(i));
902
print_int(active_counter(i));
904
print_esc(cs_text(ocp_id_base + active_ocp(i)));
906
if (i != (active_max_ptr - 2))
913
void add_ocp_stack(int min_index, scaled min_value)
919
m = min_value; /* TH: whatever this is .. */
920
p = ocp_list_lstack(holding[min_index]);
921
llstack_no = ocp_list_lstack_no(holding[min_index]);
923
while (!(is_null_ocp_lstack(p))) {
924
active_ocp(active_max_ptr) = ocp_lstack_ocp(p);
925
active_counter(active_max_ptr) = counter;
926
active_lstack_no(active_max_ptr) = llstack_no;
927
p = ocp_lstack_lnext(p);
928
active_max_ptr = active_max_ptr + 2;
929
incr(counter); /* no overflow problem */
933
void active_compile(void)
937
scaled min_stack_ocp;
941
active_min_ptr = active_max_ptr;
942
min_stack_ocp = ocp_maxint;
943
max_active = equiv(ocp_active_number_base) - 1;
944
min_index = max_active; /* TH I hope ... */
945
for (i = max_active; i >= 0; i--) {
946
holding[i] = ocp_list_list[ocp_active_base + i];
947
stack_value = ocp_list_lstack_no(holding[i]);
948
if (stack_value < min_stack_ocp) {
950
min_stack_ocp = stack_value;
953
while (min_stack_ocp < ocp_maxint) {
954
add_ocp_stack(min_index, min_stack_ocp);
955
old_min = min_stack_ocp;
956
min_stack_ocp = ocp_maxint;
957
for (i = max_active; i >= 0; i--) {
958
stack_value = ocp_list_lstack_no(holding[i]);
959
while (old_min == stack_value) {
960
holding[i] = ocp_list_lnext(holding[i]);
961
stack_value = ocp_list_lstack_no(holding[i]);
963
if (stack_value < min_stack_ocp) {
965
min_stack_ocp = stack_value;
971
void do_push_ocp_list(small_number a)
973
halfword ocp_list_no;
976
scan_ocp_list_ident();
977
ocp_list_no = cur_val;
978
old_number = equiv(ocp_active_number_base);
979
define(ocp_active_base + old_number, data_cmd, ocp_list_no);
980
define(ocp_active_number_base, data_cmd, (old_number + 1));
981
if (ocp_trace_level == 1) {
982
tprint_nl("New active ocp list: {");
983
for (i = old_number; i >= 0; i--) {
984
print_esc(ocp_list_id_text(equiv(ocp_active_base + i)));
986
print_ocp_list(ocp_list_list[equiv(ocp_active_base + i)]);
993
define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
994
define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
997
void do_pop_ocp_list(small_number a)
1001
old_number = equiv(ocp_active_number_base);
1002
if (old_number == 0) {
1003
print_err("No active ocp lists to be popped");
1005
define(ocp_active_number_base, data_cmd, (old_number - 1));
1006
if (ocp_trace_level == 1) {
1007
tprint_nl("New active ocp list: {");
1008
for (i = (old_number - 2); i >= 0; i++) {
1009
print_esc(ocp_list_id_text(equiv(ocp_active_base + i)));
1011
print_ocp_list(ocp_list_list[equiv(ocp_active_base + i)]);
1018
define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
1019
define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
1023
void do_clear_ocp_lists(small_number a)
1025
define(ocp_active_number_base, data_cmd, 0);
1027
define(ocp_active_min_ptr_base, data_cmd, active_min_ptr);
1028
define(ocp_active_max_ptr_base, data_cmd, active_max_ptr);
1032
void dump_active_ocp_info(void)
1035
dump_int(active_min_ptr);
1036
dump_int(active_max_ptr);
1037
for (k = 0; k <= active_max_ptr - 1; k++)
1038
dump_wd(active_info[k]);
1039
if (active_max_ptr > 0) {
1041
print_int(active_max_ptr);
1042
tprint(" words of active ocps");
1046
void undump_active_ocp_info(void)
1049
undump_int(active_min_ptr);
1050
/* undump_size(0)(active_mem_size)('active start point')(active_min_ptr); */
1051
undump_int(active_max_ptr);
1052
/* undump_size(0)(active_mem_size)('active mem size')(active_max_ptr); */
1053
for (k = 0; k <= active_max_ptr - 1; k++)
1054
undump_wd(active_info[k]);