aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuan Fu2023-01-13 17:26:08 -0800
committerYuan Fu2023-01-13 17:32:14 -0800
commitdc33a122230adbfa37926f4eb19c0620b3affd85 (patch)
treebb34459c4900cf2a30c9dcb568ae34b2d87fcd62 /src
parent59c3c53efa43e82f0f2e48a4c27d5bd623201d4a (diff)
downloademacs-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.c138
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
409static Lisp_Object Vtreesit_str_libtree_sitter;
410static Lisp_Object Vtreesit_str_tree_sitter;
411static Lisp_Object Vtreesit_str_dot;
412static Lisp_Object Vtreesit_str_question_mark;
413static Lisp_Object Vtreesit_str_star;
414static Lisp_Object Vtreesit_str_plus;
415static Lisp_Object Vtreesit_str_pound_equal;
416static Lisp_Object Vtreesit_str_pound_match;
417static Lisp_Object Vtreesit_str_pound_pred;
418static Lisp_Object Vtreesit_str_open_bracket;
419static Lisp_Object Vtreesit_str_close_bracket;
420static Lisp_Object Vtreesit_str_open_paren;
421static Lisp_Object Vtreesit_str_close_paren;
422static Lisp_Object Vtreesit_str_space;
423static Lisp_Object Vtreesit_str_equal;
424static Lisp_Object Vtreesit_str_match;
425static 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
2239DEFUN ("treesit-query-expand", 2259DEFUN ("treesit-query-expand",
@@ -2260,8 +2280,7 @@ A PATTERN in QUERY can be
2260See Info node `(elisp)Pattern Matching' for detailed explanation. */) 2280See 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
3377then in the system default locations for dynamic libraries, in that order. */); 3396then 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);