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.
This commit is contained in:
Yuan Fu 2023-01-13 17:26:08 -08:00
parent 59c3c53efa
commit dc33a12223
No known key found for this signature in database
GPG key ID: 56E19BC57664A442

View file

@ -406,6 +406,24 @@ init_treesit_functions (void)
/*** Initialization */
static Lisp_Object Vtreesit_str_libtree_sitter;
static Lisp_Object Vtreesit_str_tree_sitter;
static Lisp_Object Vtreesit_str_dot;
static Lisp_Object Vtreesit_str_question_mark;
static Lisp_Object Vtreesit_str_star;
static Lisp_Object Vtreesit_str_plus;
static Lisp_Object Vtreesit_str_pound_equal;
static Lisp_Object Vtreesit_str_pound_match;
static Lisp_Object Vtreesit_str_pound_pred;
static Lisp_Object Vtreesit_str_open_bracket;
static Lisp_Object Vtreesit_str_close_bracket;
static Lisp_Object Vtreesit_str_open_paren;
static Lisp_Object Vtreesit_str_close_paren;
static Lisp_Object Vtreesit_str_space;
static Lisp_Object Vtreesit_str_equal;
static Lisp_Object Vtreesit_str_match;
static Lisp_Object Vtreesit_str_pred;
/* This is the limit on recursion levels for some tree-sitter
functions. Remember to update docstrings when changing this
value. */
@ -534,9 +552,9 @@ treesit_load_language (Lisp_Object language_symbol,
/* Figure out the library name and C name. */
Lisp_Object lib_base_name
= concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name);
= concat2 (Vtreesit_str_libtree_sitter, symbol_name);
Lisp_Object base_name
= concat2 (build_pure_c_string ("tree-sitter-"), symbol_name);
= concat2 (Vtreesit_str_tree_sitter, symbol_name);
/* Override the library name and C name, if appropriate. */
Lisp_Object override_name;
@ -945,7 +963,7 @@ treesit_check_buffer_size (struct buffer *buffer)
ptrdiff_t buffer_size_bytes = (BUF_Z_BYTE (buffer) - BUF_BEG_BYTE (buffer));
if (buffer_size_bytes > UINT32_MAX)
xsignal2 (Qtreesit_buffer_too_large,
build_pure_c_string ("Buffer size cannot be larger than 4GB"),
build_string ("Buffer size cannot be larger than 4GB"),
make_fixnum (buffer_size_bytes));
}
@ -1200,7 +1218,7 @@ treesit_compose_query_signal_data (uint32_t error_offset,
return list4 (build_string (treesit_query_error_to_string (error_type)),
make_fixnum (error_offset + 1),
query_source,
build_pure_c_string ("Debug the query with `treesit-query-validate'"));
build_string ("Debug the query with `treesit-query-validate'"));
}
/* Ensure the QUERY is compiled. Return the TSQuery. It could be
@ -1498,8 +1516,8 @@ treesit_check_range_argument (Lisp_Object ranges)
EMACS_INT end = XFIXNUM (XCDR (range));
if (!(last_point <= beg && beg <= end && end <= point_max))
xsignal2 (Qtreesit_range_invalid,
build_pure_c_string ("RANGE is either overlapping,"
" out-of-order or out-of-range"),
build_string ("RANGE is either overlapping,"
" out-of-order or out-of-range"),
ranges);
last_point = end;
}
@ -1607,7 +1625,7 @@ buffer. */)
if (!success)
xsignal2 (Qtreesit_range_invalid,
build_pure_c_string ("Something went wrong when setting ranges"),
build_string ("Something went wrong when setting ranges"),
ranges);
XTS_PARSER (parser)->need_reparse = true;
@ -2210,30 +2228,32 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */)
(Lisp_Object pattern)
{
if (EQ (pattern, QCanchor))
return build_pure_c_string (".");
return Vtreesit_str_dot;
if (EQ (pattern, intern_c_string (":?")))
return build_pure_c_string ("?");
return Vtreesit_str_question_mark;
if (EQ (pattern, intern_c_string (":*")))
return build_pure_c_string ("*");
return Vtreesit_str_star;
if (EQ (pattern, intern_c_string (":+")))
return build_pure_c_string ("+");
return Vtreesit_str_plus;
if (EQ (pattern, QCequal))
return build_pure_c_string ("#equal");
return Vtreesit_str_pound_equal;
if (EQ (pattern, QCmatch))
return build_pure_c_string ("#match");
return Vtreesit_str_pound_match;
if (EQ (pattern, QCpred))
return build_pure_c_string ("#pred");
return Vtreesit_str_pound_pred;
Lisp_Object opening_delimeter
= build_pure_c_string (VECTORP (pattern) ? "[" : "(");
= VECTORP (pattern)
? Vtreesit_str_open_bracket : Vtreesit_str_open_paren;
Lisp_Object closing_delimiter
= build_pure_c_string (VECTORP (pattern) ? "]" : ")");
= VECTORP (pattern)
? Vtreesit_str_close_bracket : Vtreesit_str_close_paren;
if (VECTORP (pattern) || CONSP (pattern))
return concat3 (opening_delimeter,
Fmapconcat (Qtreesit_pattern_expand,
pattern,
build_pure_c_string (" ")),
Vtreesit_str_space),
closing_delimiter);
return CALLN (Fformat, build_pure_c_string ("%S"), pattern);
return Fprin1_to_string (pattern, Qnil, Qt);
}
DEFUN ("treesit-query-expand",
@ -2260,8 +2280,7 @@ A PATTERN in QUERY can be
See Info node `(elisp)Pattern Matching' for detailed explanation. */)
(Lisp_Object query)
{
return Fmapconcat (Qtreesit_pattern_expand,
query, build_pure_c_string (" "));
return Fmapconcat (Qtreesit_pattern_expand, query, Vtreesit_str_space);
}
/* This struct is used for passing captures to be check against
@ -2341,10 +2360,10 @@ treesit_predicate_capture_name_to_node (Lisp_Object name,
if (NILP (node))
xsignal3 (Qtreesit_query_error,
build_pure_c_string ("Cannot find captured node"),
name, build_pure_c_string ("A predicate can only refer"
" to captured nodes in the "
"same pattern"));
build_string ("Cannot find captured node"),
name, build_string ("A predicate can only refer"
" to captured nodes in the "
"same pattern"));
return node;
}
@ -2373,8 +2392,8 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures)
{
if (XFIXNUM (Flength (args)) != 2)
xsignal2 (Qtreesit_query_error,
build_pure_c_string ("Predicate `equal' requires "
"two arguments but only given"),
build_string ("Predicate `equal' requires "
"two arguments but only given"),
Flength (args));
Lisp_Object arg1 = XCAR (args);
@ -2399,8 +2418,8 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
{
if (XFIXNUM (Flength (args)) != 2)
xsignal2 (Qtreesit_query_error,
build_pure_c_string ("Predicate `equal' requires two "
"arguments but only given"),
build_string ("Predicate `equal' requires two "
"arguments but only given"),
Flength (args));
Lisp_Object regexp = XCAR (args);
@ -2412,12 +2431,12 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
string-match does.) */
if (!STRINGP (regexp))
xsignal1 (Qtreesit_query_error,
build_pure_c_string ("The first argument to `match' should "
"be a regexp string, not a capture name"));
build_string ("The first argument to `match' should "
"be a regexp string, not a capture name"));
if (!SYMBOLP (capture_name))
xsignal1 (Qtreesit_query_error,
build_pure_c_string ("The second argument to `match' should "
"be a capture name, not a string"));
build_string ("The second argument to `match' should "
"be a capture name, not a string"));
Lisp_Object text = treesit_predicate_capture_name_to_text (capture_name,
captures);
@ -2436,9 +2455,9 @@ treesit_predicate_pred (Lisp_Object args, struct capture_range captures)
{
if (XFIXNUM (Flength (args)) < 2)
xsignal2 (Qtreesit_query_error,
build_pure_c_string ("Predicate `pred' requires "
"at least two arguments, "
"but was only given"),
build_string ("Predicate `pred' requires "
"at least two arguments, "
"but was only given"),
Flength (args));
Lisp_Object fn = Fintern (XCAR (args), Qnil);
@ -2466,18 +2485,18 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates)
Lisp_Object predicate = XCAR (tail);
Lisp_Object fn = XCAR (predicate);
Lisp_Object args = XCDR (predicate);
if (!NILP (Fstring_equal (fn, build_pure_c_string ("equal"))))
if (!NILP (Fstring_equal (fn, Vtreesit_str_equal)))
pass &= treesit_predicate_equal (args, captures);
else if (!NILP (Fstring_equal (fn, build_pure_c_string ("match"))))
else if (!NILP (Fstring_equal (fn, Vtreesit_str_match)))
pass &= treesit_predicate_match (args, captures);
else if (!NILP (Fstring_equal (fn, build_pure_c_string ("pred"))))
else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred)))
pass &= treesit_predicate_pred (args, captures);
else
xsignal3 (Qtreesit_query_error,
build_pure_c_string ("Invalid predicate"),
fn, build_pure_c_string ("Currently Emacs only supports"
" equal, match, and pred"
" predicate"));
build_string ("Invalid predicate"),
fn, build_string ("Currently Emacs only supports"
" equal, match, and pred"
" predicate"));
}
/* If all predicates passed, add captures to result list. */
return pass;
@ -3377,6 +3396,41 @@ then in the `tree-sitter' subdirectory of `user-emacs-directory', and
then in the system default locations for dynamic libraries, in that order. */);
Vtreesit_extra_load_path = Qnil;
staticpro (&Vtreesit_str_libtree_sitter);
Vtreesit_str_libtree_sitter = build_pure_c_string ("libtree-sitter-");
staticpro (&Vtreesit_str_tree_sitter);
Vtreesit_str_tree_sitter = build_pure_c_string ("tree-sitter-");
staticpro (&Vtreesit_str_dot);
Vtreesit_str_dot = build_pure_c_string (".");
staticpro (&Vtreesit_str_question_mark);
Vtreesit_str_question_mark = build_pure_c_string ("?");
staticpro (&Vtreesit_str_star);
Vtreesit_str_star = build_pure_c_string ("*");
staticpro (&Vtreesit_str_plus);
Vtreesit_str_plus = build_pure_c_string ("+");
staticpro (&Vtreesit_str_pound_equal);
Vtreesit_str_pound_equal = build_pure_c_string ("#equal");
staticpro (&Vtreesit_str_pound_match);
Vtreesit_str_pound_match = build_pure_c_string ("#match");
staticpro (&Vtreesit_str_pound_pred);
Vtreesit_str_pound_pred = build_pure_c_string ("#pred");
staticpro (&Vtreesit_str_open_bracket);
Vtreesit_str_open_bracket = build_pure_c_string ("[");
staticpro (&Vtreesit_str_close_bracket);
Vtreesit_str_close_bracket = build_pure_c_string ("]");
staticpro (&Vtreesit_str_open_paren);
Vtreesit_str_open_paren = build_pure_c_string ("(");
staticpro (&Vtreesit_str_close_paren);
Vtreesit_str_close_paren = build_pure_c_string (")");
staticpro (&Vtreesit_str_space);
Vtreesit_str_space = build_pure_c_string (" ");
staticpro (&Vtreesit_str_equal);
Vtreesit_str_equal = build_pure_c_string ("equal");
staticpro (&Vtreesit_str_match);
Vtreesit_str_match = build_pure_c_string ("match");
staticpro (&Vtreesit_str_pred);
Vtreesit_str_pred = build_pure_c_string ("pred");
defsubr (&Streesit_language_available_p);
defsubr (&Streesit_library_abi_version);
defsubr (&Streesit_language_abi_version);