diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
commit | f372862c42d234710b6057449b46818e63181c90 (patch) | |
tree | a9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk/web2c/luatexdir/tex/texnodes.c | |
parent | 2dad291ab056f30816e0aea61970f38033c2f6a5 (diff) |
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf
git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex/texnodes.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/texnodes.c | 2892 |
1 files changed, 0 insertions, 2892 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.c deleted file mode 100644 index ca6af731ef1..00000000000 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c +++ /dev/null @@ -1,2892 +0,0 @@ -/* texnodes.c - - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "luatex-api.h" -#include <ptexlib.h> -#include "nodes.h" -#include "commands.h" - -#include "tokens.h" -#undef name - -#define noDEBUG - -static const char _svn_version[] = - "$Id: texnodes.c 2448 2009-06-08 07:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/tex/texnodes.c $"; - -#define append_char(A) str_pool[pool_ptr++]=(A) -#define cur_length (pool_ptr - str_start_macro(str_ptr)) -#define flush_char() pool_ptr-- - -#define stretching 1 -#define shrinking 2 - -#define adjust_pre subtype - -typedef enum { - pdf_dest_xyz = 0, - pdf_dest_fit, - pdf_dest_fith, - pdf_dest_fitv, - pdf_dest_fitb, - pdf_dest_fitbh, - pdf_dest_fitbv, - pdf_dest_fitr, -} pdf_destination_types; - - -#define obj_obj_data(A) pdf_mem[obj_data_ptr((A)) + 0] -#define obj_obj_is_stream(A) pdf_mem[obj_data_ptr((A)) + 1] -#define obj_obj_stream_attr(A) pdf_mem[obj_data_ptr((A)) + 2] -#define obj_obj_is_file(A) pdf_mem[obj_data_ptr((A)) + 3] -#define obj_xform_width(A) pdf_mem[obj_data_ptr((A)) + 0] -#define obj_xform_height(A) pdf_mem[obj_data_ptr((A)) + 1] -#define obj_xform_depth(A) pdf_mem[obj_data_ptr((A)) + 2] - - -#define MAX_CHAIN_SIZE 13 - -volatile memory_word *varmem = NULL; - -#ifndef NDEBUG -char *varmem_sizes = NULL; -#endif - -halfword var_mem_max = 0; -halfword rover = 0; - -halfword free_chain[MAX_CHAIN_SIZE] = { null }; - -static integer my_prealloc = 0; - -int fix_node_lists = 1; - -int free_error_seen = 0; -int copy_error_seen = 0; - -halfword slow_get_node(integer s); /* defined below */ -int copy_error(halfword p); /* define below */ - -#undef link /* defined by cpascal.h */ -#define info(a) fixmem[(a)].hhlh -#define link(a) fixmem[(a)].hhrh - -#define fake_node 100 -#define fake_node_size 2 -#define fake_node_name "fake" - -#define variable_node_size 2 - - -const char *node_fields_list[] = { "attr", "width", "depth", "height", "dir", "shift", - "glue_order", "glue_sign", "glue_set", "list", NULL -}; -const char *node_fields_rule[] = { "attr", "width", "depth", "height", "dir", NULL }; -const char *node_fields_insert[] = - { "attr", "cost", "depth", "height", "spec", "list", NULL }; -const char *node_fields_mark[] = { "attr", "class", "mark", NULL }; -const char *node_fields_adjust[] = { "attr", "list", NULL }; -const char *node_fields_disc[] = { "attr", "pre", "post", "replace", NULL }; -const char *node_fields_math[] = { "attr", "surround", NULL }; -const char *node_fields_glue[] = { "attr", "spec", "leader", NULL }; -const char *node_fields_kern[] = { "attr", "kern", NULL }; -const char *node_fields_penalty[] = { "attr", "penalty", NULL }; -const char *node_fields_unset[] = - { "attr", "width", "depth", "height", "dir", "shrink", - "glue_order", "glue_sign", "stretch", "span", "list", NULL -}; -const char *node_fields_margin_kern[] = { "attr", "width", "glyph", NULL }; -const char *node_fields_glyph[] = - { "attr", "char", "font", "lang", "left", "right", "uchyph", - "components", "xoffset", "yoffset", NULL -}; -const char *node_fields_style[] = { "attr", "style", NULL }; -const char *node_fields_choice[] = - { "attr", "display", "text", "script", "scriptscript", NULL }; -const char *node_fields_ord[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_op[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_bin[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_rel[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_open[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_close[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_punct[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_inner[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_under[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_over[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_vcenter[] = { "attr", "nucleus", "sub", "sup", NULL }; -const char *node_fields_radical[] = - { "attr", "nucleus", "sub", "sup", "left", "degree", NULL }; -const char *node_fields_fraction[] = - { "attr", "width", "num", "denom", "left", "right", NULL }; -const char *node_fields_accent[] = - { "attr", "nucleus", "sub", "sup", "accent", "bot_accent", NULL }; -const char *node_fields_fence[] = { "attr", "delim", NULL }; -const char *node_fields_math_char[] = { "attr", "fam", "char", NULL }; -const char *node_fields_sub_box[] = { "attr", "list", NULL }; -const char *node_fields_sub_mlist[] = { "attr", "list", NULL }; -const char *node_fields_math_text_char[] = { "attr", "fam", "char", NULL }; -const char *node_fields_delim[] = - { "attr", "small_fam", "small_char", "large_fam", "large_char", NULL }; - -const char *node_fields_inserting[] = - { "height", "last_ins_ptr", "best_ins_ptr", NULL }; - -const char *node_fields_splitup[] = { "height", "last_ins_ptr", "best_ins_ptr", - "broken_ptr", "broken_ins", NULL -}; - -const char *node_fields_action[] = { "action_type", "named_id", "action_id", - "file", "new_window", "data", "ref_count", NULL -}; -const char *node_fields_attribute[] = { "number", "value", NULL }; -const char *node_fields_glue_spec[] = { "width", "stretch", "shrink", - "stretch_order", "shrink_order", "ref_count", NULL -}; -const char *node_fields_attribute_list[] = { NULL }; - -const char *node_fields_whatsit_open[] = - { "attr", "stream", "name", "area", "ext", NULL }; -const char *node_fields_whatsit_write[] = { "attr", "stream", "data", NULL }; -const char *node_fields_whatsit_close[] = { "attr", "stream", NULL }; -const char *node_fields_whatsit_special[] = { "attr", "data", NULL }; - -const char *node_fields_whatsit_local_par[] = - { "attr", "pen_inter", "pen_broken", "dir", - "box_left", "box_left_width", "box_right", "box_right_width", NULL -}; -const char *node_fields_whatsit_dir[] = - { "attr", "dir", "level", "dvi_ptr", "dvi_h", NULL }; - -const char *node_fields_whatsit_pdf_literal[] = { "attr", "mode", "data", NULL }; -const char *node_fields_whatsit_pdf_refobj[] = { "attr", "objnum", NULL }; -const char *node_fields_whatsit_pdf_refxform[] = - { "attr", "width", "height", "depth", "objnum", NULL }; -const char *node_fields_whatsit_pdf_refximage[] = - { "attr", "width", "height", "depth", "objnum", NULL }; -const char *node_fields_whatsit_pdf_annot[] = - { "attr", "width", "height", "depth", "objnum", "data", NULL }; -const char *node_fields_whatsit_pdf_start_link[] = - { "attr", "width", "height", "depth", - "objnum", "link_attr", "action", NULL -}; -const char *node_fields_whatsit_pdf_end_link[] = { "attr", NULL }; -const char *node_fields_whatsit_pdf_dest[] = { "attr", "width", "height", "depth", - "named_id", "dest_id", "dest_type", "xyz_zoom", "objnum", NULL -}; -const char *node_fields_whatsit_pdf_thread[] = { "attr", "width", "height", "depth", - "named_id", "thread_id", "thread_attr", NULL -}; -const char *node_fields_whatsit_pdf_start_thread[] = - { "attr", "width", "height", "depth", - "named_id", "thread_id", "thread_attr", NULL -}; -const char *node_fields_whatsit_pdf_end_thread[] = { "attr", NULL }; -const char *node_fields_whatsit_pdf_save_pos[] = { "attr", NULL }; -const char *node_fields_whatsit_late_lua[] = { "attr", "reg", "data", "name", NULL }; -const char *node_fields_whatsit_close_lua[] = { "attr", "reg", NULL }; -const char *node_fields_whatsit_pdf_colorstack[] = - { "attr", "stack", "cmd", "data", NULL }; -const char *node_fields_whatsit_pdf_setmatrix[] = { "attr", "data", NULL }; -const char *node_fields_whatsit_pdf_save[] = { "attr", NULL }; -const char *node_fields_whatsit_pdf_restore[] = { "attr", NULL }; -const char *node_fields_whatsit_cancel_boundary[] = { "attr", NULL }; -const char *node_fields_whatsit_user_defined[] = - { "attr", "user_id", "type", "value", NULL }; - -node_info node_data[] = { - {hlist_node, box_node_size, node_fields_list, "hlist"}, - {vlist_node, box_node_size, node_fields_list, "vlist"}, - {rule_node, rule_node_size, node_fields_rule, "rule"}, - {ins_node, ins_node_size, node_fields_insert, "ins"}, - {mark_node, mark_node_size, node_fields_mark, "mark"}, - {adjust_node, adjust_node_size, node_fields_adjust, "adjust"}, - {fake_node, fake_node_size, NULL, fake_node_name}, /* don't touch this! */ - {disc_node, disc_node_size, node_fields_disc, "disc"}, - {whatsit_node, -1, NULL, "whatsit"}, - {math_node, math_node_size, node_fields_math, "math"}, - {glue_node, glue_node_size, node_fields_glue, "glue"}, - {kern_node, kern_node_size, node_fields_kern, "kern"}, - {penalty_node, penalty_node_size, node_fields_penalty, "penalty"}, - {unset_node, box_node_size, node_fields_unset, "unset"}, - {style_node, style_node_size, node_fields_style, "style"}, - {choice_node, style_node_size, node_fields_choice, "choice"}, - {simple_noad, noad_size, node_fields_ord, "noad"}, - {old_op_noad, noad_size, node_fields_op, "op"}, - {old_bin_noad, noad_size, node_fields_bin, "bin"}, - {old_rel_noad, noad_size, node_fields_rel, "rel"}, - {old_open_noad, noad_size, node_fields_open, "open"}, - {old_close_noad, noad_size, node_fields_close, "close"}, - {old_punct_noad, noad_size, node_fields_punct, "punct"}, - {old_inner_noad, noad_size, node_fields_inner, "inner"}, - {radical_noad, radical_noad_size, node_fields_radical, "radical"}, - {fraction_noad, fraction_noad_size, node_fields_fraction, "fraction"}, - {old_under_noad, noad_size, node_fields_under, "under"}, - {old_over_noad, noad_size, node_fields_over, "over"}, - {accent_noad, accent_noad_size, node_fields_accent, "accent"}, - {old_vcenter_noad, noad_size, node_fields_vcenter, "vcenter"}, - {fence_noad, fence_noad_size, node_fields_fence, "fence"}, - {math_char_node, math_kernel_node_size, node_fields_math_char, "math_char"}, - {sub_box_node, math_kernel_node_size, node_fields_sub_box, "sub_box"}, - {sub_mlist_node, math_kernel_node_size, node_fields_sub_mlist, "sub_mlist"}, - {math_text_char_node, math_kernel_node_size, node_fields_math_text_char, - "math_text_char"}, - {delim_node, math_shield_node_size, node_fields_delim, "delim"}, - {margin_kern_node, margin_kern_node_size, node_fields_margin_kern, - "margin_kern"}, - {glyph_node, glyph_node_size, node_fields_glyph, "glyph"}, - {align_record_node, box_node_size, NULL, "align_record"}, - {pseudo_file_node, pseudo_file_node_size, NULL, "pseudo_file"}, - {pseudo_line_node, variable_node_size, NULL, "pseudo_line"}, - {inserting_node, page_ins_node_size, node_fields_inserting, "page_insert"}, - {split_up_node, page_ins_node_size, node_fields_splitup, "split_insert"}, - {expr_node, expr_node_size, NULL, "expr_stack"}, - {nesting_node, nesting_node_size, NULL, "nested_list"}, - {span_node, span_node_size, NULL, "span"}, - {attribute_node, attribute_node_size, node_fields_attribute, "attribute"}, - {glue_spec_node, glue_spec_size, node_fields_glue_spec, "glue_spec"}, - {attribute_list_node, attribute_node_size, node_fields_attribute_list, - "attribute_list"}, - {action_node, pdf_action_size, node_fields_action, "action"}, - {temp_node, temp_node_size, NULL, "temp"}, - {align_stack_node, align_stack_node_size, NULL, "align_stack"}, - {movement_node, movement_node_size, NULL, "movement_stack"}, - {if_node, if_node_size, NULL, "if_stack"}, - {unhyphenated_node, active_node_size, NULL, "unhyphenated"}, - {hyphenated_node, active_node_size, NULL, "hyphenated"}, - {delta_node, delta_node_size, NULL, "delta"}, - {passive_node, passive_node_size, NULL, "passive"}, - {shape_node, variable_node_size, NULL, "shape"}, - {-1, -1, NULL, NULL} -}; - -#define last_normal_node shape_node - -node_info whatsit_node_data[] = { - {open_node, open_node_size, node_fields_whatsit_open, "open"}, - {write_node, write_node_size, node_fields_whatsit_write, "write"}, - {close_node, close_node_size, node_fields_whatsit_close, "close"}, - {special_node, special_node_size, node_fields_whatsit_special, "special"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {local_par_node, local_par_size, node_fields_whatsit_local_par, - "local_par"}, - {dir_node, dir_node_size, node_fields_whatsit_dir, "dir"}, - {pdf_literal_node, write_node_size, node_fields_whatsit_pdf_literal, - "pdf_literal"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {pdf_refobj_node, pdf_refobj_node_size, node_fields_whatsit_pdf_refobj, - "pdf_refobj"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {pdf_refxform_node, pdf_refxform_node_size, - node_fields_whatsit_pdf_refxform, "pdf_refxform"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {pdf_refximage_node, pdf_refximage_node_size, - node_fields_whatsit_pdf_refximage, "pdf_refximage"}, - {pdf_annot_node, pdf_annot_node_size, node_fields_whatsit_pdf_annot, - "pdf_annot"}, - {pdf_start_link_node, pdf_annot_node_size, - node_fields_whatsit_pdf_start_link, "pdf_start_link"}, - {pdf_end_link_node, pdf_end_link_node_size, - node_fields_whatsit_pdf_end_link, "pdf_end_link"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {pdf_dest_node, pdf_dest_node_size, node_fields_whatsit_pdf_dest, - "pdf_dest"}, - {pdf_thread_node, pdf_thread_node_size, node_fields_whatsit_pdf_thread, - "pdf_thread"}, - {pdf_start_thread_node, pdf_thread_node_size, - node_fields_whatsit_pdf_start_thread, "pdf_start_thread"}, - {pdf_end_thread_node, pdf_end_thread_node_size, - node_fields_whatsit_pdf_end_thread, "pdf_end_thread"}, - {pdf_save_pos_node, pdf_save_pos_node_size, - node_fields_whatsit_pdf_save_pos, "pdf_save_pos"}, - {pdf_thread_data_node, pdf_thread_node_size, NULL, "pdf_thread_data"}, - {pdf_link_data_node, pdf_annot_node_size, NULL, "pdf_link_data"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {late_lua_node, late_lua_node_size, node_fields_whatsit_late_lua, - "late_lua"}, - {close_lua_node, write_node_size, node_fields_whatsit_close_lua, - "close_lua"}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {fake_node, fake_node_size, NULL, fake_node_name}, - {pdf_colorstack_node, pdf_colorstack_node_size, - node_fields_whatsit_pdf_colorstack, "pdf_colorstack"}, - {pdf_setmatrix_node, pdf_setmatrix_node_size, - node_fields_whatsit_pdf_setmatrix, "pdf_setmatrix"}, - {pdf_save_node, pdf_save_node_size, node_fields_whatsit_pdf_save, - "pdf_save"}, - {pdf_restore_node, pdf_restore_node_size, node_fields_whatsit_pdf_restore, - "pdf_restore"}, - {cancel_boundary_node, cancel_boundary_size, - node_fields_whatsit_cancel_boundary, "cancel_boundary"}, - {user_defined_node, user_defined_node_size, - node_fields_whatsit_user_defined, "user_defined"}, - {-1, -1, NULL, NULL} -}; - -#define last_whatsit_node user_defined_node - -halfword new_node(int i, int j) -{ - register int s; - register halfword n; - s = get_node_size(i, j); - n = get_node(s); - /* it should be possible to do this memset at free_node() */ - /* type() and subtype() will be set below, and vlink() is - set to null by get_node(), so we can do we clearing one - word less than |s| */ - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (s - 1))); - switch (i) { - case glyph_node: - init_lang_data(n); - break; - case hlist_node: - case vlist_node: - box_dir(n) = -1; - break; - case whatsit_node: - if (j == open_node) { - open_name(n) = get_nullstr(); - open_area(n) = open_name(n); - open_ext(n) = open_name(n); - } - break; - case disc_node: - pre_break(n) = pre_break_head(n); - type(pre_break(n)) = nesting_node; - subtype(pre_break(n)) = pre_break_head(0); - post_break(n) = post_break_head(n); - type(post_break(n)) = nesting_node; - subtype(post_break(n)) = post_break_head(0); - no_break(n) = no_break_head(n); - type(no_break(n)) = nesting_node; - subtype(no_break(n)) = no_break_head(0); - break; - case rule_node: - depth(n) = null_flag; - height(n) = null_flag; - rule_dir(n) = -1; - /* fall through */ - case unset_node: - width(n) = null_flag; - break; - case pseudo_line_node: - case shape_node: - /* this is a trick that makes pseudo_files slightly slower, - * but the overall allocation faster then an explicit test - * at the top of new_node(). - */ - free_node(n, variable_node_size); - n = slow_get_node(j); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (j - 1))); - break; - default: - break; - } - /* handle synctex extension */ - switch (i) { - case math_node: - synctex_tag_math(n) = cur_input.synctex_tag_field; - synctex_line_math(n) = line; - break; - case glue_node: - synctex_tag_glue(n) = cur_input.synctex_tag_field; - synctex_line_glue(n) = line; - break; - case kern_node: - /* synctex ignores implicit kerns */ - if (j != 0) { - synctex_tag_kern(n) = cur_input.synctex_tag_field; - synctex_line_kern(n) = line; - } - break; - case hlist_node: - case vlist_node: - case unset_node: - synctex_tag_box(n) = cur_input.synctex_tag_field; - synctex_line_box(n) = line; - break; - case rule_node: - synctex_tag_rule(n) = cur_input.synctex_tag_field; - synctex_line_rule(n) = line; - break; - } - /* take care of attributes */ - if (nodetype_has_attributes(i)) { - build_attribute_list(n); - } - type(n) = i; - subtype(n) = j; -#ifdef DEBUG - fprintf(stderr, "Alloc-ing %s node %d\n", - get_node_name(type(n), subtype(n)), (int) n); -#endif - return n; -} - -halfword raw_glyph_node(void) -{ - register halfword n; - n = get_node(glyph_node_size); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (glyph_node_size - 1))); - type(n) = glyph_node; - subtype(n) = 0; - return n; -} - -halfword new_glyph_node(void) -{ - register halfword n; - n = get_node(glyph_node_size); - (void) memset((void *) (varmem + n + 1), 0, - (sizeof(memory_word) * (glyph_node_size - 1))); - type(n) = glyph_node; - subtype(n) = 0; - build_attribute_list(n); - return n; -} - - -/* makes a duplicate of the node list that starts at |p| and returns a - pointer to the new list */ - -halfword copy_node_list(halfword p) -{ - halfword q = null; /* previous position in new list */ - halfword h = null; /* head of the list */ - copy_error_seen = 0; - while (p != null) { - register halfword s = copy_node(p); - if (h == null) { - h = s; - } else { - couple_nodes(q, s); - } - q = s; - p = vlink(p); - } - return h; -} - - /* make a dupe of a single node */ -halfword copy_node(const halfword p) -{ - halfword r; /* current node being fabricated for new list */ - register halfword s; /* a helper variable for copying into variable mem */ - register int i; - if (copy_error(p)) { - r = new_node(temp_node, 0); - return r; - } - i = get_node_size(type(p), subtype(p)); - r = get_node(i); - - (void) memcpy((void *) (varmem + r), (void *) (varmem + p), - (sizeof(memory_word) * i)); - - /* handle synctex extension */ - switch (type(p)) { - case math_node: - synctex_tag_math(r) = cur_input.synctex_tag_field; - synctex_line_math(r) = line; - break; - case kern_node: - synctex_tag_kern(r) = cur_input.synctex_tag_field; - synctex_line_kern(r) = line; - break; - } - - if (nodetype_has_attributes(type(p))) { - add_node_attr_ref(node_attr(p)); - alink(r) = null; /* needs checking */ - } - vlink(r) = null; - - - switch (type(p)) { - case glyph_node: - s = copy_node_list(lig_ptr(p)); - lig_ptr(r) = s; - break; - case glue_node: - add_glue_ref(glue_ptr(p)); - s = copy_node_list(leader_ptr(p)); - leader_ptr(r) = s; - break; - case hlist_node: - case vlist_node: - case unset_node: - s = copy_node_list(list_ptr(p)); - list_ptr(r) = s; - break; - case ins_node: - add_glue_ref(split_top_ptr(p)); - s = copy_node_list(ins_ptr(p)); - ins_ptr(r) = s; - break; - case margin_kern_node: - s = copy_node(margin_char(p)); - margin_char(r) = s; - break; - case disc_node: - pre_break(r) = pre_break_head(r); - if (vlink_pre_break(p) != null) { - s = copy_node_list(vlink_pre_break(p)); - alink(s) = pre_break(r); - tlink_pre_break(r) = tail_of_list(s); - vlink_pre_break(r) = s; - } else { - assert(tlink(pre_break(r)) == null); - } - post_break(r) = post_break_head(r); - if (vlink_post_break(p) != null) { - s = copy_node_list(vlink_post_break(p)); - alink(s) = post_break(r); - tlink_post_break(r) = tail_of_list(s); - vlink_post_break(r) = s; - } else { - assert(tlink_post_break(r) == null); - } - no_break(r) = no_break_head(r); - if (vlink(no_break(p)) != null) { - s = copy_node_list(vlink_no_break(p)); - alink(s) = no_break(r); - tlink_no_break(r) = tail_of_list(s); - vlink_no_break(r) = s; - } else { - assert(tlink_no_break(r) == null); - } - break; - case mark_node: - add_token_ref(mark_ptr(p)); - break; - case adjust_node: - s = copy_node_list(adjust_ptr(p)); - adjust_ptr(r) = s; - break; - - case choice_node: - s = copy_node_list(display_mlist(p)); - display_mlist(r) = s; - s = copy_node_list(text_mlist(p)); - text_mlist(r) = s; - s = copy_node_list(script_mlist(p)); - script_mlist(r) = s; - s = copy_node_list(script_script_mlist(p)); - script_script_mlist(r) = s; - break; - case simple_noad: - case radical_noad: - case accent_noad: - s = copy_node_list(nucleus(p)); - nucleus(r) = s; - s = copy_node_list(subscr(p)); - subscr(r) = s; - s = copy_node_list(supscr(p)); - supscr(r) = s; - if (type(p) == accent_noad) { - s = copy_node_list(accent_chr(p)); - accent_chr(r) = s; - s = copy_node_list(bot_accent_chr(p)); - bot_accent_chr(r) = s; - } else if (type(p) == radical_noad) { - s = copy_node(left_delimiter(p)); - left_delimiter(r) = s; - s = copy_node_list(degree(p)); - degree(r) = s; - } - break; - case fence_noad: - s = copy_node(delimiter(p)); - delimiter(r) = s; - break; - /* - case style_node: - case delim_node: - case math_char_node: - case math_text_char_node: - break; - */ - case sub_box_node: - case sub_mlist_node: - s = copy_node_list(math_list(p)); - math_list(r) = s; - break; - case fraction_noad: - s = copy_node_list(numerator(p)); - numerator(r) = s; - s = copy_node_list(denominator(p)); - denominator(r) = s; - s = copy_node(left_delimiter(p)); - left_delimiter(r) = s; - s = copy_node(right_delimiter(p)); - right_delimiter(r) = s; - break; - case glue_spec_node: - glue_ref_count(r) = null; - break; - case whatsit_node: - switch (subtype(p)) { - case dir_node: - case local_par_node: - break; - case write_node: - case special_node: - add_token_ref(write_tokens(p)); - break; - case pdf_literal_node: - copy_pdf_literal(r, p); - break; - case pdf_colorstack_node: - if (pdf_colorstack_cmd(p) <= colorstack_data) - add_token_ref(pdf_colorstack_data(p)); - break; - case pdf_setmatrix_node: - add_token_ref(pdf_setmatrix_data(p)); - break; - case late_lua_node: - if (late_lua_name(p) > 0) - add_token_ref(late_lua_name(p)); - add_token_ref(late_lua_data(p)); - break; - case pdf_annot_node: - add_token_ref(pdf_annot_data(p)); - break; - case pdf_start_link_node: - if (pdf_link_attr(r) != null) - add_token_ref(pdf_link_attr(r)); - add_action_ref(pdf_link_action(r)); - break; - case pdf_dest_node: - if (pdf_dest_named_id(p) > 0) - add_token_ref(pdf_dest_id(p)); - break; - case pdf_thread_node: - case pdf_start_thread_node: - if (pdf_thread_named_id(p) > 0) - add_token_ref(pdf_thread_id(p)); - if (pdf_thread_attr(p) != null) - add_token_ref(pdf_thread_attr(p)); - break; - case user_defined_node: - switch (user_node_type(p)) { - case 'a': - add_node_attr_ref(user_node_value(p)); - break; - case 't': - add_token_ref(user_node_value(p)); - break; - case 's': - /* |add_string_ref(user_node_value(p));| *//* if this was mpost .. */ - break; - case 'n': - s = copy_node_list(user_node_value(p)); - user_node_value(r) = s; - break; - } - break; - default: - break; - } - break; - } -#ifdef DEBUG - fprintf(stderr, "Alloc-ing %s node %d (copy of %d)\n", - get_node_name(type(r), subtype(r)), (int) r, (int) p); -#endif - return r; -} - -int valid_node(halfword p) -{ - if (p > my_prealloc) { - if (p < var_mem_max) { -#ifndef NDEBUG - if (varmem_sizes[p] > 0) -#endif - return 1; - } - } else { - return 1; - } - return 0; -} - -static void do_free_error(halfword p) -{ - halfword r; - char errstr[255] = { 0 }; - const char *errhlp[] = { - "When I tried to free the node mentioned in the error message, it turned", - "out it was not (or no longer) actually in use.", - "Errors such as these are often caused by Lua node list alteration,", - "but could also point to a bug in the executable. It should be safe to continue.", - NULL - }; - - check_node_mem(); - if (free_error_seen) - return; - - r = null; - free_error_seen = 1; - if (type(p) == glyph_node) { - snprintf(errstr, 255, - "Attempt to double-free glyph (%c) node %d, ignored", - (int) character(p), (int) p); - } else { - snprintf(errstr, 255, "Attempt to double-free %s node %d, ignored", - get_node_name(type(p), subtype(p)), (int) p); - } - tex_error(errstr, errhlp); -#ifndef NDEBUG - for (r = my_prealloc + 1; r < var_mem_max; r++) { - if (vlink(r) == p) { - halfword s = r; - while (s > my_prealloc && varmem_sizes[s] == 0) - s--; - if (s != null - && s != my_prealloc - && s != var_mem_max - && (r - s) < get_node_size(type(s), subtype(s)) - && alink(s) != p) { - - if (type(s) == disc_node) { - fprintf(stdout, - " pointed to from %s node %d (vlink %d, alink %d): ", - get_node_name(type(s), subtype(s)), (int) s, - (int) vlink(s), (int) alink(s)); - fprintf(stdout, "pre_break(%d,%d,%d), ", - (int) vlink_pre_break(s), (int) tlink(pre_break(s)), - (int) alink(pre_break(s))); - fprintf(stdout, "post_break(%d,%d,%d), ", - (int) vlink_post_break(s), - (int) tlink(post_break(s)), - (int) alink(post_break(s))); - fprintf(stdout, "no_break(%d,%d,%d)", - (int) vlink_no_break(s), (int) tlink(no_break(s)), - (int) alink(no_break(s))); - fprintf(stdout, "\n"); - } else { - if (vlink(s) == p - || (type(s) == glyph_node && lig_ptr(s) == p) - || (type(s) == vlist_node && list_ptr(s) == p) - || (type(s) == hlist_node && list_ptr(s) == p) - || (type(s) == unset_node && list_ptr(s) == p) - || (type(s) == ins_node && ins_ptr(s) == p) - ) { - fprintf(stdout, - " pointed to from %s node %d (vlink %d, alink %d): ", - get_node_name(type(s), subtype(s)), (int) s, - (int) vlink(s), (int) alink(s)); - if (type(s) == glyph_node) { - fprintf(stdout, "lig_ptr(%d)", (int) lig_ptr(s)); - } else if (type(s) == vlist_node - || type(s) == hlist_node) { - fprintf(stdout, "list_ptr(%d)", (int) list_ptr(s)); - } - fprintf(stdout, "\n"); - } else { - if ((type(s) != penalty_node) - && (type(s) != math_node) - && (type(s) != kern_node) - ) { - fprintf(stdout, " pointed to from %s node %d\n", - get_node_name(type(s), subtype(s)), - (int) s); - } - } - } - } - } - } -#endif -} - -static int free_error(halfword p) -{ - assert(p > my_prealloc); - assert(p < var_mem_max); -#ifndef NDEBUG - if (varmem_sizes[p] == 0) { - do_free_error(p); - return 1; /* double free */ - } -#endif - return 0; -} - - -static void do_copy_error(halfword p) -{ - char errstr[255] = { 0 }; - const char *errhlp[] = { - "When I tried to copy the node mentioned in the error message, it turned", - "out it was not (or no longer) actually in use.", - "Errors such as these are often caused by Lua node list alteration,", - "but could also point to a bug in the executable. It should be safe to continue.", - NULL - }; - - if (copy_error_seen) - return; - - copy_error_seen = 1; - if (type(p) == glyph_node) { - snprintf(errstr, 255, - "Attempt to copy free glyph (%c) node %d, ignored", - (int) character(p), (int) p); - } else { - snprintf(errstr, 255, "Attempt to copy free %s node %d, ignored", - get_node_name(type(p), subtype(p)), (int) p); - } - tex_error(errstr, errhlp); -} - - -int copy_error(halfword p) -{ - assert(p >= 0); - assert(p < var_mem_max); -#ifndef NDEBUG - if (p > my_prealloc && varmem_sizes[p] == 0) { - do_copy_error(p); - return 1; /* copy free node */ - } -#endif - return 0; -} - - - -void flush_node(halfword p) -{ - - if (p == null) /* legal, but no-op */ - return; - -#ifdef DEBUG - fprintf(stderr, "Free-ing %s node %d\n", get_node_name(type(p), subtype(p)), - (int) p); -#endif - if (free_error(p)) - return; - - switch (type(p)) { - case glyph_node: - flush_node_list(lig_ptr(p)); - break; - case glue_node: - delete_glue_ref(glue_ptr(p)); - flush_node_list(leader_ptr(p)); - break; - - case attribute_node: - case attribute_list_node: - case temp_node: - case glue_spec_node: - case rule_node: - case kern_node: - case math_node: - case penalty_node: - break; - - case hlist_node: - case vlist_node: - case unset_node: - flush_node_list(list_ptr(p)); - break; - case whatsit_node: - switch (subtype(p)) { - - case dir_node: - break; - case open_node: - case write_node: - case close_node: - case pdf_save_node: - case pdf_restore_node: - case cancel_boundary_node: - case close_lua_node: - case pdf_refobj_node: - case pdf_refxform_node: - case pdf_refximage_node: - case pdf_end_link_node: - case pdf_end_thread_node: - case pdf_save_pos_node: - case local_par_node: - break; - - case special_node: - delete_token_ref(write_tokens(p)); - break; - case pdf_literal_node: - free_pdf_literal(p); - break; - case pdf_colorstack_node: - if (pdf_colorstack_cmd(p) <= colorstack_data) - delete_token_ref(pdf_colorstack_data(p)); - break; - case pdf_setmatrix_node: - delete_token_ref(pdf_setmatrix_data(p)); - break; - case late_lua_node: - if (late_lua_name(p) > 0) - delete_token_ref(late_lua_name(p)); - delete_token_ref(late_lua_data(p)); - break; - case pdf_annot_node: - delete_token_ref(pdf_annot_data(p)); - break; - - case pdf_link_data_node: - break; - - case pdf_start_link_node: - if (pdf_link_attr(p) != null) - delete_token_ref(pdf_link_attr(p)); - delete_action_ref(pdf_link_action(p)); - break; - case pdf_dest_node: - if (pdf_dest_named_id(p) > 0) - delete_token_ref(pdf_dest_id(p)); - break; - - case pdf_thread_data_node: - break; - - case pdf_thread_node: - case pdf_start_thread_node: - if (pdf_thread_named_id(p) > 0) - delete_token_ref(pdf_thread_id(p)); - if (pdf_thread_attr(p) != null) - delete_token_ref(pdf_thread_attr(p)); - break; - case user_defined_node: - switch (user_node_type(p)) { - case 'a': - delete_attribute_ref(user_node_value(p)); - break; - case 't': - delete_token_ref(user_node_value(p)); - break; - case 'n': - flush_node_list(user_node_value(p)); - break; - case 's': - /* |delete_string_ref(user_node_value(p));| *//* if this was mpost .. */ - break; - case 'd': - break; - default: - { - const char *hlp[] = { - "The type of the value in a user defined whatsit node should be one", - "of 'a' (attribute list), 'd' (number), 'n' (node list), 's' (string),", - "or 't' (tokenlist). Yours has an unknown type, and therefore I don't", - "know how to free the node's value. A memory leak may result.", - NULL - }; - tex_error("Unidentified user defined whatsit", hlp); - } - break; - } - break; - - default: - tconfusion("ext3"); - return; - - } - break; - case ins_node: - flush_node_list(ins_ptr(p)); - delete_glue_ref(split_top_ptr(p)); - break; - case margin_kern_node: - flush_node(margin_char(p)); - break; - case mark_node: - delete_token_ref(mark_ptr(p)); - break; - case disc_node: - flush_node_list(vlink(pre_break(p))); - flush_node_list(vlink(post_break(p))); - flush_node_list(vlink(no_break(p))); - break; - case adjust_node: - flush_node_list(adjust_ptr(p)); - break; - case style_node: /* nothing to do */ - break; - case choice_node: - flush_node_list(display_mlist(p)); - flush_node_list(text_mlist(p)); - flush_node_list(script_mlist(p)); - flush_node_list(script_script_mlist(p)); - break; - case simple_noad: - case radical_noad: - case accent_noad: - flush_node_list(nucleus(p)); - flush_node_list(subscr(p)); - flush_node_list(supscr(p)); - if (type(p) == accent_noad) { - flush_node_list(accent_chr(p)); - flush_node_list(bot_accent_chr(p)); - } else if (type(p) == radical_noad) { - flush_node(left_delimiter(p)); - flush_node_list(degree(p)); - } - break; - case fence_noad: - flush_node(delimiter(p)); - break; - case delim_node: /* nothing to do */ - case math_char_node: - case math_text_char_node: - break; - case sub_box_node: - case sub_mlist_node: - flush_node_list(math_list(p)); - break; - case fraction_noad: - flush_node_list(numerator(p)); - flush_node_list(denominator(p)); - flush_node(left_delimiter(p)); - flush_node(right_delimiter(p)); - break; - case pseudo_file_node: - flush_node_list(pseudo_lines(p)); - break; - case pseudo_line_node: - case shape_node: - free_node(p, subtype(p)); - return; - break; - case align_stack_node: - case span_node: - case movement_node: - case if_node: - case nesting_node: - case unhyphenated_node: - case hyphenated_node: - case delta_node: - case passive_node: - case action_node: - case inserting_node: - case split_up_node: - case expr_node: - break; - default: - fprintf(stdout, "flush_node: type is %d\n", type(p)); - return; - - } - if (nodetype_has_attributes(type(p))) - delete_attribute_ref(node_attr(p)); - free_node(p, get_node_size(type(p), subtype(p))); - return; -} - -void flush_node_list(halfword pp) -{ /* erase list of nodes starting at |p| */ - register halfword p = pp; - free_error_seen = 0; - if (p == null) /* legal, but no-op */ - return; - if (free_error(p)) - return; - - while (p != null) { - register halfword q = vlink(p); - flush_node(p); - p = q; - } -} - -static int test_count = 1; - -#define dorangetest(a,b,c) do { \ - if (!(b>=0 && b<c)) { \ - fprintf(stdout,"For node p:=%d, 0<=%d<%d (l.%d,r.%d)\n", \ - (int)a, (int)b, (int)c, __LINE__,test_count); \ - tconfusion("dorangetest"); \ - } } while (0) - -#define dotest(a,b,c) do { \ - if (b!=c) { \ - fprintf(stdout,"For node p:=%d, %d==%d (l.%d,r.%d)\n", \ - (int)a, (int)b, (int)c, __LINE__,test_count); \ - tconfusion("dotest"); \ - } } while (0) - -#define check_action_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_glue_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_token_ref(a) assert(1) - -void check_node(halfword p) -{ - - switch (type(p)) { - case glyph_node: - dorangetest(p, lig_ptr(p), var_mem_max); - break; - case glue_node: - check_glue_ref(glue_ptr(p)); - dorangetest(p, leader_ptr(p), var_mem_max); - break; - case hlist_node: - case vlist_node: - case unset_node: - case align_record_node: - dorangetest(p, list_ptr(p), var_mem_max); - break; - case ins_node: - dorangetest(p, ins_ptr(p), var_mem_max); - check_glue_ref(split_top_ptr(p)); - break; - case whatsit_node: - switch (subtype(p)) { - case special_node: - check_token_ref(write_tokens(p)); - break; - case pdf_literal_node: - if (pdf_literal_type(p) == normal) - check_token_ref(pdf_literal_data(p)); - break; - case pdf_colorstack_node: - if (pdf_colorstack_cmd(p) <= colorstack_data) - check_token_ref(pdf_colorstack_data(p)); - break; - case pdf_setmatrix_node: - check_token_ref(pdf_setmatrix_data(p)); - break; - case late_lua_node: - if (late_lua_name(p) > 0) - check_token_ref(late_lua_name(p)); - check_token_ref(late_lua_data(p)); - break; - case pdf_annot_node: - check_token_ref(pdf_annot_data(p)); - break; - case pdf_start_link_node: - if (pdf_link_attr(p) != null) - check_token_ref(pdf_link_attr(p)); - check_action_ref(pdf_link_action(p)); - break; - case pdf_dest_node: - if (pdf_dest_named_id(p) > 0) - check_token_ref(pdf_dest_id(p)); - break; - case pdf_thread_node: - case pdf_start_thread_node: - if (pdf_thread_named_id(p) > 0) - check_token_ref(pdf_thread_id(p)); - if (pdf_thread_attr(p) != null) - check_token_ref(pdf_thread_attr(p)); - break; - case user_defined_node: - switch (user_node_type(p)) { - case 'a': - check_attribute_ref(user_node_value(p)); - break; - case 't': - check_token_ref(user_node_value(p)); - break; - case 'n': - dorangetest(p, user_node_value(p), var_mem_max); - break; - case 's': - case 'd': - break; - default: - tconfusion("extuser"); - break; - } - break; - case dir_node: - case open_node: - case write_node: - case close_node: - case pdf_save_node: - case pdf_restore_node: - case cancel_boundary_node: - case close_lua_node: - case pdf_refobj_node: - case pdf_refxform_node: - case pdf_refximage_node: - case pdf_end_link_node: - case pdf_end_thread_node: - case pdf_save_pos_node: - case local_par_node: - break; - default: - tconfusion("ext3"); - } - break; - case margin_kern_node: - check_node(margin_char(p)); - break; - case disc_node: - dorangetest(p, vlink(pre_break(p)), var_mem_max); - dorangetest(p, vlink(post_break(p)), var_mem_max); - dorangetest(p, vlink(no_break(p)), var_mem_max); - break; - case adjust_node: - dorangetest(p, adjust_ptr(p), var_mem_max); - break; - case pseudo_file_node: - dorangetest(p, pseudo_lines(p), var_mem_max); - break; - case pseudo_line_node: - case shape_node: - break; - case choice_node: - dorangetest(p, display_mlist(p), var_mem_max); - dorangetest(p, text_mlist(p), var_mem_max); - dorangetest(p, script_mlist(p), var_mem_max); - dorangetest(p, script_script_mlist(p), var_mem_max); - break; - case fraction_noad: - dorangetest(p, numerator(p), var_mem_max); - dorangetest(p, denominator(p), var_mem_max); - dorangetest(p, left_delimiter(p), var_mem_max); - dorangetest(p, right_delimiter(p), var_mem_max); - break; - case simple_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - break; - case radical_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - dorangetest(p, degree(p), var_mem_max); - dorangetest(p, left_delimiter(p), var_mem_max); - break; - case accent_noad: - dorangetest(p, nucleus(p), var_mem_max); - dorangetest(p, subscr(p), var_mem_max); - dorangetest(p, supscr(p), var_mem_max); - dorangetest(p, accent_chr(p), var_mem_max); - dorangetest(p, bot_accent_chr(p), var_mem_max); - break; - case fence_noad: - dorangetest(p, delimiter(p), var_mem_max); - break; - case rule_node: - case kern_node: - case math_node: - case penalty_node: - case mark_node: - case style_node: - case attribute_list_node: - case attribute_node: - case glue_spec_node: - case temp_node: - case align_stack_node: - case movement_node: - case if_node: - case nesting_node: - case span_node: - case unhyphenated_node: - case hyphenated_node: - case delta_node: - case passive_node: - case expr_node: - break; - default: - fprintf(stdout, "check_node: type is %d\n", type(p)); - } -} - -static void check_static_node_mem(void) -{ - dotest(zero_glue, width(zero_glue), 0); - dotest(zero_glue, type(zero_glue), glue_spec_node); - dotest(zero_glue, vlink(zero_glue), null); - dotest(zero_glue, stretch(zero_glue), 0); - dotest(zero_glue, stretch_order(zero_glue), normal); - dotest(zero_glue, shrink(zero_glue), 0); - dotest(zero_glue, shrink_order(zero_glue), normal); - - dotest(sfi_glue, width(sfi_glue), 0); - dotest(sfi_glue, type(sfi_glue), glue_spec_node); - dotest(sfi_glue, vlink(sfi_glue), null); - dotest(sfi_glue, stretch(sfi_glue), 0); - dotest(sfi_glue, stretch_order(sfi_glue), sfi); - dotest(sfi_glue, shrink(sfi_glue), 0); - dotest(sfi_glue, shrink_order(sfi_glue), normal); - - dotest(fil_glue, width(fil_glue), 0); - dotest(fil_glue, type(fil_glue), glue_spec_node); - dotest(fil_glue, vlink(fil_glue), null); - dotest(fil_glue, stretch(fil_glue), unity); - dotest(fil_glue, stretch_order(fil_glue), fil); - dotest(fil_glue, shrink(fil_glue), 0); - dotest(fil_glue, shrink_order(fil_glue), normal); - - dotest(fill_glue, width(fill_glue), 0); - dotest(fill_glue, type(fill_glue), glue_spec_node); - dotest(fill_glue, vlink(fill_glue), null); - dotest(fill_glue, stretch(fill_glue), unity); - dotest(fill_glue, stretch_order(fill_glue), fill); - dotest(fill_glue, shrink(fill_glue), 0); - dotest(fill_glue, shrink_order(fill_glue), normal); - - dotest(ss_glue, width(ss_glue), 0); - dotest(ss_glue, type(ss_glue), glue_spec_node); - dotest(ss_glue, vlink(ss_glue), null); - dotest(ss_glue, stretch(ss_glue), unity); - dotest(ss_glue, stretch_order(ss_glue), fil); - dotest(ss_glue, shrink(ss_glue), unity); - dotest(ss_glue, shrink_order(ss_glue), fil); - - dotest(fil_neg_glue, width(fil_neg_glue), 0); - dotest(fil_neg_glue, type(fil_neg_glue), glue_spec_node); - dotest(fil_neg_glue, vlink(fil_neg_glue), null); - dotest(fil_neg_glue, stretch(fil_neg_glue), -unity); - dotest(fil_neg_glue, stretch_order(fil_neg_glue), fil); - dotest(fil_neg_glue, shrink(fil_neg_glue), 0); - dotest(fil_neg_glue, shrink_order(fil_neg_glue), normal); -} - -void check_node_mem(void) -{ - int i; - check_static_node_mem(); -#ifndef NDEBUG - for (i = (my_prealloc + 1); i < var_mem_max; i++) { - if (varmem_sizes[i] > 0) { - check_node(i); - } - } -#endif - test_count++; -} - -void fix_node_list(halfword head) -{ - halfword p, q; - if (head == null) - return; - p = head; - q = vlink(p); - while (q != null) { - alink(q) = p; - p = q; - q = vlink(p); - } -} - -halfword get_node(integer s) -{ - register halfword r; - - /*check_static_node_mem(); */ - assert(s < MAX_CHAIN_SIZE); - - r = free_chain[s]; - if (r != null) { - free_chain[s] = vlink(r); -#ifndef NDEBUG - varmem_sizes[r] = s; -#endif - vlink(r) = null; - var_used += s; /* maintain usage statistics */ - return r; - } - /* this is the end of the 'inner loop' */ - return slow_get_node(s); -} - -#if 0 /* unused */ -static void print_free_chain(int c) -{ - halfword p = free_chain[c]; - fprintf(stdout, "\nfree chain[%d] =\n ", c); - while (p != null) { - fprintf(stdout, "%d,", (int) p); - p = vlink(p); - } - fprintf(stdout, "null;\n"); -} -#endif - -void free_node(halfword p, integer s) -{ - - if (p <= my_prealloc) { - fprintf(stdout, "node %d (type %d) should not be freed!\n", (int) p, - type(p)); - return; - } -#ifndef NDEBUG - varmem_sizes[p] = 0; -#endif - if (s < MAX_CHAIN_SIZE) { - vlink(p) = free_chain[s]; - free_chain[s] = p; - } else { - /* todo ? it is perhaps possible to merge this node with an existing rover */ - node_size(p) = s; - vlink(p) = rover; - while (vlink(rover) != vlink(p)) { - rover = vlink(rover); - } - vlink(rover) = p; - } - var_used -= s; /* maintain statistics */ -} - -static void free_node_chain(halfword q, integer s) -{ - register halfword p = q; - while (vlink(p) != null) { -#ifndef NDEBUG - varmem_sizes[p] = 0; -#endif - var_used -= s; - p = vlink(p); - } - var_used -= s; -#ifndef NDEBUG - varmem_sizes[p] = 0; -#endif - vlink(p) = free_chain[s]; - free_chain[s] = q; -} - - -void init_node_mem(halfword t) -{ - my_prealloc = var_mem_stat_max; - assert(whatsit_node_data[user_defined_node].id == user_defined_node); - assert(node_data[passive_node].id == passive_node); - - varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * t); - if (varmem == NULL) { - overflow_string("node memory size", var_mem_max); - } - memset((void *) (varmem), 0, t * sizeof(memory_word)); - -#ifndef NDEBUG - varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * t); - if (varmem_sizes == NULL) { - overflow_string("node memory size", var_mem_max); - } - memset((void *) varmem_sizes, 0, sizeof(char) * t); -#endif - var_mem_max = t; - rover = var_mem_stat_max + 1; - vlink(rover) = rover; - node_size(rover) = (t - rover); - var_used = 0; - /* initialize static glue specs */ - glue_ref_count(zero_glue) = null + 1; - width(zero_glue) = 0; - type(zero_glue) = glue_spec_node; - vlink(zero_glue) = null; - stretch(zero_glue) = 0; - stretch_order(zero_glue) = normal; - shrink(zero_glue) = 0; - shrink_order(zero_glue) = normal; - glue_ref_count(sfi_glue) = null + 1; - width(sfi_glue) = 0; - type(sfi_glue) = glue_spec_node; - vlink(sfi_glue) = null; - stretch(sfi_glue) = 0; - stretch_order(sfi_glue) = sfi; - shrink(sfi_glue) = 0; - shrink_order(sfi_glue) = normal; - glue_ref_count(fil_glue) = null + 1; - width(fil_glue) = 0; - type(fil_glue) = glue_spec_node; - vlink(fil_glue) = null; - stretch(fil_glue) = unity; - stretch_order(fil_glue) = fil; - shrink(fil_glue) = 0; - shrink_order(fil_glue) = normal; - glue_ref_count(fill_glue) = null + 1; - width(fill_glue) = 0; - type(fill_glue) = glue_spec_node; - vlink(fill_glue) = null; - stretch(fill_glue) = unity; - stretch_order(fill_glue) = fill; - shrink(fill_glue) = 0; - shrink_order(fill_glue) = normal; - glue_ref_count(ss_glue) = null + 1; - width(ss_glue) = 0; - type(ss_glue) = glue_spec_node; - vlink(ss_glue) = null; - stretch(ss_glue) = unity; - stretch_order(ss_glue) = fil; - shrink(ss_glue) = unity; - shrink_order(ss_glue) = fil; - glue_ref_count(fil_neg_glue) = null + 1; - width(fil_neg_glue) = 0; - type(fil_neg_glue) = glue_spec_node; - vlink(fil_neg_glue) = null; - stretch(fil_neg_glue) = -unity; - stretch_order(fil_neg_glue) = fil; - shrink(fil_neg_glue) = 0; - shrink_order(fil_neg_glue) = normal; - /* initialize node list heads */ - vinfo(page_ins_head) = 0; - vlink(page_ins_head) = null; - alink(page_ins_head) = null; - vinfo(contrib_head) = 0; - vlink(contrib_head) = null; - alink(contrib_head) = null; - vinfo(page_head) = 0; - vlink(page_head) = null; - alink(page_head) = null; - vinfo(temp_head) = 0; - vlink(temp_head) = null; - alink(temp_head) = null; - vinfo(hold_head) = 0; - vlink(hold_head) = null; - alink(hold_head) = null; - vinfo(adjust_head) = 0; - vlink(adjust_head) = null; - alink(adjust_head) = null; - vinfo(pre_adjust_head) = 0; - vlink(pre_adjust_head) = null; - alink(pre_adjust_head) = null; - vinfo(active) = 0; - vlink(active) = null; - alink(active) = null; - vinfo(align_head) = 0; - vlink(align_head) = null; - alink(align_head) = null; - vinfo(end_span) = 0; - vlink(end_span) = null; - alink(end_span) = null; - type(begin_point) = glyph_node; - subtype(begin_point) = 0; - vlink(begin_point) = null; - vinfo(begin_point + 1) = null; - alink(begin_point) = null; - font(begin_point) = 0; - character(begin_point) = '.'; - vinfo(begin_point + 3) = 0; - vlink(begin_point + 3) = 0; - vinfo(begin_point + 4) = 0; - vlink(begin_point + 4) = 0; - type(end_point) = glyph_node; - subtype(end_point) = 0; - vlink(end_point) = null; - vinfo(end_point + 1) = null; - alink(end_point) = null; - font(end_point) = 0; - character(end_point) = '.'; - vinfo(end_point + 3) = 0; - vlink(end_point + 3) = 0; - vinfo(end_point + 4) = 0; - vlink(end_point + 4) = 0; -} - -void dump_node_mem(void) -{ - dump_int(var_mem_max); - dump_int(rover); - dump_things(varmem[0], var_mem_max); -#ifndef NDEBUG - dump_things(varmem_sizes[0], var_mem_max); -#endif - dump_things(free_chain[0], MAX_CHAIN_SIZE); - dump_int(var_used); - dump_int(my_prealloc); -} - -/* it makes sense to enlarge the varmem array immediately */ - -void undump_node_mem(void) -{ - integer x; - undump_int(x); - undump_int(rover); - var_mem_max = (x < 100000 ? 100000 : x); - varmem = xmallocarray(memory_word, var_mem_max); - /*memset ((void *)varmem,0,x*sizeof(memory_word)); */ - undump_things(varmem[0], x); -#ifndef NDEBUG - varmem_sizes = xmallocarray(char, var_mem_max); - memset((void *) varmem_sizes, 0, var_mem_max * sizeof(char)); - undump_things(varmem_sizes[0], x); -#endif - undump_things(free_chain[0], MAX_CHAIN_SIZE); - undump_int(var_used); - undump_int(my_prealloc); - if (var_mem_max > x) { - /* todo ? it is perhaps possible to merge the new node with an existing rover */ - vlink(x) = rover; - node_size(x) = (var_mem_max - x); - while (vlink(rover) != vlink(x)) { - rover = vlink(rover); - } - vlink(rover) = x; - } -} - -#if 0 -void test_rovers(char *s) -{ - int q = rover; - int r = q; - fprintf(stdout, "%s: {rover=%d,size=%d,link=%d}", s, r, node_size(r), - vlink(r)); - while (vlink(r) != q) { - r = vlink(r); - fprintf(stdout, ",{rover=%d,size=%d,link=%d}", r, node_size(r), - vlink(r)); - } - fprintf(stdout, "\n"); -} -#else -# define test_rovers(a) -#endif - -halfword slow_get_node(integer s) -{ - register int t; - - RETRY: - t = node_size(rover); - assert(vlink(rover) < var_mem_max); - assert(vlink(rover) != 0); - test_rovers("entry"); - if (t > s) { - register halfword r; - /* allocating from the bottom helps decrease page faults */ - r = rover; - rover += s; - vlink(rover) = vlink(r); - node_size(rover) = node_size(r) - s; - if (vlink(rover) != r) { /* list is longer than one */ - halfword q = r; - while (vlink(q) != r) { - q = vlink(q); - } - vlink(q) += s; - } else { - vlink(rover) += s; - } - test_rovers("taken"); - assert(vlink(rover) < var_mem_max); -#ifndef NDEBUG - varmem_sizes[r] = (s > 127 ? 127 : s); -#endif - vlink(r) = null; - var_used += s; /* maintain usage statistics */ - return r; /* this is the only exit */ - } else { - int x; - /* attempt to keep the free list small */ - if (vlink(rover) != rover) { - if (t < MAX_CHAIN_SIZE) { - halfword l = vlink(rover); - vlink(rover) = free_chain[t]; - free_chain[t] = rover; - rover = l; - while (vlink(l) != free_chain[t]) { - l = vlink(l); - } - vlink(l) = rover; - test_rovers("outtake"); - goto RETRY; - } else { - halfword l = rover; - while (vlink(rover) != l) { - if (node_size(rover) > s) { - goto RETRY; - } - rover = vlink(rover); - } - } - } - /* if we are still here, it was apparently impossible to get a match */ - x = (var_mem_max >> 2) + s; - varmem = - (memory_word *) realloc((void *) varmem, - sizeof(memory_word) * (var_mem_max + x)); - if (varmem == NULL) { - overflow_string("node memory size", var_mem_max); - } - memset((void *) (varmem + var_mem_max), 0, x * sizeof(memory_word)); - -#ifndef NDEBUG - varmem_sizes = - (char *) realloc(varmem_sizes, sizeof(char) * (var_mem_max + x)); - if (varmem_sizes == NULL) { - overflow_string("node memory size", var_mem_max); - } - memset((void *) (varmem_sizes + var_mem_max), 0, x * sizeof(char)); -#endif - - /* todo ? it is perhaps possible to merge the new memory with an existing rover */ - vlink(var_mem_max) = rover; - node_size(var_mem_max) = x; - while (vlink(rover) != vlink(var_mem_max)) { - rover = vlink(rover); - } - vlink(rover) = var_mem_max; - rover = var_mem_max; - test_rovers("realloc"); - var_mem_max += x; - goto RETRY; - } -} - -char *sprint_node_mem_usage(void) -{ - int i, b; - - char *s, *ss; -#ifndef NDEBUG - char msg[256]; - int node_counts[last_normal_node + last_whatsit_node + 2] = { 0 }; - - for (i = (var_mem_max - 1); i > my_prealloc; i--) { - if (varmem_sizes[i] > 0) { - if (type(i) > last_normal_node + last_whatsit_node) { - node_counts[last_normal_node + last_whatsit_node + 1]++; - } else if (type(i) == whatsit_node) { - node_counts[(subtype(i) + last_normal_node + 1)]++; - } else { - node_counts[type(i)]++; - } - } - } - s = strdup(""); - b = 0; - for (i = 0; i < last_normal_node + last_whatsit_node + 2; i++) { - if (node_counts[i] > 0) { - int j = - (i > (last_normal_node + 1) ? (i - last_normal_node - 1) : 0); - snprintf(msg, 255, "%s%d %s", (b ? ", " : ""), (int) node_counts[i], - get_node_name((i > last_normal_node ? whatsit_node : i), - j)); - ss = xmalloc(strlen(s) + strlen(msg) + 1); - strcpy(ss, s); - strcat(ss, msg); - free(s); - s = ss; - b = 1; - } - } -#else - s = strdup(""); -#endif - return s; -} - -halfword list_node_mem_usage(void) -{ - halfword i, j; - halfword p = null, q = null; -#ifndef NDEBUG - char *saved_varmem_sizes = xmallocarray(char, var_mem_max); - memcpy(saved_varmem_sizes, varmem_sizes, var_mem_max); - for (i = my_prealloc + 1; i < (var_mem_max - 1); i++) { - if (saved_varmem_sizes[i] > 0) { - j = copy_node(i); - if (p == null) { - q = j; - } else { - vlink(p) = j; - } - p = j; - } - } - free(saved_varmem_sizes); -#endif - return q; -} - -void print_node_mem_stats(void) -{ - int i, b; - halfword j; - char msg[256]; - char *s; - integer free_chain_counts[MAX_CHAIN_SIZE] = { 0 }; - snprintf(msg, 255, "node memory in use: %d words out of %d", - (int) (var_used + my_prealloc), (int) var_mem_max); - tprint_nl(msg); - tprint_nl("rapidly available: "); - b = 0; - for (i = 1; i < MAX_CHAIN_SIZE; i++) { - for (j = free_chain[i]; j != null; j = vlink(j)) - free_chain_counts[i]++; - if (free_chain_counts[i] > 0) { - snprintf(msg, 255, "%s%d:%d", (b ? ", " : ""), i, - (int) free_chain_counts[i]); - tprint(msg); - b = 1; - } - } - tprint(" nodes"); - s = sprint_node_mem_usage(); - tprint_nl("current usage: "); - tprint(s); - free(s); - tprint(" nodes"); - print_nlp(); /* newline, if needed */ -} - -/* this belongs in the web but i couldn't find the correct syntactic place */ - -halfword new_span_node(halfword n, int s, scaled w) -{ - halfword p = new_node(span_node, 0); - span_link(p) = n; - span_span(p) = s; - width(p) = w; - return p; -} - -halfword string_to_pseudo(integer l, integer pool_ptr, integer nl) -{ - halfword i, r, q = null; - four_quarters w; - int sz; - halfword h = new_node(pseudo_file_node, 0); - while (l < pool_ptr) { - int m = l; - while ((l < pool_ptr) && (str_pool[l] != nl)) - l++; - sz = (l - m + 7) / 4; - if (sz == 1) - sz = 2; - r = new_node(pseudo_line_node, sz); - i = r; - while (--sz > 1) { - w.b0 = str_pool[m++]; - w.b1 = str_pool[m++]; - w.b2 = str_pool[m++]; - w.b3 = str_pool[m++]; - varmem[++i].qqqq = w; - } - w.b0 = (l > m ? str_pool[m++] : ' '); - w.b1 = (l > m ? str_pool[m++] : ' '); - w.b2 = (l > m ? str_pool[m++] : ' '); - w.b3 = (l > m ? str_pool[m] : ' '); - varmem[++i].qqqq = w; - if (pseudo_lines(h) == null) { - pseudo_lines(h) = r; - q = r; - } else { - couple_nodes(q, r); - } - q = vlink(q); - if (str_pool[l] == nl) - l++; - } - return h; -} - -/* attribute stuff */ - -static halfword new_attribute_node(unsigned int i, int v) -{ - register halfword r = get_node(attribute_node_size); - type(r) = attribute_node; - attribute_id(r) = i; - attribute_value(r) = v; - return r; -} - -halfword copy_attribute_list(halfword n) -{ - halfword q = get_node(attribute_node_size); - register halfword p = q; - type(p) = attribute_list_node; - attr_list_ref(p) = 0; - n = vlink(n); - while (n != null) { - register halfword r = get_node(attribute_node_size); - /* the link will be fixed automatically in the next loop */ - (void) memcpy((void *) (varmem + r), (void *) (varmem + n), - (sizeof(memory_word) * attribute_node_size)); - vlink(p) = r; - p = r; - n = vlink(n); - } - return q; -} - -void update_attribute_cache(void) -{ - halfword p; - register int i; - attr_list_cache = get_node(attribute_node_size); - type(attr_list_cache) = attribute_list_node; - attr_list_ref(attr_list_cache) = 0; - p = attr_list_cache; - for (i = 0; i <= max_used_attr; i++) { - register int v = get_attribute(i); - if (v > UNUSED_ATTRIBUTE) { - register halfword r = new_attribute_node(i, v); - vlink(p) = r; - p = r; - } - } - if (vlink(attr_list_cache) == null) { - free_node(attr_list_cache, attribute_node_size); - attr_list_cache = null; - } - return; -} - -void build_attribute_list(halfword b) -{ - if (max_used_attr >= 0) { - if (attr_list_cache == cache_disabled) { - update_attribute_cache(); - if (attr_list_cache == null) - return; - } - attr_list_ref(attr_list_cache)++; - node_attr(b) = attr_list_cache; -#ifdef DEBUG - fprintf(stderr, "Added attrlist (%d) to node %d (count=%d)\n", - node_attr(b), b, attr_list_ref(attr_list_cache)); -#endif - } -} - -void delete_attribute_ref(halfword b) -{ - if (b != null) { - assert(type(b) == attribute_list_node); - attr_list_ref(b)--; -#ifdef DEBUG - fprintf(stderr, "Removed attrlistref (%d) (count=%d)\n", b, - attr_list_ref(b)); -#endif - if (attr_list_ref(b) == 0) { - if (b == attr_list_cache) - attr_list_cache = cache_disabled; - free_node_chain(b, attribute_node_size); - } - /* maintain sanity */ - if (attr_list_ref(b) < 0) - attr_list_ref(b) = 0; - } -} - -/* |p| is an attr list head, or zero */ - -halfword do_set_attribute(halfword p, int i, int val) -{ - register halfword q; - register int j = 0; - if (p == null) { /* add a new head & node */ - q = get_node(attribute_node_size); - type(q) = attribute_list_node; - attr_list_ref(q) = 1; - p = new_attribute_node(i, val); - vlink(q) = p; - return q; - } - q = p; - assert(vlink(p) != null); - while (vlink(p) != null) { - int t = attribute_id(vlink(p)); - if (t == i && attribute_value(vlink(p)) == val) - return q; /* no need to do anything */ - if (t >= i) - break; - j++; - p = vlink(p); - } - - p = q; - while (j-- > 0) - p = vlink(p); - if (attribute_id(vlink(p)) == i) { - attribute_value(vlink(p)) = val; - } else { /* add a new node */ - halfword r = new_attribute_node(i, val); - vlink(r) = vlink(p); - vlink(p) = r; - } - return q; -} - -void set_attribute(halfword n, int i, int val) -{ - register halfword p; - register int j = 0; - if (!nodetype_has_attributes(type(n))) - return; - p = node_attr(n); - if (p == null) { /* add a new head & node */ - p = get_node(attribute_node_size); - type(p) = attribute_list_node; - attr_list_ref(p) = 1; - node_attr(n) = p; - p = new_attribute_node(i, val); - vlink(node_attr(n)) = p; - return; - } - assert(vlink(p) != null); - while (vlink(p) != null) { - int t = attribute_id(vlink(p)); - if (t == i && attribute_value(vlink(p)) == val) - return; - if (t >= i) - break; - j++; - p = vlink(p); - } - p = node_attr(n); - if (attr_list_ref(p) != 1) { - if (attr_list_ref(p) > 1) { - p = copy_attribute_list(p); - delete_attribute_ref(node_attr(n)); - node_attr(n) = p; - } else { - fprintf(stdout, - "Node %d has an attribute list that is free already\n", - (int) n); - } - attr_list_ref(p) = 1; - } - while (j-- > 0) - p = vlink(p); - - if (attribute_id(vlink(p)) == i) { - attribute_value(vlink(p)) = val; - } else { /* add a new node */ - halfword r = new_attribute_node(i, val); - vlink(r) = vlink(p); - vlink(p) = r; - } - return; -} - - -int unset_attribute(halfword n, int i, int val) -{ - register halfword p; - register int t; - register int j = 0; - - if (!nodetype_has_attributes(type(n))) - return null; - p = node_attr(n); - if (p == null) - return UNUSED_ATTRIBUTE; - assert(vlink(p) != null); - while (vlink(p) != null) { - t = attribute_id(vlink(p)); - if (t > i) - return UNUSED_ATTRIBUTE; - if (t == i) { - p = vlink(p); - break; - } - j++; - p = vlink(p); - } - if (attribute_id(p) != i) - return UNUSED_ATTRIBUTE; - /* if we are still here, the attribute exists */ - p = node_attr(n); - if (attr_list_ref(p) != 1) { - if (attr_list_ref(p) > 1) { - p = copy_attribute_list(p); - delete_attribute_ref(node_attr(n)); - node_attr(n) = p; - } else { - fprintf(stdout, - "Node %d has an attribute list that is free already\n", - (int) n); - } - attr_list_ref(p) = 1; - } - p = vlink(p); - while (j-- > 0) - p = vlink(p); - t = attribute_value(p); - if (val == UNUSED_ATTRIBUTE || t == val) { - attribute_value(p) = UNUSED_ATTRIBUTE; - } - return t; -} - -int has_attribute(halfword n, int i, int val) -{ - register halfword p; - if (!nodetype_has_attributes(type(n))) - return UNUSED_ATTRIBUTE; - p = node_attr(n); - if (p == null || vlink(p) == null) - return UNUSED_ATTRIBUTE; - p = vlink(p); - while (p != null) { - if (attribute_id(p) == i) { - int ret = attribute_value(p); - if (val == UNUSED_ATTRIBUTE || val == ret) - return ret; - return UNUSED_ATTRIBUTE; - } else if (attribute_id(p) > i) { - return UNUSED_ATTRIBUTE; - } - p = vlink(p); - } - return UNUSED_ATTRIBUTE; -} - -void print_short_node_contents(halfword p) -{ - switch (type(p)) { - case hlist_node: - case vlist_node: - case ins_node: - case whatsit_node: - case mark_node: - case adjust_node: - case unset_node: - print_char('['); - print_char(']'); - break; - case rule_node: - print_char('|'); - break; - case glue_node: - if (glue_ptr(p) != zero_glue) - print_char(' '); - break; - case math_node: - print_char('$'); - break; - case disc_node: - short_display(vlink(pre_break(p))); - short_display(vlink(post_break(p))); - break; - default: - assert(1); - break; - } -} - - -static void show_pdftex_whatsit_rule_spec(integer p) -{ - tprint("("); - print_rule_dimen(pdf_height(p)); - print_char('+'); - print_rule_dimen(pdf_depth(p)); - tprint(")x"); - print_rule_dimen(pdf_width(p)); -} - - -/* -Each new type of node that appears in our data structure must be capable -of being displayed, copied, destroyed, and so on. The routines that we -need for write-oriented whatsits are somewhat like those for mark nodes; -other extensions might, of course, involve more subtlety here. -*/ - - -static void print_write_whatsit(const char *s, pointer p) -{ - tprint_esc(s); - if (write_stream(p) < 16) - print_int(write_stream(p)); - else if (write_stream(p) == 16) - print_char('*'); - else - print_char('-'); -} - - -static void show_whatsit_node(integer p) -{ - switch (subtype(p)) { - case open_node: - print_write_whatsit("openout", p); - print_char('='); - print_file_name(open_name(p), open_area(p), open_ext(p)); - break; - case write_node: - print_write_whatsit("write", p); - print_mark(write_tokens(p)); - break; - case close_node: - print_write_whatsit("closeout", p); - break; - case special_node: - tprint_esc("special"); - print_mark(write_tokens(p)); - break; - case dir_node: - if (dir_dir(p) < 0) { - tprint_esc("enddir"); - print_char(' '); - print_dir(dir_dir(p) + 64); - } else { - tprint_esc("begindir"); - print_char(' '); - print_dir(dir_dir(p)); - } - case local_par_node: - tprint_esc("whatsit"); - append_char('.'); - print_ln(); - print_current_string(); - tprint_esc("localinterlinepenalty"); - print_char('='); - print_int(local_pen_inter(p)); - print_ln(); - print_current_string(); - tprint_esc("localbrokenpenalty"); - print_char('='); - print_int(local_pen_broken(p)); - print_ln(); - print_current_string(); - tprint_esc("localleftbox"); - if (local_box_left(p) == null) { - tprint("=null"); - } else { - append_char('.'); - show_node_list(local_box_left(p)); - decr(pool_ptr); - } - print_ln(); - print_current_string(); - tprint_esc("localrightbox"); - if (local_box_right(p) == null) { - tprint("=null"); - } else { - append_char('.'); - show_node_list(local_box_right(p)); - decr(pool_ptr); - } - decr(pool_ptr); - break; - case pdf_literal_node: - show_pdf_literal(p); - break; - case pdf_colorstack_node: - tprint_esc("pdfcolorstack "); - print_int(pdf_colorstack_stack(p)); - switch (pdf_colorstack_cmd(p)) { - case colorstack_set: - tprint(" set "); - break; - case colorstack_push: - tprint(" push "); - break; - case colorstack_pop: - tprint(" pop"); - break; - case colorstack_current: - tprint(" current"); - break; - default: - tconfusion("pdfcolorstack"); - break; - } - if (pdf_colorstack_cmd(p) <= colorstack_data) - print_mark(pdf_colorstack_data(p)); - break; - case pdf_setmatrix_node: - tprint_esc("pdfsetmatrix"); - print_mark(pdf_setmatrix_data(p)); - break; - case pdf_save_node: - tprint_esc("pdfsave"); - break; - case pdf_restore_node: - tprint_esc("pdfrestore"); - break; - case cancel_boundary_node: - tprint_esc("noboundary"); - break; - case late_lua_node: - tprint_esc("latelua"); - print_int(late_lua_reg(p)); - print_mark(late_lua_data(p)); - break; - case close_lua_node: - tprint_esc("closelua"); - print_int(late_lua_reg(p)); - break; - case pdf_refobj_node: - tprint_esc("pdfrefobj"); - if (obj_obj_is_stream(pdf_obj_objnum(p)) > 0) { - if (obj_obj_stream_attr(pdf_obj_objnum(p)) != null) { - tprint(" attr"); - print_mark(obj_obj_stream_attr(pdf_obj_objnum(p))); - } - tprint(" stream"); - } - if (obj_obj_is_file(pdf_obj_objnum(p)) > 0) - tprint(" file"); - print_mark(obj_obj_data(pdf_obj_objnum(p))); - break; - case pdf_refxform_node: - tprint_esc("pdfrefxform"); - print_char('('); - print_scaled(obj_xform_height(pdf_xform_objnum(p))); - print_char('+'); - print_scaled(obj_xform_depth(pdf_xform_objnum(p))); - tprint(")x"); - print_scaled(obj_xform_width(pdf_xform_objnum(p))); - break; - case pdf_refximage_node: - tprint_esc("pdfrefximage"); - tprint("("); - print_scaled(pdf_height(p)); - print_char('+'); - print_scaled(pdf_depth(p)); - tprint(")x"); - print_scaled(pdf_width(p)); - break; - case pdf_annot_node: - tprint_esc("pdfannot"); - show_pdftex_whatsit_rule_spec(p); - print_mark(pdf_annot_data(p)); - break; - case pdf_start_link_node: - tprint_esc("pdfstartlink"); - show_pdftex_whatsit_rule_spec(p); - if (pdf_link_attr(p) != null) { - tprint(" attr"); - print_mark(pdf_link_attr(p)); - } - tprint(" action"); - if (pdf_action_type(pdf_link_action(p)) == pdf_action_user) { - tprint(" user"); - print_mark(pdf_action_tokens(pdf_link_action(p))); - return; - } - if (pdf_action_file(pdf_link_action(p)) != null) { - tprint(" file"); - print_mark(pdf_action_file(pdf_link_action(p))); - } - switch (pdf_action_type(pdf_link_action(p))) { - case pdf_action_goto: - if (pdf_action_named_id(pdf_link_action(p)) > 0) { - tprint(" goto name"); - print_mark(pdf_action_id(pdf_link_action(p))); - } else { - tprint(" goto num"); - print_int(pdf_action_id(pdf_link_action(p))); - } - break; - case pdf_action_page: - tprint(" page"); - print_int(pdf_action_id(pdf_link_action(p))); - print_mark(pdf_action_tokens(pdf_link_action(p))); - break; - case pdf_action_thread: - if (pdf_action_named_id(pdf_link_action(p)) > 0) { - tprint(" thread name"); - print_mark(pdf_action_id(pdf_link_action(p))); - } else { - tprint(" thread num"); - print_int(pdf_action_id(pdf_link_action(p))); - } - break; - default: - pdf_error(maketexstring("displaying"), - maketexstring("unknown action type")); - break; - } - break; - case pdf_end_link_node: - tprint_esc("pdfendlink"); - break; - case pdf_dest_node: - tprint_esc("pdfdest"); - if (pdf_dest_named_id(p) > 0) { - tprint(" name"); - print_mark(pdf_dest_id(p)); - } else { - tprint(" num"); - print_int(pdf_dest_id(p)); - } - print_char(' '); - switch (pdf_dest_type(p)) { - case pdf_dest_xyz: - tprint("xyz"); - if (pdf_dest_xyz_zoom(p) != null) { - tprint(" zoom"); - print_int(pdf_dest_xyz_zoom(p)); - } - break; - case pdf_dest_fitbh: - tprint("fitbh"); - break; - case pdf_dest_fitbv: - tprint("fitbv"); - break; - case pdf_dest_fitb: - tprint("fitb"); - break; - case pdf_dest_fith: - tprint("fith"); - break; - case pdf_dest_fitv: - tprint("fitv"); - break; - case pdf_dest_fitr: - tprint("fitr"); - show_pdftex_whatsit_rule_spec(p); - break; - case pdf_dest_fit: - tprint("fit"); - break; - default: - tprint("unknown!"); - break; - } - break; - case pdf_thread_node: - case pdf_start_thread_node: - if (subtype(p) == pdf_thread_node) - tprint_esc("pdfthread"); - else - tprint_esc("pdfstartthread"); - tprint("("); - print_rule_dimen(pdf_height(p)); - print_char('+'); - print_rule_dimen(pdf_depth(p)); - tprint(")x"); - print_rule_dimen(pdf_width(p)); - if (pdf_thread_attr(p) != null) { - tprint(" attr"); - print_mark(pdf_thread_attr(p)); - } - if (pdf_thread_named_id(p) > 0) { - tprint(" name"); - print_mark(pdf_thread_id(p)); - } else { - tprint(" num"); - print_int(pdf_thread_id(p)); - } - break; - case pdf_end_thread_node: - tprint_esc("pdfendthread"); - break; - case pdf_save_pos_node: - tprint_esc("pdfsavepos"); - break; - case user_defined_node: - tprint_esc("whatsit"); - print_int(user_node_id(p)); - print_char('='); - switch (user_node_type(p)) { - case 'a': - tprint("<>"); - break; - case 'n': - tprint("["); - show_node_list(user_node_value(p)); - tprint("]"); - break; - case 's': - print_char('"'); - print(user_node_value(p)); - print_char('"'); - break; - case 't': - print_mark(user_node_value(p)); - break; - default: /* only 'd' */ - print_int(user_node_value(p)); - break; - } - break; - default: - tprint("whatsit?"); - break; - } -} - - -/* - Now we are ready for |show_node_list| itself. This procedure has been - written to be ``extra robust'' in the sense that it should not crash or get - into a loop even if the data structures have been messed up by bugs in - the rest of the program. You can safely call its parent routine - |show_box(p)| for arbitrary values of |p| when you are debugging \TeX. - However, in the presence of bad data, the procedure may - fetch a |memory_word| whose variant is different from the way it was stored; - for example, it might try to read |mem[p].hh| when |mem[p]| - contains a scaled integer, if |p| is a pointer that has been - clobbered or chosen at random. -*/ - -/* |str_room| need not be checked; see |show_box| */ - -/* Recursive calls on |show_node_list| therefore use the following pattern: */ - -#define node_list_display(A) do { \ - append_char('.'); \ - show_node_list(A); \ - flush_char(); \ -} while (0) - -void show_node_list(integer p) -{ /* prints a node list symbolically */ - integer n; /* the number of items already printed at this level */ - real g; /* a glue ratio, as a floating point number */ - if (cur_length > depth_threshold) { - if (p > null) - tprint(" []"); /* indicate that there's been some truncation */ - return; - } - n = 0; - while (p != null) { - print_ln(); - print_current_string(); /* display the nesting history */ - if (int_par(param_tracing_online_code) < -2) - print_int(p); - incr(n); - if (n > breadth_max) { /* time to stop */ - tprint("etc."); - return; - } - /* @<Display node |p|@> */ - if (is_char_node(p)) { - print_font_and_char(p); - if (is_ligature(p)) { - /* @<Display ligature |p|@>; */ - tprint(" (ligature "); - if (is_leftboundary(p)) - print_char('|'); - font_in_short_display = font(p); - short_display(lig_ptr(p)); - if (is_rightboundary(p)) - print_char('|'); - print_char(')'); - } - } else { - switch (type(p)) { - case hlist_node: - case vlist_node: - case unset_node: - /* @<Display box |p|@>; */ - if (type(p) == hlist_node) - tprint_esc("h"); - else if (type(p) == vlist_node) - tprint_esc("v"); - else - tprint_esc("unset"); - tprint("box("); - print_scaled(height(p)); - print_char('+'); - print_scaled(depth(p)); - tprint(")x"); - print_scaled(width(p)); - if (type(p) == unset_node) { - /* @<Display special fields of the unset node |p|@>; */ - if (span_count(p) != min_quarterword) { - tprint(" ("); - print_int(span_count(p) + 1); - tprint(" columns)"); - } - if (glue_stretch(p) != 0) { - tprint(", stretch "); - print_glue(glue_stretch(p), glue_order(p), 0); - } - if (glue_shrink(p) != 0) { - tprint(", shrink "); - print_glue(glue_shrink(p), glue_sign(p), 0); - } - } else { - /*<Display the value of |glue_set(p)|@> */ - /* The code will have to change in this place if |glue_ratio| is - a structured type instead of an ordinary |real|. Note that this routine - should avoid arithmetic errors even if the |glue_set| field holds an - arbitrary random value. The following code assumes that a properly - formed nonzero |real| number has absolute value $2^{20}$ or more when - it is regarded as an integer; this precaution was adequate to prevent - floating point underflow on the author's computer. - */ - - g = (real) (glue_set(p)); - if ((g != 0.0) && (glue_sign(p) != normal)) { - tprint(", glue set "); - if (glue_sign(p) == shrinking) - tprint("- "); - if (g > 20000.0 || g < -20000.0) { - if (g > 0.0) - print_char('>'); - else - tprint("< -"); - print_glue(20000 * unity, glue_order(p), 0); - } else { - print_glue(round(unity * g), glue_order(p), 0); - } - } - - if (shift_amount(p) != 0) { - tprint(", shifted "); - print_scaled(shift_amount(p)); - } - tprint(", direction "); - print_dir(box_dir(p)); - } - node_list_display(list_ptr(p)); /* recursive call */ - break; - case rule_node: - /* @<Display rule |p|@>; */ - tprint_esc("rule("); - print_rule_dimen(height(p)); - print_char('+'); - print_rule_dimen(depth(p)); - tprint(")x"); - print_rule_dimen(width(p)); - break; - case ins_node: - /* @<Display insertion |p|@>; */ - tprint_esc("insert"); - print_int(subtype(p)); - tprint(", natural size "); - print_scaled(height(p)); - tprint("; split("); - print_spec(split_top_ptr(p), 0); - print_char(','); - print_scaled(depth(p)); - tprint("); float cost "); - print_int(float_cost(p)); - node_list_display(ins_ptr(p)); /* recursive call */ - break; - case whatsit_node: - show_whatsit_node(p); - break; - case glue_node: - /* @<Display glue |p|@>; */ - if (subtype(p) >= a_leaders) { - /* @<Display leaders |p|@>; */ - tprint_esc(""); - if (subtype(p) == c_leaders) - print_char('c'); - else if (subtype(p) == x_leaders) - print_char('x'); - tprint("leaders "); - print_spec(glue_ptr(p), 0); - node_list_display(leader_ptr(p)); /* recursive call */ - } else { - tprint_esc("glue"); - if (subtype(p) != normal) { - print_char('('); - if (subtype(p) < cond_math_glue) - print_skip_param(subtype(p) - 1); - else if (subtype(p) == cond_math_glue) - tprint_esc("nonscript"); - else - tprint_esc("mskip"); - print_char(')'); - } - if (subtype(p) != cond_math_glue) { - print_char(' '); - if (subtype(p) < cond_math_glue) - print_spec(glue_ptr(p), 0); - else - print_spec(glue_ptr(p), maketexstring("mu")); - } - } - break; - case margin_kern_node: - tprint_esc("kern"); - print_scaled(width(p)); - if (subtype(p) == left_side) - tprint(" (left margin)"); - else - tprint(" (right margin)"); - break; - case kern_node: - /* @<Display kern |p|@>; */ - /* An ``explicit'' kern value is indicated implicitly by an explicit space. */ - if (subtype(p) != mu_glue) { - tprint_esc("kern"); - if (subtype(p) != normal) - print_char(' '); - print_scaled(width(p)); - if (subtype(p) == acc_kern) - tprint(" (for accent)"); - } else { - tprint_esc("mkern"); - print_scaled(width(p)); - tprint("mu"); - } - break; - case math_node: - /* @<Display math node |p|@>; */ - tprint_esc("math"); - if (subtype(p) == before) - tprint("on"); - else - tprint("off"); - if (width(p) != 0) { - tprint(", surrounded "); - print_scaled(width(p)); - } - break; - case penalty_node: - /* @<Display penalty |p|@>; */ - tprint_esc("penalty "); - print_int(penalty(p)); - break; - case disc_node: - /* @<Display discretionary |p|@>; */ - /* The |post_break| list of a discretionary node is indicated by a prefixed - `\.{\char'174}' instead of the `\..' before the |pre_break| list. */ - tprint_esc("discretionary"); - if (vlink(no_break(p)) != null) { - tprint(" replacing "); - node_list_display(vlink(no_break(p))); - } - node_list_display(vlink(pre_break(p))); /* recursive call */ - append_char('|'); - show_node_list(vlink(post_break(p))); - flush_char(); /* recursive call */ - break; - case mark_node: - /* @<Display mark |p|@>; */ - tprint_esc("mark"); - if (mark_class(p) != 0) { - print_char('s'); - print_int(mark_class(p)); - } - print_mark(mark_ptr(p)); - break; - case adjust_node: - /* @<Display adjustment |p|@>; */ - tprint_esc("vadjust"); - if (adjust_pre(p) != 0) - tprint(" pre "); - node_list_display(adjust_ptr(p)); /* recursive call */ - break; - default: - show_math_node(p); - break; - } - } - p = vlink(p); - } -} - -/* This routine finds the 'base' width of a horizontal box, using the same logic - that \TeX82 used for \.{\\predisplaywidth} */ - -pointer actual_box_width(pointer r, scaled base_width) -{ - scaled w; /* calculated |size| */ - pointer p; /* current node when calculating |pre_display_size| */ - pointer q; /* glue specification when calculating |pre_display_size| */ - internal_font_number f; /* font in current |char_node| */ - scaled d; /* increment to |v| */ - scaled v; /* |w| plus possible glue amount */ - w = -max_dimen; - v = shift_amount(r) + base_width; - p = list_ptr(r); - while (p != null) { - if (is_char_node(p)) { - f = font(p); - d = glyph_width(p); - goto found; - } - switch (type(p)) { - case hlist_node: - case vlist_node: - case rule_node: - d = width(p); - goto found; - break; - case margin_kern_node: - d = width(p); - break; - case kern_node: - d = width(p); - break; - case math_node: - d = surround(p); - break; - case glue_node: - /* We need to be careful that |w|, |v|, and |d| do not depend on any |glue_set| - values, since such values are subject to system-dependent rounding. - System-dependent numbers are not allowed to infiltrate parameters like - |pre_display_size|, since \TeX82 is supposed to make the same decisions on all - machines. - */ - q = glue_ptr(p); - d = width(q); - if (glue_sign(r) == stretching) { - if ((glue_order(r) == stretch_order(q)) - && (stretch(q) != 0)) - v = max_dimen; - } else if (glue_sign(r) == shrinking) { - if ((glue_order(r) == shrink_order(q)) - && (shrink(q) != 0)) - v = max_dimen; - } - if (subtype(p) >= a_leaders) - goto found; - break; - case whatsit_node: - if ((subtype(p) == pdf_refxform_node) - || (subtype(p) == pdf_refximage_node)) - d = pdf_width(p); - else - d = 0; - break; - default: - d = 0; - break; - } - if (v < max_dimen) - v = v + d; - goto not_found; - found: - if (v < max_dimen) { - v = v + d; - w = v; - } else { - w = max_dimen; - break; - } - not_found: - p = vlink(p); - } - return w; -} |