diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/utils')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/avl.c | 7 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/avl.h | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/avlstuff.c | 181 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/avlstuff.h | 5 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/avlstuff.w | 63 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/managed-sa.h | 75 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/managed-sa.w | 284 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/synctex-common.h | 51 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h | 99 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/synctex.c | 1661 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/synctex.h | 48 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/utils.c | 1809 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/utils.h | 69 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/utils.w | 465 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/utils/writezip.c | 99 |
15 files changed, 1956 insertions, 2962 deletions
diff --git a/Build/source/texk/web2c/luatexdir/utils/avl.c b/Build/source/texk/web2c/luatexdir/utils/avl.c index 0c322f12071..894203d476e 100644 --- a/Build/source/texk/web2c/luatexdir/utils/avl.c +++ b/Build/source/texk/web2c/luatexdir/utils/avl.c @@ -1,4 +1,5 @@ /* Produced by texiweb from libavl.w. */ +/* *INDENT-OFF* */ /* libavl - library for manipulation of binary trees. Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc. @@ -105,7 +106,8 @@ void **avl_probe(struct avl_table *tree, void *item) if (p->avl_balance != 0) z = q, y = p, k = 0; - da[k++] = dir = cmp > 0; + dir = cmp > 0; + da[k++] = (unsigned char)dir; } n = q->avl_link[dir] = @@ -227,7 +229,7 @@ void *avl_delete(struct avl_table *tree, const void *item) int dir = cmp > 0; pa[k] = p; - da[k++] = dir; + da[k++] = (unsigned char)dir; p = p->avl_link[dir]; if (p == NULL) @@ -794,3 +796,4 @@ void *(avl_assert_delete) (struct avl_table * table, void *item) { assert(p != NULL); return p; } +/* *INDENT-ON* */ diff --git a/Build/source/texk/web2c/luatexdir/utils/avl.h b/Build/source/texk/web2c/luatexdir/utils/avl.h index b9f9e3c01a9..1501ef0b271 100644 --- a/Build/source/texk/web2c/luatexdir/utils/avl.h +++ b/Build/source/texk/web2c/luatexdir/utils/avl.h @@ -1,4 +1,5 @@ /* Produced by texiweb from libavl.w. */ +/* *INDENT-OFF* */ /* libavl - library for manipulation of binary trees. Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc. @@ -113,3 +114,4 @@ void *avl_t_cur (struct avl_traverser *); void *avl_t_replace (struct avl_traverser *, void *); #endif /* avl.h */ +/* *INDENT-ON* */ diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c b/Build/source/texk/web2c/luatexdir/utils/avlstuff.c deleted file mode 100644 index c2f2537cbd6..00000000000 --- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.c +++ /dev/null @@ -1,181 +0,0 @@ -/* avlstuff.c - - Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "ptexlib.h" -#include "avl.h" - -static const char __svn_version[] = - "$Id: avlstuff.c 2599 2009-06-25 10:35:26Z taco $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/avlstuff.c $"; - -static struct avl_table **PdfObjTree = NULL; - -/**********************************************************************/ -/* memory management functions for AVL */ - -static void *avl_xmalloc(struct libavl_allocator *allocator, size_t size) -{ - assert(allocator != NULL && size > 0); - return xmalloc(size); -} - -static void avl_xfree(struct libavl_allocator *allocator, void *block) -{ - assert(allocator != NULL && block != NULL); - xfree(block); -} - -struct libavl_allocator avl_xallocator = { - avl_xmalloc, - avl_xfree -}; - -/**********************************************************************/ -/* general AVL comparison functions */ - -int comp_int_entry(const void *pa, const void *pb, void *p) -{ - (void) p; - cmp_return(*(const int *) pa, *(const int *) pb); - return 0; -} - -int comp_string_entry(const void *pa, const void *pb, void *p) -{ - (void) p; - return strcmp((const char *) pa, (const char *) pb); -} - -/**********************************************************************/ -/* One AVL tree for each obj_type 0...pdf_objtype_max */ - -typedef struct oentry_ { - integer int0; - integer objptr; -} oentry; - -/* AVL sort oentry into avl_table[] */ - -static int compare_info(const void *pa, const void *pb, void *param) -{ - integer a, b; - int as, ae, bs, be, al, bl; - (void) param; - a = ((const oentry *) pa)->int0; - b = ((const oentry *) pb)->int0; - if (a < 0 && b < 0) { /* string comparison */ - if (a <= 2097152 && b <= 2097152) { - a += 2097152; - b += 2097152; - as = str_start[-a]; - ae = str_start[-a + 1]; /* start of next string in pool */ - bs = str_start[-b]; - be = str_start[-b + 1]; - al = ae - as; - bl = be - bs; - if (al < bl) /* compare first by string length */ - return -1; - if (al > bl) - return 1; - for (; as < ae; as++, bs++) { - if (str_pool[as] < str_pool[bs]) - return -1; - if (str_pool[as] > str_pool[bs]) - return 1; - } - } else { - pdftex_fail - ("avlstuff.c: compare_items() for single characters: NI"); - } - } else { /* integer comparison */ - if (a < b) - return -1; - if (a > b) - return 1; - } - return 0; -} - -void avl_put_obj(integer objptr, integer t) -{ - static void **pp; - static oentry *oe; - int i; - - if (PdfObjTree == NULL) { - PdfObjTree = xtalloc(pdf_objtype_max + 1, struct avl_table *); - for (i = 0; i <= pdf_objtype_max; i++) - PdfObjTree[i] = NULL; - } - if (PdfObjTree[t] == NULL) { - PdfObjTree[t] = avl_create(compare_info, NULL, &avl_xallocator); - if (PdfObjTree[t] == NULL) - pdftex_fail("avlstuff.c: avl_create() PdfObjTree failed"); - } - oe = xtalloc(1, oentry); - oe->int0 = obj_info(objptr); - oe->objptr = objptr; /* allows to relocate obj_tab */ - pp = avl_probe(PdfObjTree[t], oe); - if (pp == NULL) - pdftex_fail("avlstuff.c: avl_probe() out of memory in insertion"); -} - -/* replacement for linear search pascal function "find_obj()" */ - -integer avl_find_obj(integer t, integer i, integer byname) -{ - static oentry *p; - static oentry tmp; - - if (byname > 0) - tmp.int0 = -i; - else - tmp.int0 = i; - if (PdfObjTree == NULL || PdfObjTree[t] == NULL) - return 0; - p = (oentry *) avl_find(PdfObjTree[t], &tmp); - if (p == NULL) - return 0; - return p->objptr; -} - -/**********************************************************************/ -/* cleaning up... */ - -static void destroy_oentry(void *pa, void *pb) -{ - oentry *p = (oentry *) pa; - (void) pb; - xfree(p); -} - -void PdfObjTree_free(void) -{ - int i; - - if (PdfObjTree == NULL) - return; - for (i = 0; i <= pdf_objtype_max; i++) { - if (PdfObjTree[i] != NULL) - avl_destroy(PdfObjTree[i], destroy_oentry); - } - xfree(PdfObjTree); - PdfObjTree = NULL; -} diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h index a7b565c5152..2b694c05efa 100644 --- a/Build/source/texk/web2c/luatexdir/utils/avlstuff.h +++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.h @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -/* $Id: avlstuff.h 2328 2009-04-18 12:50:26Z hhenkel $ */ +/* $Id: avlstuff.h 2684 2009-06-29 13:01:53Z taco $ */ #ifndef AVLSTUFF_H # define AVLSTUFF_H @@ -29,8 +29,5 @@ extern struct libavl_allocator avl_xallocator; int comp_int_entry(const void *, const void *, void *); int comp_string_entry(const void *, const void *, void *); -integer avl_find_obj(integer, integer, integer); -void avl_put_obj(integer, integer); -void PdfObjTree_free(void); #endif /* AVLSTUFF_H */ diff --git a/Build/source/texk/web2c/luatexdir/utils/avlstuff.w b/Build/source/texk/web2c/luatexdir/utils/avlstuff.w new file mode 100644 index 00000000000..b122d187d45 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/avlstuff.w @@ -0,0 +1,63 @@ +% avlstuff.w + +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@* AVL helper functions. + +@ @c +#include "ptexlib.h" +#include "utils/avl.h" + +static const char _svn_version[] = + "$Id: avlstuff.w 3584 2010-04-02 17:45:55Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/avlstuff.w $"; + +@ memory management functions for AVL +@c +static void *avl_xmalloc(struct libavl_allocator *allocator, size_t size) +{ + assert(allocator != NULL && size > 0); + return xmalloc((unsigned) size); +} + +static void avl_xfree(struct libavl_allocator *allocator, void *block) +{ + assert(allocator != NULL && block != NULL); + xfree(block); +} + +struct libavl_allocator avl_xallocator = { + avl_xmalloc, + avl_xfree +}; + +@ general AVL comparison functions +@c +int comp_int_entry(const void *pa, const void *pb, void *p) +{ + (void) p; + cmp_return(*(const int *) pa, *(const int *) pb); + return 0; +} + +int comp_string_entry(const void *pa, const void *pb, void *p) +{ + (void) p; + return strcmp((const char *) pa, (const char *) pb); +} diff --git a/Build/source/texk/web2c/luatexdir/utils/managed-sa.h b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h new file mode 100644 index 00000000000..185303a2e2c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.h @@ -0,0 +1,75 @@ +/* managed-sa.h + + Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. + + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ + +/* $Id: managed-sa.h 3378 2010-01-25 20:46:26Z hhenkel $ */ + +#ifndef MANAGED_SA_H +# define MANAGED_SA_H 1 + +/* the next two sets of three had better match up exactly, but using bare numbers + is easier on the C compiler */ + +# define HIGHPART 128 +# define MIDPART 128 +# define LOWPART 128 + +# define HIGHPART_PART(a) (((a)>>14)&127) +# define MIDPART_PART(a) (((a)>>7)&127) +# define LOWPART_PART(a) ((a)&127) + +# define Mxmalloc_array(a,b) xmalloc((unsigned)((unsigned)(b)*sizeof(a))) +# define Mxcalloc_array(a,b) xcalloc((b),sizeof(a)) +# define Mxrealloc_array(a,b,c) xrealloc((a),(unsigned)((unsigned)(c)*sizeof(b))) + +typedef unsigned int sa_tree_item; + +typedef struct { + int code; + int level; + sa_tree_item value; +} sa_stack_item; + + +typedef struct { + int stack_size; /* initial stack size */ + int stack_step; /* increment stack step */ + int stack_ptr; /* current stack point */ + sa_tree_item dflt; /* default item value */ + sa_tree_item ***tree; /* item tree head */ + sa_stack_item *stack; /* stack tree head */ +} sa_tree_head; + +typedef sa_tree_head *sa_tree; + +extern sa_tree_item get_sa_item(const sa_tree head, const int n); +extern void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl); +extern void rawset_sa_item(sa_tree head, int n, sa_tree_item v); + +extern sa_tree new_sa_tree(int size, sa_tree_item dflt); + +extern sa_tree copy_sa_tree(sa_tree head); +extern void destroy_sa_tree(sa_tree head); + +extern void dump_sa_tree(sa_tree a); +extern sa_tree undump_sa_tree(void); + +extern void restore_sa_stack(sa_tree a, int gl); +extern void clear_sa_stack(sa_tree a); + +#endif diff --git a/Build/source/texk/web2c/luatexdir/utils/managed-sa.w b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w new file mode 100644 index 00000000000..c451a23c0c8 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/managed-sa.w @@ -0,0 +1,284 @@ +% managed-sa.w +% +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@* Sparse arrays with an embedded save stack. + +@ @c +#include "ptexlib.h" + +static const char _svn_version[] = + "$Id: managed-sa.w 3584 2010-04-02 17:45:55Z hhenkel $ " +"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/managed-sa.w $"; + +@ @c +static void store_sa_stack(sa_tree a, int n, sa_tree_item v, int gl) +{ + sa_stack_item st; + st.code = n; + st.value = v; + st.level = gl; + if (a->stack == NULL) { + a->stack = Mxmalloc_array(sa_stack_item, a->stack_size); + } else if (((a->stack_ptr) + 1) >= a->stack_size) { + a->stack_size += a->stack_step; + a->stack = Mxrealloc_array(a->stack, sa_stack_item, a->stack_size); + } + (a->stack_ptr)++; + a->stack[a->stack_ptr] = st; +} + +@ @c +static void skip_in_stack(sa_tree a, int n) +{ + int p = a->stack_ptr; + if (a->stack == NULL) + return; + while (p > 0) { + if (a->stack[p].code == n && a->stack[p].level > 0) { + a->stack[p].level = -(a->stack[p].level); + } + p--; + } +} + +@ @c +sa_tree_item get_sa_item(const sa_tree head, const int n) +{ + register int h; + register int m; + if (head->tree != NULL) { + h = HIGHPART_PART(n); + if (head->tree[h] != NULL) { + m = MIDPART_PART(n); + if (head->tree[h][m] != NULL) { + return head->tree[h][m][LOWPART_PART(n)]; + } + } + } + return head->dflt; +} + +@ @c +void set_sa_item(sa_tree head, int n, sa_tree_item v, int gl) +{ + int h, m, l; + int i; + h = HIGHPART_PART(n); + m = MIDPART_PART(n); + l = LOWPART_PART(n); + if (head->tree == NULL) { + head->tree = + (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART); + } + if (head->tree[h] == NULL) { + head->tree[h] = + (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART); + } + if (head->tree[h][m] == NULL) { + head->tree[h][m] = + (sa_tree_item *) Mxmalloc_array(sa_tree_item, LOWPART); + for (i = 0; i < LOWPART; i++) { + head->tree[h][m][i] = head->dflt; + } + } + if (gl <= 1) { + skip_in_stack(head, n); + } else { + store_sa_stack(head, n, head->tree[h][m][l], gl); + } + head->tree[h][m][l] = v; +} + +@ @c +void rawset_sa_item(sa_tree head, int n, sa_tree_item v) +{ + head->tree[HIGHPART_PART(n)][MIDPART_PART(n)][LOWPART_PART(n)] = v; +} + +@ @c +void clear_sa_stack(sa_tree a) +{ + xfree(a->stack); + a->stack_ptr = 0; + a->stack_size = a->stack_step; +} + +@ @c +void destroy_sa_tree(sa_tree a) +{ + int h, m; + if (a == NULL) + return; + if (a->tree != NULL) { + for (h = 0; h < HIGHPART; h++) { + if (a->tree[h] != NULL) { + for (m = 0; m < MIDPART; m++) { + xfree(a->tree[h][m]); + } + xfree(a->tree[h]); + } + } + xfree(a->tree); + } + xfree(a->stack); + xfree(a); +} + +@ @c +sa_tree copy_sa_tree(sa_tree b) +{ + int h, m; + sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); + a->stack_step = b->stack_step; + a->stack_size = b->stack_size; + a->dflt = b->dflt; + a->stack = NULL; + a->stack_ptr = 0; + a->tree = NULL; + if (b->tree != NULL) { + a->tree = (sa_tree_item ***) Mxcalloc_array(void *, HIGHPART); + for (h = 0; h < HIGHPART; h++) { + if (b->tree[h] != NULL) { + a->tree[h] = (sa_tree_item **) Mxcalloc_array(void *, MIDPART); + for (m = 0; m < MIDPART; m++) { + if (b->tree[h][m] != NULL) { + a->tree[h][m] = Mxmalloc_array(sa_tree_item, LOWPART); + memcpy(a->tree[h][m], b->tree[h][m], + sizeof(sa_tree_item) * LOWPART); + } + } + } + } + } + return a; +} + +@ The main reason to fill in the lowest entry branches here immediately +is that most of the sparse arrays have a bias toward ASCII values. + +Allocating those here immediately improves the chance of the structure +|a->tree[0][0][x]| being close together in actual memory locations + +@c +sa_tree new_sa_tree(int size, sa_tree_item dflt) +{ + sa_tree_head *a; + a = (sa_tree_head *) xmalloc(sizeof(sa_tree_head)); + a->dflt = dflt; + a->stack = NULL; + a->tree = (sa_tree_item ***) Mxcalloc_array(sa_tree_item **, HIGHPART); + a->tree[0] = (sa_tree_item **) Mxcalloc_array(sa_tree_item *, MIDPART); + a->stack_size = size; + a->stack_step = size; + a->stack_ptr = 0; + return (sa_tree) a; +} + +@ @c +void restore_sa_stack(sa_tree head, int gl) +{ + sa_stack_item st; + if (head->stack == NULL) + return; + while (head->stack_ptr > 0 && abs(head->stack[head->stack_ptr].level) >= gl) { + st = head->stack[head->stack_ptr]; + if (st.level > 0) { + rawset_sa_item(head, st.code, st.value); + } + (head->stack_ptr)--; + } +} + + +@ @c +void dump_sa_tree(sa_tree a) +{ + boolean f; + int x; + int h, m, l; + assert(a != NULL); + dump_int(a->stack_step); + x = (int) a->dflt; + dump_int(x); + if (a->tree != NULL) { + dump_int(1); + for (h = 0; h < HIGHPART; h++) { + if (a->tree[h] != NULL) { + f = 1; + dump_qqqq(f); + for (m = 0; m < MIDPART; m++) { + if (a->tree[h][m] != NULL) { + f = 1; + dump_qqqq(f); + for (l = 0; l < LOWPART; l++) { + x = (int) a->tree[h][m][l]; + dump_int(x); + } + } else { + f = 0; + dump_qqqq(f); + } + } + } else { + f = 0; + dump_qqqq(f); + } + } + } else { + dump_int(0); + } +} + +@ @c +sa_tree undump_sa_tree(void) +{ + int x; + int h, m, l; + boolean f; + sa_tree a = (sa_tree) Mxmalloc_array(sa_tree_head, 1); + undump_int(x); + a->stack_step = x; + a->stack_size = x; + undump_int(x); + a->dflt = (sa_tree_item) x; + a->stack = Mxmalloc_array(sa_stack_item, a->stack_size); + a->stack_ptr = 0; + a->tree = NULL; + undump_int(x); + if (x == 0) + return a; + a->tree = (sa_tree_item ***) Mxcalloc_array(void *, HIGHPART); + for (h = 0; h < HIGHPART; h++) { + undump_qqqq(f); + if (f > 0) { + a->tree[h] = (sa_tree_item **) Mxcalloc_array(void *, MIDPART); + for (m = 0; m < MIDPART; m++) { + undump_qqqq(f); + if (f > 0) { + a->tree[h][m] = Mxmalloc_array(sa_tree_item, LOWPART); + for (l = 0; l < LOWPART; l++) { + undump_int(x); + a->tree[h][m][l] = (unsigned int) x; + } + } + } + } + } + return a; +} diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex-common.h b/Build/source/texk/web2c/luatexdir/utils/synctex-common.h new file mode 100644 index 00000000000..82d1199ece5 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/synctex-common.h @@ -0,0 +1,51 @@ +/* synctex-common.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 + +Acknowledgments: +---------------- +The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh, +and significant help from XeTeX developer Jonathan Kew + +Nota Bene: +---------- +If you include or use a significant part of the synctex package into a software, +I would appreciate to be listed as contributor and see "SyncTeX" highlighted. + +Version 1 +Latest Revision: Wed Jul 1 08:07:50 UTC 2009 + +*/ + +#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/luatexdir/utils/synctex-luatex.h b/Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h new file mode 100644 index 00000000000..1ebcaa5738b --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/synctex-luatex.h @@ -0,0 +1,99 @@ +/* synctex-luatex.h + + Copyright (c) 2010 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. + +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. + +*/ + +/* $Id: synctex-luatex.h 3536 2010-03-22 13:07:39Z taco $ */ + +#undef synchronization_field_size +#define synchronization_field_size 1 + +#undef width_offset +#undef height_offset +#undef depth_offset +#undef box_node_size +#undef rule_node +#undef glue_node +#undef kern_node + +#undef SYNCTEX_TYPE +#undef SYNCTEX_SUBTYPE +#undef SYNCTEX_WIDTH +#undef SYNCTEX_DEPTH +#undef SYNCTEX_HEIGHT +#undef SYNCTEX_TAG_MODEL +#undef SYNCTEX_LINE_MODEL +#undef SYNCTEX_VALUE + +#define SYNCTEX_TAG_MODEL(NODE,SIZE)\ + vinfo(NODE+SIZE-synchronization_field_size) +#define SYNCTEX_LINE_MODEL(NODE,SIZE)\ + vlink(NODE+SIZE-synchronization_field_size) + +#define SYNCTEX_TYPE(NODE) type(NODE) +#define SYNCTEX_SUBTYPE(NODE) subtype(NODE) +#define SYNCTEX_WIDTH(NODE) width(NODE) +#define SYNCTEX_DEPTH(NODE) depth(NODE) +#define SYNCTEX_HEIGHT(NODE) height(NODE) +#define SYNCTEX_VALUE int_par(synctex_code) + + +#define CURV (dimen_par(page_height_code)-static_pdf->posstruct->pos.v) +#define CURH static_pdf->posstruct->pos.h + +#define GETJOBNAME() makecstring(job_name) +#define GETLOGNAME() (char *)xstrdup((const char*)texmf_log_name) +#define gettexstring(a) makecstring(a) + +#define rulewd width(p) +#define ruleht height(p) +#define ruledp depth(p) + +#define curinput cur_input +#define totalpages total_pages +#define synctextagfield synctex_tag_field +#define namefield name_field + +#include "ptexlib.h" + +/* We observe pdfoutputvalue in order to determine whether output mode is + * pdf or dvi. + * We will assume that pdf_output_value equals pdf_output before entering + * the synctex_sheet function below. */ +#undef SYNCTEX_OFFSET_IS_PDF +#define SYNCTEX_OFFSET_IS_PDF (pdf_output_value>0) +#undef SYNCTEX_OUTPUT +#define SYNCTEX_OUTPUT ((pdf_output_value>0)?"pdf":"dvi") + +#define __SyncTeX__ 1 diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex.c b/Build/source/texk/web2c/luatexdir/utils/synctex.c index de51a4c8ec5..c64c8518365 100644 --- a/Build/source/texk/web2c/luatexdir/utils/synctex.c +++ b/Build/source/texk/web2c/luatexdir/utils/synctex.c @@ -1,8 +1,10 @@ /* -Copyright (c) 2008 jerome DOT laurens AT u-bourgogne DOT fr +Copyright (c) 2008, 2009 jerome DOT laurens AT u-bourgogne DOT fr This file is part of the SyncTeX package. +Latest Revision: Wed Jul 1 11:18:09 UTC 2009 + License: -------- Permission is hereby granted, free of charge, to any person @@ -65,7 +67,7 @@ Versioning: ----------- As synctex is embedded into different TeX implementation, there is an independent versionning system. -For TeX implementations, the actual version is: 1 +For TeX implementations, the actual version is: 2 For .synctex file format, the actual version is SYNCTEX_VERSION below Please, do not remove these explanations. @@ -80,39 +82,51 @@ Nota Bene: If you include or use a significant part of the synctex package into a software, I would appreciate to be listed as contributor and see "SyncTeX" highlighted. +History: +-------- +Version 2 +Fri Sep 19 14:55:31 UTC 2008 +- support for file names containing spaces. + This is one thing that xetex and pdftex do not manage the same way. + When the input file name contains a space character ' ', + pdftex will automatically enclose this name between two quote characters '"', + making programs believe that these quotes are really part of the name. + xetex does nothing special. + For that reason, running the command line + xetex --synctex=-1 "my file.tex" + is producing the expected file named <my file.synctex>, (the '<' and '>' are not part of the name) + whereas running the command line + pdftex --synctex=-1 "my file.tex" + was producing the unexpected file named <"my file".synctex> where the two '"' chracters were part of the name. + Of course, that was breaking the typesetting mechanism when pdftex was involved. + To solve this problem, we prefer to rely on the output_file_name instead of the jobname. + In the case when no output_file_name is available, we use jobname and test if the file name + starts and ends with a quote character. Every synctex output file is removed because we consider + TeX encontered a problem. + There is some conditional coding. + Version 1 -Tue Jul 1 15:23:00 UTC 2008 +Latest Revision: Wed Jul 1 08:15:44 UTC 2009 */ -# define SYNCTEX_VERSION 1 +#define SYNCTEX_VERSION 1 -# define SYNCTEX_DEBUG 0 +#define SYNCTEX_DEBUG 0 /* Debugging: define the next macro to "return;" in order to disable the synctex code * only suplemental function calls will be used. The compiler may optimize them. */ -# define SYNCTEX_RETURN_IF_DISABLED ; +#define SYNCTEX_RETURN_IF_DISABLED ; -# define SYNCTEX_NOERR 0 +#define SYNCTEX_NOERR 0 -# define EXTERN extern +#define EXTERN extern -# ifdef xfree -# define SYNCTEX_FREE xfree -# else -# define SYNCTEX_FREE(x) free(x) -# endif - -#define ruleht rule_ht -#define ruledp rule_dp -#define rulewd rule_wd -#define jobname job_name -#define totalpages total_pages -#define curinput cur_input -#define synctextagfield synctex_tag_field -#define namefield name_field - -#define gettexstring(a) xstrdup(makecstring(a)) +#ifdef xfree +# define SYNCTEX_FREE xfree +#else +# define SYNCTEX_FREE(x) free(x) +#endif /* the macros defined below do the same job than their almost eponym * counterparts of *tex.web, the memory access is sometimes more direct @@ -122,20 +136,26 @@ Tue Jul 1 15:23:00 UTC 2008 * and *tex.web for details, the synctex_ prefix prevents name conflicts, it * is some kind of namespace */ + /* synctexoption is a global integer variable defined in *tex.web * it is set to 1 by texmfmp.c if the command line has the '-synctex=1' * option. */ -# define synctex_options synctexoption -# define SYNCTEX_NO_OPTION INT_MAX +#define synctex_options synctexoption +#define SYNCTEX_NO_OPTION INT_MAX /* if synctex_options is set to SYNCTEX_NO_OPTION, no command line option was provided. */ -# define SYNCTEX_VALUE int_par(param_synctex_code) - +/* glue code: really define the main memory, + * this is exactly the same "mem" as in *tex.web. */ +#define mem zmem +/* glue code: synctexoffset is a global integer variable defined in *tex.web + * it is set to the offset where the primitive \synctex reads and writes its + * value. */ +#define SYNCTEX_VALUE zeqtb[synctexoffset].cint /* if there were a mean to share the value of synctex_code between *tex.web * and this file, it would be great. */ -# define SYNCTEX_UNIT_FACTOR 1 -# define UNIT / synctex_ctxt.unit +#define SYNCTEX_UNIT_FACTOR 1 +#define UNIT / synctex_ctxt.unit /* UNIT is the scale. TeX coordinates are very accurate and client won't need * that, at leat in a first step. 1.0 <-> 2^16 = 65536. * The TeX unit is sp (scaled point) or pt/65536 which means that the scale @@ -148,7 +168,7 @@ Tue Jul 1 15:23:00 UTC 2008 * IMPORTANT: We can say that the natural unit of .synctex files is SYNCTEX_UNIT_FACTOR sp. * To retrieve the proper bp unit, we'll have to divide by 8.03. To reduce * rounding errors, we'll certainly have to add 0.5 for non negative integers - * and ±0.5 for negative integers. This trick is mainly to gain speed and + * and ±0.5 for negative integers. This trick is mainly to gain speed and * size. A binary file would be more appropriate in that respect, but I guess * that some clients like auctex would not like it very much. we cannot use * "<<13" instead of "/SYNCTEX_UNIT_FACTOR" because the integers are signed and we do not @@ -162,7 +182,7 @@ Tue Jul 1 15:23:00 UTC 2008 The 9 definitions below must be in sync with their eponym declarations in the proper synctex-*.ch* file. */ -# define synchronization_field_size 1 +#define synchronization_field_size 2 /* The default value is 2, it is suitable for original TeX and alike, * but it is too big for XeTeX. * The tag and the line are just the two last words of the node. This is a @@ -171,21 +191,35 @@ Tue Jul 1 15:23:00 UTC 2008 * XeTeX redefines synchronization_field_size, * SYNCTEX_TAG_MODEL and SYNCTEX_LINE_MODEL * All the default values are targeted to TeX or e-TeX. */ -# define SYNCTEX_TAG_MODEL(NODE,SIZE)\ - vinfo(NODE+SIZE-synchronization_field_size) -# define SYNCTEX_LINE_MODEL(NODE,SIZE)\ - vlink(NODE+SIZE-synchronization_field_size) +#define SYNCTEX_TAG_MODEL(NODE,SIZE)\ + mem[NODE+SIZE-synchronization_field_size].cint +#define SYNCTEX_LINE_MODEL(NODE,SIZE)\ + mem[NODE+SIZE-synchronization_field_size+1].cint /* SYNCTEX_TAG_MODEL and SYNCTEX_LINE_MODEL are used to define * SYNCTEX_TAG and SYNCTEX_LINE in a model independant way * Both are tag and line accessors */ +#define box_node_size (7+synchronization_field_size) +/* see: @d box_node_size=... + * There should be an automatic process here because these definitions + * are redundant. However, this process would certainly be overcomplicated + * (building then parsing the *tex.web file would be a pain) */ +#define width_offset 1 +/* see: @d width_offset=... */ +#define depth_offset 2 +/* see: @d depth_offset=... */ +#define height_offset 3 +/* see: @d height_offset=... */ /* Now define the local version of width(##), height(##) and depth(##) macros These only depend on the 3 macros above. */ -# define SYNCTEX_TYPE(NODE) type(NODE) -# define SYNCTEX_SUBTYPE(NODE) subtype(NODE) -# define SYNCTEX_WIDTH(NODE) width(NODE) -# define SYNCTEX_DEPTH(NODE) depth(NODE) -# define SYNCTEX_HEIGHT(NODE) height(NODE) +#define SYNCTEX_TYPE(NODE) mem[NODE].hh.b0 +#define rule_node 2 +#define glue_node 10 +#define kern_node 11 +#define SYNCTEX_SUBTYPE(NODE) mem[NODE].hh.b1 +#define SYNCTEX_WIDTH(NODE) mem[NODE+width_offset].cint +#define SYNCTEX_DEPTH(NODE) mem[NODE+depth_offset].cint +#define SYNCTEX_HEIGHT(NODE) mem[NODE+height_offset].cint /* When an hlist ships out, it can contain many different kern/glue nodes with * exactly the same sync tag and line. To reduce the size of the .synctex @@ -198,128 +232,128 @@ Tue Jul 1 15:23:00 UTC 2008 * a change in the context, this is the macro SYNCTEX_CONTEXT_DID_CHANGE. The * SYNCTEX_IGNORE macro is used to detect unproperly initialized nodes. See * details in the implementation of the functions below. */ -# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE +#define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE /* Some parts of the code may differ depending on the ouput mode, * dvi or xdv vs pdf, in particular the management of magnification. * The default is dvi mode. * Also, if pdftex is used, the origin of the coordinates is at 0, not at 1in * Default values are suitable for TeX */ -# define SYNCTEX_OUTPUT "dvi" -# define SYNCTEX_OFFSET_IS_PDF 0 - -# define SYNCTEX_YES (-1) -# define SYNCTEX_NO (0) -# define SYNCTEX_NO_ERROR (0) +#define SYNCTEX_OUTPUT "dvi" +#define SYNCTEX_OFFSET_IS_PDF 0 -# include "luatexd.h" -# include "nodes.h" -# include "commands.h" -# undef SYNCTEX_OFFSET_IS_PDF -# define SYNCTEX_OFFSET_IS_PDF (pdf_output_value>0) -# undef SYNCTEX_OUTPUT -# define SYNCTEX_OUTPUT ((pdf_output_value>0)?"pdf":"dvi") +#define SYNCTEX_TRUE 1 +#define SYNCTEX_YES (-1) +#define SYNCTEX_NO (0) +#define SYNCTEX_NO_ERROR (0) -#define __SyncTeX__ 1 +#include "synctex-luatex.h" -# include "synctex.h" +#include "synctex.h" -# if defined(__SyncTeX__) +#if defined(__SyncTeX__) -# include <stdio.h> -# include <stdarg.h> -# include "zlib.h" +# include <stdio.h> +# include <stdarg.h> +# include "zlib.h" -typedef void (*synctex_recorder_t)(halfword); /* recorders know how to record a node */ -typedef int (*synctex_fprintf_t)(void *, const char * , ...); /* print formatted to either FILE * or gzFile */ +typedef void (*synctex_recorder_t) (halfword); /* recorders know how to record a node */ +typedef int (*synctex_fprintf_t) (void *, const char *, ...); /* print formatted to either FILE * or gzFile */ -# define SYNCTEX_BITS_PER_BYTE 8 +# define SYNCTEX_BITS_PER_BYTE 8 /* Here are all the local variables gathered in one "synchronization context" */ static struct { void *file; /* the foo.synctex or foo.synctex.gz I/O identifier */ - synctex_fprintf_t fprintf; /* either fprintf or gzprintf */ + synctex_fprintf_t fprintf; /* either fprintf or gzprintf */ char *busy_name; /* the real "foo.synctex(busy)" or "foo.synctex.gz(busy)" name */ char *root_name; /* in general jobname.tex */ integer count; /* The number of interesting records in "foo.synctex" */ /* next concern the last sync record encountered */ halfword node; /* the last synchronized node, must be set * before the recorder */ - synctex_recorder_t recorder;/* the recorder of the node above, the - * routine that knows how to record the - * node to the .synctex file */ + synctex_recorder_t recorder; /* the recorder of the node above, the + * routine that knows how to record the + * node to the .synctex file */ integer tag, line; /* current tag and line */ integer curh, curv; /* current point */ integer magnification; /* The magnification as given by \mag */ integer unit; /* The unit, defaults to 1, use 8192 to produce shorter but less accurate info */ 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, corresponds to cli option -synctex=0 */ - unsigned int no_gz:1; /* Whether zlib is used or not */ - 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; + 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, corresponds to cli option -synctex=0 */ + unsigned int no_gz:1; /* Whether zlib is used or not */ + unsigned int not_void:1; /* Whether it really contains synchronization material */ + unsigned int warn:1; /* One shot warning flag */ + unsigned int quoted:1; /* Whether the input file name was quoted by tex or not, for example "\"my input file.tex\"", unused by XeTeX */ + unsigned int reserved:SYNCTEX_BITS_PER_BYTE * sizeof(int) - 6; /* Align */ + } flags; } synctex_ctxt = { -NULL, NULL, NULL, NULL, 0, 0, NULL, 0, 0, 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, 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) +# 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 synctex_init_command(void) +void synctexinitcommand(void) { - /* This is a one shot function, any subsequent call is void */ - if (synctex_ctxt.flags.option_read) { - return; - } + /* 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 == 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; + * any subsequent \synctex=1 will have no effect at all */ + SYNCTEX_IS_OFF = SYNCTEX_TRUE; SYNCTEX_VALUE = 0; } else { /* the command line options are not ignored */ - if(synctex_options < 0) { - SYNCTEX_NO_GZ = SYNCTEX_YES; - } - /* Initialize the content of the \synctex primitive */ - SYNCTEX_VALUE = synctex_options; + if (synctex_options < 0) { + SYNCTEX_NO_GZ = SYNCTEX_TRUE; + } + /* Initialize the content of the \synctex primitive */ + SYNCTEX_VALUE = synctex_options; } - synctex_ctxt.flags.option_read = SYNCTEX_YES; - return; + synctex_ctxt.flags.option_read = SYNCTEX_TRUE; + return; } -/* Free all memory used and close the file, - * It is sent locally when there is a problem with synctex output. */ -static void synctex_abort(void) +/* Free all memory used, close and remove the file if any, + * It is sent locally when there is a problem with synctex output. + * It is sent by pdftex when a fatal error occurred in pdftex.web. */ +void synctexabort(boolean log_opened __attribute__ ((unused))) { - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctex_abort\n"); -#endif +# endif if (SYNCTEX_FILE) { - if (SYNCTEX_NO_GZ) { - xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name); - } else { - gzclose((gzFile)SYNCTEX_FILE); - } + if (SYNCTEX_NO_GZ) { + xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name); + } else { + gzclose((gzFile) SYNCTEX_FILE); + } + SYNCTEX_FILE = NULL; + remove(synctex_ctxt.busy_name); SYNCTEX_FREE(synctex_ctxt.busy_name); synctex_ctxt.busy_name = NULL; } - SYNCTEX_FREE(synctex_ctxt.root_name); - synctex_ctxt.root_name = NULL; - SYNCTEX_IS_OFF = SYNCTEX_YES; /* disable synctex */ + if (NULL != synctex_ctxt.root_name) { + SYNCTEX_FREE(synctex_ctxt.root_name); + synctex_ctxt.root_name = NULL; + } + SYNCTEX_IS_OFF = SYNCTEX_TRUE; /* disable synctex */ } static inline int synctex_record_preamble(void); @@ -339,90 +373,119 @@ static const char *synctex_suffix_busy = "(busy)"; */ static void *synctex_dot_open(void) { - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctex_dot_open\n"); printf("\nwarning: SYNCTEX_VALUE=%0X\n", SYNCTEX_VALUE); printf("\nwarning: synctex_options=%0X\n", synctex_options); -# endif +# endif if (SYNCTEX_IS_OFF || !SYNCTEX_VALUE) { - return NULL; /* synchronization is disabled: do nothing */ + return NULL; /* synchronization is disabled: do nothing */ } if (SYNCTEX_FILE) { - return SYNCTEX_FILE; /* synchronization is alerady enabled */ + return SYNCTEX_FILE; /* synchronization is alerady enabled */ } -#if SYNCTEX_DEBUG +# if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctex_dot_open 1\n"); -# endif - /* 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. */ - { - char *tmp = gettexstring(jobname); - /* jobname was set by the \jobname command on the *TeX side */ - char * the_busy_name = xmalloc(strlen(tmp) + strlen(synctex_suffix) + strlen(synctex_suffix_gz) + strlen(synctex_suffix_busy) + 1); - if(!the_busy_name) { - SYNCTEX_FREE(tmp); - synctex_abort(); - return NULL; - } - 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); - } - strcat(the_busy_name, synctex_suffix_busy); - if (SYNCTEX_NO_GZ) { - SYNCTEX_FILE = xfopen(the_busy_name, FOPEN_WBIN_MODE); - synctex_ctxt.fprintf = (synctex_fprintf_t)(&fprintf); - } else { - SYNCTEX_FILE = gzopen(the_busy_name, FOPEN_WBIN_MODE); - synctex_ctxt.fprintf = (synctex_fprintf_t)(&gzprintf); - } -#if SYNCTEX_DEBUG - printf("\nwarning: Synchronize DEBUG: synctex_dot_open 2\n"); -#endif - if (SYNCTEX_FILE) { - if(SYNCTEX_NO_ERROR != synctex_record_preamble()) { - synctex_abort(); - return NULL; - } - /* Initialization of the context */ - synctex_ctxt.magnification = 1000; - synctex_ctxt.unit = SYNCTEX_UNIT_FACTOR; - /* synctex_ctxt.busy_name was NULL before, it now owns the_busy_name */ - synctex_ctxt.busy_name = the_busy_name; - the_busy_name = NULL; - /* print the preamble, this is an quite an UTF8 file */ - if (NULL != synctex_ctxt.root_name) { - synctex_record_input(1,synctex_ctxt.root_name); - SYNCTEX_FREE(synctex_ctxt.root_name); - synctex_ctxt.root_name = NULL; - } - synctex_ctxt.count = 0; -#if SYNCTEX_DEBUG - fprintf(stdout, - "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX AVAILABLE\n"); -#endif - } 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; -#if SYNCTEX_DEBUG - fprintf(stdout, - "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX DISABLED\n"); -#endif - } - } +# endif + /* 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. */ + { + size_t len; + char *tmp = GETJOBNAME(); + /* jobname was set by the \jobname command on the *TeX side */ + char *the_busy_name = xmalloc((unsigned) + (strlen(tmp) + strlen(synctex_suffix) + + strlen(synctex_suffix_gz) + + strlen(synctex_suffix_busy) + 1)); + if (!the_busy_name) { + SYNCTEX_FREE(tmp); + synctexabort(0); + return NULL; + } +# if defined(XeTeX) + synctex_ctxt.flags.quoted = 0; + strcpy(the_busy_name, tmp); +# else + len = strlen(tmp); + if (len > 0 && tmp[0] == '"' && tmp[len - 1] == '"') { + /* We are certainly on a pdftex like engine and the input file name did contain spaces inside. + Quotes where added around that file name. We prefer to remove the quotes to have a human readable name. + As of Fri Sep 19 14:00:01 UTC 2008, the file names containing quotes are not supported by pdfTeX + nor SyncTeX. */ + synctex_ctxt.flags.quoted = 1; /* we will have to add quotes around the file name in the log file. */ + strcpy(the_busy_name, tmp + 1); /* only copy what follows the leading " character */ + len = strlen(the_busy_name); + if ((len > 0) && (the_busy_name[len - 1] == '"')) { + the_busy_name[len - 1] = '\0'; + } + } else { + synctex_ctxt.flags.quoted = 0; + strcpy(the_busy_name, tmp); + } +# endif + 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. */ + if (SYNCTEX_VALUE < 0) { + SYNCTEX_NO_GZ = SYNCTEX_TRUE; + } else { + SYNCTEX_NO_GZ = SYNCTEX_NO; + } + if (!SYNCTEX_NO_GZ) { + strcat(the_busy_name, synctex_suffix_gz); + } + strcat(the_busy_name, synctex_suffix_busy); + if (SYNCTEX_NO_GZ) { + SYNCTEX_FILE = xfopen(the_busy_name, FOPEN_WBIN_MODE); + synctex_ctxt.fprintf = (synctex_fprintf_t) (&fprintf); + } else { + SYNCTEX_FILE = gzopen(the_busy_name, FOPEN_WBIN_MODE); + synctex_ctxt.fprintf = (synctex_fprintf_t) (&gzprintf); + } +# if SYNCTEX_DEBUG + printf("\nwarning: Synchronize DEBUG: synctex_dot_open 2\n"); +# endif + if (SYNCTEX_FILE) { + if (SYNCTEX_NO_ERROR != synctex_record_preamble()) { + synctexabort(0); + return NULL; + } + /* Initialization of the context */ + synctex_ctxt.magnification = 1000; + synctex_ctxt.unit = SYNCTEX_UNIT_FACTOR; + /* synctex_ctxt.busy_name was NULL before, it now owns the_busy_name */ + synctex_ctxt.busy_name = the_busy_name; + the_busy_name = NULL; + /* print the preamble, this is an quite an UTF8 file */ + if (NULL != synctex_ctxt.root_name) { + synctex_record_input(1, synctex_ctxt.root_name); + SYNCTEX_FREE(synctex_ctxt.root_name); + synctex_ctxt.root_name = NULL; + } + synctex_ctxt.count = 0; +# if SYNCTEX_DEBUG + fprintf(stdout, + "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX AVAILABLE\n"); +# endif + } else { + /* no .synctex file available, so disable synchronization */ + SYNCTEX_IS_OFF = SYNCTEX_TRUE; + 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; +# if SYNCTEX_DEBUG + fprintf(stdout, + "\nwarning: Synchronize DEBUG: synctex_dot_open SYNCTEX DISABLED\n"); +# endif + } + } return SYNCTEX_FILE; } @@ -444,17 +507,17 @@ static void *synctex_dot_open(void) * treats the same way .tex, .aux, .sty ... files, even if many of them do not * contain any material meant to be typeset. */ -void synctex_start_input(void) +void synctexstartinput(void) { static unsigned int synctex_tag_counter = 0; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctexstartinput %i", - synctex_tag_counter); + synctex_tag_counter); printf("\nwarning: SYNCTEX_VALUE=%i", SYNCTEX_VALUE); printf("\nwarning: synctex_options=%0X", synctex_options); -#endif +# endif if (SYNCTEX_IS_OFF) { return; @@ -472,35 +535,36 @@ void synctex_start_input(void) curinput.synctextagfield = 0; return; } - curinput.synctextagfield = synctex_tag_counter; /* -> *TeX.web */ + curinput.synctextagfield = (int) synctex_tag_counter; /* -> *TeX.web */ 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 necessary because \jobname can be different */ + * This is necessary because \jobname can be different */ 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. - * This occurs when some SYNCTEX_IGNORE macro is not used. - * But this must not happen unexpectedly, so we leave the unit to 0 */ -#if SYNCTEX_DEBUG + /* we could initialize the unit field to 1 to avoid floating point exception + * when accidentaly dividing by the unit. + * This occurs when some SYNCTEX_IGNORE macro is not used. + * But this must not happen unexpectedly, so we leave the unit to 0 */ +# if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctexstartinput first END\n"); -# endif +# endif return; } - if (SYNCTEX_FILE || (SYNCTEX_VALUE && (SYNCTEX_NO_ERROR != 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_record_input(curinput.synctextagfield, tmp); SYNCTEX_FREE(tmp); } -#if SYNCTEX_DEBUG +# if SYNCTEX_DEBUG printf("\nwarning: Synchronize DEBUG: synctexstartinput END\n"); -# endif +# endif return; } /* 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 varmem, + * 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 * information about a node. The other information is obtained through the * global context variable. @@ -520,71 +584,135 @@ static inline int synctex_record_postamble(void); * However, it does not mean that it will be in sync with the pdf, especially * when the output is dvi or xdv and the dvi (or xdv) to pdf driver has not been applied. */ -void synctex_terminate(boolean log_opened) +void synctexterminate(boolean log_opened) { - char *tmp = NULL; - char * the_real_syncname = NULL; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + char *tmp = NULL; + char *the_real_syncname = NULL; + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexterminate\n"); -#endif - tmp = gettexstring(jobname); - the_real_syncname = xmalloc(strlen(tmp) + strlen(synctex_suffix) + strlen(synctex_suffix_gz) + 1); - if(!the_real_syncname) { - SYNCTEX_FREE(tmp); - synctex_abort(); - return; - } - 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); - } - /* allways remove the synctex output file before renaming it, windows requires it. */ - if(0 != remove(the_real_syncname) && errno == EACCES) { - fprintf(stderr,"SyncTeX: Can't remove %s (file is open or read only)\n",the_real_syncname); - } - if (SYNCTEX_FILE) { - if (SYNCTEX_NOT_VOID) { - synctex_record_postamble(); - /* close the synctex file*/ - if (SYNCTEX_NO_GZ) { - xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name); - } else { - gzclose((gzFile)SYNCTEX_FILE); - } - /* renaming the working synctex file */ - if(0 == rename(synctex_ctxt.busy_name,the_real_syncname)) { - if(log_opened) { - printf("\nSyncTeX written on %s",the_real_syncname); /* SyncTeX also refers to the contents */ - } - } else { - fprintf(stderr,"SyncTeX: Can't rename %s to %s\n",synctex_ctxt.busy_name,the_real_syncname); - remove(synctex_ctxt.busy_name); - } - } else { - /* close and remove the synctex file because there are no pages of output */ - if (SYNCTEX_NO_GZ) { - xfclose((FILE *)SYNCTEX_FILE, synctex_ctxt.busy_name); - } else { - gzclose((gzFile)SYNCTEX_FILE); - } - remove(synctex_ctxt.busy_name); - } - SYNCTEX_FILE = NULL; - } - 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; - SYNCTEX_FREE(the_real_syncname); - SYNCTEX_FREE(tmp); - synctex_abort(); +# endif + if (log_opened && (tmp = GETLOGNAME())) { + /* In version 1, the jobname was used but it caused problems regarding spaces in file names. */ + the_real_syncname = xmalloc((unsigned) + (strlen(tmp) + strlen(synctex_suffix) + + strlen(synctex_suffix_gz) + 1)); + if (!the_real_syncname) { + SYNCTEX_FREE(tmp); + synctexabort(0); + return; + } + strcpy(the_real_syncname, tmp); + SYNCTEX_FREE(tmp); + tmp = NULL; + /* now remove the last path extension which is in general log */ + tmp = the_real_syncname + strlen(the_real_syncname); + while (tmp > the_real_syncname) { + --tmp; + if (*tmp == '.') { + *tmp = '\0'; /* end the string here */ + break; + } + } + 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); + } + /* allways remove the synctex output file before renaming it, windows requires it. */ + if (0 != remove(the_real_syncname) && errno == EACCES) { + fprintf(stderr, + "SyncTeX: Can't remove %s (file is open or read only)\n", + the_real_syncname); + } + if (SYNCTEX_FILE) { + if (SYNCTEX_NOT_VOID) { + synctex_record_postamble(); + /* close the synctex file */ + if (SYNCTEX_NO_GZ) { + xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name); + } else { + gzclose((gzFile) SYNCTEX_FILE); + } + SYNCTEX_FILE = NULL; + /* renaming the working synctex file */ + if (0 == rename(synctex_ctxt.busy_name, the_real_syncname)) { + if (log_opened) { + printf((synctex_ctxt.flags.quoted ? "\nSyncTeX written on \"%s\"" : "\nSyncTeX written on %s"), the_real_syncname); /* SyncTeX also refers to the contents */ + } + } else { + fprintf(stderr, "SyncTeX: Can't rename %s to %s\n", + synctex_ctxt.busy_name, the_real_syncname); + remove(synctex_ctxt.busy_name); + } + } else { + /* close and remove the synctex file because there are no pages of output */ + if (SYNCTEX_NO_GZ) { + xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name); + } else { + gzclose((gzFile) SYNCTEX_FILE); + } + SYNCTEX_FILE = NULL; + remove(synctex_ctxt.busy_name); + } + } + if (SYNCTEX_NO_GZ) { + /* Remove any compressed synctex file, from a previous build. */ + strcat(the_real_syncname, synctex_suffix_gz); + remove(the_real_syncname); + } + } else if ((tmp = GETJOBNAME())) { + size_t len; + /* There was a problem with the output. + We just try to remove existing synctex output files + including the busy one. */ + the_real_syncname = xmalloc((unsigned) + (strlen(tmp) + strlen(synctex_suffix) + + strlen(synctex_suffix_gz) + 1)); + if (!the_real_syncname) { + SYNCTEX_FREE(tmp); + synctexabort(0); + return; + } +# if defined(XeTeX) + strcpy(the_real_syncname, tmp); +# else + len = strlen(tmp); + if (len > 0 && tmp[0] == '"' && tmp[len - 1] == '"') { + /* See above a similar situation. */ + strcpy(the_real_syncname, tmp + 1); /* only copy what follows the leading " character */ + len = strlen(the_real_syncname); + if ((len > 0) && (the_real_syncname[len - 1] == '"')) { + the_real_syncname[len - 1] = '\0'; + } + } else { + strcpy(the_real_syncname, tmp); + } +# endif + SYNCTEX_FREE(tmp); + tmp = NULL; + strcat(the_real_syncname, synctex_suffix); + remove(the_real_syncname); + strcat(the_real_syncname, synctex_suffix_gz); + remove(the_real_syncname); + if (SYNCTEX_FILE) { + /* close the synctex file */ + if (SYNCTEX_NO_GZ) { + xfclose((FILE *) SYNCTEX_FILE, synctex_ctxt.busy_name); + } else { + gzclose((gzFile) SYNCTEX_FILE); + } + SYNCTEX_FILE = NULL; + /* removing the working synctex file */ + remove(synctex_ctxt.busy_name); + } + } + SYNCTEX_FREE(synctex_ctxt.busy_name); + synctex_ctxt.busy_name = NULL; + SYNCTEX_FREE(the_real_syncname); + the_real_syncname = NULL; + synctexabort(0); } static inline int synctex_record_content(void); @@ -594,41 +722,43 @@ static inline int synctex_record_sheet(integer sheet); /* Recording the "{..." line. In *tex.web, use synctex_sheet(pdf_output) at * the very beginning of the ship_out procedure. */ -void synctex_sheet(integer mag) +void synctexsheet(integer mag) { - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG - printf("\nSynchronize DEBUG: synctexsheet %i\n",mag); -#endif + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG + 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."); - } + if (SYNCTEX_VALUE && !SYNCTEX_WARNING_DISABLE) { + SYNCTEX_WARNING_DISABLE = SYNCTEX_TRUE; + 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_NO_ERROR != synctex_dot_open()))) { + 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 + * 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. */ - if(mag>0) { + if (mag > 0) { synctex_ctxt.magnification = mag; } - if(SYNCTEX_NO_ERROR != synctex_record_settings() - || SYNCTEX_NO_ERROR != synctex_record_content()) { - synctex_abort(); - return; - } + if (SYNCTEX_NO_ERROR != synctex_record_settings() + || SYNCTEX_NO_ERROR != synctex_record_content()) { + synctexabort(0); + return; + } } - synctex_record_sheet(totalpages+1); + synctex_record_sheet(totalpages + 1); } -#if SYNCTEX_DEBUG +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexsheet END\n"); -#endif +# endif return; } @@ -637,19 +767,19 @@ static inline int synctex_record_teehs(integer sheet); /* Recording the "}..." line. In *tex.web, use synctex_teehs at * the very end of the ship_out procedure. */ -void synctex_teehs(void) +void synctexteehs(void) { - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexteehs\n"); -#endif - if (SYNCTEX_IS_OFF || !SYNCTEX_FILE ) { +# endif + if (SYNCTEX_IS_OFF || !SYNCTEX_FILE) { return; } - synctex_record_teehs(totalpages);/* not totalpages+1*/ -#if SYNCTEX_DEBUG + synctex_record_teehs(totalpages); /* not totalpages+1 */ +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexteehs END\n"); -#endif +# endif return; } @@ -659,23 +789,21 @@ static inline void synctex_record_vlist(halfword p); * the beginning of the vliSYNCTEX_out procedure in *TeX.web. It will be balanced * by a synctex_tsilv, sent at the end of the vliSYNCTEX_out procedure. p is the * address of the vlist We assume that p is really a vlist node! */ -void synctex_vlist(halfword this_box) +void synctexvlist(halfword this_box) { - scaledpos pos; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexhlist\n"); -#endif +# endif if (SYNCTEX_IGNORE(this_box)) { return; } - synctex_ctxt.node = this_box; /* 0 to reset */ - synctex_ctxt.recorder = NULL; /* reset */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; + synctex_ctxt.node = this_box; /* 0 to reset */ + synctex_ctxt.recorder = NULL; /* reset */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; synctex_record_vlist(this_box); } @@ -685,23 +813,21 @@ static inline void synctex_record_tsilv(halfword p); * has been shipped out. It is used to close the vlist nesting level. It is * sent at the end of the vliSYNCTEX_out procedure in *TeX.web to balance a former * synctex_vlist sent at the beginning of that procedure. */ -void synctex_tsilv(halfword this_box) +void synctextsilv(halfword this_box) { - scaledpos pos; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctextsilv\n"); -#endif +# endif if (SYNCTEX_IGNORE(this_box)) { return; } /* Ignoring any pending info to be recorded */ - synctex_ctxt.node = this_box; /* 0 to reset */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; + synctex_ctxt.node = this_box; /* 0 to reset */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; synctex_ctxt.recorder = NULL; synctex_record_tsilv(this_box); } @@ -710,24 +836,21 @@ static inline void synctex_record_void_vlist(halfword p); /* This message is sent when a void vlist will be shipped out. * There is no need to balance a void vlist. */ -void synctex_void_vlist(halfword p, halfword this_box) +void synctexvoidvlist(halfword p, halfword this_box __attribute__ ((unused))) { - scaledpos pos; - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexvoidvlist\n"); -#endif +# endif if (SYNCTEX_IGNORE(p)) { return; } - synctex_ctxt.node = p; /* reset */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL; /* reset */ + synctex_ctxt.node = p; /* reset */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; + synctex_ctxt.recorder = NULL; /* reset */ synctex_record_void_vlist(p); } @@ -737,23 +860,21 @@ static inline void synctex_record_hlist(halfword p); * the beginning of the hliSYNCTEX_out procedure in *TeX.web. It will be balanced * by a synctex_tsilh, sent at the end of the hliSYNCTEX_out procedure. p is the * address of the hlist We assume that p is really an hlist node! */ -void synctex_hlist(halfword this_box) +void synctexhlist(halfword this_box) { - scaledpos pos; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexhlist\n"); -#endif +# endif if (SYNCTEX_IGNORE(this_box)) { return; } - synctex_ctxt.node = this_box; /* 0 to reset */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL; /* reset */ + synctex_ctxt.node = this_box; /* 0 to reset */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; + synctex_ctxt.recorder = NULL; /* reset */ synctex_record_hlist(this_box); } @@ -763,24 +884,22 @@ static inline void synctex_record_tsilh(halfword p); * has been shipped out it is used to close the hlist nesting level. It is * sent at the end of the hliSYNCTEX_out procedure in *TeX.web to balance a former * synctex_hlist sent at the beginning of that procedure. */ -void synctex_tsilh(halfword this_box) +void synctextsilh(halfword this_box) { - scaledpos pos; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctextsilh\n"); -#endif +# endif if (SYNCTEX_IGNORE(this_box)) { return; } /* Ignoring any pending info to be recorded */ - synctex_ctxt.node = this_box; /* 0 to force next node to be recorded! */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL; /* reset */ + synctex_ctxt.node = this_box; /* 0 to force next node to be recorded! */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(this_box, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(this_box, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; + synctex_ctxt.recorder = NULL; /* reset */ synctex_record_tsilh(this_box); } @@ -788,42 +907,39 @@ static inline void synctex_record_void_hlist(halfword p); /* This message is sent when a void hlist will be shipped out. * There is no need to balance a void hlist. */ -void synctex_void_hlist(halfword p, halfword this_box) +void synctexvoidhlist(halfword p, halfword this_box __attribute__ ((unused))) { - scaledpos pos; - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexvoidhlist\n"); -#endif +# endif if (SYNCTEX_IGNORE(p)) { return; } - /* the sync context has changed */ - if (synctex_ctxt.recorder != NULL) { - /* but was not yet recorded */ - (*synctex_ctxt.recorder) (synctex_ctxt.node); - } - synctex_ctxt.node = p; /* 0 to reset */ - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,box_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,box_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL; /* reset */ + /* the sync context has changed */ + if (synctex_ctxt.recorder != NULL) { + /* but was not yet recorded */ + (*synctex_ctxt.recorder) (synctex_ctxt.node); + } + synctex_ctxt.node = p; /* 0 to reset */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, box_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, box_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; + synctex_ctxt.recorder = NULL; /* reset */ synctex_record_void_hlist(p); } /* glue code: these only work with nodes of size medium_node_size */ -# define small_node_size 3 +# define small_node_size 3 /* see: @d small_node_size=2 {number of words to allocate for most node types} */ -# define medium_node_size (small_node_size+synchronization_field_size) +# define medium_node_size (small_node_size+synchronization_field_size) /* see: @d rule_node_size=4 */ -# /* define rule_node_size (4+synchronization_field_size)*/ +/* # define rule_node_size (4+synchronization_field_size) */ /* IN THE SEQUEL, ALL NODE ARE medium_node_size'd, UNTIL THE CONTRARY IS MENTIONNED */ -# undef SYNCTEX_IGNORE -# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \ +# undef SYNCTEX_IGNORE +# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE \ || (0 >= SYNCTEX_TAG_MODEL(NODE,medium_node_size)) \ || (0 >= SYNCTEX_LINE_MODEL(NODE,medium_node_size)) @@ -831,7 +947,7 @@ void synctex_void_hlist(halfword p, halfword this_box) * the synchronization context remains the same, there is no need to write * synchronization info: it would not help more. The synchronization context * has changed when either the line number or the file tag has changed. */ -# define SYNCTEX_CONTEXT_DID_CHANGE(NODE) ((0 == synctex_ctxt.node)\ +# define SYNCTEX_CONTEXT_DID_CHANGE(NODE) ((0 == synctex_ctxt.node)\ || (SYNCTEX_TAG_MODEL(NODE,medium_node_size) != synctex_ctxt.tag)\ || (SYNCTEX_LINE_MODEL(NODE,medium_node_size) != synctex_ctxt.line)) @@ -839,14 +955,12 @@ void synctex_math_recorder(halfword p); /* glue code this message is sent whenever an inline math node will ship out See: @ @<Output the non-|char_node| |p| for... */ -void synctex_math(halfword p, halfword this_box) +void synctexmath(halfword p, halfword this_box __attribute__ ((unused))) { - scaledpos pos; - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexmath\n"); -#endif +# endif if (SYNCTEX_IGNORE(p)) { return; } @@ -855,13 +969,12 @@ void synctex_math(halfword p, halfword this_box) (*synctex_ctxt.recorder) (synctex_ctxt.node); } synctex_ctxt.node = p; - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL;/* no need to record once more */ - synctex_math_recorder(p);/* always record synchronously */ + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); + synctex_ctxt.curh = CURH; + synctex_ctxt.curv = CURV; + synctex_ctxt.recorder = NULL; /* no need to record once more */ + synctex_math_recorder(p); /* always record synchronously */ } static inline void synctex_record_glue(halfword p); @@ -870,63 +983,60 @@ 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 \ +# 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 synctex_horizontal_rule_or_glue(halfword p, halfword this_box) +void synctexhorizontalruleorglue(halfword p, halfword this_box + __attribute__ ((unused))) { - scaledpos pos; - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexglue\n"); -#endif - 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; - pos = synch_p_with_c(cur); - synctex_ctxt.curh = pos.h - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287); - synctex_ctxt.curv = cur_page_size.v - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287) - pos.v; - synctex_ctxt.recorder = NULL; - switch(SYNCTEX_TYPE(p)) { - case rule_node: - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,rule_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,rule_node_size); - synctex_record_rule(p);/* always record synchronously: maybe some text is outside the box */ - break; - case glue_node: - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); - synctex_record_glue(p);/* always record synchronously: maybe some text is outside the box */ - break; - case kern_node: - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); - synctex_record_kern(p);/* always record synchronously: maybe some text is outside the box */ - break; - default: - printf("\nSynchronize ERROR: unknown node type %i\n",SYNCTEX_TYPE(p)); - } +# endif + 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; + synctex_ctxt.recorder = NULL; + switch (SYNCTEX_TYPE(p)) { + case rule_node: + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, rule_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, rule_node_size); + synctex_record_rule(p); /* always record synchronously: maybe some text is outside the box */ + break; + case glue_node: + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); + synctex_record_glue(p); /* always record synchronously: maybe some text is outside the box */ + break; + case kern_node: + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); + synctex_record_kern(p); /* always record synchronously: maybe some text is outside the box */ + break; + default: + printf("\nSynchronize ERROR: unknown node type %i\n", SYNCTEX_TYPE(p)); + } } void synctex_kern_recorder(halfword p); /* this message is sent whenever a kern node ships out See: @ @<Output the non-|char_node| |p| for... */ -void synctex_kern(halfword p, halfword this_box) +void synctexkern(halfword p, halfword this_box) { - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexkern\n"); -#endif +# endif if (SYNCTEX_IGNORE(p)) { return; } @@ -935,47 +1045,46 @@ void synctex_kern(halfword p, halfword this_box) if (synctex_ctxt.recorder != NULL) { /* but was not yet recorded */ (*synctex_ctxt.recorder) (synctex_ctxt.node); - } - if(synctex_ctxt.node == this_box) { + } + if (synctex_ctxt.node == this_box) { /* first node in the list */ synctex_ctxt.node = p; - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); synctex_ctxt.recorder = &synctex_kern_recorder; } else { synctex_ctxt.node = p; - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); synctex_ctxt.recorder = NULL; /* always record when the context has just changed * and when not the first node */ synctex_kern_recorder(p); } } else { - /* just update the geometry and type (for future improvements) */ + /* just update the geometry and type (for future improvements) */ synctex_ctxt.node = p; - synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p,medium_node_size); - synctex_ctxt.line = SYNCTEX_LINE_MODEL(p,medium_node_size); + synctex_ctxt.tag = SYNCTEX_TAG_MODEL(p, medium_node_size); + synctex_ctxt.line = SYNCTEX_LINE_MODEL(p, medium_node_size); synctex_ctxt.recorder = &synctex_kern_recorder; } } /* This last part is used as a tool to infer TeX behaviour, * but not for direct synchronization. */ -# undef SYNCTEX_IGNORE -# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE \ +# undef SYNCTEX_IGNORE +# define SYNCTEX_IGNORE(NODE) SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE \ || (synctex_ctxt.count>2000) void synctex_char_recorder(halfword p); /* this message is sent whenever a char node ships out */ -void synctex_char(halfword p, halfword this_box) +void synctexchar(halfword p, halfword this_box __attribute__ ((unused))) { - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexchar\n"); -#endif +# endif if (SYNCTEX_IGNORE(p)) { return; } @@ -993,19 +1102,18 @@ void synctex_char(halfword p, halfword this_box) void synctex_node_recorder(halfword p); -# undef SYNCTEX_IGNORE -# define SYNCTEX_IGNORE(NODE) (SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE) +# undef SYNCTEX_IGNORE +# define SYNCTEX_IGNORE(NODE) (SYNCTEX_IS_OFF || !SYNCTEX_VALUE || !SYNCTEX_FILE) /* this message should be sent to record information for a node of an unknown type */ -void synctex_node(halfword p, halfword this_box) +void synctexnode(halfword p, halfword this_box __attribute__ ((unused))) { - (void)this_box; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexnode\n"); -#endif - if (SYNCTEX_IGNORE(p)) { +# endif + if (SYNCTEX_IGNORE(p)) { return; } /* always record, not very usefull yet */ @@ -1014,468 +1122,461 @@ void synctex_node(halfword p, halfword this_box) /* this message should be sent to record information synchronously for the current location */ -void synctex_current(void) +void synctexcurrent(void) { - scaledpos pos; - SYNCTEX_RETURN_IF_DISABLED; -#if SYNCTEX_DEBUG + SYNCTEX_RETURN_IF_DISABLED; +# if SYNCTEX_DEBUG printf("\nSynchronize DEBUG: synctexcurrent\n"); -#endif - if (SYNCTEX_IGNORE(nothing)) { +# endif + if (SYNCTEX_IGNORE(nothing)) { return; } else { - size_t len; - pos = synch_p_with_c(cur); - len = SYNCTEX_fprintf(SYNCTEX_FILE,"x%i,%i:%i,%i\n", - synctex_ctxt.tag,synctex_ctxt.line, - pos.h UNIT,pos.v UNIT); - if(len>0) { - synctex_ctxt.total_length += len; - return; - } - } - synctex_abort(); - return; + integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "x%i,%i:%i,%i\n", + synctex_ctxt.tag, synctex_ctxt.line, + CURH UNIT, CURV UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; + return; + } + } + synctexabort(0); + return; } /* Recording the settings */ static inline int synctex_record_settings(void) { -#if SYNCTEX_DEBUG > 999 +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_settings\n"); -#endif - if(NULL == SYNCTEX_FILE) { +# endif + if (NULL == SYNCTEX_FILE) { return SYNCTEX_NOERR; } - if(SYNCTEX_FILE) { - size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"Output:%s\nMagnification:%i\nUnit:%i\nX Offset:%i\nY Offset:%i\n", - SYNCTEX_OUTPUT,synctex_ctxt.magnification,synctex_ctxt.unit, - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287 UNIT), - ((SYNCTEX_OFFSET_IS_PDF != 0) ? 0 : 4736287 UNIT)); - if(len>0) { - synctex_ctxt.total_length += len; - return SYNCTEX_NOERR; - } - } - synctex_abort(); - return -1; + if (SYNCTEX_FILE) { + integer len = SYNCTEX_fprintf(SYNCTEX_FILE, + "Output:%s\nMagnification:%i\nUnit:%i\nX Offset:%i\nY Offset:%i\n", + SYNCTEX_OUTPUT, + synctex_ctxt.magnification, + synctex_ctxt.unit, + ((SYNCTEX_OFFSET_IS_PDF != + 0) ? 0 : 4736287 UNIT), + ((SYNCTEX_OFFSET_IS_PDF != + 0) ? 0 : 4736287 UNIT)); + if (len > 0) { + synctex_ctxt.total_length += len; + return SYNCTEX_NOERR; + } + } + synctexabort(0); + return -1; } /* Recording a "SyncTeX..." line */ static inline int synctex_record_preamble(void) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_preamble\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"SyncTeX Version:%i\n",SYNCTEX_VERSION); - if(len>0) { - synctex_ctxt.total_length = len; - return SYNCTEX_NOERR; - } - synctex_abort(); - return -1; +# endif + len = + SYNCTEX_fprintf(SYNCTEX_FILE, "SyncTeX Version:%i\n", SYNCTEX_VERSION); + if (len > 0) { + synctex_ctxt.total_length = len; + return SYNCTEX_NOERR; + } + synctexabort(0); + return -1; } /* Recording a "Input:..." line */ static inline int synctex_record_input(integer tag, char *name) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_input\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"Input:%i:%s\n",tag,name); - if(len>0) { - synctex_ctxt.total_length += len; - return SYNCTEX_NOERR; - } - synctex_abort(); - return -1; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "Input:%i:%s\n", tag, name); + if (len > 0) { + synctex_ctxt.total_length += len; + return SYNCTEX_NOERR; + } + synctexabort(0); + return -1; } /* Recording a "!..." line */ static inline int synctex_record_anchor(void) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_anchor\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"!%i\n",synctex_ctxt.total_length); - if(len>0) { - synctex_ctxt.total_length = len; - ++synctex_ctxt.count; - return SYNCTEX_NOERR; - } - synctex_abort(); - return -1; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "!%i\n", synctex_ctxt.total_length); + if (len > 0) { + synctex_ctxt.total_length = len; + ++synctex_ctxt.count; + return SYNCTEX_NOERR; + } + synctexabort(0); + return -1; } /* Recording a "Content" line */ static inline int synctex_record_content(void) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_content\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"Content:\n"); - if(len>0) { - synctex_ctxt.total_length += len; - return SYNCTEX_NOERR; - } - synctex_abort(); - return -1; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "Content:\n"); + if (len > 0) { + synctex_ctxt.total_length += len; + return SYNCTEX_NOERR; + } + synctexabort(0); + return -1; } /* Recording a "{..." line */ static inline int synctex_record_sheet(integer sheet) { -#if SYNCTEX_DEBUG > 999 +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_sheet\n"); -#endif - if(SYNCTEX_NOERR == synctex_record_anchor()) { - size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"{%i\n",sheet); - if(len>0) { - synctex_ctxt.total_length += len; - ++synctex_ctxt.count; - return SYNCTEX_NOERR; - } - } - synctex_abort(); - return -1; +# endif + if (SYNCTEX_NOERR == synctex_record_anchor()) { + integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "{%i\n", sheet); + if (len > 0) { + synctex_ctxt.total_length += len; + ++synctex_ctxt.count; + return SYNCTEX_NOERR; + } + } + synctexabort(0); + return -1; } /* Recording a "}..." line */ static inline int synctex_record_teehs(integer sheet) { -#if SYNCTEX_DEBUG > 999 +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_teehs\n"); -#endif - if(SYNCTEX_NOERR == synctex_record_anchor()) { - size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"}%i\n",sheet); - if(len>0) { - synctex_ctxt.total_length += len; - ++synctex_ctxt.count; - return SYNCTEX_NOERR; - } - } - synctex_abort(); - return -1; +# endif + if (SYNCTEX_NOERR == synctex_record_anchor()) { + integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "}%i\n", sheet); + if (len > 0) { + synctex_ctxt.total_length += len; + ++synctex_ctxt.count; + return SYNCTEX_NOERR; + } + } + synctexabort(0); + return -1; } /* Recording a "v..." line */ static inline void synctex_record_void_vlist(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_void_vlist\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"v%i,%i:%i,%i:%i,%i,%i\n", - SYNCTEX_TAG_MODEL(p,box_node_size), - SYNCTEX_LINE_MODEL(p,box_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT, - SYNCTEX_HEIGHT(p) UNIT, - SYNCTEX_DEPTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "v%i,%i:%i,%i:%i,%i,%i\n", + SYNCTEX_TAG_MODEL(p, box_node_size), + SYNCTEX_LINE_MODEL(p, box_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT, + SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "[..." line */ static inline void synctex_record_vlist(halfword p) { - size_t len = 0; - SYNCTEX_NOT_VOID = SYNCTEX_YES; -#if SYNCTEX_DEBUG > 999 + integer len = 0; + SYNCTEX_NOT_VOID = SYNCTEX_TRUE; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_vlist\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"[%i,%i:%i,%i:%i,%i,%i\n", - SYNCTEX_TAG_MODEL(p,box_node_size), - SYNCTEX_LINE_MODEL(p,box_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT, - SYNCTEX_HEIGHT(p) UNIT, - SYNCTEX_DEPTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "[%i,%i:%i,%i:%i,%i,%i\n", + SYNCTEX_TAG_MODEL(p, box_node_size), + SYNCTEX_LINE_MODEL(p, box_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT, + SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "]..." line */ -static inline void synctex_record_tsilv(halfword p) +static inline void synctex_record_tsilv(halfword p __attribute__ ((unused))) { - size_t len = 0; - (void)p; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_tsilv\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"]\n"); - if(len>0) { - synctex_ctxt.total_length += len; - return; - } - synctex_abort(); - return; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "]\n"); + if (len > 0) { + synctex_ctxt.total_length += len; + return; + } + synctexabort(0); + return; } /* Recording a "h..." line */ static inline void synctex_record_void_hlist(halfword p) { - size_t len = 0; - (void)p; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_void_hlist\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"h%i,%i:%i,%i:%i,%i,%i\n", - SYNCTEX_TAG_MODEL(p,box_node_size), - SYNCTEX_LINE_MODEL(p,box_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT, - SYNCTEX_HEIGHT(p) UNIT, - SYNCTEX_DEPTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "h%i,%i:%i,%i:%i,%i,%i\n", + SYNCTEX_TAG_MODEL(p, box_node_size), + SYNCTEX_LINE_MODEL(p, box_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT, + SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "(..." line */ static inline void synctex_record_hlist(halfword p) { - size_t len = 0; - SYNCTEX_NOT_VOID = SYNCTEX_YES; -#if SYNCTEX_DEBUG > 999 + integer len = 0; + SYNCTEX_NOT_VOID = SYNCTEX_TRUE; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_hlist\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"(%i,%i:%i,%i:%i,%i,%i\n", - SYNCTEX_TAG_MODEL(p,box_node_size), - SYNCTEX_LINE_MODEL(p,box_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT, - SYNCTEX_HEIGHT(p) UNIT, - SYNCTEX_DEPTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "(%i,%i:%i,%i:%i,%i,%i\n", + SYNCTEX_TAG_MODEL(p, box_node_size), + SYNCTEX_LINE_MODEL(p, box_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT, + SYNCTEX_HEIGHT(p) UNIT, SYNCTEX_DEPTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a ")..." line */ -static inline void synctex_record_tsilh(halfword p) +static inline void synctex_record_tsilh(halfword p __attribute__ ((unused))) { - size_t len = 0; - (void)p; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_tsilh\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,")\n"); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, ")\n"); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "Count..." line */ -static inline int synctex_record_count(void) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 +static inline int synctex_record_count(void) +{ + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_count\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"Count:%i\n",synctex_ctxt.count); - if(len>0) { - synctex_ctxt.total_length += len; - return SYNCTEX_NOERR; - } - synctex_abort(); - return -1; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "Count:%i\n", synctex_ctxt.count); + if (len > 0) { + synctex_ctxt.total_length += len; + return SYNCTEX_NOERR; + } + synctexabort(0); + return -1; } /* Recording a "Postamble" section */ static inline int synctex_record_postamble(void) { -#if SYNCTEX_DEBUG > 999 +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_postamble\n"); -#endif - if(SYNCTEX_NOERR == synctex_record_anchor()) { - size_t len = SYNCTEX_fprintf(SYNCTEX_FILE,"Postamble:\n"); - if(len>0) { - synctex_ctxt.total_length += len; - if(synctex_record_count() || synctex_record_anchor()) { - } else { - len = SYNCTEX_fprintf(SYNCTEX_FILE,"Post scriptum:\n"); - if(len>0) { - synctex_ctxt.total_length += len; - return SYNCTEX_NOERR; - } - } - } - } - synctex_abort(); - return -1; +# endif + if (SYNCTEX_NOERR == synctex_record_anchor()) { + integer len = SYNCTEX_fprintf(SYNCTEX_FILE, "Postamble:\n"); + if (len > 0) { + synctex_ctxt.total_length += len; + if (synctex_record_count() || synctex_record_anchor()) { + } else { + len = SYNCTEX_fprintf(SYNCTEX_FILE, "Post scriptum:\n"); + if (len > 0) { + synctex_ctxt.total_length += len; + return SYNCTEX_NOERR; + } + } + } + } + synctexabort(0); + return -1; } /* Recording a "g..." line */ static inline void synctex_record_glue(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_glue_recorder\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"g%i,%i:%i,%i\n", - SYNCTEX_TAG_MODEL(p,medium_node_size), - SYNCTEX_LINE_MODEL(p,medium_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "g%i,%i:%i,%i\n", + SYNCTEX_TAG_MODEL(p, medium_node_size), + SYNCTEX_LINE_MODEL(p, medium_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "k..." line */ static inline void synctex_record_kern(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_kern_recorder\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"k%i,%i:%i,%i:%i\n", - SYNCTEX_TAG_MODEL(p,medium_node_size), - SYNCTEX_LINE_MODEL(p,medium_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "k%i,%i:%i,%i:%i\n", + SYNCTEX_TAG_MODEL(p, medium_node_size), + SYNCTEX_LINE_MODEL(p, medium_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "r..." line */ static inline void synctex_record_rule(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_record_tsilh\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"r%i,%i:%i,%i:%i,%i,%i\n", - SYNCTEX_TAG_MODEL(p,rule_node_size), - SYNCTEX_LINE_MODEL(p,rule_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - rulewd UNIT, - ruleht UNIT, - ruledp UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "r%i,%i:%i,%i:%i,%i,%i\n", + SYNCTEX_TAG_MODEL(p, rule_node_size), + SYNCTEX_LINE_MODEL(p, rule_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + rulewd UNIT, ruleht UNIT, ruledp UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "$..." line */ void synctex_math_recorder(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_math_recorder\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"$%i,%i:%i,%i\n", - SYNCTEX_TAG_MODEL(p,medium_node_size), - SYNCTEX_LINE_MODEL(p,medium_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "$%i,%i:%i,%i\n", + SYNCTEX_TAG_MODEL(p, medium_node_size), + SYNCTEX_LINE_MODEL(p, medium_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "k..." line */ void synctex_kern_recorder(halfword p) { - size_t len = 0; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_kern_recorder\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"k%i,%i:%i,%i:%i\n", - SYNCTEX_TAG_MODEL(p,medium_node_size), - SYNCTEX_LINE_MODEL(p,medium_node_size), - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - SYNCTEX_WIDTH(p) UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "k%i,%i:%i,%i:%i\n", + SYNCTEX_TAG_MODEL(p, medium_node_size), + SYNCTEX_LINE_MODEL(p, medium_node_size), + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + SYNCTEX_WIDTH(p) UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "c..." line */ -void synctex_char_recorder(halfword p) +void synctex_char_recorder(halfword p __attribute__ ((unused))) { - size_t len = 0; - (void)p; -#if SYNCTEX_DEBUG > 999 + integer len = 0; +# if SYNCTEX_DEBUG > 999 printf("\nSynchronize DEBUG: synctex_char_recorder\n"); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"c%i,%i\n", - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); - if(len>0) { - synctex_ctxt.total_length += len; +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "c%i,%i\n", + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } /* Recording a "?..." line, type, subtype and position */ void synctex_node_recorder(halfword p) { - size_t len = 0; - (void)p; -#if SYNCTEX_DEBUG > 999 - printf("\nSynchronize DEBUG: synctex_node_recorder(0x%x)\n",p); -#endif - len = SYNCTEX_fprintf(SYNCTEX_FILE,"?%i,%i:%i,%i\n", - synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, - type(p),subtype(p)); - if(len>0) { - synctex_ctxt.total_length += len; + integer len = 0; +# if SYNCTEX_DEBUG > 999 + printf("\nSynchronize DEBUG: synctex_node_recorder(0x%x)\n", p); +# endif + len = SYNCTEX_fprintf(SYNCTEX_FILE, "?%i,%i:%i,%i\n", + synctex_ctxt.curh UNIT, synctex_ctxt.curv UNIT, + type(p), subtype(p)); + if (len > 0) { + synctex_ctxt.total_length += len; ++synctex_ctxt.count; - return; - } - synctex_abort(); - return; + return; + } + synctexabort(0); + return; } -# else -# warning "SyncTeX is disabled" -# endif +#else +# warning "SyncTeX is disabled" +#endif diff --git a/Build/source/texk/web2c/luatexdir/utils/synctex.h b/Build/source/texk/web2c/luatexdir/utils/synctex.h index 98b11447f20..70d8b805866 100644 --- a/Build/source/texk/web2c/luatexdir/utils/synctex.h +++ b/Build/source/texk/web2c/luatexdir/utils/synctex.h @@ -1,5 +1,7 @@ /* synctex.h +Copyright (c) 2008, 2009 jerome DOT laurens AT u-bourgogne DOT fr + This file is part of the SyncTeX package. Permission is hereby granted, free of charge, to any person @@ -34,80 +36,78 @@ If you include or use a significant part of the synctex package into a software, I would appreciate to be listed as contributor and see "SyncTeX" highlighted. Version 1 -Thu Jun 19 09:39:21 UTC 2008 +Latest Revision: Wed Jul 1 08:17:50 UTC 2009 */ -# ifndef __SYNCTEX_HEADER__ -# define __SYNCTEX_HEADER__ +#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 synctex_init_command(void); +# include "synctex-common.h" -/* Send this message to clean memory, and close the file. */ -extern void synctex_terminate(int log_opened); +/* Free all memory used, close and remove the file if any. */ +void synctexabort(boolean log_opened); /* Send this message when starting a new input. */ -extern void synctex_start_input(void); +extern void synctexstartinput(void); /* Recording the "{..." line. In *tex.web, use synctex_sheet(pdf_output) at * the very beginning of the ship_out procedure. */ -extern void synctex_sheet(integer mag); +extern void synctexsheet(integer mag); /* Recording the "}..." line. In *tex.web, use synctex_teehs at * the very end of the ship_out procedure. */ -extern void synctex_teehs(void); +extern void synctexteehs(void); /* This message is sent when a vlist will be shipped out, more precisely at * the beginning of the vlist_out procedure in *TeX.web. It will be balanced * by a synctex_tsilv, sent at the end of the vlist_out procedure. p is the * address of the vlist We assume that p is really a vlist node! */ -extern void synctex_vlist(halfword this_box); +extern void synctexvlist(halfword this_box); /* Recording a "}" line ending a vbox: this message is sent whenever a vlist * has been shipped out. It is used to close the vlist nesting level. It is * sent at the end of each vlist_out procedure in *TeX.web to balance a former * synctex_vlist sent at the beginning of that procedure. */ -extern void synctex_tsilv(halfword this_box); +extern void synctextsilv(halfword this_box); /* This message is sent when a void vlist will be shipped out. * There is no need to balance a void vlist. */ -extern void synctex_void_vlist(halfword p, halfword this_box); +extern void synctexvoidvlist(halfword p, halfword this_box); /* Send this message when an hlist will be shipped out, more precisely at * the beginning of the hlist_out procedure in *TeX.web. It must be balanced * by a synctex_tsilh, sent at the end of the hlist_out procedure. p is the * address of the hlist. */ -extern void synctex_hlist(halfword this_box); +extern void synctexhlist(halfword this_box); /* Send this message at the end of the various hlist_out procedure in *TeX.web * to balance a former synctex_hlist. */ -extern void synctex_tsilh(halfword this_box); +extern void synctextsilh(halfword this_box); /* This message is sent when a void hlist will be shipped out. * There is no need to balance a void hlist. */ -extern void synctex_void_hlist(halfword p, halfword this_box); +extern void synctexvoidhlist(halfword p, halfword this_box); /* Send this message whenever an inline math node will ship out. */ -extern void synctex_math(halfword p, halfword this_box); +extern void synctexmath(halfword p, halfword this_box); /* Send this message whenever an horizontal rule or glue node will ship out. */ -extern void synctex_horizontal_rule_or_glue(halfword p, halfword this_box); +extern void synctexhorizontalruleorglue(halfword p, halfword this_box); /* Send this message whenever a kern node will ship out. */ -extern void synctex_kern(halfword p, halfword this_box); +extern void synctexkern(halfword p, halfword this_box); /* this message is sent whenever a char node ships out */ -extern void synctex_char(halfword p, halfword this_box); +extern void synctexchar(halfword p, halfword this_box); /* this message should be sent to record information for a node of an unknown type */ -extern void synctex_node(halfword p, halfword this_box); +extern void synctexnode(halfword p, halfword this_box); /* For debugging purpose only */ -extern void synctex_current(void); +extern void synctexcurrent(void); -# endif +#endif diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.c b/Build/source/texk/web2c/luatexdir/utils/utils.c deleted file mode 100644 index b8e715a4a64..00000000000 --- a/Build/source/texk/web2c/luatexdir/utils/utils.c +++ /dev/null @@ -1,1809 +0,0 @@ -/* utils.c - - Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "openbsd-compat.h" - -#include "sys/types.h" -#ifndef __MINGW32__ -# include "sysexits.h" -#else -# define EX_SOFTWARE 70 -#endif -#include "md5.h" -#include <kpathsea/c-proto.h> -#include <kpathsea/c-stat.h> -#include <kpathsea/c-fopen.h> -#include <kpathsea/version.h> -#include <string.h> -#include <time.h> -#include <float.h> /* for DBL_EPSILON */ -#include "zlib.h" -#include "ptexlib.h" -#include "utils.h" - -#include "png.h" -#ifdef POPPLER_VERSION -# define xpdfString "poppler" -# include "poppler-config.h" -# define xpdfVersion POPPLER_VERSION -#else -# define xpdfString "xpdf" -# include "xpdf/config.h" /* just to get the xpdf version */ -#endif - -static const char __svn_version[] = - "$Id: utils.c 2492 2009-06-14 13:14:50Z taco $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/utils.c $"; - -#define check_nprintf(size_get, size_want) \ - if ((unsigned)(size_get) >= (unsigned)(size_want)) \ - pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__); - -char *cur_file_name = NULL; -str_number last_tex_string; -static char print_buf[PRINTF_BUF_SIZE]; -static char *jobname_cstr = NULL; -static char *job_id_string = NULL; - -size_t last_ptr_index; /* for use with alloc_array */ - -/* define fb_ptr, fb_array & fb_limit */ -typedef char fb_entry; -define_array(fb); - -/* define char_ptr, char_array & char_limit */ -typedef char char_entry; -define_array(char); - -integer fb_offset(void) -{ - return fb_ptr - fb_array; -} - -void fb_seek(integer offset) -{ - fb_ptr = fb_array + offset; -} - -void fb_putchar(eight_bits b) -{ - alloc_array(fb, 1, SMALL_ARRAY_SIZE); - *fb_ptr++ = b; -} - -void fb_flush(void) -{ - fb_entry *p; - integer n; - for (p = fb_array; p < fb_ptr;) { - n = pdf_buf_size - pdf_ptr; - if (fb_ptr - p < n) - n = fb_ptr - p; - memcpy(pdf_buf + pdf_ptr, p, (unsigned) n); - pdf_ptr += n; - if (pdf_ptr == pdf_buf_size) - pdf_flush(); - p += n; - } - fb_ptr = fb_array; -} - -#define SUBSET_TAG_LENGTH 6 -void make_subset_tag(fd_entry * fd) -{ - int i, j = 0, a[SUBSET_TAG_LENGTH]; - md5_state_t pms; - char *glyph; - glw_entry *glw_glyph; - struct avl_traverser t; - md5_byte_t digest[16]; - void **aa; - static struct avl_table *st_tree = NULL; - if (st_tree == NULL) - st_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); - assert(fd != NULL); - assert(fd->gl_tree != NULL); - assert(fd->fontname != NULL); - assert(fd->subset_tag == NULL); - fd->subset_tag = xtalloc(SUBSET_TAG_LENGTH + 1, char); - do { - md5_init(&pms); - avl_t_init(&t, fd->gl_tree); - if (is_cidkeyed(fd->fm)) { /* glw_entry items */ - for (glw_glyph = (glw_entry *) avl_t_first(&t, fd->gl_tree); - glw_glyph != NULL; glw_glyph = (glw_entry *) avl_t_next(&t)) { - glyph = malloc(24); - sprintf(glyph, "%05u%05u ", glw_glyph->id, glw_glyph->wd); - md5_append(&pms, (md5_byte_t *) glyph, strlen(glyph)); - free(glyph); - } - } else { - for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL; - glyph = (char *) avl_t_next(&t)) { - md5_append(&pms, (md5_byte_t *) glyph, strlen(glyph)); - md5_append(&pms, (const md5_byte_t *) " ", 1); - } - } - md5_append(&pms, (md5_byte_t *) fd->fontname, strlen(fd->fontname)); - md5_append(&pms, (md5_byte_t *) & j, sizeof(int)); /* to resolve collision */ - md5_finish(&pms, digest); - for (a[0] = 0, i = 0; i < 13; i++) - a[0] += digest[i]; - for (i = 1; i < SUBSET_TAG_LENGTH; i++) - a[i] = a[i - 1] - digest[i - 1] + digest[(i + 12) % 16]; - for (i = 0; i < SUBSET_TAG_LENGTH; i++) - fd->subset_tag[i] = a[i] % 26 + 'A'; - fd->subset_tag[SUBSET_TAG_LENGTH] = '\0'; - j++; - assert(j < 100); - } - while ((char *) avl_find(st_tree, fd->subset_tag) != NULL); - aa = avl_probe(st_tree, fd->subset_tag); - assert(aa != NULL); - if (j > 2) - pdftex_warn - ("\nmake_subset_tag(): subset-tag collision, resolved in round %d.\n", - j); -} - -void pdf_puts(const char *s) -{ - pdfroom(strlen(s) + 1); - while (*s) - pdf_buf[pdf_ptr++] = *s++; -} - -__attribute__ ((format(printf, 1, 2))) -void pdf_printf(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - pdf_puts(print_buf); - va_end(args); -} - -str_number maketexstring(const char *s) -{ - if (s == NULL || *s == 0) - return get_nullstr(); - return maketexlstring(s, strlen(s)); -} - -str_number maketexlstring(const char *s, size_t l) -{ - if (s == NULL || l == 0) - return get_nullstr(); - check_pool_overflow(pool_ptr + l); - while (l-- > 0) - str_pool[pool_ptr++] = *s++; - last_tex_string = make_string(); - return last_tex_string; -} - -/* print a C string through TeX */ -void print_string(const char *j) -{ - while (*j) { - print_char(*j); - j++; - } -} - -/* append a C string to a TeX string */ -void append_string(const char *s) -{ - if (s == NULL || *s == 0) - return; - check_buf(pool_ptr + strlen(s), pool_size); - while (*s) - str_pool[pool_ptr++] = *s++; - return; -} - -__attribute__ ((format(printf, 1, 2))) -void tex_printf(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - print_string(print_buf); - xfflush(stdout); - va_end(args); -} - -/* Helper for pdftex_fail. */ -static void safe_print(const char *str) -{ - const char *c; - for (c = str; *c; ++c) - print(*c); -} - -void remove_pdffile(void) -{ - if (!kpathsea_debug && output_file_name && !fixed_pdf_draftmode) { - xfclose(pdf_file, makecstring(output_file_name)); - remove(makecstring(output_file_name)); - } -} - -/* pdftex_fail may be called when a buffer overflow has happened/is - happening, therefore may not call mktexstring. However, with the - current implementation it appears that error messages are misleading, - possibly because pool overflows are detected too late. - - The output format of this fuction must be the same as pdf_error in - pdftex.web! */ - -__attribute__ ((noreturn, format(printf, 1, 2))) -void pdftex_fail(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - print_ln(); - safe_print("!LuaTeX error"); - if (cur_file_name) { - safe_print(" (file "); - safe_print(cur_file_name); - safe_print(")"); - } - safe_print(": "); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - safe_print(print_buf); - va_end(args); - print_ln(); - remove_pdffile(); - safe_print(" ==> Fatal error occurred, no output PDF file produced!"); - print_ln(); - if (kpathsea_debug) { - abort(); - } else { - exit(EX_SOFTWARE); - } -} - -/* The output format of this fuction must be the same as pdf_warn in - pdftex.web! */ - -__attribute__ ((format(printf, 1, 2))) -void pdftex_warn(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - print_ln(); - tex_printf("LuaTeX warning"); - if (cur_file_name) - tex_printf(" (file %s)", cur_file_name); - tex_printf(": "); - vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); - print_string(print_buf); - va_end(args); - print_ln(); -} - -void tex_error(const char *msg, const char **hlp) -{ - str_number aa = 0, bb = 0, cc = 0, dd = 0, ee = 0; - int k = 0; - if (hlp != NULL) { - while (hlp[k] != NULL) - k++; - if (k > 0) - aa = maketexstring(hlp[0]); - if (k > 1) - bb = maketexstring(hlp[1]); - if (k > 2) - cc = maketexstring(hlp[2]); - if (k > 3) - dd = maketexstring(hlp[3]); - if (k > 4) - ee = maketexstring(hlp[4]); - } - do_print_err(maketexstring(msg)); - flush_str(last_tex_string); - -/* *INDENT-OFF* */ - switch (k) { - case 0: dohelp0(); break; - case 1: dohelp1(aa); break; - case 2: dohelp2(aa, bb); break; - case 3: dohelp3(aa, bb, cc); break; - case 4: dohelp4(aa, bb, cc, dd); break; - case 5: dohelp5(aa, bb, cc, dd, ee); break; - } -/* *INDENT-ON* */ - error(); - - if (ee) - flush_str(ee); - if (dd) - flush_str(dd); - if (cc) - flush_str(cc); - if (bb) - flush_str(bb); - if (aa) - flush_str(aa); -} - -void garbage_warning(void) -{ - pdftex_warn("dangling objects discarded, no output file produced."); - remove_pdffile(); -} - -char *makecstring(integer s) -{ - size_t l; - return makeclstring(s, &l); -} - -char *makeclstring(integer s, size_t * len) -{ - static char *cstrbuf = NULL; - char *p; - static int allocsize; - int allocgrow, i, l; - if (s >= 2097152) { - s -= 2097152; - l = str_start[s + 1] - str_start[s]; - *len = l; - check_buf(l + 1, MAX_CSTRING_LEN); - if (cstrbuf == NULL) { - allocsize = l + 1; - cstrbuf = xmallocarray(char, allocsize); - } else if (l + 1 > allocsize) { - allocgrow = allocsize * 0.2; - if (l + 1 - allocgrow > allocsize) - allocsize = l + 1; - else if (allocsize < MAX_CSTRING_LEN - allocgrow) - allocsize += allocgrow; - else - allocsize = MAX_CSTRING_LEN; - cstrbuf = xreallocarray(cstrbuf, char, allocsize); - } - p = cstrbuf; - for (i = 0; i < l; i++) - *p++ = str_pool[i + str_start[s]]; - *p = 0; - } else { - if (cstrbuf == NULL) { - allocsize = 5; - cstrbuf = xmallocarray(char, allocsize); - } - if (s <= 0x7F) { - cstrbuf[0] = s; - cstrbuf[1] = 0; - *len = 1; - } else if (s <= 0x7FF) { - cstrbuf[0] = 0xC0 + (s / 0x40); - cstrbuf[1] = 0x80 + (s % 0x40); - cstrbuf[2] = 0; - *len = 2; - } else if (s <= 0xFFFF) { - cstrbuf[0] = 0xE0 + (s / 0x1000); - cstrbuf[1] = 0x80 + ((s % 0x1000) / 0x40); - cstrbuf[2] = 0x80 + ((s % 0x1000) % 0x40); - cstrbuf[3] = 0; - *len = 3; - } else { - if (s >= 0x10FF00) { - cstrbuf[0] = s - 0x10FF00; - cstrbuf[1] = 0; - *len = 1; - } else { - cstrbuf[0] = 0xF0 + (s / 0x40000); - cstrbuf[1] = 0x80 + ((s % 0x40000) / 0x1000); - cstrbuf[2] = 0x80 + (((s % 0x40000) % 0x1000) / 0x40); - cstrbuf[3] = 0x80 + (((s % 0x40000) % 0x1000) % 0x40); - cstrbuf[4] = 0; - *len = 4; - } - } - } - return cstrbuf; -} - -void set_job_id(int year, int month, int day, int time) -{ - char *name_string, *format_string, *s; - size_t slen; - int i; - - if (job_id_string != NULL) - return; - - name_string = xstrdup(makecstring(job_name)); - format_string = xstrdup(makecstring(format_ident)); - slen = SMALL_BUF_SIZE + - strlen(name_string) + - strlen(format_string) + - strlen(ptexbanner) + - strlen(versionstring) + strlen(kpathsea_version_string); - s = xtalloc(slen, char); - /* The Web2c version string starts with a space. */ - i = snprintf(s, slen, - "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s%s %s", - year, month, day, time / 60, time % 60, - name_string, format_string, ptexbanner, - versionstring, kpathsea_version_string); - check_nprintf(i, slen); - job_id_string = xstrdup(s); - xfree(s); - xfree(name_string); - xfree(format_string); -} - -void make_pdftex_banner(void) -{ - static boolean pdftexbanner_init = false; - char *s; - size_t slen; - int i; - - if (pdftexbanner_init) - return; - - slen = SMALL_BUF_SIZE + - strlen(ptexbanner) + - strlen(versionstring) + strlen(kpathsea_version_string); - s = xtalloc(slen, char); - /* The Web2c version string starts with a space. */ - i = snprintf(s, slen, - "%s%s %s", ptexbanner, versionstring, kpathsea_version_string); - check_nprintf(i, slen); - pdftex_banner = maketexstring(s); - xfree(s); - pdftexbanner_init = true; -} - -str_number get_resname_prefix(void) -{ -/* static char name_str[] = */ -/* "!\"$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\" */ -/* "^_`abcdefghijklmnopqrstuvwxyz|~"; */ - static char name_str[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - char prefix[7]; /* make a tag of 6 chars long */ - unsigned long crc; - short i; - size_t base = strlen(name_str); - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, (Bytef *) job_id_string, strlen(job_id_string)); - for (i = 0; i < 6; i++) { - prefix[i] = name_str[crc % base]; - crc /= base; - } - prefix[6] = 0; - return maketexstring(prefix); -} - -size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream) -{ - if (fwrite(ptr, size, nmemb, stream) != nmemb) - pdftex_fail("fwrite() failed"); - return nmemb; -} - -int xfflush(FILE * stream) -{ - if (fflush(stream) != 0) - pdftex_fail("fflush() failed (%s)", strerror(errno)); - return 0; -} - -int xgetc(FILE * stream) -{ - int c = getc(stream); - if (c < 0 && c != EOF) - pdftex_fail("getc() failed (%s)", strerror(errno)); - return c; -} - -int xputc(int c, FILE * stream) -{ - int i = putc(c, stream); - if (i < 0) - pdftex_fail("putc() failed (%s)", strerror(errno)); - return i; -} - -void write_stream_length(integer length, longinteger offset) -{ - if (jobname_cstr == NULL) - jobname_cstr = xstrdup(makecstring(job_name)); - if (fixed_pdf_draftmode == 0) { - xfseeko(pdf_file, (off_t) offset, SEEK_SET, jobname_cstr); - fprintf(pdf_file, "%li", (long int) length); - xfseeko(pdf_file, (off_t) pdfoffset(), SEEK_SET, jobname_cstr); - } -} - -scaled ext_xn_over_d(scaled x, scaled n, scaled d) -{ - double r = (((double) x) * ((double) n)) / ((double) d); - if (r > DBL_EPSILON) - r += 0.5; - else - r -= 0.5; - if (r >= (double) max_integer || r <= -(double) max_integer) - pdftex_warn("arithmetic: number too big"); - return (scaled) r; -} - -void libpdffinish(void) -{ - xfree(fb_array); - xfree(char_array); - xfree(job_id_string); - fm_free(); - t1_free(); - enc_free(); - epdf_free(); - ttf_free(); - sfd_free(); - glyph_unicode_free(); - zip_free(); -} - -/* Converts any string given in in in an allowed PDF string which can be - * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and - * control characters are octal encoded. - * This assumes that the string does not contain any already escaped - * characters! - */ -char *convertStringToPDFString(const char *in, int len) -{ - static char pstrbuf[MAX_PSTRING_LEN]; - char *out = pstrbuf; - int i, j, k; - char buf[5]; - j = 0; - for (i = 0; i < len; i++) { - check_buf(j + sizeof(buf), MAX_PSTRING_LEN); - if (((unsigned char) in[i] < '!') || ((unsigned char) in[i] > '~')) { - /* convert control characters into oct */ - k = snprintf(buf, sizeof(buf), - "\\%03o", (unsigned int) (unsigned char) in[i]); - check_nprintf(k, sizeof(buf)); - out[j++] = buf[0]; - out[j++] = buf[1]; - out[j++] = buf[2]; - out[j++] = buf[3]; - } else if ((in[i] == '(') || (in[i] == ')')) { - /* escape paranthesis */ - out[j++] = '\\'; - out[j++] = in[i]; - } else if (in[i] == '\\') { - /* escape backslash */ - out[j++] = '\\'; - out[j++] = '\\'; - } else { - /* copy char :-) */ - out[j++] = in[i]; - } - } - out[j] = '\0'; - return pstrbuf; -} - -/* Converts any string given in in in an allowed PDF string which can be - * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and - * control characters are octal encoded. - * This assumes that the string does not contain any already escaped - * characters! - * - * See escapename for parameter description. - */ -void escapestring(poolpointer in) -{ - const poolpointer out = pool_ptr; - unsigned char ch; - int i; - while (in < out) { - if (pool_ptr + 4 >= pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - - ch = (unsigned char) str_pool[in++]; - - if ((ch < '!') || (ch > '~')) { - /* convert control characters into oct */ - i = snprintf((char *) &str_pool[pool_ptr], 5, - "\\%.3o", (unsigned int) ch); - check_nprintf(i, 5); - pool_ptr += i; - continue; - } - if ((ch == '(') || (ch == ')') || (ch == '\\')) { - /* escape parenthesis and backslash */ - str_pool[pool_ptr++] = '\\'; - } - /* copy char :-) */ - str_pool[pool_ptr++] = ch; - } -} - -/* Convert any given string in a PDF name using escaping mechanism - of PDF 1.2. The result does not include the leading slash. - - PDF specification 1.6, section 3.2.6 "Name Objects" explains: - <blockquote> - Beginning with PDF 1.2, any character except null (character code 0) may - be included in a name by writing its 2-digit hexadecimal code, preceded - by the number sign character (#); see implementation notes 3 and 4 in - Appendix H. This syntax is required to represent any of the delimiter or - white-space characters or the number sign character itself; it is - recommended but not required for characters whose codes are outside the - range 33 (!) to 126 (~). - </blockquote> - The following table shows the conversion that are done by this - function: - code result reason - ----------------------------------- - 0 ignored not allowed - 1..32 escaped must for white-space: - 9 (tab), 10 (lf), 12 (ff), 13 (cr), 32 (space) - recommended for the other control characters - 35 escaped escape char "#" - 37 escaped delimiter "%" - 40..41 escaped delimiters "(" and ")" - 47 escaped delimiter "/" - 60 escaped delimiter "<" - 62 escaped delimiter ">" - 91 escaped delimiter "[" - 93 escaped delimiter "]" - 123 escaped delimiter "{" - 125 escaped delimiter "}" - 127..255 escaped recommended - else copy regular characters - - Parameter "in" is a pointer into the string pool where - the input string is located. The output string is written - as temporary string right after the input string. - Thus at the begin of the procedure the global variable - "pool_ptr" points to the start of the output string and - after the end when the procedure returns. -*/ -void escapename(poolpointer in) -{ - const poolpointer out = pool_ptr; - unsigned char ch; - int i; - - while (in < out) { - if (pool_ptr + 3 >= pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - - ch = (unsigned char) str_pool[in++]; - - if ((ch >= 1 && ch <= 32) || ch >= 127) { - /* escape */ - i = snprintf((char *) &str_pool[pool_ptr], 4, - "#%.2X", (unsigned int) ch); - check_nprintf(i, 4); - pool_ptr += i; - continue; - } - switch (ch) { - case 0: - /* ignore */ - break; - case 35: - case 37: - case 40: - case 41: - case 47: - case 60: - case 62: - case 91: - case 93: - case 123: - case 125: - /* escape */ - i = snprintf((char *) &str_pool[pool_ptr], 4, - "#%.2X", (unsigned int) ch); - check_nprintf(i, 4); - pool_ptr += i; - break; - default: - /* copy */ - str_pool[pool_ptr++] = ch; - } - } -} - -/* Convert any given string in a PDF hexadecimal string. The - result does not include the angle brackets. - - This procedure uses uppercase hexadecimal letters. - - See escapename for description of parameters. -*/ -void escapehex(poolpointer in) -{ - const poolpointer out = pool_ptr; - unsigned char ch; - int i; - - while (in < out) { - if (pool_ptr + 2 >= pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - - ch = (unsigned char) str_pool[in++]; - - i = snprintf((char *) &str_pool[pool_ptr], 3, "%.2X", - (unsigned int) ch); - check_nprintf(i, 3); - pool_ptr += 2; - } -} - -/* Unescape any given hexadecimal string. - - Last hex digit can be omitted, it is replaced by zero, see - PDF specification. - - Invalid digits are silently ignored. - - See escapename for description of parameters. -*/ -void unescapehex(poolpointer in) -{ - const poolpointer out = pool_ptr; - unsigned char ch; - boolean first = true; - unsigned char a = 0; /* to avoid warning about uninitialized use of a */ - while (in < out) { - if (pool_ptr + 1 >= pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - - ch = (unsigned char) str_pool[in++]; - - if ((ch >= '0') && (ch <= '9')) { - ch -= '0'; - } else if ((ch >= 'A') && (ch <= 'F')) { - ch -= 'A' - 10; - } else if ((ch >= 'a') && (ch <= 'f')) { - ch -= 'a' - 10; - } else { - continue; /* ignore wrong character */ - } - - if (first) { - a = ch << 4; - first = false; - continue; - } - - str_pool[pool_ptr++] = a + ch; - first = true; - } - if (!first) { /* last hex digit is omitted */ - str_pool[pool_ptr++] = a; - } -} - -/* Converts any string given in in in an allowed PDF string which is - * hexadecimal encoded; - * sizeof(out) should be at least lin*2+1. - */ - -static void convertStringToHexString(const char *in, char *out, int lin) -{ - int i, j, k; - char buf[3]; - j = 0; - for (i = 0; i < lin; i++) { - k = snprintf(buf, sizeof(buf), - "%02X", (unsigned int) (unsigned char) in[i]); - check_nprintf(k, sizeof(buf)); - out[j++] = buf[0]; - out[j++] = buf[1]; - } - out[j] = '\0'; -} - -/* Compute the ID string as per PDF1.4 9.3: - <blockquote> - File identifers are defined by the optional ID entry in a PDF file's - trailer dictionary (see Section 3.4.4, "File Trailer"; see also - implementation note 105 in Appendix H). The value of this entry is an - array of two strings. The first string is a permanent identifier based - on the contents of the file at the time it was originally created, and - does not change when the file is incrementally updated. The second - string is a changing identifier based on the file's contents at the - time it was last updated. When a file is first written, both - identifiers are set to the same value. If both identifiers match when a - file reference is resolved, it is very likely that the correct file has - been found; if only the first identifier matches, then a different - version of the correct file has been found. - To help ensure the uniqueness of file identifiers, it is recommend - that they be computed using a message digest algorithm such as MD5 - (described in Internet RFC 1321, The MD5 Message-Digest Algorithm; see - the Bibliography), using the following information (see implementation - note 106 in Appendix H): - - The current time - - A string representation of the file's location, usually a pathname - - The size of the file in bytes - - The values of all entries in the file's document information - dictionary (see Section 9.2.1, Document Information Dictionary ) - </blockquote> - This stipulates only that the two IDs must be identical when the file is - created and that they should be reasonably unique. Since it's difficult - to get the file size at this point in the execution of pdfTeX and - scanning the info dict is also difficult, we start with a simpler - implementation using just the first two items. - */ -void print_ID(str_number filename) -{ - time_t t; - size_t size; - char time_str[32]; - md5_state_t state; - md5_byte_t digest[16]; - char id[64]; - char *file_name; - char pwd[4096]; - /* start md5 */ - md5_init(&state); - /* get the time */ - t = time(NULL); - size = strftime(time_str, sizeof(time_str), "%Y%m%dT%H%M%SZ", gmtime(&t)); - md5_append(&state, (const md5_byte_t *) time_str, size); - /* get the file name */ - if (getcwd(pwd, sizeof(pwd)) == NULL) - pdftex_fail("getcwd() failed (%s), (path too long?)", strerror(errno)); - file_name = makecstring(filename); - md5_append(&state, (const md5_byte_t *) pwd, strlen(pwd)); - md5_append(&state, (const md5_byte_t *) "/", 1); - md5_append(&state, (const md5_byte_t *) file_name, strlen(file_name)); - /* finish md5 */ - md5_finish(&state, digest); - /* write the IDs */ - convertStringToHexString((char *) digest, id, 16); - pdf_printf("/ID [<%s> <%s>]", id, id); -} - -/* Print the /CreationDate entry. - - PDF Reference, third edition says about the expected date format: - <blockquote> - 3.8.2 Dates - - PDF defines a standard date format, which closely follows that of - the international standard ASN.1 (Abstract Syntax Notation One), - defined in ISO/IEC 8824 (see the Bibliography). A date is a string - of the form - - (D:YYYYMMDDHHmmSSOHH'mm') - - where - - YYYY is the year - MM is the month - DD is the day (01-31) - HH is the hour (00-23) - mm is the minute (00-59) - SS is the second (00-59) - O is the relationship of local time to Universal Time (UT), - denoted by one of the characters +, -, or Z (see below) - HH followed by ' is the absolute value of the offset from UT - in hours (00-23) - mm followed by ' is the absolute value of the offset from UT - in minutes (00-59) - - The apostrophe character (') after HH and mm is part of the syntax. - All fields after the year are optional. (The prefix D:, although also - optional, is strongly recommended.) The default values for MM and DD - are both 01; all other numerical fields default to zero values. A plus - sign (+) as the value of the O field signifies that local time is - later than UT, a minus sign (-) that local time is earlier than UT, - and the letter Z that local time is equal to UT. If no UT information - is specified, the relationship of the specified time to UT is - considered to be unknown. Whether or not the time zone is known, the - rest of the date should be specified in local time. - - For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard - Time, is represented by the string - - D:199812231952-08'00' - </blockquote> - - The main difficulty is get the time zone offset. strftime() does this in ISO - C99 (e.g. newer glibc) with %z, but we have to work with other systems (e.g. - Solaris 2.5). -*/ - -static time_t start_time = 0; -#define TIME_STR_SIZE 30 -static char start_time_str[TIME_STR_SIZE]; /* minimum size for time_str is 24: "D:YYYYmmddHHMMSS+HH'MM'" */ - -static void makepdftime(time_t t, char *time_str) -{ - struct tm lt, gmt; - size_t size; - int i, off, off_hours, off_mins; - - /* get the time */ - lt = *localtime(&t); - size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", <); - /* expected format: "YYYYmmddHHMMSS" */ - if (size == 0) { - /* unexpected, contents of time_str is undefined */ - time_str[0] = '\0'; - return; - } - - /* correction for seconds: %S can be in range 00..61, - the PDF reference expects 00..59, - therefore we map "60" and "61" to "59" */ - if (time_str[14] == '6') { - time_str[14] = '5'; - time_str[15] = '9'; - time_str[16] = '\0'; /* for safety */ - } - - /* get the time zone offset */ - gmt = *gmtime(&t); - - /* this calculation method was found in exim's tod.c */ - off = 60 * (lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min; - if (lt.tm_year != gmt.tm_year) { - off += (lt.tm_year > gmt.tm_year) ? 1440 : -1440; - } else if (lt.tm_yday != gmt.tm_yday) { - off += (lt.tm_yday > gmt.tm_yday) ? 1440 : -1440; - } - - if (off == 0) { - time_str[size++] = 'Z'; - time_str[size] = 0; - } else { - off_hours = off / 60; - off_mins = abs(off - off_hours * 60); - i = snprintf(&time_str[size], 9, "%+03d'%02d'", off_hours, off_mins); - check_nprintf(i, 9); - } -} - -void init_start_time(void) -{ - if (start_time == 0) { - start_time = time((time_t *) NULL); - makepdftime(start_time, start_time_str); - } -} - -void print_creation_date(void) -{ - init_start_time(); - pdf_printf("/CreationDate (%s)\n", start_time_str); -} - -void print_mod_date(void) -{ - init_start_time(); - pdf_printf("/ModDate (%s)\n", start_time_str); -} - -void getcreationdate(void) -{ - /* put creation date on top of string pool and update pool_ptr */ - size_t len = strlen(start_time_str); - - init_start_time(); - - if ((unsigned) (pool_ptr + len) >= (unsigned) pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - - memcpy(&str_pool[pool_ptr], start_time_str, len); - pool_ptr += len; -} - -/* makecfilename - input/ouput same as makecstring: - input: string number - output: C string with quotes removed. - That means, file names that are legal on some operation systems - cannot any more be used since pdfTeX version 1.30.4. -*/ -char *makecfilename(str_number s) -{ - char *name = makecstring(s); - char *p = name; - char *q = name; - - while (*p) { - if (*p != '"') - *q++ = *p; - p++; - } - *q = '\0'; - return name; -} - -/* function strips trailing zeros in string with numbers; */ -/* leading zeros are not stripped (as in real life) */ -char *stripzeros(char *a) -{ - enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM; - char *p, *q, *r; - for (p = q = r = a; *p != '\0';) { - switch (s) { - case NONUM: - if (*p >= '0' && *p <= '9') - s = INT; - else if (*p == '.') - s = LEADDOT; - break; - case DOTNONUM: - if (*p != '.' && (*p < '0' || *p > '9')) - s = NONUM; - break; - case INT: - if (*p == '.') - s = DOT; - else if (*p < '0' || *p > '9') - s = NONUM; - break; - case DOT: - case LEADDOT: - if (*p >= '0' && *p <= '9') - s = FRAC; - else if (*p == '.') - s = DOTNONUM; - else - s = NONUM; - break; - case FRAC: - if (*p == '.') - s = DOTNONUM; - else if (*p < '0' || *p > '9') - s = NONUM; - break; - default:; - } - switch (s) { - case DOT: - r = q; - break; - case LEADDOT: - r = q + 1; - break; - case FRAC: - if (*p > '0') - r = q + 1; - break; - case NONUM: - if ((t == FRAC || t == DOT) && r != a) { - q = r--; - if (*r == '.') /* was a LEADDOT */ - *r = '0'; - r = a; - } - break; - default:; - } - *q++ = *p++; - t = s; - } - *q = '\0'; - return a; -} - -void initversionstring(char **versions) -{ - (void) asprintf(versions, - "Compiled with libpng %s; using libpng %s\n" - "Compiled with zlib %s; using zlib %s\n" - "Compiled with %s version %s\n", - PNG_LIBPNG_VER_STRING, png_libpng_ver, - ZLIB_VERSION, zlib_version, xpdfString, xpdfVersion); -} - -/*************************************************/ -/* Color Stack and Matrix Transformation Support */ -/*************************************************/ - -/* - In the following array and especially stack data structures are used. - They have the following properties: - - They automatically grow dynamically. - - The size never decreases. - - The variable with name ending in "size" contains the number how many - entries the data structure can hold. - - The variable with name ending in "used" contains the number of - actually used entries. - - Memory of strings in stack entries must be allocated and - freed if the stack is cleared. -*/ - -/* Color Stack */ - -#define STACK_INCREMENT 8 -#define MAX_COLORSTACKS 32768 -/* The colorstack number is stored in two bytes (info field of the node) */ -/* Condition (newcolorstack): MAX_COLORSTACKS mod STACK_INCREMENT = 0 */ - -#define COLOR_DEFAULT "0 g 0 G" -/* literal_modes, see pdftex.web */ -#define SET_ORIGIN 0 -#define DIRECT_PAGE 1 -#define DIRECT_ALWAYS 2 - -/* remember shipout mode: page/form */ -static boolean page_mode; - -typedef struct { - char **page_stack; - char **form_stack; - char *page_current; - char *form_current; - char *form_init; - int page_size; - int form_size; - int page_used; - int form_used; - int literal_mode; - boolean page_start; -} colstack_type; - -static colstack_type *colstacks = NULL; -static int colstacks_size = 0; -static int colstacks_used = 0; - -/* Initialization is done, if the color stacks are used, - init_colorstacks() is defined as macro to avoid unnecessary - procedure calls. -*/ -#define init_colorstacks() if (colstacks_size == 0) colstacks_first_init(); -static void colstacks_first_init(void) -{ - colstacks_size = STACK_INCREMENT; - colstacks = xtalloc(colstacks_size, colstack_type); - colstacks_used = 1; - colstacks[0].page_stack = NULL; - colstacks[0].form_stack = NULL; - colstacks[0].page_size = 0; - colstacks[0].form_size = 0; - colstacks[0].page_used = 0; - colstacks[0].form_used = 0; - colstacks[0].page_current = xstrdup(COLOR_DEFAULT); - colstacks[0].form_current = xstrdup(COLOR_DEFAULT); - colstacks[0].form_init = xstrdup(COLOR_DEFAULT); - colstacks[0].literal_mode = DIRECT_ALWAYS; - colstacks[0].page_start = true; -} - -int colorstackused(void) -{ - init_colorstacks(); - return colstacks_used; -} - -/* newcolorstack() - A new color stack is setup with the given parameters. - The stack number is returned or -1 in case of error (no room). -*/ -int newcolorstack(integer s, integer literal_mode, boolean page_start) -{ - colstack_type *colstack; - int colstack_num; - char *str; - - init_colorstacks(); - - /* make room */ - if (colstacks_used == MAX_COLORSTACKS) { - return -1; - } - if (colstacks_used == colstacks_size) { - colstacks_size += STACK_INCREMENT; - /* If (MAX_COLORSTACKS mod STACK_INCREMENT = 0) then we don't - need to check the case that size overruns MAX_COLORSTACKS. */ - colstacks = xreallocarray(colstacks, colstack_type, colstacks_size); - } - /* claim new color stack */ - colstack_num = colstacks_used++; - colstack = &colstacks[colstack_num]; - /* configure the new color stack */ - colstack->page_stack = NULL; - colstack->form_stack = NULL; - colstack->page_size = 0; - colstack->page_used = 0; - colstack->form_size = 0; - colstack->form_used = 0; - colstack->literal_mode = literal_mode; - colstack->page_start = page_start; - str = makecstring(s); - if (*str == 0) { - colstack->page_current = NULL; - colstack->form_current = NULL; - colstack->form_init = NULL; - } else { - colstack->page_current = xstrdup(str); - colstack->form_current = xstrdup(str); - colstack->form_init = xstrdup(str); - } - return colstack_num; -} - -#define get_colstack(n) (&colstacks[n]) - -/* Puts a string on top of the string pool and updates pool_ptr. */ -static void put_cstring_on_str_pool(poolpointer start, char *str) -{ - size_t len; - - if (str == NULL || *str == 0) { - return; - } - - len = strlen(str); - pool_ptr = start + len; - if (pool_ptr >= pool_size) { - pool_ptr = pool_size; - /* error by str_toks that calls str_room(1) */ - return; - } - memcpy(&str_pool[start], str, len); -} - -integer colorstackset(int colstack_no, integer s) -{ - colstack_type *colstack = get_colstack(colstack_no); - - if (page_mode) { - xfree(colstack->page_current); - colstack->page_current = xstrdup(makecstring(s)); - } else { - xfree(colstack->form_current); - colstack->form_current = xstrdup(makecstring(s)); - } - return colstack->literal_mode; -} - -integer colorstackcurrent(int colstack_no) -{ - colstack_type *colstack = get_colstack(colstack_no); - - if (page_mode) { - put_cstring_on_str_pool(pool_ptr, colstack->page_current); - } else { - put_cstring_on_str_pool(pool_ptr, colstack->form_current); - } - return colstack->literal_mode; -} - -integer colorstackpush(int colstack_no, integer s) -{ - colstack_type *colstack = get_colstack(colstack_no); - char *str; - - if (page_mode) { - if (colstack->page_used == colstack->page_size) { - colstack->page_size += STACK_INCREMENT; - colstack->page_stack = xretalloc(colstack->page_stack, - colstack->page_size, char *); - } - colstack->page_stack[colstack->page_used++] = colstack->page_current; - str = makecstring(s); - if (*str == 0) { - colstack->page_current = NULL; - } else { - colstack->page_current = xstrdup(str); - } - } else { - if (colstack->form_used == colstack->form_size) { - colstack->form_size += STACK_INCREMENT; - colstack->form_stack = xretalloc(colstack->form_stack, - colstack->form_size, char *); - } - colstack->form_stack[colstack->form_used++] = colstack->form_current; - str = makecstring(s); - if (*str == 0) { - colstack->form_current = NULL; - } else { - colstack->form_current = xstrdup(str); - } - } - return colstack->literal_mode; -} - -integer colorstackpop(int colstack_no) -{ - colstack_type *colstack = get_colstack(colstack_no); - - if (page_mode) { - if (colstack->page_used == 0) { - pdftex_warn("pop empty color page stack %u", - (unsigned int) colstack_no); - return colstack->literal_mode; - } - xfree(colstack->page_current); - colstack->page_current = colstack->page_stack[--colstack->page_used]; - put_cstring_on_str_pool(pool_ptr, colstack->page_current); - } else { - if (colstack->form_used == 0) { - pdftex_warn("pop empty color form stack %u", - (unsigned int) colstack_no); - return colstack->literal_mode; - } - xfree(colstack->form_current); - colstack->form_current = colstack->form_stack[--colstack->form_used]; - put_cstring_on_str_pool(pool_ptr, colstack->form_current); - } - return colstack->literal_mode; -} - -static void colorstackpagestart(void) -{ - int i, j; - colstack_type *colstack; - - if (page_mode) { - /* see procedure pdf_out_colorstack_startpage */ - return; - } - - for (i = 0; i < colstacks_used; i++) { - colstack = &colstacks[i]; - for (j = 0; j < colstack->form_used; j++) { - xfree(colstack->form_stack[j]); - } - colstack->form_used = 0; - xfree(colstack->form_current); - if (colstack->form_init == NULL) { - colstack->form_current = NULL; - } else { - colstack->form_current = xstrdup(colstack->form_init); - } - } -} - -integer colorstackskippagestart(int colstack_no) -{ - colstack_type *colstack = get_colstack(colstack_no); - - if (!colstack->page_start) { - return 1; - } - if (colstack->page_current == NULL) { - return 0; - } - if (strcmp(COLOR_DEFAULT, colstack->page_current) == 0) { - return 2; - } - return 0; -} - -/* stack for \pdfsetmatrix */ - -typedef struct { - double a; - double b; - double c; - double d; - double e; - double f; -} matrix_entry; -static matrix_entry *matrix_stack = 0; -static int matrix_stack_size = 0; -static int matrix_stack_used = 0; - -boolean matrixused(void) -{ - return matrix_stack_used > 0; -} - -/* stack for positions of \pdfsave */ -typedef struct { - scaledpos pos; - int matrix_stack; -} pos_entry; -static pos_entry *pos_stack = 0; /* the stack */ -static int pos_stack_size = 0; /* initially empty */ -static int pos_stack_used = 0; /* used entries */ - -static void matrix_stack_room(void) -{ - matrix_entry *new_stack; - - if (matrix_stack_used >= matrix_stack_size) { - matrix_stack_size += STACK_INCREMENT; - new_stack = xtalloc(matrix_stack_size, matrix_entry); - memcpy((void *) new_stack, (void *) matrix_stack, - matrix_stack_used * sizeof(matrix_entry)); - xfree(matrix_stack); - matrix_stack = new_stack; - } -} - -void checkpdfsave(scaledpos pos) -{ - pos_entry *new_stack; - - if (pos_stack_used >= pos_stack_size) { - pos_stack_size += STACK_INCREMENT; - new_stack = xtalloc(pos_stack_size, pos_entry); - memcpy((void *) new_stack, (void *) pos_stack, - pos_stack_used * sizeof(pos_entry)); - xfree(pos_stack); - pos_stack = new_stack; - } - pos_stack[pos_stack_used].pos.h = pos.h; - pos_stack[pos_stack_used].pos.v = pos.v; - if (page_mode) { - pos_stack[pos_stack_used].matrix_stack = matrix_stack_used; - } - pos_stack_used++; -} - -void checkpdfrestore(scaledpos pos) -{ - scaledpos diff; - if (pos_stack_used == 0) { - pdftex_warn("%s", "\\pdfrestore: missing \\pdfsave"); - return; - } - pos_stack_used--; - diff.h = pos.h - pos_stack[pos_stack_used].pos.h; - diff.v = pos.v - pos_stack[pos_stack_used].pos.v; - if (diff.h != 0 || diff.v != 0) { - pdftex_warn("Misplaced \\pdfrestore by (%dsp, %dsp)", (int) diff.h, - (int) diff.v); - } - if (page_mode) { - matrix_stack_used = pos_stack[pos_stack_used].matrix_stack; - } -} - -void pdfshipoutbegin(boolean shipping_page) -{ - pos_stack_used = 0; /* start with empty stack */ - - page_mode = shipping_page; - if (shipping_page) { - colorstackpagestart(); - } -} - -void pdfshipoutend(boolean shipping_page) -{ - if (pos_stack_used > 0) { - pdftex_fail("%u unmatched \\pdfsave after %s shipout", - (unsigned int) pos_stack_used, - ((shipping_page) ? "page" : "form")); - } -} - -/* \pdfsetmatrix{a b c d} - e := pos.h - f := pos.v - M_top: current active matrix at the top of - the matrix stack - - The origin of \pdfsetmatrix is the current point. - The annotation coordinate system is the original - page coordinate system. When pdfTeX calculates - annotation rectangles it does not take into - account this transformations, it uses the original - coordinate system. To get the corrected values, - first we go back to the origin, perform the - transformation and go back: - - ( 1 0 0 ) ( a b 0 ) ( 1 0 0 ) - ( 0 1 0 ) x ( c d 0 ) x ( 0 1 0 ) x M_top - ( -e -f 1 ) ( 0 0 1 ) ( e f 1 ) - - ( 1 0 0 ) ( a b 0 ) - = ( 0 1 0 ) x ( c d 0 ) x M_top - ( e f 1 ) ( -e -f 1 ) - - ( a b 0 ) - = ( c d 0 ) x M_top - ( e(1-a)-fc f(1-d)-eb 1 ) - -*/ - -void pdfsetmatrix(poolpointer in, scaledpos pos) -{ - /* Argument of \pdfsetmatrix starts with str_pool[in] and ends - before str_pool[pool_ptr]. */ - - matrix_entry x, *y, *z; - - if (page_mode) { - if (sscanf((const char *) &str_pool[in], " %lf %lf %lf %lf ", - &x.a, &x.b, &x.c, &x.d) != 4) { - pdftex_warn("Unrecognized format of \\pdfsetmatrix{%s}", - &str_pool[pool_ptr]); - return; - } - /* calculate this transformation matrix */ - x.e = (double) pos.h * (1.0 - x.a) - (double) pos.v * x.c; - x.f = (double) pos.v * (1.0 - x.d) - (double) pos.h * x.b; - matrix_stack_room(); - z = &matrix_stack[matrix_stack_used]; - if (matrix_stack_used > 0) { - y = &matrix_stack[matrix_stack_used - 1]; - z->a = x.a * y->a + x.b * y->c; - z->b = x.a * y->b + x.b * y->d; - z->c = x.c * y->a + x.d * y->c; - z->d = x.c * y->b + x.d * y->d; - z->e = x.e * y->a + x.f * y->c + y->e; - z->f = x.e * y->b + x.f * y->d + y->f; - } else { - z->a = x.a; - z->b = x.b; - z->c = x.c; - z->d = x.d; - z->e = x.e; - z->f = x.f; - } - matrix_stack_used++; - } -} - -/* Apply matrix to point (x,y) - - ( a b 0 ) - ( x y 1 ) x ( c d 0 ) = ( xa+yc+e xb+yd+f 1 ) - ( e f 1 ) - - If \pdfsetmatrix wasn't used, then return the value unchanged. -*/ - -/* Return valeus for matrix tranform functions */ -static scaled ret_llx; -static scaled ret_lly; -static scaled ret_urx; -static scaled ret_ury; - -scaled getllx(void) -{ - return ret_llx; -} - -scaled getlly(void) -{ - return ret_lly; -} - -scaled geturx(void) -{ - return ret_urx; -} - -scaled getury(void) -{ - return ret_ury; -} - -static int last_llx; -static int last_lly; -static int last_urx; -static int last_ury; - -#define DO_ROUND(x) ((x > 0) ? (x + .5) : (x - .5)) -#define DO_MIN(a, b) ((a < b) ? a : b) -#define DO_MAX(a, b) ((a > b) ? a : b) - -static void do_matrixtransform(scaled x, scaled y, scaled * retx, scaled * rety) -{ - matrix_entry *m = &matrix_stack[matrix_stack_used - 1]; - double x_old = x; - double y_old = y; - double x_new = x_old * m->a + y_old * m->c + m->e; - double y_new = x_old * m->b + y_old * m->d + m->f; - *retx = (scaled) DO_ROUND(x_new); - *rety = (scaled) DO_ROUND(y_new); -} - -void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury) -{ - scaled x1, x2, x3, x4, y1, y2, y3, y4; - - if (page_mode && matrix_stack_used > 0) { - last_llx = llx; - last_lly = lly; - last_urx = urx; - last_ury = ury; - do_matrixtransform(llx, lly, &x1, &y1); - do_matrixtransform(llx, ury, &x2, &y2); - do_matrixtransform(urx, lly, &x3, &y3); - do_matrixtransform(urx, ury, &x4, &y4); - ret_llx = DO_MIN(DO_MIN(x1, x2), DO_MIN(x3, x4)); - ret_lly = DO_MIN(DO_MIN(y1, y2), DO_MIN(y3, y4)); - ret_urx = DO_MAX(DO_MAX(x1, x2), DO_MAX(x3, x4)); - ret_ury = DO_MAX(DO_MAX(y1, y2), DO_MAX(y3, y4)); - } else { - ret_llx = llx; - ret_lly = lly; - ret_urx = urx; - ret_ury = ury; - } -} - -void matrixtransformpoint(scaled x, scaled y) -{ - if (page_mode && matrix_stack_used > 0) { - do_matrixtransform(x, y, &ret_llx, &ret_lly); - } else { - ret_llx = x; - ret_lly = y; - } -} - -void matrixrecalculate(scaled urx) -{ - matrixtransformrect(last_llx, last_lly, urx, last_ury); -} - -void check_buffer_overflow(int wsize) -{ - int nsize; - if (wsize > buf_size) { - nsize = buf_size + buf_size / 5 + 5; - if (nsize < wsize) { - nsize = wsize + 5; - } - buffer = (unsigned char *) xreallocarray(buffer, char, nsize); - buf_size = nsize; - } -} - -#define EXTRA_STRING 500 - -void check_pool_overflow(int wsize) -{ - int nsize; - if ((wsize - 1) > pool_size) { - nsize = pool_size + pool_size / 5 + EXTRA_STRING; - if (nsize < wsize) { - nsize = wsize + EXTRA_STRING; - } - str_pool = (unsigned char *) xreallocarray(str_pool, char, nsize); - pool_size = nsize; - } -} - -#define max_integer 0x7FFFFFFF - -/* the return value is a decimal number with the point |dd| places from the back, - |scaled_out| is the number of scaled points corresponding to that. -*/ - -scaled divide_scaled(scaled s, scaled m, integer dd) -{ - register scaled q; - register scaled r; - int i; - int sign = 1; - if (s < 0) { - sign = -sign; - s = -s; - } - if (m < 0) { - sign = -sign; - m = -m; - } - if (m == 0) { - pdf_error(maketexstring("arithmetic"), - maketexstring("divided by zero")); - } else if (m >= (max_integer / 10)) { - pdf_error(maketexstring("arithmetic"), maketexstring("number too big")); - } - q = s / m; - r = s % m; - for (i = 1; i <= (int) dd; i++) { - q = 10 * q + (10 * r) / m; - r = (10 * r) % m; - } - /* rounding */ - if (2 * r >= m) { - q++; - r -= m; - } - return sign * q; -} - -/* Same function, but using doubles instead of integers (faster) */ - -scaled divide_scaled_n(double sd, double md, double n) -{ - double dd, di = 0.0; - dd = sd / md * n; - if (dd > 0.0) - di = floor(dd + 0.5); - else if (dd < 0.0) - di = -floor((-dd) + 0.5); - return (scaled) di; -} - - -/* C print interface */ - -void tprint(const char *s) -{ - const unsigned char *ss = (const unsigned char*) s; - while (*ss) - print_char(*ss++); -} - -void tprint_nl(const char *s) -{ - print_nlp(); - tprint(s); -} - -#define escape_char_code 45 /* escape character for token output */ -#define int_par(a) zeqtb[static_int_base+(a)].cint /* an integer parameter */ -#define escape_char int_par(escape_char_code) - -void tprint_esc(const char *s) -{ /* prints escape character, then |s| */ - int c = -1; /* the escape character code */ - if (zeqtb != NULL) { - c = escape_char; - if (c >= 0) - print_char(c); - } - tprint(s); -} - -void tconfusion(const char *s) -{ - confusion(maketexstring(s)); -} - -#ifdef MSVC - -# include <math.h> -double rint(double x) -{ - double c, f, d1, d2; - - c = ceil(x); - f = floor(x); - d1 = fabs(c - x); - d2 = fabs(x - f); - if (d1 > d2) - return f; - else - return c; -} - -#endif diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.h b/Build/source/texk/web2c/luatexdir/utils/utils.h index eaa928387f0..82420025eaa 100644 --- a/Build/source/texk/web2c/luatexdir/utils/utils.h +++ b/Build/source/texk/web2c/luatexdir/utils/utils.h @@ -18,93 +18,36 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -/* $Id: utils.h 2333 2009-04-18 17:45:46Z hhenkel $ */ +/* $Id: utils.h 3261 2009-12-18 11:38:21Z taco $ */ #ifndef UTILS_H # define UTILS_H -# define overflow_string(a,b) { overflow(maketexstring(a),b); flush_str(last_tex_string); } +extern int epochseconds; +extern int microseconds; +extern char *pdftex_banner; -integer fb_offset(void); -void fb_flush(void); -void fb_putchar(eight_bits b); -void fb_seek(integer); void make_subset_tag(fd_entry *); -void pdf_puts(const char *); -__attribute__ ((format(printf, 1, 2))) -void pdf_printf(const char *, ...); -str_number maketexstring(const char *); -str_number maketexlstring(const char *, size_t); -void print_string(const char *j); -void append_string(const char *s); + __attribute__ ((format(printf, 1, 2))) void tex_printf(const char *, ...); -void remove_pdffile(void); + __attribute__ ((noreturn, format(printf, 1, 2))) void pdftex_fail(const char *, ...); __attribute__ ((format(printf, 1, 2))) void pdftex_warn(const char *, ...); -void tex_error(const char *msg, const char **hlp); void garbage_warning(void); -char *makecstring(integer); -char *makeclstring(integer, size_t *); -void set_job_id(int, int, int, int); void make_pdftex_banner(void); -str_number get_resname_prefix(void); size_t xfwrite(void *, size_t size, size_t nmemb, FILE *); int xfflush(FILE *); int xgetc(FILE *); int xputc(int, FILE *); -void write_stream_length(integer, longinteger); scaled ext_xn_over_d(scaled, scaled, scaled); -void libpdffinish(void); -char *convertStringToPDFString(const char *in, int len); -void escapestring(poolpointer in); -void escapename(poolpointer in); -void escapehex(poolpointer in); -void unescapehex(poolpointer in); -void print_ID(str_number); -void init_start_time(void); -void print_creation_date(void); -void print_mod_date(void); -void getcreationdate(void); -char *makecfilename(str_number s); char *stripzeros(char *); void initversionstring(char **versions); extern void check_buffer_overflow(int wsize); extern void check_pool_overflow(int wsize); -extern str_number last_tex_string; extern char *cur_file_name; -extern size_t last_ptr_index; -extern char *fb_array; - -/**********************************************************************/ -/* color stack and matrix transformation support */ - -int newcolorstack(integer s, integer literal_mode, boolean pagestart); -int colorstackused(void); -integer colorstackset(int colstack_no, integer s); -integer colorstackpush(int colstack_no, integer s); -integer colorstackpop(int colstack_no); -integer colorstackcurrent(int colstack_no); -integer colorstackskippagestart(int colstack_no); -void checkpdfsave(scaledpos pos); -void checkpdfrestore(scaledpos pos); -void pdfshipoutbegin(boolean shipping_page); -void pdfshipoutend(boolean shipping_page); -void pdfsetmatrix(poolpointer in, scaledpos pos); -scaled getllx(void); -scaled getlly(void); -scaled geturx(void); -scaled getury(void); -void tconfusion(const char *s); -void tprint(const char *s); -void tprint_nl(const char *s); -void tprint_esc(const char *s); -void matrixtransformpoint(scaled x, scaled y); -void matrixtransformrect(scaled llx, scaled lly, scaled urx, scaled ury); -boolean matrixused(void); -void matrixrecalculate(scaled urx); #endif /* UTILS_H */ diff --git a/Build/source/texk/web2c/luatexdir/utils/utils.w b/Build/source/texk/web2c/luatexdir/utils/utils.w new file mode 100644 index 00000000000..777f153ddf4 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/utils/utils.w @@ -0,0 +1,465 @@ +% utils.w + +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c +static const char _svn_version[] = + "$Id: utils.w 3584 2010-04-02 17:45:55Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/utils/utils.w $"; + +@ @c +#include "openbsd-compat.h" +#include <kpathsea/config.h> /* this is a trick to load mingw32's io.h early, + using a macro redefinition of |eof()|. */ +#ifdef HAVE_ASPRINTF /* asprintf is not defined in openbsd-compat.h, but in stdio.h */ +# include <stdio.h> +#endif + +#include "sys/types.h" +#ifndef __MINGW32__ +# include "sysexits.h" +#else +# define EX_SOFTWARE 70 +#endif +#include <kpathsea/c-stat.h> +#include <kpathsea/c-fopen.h> +#include <string.h> +#include <time.h> +#include <float.h> /* for |DBL_EPSILON| */ +#include "zlib.h" +#include "ptexlib.h" +#include "md5.h" + +#include "lua/luatex-api.h" /* for ptexbanner */ + +#include "png.h" +#ifdef POPPLER_VERSION +# define xpdfString "poppler" +# include "poppler-config.h" +# define xpdfVersion POPPLER_VERSION +#else +# define xpdfString "xpdf" +# include "xpdf/config.h" /* just to get the xpdf version */ +#endif + +@ @c +#define check_nprintf(size_get, size_want) \ + if ((unsigned)(size_get) >= (unsigned)(size_want)) \ + pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__); + +char *cur_file_name = NULL; +static char print_buf[PRINTF_BUF_SIZE]; +int epochseconds; +int microseconds; + +/* define |char_ptr|, |char_array|, and |char_limit| */ +typedef char char_entry; +define_array(char); + +@ @c +#define SUBSET_TAG_LENGTH 6 +void make_subset_tag(fd_entry * fd) +{ + int i, j = 0, a[SUBSET_TAG_LENGTH]; + md5_state_t pms; + char *glyph; + glw_entry *glw_glyph; + struct avl_traverser t; + md5_byte_t digest[16]; + void **aa; + static struct avl_table *st_tree = NULL; + if (st_tree == NULL) + st_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); + assert(fd != NULL); + assert(fd->gl_tree != NULL); + assert(fd->fontname != NULL); + assert(fd->subset_tag == NULL); + fd->subset_tag = xtalloc(SUBSET_TAG_LENGTH + 1, char); + do { + md5_init(&pms); + avl_t_init(&t, fd->gl_tree); + if (is_cidkeyed(fd->fm)) { /* |glw_entry| items */ + for (glw_glyph = (glw_entry *) avl_t_first(&t, fd->gl_tree); + glw_glyph != NULL; glw_glyph = (glw_entry *) avl_t_next(&t)) { + glyph = malloc(24); + sprintf(glyph, "%05u%05u ", glw_glyph->id, glw_glyph->wd); + md5_append(&pms, (md5_byte_t *) glyph, (int) strlen(glyph)); + free(glyph); + } + } else { + for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL; + glyph = (char *) avl_t_next(&t)) { + md5_append(&pms, (md5_byte_t *) glyph, (int) strlen(glyph)); + md5_append(&pms, (const md5_byte_t *) " ", 1); + } + } + md5_append(&pms, (md5_byte_t *) fd->fontname, + (int) strlen(fd->fontname)); + md5_append(&pms, (md5_byte_t *) & j, sizeof(int)); /* to resolve collision */ + md5_finish(&pms, digest); + for (a[0] = 0, i = 0; i < 13; i++) + a[0] += digest[i]; + for (i = 1; i < SUBSET_TAG_LENGTH; i++) + a[i] = a[i - 1] - digest[i - 1] + digest[(i + 12) % 16]; + for (i = 0; i < SUBSET_TAG_LENGTH; i++) + fd->subset_tag[i] = (char) (a[i] % 26 + 'A'); + fd->subset_tag[SUBSET_TAG_LENGTH] = '\0'; + j++; + assert(j < 100); + } + while ((char *) avl_find(st_tree, fd->subset_tag) != NULL); + aa = avl_probe(st_tree, fd->subset_tag); + assert(aa != NULL); + if (j > 2) + pdftex_warn + ("\nmake_subset_tag(): subset-tag collision, resolved in round %d.\n", + j); +} + +@ @c +__attribute__ ((format(printf, 1, 2))) +void tex_printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); + tprint(print_buf); + xfflush(stdout); + va_end(args); +} + +@ |pdftex_fail| may be called when a buffer overflow has happened/is + happening, therefore may not call mktexstring. However, with the + current implementation it appears that error messages are misleading, + possibly because pool overflows are detected too late. + + The output format of this fuction must be the same as |pdf_error| in + pdftex.web! + +@c +__attribute__ ((noreturn, format(printf, 1, 2))) +void pdftex_fail(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + print_ln(); + tprint("!LuaTeX error"); + if (cur_file_name) { + tprint(" (file "); + tprint(cur_file_name); + tprint(")"); + } + tprint(": "); + vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); + tprint(print_buf); + va_end(args); + print_ln(); + remove_pdffile(static_pdf); + tprint(" ==> Fatal error occurred, no output PDF file produced!"); + print_ln(); + if (kpathsea_debug) { + abort(); + } else { + exit(EX_SOFTWARE); + } +} + +@ The output format of this fuction must be the same as |pdf_warn| in + pdftex.web! +@c +__attribute__ ((format(printf, 1, 2))) +void pdftex_warn(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + print_ln(); + tex_printf("LuaTeX warning"); + if (cur_file_name) + tex_printf(" (file %s)", cur_file_name); + tex_printf(": "); + vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args); + tprint(print_buf); + va_end(args); + print_ln(); +} + +@ @c +void garbage_warning(void) +{ + pdftex_warn("dangling objects discarded, no output file produced."); + remove_pdffile(static_pdf); +} + +@ @c +char *pdftex_banner = NULL; + +@ @c +void make_pdftex_banner(void) +{ + char *s; + unsigned int slen; + int i; + + if (pdftex_banner != NULL) + return; + + slen = (unsigned int) (SMALL_BUF_SIZE + + strlen(ptexbanner) + + strlen(versionstring) + + strlen(kpathsea_version_string)); + s = xtalloc(slen, char); + /* The Web2c version string starts with a space. */ + i = snprintf(s, slen, + "%s%s %s", ptexbanner, versionstring, kpathsea_version_string); + check_nprintf(i, slen); + pdftex_banner = s; +} + +@ @c +size_t xfwrite(void *ptr, size_t size, size_t nmemb, FILE * stream) +{ + if (fwrite(ptr, size, nmemb, stream) != nmemb) + pdftex_fail("fwrite() failed"); + return nmemb; +} + +@ @c +int xfflush(FILE * stream) +{ + if (fflush(stream) != 0) + pdftex_fail("fflush() failed (%s)", strerror(errno)); + return 0; +} + +@ @c +int xgetc(FILE * stream) +{ + int c = getc(stream); + if (c < 0 && c != EOF) + pdftex_fail("getc() failed (%s)", strerror(errno)); + return c; +} + +@ @c +int xputc(int c, FILE * stream) +{ + int i = putc(c, stream); + if (i < 0) + pdftex_fail("putc() failed (%s)", strerror(errno)); + return i; +} + +@ @c +scaled ext_xn_over_d(scaled x, scaled n, scaled d) +{ + double r = (((double) x) * ((double) n)) / ((double) d); + if (r > DBL_EPSILON) + r += 0.5; + else + r -= 0.5; + if (r >= (double) max_integer || r <= -(double) max_integer) + pdftex_warn("arithmetic: number too big"); + return (scaled) r; +} + +@ function strips trailing zeros in string with numbers; +leading zeros are not stripped (as in real life) +@c +char *stripzeros(char *a) +{ + enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM; + char *p, *q, *r; + for (p = q = r = a; *p != '\0';) { + switch (s) { + case NONUM: + if (*p >= '0' && *p <= '9') + s = INT; + else if (*p == '.') + s = LEADDOT; + break; + case DOTNONUM: + if (*p != '.' && (*p < '0' || *p > '9')) + s = NONUM; + break; + case INT: + if (*p == '.') + s = DOT; + else if (*p < '0' || *p > '9') + s = NONUM; + break; + case DOT: + case LEADDOT: + if (*p >= '0' && *p <= '9') + s = FRAC; + else if (*p == '.') + s = DOTNONUM; + else + s = NONUM; + break; + case FRAC: + if (*p == '.') + s = DOTNONUM; + else if (*p < '0' || *p > '9') + s = NONUM; + break; + default:; + } + switch (s) { + case DOT: + r = q; + break; + case LEADDOT: + r = q + 1; + break; + case FRAC: + if (*p > '0') + r = q + 1; + break; + case NONUM: + if ((t == FRAC || t == DOT) && r != a) { + q = r--; + if (*r == '.') /* was a LEADDOT */ + *r = '0'; + r = a; + } + break; + default:; + } + *q++ = *p++; + t = s; + } + *q = '\0'; + return a; +} + +@ @c +void initversionstring(char **versions) +{ + (void) asprintf(versions, + "Compiled with libpng %s; using libpng %s\n" + "Compiled with zlib %s; using zlib %s\n" + "Compiled with %s version %s\n", + PNG_LIBPNG_VER_STRING, png_libpng_ver, + ZLIB_VERSION, zlib_version, xpdfString, xpdfVersion); +} + +@ @c +void check_buffer_overflow(int wsize) +{ + if (wsize > buf_size) { + int nsize = buf_size + buf_size / 5 + 5; + if (nsize < wsize) { + nsize = wsize + 5; + } + buffer = + (unsigned char *) xreallocarray(buffer, char, (unsigned) nsize); + buf_size = nsize; + } +} + +@ the return value is a decimal number with the point |dd| places from the back, + |scaled_out| is the number of scaled points corresponding to that. + +@c +#define max_integer 0x7FFFFFFF + +scaled divide_scaled(scaled s, scaled m, int dd) +{ + register scaled q; + register scaled r; + int i; + int sign = 1; + if (s < 0) { + sign = -sign; + s = -s; + } + if (m < 0) { + sign = -sign; + m = -m; + } + if (m == 0) { + pdf_error("arithmetic", "divided by zero"); + } else if (m >= (max_integer / 10)) { + pdf_error("arithmetic", "number too big"); + } + q = s / m; + r = s % m; + for (i = 1; i <= (int) dd; i++) { + q = 10 * q + (10 * r) / m; + r = (10 * r) % m; + } + /* rounding */ + if (2 * r >= m) { + q++; + r -= m; + } + return sign * q; +} + +@ Same function, but using doubles instead of integers (faster) +@c +scaled divide_scaled_n(double sd, double md, double n) +{ + double dd, di = 0.0; + dd = sd / md * n; + if (dd > 0.0) + di = floor(dd + 0.5); + else if (dd < 0.0) + di = -floor((-dd) + 0.5); + return (scaled) di; +} + +@ @c +int do_zround(double r) +{ + int i; + + if (r > 2147483647.0) + i = 2147483647; + else if (r < -2147483647.0) + i = -2147483647; + else if (r >= 0.0) + i = (int) (r + 0.5); + else + i = (int) (r - 0.5); + + return i; +} + + +@ MSVC doesn't have |rind|. +@c +#ifdef MSVC + +# include <math.h> +double rint(double x) +{ + double c, f, d1, d2; + + c = ceil(x); + f = floor(x); + d1 = fabs(c - x); + d2 = fabs(x - f); + if (d1 > d2) + return f; + else + return c; +} + +#endif diff --git a/Build/source/texk/web2c/luatexdir/utils/writezip.c b/Build/source/texk/web2c/luatexdir/utils/writezip.c deleted file mode 100644 index 312623093ef..00000000000 --- a/Build/source/texk/web2c/luatexdir/utils/writezip.c +++ /dev/null @@ -1,99 +0,0 @@ -/* writezip.c - - Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - LuaTeX is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - LuaTeX is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU General Public License along - with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - -#include "ptexlib.h" -#include "zlib.h" -#include <assert.h> - -static const char __svn_version[] = - "$Id: writezip.c 2271 2009-04-12 23:42:21Z oneiros $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/utils/writezip.c $"; - -#define ZIP_BUF_SIZE 32768 - -#define check_err(f, fn) \ - if (f != Z_OK) \ - pdftex_fail("zlib: %s() failed (error code %d)", fn, f) - -static char *zipbuf = NULL; -static z_stream c_stream; /* compression stream */ - -void write_zip(boolean finish) -{ - int err; - static int level_old = 0; - int level = get_pdf_compress_level(); - assert(level > 0); - cur_file_name = NULL; - if (pdf_stream_length == 0) { - if (zipbuf == NULL) { - zipbuf = xtalloc(ZIP_BUF_SIZE, char); - c_stream.zalloc = (alloc_func) 0; - c_stream.zfree = (free_func) 0; - c_stream.opaque = (voidpf) 0; - check_err(deflateInit(&c_stream, level), "deflateInit"); - } else { - if (level != level_old) { /* \pdfcompresslevel change in mid document */ - check_err(deflateEnd(&c_stream), "deflateEnd"); - c_stream.zalloc = (alloc_func) 0; /* these 3 lines no need, just to be safe */ - c_stream.zfree = (free_func) 0; - c_stream.opaque = (voidpf) 0; - check_err(deflateInit(&c_stream, level), "deflateInit"); - } else - check_err(deflateReset(&c_stream), "deflateReset"); - } - level_old = level; - c_stream.next_out = (Bytef *) zipbuf; - c_stream.avail_out = ZIP_BUF_SIZE; - } - assert(zipbuf != NULL); - c_stream.next_in = pdf_buf; - c_stream.avail_in = pdf_ptr; - for (;;) { - if (c_stream.avail_out == 0) { - pdf_gone += xfwrite(zipbuf, 1, ZIP_BUF_SIZE, pdf_file); - pdf_last_byte = zipbuf[ZIP_BUF_SIZE - 1]; /* not needed */ - c_stream.next_out = (Bytef *) zipbuf; - c_stream.avail_out = ZIP_BUF_SIZE; - } - err = deflate(&c_stream, finish ? Z_FINISH : Z_NO_FLUSH); - if (finish && err == Z_STREAM_END) - break; - check_err(err, "deflate"); - if (!finish && c_stream.avail_in == 0) - break; - } - if (finish) { - if (c_stream.avail_out < ZIP_BUF_SIZE) { /* at least one byte has been output */ - pdf_gone += - xfwrite(zipbuf, 1, ZIP_BUF_SIZE - c_stream.avail_out, pdf_file); - pdf_last_byte = zipbuf[ZIP_BUF_SIZE - c_stream.avail_out - 1]; - } - xfflush(pdf_file); - } - pdf_stream_length = c_stream.total_out; -} - -void zip_free(void) -{ - if (zipbuf != NULL) { - check_err(deflateEnd(&c_stream), "deflateEnd"); - free(zipbuf); - } -} |