summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Kew <jfkthame@googlemail.com>2009-06-06 15:47:13 +0000
committerJonathan Kew <jfkthame@googlemail.com>2009-06-06 15:47:13 +0000
commitf8d4d9017cefd1e852971cd17c934530703b89ab (patch)
tree4fe66a40ea17acf2dc7771da0497c66c01a63208
parentd0f4ada6f6525fc56363a30f313994a09a718bf7 (diff)
updated to xetex 0.9994.0
git-svn-id: svn://tug.org/texlive/trunk@13644 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/web2c/Makefile.in1
-rw-r--r--Build/source/texk/web2c/xetexdir/am/xetex.am1
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex-latex3.ch865
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.ch166
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.defines1
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.h5
-rw-r--r--Build/source/texk/web2c/xetexdir/xetex.mk1
7 files changed, 979 insertions, 61 deletions
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}
+
+@ @<Set init...@>=
+no_new_control_sequence:=true; {new identifiers are usually forbidden}
+
+@ @<Initialize table entries...@>=
+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
+
+@<Glob...@>=
+@!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;
+
+@ @<Set init...@>=
+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];
+
+@ @<Initialize table entries...@>=
+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);
+ @<Compute the primitive code |h|@>;
+ p:=h+prim_base; {we start searching here; note that |0<=h<hash_prime|}
+ loop@+begin if prim_text(p)>0 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 @<Insert a new primitive after |p|, then make
+ |p| point to it@>;
+ goto found;
+ end;
+ p:=prim_next(p);
+ end;
+ end;
+found: prim_lookup:=p;
+end;
+
+@ @<Insert a new primitive...@>=
+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.
+
+@<Compute the primitive code |h|@>=
+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
+@ @<Expand a nonmacro@>=
+@y
+@ @<Glob...@>=
+@!is_in_csname: boolean;
+
+@ @<Set init...@>=
+is_in_csname := false;
+
+@ @<Expand a nonmacro@>=
+@z
+
+% \primitive
+@x l.8354
+no_expand:@<Suppress expansion of the next token@>;
+@y
+no_expand: if cur_chr=0 then @<Suppress expansion of the next token@>
+ else @<Implement \.{\\primitive}@>;
+@z
+
+% \primitive
+@x l.8391
+@ @<Complain about an undefined macro@>=
+@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.
+
+@<Implement \.{\\primitive}@>=
+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
+
+@ @<Complain about an undefined macro@>=
+@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 @<Complain about missing \.{\\endcsname}@>;
+@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 @<Complain about missing \.{\\endcsname}@>;
+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)<pool_ptr then u:=make_string else u:=0
+@d restore_cur_string==if u<>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: @<Select the appropriate case
+ and |return| or |goto common_ending|@>;
+@y
+if_case_code: @<Select the appropriate case
+ and |return| or |goto common_ending|@>;
+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
+@<Transfer node |p| to the adjustment list@>=
+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
+@<Glob...@>=
+@!pre_adjust_tail: pointer;
+
+@ @<Set init...@>=
+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
+
+@<Transfer node |p| to the adjustment list@>=
+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 @<Get the next non-blank non-call...@>;
+ goto reswitch;
+ end;
+@y
+any_mode(ignore_spaces): begin
+ if cur_chr = 0 then begin
+ @<Get the next non-blank non-call...@>;
+ 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
+@<Dump the hash table@>=
+@y
+@<Dump the hash table@>=
+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
+@ @<Undump the hash table@>=
+@y
+@ @<Undump the hash table@>=
+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
-@ @<Read the other strings...@>=
-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
+@<Read the other strings...@>=
+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 m<math_code_base then scanned_result(equiv(m+cur_val) mod @"10000)(int_v
@#
@d XeTeX_int=eTeX_int+8 {first of \XeTeX\ codes for integers}
@#
+@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! }
+@#
@d eTeX_dim=XeTeX_int+30 {first of \eTeX\ codes for dimensions}
{changed for \XeTeX\ to make room for \XeTeX\ integers}
@z
@@ -2812,7 +2861,7 @@ if (cur_cmd>active_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;
@<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>;
@@ -5264,6 +5328,12 @@ 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
begin decr(l); c:=hu[l]; c_loc:=l; hu[l]:=max_hyph_char;
@@ -5300,6 +5370,22 @@ hc[0]:=0; hc[hn+1]:=0; hc[hn+2]:=max_hyph_char; {insert delimiters}
@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
u:=str_start_macro(k); v:=str_start_macro(s);
@@ -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)