synctex_parser_advanced.h 20 KB

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