From 290b8eb1794e8ff24f56ae9c65ec5fbc99ef9fa2 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Tue, 27 May 2008 15:14:09 +0000 Subject: synctex update; now enabled in pdftex as well as xetex git-svn-id: svn://tug.org/texlive/trunk@8363 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/lib/texmfmp.c | 6 +- Build/source/texk/web2c/pdftexdir/pdftex.mk | 6 +- Build/source/texk/web2c/synctex/man5/synctex.5 | 22 +- Build/source/texk/web2c/synctex/synctex-common.h | 38 + Build/source/texk/web2c/synctex/synctex-e-mem.ch0 | 2 +- Build/source/texk/web2c/synctex/synctex-e-rec.ch0 | 10 +- Build/source/texk/web2c/synctex/synctex-mem.ch0 | 131 +- Build/source/texk/web2c/synctex/synctex-mem.ch1 | 2 +- Build/source/texk/web2c/synctex/synctex-mem.ch2 | 4 +- .../source/texk/web2c/synctex/synctex-pdf-rec.ch2 | 88 +- Build/source/texk/web2c/synctex/synctex-rec.ch0 | 185 +- Build/source/texk/web2c/synctex/synctex-rec.ch1 | 30 +- Build/source/texk/web2c/synctex/synctex-xe-rec.ch3 | 67 + Build/source/texk/web2c/synctex/synctex.c | 124 +- Build/source/texk/web2c/synctex/synctex.h | 9 +- Build/source/texk/web2c/synctex/synctex.mk | 203 +- Build/source/texk/web2c/synctex/synctex_main.c | 215 +- Build/source/texk/web2c/synctex/synctex_parser.c | 2539 +++++++++++--------- Build/source/texk/web2c/web2c/convert | 2 +- Build/source/texk/web2c/xetexdir/sync-xetex.ch | 68 - Build/source/texk/web2c/xetexdir/xetex.ch | 37 +- Build/source/texk/web2c/xetexdir/xetex.defines | 19 - Build/source/texk/web2c/xetexdir/xetex.mk | 11 +- 23 files changed, 2120 insertions(+), 1698 deletions(-) create mode 100644 Build/source/texk/web2c/synctex/synctex-common.h create mode 100644 Build/source/texk/web2c/synctex/synctex-xe-rec.ch3 delete mode 100644 Build/source/texk/web2c/xetexdir/sync-xetex.ch (limited to 'Build') diff --git a/Build/source/texk/web2c/lib/texmfmp.c b/Build/source/texk/web2c/lib/texmfmp.c index 45be0e83f78..959395cf277 100644 --- a/Build/source/texk/web2c/lib/texmfmp.c +++ b/Build/source/texk/web2c/lib/texmfmp.c @@ -224,7 +224,7 @@ maininit P2C(int, ac, string *, av) kpse_record_input = recorder_record_input; kpse_record_output = recorder_record_output; -#if /*defined (pdfTeX) ||*/ defined(XeTeX) || defined(__syncTeX__) +#if defined(__SyncTeX__) # warning SyncTeX: -synctex command line option available /* 0 means "disable Synchronize TeXnology". * synctexoption is a *.web variable. @@ -957,7 +957,7 @@ static struct option long_options[] { "no-shell-escape", 0, &shellenabledp, -1 }, { "debug-format", 0, &debugformatfile, 1 }, { "src-specials", 2, 0, 0 }, -#if /*defined(pdfTeX) ||*/ defined(XeTeX) || defined(__syncTeX__) +#if defined(__SyncTeX__) /* Synchronization: just like "interaction" above */ { "synctex", 1, 0, 0 }, #endif @@ -1145,7 +1145,7 @@ parse_options P2C(int, argc, string *, argv) } else if (ARGUMENT_IS ("help")) { usagehelp (PROGRAM_HELP, BUG_ADDRESS); -#if /*defined (pdfTeX) ||*/ defined(XeTeX) || defined(__syncTeX__) +#if defined(__SyncTeX__) } else if (ARGUMENT_IS ("synctex")) { /* Synchronize TeXnology: catching the command line option as a long */ synctexoption = (int) strtol(optarg, NULL, 0); diff --git a/Build/source/texk/web2c/pdftexdir/pdftex.mk b/Build/source/texk/web2c/pdftexdir/pdftex.mk index 8130c237a26..7ff89824594 100644 --- a/Build/source/texk/web2c/pdftexdir/pdftex.mk +++ b/Build/source/texk/web2c/pdftexdir/pdftex.mk @@ -26,7 +26,7 @@ $(pdftexdir)/pdftex.version: $(srcdir)/$(pdftexdir)/pdftex.web # The C sources. pdftex_c = pdftexini.c pdftex0.c pdftex1.c pdftex2.c pdftex3.c pdftex_o = pdftexini.o pdftex0.o pdftex1.o pdftex2.o pdftex3.o pdftexextra.o \ -pdftex-pool.o +pdftex-pool.o $(pdftex_o-with_synctex) # Making pdftex pdftex: pdftexd.h $(pdftex_o) $(pdftexextra_o) $(pdftexlibsdep) @@ -35,7 +35,8 @@ pdftex: pdftexd.h $(pdftex_o) $(pdftexextra_o) $(pdftexlibsdep) # C file dependencies. $(pdftex_c) pdftexcoerce.h pdftexd.h: pdftex.p $(web2c_texmf) $(srcdir)/$(pdftexdir)/pdftex.defines $(srcdir)/$(pdftexdir)/pdftex.h $(web2c) pdftex -pdftexextra.c: $(pdftexdir)/pdftexextra.h lib/texmfmp.c + $(pdftexd.h-with_synctex) +pdftexextra.c: pdftexd.h $(pdftexdir)/pdftexextra.h lib/texmfmp.c test -d $(pdftexdir) || mkdir $(pdftexdir) sed s/TEX-OR-MF-OR-MP/pdftex/ $(srcdir)/lib/texmfmp.c >$@ $(pdftexdir)/pdftexextra.h: $(pdftexdir)/pdftexextra.in $(pdftexdir)/pdftex.version etexdir/etex.version @@ -54,6 +55,7 @@ pdftex.p pdftex.pool: tangle $(srcdir)/$(pdftexdir)/pdftex.web pdftex.ch pdftex_ch_srcs = $(srcdir)/$(pdftexdir)/pdftex.web \ $(srcdir)/$(pdftexdir)/tex.ch0 \ $(srcdir)/tex.ch \ + $(pdftex_ch_srcs-with_synctex) \ $(srcdir)/$(pdftexdir)/pdftex.ch # Rules: pdftex.ch: $(TIE) $(pdftex_ch_srcs) diff --git a/Build/source/texk/web2c/synctex/man5/synctex.5 b/Build/source/texk/web2c/synctex/man5/synctex.5 index 9ae2b634a42..128bdce3509 100644 --- a/Build/source/texk/web2c/synctex/man5/synctex.5 +++ b/Build/source/texk/web2c/synctex/man5/synctex.5 @@ -1,4 +1,4 @@ -.Dd August 30, 2006 +.Dd May 11, 2008 .Dt SYNCTEX 5 .Os "Independant" .\" @@ -63,21 +63,17 @@ In the following definitions, we do not mention the section ending condition. .It .Li * .It -.Li ( -.Qq Magnification: - )* +.Li Qq Magnification: + .It -.Li ( -.Qq Unit: - )* +.Li Qq Unit: + .It -.Li ( -.Qq X Offset: - )* +.Li Qq X Offset: + .It -.Li ( -.Qq Y Offset: - )* +.Li Qq Y Offset: + .El .It .Li ::= diff --git a/Build/source/texk/web2c/synctex/synctex-common.h b/Build/source/texk/web2c/synctex/synctex-common.h new file mode 100644 index 00000000000..f5ae8ac6ded --- /dev/null +++ b/Build/source/texk/web2c/synctex/synctex-common.h @@ -0,0 +1,38 @@ +/* synctex.h + +This file is part of the SyncTeX package. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE + +*/ + +# ifndef __SYNCTEX_COMMON_HEADER__ +# define __SYNCTEX_COMMON_HEADER__ + +/* Send this message to init the synctex command value to the command line option. + * Sending this message too early will cause a bus error. */ +extern void synctexinitcommand(void); + +/* Send this message to clean memory, and close the file. */ +extern void synctexterminate(int log_opened); + +# endif diff --git a/Build/source/texk/web2c/synctex/synctex-e-mem.ch0 b/Build/source/texk/web2c/synctex/synctex-e-mem.ch0 index d36577c7bfb..880fa929a70 100644 --- a/Build/source/texk/web2c/synctex/synctex-e-mem.ch0 +++ b/Build/source/texk/web2c/synctex/synctex-e-mem.ch0 @@ -95,7 +95,7 @@ end @y kern_node,math_node: begin words:=medium_node_size; {{\sl Sync\TeX}: proper size for math and kern} - r:=get_node(words); + r:=get_node(words); end; glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); {{\sl Sync\TeX}: proper size for glue} diff --git a/Build/source/texk/web2c/synctex/synctex-e-rec.ch0 b/Build/source/texk/web2c/synctex/synctex-e-rec.ch0 index 098d42c98f6..db584a92b84 100644 --- a/Build/source/texk/web2c/synctex/synctex-e-rec.ch0 +++ b/Build/source/texk/web2c/synctex/synctex-e-rec.ch0 @@ -98,17 +98,11 @@ link(prev_p):=p; @z @x etex.ch l.4459 -if tracing_scan_tokens>0 then - begin if term_offset>max_print_line-3 then print_ln - else if (term_offset>0)or(file_offset>0) then print_char(" "); name:=19; print("( "); incr(open_parens); update_terminal; end else name:=18 @y -if tracing_scan_tokens>0 then - begin if term_offset>max_print_line-3 then print_ln - else if (term_offset>0)or(file_offset>0) then print_char(" "); - name:=19; print("( "); incr(open_parens); update_terminal; + name:=19; print("( "); incr(open_parens); update_terminal; end else begin name:=18; @@ -129,7 +123,7 @@ primitive("synctex",assign_int,int_base+synctex_code);@/ synctex_code: print_esc("synctex"); @z -@x synctex-act.ch0 l.267 +@x synctex-rec.ch0 l.267 @ @= synctex_tag:=0; @y diff --git a/Build/source/texk/web2c/synctex/synctex-mem.ch0 b/Build/source/texk/web2c/synctex/synctex-mem.ch0 index bf4e5265ba7..3cb0cd1950b 100644 --- a/Build/source/texk/web2c/synctex/synctex-mem.ch0 +++ b/Build/source/texk/web2c/synctex/synctex-mem.ch0 @@ -36,7 +36,7 @@ Notice: The |synctex_field_size| depends on the TeX implementation. pdfTeX uses 2 additional words whereas XeTeX will only use one, because it naturally has bigger words of memory. -@x tex.web l.2888 +@x tex.web l.2897 @d hlist_node=0 {|type| of hlist nodes} @d box_node_size=7 {number of words to allocate for a box node} @y @@ -46,13 +46,13 @@ because it naturally has bigger words of memory. @d box_node_size=7+synctex_field_size {number of words to allocate for a box node} @z -@@x tex.web l.2935 +@x tex.web l.2944 @d rule_node_size=4 {number of words to allocate for a rule node} -@@y +@y @d rule_node_size=4+synctex_field_size {number of words to allocate for a rule node} -@@z +@z -@x tex.web l.2976 +@x tex.web l.2985 @d small_node_size=2 {number of words to allocate for most node types} @y @d small_node_size=2 {number of words to allocate for most node types} @@ -60,65 +60,76 @@ because it naturally has bigger words of memory. allocate for synchronized node types like math, kern and glue nodes} @z -@x tex.web l.3081 +@x tex.web l.3090 @p function new_math(@!w:scaled;@!s:small_number):pointer; -var p:pointer; {the new node} -begin p:=get_node(small_node_size); type(p):=math_node; -subtype(p):=s; width(p):=w; new_math:=p; -end; @y @p function new_math(@!w:scaled;@!s:small_number):pointer; -var p:pointer; {the new node} +@z + +@x +begin p:=get_node(small_node_size); type(p):=math_node; +@y begin p:=get_node(medium_node_size); type(p):=math_node; -subtype(p):=s; width(p):=w; new_math:=p; -end; @z -@x tex.web l.3176 +@x tex.web l.3185 @p function new_param_glue(@!n:small_number):pointer; -var p:pointer; {the new node} -@!q:pointer; {the glue specification} -begin p:=get_node(small_node_size); type(p):=glue_node; subtype(p):=n+1; @y @p function new_param_glue(@!n:small_number):pointer; -var p:pointer; {the new node} -@!q:pointer; {the glue specification} +@z + +@x +begin p:=get_node(small_node_size); type(p):=glue_node; subtype(p):=n+1; +@y begin p:=get_node(medium_node_size); type(p):=glue_node; subtype(p):=n+1; @z -@x tex.web l.3189 +@x tex.web l.3198 @p function new_glue(@!q:pointer):pointer; -var p:pointer; {the new node} -begin p:=get_node(small_node_size); type(p):=glue_node; subtype(p):=normal; @y @p function new_glue(@!q:pointer):pointer; -var p:pointer; {the new node} +@z + +@x +begin p:=get_node(small_node_size); type(p):=glue_node; subtype(p):=normal; +@y begin p:=get_node(medium_node_size); type(p):=glue_node; subtype(p):=normal; @z -@x tex.web l.3227 +@x tex.web l.3236 @p function new_kern(@!w:scaled):pointer; -var p:pointer; {the new node} -begin p:=get_node(small_node_size); type(p):=kern_node; @y @p function new_kern(@!w:scaled):pointer; -var p:pointer; {the new node} +@z + +@x +begin p:=get_node(small_node_size); type(p):=kern_node; +@y begin p:=get_node(medium_node_size); type(p):=kern_node; @z +@x +@p procedure flush_node_list(@!p:pointer); {erase list of nodes starting at |p|} +@y +@p procedure flush_node_list(@!p:pointer); {erase list of nodes starting at |p|} +@z -@x tex.web l.3925: free nodes with proper size +@x tex.web l.3934: free nodes with proper size glue_node: begin fast_delete_glue_ref(glue_ptr(p)); if leader_ptr(p)<>null then flush_node_list(leader_ptr(p)); end; - kern_node,math_node,penalty_node: do_nothing; @y glue_node: begin fast_delete_glue_ref(glue_ptr(p)); - if leader_ptr(p)<>null then flush_node_list(leader_ptr(p)); -free_node(p, medium_node_size); + if leader_ptr(p)<>null then flush_node_list(leader_ptr(p)); + free_node(p, medium_node_size); goto done; end; +@z + +@x + kern_node,math_node,penalty_node: do_nothing; +@y kern_node,math_node:begin free_node(p, medium_node_size); goto done; @@ -126,28 +137,32 @@ free_node(p, medium_node_size); penalty_node: do_nothing; @z -@x tex.web l.4009: +@x tex.web l.4018: +@ @= +@y +@ @= +@z + +@x glue_node: begin r:=get_node(small_node_size); add_glue_ref(glue_ptr(p)); - glue_ptr(r):=glue_ptr(p); leader_ptr(r):=copy_node_list(leader_ptr(p)); - end; +@y +glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); +@z + +@x kern_node,math_node,penalty_node: begin r:=get_node(small_node_size); words:=small_node_size; end; @y -glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); - glue_ptr(r):=glue_ptr(p); leader_ptr(r):=copy_node_list(leader_ptr(p)); - end; -kern_node,math_node: -begin +kern_node,math_node: begin r:=get_node(medium_node_size); words:=medium_node_size; - r:=get_node(words); -end; + end; penalty_node: begin r:=get_node(small_node_size); words:=small_node_size; end; @z -@x tex.web l.4903 +@x tex.web l.4912 @d pretolerance_code=0 {badness tolerance before hyphenation} @y @d REMOVE ME IF synctex_code is properly defined @@ -155,7 +170,7 @@ penalty_node: begin r:=get_node(small_node_size); @d pretolerance_code=0 {badness tolerance before hyphenation} @z -@x tex.web l.5022 +@x tex.web l.5031 @d error_context_lines==int_par(error_context_lines_code) @y @d error_context_lines==int_par(error_context_lines_code) @@ -163,7 +178,7 @@ penalty_node: begin r:=get_node(small_node_size); @d synctex == int_par(synctex_code) @z -@x tex.web l.6422 +@x In the second "@=" @!in_state_record = record @!state_field, @!index_field: quarterword; @!start_field,@!loc_field, @!limit_field, @!name_field: halfword; @@ -176,35 +191,33 @@ penalty_node: begin r:=get_node(small_node_size); end; @z -@x tex.web l.6452 +@x tex.web l.6461 @d name==cur_input.name_field {name of the current file} @y @d name==cur_input.name_field {name of the current file} @d synctex_tag==cur_input.synctex_tag_field {{\sl Sync\TeX} tag of the current file} @z -@x tex.web l. 14182 - if r<>null then if link(r)=null then if not is_char_node(r) then - if type(r)=kern_node then {unneeded italic correction} +@x +@= +@y +@= +@z + +@x tex.web l. 14189 begin free_node(r,small_node_size); link(q):=null; - end; - end @y - if r<>null then if link(r)=null then if not is_char_node(r) then - if type(r)=kern_node then {unneeded italic correction} begin free_node(r,medium_node_size); link(q):=null; - end; - end @z -@x tex.web l. 24264 +@x tex.web l. 24274 history:=spotless; {ready to go!} @y history:=spotless; {ready to go!} @ @z -@x tex.web l. 24945 +@x tex.web l. 24956 @* \[54] System-dependent changes. @y @* \[54/SyncTeX] The {\sl Synchronize \TeX nology}. @@ -248,9 +261,6 @@ Its memory address is |synctex_code|. It is initialized by the {\sl Sync\TeX} controller to the command-line option if given. The controller may filter some reserved bits. -@ @= -synctex_init_command; - @ @= primitive("synctex",assign_int,int_base+synctex_code);@/ @!@:synctex_}{\.{\\synctex} primitive@> @@ -267,6 +277,9 @@ the correct value when quite everything is initialized. @ @= synctexoffset:=int_base+synctex_code; +@ @= +synctex_init_command; + @ Synchronization is achieved with the help of an auxiliary file... @^synctex@> @^synchronization@> diff --git a/Build/source/texk/web2c/synctex/synctex-mem.ch1 b/Build/source/texk/web2c/synctex/synctex-mem.ch1 index dd31da119ce..c46ecd4f90d 100644 --- a/Build/source/texk/web2c/synctex/synctex-mem.ch1 +++ b/Build/source/texk/web2c/synctex/synctex-mem.ch1 @@ -36,7 +36,7 @@ This file contains TeX changes for synctex support. It implements the memory management for TeX like engines. It must apply after synctex-mem.ch0 -@x tex.web l.2888 + synctex-mem.ch0 +@x tex.web l.2897 + synctex-mem.ch0 @d synctex_field_size=MISSING IMPLEMENTATION @y @d synctex_field_size=2 {Declare the {\sl Sync\TeX} field size to store the {\sl Sync\TeX} information: diff --git a/Build/source/texk/web2c/synctex/synctex-mem.ch2 b/Build/source/texk/web2c/synctex/synctex-mem.ch2 index ef883eec3ab..41e74ca3dc0 100644 --- a/Build/source/texk/web2c/synctex/synctex-mem.ch2 +++ b/Build/source/texk/web2c/synctex/synctex-mem.ch2 @@ -36,7 +36,7 @@ This file contains TeX changes for synctex support. It implements the memory management for TeX like engines. It must apply after synctex-mem.ch? and synctex-act.ch? -@x tex.web l.4903 + synctex-mem.ch0 +@x tex.web l.4912 + synctex-mem.ch0 @d REMOVE ME IF synctex_code is properly defined @y @z @@ -45,5 +45,5 @@ It must apply after synctex-mem.ch? and synctex-act.ch? @d int_pars=web2c_int_pars {total number of integer parameters} @y @d synctex_code=web2c_int_pars -@d int_pars=synctex_code+1 {total number of \TeX's integer parameters} +@d int_pars=synctex_code+1 {total number of integer parameters} @z diff --git a/Build/source/texk/web2c/synctex/synctex-pdf-rec.ch2 b/Build/source/texk/web2c/synctex/synctex-pdf-rec.ch2 index d6cb5793594..501c115bb18 100644 --- a/Build/source/texk/web2c/synctex/synctex-pdf-rec.ch2 +++ b/Build/source/texk/web2c/synctex/synctex-pdf-rec.ch2 @@ -21,22 +21,21 @@ % This change file is meant to override previous changes made by synctex.ch % -Fix -@x pdftex.web l.14497 +@x margin_kern_node, kern_node: begin - @; - cur_h:=cur_h+width(p); -end; @y -margin_kern_node:cur_h:=cur_h+width(p); +margin_kern_node:cur_h:=cur_h+width(p); {separate the |margin_kern_node| case in |hlist_out|} kern_node: begin - @; - cur_h:=cur_h+width(p); -end; @z -@x pdftex.web l.18358 +@x +procedure pdf_hlist_out; {output an |hlist_node| box} +@y +procedure pdf_hlist_out; {output an |hlist_node| box} +@z + +@x pdftex.web l.18367 while p<>null do @; @@ -48,32 +47,46 @@ while p<>null do @; @z +@x +@ @= +@y +@ @= +@z + @x pdftex.web l.18382 - p:=link(p); until not is_char_node(p); @y - p:=link(p); until not is_char_node(p); @; @z -@x pdftex.web l.18395 +@x +@ @= +@y +@ @= +@z + +@x margin_kern_node, kern_node:cur_h:=cur_h+width(p); -math_node: @; @y margin_kern_node:cur_h:=cur_h+width(p); kern_node: begin @; cur_h:=cur_h+width(p); end; +@z + +@x +math_node: @; +@y math_node: begin @; @; end; @z -@x pdftex.web l.18405 +@x pdftex.web l.18411 move_past: cur_h:=cur_h+rule_wd; @y move_past: begin @@ -82,23 +95,29 @@ move_past: begin end; @z -@x pdftex.web l.18409 +@x @ @<(\pdfTeX) Output a box in an hlist@>= -if list_ptr(p)=null then cur_h:=cur_h+width(p) @y @ @<(\pdfTeX) Output a box in an hlist@>= +@z + +@x +if list_ptr(p)=null then cur_h:=cur_h+width(p) +@y if list_ptr(p)=null then - if type(p)=vlist_node then begin - @ - cur_h:=cur_h+width(p) - end - else begin - @ + begin + @; cur_h:=cur_h+width(p); end @z -@x pdftex.web l.18509 +@x +@p procedure pdf_vlist_out; {output a |pdf_vlist_node| box} +@y +@p procedure pdf_vlist_out; {output a |pdf_vlist_node| box} +@z + +@x pdftex.web l.18521 left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v; @y left_edge:=cur_h; @@ -106,7 +125,7 @@ left_edge:=cur_h; cur_v:=cur_v-height(this_box); top_edge:=cur_v; @z -@x pdftex.web l.18511 +@x pdftex.web l.18523 while p<>null do @; @@ -117,30 +136,29 @@ while p<>null do @; @z -@x pdftex.web l.18545 +@x pdftex.web l.18557 @ @<(\pdfTeX) Output a box in a vlist@>= if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) @y @ @<(\pdfTeX) Output a box in a vlist@>= if list_ptr(p)=null then begin cur_v:=cur_v+height(p); - if type(p)=vlist_node then begin - @; - end - else begin - @; - end; + @; cur_v:=cur_v+depth(p); end @z -@x pdftex.web l.18668 +@x +@p procedure pdf_ship_out(p: pointer; shipping_page: boolean); {output the box |p|} +@y +@p procedure pdf_ship_out(p: pointer; shipping_page: boolean); {output the box |p|} +@z + +@x pdftex.web l.18680 pdf_last_resources: integer; {pointer to most recently generated Resources object} -begin if tracing_output>0 then @y pdf_last_resources: integer; {pointer to most recently generated Resources object} begin @; -begin if tracing_output>0 then @z @x pdftex.web l.18699 diff --git a/Build/source/texk/web2c/synctex/synctex-rec.ch0 b/Build/source/texk/web2c/synctex/synctex-rec.ch0 index e81a9c1a7e8..8e4e0025608 100644 --- a/Build/source/texk/web2c/synctex/synctex-rec.ch0 +++ b/Build/source/texk/web2c/synctex/synctex-rec.ch0 @@ -33,76 +33,82 @@ authorization from the copyright holder. Notice: ------- -@x tex.web l.2707 -found: link(r):=null; {this node is now nonempty} -@!stat var_used:=var_used+s; {maintain usage statistics} -tats@;@/ +@x +@p function get_node(@!s:integer):pointer; {variable-size node allocation} +@y +@p function get_node(@!s:integer):pointer; {variable-size node allocation} +@z + +@x tex.web l.2716 get_node:=r; -exit:end; @y -found: link(r):=null; {this node is now nonempty} -@!stat var_used:=var_used+s; {maintain usage statistics} -tats@;@/ @; get_node:=r; -exit:end; @z -@x tex.web l.3993: Copy +@x tex.web l.4002: Copy @ @= -case type(p) of -hlist_node,vlist_node,unset_node: begin r:=get_node(box_node_size); @y @ @= -case type(p) of +@z + +@x +hlist_node,vlist_node,unset_node: begin r:=get_node(box_node_size); +@y hlist_node,vlist_node,unset_node: begin r:=get_node(box_node_size); @; @z @x tex.web l.4009: after synctex-mem.ch0 glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); - glue_ptr(r):=glue_ptr(p); leader_ptr(r):=copy_node_list(leader_ptr(p)); - end; -kern_node,math_node: -begin - words:=medium_node_size; - r:=get_node(words); -end; -penalty_node: begin r:=get_node(small_node_size); - words:=small_node_size; - end; @y glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); @; - glue_ptr(r):=glue_ptr(p); leader_ptr(r):=copy_node_list(leader_ptr(p)); +@z + +@x tex.web l.4009: after synctex-mem.ch0 +kern_node,math_node: begin r:=get_node(medium_node_size); + words:=medium_node_size; end; -kern_node,math_node: -begin +@y +kern_node,math_node: begin r:=get_node(medium_node_size); words:=medium_node_size; {{\sl Sync\TeX}: do not copy the {\sl Sync\TeX} information} - r:=get_node(words); -end; -penalty_node: begin r:=get_node(small_node_size); - words:=small_node_size; end; @z -@x tex.web l.7045 +@x +@p procedure begin_file_reading; +@y +@p procedure begin_file_reading; +@z + +@x name:=0; {|terminal_input| is now |true|} -end; @y name:=0; {|terminal_input| is now |true|} @; -end; @z -@x tex.web l.10375 +@x +@p procedure start_input; {\TeX\ will \.{\\input} something} +@y +@p procedure start_input; {\TeX\ will \.{\\input} something} +@z + +@x tex.web l.10380 @; @y @; @; @z -@x tex.web l.12332 +@x +procedure hlist_out; {output an |hlist_node| box} +@y +procedure hlist_out; {output an |hlist_node| box} +@z + +@x tex.web l.12338 while p<>null do @; @y @@ -112,16 +118,26 @@ while p<>null do @; @z -@x tex.web l.12354 +@x +@= +@y +@= +@z + +@x until not is_char_node(p); - dvi_h:=cur_h; @y until not is_char_node(p); - dvi_h:=cur_h; @; @z -@x tex.web l.12384 +@x +@ @= +@y +@ @= +@z + +@x tex.web l.12390 move_past: cur_h:=cur_h+rule_wd; @y move_past: begin @@ -130,32 +146,31 @@ move_past: begin end; @z -@x tex.web l.12388 +@x tex.web l.12394 @ @= if list_ptr(p)=null then cur_h:=cur_h+width(p) @y @ @= if list_ptr(p)=null then begin - if type(p)=vlist_node then begin - @ - cur_h:=cur_h+width(p); - end - else begin - @ - end; + @; cur_h:=cur_h+width(p); end @z -@x tex.web l.12527 +@x +@p procedure vlist_out; {output a |vlist_node| box} +@y +@p procedure vlist_out; {output a |vlist_node| box} +@z + +@x tex.web l.12533 save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); @y -save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; -@; -cur_v:=cur_v-height(this_box); +save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); +MISSING @ before cur_v:=cur_v-height(this_box); @z -@x tex.web l.12529 +@x tex.web l.12535 while p<>null do @; @y @@ -164,33 +179,23 @@ while p<>null do @; @z -@x tex.web l.12563 +@x tex.web l.12569 @= if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) @y @= -if list_ptr(p)=null then begin - cur_v:=cur_v+height(p); - if type(p)=vlist_node then begin - @; - end - else begin - @; - end; - cur_v:=cur_v+depth(p); -end +if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) +MISSING @; @z -@x tex.web l.12663 +@x tex.web l.12669 @!old_setting:0..max_selector; {saved |selector| setting} -begin if tracing_output>0 then @y @!old_setting:0..max_selector; {saved |selector| setting} -begin @ -begin if tracing_output>0 then +begin @; @z -@x tex.web l.12686 +@x tex.web l.12692 @; end; @y @@ -200,18 +205,22 @@ end; end; @z -@x tex.web l.17880 +@x +@= +@y +@= +@z + +@x tex.web l.17887 if w<>0 then begin link(t):=new_kern(w); t:=link(t); w:=0; - end; @y if w<>0 then begin link(t):=new_kern(w); t:=link(t); w:=0; MISSING IMPLEMENTATION: 0 synctag for medium sized node at mem[t] - end; @z -@x tex.web l.19326 +@x tex.web l.19335 @= type(page_head):=glue_node; subtype(page_head):=normal; @y @@ -220,21 +229,29 @@ type(page_head):=glue_node; subtype(page_head):=normal; {{\sl Sync\TeX} watch point: box(|page_head|) size >= |glue_node| size} @z -@x tex.web l.20181 -temp_ptr:=lig_stack; lig_stack:=link(temp_ptr); +@x +@= +@y +@= +@z + +@x tex.web l.20188 free_node(temp_ptr,small_node_size); @y -temp_ptr:=lig_stack; lig_stack:=link(temp_ptr); free_node(temp_ptr,small_node_size); {{\sl Sync\TeX} watch point: proper size!} @z -@x tex.web l.24288 +@x +procedure close_files_and_terminate; +@y +procedure close_files_and_terminate; +@z + +@x tex.web l.24301 if log_opened then - begin wlog_cr; a_close(log_file); selector:=selector-2; @y @; if log_opened then - begin wlog_cr; a_close(log_file); selector:=selector-2; @z @x tex.web + synctex-mem.ch0 @@ -340,17 +357,19 @@ synctex_vlist(this_box); @ @= synctex_tsilv(this_box); -@ @= -synctex_void_vlist(p,this_box); - @ @= synctex_hlist(this_box); @ @= synctex_tsilh(this_box); -@ @= -synctex_void_hlist(p,this_box); +@ @= + if type(p)=vlist_node then begin + synctex_void_vlist(p,this_box); + end + else begin + synctex_void_hlist(p,this_box); + end; @ @= synctex_current; diff --git a/Build/source/texk/web2c/synctex/synctex-rec.ch1 b/Build/source/texk/web2c/synctex/synctex-rec.ch1 index e52ef773ba9..b93863ac092 100644 --- a/Build/source/texk/web2c/synctex/synctex-rec.ch1 +++ b/Build/source/texk/web2c/synctex/synctex-rec.ch1 @@ -34,7 +34,35 @@ Notice: ------- This file contains TeX changes for synctex support. It implements the memory management for TeX like engines. -It must apply after synctex-mem.ch0 +It must apply after synctex-rec.ch0 + +@x +@p procedure vlist_out; {output a |vlist_node| box} +@y +@p procedure vlist_out; {output a |vlist_node| box} +@z + +@x tex.web l.12533 +save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); +MISSING @ before cur_v:=cur_v-height(this_box); +@y +save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; +@; +cur_v:=cur_v-height(this_box); +@z + +@x tex.web l.12569 +@= +if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) +MISSING @; +@y +@= +if list_ptr(p)=null then begin + cur_v:=cur_v+height(p); + @; + cur_v:=cur_v+depth(p); +end +@z @x MISSING IMPLEMENTATION: 0 synctag for medium sized node at mem[t] diff --git a/Build/source/texk/web2c/synctex/synctex-xe-rec.ch3 b/Build/source/texk/web2c/synctex/synctex-xe-rec.ch3 new file mode 100644 index 00000000000..880c0e4115f --- /dev/null +++ b/Build/source/texk/web2c/synctex/synctex-xe-rec.ch3 @@ -0,0 +1,67 @@ +Copyright (c) 2008 jerome DOT laurens AT u-bourgogne DOT fr + +This file is part of the SyncTeX package. + +License: +-------- +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE + +Except as contained in this notice, the name of the copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from the copyright holder. + +Notice: +------- +This file contains TeX changes for SyncTeX support. +It implements the memory management for XeTeX like engines. +It must apply after synctex.ch0 and synctex-e.ch1 + +@x +@p procedure vlist_out; {output a |vlist_node| box} +@y +@p procedure vlist_out; {output a |vlist_node| box} +@z + +@x +if upwards then cur_v:=cur_v+depth(this_box) else cur_v:=cur_v-height(this_box); +MISSING @ before cur_v:=cur_v-height(this_box); +@y +@; +if upwards then cur_v:=cur_v+depth(this_box) else cur_v:=cur_v-height(this_box); +@z + +@x +@= +if list_ptr(p)=null then begin + if upwards then cur_v:=cur_v-depth(p)-height(p) else cur_v:=cur_v+height(p)+depth(p); + end +MISSING @; +@y +@= +if list_ptr(p)=null then begin + if upwards then cur_v:=cur_v-depth(p) else cur_v:=cur_v+height(p); + @; + if upwards then cur_v:=cur_v-height(p) else cur_v:=cur_v+depth(p); +end +@z + diff --git a/Build/source/texk/web2c/synctex/synctex.c b/Build/source/texk/web2c/synctex/synctex.c index 90bcce98ab8..33c96b20f26 100644 --- a/Build/source/texk/web2c/synctex/synctex.c +++ b/Build/source/texk/web2c/synctex/synctex.c @@ -208,6 +208,7 @@ EXTERN char *gettexstring(int n); # define SYNCTEX_YES (-1) # define SYNCTEX_NO (0) +# define SYNCTEX_NO_ERROR (0) # include "synctex-TEX-OR-MF-OR-MP.h" @@ -242,34 +243,45 @@ static struct { integer total_length; /* The total length of the bytes written since the last check point */ struct _flags { unsigned int option_read:1; /* Command line option read (in case of problem or at the end) */ - unsigned int off:1; /* Definitely turn off synctex */ + unsigned int off:1; /* Definitely turn off synctex, corresponds to cli option -synctex=0 */ unsigned int no_gz:1; /* Whether zlib is used or not */ - unsigned int reserved:SYNCTEX_BITS_PER_BYTE*sizeof(int)-3; /* Align */ + unsigned int not_void:1; /* Whether it really contains synchronization material */ + unsigned int warn:1; /* One shot warning flag */ + unsigned int reserved:SYNCTEX_BITS_PER_BYTE*sizeof(int)-5; /* Align */ } flags; } synctex_ctxt = { -NULL, NULL, NULL, NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, {0,0,0,0}}; +NULL, NULL, NULL, NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0}}; #define SYNCTEX_FILE synctex_ctxt.file #define SYNCTEX_IS_OFF (synctex_ctxt.flags.off) #define SYNCTEX_NO_GZ (synctex_ctxt.flags.no_gz) +#define SYNCTEX_NOT_VOID (synctex_ctxt.flags.not_void) +#define SYNCTEX_WARNING_DISABLE (synctex_ctxt.flags.warn) #define SYNCTEX_fprintf (*synctex_ctxt.fprintf) +/* Initialize the options, synchronize the variables. + * This is sent by *tex.web before any TeX macro is used. + * */ void synctexinitcommand(void) { + /* This is a one shot function, any subsequent call is void */ if (synctex_ctxt.flags.option_read) { return; } if (SYNCTEX_NO_OPTION == synctex_options) { /* No option given from the command line */ SYNCTEX_VALUE = 0; - } else if (!synctex_options) { - /* -synctex=0 was given: SyncTeX must be disabled */ + } else if (synctex_options == 0) { + /* -synctex=0 was given: SyncTeX must be definitely disabled, + * any subsequent \synctex=1 will have no effect at all */ SYNCTEX_IS_OFF = SYNCTEX_YES; + SYNCTEX_VALUE = 0; } else { /* the command line options are not ignored */ - if(synctex_options<0) { + if(synctex_options < 0) { SYNCTEX_NO_GZ = SYNCTEX_YES; } + /* Initialize the content of the \synctex primitive */ SYNCTEX_VALUE = synctex_options; } synctex_ctxt.flags.option_read = SYNCTEX_YES; @@ -331,12 +343,10 @@ static void *synctex_dot_open(void) #if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctex_dot_open 1\n"); # endif - SYNCTEX_NO_GZ = synctex_options<0? SYNCTEX_YES:SYNCTEX_NO; /* this is the first time we are asked to open the file this part of code is executed only once: either SYNCTEX_FILE is nonnegative or synchronization is definitely disabled. */ - /* jobname was set by the \jobname command on the *TeX side */ { char *tmp = gettexstring(jobname); /* jobname was set by the \jobname command on the *TeX side */ @@ -348,7 +358,10 @@ static void *synctex_dot_open(void) } strcpy(the_busy_name, tmp); SYNCTEX_FREE(tmp); + tmp = NULL; strcat(the_busy_name, synctex_suffix); + /* Initialize SYNCTEX_NO_GZ with the content of \synctex to let the user choose the format. */ + SYNCTEX_NO_GZ = SYNCTEX_VALUE<0?SYNCTEX_YES:SYNCTEX_NO; if (!SYNCTEX_NO_GZ) { strcat(the_busy_name, synctex_suffix_gz); } @@ -364,7 +377,7 @@ static void *synctex_dot_open(void) printf("\nwarning: Synchronize DEBUG: synctex_dot_open 2\n"); #endif if (SYNCTEX_FILE) { - if(synctex_record_preamble()) { + if(SYNCTEX_NO_ERROR != synctex_record_preamble()) { synctex_abort(); return NULL; } @@ -388,6 +401,8 @@ static void *synctex_dot_open(void) } else { /* no .synctex file available, so disable synchronization */ SYNCTEX_IS_OFF = SYNCTEX_YES; + SYNCTEX_VALUE = 0; + printf("\nSyncTeX warning: no synchronization, problem with %s\n",the_busy_name); /* and free the_busy_name */ SYNCTEX_FREE(the_busy_name); the_busy_name = NULL; @@ -400,16 +415,16 @@ static void *synctex_dot_open(void) return SYNCTEX_FILE; } -/* Each time TeX opens a file, it sends a syncstartinput message and enters +/* Each time TeX opens a file, it sends a synctexstartinput message and enters * this function. Here, a new synchronization tag is created and stored in * the synctex_tag_field of the TeX current input context. Each synchronized - * TeX node will record this tag instead of the file name. syncstartinput - * writes the mapping synctag <-> file name to the .synctex file. A client + * TeX node will record this tag instead of the file name. synctexstartinput + * writes the mapping synctag <-> file name to the .synctex (or .synctex.gz) file. A client * will read the .synctex file and retrieve this mapping, it will be able to * open the correct file just knowing its tag. If the same file is read * multiple times, it might be associated to different tags. Synchronization * controllers, either in viewers, editors or standalone should be prepared to - * handle this situation and take the appropriate action of they want to + * handle this situation and take the appropriate action if they want to * optimize memory. No two different files will have the same positive tag. * It is not advisable to definitely store the file names here. If the file * names ever have to be stored, it should definitely be done at the TeX level @@ -434,7 +449,7 @@ void synctexstartinput(void) return; } /* synctex_tag_counter is a counter uniquely identifying the file actually - * open. Each time tex opens a new file, syncstartinput will increment this + * open. Each time tex opens a new file, synctexstartinput will increment this * counter */ if (~synctex_tag_counter > 0) { ++synctex_tag_counter; @@ -450,8 +465,8 @@ void synctexstartinput(void) if (synctex_tag_counter == 1) { /* this is the first file TeX ever opens, in general \jobname.tex we * do not know yet if synchronization will ever be enabled so we have - * to store the file name, because we will need it later This is - * certainly not necessary due to \jobname */ + * to store the file name, because we will need it later. + * This is certainly not necessary due to \jobname */ synctex_ctxt.root_name = gettexstring(curinput.namefield); /* we could initialize the unit field to 1 to avoid floating point exception * when accidentaly dividing by the unit. @@ -462,7 +477,7 @@ void synctexstartinput(void) # endif return; } - if (SYNCTEX_FILE || (SYNCTEX_VALUE && synctex_dot_open())) { + if (SYNCTEX_FILE || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) { char *tmp = gettexstring(curinput.namefield); synctex_record_input(curinput.synctextagfield,tmp); SYNCTEX_FREE(tmp); @@ -473,11 +488,6 @@ void synctexstartinput(void) return; } -static inline int synctex_record_postamble(void); - -/* Free all memory used and close the file, - * sent by close_files_and_terminate in tex.web. */ - /* All the synctex... functions below have the smallest set of parameters. It * appears to be either the address of a node, or nothing at all. Using zmem, * which is the place where all the nodes are stored, one can retrieve every @@ -485,7 +495,12 @@ static inline int synctex_record_postamble(void); * global context variable. */ -/* synctexterminate() is called when the TeX run terminates. +static inline int synctex_record_postamble(void); + + +/* Free all memory used and close the file, + * sent by close_files_and_terminate in tex.web. + * synctexterminate() is called when the TeX run terminates. * If synchronization was active, the working synctex file is moved to * the final synctex file name. * If synchronization was not active of if there is no output, @@ -511,15 +526,13 @@ void synctexterminate(boolean log_opened) } strcpy(the_real_syncname, tmp); strcat(the_real_syncname, synctex_suffix); - remove(the_real_syncname);/* I don't know if the previous run was made with the uncompressed mode */ - strcat(the_real_syncname, synctex_suffix_gz); - remove(the_real_syncname); - if (SYNCTEX_NO_GZ) { - strcpy(the_real_syncname, tmp); - strcat(the_real_syncname, synctex_suffix); + if (!SYNCTEX_NO_GZ) { + /* Remove any uncompressed synctex file, from a previous build. */ + remove(the_real_syncname); + strcat(the_real_syncname, synctex_suffix_gz); } if (SYNCTEX_FILE) { - if (totalpages > 0) { + if (SYNCTEX_NOT_VOID) { synctex_record_postamble(); /* close the synctex file*/ if (SYNCTEX_NO_GZ) { @@ -539,8 +552,16 @@ void synctexterminate(boolean log_opened) gzclose((gzFile)SYNCTEX_FILE); } remove(synctex_ctxt.busy_name); + remove(the_real_syncname); } SYNCTEX_FILE = NULL; + } else { + remove(the_real_syncname); + } + if (SYNCTEX_NO_GZ) { + /* Remove any compressed synctex file, from a previous build. */ + strcat(the_real_syncname, synctex_suffix_gz); + remove(the_real_syncname); } SYNCTEX_FREE(synctex_ctxt.busy_name); synctex_ctxt.busy_name = NULL; @@ -563,22 +584,25 @@ void synctexsheet(integer mag) printf("\nSynchronize DEBUG: synctexsheet %i\n",mag); #endif if (SYNCTEX_IS_OFF) { + if(SYNCTEX_VALUE && !SYNCTEX_WARNING_DISABLE) { + SYNCTEX_WARNING_DISABLE = SYNCTEX_YES; + printf("\nSyncTeX warning: Synchronization was disabled from\nthe command line with -synctex=0\nChanging the value of \\synctex has no effect."); + } return; } - if (SYNCTEX_FILE || (SYNCTEX_VALUE && synctex_dot_open())) { - /* tries to open the .synctex, useful if synchronization was enabled - * from the source file and not from the CLI + if (SYNCTEX_FILE || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != synctex_dot_open()))) { + /* First possibility: the .synctex file is already open because SyncTeX was activated on the CLI + * or it was activated with the \synctex macro and the first page is already shipped out. + * Second possibility: tries to open the .synctex, useful if synchronization was enabled + * from the source file and not from the CLI. * totalpages is defined in tex.web */ if (totalpages == 0) { - /* Now it is time to properly set up the scale factor. - * Depending on the output mode - * dvi and pdf, don't start from the same origin. - * dvi starts at (1in,1in) from the top left corner - * pdf starts exactly from the top left corner. */ + /* Now it is time to properly set up the scale factor. */ if(mag>0) { synctex_ctxt.magnification = mag; } - if(synctex_record_settings() || synctex_record_content()) { + if(SYNCTEX_NO_ERROR != synctex_record_settings() + || SYNCTEX_NO_ERROR != synctex_record_content()) { synctex_abort(); return; } @@ -593,8 +617,8 @@ void synctexsheet(integer mag) static inline int synctex_record_teehs(integer sheet); -/* Recording the "}..." line. In *tex.web, use synctex_sheet(mag) at - * the very beginning of the ship_out procedure. +/* Recording the "}..." line. In *tex.web, use synctex_teehs at + * the very end of the ship_out procedure. */ void synctexteehs(void) { @@ -812,15 +836,25 @@ static inline void synctex_record_rule(halfword p); /* this message is sent whenever an horizontal glue node or rule node ships out See: move_past:... */ +# define SYNCTEX_IGNORE_RULE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \ + || (0 >= SYNCTEX_TAG_MODEL(NODE,rule_node_size)) \ + || (0 >= SYNCTEX_LINE_MODEL(NODE,rule_node_size)) void synctexhorizontalruleorglue(halfword p, halfword this_box) { SYNCTEX_RETURN_IF_DISABLED; #if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexglue\n"); #endif - if (SYNCTEX_IGNORE(p)) { - return; - } + if (SYNCTEX_TYPE(p) == rule_node) { /* not medium_node_size so we can't use SYNCTEX_IGNORE */ + if (SYNCTEX_IGNORE_RULE(p)) { + return; + } + } + else { + if (SYNCTEX_IGNORE(p)) { + return; + } + } synctex_ctxt.node = p; synctex_ctxt.curh = curh; synctex_ctxt.curv = curv; @@ -1116,6 +1150,7 @@ static inline void synctex_record_void_vlist(halfword p) static inline void synctex_record_vlist(halfword p) { size_t len = 0; + SYNCTEX_NOT_VOID = SYNCTEX_YES; #if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_vlist\n"); #endif @@ -1178,6 +1213,7 @@ static inline void synctex_record_void_hlist(halfword p) static inline void synctex_record_hlist(halfword p) { size_t len = 0; + SYNCTEX_NOT_VOID = SYNCTEX_YES; #if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_hlist\n"); #endif diff --git a/Build/source/texk/web2c/synctex/synctex.h b/Build/source/texk/web2c/synctex/synctex.h index ab49e9038e3..1acfb96f86f 100644 --- a/Build/source/texk/web2c/synctex/synctex.h +++ b/Build/source/texk/web2c/synctex/synctex.h @@ -28,16 +28,11 @@ OTHER DEALINGS IN THE SOFTWARE # ifndef __SYNCTEX_HEADER__ # define __SYNCTEX_HEADER__ -/* Send this message to init the synctex command value to the command line option. - * Sending this message too early will cause a bus error. */ -extern void synctexinitcommand(void); +#include "synctex-common.h" /* Send this message when starting a new input. */ extern void synctexstartinput(void); -/* Send this message to clean memory. */ -extern void synctexterminate(boolean log_opened); - /* Recording the "{..." line. In *tex.web, use synctex_sheet(pdf_output) at * the very beginning of the ship_out procedure. */ @@ -97,4 +92,4 @@ extern void synctexnode(halfword p, halfword this_box); /* For debugging purpose only */ extern void synctexcurrent(void); -# endif \ No newline at end of file +# endif diff --git a/Build/source/texk/web2c/synctex/synctex.mk b/Build/source/texk/web2c/synctex/synctex.mk index 8d33f360f51..711c7cb50c1 100644 --- a/Build/source/texk/web2c/synctex/synctex.mk +++ b/Build/source/texk/web2c/synctex/synctex.mk @@ -37,23 +37,31 @@ synctex_dir = $(srcdir)/synctex -synctex_all_texd = \ - echo "Enabling SyncTeX Support.";\ - echo "s/\#include \"texmfmp.h\"/\#define __SyncTeX__\\" > synctex_sed_command.txt;\ - echo "\#include \"texmfmp.h\"/" >> synctex_sed_command.txt +Makefile: $(synctex_dir)/synctex.mk + +# for all the engines, this trick allows to enable or disable SyncTeX support from here. +# One of the synctex functions is called before the main_control routine +# this is why we must include synctex.h header +synctex_common_texd = \ + echo "Enabling SyncTeX Support.";\ + echo "s|\#include \"texmfmp.h\"|&\\"> synctex_sed_command.txt;\ + echo "/* Start of SyncTeX Section */\\" >> synctex_sed_command.txt;\ + echo "\#define __SyncTeX__\\" >> synctex_sed_command.txt;\ + echo "\#include \"$(synctex_dir)/synctex-common.h\"\\" >> synctex_sed_command.txt;\ + echo "/* End of SyncTeX Section */|g" >> synctex_sed_command.txt ### SyncTeX support in tex # list of change files -synctex-tex_ch_srcs_mem_only = \ - $(synctex_dir)/synctex-mem.ch0 \ - $(synctex_dir)/synctex-mem.ch1 \ - $(synctex_dir)/synctex-mem.ch2 -synctex-tex_ch_srcs_on = \ - $(synctex-tex_ch_srcs_mem_only) \ - $(synctex_dir)/synctex-rec.ch0 \ - $(synctex_dir)/synctex-rec.ch1 \ - $(synctex_dir)/synctex-rec.ch2 -synctex-tex_ch_srcs_off = +tex_ch_srcs-with_synctex-mem_only = \ + $(synctex_dir)/synctex-mem.ch0 \ + $(synctex_dir)/synctex-mem.ch1 \ + $(synctex_dir)/synctex-mem.ch2 +tex_ch_srcs-without_synctex = \ + $(tex_ch_srcs-with_synctex-mem_only) \ + $(synctex_dir)/synctex-rec.ch0 \ + $(synctex_dir)/synctex-rec.ch1 \ + $(synctex_dir)/synctex-rec.ch2 +tex_ch_srcs-without_synctex = synctex-tex.ch:tie tex.ch $(synctex-tex_ch_srcs) $(TIE) -c synctex-tex.ch $(srcdir)/tex.web $(synctex-tex_ch_srcs) # The C sources and headers @@ -62,37 +70,35 @@ synctex.h: $(synctex_dir)/synctex.h cat $(synctex_dir)/synctex.h >$@ synctex-tex.h: $(synctex_dir)/$@ cat $(synctex_dir)/$@ >$@ -synctex.c: texd.h $(synctex_dir)/synctex.c synctex-tex.h +synctex.c: texd.h $(synctex_dir)/synctex.c synctex.h synctex-tex.h sed s/TEX-OR-MF-OR-MP/tex/ $(synctex_dir)/synctex.c >$@ -synctex_texd_on = \ - if test -z "`grep __SyncTeX__ texd.h`";\ +texd.h-with_synctex = if test -z "`grep __SyncTeX__ texd.h`";\ then\ - $(synctex_all_texd);\ + $(synctex_common_texd);\ sed -f synctex_sed_command.txt texd.h > synctex_texd.h;\ mv synctex_texd.h texd.h;\ - rm -f synctex_sed_command.txt;\ + if test -z "`grep __SyncTeX__ texd.h`";\ + then\ + echo "warning: SyncTeX activation FAILED";\ + exit 1;\ + fi;\ + echo "warning: SyncTeX is enabled";\ fi -synctex_texd_off = -# switchers: _on to enable full synctex support, _off to completely disable synctex, _mem_only to only implement memory management. -synctex-tex_ch_srcs = \ - $(srcdir)/tex.ch \ - $(synctex-tex_ch_srcs_on) -# _on to enable -synctex command line option, _off to disable -synctex_texd = $(synctex_texd_on) +texd.h-without_synctex = echo "warning: SyncTeX is NOT enabled" ### SyncTeX support in etex # list of change files synctex-etex_ch_srcs_mem_only = \ - $(synctex_dir)/synctex-mem.ch0 \ - $(synctex_dir)/synctex-mem.ch1 \ - $(synctex_dir)/synctex-e-mem.ch0 \ - $(synctex_dir)/synctex-e-mem.ch1 + $(synctex_dir)/synctex-mem.ch0 \ + $(synctex_dir)/synctex-mem.ch1 \ + $(synctex_dir)/synctex-e-mem.ch0 \ + $(synctex_dir)/synctex-e-mem.ch1 synctex-etex_ch_srcs_on = \ - $(synctex-etex_ch_srcs_mem_only) \ - $(synctex_dir)/synctex-rec.ch0 \ - $(synctex_dir)/synctex-rec.ch1 \ - $(synctex_dir)/synctex-e-rec.ch0 \ - $(synctex_dir)/synctex-e-rec.ch1 + $(synctex-etex_ch_srcs_mem_only) \ + $(synctex_dir)/synctex-rec.ch0 \ + $(synctex_dir)/synctex-rec.ch1 \ + $(synctex_dir)/synctex-e-rec.ch0 \ + $(synctex_dir)/synctex-e-rec.ch1 synctex-etex_ch_srcs_off = # The C sources and headers synctex-etex_o = synctex-e.o @@ -102,101 +108,112 @@ synctex-etex.h: $(synctex_dir)/$@ cat $(synctex_dir)/$@ >$@ synctex-e.c: etexd.h $(synctex_dir)/synctex.c synctex-etex.h sed s/TEX-OR-MF-OR-MP/etex/ $(synctex_dir)/synctex.c >$@ -synctex_etexd_on = \ - if test -z "`grep __SyncTeX__ etexd.h`";\ +etexd.h-with_synctex = if test -z "`grep __SyncTeX__ etexd.h`";\ then\ - $(synctex_all_texd);\ + $(synctex_common_texd);\ sed -f synctex_sed_command.txt etexd.h > synctex_etexd.h;\ mv synctex_etexd.h etexd.h;\ - rm -f synctex_sed_command.txt;\ + if test -z "`grep __SyncTeX__ etexd.h`";\ + then\ + echo "warning: SyncTeX activation FAILED";\ + exit 1;\ + fi;\ + echo "warning: SyncTeX is enabled";\ fi -synctex_etexd_off = -# switchers: _on to enable full synctex support, _off to completely disable synctex, _mem_only to only implement memory management. -synctex-etex_ch_srcs = $(synctex-etex_ch_srcs_on) -# _on to enable -synctex command line option, _off to disable -synctex_etexd = $(synctex_etexd_on) +etexd.h-without_synctex = echo "warning: SyncTeX is NOT enabled" ### SyncTeX support in pdftex # list of change files -synctex-pdftex_ch_srcs_mem_only = \ - $(synctex_dir)/synctex-mem.ch0 \ - $(synctex_dir)/synctex-mem.ch1 \ - $(synctex_dir)/synctex-e-mem.ch0 \ - $(synctex_dir)/synctex-e-mem.ch1 -synctex-pdftex_ch_srcs_on = \ - $(synctex-pdftex_ch_srcs_mem_only) \ - $(synctex_dir)/synctex-rec.ch0 \ - $(synctex_dir)/synctex-rec.ch1 \ - $(synctex_dir)/synctex-e-rec.ch0 \ - $(synctex_dir)/synctex-e-rec.ch1 \ - $(synctex_dir)/synctex-pdf-rec.ch2 -synctex-pdftex_ch_srcs_off = +pdftex_ch_srcs-with_synctex-mem_only = \ + $(synctex_dir)/synctex-mem.ch0 \ + $(synctex_dir)/synctex-mem.ch1 \ + $(synctex_dir)/synctex-e-mem.ch0 \ + $(synctex_dir)/synctex-e-mem.ch1 +pdftex_ch_srcs-with_synctex = \ + $(pdftex_ch_srcs-with_synctex-mem_only) \ + $(synctex_dir)/synctex-rec.ch0 \ + $(synctex_dir)/synctex-rec.ch1 \ + $(synctex_dir)/synctex-e-rec.ch0 \ + $(synctex_dir)/synctex-e-rec.ch1 \ + $(synctex_dir)/synctex-pdf-rec.ch2 +pdftex_ch_srcs-without_synctex = # The C sources and headers -synctex-pdftex_o = synctex-pdf.o +pdftex_o-with_synctex = synctex-pdf.o +pdftex_o-without_synctex = synctex-pdf.h: $(synctex_dir)/synctex.h cat $(synctex_dir)/synctex.h >$@ synctex-pdftex.h: $(synctex_dir)/$@ cat $(synctex_dir)/$@ >$@ synctex-pdf.c: pdftexd.h $(synctex_dir)/synctex.c synctex-pdftex.h sed s/TEX-OR-MF-OR-MP/pdftex/ $(synctex_dir)/synctex.c >$@ -synctex_pdftexd_on = \ - if test -z "`grep __SyncTeX__ pdftexd.h`";\ +pdftexd.h-with_synctex = if test -z "`grep __SyncTeX__ pdftexd.h`";\ then\ - $(synctex_all_texd);\ + $(synctex_common_texd);\ sed -f synctex_sed_command.txt pdftexd.h > synctex_pdftexd.h;\ mv synctex_pdftexd.h pdftexd.h;\ - rm -f synctex_sed_command.txt;\ + if test -z "`grep __SyncTeX__ pdftexd.h`";\ + then\ + echo "warning: SyncTeX activation FAILED";\ + exit 1;\ + fi;\ + echo "warning: SyncTeX is enabled";\ fi -synctex_pdftexd_off = -# switchers: _on to enable full synctex support, _off to completely disable synctex, _mem_only to only implement memory management. -synctex-pdftex_ch_srcs = $(synctex-pdftex_ch_srcs_on) -# _on to enable -synctex command line option, _off to disable -synctex_pdftexd = $(synctex_pdftexd_on) +pdftexd.h-without_synctex = echo "warning: SyncTeX is NOT enabled" ### SyncTeX support in xetex +# Actually, xetex cannot build without SyncTeX because the tex.web +# code does not provide proper entry points # list of change files -synctex-xetex_ch_srcs_mem_only = \ - $(synctex_dir)/synctex-mem.ch0 \ - $(synctex_dir)/synctex-e-mem.ch0 \ - $(synctex_dir)/synctex-e-mem.ch1 \ - $(synctex_dir)/synctex-xe-mem.ch2 -synctex-xetex_ch_srcs_on = \ - $(synctex-xetex_ch_srcs_mem_only) \ - $(synctex_dir)/synctex-rec.ch0 \ - $(synctex_dir)/synctex-e-rec.ch0 \ - $(synctex_dir)/synctex-xe-rec.ch2 -synctex-xetex_ch_srcs_off = +xetex_ch_srcs-with_synctex-mem_only = \ + $(synctex_dir)/synctex-mem.ch0 \ + $(synctex_dir)/synctex-e-mem.ch0 \ + $(synctex_dir)/synctex-e-mem.ch1 \ + $(synctex_dir)/synctex-xe-mem.ch2 +xetex_ch_srcs-with_synctex = \ + $(xetex_ch_srcs-with_synctex-mem_only) \ + $(synctex_dir)/synctex-rec.ch0 \ + $(synctex_dir)/synctex-e-rec.ch0 \ + $(synctex_dir)/synctex-xe-rec.ch2 +xetex_ch_srcs-without_synctex = +xetex_post_ch_srcs-with_synctex = \ + $(synctex_dir)/synctex-xe-rec.ch3 +xetex_post_ch_srcs-without_synctex = # The C sources and headers -synctex-xetex_o = synctex-xe.o +xetex_o-with_synctex = synctex-xe.o +xetex_o-without_synctex = synctex-xe.h: $(synctex_dir)/synctex.h cat $(synctex_dir)/synctex.h >$@ synctex-xetex.h: $(synctex_dir)/$@ cat $(synctex_dir)/$@ >$@ synctex-xe.c: xetexd.h $(synctex_dir)/synctex.c synctex-xetex.h sed s/TEX-OR-MF-OR-MP/xetex/ $(synctex_dir)/synctex.c >$@ -synctex_xetexd_on = \ - if test -z "`grep __SyncTeX__ xetexd.h`";\ +xetexd.h-with_synctex = if test -z "`grep __SyncTeX__ xetexd.h`";\ then\ - $(synctex_all_texd);\ + $(synctex_common_texd);\ sed -f synctex_sed_command.txt xetexd.h > synctex_xetexd.h;\ mv synctex_xetexd.h xetexd.h;\ - rm -f synctex_sed_command.txt;\ + if test -z "`grep __SyncTeX__ xetexd.h`";\ + then\ + echo "warning: SyncTeX activation FAILED";\ + exit 1;\ + fi;\ + echo "warning: SyncTeX is enabled";\ fi -synctex_xetexd_off = -# switchers: _on to enable full synctex support, _off to completely disable synctex, _mem_only to only implement memory management. -synctex-xetex_ch_srcs = $(synctex-xetex_ch_srcs_on) -# _on to enable -synctex command line option, _off to disable -synctex_xetexd = $(synctex_xetexd_on) +xetexd.h-without_synctex = echo "warning: SyncTeX is NOT enabled" # the synctex tool, this is not yet implemented -synctex_parser.c synctex_parser.h synctex_main.c: - cat $(synctex_dir)/$@ >$@ -synctex:synctex_main.o synctex_parser.o - $(link_command) synctex_main.o synctex_parser.o +synctex_parser.o: $(synctex_dir)/synctex_parser.c $(synctex_dir)/synctex_parser.h + $(compile) -c -I$(synctex_dir) $(ZLIBCPPFLAGS) -o $@ $< + +synctex_main.o: $(synctex_dir)/synctex_main.c $(synctex_dir)/synctex_parser.h + $(compile) -c -I$(synctex_dir) $(ZLIBCPPFLAGS) -o $@ $< + +synctex:synctex_main.o synctex_parser.o $(ZLIBDEPS) + $(link_command) synctex_main.o synctex_parser.o $(LDZLIB) # Cleaning up. clean:: synctex-clean synctex-clean: - -rm -f synctex-* + -rm -f *synctex* # end of synctex.mk diff --git a/Build/source/texk/web2c/synctex/synctex_main.c b/Build/source/texk/web2c/synctex/synctex_main.c index 8ae5246c073..9922f28543b 100644 --- a/Build/source/texk/web2c/synctex/synctex_main.c +++ b/Build/source/texk/web2c/synctex/synctex_main.c @@ -265,7 +265,7 @@ option_hint: return -1; } } - /* Now proceed, ignore any other argument */ + /* Now proceed, ignore any other argument */ proceed: #if SYNCTEX_DEBUG printf("line:%i\n",line); @@ -279,6 +279,12 @@ proceed: printf("output:%s\n",output); printf("cwd:%s\n",getcwd(NULL,0)); #endif + /* We assume that viewer is not so big: */ +# define SYNCTEX_STR_SIZE 65536 + if(strlen(viewer)>=65536) { + synctex_help_view("Viewer command is too long"); + return -1; + } size = strlen(output)+strlen(suffix)+strlen(suffix_gz)+1; synctex = (char *)malloc(size); if(NULL == synctex) { @@ -328,30 +334,30 @@ proceed: if(node = synctex_next_result(scanner)) { /* filtering the command */ if(viewer && strlen(viewer)) { - /* Replace %{ by &{, then remove all unescaped '%'*/ char * where = NULL; - char * dictionary [] = { - "&{output}","%1$s", - "&{page}","%2$i", - "&{page+1}","%3$i", - "&{x}","%4$f", - "&{y}","%5$f", - "&{h}","%6$f", - "&{v}","%7$f", - "&{width}","%8$f", - "&{height}","%9$f", - "&{before}","%10$s", - "&{offset}","%11$i", - "&{middle}","%12$s", - "&{after}","%13$s"}; - int i = 26; char * buffer = NULL; + char * buffer_cur = NULL; + int printed = 0; int status = 0; + /* Preparing the buffer where everything will be printed */ + size = strlen(viewer)+3*sizeof(int)+6*sizeof(float)+4*(SYNCTEX_STR_SIZE); + buffer = malloc(size+1); + if(NULL == buffer) { + synctex_help_view("No memory available"); + return -1; + } + /* Properly terminate the buffer, no bad access for string related functions. */ + buffer[size] = '\0'; + /* Replace %{ by &{, then remove all unescaped '%'*/ while(where = strstr(viewer,"%{")) { *where = '&'; } + /* find all the unescaped '%', change to a safe character */ where = viewer; - while(where = strstr(viewer,"%")) { + while(where && (where = strstr(where,"%"))) { + /* Find the next occurrence of a "%", + * if it is not followed by another "%", + * replace it by a "&" */ if(strlen(++where)) { if(*where == '%') { ++where; @@ -360,42 +366,42 @@ proceed: } } } - while(i>0) { - char * value = dictionary[--i]; - char * key = dictionary[--i]; -find_a_key: - where = strstr(viewer,key); - if(where) { - memcpy(where,value,strlen(value)); - memmove(where+strlen(value),where+strlen(key),strlen(where)-strlen(key)+1); - goto find_a_key; + buffer_cur = buffer; + /* find the next occurrence of a format key */ + where = viewer; + while(viewer && (where = strstr(viewer,"&{"))) { + char * format_key = NULL; + #define TEST(KEY,FORMAT,WHAT)\ + format_key="&{output}";\ + if(!strcmp(viewer,format_key)) {\ + printed = where-viewer;\ + if(buffer != memcpy(buffer_cur,viewer,(size_t)printed)) {\ + synctex_help_view("Memory copy problem");\ + free(buffer);\ + return -1;\ + }\ + buffer_cur += printed;size-=printed;\ + printed = snprintf(buffer_cur,size,"%s","
");\ + buffer_cur += printed;size-=printed;\ + *buffer_cur='\0';\ + viewer = where+strlen(format_key);\ + continue;\ } - } - size = strlen(viewer)+3*sizeof(int)+6*sizeof(float)+4*(65536)+1; - buffer = malloc(size); - if(NULL == buffer) { - synctex_help_view("No memory available"); - return -1; - } - if(size-1<=snprintf(buffer,size,viewer, - "
", - synctex_node_page(node)-1, - synctex_node_page(node), - synctex_node_h(node), - synctex_node_v(node), - synctex_node_box_visible_h(node), - synctex_node_box_visible_v(node)+synctex_node_box_visible_depth(node), - synctex_node_box_visible_width(node), - synctex_node_box_visible_height(node)+synctex_node_box_visible_depth(node), - (before?before:""), - offset, - (middle?middle:""), - (after?after:""))) { - /* Not all the characters were printed*/ - free(buffer); - buffer= NULL; - synctex_help_view("Problem with\n%s\n",viewer); - return -1; + TEST("&{output}","%s","
"); + TEST("&{page}", "%i",synctex_node_page(node)-1); + TEST("&{page+1}","%i",synctex_node_page(node)); + TEST("&{x}", "%f",synctex_node_h(node)); + TEST("&{y}", "%f",synctex_node_v(node)); + TEST("&{h}", "%f",synctex_node_visible_h(node)); + TEST("&{v}", "%f",synctex_node_visible_v(node)); + TEST("&{width}", "%f",synctex_node_visible_width(node)); + TEST("&{height}","%f",synctex_node_visible_height(node)); + TEST("&{before}","%s",(strlen(before)start && strlen(end)>1 && *end==':') { + start = end+1; y = strtof(start,&end); if(end>start && strlen(end)>1 && *end==':') { output = ++end; @@ -565,7 +574,7 @@ proceed: printf("context:%s\n",context); printf("cwd:%s\n",getcwd(NULL,0)); #endif - size = strlen(output)+9; + size = strlen(output)+strlen(suffix)+strlen(suffix_gz)+1; synctex = (char *)malloc(size); if(NULL == synctex) { synctex_help_edit("No more memory"); @@ -588,37 +597,49 @@ proceed: } while(where = strstr(ptr+1,SYNCTEX_PATH_EXTENSION_SEPARATOR)); *ptr = '\0'; } - if(0 == strlcat(synctex,".synctex",size)){ + if(0 == strlcat(synctex,suffix,size)){ synctex_help_edit("Concatenation problem"); return -1; } - size = 0; scanner = synctex_scanner_new_with_contents_of_file(synctex); + if(!scanner) { + if(0 == strlcat(synctex,suffix_gz,size)){ + synctex_help_view("Concatenation problem (can't add suffix '%s')",suffix_gz); + return -1; + } + scanner = synctex_scanner_new_with_contents_of_file(synctex); + if(!scanner) { + synctex_help_view("No SyncTeX available"); + return -1; + } + } free(synctex); synctex = NULL; + size = 0; if(scanner && synctex_edit_query(scanner,page,x,y)) { synctex_node_t node = NULL; char * input = NULL; if((node = synctex_next_result(scanner)) && (input = (char *)synctex_scanner_get_name(scanner,synctex_node_tag(node)))) { /* filtering the command */ - if(strlen(editor)) { + if(editor && strlen(editor)) { char * buffer = NULL; + char * buffer_cur = NULL; + int printed; int status; - char * dictionary [] = { - "&{output}","%1$s", - "&{input}","%2$s", - "&{line}","%3$i", - "&{column}","%4$i", - "&{offset}","%5$i", - "&{context}","%6$s"}; - int i = 12; + size = strlen(editor)+3*sizeof(int)+3*SYNCTEX_STR_SIZE; + buffer = malloc(size+1); + if(NULL == buffer) { + printf("SyncTeX ERROR: No memory available\n",editor); + return -1; + } + buffer[size]='\0'; /* Replace %{ by &{, then remove all unescaped '%'*/ while(where = strstr(editor,"%{")) { *where = '&'; } where = editor; - while(where = strstr(editor,"%")) { + while(where &&(where = strstr(where,"%"))) { if(strlen(++where)) { if(*where == '%') { ++where; @@ -627,35 +648,35 @@ proceed: } } } - while(i>0) { - char * value = dictionary[--i]; - char * key = dictionary[--i]; -find_a_key: - where = strstr(editor,key); - if(where) { - memcpy(where,value,strlen(value)); - memmove(where+strlen(value),where+strlen(key),strlen(where)-strlen(key)+1); - goto find_a_key; + buffer_cur = buffer; + /* find the next occurrence of a format key */ + where = editor; + while(editor && (where = strstr(editor,"&{"))) { + char * format_key = NULL; + #define TEST(KEY,FORMAT,WHAT)\ + format_key="&{output}";\ + if(!strcmp(editor,format_key)) {\ + printed = where-editor;\ + if(buffer != memcpy(buffer_cur,editor,(size_t)printed)) {\ + synctex_help_view("Memory copy problem");\ + free(buffer);\ + return -1;\ + }\ + buffer_cur += printed;size-=printed;\ + printed = snprintf(buffer_cur,size,"%s","
");\ + buffer_cur += printed;size-=printed;\ + *buffer_cur='\0';\ + editor = where+strlen(format_key);\ + continue;\ } - } - size = strlen(editor)+3*sizeof(int)+6*sizeof(float)+4*(65536)+1; - buffer = malloc(size); - if(NULL == buffer) { - printf("SyncTeX ERROR: No memory available\n",editor); - return -1; - } - if(size-1<=snprintf(buffer,size,editor, - output, - input, - synctex_node_line(node), - synctex_node_column(node), - offset, - (context?context:""))) { - /* Not all the characters were printed*/ - free(buffer); - buffer= NULL; - printf("SyncTeX ERROR: Problem with\n%s\n",editor); - return -1; + TEST("&{output}", "%s",output); + TEST("&{input}", "%s",input); + TEST("&{line}", "%i",line); + TEST("&{column}", "%i",column); + TEST("&{offset}", "%i",offset); + TEST("&{context}","%s",context); + #undef TEST + break; } printf("SyncTeX: Executing\n%s\n",buffer); status = system(buffer); @@ -668,8 +689,8 @@ find_a_key: do { printf( "Output:%s\n" "Input:%s\n" - "Line:%f\n" - "Column:%s\n" + "Line:%i\n" + "Column:%i\n" "Offset:%i\n" "Context:%s\n", output, diff --git a/Build/source/texk/web2c/synctex/synctex_parser.c b/Build/source/texk/web2c/synctex/synctex_parser.c index 6e0fb7f02ef..4f45c86d88b 100644 --- a/Build/source/texk/web2c/synctex/synctex_parser.c +++ b/Build/source/texk/web2c/synctex/synctex_parser.c @@ -117,74 +117,74 @@ struct __synctex_class_t { # pragma mark Abstract OBJECTS and METHODS /* These macros are shortcuts - * INFO(node) points to the first synctex integer data of node - * INFO(node)[index] is the information at index + * SYNCTEX_INFO(node) points to the first synctex integer data of node + * SYNCTEX_INFO(node)[index] is the information at index */ -# define INFO(NODE) ((*((((NODE)->class))->info))(NODE)) +# define SYNCTEX_INFO(NODE) ((*((((NODE)->class))->info))(NODE)) /* This macro checks if a message can be sent. */ -# define CAN_PERFORM(NODE,SELECTOR)\ +# define SYNCTEX_CAN_PERFORM(NODE,SELECTOR)\ (NULL!=((((NODE)->class))->SELECTOR)) /* This macro is some kind of objc_msg_send. * It takes care of sending the proper message if possible. */ -# define MSG_SEND(NODE,SELECTOR) if(NODE && CAN_PERFORM(NODE,SELECTOR)) {\ +# define SYNCTEX_MSG_SEND(NODE,SELECTOR) if(NODE && SYNCTEX_CAN_PERFORM(NODE,SELECTOR)) {\ (*((((NODE)->class))->SELECTOR))(NODE);\ } /* read only safe getter */ -# define GET(NODE,SELECTOR)((NODE && CAN_PERFORM(NODE,SELECTOR))?GETTER(NODE,SELECTOR)[0]:(NULL)) +# define SYNCTEX_GET(NODE,SELECTOR)((NODE && SYNCTEX_CAN_PERFORM(NODE,SELECTOR))?SYNCTEX_GETTER(NODE,SELECTOR)[0]:(NULL)) /* read/write getter */ -# define GETTER(NODE,SELECTOR)\ +# define SYNCTEX_GETTER(NODE,SELECTOR)\ ((synctex_node_t *)((*((((NODE)->class))->SELECTOR))(NODE))) -# define FREE(NODE) MSG_SEND(NODE,free); +# define SYNCTEX_FREE(NODE) SYNCTEX_MSG_SEND(NODE,free); /* Parent getter and setter */ -# define PARENT(NODE) GET(NODE,parent) -# define SET_PARENT(NODE,NEW_PARENT) if(NODE && NEW_PARENT && CAN_PERFORM(NODE,parent)){\ - GETTER(NODE,parent)[0]=NEW_PARENT;\ +# define SYNCTEX_PARENT(NODE) SYNCTEX_GET(NODE,parent) +# define SYNCTEX_SET_PARENT(NODE,NEW_PARENT) if(NODE && NEW_PARENT && SYNCTEX_CAN_PERFORM(NODE,parent)){\ + SYNCTEX_GETTER(NODE,parent)[0]=NEW_PARENT;\ } /* Child getter and setter */ -# define CHILD(NODE) GET(NODE,child) -# define SET_CHILD(NODE,NEW_CHILD) if(NODE && NEW_CHILD){\ - GETTER(NODE,child)[0]=NEW_CHILD;\ - GETTER(NEW_CHILD,parent)[0]=NODE;\ +# define SYNCTEX_CHILD(NODE) SYNCTEX_GET(NODE,child) +# define SYNCTEX_SET_CHILD(NODE,NEW_CHILD) if(NODE && NEW_CHILD){\ + SYNCTEX_GETTER(NODE,child)[0]=NEW_CHILD;\ + SYNCTEX_GETTER(NEW_CHILD,parent)[0]=NODE;\ } /* Sibling getter and setter */ -# define SIBLING(NODE) GET(NODE,sibling) -# define SET_SIBLING(NODE,NEW_SIBLING) if(NODE && NEW_SIBLING) {\ - GETTER(NODE,sibling)[0]=NEW_SIBLING;\ - if(CAN_PERFORM(NEW_SIBLING,parent) && CAN_PERFORM(NODE,parent)) {\ - GETTER(NEW_SIBLING,parent)[0]=GETTER(NODE,parent)[0];\ +# define SYNCTEX_SIBLING(NODE) SYNCTEX_GET(NODE,sibling) +# define SYNCTEX_SET_SIBLING(NODE,NEW_SIBLING) if(NODE && NEW_SIBLING) {\ + SYNCTEX_GETTER(NODE,sibling)[0]=NEW_SIBLING;\ + if(SYNCTEX_CAN_PERFORM(NEW_SIBLING,parent) && SYNCTEX_CAN_PERFORM(NODE,parent)) {\ + SYNCTEX_GETTER(NEW_SIBLING,parent)[0]=SYNCTEX_GETTER(NODE,parent)[0];\ }\ } /* Friend getter and setter */ -# define FRIEND(NODE) GET(NODE,friend) -# define SET_FRIEND(NODE,NEW_FRIEND) if(NODE && NEW_FRIEND){\ - GETTER(NODE,friend)[0]=NEW_FRIEND;\ +# define SYNCTEX_FRIEND(NODE) SYNCTEX_GET(NODE,friend) +# define SYNCTEX_SET_FRIEND(NODE,NEW_FRIEND) if(NODE && NEW_FRIEND){\ + SYNCTEX_GETTER(NODE,friend)[0]=NEW_FRIEND;\ } /* A node is meant to own its child and sibling. * It is not owned by its parent, unless it is its first child. - * This destructor is for all nodes. + * This destructor is for all nodes with children. */ void _synctex_free_node(synctex_node_t node) { if(node) { (*((node->class)->sibling))(node); - FREE(SIBLING(node)); - FREE(CHILD(node)); + SYNCTEX_FREE(SYNCTEX_SIBLING(node)); + SYNCTEX_FREE(SYNCTEX_CHILD(node)); free(node); } return; @@ -196,7 +196,7 @@ void _synctex_free_node(synctex_node_t node) { */ void _synctex_free_leaf(synctex_node_t node) { if(node) { - FREE(SIBLING(node)); + SYNCTEX_FREE(SYNCTEX_SIBLING(node)); free(node); } return; @@ -205,12 +205,12 @@ void _synctex_free_leaf(synctex_node_t node) { #include /* The synctex scanner is the root object. - * Is is initiated with the contents of a text file. + * Is is initialized with the contents of a text file. * The buffer_? are first used to parse the text. */ struct __synctex_scanner_t { gzFile file; /* The (compressed) file */ - unsigned char * buffer_ptr; /* current location in the buffer */ + unsigned char * buffer_cur; /* current location in the buffer */ unsigned char * buffer_start; /* start of the buffer */ unsigned char * buffer_end; /* end of the buffer */ char * output; /* dvi or pdf, not yet used */ @@ -223,18 +223,18 @@ struct __synctex_scanner_t { float unit; /* real unit, from synctex preamble or post scriptum */ float x_offset; /* X offset, from synctex preamble or post scriptum */ float y_offset; /* Y Offset, from synctex preamble or post scriptum */ - synctex_node_t sheet; /* The first sheet node */ - synctex_node_t input; /* The first input node */ + synctex_node_t sheet; /* The first sheet node, its siblings are the other sheet nodes */ + synctex_node_t input; /* The first input node, its siblings are the other input nodes */ int number_of_lists; /* The number of friend lists */ synctex_node_t * lists_of_friends;/* The friend lists */ _synctex_class_t class[synctex_node_type_last]; /* The classes of the nodes of the scanner */ }; -/* PTR, START and END are convenient shortcuts +/* SYNCTEX_CUR, SYNCTEX_START and SYNCTEX_END are convenient shortcuts */ -# define PTR (scanner->buffer_ptr) -# define START (scanner->buffer_start) -# define END (scanner->buffer_end) +# define SYNCTEX_CUR (scanner->buffer_cur) +# define SYNCTEX_START (scanner->buffer_start) +# define SYNCTEX_END (scanner->buffer_end) # pragma mark - # pragma mark OBJECTS, their creators and destructors. @@ -253,21 +253,21 @@ typedef struct { } synctex_sheet_t; /* The next macros is used to access the node info - * for example, the page of a sheet is stored in INFO(sheet)[PAGE] + * for example, the page of a sheet is stored in SYNCTEX_INFO(sheet)[PAGE] */ # define PAGE 0 /* This macro defines implementation offsets */ -# define MAKE_GET(GETTER,OFFSET)\ -synctex_node_t * GETTER (synctex_node_t node) {\ +# define SYNCTEX_MAKE_GET(SYNCTEX_GETTER,OFFSET)\ +synctex_node_t * SYNCTEX_GETTER (synctex_node_t node) {\ return node?(synctex_node_t *)((&((node)->implementation))+OFFSET):NULL;\ } -MAKE_GET(_synctex_implementation_0,0) -MAKE_GET(_synctex_implementation_1,1) -MAKE_GET(_synctex_implementation_2,2) -MAKE_GET(_synctex_implementation_3,3) -MAKE_GET(_synctex_implementation_4,4) +SYNCTEX_MAKE_GET(_synctex_implementation_0,0) +SYNCTEX_MAKE_GET(_synctex_implementation_1,1) +SYNCTEX_MAKE_GET(_synctex_implementation_2,2) +SYNCTEX_MAKE_GET(_synctex_implementation_3,3) +SYNCTEX_MAKE_GET(_synctex_implementation_4,4) synctex_node_t _synctex_new_sheet(synctex_scanner_t scanner); void _synctex_display_sheet(synctex_node_t sheet); @@ -303,18 +303,18 @@ synctex_node_t _synctex_new_sheet(synctex_scanner_t scanner) { typedef struct { synctex_class_t class; int implementation[4+3+5]; /* parent,child,sibling,friend, - * TAG,LINE,COLUMN, - * HORIZ,VERT,WIDTH,HEIGHT,DEPTH */ + * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, + * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH,SYNCTEX_HEIGHT,SYNCTEX_DEPTH */ } synctex_vert_box_node_t; -# define TAG 0 -# define LINE (TAG+1) -# define COLUMN (LINE+1) -# define HORIZ (COLUMN+1) -# define VERT (HORIZ+1) -# define WIDTH (VERT+1) -# define HEIGHT (WIDTH+1) -# define DEPTH (HEIGHT+1) +# define SYNCTEX_TAG 0 +# define SYNCTEX_LINE (SYNCTEX_TAG+1) +# define SYNCTEX_COLUMN (SYNCTEX_LINE+1) +# define SYNCTEX_HORIZ (SYNCTEX_COLUMN+1) +# define SYNCTEX_VERT (SYNCTEX_HORIZ+1) +# define SYNCTEX_WIDTH (SYNCTEX_VERT+1) +# define SYNCTEX_HEIGHT (SYNCTEX_WIDTH+1) +# define SYNCTEX_DEPTH (SYNCTEX_HEIGHT+1) synctex_node_t _synctex_new_vbox(synctex_scanner_t scanner); void _synctex_log_box(synctex_node_t sheet); @@ -349,16 +349,16 @@ synctex_node_t _synctex_new_vbox(synctex_scanner_t scanner) { typedef struct { synctex_class_t class; int implementation[4+3+5+5]; /*parent,child,sibling,friend, - * TAG,LINE,COLUMN, - * HORIZ,VERT,WIDTH,HEIGHT,DEPTH, - * HORIZ_V,VERT_V,WIDTH_V,HEIGHT_V,DEPTH_V*/ + * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, + * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH,SYNCTEX_HEIGHT,SYNCTEX_DEPTH, + * SYNCTEX_HORIZ_V,SYNCTEX_VERT_V,SYNCTEX_WIDTH_V,SYNCTEX_HEIGHT_V,SYNCTEX_DEPTH_V*/ } synctex_horiz_box_node_t; -# define HORIZ_V (DEPTH+1) -# define VERT_V (HORIZ_V+1) -# define WIDTH_V (VERT_V+1) -# define HEIGHT_V (WIDTH_V+1) -# define DEPTH_V (HEIGHT_V+1) +# define SYNCTEX_HORIZ_V (SYNCTEX_DEPTH+1) +# define SYNCTEX_VERT_V (SYNCTEX_HORIZ_V+1) +# define SYNCTEX_WIDTH_V (SYNCTEX_VERT_V+1) +# define SYNCTEX_HEIGHT_V (SYNCTEX_WIDTH_V+1) +# define SYNCTEX_DEPTH_V (SYNCTEX_HEIGHT_V+1) synctex_node_t _synctex_new_hbox(synctex_scanner_t scanner); void _synctex_display_hbox(synctex_node_t node); @@ -394,8 +394,8 @@ synctex_node_t _synctex_new_hbox(synctex_scanner_t scanner) { typedef struct { synctex_class_t class; int implementation[3+3+5]; /* parent,sibling,friend, - * TAG,LINE,COLUMN, - * HORIZ,VERT,WIDTH,HEIGHT,DEPTH*/ + * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, + * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH,SYNCTEX_HEIGHT,SYNCTEX_DEPTH*/ } synctex_void_box_node_t; synctex_node_t _synctex_new_void_vbox(synctex_scanner_t scanner); @@ -455,8 +455,8 @@ synctex_node_t _synctex_new_void_hbox(synctex_scanner_t scanner) { typedef struct { synctex_class_t class; int implementation[3+3+3]; /* parent,sibling,friend, - * TAG,LINE,COLUMN, - * HORIZ,VERT,WIDTH */ + * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, + * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH */ } synctex_medium_node_t; synctex_node_t _synctex_new_math(synctex_scanner_t scanner); @@ -538,15 +538,15 @@ synctex_node_t _synctex_new_kern(synctex_scanner_t scanner) { } /* Input nodes only know about their sibling, which is another input node. - * The synctex information is the TAG and NAME*/ + * The synctex information is the SYNCTEX_TAG and SYNCTEX_NAME*/ typedef struct { synctex_class_t class; int implementation[1+2]; /* sibling, - * TAG,NAME */ + * SYNCTEX_TAG,SYNCTEX_NAME */ } synctex_input_t; -/* The TAG previously defined is also used here */ -# define NAME 1 +/* The SYNCTEX_TAG previously defined is also used here */ +# define SYNCTEX_NAME 1 synctex_node_t _synctex_new_input(synctex_scanner_t scanner); void _synctex_display_input(synctex_node_t node); @@ -578,33 +578,33 @@ synctex_node_t _synctex_new_input(synctex_scanner_t scanner) { #pragma mark Navigation synctex_node_t synctex_node_parent(synctex_node_t node) { - return PARENT(node); + return SYNCTEX_PARENT(node); } synctex_node_t synctex_node_sheet(synctex_node_t node) { while(node && node->class->type != synctex_node_type_sheet) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } /* exit the while loop either when node is NULL or node is a sheet */ return node; } synctex_node_t synctex_node_child(synctex_node_t node) { - return CHILD(node); + return SYNCTEX_CHILD(node); } synctex_node_t synctex_node_sibling(synctex_node_t node) { - return SIBLING(node); + return SYNCTEX_SIBLING(node); } synctex_node_t synctex_node_next(synctex_node_t node) { - if(CHILD(node)) { - return CHILD(node); + if(SYNCTEX_CHILD(node)) { + return SYNCTEX_CHILD(node); } sibling: - if(SIBLING(node)) { - return SIBLING(node); + if(SYNCTEX_SIBLING(node)) { + return SYNCTEX_SIBLING(node); } - if(node = PARENT(node)) { + if(node = SYNCTEX_PARENT(node)) { if(node->class->type == synctex_node_type_sheet) {/* EXC_BAD_ACCESS? */ return NULL; } @@ -631,634 +631,953 @@ static const char * isa[synctex_node_type_last] = } # pragma mark - -# pragma mark LOG +# pragma mark SYNCTEX_LOG -# define LOG(NODE) MSG_SEND(NODE,log) +# define SYNCTEX_LOG(NODE) SYNCTEX_MSG_SEND(NODE,log) /* Public node logger */ void synctex_node_log(synctex_node_t node) { - LOG(node); + SYNCTEX_LOG(node); } void _synctex_log_sheet(synctex_node_t sheet) { if(sheet) { - printf("%s:%i\n",synctex_node_isa(sheet),INFO(sheet)[PAGE]); + printf("%s:%i\n",synctex_node_isa(sheet),SYNCTEX_INFO(sheet)[PAGE]); printf("SELF:0x%x",sheet); - printf(" PARENT:0x%x",PARENT(sheet)); - printf(" CHILD:0x%x",CHILD(sheet)); - printf(" SIBLING:0x%x",SIBLING(sheet)); - printf(" FRIEND:0x%x\n",FRIEND(sheet)); + printf(" SYNCTEX_PARENT:0x%x",SYNCTEX_PARENT(sheet)); + printf(" SYNCTEX_CHILD:0x%x",SYNCTEX_CHILD(sheet)); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(sheet)); + printf(" SYNCTEX_FRIEND:0x%x\n",SYNCTEX_FRIEND(sheet)); } } void _synctex_log_medium_node(synctex_node_t node) { printf("%s:%i,%i:%i,%i:%i\n", synctex_node_isa(node), - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH]); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH]); printf("SELF:0x%x",node); - printf(" PARENT:0x%x",PARENT(node)); - printf(" CHILD:0x%x",CHILD(node)); - printf(" SIBLING:0x%x",SIBLING(node)); - printf(" FRIEND:0x%x\n",FRIEND(node)); + printf(" SYNCTEX_PARENT:0x%x",SYNCTEX_PARENT(node)); + printf(" SYNCTEX_CHILD:0x%x",SYNCTEX_CHILD(node)); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(node)); + printf(" SYNCTEX_FRIEND:0x%x\n",SYNCTEX_FRIEND(node)); } void _synctex_log_void_box(synctex_node_t node) { - int * info = INFO(node); + int * info = SYNCTEX_INFO(node); printf("%s",synctex_node_isa(node)); - printf(":%i",info[TAG]); - printf(",%i",info[LINE]); + printf(":%i",info[SYNCTEX_TAG]); + printf(",%i",info[SYNCTEX_LINE]); printf(",%i",0); - printf(":%i",info[HORIZ]); - printf(",%i",info[VERT]); - printf(":%i",info[WIDTH]); - printf(",%i",info[HEIGHT]); - printf(",%i",info[DEPTH]); + printf(":%i",info[SYNCTEX_HORIZ]); + printf(",%i",info[SYNCTEX_VERT]); + printf(":%i",info[SYNCTEX_WIDTH]); + printf(",%i",info[SYNCTEX_HEIGHT]); + printf(",%i",info[SYNCTEX_DEPTH]); printf("\nSELF:0x%x",node); - printf(" PARENT:0x%x",PARENT(node)); - printf(" CHILD:0x%x",CHILD(node)); - printf(" SIBLING:0x%x",SIBLING(node)); - printf(" FRIEND:0x%x\n",FRIEND(node)); + printf(" SYNCTEX_PARENT:0x%x",SYNCTEX_PARENT(node)); + printf(" SYNCTEX_CHILD:0x%x",SYNCTEX_CHILD(node)); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(node)); + printf(" SYNCTEX_FRIEND:0x%x\n",SYNCTEX_FRIEND(node)); } void _synctex_log_box(synctex_node_t node) { - int * info = INFO(node); + int * info = SYNCTEX_INFO(node); printf("%s",synctex_node_isa(node)); - printf(":%i",info[TAG]); - printf(",%i",info[LINE]); + printf(":%i",info[SYNCTEX_TAG]); + printf(",%i",info[SYNCTEX_LINE]); printf(",%i",0); - printf(":%i",info[HORIZ]); - printf(",%i",info[VERT]); - printf(":%i",info[WIDTH]); - printf(",%i",info[HEIGHT]); - printf(",%i",info[DEPTH]); + printf(":%i",info[SYNCTEX_HORIZ]); + printf(",%i",info[SYNCTEX_VERT]); + printf(":%i",info[SYNCTEX_WIDTH]); + printf(",%i",info[SYNCTEX_HEIGHT]); + printf(",%i",info[SYNCTEX_DEPTH]); printf("\nSELF:0x%x",node); - printf(" PARENT:0x%x",PARENT(node)); - printf(" CHILD:0x%x",CHILD(node)); - printf(" SIBLING:0x%x",SIBLING(node)); - printf(" FRIEND:0x%x\n",FRIEND(node)); + printf(" SYNCTEX_PARENT:0x%x",SYNCTEX_PARENT(node)); + printf(" SYNCTEX_CHILD:0x%x",SYNCTEX_CHILD(node)); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(node)); + printf(" SYNCTEX_FRIEND:0x%x\n",SYNCTEX_FRIEND(node)); } void _synctex_log_horiz_box(synctex_node_t node) { - int * info = INFO(node); + int * info = SYNCTEX_INFO(node); printf("%s",synctex_node_isa(node)); - printf(":%i",info[TAG]); - printf(",%i",info[LINE]); + printf(":%i",info[SYNCTEX_TAG]); + printf(",%i",info[SYNCTEX_LINE]); printf(",%i",0); - printf(":%i",info[HORIZ]); - printf(",%i",info[VERT]); - printf(":%i",info[WIDTH]); - printf(",%i",info[HEIGHT]); - printf(",%i",info[DEPTH]); - printf(":%i",info[HORIZ_V]); - printf(",%i",info[VERT_V]); - printf(":%i",info[WIDTH_V]); - printf(",%i",info[HEIGHT_V]); - printf(",%i",info[DEPTH_V]); + printf(":%i",info[SYNCTEX_HORIZ]); + printf(",%i",info[SYNCTEX_VERT]); + printf(":%i",info[SYNCTEX_WIDTH]); + printf(",%i",info[SYNCTEX_HEIGHT]); + printf(",%i",info[SYNCTEX_DEPTH]); + printf(":%i",info[SYNCTEX_HORIZ_V]); + printf(",%i",info[SYNCTEX_VERT_V]); + printf(":%i",info[SYNCTEX_WIDTH_V]); + printf(",%i",info[SYNCTEX_HEIGHT_V]); + printf(",%i",info[SYNCTEX_DEPTH_V]); printf("\nSELF:0x%x",node); - printf(" PARENT:0x%x",PARENT(node)); - printf(" CHILD:0x%x",CHILD(node)); - printf(" SIBLING:0x%x",SIBLING(node)); - printf(" FRIEND:0x%x\n",FRIEND(node)); + printf(" SYNCTEX_PARENT:0x%x",SYNCTEX_PARENT(node)); + printf(" SYNCTEX_CHILD:0x%x",SYNCTEX_CHILD(node)); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(node)); + printf(" SYNCTEX_FRIEND:0x%x\n",SYNCTEX_FRIEND(node)); } void _synctex_log_input(synctex_node_t node) { - int * info = INFO(node); + int * info = SYNCTEX_INFO(node); printf("%s",synctex_node_isa(node)); - printf(":%i",info[TAG]); - printf(",%s",info[NAME]); - printf(" SIBLING:0x%x",SIBLING(node)); + printf(":%i",info[SYNCTEX_TAG]); + printf(",%s",info[SYNCTEX_NAME]); + printf(" SYNCTEX_SIBLING:0x%x",SYNCTEX_SIBLING(node)); } -# define DISPLAY(NODE) MSG_SEND(NODE,display) +# define SYNCTEX_DISPLAY(NODE) SYNCTEX_MSG_SEND(NODE,display) void _synctex_display_sheet(synctex_node_t sheet) { if(sheet) { - printf("....{%i\n",INFO(sheet)[PAGE]); - DISPLAY(CHILD(sheet)); + printf("....{%i\n",SYNCTEX_INFO(sheet)[PAGE]); + SYNCTEX_DISPLAY(SYNCTEX_CHILD(sheet)); printf("....}\n"); - DISPLAY(SIBLING(sheet)); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(sheet)); } } void _synctex_display_vbox(synctex_node_t node) { printf("....[%i,%i:%i,%i:%i,%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH], - INFO(node)[HEIGHT], - INFO(node)[DEPTH]); - DISPLAY(CHILD(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH], + SYNCTEX_INFO(node)[SYNCTEX_HEIGHT], + SYNCTEX_INFO(node)[SYNCTEX_DEPTH]); + SYNCTEX_DISPLAY(SYNCTEX_CHILD(node)); printf("....]\n"); - DISPLAY(SIBLING(node)); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_hbox(synctex_node_t node) { printf("....(%i,%i:%i,%i:%i,%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH], - INFO(node)[HEIGHT], - INFO(node)[DEPTH]); - DISPLAY(CHILD(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH], + SYNCTEX_INFO(node)[SYNCTEX_HEIGHT], + SYNCTEX_INFO(node)[SYNCTEX_DEPTH]); + SYNCTEX_DISPLAY(SYNCTEX_CHILD(node)); printf("....)\n"); - DISPLAY(SIBLING(node)); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_void_vbox(synctex_node_t node) { printf("....v%i,%i;%i,%i:%i,%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH], - INFO(node)[HEIGHT], - INFO(node)[DEPTH]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH], + SYNCTEX_INFO(node)[SYNCTEX_HEIGHT], + SYNCTEX_INFO(node)[SYNCTEX_DEPTH]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_void_hbox(synctex_node_t node) { printf("....h%i,%i:%i,%i:%i,%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH], - INFO(node)[HEIGHT], - INFO(node)[DEPTH]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH], + SYNCTEX_INFO(node)[SYNCTEX_HEIGHT], + SYNCTEX_INFO(node)[SYNCTEX_DEPTH]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_glue(synctex_node_t node) { printf("....glue:%i,%i:%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_math(synctex_node_t node) { printf("....math:%i,%i:%i,%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_kern(synctex_node_t node) { printf("....kern:%i,%i:%i,%i:%i\n", - INFO(node)[TAG], - INFO(node)[LINE], - INFO(node)[HORIZ], - INFO(node)[VERT], - INFO(node)[WIDTH]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE], + SYNCTEX_INFO(node)[SYNCTEX_HORIZ], + SYNCTEX_INFO(node)[SYNCTEX_VERT], + SYNCTEX_INFO(node)[SYNCTEX_WIDTH]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } void _synctex_display_input(synctex_node_t node) { printf("....Input:%i:%s\n", - INFO(node)[TAG], - INFO(node)[NAME]); - DISPLAY(SIBLING(node)); + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_NAME]); + SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } # pragma mark - # pragma mark SCANNER -#define SYNCTEX_NOERR 0 +/* Here are gathered all the possible status that the next scanning functions will return. + * All these functions return a status, and pass their result through pointers. + * Negative values correspond to errors. + * The management of the buffer is causing some significant overhead. + * Every function that may access the buffer returns a status related to the buffer and file state. + * status >= SYNCTEX_STATUS_OK means the function worked as expected + * status < SYNCTEX_STATUS_OK means the function did not work as expected + * status == SYNCTEX_STATUS_NOT_OK means the function did not work as expected but there is still some material to parse. + * status == SYNCTEX_STATUS_EOF means the function did not work as expected and there is no more material. + * statusfile + +/* Actually, the minimum buffer size is driven by integer and float parsing. + * ±0.123456789e123 + */ +# define SYNCTEX_BUFFER_MIN_SIZE 16 +# define SYNCTEX_BUFFER_SIZE 32768 -#define F scanner->file -#define SYNCTEX_BUF_SIZE 32768 +#include + +static int inline _synctex_error(char * reason,...) { + va_list arg; + int result; + result = printf("SyncTeX ERROR: "); + va_start (arg, reason); + result += vfprintf(stdout, reason, arg); + va_end (arg); + result = printf("\n"); + return result; +} -/* Ensures that the buffer contains at least size bytes. +/* Try to ensure that the buffer contains at least size bytes. * Passing a negative size argument means the whole buffer length. - * The return value is the number of bytes now available in the buffer. - * -1 is returned in case of error. */ -int _synctex_fill_buffer_up_to_size(synctex_scanner_t scanner, int size) { - int count = END - PTR; /* count is the number of unparsed chars in the buffer */ - if(size<0) { - size = SYNCTEX_BUF_SIZE; - } - if(size<=count) { - return count; - } - if(F) { + * Passing a null size argument means return the available buffer length, without reading the file. + * In that case, the return status is always SYNCTEX_STATUS_OK unless the given scanner is NULL, + * in which case, SYNCTEX_STATUS_BAD_ARGUMENT is returned. + * The value returned in size_ptr is the number of bytes now available in the buffer. + * This is a nonnegative integer, it may take the value 0. + * It is the responsibility of the caller to test whether this size is conforming to its needs. + * Negative values may returned in case of error, actually + * when there was an error reading the synctex file. */ +synctex_status_t _synctex_buffer_get_available_size(synctex_scanner_t scanner, size_t * size_ptr) { + int available = 0; + if(NULL == scanner || NULL == size_ptr) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } +# define size (* size_ptr) + if((size<0) || (size>SYNCTEX_BUFFER_SIZE)){ + size = SYNCTEX_BUFFER_SIZE; + } + available = SYNCTEX_END - SYNCTEX_CUR; /* available is the number of unparsed chars in the buffer */ + if(size<=available) { + /* There are already sufficiently many characters in the buffer */ + size = available; + return SYNCTEX_STATUS_OK; + } + if(SYNCTEX_FILE) { /* Copy the remaining part of the buffer to the beginning, * then read the next part of the file */ int read = 0; - if(count) { - memmove(START, PTR, count); + if(available) { + memmove(SYNCTEX_START, SYNCTEX_CUR, available); } - PTR = START + count; /* the next character after the move, will change. */ + SYNCTEX_CUR = SYNCTEX_START + available; /* the next character after the move, will change. */ /* Fill the buffer up to its end */ - read = gzread(F,(void *)PTR,SYNCTEX_BUF_SIZE - count); + read = gzread(SYNCTEX_FILE,(void *)SYNCTEX_CUR,SYNCTEX_BUFFER_SIZE - available); if(read>0) { - END = PTR + read; - PTR = START; - if(SYNCTEX_BUF_SIZE==size || size<=END-PTR) { - return END - PTR; - } - return -1; + /* We assume that 0 0) - return END - PTR; - /* There was nothing left in the file */ - return -1; + /* We cannot enlarge the buffer because the end of the file was reached. */ + size = available; + return SYNCTEX_STATUS_EOF; +# undef size } /* Used when parsing the synctex file. * Advance to the next character starting a line. - * Actually, only \n is recognized as end of line marker. */ -int _synctex_next_line(synctex_scanner_t scanner) { + * Actually, only '\n' is recognized as end of line marker. + * On normal completion, the returned value is the number of unparsed characters available in the buffer. + * In general, it is a positive value, 0 meaning that the end of file was reached. + * -1 is returned in case of error, actually because there was an error while feeding the buffer. + * When the function returns with no error, SYNCTEX_CUR points to the first character of the next line, if any. + * J. Laurens: Sat May 10 07:52:31 UTC 2008 + */ +synctex_status_t _synctex_next_line(synctex_scanner_t scanner) { + synctex_status_t status = SYNCTEX_STATUS_OK; + size_t available = 0; if(NULL == scanner) { - return -1; - } - do { - while(PTR=remaining_len) { + /* The buffer is sufficiently big to hold the expected number of characters. */ + if(strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) { + return SYNCTEX_STATUS_NOT_OK; + } +return_OK: + /* Advance SYNCTEX_CUR to the next character after the_string. */ + SYNCTEX_CUR += remaining_len; + return SYNCTEX_STATUS_OK; + } else if(strncmp((char *)SYNCTEX_CUR,the_string,available)) { + /* No need to goo further, this is not the expected string in the buffer. */ + return SYNCTEX_STATUS_NOT_OK; + } else if(SYNCTEX_FILE) { + /* The buffer was too small to contain remaining_len characters. + * We have to cut the string into pieces. */ + z_off_t offset = 0L; + /* the first part of the string is found, advance the_string to the next untested character. */ + the_string += available; + /* update the remaining length and the parsed length. */ + remaining_len -= available; + tested_len += available; + SYNCTEX_CUR += available; /* We validate the tested characters. */ + if(0 == remaining_len) { + /* Nothing left to test, we have found the given string, we return the length. */ + return tested_len; + } + /* We also have to record the current state of the file cursor because + * if the_string does not match, all this should be a totally blank operation, + * for which the file and buffer states should not be modified at all. + * In fact, the states of the buffer before and after this function are in general different + * but they are totally equivalent as long as the values of the buffer before SYNCTEX_CUR + * can be safely discarded. */ + offset = gztell(SYNCTEX_FILE); + /* offset now corresponds to the first character of the file that was not buffered. */ + available = SYNCTEX_CUR - SYNCTEX_START; /* available can be used as temporary placeholder. */ + /* available now corresponds to the number of chars that where already buffered and + * that match the head of the_string. If in fine the_string does not match, all these chars must be recovered + * because the buffer contents is completely replaced by _synctex_buffer_get_available_size. + * They were buffered from offset-len location in the file. */ + offset -= available; +more_characters: + /* There is still some work to be done, so read another bunch of file. + * This is the second call to _synctex_buffer_get_available_size, + * which means that the actual contents of the buffer will be discarded. + * We will definitely have to recover the previous state in case we do not find the expected string. */ + available = remaining_len; + status = _synctex_buffer_get_available_size(scanner,&available); + if(status0); - return 1; + /* This is the last step. */ + if(strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) { + /* This is not the expected string, recover the previous state and return. */ + goto return_NOT_OK; + } + goto return_OK; + } else { + /* The buffer can't contain the given string argument, and the EOF was reached */ + return SYNCTEX_STATUS_EOF; + } } /* Used when parsing the synctex file. * Decode an integer. - * First file separators are skipped + * First, field separators, namely ':' and ',' characters are skipped + * The returned value is -1 if there is an unrecoverable error. + * It is 0 if an integer could not be parsed, for example + * if the characters at the current cursor position are not digits or + * if the end of the file has been reached. + * It is SYNCTEX_STATUS_OK if an int has been successfully parsed. + * The given scanner argument must not be NULL, on the contrary, value_ref may be NULL. */ -int _synctex_decode_int(synctex_scanner_t scanner, int* valueRef) { - unsigned char * ptr; +synctex_status_t _synctex_decode_int(synctex_scanner_t scanner, int* value_ref) { + unsigned char * ptr = NULL; unsigned char * end = NULL; int result = 0; - if(NULL == scanner) return -1; - if(END-PTR<=15) { - _synctex_fill_buffer_up_to_size(scanner, -1); + size_t available = 0; + synctex_status_t status = 0; + if(NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + available = SYNCTEX_BUFFER_MIN_SIZE; + status = _synctex_buffer_get_available_size(scanner, &available); + if(status=END) return -1; + ptr = SYNCTEX_CUR; if(*ptr==':' || *ptr==',') { ++ptr; + --available; + if(available==0) { + return SYNCTEX_STATUS_NOT_OK;/* It is not possible to scan an int */ + } } result = (int)strtol((char *)ptr, (char **)&end, 10); if(end>ptr) { - PTR = end; - if(valueRef) { - * valueRef = result; + SYNCTEX_CUR = end; + if(value_ref) { + * value_ref = result; } - return 0; - } - return -1; -} - -int _synctex_decode_string(synctex_scanner_t scanner, char ** valueRef) { - unsigned char * end = PTR; + return SYNCTEX_STATUS_OK;/* Successfully scanned an int */ + } + return SYNCTEX_STATUS_NOT_OK;/* Could not scan an int */ +} + +/* The purpose of this function is to read a string. + * A string is an array of characters from the current parser location + * and before the next '\n' character. + * If a string was properly decoded, it is returned in value_ref and + * the cursor points to the new line marker. + * The returned string was alloced on the heap, the caller is the owner and + * is responsible to free it in due time. + * If no string is parsed, * value_ref is undefined. + * The maximum length of a string that a scanner can decode is platform dependent, namely UINT_MAX. + * If you just want to blindly parse the file up to the end of the current line, + * use _synctex_next_line instead. + * On return, the scanner cursor is unchanged if a string could not be scanned or + * points to the terminating '\n' character otherwise. As a consequence, + * _synctex_next_line is necessary after. + * If either scanner or value_ref is NULL, it is considered as an error and + * SYNCTEX_STATUS_BAD_ARGUMENT is returned. + */ +synctex_status_t _synctex_decode_string(synctex_scanner_t scanner, char ** value_ref) { + unsigned char * end = NULL; size_t current_size = 0; + size_t new_size = 0; size_t len = 0;/* The number of bytes to copy */ - if(NULL == scanner || NULL == valueRef) return -1; - if(PTR>=END) return -1; - /* We scan all the characters up to the next '\n' - * There is a problem with the buffer. */ + size_t available = 0; + synctex_status_t status = 0; + if(NULL == scanner || NULL == value_ref) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + /* The buffer must at least contain one character: the '\n' end of line marker */ + if(SYNCTEX_CUR>=SYNCTEX_END) { + available = 1; + status = _synctex_buffer_get_available_size(scanner,&available); + if(status < 0) { + return status; + } + if(0 == available) { + return SYNCTEX_STATUS_EOF; + } + } + /* Now we are sure that there is at least one available character, either because + * SYNCTEX_CUR was already < SYNCTEX_END, or because the buffer has been properly filled. */ + /* end will point to the next unparsed '\n' character in the file, when mapped to the buffer. */ + end = SYNCTEX_CUR; + * value_ref = NULL;/* Initialize, it will be realloc'ed */ + /* We scan all the characters up to the next '\n' */ next_character: - if(endUINT_MAX-len-1) { + /* But we have reached the limit: we do not have current_size+len+1>UINT_MAX. + * We return the missing amount of memory. + * This will never occur in practice. */ + return UINT_MAX-len-1 - current_size; + } + new_size = current_size+len; + /* We have current_size+len+1<=UINT_MAX + * or equivalently new_size0) { - end = PTR; - goto next_character; - } else { - return 0; - } + /* end == SYNCTEX_END */ + len = SYNCTEX_END - SYNCTEX_CUR; + if(current_size>UINT_MAX-len-1) { + /* We have reached the limit. */ + _synctex_error("limit reached (missing %i).",current_size-(UINT_MAX-len-1)); + return SYNCTEX_STATUS_ERROR; + } + new_size = current_size+len; + if(* value_ref = realloc(* value_ref,new_size+1)) { + if(memcpy((*value_ref)+current_size,SYNCTEX_CUR,len)) { + (* value_ref)[new_size]='\0'; /* Terminate the string */ + SYNCTEX_CUR = SYNCTEX_END;/* Advance the cursor to the end of the bufer */ + return SYNCTEX_STATUS_OK; } - free(* valueRef); - * valueRef = NULL; - return -1; + free(* value_ref); + * value_ref = NULL; + _synctex_error("could not copy memory (2)."); + return SYNCTEX_STATUS_ERROR; } /* Huge memory problem */ - PTR += len; - return -1; + _synctex_error("could not allocate memory (2)."); + return SYNCTEX_STATUS_ERROR; } } /* Used when parsing the synctex file. * Read an Input record. */ -int _synctex_scan_input(synctex_scanner_t scanner) { +synctex_status_t _synctex_scan_input(synctex_scanner_t scanner) { + synctex_status_t status = 0; + size_t available = 0; + synctex_node_t input = NULL; if(NULL == scanner) { - return -1; - } - if(0 == _synctex_scan_string(scanner,"Input:")) { - synctex_node_t input = _synctex_new_input(scanner); - if(_synctex_decode_int(scanner,INFO(input)+TAG) - || (++PTR,_synctex_decode_string(scanner,(char **)(INFO(input)+NAME))) - || _synctex_next_line(scanner)) { - FREE(input); - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + status = _synctex_match_string(scanner,"Input:"); + if(statusinput); + scanner->input = input; + return _synctex_next_line(scanner);/* read the line termination character, if any */ +} + +typedef synctex_status_t (*synctex_decoder_t)(synctex_scanner_t,void *); + +/* Used when parsing the synctex file. + * Read one of the settings. + * On normal completion, returns SYNCTEX_STATUS_OK. + * On error, returns SYNCTEX_STATUS_ERROR. + * Both arguments must not be NULL. + * On return, the scanner points to the next character after the decoded object whatever it is. + * It is the responsibility of the caller to prepare the scanner for the next line. + */ +synctex_status_t _synctex_scan_named(synctex_scanner_t scanner,char * name,void * value_ref,synctex_decoder_t decoder) { + synctex_status_t status = 0; + if(NULL == scanner || NULL == name || NULL == value_ref || NULL == decoder) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } +not_found: + status = _synctex_match_string(scanner,name); + if(statusinput) - scanner->input = input; - return 0; + goto not_found; } - return 1; + /* A line is found, scan the value */ + return (*decoder)(scanner,value_ref); } /* Used when parsing the synctex file. - * Read the settings as part of the preamble. + * Read the preamble. */ -int _synctex_scan_settings(synctex_scanner_t scanner) { +synctex_status_t _synctex_scan_preamble(synctex_scanner_t scanner) { + synctex_status_t status = 0; if(NULL == scanner) { - return -1; - } - while(_synctex_scan_string(scanner,"Output:")) { - if(_synctex_next_line(scanner)) { - return -1; - } - } - if(_synctex_decode_string(scanner,&(scanner->output)) - || _synctex_next_line(scanner)) { - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; } - while(_synctex_scan_string(scanner,"Magnification:")) { - if(_synctex_next_line(scanner)) { - return -1; - } + status = _synctex_scan_named(scanner,"SyncTeX Version:",&(scanner->version),(synctex_decoder_t)&_synctex_decode_int); + if(statuspre_magnification)) - || _synctex_next_line(scanner)) { - return -1; + status = _synctex_next_line(scanner); + if(statusoutput),(synctex_decoder_t)&_synctex_decode_string); + if(statuspre_unit)) - || _synctex_next_line(scanner)) { - return -1; + status = _synctex_next_line(scanner); + if(statuspre_magnification),(synctex_decoder_t)&_synctex_decode_int); + if(statuspre_x_offset)) - || _synctex_next_line(scanner)) { - return -1; + status = _synctex_next_line(scanner); + if(statuspre_unit),(synctex_decoder_t)&_synctex_decode_int); + if(statuspre_y_offset)) - || _synctex_next_line(scanner)) { - return -1; + status = _synctex_next_line(scanner); + if(statuspre_x_offset),(synctex_decoder_t)&_synctex_decode_int); + if(statusEND-PTR) { - return -1; + status = _synctex_next_line(scanner); + if(statuspre_y_offset),(synctex_decoder_t)&_synctex_decode_int); + if(statusversion)) - || _synctex_next_line(scanner)) { - printf("SyncTeX Error: Missing version\n"); - return -1; - } - while(SYNCTEX_NOERR == _synctex_scan_input(scanner)) { - } - return _synctex_scan_settings(scanner); -} - -/* parse the post scriptum */ +/* parse a float with a dimension */ #include "xlocale.h" -int _synctex_scan_post_scriptum(synctex_scanner_t scanner) { - int status = 0; - while(_synctex_scan_string(scanner,"Post scriptum:")) { - if(_synctex_next_line(scanner)) { - return -1; +synctex_status_t _synctex_scan_float_and_dimension(synctex_scanner_t scanner, float * value_ref) { + synctex_status_t status = 0; + unsigned char * endptr = NULL; + float f = 0; + size_t available = 0; + if(NULL == scanner || NULL == value_ref) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + available = SYNCTEX_BUFFER_MIN_SIZE; + status = _synctex_buffer_get_available_size(scanner, &available); + if(status= SYNCTEX_STATUS_OK) { + f *= 72.27*65536; + } else if(status= SYNCTEX_STATUS_OK) { + f *= 72.27*65536/2.54; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"mm")) >= SYNCTEX_STATUS_OK) { + f *= 72.27*65536/25.4; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"pt")) >= SYNCTEX_STATUS_OK) { + f *= 65536.0; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"bp")) >= SYNCTEX_STATUS_OK) { + f *= 72.27/72*65536; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"pc")) >= SYNCTEX_STATUS_OK) { + f *= 12.0*65536; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"sp")) >= SYNCTEX_STATUS_OK) { + f *= 1.0; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"dd")) >= SYNCTEX_STATUS_OK) { + f *= 1238.0/1157*65536; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"cc")) >= SYNCTEX_STATUS_OK) { + f *= 14856.0/1157*65536; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"nd")) >= SYNCTEX_STATUS_OK) { + f *= 685.0/642*65536; + } else if(status<0) { + goto report_unit_error; + } else if((status = _synctex_match_string(scanner,"nc")) >= SYNCTEX_STATUS_OK) { + f *= 1370.0/107*65536; + } else if(status<0) { + goto report_unit_error; + } + *value_ref = f; + return SYNCTEX_STATUS_OK; +} + +/* parse the post scriptum + * SYNCTEX_STATUS_OK is returned on completion + * a negative error is returned otherwise */ +synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_t scanner) { + synctex_status_t status = 0; + unsigned char * endptr = NULL; + if(NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + /* Scan the file until a post scriptum line is found */ +post_scriptum_not_found: + status = _synctex_match_string(scanner,"Post scriptum:"); + if(statusx_offset = 6.027e23; - scanner->y_offset = scanner->x_offset; /* By default, all "*_l" functions are used with a C locale. */ next_record: - if(0 == _synctex_scan_string(scanner,"Magnification:")) { - if(PTRunit = strtof_l((char *)PTR,(char **)&PTR,NULL); -next_line: - status = _synctex_next_line(scanner); - if(status<0) { - return -1; - } else if(0 == status) { - goto next_record; - } + status = _synctex_match_string(scanner,"Magnification:"); + if(status == SYNCTEX_STATUS_OK ) { + scanner->unit = strtof_l((char *)SYNCTEX_CUR,(char **)&endptr,NULL); + if(endptr == SYNCTEX_CUR) { + _synctex_error("bad magnification in the post scriptum, a float was expected."); + return SYNCTEX_STATUS_ERROR; } - return 0; - } else if(0 == _synctex_scan_string(scanner,"X Offset:")) { - if(PTRPTR) { - /* scan the x offset */ - /* 72/72.27/65536*16384+0.5; */ - PTR = end; - if(_synctex_scan_string(scanner,"in") == 0) { - f *= 72.27*65536; - } - else if(_synctex_scan_string(scanner,"cm") == 0) { - f *= 72.27*65536/2.54; - } - else if(_synctex_scan_string(scanner,"mm") == 0) { - f *= 72.27*65536/25.4; - } - else if(_synctex_scan_string(scanner,"pt") == 0) { - f *= 65536.0; - } - else if(_synctex_scan_string(scanner,"bp") == 0) { - f *= 72.27/72*65536; - } - else if(_synctex_scan_string(scanner,"pc") == 0) { - f *= 12.0*65536; - } - else if(_synctex_scan_string(scanner,"sp") == 0) { - f *= 1.0; - } - else if(_synctex_scan_string(scanner,"dd") == 0) { - f *= 1238.0/1157*65536; - } - else if(_synctex_scan_string(scanner,"cc") == 0) { - f *= 14856.0/1157*65536; - } - else if(_synctex_scan_string(scanner,"nd") == 0) { - f *= 685.0/642*65536; - } - else if(_synctex_scan_string(scanner,"nc") == 0) { - f *= 1370.0/107*65536; - } - else { - f *= 1.0; - PTR -= 2; - } - scanner->x_offset = f; - } - goto next_line; + if(scanner->unit<=0) { + _synctex_error("bad magnification in the post scriptum, a positive float was expected."); + return SYNCTEX_STATUS_ERROR; } - return 0; - } else if(0 == _synctex_scan_string(scanner,"Y Offset:")) { - if(PTRPTR) { - /* scan the x offset */ - /* 72/72.27/65536*16384+0.5; */ - PTR = end; - if(_synctex_scan_string(scanner,"in") == 0) { - f *= 72.27*65536; - } - else if(_synctex_scan_string(scanner,"cm") == 0) { - f *= 72.27*65536/2.54; - } - else if(_synctex_scan_string(scanner,"mm") == 0) { - f *= 72.27*65536/25.4; - } - else if(_synctex_scan_string(scanner,"pt") == 0) { - f *= 65536.0; - } - else if(_synctex_scan_string(scanner,"bp") == 0) { - f *= 72.27/72*65536; - } - else if(_synctex_scan_string(scanner,"pc") == 0) { - f *= 12.0*65536; - } - else if(_synctex_scan_string(scanner,"sp") == 0) { - f *= 1.0; - } - else if(_synctex_scan_string(scanner,"dd") == 0) { - f *= 1238.0/1157*65536; - } - else if(_synctex_scan_string(scanner,"cc") == 0) { - f *= 14856.0/1157*65536; - } - else if(_synctex_scan_string(scanner,"nd") == 0) { - f *= 685.0/642*65536; - } - else if(_synctex_scan_string(scanner,"nc") == 0) { - f *= 1370.0/107*65536; - } - else { - f *= 1.0; - PTR -= 2; - } - scanner->y_offset = f; - } - goto next_line; + SYNCTEX_CUR = endptr; + goto next_line; + } + if(statusx_offset)); + if(statusy_offset)); + if(statuscount)) - || _synctex_next_line(scanner)) { - return -1; - } - } - while(_synctex_scan_post_scriptum(scanner)) { - if(_synctex_next_line(scanner)) { - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + status = _synctex_match_string(scanner,"Postamble:"); + if(status < SYNCTEX_STATUS_OK) { + return status; + } +count_again: + status = _synctex_next_line(scanner); + if(status < SYNCTEX_STATUS_OK) { + return status; + } + status = _synctex_scan_named(scanner,"Count:",&(scanner->count),(synctex_decoder_t)&_synctex_decode_int); + if(status < SYNCTEX_STATUS_EOF) { + return status; /* forward the error */ + } else if(status < SYNCTEX_STATUS_OK) { /* No Count record found */ + status = _synctex_next_line(scanner); /* Advance one more line */ + if(statusclass->type != synctex_node_type_hbox) { - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; } - info = INFO(box); + info = SYNCTEX_INFO(box); if(info) { - info[HORIZ_V] = info[HORIZ]; - info[VERT_V] = info[VERT]; - info[WIDTH_V] = info[WIDTH]; - info[HEIGHT_V] = info[HEIGHT]; - info[DEPTH_V] = info[DEPTH]; - return 0; + info[SYNCTEX_HORIZ_V] = info[SYNCTEX_HORIZ]; + info[SYNCTEX_VERT_V] = info[SYNCTEX_VERT]; + info[SYNCTEX_WIDTH_V] = info[SYNCTEX_WIDTH]; + info[SYNCTEX_HEIGHT_V] = info[SYNCTEX_HEIGHT]; + info[SYNCTEX_DEPTH_V] = info[SYNCTEX_DEPTH]; + return SYNCTEX_STATUS_OK; } - return -1; + return SYNCTEX_STATUS_ERROR; } /* This method is sent to an horizontal box to setup the visible size * Some box have 0 width but do contain text material. * With this method, one can enlarge the box to contain the given point (h,v). */ -int _synctex_horiz_box_setup_visible(synctex_node_t node,int h, int v) { +synctex_status_t _synctex_horiz_box_setup_visible(synctex_node_t node,int h, int v) { int * itsINFO = NULL; int itsBtm, itsTop; if(NULL == node || node->class->type != synctex_node_type_hbox) { - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; } - itsINFO = INFO(node); - if(itsINFO[WIDTH_V]<0) { - itsBtm = itsINFO[HORIZ_V]+itsINFO[WIDTH_V]; - itsTop = itsINFO[HORIZ_V]; + itsINFO = SYNCTEX_INFO(node); + if(itsINFO[SYNCTEX_WIDTH_V]<0) { + itsBtm = itsINFO[SYNCTEX_HORIZ_V]+itsINFO[SYNCTEX_WIDTH_V]; + itsTop = itsINFO[SYNCTEX_HORIZ_V]; if(hitsTop) { h -= itsTop; - itsINFO[WIDTH_V] -= h; - itsINFO[HORIZ_V] += h; + itsINFO[SYNCTEX_WIDTH_V] -= h; + itsINFO[SYNCTEX_HORIZ_V] += h; } } else { - itsBtm = itsINFO[HORIZ_V]; - itsTop = itsINFO[HORIZ_V]+itsINFO[WIDTH_V]; + itsBtm = itsINFO[SYNCTEX_HORIZ_V]; + itsTop = itsINFO[SYNCTEX_HORIZ_V]+itsINFO[SYNCTEX_WIDTH_V]; if(hitsTop) { h -= itsTop; - itsINFO[WIDTH_V] += h; + itsINFO[SYNCTEX_WIDTH_V] += h; } } - return 0; + return SYNCTEX_STATUS_OK; } int synctex_bail(void); @@ -1328,550 +1647,604 @@ int synctex_bail(void); * The parent is a newly created sheet node that will hold the contents. * Something is returned in case of error. */ -int _synctex_scan_sheet(synctex_scanner_t scanner, synctex_node_t parent) { +synctex_status_t _synctex_scan_sheet(synctex_scanner_t scanner, synctex_node_t parent) { synctex_node_t child = NULL; synctex_node_t sibling = NULL; int friend_index = 0; int * info = NULL; int curh, curv; - if((NULL == scanner) || (NULL == parent))return -1; + synctex_status_t status = 0; + size_t available = 0; + if((NULL == scanner) || (NULL == parent)) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } vertical_loop: -// printf("H loop:%i\n",++loop); - if(PTRclass->type == synctex_node_type_vbox) { - #define UPDATE_BOX_FRIEND(NODE)\ - friend_index = ((INFO(NODE))[TAG]+(INFO(NODE))[LINE])%(scanner->number_of_lists);\ - SET_FRIEND(NODE,(scanner->lists_of_friends)[friend_index]);\ + #define SYNCTEX_UPDATE_BOX_FRIEND(NODE)\ + friend_index = ((SYNCTEX_INFO(NODE))[SYNCTEX_TAG]+(SYNCTEX_INFO(NODE))[SYNCTEX_LINE])%(scanner->number_of_lists);\ + SYNCTEX_SET_FRIEND(NODE,(scanner->lists_of_friends)[friend_index]);\ (scanner->lists_of_friends)[friend_index] = NODE; - if(NULL == CHILD(parent)) { + if(NULL == SYNCTEX_CHILD(parent)) { /* only void boxes are friends */ - UPDATE_BOX_FRIEND(parent); + SYNCTEX_UPDATE_BOX_FRIEND(parent); } child = parent; - parent = PARENT(child); + parent = SYNCTEX_PARENT(child); } else { - printf("SyncTeX Error: Unexpected ']', ignored.\n"); + _synctex_error("Unexpected ']', ignored."); } - if(_synctex_next_line(scanner)) { - printf("SyncTeX Error: Uncomplete sheet.\n"); - return -1; + if(_synctex_next_line(scanner)class->type == synctex_node_type_hbox) { if(NULL == child) { - UPDATE_BOX_FRIEND(parent); + SYNCTEX_UPDATE_BOX_FRIEND(parent); } child = parent; - parent = PARENT(child); + parent = SYNCTEX_PARENT(child); } else { - printf("SyncTeX Error: Unexpected ')', ignored.\n"); + _synctex_error("Unexpected ')', ignored."); } - if(_synctex_next_line(scanner)) { - printf("SyncTeX Error: Uncomplete sheet.\n"); - return -1; + if(_synctex_next_line(scanner)number_of_lists);\ - SET_FRIEND(NODE,(scanner->lists_of_friends)[friend_index]);\ + SYNCTEX_SET_CHILD(parent,child); + #define SYNCTEX_UPDATE_FRIEND(NODE)\ + friend_index = (info[SYNCTEX_TAG]+info[SYNCTEX_LINE])%(scanner->number_of_lists);\ + SYNCTEX_SET_FRIEND(NODE,(scanner->lists_of_friends)[friend_index]);\ (scanner->lists_of_friends)[friend_index] = NODE; - UPDATE_FRIEND(child); + SYNCTEX_UPDATE_FRIEND(child); goto horizontal_loop; } else { - printf("SyncTeX Error: Can't create vbox record.\n"); - return -1; + _synctex_error("Can't create vbox record."); + return SYNCTEX_STATUS_ERROR; } - } else if(*PTR == 'h') { - ++PTR; - if((child = _synctex_new_void_hbox(scanner)) && (info = INFO(child))) { - if(_synctex_decode_int(scanner,(int*)(info+TAG)) - || _synctex_decode_int(scanner,(int*)(info+LINE)) - || _synctex_decode_int(scanner,(int*)(info+HORIZ)) - || _synctex_decode_int(scanner,(int*)(info+VERT)) - || _synctex_decode_int(scanner,(int*)(info+WIDTH)) - || _synctex_decode_int(scanner,(int*)(info+HEIGHT)) - || _synctex_decode_int(scanner,(int*)(info+DEPTH)) - || _synctex_next_line(scanner)) { - printf("SyncTeX Error: Bad void hbox record.\n"); - return -1; + } else if(*SYNCTEX_CUR == 'h') { + ++SYNCTEX_CUR; + if((child = _synctex_new_void_hbox(scanner)) && (info = SYNCTEX_INFO(child))) { + if(SYNCTEX_DECODE_FAILED(SYNCTEX_TAG) + || SYNCTEX_DECODE_FAILED(SYNCTEX_LINE) + || SYNCTEX_DECODE_FAILED(SYNCTEX_HORIZ) + || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT) + || SYNCTEX_DECODE_FAILED(SYNCTEX_WIDTH) + || SYNCTEX_DECODE_FAILED(SYNCTEX_HEIGHT) + || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH) + || (_synctex_next_line(scanner)class->type != synctex_node_type_sheet - || _synctex_next_line(scanner)) { - printf("SyncTeX Error: Unexpected end of sheet.\n"); - return -1; + || (_synctex_next_line(scanner)0){ - goto vertical_loop; } else { - printf("SyncTeX Error: Uncomplete sheet(0)\n"); - return -1; + available = 1; + status = _synctex_buffer_get_available_size(scanner,&available); + if(status0){ + _synctex_error("Uncomplete sheet(0)"); + return SYNCTEX_STATUS_ERROR; + } else { + goto vertical_loop; + } } synctex_bail(); horizontal_loop: -// printf("V loop:%i\n",++loop); - if(PTRclass->type == synctex_node_type_vbox) { if(NULL == child) { - UPDATE_BOX_FRIEND(parent); + SYNCTEX_UPDATE_BOX_FRIEND(parent); } child = parent; - parent = PARENT(child); + parent = SYNCTEX_PARENT(child); } else { - printf("SyncTeX Error: Unexpected end of vbox record (2), ignored.\n"); + _synctex_error("Unexpected end of vbox record (2), ignored."); } - if(_synctex_next_line(scanner)) { - printf("SyncTeX Error: Unexpected end of file (2).\n"); - return -1; + if(_synctex_next_line(scanner)class->type == synctex_node_type_hbox) { if(NULL == child) { - UPDATE_BOX_FRIEND(parent); + SYNCTEX_UPDATE_BOX_FRIEND(parent); } child = parent; - parent = PARENT(child); + parent = SYNCTEX_PARENT(child); } else { - printf("SyncTeX Error: Unexpected end of hbox record (2).\n"); + _synctex_error("Unexpected end of hbox record (2)."); } - if(_synctex_next_line(scanner)) { - printf("SyncTeX Error: Unexpected end of file (2,')').\n"); - return -1; + if(_synctex_next_line(scanner)class->type != synctex_node_type_sheet - || _synctex_next_line(scanner)) { - printf("SyncTeX Error: Unexpected end of vbox (2).\n"); - return -1; + || (_synctex_next_line(scanner)0){ - goto horizontal_loop; } else { - printf("SyncTeX Error: Uncomplete sheet(2)\n"); - return -1; + available = 1; + status = _synctex_buffer_get_available_size(scanner,&available); + if(status0){ + goto horizontal_loop; + } else { + _synctex_error("Uncomplete sheet(2)"); + return SYNCTEX_STATUS_ERROR; + } } +# undef SYNCTEX_DECODE_FAILED } /* Used when parsing the synctex file */ -int _synctex_scan_content(synctex_scanner_t scanner) { +synctex_status_t _synctex_scan_content(synctex_scanner_t scanner) { synctex_node_t sheet = NULL; + synctex_status_t status = 0; if(NULL == scanner) { - return -1; + return SYNCTEX_STATUS_BAD_ARGUMENT; } /* set up the lists of friends */ if(NULL == scanner->lists_of_friends) { scanner->number_of_lists = 1024; scanner->lists_of_friends = (synctex_node_t *)_synctex_malloc(scanner->number_of_lists*sizeof(synctex_node_t)); if(NULL == scanner->lists_of_friends) { - printf("SyncTeX Error: malloc:2\n"); - return -1; + _synctex_error("malloc:2"); + return SYNCTEX_STATUS_ERROR; } } /* Find where this section starts */ - while(_synctex_scan_string(scanner,"Content:")) { - if(_synctex_next_line(scanner)) { - return -1; - } +content_not_found: + status = _synctex_match_string(scanner,"Content:"); + if(statussheet); + SYNCTEX_SET_SIBLING(sheet,scanner->sheet); scanner->sheet = sheet; - while(SYNCTEX_NOERR == _synctex_scan_input(scanner)) { + sheet = NULL; + /* Now read the list of Inputs between 2 sheets. */ + do { + status = _synctex_scan_input(scanner); + if(status= SYNCTEX_STATUS_OK); goto next_sheet; } /* Where the synctex scanner is created. - * name is the full path of the uncompressed synctex file. */ + * name is the full path of the uncompressed synctex file. + * On error, NULL is returned. + * This can be due to allocation error, or an internal inconsistency (bad SYNCTEX_BUFFER_SIZE). */ synctex_scanner_t synctex_scanner_new_with_contents_of_file(const char * name) { - synctex_scanner_t scanner = (synctex_scanner_t)_synctex_malloc(sizeof(_synctex_scanner_t)); - int size = 0; + synctex_scanner_t scanner = NULL; + synctex_status_t status = 0; + /* We ensure that SYNCTEX_BUFFER_SIZE < UINT_MAX */ + if(SYNCTEX_BUFFER_SIZE >= UINT_MAX) { + printf("SyncTeX BUG: Internal inconsistency, bad SYNCTEX_BUFFER_SIZE (1)"); + return NULL; + } + /* for integers: */ + if(SYNCTEX_BUFFER_SIZE < SYNCTEX_BUFFER_MIN_SIZE) { + printf("SyncTeX BUG: Internal inconsistency, bad SYNCTEX_BUFFER_SIZE (2)"); + return NULL; + } + scanner = (synctex_scanner_t)_synctex_malloc(sizeof(_synctex_scanner_t)); if(NULL == scanner) { return NULL; } scanner->pre_magnification = 1000; scanner->pre_unit = 8192; scanner->pre_x_offset = scanner->pre_y_offset = 578; + /* initialize the offset with a fake unprobable value, + * If there is a post scriptum section, this value will be overriden by the real life value */ + scanner->x_offset = scanner->y_offset = 6.027e23; scanner->class[synctex_node_type_sheet] = synctex_class_sheet; (scanner->class[synctex_node_type_sheet]).scanner = scanner; scanner->class[synctex_node_type_vbox] = synctex_class_vbox; @@ -1890,42 +2263,43 @@ synctex_scanner_t synctex_scanner_new_with_contents_of_file(const char * name) { (scanner->class[synctex_node_type_math]).scanner = scanner; scanner->class[synctex_node_type_input] = synctex_class_input; (scanner->class[synctex_node_type_input]).scanner = scanner; - F = gzopen(name,"r"); - if(NULL == F) { + SYNCTEX_FILE = gzopen(name,"r"); + if(NULL == SYNCTEX_FILE) { printf("SyncTeX: could not open %s, error %i\n",name,errno); bail: synctex_scanner_free(scanner); return NULL; } - START = (unsigned char *)malloc(SYNCTEX_BUF_SIZE+1); - if(NULL == START) { - printf("SyncTeX: malloc error\n"); - gzclose(F); + SYNCTEX_START = (unsigned char *)malloc(SYNCTEX_BUFFER_SIZE+1); /* one more character for null termination */ + if(NULL == SYNCTEX_START) { + printf("SyncTeX: malloc error"); + gzclose(SYNCTEX_FILE); goto bail; } - START[SYNCTEX_BUF_SIZE] = '\0'; - PTR = START; - END = START+SYNCTEX_BUF_SIZE; - size = gzread(F,(void *)START, SYNCTEX_BUF_SIZE); - if(!size) { - printf("SyncTeX: No gzread content\n"); + SYNCTEX_END = SYNCTEX_START+SYNCTEX_BUFFER_SIZE; + /* SYNCTEX_END always points to a null terminating character. + * Maybe there is another null terminating character between SYNCTEX_CUR and SYNCTEX_END-1. + * At least, we are sure that SYNCTEX_CUR points to a string covering a valid part of the memory. */ + * SYNCTEX_END = '\0'; + SYNCTEX_CUR = SYNCTEX_END; + status = _synctex_scan_preamble(scanner); + if(statuspre_unit)/65536 pt = (scanner->pre_unit)/65781.76 bp * 1 pt = 65536 sp */ if(scanner->pre_unit<=0) { @@ -1952,7 +2326,7 @@ bailey: scanner->y_offset /= 65781.76; } return scanner; - #undef F + #undef SYNCTEX_FILE } /* The scanner destructor @@ -1961,8 +2335,8 @@ void synctex_scanner_free(synctex_scanner_t scanner) { if(NULL == scanner) { return; } - FREE(scanner->sheet); - free(START); + SYNCTEX_FREE(scanner->sheet); + free(SYNCTEX_START); free(scanner->output); free(scanner->input); free(scanner->lists_of_friends); @@ -1991,14 +2365,14 @@ void synctex_scanner_display(synctex_scanner_t scanner) { return; } printf("The scanner:\noutput:%s\nversion:%i\n",scanner->output,scanner->version); - printf("pre_unit:%i\nx_offset:%i\nx_offset:%i\n",scanner->pre_unit,scanner->pre_x_offset,scanner->pre_y_offset); - printf("count:%i\npost_magnification:%f\npost_x_offset:%i\npost_x_offset:%i\n", + printf("pre_unit:%i\nx_offset:%i\ny_offset:%i\n",scanner->pre_unit,scanner->pre_x_offset,scanner->pre_y_offset); + printf("count:%i\npost_magnification:%f\npost_x_offset:%i\npost_y_offset:%i\n", scanner->count,scanner->unit,scanner->x_offset,scanner->y_offset); printf("The input:\n"); - DISPLAY(scanner->input); + SYNCTEX_DISPLAY(scanner->input); if(scanner->count<1000) { printf("The sheets:\n"); - DISPLAY(scanner->sheet); + SYNCTEX_DISPLAY(scanner->sheet); printf("The friends:\n"); if(scanner->lists_of_friends) { int i = scanner->number_of_lists; @@ -2009,15 +2383,15 @@ void synctex_scanner_display(synctex_scanner_t scanner) { while(node) { printf("%s:%i,%i\n", synctex_node_isa(node), - INFO(node)[TAG], - INFO(node)[LINE] + SYNCTEX_INFO(node)[SYNCTEX_TAG], + SYNCTEX_INFO(node)[SYNCTEX_LINE] ); - node = FRIEND(node); + node = SYNCTEX_FRIEND(node); } } } } else { - printf("Too many objects"); + printf("SyncTeX Warning: Too many objects\n"); } } /* Public*/ @@ -2028,10 +2402,10 @@ const char * synctex_scanner_get_name(synctex_scanner_t scanner,int tag) { } input = scanner->input; do { - if(tag == INFO(input)[TAG]) { - return (char *)(INFO(input)[NAME]); + if(tag == SYNCTEX_INFO(input)[SYNCTEX_TAG]) { + return (char *)(SYNCTEX_INFO(input)[SYNCTEX_NAME]); } - } while(input = SIBLING(input)); + } while(input = SYNCTEX_SIBLING(input)); return NULL; } int synctex_scanner_get_tag(synctex_scanner_t scanner,const char * name) { @@ -2041,11 +2415,11 @@ int synctex_scanner_get_tag(synctex_scanner_t scanner,const char * name) { } input = scanner->input; do { - if((strlen(name) == strlen((char *)(INFO(input)[NAME]))) && - (0 == strncmp(name,(char *)(INFO(input)[NAME]),strlen(name)))) { - return INFO(input)[TAG]; + if((strlen(name) == strlen((char *)(SYNCTEX_INFO(input)[SYNCTEX_NAME]))) && + (0 == strncmp(name,(char *)(SYNCTEX_INFO(input)[SYNCTEX_NAME]),strlen(name)))) { + return SYNCTEX_INFO(input)[SYNCTEX_TAG]; } - } while(input = SIBLING(input)); + } while(input = SYNCTEX_SIBLING(input)); return 0; } synctex_node_t synctex_scanner_input(synctex_scanner_t scanner) { @@ -2057,19 +2431,19 @@ float synctex_node_h(synctex_node_t node){ if(!node) { return 0; } - return (float)INFO(node)[HORIZ]; + return (float)SYNCTEX_INFO(node)[SYNCTEX_HORIZ]; } float synctex_node_v(synctex_node_t node){ if(!node) { return 0; } - return (float)INFO(node)[VERT]; + return (float)SYNCTEX_INFO(node)[SYNCTEX_VERT]; } float synctex_node_width(synctex_node_t node){ if(!node) { return 0; } - return (float)INFO(node)[WIDTH]; + return (float)SYNCTEX_INFO(node)[SYNCTEX_WIDTH]; } float synctex_node_box_h(synctex_node_t node){ if(!node) { @@ -2079,9 +2453,9 @@ float synctex_node_box_h(synctex_node_t node){ && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) && (node->class->type != synctex_node_type_void_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } - return (node->class->type == synctex_node_type_sheet)?0:(float)(INFO(node)[HORIZ]); + return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_INFO(node)[SYNCTEX_HORIZ]); } float synctex_node_box_v(synctex_node_t node){ if(!node) { @@ -2091,9 +2465,9 @@ float synctex_node_box_v(synctex_node_t node){ && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) && (node->class->type != synctex_node_type_void_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } - return (node->class->type == synctex_node_type_sheet)?0:(float)(INFO(node)[VERT]); + return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_INFO(node)[SYNCTEX_VERT]); } float synctex_node_box_width(synctex_node_t node){ if(!node) { @@ -2103,9 +2477,9 @@ float synctex_node_box_width(synctex_node_t node){ && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) && (node->class->type != synctex_node_type_void_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } - return (node->class->type == synctex_node_type_sheet)?0:(float)(INFO(node)[WIDTH]); + return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_INFO(node)[SYNCTEX_WIDTH]); } float synctex_node_box_height(synctex_node_t node){ if(!node) { @@ -2115,9 +2489,9 @@ float synctex_node_box_height(synctex_node_t node){ && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) && (node->class->type != synctex_node_type_void_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } - return (node->class->type == synctex_node_type_sheet)?0:(float)(INFO(node)[HEIGHT]); + return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_INFO(node)[SYNCTEX_HEIGHT]); } float synctex_node_box_depth(synctex_node_t node){ if(!node) { @@ -2127,9 +2501,9 @@ float synctex_node_box_depth(synctex_node_t node){ && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) && (node->class->type != synctex_node_type_void_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } - return (node->class->type == synctex_node_type_sheet)?0:(float)(INFO(node)[DEPTH]); + return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_INFO(node)[SYNCTEX_DEPTH]); } #pragma mark - #pragma mark Public node visible attributes @@ -2137,19 +2511,19 @@ float synctex_node_visible_h(synctex_node_t node){ if(!node) { return 0; } - return INFO(node)[HORIZ]*node->class->scanner->unit+node->class->scanner->x_offset; + return SYNCTEX_INFO(node)[SYNCTEX_HORIZ]*node->class->scanner->unit+node->class->scanner->x_offset; } float synctex_node_visible_v(synctex_node_t node){ if(!node) { return 0; } - return INFO(node)[VERT]*node->class->scanner->unit+node->class->scanner->y_offset; + return SYNCTEX_INFO(node)[SYNCTEX_VERT]*node->class->scanner->unit+node->class->scanner->y_offset; } float synctex_node_visible_width(synctex_node_t node){ if(!node) { return 0; } - return INFO(node)[WIDTH]*node->class->scanner->unit; + return SYNCTEX_INFO(node)[SYNCTEX_WIDTH]*node->class->scanner->unit; } float synctex_node_box_visible_h(synctex_node_t node){ if(!node) { @@ -2159,12 +2533,12 @@ float synctex_node_box_visible_h(synctex_node_t node){ || (node->class->type == synctex_node_type_void_hbox) || (node->class->type == synctex_node_type_void_vbox)) { result: - return INFO(node)[WIDTH]<0? - (INFO(node)[HORIZ]+INFO(node)[WIDTH])*node->class->scanner->unit+node->class->scanner->x_offset: - INFO(node)[HORIZ]*node->class->scanner->unit+node->class->scanner->x_offset; + return SYNCTEX_INFO(node)[SYNCTEX_WIDTH]<0? + (SYNCTEX_INFO(node)[SYNCTEX_HORIZ]+SYNCTEX_INFO(node)[SYNCTEX_WIDTH])*node->class->scanner->unit+node->class->scanner->x_offset: + SYNCTEX_INFO(node)[SYNCTEX_HORIZ]*node->class->scanner->unit+node->class->scanner->x_offset; } if(node->class->type != synctex_node_type_hbox) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { return 0; @@ -2172,9 +2546,9 @@ result: if(node->class->type == synctex_node_type_vbox) { goto result; } - return INFO(node)[WIDTH_V]<0? - (INFO(node)[HORIZ_V]+INFO(node)[WIDTH_V])*node->class->scanner->unit+node->class->scanner->x_offset: - INFO(node)[HORIZ_V]*node->class->scanner->unit+node->class->scanner->x_offset; + return SYNCTEX_INFO(node)[SYNCTEX_WIDTH_V]<0? + (SYNCTEX_INFO(node)[SYNCTEX_HORIZ_V]+SYNCTEX_INFO(node)[SYNCTEX_WIDTH_V])*node->class->scanner->unit+node->class->scanner->x_offset: + SYNCTEX_INFO(node)[SYNCTEX_HORIZ_V]*node->class->scanner->unit+node->class->scanner->x_offset; } float synctex_node_box_visible_v(synctex_node_t node){ if(!node) { @@ -2184,11 +2558,11 @@ float synctex_node_box_visible_v(synctex_node_t node){ || (node->class->type == synctex_node_type_void_hbox) || (node->class->type == synctex_node_type_void_vbox)) { result: - return (float)(INFO(node)[VERT])*node->class->scanner->unit+node->class->scanner->y_offset; + return (float)(SYNCTEX_INFO(node)[SYNCTEX_VERT])*node->class->scanner->unit+node->class->scanner->y_offset; } if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_hbox)) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { return 0; @@ -2196,7 +2570,7 @@ result: if(node->class->type == synctex_node_type_vbox) { goto result; } - return INFO(node)[VERT_V]*node->class->scanner->unit+node->class->scanner->y_offset; + return SYNCTEX_INFO(node)[SYNCTEX_VERT_V]*node->class->scanner->unit+node->class->scanner->y_offset; } float synctex_node_box_visible_width(synctex_node_t node){ if(!node) { @@ -2206,12 +2580,12 @@ float synctex_node_box_visible_width(synctex_node_t node){ || (node->class->type == synctex_node_type_void_hbox) || (node->class->type == synctex_node_type_void_vbox)) { result: - return INFO(node)[WIDTH]<0? - -INFO(node)[WIDTH]*node->class->scanner->unit: - INFO(node)[WIDTH]*node->class->scanner->unit; + return SYNCTEX_INFO(node)[SYNCTEX_WIDTH]<0? + -SYNCTEX_INFO(node)[SYNCTEX_WIDTH]*node->class->scanner->unit: + SYNCTEX_INFO(node)[SYNCTEX_WIDTH]*node->class->scanner->unit; } if(node->class->type != synctex_node_type_hbox) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { return 0; @@ -2219,9 +2593,9 @@ result: if(node->class->type == synctex_node_type_vbox) { goto result; } - return INFO(node)[WIDTH_V]<0? - -INFO(node)[WIDTH_V]*node->class->scanner->unit: - INFO(node)[WIDTH_V]*node->class->scanner->unit; + return SYNCTEX_INFO(node)[SYNCTEX_WIDTH_V]<0? + -SYNCTEX_INFO(node)[SYNCTEX_WIDTH_V]*node->class->scanner->unit: + SYNCTEX_INFO(node)[SYNCTEX_WIDTH_V]*node->class->scanner->unit; } float synctex_node_box_visible_height(synctex_node_t node){ if(!node) { @@ -2231,10 +2605,10 @@ float synctex_node_box_visible_height(synctex_node_t node){ || (node->class->type == synctex_node_type_void_hbox) || (node->class->type == synctex_node_type_void_vbox)) { result: - return (float)(INFO(node)[HEIGHT])*node->class->scanner->unit; + return (float)(SYNCTEX_INFO(node)[SYNCTEX_HEIGHT])*node->class->scanner->unit; } if(node->class->type != synctex_node_type_hbox) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { return 0; @@ -2242,7 +2616,7 @@ result: if(node->class->type == synctex_node_type_vbox) { goto result; } - return INFO(node)[HEIGHT_V]*node->class->scanner->unit; + return SYNCTEX_INFO(node)[SYNCTEX_HEIGHT_V]*node->class->scanner->unit; } float synctex_node_box_visible_depth(synctex_node_t node){ if(!node) { @@ -2252,10 +2626,10 @@ float synctex_node_box_visible_depth(synctex_node_t node){ || (node->class->type == synctex_node_type_void_hbox) || (node->class->type == synctex_node_type_void_vbox)) { result: - return (float)(INFO(node)[DEPTH])*node->class->scanner->unit; + return (float)(SYNCTEX_INFO(node)[SYNCTEX_DEPTH])*node->class->scanner->unit; } if(node->class->type != synctex_node_type_hbox) { - node = PARENT(node); + node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { return 0; @@ -2263,7 +2637,7 @@ result: if(node->class->type == synctex_node_type_vbox) { goto result; } - return INFO(node)[DEPTH_V]*node->class->scanner->unit; + return SYNCTEX_INFO(node)[SYNCTEX_DEPTH_V]*node->class->scanner->unit; } #pragma mark - #pragma mark Other public node attributes @@ -2272,21 +2646,21 @@ int synctex_node_page(synctex_node_t node){ if(!node) { return -1; } - parent = PARENT(node); + parent = SYNCTEX_PARENT(node); while(parent) { node = parent; - parent = PARENT(node); + parent = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { - return INFO(node)[PAGE]; + return SYNCTEX_INFO(node)[PAGE]; } return -1; } int synctex_node_tag(synctex_node_t node) { - return node?INFO(node)[TAG]:-1; + return node?SYNCTEX_INFO(node)[SYNCTEX_TAG]:-1; } int synctex_node_line(synctex_node_t node) { - return node?INFO(node)[LINE]:-1; + return node?SYNCTEX_INFO(node)[SYNCTEX_LINE]:-1; } int synctex_node_column(synctex_node_t node) { return -1; @@ -2298,10 +2672,10 @@ synctex_node_t synctex_sheet_content(synctex_scanner_t scanner,int page) { if(scanner) { synctex_node_t sheet = scanner->sheet; while(sheet) { - if(page == INFO(sheet)[PAGE]) { - return CHILD(sheet); + if(page == SYNCTEX_INFO(sheet)[PAGE]) { + return SYNCTEX_CHILD(sheet); } - sheet = SIBLING(sheet); + sheet = SYNCTEX_SIBLING(sheet); } } return NULL; @@ -2313,30 +2687,30 @@ int synctex_display_query(synctex_scanner_t scanner,const char * name,int line,i int friend_index = 0; synctex_node_t node = NULL; if(tag == 0) { - printf("No tag for %s\n",name); + printf("SyncTeX Warning: No tag for %s\n",name); return -1; } - free(START); - PTR = END = START = NULL; + free(SYNCTEX_START); + SYNCTEX_CUR = SYNCTEX_END = SYNCTEX_START = NULL; friend_index = (tag+line)%(scanner->number_of_lists); node = (scanner->lists_of_friends)[friend_index]; while(node) { - if((tag == INFO(node)[TAG]) && (line == INFO(node)[LINE])) { - if(PTR == END) { + if((tag == SYNCTEX_INFO(node)[SYNCTEX_TAG]) && (line == SYNCTEX_INFO(node)[SYNCTEX_LINE])) { + if(SYNCTEX_CUR == SYNCTEX_END) { size += 16; - END = realloc(START,size*sizeof(synctex_node_t *)); - PTR += END - START; - START = END; - END = START + size*sizeof(synctex_node_t *); + SYNCTEX_END = realloc(SYNCTEX_START,size*sizeof(synctex_node_t *)); + SYNCTEX_CUR += SYNCTEX_END - SYNCTEX_START; + SYNCTEX_START = SYNCTEX_END; + SYNCTEX_END = SYNCTEX_START + size*sizeof(synctex_node_t *); } - *(int *)PTR = (int)node; - PTR += sizeof(int); + *(int *)SYNCTEX_CUR = (int)node; + SYNCTEX_CUR += sizeof(int); } - node = FRIEND(node); + node = SYNCTEX_FRIEND(node); } - END = PTR; - PTR = NULL; - return END-START; + SYNCTEX_END = SYNCTEX_CUR; + SYNCTEX_CUR = NULL; + return SYNCTEX_END-SYNCTEX_START; } int _synctex_node_is_box(synctex_node_t node) { @@ -2378,20 +2752,20 @@ int synctex_edit_query(synctex_scanner_t scanner,int page,float h,float v) { if(NULL == scanner) { return 0; } - free(START); - START = END = PTR = NULL; + free(SYNCTEX_START); + SYNCTEX_START = SYNCTEX_END = SYNCTEX_CUR = NULL; sheet = scanner->sheet; - while(INFO(sheet)[PAGE] != page) { - sheet = SIBLING(sheet); + while(SYNCTEX_INFO(sheet)[PAGE] != page) { + sheet = SYNCTEX_SIBLING(sheet); } if(NULL == sheet) { return -1; } /* Now sheet points to the sheet node with proper page number */ /* Declare memory storage, a buffer to hold found nodes */ - node = CHILD(sheet); /* start with the child of the sheet */ + node = SYNCTEX_CHILD(sheet); /* start with the child of the sheet */ has_node_any_child: - if(next = CHILD(node)) { + if(next = SYNCTEX_CHILD(node)) { /* node is a non void box */ if(_synctex_point_in_visible_box(h,v,node)) { /* we found a non void box containing the point */ @@ -2438,13 +2812,13 @@ node_has_no_child: *ptr = NULL; } next_sibling: - if(next = SIBLING(node)) { + if(next = SYNCTEX_SIBLING(node)) { node = next; goto has_node_any_child; } /* This is the last node at this level * The next step is the parent's sibling */ - next = PARENT(node); + next = SYNCTEX_PARENT(node); if(ptr && *ptr == next) { /* No included box does contain the point * next was already tagged to contain the hit point @@ -2483,7 +2857,7 @@ we_are_done: /* We do need to check children to find out the node closest to the hit point. * Working with boxes is not very accurate because in general boxes are created asynchronously. * The glue, kern, math are more appropriate for synchronization. */ - if(node = CHILD(*start)) { + if(node = SYNCTEX_CHILD(*start)) { synctex_node_t best_node = NULL; best = INFINITY; do { @@ -2498,24 +2872,24 @@ we_are_done: case synctex_node_type_vbox: break; } - } while(node = SIBLING(node)); + } while(node = SYNCTEX_SIBLING(node)); if(best_node) { - if(START = malloc(sizeof(synctex_node_t))) { - * (synctex_node_t *)START = best_node; - END = START + sizeof(synctex_node_t); - PTR = NULL; + if(SYNCTEX_START = malloc(sizeof(synctex_node_t))) { + * (synctex_node_t *)SYNCTEX_START = best_node; + SYNCTEX_END = SYNCTEX_START + sizeof(synctex_node_t); + SYNCTEX_CUR = NULL; free(start); - return (END-START)/sizeof(synctex_node_t); + return (SYNCTEX_END-SYNCTEX_START)/sizeof(synctex_node_t); } } } - START = (unsigned char *)start; - END = (unsigned char *)end; - PTR = NULL; - return (END-START)/sizeof(synctex_node_t); + SYNCTEX_START = (unsigned char *)start; + SYNCTEX_END = (unsigned char *)end; + SYNCTEX_CUR = NULL; + return (SYNCTEX_END-SYNCTEX_START)/sizeof(synctex_node_t); } else if(NULL == next) { /* What? a node with no parent? */ - printf("This is an error\n"); + _synctex_error("Internal inconsistency, an unexpected node with no parent"); goto we_are_done; } node = next; @@ -2523,114 +2897,19 @@ we_are_done: } synctex_node_t synctex_next_result(synctex_scanner_t scanner) { - if(NULL == PTR) { - PTR = START; + if(NULL == SYNCTEX_CUR) { + SYNCTEX_CUR = SYNCTEX_START; } else { - PTR+=sizeof(synctex_node_t); + SYNCTEX_CUR+=sizeof(synctex_node_t); } - if(PTRpre_unit = 8192; - scanner->pre_x_offset = scanner->pre_y_offset = 578; - if(_synctex_scan_preamble(scanner)) { - goto bail; - } - do { - if(the_char == '{') { - if(_synctex_scan_content(scanner)) { - goto bail; - } - break; - } - } while(SYNCTEX_NOERR == _synctex_scan_next_line_header(scanner,&the_char)); - } - return scanner; -} - -int synctex_jump(synctex_scanner_t scanner) -{ - unsigned char the_char; - int n; - unsigned char * offset = END; - while(offset>scanner->buffer_start) { - if(*(--offset)) { - continue; - } - PTR = offset; - if(SYNCTEX_NOERR == _synctex_scan_next_line_header(scanner,&the_char)) { - if(the_char == '}') { - offset = PTR-1; -next: - if(SYNCTEX_NOERR == _synctex_decode_int(scanner,&n)) { - printf("}%i\n",n); - if(offset - n>START) { - offset -= n; - the_char = *offset; - if(the_char == '{') { - scanner->buffer_ptr=offset+1; - if(SYNCTEX_NOERR == _synctex_decode_int(scanner,&n)) { - printf("{%i\n",n); - if(offset - n>START) { - offset -= n; - the_char = *offset; - if(the_char == '}') { - PTR=offset+1; - goto next; - } else { - printf("This is not an '}', this is an %c\n", the_char); - } - } else { - printf("The start is reached %i\n",n); - } - } - } else { - printf("This is not an '{', this is an %c\n", the_char); - } - } else { - printf("ERROR: Too long %i\n",n); - } - } - break; - } - } - } - return 0; -} diff --git a/Build/source/texk/web2c/web2c/convert b/Build/source/texk/web2c/web2c/convert index de6c251eb95..a49bb6af6ae 100755 --- a/Build/source/texk/web2c/web2c/convert +++ b/Build/source/texk/web2c/web2c/convert @@ -97,7 +97,7 @@ ${basefile}coerce.h" ;; tex|eomega|etex|pdftex|pdfetex|omega|aleph|xetex) - more_defines="$srcdir/web2c/texmf.defines" + more_defines="$srcdir/web2c/texmf.defines $srcdir/synctex/synctex.defines" prog_defines="$srcdir/${basefile}dir/$basefile.defines" if test -f $prog_defines; then more_defines="$more_defines $prog_defines" diff --git a/Build/source/texk/web2c/xetexdir/sync-xetex.ch b/Build/source/texk/web2c/xetexdir/sync-xetex.ch deleted file mode 100644 index d25d1a21b26..00000000000 --- a/Build/source/texk/web2c/xetexdir/sync-xetex.ch +++ /dev/null @@ -1,68 +0,0 @@ -This file contains XeTeX changes for synctex support, -closely based on a patch to pdftex.web by Jérôme Laurens. - -****************************************************************************** -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL SIL INTERNATIONAL BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of SIL International -shall not be used in advertising or otherwise to promote the sale, -use or other dealings in this Software without prior written -authorization from SIL International. -****************************************************************************** - -@x -@d synctex_field_size=MISSING IMPLEMENTATION -@y -@d synctex_field_size=1 {Declare the {\sl synctex} field size to store the {\sl synctex} information: - we will put file tag and line into lh and rh fields of one word} -@z - -@x - MISSING IMPLEMENTATION: 0 synctag for medium sized node at mem[t] -@y - mem[t+medium_node_size-synctex_field_size].hh.lh:=0; {{\sl synctex}: do nothing, it is too late} -@z - -@x -MISSING IMPLEMENTATION: 0 synctag for medium sized node at mem[p] -@y -mem[p+medium_node_size-synctex_field_size].hh.lh:=0; {{\sl synctex}: do nothing, it is too late} -@z - -@x - MISSING IMPLEMENTATION: update the synctex information for node at mem[r] with size s -@y - mem[r+s-synctex_field_size].hh.lh := synctex_tag; - mem[r+s-synctex_field_size].hh.rh := line; -@z - -@x -MISSING IMPLEMENTATION: copy the synctex information for box node at mem[r] from node at mem[p] -@y -mem[r+box_node_size-synctex_field_size].hh.lh:=mem[p+box_node_size-synctex_field_size].hh.lh; -mem[r+box_node_size-synctex_field_size].hh.rh:=mem[p+box_node_size-synctex_field_size].hh.rh; -@z - -@x -MISSING IMPLEMENTATION: copy the synctex information for glue node at mem[r] from node at mem[p] -@y -mem[r+medium_node_size-synctex_field_size].hh.lh:=mem[p+medium_node_size-synctex_field_size].hh.lh; -mem[r+medium_node_size-synctex_field_size].hh.rh:=mem[p+medium_node_size-synctex_field_size].hh.rh; -@z diff --git a/Build/source/texk/web2c/xetexdir/xetex.ch b/Build/source/texk/web2c/xetexdir/xetex.ch index 2c84aa57c05..c60b9af9775 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==".998" -@d XeTeX_version_string=='-0.998.5-dev' {current \XeTeX\ version} +@d XeTeX_revision==".999" +@d XeTeX_version_string=='-0.999.0-dev' {current \XeTeX\ version} @z @x @@ -3783,9 +3783,7 @@ g_sign:=glue_sign(this_box); p:=list_ptr(this_box); incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; -save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; -@; -cur_v:=cur_v-height(this_box); +save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; cur_v:=cur_v-height(this_box); @y @!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio} @!upwards:boolean; {whether we're stacking upwards} @@ -3797,7 +3795,6 @@ incr(cur_s); if cur_s>0 then dvi_out(push); if cur_s>max_push then max_push:=cur_s; save_loc:=dvi_offset+dvi_ptr; left_edge:=cur_h; -@; if upwards then cur_v:=cur_v+depth(this_box) else cur_v:=cur_v-height(this_box); @z @@ -3815,16 +3812,15 @@ move_past: if upwards then cur_v:=cur_v-rule_ht else cur_v:=cur_v+rule_ht; @x @= +if list_ptr(p)=null then cur_v:=cur_v+height(p)+depth(p) +@y +@= if list_ptr(p)=null then begin - cur_v:=cur_v+height(p); - if type(p)=vlist_node then begin - @; - end - else begin - @; - end; - cur_v:=cur_v+depth(p); -end + if upwards then cur_v:=cur_v-depth(p)-height(p) else cur_v:=cur_v+height(p)+depth(p); + end +@z + +@x else begin cur_v:=cur_v+height(p); synch_v; save_h:=dvi_h; save_v:=dvi_v; if cur_dir=right_to_left then cur_h:=left_edge-shift_amount(p) @@ -3835,17 +3831,6 @@ else begin cur_v:=cur_v+height(p); synch_v; cur_v:=save_v+depth(p); cur_h:=left_edge; end @y -@= -if list_ptr(p)=null then begin - if upwards then cur_v:=cur_v-depth(p) else cur_v:=cur_v+height(p); - if type(p)=vlist_node then begin - @; - end - else begin - @; - end; - if upwards then cur_v:=cur_v-height(p) else cur_v:=cur_v+depth(p); -end else begin if upwards then cur_v:=cur_v-depth(p) else cur_v:=cur_v+height(p); synch_v; save_h:=dvi_h; save_v:=dvi_v; if cur_dir=right_to_left then cur_h:=left_edge-shift_amount(p) diff --git a/Build/source/texk/web2c/xetexdir/xetex.defines b/Build/source/texk/web2c/xetexdir/xetex.defines index be239481b07..15ddd0aeacb 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.defines +++ b/Build/source/texk/web2c/xetexdir/xetex.defines @@ -172,22 +172,3 @@ authorization from SIL International. @define function wdField(); @define function htField(); @define function applymapping(); - -{ functions from the synctex controller in synctex.c } -@define procedure synctexinitcommand; -@define procedure synctexstartinput; -@define procedure synctexterminate(); -@define procedure synctexsheet(); -@define procedure synctexteehs; -@define procedure synctexvlist(); -@define procedure synctextsilv(); -@define procedure synctexvoidvlist(); -@define procedure synctexhlist(); -@define procedure synctextsilh(); -@define procedure synctexvoidhlist(); -@define procedure synctexmath(); -@define procedure synctexkern(); -@define procedure synctexchar(); -@define procedure synctexnode(); -@define procedure synctexcurrent; -@define procedure synctexhorizontalruleorglue(); diff --git a/Build/source/texk/web2c/xetexdir/xetex.mk b/Build/source/texk/web2c/xetexdir/xetex.mk index d3e32a38c43..55a18d09261 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.mk +++ b/Build/source/texk/web2c/xetexdir/xetex.mk @@ -128,7 +128,7 @@ xetexdir/etex.version: $(srcdir)/etexdir/etex.ch # The C sources. xetex_c = xetexini.c xetex0.c xetex1.c xetex2.c xetex_o = xetexini.o xetex0.o xetex1.o xetex2.o xetexextra.o -xetex_add_o = trans.o XeTeX_ext.o xetex_pool.o $(xetex_platform_o) $(synctex-xetex_o) +xetex_add_o = trans.o XeTeX_ext.o xetex_pool.o $(xetex_platform_o) $(xetex_o-with_synctex) # these compilations require the path to TECkit headers; # just setting it in XCFLAGS doesn't seem to work when we're called @@ -232,9 +232,9 @@ xetex: $(xetex_o) $(xetex_add_o) $(xetex_images_o) $(xetex_ot_layout_o) \ # C file dependencies $(xetex_c) xetexcoerce.h xetexd.h: xetex.p $(web2c_texmf) $(web2c) xetex - $(synctex_xetexd) + $(xetexd.h-with_synctex) -xetexextra.c: lib/texmfmp.c xetexdir/xetexextra.h +xetexextra.c: xetexd.h lib/texmfmp.c xetexdir/xetexextra.h sed s/TEX-OR-MF-OR-MP/xetex/ $(srcdir)/lib/texmfmp.c >$@ xetexdir/xetexextra.h: xetexdir/xetexextra.in xetexdir/xetex.version xetexdir/etex.version test -d xetexdir || mkdir xetexdir @@ -257,8 +257,9 @@ xetex_web_srcs = $(srcdir)/tex.web \ $(srcdir)/tex.ch \ $(srcdir)/etexdir/tex.ch1 \ $(srcdir)/etexdir/tex.ech \ - $(synctex-xetex_ch_srcs) \ - $(srcdir)/xetexdir/xetex.ch + $(xetex_ch_srcs-with_synctex) \ + $(srcdir)/xetexdir/xetex.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