File indexing completed on 2024-05-12 04:33:36
0001 /* 0002 SPDX-FileCopyrightText: 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr 0003 SPDX-License-Identifier: X11 0004 0005 This file is part of the __SyncTeX__ package. 0006 0007 [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) 0008 [//]: # (Version: 1.19) 0009 0010 See `synctex_parser_readme.md` for more details 0011 */ 0012 0013 #include "synctex_parser.h" 0014 #include "synctex_parser_utils.h" 0015 0016 #ifndef __SYNCTEX_PARSER_PRIVATE__ 0017 #define __SYNCTEX_PARSER_PRIVATE__ 0018 0019 #ifdef __cplusplus 0020 extern "C" { 0021 #endif 0022 /* Reminder that the argument must not be NULL */ 0023 typedef synctex_node_p synctex_non_null_node_p; 0024 0025 /* Each node of the tree, except the scanner itself belongs to a class. 0026 * The class object is just a struct declaring the owning scanner 0027 * This is a pointer to the scanner as root of the tree. 0028 * The type is used to identify the kind of node. 0029 * The class declares pointers to a creator and a destructor method. 0030 * The log and display fields are used to log and display the node. 0031 * display will also display the child, sibling and parent sibling. 0032 * parent, child and sibling are used to navigate the tree, 0033 * from TeX box hierarchy point of view. 0034 * The friend field points to a method which allows to navigate from friend to friend. 0035 * A friend is a node with very close tag and line numbers. 0036 * Finally, the info field point to a method giving the private node info offset. 0037 */ 0038 0039 /** 0040 * These are the masks for the synctex node types. 0041 * int's are 32 bits at least. 0042 */ 0043 enum { synctex_shift_root, synctex_shift_no_root, synctex_shift_void, synctex_shift_no_void, synctex_shift_box, synctex_shift_no_box, synctex_shift_proxy, synctex_shift_no_proxy, synctex_shift_h, synctex_shift_v }; 0044 enum { 0045 synctex_mask_root = 1, 0046 synctex_mask_no_root = synctex_mask_root << 1, 0047 synctex_mask_void = synctex_mask_no_root << 1, 0048 synctex_mask_no_void = synctex_mask_void << 1, 0049 synctex_mask_box = synctex_mask_no_void << 1, 0050 synctex_mask_no_box = synctex_mask_box << 1, 0051 synctex_mask_proxy = synctex_mask_no_box << 1, 0052 synctex_mask_no_proxy = synctex_mask_proxy << 1, 0053 synctex_mask_h = synctex_mask_no_proxy << 1, 0054 synctex_mask_v = synctex_mask_h << 1, 0055 }; 0056 enum { synctex_mask_non_void_hbox = synctex_mask_no_void | synctex_mask_box | synctex_mask_h, synctex_mask_non_void_vbox = synctex_mask_no_void | synctex_mask_box | synctex_mask_v }; 0057 typedef enum { 0058 synctex_node_mask_sf = synctex_mask_root | synctex_mask_no_void | synctex_mask_no_box | synctex_mask_no_proxy, 0059 synctex_node_mask_vbox = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_v, 0060 synctex_node_mask_hbox = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_h, 0061 synctex_node_mask_void_vbox = synctex_mask_no_root | synctex_mask_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_v, 0062 synctex_node_mask_void_hbox = synctex_mask_no_root | synctex_mask_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_h, 0063 synctex_node_mask_vbox_proxy = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_proxy | synctex_mask_v, 0064 synctex_node_mask_hbox_proxy = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_proxy | synctex_mask_h, 0065 synctex_node_mask_nvnn = synctex_mask_no_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_no_proxy, 0066 synctex_node_mask_input = synctex_mask_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_no_proxy, 0067 synctex_node_mask_proxy = synctex_mask_no_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_proxy 0068 } synctex_node_mask_t; 0069 0070 enum { 0071 /* input */ 0072 synctex_tree_sibling_idx = 0, 0073 synctex_tree_s_input_max = 1, 0074 /* All */ 0075 synctex_tree_s_parent_idx = 1, 0076 synctex_tree_sp_child_idx = 2, 0077 synctex_tree_spc_friend_idx = 3, 0078 synctex_tree_spcf_last_idx = 4, 0079 synctex_tree_spcfl_vbox_max = 5, 0080 /* hbox supplement */ 0081 synctex_tree_spcfl_next_hbox_idx = 5, 0082 synctex_tree_spcfln_hbox_max = 6, 0083 /* hbox proxy supplement */ 0084 synctex_tree_spcfln_target_idx = 6, 0085 synctex_tree_spcflnt_proxy_hbox_max = 7, 0086 /* vbox proxy supplement */ 0087 synctex_tree_spcfl_target_idx = 5, 0088 synctex_tree_spcflt_proxy_vbox_max = 6, 0089 /* spf supplement*/ 0090 synctex_tree_sp_friend_idx = 2, 0091 synctex_tree_spf_max = 3, 0092 /* box boundary supplement */ 0093 synctex_tree_spf_arg_sibling_idx = 3, 0094 synctex_tree_spfa_max = 4, 0095 /* proxy supplement */ 0096 synctex_tree_spf_target_idx = 3, 0097 synctex_tree_spft_proxy_max = 4, 0098 /* last proxy supplement */ 0099 synctex_tree_spfa_target_idx = 4, 0100 synctex_tree_spfat_proxy_last_max = 5, 0101 /* sheet supplement */ 0102 synctex_tree_s_child_idx = 1, 0103 synctex_tree_sc_next_hbox_idx = 2, 0104 synctex_tree_scn_sheet_max = 3, 0105 /* form supplement */ 0106 synctex_tree_sc_target_idx = 2, 0107 synctex_tree_sct_form_max = 3, 0108 /* spct */ 0109 synctex_tree_spc_target_idx = 3, 0110 synctex_tree_spct_handle_max = 4, 0111 }; 0112 0113 enum { 0114 /* input */ 0115 synctex_data_input_tag_idx = 0, 0116 synctex_data_input_line_idx = 1, 0117 synctex_data_input_name_idx = 2, 0118 synctex_data_input_tln_max = 3, 0119 /* sheet */ 0120 synctex_data_sheet_page_idx = 0, 0121 synctex_data_p_sheet_max = 1, 0122 /* form */ 0123 synctex_data_form_tag_idx = 0, 0124 synctex_data_t_form_max = 1, 0125 /* tlchv */ 0126 synctex_data_tag_idx = 0, 0127 synctex_data_line_idx = 1, 0128 synctex_data_column_idx = 2, 0129 synctex_data_h_idx = 3, 0130 synctex_data_v_idx = 4, 0131 synctex_data_tlchv_max = 5, 0132 /* tlchvw */ 0133 synctex_data_width_idx = 5, 0134 synctex_data_tlchvw_max = 6, 0135 /* box */ 0136 synctex_data_height_idx = 6, 0137 synctex_data_depth_idx = 7, 0138 synctex_data_box_max = 8, 0139 /* hbox supplement */ 0140 synctex_data_mean_line_idx = 8, 0141 synctex_data_weight_idx = 9, 0142 synctex_data_h_V_idx = 10, 0143 synctex_data_v_V_idx = 11, 0144 synctex_data_width_V_idx = 12, 0145 synctex_data_height_V_idx = 13, 0146 synctex_data_depth_V_idx = 14, 0147 synctex_data_hbox_max = 15, 0148 /* ref */ 0149 synctex_data_ref_tag_idx = 0, 0150 synctex_data_ref_h_idx = 1, 0151 synctex_data_ref_v_idx = 2, 0152 synctex_data_ref_thv_max = 3, 0153 /* proxy */ 0154 synctex_data_proxy_h_idx = 0, 0155 synctex_data_proxy_v_idx = 1, 0156 synctex_data_proxy_hv_max = 2, 0157 }; 0158 0159 /* each synctex node has a class */ 0160 typedef struct synctex_class_t synctex_class_s; 0161 typedef synctex_class_s *synctex_class_p; 0162 0163 /* synctex_node_p is a pointer to a node 0164 * synctex_node_s is the target of the synctex_node_p pointer 0165 * It is a pseudo object oriented program. 0166 * class is a pointer to the class object the node belongs to. 0167 * implementation is meant to contain the private data of the node 0168 * basically, there are 2 kinds of information: navigation information and 0169 * synctex information. Both will depend on the type of the node, 0170 * thus different nodes will have different private data. 0171 * There is no inheritancy overhead. 0172 */ 0173 typedef union { 0174 synctex_node_p as_node; 0175 int as_integer; 0176 char *as_string; 0177 void *as_pointer; 0178 } synctex_data_u; 0179 typedef synctex_data_u *synctex_data_p; 0180 0181 #if defined(SYNCTEX_USE_CHARINDEX) 0182 typedef unsigned int synctex_charindex_t; 0183 synctex_charindex_t synctex_node_charindex(synctex_node_p node); 0184 typedef synctex_charindex_t synctex_lineindex_t; 0185 synctex_lineindex_t synctex_node_lineindex(synctex_node_p node); 0186 synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner); 0187 #define SYNCTEX_DECLARE_CHARINDEX \ 0188 synctex_charindex_t char_index; \ 0189 synctex_lineindex_t line_index; 0190 #define SYNCTEX_DECLARE_CHAR_OFFSET synctex_charindex_t charindex_offset; 0191 #else 0192 #define SYNCTEX_DECLARE_CHARINDEX 0193 #define SYNCTEX_DECLARE_CHAR_OFFSET 0194 #endif 0195 struct synctex_node_t { 0196 SYNCTEX_DECLARE_CHARINDEX 0197 synctex_class_p class; 0198 #ifdef DEBUG 0199 synctex_data_u data[22]; 0200 #else 0201 synctex_data_u data[1]; 0202 #endif 0203 }; 0204 0205 typedef synctex_node_p *synctex_node_r; 0206 0207 typedef struct { 0208 int h; 0209 int v; 0210 } synctex_point_s; 0211 0212 typedef synctex_point_s *synctex_point_p; 0213 0214 typedef struct { 0215 synctex_point_s min; /* top left */ 0216 synctex_point_s max; /* bottom right */ 0217 } synctex_box_s; 0218 0219 typedef synctex_box_s *synctex_box_p; 0220 /** 0221 * These are the types of the synctex nodes. 0222 * No need to use them but the compiler needs them here. 0223 * There are 3 kinds of nodes. 0224 * - primary nodes 0225 * - proxies 0226 * - handles 0227 * Primary nodes are created at parse time 0228 * of the synctex file. 0229 * Proxies are used to support pdf forms. 0230 * The ref primary nodes are replaced by a tree 0231 * of proxy nodes which duplicate the tree of primary 0232 * nodes available in the referred form. 0233 * Roughly speaking, the primary nodes of the form 0234 * know what to display, the proxy nodes know where. 0235 * Handles are used in queries. They point to either 0236 * primary nodes or proxies. 0237 */ 0238 typedef enum { 0239 synctex_node_type_none = 0, 0240 synctex_node_type_input, 0241 synctex_node_type_sheet, 0242 synctex_node_type_form, 0243 synctex_node_type_ref, 0244 synctex_node_type_vbox, 0245 synctex_node_type_void_vbox, 0246 synctex_node_type_hbox, 0247 synctex_node_type_void_hbox, 0248 synctex_node_type_kern, 0249 synctex_node_type_glue, 0250 synctex_node_type_rule, 0251 synctex_node_type_math, 0252 synctex_node_type_boundary, 0253 synctex_node_type_box_bdry, 0254 synctex_node_type_proxy, 0255 synctex_node_type_proxy_last, 0256 synctex_node_type_proxy_vbox, 0257 synctex_node_type_proxy_hbox, 0258 synctex_node_type_handle, 0259 synctex_node_number_of_types 0260 } synctex_node_type_t; 0261 /* synctex_node_type gives the type of a given node, 0262 * synctex_node_isa gives the same information as a human readable text. */ 0263 synctex_node_type_t synctex_node_type(synctex_node_p node); 0264 const char *synctex_node_isa(synctex_node_p node); 0265 0266 synctex_node_type_t synctex_node_target_type(synctex_node_p node); 0267 0268 synctex_node_type_t synctex_node_type(synctex_node_p node); 0269 const char *synctex_node_isa(synctex_node_p node); 0270 0271 void synctex_node_log(synctex_node_p node); 0272 void synctex_node_display(synctex_node_p node); 0273 0274 /* Given a node, access to the location in the synctex file where it is defined. 0275 */ 0276 0277 int synctex_node_form_tag(synctex_node_p node); 0278 0279 int synctex_node_mean_line(synctex_node_p node); 0280 int synctex_node_weight(synctex_node_p node); 0281 int synctex_node_child_count(synctex_node_p node); 0282 0283 int synctex_node_h(synctex_node_p node); 0284 int synctex_node_v(synctex_node_p node); 0285 int synctex_node_width(synctex_node_p node); 0286 0287 int synctex_node_box_h(synctex_node_p node); 0288 int synctex_node_box_v(synctex_node_p node); 0289 int synctex_node_box_width(synctex_node_p node); 0290 int synctex_node_box_height(synctex_node_p node); 0291 int synctex_node_box_depth(synctex_node_p node); 0292 0293 int synctex_node_hbox_h(synctex_node_p node); 0294 int synctex_node_hbox_v(synctex_node_p node); 0295 int synctex_node_hbox_width(synctex_node_p node); 0296 int synctex_node_hbox_height(synctex_node_p node); 0297 int synctex_node_hbox_depth(synctex_node_p node); 0298 0299 synctex_scanner_p synctex_scanner_new(); 0300 synctex_node_p synctex_node_new(synctex_scanner_p scanner, synctex_node_type_t type); 0301 0302 /** 0303 * Scanner display switcher getter. 0304 * If the switcher is 0, synctex_node_display is disabled. 0305 * If the switcher is <0, synctex_node_display has no limit. 0306 * If the switcher is >0, only the first switcher (as number) nodes are displayed. 0307 * - parameter: a scanner 0308 * - returns: an integer 0309 */ 0310 int synctex_scanner_display_switcher(synctex_scanner_p scanR); 0311 void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher); 0312 0313 /** 0314 * Iterator is the structure used to traverse 0315 * the answer to client queries. 0316 * First answers are the best matches, according 0317 * to criteria explained below. 0318 * Next answers are not ordered. 0319 * Objects are handles to nodes in the synctex node tree starting at scanner. 0320 */ 0321 typedef struct synctex_iterator_t synctex_iterator_s; 0322 typedef synctex_iterator_s *synctex_iterator_p; 0323 0324 /** 0325 * Designated creator for a display query, id est, 0326 * forward navigation from source to output. 0327 * Returns NULL if the query has no answer. 0328 * Code example: 0329 * synctex_iterator_p iterator = NULL; 0330 * if ((iterator = synctex_iterator_new_display(...)) { 0331 * synctex_node_p node = NULL; 0332 * while((node = synctex_iterator_next_result(iterator))) { 0333 * do something with node... 0334 * } 0335 */ 0336 synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint); 0337 /** 0338 * Designated creator for an edit query, id est, 0339 * backward navigation from output to source. 0340 * Code example: 0341 * synctex_iterator_p iterator = NULL; 0342 * if ((iterator = synctex_iterator_new_edit(...)) { 0343 * synctex_node_p node = NULL; 0344 * while((node = synctex_iterator_next_result(iterator))) { 0345 * do something with node... 0346 * } 0347 */ 0348 synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner, int page, float h, float v); 0349 /** 0350 * Free all the resources. 0351 * - argument iterator: the object to free... 0352 * You should free the iterator before the scanner 0353 * owning the nodes it iterates with. 0354 */ 0355 void synctex_iterator_free(synctex_iterator_p iterator); 0356 /** 0357 * Whether the iterator actually points to an object. 0358 * - argument iterator: the object to iterate on... 0359 */ 0360 synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator); 0361 /** 0362 * Returns the pointed object and advance the cursor 0363 * to the next object. Returns NULL and does nothing 0364 * if the end has already been reached. 0365 * - argument iterator: the object to iterate on... 0366 */ 0367 synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator); 0368 /** 0369 * Reset the cursor position to the first result. 0370 * - argument iterator: the object to iterate on... 0371 */ 0372 int synctex_iterator_reset(synctex_iterator_p iterator); 0373 /** 0374 * The number of objects left for traversal. 0375 * - argument iterator: the object to iterate on... 0376 */ 0377 int synctex_iterator_count(synctex_iterator_p iterator); 0378 0379 /** 0380 * The target of the node, either a handle or a proxy. 0381 */ 0382 synctex_node_p synctex_node_target(synctex_node_p node); 0383 0384 #ifndef SYNCTEX_NO_UPDATER 0385 /* The main synctex updater object. 0386 * This object is used to append information to the synctex file. 0387 * Its implementation is considered private. 0388 * It is used by the synctex command line tool to take into account modifications 0389 * that could occur while postprocessing files by dvipdf like filters. 0390 */ 0391 typedef struct synctex_updater_t synctex_updater_s; 0392 typedef synctex_updater_s *synctex_updater_p; 0393 0394 /* Designated initializer. 0395 * Once you are done with your whole job, 0396 * free the updater */ 0397 synctex_updater_p synctex_updater_new_with_output_file(const char *output, const char *directory); 0398 0399 /* Use the next functions to append records to the synctex file, 0400 * no consistency tests made on the arguments */ 0401 void synctex_updater_append_magnification(synctex_updater_p updater, char *magnification); 0402 void synctex_updater_append_x_offset(synctex_updater_p updater, char *x_offset); 0403 void synctex_updater_append_y_offset(synctex_updater_p updater, char *y_offset); 0404 0405 /* You MUST free the updater, once everything is properly appended */ 0406 void synctex_updater_free(synctex_updater_p updater); 0407 #endif 0408 0409 #if defined(SYNCTEX_DEBUG) 0410 #include "assert.h" 0411 #define SYNCTEX_ASSERT assert 0412 #else 0413 #define SYNCTEX_ASSERT(UNUSED) 0414 #endif 0415 0416 #if defined(SYNCTEX_TESTING) 0417 #warning TESTING IS PROHIBITED 0418 #if __clang__ 0419 #define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wformat-extra-args\"") 0420 0421 #define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic pop") 0422 #else 0423 #define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS 0424 #define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS 0425 #endif 0426 0427 #define SYNCTEX_TEST_BODY(counter, condition, desc, ...) \ 0428 do { \ 0429 __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \ 0430 if (!(condition)) { \ 0431 ++counter; \ 0432 printf("**** Test failed: %s\nfile %s\nfunction %s\nline %i\n", #condition, __FILE__, __FUNCTION__, __LINE__); \ 0433 printf((desc), ##__VA_ARGS__); \ 0434 } \ 0435 __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \ 0436 } while (0) 0437 0438 #define SYNCTEX_TEST_PARAMETER(counter, condition) SYNCTEX_TEST_BODY(counter, (condition), "Invalid parameter not satisfying: %s", #condition) 0439 0440 int synctex_test_input(synctex_scanner_p scanner); 0441 int synctex_test_proxy(synctex_scanner_p scanner); 0442 int synctex_test_tree(synctex_scanner_p scanner); 0443 int synctex_test_page(synctex_scanner_p scanner); 0444 int synctex_test_handle(synctex_scanner_p scanner); 0445 int synctex_test_display_query(synctex_scanner_p scanner); 0446 int synctex_test_charindex(); 0447 int synctex_test_sheet_1(); 0448 int synctex_test_sheet_2(); 0449 int synctex_test_sheet_3(); 0450 int synctex_test_form(); 0451 #endif 0452 0453 #ifdef __cplusplus 0454 } 0455 #endif 0456 0457 #endif