diff options
| author | Yuan Fu | 2023-01-13 17:26:08 -0800 |
|---|---|---|
| committer | Yuan Fu | 2023-01-13 17:32:14 -0800 |
| commit | dc33a122230adbfa37926f4eb19c0620b3affd85 (patch) | |
| tree | bb34459c4900cf2a30c9dcb568ae34b2d87fcd62 /src | |
| parent | 59c3c53efa43e82f0f2e48a4c27d5bd623201d4a (diff) | |
| download | emacs-dc33a122230adbfa37926f4eb19c0620b3affd85.tar.gz emacs-dc33a122230adbfa37926f4eb19c0620b3affd85.zip | |
Fix use of build_pure_c_string in treesit.c
This is brought up in bug#60691. build_pure_c_string should only be
used in places such as syms_of_treesit, which are called just once,
during dumping.
* src/treesit.c (Vtreesit_str_libtree_sitter):
(Vtreesit_str_tree_sitter):
(Vtreesit_str_dot):
(Vtreesit_str_question_mark):
(Vtreesit_str_star):
(Vtreesit_str_plus):
(Vtreesit_str_pound_equal):
(Vtreesit_str_pound_match):
(Vtreesit_str_pound_pred):
(Vtreesit_str_open_bracket):
(Vtreesit_str_close_bracket):
(Vtreesit_str_open_paren):
(Vtreesit_str_close_paren):
(Vtreesit_str_space):
(Vtreesit_str_equal):
(Vtreesit_str_match):
(Vtreesit_str_pred): New variables.
(treesit_load_language):
(Ftreesit_pattern_expand):
(Ftreesit_query_expand):
(treesit_eval_predicates): Use new varaibles.
(treesit_check_buffer_size):
(treesit_compose_query_signal_data):
(treesit_check_range_argument):
(Ftreesit_parser_set_included_ranges):
(treesit_predicate_capture_name_to_node):
(treesit_predicate_equal):
(treesit_predicate_match):
(treesit_predicate_pred): Use build_string for signal message.
(syms_of_treesit): Initialize new variables.
Diffstat (limited to 'src')
| -rw-r--r-- | src/treesit.c | 138 |
1 files changed, 96 insertions, 42 deletions
diff --git a/src/treesit.c b/src/treesit.c index 33a7e3c8528..3886fed346e 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -406,6 +406,24 @@ init_treesit_functions (void) | |||
| 406 | 406 | ||
| 407 | /*** Initialization */ | 407 | /*** Initialization */ |
| 408 | 408 | ||
| 409 | static Lisp_Object Vtreesit_str_libtree_sitter; | ||
| 410 | static Lisp_Object Vtreesit_str_tree_sitter; | ||
| 411 | static Lisp_Object Vtreesit_str_dot; | ||
| 412 | static Lisp_Object Vtreesit_str_question_mark; | ||
| 413 | static Lisp_Object Vtreesit_str_star; | ||
| 414 | static Lisp_Object Vtreesit_str_plus; | ||
| 415 | static Lisp_Object Vtreesit_str_pound_equal; | ||
| 416 | static Lisp_Object Vtreesit_str_pound_match; | ||
| 417 | static Lisp_Object Vtreesit_str_pound_pred; | ||
| 418 | static Lisp_Object Vtreesit_str_open_bracket; | ||
| 419 | static Lisp_Object Vtreesit_str_close_bracket; | ||
| 420 | static Lisp_Object Vtreesit_str_open_paren; | ||
| 421 | static Lisp_Object Vtreesit_str_close_paren; | ||
| 422 | static Lisp_Object Vtreesit_str_space; | ||
| 423 | static Lisp_Object Vtreesit_str_equal; | ||
| 424 | static Lisp_Object Vtreesit_str_match; | ||
| 425 | static Lisp_Object Vtreesit_str_pred; | ||
| 426 | |||
| 409 | /* This is the limit on recursion levels for some tree-sitter | 427 | /* This is the limit on recursion levels for some tree-sitter |
| 410 | functions. Remember to update docstrings when changing this | 428 | functions. Remember to update docstrings when changing this |
| 411 | value. */ | 429 | value. */ |
| @@ -534,9 +552,9 @@ treesit_load_language (Lisp_Object language_symbol, | |||
| 534 | 552 | ||
| 535 | /* Figure out the library name and C name. */ | 553 | /* Figure out the library name and C name. */ |
| 536 | Lisp_Object lib_base_name | 554 | Lisp_Object lib_base_name |
| 537 | = concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); | 555 | = concat2 (Vtreesit_str_libtree_sitter, symbol_name); |
| 538 | Lisp_Object base_name | 556 | Lisp_Object base_name |
| 539 | = concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); | 557 | = concat2 (Vtreesit_str_tree_sitter, symbol_name); |
| 540 | 558 | ||
| 541 | /* Override the library name and C name, if appropriate. */ | 559 | /* Override the library name and C name, if appropriate. */ |
| 542 | Lisp_Object override_name; | 560 | Lisp_Object override_name; |
| @@ -945,7 +963,7 @@ treesit_check_buffer_size (struct buffer *buffer) | |||
| 945 | ptrdiff_t buffer_size_bytes = (BUF_Z_BYTE (buffer) - BUF_BEG_BYTE (buffer)); | 963 | ptrdiff_t buffer_size_bytes = (BUF_Z_BYTE (buffer) - BUF_BEG_BYTE (buffer)); |
| 946 | if (buffer_size_bytes > UINT32_MAX) | 964 | if (buffer_size_bytes > UINT32_MAX) |
| 947 | xsignal2 (Qtreesit_buffer_too_large, | 965 | xsignal2 (Qtreesit_buffer_too_large, |
| 948 | build_pure_c_string ("Buffer size cannot be larger than 4GB"), | 966 | build_string ("Buffer size cannot be larger than 4GB"), |
| 949 | make_fixnum (buffer_size_bytes)); | 967 | make_fixnum (buffer_size_bytes)); |
| 950 | } | 968 | } |
| 951 | 969 | ||
| @@ -1200,7 +1218,7 @@ treesit_compose_query_signal_data (uint32_t error_offset, | |||
| 1200 | return list4 (build_string (treesit_query_error_to_string (error_type)), | 1218 | return list4 (build_string (treesit_query_error_to_string (error_type)), |
| 1201 | make_fixnum (error_offset + 1), | 1219 | make_fixnum (error_offset + 1), |
| 1202 | query_source, | 1220 | query_source, |
| 1203 | build_pure_c_string ("Debug the query with `treesit-query-validate'")); | 1221 | build_string ("Debug the query with `treesit-query-validate'")); |
| 1204 | } | 1222 | } |
| 1205 | 1223 | ||
| 1206 | /* Ensure the QUERY is compiled. Return the TSQuery. It could be | 1224 | /* Ensure the QUERY is compiled. Return the TSQuery. It could be |
| @@ -1498,8 +1516,8 @@ treesit_check_range_argument (Lisp_Object ranges) | |||
| 1498 | EMACS_INT end = XFIXNUM (XCDR (range)); | 1516 | EMACS_INT end = XFIXNUM (XCDR (range)); |
| 1499 | if (!(last_point <= beg && beg <= end && end <= point_max)) | 1517 | if (!(last_point <= beg && beg <= end && end <= point_max)) |
| 1500 | xsignal2 (Qtreesit_range_invalid, | 1518 | xsignal2 (Qtreesit_range_invalid, |
| 1501 | build_pure_c_string ("RANGE is either overlapping," | 1519 | build_string ("RANGE is either overlapping," |
| 1502 | " out-of-order or out-of-range"), | 1520 | " out-of-order or out-of-range"), |
| 1503 | ranges); | 1521 | ranges); |
| 1504 | last_point = end; | 1522 | last_point = end; |
| 1505 | } | 1523 | } |
| @@ -1607,7 +1625,7 @@ buffer. */) | |||
| 1607 | 1625 | ||
| 1608 | if (!success) | 1626 | if (!success) |
| 1609 | xsignal2 (Qtreesit_range_invalid, | 1627 | xsignal2 (Qtreesit_range_invalid, |
| 1610 | build_pure_c_string ("Something went wrong when setting ranges"), | 1628 | build_string ("Something went wrong when setting ranges"), |
| 1611 | ranges); | 1629 | ranges); |
| 1612 | 1630 | ||
| 1613 | XTS_PARSER (parser)->need_reparse = true; | 1631 | XTS_PARSER (parser)->need_reparse = true; |
| @@ -2210,30 +2228,32 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */) | |||
| 2210 | (Lisp_Object pattern) | 2228 | (Lisp_Object pattern) |
| 2211 | { | 2229 | { |
| 2212 | if (EQ (pattern, QCanchor)) | 2230 | if (EQ (pattern, QCanchor)) |
| 2213 | return build_pure_c_string ("."); | 2231 | return Vtreesit_str_dot; |
| 2214 | if (EQ (pattern, intern_c_string (":?"))) | 2232 | if (EQ (pattern, intern_c_string (":?"))) |
| 2215 | return build_pure_c_string ("?"); | 2233 | return Vtreesit_str_question_mark; |
| 2216 | if (EQ (pattern, intern_c_string (":*"))) | 2234 | if (EQ (pattern, intern_c_string (":*"))) |
| 2217 | return build_pure_c_string ("*"); | 2235 | return Vtreesit_str_star; |
| 2218 | if (EQ (pattern, intern_c_string (":+"))) | 2236 | if (EQ (pattern, intern_c_string (":+"))) |
| 2219 | return build_pure_c_string ("+"); | 2237 | return Vtreesit_str_plus; |
| 2220 | if (EQ (pattern, QCequal)) | 2238 | if (EQ (pattern, QCequal)) |
| 2221 | return build_pure_c_string ("#equal"); | 2239 | return Vtreesit_str_pound_equal; |
| 2222 | if (EQ (pattern, QCmatch)) | 2240 | if (EQ (pattern, QCmatch)) |
| 2223 | return build_pure_c_string ("#match"); | 2241 | return Vtreesit_str_pound_match; |
| 2224 | if (EQ (pattern, QCpred)) | 2242 | if (EQ (pattern, QCpred)) |
| 2225 | return build_pure_c_string ("#pred"); | 2243 | return Vtreesit_str_pound_pred; |
| 2226 | Lisp_Object opening_delimeter | 2244 | Lisp_Object opening_delimeter |
| 2227 | = build_pure_c_string (VECTORP (pattern) ? "[" : "("); | 2245 | = VECTORP (pattern) |
| 2246 | ? Vtreesit_str_open_bracket : Vtreesit_str_open_paren; | ||
| 2228 | Lisp_Object closing_delimiter | 2247 | Lisp_Object closing_delimiter |
| 2229 | = build_pure_c_string (VECTORP (pattern) ? "]" : ")"); | 2248 | = VECTORP (pattern) |
| 2249 | ? Vtreesit_str_close_bracket : Vtreesit_str_close_paren; | ||
| 2230 | if (VECTORP (pattern) || CONSP (pattern)) | 2250 | if (VECTORP (pattern) || CONSP (pattern)) |
| 2231 | return concat3 (opening_delimeter, | 2251 | return concat3 (opening_delimeter, |
| 2232 | Fmapconcat (Qtreesit_pattern_expand, | 2252 | Fmapconcat (Qtreesit_pattern_expand, |
| 2233 | pattern, | 2253 | pattern, |
| 2234 | build_pure_c_string (" ")), | 2254 | Vtreesit_str_space), |
| 2235 | closing_delimiter); | 2255 | closing_delimiter); |
| 2236 | return CALLN (Fformat, build_pure_c_string ("%S"), pattern); | 2256 | return Fprin1_to_string (pattern, Qnil, Qt); |
| 2237 | } | 2257 | } |
| 2238 | 2258 | ||
| 2239 | DEFUN ("treesit-query-expand", | 2259 | DEFUN ("treesit-query-expand", |
| @@ -2260,8 +2280,7 @@ A PATTERN in QUERY can be | |||
| 2260 | See Info node `(elisp)Pattern Matching' for detailed explanation. */) | 2280 | See Info node `(elisp)Pattern Matching' for detailed explanation. */) |
| 2261 | (Lisp_Object query) | 2281 | (Lisp_Object query) |
| 2262 | { | 2282 | { |
| 2263 | return Fmapconcat (Qtreesit_pattern_expand, | 2283 | return Fmapconcat (Qtreesit_pattern_expand, query, Vtreesit_str_space); |
| 2264 | query, build_pure_c_string (" ")); | ||
| 2265 | } | 2284 | } |
| 2266 | 2285 | ||
| 2267 | /* This struct is used for passing captures to be check against | 2286 | /* This struct is used for passing captures to be check against |
| @@ -2341,10 +2360,10 @@ treesit_predicate_capture_name_to_node (Lisp_Object name, | |||
| 2341 | 2360 | ||
| 2342 | if (NILP (node)) | 2361 | if (NILP (node)) |
| 2343 | xsignal3 (Qtreesit_query_error, | 2362 | xsignal3 (Qtreesit_query_error, |
| 2344 | build_pure_c_string ("Cannot find captured node"), | 2363 | build_string ("Cannot find captured node"), |
| 2345 | name, build_pure_c_string ("A predicate can only refer" | 2364 | name, build_string ("A predicate can only refer" |
| 2346 | " to captured nodes in the " | 2365 | " to captured nodes in the " |
| 2347 | "same pattern")); | 2366 | "same pattern")); |
| 2348 | return node; | 2367 | return node; |
| 2349 | } | 2368 | } |
| 2350 | 2369 | ||
| @@ -2373,8 +2392,8 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures) | |||
| 2373 | { | 2392 | { |
| 2374 | if (XFIXNUM (Flength (args)) != 2) | 2393 | if (XFIXNUM (Flength (args)) != 2) |
| 2375 | xsignal2 (Qtreesit_query_error, | 2394 | xsignal2 (Qtreesit_query_error, |
| 2376 | build_pure_c_string ("Predicate `equal' requires " | 2395 | build_string ("Predicate `equal' requires " |
| 2377 | "two arguments but only given"), | 2396 | "two arguments but only given"), |
| 2378 | Flength (args)); | 2397 | Flength (args)); |
| 2379 | 2398 | ||
| 2380 | Lisp_Object arg1 = XCAR (args); | 2399 | Lisp_Object arg1 = XCAR (args); |
| @@ -2399,8 +2418,8 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures) | |||
| 2399 | { | 2418 | { |
| 2400 | if (XFIXNUM (Flength (args)) != 2) | 2419 | if (XFIXNUM (Flength (args)) != 2) |
| 2401 | xsignal2 (Qtreesit_query_error, | 2420 | xsignal2 (Qtreesit_query_error, |
| 2402 | build_pure_c_string ("Predicate `equal' requires two " | 2421 | build_string ("Predicate `equal' requires two " |
| 2403 | "arguments but only given"), | 2422 | "arguments but only given"), |
| 2404 | Flength (args)); | 2423 | Flength (args)); |
| 2405 | 2424 | ||
| 2406 | Lisp_Object regexp = XCAR (args); | 2425 | Lisp_Object regexp = XCAR (args); |
| @@ -2412,12 +2431,12 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures) | |||
| 2412 | string-match does.) */ | 2431 | string-match does.) */ |
| 2413 | if (!STRINGP (regexp)) | 2432 | if (!STRINGP (regexp)) |
| 2414 | xsignal1 (Qtreesit_query_error, | 2433 | xsignal1 (Qtreesit_query_error, |
| 2415 | build_pure_c_string ("The first argument to `match' should " | 2434 | build_string ("The first argument to `match' should " |
| 2416 | "be a regexp string, not a capture name")); | 2435 | "be a regexp string, not a capture name")); |
| 2417 | if (!SYMBOLP (capture_name)) | 2436 | if (!SYMBOLP (capture_name)) |
| 2418 | xsignal1 (Qtreesit_query_error, | 2437 | xsignal1 (Qtreesit_query_error, |
| 2419 | build_pure_c_string ("The second argument to `match' should " | 2438 | build_string ("The second argument to `match' should " |
| 2420 | "be a capture name, not a string")); | 2439 | "be a capture name, not a string")); |
| 2421 | 2440 | ||
| 2422 | Lisp_Object text = treesit_predicate_capture_name_to_text (capture_name, | 2441 | Lisp_Object text = treesit_predicate_capture_name_to_text (capture_name, |
| 2423 | captures); | 2442 | captures); |
| @@ -2436,9 +2455,9 @@ treesit_predicate_pred (Lisp_Object args, struct capture_range captures) | |||
| 2436 | { | 2455 | { |
| 2437 | if (XFIXNUM (Flength (args)) < 2) | 2456 | if (XFIXNUM (Flength (args)) < 2) |
| 2438 | xsignal2 (Qtreesit_query_error, | 2457 | xsignal2 (Qtreesit_query_error, |
| 2439 | build_pure_c_string ("Predicate `pred' requires " | 2458 | build_string ("Predicate `pred' requires " |
| 2440 | "at least two arguments, " | 2459 | "at least two arguments, " |
| 2441 | "but was only given"), | 2460 | "but was only given"), |
| 2442 | Flength (args)); | 2461 | Flength (args)); |
| 2443 | 2462 | ||
| 2444 | Lisp_Object fn = Fintern (XCAR (args), Qnil); | 2463 | Lisp_Object fn = Fintern (XCAR (args), Qnil); |
| @@ -2466,18 +2485,18 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates) | |||
| 2466 | Lisp_Object predicate = XCAR (tail); | 2485 | Lisp_Object predicate = XCAR (tail); |
| 2467 | Lisp_Object fn = XCAR (predicate); | 2486 | Lisp_Object fn = XCAR (predicate); |
| 2468 | Lisp_Object args = XCDR (predicate); | 2487 | Lisp_Object args = XCDR (predicate); |
| 2469 | if (!NILP (Fstring_equal (fn, build_pure_c_string ("equal")))) | 2488 | if (!NILP (Fstring_equal (fn, Vtreesit_str_equal))) |
| 2470 | pass &= treesit_predicate_equal (args, captures); | 2489 | pass &= treesit_predicate_equal (args, captures); |
| 2471 | else if (!NILP (Fstring_equal (fn, build_pure_c_string ("match")))) | 2490 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_match))) |
| 2472 | pass &= treesit_predicate_match (args, captures); | 2491 | pass &= treesit_predicate_match (args, captures); |
| 2473 | else if (!NILP (Fstring_equal (fn, build_pure_c_string ("pred")))) | 2492 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred))) |
| 2474 | pass &= treesit_predicate_pred (args, captures); | 2493 | pass &= treesit_predicate_pred (args, captures); |
| 2475 | else | 2494 | else |
| 2476 | xsignal3 (Qtreesit_query_error, | 2495 | xsignal3 (Qtreesit_query_error, |
| 2477 | build_pure_c_string ("Invalid predicate"), | 2496 | build_string ("Invalid predicate"), |
| 2478 | fn, build_pure_c_string ("Currently Emacs only supports" | 2497 | fn, build_string ("Currently Emacs only supports" |
| 2479 | " equal, match, and pred" | 2498 | " equal, match, and pred" |
| 2480 | " predicate")); | 2499 | " predicate")); |
| 2481 | } | 2500 | } |
| 2482 | /* If all predicates passed, add captures to result list. */ | 2501 | /* If all predicates passed, add captures to result list. */ |
| 2483 | return pass; | 2502 | return pass; |
| @@ -3377,6 +3396,41 @@ then in the `tree-sitter' subdirectory of `user-emacs-directory', and | |||
| 3377 | then in the system default locations for dynamic libraries, in that order. */); | 3396 | then in the system default locations for dynamic libraries, in that order. */); |
| 3378 | Vtreesit_extra_load_path = Qnil; | 3397 | Vtreesit_extra_load_path = Qnil; |
| 3379 | 3398 | ||
| 3399 | staticpro (&Vtreesit_str_libtree_sitter); | ||
| 3400 | Vtreesit_str_libtree_sitter = build_pure_c_string ("libtree-sitter-"); | ||
| 3401 | staticpro (&Vtreesit_str_tree_sitter); | ||
| 3402 | Vtreesit_str_tree_sitter = build_pure_c_string ("tree-sitter-"); | ||
| 3403 | staticpro (&Vtreesit_str_dot); | ||
| 3404 | Vtreesit_str_dot = build_pure_c_string ("."); | ||
| 3405 | staticpro (&Vtreesit_str_question_mark); | ||
| 3406 | Vtreesit_str_question_mark = build_pure_c_string ("?"); | ||
| 3407 | staticpro (&Vtreesit_str_star); | ||
| 3408 | Vtreesit_str_star = build_pure_c_string ("*"); | ||
| 3409 | staticpro (&Vtreesit_str_plus); | ||
| 3410 | Vtreesit_str_plus = build_pure_c_string ("+"); | ||
| 3411 | staticpro (&Vtreesit_str_pound_equal); | ||
| 3412 | Vtreesit_str_pound_equal = build_pure_c_string ("#equal"); | ||
| 3413 | staticpro (&Vtreesit_str_pound_match); | ||
| 3414 | Vtreesit_str_pound_match = build_pure_c_string ("#match"); | ||
| 3415 | staticpro (&Vtreesit_str_pound_pred); | ||
| 3416 | Vtreesit_str_pound_pred = build_pure_c_string ("#pred"); | ||
| 3417 | staticpro (&Vtreesit_str_open_bracket); | ||
| 3418 | Vtreesit_str_open_bracket = build_pure_c_string ("["); | ||
| 3419 | staticpro (&Vtreesit_str_close_bracket); | ||
| 3420 | Vtreesit_str_close_bracket = build_pure_c_string ("]"); | ||
| 3421 | staticpro (&Vtreesit_str_open_paren); | ||
| 3422 | Vtreesit_str_open_paren = build_pure_c_string ("("); | ||
| 3423 | staticpro (&Vtreesit_str_close_paren); | ||
| 3424 | Vtreesit_str_close_paren = build_pure_c_string (")"); | ||
| 3425 | staticpro (&Vtreesit_str_space); | ||
| 3426 | Vtreesit_str_space = build_pure_c_string (" "); | ||
| 3427 | staticpro (&Vtreesit_str_equal); | ||
| 3428 | Vtreesit_str_equal = build_pure_c_string ("equal"); | ||
| 3429 | staticpro (&Vtreesit_str_match); | ||
| 3430 | Vtreesit_str_match = build_pure_c_string ("match"); | ||
| 3431 | staticpro (&Vtreesit_str_pred); | ||
| 3432 | Vtreesit_str_pred = build_pure_c_string ("pred"); | ||
| 3433 | |||
| 3380 | defsubr (&Streesit_language_available_p); | 3434 | defsubr (&Streesit_language_available_p); |
| 3381 | defsubr (&Streesit_library_abi_version); | 3435 | defsubr (&Streesit_library_abi_version); |
| 3382 | defsubr (&Streesit_language_abi_version); | 3436 | defsubr (&Streesit_language_abi_version); |