From f8d4d9017cefd1e852971cd17c934530703b89ab Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 6 Jun 2009 15:47:13 +0000 Subject: updated to xetex 0.9994.0 git-svn-id: svn://tug.org/texlive/trunk@13644 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/Makefile.in | 1 + Build/source/texk/web2c/xetexdir/am/xetex.am | 1 + Build/source/texk/web2c/xetexdir/xetex-latex3.ch | 865 +++++++++++++++++++++++ Build/source/texk/web2c/xetexdir/xetex.ch | 166 +++-- Build/source/texk/web2c/xetexdir/xetex.defines | 1 + Build/source/texk/web2c/xetexdir/xetex.h | 5 + Build/source/texk/web2c/xetexdir/xetex.mk | 1 + 7 files changed, 979 insertions(+), 61 deletions(-) create mode 100644 Build/source/texk/web2c/xetexdir/xetex-latex3.ch diff --git a/Build/source/texk/web2c/Makefile.in b/Build/source/texk/web2c/Makefile.in index b8b81f21303..809cdf4e272 100644 --- a/Build/source/texk/web2c/Makefile.in +++ b/Build/source/texk/web2c/Makefile.in @@ -1866,6 +1866,7 @@ xetex_web_srcs = \ etexdir/tex.ech \ $(xetex_ch_synctex) \ xetexdir/xetex.ch \ + xetexdir/xetex-latex3.ch \ $(xetex_post_ch_synctex) libxetex_a_CPPFLAGS = $(xetex_cppflags) diff --git a/Build/source/texk/web2c/xetexdir/am/xetex.am b/Build/source/texk/web2c/xetexdir/am/xetex.am index 4ed3231b279..e55f89af3da 100644 --- a/Build/source/texk/web2c/xetexdir/am/xetex.am +++ b/Build/source/texk/web2c/xetexdir/am/xetex.am @@ -115,6 +115,7 @@ xetex_web_srcs = \ etexdir/tex.ech \ $(xetex_ch_synctex) \ xetexdir/xetex.ch \ + xetexdir/xetex-latex3.ch \ $(xetex_post_ch_synctex) ## EXTRA_DIST += $(xetex_web_srcs) xetexdir/xetex.defines xetexdir/xetexextra.in diff --git a/Build/source/texk/web2c/xetexdir/xetex-latex3.ch b/Build/source/texk/web2c/xetexdir/xetex-latex3.ch new file mode 100644 index 00000000000..2db7198b330 --- /dev/null +++ b/Build/source/texk/web2c/xetexdir/xetex-latex3.ch @@ -0,0 +1,865 @@ +% When updating code here, also increment version number/string in xetex.ch + +% \vadjust +@x l.3142 +@d adjust_node=5 {|type| of an adjust node} +@y +@d adjust_node=5 {|type| of an adjust node} +@d adjust_pre == subtype {pre-adjustment?} +@#{|append_list| is used to append a list to |tail|} +@d append_list(#) == begin link(tail) := link(#); append_list_end +@d append_list_end(#) == tail := #; end +@z + +% \vadjust +@x l.3581 +@d backup_head==mem_top-13 {head of token list built by |scan_keyword|} +@d hi_mem_stat_min==mem_top-13 {smallest statically allocated word in + the one-word |mem|} +@d hi_mem_stat_usage=14 {the number of one-word nodes always present} +@y +@d backup_head==mem_top-13 {head of token list built by |scan_keyword|} +@d pre_adjust_head==mem_top-14 {head of pre-adjustment list returned by |hpack|} +@d hi_mem_stat_min==mem_top-14 {smallest statically allocated word in + the one-word |mem|} +@d hi_mem_stat_usage=15 {the number of one-word nodes always present} +@z + +% \vadjust +@x l.4145 +begin print_esc("vadjust"); node_list_display(adjust_ptr(p)); {recursive call} +@y +begin print_esc("vadjust"); if adjust_pre(p) <> 0 then print(" pre "); +node_list_display(adjust_ptr(p)); {recursive call} +@z + +% \primitive +@x l.4868 +@d frozen_null_font=frozen_control_sequence+11 + {permanent `\.{\\nullfont}'} +@y +@d frozen_primitive=frozen_control_sequence+11 + {permanent `\.{\\primitive}'} +@d frozen_null_font=frozen_control_sequence+12 + {permanent `\.{\\nullfont}'} +@z + +% \primitive +% \ifprimitive +@x l.5942 +@!cs_count:integer; {total number of known identifiers} + +@ @= +no_new_control_sequence:=true; {new identifiers are usually forbidden} + +@ @= +hash_used:=frozen_control_sequence; {nothing is used} +hash_high:=0; +cs_count:=0; +eq_type(frozen_dont_expand):=dont_expand; +text(frozen_dont_expand):="notexpanded:"; +@.notexpanded:@> +@y +@!cs_count:integer; {total number of known identifiers} + +@ Primitive support needs a few extra variables and definitions + +@d prim_size=480 {maximum number of primitives } +@d prim_prime=409 {about 85\pct! of |primitive_size|} +@d prim_base=1 +@d prim_next(#) == prim[#].lh {link for coalesced lists} +@d prim_text(#) == prim[#].rh {string number for control sequence name} +@d prim_is_full == (prim_used=prim_base) {test if all positions are occupied} +@d prim_eq_level_field(#)==#.hh.b1 +@d prim_eq_type_field(#)==#.hh.b0 +@d prim_equiv_field(#)==#.hh.rh +@d prim_eq_level(#)==prim_eq_level_field(prim_eqtb[#]) {level of definition} +@d prim_eq_type(#)==prim_eq_type_field(prim_eqtb[#]) {command code for equivalent} +@d prim_equiv(#)==prim_equiv_field(prim_eqtb[#]) {equivalent value} +@d undefined_primitive=0 + +@= +@!prim: array [0..prim_size] of two_halves; {the primitives table} +@!prim_used:pointer; {allocation pointer for |prim|} +@!prim_eqtb:array[0..prim_size] of memory_word; + +@ @= +no_new_control_sequence:=true; {new identifiers are usually forbidden} +prim_next(0):=0; prim_text(0):=0; +for k:=1 to prim_size do prim[k]:=prim[0]; +prim_eq_level(0) := level_zero; +prim_eq_type(0) := undefined_cs; +prim_equiv(0) := null; +for k:=1 to prim_size do prim_eqtb[k]:=prim_eqtb[0]; + +@ @= +prim_used:=prim_size; {nothing is used} +hash_used:=frozen_control_sequence; {nothing is used} +hash_high:=0; +cs_count:=0; +eq_type(frozen_dont_expand):=dont_expand; +text(frozen_dont_expand):="notexpanded:"; +@.notexpanded:@> + +eq_type(frozen_primitive):=ignore_spaces; +equiv(frozen_primitive):=1; +eq_level(frozen_primitive):=level_one; +text(frozen_primitive):="primitive"; +@z + +% \primitive +% \ifprimitive +@x l.6029 +@ Single-character control sequences do not need to be looked up in a hash +@y +@ Here is the subroutine that searches the primitive table for an identifier + +@p function prim_lookup(@!s:str_number):pointer; {search the primitives table} +label found; {go here if you found it} +var h:integer; {hash code} +@!p:pointer; {index in |hash| array} +@!k:pointer; {index in string pool} +@!j,@!l:integer; +begin +if s<256 then begin + p := s; + if (p<0) or (prim_eq_level(p)<>level_one) then + p := undefined_primitive; +end +else begin + j:=str_start_macro(s); + if s = str_ptr then l := cur_length else l := length(s); + @; + p:=h+prim_base; {we start searching here; note that |0<=h0 then if length(prim_text(p))=l then + if str_eq_str(prim_text(p),s) then goto found; + if prim_next(p)=0 then + begin if no_new_control_sequence then + p:=undefined_primitive + else @; + goto found; + end; + p:=prim_next(p); + end; + end; +found: prim_lookup:=p; +end; + +@ @= +begin if prim_text(p)>0 then + begin repeat if prim_is_full then overflow("primitive size",prim_size); +@:TeX capacity exceeded primitive size}{\quad primitive size@> + decr(prim_used); + until prim_text(prim_used)=0; {search for an empty location in |prim|} + prim_next(p):=prim_used; p:=prim_used; + end; +prim_text(p):=s; +end + +@ The value of |prim_prime| should be roughly 85\pct! of +|prim_size|, and it should be a prime number. + +@= +h:=str_pool[j]; +for k:=j+1 to j+l-1 do + begin h:=h+h+str_pool[k]; + while h>=prim_prime do h:=h-prim_prime; + end + +@ Single-character control sequences do not need to be looked up in a hash +@z + +% \primitive +@x +@p @!init procedure primitive(@!s:str_number;@!c:quarterword;@!o:halfword); +var k:pool_pointer; {index into |str_pool|} +@!j:0..buf_size; {index into |buffer|} +@!l:small_number; {length of the string} +begin if s<256 then cur_val:=s+single_base +else begin k:=str_start_macro(s); l:=str_start_macro(s+1)-k; + {we will move |s| into the (possibly non-empty) |buffer|} + if first+l>buf_size+1 then + overflow("buffer size",buf_size); +@:TeX capacity exceeded buffer size}{\quad buffer size@> + for j:=0 to l-1 do buffer[first+j]:=so(str_pool[k+j]); + cur_val:=id_lookup(first,l); {|no_new_control_sequence| is |false|} + flush_string; text(cur_val):=s; {we don't want to have the string twice} + end; +eq_level(cur_val):=level_one; eq_type(cur_val):=c; equiv(cur_val):=o; +end; +@y +@p @!init procedure primitive(@!s:str_number;@!c:quarterword;@!o:halfword); +var k:pool_pointer; {index into |str_pool|} +@!j:0..buf_size; {index into |buffer|} +@!l:small_number; {length of the string} +@!prim_val:integer; {needed to fill |prim_eqtb|} +begin if s<256 then begin + cur_val:=s+single_base; + prim_val:=s; +end +else begin k:=str_start_macro(s); l:=str_start_macro(s+1)-k; + {we will move |s| into the (possibly non-empty) |buffer|} + if first+l>buf_size+1 then + overflow("buffer size",buf_size); +@:TeX capacity exceeded buffer size}{\quad buffer size@> + for j:=0 to l-1 do buffer[first+j]:=so(str_pool[k+j]); + cur_val:=id_lookup(first,l); {|no_new_control_sequence| is |false|} + flush_string; text(cur_val):=s; {we don't want to have the string twice} + prim_val:=prim_lookup(s); + end; +eq_level(cur_val):=level_one; eq_type(cur_val):=c; equiv(cur_val):=o; +prim_eq_level(prim_val):=level_one; +prim_eq_type(prim_val):=c; +prim_equiv(prim_val):=o; +end; +@z + +% \primitive +@x l.6163 +@!@:no_expand_}{\.{\\noexpand} primitive@> +@y +@!@:no_expand_}{\.{\\noexpand} primitive@> +primitive("primitive",no_expand,1);@/ +@!@:primitive_}{\.{\\primitive} primitive@> +@z + +% \primitive +@x l.6224 +ignore_spaces: print_esc("ignorespaces"); +@y +ignore_spaces: if chr_code=0 then print_esc("ignorespaces") else print_esc("primitive"); +@z + +% \primitive +@x l.6239 +no_expand: print_esc("noexpand"); +@y +no_expand: if chr_code=0 then print_esc("noexpand") + else print_esc("primitive"); +@z + +% \ifincsname +@x l.8348 +@ @= +@y +@ @= +@!is_in_csname: boolean; + +@ @= +is_in_csname := false; + +@ @= +@z + +% \primitive +@x l.8354 +no_expand:@; +@y +no_expand: if cur_chr=0 then @ + else @; +@z + +% \primitive +@x l.8391 +@ @= +@y +@ The \.{\\primitive} handling. If the primitive meaning of the next +token is an expandable command, it suffices to replace the current +token with the primitive one and restart |expand|/ + +Otherwise, the token we just read has to be pushed back, as well +as a token matching the internal form of \.{\\primitive}, that is +sneaked in as an alternate form of |ignore_spaces|. +@!@:primitive_}{\.{\\primitive} primitive (internalized)@> + +Simply pushing back a token that matches the correct internal command +does not work, because approach would not survive roundtripping to a +temporary file. + +@= +begin save_scanner_status := scanner_status; scanner_status:=normal; +get_token; scanner_status:=save_scanner_status; +if cur_cs < hash_base then + cur_cs := prim_lookup(cur_cs-257) +else + cur_cs := prim_lookup(text(cur_cs)); +if cur_cs<>undefined_primitive then begin + t := prim_eq_type(cur_cs); + if t>max_command then begin + cur_cmd := t; + cur_chr := prim_equiv(cur_cs); + cur_tok := (cur_cmd*max_char_val)+cur_chr; + cur_cs := 0; + goto reswitch; + end + else begin + back_input; { now |loc| and |start| point to a one-item list } + p:=get_avail; info(p):=cs_token_flag+frozen_primitive; + link(p):=loc; loc:=p; start:=p; + end; + end; +end + +@ @= +@z + +% \ifincsname +@x l.8415 +repeat get_x_token; +if cur_cs=0 then store_new_token(cur_tok); +until cur_cs<>0; +if (cur_cmd<>end_cs_name) or (cur_chr<>0) then @; +@y +is_in_csname := true; +repeat get_x_token; +if cur_cs=0 then store_new_token(cur_tok); +until cur_cs<>0; +if (cur_cmd<>end_cs_name) or (cur_chr<>0) then @; +is_in_csname := false; +@z + +% \strcmp +% \shellescape +@x l.29172 +@d pdf_last_x_pos_code = XeTeX_int+27 +@d pdf_last_y_pos_code = XeTeX_int+28 + +@d XeTeX_pdf_page_count_code = XeTeX_int+29 + +{ NB: must update |eTeX_dim| when items are added here! } +@# +@d eTeX_dim=XeTeX_int+30 {first of \eTeX\ codes for dimensions} + {changed for \XeTeX\ to make room for \XeTeX\ integers} +@y +@d pdf_last_x_pos_code = XeTeX_int+27 +@d pdf_last_y_pos_code = XeTeX_int+28 +@d pdf_strcmp_code = XeTeX_int+29 +@d pdf_shell_escape_code = XeTeX_int+30 + +@d XeTeX_pdf_page_count_code = XeTeX_int+31 + +{ NB: must update |eTeX_dim| when items are added here! } +@# +@d eTeX_dim=XeTeX_int+32 {first of \eTeX\ codes for dimensions} + {changed for \XeTeX\ to make room for \XeTeX\ integers} +@z + +% \shellescape +@x l.9244 + input_line_no_code: print_esc("inputlineno"); +@y + input_line_no_code: print_esc("inputlineno"); + pdf_shell_escape_code: print_esc("shellescape"); +@z + +@x l.9322 + badness_code: cur_val:=last_badness; +@y + badness_code: cur_val:=last_badness; + pdf_shell_escape_code: + begin + if shellenabledp then cur_val := 1 + else cur_val := 0; + end; +@z + +% \strcmp +@x l.10165 + font_name_code: print_esc("fontname"); +@y + font_name_code: print_esc("fontname"); + pdf_strcmp_code: print_esc("strcmp"); +@z + +% \strcmp +@x l.10174 +@p procedure conv_toks; +var old_setting:0..max_selector; {holds |selector| setting} +@y +The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates +any pending string in its output. In order to save such a pending string, +we have to create a temporary string that is destroyed immediately after. + +@d save_cur_string==if str_start_macro(str_ptr)0 then decr(str_ptr) + +@p procedure conv_toks; +var old_setting:0..max_selector; {holds |selector| setting} +@!save_warning_index, @!save_def_ref:pointer; +@!u: str_number; +@z + +% \ifprimitive +@x l.10483 +@d if_case_code=16 { `\.{\\ifcase}' } +@y +@d if_case_code=16 { `\.{\\ifcase}' } +@d if_primitive_code=21 { `\.{\\ifprimitive}' } +@z + +% \ifprimitive +@x l.10519 +@!@:if_case_}{\.{\\ifcase} primitive@> +@y +@!@:if_case_}{\.{\\ifcase} primitive@> +primitive("ifprimitive",if_test,if_primitive_code); +@!@:if_primitive_}{\.{\\ifprimitive} primitive@> +@z + +% \ifprimitive +@x l.10539 + if_case_code:print_esc("ifcase"); +@y + if_case_code:print_esc("ifcase"); + if_primitive_code:print_esc("ifprimitive"); +@z + +% \ifprimitive +@x l.10723 +if_case_code: @; +if_primitive_code: begin + save_scanner_status:=scanner_status; + scanner_status:=normal; + get_next; + scanner_status:=save_scanner_status; + if cur_cs < hash_base then + m := prim_lookup(cur_cs-257) + else + m := prim_lookup(text(cur_cs)); + b :=((cur_cmd<>undefined_cs) and + (m<>undefined_primitive) and + (cur_cmd=prim_eq_type(m)) and + (cur_chr=prim_equiv(m))); + end; +@z + +% \vadjust +@x l.14527 +if adjust_tail<>null then link(adjust_tail):=null; +@y +if adjust_tail<>null then link(adjust_tail):=null; +if pre_adjust_tail<>null then link(pre_adjust_tail):=null; +@z + +% \vadjust +@x l.14607 +@= +begin while link(q)<>p do q:=link(q); +if type(p)=adjust_node then + begin link(adjust_tail):=adjust_ptr(p); + while link(adjust_tail)<>null do adjust_tail:=link(adjust_tail); + p:=link(p); free_node(link(q),small_node_size); + end +else begin link(adjust_tail):=p; adjust_tail:=p; p:=link(p); + end; +link(q):=p; p:=q; +end +@y +@= +@!pre_adjust_tail: pointer; + +@ @= +pre_adjust_tail := null; + +@ Materials in \.{\\vadjust} used with \.{pre} keyword will be appended to +|pre_adjust_tail| instead of |adjust_tail|. + +@d update_adjust_list(#) == begin + link(#) := adjust_ptr(p); + while link(#) <> null do + # := link(#); +end + +@= +begin while link(q)<>p do q:=link(q); + if type(p) = adjust_node then begin + if adjust_pre(p) <> 0 then + update_adjust_list(pre_adjust_tail) + else + update_adjust_list(adjust_tail); + p := link(p); free_node(link(q), small_node_size); + end +else begin link(adjust_tail):=p; adjust_tail:=p; p:=link(p); + end; +link(q):=p; p:=q; +end +@z + +% \vadjust +@x l.17583 +@d align_stack_node_size=5 {number of |mem| words to save alignment states} +@y +@d align_stack_node_size=6 {number of |mem| words to save alignment states} +@z + +% \vadjust +@x l.17590 +@!cur_head,@!cur_tail:pointer; {adjustment list pointers} +@y +@!cur_head,@!cur_tail:pointer; {adjustment list pointers} +@!cur_pre_head,@!cur_pre_tail:pointer; {pre-adjustment list pointers} +@z + +% \vadjust +@x l.17596 +cur_head:=null; cur_tail:=null; +@y +cur_head:=null; cur_tail:=null; +cur_pre_head:=null; cur_pre_tail:=null; +@z + +% \vadjust +@x l.17607 +info(p+4):=cur_head; link(p+4):=cur_tail; +@y +info(p+4):=cur_head; link(p+4):=cur_tail; +info(p+5):=cur_pre_head; link(p+5):=cur_pre_tail; +@z + +% \vadjust +@x l.17616 +cur_tail:=link(p+4); cur_head:=info(p+4); +@y +cur_pre_tail:=link(p+5); cur_pre_head:=info(p+5); +cur_tail:=link(p+4); cur_head:=info(p+4); +@z + +% \vadjust +@x l.17690 + begin adjust_tail:=cur_tail; u:=hpack(link(head),natural); w:=width(u); + cur_tail:=adjust_tail; adjust_tail:=null; + end +@y + begin adjust_tail:=cur_tail; pre_adjust_tail:=cur_pre_tail; + u:=hpack(link(head),natural); w:=width(u); + cur_tail:=adjust_tail; adjust_tail:=null; + cur_pre_tail:=pre_adjust_tail; pre_adjust_tail:=null; + end +@z + +% \vadjust +@x l.19508 +append_to_vlist(just_box); +if adjust_head<>adjust_tail then + begin link(tail):=link(adjust_head); tail:=adjust_tail; + end; +@y +if pre_adjust_head <> pre_adjust_tail then + append_list(pre_adjust_head)(pre_adjust_tail); +pre_adjust_tail := null; +append_to_vlist(just_box); +if adjust_head <> adjust_tail then + append_list(adjust_head)(adjust_tail); +@z + +% \vadjust +@x 19529 +adjust_tail:=adjust_head; just_box:=hpack(q,cur_width,exactly); +@y +adjust_tail:=adjust_head; +pre_adjust_tail := pre_adjust_head; +just_box:=hpack(q,cur_width,exactly); +@z + +% \primitive +@x +any_mode(ignore_spaces): begin @; + goto reswitch; + end; +@y +any_mode(ignore_spaces): begin + if cur_chr = 0 then begin + @; + goto reswitch; + end + else begin + t:=scanner_status; + scanner_status:=normal; + get_next; + scanner_status:=t; + if cur_cs < hash_base then + cur_cs := prim_lookup(cur_cs-257) + else + cur_cs := prim_lookup(text(cur_cs)); + if cur_cs<>undefined_primitive then begin + cur_cmd := prim_eq_type(cur_cs); + cur_chr := prim_equiv(cur_cs); + goto reswitch; + end; + end; + end; +@z + +% \vadjust +@x l.23545 + begin append_to_vlist(cur_box); + if adjust_tail<>null then + begin if adjust_head<>adjust_tail then + begin link(tail):=link(adjust_head); tail:=adjust_tail; + end; +@y + begin + if pre_adjust_tail <> null then begin + if pre_adjust_head <> pre_adjust_tail then + append_list(pre_adjust_head)(pre_adjust_tail); + pre_adjust_tail := null; + end; + append_to_vlist(cur_box); + if adjust_tail <> null then begin + if adjust_head <> adjust_tail then + append_list(adjust_head)(adjust_tail); +@z + +% \vadjust +@x l.23716 +adjusted_hbox_group: begin adjust_tail:=adjust_head; package(0); +@y +adjusted_hbox_group: begin adjust_tail:=adjust_head; + pre_adjust_tail:=pre_adjust_head; package(0); +@z + +% \vadjust +@x l.23870 + help1("I'm changing to \insert0; box 255 is special."); + error; cur_val:=0; + end; + end; +saved(0):=cur_val; incr(save_ptr); +new_save_level(insert_group); scan_left_brace; normal_paragraph; +push_nest; mode:=-vmode; prev_depth:=ignore_depth; +end; +@y + help1("I'm changing to \insert0; box 255 is special."); + error; cur_val:=0; + end; + end; +saved(0) := cur_val; +if (cur_cmd = vadjust) and scan_keyword("pre") then + saved(1) := 1 +else + saved(1) := 0; +save_ptr := save_ptr + 2; +new_save_level(insert_group); scan_left_brace; normal_paragraph; +push_nest; mode:=-vmode; prev_depth:=ignore_depth; +end; +@z + +% \vadjust +@x + d:=split_max_depth; f:=floating_penalty; unsave; decr(save_ptr); +@y + d:=split_max_depth; f:=floating_penalty; unsave; save_ptr:=save_ptr-2; +@z + +% \vadjust +@x l.23892 + subtype(tail):=0; {the |subtype| is not used} +@y + adjust_pre(tail) := saved(1); {the |subtype| is used for |adjust_pre|} +@z + +% \vadjust +@x +@!t:pointer; {tail of adjustment list} +@y +@!t:pointer; {tail of adjustment list} +@!pre_t:pointer; {tail of pre-adjustment list} +@z + +% \vadjust +@x l.25339 +adjust_tail:=adjust_head; b:=hpack(p,natural); p:=list_ptr(b); +t:=adjust_tail; adjust_tail:=null;@/ +@y +adjust_tail:=adjust_head; pre_adjust_tail:=pre_adjust_head; +b:=hpack(p,natural); p:=list_ptr(b); +t:=adjust_tail; adjust_tail:=null;@/ +pre_t:=pre_adjust_tail; pre_adjust_tail:=null;@/ +@z + +% \vadjust +@x l.25448 +tail_append(new_penalty(post_display_penalty)); +@y +if pre_t<>pre_adjust_head then + begin link(tail):=link(pre_adjust_head); tail:=pre_t; + end; +tail_append(new_penalty(post_display_penalty)); +@z + +% \primitive +@x +@= +@y +@= +for p:=0 to prim_size do dump_hh(prim[p]); +for p:=0 to prim_size do dump_wd(prim_eqtb[p]); +@z + +% \primitive +@x +@ @= +@y +@ @= +for p:=0 to prim_size do undump_hh(prim[p]); +for p:=0 to prim_size do undump_wd(prim_eqtb[p]); +@z + +% \strcmp +@x l.28174 +@ Each new type of node that appears in our data structure must be capable +@y +@ @d call_func(#) == begin if # <> 0 then do_nothing end +@d flushable(#) == (# = str_ptr - 1) + +@p procedure flush_str(s: str_number); {flush a string if possible} +begin + if flushable(s) then + flush_string; +end; + +procedure pdf_error(t, p: str_number); +begin + normalize_selector; + print_err("Error"); + if t <> 0 then begin + print(" ("); + print(t); + print(")"); + end; + print(": "); print(p); + succumb; +end; + +function tokens_to_string(p: pointer): str_number; {return a string from tokens +list} +begin + if selector = new_string then + pdf_error("tokens", "tokens_to_string() called while selector = new_string"); + old_setting:=selector; selector:=new_string; + show_token_list(link(p),null,pool_size-pool_ptr); + selector:=old_setting; +{ + last_tokens_string := make_string; + tokens_to_string := last_tokens_string; +} + tokens_to_string := make_string; +end; + +procedure compare_strings; {to implement \.{\\strcmp}} +label done; +var s1, s2: str_number; + i1, i2, j1, j2: pool_pointer; +begin + call_func(scan_toks(false, true)); + s1 := tokens_to_string(def_ref); + delete_token_ref(def_ref); + call_func(scan_toks(false, true)); + s2 := tokens_to_string(def_ref); + delete_token_ref(def_ref); + i1 := str_start_macro(s1); + j1 := str_start_macro(s1 + 1); + i2 := str_start_macro(s2); + j2 := str_start_macro(s2 + 1); + while (i1 < j1) and (i2 < j2) do begin + if str_pool[i1] < str_pool[i2] then begin + cur_val := -1; + goto done; + end; + if str_pool[i1] > str_pool[i2] then begin + cur_val := 1; + goto done; + end; + incr(i1); + incr(i2); + end; + if (i1 = j1) and (i2 = j2) then + cur_val := 0 + else if i1 < j1 then + cur_val := 1 + else + cur_val := -1; +done: + flush_str(s2); + flush_str(s1); + cur_val_level := int_val; +end; + +@ Each new type of node that appears in our data structure must be capable +@z + +% \strcmp +% \shellescape +@x l.29232 +primitive("pdflastypos",last_item,pdf_last_y_pos_code); +@y +primitive("pdflastypos",last_item,pdf_last_y_pos_code); +primitive("strcmp",convert,pdf_strcmp_code); +primitive("shellescape",last_item,pdf_shell_escape_code); +@z + +% \strcmp +@x +eTeX_revision_code: do_nothing; +@y +eTeX_revision_code: do_nothing; +pdf_strcmp_code: + begin + save_scanner_status := scanner_status; + save_warning_index := warning_index; + save_def_ref := def_ref; + save_cur_string; + compare_strings; + def_ref := save_def_ref; + warning_index := save_warning_index; + scanner_status := save_scanner_status; + restore_cur_string; + end; +@z + +% \strcmp +@x +eTeX_revision_code: print(eTeX_revision); +@y +eTeX_revision_code: print(eTeX_revision); +pdf_strcmp_code: print_int(cur_val); +@z + +% \ifincsname +@x l.31105 +@d if_font_char_code=19 { `\.{\\iffontchar}' } +@y +@d if_font_char_code=19 { `\.{\\iffontchar}' } +@d if_in_csname_code=20 { `\.{\\ifincsname}' } +@z + +% \ifincsname +@x l.31115 +@!@:if_font_char_}{\.{\\iffontchar} primitive@> +@y +@!@:if_font_char_}{\.{\\iffontchar} primitive@> +primitive("ifincsname",if_test,if_in_csname_code); +@!@:if_in_csname_}{\.{\\ifincsname} primitive@> +@z + +% \ifincsname +@x l.31123 +if_font_char_code:print_esc("iffontchar"); +@y +if_font_char_code:print_esc("iffontchar"); +if_in_csname_code:print_esc("ifincsname"); +@z + +% \ifincsname +@x l.31189 +if_font_char_code:begin scan_font_ident; n:=cur_val; scan_usv_num; +@y +if_in_csname_code: b := is_in_csname; +if_font_char_code:begin scan_font_ident; n:=cur_val; scan_usv_num; +@z + diff --git a/Build/source/texk/web2c/xetexdir/xetex.ch b/Build/source/texk/web2c/xetexdir/xetex.ch index 7bc3ce5bcaf..a8149933ef5 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.ch +++ b/Build/source/texk/web2c/xetexdir/xetex.ch @@ -64,8 +64,8 @@ authorization from SIL International. @d eTeX_version_string=='-2.2' {current \eTeX\ version} @d XeTeX_version=0 -@d XeTeX_revision==".999" -@d XeTeX_version_string=='-0.999.7' {current \XeTeX\ version} +@d XeTeX_revision==".9994" +@d XeTeX_version_string=='-0.9994.0' {current \XeTeX\ version} @z @x @@ -129,12 +129,15 @@ authorization from SIL International. @d hyph_prime=607 {another prime for hashing \.{\\hyphenation} exceptions; if you change this, you should also change |iinf_hyphen_size|.} +{NB: |biggest_char| here refers to UTF16 codepoints that we store in strings, etc; + actual character codes can exceed this range, up to |biggest_usv|.} @d biggest_char=65535 {the largest allowed character number; must be |<=max_quarterword|} @d biggest_usv=@"10FFFF {the largest Unicode Scalar Value} @d too_big_char=65536 {|biggest_char+1|} @d special_char=65537 {|biggest_char+2|} @d number_chars=65536 {|biggest_char+1|} +@d too_big_usv=@"110000 @d number_usvs=@"110000 @d biggest_reg=255 {the largest allowed register number; must be |<=max_quarterword|} @@ -633,10 +636,14 @@ done: if a<>@$ then c:=true; end @y -@ @= -if init_pool(pool_size-string_vacancies) = 0 then - get_strings_started:=false; -get_strings_started:=true; +@ @d bad_pool(#)==begin wake_up_terminal; write_ln(term_out,#); + get_strings_started:=false; return; + end +@= +if init_pool(pool_size-string_vacancies) = 0 then begin + bad_pool('! You have to increase POOLSIZE.'); +end else + get_strings_started := true; @z @x @@ -1754,7 +1761,7 @@ primitive("XeTeXradical",radical,1);@/ @x primitive("relax",relax,256); {cf.\ |scan_file_name|} @y -primitive("relax",relax,too_big_char); {cf.\ |scan_file_name|} +primitive("relax",relax,too_big_usv); {cf.\ |scan_file_name|} @z @x @@ -2047,7 +2054,7 @@ declared at this point. @x primitive("par",par_end,256); {cf.\ |scan_file_name|} @y -primitive("par",par_end,too_big_char); {cf.\ |scan_file_name|} +primitive("par",par_end,too_big_usv); {cf.\ |scan_file_name|} @z @x @@ -2369,7 +2376,7 @@ if cur_cs=0 then cur_tok:=(cur_cmd*max_char_val)+cur_chr @x begin eq_define(cur_cs,relax,256); {N.B.: The |save_stack| might change} @y - begin eq_define(cur_cs,relax,too_big_char); + begin eq_define(cur_cs,relax,too_big_usv); {N.B.: The |save_stack| might change} @z @@ -2549,6 +2556,48 @@ else if mactive_char)or(cur_chr>255) then {not a character} begin m:=relax; n:=256; @y if (cur_cmd>active_char)or(cur_chr>biggest_usv) then {not a character} - begin m:=relax; n:=too_big_char; + begin m:=relax; n:=too_big_usv; @z @x @@ -2820,7 +2869,7 @@ if (cur_cmd>active_char)or(cur_chr>255) then begin cur_cmd:=relax; cur_chr:=256; @y if (cur_cmd>active_char)or(cur_chr>biggest_usv) then - begin cur_cmd:=relax; cur_chr:=too_big_char; + begin cur_cmd:=relax; cur_chr:=too_big_usv; @z @x @@ -5032,13 +5081,15 @@ ligature_node: begin f:=font(lig_char(cur_p)); @x @!hc:array[0..65] of 0..256; {word to be hyphenated} @y -@!hc:array[0..65] of 0..too_big_char; {word to be hyphenated} +@!hc:array[0..66] of 0..number_usvs; {word to be hyphenated} +{ note that element 0 needs to be a full UnicodeScalar, even though we + basically work in utf16 } @z @x @!hu:array[0..63] of 0..256; {like |hc|, before conversion to lowercase} @y -@!hu:array[0..63] of 0..too_big_char; +@!hu:array[0..64] of 0..too_big_char; {like |hc|, before conversion to lowercase} @z @@ -5062,7 +5113,7 @@ max_hyph_char:=too_big_lang; @x @!c:0..255; {character being considered for hyphenation} @y -@!c:ASCII_code; {character being considered for hyphenation} +@!c:UnicodeScalar; {character being considered for hyphenation} @z @x @@ -5099,7 +5150,7 @@ done6: hn := 0; restart: for l := 0 to native_length(ha)-1 do begin - c := get_native_char(ha, l); + c := get_native_usv(ha, l); set_lc_code(c); if (hc[0] = 0) then begin if (hn > 0) then begin @@ -5118,7 +5169,19 @@ for l := 0 to native_length(ha)-1 do begin goto done3 else begin { found a letter that is part of a potentially hyphenatable sequence } - incr(hn); hu[hn] := c; hc[hn] := hc[0]; hyf_bchar := non_char; + incr(hn); + if c<@"10000 then begin + hu[hn] := c; hc[hn] := hc[0]; + end + else begin + hu[hn] := (c - @"10000) div @"400 + @"D800; + hc[hn] := (hc[0] - @"10000) div @"400 + @"D800; + incr(hn); + hu[hn] := c mod @"400 + @"DC00; + hc[hn] := hc[0] mod @"400 + @"DC00; + incr(l); + end; + hyf_bchar := non_char; end end; @@ -5149,12 +5212,13 @@ first letter. if subtype(s) = native_word_node then begin { we only consider the node if it contains at least one letter, otherwise we'll skip it } for l:=0 to native_length(s) - 1 do begin - c := get_native_char(s, l); + c := get_native_usv(s, l); if lc_code(c) <> 0 then begin hf := native_font(s); prev_s := s; goto done2; - end + end; + if c>=@"10000 then incr(l); end end; @; @@ -5263,6 +5327,12 @@ link(ha) := null; flush_node_list(ha); @z +@x +@!c:ASCII_code; {character temporarily replaced by a hyphen} +@y +@!c:UnicodeScalar; {character temporarily replaced by a hyphen} +@z + @x begin decr(l); c:=hu[l]; c_loc:=l; hu[l]:=256; @y @@ -5299,6 +5369,22 @@ hc[0]:=0; hc[hn+1]:=0; hc[hn+2]:=max_hyph_char; {insert delimiters} else if language>biggest_lang then cur_lang:=0 @z +@x + else if n<63 then + begin incr(n); hc[n]:=hc[0]; + end; +@y + else if n<63 then + begin incr(n); + if hc[0]<@"10000 then hc[n]:=hc[0] + else begin + hc[n] := (hc[0] - @"10000) div @"400 + @"D800; + incr(n); + hc[n] := hc[0] mod @"400 + @"DC00; + end; + end; +@z + @x u:=str_start[k]; v:=str_start[s]; @y @@ -6381,7 +6467,7 @@ XeTeX_math_given: begin print_esc("XeTeXmathchar"); print_hex(chr_code); @x else begin n:=cur_chr; get_r_token; p:=cur_cs; define(p,relax,256); @y -else begin n:=cur_chr; get_r_token; p:=cur_cs; define(p,relax,too_big_char); +else begin n:=cur_chr; get_r_token; p:=cur_cs; define(p,relax,too_big_usv); @z @x @@ -7835,48 +7921,6 @@ end @d eTeX_version_code=eTeX_int {code for \.{\\eTeXversion}} @y @d eTeX_version_code=eTeX_int {code for \.{\\eTeXversion}} - -@d XeTeX_version_code=XeTeX_int {code for \.{\\XeTeXversion}} - -{ these are also in xetexmac.c and must correspond! } -@d XeTeX_count_glyphs_code=XeTeX_int+1 - -@d XeTeX_count_variations_code=XeTeX_int+2 -@d XeTeX_variation_code=XeTeX_int+3 -@d XeTeX_find_variation_by_name_code=XeTeX_int+4 -@d XeTeX_variation_min_code=XeTeX_int+5 -@d XeTeX_variation_max_code=XeTeX_int+6 -@d XeTeX_variation_default_code=XeTeX_int+7 - -@d XeTeX_count_features_code=XeTeX_int+8 -@d XeTeX_feature_code_code=XeTeX_int+9 -@d XeTeX_find_feature_by_name_code=XeTeX_int+10 -@d XeTeX_is_exclusive_feature_code=XeTeX_int+11 -@d XeTeX_count_selectors_code=XeTeX_int+12 -@d XeTeX_selector_code_code=XeTeX_int+13 -@d XeTeX_find_selector_by_name_code=XeTeX_int+14 -@d XeTeX_is_default_selector_code=XeTeX_int+15 - -@d XeTeX_OT_count_scripts_code=XeTeX_int+16 -@d XeTeX_OT_count_languages_code=XeTeX_int+17 -@d XeTeX_OT_count_features_code=XeTeX_int+18 -@d XeTeX_OT_script_code=XeTeX_int+19 -@d XeTeX_OT_language_code=XeTeX_int+20 -@d XeTeX_OT_feature_code=XeTeX_int+21 - -@d XeTeX_map_char_to_glyph_code=XeTeX_int+22 -@d XeTeX_glyph_index_code=XeTeX_int+23 -@d XeTeX_font_type_code=XeTeX_int+24 - -@d XeTeX_first_char_code=XeTeX_int+25 -@d XeTeX_last_char_code=XeTeX_int+26 - -@d pdf_last_x_pos_code = XeTeX_int+27 -@d pdf_last_y_pos_code = XeTeX_int+28 - -@d XeTeX_pdf_page_count_code = XeTeX_int+29 - -{ NB: must update |eTeX_dim| when items are added here! } @z @x diff --git a/Build/source/texk/web2c/xetexdir/xetex.defines b/Build/source/texk/web2c/xetexdir/xetex.defines index 15ddd0aeacb..5f9dd5c51dc 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.defines +++ b/Build/source/texk/web2c/xetexdir/xetex.defines @@ -36,6 +36,7 @@ authorization from SIL International. @define const nullptr; @define type voidpointer; @define function getnativechar(); +@define function getnativeusv(); @define procedure setnativechar(); @define function getnativeglyph(); @define procedure setnativemetrics(); diff --git a/Build/source/texk/web2c/xetexdir/xetex.h b/Build/source/texk/web2c/xetexdir/xetex.h index a7282d07881..37a089933ec 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.h +++ b/Build/source/texk/web2c/xetexdir/xetex.h @@ -36,6 +36,11 @@ authorization from SIL International. #define getnativechar(p,i) native_node_text(p)[i] #define setnativechar(p,i,v) native_node_text(p)[i] = v +#define getnativeusv(p,i) \ + ((native_node_text(p)[i] >= 0xd800 && native_node_text(p)[i] < 0xdc00) ? \ + 0x10000 + (native_node_text(p)[i] - 0xd800) * 0x400 + native_node_text(p)[(i)+1] - 0xdc00 : \ + native_node_text(p)[i]) + /* p is native_word node; g is XeTeX_use_glyph_metrics flag */ #define setnativemetrics(p,g) measure_native_node(&(mem[p]), g) diff --git a/Build/source/texk/web2c/xetexdir/xetex.mk b/Build/source/texk/web2c/xetexdir/xetex.mk index 722ff594b58..9c3a180c091 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.mk +++ b/Build/source/texk/web2c/xetexdir/xetex.mk @@ -264,6 +264,7 @@ xetex_web_srcs = $(srcdir)/tex.web \ $(srcdir)/etexdir/tex.ech \ $(xetex_ch_srcs-with_synctex) \ $(srcdir)/xetexdir/xetex.ch \ + $(srcdir)/xetexdir/xetex-latex3.ch \ $(xetex_post_ch_srcs-with_synctex) xetex.web: tie xetexdir/xetex.mk $(xetex_web_srcs) $(TIE) -m xetex.web $(xetex_web_srcs) -- cgit v1.2.3