synctex_parser_advanced.h (20536B)
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 40 #include "synctex_parser.h" 41 #include "synctex_parser_utils.h" 42 43 #ifndef __SYNCTEX_PARSER_PRIVATE__ 44 # define __SYNCTEX_PARSER_PRIVATE__ 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 /* Reminder that the argument must not be NULL */ 50 typedef synctex_node_p synctex_non_null_node_p; 51 52 /* Each node of the tree, except the scanner itself belongs to a class. 53 * The class object is just a struct declaring the owning scanner 54 * This is a pointer to the scanner as root of the tree. 55 * The type is used to identify the kind of node. 56 * The class declares pointers to a creator and a destructor method. 57 * The log and display fields are used to log and display the node. 58 * display will also display the child, sibling and parent sibling. 59 * parent, child and sibling are used to navigate the tree, 60 * from TeX box hierarchy point of view. 61 * The friend field points to a method which allows to navigate from friend to friend. 62 * A friend is a node with very close tag and line numbers. 63 * Finally, the info field point to a method giving the private node info offset. 64 */ 65 66 /** 67 * These are the masks for the synctex node types. 68 * int's are 32 bits at least. 69 */ 70 enum { 71 synctex_shift_root, 72 synctex_shift_no_root, 73 synctex_shift_void, 74 synctex_shift_no_void, 75 synctex_shift_box, 76 synctex_shift_no_box, 77 synctex_shift_proxy, 78 synctex_shift_no_proxy, 79 synctex_shift_h, 80 synctex_shift_v 81 }; 82 enum { 83 synctex_mask_root = 1, 84 synctex_mask_no_root = synctex_mask_root<<1, 85 synctex_mask_void = synctex_mask_no_root<<1, 86 synctex_mask_no_void = synctex_mask_void<<1, 87 synctex_mask_box = synctex_mask_no_void<<1, 88 synctex_mask_no_box = synctex_mask_box<<1, 89 synctex_mask_proxy = synctex_mask_no_box<<1, 90 synctex_mask_no_proxy = synctex_mask_proxy<<1, 91 synctex_mask_h = synctex_mask_no_proxy<<1, 92 synctex_mask_v = synctex_mask_h<<1, 93 }; 94 enum { 95 synctex_mask_non_void_hbox = synctex_mask_no_void 96 | synctex_mask_box 97 | synctex_mask_h, 98 synctex_mask_non_void_vbox = synctex_mask_no_void 99 | synctex_mask_box 100 | synctex_mask_v 101 }; 102 typedef enum { 103 synctex_node_mask_sf = 104 synctex_mask_root 105 |synctex_mask_no_void 106 |synctex_mask_no_box 107 |synctex_mask_no_proxy, 108 synctex_node_mask_vbox = 109 synctex_mask_no_root 110 |synctex_mask_no_void 111 |synctex_mask_box 112 |synctex_mask_no_proxy 113 |synctex_mask_v, 114 synctex_node_mask_hbox = 115 synctex_mask_no_root 116 |synctex_mask_no_void 117 |synctex_mask_box 118 |synctex_mask_no_proxy 119 |synctex_mask_h, 120 synctex_node_mask_void_vbox = 121 synctex_mask_no_root 122 |synctex_mask_void 123 |synctex_mask_box 124 |synctex_mask_no_proxy 125 |synctex_mask_v, 126 synctex_node_mask_void_hbox = 127 synctex_mask_no_root 128 |synctex_mask_void 129 |synctex_mask_box 130 |synctex_mask_no_proxy 131 |synctex_mask_h, 132 synctex_node_mask_vbox_proxy = 133 synctex_mask_no_root 134 |synctex_mask_no_void 135 |synctex_mask_box 136 |synctex_mask_proxy 137 |synctex_mask_v, 138 synctex_node_mask_hbox_proxy = 139 synctex_mask_no_root 140 |synctex_mask_no_void 141 |synctex_mask_box 142 |synctex_mask_proxy 143 |synctex_mask_h, 144 synctex_node_mask_nvnn = 145 synctex_mask_no_root 146 |synctex_mask_void 147 |synctex_mask_no_box 148 |synctex_mask_no_proxy, 149 synctex_node_mask_input = 150 synctex_mask_root 151 |synctex_mask_void 152 |synctex_mask_no_box 153 |synctex_mask_no_proxy, 154 synctex_node_mask_proxy = 155 synctex_mask_no_root 156 |synctex_mask_void 157 |synctex_mask_no_box 158 |synctex_mask_proxy 159 } synctex_node_mask_t; 160 161 enum { 162 /* input */ 163 synctex_tree_sibling_idx = 0, 164 synctex_tree_s_input_max = 1, 165 /* All */ 166 synctex_tree_s_parent_idx = 1, 167 synctex_tree_sp_child_idx = 2, 168 synctex_tree_spc_friend_idx = 3, 169 synctex_tree_spcf_last_idx = 4, 170 synctex_tree_spcfl_vbox_max = 5, 171 /* hbox supplement */ 172 synctex_tree_spcfl_next_hbox_idx = 5, 173 synctex_tree_spcfln_hbox_max = 6, 174 /* hbox proxy supplement */ 175 synctex_tree_spcfln_target_idx = 6, 176 synctex_tree_spcflnt_proxy_hbox_max = 7, 177 /* vbox proxy supplement */ 178 synctex_tree_spcfl_target_idx = 5, 179 synctex_tree_spcflt_proxy_vbox_max = 6, 180 /* spf supplement*/ 181 synctex_tree_sp_friend_idx = 2, 182 synctex_tree_spf_max = 3, 183 /* box boundary supplement */ 184 synctex_tree_spf_arg_sibling_idx = 3, 185 synctex_tree_spfa_max = 4, 186 /* proxy supplement */ 187 synctex_tree_spf_target_idx = 3, 188 synctex_tree_spft_proxy_max = 4, 189 /* last proxy supplement */ 190 synctex_tree_spfa_target_idx = 4, 191 synctex_tree_spfat_proxy_last_max = 5, 192 /* sheet supplement */ 193 synctex_tree_s_child_idx = 1, 194 synctex_tree_sc_next_hbox_idx = 2, 195 synctex_tree_scn_sheet_max = 3, 196 /* form supplement */ 197 synctex_tree_sc_target_idx = 2, 198 synctex_tree_sct_form_max = 3, 199 /* spct */ 200 synctex_tree_spc_target_idx = 3, 201 synctex_tree_spct_handle_max = 4, 202 }; 203 204 enum { 205 /* input */ 206 synctex_data_input_tag_idx = 0, 207 synctex_data_input_line_idx = 1, 208 synctex_data_input_name_idx = 2, 209 synctex_data_input_tln_max = 3, 210 /* sheet */ 211 synctex_data_sheet_page_idx = 0, 212 synctex_data_p_sheet_max = 1, 213 /* form */ 214 synctex_data_form_tag_idx = 0, 215 synctex_data_t_form_max = 1, 216 /* tlchv */ 217 synctex_data_tag_idx = 0, 218 synctex_data_line_idx = 1, 219 synctex_data_column_idx = 2, 220 synctex_data_h_idx = 3, 221 synctex_data_v_idx = 4, 222 synctex_data_tlchv_max = 5, 223 /* tlchvw */ 224 synctex_data_width_idx = 5, 225 synctex_data_tlchvw_max = 6, 226 /* box */ 227 synctex_data_height_idx = 6, 228 synctex_data_depth_idx = 7, 229 synctex_data_box_max = 8, 230 /* hbox supplement */ 231 synctex_data_mean_line_idx = 8, 232 synctex_data_weight_idx = 9, 233 synctex_data_h_V_idx = 10, 234 synctex_data_v_V_idx = 11, 235 synctex_data_width_V_idx = 12, 236 synctex_data_height_V_idx = 13, 237 synctex_data_depth_V_idx = 14, 238 synctex_data_hbox_max = 15, 239 /* ref */ 240 synctex_data_ref_tag_idx = 0, 241 synctex_data_ref_h_idx = 1, 242 synctex_data_ref_v_idx = 2, 243 synctex_data_ref_thv_max = 3, 244 /* proxy */ 245 synctex_data_proxy_h_idx = 0, 246 synctex_data_proxy_v_idx = 1, 247 synctex_data_proxy_hv_max = 2, 248 /* handle */ 249 synctex_data_handle_w_idx = 0, 250 synctex_data_handle_w_max = 1, 251 }; 252 253 /* each synctex node has a class */ 254 typedef struct synctex_class_t synctex_class_s; 255 typedef synctex_class_s * synctex_class_p; 256 257 258 /* synctex_node_p is a pointer to a node 259 * synctex_node_s is the target of the synctex_node_p pointer 260 * It is a pseudo object oriented program. 261 * class is a pointer to the class object the node belongs to. 262 * implementation is meant to contain the private data of the node 263 * basically, there are 2 kinds of information: navigation information and 264 * synctex information. Both will depend on the type of the node, 265 * thus different nodes will have different private data. 266 * There is no inheritancy overhead. 267 */ 268 typedef union { 269 synctex_node_p as_node; 270 int as_integer; 271 char * as_string; 272 void * as_pointer; 273 } synctex_data_u; 274 typedef synctex_data_u * synctex_data_p; 275 276 # if defined(SYNCTEX_USE_CHARINDEX) 277 typedef unsigned int synctex_charindex_t; 278 synctex_charindex_t synctex_node_charindex(synctex_node_p node); 279 typedef synctex_charindex_t synctex_lineindex_t; 280 synctex_lineindex_t synctex_node_lineindex(synctex_node_p node); 281 synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner); 282 # define SYNCTEX_DECLARE_CHARINDEX \ 283 synctex_charindex_t char_index;\ 284 synctex_lineindex_t line_index; 285 # define SYNCTEX_DECLARE_CHAR_OFFSET \ 286 synctex_charindex_t charindex_offset; 287 # else 288 # define SYNCTEX_DECLARE_CHARINDEX 289 # define SYNCTEX_DECLARE_CHAR_OFFSET 290 # endif 291 struct synctex_node_t { 292 SYNCTEX_DECLARE_CHARINDEX 293 synctex_class_p class_; 294 #ifdef DEBUG 295 synctex_data_u data[22]; 296 #else 297 synctex_data_u data[1]; 298 #endif 299 }; 300 301 typedef synctex_node_p * synctex_node_r; 302 303 typedef struct { 304 int h; 305 int v; 306 } synctex_point_s; 307 308 typedef synctex_point_s * synctex_point_p; 309 310 typedef struct { 311 synctex_point_s min; /* top left */ 312 synctex_point_s max; /* bottom right */ 313 } synctex_box_s; 314 315 typedef synctex_box_s * synctex_box_p; 316 /** 317 * These are the types of the synctex nodes. 318 * No need to use them but the compiler needs them here. 319 * There are 3 kinds of nodes. 320 * - primary nodes 321 * - proxies 322 * - handles 323 * Primary nodes are created at parse time 324 * of the synctex file. 325 * Proxies are used to support pdf forms. 326 * The ref primary nodes are replaced by a tree 327 * of proxy nodes which duplicate the tree of primary 328 * nodes available in the referred form. 329 * Roughly speaking, the primary nodes of the form 330 * know what to display, the proxy nodes know where. 331 * Handles are used in queries. They point to either 332 * primary nodes or proxies. 333 */ 334 typedef enum { 335 synctex_node_type_none = 0, 336 synctex_node_type_input, 337 synctex_node_type_sheet, 338 synctex_node_type_form, 339 synctex_node_type_ref, 340 synctex_node_type_vbox, 341 synctex_node_type_void_vbox, 342 synctex_node_type_hbox, 343 synctex_node_type_void_hbox, 344 synctex_node_type_kern, 345 synctex_node_type_glue, 346 synctex_node_type_rule, 347 synctex_node_type_math, 348 synctex_node_type_boundary, 349 synctex_node_type_box_bdry, 350 synctex_node_type_proxy, 351 synctex_node_type_proxy_last, 352 synctex_node_type_proxy_vbox, 353 synctex_node_type_proxy_hbox, 354 synctex_node_type_handle, 355 synctex_node_number_of_types 356 } synctex_node_type_t; 357 /* synctex_node_type gives the type of a given node, 358 * synctex_node_isa gives the same information as a human readable text. */ 359 synctex_node_type_t synctex_node_type(synctex_node_p node); 360 const char * synctex_node_isa(synctex_node_p node); 361 362 synctex_node_type_t synctex_node_target_type(synctex_node_p node); 363 364 synctex_node_type_t synctex_node_type(synctex_node_p node); 365 const char * synctex_node_isa(synctex_node_p node); 366 367 void synctex_node_log(synctex_node_p node); 368 void synctex_node_display(synctex_node_p node); 369 370 /* Given a node, access to the location in the synctex file where it is defined. 371 */ 372 373 int synctex_node_form_tag(synctex_node_p node); 374 375 int synctex_node_weight(synctex_node_p node); 376 int synctex_node_child_count(synctex_node_p node); 377 378 int synctex_node_h(synctex_node_p node); 379 int synctex_node_v(synctex_node_p node); 380 int synctex_node_width(synctex_node_p node); 381 382 int synctex_node_box_h(synctex_node_p node); 383 int synctex_node_box_v(synctex_node_p node); 384 int synctex_node_box_width(synctex_node_p node); 385 int synctex_node_box_height(synctex_node_p node); 386 int synctex_node_box_depth(synctex_node_p node); 387 388 int synctex_node_hbox_h(synctex_node_p node); 389 int synctex_node_hbox_v(synctex_node_p node); 390 int synctex_node_hbox_width(synctex_node_p node); 391 int synctex_node_hbox_height(synctex_node_p node); 392 int synctex_node_hbox_depth(synctex_node_p node); 393 394 synctex_scanner_p synctex_scanner_new(void); 395 synctex_node_p synctex_node_new(synctex_scanner_p scanner,synctex_node_type_t type); 396 397 /** 398 * Scanner display switcher getter. 399 * If the switcher is 0, synctex_node_display is disabled. 400 * If the switcher is <0, synctex_node_display has no limit. 401 * If the switcher is >0, only the first switcher (as number) nodes are displayed. 402 * - parameter: a scanner 403 * - returns: an integer 404 */ 405 int synctex_scanner_display_switcher(synctex_scanner_p scanR); 406 void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher); 407 408 /** 409 * Iterator is the structure used to traverse 410 * the answer to client queries. 411 * First answers are the best matches, according 412 * to criteria explained below. 413 * Next answers are not ordered. 414 * Objects are handles to nodes in the synctex node tree starting at scanner. 415 */ 416 typedef struct synctex_iterator_t synctex_iterator_s; 417 typedef synctex_iterator_s * synctex_iterator_p; 418 419 /** 420 * Designated creator for a display query, id est, 421 * forward navigation from source to output. 422 * Returns NULL if the query has no answer. 423 * Code example: 424 * synctex_iterator_p iterator = NULL; 425 * if ((iterator = synctex_iterator_new_display(...)) { 426 * synctex_node_p node = NULL; 427 * while((node = synctex_iterator_next_result(iterator))) { 428 * do something with node... 429 * } 430 */ 431 synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint); 432 /** 433 * Designated creator for an edit query, id est, 434 * backward navigation from output to source. 435 * Code example: 436 * synctex_iterator_p iterator = NULL; 437 * if ((iterator = synctex_iterator_new_edit(...)) { 438 * synctex_node_p node = NULL; 439 * while((node = synctex_iterator_next_result(iterator))) { 440 * do something with node... 441 * } 442 */ 443 synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner,int page,float h,float v); 444 /** 445 * Free all the resources. 446 * - argument iterator: the object to free... 447 * You should free the iterator before the scanner 448 * owning the nodes it iterates with. 449 */ 450 void synctex_iterator_free(synctex_iterator_p iterator); 451 /** 452 * Whether the iterator actually points to an object. 453 * - argument iterator: the object to iterate on... 454 */ 455 synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator); 456 /** 457 * Returns the pointed object and advance the cursor 458 * to the next object. Returns NULL and does nothing 459 * if the end has already been reached. 460 * - argument iterator: the object to iterate on... 461 */ 462 synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator); 463 /** 464 * Reset the cursor position to the first result. 465 * - argument iterator: the object to iterate on... 466 */ 467 int synctex_iterator_reset(synctex_iterator_p iterator); 468 /** 469 * The number of objects left for traversal. 470 * - argument iterator: the object to iterate on... 471 */ 472 int synctex_iterator_count(synctex_iterator_p iterator); 473 474 /** 475 * The target of the node, either a handle or a proxy. 476 */ 477 synctex_node_p synctex_node_target(synctex_node_p node); 478 479 #ifndef SYNCTEX_NO_UPDATER 480 /* The main synctex updater object. 481 * This object is used to append information to the synctex file. 482 * Its implementation is considered private. 483 * It is used by the synctex command line tool to take into account modifications 484 * that could occur while postprocessing files by dvipdf like filters. 485 */ 486 typedef struct synctex_updater_t synctex_updater_s; 487 typedef synctex_updater_s * synctex_updater_p; 488 489 /* Designated initializer. 490 * Once you are done with your whole job, 491 * free the updater */ 492 synctex_updater_p synctex_updater_new_with_output_file(const char * output, const char * directory); 493 494 /* Use the next functions to append records to the synctex file, 495 * no consistency tests made on the arguments */ 496 void synctex_updater_append_magnification(synctex_updater_p updater, char * magnification); 497 void synctex_updater_append_x_offset(synctex_updater_p updater, char * x_offset); 498 void synctex_updater_append_y_offset(synctex_updater_p updater, char * y_offset); 499 500 /* You MUST free the updater, once everything is properly appended */ 501 void synctex_updater_free(synctex_updater_p updater); 502 #endif 503 504 #if defined(SYNCTEX_DEBUG) 505 # include "assert.h" 506 # define SYNCTEX_ASSERT assert 507 #else 508 # define SYNCTEX_ASSERT(UNUSED) 509 #endif 510 511 #if defined(SYNCTEX_TESTING) 512 #warning TESTING IS PROHIBITED 513 #if __clang__ 514 #define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \ 515 _Pragma("clang diagnostic push") \ 516 _Pragma("clang diagnostic ignored \"-Wformat-extra-args\"") 517 518 #define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic pop") 519 #else 520 #define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS 521 #define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS 522 #endif 523 524 # define SYNCTEX_TEST_BODY(counter, condition, desc, ...) \ 525 do { \ 526 __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \ 527 if (!(condition)) { \ 528 ++counter; \ 529 printf("**** Test failed: %s\nfile %s\nfunction %s\nline %i\n",#condition,__FILE__,__FUNCTION__,__LINE__); \ 530 printf((desc), ##__VA_ARGS__); \ 531 } \ 532 __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \ 533 } while(0) 534 535 # define SYNCTEX_TEST_PARAMETER(counter, condition) SYNCTEX_TEST_BODY(counter, (condition), "Invalid parameter not satisfying: %s", #condition) 536 537 int synctex_test_input(synctex_scanner_p scanner); 538 int synctex_test_proxy(synctex_scanner_p scanner); 539 int synctex_test_tree(synctex_scanner_p scanner); 540 int synctex_test_page(synctex_scanner_p scanner); 541 int synctex_test_handle(synctex_scanner_p scanner); 542 int synctex_test_display_query(synctex_scanner_p scanner); 543 int synctex_test_charindex(); 544 int synctex_test_sheet_1(); 545 int synctex_test_sheet_2(); 546 int synctex_test_sheet_3(); 547 int synctex_test_form(); 548 #endif 549 550 #ifdef __cplusplus 551 } 552 #endif 553 554 #endif