diff --git a/main/field.c b/main/field.c index c0e220a6ff..6c3a1ac1f2 100644 --- a/main/field.c +++ b/main/field.c @@ -1371,6 +1371,8 @@ extern int defineField (fieldDefinition *def, langType language) fobj->sibling = FIELD_UNKNOWN; updateSiblingField (def->ftype, def->name); + installOptscriptFieldAccessor (def->ftype); + return def->ftype; } diff --git a/main/lregex.c b/main/lregex.c index 2d6c84f509..cd8d0011c8 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -4564,6 +4564,19 @@ static struct optscriptOperatorRegistration lropOperators [] = { }, }; +extern bool installOptscriptFieldAccessor (fieldType ftype) +{ + /* This function is called via defineField(). + defineField() is called via --fielddef option of built-in parsers + defining their specific fields. + built-in parsers are initialized lazily in the current implementation. + optvm is initialized earlier than parsers. */ + Assert (!es_null(lregex_dict)); + + optscriptInstallFieldAccessor (lregex_dict, ftype); + return true; +} + extern void initRegexOptscript (void) { if (!regexAvailable) diff --git a/main/lregex_p.h b/main/lregex_p.h index 103944f2f1..9ada840b71 100644 --- a/main/lregex_p.h +++ b/main/lregex_p.h @@ -19,6 +19,7 @@ * INCLUDE FILES */ #include "general.h" +#include "field.h" #include "flags_p.h" #include "kind_p.h" #include "lregex.h" @@ -114,6 +115,8 @@ extern void extendRegexTable (struct lregexControlBlock *lcb, const char *src, c extern void initRegexOptscript (void); extern void listRegexOpscriptOperators (FILE *fp); +extern bool installOptscriptFieldAccessor (fieldType ftype); + extern void addOptscriptToHook (struct lregexControlBlock *lcb, enum scriptHook hook, const char *code); extern void propagateParamToOptscript (struct lregexControlBlock *lcb, const char *param, const char *value); diff --git a/main/options.c b/main/options.c index 27dca2da6a..b28eb34d9f 100644 --- a/main/options.c +++ b/main/options.c @@ -2320,6 +2320,7 @@ static void processListSubparsersOptions (const char *const option CTAGS_ATTR_UN static void processListOperators (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter) { + initializeParser (LANG_AUTO); listRegexOpscriptOperators (stdout); exit (0); } diff --git a/main/script.c b/main/script.c index 4b3f17a1fa..eeeee36951 100644 --- a/main/script.c +++ b/main/script.c @@ -167,12 +167,22 @@ static EsObject* lrop_set_field_value (OptVM *vm, EsObject *name) return es_false; } -static void optscriptInstallFieldGetter (EsObject *dict, fieldType ftype, - vString *op_name, vString *op_desc) +static void optscriptInstallFieldGetterFast (EsObject *dict, fieldType ftype, + vString *op_name, vString *op_desc) { - const char *fname = getFieldName (ftype); vStringPut (op_name, ':'); + + langType lang = getFieldLanguage (ftype); + if (lang != LANG_IGNORE) + { + const char *lname = getLanguageName (lang); + vStringCatS (op_name, lname); + vStringPut (op_name, '.'); + } + + const char *fname = getFieldName (ftype); vStringCatS (op_name, fname); + EsObject *op_sym = es_symbol_intern (vStringValue (op_name)); es_symbol_set_data (op_sym, HT_INT_TO_PTR (ftype)); @@ -213,9 +223,17 @@ static void optscriptInstallFieldGetter (EsObject *dict, fieldType ftype, es_object_unref (op); } -static void optscriptInstallFieldSetter (EsObject *dict, fieldType ftype, - vString *op_name, vString *op_desc) +static void optscriptInstallFieldSetterFast (EsObject *dict, fieldType ftype, + vString *op_name, vString *op_desc) { + langType lang = getFieldLanguage (ftype); + if (lang != LANG_IGNORE) + { + const char *lname = getLanguageName (lang); + vStringCatS (op_name, lname); + vStringPut (op_name, '.'); + } + const char *fname = getFieldName (ftype); vStringCatS (op_name, fname); vStringPut (op_name, ':'); @@ -252,22 +270,46 @@ static void optscriptInstallFieldSetter (EsObject *dict, fieldType ftype, es_object_unref (op); } +extern void optscriptInstallFieldAccessor (EsObject *dict, fieldType ftype) +{ + vString *op_name = vStringNew (); + vString *op_desc = vStringNew (); + + if (hasFieldGetter (ftype)) + { + optscriptInstallFieldGetterFast (dict, ftype, op_name, op_desc); + vStringClear (op_name); + vStringClear (op_desc); + } + + if (hasFieldSetter (ftype)) + optscriptInstallFieldSetterFast (dict, ftype, op_name, op_desc); + + vStringDelete (op_name); + vStringDelete (op_desc); +} + static void optscriptInstallFieldAccessors (EsObject *dict) { vString *op_name = vStringNew (); vString *op_desc = vStringNew (); + /* In the current implementation, the upper boundary of the loop + can be "<= FIELD_BUILTIN_LAST" because the parser specific fields + are registered via defineField. However, when we change the order + and the way to initialize parsers, we may have to use "< countFields()" + instead. */ for (fieldType ftype = 0; ftype <= FIELD_BUILTIN_LAST; ftype++) { if (hasFieldGetter (ftype)) { - optscriptInstallFieldGetter (dict, ftype, op_name, op_desc); + optscriptInstallFieldGetterFast (dict, ftype, op_name, op_desc); vStringClear (op_name); vStringClear (op_desc); } if (hasFieldSetter (ftype)) { - optscriptInstallFieldSetter (dict, ftype, op_name, op_desc); + optscriptInstallFieldSetterFast (dict, ftype, op_name, op_desc); vStringClear (op_name); vStringClear (op_desc); } diff --git a/main/script_p.h b/main/script_p.h index bf5d8cc5b0..86197f4088 100644 --- a/main/script_p.h +++ b/main/script_p.h @@ -13,6 +13,7 @@ #include "general.h" /* must always come first */ +#include "field.h" #include "optscript.h" #include "mio.h" @@ -33,6 +34,7 @@ extern EsObject *OPTSCRIPT_ERR_LANGMISMATCH; extern OptVM *optscriptInit (void); extern void optscriptInstallProcs (EsObject *dict, OptOperatorFn matchResultAccessor); +extern void optscriptInstallFieldAccessor (EsObject *dict, fieldType ftype); extern void optscriptSetup (OptVM *vm, EsObject *dict, int corkIndex); extern void optscriptTeardown (OptVM *vm, EsObject *dict);