#include <config.h>
#include "lisp.h"
#include "buffer.h"
+#include "coding.h"
#include "treesit.h"
\f
/*** Loading language library */
+struct treesit_loaded_lang
+{
+ /* The language object, or NULL if the language failed to load. */
+ TSLanguage *lang;
+ /* The absolute file name of the shared library, or NULL if access
+ failed. */
+ const char *filename;
+};
+
/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */
static void
treesit_symbol_to_c_name (char *symbol_name)
If error occurs, return NULL and fill SIGNAL_SYMBOL and SIGNAL_DATA
with values suitable for xsignal. */
-static TSLanguage *
+static struct treesit_loaded_lang
treesit_load_language (Lisp_Object language_symbol,
Lisp_Object *signal_symbol, Lisp_Object *signal_data)
{
dynlib_handle_ptr handle;
const char *error;
Lisp_Object error_list = Qnil;
+ struct treesit_loaded_lang loaded_lang = { NULL, NULL };
tail = path_candidates;
error = NULL;
mismatch. */
*signal_symbol = Qtreesit_load_language_error;
*signal_data = Fcons (Qnot_found, Fnreverse (error_list));
- return NULL;
+ return loaded_lang;
}
/* Load TSLanguage. */
{
*signal_symbol = Qtreesit_load_language_error;
*signal_data = list2 (Qsymbol_error, build_string (error));
- return NULL;
+ return loaded_lang;
}
TSLanguage *lang = (*langfn) ();
*signal_symbol = Qtreesit_load_language_error;
*signal_data = list2 (Qversion_mismatch,
make_fixnum (ts_language_version (lang)));
- return NULL;
+ return loaded_lang;
}
- return lang;
+
+ const char *sym;
+ dynlib_addr ((void (*)) langfn, &loaded_lang.filename, &sym);
+
+ loaded_lang.lang = lang;
+ return loaded_lang;
}
DEFUN ("treesit-language-available-p", Ftreesit_language_available_p,
treesit_initialize ();
Lisp_Object signal_symbol = Qnil;
Lisp_Object signal_data = Qnil;
- if (treesit_load_language (language, &signal_symbol, &signal_data) == NULL)
+ struct treesit_loaded_lang loaded_lang
+ = treesit_load_language (language, &signal_symbol, &signal_data);
+ if (loaded_lang.lang == NULL)
{
if (NILP (detail))
return Qnil;
{
Lisp_Object signal_symbol = Qnil;
Lisp_Object signal_data = Qnil;
- TSLanguage *ts_language = treesit_load_language (language,
- &signal_symbol,
- &signal_data);
+ struct treesit_loaded_lang lang
+ = treesit_load_language (language, &signal_symbol, &signal_data);
+ TSLanguage *ts_language = lang.lang;
if (ts_language == NULL)
return Qnil;
uint32_t version = ts_language_version (ts_language);
}
}
+/* This function isn't documented in the manual since it's mainly for
+ debugging. */
+DEFUN ("treesit-grammar-location", Ftreesit_grammar_location,
+ Streesit_grammar_location,
+ 1, 1, 0,
+ doc: /* Return the absolute file name of the grammar file for LANGUAGE.
+
+If LANGUAGE isn't loaded yet, load it first. If the language can't be
+loaded or the file name couldn't be determined, return nil. */)
+ (Lisp_Object language)
+{
+ CHECK_SYMBOL (language);
+
+ Lisp_Object signal_symbol = Qnil;
+ Lisp_Object signal_data = Qnil;
+ struct treesit_loaded_lang lang
+ = treesit_load_language (language, &signal_symbol, &signal_data);
+
+ if (!lang.lang || !lang.filename) return Qnil;
+
+ return DECODE_FILE (make_unibyte_string (lang.filename,
+ strlen (lang.filename)));
+}
+
\f
/*** Parsing functions */
Lisp_Object language = XTS_COMPILED_QUERY (query)->language;
/* This is the main reason why we compile query lazily: to avoid
loading languages early. */
- TSLanguage *treesit_lang = treesit_load_language (language, signal_symbol,
- signal_data);
+ struct treesit_loaded_lang lang
+ = treesit_load_language (language, signal_symbol, signal_data);
+ TSLanguage *treesit_lang = lang.lang;
if (treesit_lang == NULL)
return NULL;
Lisp_Object signal_symbol = Qnil;
Lisp_Object signal_data = Qnil;
TSParser *parser = ts_parser_new ();
- TSLanguage *lang = treesit_load_language (language, &signal_symbol,
- &signal_data);
+ struct treesit_loaded_lang loaded_lang
+ = treesit_load_language (language, &signal_symbol, &signal_data);
+ TSLanguage *lang = loaded_lang.lang;
if (lang == NULL)
xsignal (signal_symbol, signal_data);
/* We check language version when loading a language, so this should
defsubr (&Streesit_language_available_p);
defsubr (&Streesit_library_abi_version);
defsubr (&Streesit_language_abi_version);
+ defsubr (&Streesit_grammar_location);
defsubr (&Streesit_parser_p);
defsubr (&Streesit_node_p);