config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

synctex_parser.c (338694B)


      1 /*
      2  Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
      3  
      4  This file is part of the __SyncTeX__ package.
      5  
      6  [//]: # (Latest Revision: Sun Oct 15 15:09:55 UTC 2017)
      7  [//]: # (Version: 1.21)
      8  
      9  See `synctex_parser_readme.md` for more details
     10  
     11  ## License
     12  
     13  Permission is hereby granted, free of charge, to any person
     14  obtaining a copy of this software and associated documentation
     15  files (the "Software"), to deal in the Software without
     16  restriction, including without limitation the rights to use,
     17  copy, modify, merge, publish, distribute, sublicense, and/or sell
     18  copies of the Software, and to permit persons to whom the
     19  Software is furnished to do so, subject to the following
     20  conditions:
     21  
     22  The above copyright notice and this permission notice shall be
     23  included in all copies or substantial portions of the Software.
     24  
     25  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     26  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     27  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     28  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     29  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     30  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     31  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     32  OTHER DEALINGS IN THE SOFTWARE
     33  
     34  Except as contained in this notice, the name of the copyright holder
     35  shall not be used in advertising or otherwise to promote the sale,
     36  use or other dealings in this Software without prior written
     37  authorization from the copyright holder.
     38  
     39  Acknowledgments:
     40  ----------------
     41  The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh,
     42  and significant help from XeTeX developer Jonathan Kew
     43  
     44  Nota Bene:
     45  ----------
     46  If you include or use a significant part of the synctex package into a software,
     47  I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
     48  
     49  */
     50 
     51 /*  We assume that high level application like pdf viewers will want
     52  *  to embed this code as is. We assume that they also have locale.h and setlocale.
     53  *  For other tools such as TeXLive tools, you must define SYNCTEX_USE_LOCAL_HEADER,
     54  *  when building. You also have to create and customize synctex_parser_local.h to fit your system.
     55  *  In particular, the HAVE_LOCALE_H and HAVE_SETLOCALE macros should be properly defined.
     56  *  With this design, you should not need to edit this file. */
     57 
     58 /**
     59  *  \file synctex_parser.c
     60  *  \brief SyncTeX file parser and controller.
     61  *  - author: Jérôme LAURENS
     62  *  \version 1.21
     63  *  \date Sun Oct 15 15:09:55 UTC 2017
     64  *
     65  *  Reads and parse *.synctex[.gz] files,
     66  *  performs edit and display queries.
     67  *
     68  *  See
     69  *  - synctex_scanner_new_with_output_file
     70  *  - synctex_scanner_parse
     71  *  - synctex_scanner_free
     72  *  - synctex_display_query
     73  *  - synctex_edit_query
     74  *  - synctex_scanner_next_result
     75  *  - synctex_scanner_reset_result
     76  *
     77  *  The data is organized in a graph with multiple entries.
     78  *  The root object is a scanner, it is created with the contents on a synctex file.
     79  *  Each node of the tree is a synctex_node_t object.
     80  *  There are 3 subtrees, two of them sharing the same leaves.
     81  *  The first tree is the list of input records, where input file names are associated with tags.
     82  *  The second tree is the box tree as given by TeX when shipping pages out.
     83  *  First level objects are sheets and forms, containing boxes, glues, kerns...
     84  *  The third tree allows to browse leaves according to tag and line.
     85  */
     86 #   if defined(SYNCTEX_USE_LOCAL_HEADER)
     87 #       include "synctex_parser_local.h"
     88 #   else
     89 #       define HAVE_LOCALE_H 1
     90 #       define HAVE_SETLOCALE 1
     91 #       if defined(_MSC_VER)
     92 #          define SYNCTEX_INLINE __inline
     93 #       else
     94 #          define SYNCTEX_INLINE inline
     95 #       endif
     96 #   endif
     97 
     98 #include <stdlib.h>
     99 #include <stdarg.h>
    100 #include <stdio.h>
    101 #include <string.h>
    102 #include <errno.h>
    103 #include <limits.h>
    104 
    105 #if defined(HAVE_LOCALE_H)
    106 #include <locale.h>
    107 #endif
    108 
    109 /* Mark unused parameters, so that there will be no compile warnings. */
    110 #ifdef __DARWIN_UNIX03
    111 #   define SYNCTEX_UNUSED(x) SYNCTEX_PRAGMA(unused(x))
    112 #   define SYNCTEX_PRAGMA(x) _Pragma ( #x )
    113 #else
    114 #   define SYNCTEX_UNUSED(x) (void)(x);
    115 #endif
    116 
    117 #include "synctex_parser_advanced.h"
    118 
    119 SYNCTEX_INLINE static int _synctex_abs(int x) {
    120     return x>0? x: -x;
    121 }
    122 /*  These are the possible extensions of the synctex file */
    123 const char * synctex_suffix = ".synctex";
    124 const char * synctex_suffix_gz = ".gz";
    125 
    126 typedef synctex_node_p(*synctex_node_new_f)(synctex_scanner_p);
    127 typedef void(*synctex_node_fld_f)(synctex_node_p);
    128 typedef char *(*synctex_node_str_f)(synctex_node_p);
    129 
    130 /**
    131  *  Pseudo class.
    132  *  - author: J. Laurens
    133  *
    134  *  Each nodes has a class, it is therefore called an object.
    135  *  Each class has a unique scanner.
    136  *  Each class has a type which is a unique identifier.
    137  *  The class points to various methods,
    138  *  each of them vary amongst objects.
    139  *  Each class has a data model which stores node's attributes.
    140  *  Each class has an tree model which stores children and parent.
    141  *  Inspectors give access to data and tree elements.
    142  */
    143 
    144 /*  8 fields + size: spcflnat */
    145 typedef struct synctex_tree_model_t {
    146     int sibling;
    147     int parent;
    148     int child;
    149     int friend;
    150     int last;
    151     int next_hbox;
    152     int arg_sibling;
    153     int target;
    154     int size;
    155 } synctex_tree_model_s;
    156 typedef const synctex_tree_model_s * synctex_tree_model_p;
    157 
    158 typedef struct synctex_data_model_t {
    159     int tag;
    160     int line;
    161     int column;
    162     int h;
    163     int v;
    164     int width;
    165     int height;
    166     int depth;
    167     int mean_line;
    168     int weight;
    169     int h_V;
    170     int v_V;
    171     int width_V;
    172     int height_V;
    173     int depth_V;
    174     int name;
    175     int page;
    176     int size;
    177 } synctex_data_model_s;
    178 
    179 typedef const synctex_data_model_s * synctex_data_model_p;
    180 
    181 typedef int (*synctex_int_getter_f)(synctex_node_p);
    182 typedef struct synctex_tlcpector_t {
    183     synctex_int_getter_f tag;
    184     synctex_int_getter_f line;
    185     synctex_int_getter_f column;
    186 } synctex_tlcpector_s;
    187 typedef const synctex_tlcpector_s * synctex_tlcpector_p;
    188 static int _synctex_int_none(synctex_node_p node) {
    189     SYNCTEX_UNUSED(node)
    190     return 0;
    191 }
    192 static const synctex_tlcpector_s synctex_tlcpector_none = {
    193     &_synctex_int_none, /* tag */
    194     &_synctex_int_none, /* line */
    195     &_synctex_int_none, /* column */
    196 };
    197 
    198 typedef struct synctex_inspector_t {
    199     synctex_int_getter_f h;
    200     synctex_int_getter_f v;
    201     synctex_int_getter_f width;
    202     synctex_int_getter_f height;
    203     synctex_int_getter_f depth;
    204 } synctex_inspector_s;
    205 typedef const synctex_inspector_s * synctex_inspector_p;
    206 static const synctex_inspector_s synctex_inspector_none = {
    207     &_synctex_int_none, /* h */
    208     &_synctex_int_none, /* v */
    209     &_synctex_int_none, /* width */
    210     &_synctex_int_none, /* height */
    211     &_synctex_int_none, /* depth */
    212 };
    213 
    214 typedef float (*synctex_float_getter_f)(synctex_node_p);
    215 typedef struct synctex_vispector_t {
    216     synctex_float_getter_f h;
    217     synctex_float_getter_f v;
    218     synctex_float_getter_f width;
    219     synctex_float_getter_f height;
    220     synctex_float_getter_f depth;
    221 } synctex_vispector_s;
    222 static float _synctex_float_none(synctex_node_p node) {
    223     SYNCTEX_UNUSED(node)
    224     return 0;
    225 }
    226 static const synctex_vispector_s synctex_vispector_none = {
    227     &_synctex_float_none, /* h */
    228     &_synctex_float_none, /* v */
    229     &_synctex_float_none, /* width */
    230     &_synctex_float_none, /* height */
    231     &_synctex_float_none, /* depth */
    232 };
    233 typedef const synctex_vispector_s * synctex_vispector_p;
    234 
    235 struct synctex_class_t {
    236     synctex_scanner_p scanner;
    237     synctex_node_type_t type;
    238     synctex_node_new_f new;
    239     synctex_node_fld_f free;
    240     synctex_node_fld_f log;
    241     synctex_node_fld_f display;
    242     synctex_node_str_f abstract;
    243     synctex_tree_model_p navigator;
    244     synctex_data_model_p modelator;
    245     synctex_tlcpector_p tlcpector;
    246     synctex_inspector_p inspector;
    247     synctex_vispector_p vispector;
    248 };
    249 
    250 /**
    251  *  Nota bene: naming convention.
    252  *  For static API, when the name contains "proxy", it applies to proxies.
    253  *  When the name contains "noxy", it applies to non proxies only.
    254  *  When the name contains "node", well it depends...
    255  */
    256 
    257 typedef synctex_node_p synctex_proxy_p;
    258 typedef synctex_node_p synctex_noxy_p;
    259 
    260 #	ifdef SYNCTEX_NOTHING
    261 #       pragma mark -
    262 #       pragma mark Abstract OBJECTS and METHODS
    263 #   endif
    264 
    265 /**
    266  *  \def SYNCTEX_MSG_SEND
    267  *  \brief Takes care of sending the given message if possible.
    268  *  - parameter NODE: of type synctex_node_p
    269  *  - parameter SELECTOR: one of the class_ pointer properties
    270  */
    271 #   define SYNCTEX_MSG_SEND(NODE,SELECTOR) do {\
    272     synctex_node_p N__ = NODE;\
    273     if (N__ && N__->class_->SELECTOR) {\
    274         (*(N__->class_->SELECTOR))(N__);\
    275     }\
    276 } while (synctex_NO)
    277 
    278 /**
    279  *  Free the given node by sending the free message.
    280  *  - parameter NODE: of type synctex_node_p
    281  */
    282 void synctex_node_free(synctex_node_p node) {
    283     SYNCTEX_MSG_SEND(node,free);
    284 }
    285 #   if defined(SYNCTEX_TESTING)
    286 #       if !defined(SYNCTEX_USE_HANDLE)
    287 #           define SYNCTEX_USE_HANDLE 1
    288 #       endif
    289 #       if !defined(SYNCTEX_USE_CHARINDEX)
    290 #           define SYNCTEX_USE_CHARINDEX 1
    291 #       endif
    292 #   endif
    293 SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target);
    294 #   if defined(SYNCTEX_USE_HANDLE)
    295 #       define SYNCTEX_SCANNER_FREE_HANDLE(SCANR) \
    296 __synctex_scanner_free_handle(SCANR)
    297 #       define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT) \
    298 __synctex_scanner_remove_handle_to(WHAT)
    299 #       define SYNCTEX_REGISTER_HANDLE_TO(NODE) \
    300 __synctex_scanner_register_handle_to(NODE)
    301 #   else
    302 #       define SYNCTEX_SCANNER_FREE_HANDLE(SCANR)
    303 #       define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT)
    304 #       define SYNCTEX_REGISTER_HANDLE_TO(NODE)
    305 #   endif
    306 
    307 #   if defined(SYNCTEX_USE_CHARINDEX)
    308 #       define SYNCTEX_CHARINDEX(NODE) (NODE->char_index)
    309 #       define SYNCTEX_LINEINDEX(NODE) (NODE->line_index)
    310 #       define SYNCTEX_PRINT_CHARINDEX_FMT "#%i"
    311 #       define SYNCTEX_PRINT_CHARINDEX_WHAT ,SYNCTEX_CHARINDEX(node)
    312 #       define SYNCTEX_PRINT_CHARINDEX \
    313             printf(SYNCTEX_PRINT_CHARINDEX_FMT SYNCTEX_PRINT_CHARINDEX_WHAT)
    314 #       define SYNCTEX_PRINT_LINEINDEX_FMT "L#%i"
    315 #       define SYNCTEX_PRINT_LINEINDEX_WHAT ,SYNCTEX_LINEINDEX(node)
    316 #       define SYNCTEX_PRINT_LINEINDEX \
    317             printf(SYNCTEX_PRINT_LINEINDEX_FMT SYNCTEX_PRINT_LINEINDEX_WHAT)
    318 #       define SYNCTEX_PRINT_CHARINDEX_NL \
    319             printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n" SYNCTEX_PRINT_CHARINDEX_WHAT)
    320 #       define SYNCTEX_PRINT_LINEINDEX_NL \
    321             printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n"SYNCTEX_PRINT_LINEINDEX_WHAT)
    322 #       define SYNCTEX_IMPLEMENT_CHARINDEX(NODE,CORRECTION)\
    323             NODE->char_index = (synctex_charindex_t)(scanner->reader->charindex_offset+SYNCTEX_CUR-SYNCTEX_START+(CORRECTION)); \
    324             NODE->line_index = scanner->reader->line_number;
    325 #   else
    326 #       define SYNCTEX_CHARINDEX(NODE) 0
    327 #       define SYNCTEX_LINEINDEX(NODE) 0
    328 #       define SYNCTEX_PRINT_CHARINDEX_FMT
    329 #       define SYNCTEX_PRINT_CHARINDEX_WHAT
    330 #       define SYNCTEX_PRINT_CHARINDEX
    331 #       define SYNCTEX_PRINT_CHARINDEX
    332 #       define SYNCTEX_PRINT_LINEINDEX_FMT
    333 #       define SYNCTEX_PRINT_LINEINDEX_WHAT
    334 #       define SYNCTEX_PRINT_LINEINDEX
    335 #       define SYNCTEX_PRINT_CHARINDEX_NL printf("\n")
    336 #       define SYNCTEX_PRINT_LINEINDEX_NL printf("\n")
    337 #       define SYNCTEX_IMPLEMENT_CHARINDEX(NODE,CORRECTION)
    338 #   endif
    339 
    340 /**
    341  *  The next macros are used to access the node tree info
    342  *  SYNCTEX_DATA(node) points to the first synctex integer or pointer data of node
    343  *  SYNCTEX_DATA(node)[index] is the information at index
    344  *  for example, the page of a sheet is stored in SYNCTEX_DATA(sheet)[_synctex_data_page_idx]
    345  *  - parameter NODE: of type synctex_node_p
    346  *  If the name starts with "__", the argument is nonullable
    347  */
    348 #	ifdef SYNCTEX_NOTHING
    349 #       pragma mark -
    350 #       pragma mark Tree SETGET
    351 #   endif
    352 
    353 #if SYNCTEX_DEBUG > 1000
    354 #define SYNCTEX_PARAMETER_ASSERT(WHAT) \
    355     do { \
    356         if (!(WHAT)) { \
    357             printf("! Parameter failure: %s\n",#WHAT); \
    358         } \
    359     } while (synctex_NO)
    360 #define DEFINE_SYNCTEX_TREE_HAS(WHAT)\
    361 static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) {\
    362     if (node) {\
    363         if (node->class_->navigator->WHAT>=0) {\
    364             return  synctex_YES; \
    365         } else {\
    366             printf("WARNING: NO tree %s for %s\n", #WHAT, synctex_node_isa(node));\
    367         }\
    368     }\
    369     return synctex_NO;\
    370 }
    371 #else
    372 #define SYNCTEX_PARAMETER_ASSERT(WHAT)
    373 #define DEFINE_SYNCTEX_TREE_HAS(WHAT) \
    374 static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) {\
    375     return (node && (node->class_->navigator->WHAT>=0));\
    376 }
    377 #endif
    378 
    379 #   define DEFINE_SYNCTEX_TREE__GET(WHAT) \
    380 SYNCTEX_INLINE static synctex_node_p __synctex_tree_##WHAT(synctex_non_null_node_p node) {\
    381     return node->data[node->class_->navigator->WHAT].as_node;\
    382 }
    383 #   define DEFINE_SYNCTEX_TREE_GET(WHAT) \
    384 DEFINE_SYNCTEX_TREE__GET(WHAT) \
    385 static synctex_node_p _synctex_tree_##WHAT(synctex_node_p node) {\
    386     if (_synctex_tree_has_##WHAT(node)) {\
    387         return __synctex_tree_##WHAT(node);\
    388     }\
    389     return 0;\
    390 }
    391 #   define DEFINE_SYNCTEX_TREE__RESET(WHAT) \
    392 SYNCTEX_INLINE static synctex_node_p __synctex_tree_reset_##WHAT(synctex_non_null_node_p node) {\
    393     synctex_node_p old = node->data[node->class_->navigator->WHAT].as_node;\
    394     node->data[node->class_->navigator->WHAT].as_node=NULL;\
    395     return old;\
    396 }
    397 #   define DEFINE_SYNCTEX_TREE_RESET(WHAT) \
    398 DEFINE_SYNCTEX_TREE__RESET(WHAT) \
    399 SYNCTEX_INLINE static synctex_node_p _synctex_tree_reset_##WHAT(synctex_node_p node) {\
    400         return _synctex_tree_has_##WHAT(node)? \
    401             __synctex_tree_reset_##WHAT(node): NULL; \
    402 }
    403 #   define DEFINE_SYNCTEX_TREE__SET(WHAT) \
    404 SYNCTEX_INLINE static synctex_node_p __synctex_tree_set_##WHAT(synctex_non_null_node_p node, synctex_node_p new_value) {\
    405     synctex_node_p old = __synctex_tree_##WHAT(node);\
    406     node->data[node->class_->navigator->WHAT].as_node=new_value;\
    407     return old;\
    408 }
    409 #   define DEFINE_SYNCTEX_TREE_SET(WHAT) \
    410 DEFINE_SYNCTEX_TREE__SET(WHAT) \
    411 SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_##WHAT(synctex_node_p node, synctex_node_p new_value) {\
    412     return _synctex_tree_has_##WHAT(node)?\
    413         __synctex_tree_set_##WHAT(node,new_value):NULL;\
    414 }
    415 #   define DEFINE_SYNCTEX_TREE__GETSETRESET(WHAT) \
    416 DEFINE_SYNCTEX_TREE__GET(WHAT) \
    417 DEFINE_SYNCTEX_TREE__SET(WHAT) \
    418 DEFINE_SYNCTEX_TREE__RESET(WHAT)
    419 
    420 #   define DEFINE_SYNCTEX_TREE_GETSET(WHAT) \
    421 DEFINE_SYNCTEX_TREE_HAS(WHAT) \
    422 DEFINE_SYNCTEX_TREE_GET(WHAT) \
    423 DEFINE_SYNCTEX_TREE_SET(WHAT)
    424 
    425 #   define DEFINE_SYNCTEX_TREE_GETRESET(WHAT) \
    426 DEFINE_SYNCTEX_TREE_HAS(WHAT) \
    427 DEFINE_SYNCTEX_TREE_GET(WHAT) \
    428 DEFINE_SYNCTEX_TREE_RESET(WHAT)
    429 
    430 #   define DEFINE_SYNCTEX_TREE_GETSETRESET(WHAT) \
    431 DEFINE_SYNCTEX_TREE_HAS(WHAT) \
    432 DEFINE_SYNCTEX_TREE_GET(WHAT) \
    433 DEFINE_SYNCTEX_TREE_SET(WHAT) \
    434 DEFINE_SYNCTEX_TREE_RESET(WHAT)
    435 
    436 /*
    437  *  _synctex_tree_set_... methods return the old value.
    438  *  The return value of _synctex_tree_set_child and 
    439  *  _synctex_tree_set_sibling must be released somehown.
    440  */
    441 DEFINE_SYNCTEX_TREE__GETSETRESET(sibling)
    442 DEFINE_SYNCTEX_TREE_GETSETRESET(parent)
    443 DEFINE_SYNCTEX_TREE_GETSETRESET(child)
    444 DEFINE_SYNCTEX_TREE_GETSETRESET(friend)
    445 DEFINE_SYNCTEX_TREE_GETSET(last)
    446 DEFINE_SYNCTEX_TREE_GETSET(next_hbox)
    447 DEFINE_SYNCTEX_TREE_GETSET(arg_sibling)
    448 DEFINE_SYNCTEX_TREE_GETSETRESET(target)
    449 
    450 #if SYNCTEX_DEBUG>1000
    451 #   undef SYNCTEX_USE_NODE_COUNT
    452 #   define SYNCTEX_USE_NODE_COUNT 1
    453 #endif
    454 #if SYNCTEX_USE_NODE_COUNT>0
    455 #   define SYNCTEX_DECLARE_NODE_COUNT int node_count;
    456 #   define SYNCTEX_INIT_NODE_COUNT \
    457         do { node_count = 0; } while(synctex_NO)
    458 #else
    459 #   define SYNCTEX_DECLARE_NODE_COUNT
    460 #   define SYNCTEX_INIT_NODE_COUNT
    461 #endif
    462 
    463 #if SYNCTEX_USE_NODE_COUNT>10
    464 #   define SYNCTEX_DID_NEW(N)   _synctex_did_new(N)
    465 #   define SYNCTEX_WILL_FREE(N) _synctex_will_free(N)
    466 #else
    467 #   define SYNCTEX_DID_NEW(N)
    468 #   define SYNCTEX_WILL_FREE(N)
    469 #endif
    470 
    471 #define SYNCTEX_HAS_CHILDREN(NODE) (NODE && _synctex_tree_child(NODE))
    472 #	ifdef	__SYNCTEX_WORK__
    473 #		include "/usr/include/zlib.h"
    474 #	else
    475 #		include <zlib.h>
    476 #	endif
    477 
    478 #	ifdef SYNCTEX_NOTHING
    479 #       pragma mark -
    480 #       pragma mark STATUS
    481 #   endif
    482 /*  When the end of the synctex file has been reached: */
    483 #   define SYNCTEX_STATUS_EOF 0
    484 /*  When the function could not return the value it was asked for: */
    485 #   define SYNCTEX_STATUS_NOT_OK (SYNCTEX_STATUS_EOF+1)
    486 /*  When the function returns the value it was asked for:
    487  It must be the biggest one */
    488 #   define SYNCTEX_STATUS_OK (SYNCTEX_STATUS_NOT_OK+1)
    489 /*  Generic error: */
    490 #   define SYNCTEX_STATUS_ERROR (SYNCTEX_STATUS_EOF-1)
    491 /*  Parameter error: */
    492 #   define SYNCTEX_STATUS_BAD_ARGUMENT (SYNCTEX_STATUS_ERROR-1)
    493 
    494 #	ifdef SYNCTEX_NOTHING
    495 #       pragma mark -
    496 #       pragma mark File reader
    497 #   endif
    498 
    499 /*  We ensure that SYNCTEX_BUFFER_SIZE < UINT_MAX, I don't know if it makes sense... */
    500 /*  Actually, the minimum buffer size is driven by integer and float parsing, including the unit.
    501  *  ±0.123456789e123??
    502  */
    503 #   define SYNCTEX_BUFFER_MIN_SIZE 32
    504 #   define SYNCTEX_BUFFER_SIZE 32768
    505 
    506 #if SYNCTEX_BUFFER_SIZE >= UINT_MAX
    507 #   error BAD BUFFER SIZE(1)
    508 #endif
    509 #if SYNCTEX_BUFFER_SIZE < SYNCTEX_BUFFER_MIN_SIZE
    510 #   error BAD BUFFER SIZE(2)
    511 #endif
    512 
    513 typedef struct synctex_reader_t {
    514     gzFile file;    /*  The (possibly compressed) file */
    515     char * output;
    516     char * synctex;
    517     char * current; /*  current location in the buffer */
    518     char * start;   /*  start of the buffer */
    519     char * end;     /*  end of the buffer */
    520     size_t min_size;
    521     size_t size;
    522     int lastv;
    523     int line_number;
    524     SYNCTEX_DECLARE_CHAR_OFFSET
    525 } synctex_reader_s;
    526 
    527 typedef synctex_reader_s * synctex_reader_p;
    528 
    529 typedef struct {
    530     synctex_status_t status;
    531     char * synctex;
    532     gzFile file;
    533     synctex_io_mode_t io_mode;
    534 } synctex_open_s;
    535 
    536 /*	This functions opens the file at the "output" given location.
    537  *  It manages the problem of quoted filenames that appear with pdftex and filenames containing the space character.
    538  *  In TeXLive 2008, the synctex file created with pdftex did contain unexpected quotes.
    539  *	This function will remove them if possible.
    540  *  All the reference arguments will take a value on return. They must be non NULL.
    541  *	- returns: an open structure which status is
    542  *      SYNCTEX_STATUS_OK on success,
    543  *      SYNCTEX_STATUS_ERROR on failure.
    544  *  - note: on success, the caller is the owner
    545  *      of the fields of the returned open structure.
    546  */
    547 static synctex_open_s __synctex_open_v2(const char * output, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) {
    548     synctex_open_s open = {SYNCTEX_STATUS_ERROR, NULL, NULL, io_mode};
    549     char * quoteless_synctex_name = NULL;
    550     const char * mode = _synctex_get_io_mode_name(open.io_mode);
    551     size_t size = strlen(output)+strlen(synctex_suffix)+strlen(synctex_suffix_gz)+1;
    552     if (NULL == (open.synctex = (char *)malloc(size))) {
    553         _synctex_error("!  __synctex_open_v2: Memory problem (1)\n");
    554         return open;
    555     }
    556     /*  we have reserved for synctex enough memory to copy output (including its 2 eventual quotes), both suffices,
    557      *  including the terminating character. size is free now. */
    558     if (open.synctex != strcpy(open.synctex,output)) {
    559         _synctex_error("!  __synctex_open_v2: Copy problem\n");
    560     return_on_error:
    561         free(open.synctex);
    562         open.synctex = NULL;
    563         free(quoteless_synctex_name);/* We MUST have quoteless_synctex_name<>synctex_name */
    564         return open;
    565     }
    566     /*  remove the last path extension if any */
    567     _synctex_strip_last_path_extension(open.synctex);
    568     if (!strlen(open.synctex)) {
    569         goto return_on_error;
    570     }
    571     /*  now insert quotes. */
    572     if (add_quotes) {
    573         char * quoted = NULL;
    574         if (_synctex_copy_with_quoting_last_path_component(open.synctex,&quoted,size) || quoted == NULL) {
    575             /*	There was an error or quoting does not make sense: */
    576             goto return_on_error;
    577         }
    578         quoteless_synctex_name = open.synctex;
    579         open.synctex = quoted;
    580     }
    581     /*	Now add to open.synctex the first path extension. */
    582     if (open.synctex != strcat(open.synctex,synctex_suffix)){
    583         _synctex_error("!  __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n",synctex_suffix);
    584         goto return_on_error;
    585     }
    586     /*	Add to quoteless_synctex_name as well, if relevant. */
    587     if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name,synctex_suffix))){
    588         free(quoteless_synctex_name);
    589         quoteless_synctex_name = NULL;
    590     }
    591     if (NULL == (open.file = gzopen(open.synctex,mode))) {
    592         /*  Could not open this file */
    593         if (errno != ENOENT) {
    594             /*  The file does exist, this is a lower level error, I can't do anything. */
    595             _synctex_error("could not open %s, error %i\n",open.synctex,errno);
    596             goto return_on_error;
    597         }
    598         /*  Apparently, there is no uncompressed synctex file. Try the compressed version */
    599         if (open.synctex != strcat(open.synctex,synctex_suffix_gz)){
    600             _synctex_error("!  __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n",synctex_suffix_gz);
    601             goto return_on_error;
    602         }
    603         open.io_mode |= synctex_io_gz_mask;
    604         mode = _synctex_get_io_mode_name(open.io_mode); /* the file is a compressed and is a binary file, this caused errors on Windows */
    605         /*	Add the suffix to the quoteless_synctex_name as well. */
    606         if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name,synctex_suffix_gz))){
    607             free(quoteless_synctex_name);
    608             quoteless_synctex_name = NULL;
    609         }
    610         if (NULL == (open.file = gzopen(open.synctex,mode))) {
    611             /*  Could not open this file */
    612             if (errno != ENOENT) {
    613                 /*  The file does exist, this is a lower level error, I can't do anything. */
    614                 _synctex_error("Could not open %s, error %i\n",open.synctex,errno);
    615             }
    616             goto return_on_error;
    617         }
    618     }
    619     /*	At this point, the file is properly open.
    620      *  If we are in the add_quotes mode, we change the file name by removing the quotes. */
    621     if (quoteless_synctex_name) {
    622         gzclose(open.file);
    623         if (rename(open.synctex,quoteless_synctex_name)) {
    624             _synctex_error("Could not rename %s to %s, error %i\n",open.synctex,quoteless_synctex_name,errno);
    625             /*	We could not rename, reopen the file with the quoted name. */
    626             if (NULL == (open.file = gzopen(open.synctex,mode))) {
    627                 /*  No luck, could not re open this file, something has happened meanwhile */
    628                 if (errno != ENOENT) {
    629                     /*  The file does not exist any more, it has certainly be removed somehow
    630                      *  this is a lower level error, I can't do anything. */
    631                     _synctex_error("Could not open again %s, error %i\n",open.synctex,errno);
    632                 }
    633                 goto return_on_error;
    634             }
    635         } else {
    636             /*  The file has been successfully renamed */
    637             if (NULL == (open.file = gzopen(quoteless_synctex_name,mode))) {
    638                 /*  Could not open this file */
    639                 if (errno != ENOENT) {
    640                     /*  The file does exist, this is a lower level error, I can't do anything. */
    641                     _synctex_error("Could not open renamed %s, error %i\n",quoteless_synctex_name,errno);
    642                 }
    643                 goto return_on_error;
    644             }
    645             /*  The quote free file name should replace the old one:*/
    646             free(open.synctex);
    647             open.synctex = quoteless_synctex_name;
    648             quoteless_synctex_name = NULL;
    649         }
    650     }
    651     /*  The operation is successful, return the arguments by value.    */
    652     open.status = SYNCTEX_STATUS_OK;
    653     return open;
    654 }
    655 
    656 /*	Opens the output file, taking into account the eventual build_directory.
    657  *	- returns: an open structure which status is
    658  *      SYNCTEX_STATUS_OK on success,
    659  *      SYNCTEX_STATUS_ERROR on failure.
    660  *  - note: on success, the caller is the owner
    661  *      of the fields of the returned open structure.
    662  */
    663 static synctex_open_s _synctex_open_v2(const char * output, const char * build_directory, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) {
    664     synctex_open_s open = __synctex_open_v2(output,io_mode,add_quotes);
    665     if (open.status == SYNCTEX_STATUS_OK) {
    666         return open;
    667     }
    668     if (build_directory && strlen(build_directory)) {
    669         char * build_output;
    670         const char *lpc;
    671         size_t size;
    672         synctex_bool_t is_absolute;
    673         build_output = NULL;
    674         lpc = _synctex_last_path_component(output);
    675         size = strlen(build_directory)+strlen(lpc)+2;   /*  One for the '/' and one for the '\0'.   */
    676         is_absolute = _synctex_path_is_absolute(build_directory);
    677         if (!is_absolute) {
    678             size += strlen(output);
    679         }
    680         if ((build_output = (char *)_synctex_malloc(size))) {
    681             if (is_absolute) {
    682                 build_output[0] = '\0';
    683             } else {
    684                 if (build_output != strcpy(build_output,output)) {
    685                     _synctex_free(build_output);
    686                     return open;
    687                 }
    688                 build_output[lpc-output]='\0';
    689             }
    690             if (build_output == strcat(build_output,build_directory)) {
    691                 /*	Append a path separator if necessary. */
    692                 if (!SYNCTEX_IS_PATH_SEPARATOR(build_output[strlen(build_directory)-1])) {
    693                     if (build_output != strcat(build_output,"/")) {
    694                         _synctex_free(build_output);
    695                         return open;
    696                     }
    697                 }
    698                 /*	Append the last path component of the output. */
    699                 if (build_output != strcat(build_output,lpc)) {
    700                     _synctex_free(build_output);
    701                     return open;
    702                 }
    703                 open = __synctex_open_v2(build_output,io_mode,add_quotes);
    704             }
    705             _synctex_free(build_output);
    706         } /* if ((build_output... */
    707     } /* if (build_directory...) */
    708     return open;
    709 }
    710 void synctex_reader_free(synctex_reader_p reader) {
    711     if (reader) {
    712         _synctex_free(reader->output);
    713         _synctex_free(reader->synctex);
    714         _synctex_free(reader->start);
    715         gzclose(reader->file);
    716         _synctex_free(reader);
    717     }
    718 }
    719 /*
    720  *  Return reader on success.
    721  *  Deallocate reader and return NULL on failure.
    722  */
    723 synctex_reader_p synctex_reader_init_with_output_file(synctex_reader_p reader, const char * output, const char * build_directory) {
    724     if (reader) {
    725         /*  now open the synctex file */
    726         synctex_open_s open = _synctex_open_v2(output,build_directory,0,synctex_ADD_QUOTES);
    727         if (open.status<SYNCTEX_STATUS_OK) {
    728             open = _synctex_open_v2(output,build_directory,0,synctex_DONT_ADD_QUOTES);
    729             if (open.status<SYNCTEX_STATUS_OK) {
    730                 return NULL;
    731             }
    732         }
    733         reader->synctex = open.synctex;
    734         reader->file = open.file;
    735         /*  make a private copy of output */
    736         if (NULL == (reader->output = (char *)_synctex_malloc(strlen(output)+1))){
    737             _synctex_error("!  synctex_scanner_new_with_output_file: Memory problem (2), reader's output is not reliable.");
    738         } else if (reader->output != strcpy(reader->output,output)) {
    739             _synctex_free(reader->output);
    740             reader->output = NULL;
    741             _synctex_error("!  synctex_scanner_new_with_output_file: Copy problem, reader's output is not reliable.");
    742         }
    743         reader->start = reader->end = reader->current = NULL;
    744         reader->min_size = SYNCTEX_BUFFER_MIN_SIZE;
    745         reader->size = SYNCTEX_BUFFER_SIZE;
    746         reader->start = reader->current =
    747             (char *)_synctex_malloc(reader->size+1); /*  one more character for null termination */
    748         if (NULL == reader->start) {
    749             _synctex_error("!  malloc error in synctex_reader_init_with_output_file.");
    750         bailey:
    751 #ifdef SYNCTEX_DEBUG
    752             return reader;
    753 #else
    754             synctex_reader_free(reader);
    755             return NULL;
    756 #endif
    757         }
    758         reader->end = reader->start+reader->size;
    759         /*  reader->end always points to a null terminating character.
    760          *  Maybe there is another null terminating character between reader->current and reader->end-1.
    761          *  At least, we are sure that reader->current points to a string covering a valid part of the memory. */
    762 #   if defined(SYNCTEX_USE_CHARINDEX)
    763         reader->charindex_offset = -reader->size;
    764 #   endif
    765     }
    766     return reader;
    767 }
    768 
    769 #   if defined(SYNCTEX_USE_HANDLE)
    770 #       define SYNCTEX_DECLARE_HANDLE synctex_node_p handle;
    771 #   else
    772 #       define SYNCTEX_DECLARE_HANDLE
    773 #   endif
    774 
    775 #   ifdef SYNCTEX_NOTHING
    776 #       pragma mark -
    777 #       pragma mark SCANNER
    778 #   endif
    779 /**
    780  *  The synctex scanner is the root object.
    781  *  Is is initialized with the contents of a text file or a gzipped file.
    782  *  The buffer_.* are first used to parse the text.
    783  */
    784 struct synctex_scanner_t {
    785     synctex_reader_p reader;
    786     SYNCTEX_DECLARE_NODE_COUNT
    787     SYNCTEX_DECLARE_HANDLE
    788     char * output_fmt;          /*  dvi or pdf, not yet used */
    789     synctex_iterator_p iterator;/*  result iterator */
    790     int version;                /*  1, not yet used */
    791     struct {
    792         unsigned has_parsed:1;		/*  Whether the scanner has parsed its underlying synctex file. */
    793         unsigned postamble:1;		/*  Whether the scanner has parsed its underlying synctex file. */
    794         unsigned reserved:sizeof(unsigned)-2;	/*  alignment */
    795     } flags;
    796     int pre_magnification;  /*  magnification from the synctex preamble */
    797     int pre_unit;           /*  unit from the synctex preamble */
    798     int pre_x_offset;       /*  X offset from the synctex preamble */
    799     int pre_y_offset;       /*  Y offset from the synctex preamble */
    800     int count;              /*  Number of records, from the synctex postamble */
    801     float unit;             /*  real unit, from synctex preamble or post scriptum */
    802     float x_offset;         /*  X offset, from synctex preamble or post scriptum */
    803     float y_offset;         /*  Y Offset, from synctex preamble or post scriptum */
    804     synctex_node_p input;   /*  The first input node, its siblings are the other input nodes */
    805     synctex_node_p sheet;   /*  The first sheet node, its siblings are the other sheet nodes */
    806     synctex_node_p form;    /*  The first form, its siblings are the other forms */
    807     synctex_node_p ref_in_sheet; /*  The first form ref node in sheet, its friends are the other form ref nodes */
    808     synctex_node_p ref_in_form;  /*  The first form ref node, its friends are the other form ref nodes in sheet */
    809     int number_of_lists;    /*  The number of friend lists */
    810     synctex_node_r lists_of_friends;/*  The friend lists */
    811     synctex_class_s class_[synctex_node_number_of_types]; /*  The classes of the nodes of the scanner */
    812     int display_switcher;
    813     char * display_prompt;
    814 };
    815 
    816 /**
    817  *  Create a new node of the given type.
    818  *  - parameter scanner: of type synctex_node_p
    819  *  - parameter type: a type, the client is responsible
    820  *  to ask for an acceptable type.
    821  */
    822 synctex_node_p synctex_node_new(synctex_scanner_p scanner, synctex_node_type_t type) {
    823     return scanner? scanner->class_[type].new(scanner):NULL;
    824 }
    825 #   if defined(SYNCTEX_USE_HANDLE)
    826 SYNCTEX_INLINE static void __synctex_scanner_free_handle(synctex_scanner_p scanner) {
    827     synctex_node_free(scanner->handle);
    828 }
    829 SYNCTEX_INLINE static void __synctex_scanner_remove_handle_to(synctex_node_p node) {
    830     synctex_node_p arg_sibling = NULL;
    831     synctex_node_p handle = node->class_->scanner->handle;
    832     while (handle) {
    833         synctex_node_p sibling;
    834         if (node == _synctex_tree_target(handle)) {
    835             sibling = __synctex_tree_reset_sibling(handle);
    836             if (arg_sibling) {
    837                 __synctex_tree_set_sibling(arg_sibling, sibling);
    838             } else {
    839                 node->class_->scanner->handle = sibling;
    840             }
    841             synctex_node_free(handle);
    842             break;
    843         } else {
    844             sibling = __synctex_tree_sibling(handle);
    845         }
    846         arg_sibling = handle;
    847         handle = sibling;
    848     }
    849 }
    850 SYNCTEX_INLINE static void __synctex_scanner_register_handle_to(synctex_node_p  node) {
    851     synctex_node_p NNN = _synctex_new_handle_with_target(node);
    852     __synctex_tree_set_sibling(NNN,node->class_->scanner->handle);
    853     node->class_->scanner->handle = NNN;
    854 }
    855 #endif
    856 #if SYNCTEX_USE_NODE_COUNT>10
    857 SYNCTEX_INLINE static void _synctex_did_new(synctex_node_p node) {
    858     printf("NODE CREATED # %i, %s, %p\n",
    859            (node->class_->scanner->node_count)++,
    860            synctex_node_isa(node),
    861            node);
    862 }
    863 SYNCTEX_INLINE static void _synctex_will_free(synctex_node_p node) {
    864     printf("NODE DELETED # %i, %s, %p\n",
    865            --(node->class_->scanner->node_count),
    866            synctex_node_isa(node),
    867            node);
    868 }
    869 #endif
    870 
    871 /**
    872  *  Free the given node.
    873  *  - parameter node: of type synctex_node_p
    874  *  - note: a node is meant to own its child and sibling.
    875  *  It is not owned by its parent, unless it is its first child.
    876  *  This destructor is for all nodes with children.
    877  */
    878 static void _synctex_free_node(synctex_node_p node) {
    879     if (node) {
    880         SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
    881         SYNCTEX_WILL_FREE(node);
    882         synctex_node_free(__synctex_tree_sibling(node));
    883         synctex_node_free(_synctex_tree_child(node));
    884         _synctex_free(node);
    885     }
    886     return;
    887 }
    888 /**
    889  *  Free the given handle.
    890  *  - parameter node: of type synctex_node_p
    891  *  - note: a node is meant to own its child and sibling.
    892  *  It is not owned by its parent, unless it is its first child.
    893  *  This destructor is for all handles.
    894  */
    895 static void _synctex_free_handle(synctex_node_p handle) {
    896     if (handle) {
    897         _synctex_free_handle(__synctex_tree_sibling(handle));
    898         _synctex_free_handle(_synctex_tree_child(handle));
    899         _synctex_free(handle);
    900     }
    901     return;
    902 }
    903 
    904 /**
    905  *  Free the given leaf node.
    906  *  - parameter node: of type synctex_node_p, with no child nor sibling.
    907  *  - note: a node is meant to own its child and sibling.
    908  *  It is not owned by its parent, unless it is its first child.
    909  *  This destructor is for all nodes with no children.
    910  */
    911 static void _synctex_free_leaf(synctex_node_p node) {
    912     if (node) {
    913         SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
    914         SYNCTEX_WILL_FREE(node);
    915         synctex_node_free(__synctex_tree_sibling(node));
    916         _synctex_free(node);
    917     }
    918     return;
    919 }
    920 
    921 /**
    922  SYNCTEX_CUR, SYNCTEX_START and SYNCTEX_END are convenient shortcuts
    923  */
    924 #   define SYNCTEX_CUR (scanner->reader->current)
    925 #   define SYNCTEX_START (scanner->reader->start)
    926 #   define SYNCTEX_END (scanner->reader->end)
    927 
    928 /*  Here are gathered all the possible status that the next scanning functions will return.
    929  *  All these functions return a status, and pass their result through pointers.
    930  *  Negative values correspond to errors.
    931  *  The management of the buffer is causing some significant overhead.
    932  *  Every function that may access the buffer returns a status related to the buffer and file state.
    933  *  status >= SYNCTEX_STATUS_OK means the function worked as expected
    934  *  status < SYNCTEX_STATUS_OK means the function did not work as expected
    935  *  status == SYNCTEX_STATUS_NOT_OK means the function did not work as expected but there is still some material to parse.
    936  *  status == SYNCTEX_STATUS_EOF means the function did not work as expected and there is no more material.
    937  *  status<SYNCTEX_STATUS_EOF means an error
    938  */
    939 #if defined(SYNCTEX_USE_CHARINDEX)
    940 synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner) {
    941     return scanner? scanner->handle:NULL;
    942 }
    943 #endif
    944 
    945 #	ifdef SYNCTEX_NOTHING
    946 #       pragma mark -
    947 #       pragma mark Decoding prototypes
    948 #   endif
    949 
    950 typedef struct {
    951     int integer;
    952     synctex_status_t status;
    953 } synctex_is_s;
    954 
    955 static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner);
    956 static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value);
    957 static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner);
    958 
    959 typedef struct {
    960     char * string;
    961     synctex_status_t status;
    962 } synctex_ss_s;
    963 
    964 static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner);
    965 
    966 #	ifdef SYNCTEX_NOTHING
    967 #       pragma mark -
    968 #       pragma mark Data SETGET
    969 #   endif
    970 
    971 /**
    972  *  The next macros are used to access the node data info
    973  *  through the class modelator integer fields.
    974   *  - parameter NODE: of type synctex_node_p
    975  */
    976 #   define SYNCTEX_DATA(NODE) ((*((((NODE)->class_))->info))(NODE))
    977 #if defined SYNCTEX_DEBUG > 1000
    978 #   define DEFINE_SYNCTEX_DATA_HAS(WHAT) \
    979 SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) {\
    980     return (node && (node->class_->modelator->WHAT>=0));\
    981 }\
    982 SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) {\
    983     if (node && (node->class_->modelator->WHAT<0)) {\
    984         printf("WARNING: NO %s for %s\n", #WHAT, synctex_node_isa(node));\
    985     }\
    986     return __synctex_data_has_##WHAT(node);\
    987 }
    988 #else
    989 #   define DEFINE_SYNCTEX_DATA_HAS(WHAT) \
    990 SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) {\
    991     return (node && (node->class_->modelator->WHAT>=0));\
    992 }\
    993 SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) {\
    994     return __synctex_data_has_##WHAT(node);\
    995 }
    996 #endif
    997 
    998 SYNCTEX_INLINE static synctex_data_p __synctex_data(synctex_node_p node) {
    999     return node->data+node->class_->navigator->size;
   1000 }
   1001 #   define DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
   1002 DEFINE_SYNCTEX_DATA_HAS(WHAT)\
   1003 static int _synctex_data_##WHAT(synctex_node_p node) {\
   1004     if (_synctex_data_has_##WHAT(node)) {\
   1005         return __synctex_data(node)[node->class_->modelator->WHAT].as_integer;\
   1006     }\
   1007     return 0;\
   1008 }\
   1009 static int _synctex_data_set_##WHAT(synctex_node_p node, int new_value) {\
   1010     int old = 0;\
   1011     if (_synctex_data_has_##WHAT(node)) {\
   1012         old = __synctex_data(node)[node->class_->modelator->WHAT].as_integer;\
   1013         __synctex_data(node)[node->class_->modelator->WHAT].as_integer=new_value;\
   1014     }\
   1015     return old;\
   1016 }
   1017 #define DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT) \
   1018 static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) {\
   1019     if (_synctex_data_has_##WHAT(node)) {\
   1020         synctex_is_s is = _synctex_decode_int(node->class_->scanner);\
   1021         if (is.status == SYNCTEX_STATUS_OK) {\
   1022             _synctex_data_set_##WHAT(node,is.integer);\
   1023         } \
   1024         return is.status;\
   1025     }\
   1026     return SYNCTEX_STATUS_BAD_ARGUMENT;\
   1027 }
   1028 #   define DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT) \
   1029 static synctex_status_t _synctex_data_decode_##WHAT##_v(synctex_node_p node) {\
   1030     if (_synctex_data_has_##WHAT(node)) {\
   1031         synctex_is_s is = _synctex_decode_int_v(node->class_->scanner);\
   1032         if (is.status == SYNCTEX_STATUS_OK) {\
   1033             _synctex_data_set_##WHAT(node,is.integer);\
   1034         } \
   1035         return is.status;\
   1036     }\
   1037     return SYNCTEX_STATUS_BAD_ARGUMENT;\
   1038 }
   1039 #define DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \
   1040 DEFINE_SYNCTEX_DATA_HAS(WHAT)\
   1041 static char * _synctex_data_##WHAT(synctex_node_p node) {\
   1042     if (_synctex_data_has_##WHAT(node)) {\
   1043         return node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string;\
   1044     }\
   1045     return NULL;\
   1046 }\
   1047 static char * _synctex_data_set_##WHAT(synctex_node_p node, char * new_value) {\
   1048     char * old = "";\
   1049     if (_synctex_data_has_##WHAT(node)) {\
   1050         old = node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string;\
   1051         node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string =new_value;\
   1052     }\
   1053     return old;\
   1054 }
   1055 #define DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT) \
   1056 static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) {\
   1057     if (_synctex_data_has_##WHAT(node)) {\
   1058         synctex_ss_s ss = _synctex_decode_string(node->class_->scanner);\
   1059         if (ss.status == SYNCTEX_STATUS_OK) {\
   1060             _synctex_data_set_##WHAT(node,ss.string);\
   1061         } \
   1062         return ss.status;\
   1063     }\
   1064     return SYNCTEX_STATUS_BAD_ARGUMENT;\
   1065 }
   1066 #define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(WHAT) \
   1067 DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
   1068 DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT)
   1069 #define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(WHAT) \
   1070 DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
   1071 DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT)
   1072 #define DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(WHAT) \
   1073 DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \
   1074 DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT)
   1075 
   1076 #	ifdef SYNCTEX_NOTHING
   1077 #       pragma mark -
   1078 #       pragma mark OBJECTS, their creators and destructors.
   1079 #   endif
   1080 
   1081 #	ifdef SYNCTEX_NOTHING
   1082 #       pragma mark input.
   1083 #   endif
   1084 
   1085 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(tag)
   1086 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(line)
   1087 DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(name)
   1088 
   1089 /*  Input nodes only know about their sibling, which is another input node.
   1090  *  The synctex information is the _synctex_data_tag and _synctex_data_name
   1091  *  note: the input owns its name. */
   1092 
   1093 #   define SYNCTEX_INPUT_MARK "Input:"
   1094 
   1095 static const synctex_tree_model_s synctex_tree_model_input = {
   1096     synctex_tree_sibling_idx, /* sibling */
   1097     -1, /* parent */
   1098     -1, /* child */
   1099     -1, /* friend */
   1100     -1, /* last */
   1101     -1, /* next_hbox */
   1102     -1, /* arg_sibling */
   1103     -1, /* target */
   1104     synctex_tree_s_input_max
   1105 };
   1106 static const synctex_data_model_s synctex_data_model_input = {
   1107     synctex_data_input_tag_idx, /* tag */
   1108     synctex_data_input_line_idx,/* line */
   1109     -1, /* column */
   1110     -1, /* h */
   1111     -1, /* v */
   1112     -1, /* width */
   1113     -1, /* height */
   1114     -1, /* depth */
   1115     -1, /* mean_line */
   1116     -1, /* weight */
   1117     -1, /* h_V */
   1118     -1, /* v_V */
   1119     -1, /* width_V */
   1120     -1, /* height_V */
   1121     -1, /* depth_V */
   1122     synctex_data_input_name_idx, /* name */
   1123     -1, /* page */
   1124     synctex_data_input_tln_max
   1125 };
   1126 
   1127 #define SYNCTEX_INSPECTOR_GETTER_F(WHAT)\
   1128 &_synctex_data_##WHAT, &_synctex_data_set_##WHAT
   1129 
   1130 static synctex_node_p _synctex_new_input(synctex_scanner_p scanner);
   1131 static void _synctex_free_input(synctex_node_p node);
   1132 static void _synctex_log_input(synctex_node_p node);
   1133 static char * _synctex_abstract_input(synctex_node_p node);
   1134 static void _synctex_display_input(synctex_node_p node);
   1135 
   1136 static const synctex_tlcpector_s synctex_tlcpector_input = {
   1137     &_synctex_data_tag, /* tag */
   1138     &_synctex_int_none, /* line */
   1139     &_synctex_int_none, /* column */
   1140 };
   1141 
   1142 static synctex_class_s synctex_class_input = {
   1143     NULL,                       /*  No scanner yet */
   1144     synctex_node_type_input,    /*  Node type */
   1145     &_synctex_new_input,        /*  creator */
   1146     &_synctex_free_input,       /*  destructor */
   1147     &_synctex_log_input,        /*  log */
   1148     &_synctex_display_input,    /*  display */
   1149     &_synctex_abstract_input,   /*  abstract */
   1150     &synctex_tree_model_input,  /*  tree model */
   1151     &synctex_data_model_input,  /*  data model */
   1152     &synctex_tlcpector_input,   /*  inspector */
   1153     &synctex_inspector_none,    /*  inspector */
   1154     &synctex_vispector_none,    /*  vispector */
   1155 };
   1156 
   1157 typedef struct {
   1158     SYNCTEX_DECLARE_CHARINDEX
   1159     synctex_class_p class_;
   1160     synctex_data_u data[synctex_tree_s_input_max+synctex_data_input_tln_max];
   1161 } synctex_input_s;
   1162 
   1163 static synctex_node_p _synctex_new_input(synctex_scanner_p scanner) {
   1164     if (scanner) {
   1165         synctex_node_p node = _synctex_malloc(sizeof(synctex_input_s));
   1166         if (node) {
   1167             node->class_ = scanner->class_+synctex_node_type_input;
   1168             SYNCTEX_DID_NEW(node);
   1169             SYNCTEX_IMPLEMENT_CHARINDEX(node,0);
   1170             SYNCTEX_REGISTER_HANDLE_TO(node);
   1171         }
   1172         return node;
   1173     }
   1174     return NULL;
   1175 }
   1176 
   1177 static void _synctex_free_input(synctex_node_p node){
   1178     if (node) {
   1179         SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
   1180         SYNCTEX_WILL_FREE(node);
   1181         synctex_node_free(__synctex_tree_sibling(node));
   1182         _synctex_free(_synctex_data_name(node));
   1183         _synctex_free(node);
   1184     }
   1185 }
   1186 
   1187 /*  The sheet is a first level node.
   1188  *  It has no parent (the owner is the scanner itself)
   1189  *  Its sibling points to another sheet.
   1190  *  Its child points to its first child, in general a box.
   1191  *  A sheet node contains only one synctex information: the page.
   1192  *  This is the 1 based page index as given by TeX.
   1193  */
   1194 
   1195 #	ifdef SYNCTEX_NOTHING
   1196 #       pragma mark sheet.
   1197 #   endif
   1198 /**
   1199  *  Every node has the same structure, but not the same size.
   1200  */
   1201 
   1202 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(page)
   1203 
   1204 typedef struct {
   1205     SYNCTEX_DECLARE_CHARINDEX
   1206     synctex_class_p class_;
   1207     synctex_data_u data[synctex_tree_scn_sheet_max+synctex_data_p_sheet_max];
   1208 } synctex_node_sheet_s;
   1209 
   1210 /*  sheet node creator */
   1211 
   1212 #define DEFINE_synctex_new_scanned_NODE(NAME)\
   1213 static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) {\
   1214     if (scanner) {\
   1215         ++SYNCTEX_CUR;\
   1216         synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s));\
   1217         if (node) {\
   1218             node->class_ = scanner->class_+synctex_node_type_##NAME;\
   1219             SYNCTEX_DID_NEW(node); \
   1220             SYNCTEX_IMPLEMENT_CHARINDEX(node,-1);\
   1221             SYNCTEX_REGISTER_HANDLE_TO(node); \
   1222         }\
   1223         return node;\
   1224     }\
   1225     return NULL;\
   1226 }
   1227 /*  NB: -1 in SYNCTEX_IMPLEMENT_CHARINDEX above because
   1228  *  the first char of the line has been scanned
   1229  */
   1230 DEFINE_synctex_new_scanned_NODE(sheet)
   1231 static void _synctex_log_sheet(synctex_node_p node);
   1232 static char * _synctex_abstract_sheet(synctex_node_p node);
   1233 static void _synctex_display_sheet(synctex_node_p node);
   1234 
   1235 static const synctex_tree_model_s synctex_tree_model_sheet = {
   1236     synctex_tree_sibling_idx, /* sibling */
   1237     -1, /* parent */
   1238     synctex_tree_s_child_idx, /* child */
   1239     -1, /* friend */
   1240     -1, /* last */
   1241     synctex_tree_sc_next_hbox_idx, /* next_hbox */
   1242     -1, /* arg_sibling */
   1243     -1, /* target */
   1244     synctex_tree_scn_sheet_max
   1245 };
   1246 static const synctex_data_model_s synctex_data_model_sheet = {
   1247     -1, /* tag */
   1248     -1, /* line */
   1249     -1, /* column */
   1250     -1, /* h */
   1251     -1, /* v */
   1252     -1, /* width */
   1253     -1, /* height */
   1254     -1, /* depth */
   1255     -1, /* mean_line */
   1256     -1, /* weight */
   1257     -1, /* h_V */
   1258     -1, /* v_V */
   1259     -1, /* width_V */
   1260     -1, /* height_V */
   1261     -1, /* depth_V */
   1262     -1, /* name */
   1263     synctex_data_sheet_page_idx, /* page */
   1264     synctex_data_p_sheet_max
   1265 };
   1266 static synctex_class_s synctex_class_sheet = {
   1267     NULL,                       /*  No scanner yet */
   1268     synctex_node_type_sheet,    /*  Node type */
   1269     &_synctex_new_sheet,        /*  creator */
   1270     &_synctex_free_node,        /*  destructor */
   1271     &_synctex_log_sheet,        /*  log */
   1272     &_synctex_display_sheet,    /*  display */
   1273     &_synctex_abstract_sheet,   /*  abstract */
   1274     &synctex_tree_model_sheet,  /*  tree model */
   1275     &synctex_data_model_sheet,  /*  data model */
   1276     &synctex_tlcpector_none,    /*  tlcpector */
   1277     &synctex_inspector_none,    /*  inspector */
   1278     &synctex_vispector_none,    /*  vispector */
   1279 };
   1280 
   1281 #	ifdef SYNCTEX_NOTHING
   1282 #       pragma mark form.
   1283 #   endif
   1284 /**
   1285  *  Every node has the same structure, but not the same size.
   1286  */
   1287 typedef struct {
   1288     SYNCTEX_DECLARE_CHARINDEX
   1289     synctex_class_p class_;
   1290     synctex_data_u data[synctex_tree_sct_form_max+synctex_data_t_form_max];
   1291 } synctex_node_form_s;
   1292 
   1293 DEFINE_synctex_new_scanned_NODE(form)
   1294 
   1295 static char * _synctex_abstract_form(synctex_node_p node);
   1296 static void _synctex_display_form(synctex_node_p node);
   1297 static void _synctex_log_form(synctex_node_p node);
   1298 
   1299 static const synctex_tree_model_s synctex_tree_model_form = {
   1300     synctex_tree_sibling_idx, /* sibling */
   1301     -1, /* parent */
   1302     synctex_tree_s_child_idx, /* child */
   1303     -1, /* friend */
   1304     -1, /* last */
   1305     -1, /* next_hbox */
   1306     -1, /* arg_sibling */
   1307     synctex_tree_sc_target_idx, /* target */
   1308     synctex_tree_sct_form_max
   1309 };
   1310 static const synctex_data_model_s synctex_data_model_form = {
   1311     synctex_data_form_tag_idx, /* tag */
   1312     -1, /* line */
   1313     -1, /* column */
   1314     -1, /* h */
   1315     -1, /* v */
   1316     -1, /* width */
   1317     -1, /* height */
   1318     -1, /* depth */
   1319     -1, /* mean_line */
   1320     -1, /* weight */
   1321     -1, /* h_V */
   1322     -1, /* v_V */
   1323     -1, /* width_V */
   1324     -1, /* height_V */
   1325     -1, /* depth_V */
   1326     -1, /* name */
   1327     -1, /* page */
   1328     synctex_data_t_form_max
   1329 };
   1330 static synctex_class_s synctex_class_form = {
   1331     NULL,                       /*  No scanner yet */
   1332     synctex_node_type_form,     /*  Node type */
   1333     &_synctex_new_form,         /*  creator */
   1334     &_synctex_free_node,        /*  destructor */
   1335     &_synctex_log_form,         /*  log */
   1336     &_synctex_display_form,     /*  display */
   1337     &_synctex_abstract_form,    /*  abstract */
   1338     &synctex_tree_model_form,   /*  tree model */
   1339     &synctex_data_model_form,   /*  data model */
   1340     &synctex_tlcpector_none,    /*  tlcpector */
   1341     &synctex_inspector_none,    /*  inspector */
   1342     &synctex_vispector_none,    /*  vispector */
   1343 };
   1344 
   1345 #	ifdef SYNCTEX_NOTHING
   1346 #       pragma mark vbox.
   1347 #   endif
   1348 
   1349 /*  A box node contains navigation and synctex information
   1350  *  There are different kinds of boxes.
   1351  *  Only horizontal boxes are treated differently because of their visible size.
   1352  */
   1353 typedef struct {
   1354     SYNCTEX_DECLARE_CHARINDEX
   1355     synctex_class_p class_;
   1356     synctex_data_u data[synctex_tree_spcfl_vbox_max+synctex_data_box_max];
   1357 } synctex_node_vbox_s;
   1358 
   1359 /*  vertical box node creator */
   1360 DEFINE_synctex_new_scanned_NODE(vbox)
   1361 
   1362 static char * _synctex_abstract_vbox(synctex_node_p node);
   1363 static void _synctex_display_vbox(synctex_node_p node);
   1364 static void _synctex_log_vbox(synctex_node_p node);
   1365 
   1366 static const synctex_tree_model_s synctex_tree_model_vbox = {
   1367     synctex_tree_sibling_idx,       /* sibling */
   1368     synctex_tree_s_parent_idx,      /* parent */
   1369     synctex_tree_sp_child_idx,      /* child */
   1370     synctex_tree_spc_friend_idx,    /* friend */
   1371     synctex_tree_spcf_last_idx,     /* last */
   1372     -1, /* next_hbox */
   1373     -1, /* arg_sibling */
   1374     -1, /* target */
   1375     synctex_tree_spcfl_vbox_max
   1376 };
   1377 
   1378 #define SYNCTEX_DFLT_COLUMN -1
   1379 
   1380 DEFINE_SYNCTEX_DATA_INT_GETSET(column)
   1381 static synctex_status_t _synctex_data_decode_column(synctex_node_p node) {
   1382     if (_synctex_data_has_column(node)) {
   1383         synctex_is_s is = _synctex_decode_int_opt(node->class_->scanner,
   1384             SYNCTEX_DFLT_COLUMN);
   1385         if (is.status == SYNCTEX_STATUS_OK) {
   1386             _synctex_data_set_column(node,is.integer);
   1387         }
   1388         return is.status;
   1389     }
   1390     return SYNCTEX_STATUS_BAD_ARGUMENT;
   1391 }
   1392 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(h)
   1393 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(v)
   1394 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(width)
   1395 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(height)
   1396 DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(depth)
   1397 
   1398 SYNCTEX_INLINE static void _synctex_data_set_tlc(synctex_node_p node, synctex_node_p model) {
   1399     _synctex_data_set_tag(node, _synctex_data_tag(model));
   1400     _synctex_data_set_line(node, _synctex_data_line(model));
   1401     _synctex_data_set_column(node, _synctex_data_column(model));
   1402 }
   1403 SYNCTEX_INLINE static void _synctex_data_set_tlchv(synctex_node_p node, synctex_node_p model) {
   1404     _synctex_data_set_tlc(node,model);
   1405     _synctex_data_set_h(node, _synctex_data_h(model));
   1406     _synctex_data_set_v(node, _synctex_data_v(model));
   1407 }
   1408 
   1409 static const synctex_data_model_s synctex_data_model_box = {
   1410     synctex_data_tag_idx, /* tag */
   1411     synctex_data_line_idx,  /* line */
   1412     synctex_data_column_idx,/* column */
   1413     synctex_data_h_idx,     /* h */
   1414     synctex_data_v_idx,     /* v */
   1415     synctex_data_width_idx, /* width */
   1416     synctex_data_height_idx,/* height */
   1417     synctex_data_depth_idx, /* depth */
   1418     -1, /* mean_line */
   1419     -1, /* weight */
   1420     -1, /* h_V */
   1421     -1, /* v_V */
   1422     -1, /* width_V */
   1423     -1, /* height_V */
   1424     -1, /* depth_V */
   1425     -1, /* name */
   1426     -1, /* page */
   1427     synctex_data_box_max
   1428 };
   1429 static const synctex_tlcpector_s synctex_tlcpector_default = {
   1430     &_synctex_data_tag, /* tag */
   1431     &_synctex_data_line, /* line */
   1432     &_synctex_data_column, /* column */
   1433 };
   1434 static const synctex_inspector_s synctex_inspector_box = {
   1435     &_synctex_data_h,
   1436     &_synctex_data_v,
   1437     &_synctex_data_width,
   1438     &_synctex_data_height,
   1439     &_synctex_data_depth,
   1440 };
   1441 static float __synctex_node_visible_h(synctex_node_p node);
   1442 static float __synctex_node_visible_v(synctex_node_p node);
   1443 static float __synctex_node_visible_width(synctex_node_p node);
   1444 static float __synctex_node_visible_height(synctex_node_p node);
   1445 static float __synctex_node_visible_depth(synctex_node_p node);
   1446 static synctex_vispector_s synctex_vispector_box = {
   1447     &__synctex_node_visible_h,
   1448     &__synctex_node_visible_v,
   1449     &__synctex_node_visible_width,
   1450     &__synctex_node_visible_height,
   1451     &__synctex_node_visible_depth,
   1452 };
   1453 /*  These are static class objects, each scanner will make a copy of them and setup the scanner field.
   1454  */
   1455 static synctex_class_s synctex_class_vbox = {
   1456     NULL,                       /*  No scanner yet */
   1457     synctex_node_type_vbox,     /*  Node type */
   1458     &_synctex_new_vbox,         /*  creator */
   1459     &_synctex_free_node,        /*  destructor */
   1460     &_synctex_log_vbox,         /*  log */
   1461     &_synctex_display_vbox,     /*  display */
   1462     &_synctex_abstract_vbox,    /*  abstract */
   1463     &synctex_tree_model_vbox,   /*  tree model */
   1464     &synctex_data_model_box,    /*  data model */
   1465     &synctex_tlcpector_default, /*  tlcpector */
   1466     &synctex_inspector_box,     /*  inspector */
   1467     &synctex_vispector_box,     /*  vispector */
   1468 };
   1469 
   1470 #	ifdef SYNCTEX_NOTHING
   1471 #       pragma mark hbox.
   1472 #   endif
   1473 
   1474 /*  Horizontal boxes must contain visible size, because 0 width does not mean emptiness.
   1475  *  They also contain an average of the line numbers of the containing nodes. */
   1476 
   1477 static const synctex_tree_model_s synctex_tree_model_hbox = {
   1478     synctex_tree_sibling_idx,       /* sibling */
   1479     synctex_tree_s_parent_idx,      /* parent */
   1480     synctex_tree_sp_child_idx,      /* child */
   1481     synctex_tree_spc_friend_idx,    /* friend */
   1482     synctex_tree_spcf_last_idx,     /* last */
   1483     synctex_tree_spcfl_next_hbox_idx, /* next_hbox */
   1484     -1, /* arg_sibling */
   1485     -1, /* target */
   1486     synctex_tree_spcfln_hbox_max
   1487 };
   1488 
   1489 DEFINE_SYNCTEX_DATA_INT_GETSET(mean_line)
   1490 DEFINE_SYNCTEX_DATA_INT_GETSET(weight)
   1491 DEFINE_SYNCTEX_DATA_INT_GETSET(h_V)
   1492 DEFINE_SYNCTEX_DATA_INT_GETSET(v_V)
   1493 DEFINE_SYNCTEX_DATA_INT_GETSET(width_V)
   1494 DEFINE_SYNCTEX_DATA_INT_GETSET(height_V)
   1495 DEFINE_SYNCTEX_DATA_INT_GETSET(depth_V)
   1496 
   1497 /**
   1498  *  The hbox model.
   1499  *  It contains V variants of geometrical information.
   1500  *  It happens that hboxes contain material that is not used to compute
   1501  *  the bounding box. Some letters may appear out of the box given by TeX.
   1502  *  In such a situation, the visible bounding box is bigger ence the V variant.
   1503  *  Only hboxes have such variant. It does not make sense for void boxes
   1504  *  and it is not used here for vboxes.
   1505  *  - author: JL
   1506  */
   1507 
   1508 static const synctex_data_model_s synctex_data_model_hbox = {
   1509     synctex_data_tag_idx, /* tag */
   1510     synctex_data_line_idx,  /* line */
   1511     synctex_data_column_idx,/* column */
   1512     synctex_data_h_idx,     /* h */
   1513     synctex_data_v_idx,     /* v */
   1514     synctex_data_width_idx, /* width */
   1515     synctex_data_height_idx,/* height */
   1516     synctex_data_depth_idx, /* depth */
   1517     synctex_data_mean_line_idx, /* mean_line */
   1518     synctex_data_weight_idx, /* weight */
   1519     synctex_data_h_V_idx, /* h_V */
   1520     synctex_data_v_V_idx, /* v_V */
   1521     synctex_data_width_V_idx, /* width_V */
   1522     synctex_data_height_V_idx, /* height_V */
   1523     synctex_data_depth_V_idx, /* depth_V */
   1524     -1, /* name */
   1525     -1, /* page */
   1526     synctex_data_hbox_max
   1527 };
   1528 
   1529 typedef struct {
   1530     SYNCTEX_DECLARE_CHARINDEX
   1531     synctex_class_p class_;
   1532     synctex_data_u data[synctex_tree_spcfln_hbox_max+synctex_data_hbox_max];
   1533 } synctex_node_hbox_s;
   1534 
   1535 /*  horizontal box node creator */
   1536 DEFINE_synctex_new_scanned_NODE(hbox)
   1537 
   1538 static void _synctex_log_hbox(synctex_node_p node);
   1539 static char * _synctex_abstract_hbox(synctex_node_p node);
   1540 static void _synctex_display_hbox(synctex_node_p node);
   1541 
   1542 static synctex_class_s synctex_class_hbox = {
   1543     NULL,                       /*  No scanner yet */
   1544     synctex_node_type_hbox,     /*  Node type */
   1545     &_synctex_new_hbox,         /*  creator */
   1546     &_synctex_free_node,        /*  destructor */
   1547     &_synctex_log_hbox,         /*  log */
   1548     &_synctex_display_hbox,     /*  display */
   1549     &_synctex_abstract_hbox,    /*  abstract */
   1550     &synctex_tree_model_hbox,   /*  tree model */
   1551     &synctex_data_model_hbox,   /*  data model */
   1552     &synctex_tlcpector_default, /*  tlcpector */
   1553     &synctex_inspector_box,     /*  inspector */
   1554     &synctex_vispector_box,     /*  vispector */
   1555 };
   1556 
   1557 #	ifdef SYNCTEX_NOTHING
   1558 #       pragma mark void vbox.
   1559 #   endif
   1560 
   1561 /*  This void box node implementation is either horizontal or vertical
   1562  *  It does not contain a child field.
   1563  */
   1564 static const synctex_tree_model_s synctex_tree_model_spf = {
   1565     synctex_tree_sibling_idx,   /* sibling */
   1566     synctex_tree_s_parent_idx,  /* parent */
   1567     -1, /* child */
   1568     synctex_tree_sp_friend_idx, /* friend */
   1569     -1, /* last */
   1570     -1, /* next_hbox */
   1571     -1, /* arg_sibling */
   1572     -1, /* target */
   1573     synctex_tree_spf_max
   1574 };
   1575 typedef struct {
   1576     SYNCTEX_DECLARE_CHARINDEX
   1577     synctex_class_p class_;
   1578     synctex_data_u data[synctex_tree_spf_max+synctex_data_box_max];
   1579 } synctex_node_void_vbox_s;
   1580 
   1581 /*  vertical void box node creator */
   1582 DEFINE_synctex_new_scanned_NODE(void_vbox)
   1583 
   1584 static void _synctex_log_void_box(synctex_node_p node);
   1585 static char * _synctex_abstract_void_vbox(synctex_node_p node);
   1586 static void _synctex_display_void_vbox(synctex_node_p node);
   1587 
   1588 static synctex_class_s synctex_class_void_vbox = {
   1589     NULL,                       /*  No scanner yet */
   1590     synctex_node_type_void_vbox,/*  Node type */
   1591     &_synctex_new_void_vbox,    /*  creator */
   1592     &_synctex_free_leaf,        /*  destructor */
   1593     &_synctex_log_void_box,     /*  log */
   1594     &_synctex_display_void_vbox,/*  display */
   1595     &_synctex_abstract_void_vbox,/*  abstract */
   1596     &synctex_tree_model_spf,    /*  tree model */
   1597     &synctex_data_model_box,    /*  data model */
   1598     &synctex_tlcpector_default, /*  tlcpector */
   1599     &synctex_inspector_box,     /*  inspector */
   1600     &synctex_vispector_box,     /*  vispector */
   1601 };
   1602 
   1603 #	ifdef SYNCTEX_NOTHING
   1604 #       pragma mark void hbox.
   1605 #   endif
   1606 
   1607 typedef synctex_node_void_vbox_s synctex_node_void_hbox_s;
   1608 
   1609 /*  horizontal void box node creator */
   1610 DEFINE_synctex_new_scanned_NODE(void_hbox)
   1611 
   1612 static char * _synctex_abstract_void_hbox(synctex_node_p node);
   1613 static void _synctex_display_void_hbox(synctex_node_p node);
   1614 
   1615 static synctex_class_s synctex_class_void_hbox = {
   1616     NULL,                       /*  No scanner yet */
   1617     synctex_node_type_void_hbox,/*  Node type */
   1618     &_synctex_new_void_hbox,    /*  creator */
   1619     &_synctex_free_leaf,        /*  destructor */
   1620     &_synctex_log_void_box,     /*  log */
   1621     &_synctex_display_void_hbox,/*  display */
   1622     &_synctex_abstract_void_hbox,/*  abstract */
   1623     &synctex_tree_model_spf,    /*  tree model */
   1624     &synctex_data_model_box,    /*  data model */
   1625     &synctex_tlcpector_default, /*  tlcpector */
   1626     &synctex_inspector_box,     /*  inspector */
   1627     &synctex_vispector_box,     /*  vispector */
   1628 };
   1629 
   1630 #	ifdef SYNCTEX_NOTHING
   1631 #       pragma mark form ref.
   1632 #   endif
   1633 
   1634 /*  The form ref node.  */
   1635 typedef struct {
   1636     SYNCTEX_DECLARE_CHARINDEX
   1637     synctex_class_p class_;
   1638     synctex_data_u data[synctex_tree_spfa_max+synctex_data_ref_thv_max];
   1639 } synctex_node_ref_s;
   1640 
   1641 /*  form ref node creator */
   1642 DEFINE_synctex_new_scanned_NODE(ref)
   1643 
   1644 static void _synctex_log_ref(synctex_node_p node);
   1645 static char * _synctex_abstract_ref(synctex_node_p node);
   1646 static void _synctex_display_ref(synctex_node_p node);
   1647 
   1648 static const synctex_tree_model_s synctex_tree_model_spfa = {
   1649     synctex_tree_sibling_idx,   /* sibling */
   1650     synctex_tree_s_parent_idx,  /* parent */
   1651     -1, /* child */
   1652     synctex_tree_sp_friend_idx, /* friend */
   1653     -1, /* last */
   1654     -1, /* next_hbox */
   1655     synctex_tree_spf_arg_sibling_idx, /* arg_sibling */
   1656     -1, /* target */
   1657     synctex_tree_spfa_max
   1658 };
   1659 static const synctex_data_model_s synctex_data_model_ref = {
   1660     synctex_data_tag_idx, /* tag */
   1661     -1, /* line */
   1662     -1, /* column */
   1663     synctex_data_ref_h_idx, /* h */
   1664     synctex_data_ref_v_idx, /* v */
   1665     -1, /* width */
   1666     -1, /* height */
   1667     -1, /* depth */
   1668     -1, /* mean_line */
   1669     -1, /* weight */
   1670     -1, /* h_V */
   1671     -1, /* v_V */
   1672     -1, /* width_V */
   1673     -1, /* height_V */
   1674     -1, /* depth_V */
   1675     -1, /* name */
   1676     -1, /* page */
   1677     synctex_data_ref_thv_max /* size */
   1678 };
   1679 static synctex_class_s synctex_class_ref = {
   1680     NULL,                       /*  No scanner yet */
   1681     synctex_node_type_ref,      /*  Node type */
   1682     &_synctex_new_ref,          /*  creator */
   1683     &_synctex_free_leaf,        /*  destructor */
   1684     &_synctex_log_ref,          /*  log */
   1685     &_synctex_display_ref,      /*  display */
   1686     &_synctex_abstract_ref,     /*  abstract */
   1687     &synctex_tree_model_spfa,   /*  navigator */
   1688     &synctex_data_model_ref,    /*  data model */
   1689     &synctex_tlcpector_none,    /*  tlcpector */
   1690     &synctex_inspector_none,    /*  inspector */
   1691     &synctex_vispector_none,    /*  vispector */
   1692 };
   1693 #	ifdef SYNCTEX_NOTHING
   1694 #       pragma mark small node.
   1695 #   endif
   1696 
   1697 /*  The small nodes correspond to glue, penalty, math and boundary nodes. */
   1698 static const synctex_data_model_s synctex_data_model_tlchv = {
   1699     synctex_data_tag_idx, /* tag */
   1700     synctex_data_line_idx, /* line */
   1701     synctex_data_column_idx, /* column */
   1702     synctex_data_h_idx, /* h */
   1703     synctex_data_v_idx, /* v */
   1704     -1, /* width */
   1705     -1, /* height */
   1706     -1, /* depth */
   1707     -1, /* mean_line */
   1708     -1, /* weight */
   1709     -1, /* h_V */
   1710     -1, /* v_V */
   1711     -1, /* width_V */
   1712     -1, /* height_V */
   1713     -1, /* depth_V */
   1714     -1, /* name */
   1715     -1, /* page */
   1716     synctex_data_tlchv_max
   1717 };
   1718 
   1719 typedef struct {
   1720     SYNCTEX_DECLARE_CHARINDEX
   1721     synctex_class_p class_;
   1722     synctex_data_u data[synctex_tree_spf_max+synctex_data_tlchv_max];
   1723 } synctex_node_tlchv_s;
   1724 
   1725 static void _synctex_log_tlchv_node(synctex_node_p node);
   1726 
   1727 #	ifdef SYNCTEX_NOTHING
   1728 #       pragma mark math.
   1729 #   endif
   1730 
   1731 typedef synctex_node_tlchv_s synctex_node_math_s;
   1732 
   1733 /*  math node creator */
   1734 DEFINE_synctex_new_scanned_NODE(math)
   1735 
   1736 static char * _synctex_abstract_math(synctex_node_p node);
   1737 static void _synctex_display_math(synctex_node_p node);
   1738 static synctex_inspector_s synctex_inspector_hv = {
   1739     &_synctex_data_h,
   1740     &_synctex_data_v,
   1741     &_synctex_int_none,
   1742     &_synctex_int_none,
   1743     &_synctex_int_none,
   1744 };
   1745 static synctex_vispector_s synctex_vispector_hv = {
   1746     &__synctex_node_visible_h,
   1747     &__synctex_node_visible_v,
   1748     &_synctex_float_none,
   1749     &_synctex_float_none,
   1750     &_synctex_float_none,
   1751 };
   1752 
   1753 static synctex_class_s synctex_class_math = {
   1754     NULL,                       /*  No scanner yet */
   1755     synctex_node_type_math,     /*  Node type */
   1756     &_synctex_new_math,         /*  creator */
   1757     &_synctex_free_leaf,        /*  destructor */
   1758     &_synctex_log_tlchv_node,   /*  log */
   1759     &_synctex_display_math,     /*  display */
   1760     &_synctex_abstract_math,    /*  abstract */
   1761     &synctex_tree_model_spf,    /*  tree model */
   1762     &synctex_data_model_tlchv,  /*  data model */
   1763     &synctex_tlcpector_default, /*  tlcpector */
   1764     &synctex_inspector_hv,      /*  inspector */
   1765     &synctex_vispector_hv,      /*  vispector */
   1766 };
   1767 
   1768 #	ifdef SYNCTEX_NOTHING
   1769 #       pragma mark kern node.
   1770 #   endif
   1771 
   1772 static const synctex_data_model_s synctex_data_model_tlchvw = {
   1773     synctex_data_tag_idx,   /* tag */
   1774     synctex_data_line_idx,  /* line */
   1775     synctex_data_column_idx,/* column */
   1776     synctex_data_h_idx,     /* h */
   1777     synctex_data_v_idx,     /* v */
   1778     synctex_data_width_idx, /* width */
   1779     -1, /* height */
   1780     -1, /* depth */
   1781     -1, /* mean_line */
   1782     -1, /* weight */
   1783     -1, /* h_V */
   1784     -1, /* v_V */
   1785     -1, /* width_V */
   1786     -1, /* height_V */
   1787     -1, /* depth_V */
   1788     -1, /* name */
   1789     -1, /* page */
   1790     synctex_data_tlchvw_max
   1791 };
   1792 typedef struct {
   1793     SYNCTEX_DECLARE_CHARINDEX
   1794     synctex_class_p class_;
   1795     synctex_data_u data[synctex_tree_spf_max+synctex_data_tlchvw_max];
   1796 } synctex_node_kern_s;
   1797 
   1798 /*  kern node creator */
   1799 DEFINE_synctex_new_scanned_NODE(kern)
   1800 
   1801 static void _synctex_log_kern_node(synctex_node_p node);
   1802 static char * _synctex_abstract_kern(synctex_node_p node);
   1803 static void _synctex_display_kern(synctex_node_p node);
   1804 
   1805 static synctex_inspector_s synctex_inspector_kern = {
   1806     &_synctex_data_h,
   1807     &_synctex_data_v,
   1808     &_synctex_data_width,
   1809     &_synctex_int_none,
   1810     &_synctex_int_none,
   1811 };
   1812 static float __synctex_kern_visible_h(synctex_node_p node);
   1813 static float __synctex_kern_visible_width(synctex_node_p node);
   1814 static synctex_vispector_s synctex_vispector_kern = {
   1815     &__synctex_kern_visible_h,
   1816     &__synctex_node_visible_v,
   1817     &__synctex_kern_visible_width,
   1818     &_synctex_float_none,
   1819     &_synctex_float_none,
   1820 };
   1821 
   1822 static synctex_class_s synctex_class_kern = {
   1823     NULL,                       /*  No scanner yet */
   1824     synctex_node_type_kern,     /*  Node type */
   1825     &_synctex_new_kern,         /*  creator */
   1826     &_synctex_free_leaf,        /*  destructor */
   1827     &_synctex_log_kern_node,    /*  log */
   1828     &_synctex_display_kern,     /*  display */
   1829     &_synctex_abstract_kern,    /*  abstract */
   1830     &synctex_tree_model_spf,    /*  tree model */
   1831     &synctex_data_model_tlchvw, /*  data model */
   1832     &synctex_tlcpector_default, /*  tlcpector */
   1833     &synctex_inspector_kern,    /*  inspector */
   1834     &synctex_vispector_kern,    /*  vispector */
   1835 };
   1836 
   1837 #	ifdef SYNCTEX_NOTHING
   1838 #       pragma mark glue.
   1839 #   endif
   1840 
   1841 /*  glue node creator */
   1842 typedef synctex_node_tlchv_s synctex_node_glue_s;
   1843 DEFINE_synctex_new_scanned_NODE(glue)
   1844 
   1845 static char * _synctex_abstract_glue(synctex_node_p node);
   1846 static void _synctex_display_glue(synctex_node_p node);
   1847 
   1848 static synctex_class_s synctex_class_glue = {
   1849     NULL,                       /*  No scanner yet */
   1850     synctex_node_type_glue,     /*  Node type */
   1851     &_synctex_new_glue,         /*  creator */
   1852     &_synctex_free_leaf,        /*  destructor */
   1853     &_synctex_log_tlchv_node,   /*  log */
   1854     &_synctex_display_glue,     /*  display */
   1855     &_synctex_abstract_glue,    /*  abstract */
   1856     &synctex_tree_model_spf,    /*  tree model */
   1857     &synctex_data_model_tlchv,  /*  data model */
   1858     &synctex_tlcpector_default, /*  tlcpector */
   1859     &synctex_inspector_hv,      /*  inspector */
   1860     &synctex_vispector_hv,      /*  vispector */
   1861 };
   1862 
   1863 /*  The small nodes correspond to glue and boundary nodes.  */
   1864 
   1865 #	ifdef SYNCTEX_NOTHING
   1866 #       pragma mark rule.
   1867 #   endif
   1868 
   1869 typedef struct {
   1870     SYNCTEX_DECLARE_CHARINDEX
   1871     synctex_class_p class_;
   1872     synctex_data_u data[synctex_tree_spf_max+synctex_data_box_max];
   1873 } synctex_node_rule_s;
   1874 
   1875 DEFINE_synctex_new_scanned_NODE(rule)
   1876 
   1877 static void _synctex_log_rule(synctex_node_p node);
   1878 static char * _synctex_abstract_rule(synctex_node_p node);
   1879 static void _synctex_display_rule(synctex_node_p node);
   1880 
   1881 static float __synctex_rule_visible_h(synctex_node_p node);
   1882 static float __synctex_rule_visible_v(synctex_node_p node);
   1883 static float __synctex_rule_visible_width(synctex_node_p node);
   1884 static float __synctex_rule_visible_height(synctex_node_p node);
   1885 static float __synctex_rule_visible_depth(synctex_node_p node);
   1886 static synctex_vispector_s synctex_vispector_rule = {
   1887     &__synctex_rule_visible_h,
   1888     &__synctex_rule_visible_v,
   1889     &__synctex_rule_visible_width,
   1890     &__synctex_rule_visible_height,
   1891     &__synctex_rule_visible_depth,
   1892 };
   1893 
   1894 static synctex_class_s synctex_class_rule = {
   1895     NULL,                       /*  No scanner yet */
   1896     synctex_node_type_rule,     /*  Node type */
   1897     &_synctex_new_rule,         /*  creator */
   1898     &_synctex_free_leaf,        /*  destructor */
   1899     &_synctex_log_rule,         /*  log */
   1900     &_synctex_display_rule,     /*  display */
   1901     &_synctex_abstract_rule,    /*  abstract */
   1902     &synctex_tree_model_spf,    /*  tree model */
   1903     &synctex_data_model_box,    /*  data model */
   1904     &synctex_tlcpector_default, /*  tlcpector */
   1905     &synctex_inspector_box,     /*  inspector */
   1906     &synctex_vispector_rule,    /*  vispector */
   1907 };
   1908 
   1909 #	ifdef SYNCTEX_NOTHING
   1910 #       pragma mark boundary.
   1911 #   endif
   1912 
   1913 /*  boundary node creator */
   1914 typedef synctex_node_tlchv_s synctex_node_boundary_s;
   1915 DEFINE_synctex_new_scanned_NODE(boundary)
   1916 
   1917 static char * _synctex_abstract_boundary(synctex_node_p node);
   1918 static void _synctex_display_boundary(synctex_node_p node);
   1919 
   1920 static synctex_class_s synctex_class_boundary = {
   1921     NULL,                       /*  No scanner yet */
   1922     synctex_node_type_boundary, /*  Node type */
   1923     &_synctex_new_boundary,     /*  creator */
   1924     &_synctex_free_leaf,        /*  destructor */
   1925     &_synctex_log_tlchv_node,   /*  log */
   1926     &_synctex_display_boundary, /*  display */
   1927     &_synctex_abstract_boundary,/*  abstract */
   1928     &synctex_tree_model_spf,    /*  tree model */
   1929     &synctex_data_model_tlchv,  /*  data model */
   1930     &synctex_tlcpector_default, /*  tlcpector */
   1931     &synctex_inspector_hv,      /*  inspector */
   1932     &synctex_vispector_hv,      /*  vispector */
   1933 };
   1934 
   1935 #	ifdef SYNCTEX_NOTHING
   1936 #       pragma mark box boundary.
   1937 #   endif
   1938 
   1939 typedef struct {
   1940     SYNCTEX_DECLARE_CHARINDEX
   1941     synctex_class_p class_;
   1942     synctex_data_u data[synctex_tree_spfa_max+synctex_data_tlchv_max];
   1943 } synctex_node_box_bdry_s;
   1944 
   1945 #define DEFINE_synctex_new_unscanned_NODE(NAME)\
   1946 SYNCTEX_INLINE static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) {\
   1947     if (scanner) {\
   1948         synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s));\
   1949         if (node) {\
   1950             node->class_ = scanner->class_+synctex_node_type_##NAME;\
   1951             SYNCTEX_DID_NEW(node); \
   1952         }\
   1953         return node;\
   1954     }\
   1955     return NULL;\
   1956 }
   1957 DEFINE_synctex_new_unscanned_NODE(box_bdry)
   1958 
   1959 static char * _synctex_abstract_box_bdry(synctex_node_p node);
   1960 static void _synctex_display_box_bdry(synctex_node_p node);
   1961 
   1962 static synctex_class_s synctex_class_box_bdry = {
   1963     NULL,                       /*  No scanner yet */
   1964     synctex_node_type_box_bdry, /*  Node type */
   1965     &_synctex_new_box_bdry,     /*  creator */
   1966     &_synctex_free_leaf,        /*  destructor */
   1967     &_synctex_log_tlchv_node,   /*  log */
   1968     &_synctex_display_box_bdry, /*  display */
   1969     &_synctex_abstract_box_bdry,/*  display */
   1970     &synctex_tree_model_spfa,   /*  tree model */
   1971     &synctex_data_model_tlchv,  /*  data model */
   1972     &synctex_tlcpector_default, /*  tlcpector */
   1973     &synctex_inspector_hv,      /*  inspector */
   1974     &synctex_vispector_hv,      /*  vispector */
   1975 };
   1976 
   1977 #	ifdef SYNCTEX_NOTHING
   1978 #       pragma mark hbox proxy.
   1979 #   endif
   1980 
   1981 /**
   1982  *  Standard nodes refer to TeX nodes: math, kern, boxes...
   1983  *  Proxy nodes are used to support forms.
   1984  *  A form is parsed as a tree of standard nodes starting
   1985  *  at the top left position.
   1986  *  When a reference is used, the form is duplicated
   1987  *  to the location specified by the reference.
   1988  *  As the same form can be duplicated at different locations,
   1989  *  the geometrical information is relative to its own top left point.
   1990  *  As we need absolute locations, we use proxy nodes.
   1991  *  A proxy node records an offset and the target node.
   1992  *  The target partly acts as a delegate.
   1993  *  The h and v position of the proxy node is the h and v
   1994  *  position of the target shifted by the proxy's offset.
   1995  *  The width, height and depth are not sensitive to offsets.
   1996  *  When are proxies created ?
   1997  *  1)  when the synctex file has been parsed, all the form refs
   1998  *  are replaced by proxies to the content of a form.
   1999  *  This content is a node with siblings (actually none).
   2000  *  Those root proxies have the parent of the ref they replace,
   2001  *  so their parents exist and are no proxy.
   2002  *  Moreover, if they have no sibling, it means that their target have no
   2003  *  sibling as well.
   2004  *  Such nodes are called root proxies.
   2005  *  2)  On the fly, when a proxy is asked for its child
   2006  *  (or sibling) and has none, a proxy to its target's child
   2007  *  (or sibling) is created if any. There are only 2 possible situations:
   2008  *  either the newly created proxy is the child of a proxy,
   2009  *  or it is the sibling of a proxy created on the fly.
   2010  *  In both cases, the parent is a proxy with children.
   2011  *  Such nodes are called child proxies.
   2012  *  How to compute the offset of a proxy ?
   2013  *  The offset of root proxy objects is exactly
   2014  *  the offset of the ref they replace.
   2015  *  The offset of other proxies is their owner's,
   2016  *  except when pointing to a root proxy.
   2017  *  What happens for cascading forms ?
   2018  *  Here is an example diagram
   2019  *
   2020  *  At parse time, the arrow means "owns":
   2021  *  sheet0 -> ref_to1
   2022  *
   2023  *            target1 -> ref_to2
   2024  *
   2025  *                       target2 -> child22
   2026  *
   2027  *  After replacing the refs:
   2028  *  sheet0 -> proxy00 -> proxy01 -> proxy02
   2029  *               |          |          |
   2030  *            target1 -> proxy11 -> proxy12
   2031  *                          |          |
   2032  *                       target2 -> proxy22
   2033  *
   2034  *  proxy00, proxy11 and proxy22 are root proxies.
   2035  *  Their offset is the one of the ref they replace
   2036  *  proxy01, proxy02 and proxy12 are child proxies.
   2037  *  Their proxy is the one of their parent.
   2038  *  Optimization.
   2039  *  After all the refs are replaced, there are only root nodes
   2040  *  targeting standard node. We make sure that each child proxy
   2041  *  also targets a standard node.
   2042  *  It is possible for a proxy to have a standard sibling 
   2043  *  whereas its target has no sibling at all. Root proxies
   2044  *  are such nodes, and are the only ones.
   2045  *  The consequence is that proxies created on the fly
   2046  *  must take into account this situation.
   2047  */
   2048 
   2049 /*  A proxy to a hbox.
   2050  *  A proxy do have a target, which can be a proxy
   2051  */
   2052 
   2053 static const synctex_tree_model_s synctex_tree_model_proxy_hbox = {
   2054     synctex_tree_sibling_idx,       /* sibling */
   2055     synctex_tree_s_parent_idx,      /* parent */
   2056     synctex_tree_sp_child_idx,      /* child */
   2057     synctex_tree_spc_friend_idx,    /* friend */
   2058     synctex_tree_spcf_last_idx,     /* last */
   2059     synctex_tree_spcfl_next_hbox_idx,   /* next_hbox */
   2060     -1, /* arg_sibling */
   2061     synctex_tree_spcfln_target_idx, /* target */
   2062     synctex_tree_spcflnt_proxy_hbox_max
   2063 };
   2064 static const synctex_data_model_s synctex_data_model_proxy = {
   2065     -1, /* tag */
   2066     -1, /* line */
   2067     -1, /* column */
   2068     synctex_data_proxy_h_idx, /* h */
   2069     synctex_data_proxy_v_idx, /* v */
   2070     -1, /* width */
   2071     -1, /* height */
   2072     -1, /* depth */
   2073     -1, /* mean_line */
   2074     -1, /* weight */
   2075     -1, /* h_V */
   2076     -1, /* v_V */
   2077     -1, /* width_V */
   2078     -1, /* height_V */
   2079     -1, /* depth_V */
   2080     -1, /* name */
   2081     -1, /* page */
   2082     synctex_data_proxy_hv_max
   2083 };
   2084 typedef struct {
   2085     SYNCTEX_DECLARE_CHARINDEX
   2086     synctex_class_p class_;
   2087     synctex_data_u data[synctex_tree_spcflnt_proxy_hbox_max+synctex_data_proxy_hv_max];
   2088 } synctex_node_proxy_hbox_s;
   2089 
   2090 /*  box proxy node creator */
   2091 DEFINE_synctex_new_unscanned_NODE(proxy_hbox)
   2092 
   2093 static void _synctex_log_proxy(synctex_node_p node);
   2094 static char * _synctex_abstract_proxy_hbox(synctex_node_p node);
   2095 static void _synctex_display_proxy_hbox(synctex_node_p node);
   2096 
   2097 static int _synctex_proxy_tag(synctex_node_p);
   2098 static int _synctex_proxy_line(synctex_node_p);
   2099 static int _synctex_proxy_column(synctex_node_p);
   2100 
   2101 static synctex_tlcpector_s synctex_tlcpector_proxy = {
   2102     &_synctex_proxy_tag,
   2103     &_synctex_proxy_line,
   2104     &_synctex_proxy_column,
   2105 };
   2106 static int _synctex_proxy_h(synctex_node_p);
   2107 static int _synctex_proxy_v(synctex_node_p);
   2108 static int _synctex_proxy_width(synctex_node_p);
   2109 static int _synctex_proxy_height(synctex_node_p);
   2110 static int _synctex_proxy_depth(synctex_node_p);
   2111 static synctex_inspector_s synctex_inspector_proxy_box = {
   2112     &_synctex_proxy_h,
   2113     &_synctex_proxy_v,
   2114     &_synctex_proxy_width,
   2115     &_synctex_proxy_height,
   2116     &_synctex_proxy_depth,
   2117 };
   2118 
   2119 static float __synctex_proxy_visible_h(synctex_node_p);
   2120 static float __synctex_proxy_visible_v(synctex_node_p);
   2121 static float __synctex_proxy_visible_width(synctex_node_p);
   2122 static float __synctex_proxy_visible_height(synctex_node_p);
   2123 static float __synctex_proxy_visible_depth(synctex_node_p);
   2124 
   2125 static synctex_vispector_s synctex_vispector_proxy_box = {
   2126     &__synctex_proxy_visible_h,
   2127     &__synctex_proxy_visible_v,
   2128     &__synctex_proxy_visible_width,
   2129     &__synctex_proxy_visible_height,
   2130     &__synctex_proxy_visible_depth,
   2131 };
   2132 
   2133 static synctex_class_s synctex_class_proxy_hbox = {
   2134     NULL,                           /*  No scanner yet */
   2135     synctex_node_type_proxy_hbox,   /*  Node type */
   2136     &_synctex_new_proxy_hbox,       /*  creator */
   2137     &_synctex_free_node,            /*  destructor */
   2138     &_synctex_log_proxy,            /*  log */
   2139     &_synctex_display_proxy_hbox,   /*  display */
   2140     &_synctex_abstract_proxy_hbox,  /*  abstract */
   2141     &synctex_tree_model_proxy_hbox, /*  tree model */
   2142     &synctex_data_model_proxy,      /*  data model */
   2143     &synctex_tlcpector_proxy,       /*  tlcpector */
   2144     &synctex_inspector_proxy_box,   /*  inspector */
   2145     &synctex_vispector_proxy_box,   /*  vispector */
   2146 };
   2147 
   2148 #	ifdef SYNCTEX_NOTHING
   2149 #       pragma mark vbox proxy.
   2150 #   endif
   2151 
   2152 /*  A proxy to a vbox. */
   2153 
   2154 static const synctex_tree_model_s synctex_tree_model_proxy_vbox = {
   2155     synctex_tree_sibling_idx,       /* sibling */
   2156     synctex_tree_s_parent_idx,      /* parent */
   2157     synctex_tree_sp_child_idx,      /* child */
   2158     synctex_tree_spc_friend_idx,    /* friend */
   2159     synctex_tree_spcf_last_idx, /* last */
   2160     -1, /* next_hbox */
   2161     -1, /* arg_sibling */
   2162     synctex_tree_spcfl_target_idx,    /* target */
   2163     synctex_tree_spcflt_proxy_vbox_max
   2164 };
   2165 
   2166 typedef struct {
   2167     SYNCTEX_DECLARE_CHARINDEX
   2168     synctex_class_p class_;
   2169     synctex_data_u data[synctex_tree_spcflt_proxy_vbox_max+synctex_data_proxy_hv_max];
   2170 } synctex_node_proxy_vbox_s;
   2171 
   2172 /*  box proxy node creator */
   2173 DEFINE_synctex_new_unscanned_NODE(proxy_vbox)
   2174 
   2175 static void _synctex_log_proxy(synctex_node_p node);
   2176 static char * _synctex_abstract_proxy_vbox(synctex_node_p node);
   2177 static void _synctex_display_proxy_vbox(synctex_node_p node);
   2178 
   2179 static synctex_class_s synctex_class_proxy_vbox = {
   2180     NULL,                           /*  No scanner yet */
   2181     synctex_node_type_proxy_vbox,   /*  Node type */
   2182     &_synctex_new_proxy_vbox,       /*  creator */
   2183     &_synctex_free_node,            /*  destructor */
   2184     &_synctex_log_proxy,            /*  log */
   2185     &_synctex_display_proxy_vbox,   /*  display */
   2186     &_synctex_abstract_proxy_vbox,  /*  abstract */
   2187     &synctex_tree_model_proxy_vbox, /*  tree model */
   2188     &synctex_data_model_proxy,      /*  data model */
   2189     &synctex_tlcpector_proxy,       /*  tlcpector */
   2190     &synctex_inspector_proxy_box,   /*  inspector */
   2191     &synctex_vispector_proxy_box,   /*  vispector */
   2192 };
   2193 
   2194 #	ifdef SYNCTEX_NOTHING
   2195 #       pragma mark proxy.
   2196 #   endif
   2197 
   2198 /**
   2199  *  A proxy to a node but a box.
   2200  */
   2201 
   2202 static const synctex_tree_model_s synctex_tree_model_proxy = {
   2203     synctex_tree_sibling_idx,   /* sibling */
   2204     synctex_tree_s_parent_idx,  /* parent */
   2205     -1, /* child */
   2206     synctex_tree_sp_friend_idx, /* friend */
   2207     -1, /* last */
   2208     -1, /* next_hbox */
   2209     -1, /* arg_sibling */
   2210     synctex_tree_spf_target_idx,/* target */
   2211     synctex_tree_spft_proxy_max
   2212 };
   2213 
   2214 typedef struct {
   2215     SYNCTEX_DECLARE_CHARINDEX
   2216     synctex_class_p class_;
   2217     synctex_data_u data[synctex_tree_spft_proxy_max+synctex_data_proxy_hv_max];
   2218 } synctex_node_proxy_s;
   2219 
   2220 /*  proxy node creator */
   2221 DEFINE_synctex_new_unscanned_NODE(proxy)
   2222 
   2223 static void _synctex_log_proxy(synctex_node_p node);
   2224 static char * _synctex_abstract_proxy(synctex_node_p node);
   2225 static void _synctex_display_proxy(synctex_node_p node);
   2226 
   2227 static synctex_vispector_s synctex_vispector_proxy = {
   2228     &__synctex_proxy_visible_h,
   2229     &__synctex_proxy_visible_v,
   2230     &__synctex_proxy_visible_width,
   2231     &_synctex_float_none,
   2232     &_synctex_float_none,
   2233 };
   2234 
   2235 static synctex_class_s synctex_class_proxy = {
   2236     NULL,                       /*  No scanner yet */
   2237     synctex_node_type_proxy,    /*  Node type */
   2238     &_synctex_new_proxy,        /*  creator */
   2239     &_synctex_free_leaf,        /*  destructor */
   2240     &_synctex_log_proxy,        /*  log */
   2241     &_synctex_display_proxy,    /*  display */
   2242     &_synctex_abstract_proxy,   /*  abstract */
   2243     &synctex_tree_model_proxy,  /*  tree model */
   2244     &synctex_data_model_proxy,  /*  data model */
   2245     &synctex_tlcpector_proxy,   /*  tlcpector */
   2246     &synctex_inspector_proxy_box,   /*  inspector */
   2247     &synctex_vispector_proxy,   /*  vispector */
   2248 };
   2249 
   2250 #	ifdef SYNCTEX_NOTHING
   2251 #       pragma mark last proxy.
   2252 #   endif
   2253 
   2254 /**
   2255  *  A proxy to the last proxy/box boundary.
   2256  */
   2257 
   2258 static const synctex_tree_model_s synctex_tree_model_proxy_last = {
   2259     synctex_tree_sibling_idx,   /* sibling */
   2260     synctex_tree_s_parent_idx,  /* parent */
   2261     -1, /* child */
   2262     synctex_tree_sp_friend_idx, /* friend */
   2263     -1, /* last */
   2264     -1, /* next_hbox */
   2265     synctex_tree_spf_arg_sibling_idx, /* arg_sibling */
   2266     synctex_tree_spfa_target_idx,     /* target */
   2267     synctex_tree_spfat_proxy_last_max
   2268 };
   2269 
   2270 typedef struct {
   2271     SYNCTEX_DECLARE_CHARINDEX
   2272     synctex_class_p class_;
   2273     synctex_data_u data[synctex_tree_spfat_proxy_last_max+synctex_data_proxy_hv_max];
   2274 } synctex_node_proxy_last_s;
   2275 
   2276 /*  proxy node creator */
   2277 DEFINE_synctex_new_unscanned_NODE(proxy_last)
   2278 
   2279 static void _synctex_log_proxy(synctex_node_p node);
   2280 static char * _synctex_abstract_proxy(synctex_node_p node);
   2281 static void _synctex_display_proxy(synctex_node_p node);
   2282 
   2283 static synctex_class_s synctex_class_proxy_last = {
   2284     NULL,                           /*  No scanner yet */
   2285     synctex_node_type_proxy_last,   /*  Node type */
   2286     &_synctex_new_proxy,            /*  creator */
   2287     &_synctex_free_leaf,            /*  destructor */
   2288     &_synctex_log_proxy,            /*  log */
   2289     &_synctex_display_proxy,        /*  display */
   2290     &_synctex_abstract_proxy,       /*  abstract */
   2291     &synctex_tree_model_proxy_last, /*  tree model */
   2292     &synctex_data_model_proxy,      /*  data model */
   2293     &synctex_tlcpector_proxy,       /*  tlcpector */
   2294     &synctex_inspector_proxy_box,       /*  inspector */
   2295     &synctex_vispector_proxy,       /*  vispector */
   2296 };
   2297 
   2298 #	ifdef SYNCTEX_NOTHING
   2299 #       pragma mark handle.
   2300 #   endif
   2301 
   2302 /**
   2303  *  A handle node.
   2304  *  A handle is never the target of a proxy
   2305  *  or another handle.
   2306  *  The child of a handle is always a handle if any.
   2307  *  The sibling of a handle is always a handle if any.
   2308  *  The parent of a handle is always a handle if any.
   2309  */
   2310 
   2311 static const synctex_tree_model_s synctex_tree_model_handle = {
   2312     synctex_tree_sibling_idx,   /* sibling */
   2313     synctex_tree_s_parent_idx,  /* parent */
   2314     synctex_tree_sp_child_idx,  /* child */
   2315     -1, /* friend */
   2316     -1, /* last */
   2317     -1, /* next_hbox */
   2318     -1, /* arg_sibling */
   2319     synctex_tree_spc_target_idx,/* target */
   2320     synctex_tree_spct_handle_max
   2321 };
   2322 
   2323 static const synctex_data_model_s synctex_data_model_handle = {
   2324     -1, /* tag */
   2325     -1, /* line */
   2326     -1, /* column */
   2327     -1, /* h */
   2328     -1, /* v */
   2329     -1, /* width */
   2330     -1, /* height */
   2331     -1, /* depth */
   2332     -1, /* mean_line */
   2333     synctex_data_handle_w_idx, /* weight */
   2334     -1, /* h_V */
   2335     -1, /* v_V */
   2336     -1, /* width_V */
   2337     -1, /* height_V */
   2338     -1, /* depth_V */
   2339     -1, /* name */
   2340     -1, /* page */
   2341     synctex_data_handle_w_max
   2342 };
   2343 
   2344 typedef struct {
   2345     SYNCTEX_DECLARE_CHARINDEX
   2346     synctex_class_p class_;
   2347     synctex_data_u data[synctex_tree_spct_handle_max+synctex_data_handle_w_max];
   2348 } synctex_node_handle_s;
   2349 
   2350 /*  handle node creator */
   2351 DEFINE_synctex_new_unscanned_NODE(handle)
   2352 
   2353 static void _synctex_log_handle(synctex_node_p node);
   2354 static char * _synctex_abstract_handle(synctex_node_p node);
   2355 static void _synctex_display_handle(synctex_node_p node);
   2356 
   2357 static synctex_class_s synctex_class_handle = {
   2358     NULL,                       /*  No scanner yet */
   2359     synctex_node_type_handle,   /*  Node type */
   2360     &_synctex_new_handle,       /*  creator */
   2361     &_synctex_free_handle,      /*  destructor */
   2362     &_synctex_log_handle,       /*  log */
   2363     &_synctex_display_handle,   /*  display */
   2364     &_synctex_abstract_handle,  /*  abstract */
   2365     &synctex_tree_model_handle, /*  tree model */
   2366     &synctex_data_model_handle, /*  data model */
   2367     &synctex_tlcpector_proxy,   /*  tlcpector */
   2368     &synctex_inspector_proxy_box,   /*  inspector */
   2369     &synctex_vispector_proxy_box,   /*  vispector */
   2370 };
   2371 
   2372 SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target) {
   2373     if (target) {
   2374         synctex_node_p result = _synctex_new_handle(target->class_->scanner);
   2375         if (result) {
   2376             _synctex_tree_set_target(result,target);
   2377             return result;
   2378         }
   2379     }
   2380     return NULL;
   2381 }
   2382 SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_child(synctex_node_p child) {
   2383     if (child) {
   2384         synctex_node_p result = _synctex_new_handle(child->class_->scanner);
   2385         if (result) {
   2386             _synctex_tree_set_child(result,child);
   2387             return result;
   2388         }
   2389     }
   2390     return NULL;
   2391 }
   2392 
   2393 #	ifdef SYNCTEX_NOTHING
   2394 #       pragma mark -
   2395 #       pragma mark Navigation
   2396 #   endif
   2397 synctex_node_p synctex_node_parent(synctex_node_p node)
   2398 {
   2399     return _synctex_tree_parent(node);
   2400 }
   2401 synctex_node_p synctex_node_parent_sheet(synctex_node_p node)
   2402 {
   2403     while(node && synctex_node_type(node) != synctex_node_type_sheet) {
   2404         node = _synctex_tree_parent(node);
   2405     }
   2406     /*  exit the while loop either when node is NULL or node is a sheet */
   2407     return node;
   2408 }
   2409 synctex_node_p synctex_node_parent_form(synctex_node_p node)
   2410 {
   2411     while(node && synctex_node_type(node) != synctex_node_type_form) {
   2412         node = _synctex_tree_parent(node);
   2413     }
   2414     /*  exit the while loop either when node is NULL or node is a form */
   2415     return node;
   2416 }
   2417 
   2418 /**
   2419  *  The returned proxy will be the child or a sibling of source.
   2420  *  The returned proxy has no parent, child nor sibling.
   2421  *  Used only by __synctex_replace_ref.
   2422  *  argument to_node: a box, not a proxy nor anything else.
   2423  */
   2424 SYNCTEX_INLINE static synctex_node_p __synctex_new_proxy_from_ref_to(synctex_node_p ref, synctex_node_p to_node) {
   2425     synctex_node_p proxy = NULL;
   2426     if (!ref || !to_node) {
   2427         return NULL;
   2428     }
   2429     switch(synctex_node_type(to_node)) {
   2430         case synctex_node_type_vbox:
   2431             proxy = _synctex_new_proxy_vbox(ref->class_->scanner);
   2432             break;
   2433         case synctex_node_type_hbox:
   2434             proxy = _synctex_new_proxy_hbox(ref->class_->scanner);
   2435             break;
   2436         default:
   2437             _synctex_error("!  __synctex_new_proxy_from_ref_to. Unexpected form child (%s). Please report.", synctex_node_isa(to_node));
   2438             return NULL;
   2439     }
   2440     if (!proxy) {
   2441         _synctex_error("!  __synctex_new_proxy_from_ref_to. Internal error. Please report.");
   2442         return NULL;
   2443     }
   2444     _synctex_data_set_h(proxy, _synctex_data_h(ref));
   2445     _synctex_data_set_v(proxy, _synctex_data_v(ref)-_synctex_data_height(to_node));
   2446     _synctex_tree_set_target(proxy,to_node);
   2447 #   if defined(SYNCTEX_USE_CHARINDEX)
   2448     proxy->line_index=to_node?to_node->line_index:0;
   2449     proxy->char_index=to_node?to_node->char_index:0;
   2450 #   endif
   2451     return proxy;
   2452 }
   2453 /**
   2454  *  The returned proxy will be the child or a sibling of owning_proxy.
   2455  *  The returned proxy has no parent, nor child.
   2456  *  Used only by synctex_node_child and synctex_node_sibling
   2457  *  to create proxies on the fly.
   2458  *  If the to_node has an already computed sibling,
   2459  *  then the returned proxy has itself a sibling
   2460  *  pointing to that already computed sibling.
   2461  */
   2462 SYNCTEX_INLINE static synctex_node_p __synctex_new_child_proxy_to(synctex_node_p owner, synctex_node_p to_node) {
   2463     synctex_node_p proxy = NULL;
   2464     synctex_node_p target = to_node;
   2465     if (!owner) {
   2466         return NULL;
   2467     }
   2468     switch(synctex_node_type(target)) {
   2469         case synctex_node_type_vbox:
   2470             if ((proxy = _synctex_new_proxy_vbox(owner->class_->scanner))) {
   2471             exit_standard:
   2472                 _synctex_data_set_h(proxy, _synctex_data_h(owner));
   2473                 _synctex_data_set_v(proxy, _synctex_data_v(owner));
   2474             exit0:
   2475                 _synctex_tree_set_target(proxy,target);
   2476 #   if defined(SYNCTEX_USE_CHARINDEX)
   2477                 proxy->line_index=to_node?to_node->line_index:0;
   2478                 proxy->char_index=to_node?to_node->char_index:0;
   2479 #   endif
   2480                 return proxy;
   2481             };
   2482             break;
   2483         case synctex_node_type_proxy_vbox:
   2484             if ((proxy = _synctex_new_proxy_vbox(owner->class_->scanner))) {
   2485             exit_proxy:
   2486                 target = _synctex_tree_target(to_node);
   2487                 _synctex_data_set_h(proxy, _synctex_data_h(owner)+_synctex_data_h(to_node));
   2488                 _synctex_data_set_v(proxy, _synctex_data_v(owner)+_synctex_data_v(to_node));
   2489                 goto exit0;
   2490             };
   2491             break;
   2492         case synctex_node_type_hbox:
   2493             if ((proxy = _synctex_new_proxy_hbox(owner->class_->scanner))) {
   2494                 goto exit_standard;
   2495             };
   2496             break;
   2497         case synctex_node_type_proxy_hbox:
   2498             if ((proxy = _synctex_new_proxy_hbox(owner->class_->scanner))) {
   2499                 goto exit_proxy;
   2500             };
   2501             break;
   2502         case synctex_node_type_proxy:
   2503         case synctex_node_type_proxy_last:
   2504             if ((proxy = _synctex_new_proxy(owner->class_->scanner))) {
   2505                 goto exit_proxy;
   2506             };
   2507             break;
   2508         default:
   2509             if ((proxy = _synctex_new_proxy(owner->class_->scanner))) {
   2510                 goto exit_standard;
   2511             };
   2512             break;
   2513     }
   2514     _synctex_error("!  __synctex_new_child_proxy_to. "
   2515                    "Internal error. "
   2516                    "Please report.");
   2517     return NULL;
   2518 }
   2519 SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling);
   2520 typedef struct synctex_nns_t {
   2521     synctex_node_p first;
   2522     synctex_node_p last;
   2523     synctex_status_t status;
   2524 } synctex_nns_s;
   2525 /**
   2526  *  Given a target node, create a list of proxies.
   2527  *  The first proxy points to the target node,
   2528  *  its sibling points to the target's sibling and so on.
   2529  *  Returns the first created proxy, the last one and
   2530  *  an error status.
   2531  */
   2532 SYNCTEX_INLINE static synctex_nns_s _synctex_new_child_proxies_to(synctex_node_p owner, synctex_node_p to_node) {
   2533     synctex_nns_s nns = {NULL,NULL,SYNCTEX_STATUS_OK};
   2534     if ((nns.first = nns.last = __synctex_new_child_proxy_to(owner,to_node))) {
   2535         synctex_node_p to_next_sibling = __synctex_tree_sibling(to_node);
   2536         synctex_node_p to_sibling;
   2537         while ((to_sibling = to_next_sibling)) {
   2538             synctex_node_p sibling;
   2539             if ((to_next_sibling = __synctex_tree_sibling(to_sibling))) {
   2540                 /*  This is not the last sibling */
   2541                 if((sibling = __synctex_new_child_proxy_to(owner,to_sibling))) {
   2542                     _synctex_tree_set_sibling(nns.last,sibling);
   2543                     nns.last = sibling;
   2544                     continue;
   2545                 } else {
   2546                     _synctex_error("!  _synctex_new_child_proxy_to. "
   2547                                    "Internal error (1). "
   2548                                    "Please report.");
   2549                     nns.status = SYNCTEX_STATUS_ERROR;
   2550                 }
   2551             } else if((sibling = _synctex_new_proxy_last(owner->class_->scanner))) {
   2552                 _synctex_tree_set_sibling(nns.last,sibling);
   2553                 nns.last = sibling;
   2554                 _synctex_data_set_h(nns.last, _synctex_data_h(nns.first));
   2555                 _synctex_data_set_v(nns.last, _synctex_data_v(nns.first));
   2556                 _synctex_tree_set_target(nns.last,to_sibling);
   2557 #   if defined(SYNCTEX_USE_CHARINDEX)
   2558                 nns.last->line_index=to_sibling->line_index;
   2559                 nns.last->char_index=to_sibling->char_index;
   2560 #   endif
   2561             } else {
   2562                 _synctex_error("!  _synctex_new_child_proxy_to. "
   2563                                "Internal error (2). "
   2564                                "Please report.");
   2565                 nns.status = SYNCTEX_STATUS_ERROR;
   2566             }
   2567             break;
   2568         }
   2569     }
   2570     return nns;
   2571 }
   2572 static char * _synctex_node_abstract(synctex_node_p node);
   2573 SYNCTEX_INLINE static synctex_node_p synctex_tree_set_friend(synctex_node_p node,synctex_node_p new_friend) {
   2574 #if SYNCTEX_DEBUG
   2575     synctex_node_p F = new_friend;
   2576     while (F) {
   2577         if (node == F) {
   2578             printf("THIS IS AN ERROR\n");
   2579             F = new_friend;
   2580             while (F) {
   2581                 printf("%s\n",_synctex_node_abstract(F));
   2582                 if (node == F) {
   2583                     return NULL;
   2584                 }
   2585                 F = _synctex_tree_friend(F);
   2586             }
   2587             return NULL;
   2588         }
   2589         F = _synctex_tree_friend(F);
   2590     }
   2591 #endif
   2592     return new_friend?_synctex_tree_set_friend(node,new_friend):_synctex_tree_reset_friend(node);
   2593 }
   2594 /**
   2595  *
   2596  */
   2597 SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend(synctex_node_p node, int i) {
   2598     synctex_node_p old = NULL;
   2599     if (i>=0) {
   2600         i = i%(node->class_->scanner->number_of_lists);
   2601         old = synctex_tree_set_friend(node,(node->class_->scanner->lists_of_friends)[i]);
   2602         (node->class_->scanner->lists_of_friends)[i] = node;
   2603 #if SYNCTEX_DEBUG>500
   2604         printf("tl(%i)=>",i);
   2605         synctex_node_log(node);
   2606         if (synctex_node_parent_form(node)) {
   2607             printf("!  ERROR. No registration expected!\n");
   2608         }
   2609 #endif
   2610     }
   2611     return old;
   2612 }
   2613 /**
   2614  *  All proxies have tlc attributes, on behalf of their target.
   2615  *  The purpose is to register all af them.
   2616  *  - argument node: is the proxy, must not be NULL
   2617  */
   2618 SYNCTEX_INLINE static synctex_node_p __synctex_proxy_make_friend_and_next_hbox(synctex_node_p node) {
   2619     synctex_node_p old = NULL;
   2620     synctex_node_p target = _synctex_tree_target(node);
   2621     if (target) {
   2622         int i = _synctex_data_tag(target)+_synctex_data_line(target);
   2623         old = __synctex_node_make_friend(node,i);
   2624     } else {
   2625         old = __synctex_tree_reset_friend(node);
   2626     }
   2627     if (synctex_node_type(node) == synctex_node_type_proxy_hbox) {
   2628         synctex_node_p sheet = synctex_node_parent_sheet(node);
   2629         if (sheet) {
   2630             _synctex_tree_set_next_hbox(node,_synctex_tree_next_hbox(sheet));
   2631             _synctex_tree_set_next_hbox(sheet,node);
   2632         }
   2633     }
   2634     return old;
   2635 }
   2636 /**
   2637  *  Register a node which have tag, line and column.
   2638  *  - argument node: the node
   2639  */
   2640 SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node) {
   2641     int i = synctex_node_tag(node)+synctex_node_line(node);
   2642     return __synctex_node_make_friend(node,i);
   2643 }
   2644 /**
   2645  *  Register a node which have tag, line and column.
   2646  *  Does nothing if the argument is NULL.
   2647  *  Calls __synctex_node_make_friend_tlc.
   2648  *  - argument node: the node
   2649  */
   2650 SYNCTEX_INLINE static void _synctex_node_make_friend_tlc(synctex_node_p node) {
   2651     if (node) {
   2652         __synctex_node_make_friend_tlc(node);
   2653     }
   2654 }
   2655 static synctex_node_p _synctex_node_set_child(synctex_node_p node, synctex_node_p new_child);
   2656 /**
   2657  *  The (first) child of the node, if any, NULL otherwise.
   2658  *  At parse time, non void box nodes have children.
   2659  *  All other nodes have no children.
   2660  *  In order to support pdf forms, proxies are created
   2661  *  to place form nodes at real locations.
   2662  *  Ref nodes are replaced by root proxies targeting
   2663  *  form contents. If root proxies have no children,
   2664  *  they are created on the fly as proxies to the
   2665  *  children of the targeted box.
   2666  *  As such, proxies created here are targeting a
   2667  *  node that belongs to a form.
   2668  *  This is the only place where child proxies are created.
   2669  */
   2670 synctex_node_p synctex_node_child(synctex_node_p node) {
   2671     synctex_node_p child = NULL;
   2672     synctex_node_p target = NULL;
   2673     if ((child = _synctex_tree_child(node))) {
   2674         return child;
   2675     } else if ((target = _synctex_tree_target(node))) {
   2676         if ((child = synctex_node_child(target))) {
   2677             /*  This is a proxy with no child
   2678              *  which target does have a child. */
   2679             synctex_nns_s nns = _synctex_new_child_proxies_to(node, child);
   2680             if (nns.first) {
   2681                 _synctex_node_set_child(node,nns.first);
   2682                 return nns.first;
   2683             } else {
   2684                 _synctex_error("!  synctex_node_child. Internal inconsistency. Please report.");
   2685             }
   2686         }
   2687     }
   2688     return NULL;
   2689 }
   2690 /*
   2691  *  Set the parent/child bound.
   2692  *  Things get complicated when new_child has siblings.
   2693  *  The caller is responsible for releasing the returned value.
   2694  */
   2695 static synctex_node_p _synctex_node_set_child(synctex_node_p parent, synctex_node_p new_child) {
   2696     if (parent) {
   2697         synctex_node_p old = _synctex_tree_set_child(parent,new_child);
   2698         synctex_node_p last_child = NULL;
   2699         synctex_node_p child;
   2700         if ((child = old)) {
   2701             do {
   2702                 _synctex_tree_reset_parent(child);
   2703             } while ((child = __synctex_tree_sibling(child)));
   2704         }
   2705         if ((child = new_child)) {
   2706             do {
   2707                 _synctex_tree_set_parent(child,parent);
   2708                 last_child = child;
   2709             } while ((child = __synctex_tree_sibling(child)));
   2710         }
   2711         _synctex_tree_set_last(parent,last_child);
   2712         return old;
   2713     }
   2714     return NULL;
   2715 }
   2716 
   2717 /*  The last child of the given node, or NULL.
   2718  */
   2719 synctex_node_p synctex_node_last_child(synctex_node_p node) {
   2720     return _synctex_tree_last(node);
   2721 }
   2722 /**
   2723  *  All nodes siblings are properly set up at parse time
   2724  *  except for non root proxies.
   2725  */
   2726 synctex_node_p synctex_node_sibling(synctex_node_p node) {
   2727     return node? __synctex_tree_sibling(node): NULL;
   2728 }
   2729 /**
   2730  *  All the _synctex_tree_... methods refer to the tree model.
   2731  *  __synctex_tree_... methods are low level.
   2732  */
   2733 /**
   2734  *  Replace the sibling.
   2735  *  Connect to the arg_sibling of the new_sibling if relevant.
   2736  *  - returns the old sibling.
   2737  *  The caller is responsible for releasing the old sibling.
   2738  *  The bound to the parent is managed below.
   2739  */
   2740 SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling) {
   2741     if (node == new_sibling) {
   2742         printf("BOF\n");
   2743     }
   2744     synctex_node_p old = node? __synctex_tree_set_sibling(node,new_sibling): NULL;
   2745     _synctex_tree_set_arg_sibling(new_sibling,node);
   2746     return old;
   2747 }
   2748 /**
   2749  *  Replace the sibling.
   2750  *  Set the parent of the new sibling (and further siblings)
   2751  *  to the parent of the receiver.
   2752  *  Also set the last sibling of parent.
   2753  *  - argument new_sibling: must not be NULL.
   2754  *  - returns the old sibling.
   2755  *  The caller is responsible for releasing the old sibling.
   2756  */
   2757 static synctex_node_p _synctex_node_set_sibling(synctex_node_p node, synctex_node_p new_sibling) {
   2758     if (node && new_sibling) {
   2759         synctex_node_p old = _synctex_tree_set_sibling(node,new_sibling);
   2760         if (_synctex_tree_has_parent(node)) {
   2761             synctex_node_p parent = __synctex_tree_parent(node);
   2762             if (parent) {
   2763                 synctex_node_p N = new_sibling;
   2764                 while (synctex_YES) {
   2765                     if (_synctex_tree_has_parent(N)) {
   2766                         __synctex_tree_set_parent(N,parent);
   2767                         _synctex_tree_set_last(parent,N);
   2768                         N = __synctex_tree_sibling(N);
   2769                         continue;
   2770                     } else if (N) {
   2771                         _synctex_error("!  synctex_node_sibling. "
   2772                                        "Internal inconsistency. "
   2773                                        "Please report.");
   2774                     }
   2775                     break;
   2776                 }
   2777             }
   2778         }
   2779         return old;
   2780     }
   2781     return NULL;
   2782 }
   2783 /**
   2784  *  The last sibling of the given node, or NULL with node.
   2785  */
   2786 synctex_node_p synctex_node_last_sibling(synctex_node_p node) {
   2787     synctex_node_p sibling;
   2788     do {
   2789         sibling = node;
   2790     } while((node = synctex_node_sibling(node)));
   2791     return sibling;
   2792 }
   2793 /**
   2794  *  The next nodes corresponds to a deep first tree traversal.
   2795  *  Does not create child proxies as side effect contrary to
   2796  *  the synctex_node_next method above.
   2797  *  May loop infinitely many times if the tree
   2798  *  is not properly built (contains loops).
   2799  */
   2800 SYNCTEX_INLINE static synctex_node_p _synctex_node_sibling_or_parents(synctex_node_p node) {
   2801     while (node) {
   2802         synctex_node_p N;
   2803         if ((N = __synctex_tree_sibling(node))) {
   2804             return N;
   2805         } else if ((node = _synctex_tree_parent(node))) {
   2806             if (synctex_node_type(node) == synctex_node_type_sheet) {/*  EXC_BAD_ACCESS? */
   2807                 return NULL;
   2808             } else if (synctex_node_type(node) == synctex_node_type_form) {
   2809                 return NULL;
   2810             }
   2811         } else {
   2812             return NULL;
   2813         }
   2814     }
   2815     return NULL;
   2816 }
   2817 /**
   2818  *  The next nodes corresponds to a deep first tree traversal.
   2819  *  Creates child proxies as side effect.
   2820  *  May loop infinitely many times if the tree
   2821  *  is not properly built (contains loops).
   2822  */
   2823 synctex_node_p synctex_node_next(synctex_node_p node) {
   2824     synctex_node_p N = synctex_node_child(node);
   2825     if (N) {
   2826         return N;
   2827     }
   2828     return _synctex_node_sibling_or_parents(node);
   2829 }
   2830 /**
   2831  *  The next nodes corresponds to a deep first tree traversal.
   2832  *  Does not create child proxies as side effect contrary to
   2833  *  the synctex_node_next method above.
   2834  *  May loop infinitely many times if the tree
   2835  *  is not properly built (contains loops).
   2836  */
   2837 synctex_node_p _synctex_node_next(synctex_node_p node) {
   2838     synctex_node_p N = _synctex_tree_child(node);
   2839     if (N) {
   2840         return N;
   2841     }
   2842     return _synctex_node_sibling_or_parents(node);
   2843 }
   2844 /**
   2845  *  The node which argument is the sibling.
   2846  *  - return: NULL if the argument has no parent or
   2847  *      is the first child of its parent.
   2848  *  - Input nodes have no arg siblings
   2849  */
   2850 synctex_node_p synctex_node_arg_sibling(synctex_node_p node) {
   2851 #if 1
   2852     return _synctex_tree_arg_sibling(node);
   2853 #else
   2854     synctex_node_p N = _synctex_tree_parent(node);
   2855     if ((N = _synctex_tree_child(N))) {
   2856         do {
   2857             synctex_node_p NN = __synctex_tree_sibling(N);
   2858             if (NN == node) {
   2859                 return N;
   2860             }
   2861             N = NN;
   2862         } while (N);
   2863     }
   2864     return N;
   2865 #endif
   2866 }
   2867 #	ifdef SYNCTEX_NOTHING
   2868 #       pragma mark -
   2869 #       pragma mark CLASS
   2870 #   endif
   2871 
   2872 /*  Public node accessor: the type  */
   2873 synctex_node_type_t synctex_node_type(synctex_node_p node) {
   2874     return node? node->class_->type: synctex_node_type_none;
   2875 }
   2876 
   2877 /*  Public node accessor: the type  */
   2878 synctex_node_type_t synctex_node_target_type(synctex_node_p node) {
   2879     synctex_node_p target = _synctex_tree_target(node);
   2880     if (target) {
   2881         return (((target)->class_))->type;
   2882     } else if (node) {
   2883         return (((node)->class_))->type;
   2884     }
   2885     return synctex_node_type_none;
   2886 }
   2887 
   2888 /*  Public node accessor: the human readable type  */
   2889 const char * synctex_node_isa(synctex_node_p node) {
   2890     static const char * isa[synctex_node_number_of_types] =
   2891     {"Not a node",
   2892         "input",
   2893         "sheet",
   2894         "form",
   2895         "ref",
   2896         "vbox",
   2897         "void vbox",
   2898         "hbox",
   2899         "void hbox",
   2900         "kern",
   2901         "glue",
   2902         "rule",
   2903         "math",
   2904         "boundary",
   2905         "box_bdry",
   2906         "proxy",
   2907         "last proxy",
   2908         "vbox proxy",
   2909         "hbox proxy",
   2910         "handle"};
   2911     return isa[synctex_node_type(node)];
   2912 }
   2913 
   2914 #	ifdef SYNCTEX_NOTHING
   2915 #       pragma mark -
   2916 #       pragma mark LOG
   2917 #   endif
   2918 
   2919 /*  Public node logger  */
   2920 void synctex_node_log(synctex_node_p node) {
   2921     SYNCTEX_MSG_SEND(node,log);
   2922 }
   2923 
   2924 static void _synctex_log_input(synctex_node_p node) {
   2925     if (node) {
   2926         printf("%s:%i,%s(%i)\n",synctex_node_isa(node),
   2927                _synctex_data_tag(node),
   2928                _synctex_data_name(node),
   2929                _synctex_data_line(node));
   2930         printf("SELF:%p\n",(void *)node);
   2931         printf("    SIBLING:%p\n",
   2932                (void *)__synctex_tree_sibling(node));
   2933     }
   2934 }
   2935 
   2936 static void _synctex_log_sheet(synctex_node_p node) {
   2937     if (node) {
   2938         printf("%s:%i",synctex_node_isa(node),_synctex_data_page(node));
   2939         SYNCTEX_PRINT_CHARINDEX_NL;
   2940         printf("SELF:%p\n",(void *)node);
   2941         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   2942         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   2943         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   2944         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   2945         printf("    NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
   2946     }
   2947 }
   2948 
   2949 static void _synctex_log_form(synctex_node_p node) {
   2950     if (node) {
   2951         printf("%s:%i",synctex_node_isa(node),_synctex_data_tag(node));
   2952         SYNCTEX_PRINT_CHARINDEX_NL;
   2953         printf("SELF:%p\n",(void *)node);
   2954         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   2955         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   2956         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   2957         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   2958     }
   2959 }
   2960 
   2961 static void _synctex_log_ref(synctex_node_p node) {
   2962     if (node) {
   2963         printf("%s:%i:%i,%i",
   2964                synctex_node_isa(node),
   2965                _synctex_data_tag(node),
   2966                _synctex_data_h(node),
   2967                _synctex_data_v(node));
   2968         SYNCTEX_PRINT_CHARINDEX_NL;
   2969         printf("SELF:%p\n",(void *)node);
   2970         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   2971         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   2972     }
   2973 }
   2974 
   2975 static void _synctex_log_tlchv_node(synctex_node_p node) {
   2976     if (node) {
   2977         printf("%s:%i,%i,%i:%i,%i",
   2978                synctex_node_isa(node),
   2979                _synctex_data_tag(node),
   2980                _synctex_data_line(node),
   2981                _synctex_data_column(node),
   2982                _synctex_data_h(node),
   2983                _synctex_data_v(node));
   2984         SYNCTEX_PRINT_CHARINDEX_NL;
   2985         printf("SELF:%p\n",(void *)node);
   2986         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   2987         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   2988         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   2989         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   2990     }
   2991 }
   2992 
   2993 static void _synctex_log_kern_node(synctex_node_p node) {
   2994     if (node) {
   2995         printf("%s:%i,%i,%i:%i,%i:%i",
   2996                synctex_node_isa(node),
   2997                _synctex_data_tag(node),
   2998                _synctex_data_line(node),
   2999                _synctex_data_column(node),
   3000                _synctex_data_h(node),
   3001                _synctex_data_v(node),
   3002                _synctex_data_width(node));
   3003         SYNCTEX_PRINT_CHARINDEX_NL;
   3004         printf("SELF:%p\n",(void *)node);
   3005         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3006         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   3007         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   3008         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3009     }
   3010 }
   3011 
   3012 static void _synctex_log_rule(synctex_node_p node) {
   3013     if (node) {
   3014         printf("%s:%i,%i,%i:%i,%i",
   3015                synctex_node_isa(node),
   3016                _synctex_data_tag(node),
   3017                _synctex_data_line(node),
   3018                _synctex_data_column(node),
   3019                _synctex_data_h(node),
   3020                _synctex_data_v(node));
   3021         printf(":%i",_synctex_data_width(node));
   3022         printf(",%i",_synctex_data_height(node));
   3023         printf(",%i",_synctex_data_depth(node));
   3024         SYNCTEX_PRINT_CHARINDEX_NL;
   3025         printf("SELF:%p\n",(void *)node);
   3026         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3027         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   3028         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3029     }
   3030 }
   3031 
   3032 static void _synctex_log_void_box(synctex_node_p node) {
   3033     if (node) {
   3034         printf("%s",synctex_node_isa(node));
   3035         printf(":%i",_synctex_data_tag(node));
   3036         printf(",%i",_synctex_data_line(node));
   3037         printf(",%i",_synctex_data_column(node));
   3038         printf(":%i",_synctex_data_h(node));
   3039         printf(",%i",_synctex_data_v(node));
   3040         printf(":%i",_synctex_data_width(node));
   3041         printf(",%i",_synctex_data_height(node));
   3042         printf(",%i",_synctex_data_depth(node));
   3043         SYNCTEX_PRINT_CHARINDEX_NL;
   3044         printf("SELF:%p\n",(void *)node);
   3045         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3046         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   3047         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   3048         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3049     }
   3050 }
   3051 
   3052 static void _synctex_log_vbox(synctex_node_p node) {
   3053     if (node) {
   3054         printf("%s",synctex_node_isa(node));
   3055         printf(":%i",_synctex_data_tag(node));
   3056         printf(",%i",_synctex_data_line(node));
   3057         printf(",%i",_synctex_data_column(node));
   3058         printf(":%i",_synctex_data_h(node));
   3059         printf(",%i",_synctex_data_v(node));
   3060         printf(":%i",_synctex_data_width(node));
   3061         printf(",%i",_synctex_data_height(node));
   3062         printf(",%i",_synctex_data_depth(node));
   3063         SYNCTEX_PRINT_CHARINDEX_NL;
   3064         printf("SELF:%p\n",(void *)node);
   3065         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3066         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   3067         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   3068         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3069         printf("    NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
   3070     }
   3071 }
   3072 
   3073 static void _synctex_log_hbox(synctex_node_p node) {
   3074     if (node) {
   3075         printf("%s",synctex_node_isa(node));
   3076         printf(":%i",_synctex_data_tag(node));
   3077         printf(",%i~%i*%i",_synctex_data_line(node),_synctex_data_mean_line(node),_synctex_data_weight(node));
   3078         printf(",%i",_synctex_data_column(node));
   3079         printf(":%i",_synctex_data_h(node));
   3080         printf(",%i",_synctex_data_v(node));
   3081         printf(":%i",_synctex_data_width(node));
   3082         printf(",%i",_synctex_data_height(node));
   3083         printf(",%i",_synctex_data_depth(node));
   3084         printf("/%i",_synctex_data_h_V(node));
   3085         printf(",%i",_synctex_data_v_V(node));
   3086         printf(":%i",_synctex_data_width_V(node));
   3087         printf(",%i",_synctex_data_height_V(node));
   3088         printf(",%i",_synctex_data_depth_V(node));
   3089         SYNCTEX_PRINT_CHARINDEX_NL;
   3090         printf("SELF:%p\n",(void *)node);
   3091         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3092         printf("    PARENT:%p\n",(void *)_synctex_tree_parent(node));
   3093         printf("    CHILD:%p\n",(void *)_synctex_tree_child(node));
   3094         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3095         printf("    NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
   3096     }
   3097 }
   3098 static void _synctex_log_proxy(synctex_node_p node) {
   3099     if (node) {
   3100         synctex_node_p N = _synctex_tree_target(node);
   3101         printf("%s",synctex_node_isa(node));
   3102         printf(":%i",_synctex_data_h(node));
   3103         printf(",%i",_synctex_data_v(node));
   3104         SYNCTEX_PRINT_CHARINDEX_NL;
   3105         printf("SELF:%p\n",(void *)node);
   3106         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3107         printf("    LEFT:%p\n",(void *)_synctex_tree_friend(node));
   3108         printf("    ->%s\n",_synctex_node_abstract(N));
   3109     }
   3110 }
   3111 static void _synctex_log_handle(synctex_node_p node) {
   3112     if (node) {
   3113         synctex_node_p N = _synctex_tree_target(node);
   3114         printf("%s",synctex_node_isa(node));
   3115         SYNCTEX_PRINT_CHARINDEX_NL;
   3116         printf("SELF:%p\n",(void *)node);
   3117         printf("    SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
   3118         printf("    ->%s\n",_synctex_node_abstract(N));
   3119     }
   3120 }
   3121 
   3122 #	ifdef SYNCTEX_NOTHING
   3123 #       pragma mark -
   3124 #       pragma mark SYNCTEX_DISPLAY
   3125 #   endif
   3126 
   3127 int synctex_scanner_display_switcher(synctex_scanner_p scanR) {
   3128     return scanR->display_switcher;
   3129 }
   3130 void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher) {
   3131     scanR->display_switcher = switcher;
   3132 }
   3133 static const char * const _synctex_display_prompt = "................................";
   3134 
   3135 static char * _synctex_scanner_display_prompt_down(synctex_scanner_p scanR) {
   3136     if (scanR->display_prompt>_synctex_display_prompt) {
   3137         --scanR->display_prompt;
   3138     }
   3139     return scanR->display_prompt;
   3140 }
   3141 static char * _synctex_scanner_display_prompt_up(synctex_scanner_p scanR) {
   3142     if (scanR->display_prompt+1<_synctex_display_prompt+strlen(_synctex_display_prompt)) {
   3143         ++scanR->display_prompt;
   3144     }
   3145     return scanR->display_prompt;
   3146 }
   3147 
   3148 void synctex_node_display(synctex_node_p node) {
   3149     if (node) {
   3150         synctex_scanner_p scanR = node->class_->scanner;
   3151         if (scanR) {
   3152             if (scanR->display_switcher<0) {
   3153                 SYNCTEX_MSG_SEND(node, display);
   3154             } else if (scanR->display_switcher>0 && --scanR->display_switcher>0) {
   3155                 SYNCTEX_MSG_SEND(node, display);
   3156             } else if (scanR->display_switcher-->=0) {
   3157                 printf("%s Next display skipped. Reset display switcher.\n",node->class_->scanner->display_prompt);
   3158             }
   3159         } else {
   3160             SYNCTEX_MSG_SEND(node, display);
   3161         }
   3162     }
   3163 }
   3164 static char * _synctex_node_abstract(synctex_node_p node) {
   3165     SYNCTEX_PARAMETER_ASSERT(node || node->class_);
   3166     return (node && node->class_->abstract)? node->class_->abstract(node):"none";
   3167 }
   3168 
   3169 SYNCTEX_INLINE static void _synctex_display_child(synctex_node_p node) {
   3170     synctex_node_p N = _synctex_tree_child(node);
   3171     if (N) {
   3172         _synctex_scanner_display_prompt_down(N->class_->scanner);
   3173         synctex_node_display(N);
   3174         _synctex_scanner_display_prompt_up(N->class_->scanner);
   3175     }
   3176 }
   3177 
   3178 SYNCTEX_INLINE static void _synctex_display_sibling(synctex_node_p node) {
   3179     synctex_node_display(__synctex_tree_sibling(node));
   3180 }
   3181 #define SYNCTEX_ABSTRACT_MAX 128
   3182 static char * _synctex_abstract_input(synctex_node_p node) {
   3183     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3184     if (node) {
   3185         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"Input:%i:%s(%i)" SYNCTEX_PRINT_CHARINDEX_FMT,
   3186                _synctex_data_tag(node),
   3187                _synctex_data_name(node),
   3188                _synctex_data_line(node)
   3189                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3190     }
   3191     return abstract;
   3192 }
   3193 
   3194 static void _synctex_display_input(synctex_node_p node) {
   3195     if (node) {
   3196         printf("Input:%i:%s(%i)"
   3197                SYNCTEX_PRINT_CHARINDEX_FMT
   3198                "\n",
   3199                _synctex_data_tag(node),
   3200                _synctex_data_name(node),
   3201                _synctex_data_line(node)
   3202                 SYNCTEX_PRINT_CHARINDEX_WHAT);
   3203         synctex_node_display(__synctex_tree_sibling(node));
   3204     }
   3205 }
   3206 
   3207 static char * _synctex_abstract_sheet(synctex_node_p node) {
   3208     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3209     if (node) {
   3210         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"{%i...}" SYNCTEX_PRINT_CHARINDEX_FMT,
   3211                _synctex_data_page(node)
   3212                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3213     }
   3214     return abstract;
   3215 }
   3216 
   3217 static void _synctex_display_sheet(synctex_node_p node) {
   3218     if (node) {
   3219         printf("%s{%i"
   3220                SYNCTEX_PRINT_CHARINDEX_FMT
   3221                "\n",
   3222                node->class_->scanner->display_prompt,
   3223                _synctex_data_page(node)
   3224                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3225         _synctex_display_child(node);
   3226         printf("%s}\n",node->class_->scanner->display_prompt);
   3227         _synctex_display_sibling(node);
   3228     }
   3229 }
   3230 
   3231 static char * _synctex_abstract_form(synctex_node_p node) {
   3232     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3233     if (node) {
   3234         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"<%i...>" SYNCTEX_PRINT_CHARINDEX_FMT,
   3235                _synctex_data_tag(node)
   3236                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3237         SYNCTEX_PRINT_CHARINDEX;
   3238     }
   3239     return abstract;
   3240 }
   3241 
   3242 static void _synctex_display_form(synctex_node_p node) {
   3243     if (node) {
   3244         printf("%s<%i"
   3245                SYNCTEX_PRINT_CHARINDEX_FMT
   3246                "\n",
   3247                node->class_->scanner->display_prompt,
   3248                _synctex_data_tag(node)
   3249                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3250         _synctex_display_child(node);
   3251         printf("%s>\n",node->class_->scanner->display_prompt);
   3252         _synctex_display_sibling(node);
   3253     }
   3254 }
   3255 
   3256 static char * _synctex_abstract_vbox(synctex_node_p node) {
   3257     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3258     if (node) {
   3259         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"[%i,%i:%i,%i:%i,%i,%i...]"
   3260                SYNCTEX_PRINT_CHARINDEX_FMT,
   3261                _synctex_data_tag(node),
   3262                _synctex_data_line(node),
   3263                _synctex_data_h(node),
   3264                _synctex_data_v(node),
   3265                _synctex_data_width(node),
   3266                _synctex_data_height(node),
   3267                _synctex_data_depth(node)
   3268                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3269     }
   3270     return abstract;
   3271 }
   3272 
   3273 static void _synctex_display_vbox(synctex_node_p node) {
   3274     if (node) {
   3275         printf("%s[%i,%i:%i,%i:%i,%i,%i"
   3276                SYNCTEX_PRINT_CHARINDEX_FMT
   3277                "\n",
   3278                node->class_->scanner->display_prompt,
   3279                _synctex_data_tag(node),
   3280                _synctex_data_line(node),
   3281                _synctex_data_h(node),
   3282                _synctex_data_v(node),
   3283                _synctex_data_width(node),
   3284                _synctex_data_height(node),
   3285                _synctex_data_depth(node)
   3286                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3287         _synctex_display_child(node);
   3288         printf("%s]\n%slast:%s\n",
   3289                node->class_->scanner->display_prompt,
   3290                node->class_->scanner->display_prompt,
   3291                _synctex_node_abstract(_synctex_tree_last(node)));
   3292         _synctex_display_sibling(node);
   3293     }
   3294 }
   3295 
   3296 static char * _synctex_abstract_hbox(synctex_node_p node) {
   3297     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3298     if (node) {
   3299         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"(%i,%i~%i*%i:%i,%i:%i,%i,%i...)"
   3300                SYNCTEX_PRINT_CHARINDEX_FMT,
   3301                _synctex_data_tag(node),
   3302                _synctex_data_line(node),
   3303                _synctex_data_mean_line(node),
   3304                _synctex_data_weight(node),
   3305                _synctex_data_h(node),
   3306                _synctex_data_v(node),
   3307                _synctex_data_width(node),
   3308                _synctex_data_height(node),
   3309                _synctex_data_depth(node)
   3310                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3311     }
   3312     return abstract;
   3313 }
   3314 
   3315 static void _synctex_display_hbox(synctex_node_p node) {
   3316     if (node) {
   3317         printf("%s(%i,%i~%i*%i:%i,%i:%i,%i,%i"
   3318                SYNCTEX_PRINT_CHARINDEX_FMT
   3319                "\n",
   3320                node->class_->scanner->display_prompt,
   3321                _synctex_data_tag(node),
   3322                _synctex_data_line(node),
   3323                _synctex_data_mean_line(node),
   3324                _synctex_data_weight(node),
   3325                _synctex_data_h(node),
   3326                _synctex_data_v(node),
   3327                _synctex_data_width(node),
   3328                _synctex_data_height(node),
   3329                _synctex_data_depth(node)
   3330                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3331         _synctex_display_child(node);
   3332         printf("%s)\n%slast:%s\n",
   3333                node->class_->scanner->display_prompt,
   3334                node->class_->scanner->display_prompt,
   3335                _synctex_node_abstract(_synctex_tree_last(node)));
   3336         _synctex_display_sibling(node);
   3337     }
   3338 }
   3339 
   3340 static char * _synctex_abstract_void_vbox(synctex_node_p node) {
   3341     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3342     if (node) {
   3343         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"v%i,%i;%i,%i:%i,%i,%i"
   3344                        SYNCTEX_PRINT_CHARINDEX_FMT
   3345                        "\n",
   3346                _synctex_data_tag(node),
   3347                _synctex_data_line(node),
   3348                _synctex_data_h(node),
   3349                _synctex_data_v(node),
   3350                _synctex_data_width(node),
   3351                _synctex_data_height(node),
   3352                _synctex_data_depth(node)
   3353                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3354     }
   3355     return abstract;
   3356 }
   3357 
   3358 static void _synctex_display_void_vbox(synctex_node_p node) {
   3359     if (node) {
   3360         printf("%sv%i,%i;%i,%i:%i,%i,%i"
   3361                SYNCTEX_PRINT_CHARINDEX_FMT
   3362                "\n",
   3363                node->class_->scanner->display_prompt,
   3364                _synctex_data_tag(node),
   3365                _synctex_data_line(node),
   3366                _synctex_data_h(node),
   3367                _synctex_data_v(node),
   3368                _synctex_data_width(node),
   3369                _synctex_data_height(node),
   3370                _synctex_data_depth(node)
   3371                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3372         _synctex_display_sibling(node);
   3373     }
   3374 }
   3375 
   3376 static char * _synctex_abstract_void_hbox(synctex_node_p node) {
   3377     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3378     if (node) {
   3379         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"h%i,%i:%i,%i:%i,%i,%i"
   3380                        SYNCTEX_PRINT_CHARINDEX_FMT,
   3381                _synctex_data_tag(node),
   3382                _synctex_data_line(node),
   3383                _synctex_data_h(node),
   3384                _synctex_data_v(node),
   3385                _synctex_data_width(node),
   3386                _synctex_data_height(node),
   3387                _synctex_data_depth(node)
   3388                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3389     }
   3390     return abstract;
   3391 }
   3392 
   3393 static void _synctex_display_void_hbox(synctex_node_p node) {
   3394     if (node) {
   3395         printf("%sh%i,%i:%i,%i:%i,%i,%i"
   3396                SYNCTEX_PRINT_CHARINDEX_FMT
   3397                "\n",
   3398                node->class_->scanner->display_prompt,
   3399                _synctex_data_tag(node),
   3400                _synctex_data_line(node),
   3401                _synctex_data_h(node),
   3402                _synctex_data_v(node),
   3403                _synctex_data_width(node),
   3404                _synctex_data_height(node),
   3405                _synctex_data_depth(node)
   3406                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3407         _synctex_display_sibling(node);
   3408     }
   3409 }
   3410 
   3411 static char * _synctex_abstract_glue(synctex_node_p node) {
   3412     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3413     if (node) {
   3414         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"glue:%i,%i:%i,%i"
   3415                        SYNCTEX_PRINT_CHARINDEX_FMT,
   3416                _synctex_data_tag(node),
   3417                _synctex_data_line(node),
   3418                _synctex_data_h(node),
   3419                _synctex_data_v(node)
   3420                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3421     }
   3422     return abstract;
   3423 }
   3424 
   3425 static void _synctex_display_glue(synctex_node_p node) {
   3426     if (node) {
   3427         printf("%sglue:%i,%i:%i,%i"
   3428                SYNCTEX_PRINT_CHARINDEX_FMT
   3429                "\n",
   3430                node->class_->scanner->display_prompt,
   3431                _synctex_data_tag(node),
   3432                _synctex_data_line(node),
   3433                _synctex_data_h(node),
   3434                _synctex_data_v(node)
   3435                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3436         _synctex_display_sibling(node);
   3437     }
   3438 }
   3439 
   3440 static char * _synctex_abstract_rule(synctex_node_p node) {
   3441     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3442     if (node) {
   3443         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"rule:%i,%i:%i,%i:%i,%i,%i"
   3444                SYNCTEX_PRINT_CHARINDEX_FMT,
   3445                _synctex_data_tag(node),
   3446                _synctex_data_line(node),
   3447                _synctex_data_h(node),
   3448                _synctex_data_v(node),
   3449                _synctex_data_width(node),
   3450                _synctex_data_height(node),
   3451                _synctex_data_depth(node)
   3452                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3453     }
   3454     return abstract;
   3455 }
   3456 
   3457 static void _synctex_display_rule(synctex_node_p node) {
   3458     if (node) {
   3459         printf("%srule:%i,%i:%i,%i:%i,%i,%i"
   3460                SYNCTEX_PRINT_CHARINDEX_FMT
   3461                "\n",
   3462                node->class_->scanner->display_prompt,
   3463                _synctex_data_tag(node),
   3464                _synctex_data_line(node),
   3465                _synctex_data_h(node),
   3466                _synctex_data_v(node),
   3467                _synctex_data_width(node),
   3468                _synctex_data_height(node),
   3469                _synctex_data_depth(node)
   3470                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3471         _synctex_display_sibling(node);
   3472     }
   3473 }
   3474 
   3475 static char * _synctex_abstract_math(synctex_node_p node) {
   3476     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3477     if (node) {
   3478         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"math:%i,%i:%i,%i"
   3479                        SYNCTEX_PRINT_CHARINDEX_FMT,
   3480                _synctex_data_tag(node),
   3481                _synctex_data_line(node),
   3482                _synctex_data_h(node),
   3483                _synctex_data_v(node)
   3484                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3485     }
   3486     return abstract;
   3487 }
   3488 
   3489 static void _synctex_display_math(synctex_node_p node) {
   3490     if (node) {
   3491         printf("%smath:%i,%i:%i,%i"
   3492                SYNCTEX_PRINT_CHARINDEX_FMT
   3493                "\n",
   3494                node->class_->scanner->display_prompt,
   3495                _synctex_data_tag(node),
   3496                _synctex_data_line(node),
   3497                _synctex_data_h(node),
   3498                _synctex_data_v(node)
   3499                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3500         _synctex_display_sibling(node);
   3501     }
   3502 }
   3503 
   3504 static char * _synctex_abstract_kern(synctex_node_p node) {
   3505     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3506     if (node) {
   3507         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"kern:%i,%i:%i,%i:%i"
   3508                        SYNCTEX_PRINT_CHARINDEX_FMT,
   3509                _synctex_data_tag(node),
   3510                _synctex_data_line(node),
   3511                _synctex_data_h(node),
   3512                _synctex_data_v(node),
   3513                _synctex_data_width(node)
   3514                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3515     }
   3516     return abstract;
   3517 }
   3518 
   3519 static void _synctex_display_kern(synctex_node_p node) {
   3520     if (node) {
   3521         printf("%skern:%i,%i:%i,%i:%i"
   3522                SYNCTEX_PRINT_CHARINDEX_FMT
   3523                "\n",
   3524                node->class_->scanner->display_prompt,
   3525                _synctex_data_tag(node),
   3526                _synctex_data_line(node),
   3527                _synctex_data_h(node),
   3528                _synctex_data_v(node),
   3529                _synctex_data_width(node)
   3530                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3531         _synctex_display_sibling(node);
   3532     }
   3533 }
   3534 
   3535 static char * _synctex_abstract_boundary(synctex_node_p node) {
   3536     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3537     if (node) {
   3538         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"boundary:%i,%i:%i,%i"
   3539                        SYNCTEX_PRINT_CHARINDEX_FMT,
   3540                _synctex_data_tag(node),
   3541                _synctex_data_line(node),
   3542                _synctex_data_h(node),
   3543                _synctex_data_v(node)
   3544                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3545     }
   3546     return abstract;
   3547 }
   3548 
   3549 static void _synctex_display_boundary(synctex_node_p node) {
   3550     if (node) {
   3551         printf("%sboundary:%i,%i:%i,%i"
   3552                SYNCTEX_PRINT_CHARINDEX_FMT
   3553                "\n",
   3554                node->class_->scanner->display_prompt,
   3555                _synctex_data_tag(node),
   3556                _synctex_data_line(node),
   3557                _synctex_data_h(node),
   3558                _synctex_data_v(node)
   3559                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3560         _synctex_display_sibling(node);
   3561     }
   3562 }
   3563 
   3564 static char * _synctex_abstract_box_bdry(synctex_node_p node) {
   3565     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3566     if (node) {
   3567         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"box bdry:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT,
   3568                _synctex_data_tag(node),
   3569                _synctex_data_line(node),
   3570                _synctex_data_h(node),
   3571                _synctex_data_v(node)
   3572                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3573     }
   3574     return abstract;
   3575 }
   3576 
   3577 static void _synctex_display_box_bdry(synctex_node_p node) {
   3578     if (node) {
   3579         printf("%sbox bdry:%i,%i:%i,%i",
   3580                node->class_->scanner->display_prompt,
   3581                _synctex_data_tag(node),
   3582                _synctex_data_line(node),
   3583                _synctex_data_h(node),
   3584                _synctex_data_v(node));
   3585         SYNCTEX_PRINT_CHARINDEX_NL;
   3586         _synctex_display_sibling(node);
   3587     }
   3588 }
   3589 
   3590 static char * _synctex_abstract_ref(synctex_node_p node) {
   3591     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3592     if (node) {
   3593         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"form ref:%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT,
   3594                _synctex_data_tag(node),
   3595                _synctex_data_h(node),
   3596                _synctex_data_v(node)
   3597                        SYNCTEX_PRINT_CHARINDEX_WHAT);
   3598     }
   3599     return abstract;
   3600 }
   3601 
   3602 static void _synctex_display_ref(synctex_node_p node) {
   3603     if (node) {
   3604         printf("%sform ref:%i:%i,%i",
   3605                node->class_->scanner->display_prompt,
   3606                _synctex_data_tag(node),
   3607                _synctex_data_h(node),
   3608                _synctex_data_v(node));
   3609         SYNCTEX_PRINT_CHARINDEX_NL;
   3610         _synctex_display_sibling(node);
   3611     }
   3612 }
   3613 static char * _synctex_abstract_proxy(synctex_node_p node) {
   3614     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3615     if (node) {
   3616         synctex_node_p N = _synctex_tree_target(node);
   3617         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"%s:%i,%i:%i,%i/%p%s",
   3618                synctex_node_isa(node),
   3619                synctex_node_tag(node),
   3620                synctex_node_line(node),
   3621                _synctex_data_h(node),
   3622                _synctex_data_v(node),
   3623                node,
   3624                _synctex_node_abstract(N));
   3625     }
   3626     return abstract;
   3627 }
   3628 static void _synctex_display_proxy(synctex_node_p node) {
   3629     if (node) {
   3630         synctex_node_p N = _synctex_tree_target(node);
   3631         printf("%s%s:%i,%i:%i,%i",
   3632                node->class_->scanner->display_prompt,
   3633                synctex_node_isa(node),
   3634                synctex_node_tag(node),
   3635                synctex_node_line(node),
   3636                _synctex_data_h(node),
   3637                _synctex_data_v(node));
   3638         if (N) {
   3639             printf("=%i,%i:%i,%i,%i->%s",
   3640                    synctex_node_h(node),
   3641                    synctex_node_v(node),
   3642                    synctex_node_width(node),
   3643                    synctex_node_height(node),
   3644                    synctex_node_depth(node),
   3645                    _synctex_node_abstract(N));
   3646         }
   3647         printf("\n");
   3648         _synctex_display_child(node);
   3649         _synctex_display_sibling(node);
   3650     }
   3651 }
   3652 static char * _synctex_abstract_proxy_vbox(synctex_node_p node) {
   3653     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3654     if (node) {
   3655         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,
   3656                  "[*%i,%i:%i,%i:%i,%i,%i...*]"
   3657                SYNCTEX_PRINT_CHARINDEX_FMT,
   3658                synctex_node_tag(node),
   3659                synctex_node_line(node),
   3660                synctex_node_h(node),
   3661                synctex_node_v(node),
   3662                synctex_node_width(node),
   3663                synctex_node_height(node),
   3664                synctex_node_depth(node)
   3665                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3666     }
   3667     return abstract;
   3668 }
   3669 
   3670 static void _synctex_display_proxy_vbox(synctex_node_p node) {
   3671     if (node) {
   3672         printf("%s[*%i,%i:%i,%i:%i,%i,%i"
   3673                SYNCTEX_PRINT_CHARINDEX_FMT
   3674                "\n",
   3675                node->class_->scanner->display_prompt,
   3676                synctex_node_tag(node),
   3677                synctex_node_line(node),
   3678                synctex_node_h(node),
   3679                synctex_node_v(node),
   3680                synctex_node_width(node),
   3681                synctex_node_height(node),
   3682                synctex_node_depth(node)
   3683                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3684         _synctex_display_child(node);
   3685         printf("%s*]\n%slast:%s\n",
   3686                node->class_->scanner->display_prompt,
   3687                node->class_->scanner->display_prompt,
   3688                _synctex_node_abstract(_synctex_tree_last(node)));
   3689         _synctex_display_sibling(node);
   3690     }
   3691 }
   3692 
   3693 static char * _synctex_abstract_proxy_hbox(synctex_node_p node) {
   3694     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3695     if (node) {
   3696         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"(*%i,%i~%i*%i:%i,%i:%i,%i,%i...*)/%p"
   3697                SYNCTEX_PRINT_CHARINDEX_FMT,
   3698                synctex_node_tag(node),
   3699                synctex_node_line(node),
   3700                synctex_node_mean_line(node),
   3701                synctex_node_weight(node),
   3702                synctex_node_h(node),
   3703                synctex_node_v(node),
   3704                synctex_node_width(node),
   3705                synctex_node_height(node),
   3706                synctex_node_depth(node),
   3707                node
   3708                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3709     }
   3710     return abstract;
   3711 }
   3712 
   3713 static void _synctex_display_proxy_hbox(synctex_node_p node) {
   3714     if (node) {
   3715         printf("%s(*%i,%i~%i*%i:%i,%i:%i,%i,%i"
   3716                SYNCTEX_PRINT_CHARINDEX_FMT
   3717                "\n",
   3718                node->class_->scanner->display_prompt,
   3719                synctex_node_tag(node),
   3720                synctex_node_line(node),
   3721                synctex_node_mean_line(node),
   3722                synctex_node_weight(node),
   3723                synctex_node_h(node),
   3724                synctex_node_v(node),
   3725                synctex_node_width(node),
   3726                synctex_node_height(node),
   3727                synctex_node_depth(node)
   3728                SYNCTEX_PRINT_CHARINDEX_WHAT);
   3729         _synctex_display_child(node);
   3730         printf("%s*)\n%slast:%s\n",
   3731                node->class_->scanner->display_prompt,
   3732                node->class_->scanner->display_prompt,
   3733                _synctex_node_abstract(_synctex_tree_last(node)));
   3734         _synctex_display_sibling(node);
   3735     }
   3736 }
   3737 
   3738 static char * _synctex_abstract_handle(synctex_node_p node) {
   3739     static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
   3740     if (node) {
   3741         synctex_node_p N = _synctex_tree_target(node);
   3742         if (N && !N->class_) {
   3743             exit(1);
   3744         }
   3745         snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"%s:%s",
   3746                synctex_node_isa(node),
   3747                (N?_synctex_node_abstract(N):""));
   3748     }
   3749     return abstract;
   3750 }
   3751 static void _synctex_display_handle(synctex_node_p node) {
   3752     if (node) {
   3753         synctex_node_p N = _synctex_tree_target(node);
   3754         printf("%s%s(%i):->%s\n",
   3755                node->class_->scanner->display_prompt,
   3756                synctex_node_isa(node),
   3757                _synctex_data_weight(N),
   3758                _synctex_node_abstract(N));
   3759         _synctex_display_child(node);
   3760         _synctex_display_sibling(node);
   3761     }
   3762 }
   3763 #	ifdef SYNCTEX_NOTHING
   3764 #       pragma mark -
   3765 #       pragma mark STATUS
   3766 #   endif
   3767 
   3768 #	ifdef SYNCTEX_NOTHING
   3769 #       pragma mark -
   3770 #       pragma mark Prototypes
   3771 #   endif
   3772 typedef struct {
   3773     size_t size;
   3774     synctex_status_t status;
   3775 } synctex_zs_s;
   3776 static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t size);
   3777 static synctex_status_t _synctex_next_line(synctex_scanner_p scanner);
   3778 static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char * the_string);
   3779 
   3780 typedef struct synctex_ns_t {
   3781     synctex_node_p node;
   3782     synctex_status_t status;
   3783 } synctex_ns_s;
   3784 static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner);
   3785 static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner);
   3786 typedef struct {
   3787     float value;
   3788     synctex_status_t status;
   3789 } synctex_fs_s;
   3790 static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner);
   3791 static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner);
   3792 static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner);
   3793 static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box);
   3794 static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner);
   3795 int synctex_scanner_pre_x_offset(synctex_scanner_p scanner);
   3796 int synctex_scanner_pre_y_offset(synctex_scanner_p scanner);
   3797 const char * synctex_scanner_get_output_fmt(synctex_scanner_p scanner);
   3798 
   3799 #	ifdef SYNCTEX_NOTHING
   3800 #       pragma mark -
   3801 #       pragma mark SCANNER UTILITIES
   3802 #   endif
   3803 
   3804 #   define SYNCTEX_FILE (scanner->reader->file)
   3805 
   3806 /**
   3807  *  Try to ensure that the buffer contains at least size bytes.
   3808  *  Passing a huge size argument means the whole buffer length.
   3809  *  Passing a 0 size argument means return the available buffer length, without reading the file.
   3810  *  In that case, the return status is always SYNCTEX_STATUS_OK unless the given scanner is NULL.
   3811  *  The size_t value returned is the number of bytes now available in the buffer. This is a nonnegative integer, it may take the value 0.
   3812  *  It is the responsibility of the caller to test whether this size is conforming to its needs.
   3813  *  Negative values may return in case of error, actually
   3814  *  when there was an error reading the synctex file.
   3815  *  - parameter scanner: The owning scanner. When NULL, returns SYNCTEX_STATUS_BAD_ARGUMENT.
   3816  *  - parameter expected: expected number of bytes.
   3817  *  - returns: a size and a status.
   3818  */
   3819 static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t expected) {
   3820     size_t size = 0;
   3821     if (NULL == scanner) {
   3822         return (synctex_zs_s){0,SYNCTEX_STATUS_BAD_ARGUMENT};
   3823     }
   3824     if (expected>scanner->reader->size){
   3825         expected = scanner->reader->size;
   3826     }
   3827     size = SYNCTEX_END - SYNCTEX_CUR; /*  available is the number of unparsed chars in the buffer */
   3828     if (expected<=size) {
   3829         /*  There are already sufficiently many characters in the buffer */
   3830         return (synctex_zs_s){size,SYNCTEX_STATUS_OK};
   3831     }
   3832     if (SYNCTEX_FILE) {
   3833         /*  Copy the remaining part of the buffer to the beginning,
   3834          *  then read the next part of the file */
   3835         int already_read = 0;
   3836 #   if defined(SYNCTEX_USE_CHARINDEX)
   3837         scanner->reader->charindex_offset += SYNCTEX_CUR - SYNCTEX_START;
   3838 #   endif
   3839         if (size) {
   3840             memmove(SYNCTEX_START, SYNCTEX_CUR, size);
   3841         }
   3842         SYNCTEX_CUR = SYNCTEX_START + size; /*  the next character after the move, will change. */
   3843         /*  Fill the buffer up to its end */
   3844         already_read = gzread(SYNCTEX_FILE,(void *)SYNCTEX_CUR,(int)(SYNCTEX_BUFFER_SIZE - size));
   3845         if (already_read>0) {
   3846             /*  We assume that 0<already_read<=SYNCTEX_BUFFER_SIZE - size, such that
   3847              *  SYNCTEX_CUR + already_read = SYNCTEX_START + size  + already_read <= SYNCTEX_START + SYNCTEX_BUFFER_SIZE */
   3848             SYNCTEX_END = SYNCTEX_CUR + already_read;
   3849             /*  If the end of the file was reached, all the required SYNCTEX_BUFFER_SIZE - available
   3850              *  may not be filled with values from the file.
   3851              *  In that case, the buffer should stop properly after already_read characters. */
   3852             * SYNCTEX_END = '\0'; /* there is enough room */
   3853             SYNCTEX_CUR = SYNCTEX_START;
   3854             /*  May be available is less than size, the caller will have to test. */
   3855             return (synctex_zs_s){SYNCTEX_END - SYNCTEX_CUR,SYNCTEX_STATUS_OK};
   3856         } else if (0>already_read) {
   3857             /*  There is a possible error in reading the file */
   3858             int errnum = 0;
   3859             const char * error_string = gzerror(SYNCTEX_FILE, &errnum);
   3860             if (Z_ERRNO == errnum) {
   3861                 /*  There is an error in zlib caused by the file system */
   3862                 _synctex_error("gzread error from the file system (%i)",errno);
   3863                 return (synctex_zs_s){0,SYNCTEX_STATUS_ERROR};
   3864             } else if (errnum) {
   3865                 _synctex_error("gzread error (%i:%i,%s)",already_read,errnum,error_string);
   3866                 return (synctex_zs_s){0,SYNCTEX_STATUS_ERROR};
   3867             }
   3868         }
   3869         /*  Nothing was read, we are at the end of the file. */
   3870         gzclose(SYNCTEX_FILE);
   3871         SYNCTEX_FILE = NULL;
   3872         SYNCTEX_END = SYNCTEX_CUR;
   3873         SYNCTEX_CUR = SYNCTEX_START;
   3874         * SYNCTEX_END = '\0';/*  Terminate the string properly.*/
   3875         /*  there might be a bit of text left */
   3876         return (synctex_zs_s){SYNCTEX_END - SYNCTEX_CUR,SYNCTEX_STATUS_EOF};
   3877     }
   3878     /*  We cannot enlarge the buffer because the end of the file was reached. */
   3879     return (synctex_zs_s){size,SYNCTEX_STATUS_EOF};
   3880 }
   3881 
   3882 /*  Used when parsing the synctex file.
   3883  *  Advance to the next character starting a line.
   3884  *  Actually, only '\n' is recognized as end of line marker.
   3885  *  On normal completion, the returned value is the number of unparsed characters available in the buffer.
   3886  *  In general, it is a positive value, 0 meaning that the end of file was reached.
   3887  *  -1 is returned in case of error, actually because there was an error while feeding the buffer.
   3888  *  When the function returns with no error, SYNCTEX_CUR points to the first character of the next line, if any.
   3889  *  J. Laurens: Sat May 10 07:52:31 UTC 2008
   3890  */
   3891 static synctex_status_t _synctex_next_line(synctex_scanner_p scanner) {
   3892     synctex_status_t status = SYNCTEX_STATUS_OK;
   3893     if (NULL == scanner) {
   3894         return SYNCTEX_STATUS_BAD_ARGUMENT;
   3895     }
   3896 infinite_loop:
   3897     while(SYNCTEX_CUR<SYNCTEX_END) {
   3898         if (*SYNCTEX_CUR == '\n') {
   3899             ++SYNCTEX_CUR;
   3900             ++scanner->reader->line_number;
   3901             return _synctex_buffer_get_available_size(scanner, 1).status;
   3902         }
   3903         ++SYNCTEX_CUR;
   3904     }
   3905     /*  Here, we have SYNCTEX_CUR == SYNCTEX_END, such that the next call to _synctex_buffer_get_available_size
   3906      *  will read another bunch of synctex file. Little by little, we advance to the end of the file. */
   3907     status = _synctex_buffer_get_available_size(scanner, 1).status;
   3908     if (status<=SYNCTEX_STATUS_EOF) {
   3909         return status;
   3910     }
   3911     goto infinite_loop;
   3912 }
   3913 
   3914 /*  Scan the given string.
   3915  *  Both scanner and the_string must not be NULL, and the_string must not be 0 length.
   3916  *  SYNCTEX_STATUS_OK is returned if the string is found,
   3917  *  SYNCTEX_STATUS_EOF is returned when the EOF is reached,
   3918  *  SYNCTEX_STATUS_NOT_OK is returned is the string is not found,
   3919  *  an error status is returned otherwise.
   3920  *  This is a critical method because buffering renders things more difficult.
   3921  *  The given string might be as long as the maximum size_t value.
   3922  *  As side effect, the buffer state may have changed if the given argument string can't fit into the buffer.
   3923  */
   3924 static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char * the_string) {
   3925     size_t tested_len = 0; /*  the number of characters at the beginning of the_string that match */
   3926     size_t remaining_len = 0; /*  the number of remaining characters of the_string that should match */
   3927     size_t available = 0;
   3928     synctex_zs_s zs = {0,0};
   3929     if (NULL == scanner || NULL == the_string) {
   3930         return SYNCTEX_STATUS_BAD_ARGUMENT;
   3931     }
   3932     remaining_len = strlen(the_string); /*  All the_string should match */
   3933     if (0 == remaining_len) {
   3934         return SYNCTEX_STATUS_BAD_ARGUMENT;
   3935     }
   3936     /*  How many characters available in the buffer? */
   3937     zs = _synctex_buffer_get_available_size(scanner,remaining_len);
   3938     if (zs.status<SYNCTEX_STATUS_EOF) {
   3939         return zs.status;
   3940     }
   3941     /*  Maybe we have less characters than expected because the buffer is too small. */
   3942     if (zs.size>=remaining_len) {
   3943         /*  The buffer is sufficiently big to hold the expected number of characters. */
   3944         if (strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) {
   3945             return SYNCTEX_STATUS_NOT_OK;
   3946         }
   3947     return_OK:
   3948         /*  Advance SYNCTEX_CUR to the next character after the_string. */
   3949         SYNCTEX_CUR += remaining_len;
   3950         return SYNCTEX_STATUS_OK;
   3951     } else if (strncmp((char *)SYNCTEX_CUR,the_string,zs.size)) {
   3952         /*  No need to go further, this is not the expected string in the buffer. */
   3953         return SYNCTEX_STATUS_NOT_OK;
   3954     } else if (SYNCTEX_FILE) {
   3955         /*  The buffer was too small to contain remaining_len characters.
   3956          *  We have to cut the string into pieces. */
   3957         z_off_t offset = 0L;
   3958         /*  the first part of the string is found, advance the_string to the next untested character. */
   3959         the_string += zs.size;
   3960         /*  update the remaining length and the parsed length. */
   3961         remaining_len -= zs.size;
   3962         tested_len += zs.size;
   3963         SYNCTEX_CUR += zs.size; /*  We validate the tested characters. */
   3964         if (0 == remaining_len) {
   3965             /*  Nothing left to test, we have found the given string. */
   3966             return SYNCTEX_STATUS_OK;
   3967         }
   3968         /*  We also have to record the current state of the file cursor because
   3969          *  if the_string does not match, all this should be a totally blank operation,
   3970          *  for which the file and buffer states should not be modified at all.
   3971          *  In fact, the states of the buffer before and after this function are in general different
   3972          *  but they are totally equivalent as long as the values of the buffer before SYNCTEX_CUR
   3973          *  can be safely discarded.  */
   3974         offset = gztell(SYNCTEX_FILE);
   3975         /*  offset now corresponds to the first character of the file that was not buffered. */
   3976         /*  SYNCTEX_CUR - SYNCTEX_START is the number of chars that where already buffered and
   3977          *  that match the head of the_string. If in fine the_string does not match, all these chars must be recovered
   3978          *  because the whole buffer contents is replaced in _synctex_buffer_get_available_size.
   3979          *  They were buffered from offset-len location in the file. */
   3980         offset -= SYNCTEX_CUR - SYNCTEX_START;
   3981     more_characters:
   3982         /*  There is still some work to be done, so read another bunch of file.
   3983          *  This is the second call to _synctex_buffer_get_available_size,
   3984          *  which means that the actual contents of the buffer will be discarded.
   3985          *  We will definitely have to recover the previous state in case we do not find the expected string. */
   3986         zs = _synctex_buffer_get_available_size(scanner,remaining_len);
   3987         if (zs.status<SYNCTEX_STATUS_EOF) {
   3988             return zs.status; /*  This is an error, no need to go further. */
   3989         }
   3990         if (zs.size==0) {
   3991             /*  Missing characters: recover the initial state of the file and return. */
   3992         return_NOT_OK:
   3993             if (offset != gzseek(SYNCTEX_FILE,offset,SEEK_SET)) {
   3994                 /*  This is a critical error, we could not recover the previous state. */
   3995                 _synctex_error("Can't seek file");
   3996                 return SYNCTEX_STATUS_ERROR;
   3997             }
   3998             /*  Next time we are asked to fill the buffer,
   3999              *  we will read a complete bunch of text from the file. */
   4000             SYNCTEX_CUR = SYNCTEX_END;
   4001             return SYNCTEX_STATUS_NOT_OK;
   4002         }
   4003         if (zs.size<remaining_len) {
   4004             /*  We'll have to loop one more time. */
   4005             if (strncmp((char *)SYNCTEX_CUR,the_string,zs.size)) {
   4006                 /*  This is not the expected string, recover the previous state and return. */
   4007                 goto return_NOT_OK;
   4008             }
   4009             /*  Advance the_string to the first untested character. */
   4010             the_string += available;
   4011             /*  update the remaining length and the parsed length. */
   4012             remaining_len -= zs.size;
   4013             tested_len += zs.size;
   4014             SYNCTEX_CUR += zs.size; /*  We validate the tested characters. */
   4015             goto more_characters;
   4016         }
   4017         /*  This is the last step. */
   4018         if (strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) {
   4019             /*  This is not the expected string, recover the previous state and return. */
   4020             goto return_NOT_OK;
   4021         }
   4022         goto return_OK;
   4023     } else {
   4024         /*  The buffer can't contain the given string argument, and the EOF was reached */
   4025         return SYNCTEX_STATUS_EOF;
   4026     }
   4027 }
   4028 
   4029 /*  Used when parsing the synctex file.
   4030  *  Decode an integer.
   4031  *  First, field separators, namely ':' and ',' characters are skipped
   4032  *  The returned value is negative if there is an unrecoverable error.
   4033  *  It is SYNCTEX_STATUS_NOT_OK if an integer could not be parsed, for example
   4034  *  if the characters at the current cursor position are not digits or
   4035  *  if the end of the file has been reached.
   4036  *  It is SYNCTEX_STATUS_OK if an int has been successfully parsed.
   4037  *  The given scanner argument must not be NULL, on the contrary, value_ref may be NULL.
   4038  */
   4039 static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner) {
   4040     char * ptr = NULL;
   4041     char * end = NULL;
   4042     synctex_zs_s zs = {0,0};
   4043     int result;
   4044     if (NULL == scanner) {
   4045         return (synctex_is_s){0, SYNCTEX_STATUS_BAD_ARGUMENT};
   4046     }
   4047     zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
   4048     if (zs.status<SYNCTEX_STATUS_EOF) {
   4049         return (synctex_is_s){0,zs.status};
   4050     }
   4051     if (zs.size==0) {
   4052         return (synctex_is_s){0,SYNCTEX_STATUS_NOT_OK};
   4053     }
   4054     ptr = SYNCTEX_CUR;
   4055     /*  Optionally parse the separator */
   4056     if (*ptr==':' || *ptr==',') {
   4057         ++ptr;
   4058         --zs.size;
   4059         if (zs.size==0) {
   4060             return (synctex_is_s){0,SYNCTEX_STATUS_NOT_OK};
   4061         }
   4062     }
   4063     result = (int)strtol(ptr, &end, 10);
   4064     if (end>ptr) {
   4065         SYNCTEX_CUR = end;
   4066         return (synctex_is_s){result,SYNCTEX_STATUS_OK};
   4067     }
   4068     return (synctex_is_s){result,SYNCTEX_STATUS_NOT_OK};
   4069 }
   4070 static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value) {
   4071     char * ptr = NULL;
   4072     char * end = NULL;
   4073     synctex_zs_s zs = {0, 0};
   4074     if (NULL == scanner) {
   4075         return (synctex_is_s){default_value, SYNCTEX_STATUS_BAD_ARGUMENT};
   4076     }
   4077     zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
   4078     if (zs.status<SYNCTEX_STATUS_EOF) {
   4079         return (synctex_is_s){default_value,zs.status};
   4080     }
   4081     if (zs.size==0) {
   4082         return (synctex_is_s){default_value,SYNCTEX_STATUS_OK};
   4083     }
   4084     ptr = SYNCTEX_CUR;
   4085     /*  Comma separator required */
   4086     if (*ptr==',') {
   4087         int result;
   4088         ++ptr;
   4089         --zs.size;
   4090         if (zs.size==0) {
   4091             return (synctex_is_s){default_value,SYNCTEX_STATUS_NOT_OK};
   4092         }
   4093         result = (int)strtol(ptr, &end, 10);
   4094         if (end>ptr) {
   4095             SYNCTEX_CUR = end;
   4096             return (synctex_is_s){result,SYNCTEX_STATUS_OK};
   4097         }
   4098         return (synctex_is_s){default_value,SYNCTEX_STATUS_NOT_OK};
   4099     }
   4100     return (synctex_is_s){default_value,SYNCTEX_STATUS_OK};
   4101 }
   4102 /*  Used when parsing the synctex file.
   4103  *  Decode an integer for a v field.
   4104  *  Try the _synctex_decode_int version and set the last v field scanned.
   4105  *  If it does not succeed, tries to match an '=' sign,
   4106  *  which is a shortcut for the last v field scanned.
   4107  */
   4108 #   define SYNCTEX_INPUT_COMEQUALS ",="
   4109 static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner) {
   4110     synctex_is_s is = _synctex_decode_int(scanner);
   4111     if (SYNCTEX_STATUS_OK == is.status) {
   4112         scanner->reader->lastv = is.integer;
   4113         return is;
   4114     }
   4115     is.status = _synctex_match_string(scanner,SYNCTEX_INPUT_COMEQUALS);
   4116     if (is.status<SYNCTEX_STATUS_OK) {
   4117         return is;
   4118     }
   4119     is.integer = scanner->reader->lastv;
   4120     return is;
   4121 }
   4122 
   4123 /*  The purpose of this function is to read a string.
   4124  *  A string is an array of characters from the current parser location
   4125  *  and before the next '\n' character.
   4126  *  If a string was properly decoded, it is returned in value_ref and
   4127  *  the cursor points to the new line marker.
   4128  *  The returned string was allocated on the heap, the caller is the owner and
   4129  *  is responsible to free it in due time,
   4130  *  unless it transfers the ownership to another object.
   4131  *  If no string is parsed, * value_ref is undefined.
   4132  *  The maximum length of a string that a scanner can decode is platform dependent, namely UINT_MAX.
   4133  *  If you just want to blindly parse the file up to the end of the current line,
   4134  *  use _synctex_next_line instead.
   4135  *  On return, the scanner cursor is unchanged if a string could not be scanned or
   4136  *  points to the terminating '\n' character otherwise. As a consequence,
   4137  *  _synctex_next_line is necessary after.
   4138  *  If either scanner or value_ref is NULL, it is considered as an error and
   4139  *  SYNCTEX_STATUS_BAD_ARGUMENT is returned.
   4140  */
   4141 static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner) {
   4142     char * end = NULL;
   4143     size_t len = 0;/*  The number of bytes to copy */
   4144     size_t already_len = 0;
   4145     synctex_zs_s zs = {0,0};
   4146     char * string = NULL;
   4147     if (NULL == scanner) {
   4148         return (synctex_ss_s){NULL,SYNCTEX_STATUS_BAD_ARGUMENT};
   4149     }
   4150     /*  The buffer must at least contain one character: the '\n' end of line marker */
   4151     if (SYNCTEX_CUR>=SYNCTEX_END) {
   4152 more_characters:
   4153         zs = _synctex_buffer_get_available_size(scanner,1);
   4154         if (zs.status < SYNCTEX_STATUS_EOF) {
   4155             return (synctex_ss_s){NULL,zs.status};
   4156         } else if (0 == zs.size) {
   4157             return (synctex_ss_s){NULL,SYNCTEX_STATUS_EOF};
   4158         }
   4159     }
   4160     /*  Now we are sure that there is at least one available character, either because
   4161      *  SYNCTEX_CUR was already < SYNCTEX_END, or because the buffer has been properly filled. */
   4162     /*  end will point to the next unparsed '\n' character in the file, when mapped to the buffer. */
   4163     end = SYNCTEX_CUR;
   4164     /*  We scan all the characters up to the next '\n' */
   4165     while (end<SYNCTEX_END && *end != '\n') {
   4166         ++end;
   4167     }
   4168     /*  OK, we found where to stop:
   4169      *      either end == SYNCTEX_END
   4170      *      or *end == '\n' */
   4171     len = end - SYNCTEX_CUR;
   4172     if (len<UINT_MAX-already_len) {
   4173         if ((string = realloc(string,len+already_len+1)) != NULL) {
   4174             if (memcpy(string+already_len,SYNCTEX_CUR,len)) {
   4175                 already_len += len;
   4176                 string[already_len]='\0'; /*  Terminate the string */
   4177                 SYNCTEX_CUR += len;/*  Eventually advance to the terminating '\n' */
   4178                 if (SYNCTEX_CUR==SYNCTEX_END) {
   4179                     /* No \n found*/
   4180                     goto more_characters;
   4181                 }
   4182                 /* trim the trailing whites */
   4183                 len = already_len;
   4184                 while (len>0) {
   4185                     already_len = len--;
   4186                     if (string[len]!=' ') {
   4187                         break;
   4188                     }
   4189                 }
   4190                 string[already_len] = '\0';
   4191                 return (synctex_ss_s){string,SYNCTEX_STATUS_OK};
   4192             }
   4193             free(string);
   4194             _synctex_error("could not copy memory (1).");
   4195             return (synctex_ss_s){NULL,SYNCTEX_STATUS_ERROR};
   4196         }
   4197     }
   4198     _synctex_error("could not (re)allocate memory (1).");
   4199     return (synctex_ss_s){NULL,SYNCTEX_STATUS_ERROR};
   4200 }
   4201 
   4202 /*  Used when parsing the synctex file.
   4203  *  Read an Input record.
   4204  *  - parameter scanner: non NULL scanner
   4205  *  - returns SYNCTEX_STATUS_OK on successful completions, others values otherwise.
   4206  */
   4207 static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner) {
   4208     synctex_node_p input = NULL;
   4209     synctex_status_t status = SYNCTEX_STATUS_BAD_ARGUMENT;
   4210     synctex_zs_s zs = {0,0};
   4211     if (NULL == scanner) {
   4212         return (synctex_ns_s){NULL,status};
   4213     }
   4214     if ((status=_synctex_match_string(scanner,SYNCTEX_INPUT_MARK))<SYNCTEX_STATUS_OK) {
   4215         return (synctex_ns_s){NULL,status};
   4216     }
   4217     /*  Create a node */
   4218     if (NULL == (input = _synctex_new_input(scanner))) {
   4219         _synctex_error("Could not create an input node.");
   4220         return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4221     }
   4222     /*  Decode the tag  */
   4223     if ((status=_synctex_data_decode_tag(input))<SYNCTEX_STATUS_OK) {
   4224         _synctex_error("Bad format of input node.");
   4225         synctex_node_free(input);
   4226         return (synctex_ns_s){NULL,status};
   4227     }
   4228     /*  The next character is a field separator, we expect one character in the buffer. */
   4229     zs = _synctex_buffer_get_available_size(scanner, 1);
   4230     if (zs.status<=SYNCTEX_STATUS_ERROR) {
   4231         return (synctex_ns_s){NULL,status};
   4232     }
   4233     if (0 == zs.size) {
   4234         return (synctex_ns_s){NULL,SYNCTEX_STATUS_EOF};
   4235     }
   4236     /*  We can now safely advance to the next character, stepping over the field separator. */
   4237     ++SYNCTEX_CUR;
   4238     --zs.size;
   4239     /*  Then we scan the file name */
   4240     if ((status=_synctex_data_decode_name(input))<SYNCTEX_STATUS_OK) {
   4241         synctex_node_free(input);
   4242         _synctex_next_line(scanner);/* Ignore this whole line */
   4243         return (synctex_ns_s){NULL,status};
   4244     }
   4245     /*  Prepend this input node to the input linked list of the scanner */
   4246     __synctex_tree_set_sibling(input,scanner->input);/* input has no parent */
   4247     scanner->input = input;
   4248 #   if SYNCTEX_VERBOSE
   4249     synctex_node_log(input);
   4250 #   endif
   4251     return (synctex_ns_s){input,_synctex_next_line(scanner)};/*  read the line termination character, if any */
   4252 }
   4253 
   4254 typedef synctex_is_s (*synctex_decoder_t)(synctex_scanner_p);
   4255 
   4256 /*  Used when parsing the synctex file.
   4257  *  Read one of the settings.
   4258  *  On normal completion, returns SYNCTEX_STATUS_OK.
   4259  *  On error, returns SYNCTEX_STATUS_ERROR.
   4260  *  Both arguments must not be NULL.
   4261  *  On return, the scanner points to the next character after the decoded object whatever it is.
   4262  *  It is the responsibility of the caller to prepare the scanner for the next line.
   4263  */
   4264 static synctex_status_t _synctex_scan_named(synctex_scanner_p scanner,const char * name) {
   4265     synctex_status_t status = 0;
   4266     if (NULL == scanner || NULL == name) {
   4267         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4268     }
   4269 not_found:
   4270     status = _synctex_match_string(scanner,name);
   4271     if (status<SYNCTEX_STATUS_NOT_OK) {
   4272         return status;
   4273     } else if (status == SYNCTEX_STATUS_NOT_OK) {
   4274         status = _synctex_next_line(scanner);
   4275         if (status<SYNCTEX_STATUS_OK) {
   4276             return status;
   4277         }
   4278         goto not_found;
   4279     }
   4280     return SYNCTEX_STATUS_OK;
   4281 }
   4282 
   4283 /*  Used when parsing the synctex file.
   4284  *  Read the preamble.
   4285  */
   4286 static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner) {
   4287     synctex_status_t status = 0;
   4288     synctex_is_s is = {0,0};
   4289     synctex_ss_s ss = {NULL,0};
   4290     if (NULL == scanner) {
   4291         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4292     }
   4293     status = _synctex_scan_named(scanner,"SyncTeX Version:");
   4294     if (status<SYNCTEX_STATUS_OK) {
   4295         return status;
   4296     }
   4297     is = _synctex_decode_int(scanner);
   4298     if (is.status<SYNCTEX_STATUS_OK) {
   4299         return is.status;
   4300     }
   4301     status = _synctex_next_line(scanner);
   4302     if (status<SYNCTEX_STATUS_OK) {
   4303         return status;
   4304     }
   4305     scanner->version = is.integer;
   4306     /*  Read all the input records */
   4307     do {
   4308         status = __synctex_parse_new_input(scanner).status;
   4309         if (status<SYNCTEX_STATUS_NOT_OK) {
   4310             return status;
   4311         }
   4312     } while(status == SYNCTEX_STATUS_OK);
   4313     /*  the loop exits when status == SYNCTEX_STATUS_NOT_OK */
   4314     /*  Now read all the required settings. */
   4315     if ((status=_synctex_scan_named(scanner,"Output:"))<SYNCTEX_STATUS_OK) {
   4316         return status;
   4317     }
   4318     if ((ss=_synctex_decode_string(scanner)).status<SYNCTEX_STATUS_OK) {
   4319         return is.status;
   4320     }
   4321     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4322         return status;
   4323     }
   4324     scanner->output_fmt = ss.string;
   4325     if ((status=_synctex_scan_named(scanner,"Magnification:"))<SYNCTEX_STATUS_OK) {
   4326         return status;
   4327     }
   4328     if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
   4329         return is.status;
   4330     }
   4331     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4332         return status;
   4333     }
   4334     scanner->pre_magnification = is.integer;
   4335     if ((status=_synctex_scan_named(scanner,"Unit:"))<SYNCTEX_STATUS_OK) {
   4336         return status;
   4337     }
   4338     if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
   4339         return is.status;
   4340     }
   4341     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4342         return status;
   4343     }
   4344     scanner->pre_unit = is.integer;
   4345     if ((status=_synctex_scan_named(scanner,"X Offset:"))<SYNCTEX_STATUS_OK) {
   4346         return status;
   4347     }
   4348     if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
   4349         return is.status;
   4350     }
   4351     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4352         return status;
   4353     }
   4354     scanner->pre_x_offset = is.integer;
   4355     if ((status=_synctex_scan_named(scanner,"Y Offset:"))<SYNCTEX_STATUS_OK) {
   4356         return status;
   4357     }
   4358     if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
   4359         return is.status;
   4360     }
   4361     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4362         return status;
   4363     }
   4364     scanner->pre_y_offset = is.integer;
   4365     return SYNCTEX_STATUS_OK;
   4366 }
   4367 
   4368 /*  parse a float with a dimension */
   4369 static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner) {
   4370     synctex_fs_s fs = {0,0};
   4371     synctex_zs_s zs = {0,0};
   4372     char * endptr = NULL;
   4373 #ifdef HAVE_SETLOCALE
   4374     char * loc = setlocale(LC_NUMERIC, NULL);
   4375 #endif
   4376     if (NULL == scanner) {
   4377         return (synctex_fs_s){0,SYNCTEX_STATUS_BAD_ARGUMENT};
   4378     }
   4379     zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
   4380     if (zs.status<SYNCTEX_STATUS_EOF) {
   4381         _synctex_error("Problem with float.");
   4382         return (synctex_fs_s){0,zs.status};
   4383     }
   4384 #ifdef HAVE_SETLOCALE
   4385     setlocale(LC_NUMERIC, "C");
   4386 #endif
   4387     fs.value = strtod(SYNCTEX_CUR,&endptr);
   4388 #ifdef HAVE_SETLOCALE
   4389     setlocale(LC_NUMERIC, loc);
   4390 #endif
   4391     if (endptr == SYNCTEX_CUR) {
   4392         _synctex_error("A float was expected.");
   4393         return (synctex_fs_s){0,SYNCTEX_STATUS_ERROR};
   4394     }
   4395     SYNCTEX_CUR = endptr;
   4396     if ((fs.status = _synctex_match_string(scanner,"in")) >= SYNCTEX_STATUS_OK) {
   4397         fs.value *= 72.27f*65536;
   4398     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4399     report_unit_error:
   4400         _synctex_error("problem with unit.");
   4401         return fs;
   4402     } else if ((fs.status = _synctex_match_string(scanner,"cm")) >= SYNCTEX_STATUS_OK) {
   4403         fs.value *= 72.27f*65536/2.54f;
   4404     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4405         goto report_unit_error;
   4406     } else if ((fs.status = _synctex_match_string(scanner,"mm")) >= SYNCTEX_STATUS_OK) {
   4407         fs.value *= 72.27f*65536/25.4f;
   4408     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4409         goto report_unit_error;
   4410     } else if ((fs.status = _synctex_match_string(scanner,"pt")) >= SYNCTEX_STATUS_OK) {
   4411         fs.value *= 65536.0f;
   4412     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4413         goto report_unit_error;
   4414     } else if ((fs.status = _synctex_match_string(scanner,"bp")) >= SYNCTEX_STATUS_OK) {
   4415         fs.value *= 72.27f/72*65536.0f;
   4416     }  else if (fs.status<SYNCTEX_STATUS_EOF) {
   4417         goto report_unit_error;
   4418     } else if ((fs.status = _synctex_match_string(scanner,"pc")) >= SYNCTEX_STATUS_OK) {
   4419         fs.value *= 12.0*65536.0f;
   4420     }  else if (fs.status<SYNCTEX_STATUS_EOF) {
   4421         goto report_unit_error;
   4422     } else if ((fs.status = _synctex_match_string(scanner,"sp")) >= SYNCTEX_STATUS_OK) {
   4423         fs.value *= 1.0f;
   4424     }  else if (fs.status<SYNCTEX_STATUS_EOF) {
   4425         goto report_unit_error;
   4426     } else if ((fs.status = _synctex_match_string(scanner,"dd")) >= SYNCTEX_STATUS_OK) {
   4427         fs.value *= 1238.0f/1157*65536.0f;
   4428     }  else if (fs.status<SYNCTEX_STATUS_EOF) {
   4429         goto report_unit_error;
   4430     } else if ((fs.status = _synctex_match_string(scanner,"cc")) >= SYNCTEX_STATUS_OK) {
   4431         fs.value *= 14856.0f/1157*65536;
   4432     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4433         goto report_unit_error;
   4434     } else if ((fs.status = _synctex_match_string(scanner,"nd")) >= SYNCTEX_STATUS_OK) {
   4435         fs.value *= 685.0f/642*65536;
   4436     }  else if (fs.status<SYNCTEX_STATUS_EOF) {
   4437         goto report_unit_error;
   4438     } else if ((fs.status = _synctex_match_string(scanner,"nc")) >= SYNCTEX_STATUS_OK) {
   4439         fs.value *= 1370.0f/107*65536;
   4440     } else if (fs.status<SYNCTEX_STATUS_EOF) {
   4441         goto report_unit_error;
   4442     }
   4443     return fs;
   4444 }
   4445 
   4446 /*  parse the post scriptum
   4447  *  SYNCTEX_STATUS_OK is returned on completion
   4448  *  a negative error is returned otherwise */
   4449 static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner) {
   4450     synctex_status_t status = 0;
   4451     synctex_fs_s fs = {0,0};
   4452     char * endptr = NULL;
   4453 #ifdef HAVE_SETLOCALE
   4454     char * loc = setlocale(LC_NUMERIC, NULL);
   4455 #endif
   4456     if (NULL == scanner) {
   4457         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4458     }
   4459     /*  Scan the file until a post scriptum line is found */
   4460 post_scriptum_not_found:
   4461     status = _synctex_match_string(scanner,"Post scriptum:");
   4462     if (status<SYNCTEX_STATUS_NOT_OK) {
   4463         return status;
   4464     }
   4465     if (status == SYNCTEX_STATUS_NOT_OK) {
   4466         status = _synctex_next_line(scanner);
   4467         if (status<SYNCTEX_STATUS_EOF) {
   4468             return status;
   4469         } else if (status<SYNCTEX_STATUS_OK) {
   4470             return SYNCTEX_STATUS_OK;/*  The EOF is found, we have properly scanned the file */
   4471         }
   4472         goto post_scriptum_not_found;
   4473     }
   4474     /*  We found the name, advance to the next line. */
   4475 next_line:
   4476     status = _synctex_next_line(scanner);
   4477     if (status<SYNCTEX_STATUS_EOF) {
   4478         return status;
   4479     } else if (status<SYNCTEX_STATUS_OK) {
   4480         return SYNCTEX_STATUS_OK;/*  The EOF is found, we have properly scanned the file */
   4481     }
   4482     /*  Scanning the information */
   4483     status = _synctex_match_string(scanner,"Magnification:");
   4484     if (status == SYNCTEX_STATUS_OK ) {
   4485 #ifdef HAVE_SETLOCALE
   4486         setlocale(LC_NUMERIC, "C");
   4487 #endif
   4488         scanner->unit = strtod(SYNCTEX_CUR,&endptr);
   4489 #ifdef HAVE_SETLOCALE
   4490         setlocale(LC_NUMERIC, loc);
   4491 #endif
   4492         if (endptr == SYNCTEX_CUR) {
   4493             _synctex_error("bad magnification in the post scriptum, a float was expected.");
   4494             return SYNCTEX_STATUS_ERROR;
   4495         }
   4496         if (scanner->unit<=0) {
   4497             _synctex_error("bad magnification in the post scriptum, a positive float was expected.");
   4498             return SYNCTEX_STATUS_ERROR;
   4499         }
   4500         SYNCTEX_CUR = endptr;
   4501         goto next_line;
   4502     }
   4503     if (status<SYNCTEX_STATUS_EOF){
   4504     report_record_problem:
   4505         _synctex_error("Problem reading the Post Scriptum records");
   4506         return status; /*  echo the error. */
   4507     }
   4508     status = _synctex_match_string(scanner,"X Offset:");
   4509     if (status == SYNCTEX_STATUS_OK) {
   4510         fs = _synctex_scan_float_and_dimension(scanner);
   4511         if (fs.status<SYNCTEX_STATUS_OK) {
   4512             _synctex_error("Problem with X offset in the Post Scriptum.");
   4513             return fs.status;
   4514         }
   4515         scanner->x_offset = fs.value;
   4516         goto next_line;
   4517     } else if (status<SYNCTEX_STATUS_EOF){
   4518         goto report_record_problem;
   4519     }
   4520     status = _synctex_match_string(scanner,"Y Offset:");
   4521     if (status==SYNCTEX_STATUS_OK) {
   4522         fs = _synctex_scan_float_and_dimension(scanner);
   4523         if (fs.status<SYNCTEX_STATUS_OK) {
   4524             _synctex_error("Problem with Y offset in the Post Scriptum.");
   4525             return fs.status;
   4526         }
   4527         scanner->x_offset = fs.value;
   4528         goto next_line;
   4529     } else if (status<SYNCTEX_STATUS_EOF){
   4530         goto report_record_problem;
   4531     }
   4532     goto next_line;
   4533 }
   4534 
   4535 /*  SYNCTEX_STATUS_OK is returned if the postamble is read
   4536  *  SYNCTEX_STATUS_NOT_OK is returned if the postamble is not at the current location
   4537  *  a negative error otherwise
   4538  *  The postamble comprises the post scriptum section.
   4539  */
   4540 static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner) {
   4541     synctex_status_t status = 0;
   4542     synctex_is_s is = {0,0};
   4543     if (NULL == scanner) {
   4544         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4545     }
   4546     if (!scanner->flags.postamble && (status=_synctex_match_string(scanner,"Postamble:"))<SYNCTEX_STATUS_OK) {
   4547         return status;
   4548     }
   4549 count_again:
   4550     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4551         return status;
   4552     }
   4553     if ((status=_synctex_scan_named(scanner,"Count:"))< SYNCTEX_STATUS_EOF) {
   4554         return status; /*  forward the error */
   4555     } else if (status < SYNCTEX_STATUS_OK) { /*  No Count record found */
   4556         goto count_again;
   4557     }
   4558     if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
   4559         return is.status;
   4560     }
   4561     if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
   4562         return status;
   4563     }
   4564     scanner->count = is.integer;
   4565     /*  Now we scan the last part of the SyncTeX file: the Post Scriptum section. */
   4566     return _synctex_scan_post_scriptum(scanner);
   4567 }
   4568 
   4569 /*  Horizontal boxes also have visible size.
   4570  *  Visible size are bigger than real size.
   4571  *  For example 0 width boxes may contain text.
   4572  *  At creation time, the visible size is set to the values of the real size.
   4573  */
   4574 static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box) {
   4575     if (box) {
   4576         switch(synctex_node_type(box)) {
   4577             case synctex_node_type_hbox:
   4578                 _synctex_data_set_h_V(box,_synctex_data_h(box));
   4579                 _synctex_data_set_v_V(box,_synctex_data_v(box));
   4580                 _synctex_data_set_width_V(box,_synctex_data_width(box));
   4581                 _synctex_data_set_height_V(box,_synctex_data_height(box));
   4582                 _synctex_data_set_depth_V(box,_synctex_data_depth(box));
   4583                 return SYNCTEX_STATUS_OK;
   4584             default:
   4585                 break;
   4586         }
   4587     }
   4588     return SYNCTEX_STATUS_BAD_ARGUMENT;
   4589 }
   4590 
   4591 /*  This method is sent to an horizontal box to setup the visible size
   4592  *  Some box have 0 width but do contain text material.
   4593  *  With this method, one can enlarge the box to contain the given point (h,v).
   4594  */
   4595 static synctex_status_t _synctex_make_hbox_contain_point(synctex_node_p node,synctex_point_s point) {
   4596     int min, max, n;
   4597     if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) {
   4598         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4599     }
   4600     if ((n = _synctex_data_width_V(node))<0) {
   4601         max = _synctex_data_h_V(node);
   4602         min = max+n;
   4603         if (point.h<min) {
   4604             _synctex_data_set_width_V(node,point.h-max);
   4605         } else if (point.h>max) {
   4606             _synctex_data_set_h_V(node,point.h);
   4607             _synctex_data_set_width_V(node,min-point.h);
   4608         }
   4609     } else {
   4610         min = _synctex_data_h_V(node);
   4611         max = min+n;
   4612         if (point.h<min) {
   4613             _synctex_data_set_h_V(node,point.h);
   4614             _synctex_data_set_width_V(node,max - point.h);
   4615         } else if (point.h>max) {
   4616             _synctex_data_set_width_V(node,point.h - min);
   4617         }
   4618     }
   4619     n = _synctex_data_v_V(node);
   4620     min = n - _synctex_data_height_V(node);
   4621     max = n + _synctex_data_depth_V(node);
   4622     if (point.v<min) {
   4623         _synctex_data_set_height_V(node,n-point.v);
   4624     } else if (point.v>max) {
   4625         _synctex_data_set_depth_V(node,point.v-n);
   4626     }
   4627     return SYNCTEX_STATUS_OK;
   4628 }
   4629 static synctex_status_t _synctex_make_hbox_contain_box(synctex_node_p node,synctex_box_s box) {
   4630     int min, max, n;
   4631     if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) {
   4632         return SYNCTEX_STATUS_BAD_ARGUMENT;
   4633     }
   4634     if ((n = _synctex_data_width_V(node))<0) {
   4635         max = _synctex_data_h_V(node);
   4636         min = max+n;
   4637         if (box.min.h <min) {
   4638             _synctex_data_set_width_V(node,box.min.h-max);
   4639         } else if (box.max.h>max) {
   4640             _synctex_data_set_h_V(node,box.max.h);
   4641             _synctex_data_set_width_V(node,min-box.max.h);
   4642         }
   4643     } else {
   4644         min = _synctex_data_h_V(node);
   4645         max = min+n;
   4646         if (box.min.h<min) {
   4647             _synctex_data_set_h_V(node,box.min.h);
   4648             _synctex_data_set_width_V(node,max - box.min.h);
   4649         } else if (box.max.h>max) {
   4650             _synctex_data_set_width_V(node,box.max.h - min);
   4651         }
   4652     }
   4653     n = _synctex_data_v_V(node);
   4654     min = n - _synctex_data_height_V(node);
   4655     max = n + _synctex_data_depth_V(node);
   4656     if (box.min.v<min) {
   4657         _synctex_data_set_height_V(node,n-box.min.v);
   4658     } else if (box.max.v>max) {
   4659         _synctex_data_set_depth_V(node,box.max.v-n);
   4660     }
   4661     return SYNCTEX_STATUS_OK;
   4662 }
   4663 #	ifdef SYNCTEX_NOTHING
   4664 #       pragma mark -
   4665 #       pragma mark SPECIAL CHARACTERS
   4666 #   endif
   4667 
   4668 
   4669 /*  Here are the control characters that start each line of the synctex output file.
   4670  *  Their values define the meaning of the line.
   4671  */
   4672 #   define SYNCTEX_CHAR_BEGIN_SHEET '{'
   4673 #   define SYNCTEX_CHAR_END_SHEET   '}'
   4674 #   define SYNCTEX_CHAR_BEGIN_FORM  '<'
   4675 #   define SYNCTEX_CHAR_END_FORM    '>'
   4676 #   define SYNCTEX_CHAR_BEGIN_VBOX  '['
   4677 #   define SYNCTEX_CHAR_END_VBOX    ']'
   4678 #   define SYNCTEX_CHAR_BEGIN_HBOX  '('
   4679 #   define SYNCTEX_CHAR_END_HBOX    ')'
   4680 #   define SYNCTEX_CHAR_ANCHOR      '!'
   4681 #   define SYNCTEX_CHAR_VOID_VBOX   'v'
   4682 #   define SYNCTEX_CHAR_VOID_HBOX   'h'
   4683 #   define SYNCTEX_CHAR_KERN        'k'
   4684 #   define SYNCTEX_CHAR_GLUE        'g'
   4685 #   define SYNCTEX_CHAR_RULE        'r'
   4686 #   define SYNCTEX_CHAR_MATH        '$'
   4687 #   define SYNCTEX_CHAR_FORM_REF    'f'
   4688 #   define SYNCTEX_CHAR_BOUNDARY    'x'
   4689 #   define SYNCTEX_CHAR_CHARACTER   'c'
   4690 #   define SYNCTEX_CHAR_COMMENT     '%'
   4691 
   4692 #	ifdef SYNCTEX_NOTHING
   4693 #       pragma mark -
   4694 #       pragma mark SCANNERS & PARSERS
   4695 #   endif
   4696 
   4697 #   define SYNCTEX_DECODE_FAILED(NODE,WHAT) \
   4698 (_synctex_data_decode_##WHAT(NODE)<SYNCTEX_STATUS_OK)
   4699 #   define SYNCTEX_DECODE_FAILED_V(NODE,WHAT) \
   4700 (_synctex_data_decode_##WHAT##_v(NODE)<SYNCTEX_STATUS_OK)
   4701 
   4702 #define SYNCTEX_NS_NULL (synctex_ns_s){NULL,SYNCTEX_STATUS_NOT_OK}
   4703 static synctex_ns_s _synctex_parse_new_sheet(synctex_scanner_p scanner) {
   4704     synctex_node_p node;
   4705     if ((node = _synctex_new_sheet(scanner))) {
   4706         if (
   4707             SYNCTEX_DECODE_FAILED(node,page)) {
   4708             _synctex_error("Bad sheet record.");
   4709         } else if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4710             _synctex_error("Missing end of sheet.");
   4711         } else {
   4712             /* Now set the owner */
   4713             if (scanner->sheet) {
   4714                 synctex_node_p last_sheet = scanner->sheet;
   4715                 synctex_node_p next_sheet = NULL;
   4716                 while ((next_sheet = __synctex_tree_sibling(last_sheet))) {
   4717                     last_sheet = next_sheet;
   4718                 }
   4719                 /* sheets have no parent */
   4720                 __synctex_tree_set_sibling(last_sheet,node);
   4721             } else {
   4722                 scanner->sheet = node;
   4723             }
   4724             return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4725         }
   4726         _synctex_free_node(node);
   4727     }
   4728     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4729 }
   4730 /**
   4731  *  - requirement: scanner != NULL
   4732  */
   4733 static synctex_ns_s _synctex_parse_new_form(synctex_scanner_p scanner) {
   4734     synctex_node_p node;
   4735     if ((node = _synctex_new_form(scanner))) {
   4736         if (
   4737             SYNCTEX_DECODE_FAILED(node,tag)) {
   4738             _synctex_error("Bad sheet record.");
   4739         } else if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4740             _synctex_error("Missing end of form.");
   4741         } else {
   4742             /* Now set the owner */
   4743             if (scanner->form) {
   4744                 synctex_node_p last_form = scanner->form;
   4745                 synctex_node_p next_form = NULL;
   4746                 while ((next_form = __synctex_tree_sibling(last_form))) {
   4747                     last_form = next_form;
   4748                 }
   4749                 __synctex_tree_set_sibling(last_form,node);
   4750             } else {
   4751                 scanner->form = node;
   4752             }
   4753             return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4754         }
   4755         _synctex_free_node(node);
   4756     }
   4757     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4758 }
   4759 #   define SYNCTEX_SHOULD_DECODE_FAILED(NODE,WHAT) \
   4760 (_synctex_data_has_##WHAT(NODE) &&(_synctex_data_decode_##WHAT(NODE)<SYNCTEX_STATUS_OK))
   4761 #   define SYNCTEX_SHOULD_DECODE_FAILED_V(NODE,WHAT) \
   4762 (_synctex_data_has_##WHAT(NODE) &&(_synctex_data_decode_##WHAT##_v(NODE)<SYNCTEX_STATUS_OK))
   4763 
   4764 static synctex_status_t _synctex_data_decode_tlchvwhd(synctex_node_p node) {
   4765     return SYNCTEX_SHOULD_DECODE_FAILED(node,tag)
   4766     || SYNCTEX_SHOULD_DECODE_FAILED(node,line)
   4767     || SYNCTEX_SHOULD_DECODE_FAILED(node,column)
   4768     || SYNCTEX_SHOULD_DECODE_FAILED(node,h)
   4769     || SYNCTEX_SHOULD_DECODE_FAILED_V(node,v)
   4770     || SYNCTEX_SHOULD_DECODE_FAILED(node,width)
   4771     || SYNCTEX_SHOULD_DECODE_FAILED(node,height)
   4772     || SYNCTEX_SHOULD_DECODE_FAILED(node,depth);
   4773 }
   4774 static synctex_ns_s _synctex_parse_new_vbox(synctex_scanner_p scanner) {
   4775     synctex_node_p node;
   4776     if ((node = _synctex_new_vbox(scanner))) {
   4777         if (_synctex_data_decode_tlchvwhd(node)) {
   4778             _synctex_error("Bad vbox record.");
   4779             _synctex_next_line(scanner);
   4780         out:
   4781             _synctex_free_node(node);
   4782             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4783         }
   4784         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4785             _synctex_error("Missing end of vbox.");
   4786             goto out;
   4787         }
   4788         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4789     }
   4790     _synctex_next_line(scanner);
   4791     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4792 }
   4793 SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node);
   4794 static synctex_ns_s _synctex_parse_new_hbox(synctex_scanner_p scanner) {
   4795     synctex_node_p node;
   4796     if ((node = _synctex_new_hbox(scanner))) {
   4797         if (_synctex_data_decode_tlchvwhd(node)) {
   4798             _synctex_error("Bad hbox record.");
   4799             _synctex_next_line(scanner);
   4800         out:
   4801             _synctex_free_node(node);
   4802             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4803         }
   4804         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4805             _synctex_error("Missing end of hbox.");
   4806             goto out;
   4807         }
   4808         if (_synctex_setup_visible_hbox(node)<SYNCTEX_STATUS_OK) {
   4809             _synctex_error("Unexpected error (_synctex_parse_new_hbox).");
   4810             goto out;
   4811         }
   4812         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4813     }
   4814     _synctex_next_line(scanner);
   4815     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4816 }
   4817 static synctex_ns_s _synctex_parse_new_void_vbox(synctex_scanner_p scanner) {
   4818     synctex_node_p node;
   4819     if ((node = _synctex_new_void_vbox(scanner))) {
   4820         if (_synctex_data_decode_tlchvwhd(node)) {
   4821             _synctex_error("Bad void vbox record.");
   4822             _synctex_next_line(scanner);
   4823         out:
   4824             _synctex_free_node(node);
   4825             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4826         }
   4827         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4828             _synctex_error("Missing end of container.");
   4829             goto out;
   4830         }
   4831         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4832     }
   4833     _synctex_next_line(scanner);
   4834     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4835 }
   4836 static synctex_ns_s _synctex_parse_new_void_hbox(synctex_scanner_p scanner) {
   4837     synctex_node_p node;
   4838     if ((node = _synctex_new_void_hbox(scanner))) {
   4839         if (_synctex_data_decode_tlchvwhd(node)) {
   4840             _synctex_error("Bad void hbox record.");
   4841             _synctex_next_line(scanner);
   4842         out:
   4843             _synctex_free_node(node);
   4844             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4845         }
   4846         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4847             _synctex_error("Missing end of container.");
   4848             goto out;
   4849         }
   4850         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4851     }
   4852     _synctex_next_line(scanner);
   4853     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4854 }
   4855 static synctex_ns_s _synctex_parse_new_kern(synctex_scanner_p scanner) {
   4856     synctex_node_p node;
   4857     if ((node = _synctex_new_kern(scanner))) {
   4858         if (_synctex_data_decode_tlchvwhd(node)) {
   4859             _synctex_error("Bad kern record.");
   4860             _synctex_next_line(scanner);
   4861         out:
   4862             _synctex_free_node(node);
   4863             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4864         }
   4865         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4866             _synctex_error("Missing end of container.");
   4867             goto out;
   4868         }
   4869         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4870     }
   4871     _synctex_next_line(scanner);
   4872     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4873 }
   4874 static synctex_ns_s _synctex_parse_new_glue(synctex_scanner_p scanner) {
   4875     synctex_node_p node;
   4876     if ((node = _synctex_new_glue(scanner))) {
   4877         if (_synctex_data_decode_tlchvwhd(node)) {
   4878             _synctex_error("Bad glue record.");
   4879             _synctex_next_line(scanner);
   4880         out:
   4881             _synctex_free_node(node);
   4882             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4883         }
   4884         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4885             _synctex_error("Missing end of container.");
   4886             goto out;
   4887         }
   4888         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4889     }
   4890     _synctex_next_line(scanner);
   4891     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4892 }
   4893 static synctex_ns_s _synctex_parse_new_rule(synctex_scanner_p scanner) {
   4894     synctex_node_p node;
   4895     if ((node = _synctex_new_rule(scanner))) {
   4896         if (_synctex_data_decode_tlchvwhd(node)) {
   4897             _synctex_error("Bad rule record.");
   4898             _synctex_next_line(scanner);
   4899         out:
   4900             _synctex_free_node(node);
   4901             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4902         }
   4903         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4904             _synctex_error("Missing end of container.");
   4905             goto out;
   4906         }
   4907         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4908     }
   4909     _synctex_next_line(scanner);
   4910     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4911 }
   4912 static synctex_ns_s _synctex_parse_new_math(synctex_scanner_p scanner) {
   4913     synctex_node_p node;
   4914     if ((node = _synctex_new_math(scanner))) {
   4915         if (_synctex_data_decode_tlchvwhd(node)) {
   4916             _synctex_error("Bad math record.");
   4917             _synctex_next_line(scanner);
   4918         out:
   4919             _synctex_free_node(node);
   4920             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4921         }
   4922         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4923             _synctex_error("Missing end of container.");
   4924             goto out;
   4925         }
   4926         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4927     }
   4928     _synctex_next_line(scanner);
   4929     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4930 }
   4931 static synctex_ns_s _synctex_parse_new_boundary(synctex_scanner_p scanner) {
   4932     synctex_node_p node;
   4933     if ((node = _synctex_new_boundary(scanner))) {
   4934         if (_synctex_data_decode_tlchvwhd(node)) {
   4935             _synctex_error("Bad boundary record.");
   4936             _synctex_next_line(scanner);
   4937         out:
   4938             _synctex_free_node(node);
   4939             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4940         }
   4941         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4942             _synctex_error("Missing end of container.");
   4943             goto out;
   4944         }
   4945         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4946     }
   4947     _synctex_next_line(scanner);
   4948     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4949 }
   4950 SYNCTEX_INLINE static synctex_ns_s _synctex_parse_new_ref(synctex_scanner_p scanner) {
   4951     synctex_node_p node;
   4952     if ((node = _synctex_new_ref(scanner))) {
   4953         if (SYNCTEX_DECODE_FAILED(node,tag)
   4954             || SYNCTEX_DECODE_FAILED(node,h)
   4955             || SYNCTEX_DECODE_FAILED_V(node,v)) {
   4956             _synctex_error("Bad form ref record.");
   4957             _synctex_next_line(scanner);
   4958         out:
   4959             _synctex_free_node(node);
   4960             return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4961         }
   4962         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   4963             _synctex_error("Missing end of container.");
   4964             goto out;
   4965         }
   4966         return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
   4967     }
   4968     _synctex_next_line(scanner);
   4969     return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
   4970 }
   4971 #   undef SYNCTEX_DECODE_FAILED
   4972 #   undef SYNCTEX_DECODE_FAILED_V
   4973 
   4974 SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node);
   4975 SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node);
   4976 SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point);
   4977 SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node);
   4978 SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node);
   4979 SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node);
   4980 
   4981 SYNCTEX_INLINE static synctex_node_p _synctex_input_register_line(synctex_node_p input,synctex_node_p node) {
   4982     if (node && _synctex_data_tag(input) != _synctex_data_tag(node)) {
   4983         input = synctex_scanner_input_with_tag(node->class_->scanner,_synctex_data_tag(node));
   4984     }
   4985     if (_synctex_data_line(node)>_synctex_data_line(input)) {
   4986         _synctex_data_set_line(input,_synctex_data_line(node));
   4987     }
   4988     return input;
   4989 }
   4990 /**
   4991  *  Free node and its siblings and return its detached child.
   4992  */
   4993 SYNCTEX_INLINE static synctex_node_p _synctex_handle_pop_child(synctex_node_p handle) {
   4994     synctex_node_p child = _synctex_tree_reset_child(handle);
   4995     synctex_node_free(handle);
   4996     return child;
   4997 }
   4998 /**
   4999  *  Set the tlc of all the x nodes that are targets of
   5000  *  x_handle and its sibling.
   5001  *  Reset the target of x_handle and deletes its siblings.
   5002  *  child is a node that has just been parsed and is not a boundary node.
   5003  */
   5004 SYNCTEX_INLINE static void _synctex_handle_set_tlc(synctex_node_p x_handle, synctex_node_p child, synctex_bool_t make_friend) {
   5005     if (x_handle) {
   5006         synctex_node_p sibling = x_handle;
   5007         if (child) {
   5008             synctex_node_p target;
   5009             while ((target = synctex_node_target(sibling))) {
   5010                 _synctex_data_set_tlc(target,child);
   5011                 if (make_friend) {
   5012                     _synctex_node_make_friend_tlc(target);
   5013                 }
   5014                 if ((sibling = __synctex_tree_sibling(sibling))) {
   5015                     continue;
   5016                 } else {
   5017                     break;
   5018                 }
   5019             }
   5020         }
   5021         _synctex_tree_reset_target(x_handle);
   5022         sibling = __synctex_tree_reset_sibling(x_handle);
   5023         synctex_node_free(sibling);
   5024     }
   5025 }
   5026 /**
   5027  *  When we have parsed a box, we must register
   5028  *  all the contained heading boundary nodes
   5029  *  that have not yet been registered.
   5030  *  Those handles will be deleted when popping.
   5031  */
   5032 SYNCTEX_INLINE static void _synctex_handle_make_friend_tlc(synctex_node_p node) {
   5033     while (node) {
   5034         synctex_node_p target = _synctex_tree_reset_target(node);
   5035         _synctex_node_make_friend_tlc(target);
   5036         node = __synctex_tree_sibling(node);
   5037     }
   5038 }
   5039 /**
   5040  *  Scan sheets, forms and input records.
   5041  *  - parameter scanner: owning scanner
   5042  *  - returns: status
   5043  */
   5044 static synctex_status_t __synctex_parse_sfi(synctex_scanner_p scanner) {
   5045     synctex_status_t status = SYNCTEX_STATUS_OK;
   5046     synctex_zs_s zs = {0,0};
   5047     synctex_ns_s input = SYNCTEX_NS_NULL;
   5048     synctex_node_p sheet = NULL;
   5049     synctex_node_p form = NULL;
   5050     synctex_node_p parent = NULL;
   5051     synctex_node_p child = NULL;
   5052     /*
   5053      *  Experimentations lead to the forthcoming conclusion:
   5054      *  Sometimes, the first nodes of a box have the wrong line number.
   5055      *  These are only boundary (x) nodes.
   5056      *  We observed that boundary nodes do have the proper line number
   5057      *  if they follow a node with a different type.
   5058      *  We keep track of these leading x nodes in a handle tree.
   5059      */
   5060     synctex_node_p x_handle = NULL;
   5061 #   define SYNCTEX_RETURN(STATUS) \
   5062         synctex_node_free(x_handle);\
   5063         return STATUS
   5064     synctex_node_p last_k = NULL;
   5065     synctex_node_p last_g = NULL;
   5066     synctex_ns_s ns = SYNCTEX_NS_NULL;
   5067     int form_depth = 0;
   5068     int ignored_form_depth = 0;
   5069     synctex_bool_t try_input = synctex_YES;
   5070     if (!(x_handle = _synctex_new_handle(scanner))) {
   5071         SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5072     }
   5073 #	ifdef SYNCTEX_NOTHING
   5074 #       pragma mark MAIN LOOP
   5075 #   endif
   5076 main_loop:
   5077     status = SYNCTEX_STATUS_OK;
   5078     sheet = form = parent = child = NULL;
   5079 #   define SYNCTEX_START_SCAN(WHAT)\
   5080 (*SYNCTEX_CUR == SYNCTEX_CHAR_##WHAT)
   5081     if (SYNCTEX_CUR<SYNCTEX_END) {
   5082         if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
   5083 #	ifdef SYNCTEX_NOTHING
   5084 #       pragma mark + SCAN FORM
   5085 #   endif
   5086         scan_form:
   5087             ns = _synctex_parse_new_form(scanner);
   5088             if (ns.status == SYNCTEX_STATUS_OK) {
   5089                 ++form_depth;
   5090                 if (_synctex_tree_parent(form)) {
   5091                     /* This form is already being parsed */
   5092                     ++ignored_form_depth;
   5093                     goto ignore_loop;
   5094                 }
   5095                 _synctex_tree_set_parent(ns.node,form);
   5096                 form = ns.node;
   5097                 parent = form;
   5098                 child = NULL;
   5099                 last_k = last_g = NULL;
   5100                 goto content_loop;
   5101             }
   5102             if (form || sheet) {
   5103                 last_k = last_g = NULL;
   5104                 goto content_loop;
   5105             }
   5106             try_input = synctex_YES;
   5107             goto main_loop;
   5108         } else if (SYNCTEX_START_SCAN(BEGIN_SHEET)) {
   5109 #	ifdef SYNCTEX_NOTHING
   5110 #       pragma mark + SCAN SHEET
   5111 #   endif
   5112             try_input = synctex_YES;
   5113             ns = _synctex_parse_new_sheet(scanner);
   5114             if (ns.status == SYNCTEX_STATUS_OK) {
   5115                 sheet = ns.node;
   5116                 parent = sheet;
   5117                 last_k = last_g = NULL;
   5118                 goto content_loop;
   5119             }
   5120             goto main_loop;
   5121         } else if (SYNCTEX_START_SCAN(ANCHOR)) {
   5122 #	ifdef SYNCTEX_NOTHING
   5123 #       pragma mark + SCAN ANCHOR
   5124 #   endif
   5125         scan_anchor:
   5126             ++SYNCTEX_CUR;
   5127             if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5128                 _synctex_error("Missing anchor.");
   5129                 SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5130             }
   5131             if (form || sheet) {
   5132                 last_k = last_g = NULL;
   5133                 goto content_loop;
   5134             }
   5135             try_input = synctex_YES;
   5136             goto main_loop;
   5137         } else if (SYNCTEX_START_SCAN(ANCHOR)) {
   5138 #	ifdef SYNCTEX_NOTHING
   5139 #       pragma mark + SCAN COMMENT
   5140 #   endif
   5141             ++SYNCTEX_CUR;
   5142             _synctex_next_line(scanner);
   5143             try_input = synctex_YES;
   5144             goto main_loop;
   5145         } else if (try_input) {
   5146 #	ifdef SYNCTEX_NOTHING
   5147 #       pragma mark + SCAN INPUT
   5148 #   endif
   5149             try_input = synctex_NO;
   5150             do {
   5151                 input = __synctex_parse_new_input(scanner);
   5152             } while (input.status == SYNCTEX_STATUS_OK);
   5153             goto main_loop;
   5154         }
   5155         status = _synctex_match_string(scanner,"Postamble:");
   5156         if (status==SYNCTEX_STATUS_OK) {
   5157             scanner->flags.postamble = 1;
   5158             SYNCTEX_RETURN(status);
   5159         }
   5160         status = _synctex_next_line(scanner);
   5161         if (status<SYNCTEX_STATUS_OK) {
   5162             SYNCTEX_RETURN(status);
   5163         }
   5164    }
   5165     /* At least 1 more character */
   5166     zs = _synctex_buffer_get_available_size(scanner,1);
   5167     if (zs.size == 0){
   5168         _synctex_error("Incomplete synctex file, postamble missing.");
   5169         SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5170     }
   5171     goto main_loop;
   5172     /*  Unreachable. */
   5173 #	ifdef SYNCTEX_NOTHING
   5174 #       pragma mark IGNORE LOOP
   5175 #   endif
   5176 ignore_loop:
   5177     ns = SYNCTEX_NS_NULL;
   5178     if (SYNCTEX_CUR<SYNCTEX_END) {
   5179         if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
   5180             ++ignored_form_depth;
   5181         } else if (SYNCTEX_START_SCAN(END_FORM)) {
   5182             --ignored_form_depth;
   5183         }
   5184         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5185             _synctex_error("Incomplete container.");
   5186             SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5187         }
   5188     } else {
   5189         zs = _synctex_buffer_get_available_size(scanner,1);
   5190         if (zs.size == 0){
   5191             _synctex_error("Incomplete synctex file, postamble missing.");
   5192             SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5193         }
   5194     }
   5195     if (ignored_form_depth) {
   5196         goto ignore_loop;
   5197     } else {
   5198         last_k = last_g = NULL;
   5199         goto content_loop;
   5200     }
   5201 
   5202 #	ifdef SYNCTEX_NOTHING
   5203 #       pragma mark CONTENT LOOP
   5204 #   endif
   5205 content_loop:
   5206     /*  Either in a form, a sheet or a box.
   5207      *  - in a sheet, "{" is not possible, only boxes and "}" at top level.
   5208      *  - in a form, "{" is not possible, only boxes, "<" and ">" at top level.
   5209      *  - in a box, the unique possibility is '<', '[', '(' or ">".
   5210      *  We still keep the '(' for a sheet, because that dos not cost too much.
   5211      *  We must also consider void boxes as children.
   5212      */
   5213     /* forms are everywhere */
   5214     ns = SYNCTEX_NS_NULL;
   5215 #if SYNCTEX_VERBOSE
   5216     synctex_scanner_set_display_switcher(scanner,-1);
   5217     printf("NEW CONTENT LOOP\n");
   5218 #if SYNCTEX_DEBUG>500
   5219     synctex_node_display(sheet);
   5220 #endif
   5221 #endif
   5222     if (SYNCTEX_CUR<SYNCTEX_END) {
   5223         if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
   5224             goto scan_form;
   5225         } else if (SYNCTEX_START_SCAN(BEGIN_VBOX)) {
   5226 #	ifdef SYNCTEX_NOTHING
   5227 #       pragma mark + SCAN VBOX
   5228 #   endif
   5229             ns = _synctex_parse_new_vbox(scanner);
   5230             if (ns.status == SYNCTEX_STATUS_OK) {
   5231                 x_handle = _synctex_new_handle_with_child(x_handle);
   5232                 if (child) {
   5233                     _synctex_node_set_sibling(child,ns.node);
   5234                 } else {
   5235                     _synctex_node_set_child(parent,ns.node);
   5236                 }
   5237                 parent = ns.node;
   5238                 child = _synctex_tree_last(parent);
   5239 #   if SYNCTEX_VERBOSE
   5240                 synctex_node_log(parent);
   5241 #   endif
   5242                 input.node = _synctex_input_register_line(input.node,parent);
   5243                 last_k = last_g = NULL;
   5244                 goto content_loop;
   5245             }
   5246         } else if (SYNCTEX_START_SCAN(END_VBOX)) {
   5247             if (synctex_node_type(parent) == synctex_node_type_vbox) {
   5248 #	ifdef SYNCTEX_NOTHING
   5249 #       pragma mark + SCAN XOBV
   5250 #   endif
   5251                 ++SYNCTEX_CUR;
   5252                 if (NULL == _synctex_tree_child(parent) && !form) {
   5253                     /*  only void v boxes are friends */
   5254                     _synctex_node_make_friend_tlc(parent);
   5255                 }
   5256                 child = parent;
   5257                 parent = _synctex_tree_parent(child);
   5258                 if (!form) {
   5259                     _synctex_handle_make_friend_tlc(x_handle);
   5260                 }
   5261                 x_handle = _synctex_handle_pop_child(x_handle);
   5262                 _synctex_handle_set_tlc(x_handle,child,!form);
   5263 #   if SYNCTEX_VERBOSE
   5264                 synctex_node_log(child);
   5265 #   endif
   5266                 if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5267                     _synctex_error("Incomplete container.");
   5268                     SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5269                 }
   5270                 last_k = last_g = NULL;
   5271                 goto content_loop;
   5272             }
   5273         } else if (SYNCTEX_START_SCAN(BEGIN_HBOX)) {
   5274 #	ifdef SYNCTEX_NOTHING
   5275 #       pragma mark + SCAN HBOX
   5276 #   endif
   5277 #   if defined(SYNCTEX_USE_CHARINDEX)
   5278             synctex_charindex_t char_index = (synctex_charindex_t)(scanner->reader->charindex_offset+SYNCTEX_CUR-SYNCTEX_START);
   5279             synctex_lineindex_t line_index = scanner->reader->line_number;
   5280 #   endif
   5281             ns = _synctex_parse_new_hbox(scanner);
   5282             if (ns.status == SYNCTEX_STATUS_OK) {
   5283                 x_handle = _synctex_new_handle_with_child(x_handle);
   5284                 if (child) {
   5285                     _synctex_node_set_sibling(child,ns.node);
   5286                 } else {
   5287                     _synctex_node_set_child(parent,ns.node);
   5288                 }
   5289                 parent = ns.node;
   5290                 /*  add a box boundary node at the start */
   5291                 if ((child = _synctex_new_box_bdry(scanner))) {
   5292 #   if defined(SYNCTEX_USE_CHARINDEX)
   5293                     child->line_index=line_index;
   5294                     child->char_index=char_index;
   5295 #   endif
   5296                     _synctex_node_set_child(parent,child);
   5297                     _synctex_data_set_tlchv(child,parent);
   5298                     if (!form) {
   5299                         __synctex_node_make_friend_tlc(child);
   5300                     }
   5301                 } else {
   5302                     _synctex_error("Can't create box bdry record.");
   5303                 }
   5304 #   if SYNCTEX_VERBOSE
   5305                 synctex_node_log(parent);
   5306 #   endif
   5307                 input.node = _synctex_input_register_line(input.node,parent);
   5308                 last_k = last_g = NULL;
   5309                 goto content_loop;
   5310             }
   5311         } else if (SYNCTEX_START_SCAN(END_HBOX)) {
   5312             if (synctex_node_type(parent) == synctex_node_type_hbox) {
   5313 #	ifdef SYNCTEX_NOTHING
   5314 #       pragma mark + SCAN XOBH
   5315 #   endif
   5316                 ++SYNCTEX_CUR;
   5317                 /*  setting the next horizontal box at the end ensures
   5318                  * that a child is recorded before any of its ancestors.
   5319                  */
   5320                 if (form == NULL /* && sheet != NULL*/ ) {
   5321                     _synctex_tree_set_next_hbox(parent,_synctex_tree_next_hbox(sheet));
   5322                     _synctex_tree_set_next_hbox(sheet,parent);
   5323                 }
   5324                 {
   5325                     /*  Update the mean line number */
   5326                     synctex_node_p node = _synctex_tree_child(parent);
   5327                     synctex_node_p sibling = NULL;
   5328                     /*  Ignore the first node (a box_bdry) */
   5329                     if (node && (sibling = __synctex_tree_sibling(node))) {
   5330                         unsigned int node_weight = 0;
   5331                         unsigned int cumulated_line_numbers = 0;
   5332                         _synctex_data_set_line(node, _synctex_data_line(sibling));
   5333                         node = sibling;
   5334                         do {
   5335                             if (synctex_node_type(node)==synctex_node_type_hbox) {
   5336                                 if (_synctex_data_weight(node)) {
   5337                                     node_weight += _synctex_data_weight(node);
   5338                                     cumulated_line_numbers += _synctex_data_mean_line(node)*_synctex_data_weight(node);
   5339                                 } else {
   5340                                     ++node_weight;
   5341                                     cumulated_line_numbers += _synctex_data_mean_line(node);
   5342                                 }
   5343                             } else {
   5344                                 ++node_weight;
   5345                                 cumulated_line_numbers += synctex_node_line(node);
   5346                             }
   5347                         } while ((node = __synctex_tree_sibling(node)));
   5348                         _synctex_data_set_mean_line(parent,(cumulated_line_numbers + node_weight/2)/node_weight);
   5349                         _synctex_data_set_weight(parent,node_weight);
   5350                     } else {
   5351                         _synctex_data_set_mean_line(parent,_synctex_data_line(parent));
   5352                         _synctex_data_set_weight(parent,1);
   5353                     }
   5354                     if ((sibling = _synctex_new_box_bdry(scanner))) {
   5355 #   if defined(SYNCTEX_USE_CHARINDEX)
   5356                         sibling->line_index=child->line_index;
   5357                         sibling->char_index=child->char_index;
   5358 #   endif
   5359                         _synctex_node_set_sibling(child,sibling);
   5360                         {
   5361                             synctex_node_p N = child;
   5362                             while (synctex_node_type(N) == synctex_node_type_ref) {
   5363                                 N = _synctex_tree_arg_sibling(N);
   5364                             }
   5365                             _synctex_data_set_tlc(sibling,N);
   5366                         }
   5367                         _synctex_data_set_h(sibling,_synctex_data_h_V(parent)+_synctex_data_width_V(parent));
   5368                         _synctex_data_set_v(sibling,_synctex_data_v_V(parent));
   5369                         child = sibling;
   5370                     } else {
   5371                         _synctex_error("Can't create box bdry record.");
   5372                     }
   5373                     sibling = _synctex_tree_child(parent);
   5374                     _synctex_data_set_point(sibling,_synctex_data_point_V(parent));
   5375                     if (last_k && last_g && (child = synctex_node_child(parent))) {
   5376                         /* Find the node preceding last_k */
   5377                         synctex_node_p next;
   5378                         while ((next = __synctex_tree_sibling(child))) {
   5379                             if (next == last_k) {
   5380                                 _synctex_data_set_tlc(last_k,child);
   5381                                 _synctex_data_set_tlc(last_g,child);
   5382                                 break;
   5383                             }
   5384                             child = next;
   5385                         }
   5386                     }
   5387                     child = parent;
   5388                     parent = _synctex_tree_parent(child);
   5389                     if (!form) {
   5390                         _synctex_handle_make_friend_tlc(x_handle);
   5391                     }
   5392                     x_handle = _synctex_handle_pop_child(x_handle);
   5393                     _synctex_handle_set_tlc(x_handle,child,!form);
   5394                     _synctex_make_hbox_contain_box(parent,                                    _synctex_data_box_V(child));
   5395 #   if SYNCTEX_VERBOSE
   5396                     synctex_node_log(child);
   5397 #   endif
   5398                 }
   5399                 if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5400                     _synctex_error("Incomplete container.");
   5401                     SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5402                 }
   5403                 last_k = last_g = NULL;
   5404                 goto content_loop;
   5405             }
   5406         } else if (SYNCTEX_START_SCAN(VOID_VBOX)) {
   5407 #	ifdef SYNCTEX_NOTHING
   5408 #       pragma mark + SCAN VOID VBOX
   5409 #   endif
   5410             ns = _synctex_parse_new_void_vbox(scanner);
   5411             if (ns.status == SYNCTEX_STATUS_OK) {
   5412                 if (child) {
   5413                     _synctex_node_set_sibling(child,ns.node);
   5414                 } else {
   5415                     _synctex_node_set_child(parent,ns.node);
   5416                 }
   5417                 child = ns.node;
   5418                 _synctex_handle_set_tlc(x_handle, child,!form);
   5419 #   if SYNCTEX_VERBOSE
   5420                 synctex_node_log(child);
   5421 #   endif
   5422                 input.node = _synctex_input_register_line(input.node,child);
   5423                 last_k = last_g = NULL;
   5424                 goto content_loop;
   5425             }
   5426         } else if (SYNCTEX_START_SCAN(VOID_HBOX)) {
   5427 #	ifdef SYNCTEX_NOTHING
   5428 #       pragma mark + SCAN VOID HBOX
   5429 #   endif
   5430             ns = _synctex_parse_new_void_hbox(scanner);
   5431             if (ns.status == SYNCTEX_STATUS_OK) {
   5432                 if (_synctex_data_width(ns.node)<0) {
   5433                     printf("Negative width\n");
   5434                 }
   5435                 if (child) {
   5436                     _synctex_node_set_sibling(child,ns.node);
   5437                 } else {
   5438                     _synctex_node_set_child(parent,ns.node);
   5439                 }
   5440                 child = ns.node;
   5441                 _synctex_handle_set_tlc(x_handle, child,!form);
   5442                 _synctex_make_hbox_contain_box(parent,_synctex_data_box(child));
   5443 #   if SYNCTEX_VERBOSE
   5444                 synctex_node_log(child);
   5445 #   endif
   5446                 input.node = _synctex_input_register_line(input.node,child);
   5447                 last_k = last_g = NULL;
   5448                 goto content_loop;
   5449             }
   5450         } else if (SYNCTEX_START_SCAN(KERN)) {
   5451 #	ifdef SYNCTEX_NOTHING
   5452 #       pragma mark + SCAN KERN
   5453 #   endif
   5454             ns = _synctex_parse_new_kern(scanner);
   5455         continue_scan:
   5456             if (ns.status == SYNCTEX_STATUS_OK) {
   5457                 if (child) {
   5458                     _synctex_node_set_sibling(child,ns.node);
   5459                 } else {
   5460                     _synctex_node_set_child(parent,ns.node);
   5461                 }
   5462                 child = ns.node;
   5463                 if (!form) {
   5464                     __synctex_node_make_friend_tlc(child);
   5465                 }
   5466                 _synctex_handle_set_tlc(x_handle, child,!form);
   5467                 _synctex_make_hbox_contain_box(parent,_synctex_data_xob(child));
   5468 #   if SYNCTEX_VERBOSE
   5469                 synctex_node_log(child);
   5470 #   endif
   5471                 input.node = _synctex_input_register_line(input.node,child);
   5472                 last_k = child;
   5473                 last_g = NULL;
   5474                 goto content_loop;
   5475             }
   5476         } else if (SYNCTEX_START_SCAN(GLUE)) {
   5477 #	ifdef SYNCTEX_NOTHING
   5478 #       pragma mark + SCAN GLUE
   5479 #   endif
   5480             ns = _synctex_parse_new_glue(scanner);
   5481             if (ns.status == SYNCTEX_STATUS_OK) {
   5482                 if (child) {
   5483                     _synctex_node_set_sibling(child,ns.node);
   5484                 } else {
   5485                     _synctex_node_set_child(parent,ns.node);
   5486                 }
   5487                 child = ns.node;
   5488                 if (!form) {
   5489                     __synctex_node_make_friend_tlc(child);
   5490                 }
   5491                 _synctex_handle_set_tlc(x_handle, child,!form);
   5492                 _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
   5493 #   if SYNCTEX_VERBOSE
   5494                 synctex_node_log(child);
   5495 #   endif
   5496                 input.node = _synctex_input_register_line(input.node,child);
   5497                 if (last_k) {
   5498                     last_g = child;
   5499                 } else {
   5500                     last_k = last_g = NULL;
   5501                 }
   5502                 goto content_loop;
   5503             }
   5504         } else if (SYNCTEX_START_SCAN(RULE)) {
   5505 #	ifdef SYNCTEX_NOTHING
   5506 #       pragma mark + SCAN RULE
   5507 #   endif
   5508             ns = _synctex_parse_new_rule(scanner);
   5509             if (ns.status == SYNCTEX_STATUS_OK) {
   5510                 if (child) {
   5511                     _synctex_node_set_sibling(child,ns.node);
   5512                 } else {
   5513                     _synctex_node_set_child(parent,ns.node);
   5514                 }
   5515                 child = ns.node;
   5516                 if (!form) {
   5517                     __synctex_node_make_friend_tlc(child);
   5518                 }
   5519                 _synctex_handle_set_tlc(x_handle, child,!form);
   5520                 /* Rules are sometimes far too big
   5521 _synctex_make_hbox_contain_box(parent,_synctex_data_box(child));
   5522                  */
   5523 #   if SYNCTEX_VERBOSE
   5524                 synctex_node_log(child);
   5525 #   endif
   5526                 input.node = _synctex_input_register_line(input.node,child);
   5527                 last_k = last_g = NULL;
   5528                 goto content_loop;
   5529             }
   5530         } else if (SYNCTEX_START_SCAN(MATH)) {
   5531 #	ifdef SYNCTEX_NOTHING
   5532 #       pragma mark + SCAN MATH
   5533 #   endif
   5534             ns = _synctex_parse_new_math(scanner);
   5535             if (ns.status == SYNCTEX_STATUS_OK) {
   5536                 if (child) {
   5537                     _synctex_node_set_sibling(child,ns.node);
   5538                 } else {
   5539                     _synctex_node_set_child(parent,ns.node);
   5540                 }
   5541                 child = ns.node;
   5542                 if (!form) {
   5543                     __synctex_node_make_friend_tlc(child);
   5544                 }
   5545                 _synctex_handle_set_tlc(x_handle, child,!form);
   5546                 _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
   5547 #   if SYNCTEX_VERBOSE
   5548                 synctex_node_log(child);
   5549 #   endif
   5550                 input.node = _synctex_input_register_line(input.node,child);
   5551                 last_k = last_g = NULL;
   5552                 goto content_loop;
   5553             }
   5554         } else if (SYNCTEX_START_SCAN(FORM_REF)) {
   5555 #	ifdef SYNCTEX_NOTHING
   5556 #       pragma mark + SCAN FORM REF
   5557 #   endif
   5558 #if SYNCTEX_DEBUG>500
   5559             synctex_node_display(parent);
   5560             synctex_node_display(child);
   5561 #endif
   5562             ns = _synctex_parse_new_ref(scanner);
   5563             if (ns.status == SYNCTEX_STATUS_OK) {
   5564                 if (child) {
   5565                     _synctex_node_set_sibling(child,ns.node);
   5566                 } else {
   5567                     _synctex_node_set_child(parent,ns.node);
   5568                 }
   5569                 child = ns.node;
   5570                 if (form) {
   5571                     if (scanner->ref_in_form) {
   5572                         synctex_tree_set_friend(child,scanner->ref_in_form);
   5573                     }
   5574                     scanner->ref_in_form = child;
   5575                 } else {
   5576                     if (scanner->ref_in_sheet) {
   5577                         synctex_tree_set_friend(child,scanner->ref_in_sheet);
   5578                     }
   5579                     scanner->ref_in_sheet = child;
   5580                 }
   5581 #   if SYNCTEX_VERBOSE
   5582                 synctex_node_log(child);
   5583 #   endif
   5584                 last_k = last_g = NULL;
   5585                 goto content_loop;
   5586             }
   5587         } else if (SYNCTEX_START_SCAN(BOUNDARY)) {
   5588 #	ifdef SYNCTEX_NOTHING
   5589 #       pragma mark + SCAN BOUNDARY
   5590 #   endif
   5591             ns = _synctex_parse_new_boundary(scanner);
   5592             if (ns.status == SYNCTEX_STATUS_OK) {
   5593                 if (child) {
   5594                     _synctex_node_set_sibling(child,ns.node);
   5595                 } else {
   5596                     _synctex_node_set_child(parent,ns.node);
   5597                 }
   5598                 if (synctex_node_type(child)==synctex_node_type_box_bdry
   5599                     || _synctex_tree_target(x_handle)) {
   5600                     child = _synctex_tree_reset_child(x_handle);
   5601                     child = _synctex_new_handle_with_child(child);
   5602                     __synctex_tree_set_sibling(child, x_handle);
   5603                     x_handle = child;
   5604                     _synctex_tree_set_target(x_handle,ns.node);
   5605                 } else if (!form) {
   5606                     __synctex_node_make_friend_tlc(ns.node);
   5607                 }
   5608                 child = ns.node;
   5609                 _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
   5610 #   if SYNCTEX_VERBOSE
   5611                 synctex_node_log(child);
   5612 #   endif
   5613                 input.node = _synctex_input_register_line(input.node,child);
   5614                 last_k = last_g = NULL;
   5615                 goto content_loop;
   5616             }
   5617         } else if (SYNCTEX_START_SCAN(CHARACTER)) {
   5618 #	ifdef SYNCTEX_NOTHING
   5619 #       pragma mark + SCAN CHARACTER
   5620 #   endif
   5621             ++SYNCTEX_CUR;
   5622             if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5623                 _synctex_error("Missing end of container.");
   5624                 SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5625             }
   5626             last_k = last_g = NULL;
   5627             goto content_loop;
   5628         } else if (SYNCTEX_START_SCAN(ANCHOR)) {
   5629 #	ifdef SYNCTEX_NOTHING
   5630 #       pragma mark + SCAN ANCHOR
   5631 #   endif
   5632             goto scan_anchor;
   5633         } else if (SYNCTEX_START_SCAN(END_SHEET)) {
   5634             if (sheet && parent == sheet) {
   5635 #	ifdef SYNCTEX_NOTHING
   5636 #       pragma mark + SCAN TEEHS
   5637 #   endif
   5638                 ++SYNCTEX_CUR;
   5639                 if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5640                     _synctex_error("Missing anchor.");
   5641                 }
   5642                 parent = sheet = NULL;
   5643                 goto main_loop;
   5644             }
   5645         } else if (SYNCTEX_START_SCAN(END_FORM)) {
   5646             if (parent == form && form_depth > 0) {
   5647 #	ifdef SYNCTEX_NOTHING
   5648 #       pragma mark + SCAN MROF
   5649 #   endif
   5650                 ++SYNCTEX_CUR;
   5651                 --form_depth;
   5652                 if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK
   5653                     && (form_depth || sheet)) {
   5654                     _synctex_error("Missing end of container.");
   5655                     SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5656                 }
   5657                 if ((parent = _synctex_tree_parent(form))) {
   5658                     _synctex_tree_reset_parent(form);
   5659                     child = form;
   5660                     form = parent;
   5661                     goto content_loop;
   5662                 } else if (sheet) {
   5663                     form = NULL;
   5664                     parent = sheet;
   5665                     child = synctex_node_last_sibling(child);
   5666                     goto content_loop;
   5667                 }
   5668                 goto main_loop;
   5669             }
   5670         }
   5671         _synctex_error("Ignored record <%.20s...>(line %i)\n",SYNCTEX_CUR, scanner->reader->line_number+1);
   5672         if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5673             _synctex_error("Missing end of sheet/form.");
   5674             SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5675         }
   5676         last_k = last_g = NULL;
   5677         goto content_loop;
   5678     }
   5679     zs = _synctex_buffer_get_available_size(scanner,1);
   5680     if (zs.size == 0){
   5681         _synctex_error("Incomplete synctex file, postamble missing.");
   5682         SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
   5683     }
   5684     last_k = last_g = NULL;
   5685     goto content_loop;
   5686 }
   5687 #undef SYNCTEX_RETURN
   5688 /**
   5689  *  Replace ref in its tree hierarchy by a single box
   5690  *  proxy to the contents of the associated form.
   5691  *  - argument ref: a ref node with no friend
   5692  *  - return the proxy created.
   5693  *  - note: Does nothing if ref is not owned.
   5694  *  - note: On return, ref will have no parent nor sibling.
   5695  *      The caller is responsible for releasing ref.
   5696  *  - note: this is where root proxies are created.
   5697  *  - note: the target of the root proxy is the content
   5698  *      of a form.
   5699  */
   5700 SYNCTEX_INLINE static synctex_ns_s __synctex_replace_ref(synctex_node_p ref) {
   5701     synctex_ns_s ns = {NULL,SYNCTEX_STATUS_OK};
   5702     synctex_node_p parent;
   5703     if ((parent = _synctex_tree_parent(ref))) {
   5704         synctex_node_p sibling = __synctex_tree_reset_sibling(ref);
   5705         synctex_node_p arg_sibling = synctex_node_arg_sibling(ref);
   5706         /*  arg_sibling != NULL because the child of a box
   5707          *  is always a box boundary, not a ref. */
   5708         synctex_node_p target = synctex_form_content(ref->class_->scanner, _synctex_data_tag(ref));
   5709         /*  The target is a single node (box)
   5710          *  with children and no siblings. */
   5711         if ((ns.node = __synctex_new_proxy_from_ref_to(ref, target))) {
   5712             /*  Insert this proxy instead of ref. */
   5713             _synctex_node_set_sibling(arg_sibling,ns.node);
   5714             /*  Then append the original sibling of ref. */
   5715             _synctex_node_set_sibling(ns.node,sibling);
   5716 #   if defined(SYNCTEX_USE_CHARINDEX)
   5717             if (synctex_node_type(sibling) == synctex_node_type_box_bdry) {
   5718                 /*  The sibling is the last box boundary
   5719                  *  which may have a less accurate information */
   5720                 sibling->char_index = arg_sibling->char_index;
   5721                 sibling->line_index = arg_sibling->line_index;
   5722             }
   5723 #endif
   5724 #if SYNCTEX_DEBUG>500
   5725             printf("!  Ref replacement:\n");
   5726             synctex_node_log(ref);
   5727             synctex_node_display(synctex_node_sibling(ref));
   5728 #endif
   5729         } else /*  simply remove ref */ {
   5730             _synctex_tree_set_sibling(arg_sibling,sibling);
   5731         }
   5732         __synctex_tree_reset_parent(ref);
   5733     } else {
   5734         _synctex_error("!  Missing parent in __synctex_replace_ref. "
   5735                        "Please report.");
   5736         ns.status = SYNCTEX_STATUS_BAD_ARGUMENT;
   5737     }
   5738     return ns;
   5739 }
   5740 /**
   5741  *  - argument ref: is the starting point of a linked list
   5742  *      of refs. The link is made through the friend field.
   5743  *  - returns: the status and the list of all the proxies
   5744  *      created. The link is made through the friend field.
   5745  *  - note: All refs are freed
   5746  */
   5747 SYNCTEX_INLINE static synctex_ns_s _synctex_post_process_ref(synctex_node_p ref) {
   5748     synctex_ns_s ns = {NULL, SYNCTEX_STATUS_OK};
   5749     while (ref) {
   5750         synctex_node_p next_ref = _synctex_tree_reset_friend(ref);
   5751         synctex_ns_s sub_ns = __synctex_replace_ref(ref);
   5752         if (sub_ns.status < ns.status) {
   5753             ns.status = sub_ns.status;
   5754         } else {
   5755             /*  Insert all the created proxies in the list
   5756              *  sub_ns.node is the last friend,
   5757              */
   5758             synctex_tree_set_friend(sub_ns.node,ns.node);
   5759             ns.node = sub_ns.node;
   5760         }
   5761         synctex_node_free(ref);
   5762         ref = next_ref;
   5763     }
   5764     return ns;
   5765 }
   5766 typedef synctex_node_p (* synctex_processor_f)(synctex_node_p node);
   5767 /**
   5768  *  Apply the processor f to the tree hierarchy rooted at proxy.
   5769  *  proxy has replaced a form ref, no children yet.
   5770  *  As a side effect all the hierarchy of nodes will be created.
   5771  */
   5772 SYNCTEX_INLINE static synctex_status_t _synctex_post_process_proxy(synctex_node_p proxy, synctex_processor_f f) {
   5773     while(proxy) {
   5774         synctex_node_p next_proxy = _synctex_tree_friend(proxy);
   5775         synctex_node_p halt = __synctex_tree_sibling(proxy);
   5776         /*  if proxy is the last sibling, halt is NULL.
   5777          *  Find what should be a next node,
   5778          *  without creating new nodes. */
   5779         if (!halt) {
   5780             synctex_node_p parent = _synctex_tree_parent(proxy);
   5781             halt = __synctex_tree_sibling(parent);
   5782             while (!halt && parent) {
   5783                 parent = _synctex_tree_parent(parent);
   5784                 halt = __synctex_tree_sibling(parent);
   5785             }
   5786         }
   5787         do {
   5788 #if SYNCTEX_DEBUG>500
   5789             printf("POST PROCESSING %s\n",_synctex_node_abstract(proxy));
   5790             {
   5791                 int i,j = 0;
   5792                 for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
   5793                     synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
   5794                     do {
   5795                         if (N==proxy) {
   5796                             ++j;
   5797                             printf("%s",_synctex_node_abstract(N));
   5798                         }
   5799                     } while ((N = _synctex_tree_friend(N)));
   5800                 }
   5801                 if (j) {
   5802                     printf("\nBeforehand %i match\n",j);
   5803                 }
   5804             }
   5805 #endif
   5806             f(proxy);
   5807 #if SYNCTEX_DEBUG>500
   5808             {
   5809                 int i,j = 0;
   5810                 for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
   5811                     synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
   5812                     do {
   5813                         if (N==proxy) {
   5814                             ++j;
   5815                             printf("%s",_synctex_node_abstract(N));
   5816                         }
   5817                     } while ((N = _synctex_tree_friend(N)));
   5818                 }
   5819                 if (j) {
   5820                     printf("\n%i match\n",j);
   5821                 }
   5822             }
   5823 #endif
   5824             /*  Side effect: create the hierarchy on the fly */
   5825             proxy = synctex_node_next(proxy); /*  Change is here */
   5826 #if SYNCTEX_DEBUG>500
   5827             if (proxy) {
   5828                 int i,j = 0;
   5829                 for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
   5830                     synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
   5831                     do {
   5832                         if (N==proxy) {
   5833                             ++j;
   5834                             printf("%s",_synctex_node_abstract(N));
   5835                         }
   5836                     } while ((N = _synctex_tree_friend(N)));
   5837                 }
   5838                 if (j) {
   5839                     printf("\nnext %i match\n",j);
   5840                 }
   5841             }
   5842 #endif
   5843         } while (proxy && proxy != halt);
   5844         proxy = next_proxy;
   5845     }
   5846     return SYNCTEX_STATUS_OK;
   5847 }
   5848 /**
   5849  *  Replace all the form refs by root box proxies.
   5850  *  Create the node hierarchy and update the friends.
   5851  *  On entry, the refs are collected as a friend list
   5852  *  in either a form or a sheet
   5853  *  - parameter: the owning scanner
   5854  */
   5855 SYNCTEX_INLINE static synctex_status_t _synctex_post_process(synctex_scanner_p scanner) {
   5856     synctex_status_t status = SYNCTEX_STATUS_OK;
   5857     synctex_ns_s ns = {NULL,SYNCTEX_STATUS_NOT_OK};
   5858 #if SYNCTEX_DEBUG>500
   5859     printf("!  entering _synctex_post_process.\n");
   5860     synctex_node_display(scanner->sheet);
   5861     synctex_node_display(scanner->form);
   5862 #endif
   5863     /*  replace form refs inside forms by box proxies */
   5864     ns = _synctex_post_process_ref(scanner->ref_in_form);
   5865     scanner->ref_in_form = NULL;/*  it was just released */
   5866     if (ns.status<status) {
   5867         status = ns.status;
   5868     }
   5869 #if SYNCTEX_DEBUG>500
   5870     printf("!  ref replaced in form _synctex_post_process.\n");
   5871     synctex_node_display(scanner->form);
   5872 #endif
   5873     /*  Create all the form proxy nodes on the fly.
   5874      *  ns.node is the root of the list of
   5875      *  newly created proxies.
   5876      *  There might be a problem with cascading proxies.
   5877      *  In order to be properly managed, the data must
   5878      *  be organized in the right way.
   5879      *  The inserted form must be defined before
   5880      *  the inserting one. *TeX will take care of that.   */
   5881     ns.status = _synctex_post_process_proxy(ns.node,&_synctex_tree_reset_friend);
   5882     if (ns.status<status) {
   5883         status = ns.status;
   5884     }
   5885     /*  replace form refs inside sheets by box proxies */
   5886     ns = _synctex_post_process_ref(scanner->ref_in_sheet);
   5887     if (ns.status<status) {
   5888         status = ns.status;
   5889     }
   5890     scanner->ref_in_sheet = NULL;
   5891 #if SYNCTEX_DEBUG>500
   5892     printf("!  ref replaced in sheet _synctex_post_process.\n");
   5893     synctex_node_display(scanner->sheet);
   5894 #endif
   5895 #if 0
   5896     {
   5897         int i;
   5898         for (i=0;i<scanner->number_of_lists;++i) {
   5899             synctex_node_p P = ns.node;
   5900             do {
   5901                 synctex_node_p N = scanner->lists_of_friends[i];
   5902                 do {
   5903                     if (P == N) {
   5904                         printf("Already registered.\n");
   5905                         synctex_node_display(N);
   5906                         break;
   5907                     }
   5908                 } while ((N = _synctex_tree_friend(N)));
   5909             } while((P = _synctex_tree_friend(P)));
   5910         }
   5911     }
   5912 #endif
   5913 #if SYNCTEX_DEBUG>10000
   5914     {
   5915         int i;
   5916         for (i=0;i<scanner->number_of_lists;++i) {
   5917             synctex_node_p P = scanner->lists_of_friends[i];
   5918             int j = 0;
   5919             while (P) {
   5920                 ++j;
   5921                 synctex_node_log(P);
   5922                 P = _synctex_tree_friend(P);
   5923             }
   5924             if (j) {
   5925                 printf("friends %i -> # %i\n",i,j);
   5926             }
   5927         }
   5928     }
   5929 #endif
   5930     ns.status = _synctex_post_process_proxy(ns.node,&__synctex_proxy_make_friend_and_next_hbox);
   5931     if (ns.status<status) {
   5932         status = ns.status;
   5933     }
   5934 #if SYNCTEX_DEBUG>500
   5935     printf("!  exiting _synctex_post_process.\n");
   5936     synctex_node_display(scanner->sheet);
   5937     synctex_node_display(scanner->form);
   5938     printf("!  display all.\n");
   5939     synctex_node_display(scanner->sheet);
   5940     synctex_node_display(scanner->form);
   5941 #endif
   5942     return status;
   5943 }
   5944 /*  Used when parsing the synctex file
   5945  */
   5946 static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner) {
   5947     scanner->reader->lastv = -1;
   5948     synctex_status_t status = 0;
   5949     if (NULL == scanner) {
   5950         return SYNCTEX_STATUS_BAD_ARGUMENT;
   5951     }
   5952     /*  Find where this section starts */
   5953 content_not_found:
   5954     status = _synctex_match_string(scanner,"Content:");
   5955     if (status<SYNCTEX_STATUS_EOF) {
   5956         return status;
   5957     }
   5958     if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
   5959         _synctex_error("Incomplete Content.");
   5960         return SYNCTEX_STATUS_ERROR;
   5961     }
   5962     if (status == SYNCTEX_STATUS_NOT_OK) {
   5963         goto content_not_found;
   5964     }
   5965     status = __synctex_parse_sfi(scanner);
   5966     if (status == SYNCTEX_STATUS_OK) {
   5967         status = _synctex_post_process(scanner);
   5968     }
   5969     return status;
   5970 }
   5971 synctex_scanner_p synctex_scanner_new() {
   5972     synctex_scanner_p scanner =(synctex_scanner_p)_synctex_malloc(sizeof(synctex_scanner_s));
   5973     if (scanner) {
   5974         if (!(scanner->reader = _synctex_malloc(sizeof(synctex_reader_s)))) {
   5975             _synctex_free(scanner);
   5976             return NULL;
   5977         }
   5978 #	ifdef SYNCTEX_NOTHING
   5979 #       pragma mark -
   5980 #   endif
   5981 #   define DEFINE_synctex_scanner_class(NAME)\
   5982     scanner->class_[synctex_node_type_##NAME] = synctex_class_##NAME;\
   5983 (scanner->class_[synctex_node_type_##NAME]).scanner = scanner
   5984         DEFINE_synctex_scanner_class(input);
   5985         DEFINE_synctex_scanner_class(sheet);
   5986         DEFINE_synctex_scanner_class(form);
   5987         DEFINE_synctex_scanner_class(hbox);
   5988         DEFINE_synctex_scanner_class(void_hbox);
   5989         DEFINE_synctex_scanner_class(vbox);
   5990         DEFINE_synctex_scanner_class(void_vbox);
   5991         DEFINE_synctex_scanner_class(kern);
   5992         DEFINE_synctex_scanner_class(glue);
   5993         DEFINE_synctex_scanner_class(rule);
   5994         DEFINE_synctex_scanner_class(math);
   5995         DEFINE_synctex_scanner_class(boundary);
   5996         DEFINE_synctex_scanner_class(box_bdry);
   5997         DEFINE_synctex_scanner_class(ref);
   5998         DEFINE_synctex_scanner_class(proxy_hbox);
   5999         DEFINE_synctex_scanner_class(proxy_vbox);
   6000         DEFINE_synctex_scanner_class(proxy);
   6001         DEFINE_synctex_scanner_class(proxy_last);
   6002         DEFINE_synctex_scanner_class(handle);
   6003         /*  set up the lists of friends */
   6004         scanner->number_of_lists = 1024;
   6005         scanner->lists_of_friends = (synctex_node_r)_synctex_malloc(scanner->number_of_lists*sizeof(synctex_node_p));
   6006         if (NULL == scanner->lists_of_friends) {
   6007             synctex_scanner_free(scanner);
   6008             _synctex_error("malloc:2");
   6009             return NULL;
   6010         }
   6011         scanner->display_switcher = 100;
   6012         scanner->display_prompt = (char *)_synctex_display_prompt+strlen(_synctex_display_prompt)-1;
   6013     }
   6014     return scanner;
   6015 }
   6016 /*  Where the synctex scanner is created. */
   6017 synctex_scanner_p synctex_scanner_new_with_output_file(const char * output, const char * build_directory, int parse) {
   6018     synctex_scanner_p scanner = synctex_scanner_new();
   6019     if (NULL == scanner) {
   6020         _synctex_error("malloc problem");
   6021         return NULL;
   6022     }
   6023     if ((scanner->reader = synctex_reader_init_with_output_file(scanner->reader, output, build_directory))) {
   6024         return parse? synctex_scanner_parse(scanner):scanner;
   6025     }
   6026     _synctex_error("No file?");
   6027     return NULL;
   6028 }
   6029 
   6030 /*  The scanner destructor
   6031  */
   6032 int synctex_scanner_free(synctex_scanner_p scanner) {
   6033     int node_count = 0;
   6034     if (scanner) {
   6035         if (SYNCTEX_FILE) {
   6036             gzclose(SYNCTEX_FILE);
   6037             SYNCTEX_FILE = NULL;
   6038         }
   6039         synctex_node_free(scanner->sheet);
   6040         synctex_node_free(scanner->form);
   6041         synctex_node_free(scanner->input);
   6042         synctex_reader_free(scanner->reader);
   6043         SYNCTEX_SCANNER_FREE_HANDLE(scanner);
   6044         synctex_iterator_free(scanner->iterator);
   6045         free(scanner->output_fmt);
   6046         free(scanner->lists_of_friends);
   6047 #if SYNCTEX_USE_NODE_COUNT>0
   6048         node_count = scanner->node_count;
   6049 #endif
   6050         free(scanner);
   6051     }
   6052     return node_count;
   6053 }
   6054 
   6055 /*  Where the synctex scanner parses the contents of the file. */
   6056 synctex_scanner_p synctex_scanner_parse(synctex_scanner_p scanner) {
   6057     synctex_status_t status = 0;
   6058     if (!scanner || scanner->flags.has_parsed) {
   6059         return scanner;
   6060     }
   6061     scanner->flags.has_parsed=1;
   6062     scanner->pre_magnification = 1000;
   6063     scanner->pre_unit = 8192;
   6064     scanner->pre_x_offset = scanner->pre_y_offset = 578;
   6065     /*  initialize the offset with a fake unprobable value,
   6066      *  If there is a post scriptum section, this value will be overridden by the real life value */
   6067     scanner->x_offset = scanner->y_offset = 6.027e23f;
   6068     scanner->reader->line_number = 1;
   6069     
   6070     SYNCTEX_START = (char *)malloc(SYNCTEX_BUFFER_SIZE+1); /*  one more character for null termination */
   6071     if (NULL == SYNCTEX_START) {
   6072         _synctex_error("!  malloc error in synctex_scanner_parse.");
   6073     bailey:
   6074 #ifdef SYNCTEX_DEBUG
   6075         return scanner;
   6076 #else
   6077         synctex_scanner_free(scanner);
   6078         return NULL;
   6079 #endif
   6080     }
   6081     synctex_scanner_set_display_switcher(scanner, 1000);
   6082     SYNCTEX_END = SYNCTEX_START+SYNCTEX_BUFFER_SIZE;
   6083     /*  SYNCTEX_END always points to a null terminating character.
   6084      *  Maybe there is another null terminating character between SYNCTEX_CUR and SYNCTEX_END-1.
   6085      *  At least, we are sure that SYNCTEX_CUR points to a string covering a valid part of the memory. */
   6086     *SYNCTEX_END = '\0';
   6087     SYNCTEX_CUR = SYNCTEX_END;
   6088 #   if defined(SYNCTEX_USE_CHARINDEX)
   6089     scanner->reader->charindex_offset = -SYNCTEX_BUFFER_SIZE;
   6090 #   endif
   6091     status = _synctex_scan_preamble(scanner);
   6092     if (status<SYNCTEX_STATUS_OK) {
   6093         _synctex_error("Bad preamble\n");
   6094         goto bailey;
   6095     }
   6096     status = _synctex_scan_content(scanner);
   6097     if (status<SYNCTEX_STATUS_OK) {
   6098         _synctex_error("Bad content\n");
   6099         goto bailey;
   6100     }
   6101     status = _synctex_scan_postamble(scanner);
   6102     if (status<SYNCTEX_STATUS_OK) {
   6103         _synctex_error("Bad postamble. Ignored\n");
   6104     }
   6105 #if SYNCTEX_DEBUG>500
   6106     synctex_scanner_set_display_switcher(scanner, 100);
   6107     synctex_node_display(scanner->sheet);
   6108     synctex_node_display(scanner->form);
   6109 #endif
   6110     synctex_scanner_set_display_switcher(scanner, 1000);
   6111     /*  Everything is finished, free the buffer, close the file */
   6112     free((void *)SYNCTEX_START);
   6113     SYNCTEX_START = SYNCTEX_CUR = SYNCTEX_END = NULL;
   6114     gzclose(SYNCTEX_FILE);
   6115     SYNCTEX_FILE = NULL;
   6116     /*  Final tuning: set the default values for various parameters */
   6117     /*  1 pre_unit = (scanner->pre_unit)/65536 pt = (scanner->pre_unit)/65781.76 bp
   6118      * 1 pt = 65536 sp */
   6119     if (scanner->pre_unit<=0) {
   6120         scanner->pre_unit = 8192;
   6121     }
   6122     if (scanner->pre_magnification<=0) {
   6123         scanner->pre_magnification = 1000;
   6124     }
   6125     if (scanner->unit <= 0) {
   6126         /*  no post magnification */
   6127         scanner->unit = scanner->pre_unit / 65781.76;/*  65781.76 or 65536.0*/
   6128     } else {
   6129         /*  post magnification */
   6130         scanner->unit *= scanner->pre_unit / 65781.76;
   6131     }
   6132     scanner->unit *= scanner->pre_magnification / 1000.0;
   6133     if (scanner->x_offset > 6e23) {
   6134         /*  no post offset */
   6135         scanner->x_offset = scanner->pre_x_offset * (scanner->pre_unit / 65781.76);
   6136         scanner->y_offset = scanner->pre_y_offset * (scanner->pre_unit / 65781.76);
   6137     } else {
   6138         /*  post offset */
   6139         scanner->x_offset /= 65781.76f;
   6140         scanner->y_offset /= 65781.76f;
   6141     }
   6142     return scanner;
   6143 #undef SYNCTEX_FILE
   6144 }
   6145 
   6146 /*  Scanner accessors.
   6147  */
   6148 int synctex_scanner_pre_x_offset(synctex_scanner_p scanner){
   6149     return scanner?scanner->pre_x_offset:0;
   6150 }
   6151 int synctex_scanner_pre_y_offset(synctex_scanner_p scanner){
   6152     return scanner?scanner->pre_y_offset:0;
   6153 }
   6154 int synctex_scanner_x_offset(synctex_scanner_p scanner){
   6155     return scanner?scanner->x_offset:0;
   6156 }
   6157 int synctex_scanner_y_offset(synctex_scanner_p scanner){
   6158     return scanner?scanner->y_offset:0;
   6159 }
   6160 float synctex_scanner_magnification(synctex_scanner_p scanner){
   6161     return scanner?scanner->unit:1;
   6162 }
   6163 void synctex_scanner_display(synctex_scanner_p scanner) {
   6164     if (NULL == scanner) {
   6165         return;
   6166     }
   6167     printf("The scanner:\noutput:%s\noutput_fmt:%s\nversion:%i\n",scanner->reader->output,scanner->output_fmt,scanner->version);
   6168     printf("pre_unit:%i\nx_offset:%i\ny_offset:%i\n",scanner->pre_unit,scanner->pre_x_offset,scanner->pre_y_offset);
   6169     printf("count:%i\npost_magnification:%f\npost_x_offset:%f\npost_y_offset:%f\n",
   6170            scanner->count,scanner->unit,scanner->x_offset,scanner->y_offset);
   6171     printf("The input:\n");
   6172     synctex_node_display(scanner->input);
   6173     if (scanner->count<1000) {
   6174         printf("The sheets:\n");
   6175         synctex_node_display(scanner->sheet);
   6176         printf("The friends:\n");
   6177         if (scanner->lists_of_friends) {
   6178             int i = scanner->number_of_lists;
   6179             synctex_node_p node;
   6180             while(i--) {
   6181                 printf("Friend index:%i\n",i);
   6182                 node = (scanner->lists_of_friends)[i];
   6183                 while(node) {
   6184                     printf("%s:%i,%i\n",
   6185                            synctex_node_isa(node),
   6186                            _synctex_data_tag(node),
   6187                            _synctex_data_line(node)
   6188                            );
   6189                     node = _synctex_tree_friend(node);
   6190                 }
   6191             }
   6192         }
   6193     } else {
   6194         printf("SyncTeX Warning: Too many objects\n");
   6195     }
   6196 }
   6197 /*  Public */
   6198 const char * synctex_scanner_get_name(synctex_scanner_p scanner,int tag) {
   6199     synctex_node_p input = NULL;
   6200     if (NULL == scanner) {
   6201         return NULL;
   6202     }
   6203     if ((input = scanner->input)) {;
   6204         do {
   6205             if (tag == _synctex_data_tag(input)) {
   6206                 return (_synctex_data_name(input));
   6207             }
   6208         } while((input = __synctex_tree_sibling(input)));
   6209     }
   6210     return NULL;
   6211 }
   6212 const char * synctex_node_get_name(synctex_node_p node) {
   6213     if (node) {
   6214         return synctex_scanner_get_name(node->class_->scanner,_synctex_data_tag(node));
   6215     }
   6216     return NULL;
   6217 }
   6218 
   6219 static int _synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name);
   6220 static int _synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name) {
   6221     synctex_node_p input = NULL;
   6222     if (NULL == scanner) {
   6223         return 0;
   6224     }
   6225     if ((input = scanner->input)) {
   6226         do {
   6227             if (_synctex_is_equivalent_file_name(name,(_synctex_data_name(input)))) {
   6228                 return _synctex_data_tag(input);
   6229             }
   6230         } while((input = __synctex_tree_sibling(input)));
   6231     }
   6232     //  2011 version
   6233     name = _synctex_base_name(name);
   6234     if ((input = scanner->input)) {
   6235         do {
   6236             if (_synctex_is_equivalent_file_name(name,_synctex_base_name(_synctex_data_name(input)))) {
   6237                 synctex_node_p other_input = input;
   6238                 while((other_input = __synctex_tree_sibling(other_input))) {
   6239                     if (_synctex_is_equivalent_file_name(name,_synctex_base_name(_synctex_data_name(other_input)))
   6240                         && (strlen(_synctex_data_name(input))!=strlen(_synctex_data_name(other_input))
   6241                             || strncmp(_synctex_data_name(other_input),_synctex_data_name(input),strlen(_synctex_data_name(input))))) {
   6242                             // There is a second possible candidate
   6243                             return 0;
   6244                         }
   6245                 }
   6246                 return _synctex_data_tag(input);
   6247             }
   6248         } while((input = __synctex_tree_sibling(input)));
   6249     }
   6250     return 0;
   6251 }
   6252 
   6253 int synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name) {
   6254     size_t char_index = strlen(name);
   6255     if ((scanner = synctex_scanner_parse(scanner)) && (0 < char_index)) {
   6256         /*  the name is not void */
   6257         char_index -= 1;
   6258         if (!SYNCTEX_IS_PATH_SEPARATOR(name[char_index])) {
   6259             /*  the last character of name is not a path separator */
   6260             int result = _synctex_scanner_get_tag(scanner,name);
   6261             if (result) {
   6262                 return result;
   6263             } else {
   6264                 /*  the given name was not the one known by TeX
   6265                  *  try a name relative to the enclosing directory of the scanner->output file */
   6266                 const char * relative = name;
   6267                 const char * ptr = scanner->reader->output;
   6268                 while((strlen(relative) > 0) && (strlen(ptr) > 0) && (*relative == *ptr))
   6269                 {
   6270                     relative += 1;
   6271                     ptr += 1;
   6272                 }
   6273                 /*  Find the last path separator before relative */
   6274                 while(relative > name) {
   6275                     if (SYNCTEX_IS_PATH_SEPARATOR(*(relative-1))) {
   6276                         break;
   6277                     }
   6278                     relative -= 1;
   6279                 }
   6280                 if ((relative > name) && (result = _synctex_scanner_get_tag(scanner,relative))) {
   6281                     return result;
   6282                 }
   6283                 if (SYNCTEX_IS_PATH_SEPARATOR(name[0])) {
   6284                     /*  No tag found for the given absolute name,
   6285                      *  Try each relative path starting from the shortest one */
   6286                     while(0<char_index) {
   6287                         char_index -= 1;
   6288                         if (SYNCTEX_IS_PATH_SEPARATOR(name[char_index])
   6289                             && (result = _synctex_scanner_get_tag(scanner,name+char_index+1))) {
   6290                             return result;
   6291                         }
   6292                     }
   6293                 }
   6294             }
   6295             return result;
   6296         }
   6297     }
   6298     return 0;
   6299 }
   6300 synctex_node_p synctex_scanner_input(synctex_scanner_p scanner) {
   6301     return scanner?scanner->input:NULL;
   6302 }
   6303 synctex_node_p synctex_scanner_input_with_tag(synctex_scanner_p scanner, int tag) {
   6304     synctex_node_p input = scanner?scanner->input:NULL;
   6305     while (_synctex_data_tag(input)!=tag) {
   6306         if ((input = __synctex_tree_sibling(input))) {
   6307             continue;
   6308         }
   6309         break;
   6310     }
   6311     return input;
   6312 }
   6313 const char * synctex_scanner_get_output_fmt(synctex_scanner_p scanner) {
   6314     return NULL != scanner && scanner->output_fmt?scanner->output_fmt:"";
   6315 }
   6316 const char * synctex_scanner_get_output(synctex_scanner_p scanner) {
   6317     return NULL != scanner && scanner->reader->output?scanner->reader->output:"";
   6318 }
   6319 const char * synctex_scanner_get_synctex(synctex_scanner_p scanner) {
   6320     return NULL != scanner && scanner->reader->synctex?scanner->reader->synctex:"";
   6321 }
   6322 #	ifdef SYNCTEX_NOTHING
   6323 #       pragma mark -
   6324 #       pragma mark Public node attributes
   6325 #   endif
   6326 
   6327 #   define SYNCTEX_DEFINE_NODE_HVWHD(WHAT) \
   6328 int synctex_node_##WHAT(synctex_node_p node) { \
   6329     return (node && node->class_->inspector->WHAT)? \
   6330         node->class_->inspector->WHAT(node): 0; \
   6331 }
   6332 #   define SYNCTEX_DEFINE_PROXY_HV(WHAT) \
   6333 static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) { \
   6334     synctex_node_p target = _synctex_tree_target(proxy); \
   6335     if (target) { \
   6336         return _synctex_data_##WHAT(proxy)+synctex_node_##WHAT(target); \
   6337     } else { \
   6338         return proxy? _synctex_data_##WHAT(proxy): 0; \
   6339     } \
   6340 }
   6341 #define SYNCTEX_DEFINE_PROXY_TLCWVD(WHAT) \
   6342 static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) { \
   6343     synctex_node_p target = _synctex_tree_target(proxy); \
   6344     return target? synctex_node_##WHAT(target): 0; \
   6345 }
   6346 
   6347 /**
   6348  *  The horizontal location of the node.
   6349  *  Idem for v, width, height and depth.
   6350  *  - parameter node: a node with geometrical information.
   6351  *  - returns: an integer.
   6352  *  - requires: every proxy node has a target.
   6353  *  - note: recursive call if the parameter has a proxy.
   6354  *  - author: JL
   6355  */
   6356 SYNCTEX_DEFINE_NODE_HVWHD(h)
   6357 SYNCTEX_DEFINE_NODE_HVWHD(v)
   6358 SYNCTEX_DEFINE_NODE_HVWHD(width)
   6359 SYNCTEX_DEFINE_NODE_HVWHD(height)
   6360 SYNCTEX_DEFINE_NODE_HVWHD(depth)
   6361 SYNCTEX_DEFINE_PROXY_TLCWVD(tag)
   6362 SYNCTEX_DEFINE_PROXY_TLCWVD(line)
   6363 SYNCTEX_DEFINE_PROXY_TLCWVD(column)
   6364 SYNCTEX_DEFINE_PROXY_HV(h)
   6365 SYNCTEX_DEFINE_PROXY_HV(v)
   6366 SYNCTEX_DEFINE_PROXY_TLCWVD(width)
   6367 SYNCTEX_DEFINE_PROXY_TLCWVD(height)
   6368 SYNCTEX_DEFINE_PROXY_TLCWVD(depth)
   6369 
   6370 /**
   6371  *  Whether the argument is a box,
   6372  *  either vertical or horizontal,
   6373  *  either void or not,
   6374  *  or a proxy to such a box.
   6375  *  - parameter NODE: of type synctex_node_p
   6376  *  - returns: yorn
   6377  */
   6378 
   6379 SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_box(synctex_node_p node) {
   6380     return node &&
   6381     (node->class_->type == synctex_node_type_hbox
   6382      || node->class_->type == synctex_node_type_void_hbox
   6383      || node->class_->type == synctex_node_type_vbox
   6384      || node->class_->type == synctex_node_type_void_vbox
   6385      || _synctex_node_is_box(_synctex_tree_target(node)));
   6386 }
   6387 
   6388 /**
   6389  *  Whether the argument is a handle.
   6390  *  Handles are similar to proxies because they have a target.
   6391  *  They are used for query results.
   6392  *  - parameter NODE: of type synctex_node_p
   6393  *  - returns: yorn
   6394  */
   6395 
   6396 SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_handle(synctex_node_p node) {
   6397     return node &&
   6398     (node->class_->type == synctex_node_type_handle);
   6399 }
   6400 
   6401 /**
   6402  *  Resolves handle indirection.
   6403  *  - parameter node: of type synctex_node_p
   6404  *  - returns: node if it is not a handle,
   6405  *  its target otherwise.
   6406  */
   6407 
   6408 SYNCTEX_INLINE static synctex_node_p _synctex_node_or_handle_target(synctex_node_p node) {
   6409     return _synctex_node_is_handle(node)?
   6410     _synctex_tree_target(node):node;
   6411 }
   6412 
   6413 /**
   6414  *  Whether the argument is an hbox.
   6415  *  - parameter NODE: of type synctex_node_p
   6416  *  - returns: yorn
   6417  */
   6418 
   6419 SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_hbox(synctex_node_p node) {
   6420     return node &&
   6421     (node->class_->type == synctex_node_type_hbox
   6422      || node->class_->type == synctex_node_type_void_hbox
   6423      || _synctex_node_is_hbox(_synctex_tree_target(node)));
   6424 }
   6425 
   6426 /**
   6427  *  The horizontal location of the first box enclosing node.
   6428  *  - parameter node: a node with geometrical information.
   6429  *  - returns: an integer.
   6430  *  - author: JL
   6431  */
   6432 int synctex_node_box_h(synctex_node_p node) {
   6433     if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
   6434         return synctex_node_h(node);
   6435     }
   6436     return 0;
   6437 }
   6438 /**
   6439  *  The vertical location of the first box enclosing node.
   6440  *  - parameter node: a node with geometrical information.
   6441  *  - returns: an integer.
   6442  *  - author: JL
   6443  */
   6444 int synctex_node_box_v(synctex_node_p node) {
   6445     if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
   6446         return synctex_node_v(node);
   6447     }
   6448     return 0;
   6449 }
   6450 /**
   6451  *  The width of the first box enclosing node.
   6452  *  - parameter node: a node with geometrical information.
   6453  *  - returns: an integer.
   6454  *  - author: JL
   6455  */
   6456 int synctex_node_box_width(synctex_node_p node) {
   6457     if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
   6458         return synctex_node_width(node);
   6459     }
   6460     return 0;
   6461 }
   6462 /**
   6463  *  The height of the first box enclosing node.
   6464  *  - parameter node: a node with geometrical information.
   6465  *  - returns: an integer.
   6466  *  - author: JL
   6467  */
   6468 int synctex_node_box_height(synctex_node_p node) {
   6469     if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
   6470         return synctex_node_height(node);
   6471     }
   6472     return 0;
   6473 }
   6474 /**
   6475  *  The depth of the first box enclosing node.
   6476  *  - parameter node: a node with geometrical information.
   6477  *  - returns: an integer.
   6478  *  - author: JL
   6479  */
   6480 int synctex_node_box_depth(synctex_node_p node) {
   6481     if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
   6482         return synctex_node_depth(node);
   6483     }
   6484     return 0;
   6485 }
   6486 /**
   6487  *  The horizontal location of an hbox, corrected with contents.
   6488  *  - parameter node: an hbox node.
   6489  *  - returns: an integer, 0 if node is not an hbox or an hbox proxy.
   6490  *  - note: recursive call when node is an hbox proxy.
   6491  *  - author: JL
   6492  */
   6493 int synctex_node_hbox_h(synctex_node_p node) {
   6494     switch(synctex_node_type(node)) {
   6495         case synctex_node_type_hbox:
   6496             return _synctex_data_h_V(node);
   6497         case synctex_node_type_proxy_hbox:
   6498             return _synctex_data_h(node)+synctex_node_hbox_h(_synctex_tree_target(node));
   6499         default:
   6500             return 0;
   6501     }
   6502 }
   6503 /**
   6504  *  The vertical location of an hbox, corrected with contents.
   6505  *  - parameter node: an hbox node.
   6506  *  - returns: an integer, 0 if node is not an hbox or an hbox proxy.
   6507  *  - note: recursive call when node is an hbox proxy.
   6508  *  - author: JL
   6509  */
   6510 int synctex_node_hbox_v(synctex_node_p node) {
   6511     switch(synctex_node_type(node)) {
   6512         case synctex_node_type_hbox:
   6513             return _synctex_data_v_V(node);
   6514         case synctex_node_type_proxy_hbox:
   6515             return _synctex_data_v(node)+synctex_node_hbox_v(_synctex_tree_target(node));
   6516         default:
   6517             return 0;
   6518     }
   6519 }
   6520 /**
   6521  *  The width of an hbox, corrected with contents.
   6522  *  - parameter node: an hbox node, 0 if node is not an hbox or an hbox proxy.
   6523  *  - returns: an integer.
   6524  *  - author: JL
   6525  */
   6526 int synctex_node_hbox_width(synctex_node_p node) {
   6527     synctex_node_p target = _synctex_tree_target(node);
   6528     if (target) {
   6529         node = target;
   6530     }
   6531     return synctex_node_type(node) == synctex_node_type_hbox?
   6532     _synctex_data_width_V(node): 0;
   6533 }
   6534 /**
   6535  *  The height of an hbox, corrected with contents.
   6536  *  - parameter node: an hbox node.
   6537  *  - returns: an integer, 0 if node is not an hbox or an hbox proxy.
   6538  *  - author: JL
   6539  */
   6540 int synctex_node_hbox_height(synctex_node_p node) {
   6541     synctex_node_p target = _synctex_tree_target(node);
   6542     if (target) {
   6543         node = target;
   6544     }
   6545     return synctex_node_type(node) == synctex_node_type_hbox?
   6546     _synctex_data_height_V(node): 0;
   6547 }
   6548 /**
   6549  *  The depth of an hbox, corrected with contents.
   6550  *  - parameter node: an hbox node.
   6551  *  - returns: an integer, 0 if node is not an hbox or an hbox proxy.
   6552  *  - note: recursive call when node is an hbox proxy.
   6553  *  - author: JL
   6554  */
   6555 int synctex_node_hbox_depth(synctex_node_p node) {
   6556     synctex_node_p target = _synctex_tree_target(node);
   6557     if (target) {
   6558         node = target;
   6559     }
   6560     return synctex_node_type(node) == synctex_node_type_hbox?
   6561     _synctex_data_depth_V(node): 0;
   6562 }
   6563 #	ifdef SYNCTEX_NOTHING
   6564 #       pragma mark -
   6565 #       pragma mark Public node visible attributes
   6566 #   endif
   6567 
   6568 #define SYNCTEX_VISIBLE_SIZE(node,s) \
   6569 (s)*node->class_->scanner->unit
   6570 #define SYNCTEX_VISIBLE_DISTANCE_h(node,d) \
   6571 ((d)*node->class_->scanner->unit+node->class_->scanner->x_offset)
   6572 #define SYNCTEX_VISIBLE_DISTANCE_v(node,d) \
   6573 ((d)*node->class_->scanner->unit+node->class_->scanner->y_offset)
   6574 static float __synctex_node_visible_h(synctex_node_p node) {
   6575     return SYNCTEX_VISIBLE_DISTANCE_h(node,synctex_node_h(node));
   6576 }
   6577 static float __synctex_node_visible_v(synctex_node_p node) {
   6578     return SYNCTEX_VISIBLE_DISTANCE_v(node,synctex_node_v(node));
   6579 }
   6580 static float __synctex_node_visible_width(synctex_node_p node) {
   6581     return SYNCTEX_VISIBLE_SIZE(node,synctex_node_width(node));
   6582 }
   6583 static float __synctex_node_visible_height(synctex_node_p node) {
   6584     return SYNCTEX_VISIBLE_SIZE(node,synctex_node_height(node));
   6585 }
   6586 static float __synctex_node_visible_depth(synctex_node_p node) {
   6587     return SYNCTEX_VISIBLE_SIZE(node,synctex_node_depth(node));
   6588 }
   6589 static float __synctex_proxy_visible_h(synctex_node_p node) {
   6590     return SYNCTEX_VISIBLE_DISTANCE_h(node,synctex_node_h(node));
   6591 }
   6592 static float __synctex_proxy_visible_v(synctex_node_p node) {
   6593     return SYNCTEX_VISIBLE_DISTANCE_v(node,synctex_node_v(node));
   6594 }
   6595 static float __synctex_proxy_visible_width(synctex_node_p node) {
   6596     synctex_node_p target = _synctex_tree_target(node);
   6597     return __synctex_node_visible_width(target);
   6598 }
   6599 static float __synctex_proxy_visible_height(synctex_node_p node) {
   6600     synctex_node_p target = _synctex_tree_target(node);
   6601     return __synctex_node_visible_height(target);
   6602 }
   6603 static float __synctex_proxy_visible_depth(synctex_node_p node) {
   6604     synctex_node_p target = _synctex_tree_target(node);
   6605     return __synctex_node_visible_depth(target);
   6606 }
   6607 static float __synctex_kern_visible_h(synctex_noxy_p noxy) {
   6608     int h = _synctex_data_h(noxy);
   6609     int width = _synctex_data_width(noxy);
   6610     return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width>0?h-width:h);
   6611 }
   6612 static float __synctex_kern_visible_width(synctex_noxy_p noxy) {
   6613     int width = _synctex_data_width(noxy);
   6614     return SYNCTEX_VISIBLE_SIZE(noxy, width>0?width:-width);
   6615 }
   6616 static float __synctex_rule_visible_h(synctex_noxy_p noxy) {
   6617     int h = _synctex_data_h(noxy);
   6618     int width = _synctex_data_width(noxy);
   6619     return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width>0?h:h-width);
   6620 }
   6621 static float __synctex_rule_visible_width(synctex_noxy_p noxy) {
   6622     int width = _synctex_data_width(noxy);
   6623     return SYNCTEX_VISIBLE_SIZE(noxy, width>0?width:-width);
   6624 }
   6625 static float __synctex_rule_visible_v(synctex_noxy_p noxy) {
   6626     return __synctex_node_visible_v(noxy);
   6627 }
   6628 static float __synctex_rule_visible_height(synctex_noxy_p noxy) {
   6629     return __synctex_node_visible_height(noxy);
   6630 }
   6631 static float __synctex_rule_visible_depth(synctex_noxy_p noxy) {
   6632     return __synctex_node_visible_depth(noxy);
   6633 }
   6634 
   6635 /**
   6636  *  The horizontal location of node, in page coordinates.
   6637  *  - parameter node: a node.
   6638  *  - returns: a float.
   6639  *  - author: JL
   6640  */
   6641 float synctex_node_visible_h(synctex_node_p node){
   6642     return node? node->class_->vispector->h(node): 0;
   6643 }
   6644 /**
   6645  *  The vertical location of node, in page coordinates.
   6646  *  - parameter node: a node.
   6647  *  - returns: a float.
   6648  *  - author: JL
   6649  */
   6650 float synctex_node_visible_v(synctex_node_p node){
   6651     return node? node->class_->vispector->v(node): 0;
   6652 }
   6653 /**
   6654  *  The width of node, in page coordinates.
   6655  *  - parameter node: a node.
   6656  *  - returns: a float.
   6657  *  - author: JL
   6658  */
   6659 float synctex_node_visible_width(synctex_node_p node){
   6660     return node? node->class_->vispector->width(node): 0;
   6661 }
   6662 /**
   6663  *  The height of node, in page coordinates.
   6664  *  - parameter node: a node.
   6665  *  - returns: a float.
   6666  *  - author: JL
   6667  */
   6668 float synctex_node_visible_height(synctex_node_p node){
   6669     return node? node->class_->vispector->height(node): 0;
   6670 }
   6671 /**
   6672  *  The depth of node, in page coordinates.
   6673  *  - parameter node: a node.
   6674  *  - returns: a float.
   6675  *  - author: JL
   6676  */
   6677 float synctex_node_visible_depth(synctex_node_p node){
   6678     return node? node->class_->vispector->depth(node): 0;
   6679 }
   6680 
   6681 /**
   6682  *  The V variant of geometrical information.
   6683  *  - parameter node: a node.
   6684  *  - returns: an integer.
   6685  *  - author: JL
   6686  */
   6687 #define SYNCTEX_DEFINE_V(WHAT)\
   6688 SYNCTEX_INLINE static int _synctex_node_##WHAT##_V(synctex_node_p node) { \
   6689     synctex_node_p target = _synctex_tree_target(node); \
   6690     if (target) { \
   6691         return _synctex_data_##WHAT(node)+_synctex_node_##WHAT##_V(target); \
   6692     } else if (_synctex_data_has_##WHAT##_V(node)) { \
   6693         return _synctex_data_##WHAT##_V(node); \
   6694     } else { \
   6695         return _synctex_data_##WHAT(node); \
   6696     } \
   6697 }
   6698 SYNCTEX_DEFINE_V(h)
   6699 SYNCTEX_DEFINE_V(v)
   6700 SYNCTEX_DEFINE_V(width)
   6701 SYNCTEX_DEFINE_V(height)
   6702 SYNCTEX_DEFINE_V(depth)
   6703 
   6704 SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node) {
   6705     return (synctex_point_s){synctex_node_h(node),synctex_node_v(node)};
   6706 }
   6707 SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node) {
   6708     return (synctex_point_s){_synctex_node_h_V(node),_synctex_node_v_V(node)};
   6709 }
   6710 SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point) {
   6711     synctex_point_s old = _synctex_data_point(node);
   6712     _synctex_data_set_h(node,point.h);
   6713     _synctex_data_set_v(node,point.v);
   6714     return old;
   6715 }
   6716 SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node) {
   6717     synctex_box_s box = {{0,0},{0,0}};
   6718     int n;
   6719     n = synctex_node_width(node);
   6720     if (n<0) {
   6721         box.max.h = synctex_node_h(node);
   6722         box.min.h = box.max.h + n;
   6723     } else {
   6724         box.min.h = synctex_node_h(node);
   6725         box.max.h = box.min.h + n;
   6726     }
   6727     n = synctex_node_v(node);
   6728     box.min.v = n - synctex_node_height(node);
   6729     box.max.v = n + synctex_node_depth(node);
   6730     return box;
   6731 }
   6732 SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node) {
   6733     synctex_box_s box = {{0,0},{0,0}};
   6734     int n;
   6735     n = synctex_node_width(node);
   6736     if (n>0) {
   6737         box.max.h = synctex_node_h(node);
   6738         box.min.h = box.max.h - n;
   6739     } else {
   6740         box.min.h = synctex_node_h(node);
   6741         box.max.h = box.min.h - n;
   6742     }
   6743     n = synctex_node_v(node);
   6744     box.min.v = n - synctex_node_height(node);
   6745     box.max.v = n + synctex_node_depth(node);
   6746     return box;
   6747 }
   6748 SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node) {
   6749     synctex_box_s box = {{0,0},{0,0}};
   6750     int n;
   6751     n = _synctex_node_width_V(node);
   6752     if (n<0) {
   6753         box.max.h = _synctex_node_h_V(node);
   6754         box.min.h = box.max.h + n;
   6755     } else {
   6756         box.min.h = _synctex_node_h_V(node);
   6757         box.max.h = box.min.h + n;
   6758     }
   6759     n = _synctex_node_v_V(node);
   6760     box.min.v = n - _synctex_node_height_V(node);
   6761     box.max.v = n + _synctex_node_depth_V(node);
   6762     return box;
   6763 }
   6764 
   6765 /**
   6766  *  The higher box node in the parent hierarchy which
   6767  *  mean line number is the one of node ±1.
   6768  *  This enclosing box is computed as follows
   6769  *  1) get the first hbox in the parent linked list
   6770  *  starting at node.
   6771  *  If there is none, simply return the parent of node.
   6772  *  2) compute the mean line number
   6773  *  3) scans up the tree for the higher hbox with
   6774  *  the same mean line number, ±1 eventually
   6775 *  - parameter node: a node.
   6776  *  - returns: a (proxy to a) box node.
   6777  *  - author: JL
   6778  */
   6779 static synctex_node_p _synctex_node_box_visible(synctex_node_p node) {
   6780     if ((node = _synctex_node_or_handle_target(node))) {
   6781         int mean = 0;
   6782         int bound = 1500000/(node->class_->scanner->pre_magnification/1000.0);
   6783         synctex_node_p parent = NULL;
   6784         /*  get the first enclosing parent
   6785          *  then get the highest enclosing parent with the same mean line ±1 */
   6786         node = _synctex_node_or_handle_target(node);
   6787         if (!_synctex_node_is_box(node)) {
   6788             if ((parent = _synctex_tree_parent(node))) {
   6789                 node = parent;
   6790             } else if ((node = _synctex_tree_target(node))) {
   6791                 if (!_synctex_node_is_box(node)) {
   6792                     if ((parent = _synctex_tree_parent(node))) {
   6793                         node = parent;
   6794                     } else {
   6795                         return NULL;
   6796                     }
   6797                 }
   6798             }
   6799         }
   6800         parent = node;
   6801         mean = synctex_node_mean_line(node);
   6802         while ((parent = _synctex_tree_parent(parent))) {
   6803             if (_synctex_node_is_hbox(parent)) {
   6804                 if (_synctex_abs(mean-synctex_node_mean_line(parent))>1) {
   6805                     return node;
   6806                 } else if (synctex_node_width(parent)>bound) {
   6807                     return parent;
   6808                 } else if (synctex_node_height(parent)+synctex_node_depth(parent)>bound) {
   6809                     return parent;
   6810                 }
   6811                 node = parent;
   6812             }
   6813         }
   6814     }
   6815     return node;
   6816 }
   6817 /**
   6818  *  The horizontal location of the first box enclosing node, in page coordinates.
   6819  *  - parameter node: a node.
   6820  *  - returns: a float.
   6821  *  - author: JL
   6822  */
   6823 float synctex_node_box_visible_h(synctex_node_p node) {
   6824     return SYNCTEX_VISIBLE_DISTANCE_h(node,_synctex_node_h_V(_synctex_node_box_visible(node)));
   6825 }
   6826 /**
   6827  *  The vertical location of the first box enclosing node, in page coordinates.
   6828  *  - parameter node: a node.
   6829  *  - returns: a float.
   6830  *  - author: JL
   6831  */
   6832 float synctex_node_box_visible_v(synctex_node_p node) {
   6833     return SYNCTEX_VISIBLE_DISTANCE_v(node,_synctex_node_v_V(_synctex_node_box_visible(node)));
   6834 }
   6835 /**
   6836  *  The width of the first box enclosing node, in page coordinates.
   6837  *  - parameter node: a node.
   6838  *  - returns: a float.
   6839  *  - author: JL
   6840  */
   6841 float synctex_node_box_visible_width(synctex_node_p node) {
   6842     return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_width_V(_synctex_node_box_visible(node)));
   6843 }
   6844 /**
   6845  *  The height of the first box enclosing node, in page coordinates.
   6846  *  - parameter node: a node.
   6847  *  - returns: a float.
   6848  *  - author: JL
   6849  */
   6850 float synctex_node_box_visible_height(synctex_node_p node) {
   6851     return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_height_V(_synctex_node_box_visible(node)));
   6852 }
   6853 /**
   6854  *  The depth of the first box enclosing node, in page coordinates.
   6855  *  - parameter node: a node.
   6856  *  - returns: a float.
   6857  *  - author: JL
   6858  */
   6859 float synctex_node_box_visible_depth(synctex_node_p node) {
   6860     return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_depth_V(_synctex_node_box_visible(node)));
   6861 }
   6862 #	ifdef SYNCTEX_NOTHING
   6863 #       pragma mark -
   6864 #       pragma mark Other public node attributes
   6865 #   endif
   6866 
   6867 /**
   6868  *  The page number of the sheet enclosing node.
   6869  *  - parameter node: a node.
   6870  *  - returns: the page number or -1 if node does not belong to a sheet tree.
   6871  *  - note: a proxy target does not belong to a sheet
   6872  *      but a form, its page number is always -1.
   6873  *  - note: a handles does not belong to a sheet not a form.
   6874  *      its page number is -1.
   6875  *  - author: JL
   6876  */
   6877 int synctex_node_page(synctex_node_p node){
   6878     synctex_node_p parent = NULL;
   6879     while((parent = _synctex_tree_parent(node))) {
   6880         node = parent;
   6881     }
   6882     if (synctex_node_type(node) == synctex_node_type_sheet) {
   6883         return _synctex_data_page(node);
   6884     }
   6885     return -1;
   6886 }
   6887 /**
   6888  *  The page number of the target.
   6889  *  - author: JL
   6890  */
   6891 SYNCTEX_INLINE static int _synctex_node_target_page(synctex_node_p node){
   6892     return synctex_node_page(_synctex_tree_target(node));
   6893 }
   6894 
   6895 #if defined (SYNCTEX_USE_CHARINDEX)
   6896 synctex_charindex_t synctex_node_charindex(synctex_node_p node) {
   6897     synctex_node_p target = _synctex_tree_target(node);
   6898     return target? SYNCTEX_CHARINDEX(target):(node?SYNCTEX_CHARINDEX(node):0);
   6899 }
   6900 #endif
   6901 
   6902 /**
   6903  *  The tag of the node.
   6904  *  - parameter node: a node.
   6905  *  - returns: the tag or -1 if node is NULL.
   6906  *  - author: JL
   6907  */
   6908 int synctex_node_tag(synctex_node_p node) {
   6909     return node? node->class_->tlcpector->tag(node): -1;
   6910 }
   6911 /**
   6912  *  The line of the node.
   6913  *  - parameter node: a node.
   6914  *  - returns: the line or -1 if node is NULL.
   6915  *  - author: JL
   6916  */
   6917 int synctex_node_line(synctex_node_p node) {
   6918     return node? node->class_->tlcpector->line(node): -1;
   6919 }
   6920 /**
   6921  *  The column of the node.
   6922  *  - parameter node: a node.
   6923  *  - returns: the column or -1 if node is NULL.
   6924  *  - author: JL
   6925  */
   6926 int synctex_node_column(synctex_node_p node) {
   6927     return node? node->class_->tlcpector->column(node): -1;
   6928 }
   6929 /**
   6930  *  The mean line number of the node.
   6931  *  - parameter node: a node.
   6932  *  - returns: the mean line or -1 if node is NULL.
   6933  *  - author: JL
   6934  */
   6935 int synctex_node_mean_line(synctex_node_p node) {
   6936     synctex_node_p other = _synctex_tree_target(node);
   6937     if (other) {
   6938         node = other;
   6939     }
   6940     if (_synctex_data_has_mean_line(node)) {
   6941         return _synctex_data_mean_line(node);
   6942     }
   6943     if ((other = synctex_node_parent(node))) {
   6944         if (_synctex_data_has_mean_line(other)) {
   6945             return _synctex_data_mean_line(other);
   6946         }
   6947     }
   6948     return synctex_node_line(node);
   6949 }
   6950 /**
   6951  *  The weight of the node.
   6952  *  - parameter node: a node.
   6953  *  - returns: the weight or -1 if node is NULL.
   6954  *  - author: JL
   6955  */
   6956 int synctex_node_weight(synctex_node_p node) {
   6957     synctex_node_p target = _synctex_tree_target(node);
   6958     if (target) {
   6959         node = target;
   6960     }
   6961     return node?(synctex_node_type(node)==synctex_node_type_hbox?_synctex_data_weight(node):0):-1;
   6962 }
   6963 /**
   6964  *  The number of children of the node.
   6965  *  - parameter node: a node.
   6966  *  - returns: the count or -1 if node is NULL.
   6967  *  - author: JL
   6968  */
   6969 int synctex_node_child_count(synctex_node_p node) {
   6970     synctex_node_p target = _synctex_tree_target(node);
   6971     if (target) {
   6972         node = target;
   6973     }
   6974     return node?(synctex_node_type(node)==synctex_node_type_hbox?_synctex_data_weight(node):0):-1;
   6975 }
   6976 #	ifdef SYNCTEX_NOTHING
   6977 #       pragma mark -
   6978 #       pragma mark Sheet & Form
   6979 #   endif
   6980 
   6981 /**
   6982  *  The sheet of the scanner with a given page number.
   6983  *  - parameter scanner: a scanner.
   6984  *  - parameter page: a 1 based page number.
   6985  *      If page == 0, returns the first sheet.
   6986  *  - returns: a sheet or NULL.
   6987  *  - author: JL
   6988  */
   6989 synctex_node_p synctex_sheet(synctex_scanner_p scanner,int page) {
   6990     if (scanner) {
   6991         synctex_node_p sheet = scanner->sheet;
   6992         while(sheet) {
   6993             if (page == _synctex_data_page(sheet)) {
   6994                 return sheet;
   6995             }
   6996             sheet = __synctex_tree_sibling(sheet);
   6997         }
   6998         if (page == 0) {
   6999             return scanner->sheet;
   7000         }
   7001     }
   7002     return NULL;
   7003 }
   7004 /**
   7005  *  The form of the scanner with a given tag.
   7006  *  - parameter scanner: a scanner.
   7007  *  - parameter tag: an integer identifier.
   7008  *      If tag == 0, returns the first form.
   7009  *  - returns: a form.
   7010  *  - author: JL
   7011  */
   7012 synctex_node_p synctex_form(synctex_scanner_p scanner,int tag) {
   7013     if (scanner) {
   7014         synctex_node_p form = scanner->form;
   7015         while(form) {
   7016             if (tag == _synctex_data_tag(form)) {
   7017                 return form;
   7018             }
   7019             form = __synctex_tree_sibling(form);
   7020         }
   7021         if (tag == 0) {
   7022             return scanner->form;
   7023         }
   7024     }
   7025     return NULL;
   7026 }
   7027 
   7028 /**
   7029  *  The content of the sheet with given page number.
   7030  *  - parameter scanner: a scanner.
   7031  *  - parameter page: a 1 based page number.
   7032  *  - returns: a (vertical) box node.
   7033  *  - author: JL
   7034  */
   7035 synctex_node_p synctex_sheet_content(synctex_scanner_p scanner,int page) {
   7036     if (scanner) {
   7037         return _synctex_tree_child(synctex_sheet(scanner,page));
   7038     }
   7039     return NULL;
   7040 }
   7041 
   7042 /**
   7043  *  The content of the sheet with given page number.
   7044  *  - parameter scanner: a scanner.
   7045  *  - parameter tag: an integer identifier.
   7046  *  - returns: a box node.
   7047  *  - author: JL
   7048  */
   7049 synctex_node_p synctex_form_content(synctex_scanner_p scanner,int tag) {
   7050     if (scanner) {
   7051         return _synctex_tree_child(synctex_form(scanner,tag));
   7052     }
   7053     return NULL;
   7054 }
   7055 
   7056 SYNCTEX_INLINE static synctex_node_p _synctex_scanner_friend(synctex_scanner_p scanner,int i) {
   7057     if (i>=0) {
   7058         i = _synctex_abs(i)%(scanner->number_of_lists);
   7059         return (scanner->lists_of_friends)[i];
   7060     }
   7061     return NULL;
   7062 }
   7063 SYNCTEX_INLINE static synctex_bool_t _synctex_nodes_are_friend(synctex_node_p left, synctex_node_p right) {
   7064     return synctex_node_tag(left) == synctex_node_tag(right) && synctex_node_line(left) == synctex_node_line(right);
   7065 }
   7066 /**
   7067  *  The sibling argument is a parent/child list of nodes of the same page.
   7068  */
   7069 typedef struct {
   7070     int count;
   7071     synctex_node_p node;
   7072 } synctex_counted_node_s;
   7073 
   7074 SYNCTEX_INLINE static synctex_counted_node_s _synctex_vertically_sorted_v2(synctex_node_p sibling) {
   7075     /* Clean the weights of the parents */
   7076     synctex_counted_node_s result = {0, NULL};
   7077     synctex_node_p h = NULL;
   7078     synctex_node_p next_h = NULL;
   7079     synctex_node_p parent = NULL;
   7080     int weight = 0;
   7081     synctex_node_p N = NULL;
   7082     h = sibling;
   7083     do {
   7084         N = _synctex_tree_target(h);
   7085         parent = _synctex_tree_parent(N);
   7086         _synctex_data_set_weight(parent, 0);
   7087     } while((h = _synctex_tree_child(h)));
   7088     /* Compute the weights of the nodes */
   7089     h = sibling;
   7090     do {
   7091         N = _synctex_tree_target(h);
   7092         parent = _synctex_tree_parent(N);
   7093         weight = _synctex_data_weight(parent);
   7094         if (weight==0) {
   7095             N = _synctex_tree_child(parent);
   7096             do {
   7097                 if (_synctex_nodes_are_friend(N,sibling)) {
   7098                     ++ weight;
   7099                 }
   7100             } while ((N = __synctex_tree_sibling(N)));
   7101             _synctex_data_set_weight(h,weight);
   7102             _synctex_data_set_weight(parent,weight);
   7103         }
   7104     } while((h = _synctex_tree_child(h)));
   7105     /* Order handle nodes according to the weight */
   7106     h = _synctex_tree_reset_child(sibling);
   7107     result.node = sibling;
   7108     weight = 0;
   7109     while((h)) {
   7110         N = result.node;
   7111         if (_synctex_data_weight(h)>_synctex_data_weight(N)) {
   7112             next_h = _synctex_tree_set_child(h,N);
   7113             result.node = h;
   7114         } else if (_synctex_data_weight(h) == 0) {
   7115             ++ weight;
   7116             next_h = _synctex_tree_reset_child(h);
   7117             synctex_node_free(h);
   7118         } else {
   7119             synctex_node_p next_N = NULL;
   7120             while((next_N = _synctex_tree_child(N))) {
   7121                 N = next_N;
   7122                 if (_synctex_data_weight(h)<_synctex_data_weight(next_N)) {
   7123                     continue;
   7124                 }
   7125                 break;
   7126             }
   7127             next_h = _synctex_tree_set_child(h,_synctex_tree_set_child(N,h));
   7128         }
   7129         h = next_h;
   7130     };
   7131     h = result.node;
   7132     weight = 0;
   7133     do {
   7134         ++weight;
   7135     } while((h = _synctex_tree_child(h)));
   7136     result.count = 1;
   7137     h = result.node;
   7138     while((next_h = _synctex_tree_child(h))) {
   7139         if (_synctex_data_weight(next_h)==0) {
   7140             _synctex_tree_reset_child(h);
   7141             weight = 1;
   7142             h = next_h;
   7143             while((h = _synctex_tree_child(h))) {
   7144                 ++weight;
   7145             }
   7146             synctex_node_free(next_h);
   7147             break;
   7148         }
   7149         ++result.count;
   7150         h = next_h;
   7151     }
   7152     return result;
   7153 }
   7154 
   7155 SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hitP, synctex_node_p node);
   7156 
   7157 /*  This struct records distances, the left one is non negative and the right one is non positive.
   7158  *  When comparing the locations of 2 different graphical objects on the page, we will have to also record the
   7159  *  horizontal distance as signed to keep track of the typesetting order.*/
   7160 
   7161 typedef struct {
   7162     synctex_node_p node;
   7163     int distance;
   7164 } synctex_nd_s;
   7165 
   7166 #define SYNCTEX_ND_0 (synctex_nd_s){NULL,INT_MAX}
   7167 
   7168 typedef synctex_nd_s * synctex_nd_p;
   7169 
   7170 typedef struct {
   7171     synctex_nd_s l;
   7172     synctex_nd_s r;
   7173 } synctex_nd_lr_s;
   7174 
   7175 /*  The best container is the deeper box that contains the hit point (H,V).
   7176  *  _synctex_eq_deepest_container_v2 starts with node whereas
   7177  *  _synctex_box_child_deepest starts with node's children, if any
   7178  *  if node is not a box, or a void box, NULL is returned.
   7179  *  We traverse the node tree in a deep first manner and stop as soon as a result is found. */
   7180 static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hitP, synctex_node_p node);
   7181 
   7182 SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node);
   7183 
   7184 /*  Closest child, recursive.  */
   7185 static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node);
   7186 
   7187 /*  The smallest container between two has the smallest width or height.
   7188  *  This comparison is used when there are 2 overlapping boxes that contain the hit point.
   7189  *  For ConTeXt, the problem appears at each page.
   7190  *  The chosen box is the one with the smallest height, then the smallest width. */
   7191 SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node);
   7192 
   7193 /*  Returns the distance between the hit point hit point=(H,V) and the given node. */
   7194 
   7195 static int _synctex_point_node_distance_v2(synctex_point_p hitP, synctex_node_p node);
   7196 
   7197 /*  The closest container is the box that is the one closest to the given point.
   7198  *  The "visible" version takes into account the visible dimensions instead of the real ones given by TeX. */
   7199 static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node);
   7200 
   7201 #	ifdef SYNCTEX_NOTHING
   7202 #       pragma mark -
   7203 #       pragma mark Queries
   7204 #   endif
   7205 
   7206 /**
   7207  *  iterator for a deep first tree traversal.
   7208  */
   7209 struct synctex_iterator_t {
   7210     synctex_node_p seed;
   7211     synctex_node_p top;
   7212     synctex_node_p next;
   7213     int count0;
   7214     int count;
   7215 };
   7216 
   7217 SYNCTEX_INLINE static synctex_iterator_p _synctex_iterator_new(synctex_node_p result, int count) {
   7218     synctex_iterator_p iterator;
   7219     if ((iterator = _synctex_malloc(sizeof(synctex_iterator_s)))) {
   7220         iterator->seed = iterator->top = iterator->next = result;
   7221         iterator->count0 = iterator->count = count;
   7222     }
   7223     return iterator;
   7224 };
   7225 
   7226 void synctex_iterator_free(synctex_iterator_p iterator) {
   7227     if (iterator) {
   7228         synctex_node_free(iterator->seed);
   7229         _synctex_free(iterator);
   7230     }
   7231 }
   7232 synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator) {
   7233     return iterator?iterator->count>0:0;
   7234 }
   7235 int synctex_iterator_count(synctex_iterator_p iterator) {
   7236     return iterator? iterator->count: 0;
   7237 }
   7238 
   7239 /**
   7240  *  The next result of the iterator.
   7241  *  Internally, the iterator stores handles to nodes.
   7242  *  Externally, it returns the targets,
   7243  *  such that the caller only sees nodes.
   7244  */
   7245 synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator) {
   7246     if (iterator && iterator->count>0) {
   7247         synctex_node_p N = iterator->next;
   7248         if(!(iterator->next = _synctex_tree_child(N))) {
   7249             iterator->next = iterator->top = __synctex_tree_sibling(iterator->top);
   7250         }
   7251         --iterator->count;
   7252         return _synctex_tree_target(N);
   7253     }
   7254     return NULL;
   7255 }
   7256 int synctex_iterator_reset(synctex_iterator_p iterator) {
   7257     if (iterator) {
   7258         iterator->next = iterator->top = iterator->seed;
   7259         return iterator->count = iterator->count0;
   7260     }
   7261     return 0;
   7262 }
   7263 
   7264 synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner,int page,float h,float v){
   7265     if (scanner) {
   7266         synctex_node_p sheet = NULL;
   7267         synctex_point_s hit;
   7268         synctex_node_p node = NULL;
   7269         synctex_nd_lr_s nds = {{NULL,0},{NULL,0}};
   7270         if (NULL == (scanner = synctex_scanner_parse(scanner)) || 0 >= scanner->unit) {/*  scanner->unit must be >0 */
   7271             return NULL;
   7272         }
   7273         /*  Find the proper sheet */
   7274         sheet = synctex_sheet(scanner,page);
   7275         if (NULL == sheet) {
   7276             return NULL;
   7277         }
   7278         /*  Now sheet points to the sheet node with proper page number. */
   7279         /*  Now that scanner has been initialized, we can convert
   7280          *  the given point to scanner integer coordinates */
   7281         hit = (synctex_point_s)
   7282         {(h-scanner->x_offset)/scanner->unit,
   7283             (v-scanner->y_offset)/scanner->unit};
   7284         /*  At first, we browse all the horizontal boxes of the sheet
   7285          *  until we find one containing the hit point. */
   7286         if ((node = _synctex_tree_next_hbox(sheet))) {
   7287             do {
   7288                 if (_synctex_point_in_box_v2(&hit,node)) {
   7289                     /*  Maybe the hit point belongs to a contained vertical box.
   7290                      *  This is the most likely situation.
   7291                      */
   7292                     synctex_node_p next = node;
   7293 #if defined(SYNCTEX_DEBUG)
   7294                     printf("--- We are lucky\n");
   7295 #endif
   7296                     /*  This trick is for catching overlapping boxes */
   7297                     while ((next = _synctex_tree_next_hbox(next))) {
   7298                         if (_synctex_point_in_box_v2(&hit,next)) {
   7299                             node = _synctex_smallest_container_v2(next,node);
   7300                         }
   7301                     }
   7302                     /*  node is the smallest horizontal box that contains hit,
   7303                      *  unless there is no hbox at all.
   7304                      */
   7305                     node = _synctex_eq_deepest_container_v2(&hit, node);
   7306                     nds = _synctex_eq_get_closest_children_in_box_v2(&hit, node);
   7307                 end:
   7308                     if (nds.r.node && nds.l.node) {
   7309                         if ((_synctex_data_tag(nds.r.node)!=_synctex_data_tag(nds.l.node))
   7310                             || (_synctex_data_line(nds.r.node)!=_synctex_data_line(nds.l.node))
   7311                             || (_synctex_data_column(nds.r.node)!=_synctex_data_column(nds.l.node))) {
   7312                             if (_synctex_data_line(nds.r.node)<_synctex_data_line(nds.l.node)) {
   7313                                 node = nds.r.node;
   7314                                 nds.r.node = nds.l.node;
   7315                                 nds.l.node = node;
   7316                             } else if (_synctex_data_line(nds.r.node)==_synctex_data_line(nds.l.node)) {
   7317                                 if (nds.l.distance>nds.r.distance) {
   7318                                     node = nds.r.node;
   7319                                     nds.r.node = nds.l.node;
   7320                                     nds.l.node = node;
   7321                                 }
   7322                             }
   7323                             if((node = _synctex_new_handle_with_target(nds.l.node))) {
   7324                                 synctex_node_p other_handle;
   7325                                 if((other_handle = _synctex_new_handle_with_target(nds.r.node))) {
   7326                                     _synctex_tree_set_sibling(node,other_handle);
   7327                                     return _synctex_iterator_new(node,2);
   7328                                 }
   7329                                 return _synctex_iterator_new(node,1);
   7330                             }
   7331                             return NULL;
   7332                         }
   7333                         /*  both nodes have the same input coordinates
   7334                          *  We choose the one closest to the hit point  */
   7335                         if (nds.l.distance>nds.r.distance) {
   7336                             nds.l.node = nds.r.node;
   7337                         }
   7338                         nds.r.node = NULL;
   7339                     } else if (nds.r.node) {
   7340                         nds.l = nds.r;
   7341                     } else if (!nds.l.node) {
   7342                         nds.l.node = node;
   7343                     }
   7344                     if((node = _synctex_new_handle_with_target(nds.l.node))) {
   7345                         return _synctex_iterator_new(node,1);
   7346                     }
   7347                     return 0;
   7348                 }
   7349             } while ((node = _synctex_tree_next_hbox(node)));
   7350             /*  All the horizontal boxes have been tested,
   7351              *  None of them contains the hit point.
   7352              */
   7353         }
   7354         /*  We are not lucky,
   7355          *  we test absolutely all the node
   7356          *  to find the closest... */
   7357         if ((node = _synctex_tree_child(sheet))) {
   7358 #if defined(SYNCTEX_DEBUG)
   7359             printf("--- We are not lucky\n");
   7360 #endif
   7361             nds.l = __synctex_closest_deep_child_v2(&hit, node);
   7362 #if defined(SYNCTEX_DEBUG)
   7363             printf("Edit query best: %i\n", nds.l.distance);
   7364 #endif
   7365             goto end;
   7366         }
   7367     }
   7368     return NULL;
   7369 }
   7370 
   7371 /**
   7372  *  Loop the candidate friendly list to find the ones with the proper
   7373  *  tag and line.
   7374  *  Returns a tree of results targeting the found candidates.
   7375  *  At the top level each sibling has its own page number.
   7376  *  All the results with the same page number are linked by child/parent entry.
   7377  *  - parameter candidate: a friendly list of candidates
   7378  */
   7379 static synctex_node_p _synctex_display_query_v2(synctex_node_p target, int tag, int line, synctex_bool_t exclude_box) {
   7380     synctex_node_p first_handle = NULL;
   7381     /*  Search the first match */
   7382     if (target == NULL) {
   7383         return first_handle;
   7384     }
   7385     do {
   7386         int page;
   7387         if ((exclude_box
   7388              && _synctex_node_is_box(target))
   7389             || (tag != synctex_node_tag(target))
   7390             || (line != synctex_node_line(target))) {
   7391             continue;
   7392         }
   7393         /*  We found a first match, create
   7394          *  a result handle targeting that candidate. */
   7395         first_handle = _synctex_new_handle_with_target(target);
   7396         if (first_handle == NULL) {
   7397             return first_handle;
   7398         }
   7399         /*  target is either a node,
   7400          *  or a proxy to some node, in which case,
   7401          *  the target's target belongs to a form,
   7402          *  not a sheet. */
   7403         page = synctex_node_page(target);
   7404         /*  Now create all the other results  */
   7405         while ((target = _synctex_tree_friend(target))) {
   7406             synctex_node_p result = NULL;
   7407             if ((exclude_box
   7408                  && _synctex_node_is_box(target))
   7409                 || (tag != synctex_node_tag(target))
   7410                 || (line != synctex_node_line(target))) {
   7411                 continue;
   7412             }
   7413             /*  Another match, same page number ? */
   7414             result = _synctex_new_handle_with_target(target);
   7415             if (NULL == result ) {
   7416                 return first_handle;
   7417             }
   7418             /*  is it the same page number ? */
   7419             if (synctex_node_page(target) == page) {
   7420                 __synctex_tree_set_child(result, first_handle);
   7421                 first_handle = result;
   7422             } else {
   7423                 /*  We have 2 page numbers involved */
   7424                 __synctex_tree_set_sibling(first_handle, result);
   7425                 while ((target = _synctex_tree_friend(target))) {
   7426                     synctex_node_p same_page_node;
   7427                     if ((exclude_box
   7428                          && _synctex_node_is_box(target))
   7429                         || (tag != synctex_node_tag(target))
   7430                         || (line != synctex_node_line(target))) {
   7431                         continue;
   7432                     }
   7433                     /*  New match found, which page? */
   7434                     result = _synctex_new_handle_with_target(target);
   7435                     if (NULL == result) {
   7436                         return first_handle;
   7437                     }
   7438                     same_page_node = first_handle;
   7439                     page = synctex_node_page(target);
   7440                     /*  Find a result with the same page number */;
   7441                     do {
   7442                         if (_synctex_node_target_page(same_page_node) == page) {
   7443                             /* Insert result between same_page_node and its child */
   7444                             _synctex_tree_set_child(result,_synctex_tree_set_child(same_page_node,result));
   7445                         } else if ((same_page_node = __synctex_tree_sibling(same_page_node))) {
   7446                             continue;
   7447                         } else {
   7448                             /*  This is a new page number */
   7449                             __synctex_tree_set_sibling(result,first_handle);
   7450                             first_handle = result;
   7451                         }
   7452                         break;
   7453                     } while (synctex_YES);
   7454                 }
   7455                 return first_handle;
   7456             }
   7457         }
   7458     } while ((target = _synctex_tree_friend(target)));
   7459     return first_handle;
   7460 }
   7461 synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint) {
   7462     SYNCTEX_UNUSED(column)
   7463     if (scanner) {
   7464         int tag = synctex_scanner_get_tag(scanner,name);/* parse if necessary */
   7465         int max_line = 0;
   7466         int line_offset = 1;
   7467         int try_count = 100;
   7468         synctex_node_p node = NULL;
   7469         synctex_node_p result = NULL;
   7470         if (tag == 0) {
   7471             printf("SyncTeX Warning: No tag for %s\n",name);
   7472             return NULL;
   7473         }
   7474         node = synctex_scanner_input_with_tag(scanner, tag);
   7475         max_line = _synctex_data_line(node);
   7476         /*  node = NULL; */
   7477         if (line>max_line) {
   7478             line = max_line;
   7479         }
   7480         while(try_count--) {
   7481             if (line<=max_line) {
   7482                 /*  This loop will only be performed once for advanced viewers */
   7483                 synctex_node_p friend = _synctex_scanner_friend(scanner,tag+line);
   7484                 if ((node = friend)) {
   7485                     result = _synctex_display_query_v2(node,tag,line,synctex_YES);
   7486                     if (!result) {
   7487                         /*  We did not find any matching boundary, retry including boxes */
   7488                         node = friend;/*  no need to test it again, already done */
   7489                         result = _synctex_display_query_v2(node,tag,line,synctex_NO);
   7490                     }
   7491                     /*  Now reverse the order to have nodes in display order, and then keep just a few nodes.
   7492                      *  Order first the best node. */
   7493                     /*  The result is a tree. At the root level, all nodes
   7494                      *  correspond to different page numbers.
   7495                      *  Each node has a child which corresponds to the same
   7496                      *  page number if relevant.
   7497                      *  Then reorder the nodes to put first the one which fits best.
   7498                      *  The idea is to count the number of nodes
   7499                      *  with the same tag and line number in the parents
   7500                      *  and choose the ones with the biggest count.
   7501                      */
   7502                     if (result) {
   7503                         /*  navigate through siblings, then children   */
   7504                         synctex_node_p next_sibling = __synctex_tree_reset_sibling(result);
   7505                         int best_match = abs(page_hint-_synctex_node_target_page(result));
   7506                         synctex_node_p sibling;
   7507                         int match;
   7508                         synctex_counted_node_s cn = _synctex_vertically_sorted_v2(result);
   7509                         int count = cn.count;
   7510                         result = cn.node;
   7511                         while((sibling = next_sibling)) {
   7512                             /* What is next? Do not miss that step! */
   7513                             next_sibling = __synctex_tree_reset_sibling(sibling);
   7514                             cn = _synctex_vertically_sorted_v2(sibling);
   7515                             count += cn.count;
   7516                             sibling = cn.node;
   7517                             match = abs(page_hint-_synctex_node_target_page(sibling));
   7518                             if (match<best_match) {
   7519                                 /*  Order this node first */
   7520                                 __synctex_tree_set_sibling(sibling,result);
   7521                                 result = sibling;
   7522                                 best_match = match;
   7523                             } else /*if (match>=best_match)*/ {
   7524                                 __synctex_tree_set_sibling(sibling,__synctex_tree_sibling(result));
   7525                                 __synctex_tree_set_sibling(result,sibling);
   7526                             }
   7527                         }
   7528                         return _synctex_iterator_new(result,count);
   7529                     }
   7530                 }
   7531 #       if defined(__SYNCTEX_STRONG_DISPLAY_QUERY__)
   7532                 break;
   7533 #       else
   7534                 line += line_offset;
   7535                 line_offset=line_offset<0?-(line_offset-1):-(line_offset+1);
   7536                 if (line <= 0) {
   7537                     line += line_offset;
   7538                     line_offset=line_offset<0?-(line_offset-1):-(line_offset+1);
   7539                 }
   7540 #       endif
   7541             }
   7542         }
   7543     }
   7544     return NULL;
   7545 }
   7546 synctex_status_t synctex_display_query(synctex_scanner_p scanner,const char *  name,int line,int column, int page_hint) {
   7547     if (scanner) {
   7548         synctex_iterator_free(scanner->iterator);
   7549         scanner->iterator = synctex_iterator_new_display(scanner, name,line,column, page_hint);
   7550         return synctex_iterator_count(scanner->iterator);
   7551     }
   7552     return SYNCTEX_STATUS_ERROR;
   7553 }
   7554 synctex_status_t synctex_edit_query(synctex_scanner_p scanner,int page,float h,float v) {
   7555     if (scanner) {
   7556         synctex_iterator_free(scanner->iterator);
   7557         scanner->iterator = synctex_iterator_new_edit(scanner, page, h, v);
   7558         return synctex_iterator_count(scanner->iterator);
   7559     }
   7560     return SYNCTEX_STATUS_ERROR;
   7561 }
   7562 /**
   7563  *  The next result of a query.
   7564  */
   7565 synctex_node_p synctex_scanner_next_result(synctex_scanner_p scanner) {
   7566     return scanner? synctex_iterator_next_result(scanner->iterator): NULL;
   7567 }
   7568 synctex_status_t synctex_scanner_reset_result(synctex_scanner_p scanner) {
   7569     return scanner? synctex_iterator_reset(scanner->iterator): SYNCTEX_STATUS_ERROR;
   7570 }
   7571 
   7572 synctex_node_p synctex_node_target(synctex_node_p node) {
   7573     return _synctex_tree_target(node);
   7574 }
   7575 
   7576 #	ifdef SYNCTEX_NOTHING
   7577 #       pragma mark -
   7578 #       pragma mark Geometric utilities
   7579 #   endif
   7580 
   7581 /** Roughly speaking, this is:
   7582  *  node's h coordinate - hit point's h coordinate.
   7583  *  If node is to the right of the hit point, then this distance is positive,
   7584  *  if node is to the left of the hit point, this distance is negative.
   7585  *  If the argument is a pdf form reference, then the child is used and returned instead.
   7586  *  Last Revision: Mon Apr 24 07:05:27 UTC 2017
   7587  */
   7588 static synctex_nd_s _synctex_point_h_ordered_distance_v2
   7589 (synctex_point_p hit, synctex_node_p node) {
   7590     synctex_nd_s nd = {node,INT_MAX};
   7591     if (node) {
   7592         int min,med,max,width;
   7593         switch(synctex_node_type(node)) {
   7594                 /*  The distance between a point and a box is special.
   7595                  *  It is not the euclidean distance, nor something similar.
   7596                  *  We have to take into account the particular layout,
   7597                  *  and the box hierarchy.
   7598                  *  Given a box, there are 9 regions delimited by the lines of the edges of the box.
   7599                  *  The origin being at the top left corner of the page,
   7600                  *  we also give names to the vertices of the box.
   7601                  *
   7602                  *   1 | 2 | 3
   7603                  *  ---A---B--->
   7604                  *   4 | 5 | 6
   7605                  *  ---C---D--->
   7606                  *   7 | 8 | 9
   7607                  *     v   v
   7608                  */
   7609             case synctex_node_type_vbox:
   7610             case synctex_node_type_void_vbox:
   7611             case synctex_node_type_void_hbox:
   7612                 /*  getting the box bounds, taking into account negative width, height and depth. */
   7613                 width = _synctex_data_width(node);
   7614                 min = _synctex_data_h(node);
   7615                 max = min + (width>0?width:-width);
   7616                 /*  We always have min <= max */
   7617                 if (hit->h<min) {
   7618                     nd.distance = min - hit->h; /*  regions 1+4+7, result is > 0 */
   7619                 } else if (hit->h>max) {
   7620                     nd.distance = max - hit->h; /*  regions 3+6+9, result is < 0 */
   7621                 } else {
   7622                     nd.distance = 0; /*  regions 2+5+8, inside the box, except for vertical coordinates */
   7623                 }
   7624                 break;
   7625             case synctex_node_type_proxy_vbox:
   7626                 /*  getting the box bounds, taking into account negative width, height and depth. */
   7627                 width = synctex_node_width(node);
   7628                 min = synctex_node_h(node);
   7629                 max = min + (width>0?width:-width);
   7630                 /*  We always have min <= max */
   7631                 if (hit->h<min) {
   7632                     nd.distance = min - hit->h; /*  regions 1+4+7, result is > 0 */
   7633                 } else if (hit->h>max) {
   7634                     nd.distance = max - hit->h; /*  regions 3+6+9, result is < 0 */
   7635                 } else {
   7636                     nd.distance = 0; /*  regions 2+5+8, inside the box, except for vertical coordinates */
   7637                 }
   7638                 break;
   7639             case synctex_node_type_hbox:
   7640             case synctex_node_type_proxy_hbox:
   7641                 /*  getting the box bounds, taking into account negative width, height and depth. */
   7642                 width = synctex_node_hbox_width(node);
   7643                 min = synctex_node_hbox_h(node);
   7644                 max = min + (width>0?width:-width);
   7645                 /*  We always have min <= max */
   7646                 if (hit->h<min) {
   7647                     nd.distance = min - hit->h; /*  regions 1+4+7, result is > 0 */
   7648                 } else if (hit->h>max) {
   7649                     nd.distance = max - hit->h; /*  regions 3+6+9, result is < 0 */
   7650                 } else {
   7651                     nd.distance = 0; /*  regions 2+5+8, inside the box, except for vertical coordinates */
   7652                 }
   7653                 break;
   7654             case synctex_node_type_kern:
   7655                 /*  IMPORTANT NOTICE: the location of the kern is recorded AFTER the move.
   7656                  *  The distance to the kern is very special,
   7657                  *  in general, there is no text material in the kern,
   7658                  *  this is why we compute the offset relative to the closest edge of the kern.*/
   7659                 max = _synctex_data_width(node);
   7660                 if (max<0) {
   7661                     min = _synctex_data_h(node);
   7662                     max = min - max;
   7663                 } else {
   7664                     min = -max;
   7665                     max = _synctex_data_h(node);
   7666                     min += max;
   7667                 }
   7668                 med = (min+max)/2;
   7669                 /*  positive kern: '.' means text, '>' means kern offset
   7670                  *      .............
   7671                  *                   min>>>>med>>>>max
   7672                  *                                    ...............
   7673                  *  negative kern: '.' means text, '<' means kern offset
   7674                  *      ............................
   7675                  *                 min<<<<med<<<<max
   7676                  *                 .................................
   7677                  *  Actually, we do not take into account negative widths.
   7678                  *  There is a problem for such situation when there is effectively overlapping text.
   7679                  *  But this should be extremely rare. I guess that in that case, many different choices
   7680                  *  could be made, one being in contradiction with the other.
   7681                  *  It means that the best choice should be made according to the situation that occurs
   7682                  *  most frequently.
   7683                  */
   7684                 if (hit->h<min) {
   7685                     nd.distance = min - hit->h + 1; /*  penalty to ensure other nodes are chosen first in case of overlapping ones */
   7686                 } else if (hit->h>max) {
   7687                     nd.distance = max - hit->h - 1; /*  same kind of penalty */
   7688                 } else if (hit->h>med) {
   7689                     /*  do things like if the node had 0 width and was placed at the max edge + 1*/
   7690                     nd.distance = max - hit->h + 1; /*  positive, the kern is to the right of the hit point */
   7691                 } else {
   7692                     nd.distance = min - hit->h - 1; /*  negative, the kern is to the left of the hit point */
   7693                 }
   7694                 break;
   7695             case synctex_node_type_rule:/* to do: special management */
   7696             case synctex_node_type_glue:
   7697             case synctex_node_type_math:
   7698             case synctex_node_type_boundary:
   7699             case synctex_node_type_box_bdry:
   7700                 nd.distance = _synctex_data_h(node) - hit->h;
   7701                 break;
   7702             case synctex_node_type_ref:
   7703                 nd.node = synctex_node_child(node);
   7704                 nd = _synctex_point_h_ordered_distance_v2(hit,nd.node);
   7705                 break;
   7706             case synctex_node_type_proxy:
   7707             case synctex_node_type_proxy_last:
   7708             {
   7709                 /* shift the hit point to be relative to the proxy origin,
   7710                  *  then compute the distance to the target
   7711                  */
   7712                 synctex_point_s otherHit = *hit;
   7713                 otherHit.h -= _synctex_data_h(node);
   7714                 otherHit.v -= _synctex_data_v(node);
   7715                 nd.node = _synctex_tree_target(node);
   7716                 nd = _synctex_point_h_ordered_distance_v2(&otherHit,nd.node);
   7717                 nd.node = node;
   7718             }
   7719             default:
   7720                 break;
   7721         }
   7722     }
   7723     return nd;
   7724 }
   7725 /** Roughly speaking, this is:
   7726  *  node's v coordinate - hit point's v coordinate.
   7727  *  If node is at the top of the hit point, then this distance is positive,
   7728  *  if node is at the bottom of the hit point, this distance is negative.
   7729  */
   7730 static synctex_nd_s _synctex_point_v_ordered_distance_v2
   7731 (synctex_point_p hit, synctex_node_p node) {
   7732     synctex_nd_s nd = {node, INT_MAX};
   7733     int min,max,depth,height;
   7734     switch(synctex_node_type(node)) {
   7735             /*  The distance between a point and a box is special.
   7736              *  It is not the euclidean distance, nor something similar.
   7737              *  We have to take into account the particular layout,
   7738              *  and the box hierarchy.
   7739              *  Given a box, there are 9 regions delimited by the lines of the edges of the box.
   7740              *  The origin being at the top left corner of the page,
   7741              *  we also give names to the vertices of the box.
   7742              *
   7743              *   1 | 2 | 3
   7744              *  ---A---B--->
   7745              *   4 | 5 | 6
   7746              *  ---C---D--->
   7747              *   7 | 8 | 9
   7748              *     v   v
   7749              */
   7750         case synctex_node_type_vbox:
   7751         case synctex_node_type_void_vbox:
   7752         case synctex_node_type_void_hbox:
   7753             /*  getting the box bounds, taking into account negative width, height and depth. */
   7754             min = synctex_node_v(node);
   7755             max = min + _synctex_abs(_synctex_data_depth(node));
   7756             min -= _synctex_abs(_synctex_data_height(node));
   7757             /*  We always have min <= max */
   7758             if (hit->v<min) {
   7759                 nd.distance = min - hit->v; /*  regions 1+2+3, result is > 0 */
   7760             } else if (hit->v>max) {
   7761                 nd.distance = max - hit->v; /*  regions 7+8+9, result is < 0 */
   7762             } else {
   7763                 nd.distance = 0; /*  regions 4.5.6, inside the box, except for horizontal coordinates */
   7764             }
   7765             break;
   7766         case synctex_node_type_proxy_vbox:
   7767             /*  getting the box bounds, taking into account negative width, height and depth. */
   7768             min = synctex_node_v(node);
   7769             max = min + _synctex_abs(synctex_node_depth(node));
   7770             min -= _synctex_abs(synctex_node_height(node));
   7771             /*  We always have min <= max */
   7772             if (hit->v<min) {
   7773                 nd.distance = min - hit->v; /*  regions 1+2+3, result is > 0 */
   7774             } else if (hit->v>max) {
   7775                 nd.distance = max - hit->v; /*  regions 7+8+9, result is < 0 */
   7776             } else {
   7777                 nd.distance = 0; /*  regions 4.5.6, inside the box, except for horizontal coordinates */
   7778             }
   7779             break;
   7780         case synctex_node_type_hbox:
   7781         case synctex_node_type_proxy_hbox:
   7782             /*  getting the box bounds, taking into account negative height and depth. */
   7783             min = synctex_node_hbox_v(node);
   7784             depth = synctex_node_hbox_depth(node);
   7785             max = min + (depth>0?depth:-depth);
   7786             height = synctex_node_hbox_height(node);
   7787             min -= (height>0?height:-height);
   7788             /*  We always have min <= max */
   7789             if (hit->v<min) {
   7790                 nd.distance = min - hit->v; /*  regions 1+2+3, result is > 0 */
   7791             } else if (hit->v>max) {
   7792                 nd.distance = max - hit->v; /*  regions 7+8+9, result is < 0 */
   7793             } else {
   7794                 nd.distance = 0; /*  regions 4.5.6, inside the box, except for horizontal coordinates */
   7795             }
   7796             break;
   7797         case synctex_node_type_rule:/* to do: special management */
   7798         case synctex_node_type_kern:
   7799         case synctex_node_type_glue:
   7800         case synctex_node_type_math:
   7801             min = _synctex_data_v(node);
   7802             max = min + _synctex_abs(_synctex_data_depth(_synctex_tree_parent(node)));
   7803             min -= _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
   7804             /*  We always have min <= max */
   7805             if (hit->v<min) {
   7806                 nd.distance = min - hit->v; /*  regions 1+2+3, result is > 0 */
   7807             } else if (hit->v>max) {
   7808                 nd.distance = max - hit->v; /*  regions 7+8+9, result is < 0 */
   7809             } else {
   7810                 nd.distance = 0; /*  regions 4.5.6, inside the box, except for horizontal coordinates */
   7811             }
   7812             break;
   7813         case synctex_node_type_ref:
   7814             nd.node = synctex_node_child(node);
   7815             nd = _synctex_point_v_ordered_distance_v2(hit,nd.node);
   7816             break;
   7817         case synctex_node_type_proxy:
   7818         case synctex_node_type_proxy_last:
   7819         {
   7820             synctex_point_s otherHit = *hit;
   7821             otherHit.h -= _synctex_data_h(node);
   7822             otherHit.v -= _synctex_data_v(node);
   7823             nd.node = _synctex_tree_target(node);
   7824             nd = _synctex_point_v_ordered_distance_v2(&otherHit,nd.node);
   7825             nd.node = node;
   7826         }
   7827         default: break;
   7828     }
   7829     return nd;
   7830 }
   7831 /**
   7832  *  The best is the one with the smallest area.
   7833  *  The area is width*height where width and height may be big.
   7834  *  So there is a real risk of overflow if we stick with ints.
   7835  */
   7836 SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node) {
   7837     long total_height, other_total_height;
   7838     unsigned long area, other_area;
   7839     long width = synctex_node_hbox_width(node);
   7840     long other_width = synctex_node_hbox_width(other_node);
   7841     if (width<0) {
   7842         width = -width;
   7843     }
   7844     if (other_width<0) {
   7845         other_width = -other_width;
   7846     }
   7847     total_height = _synctex_abs(synctex_node_hbox_depth(node)) + _synctex_abs(synctex_node_hbox_height(node));
   7848     other_total_height = _synctex_abs(synctex_node_hbox_depth(other_node)) + _synctex_abs(synctex_node_hbox_height(other_node));
   7849     area = total_height*width;
   7850     other_area = other_total_height*other_width;
   7851     if (area<other_area) {
   7852         return node;
   7853     }
   7854     if (area>other_area) {
   7855         return other_node;
   7856     }
   7857     if (_synctex_abs(_synctex_data_width(node))>_synctex_abs(_synctex_data_width(other_node))) {
   7858         return node;
   7859     }
   7860     if (_synctex_abs(_synctex_data_width(node))<_synctex_abs(_synctex_data_width(other_node))) {
   7861         return other_node;
   7862     }
   7863     if (total_height<other_total_height) {
   7864         return node;
   7865     }
   7866     if (total_height>other_total_height) {
   7867         return other_node;
   7868     }
   7869     return node;
   7870 }
   7871 
   7872 SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hit, synctex_node_p node) {
   7873     if (node) {
   7874         if (0 == _synctex_point_h_ordered_distance_v2(hit,node).distance
   7875             && 0 == _synctex_point_v_ordered_distance_v2(hit,node).distance) {
   7876             return synctex_YES;
   7877         }
   7878     }
   7879     return synctex_NO;
   7880 }
   7881 
   7882 static int _synctex_distance_to_box_v2(synctex_point_p hit,synctex_box_p box) {
   7883     /*  The distance between a point and a box is special.
   7884      *  It is not the euclidean distance, nor something similar.
   7885      *  We have to take into account the particular layout,
   7886      *  and the box hierarchy.
   7887      *  Given a box, there are 9 regions delimited by the lines of the edges of the box.
   7888      *  The origin being at the top left corner of the page,
   7889      *  we also give names to the vertices of the box.
   7890      *
   7891      *   1 | 2 | 3
   7892      *  ---A---B--->
   7893      *   4 | 5 | 6
   7894      *  ---C---D--->
   7895      *   7 | 8 | 9
   7896      *     v   v
   7897      *  In each region, there is a different formula.
   7898      *  In the end we have a continuous distance which may not be a mathematical distance but who cares. */
   7899     if (hit->v<box->min.v) {
   7900         /*  Regions 1, 2 or 3 */
   7901         if (hit->h<box->min.h) {
   7902             /*  This is region 1. The distance to the box is the L1 distance PA. */
   7903             return box->min.v - hit->v + box->min.h - hit->h;/*  Integer overflow? probability epsilon */
   7904         } else if (hit->h<=box->max.h) {
   7905             /*  This is region 2. The distance to the box is the geometrical distance to the top edge.  */
   7906             return box->min.v - hit->v;
   7907         } else {
   7908             /*  This is region 3. The distance to the box is the L1 distance PB. */
   7909             return box->min.v - hit->v + hit->h - box->max.h;
   7910         }
   7911     } else if (hit->v<=box->max.v) {
   7912         /*  Regions 4, 5 or 6 */
   7913         if (hit->h<box->min.h) {
   7914             /*  This is region 4. The distance to the box is the geometrical distance to the left edge.  */
   7915             return box->min.h - hit->h;
   7916         } else if (hit->h<=box->max.h) {
   7917             /*  This is region 5. We are inside the box.  */
   7918             return 0;
   7919         } else {
   7920             /*  This is region 6. The distance to the box is the geometrical distance to the right edge.  */
   7921             return hit->h - box->max.h;
   7922         }
   7923     } else {
   7924         /*  Regions 7, 8 or 9 */
   7925         if (hit->h<box->min.h) {
   7926             /*  This is region 7. The distance to the box is the L1 distance PC. */
   7927             return hit->v - box->max.v + box->min.h - hit->h;
   7928         } else if (hit->h<=box->max.h) {
   7929             /*  This is region 8. The distance to the box is the geometrical distance to the top edge.  */
   7930             return hit->v - box->max.v;
   7931         } else {
   7932             /*  This is region 9. The distance to the box is the L1 distance PD. */
   7933             return hit->v - box->max.v + hit->h - box->max.h;
   7934         }
   7935     }
   7936 }
   7937 
   7938 /**
   7939  *  The distance from the hit point to the node.
   7940  */
   7941 static int _synctex_point_node_distance_v2(synctex_point_p hit, synctex_node_p node) {
   7942     int d = INT_MAX;
   7943     if (node) {
   7944         synctex_box_s box = {{0,0},{0,0}};
   7945         int dd = INT_MAX;
   7946         switch(synctex_node_type(node)) {
   7947             case synctex_node_type_vbox:
   7948                 box.min.h = _synctex_data_h(node);
   7949                 box.max.h = box.min.h + _synctex_abs(_synctex_data_width(node));
   7950                 box.min.v = synctex_node_v(node);
   7951                 box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node));
   7952                 box.min.v -= _synctex_abs(_synctex_data_height(node));
   7953                 return _synctex_distance_to_box_v2(hit,&box);
   7954             case synctex_node_type_proxy_vbox:
   7955                 box.min.h = synctex_node_h(node);
   7956                 box.max.h = box.min.h + _synctex_abs(synctex_node_width(node));
   7957                 box.min.v = synctex_node_v(node);
   7958                 box.max.v = box.min.v + _synctex_abs(synctex_node_depth(node));
   7959                 box.min.v -= _synctex_abs(synctex_node_height(node));
   7960                 return _synctex_distance_to_box_v2(hit,&box);
   7961             case synctex_node_type_hbox:
   7962             case synctex_node_type_proxy_hbox:
   7963                 box.min.h = synctex_node_hbox_h(node);
   7964                 box.max.h = box.min.h + _synctex_abs(synctex_node_hbox_width(node));
   7965                 box.min.v = synctex_node_hbox_v(node);
   7966                 box.max.v = box.min.v + _synctex_abs(synctex_node_hbox_depth(node));
   7967                 box.min.v -= _synctex_abs(synctex_node_hbox_height(node));
   7968                 return _synctex_distance_to_box_v2(hit,&box);
   7969             case synctex_node_type_void_vbox:
   7970             case synctex_node_type_void_hbox:
   7971                 /*  best of distances from the left edge and right edge*/
   7972                 box.min.h = _synctex_data_h(node);
   7973                 box.max.h = box.min.h;
   7974                 box.min.v = _synctex_data_v(node);
   7975                 box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node));
   7976                 box.min.v -= _synctex_abs(_synctex_data_height(node));
   7977                 d = _synctex_distance_to_box_v2(hit,&box);
   7978                 box.min.h = box.min.h + _synctex_abs(_synctex_data_width(node));
   7979                 box.max.h = box.min.h;
   7980                 dd = _synctex_distance_to_box_v2(hit,&box);
   7981                 return d<dd ? d:dd;
   7982             case synctex_node_type_kern:
   7983                 box.min.h = _synctex_data_h(node);
   7984                 box.max.h = box.min.h;
   7985                 box.max.v = _synctex_data_v(node);
   7986                 box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
   7987                 d = _synctex_distance_to_box_v2(hit,&box);
   7988                 box.min.h -= _synctex_data_width(node);
   7989                 box.max.h = box.min.h;
   7990                 dd = _synctex_distance_to_box_v2(hit,&box);
   7991                 return d<dd ? d:dd;
   7992             case synctex_node_type_glue:
   7993             case synctex_node_type_math:
   7994             case synctex_node_type_boundary:
   7995             case synctex_node_type_box_bdry:
   7996                 box.min.h = _synctex_data_h(node);
   7997                 box.max.h = box.min.h;
   7998                 box.max.v = _synctex_data_v(node);
   7999                 box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
   8000                 return _synctex_distance_to_box_v2(hit,&box);
   8001             case synctex_node_type_proxy:
   8002             case synctex_node_type_proxy_last:
   8003             {
   8004                 synctex_point_s otherHit = *hit;
   8005                 otherHit.h -= _synctex_data_h(node);
   8006                 otherHit.v -= _synctex_data_v(node);
   8007                 return _synctex_point_node_distance_v2(&otherHit, _synctex_tree_target(node));
   8008             }
   8009             default: break;
   8010         }
   8011     }
   8012     return d;
   8013 }
   8014 static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hit, synctex_node_p node) {
   8015     if (node) {
   8016         /**/
   8017         synctex_node_p child;
   8018         if ((child = synctex_node_child(node))) {
   8019             /*  Non void hbox or vbox, form ref or proxy */
   8020             /*  We go deep first because some boxes have 0 dimensions
   8021              *  despite they do contain some black material.
   8022              */
   8023             do {
   8024                 if ((_synctex_point_in_box_v2(hit,child))) {
   8025                     synctex_node_p deep = _synctex_eq_deepest_container_v2(hit,child);
   8026                     if (deep) {
   8027                         /*  One of the children contains the hit. */
   8028                         return deep;
   8029                     }
   8030                 }
   8031             } while((child = synctex_node_sibling(child)));
   8032             /*  is the hit point inside the box? */
   8033             if (synctex_node_type(node) == synctex_node_type_vbox
   8034                 || synctex_node_type(node) == synctex_node_type_proxy_vbox) {
   8035                 /*  For vboxes we try to use some node inside.
   8036                  *  Walk through the list of siblings until we find the closest one.
   8037                  *  Only consider siblings with children inside. */
   8038                 if ((child = _synctex_tree_child(node))) {
   8039                     synctex_nd_s best = SYNCTEX_ND_0;
   8040                     do {
   8041                         if (_synctex_tree_child(child)) {
   8042                             int d = _synctex_point_node_distance_v2(hit,child);
   8043                             if (d <= best.distance) {
   8044                                 best = (synctex_nd_s){child, d};
   8045                             }
   8046                         }
   8047                     } while((child = __synctex_tree_sibling(child)));
   8048                     if (best.node) {
   8049                         return best.node;
   8050                     }
   8051                 }
   8052             }
   8053             if (_synctex_point_in_box_v2(hit,node)) {
   8054                 return node;
   8055             }
   8056         }
   8057     }
   8058     return NULL;
   8059 }
   8060 static synctex_nd_s _synctex_eq_deepest_container_v3(synctex_point_p hit, synctex_node_p node) {
   8061     if (node) {
   8062         synctex_node_p child = NULL;
   8063         if ((child = synctex_node_child(node))) {
   8064             /*  Non void hbox, vbox, box proxy or form ref */
   8065             /*  We go deep first because some boxes have 0 dimensions
   8066              *  despite they do contain some black material.
   8067              */
   8068             do {
   8069                 synctex_nd_s deep = _synctex_eq_deepest_container_v3(hit, child);
   8070                 if (deep.node) {
   8071                     /*  One of the children contains the hit-> */
   8072                     return deep;
   8073                 }
   8074             } while((child = synctex_node_sibling(child)));
   8075             /*  For vboxes we try to use some node inside.
   8076              *  Walk through the list of siblings until we find the closest one.
   8077              *  Only consider siblings with children inside. */
   8078             if (synctex_node_type(node) == synctex_node_type_vbox
   8079                 || synctex_node_type(node) == synctex_node_type_proxy_vbox) {
   8080                 if ((child = synctex_node_child(node))) {
   8081                     synctex_nd_s best = SYNCTEX_ND_0;
   8082                     do {
   8083                         if (synctex_node_child(child)) {
   8084                             int d = _synctex_point_node_distance_v2(hit,child);
   8085                             if (d < best.distance) {
   8086                                 best = (synctex_nd_s){child,d};
   8087                             }
   8088                         }
   8089                     } while((child = synctex_node_sibling(child)));
   8090                     if (best.node) {
   8091                         return best;
   8092                     }
   8093                 }
   8094             }
   8095             /*  is the hit point inside the box? */
   8096             if (_synctex_point_in_box_v2(hit,node)) {
   8097                 return (synctex_nd_s){node, 0};
   8098             }
   8099         }
   8100     }
   8101     return SYNCTEX_ND_0;
   8102 }
   8103 
   8104 /*  Compares the locations of the hit point with the locations of
   8105  *  the various nodes contained in the box.
   8106  *  As it is an horizontal box, we only compare horizontal coordinates.
   8107  */
   8108 SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v2(synctex_point_p hitP, synctex_node_p node) {
   8109     synctex_nd_s childd = SYNCTEX_ND_0;
   8110     synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
   8111     if ((childd.node = synctex_node_child(node))) {
   8112         synctex_nd_s nd = SYNCTEX_ND_0;
   8113         do {
   8114             childd = _synctex_point_h_ordered_distance_v2(hitP,childd.node);
   8115             if (childd.distance > 0) {
   8116                 /*  node is to the right of the hit point.
   8117                  *  We compare node and the previously recorded one, through the recorded distance.
   8118                  *  If the nodes have the same tag, prefer the one with the smallest line number,
   8119                  *  if the nodes also have the same line number, prefer the one with the smallest column. */
   8120                 if (nds.r.distance > childd.distance) {
   8121                     nds.r = childd;
   8122                 } else if (nds.r.distance == childd.distance && nds.r.node) {
   8123                     if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(childd.node)
   8124                         && (_synctex_data_line(nds.r.node) > _synctex_data_line(childd.node)
   8125                             || (_synctex_data_line(nds.r.node) == _synctex_data_line(childd.node)
   8126                                 && _synctex_data_column(nds.r.node) > _synctex_data_column(childd.node)))) {
   8127                                 nds.r = childd;
   8128                             }
   8129                 }
   8130             } else if (childd.distance == 0) {
   8131                 /*  hit point is inside node. */
   8132                 if (_synctex_tree_child(childd.node)) {
   8133                     return _synctex_eq_get_closest_children_in_box_v2(hitP, childd.node);
   8134                 }
   8135                 nds.l = childd;
   8136             } else { /*  here childd.distance < 0, the hit point is to the right of node */
   8137                 childd.distance = -childd.distance;
   8138                 if (nds.l.distance > childd.distance) {
   8139                     nds.l = childd;
   8140                 } else if (nds.l.distance == childd.distance && nds.l.node) {
   8141                     if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(childd.node)
   8142                         && (_synctex_data_line(nds.l.node) > _synctex_data_line(childd.node)
   8143                             || (_synctex_data_line(nds.l.node) == _synctex_data_line(childd.node)
   8144                                 && _synctex_data_column(nds.l.node) > _synctex_data_column(childd.node)))) {
   8145                                 nds.l = childd;
   8146                             }
   8147                 }
   8148             }
   8149         } while((childd.node = synctex_node_sibling(childd.node)));
   8150         if (nds.l.node) {
   8151             /*  the left node is new, try to narrow the result */
   8152             if ((nd = _synctex_eq_deepest_container_v3(hitP,nds.l.node)).node) {
   8153                 nds.l = nd;
   8154             }
   8155             if((nd = __synctex_closest_deep_child_v2(hitP,nds.l.node)).node) {
   8156                 nds.l.node = nd.node;
   8157             }
   8158         }
   8159         if (nds.r.node) {
   8160             /*  the right node is new, try to narrow the result */
   8161             if ((nd = _synctex_eq_deepest_container_v3(hitP,nds.r.node)).node) {
   8162                 nds.r = nd;
   8163             }
   8164             if((nd = __synctex_closest_deep_child_v2(hitP,nds.r.node)).node) {
   8165                 nds.r.node = nd.node;
   8166             }
   8167         }
   8168     }
   8169     return nds;
   8170 }
   8171 
   8172 #if 0
   8173 SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v3(synctex_point_p hitP, synctex_node_p nodeP) {
   8174     synctex_nd_s nd = SYNCTEX_ND_0;
   8175     synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
   8176     if ((nd.node = _synctex_tree_child(nodeP))) {
   8177         do {
   8178             nd = _synctex_point_h_ordered_distance_v2(hitP,nd.node);
   8179             if (nd.distance > 0) {
   8180                 /*  node is to the right of the hit point.
   8181                  *  We compare node and the previously recorded one, through the recorded distance.
   8182                  *  If the nodes have the same tag, prefer the one with the smallest line number,
   8183                  *  if the nodes also have the same line number, prefer the one with the smallest column. */
   8184                 if (nds.r.distance > nd.distance) {
   8185                     nds.r = nd;
   8186                 } else if (nds.r.distance == nd.distance && nds.r.node) {
   8187                     if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node)
   8188                         && (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node)
   8189                             || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node)
   8190                                 && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) {
   8191                                 nds.r = nd;
   8192                             }
   8193                 }
   8194             } else if (nd.distance == 0) {
   8195                 /*  hit point is inside node. */
   8196                 nds.l = nd;
   8197             } else { /*  here nd.d < 0, the hit point is to the right of node */
   8198                 nd.distance = -nd.distance;
   8199                 if (nds.l.distance > nd.distance) {
   8200                     nds.l = nd;
   8201                 } else if (nds.l.distance == nd.distance && nds.l.node) {
   8202                     if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node)
   8203                         && (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node)
   8204                             || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node)
   8205                                 && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) {
   8206                                 nds.l = nd;
   8207                             }
   8208                 }
   8209             }
   8210         } while((nd.node = __synctex_tree_sibling(nd.node)));
   8211         if (nds.l.node) {
   8212             /*  the left node is new, try to narrow the result */
   8213             if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.l.node))) {
   8214                 nds.l.node = nd.node;
   8215             }
   8216             if((nd = _synctex_eq_closest_child_v2(hitP,nds.l.node)).node) {
   8217                 nds.l.node = nd.node;
   8218             }
   8219         }
   8220         if (nds.r.node) {
   8221             /*  the right node is new, try to narrow the result */
   8222             if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.r.node))) {
   8223                 nds.r.node = nd.node;
   8224             }
   8225             if((nd = _synctex_eq_closest_child_v2(hitP,nds.r.node)).node) {
   8226                 nds.r.node = nd.node;
   8227             }
   8228         }
   8229     }
   8230     return nds;
   8231 }
   8232 #endif
   8233 SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_vbox_v2(synctex_point_p hitP, synctex_node_p nodeP) {
   8234     SYNCTEX_UNUSED(nodeP)
   8235     synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
   8236     synctex_nd_s nd = SYNCTEX_ND_0;
   8237     if ((nd.node = synctex_node_child(nd.node))) {
   8238         do {
   8239             nd = _synctex_point_v_ordered_distance_v2(hitP,nd.node);
   8240             /*  this is what makes the difference with the h version above */
   8241             if (nd.distance > 0) {
   8242                 /*  node is to the top of the hit point (below because TeX is oriented from top to bottom.
   8243                  *  We compare node and the previously recorded one, through the recorded distance.
   8244                  *  If the nodes have the same tag, prefer the one with the smallest line number,
   8245                  *  if the nodes also have the same line number, prefer the one with the smallest column. */
   8246                 if (nds.r.distance > nd.distance) {
   8247                     nds.r = nd;
   8248                 } else if (nds.r.distance == nd.distance && nds.r.node) {
   8249                     if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node)
   8250                         && (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node)
   8251                             || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node)
   8252                                 && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) {
   8253                                 nds.r = nd;
   8254                             }
   8255                 }
   8256             } else if (nd.distance == 0) {
   8257                 nds.l = nd;
   8258             } else { /*  here nd < 0 */
   8259                 nd.distance = -nd.distance;
   8260                 if (nds.l.distance > nd.distance) {
   8261                     nds.l = nd;
   8262                 } else if (nds.l.distance == nd.distance && nds.l.node) {
   8263                     if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node)
   8264                         && (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node)
   8265                             || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node)
   8266                                 && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) {
   8267                                 nds.l = nd;
   8268                             }
   8269                 }
   8270             }
   8271         } while((nd.node = synctex_node_sibling(nd.node)));
   8272         if (nds.l.node) {
   8273             if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.l.node))) {
   8274                 nds.l.node = nd.node;
   8275             }
   8276             if((nd = _synctex_eq_closest_child_v2(hitP,nds.l.node)).node) {
   8277                 nds.l.node = nd.node;
   8278             }
   8279         }
   8280         if (nds.r.node) {
   8281             if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.r.node))) {
   8282                 nds.r.node = nd.node;
   8283             }
   8284             if((nd = _synctex_eq_closest_child_v2(hitP,nds.r.node)).node) {
   8285                 nds.r.node = nd.node;
   8286             }
   8287         }
   8288     }
   8289     return nds;
   8290 }
   8291 
   8292 /**
   8293  *  Get the child closest to the hit point.
   8294  *  - parameter: hit point
   8295  *  - parameter: containing node
   8296  *  - returns: the child and the distance to the hit point.
   8297  *      SYNCTEX_ND_0 if the parameter node has no children.
   8298  *  - note: recursive call.
   8299  */
   8300 static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node) {
   8301     synctex_nd_s best = SYNCTEX_ND_0;
   8302     synctex_node_p child = NULL;
   8303     if ((child = synctex_node_child(node))) {
   8304 #if defined(SYNCTEX_DEBUG)
   8305         printf("Closest deep child on box at line %i\n",
   8306                SYNCTEX_LINEINDEX(node));
   8307 #endif
   8308         do {
   8309 #if SYNCTEX_DEBUG>500
   8310             synctex_node_display(child);
   8311 #endif
   8312             synctex_nd_s nd = SYNCTEX_ND_0;
   8313             if (_synctex_node_is_box(child)) {
   8314                 nd = __synctex_closest_deep_child_v2(hitP,child);
   8315             } else {
   8316                 nd = (synctex_nd_s) {child, _synctex_point_node_distance_v2(hitP,child)};
   8317             }
   8318             if (nd.distance < best.distance ||(nd.distance == best.distance
   8319                                                && synctex_node_type(nd.node) != synctex_node_type_kern)) {
   8320 #if defined(SYNCTEX_DEBUG)
   8321                 if(nd.node) {
   8322                     printf("New best %i<=%i line %i\n",nd.distance,
   8323                            best.distance,SYNCTEX_LINEINDEX(nd.node));
   8324                 }
   8325 #endif
   8326                 best = nd;
   8327             }
   8328         } while((child = synctex_node_sibling(child)));
   8329 #if defined(SYNCTEX_DEBUG)
   8330         if(best.node) {
   8331             printf("Found new best %i line %i\n",best.distance,SYNCTEX_LINEINDEX(best.node));
   8332         }
   8333 #endif
   8334     }
   8335     return best;
   8336 }
   8337 
   8338 /**
   8339  *  Return the closest child.
   8340  *  - parameter: a pointer to the hit point,
   8341  *  - parameter: the container
   8342  *  - return: SYNCTEX_ND_0 if node has no child,
   8343  *      the __synctex_closest_deep_child_v2 otherwise.
   8344  */
   8345 static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node) {
   8346     synctex_nd_s nd = SYNCTEX_ND_0;
   8347     if (_synctex_node_is_box(node)) {
   8348         nd = __synctex_closest_deep_child_v2(hitP, node);
   8349         if (_synctex_node_is_box(nd.node)) {
   8350             synctex_node_p child = NULL;
   8351             if ((child = synctex_node_child(nd.node))) {
   8352                 synctex_nd_s best = {child,_synctex_point_node_distance_v2(hitP,child)};
   8353                 while((child = synctex_node_sibling(child))) {
   8354                     int d = _synctex_point_node_distance_v2(hitP,child);
   8355                     if (d < best.distance) {
   8356                         best = (synctex_nd_s){child,d};
   8357                     } else if (d == best.distance && synctex_node_type(child) != synctex_node_type_kern) {
   8358                         best.node = child;
   8359                     }
   8360                 }
   8361                 return best;
   8362             }
   8363         }
   8364         return nd;
   8365     }
   8366     return SYNCTEX_ND_0;
   8367 }
   8368 SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node) {
   8369     synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
   8370     if(_synctex_tree_has_child(node)) { /* node != NULL */
   8371         if (node->class_->type==synctex_node_type_hbox ||
   8372             node->class_->type==synctex_node_type_proxy_hbox) {
   8373             return __synctex_eq_get_closest_children_in_hbox_v2(hitP,node);
   8374         } else {
   8375             return __synctex_eq_get_closest_children_in_vbox_v2(hitP,node);
   8376         }
   8377     }
   8378     return nds;
   8379 }
   8380 
   8381 #ifndef SYNCTEX_NO_UPDATER
   8382 
   8383 #	ifdef SYNCTEX_NOTHING
   8384 #       pragma mark -
   8385 #       pragma mark Updater
   8386 #   endif
   8387 
   8388 typedef int (*synctex_print_f)(synctex_updater_p, const char * , ...); /*  print formatted to either FILE *  or gzFile */
   8389 typedef void (*synctex_close_f)(synctex_updater_p); /*  close FILE *  or gzFile */
   8390 
   8391 #   define SYNCTEX_BITS_PER_BYTE 8
   8392 
   8393 typedef union {
   8394     gzFile as_gzFile;
   8395     FILE * as_FILE_p;
   8396     void * as_ptr;
   8397 } syncex_file_u;
   8398 
   8399 struct synctex_updater_t {
   8400     syncex_file_u file;
   8401     synctex_print_f print;
   8402     synctex_close_f close;
   8403     int length;             /*  the number of chars appended */
   8404 };
   8405 
   8406 static int _synctex_updater_print(synctex_updater_p updater, const char * format, ...) {
   8407     int result = 0;
   8408     if (updater) {
   8409         va_list va;
   8410         va_start(va, format);
   8411         result = vfprintf(updater->file.as_FILE_p,
   8412                            format,
   8413                            va);
   8414         va_end(va);
   8415     }
   8416     return result;
   8417 }
   8418 #if defined(_MSC_VER)
   8419 #include <stdio.h>
   8420 #include <stdlib.h>
   8421 #include <stdarg.h>
   8422 
   8423 static int vasprintf(char **ret,
   8424                      const char *format,
   8425                      va_list ap)
   8426 {
   8427     int len;
   8428     len = _vsnprintf(NULL, 0, format, ap);
   8429     if (len < 0) return -1;
   8430     *ret = malloc(len + 1);
   8431     if (!*ret) return -1;
   8432     _vsnprintf(*ret, len+1, format, ap);
   8433     (*ret)[len] = '\0';
   8434     return len;
   8435 }
   8436 
   8437 #endif
   8438 
   8439 /**
   8440  *  gzvprintf is not available until OSX 10.10
   8441  */
   8442 static int _synctex_updater_print_gz(synctex_updater_p updater, const char * format, ...) {
   8443     int result = 0;
   8444     if (updater) {
   8445         char * buffer;
   8446         va_list va;
   8447         va_start(va, format);
   8448         if (vasprintf(&buffer, format, va) < 0) {
   8449             _synctex_error("Out of memory...");
   8450         } else if ((result = (int)strlen(buffer))) {
   8451             result = gzwrite(updater->file.as_gzFile, buffer, (unsigned)result);
   8452         }
   8453         va_end(va);
   8454         free(buffer);
   8455     }
   8456     return result;
   8457 }
   8458 
   8459 static void _synctex_updater_close(synctex_updater_p updater) {
   8460     if (updater) {
   8461         fclose(updater->file.as_FILE_p);
   8462     }
   8463 }
   8464 
   8465 static void _synctex_updater_close_gz(synctex_updater_p updater) {
   8466     if (updater) {
   8467         gzclose(updater->file.as_gzFile);
   8468     }
   8469 }
   8470 
   8471 synctex_updater_p synctex_updater_new_with_output_file(const char * output, const char * build_directory) {
   8472     synctex_updater_p updater = NULL;
   8473     const char * mode = NULL;
   8474     synctex_open_s open;
   8475     /*  prepare the updater, the memory is the only one dynamically allocated */
   8476     updater = (synctex_updater_p)_synctex_malloc(sizeof(synctex_updater_s));
   8477     if (NULL == updater) {
   8478         _synctex_error("!  synctex_updater_new_with_file: malloc problem");
   8479         return NULL;
   8480     }
   8481     open = _synctex_open_v2(output,build_directory,0,synctex_ADD_QUOTES);
   8482     if (open.status < SYNCTEX_STATUS_OK) {
   8483         open = _synctex_open_v2(output,build_directory,0,synctex_DONT_ADD_QUOTES);
   8484         if (open.status < SYNCTEX_STATUS_OK) {
   8485         return_on_error:
   8486             _synctex_free(updater);
   8487             return updater = NULL;
   8488         }
   8489     }
   8490     /*  OK, the file exists, we close it and reopen it with the correct mode.
   8491      *  The receiver is now the owner of the "synctex" variable. */
   8492     gzclose(open.file);
   8493     updater->file.as_ptr = NULL;
   8494     mode = _synctex_get_io_mode_name(open.io_mode|synctex_io_append_mask);/* either "a" or "ab", depending on the file extension */
   8495     if (open.io_mode&synctex_io_gz_mask) {
   8496         if (NULL == (updater->file.as_FILE_p = fopen(open.synctex,mode))) {
   8497         no_write_error:
   8498             _synctex_error("!  synctex_updater_new_with_file: Can't append to %s",open.synctex);
   8499             free(open.synctex);
   8500             goto return_on_error;
   8501         }
   8502         updater->print = &_synctex_updater_print;
   8503         updater->close = &_synctex_updater_close;
   8504     } else {
   8505         if (NULL == (updater->file.as_gzFile = gzopen(open.synctex,mode))) {
   8506             goto no_write_error;
   8507         }
   8508         updater->print = &_synctex_updater_print_gz;
   8509         updater->close = &_synctex_updater_close_gz;
   8510     }
   8511     printf("SyncTeX: updating %s...",open.synctex);
   8512     _synctex_free(open.synctex);
   8513     return updater;
   8514 }
   8515 
   8516 void synctex_updater_append_magnification(synctex_updater_p updater, char * magnification){
   8517     if (NULL==updater) {
   8518         return;
   8519     }
   8520     if (magnification && strlen(magnification)) {
   8521         updater->length +=
   8522         updater->print(updater,"Magnification:%s\n",magnification);
   8523     }
   8524 }
   8525 
   8526 void synctex_updater_append_x_offset(synctex_updater_p updater, char * x_offset){
   8527     if (NULL==updater) {
   8528         return;
   8529     }
   8530     if (x_offset && strlen(x_offset)) {
   8531         updater->length += updater->print(updater,"X Offset:%s\n",x_offset);
   8532     }
   8533 }
   8534 
   8535 void synctex_updater_append_y_offset(synctex_updater_p updater, char * y_offset){
   8536     if (NULL==updater) {
   8537         return;
   8538     }
   8539     if (y_offset && strlen(y_offset)) {
   8540         updater->length += updater->print(updater,"Y Offset:%s\n",y_offset);
   8541     }
   8542 }
   8543 
   8544 void synctex_updater_free(synctex_updater_p updater){
   8545     if (NULL==updater) {
   8546         return;
   8547     }
   8548     if (updater->length>0) {
   8549         updater->print(updater,"!%i\n",updater->length);
   8550     }
   8551     updater->close(updater);
   8552     _synctex_free(updater);
   8553     printf("... done.\n");
   8554     return;
   8555 }
   8556 #endif
   8557 
   8558 #if defined(SYNCTEX_TESTING)
   8559 #	ifdef SYNCTEX_NOTHING
   8560 #       pragma mark -
   8561 #       pragma mark Testers
   8562 #   endif
   8563 static int _synctex_input_copy_name(synctex_node_p input, char * name) {
   8564     char * copy = _synctex_malloc(strlen(name)+1);
   8565     memcpy(copy,name,strlen(name)+1);
   8566     _synctex_data_set_name(input,copy);
   8567     return 0;
   8568 }
   8569 int synctex_test_setup_scanner_sheets_421(synctex_scanner_p scanner) {
   8570     int TC = 0;
   8571     synctex_node_p sheet = synctex_node_new(scanner,synctex_node_type_sheet);
   8572     _synctex_data_set_page(sheet,4);
   8573     SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==4,"");
   8574     synctex_node_free(scanner->sheet);
   8575     scanner->sheet = sheet;
   8576     sheet = synctex_node_new(scanner,synctex_node_type_sheet);
   8577     _synctex_data_set_page(sheet,2);
   8578     SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==2,"");
   8579     __synctex_tree_set_sibling(sheet, scanner->sheet);
   8580     scanner->sheet = sheet;
   8581     sheet = synctex_node_new(scanner,synctex_node_type_sheet);
   8582     _synctex_data_set_page(sheet,1);
   8583     SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==1,"");
   8584     __synctex_tree_set_sibling(sheet, scanner->sheet);
   8585     scanner->sheet = sheet;
   8586     return TC;
   8587 }
   8588 int synctex_test_input(synctex_scanner_p scanner) {
   8589     int TC = 0;
   8590     synctex_node_p input = synctex_node_new(scanner,synctex_node_type_input);
   8591     _synctex_data_set_tag(input,421);
   8592     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==421,"");
   8593     _synctex_data_set_tag(input,124);
   8594     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==124,"");
   8595     _synctex_data_set_line(input,421);
   8596     SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==421,"");
   8597     _synctex_data_set_line(input,214);
   8598     SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==214,"");
   8599     _synctex_data_set_line(input,214);
   8600     SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==214,"");
   8601     _synctex_input_copy_name(input,"214");
   8602     SYNCTEX_TEST_BODY(TC, 0==memcmp(_synctex_data_name(input),"214",4),"");
   8603     _synctex_input_copy_name(input,"421421");
   8604 
   8605     SYNCTEX_TEST_BODY(TC,
   8606                       0==memcmp(_synctex_data_name(input),
   8607                                 "421421",
   8608                                 4),
   8609                       "");
   8610     synctex_node_free(input);
   8611     return TC;
   8612 }
   8613 int synctex_test_proxy(synctex_scanner_p scanner) {
   8614     int TC = 0;
   8615     synctex_node_p proxy = synctex_node_new(scanner,synctex_node_type_proxy);
   8616     synctex_node_p target = synctex_node_new(scanner,synctex_node_type_rule);
   8617     _synctex_tree_set_target(proxy,target);
   8618     _synctex_data_set_tag(target,421);
   8619     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==421,"");
   8620     SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==421,"");
   8621     SYNCTEX_TEST_BODY(TC, synctex_node_tag(proxy)==421,"");
   8622     synctex_node_free(proxy);
   8623     synctex_node_free(target);
   8624     return TC;
   8625 }
   8626 int synctex_test_handle(synctex_scanner_p scanner) {
   8627     int TC = 0;
   8628     synctex_node_p handle = synctex_node_new(scanner,synctex_node_type_handle);
   8629     synctex_node_p proxy = synctex_node_new(scanner, synctex_node_type_proxy);
   8630     synctex_node_p target = synctex_node_new(scanner,synctex_node_type_rule);
   8631     _synctex_tree_set_target(handle,target);
   8632     _synctex_data_set_tag(target,421);
   8633     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==421,"");
   8634     SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==421,"");
   8635     SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle)==421,"");
   8636     _synctex_data_set_line(target,214);
   8637     SYNCTEX_TEST_BODY(TC, _synctex_data_line(target)==214,"");
   8638     SYNCTEX_TEST_BODY(TC, synctex_node_line(target)==214,"");
   8639     SYNCTEX_TEST_BODY(TC, synctex_node_line(handle)==214,"");
   8640     _synctex_data_set_column(target,142);
   8641     SYNCTEX_TEST_BODY(TC, _synctex_data_column(target)==142,"");
   8642     SYNCTEX_TEST_BODY(TC, synctex_node_column(target)==142,"");
   8643     SYNCTEX_TEST_BODY(TC, synctex_node_column(handle)==142,"");
   8644     _synctex_tree_set_target(proxy,target);
   8645     _synctex_tree_set_target(handle,proxy);
   8646     _synctex_data_set_tag(target,412);
   8647     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==412,"");
   8648     SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==412,"");
   8649     SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle)==412,"");
   8650     _synctex_data_set_line(target,124);
   8651     SYNCTEX_TEST_BODY(TC, _synctex_data_line(target)==124,"");
   8652     SYNCTEX_TEST_BODY(TC, synctex_node_line(target)==124,"");
   8653     SYNCTEX_TEST_BODY(TC, synctex_node_line(handle)==124,"");
   8654     _synctex_data_set_column(target,241);
   8655     SYNCTEX_TEST_BODY(TC, _synctex_data_column(target)==241,"");
   8656     SYNCTEX_TEST_BODY(TC, synctex_node_column(target)==241,"");
   8657     SYNCTEX_TEST_BODY(TC, synctex_node_column(handle)==241,"");
   8658     synctex_node_free(handle);
   8659     synctex_node_free(proxy);
   8660     synctex_node_free(target);
   8661     return TC;
   8662 }
   8663 int synctex_test_setup_scanner_input(synctex_scanner_p scanner) {
   8664     int TC = 0;
   8665     synctex_node_p input = synctex_node_new(scanner,synctex_node_type_input);
   8666     _synctex_data_set_tag(input,4);
   8667     _synctex_input_copy_name(input,"21");
   8668     _synctex_data_set_line(input,421);
   8669     synctex_node_free(scanner->input);
   8670     scanner->input = input;
   8671     SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==4,"");
   8672     SYNCTEX_TEST_BODY(TC, strcmp(_synctex_data_name(input),"21")==0,"");
   8673     SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==421,"");
   8674     return TC;
   8675 }
   8676 int synctex_test_setup_nodes(synctex_scanner_p scanner, synctex_node_r nodes) {
   8677     int TC = 0;
   8678     int n;
   8679     for (n=0;n<synctex_node_number_of_types;++n) {
   8680         nodes[n] = synctex_node_new(scanner,n);
   8681         SYNCTEX_TEST_BODY(TC, nodes[n]!=NULL,"");
   8682     }
   8683     return TC;
   8684 }
   8685 int synctex_test_teardown_nodes(synctex_scanner_p scanner, synctex_node_r nodes) {
   8686     int n;
   8687     for (n=0;n<synctex_node_number_of_types;++n) {
   8688         synctex_node_free(nodes[n]);
   8689         nodes[n]=NULL;
   8690     }
   8691     return 1;
   8692 }
   8693 int synctex_test_tree(synctex_scanner_p scanner) {
   8694     int TC = 0;
   8695     synctex_node_p nodes1[synctex_node_number_of_types];
   8696     synctex_node_p nodes2[synctex_node_number_of_types];
   8697     synctex_node_p nodes3[synctex_node_number_of_types];
   8698     int i,j;
   8699     TC += synctex_test_setup_nodes(scanner,nodes1);
   8700     TC += synctex_test_setup_nodes(scanner,nodes2);
   8701     TC += synctex_test_setup_nodes(scanner,nodes3);
   8702     /*  Every node has a sibling */
   8703     for (i=0;i<synctex_node_number_of_types;++i) {
   8704         for (j=0;j<synctex_node_number_of_types;++j) {
   8705             _synctex_tree_set_sibling(nodes1[i],nodes2[i]);
   8706             SYNCTEX_TEST_BODY(TC, nodes2[i]==synctex_node_sibling(nodes1[i]),"");
   8707         }
   8708     }
   8709     synctex_test_teardown_nodes(scanner,nodes3);
   8710     synctex_test_teardown_nodes(scanner,nodes2);
   8711     synctex_test_teardown_nodes(scanner,nodes1);
   8712     return TC;
   8713 }
   8714 int synctex_test_page(synctex_scanner_p scanner) {
   8715     int TC = synctex_test_setup_scanner_sheets_421(scanner);
   8716     synctex_node_p sheet = scanner->sheet;
   8717     synctex_node_p node = synctex_node_new(scanner,synctex_node_type_rule);
   8718     _synctex_data_set_tag(node,4);
   8719     _synctex_data_set_line(node,21);
   8720     synctex_node_free(_synctex_node_set_child(sheet,node));
   8721     SYNCTEX_TEST_BODY(TC, synctex_node_page(node)==synctex_node_page(sheet),"");
   8722     return TC;
   8723 }
   8724 int synctex_test_display_query(synctex_scanner_p scanner) {
   8725     int TC = synctex_test_setup_scanner_sheets_421(scanner);
   8726     synctex_node_p sheet = scanner->sheet;
   8727     synctex_node_p node = synctex_node_new(scanner,synctex_node_type_rule);
   8728     _synctex_data_set_tag(node,4);
   8729     _synctex_data_set_line(node,21);
   8730     synctex_node_free(_synctex_node_set_child(sheet,node));
   8731     SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
   8732     __synctex_node_make_friend_tlc(node);
   8733     SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25)==node,"");
   8734     sheet = __synctex_tree_sibling(sheet);
   8735     node = synctex_node_new(scanner,synctex_node_type_rule);
   8736     _synctex_data_set_tag(node,4);
   8737     _synctex_data_set_line(node,21);
   8738     synctex_node_free(_synctex_node_set_child(sheet,node));
   8739     SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
   8740     __synctex_node_make_friend_tlc(node);
   8741     SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25)==node,"");
   8742     sheet = __synctex_tree_sibling(sheet);
   8743     node = synctex_node_new(scanner,synctex_node_type_rule);
   8744     _synctex_data_set_tag(node,4);
   8745     _synctex_data_set_line(node,21);
   8746     synctex_node_free(_synctex_node_set_child(sheet,node));
   8747     SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
   8748     __synctex_node_make_friend_tlc(node);
   8749     SYNCTEX_TEST_BODY(TC, (_synctex_scanner_friend(scanner, 25)==node),"");
   8750     synctex_test_setup_scanner_input(scanner);
   8751     scanner->flags.has_parsed = synctex_YES;
   8752 #if 1
   8753     SYNCTEX_TEST_BODY(TC, (synctex_display_query(scanner,"21",21,4,-1)==3),"");
   8754 #endif
   8755     return TC;
   8756 }
   8757 typedef struct {
   8758     int s;      /* status */
   8759     char n[25]; /* name */
   8760 } synctex_test_sn_s;
   8761 
   8762 synctex_test_sn_s synctex_test_tmp_sn(char * content) {
   8763     synctex_test_sn_s sn = {0, "/tmp/test.XXXXXX.synctex"};
   8764     FILE *sfp;
   8765     int fd = mkstemps(sn.n,8);
   8766     if (fd < 0) {
   8767         fprintf(stderr, "%s: %s\n", sn.n, strerror(errno));
   8768         sn.s = -1;
   8769         return sn;
   8770     }
   8771     if ((sfp = fdopen(fd, "w+")) == NULL) {
   8772         unlink(sn.n);
   8773         close(fd);
   8774         fprintf(stderr, "%s: %s\n", sn.n, strerror(errno));
   8775         sn.s = -2;
   8776         return sn;
   8777     }
   8778     sn.s = fputs(content,sfp);
   8779     printf("temp:%s\n%i\n",sn.n,sn.s);
   8780     fclose(sfp);
   8781     if (sn.s==0) {
   8782         sn.s = -2;
   8783         unlink(sn.n);
   8784     }
   8785     return sn;
   8786 }
   8787 int synctex_test_sheet_1() {
   8788     int TC = 0;
   8789     char * content =
   8790     "SyncTeX Version:1  \n" /*00-19*/
   8791     "Input:1:./1.tex    \n" /*20-39*/
   8792     "Output:pdf         \n" /*40-59*/
   8793     "Magnification:100000000      \n" /*60-89*/
   8794     "Unit:1   \n"           /*90-99*/
   8795     "X Offset:0         \n" /*00-19*/
   8796     "Y Offset:0         \n" /*20-39*/
   8797     "Content: \n"           /*40-49*/
   8798     "{1       \n"           /*50-59*/
   8799     "[1,10:20,350:330,330,0       \n" /*60-89*/
   8800     "]        \n"           /*90-99*/
   8801     "}        \n"           /*00-09*/
   8802     "Postamble:\n";
   8803     synctex_test_sn_s sn = synctex_test_tmp_sn(content);
   8804     if (sn.s>0) {
   8805         synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
   8806         synctex_node_p node = synctex_scanner_handle(scanner);
   8807         printf("Created nodes:\n");
   8808         while (node) {
   8809             printf("%s\n",_synctex_node_abstract(node));
   8810             node = synctex_node_next(node);
   8811         }
   8812         synctex_scanner_free(scanner);
   8813         unlink(sn.n);
   8814     } else {
   8815         ++TC;
   8816     }
   8817     return TC;
   8818 }
   8819 int synctex_test_sheet_2() {
   8820     int TC = 0;
   8821     char * content =
   8822     "SyncTeX Version:1  \n" /*00-19*/
   8823     "Input:1:./1.tex    \n" /*20-39*/
   8824     "Output:pdf         \n" /*40-59*/
   8825     "Magnification:100000000      \n" /*60-89*/
   8826     "Unit:1   \n"           /*90-99*/
   8827     "X Offset:0         \n" /*00-19*/
   8828     "Y Offset:0         \n" /*20-39*/
   8829     "Content: \n"           /*40-49*/
   8830     "{1       \n"           /*50-59*/
   8831     "(1,10:20,350:330,330,0       \n" /*60-89*/
   8832     ")        \n"           /*90-99*/
   8833     "}        \n"           /*00-09*/
   8834     "Postamble:\n";
   8835     synctex_test_sn_s sn = synctex_test_tmp_sn(content);
   8836     if (sn.s>0) {
   8837         synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
   8838         synctex_node_p node = synctex_scanner_handle(scanner);
   8839         printf("Created nodes:\n");
   8840         while (node) {
   8841             printf("%s\n",_synctex_node_abstract(node));
   8842             node = _synctex_node_next(node);
   8843         }
   8844         TC += synctex_scanner_free(scanner);
   8845         unlink(sn.n);
   8846     } else {
   8847         ++TC;
   8848     }
   8849     return TC;
   8850 }
   8851 int synctex_test_charindex() {
   8852     int TC = 0;
   8853     char * content =
   8854     "SyncTeX Version:1  \n" /*00-19*/
   8855     "Input:1:./1.tex    \n" /*20-39*/
   8856     "Output:pdf         \n" /*40-59*/
   8857     "Magnification:100000000      \n" /*60-89*/
   8858     "Unit:1   \n"           /*90-99*/
   8859     "X Offset:0         \n" /*00-19*/
   8860     "Y Offset:0         \n" /*20-39*/
   8861     "Content: \n"           /*40-49*/
   8862     "{1       \n"           /*50-59*/
   8863     "[1,10:20,350:330,330,0       \n" /*60-89*/
   8864     "(1,58:20,100:250,10,5        \n" /*90-119*/
   8865     "f1000:50,100       \n" /*20-39*/
   8866     ")        \n"           /*40-49*/
   8867     "]        \n"           /*50-59*/
   8868     "}        \n"           /*60-69*/
   8869     "Postamble:\n";
   8870     synctex_test_sn_s sn = synctex_test_tmp_sn(content);
   8871     if (sn.s>0) {
   8872         synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
   8873         synctex_node_p node = synctex_scanner_handle(scanner);
   8874         printf("Created nodes:\n");
   8875         while (node) {
   8876             printf("%s\n",_synctex_node_abstract(node));
   8877             node = synctex_node_next(node);
   8878         }
   8879         TC += synctex_scanner_free(scanner);
   8880         unlink(sn.n);
   8881     } else {
   8882         ++TC;
   8883     }
   8884     return TC;
   8885 }
   8886 int synctex_test_form() {
   8887     int TC = 0;
   8888     char * content =
   8889     "SyncTeX Version:1  \n" /*00-19*/
   8890     "Input:1:./1.tex    \n" /*20-39*/
   8891     "Output:pdf         \n" /*40-59*/
   8892     "Magnification:100000000      \n" /*60-89*/
   8893     "Unit:1   \n"           /*90-99*/
   8894     "X Offset:0         \n" /*00-19*/
   8895     "Y Offset:0         \n" /*20-39*/
   8896     "Content: \n"           /*40-49*/
   8897     "{1       \n"           /*50-59*/
   8898     "[1,10:20,350:330,330,0       \n" /*60-89*/
   8899     "(1,58:20,100:250,10,5        \n" /*90-119*/
   8900     "f1000:50,100       \n" /*20-39*/
   8901     ")        \n"           /*40-49*/
   8902     "]        \n"           /*50-59*/
   8903     "}        \n"           /*60-69*/
   8904     "<1000    \n"           /*70-79*/
   8905     "(1,63:0,0:100,8,3  \n" /*80-99*/
   8906     ")        \n"           /*00-09*/
   8907     ">        \n"           /*10-19*/
   8908     "Postamble:\n";
   8909     synctex_test_sn_s sn = synctex_test_tmp_sn(content);
   8910     if (sn.s>0) {
   8911         synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
   8912         synctex_node_p node = synctex_scanner_handle(scanner);
   8913         while (node) {
   8914             printf("%s\n",_synctex_node_abstract(node));
   8915             node = _synctex_node_next(node);
   8916         }
   8917         TC += synctex_scanner_free(scanner);
   8918         unlink(sn.n);
   8919     } else {
   8920         ++TC;
   8921     }
   8922     return TC;
   8923 }
   8924 #endif