diff --git a/Units/optscript.r/op-anongen.d/args.ctags b/Units/optscript.r/op-anongen.d/args.ctags new file mode 100644 index 0000000000..7c19a90464 --- /dev/null +++ b/Units/optscript.r/op-anongen.d/args.ctags @@ -0,0 +1,14 @@ +--sort=no +--fields=+{extras}{language} + +--langdef=Foo{_foreignLanguage=C} +--map-Foo=.foo +--kinddef-Foo=a,app,applications + +--regex-Foo=/^c:(.)$//{{ + \1 /C /struct _anongen /C /struct _foreigntag _commit /anonymous _markextra +}} + +--regex-Foo=/^f:(.)$//{{ + \1 /app _anongen /app _tag _commit /anonymous _markextra +}} diff --git a/Units/optscript.r/op-anongen.d/expected.tags b/Units/optscript.r/op-anongen.d/expected.tags new file mode 100644 index 0000000000..86e84034b5 --- /dev/null +++ b/Units/optscript.r/op-anongen.d/expected.tags @@ -0,0 +1,2 @@ +15263c7700108 input.foo /^c:1$/;" s language:C extras:anonymous +25263c7700100 input.foo /^f:2$/;" a language:Foo extras:anonymous diff --git a/Units/optscript.r/op-anongen.d/input.foo b/Units/optscript.r/op-anongen.d/input.foo new file mode 100644 index 0000000000..9fef07ee7a --- /dev/null +++ b/Units/optscript.r/op-anongen.d/input.foo @@ -0,0 +1,2 @@ +c:1 +f:2 diff --git a/main/lregex.c b/main/lregex.c index 5923387224..260c28db1c 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -4304,6 +4304,66 @@ static EsObject *lrop_intervaltab (OptVM *vm, EsObject *name) return false; } +static EsObject *lrop_anongen (OptVM *vm, EsObject *name) +{ + int n_pop = 2; + + if (opt_vm_ostack_count (vm) < 2) + return OPT_ERR_UNDERFLOW; + + EsObject *kind_obj = opt_vm_ostack_top (vm); + if (es_object_get_type (kind_obj) != OPT_TYPE_NAME) + return OPT_ERR_TYPECHECK; + EsObject *kind_sym = es_pointer_get (kind_obj); + const char *kind_str = es_symbol_get (kind_sym); + + EsObject *tmp_obj = opt_vm_ostack_peek (vm, 1); + langType lang = LANG_IGNORE; + EsObject *prefix_obj = es_nil; + if (es_object_get_type (tmp_obj) == OPT_TYPE_NAME) + { + EsObject *lang_sym = es_pointer_get (tmp_obj); + const char *lang_str = es_symbol_get (lang_sym); + lang = getNamedLanguageOrAlias (lang_str, 0); + if (lang == LANG_IGNORE) + return OPTSCRIPT_ERR_UNKNOWNLANGUAGE; + } + else + { + lang = getInputLanguage (); + prefix_obj = tmp_obj; + } + Assert(lang != LANG_IGNORE); + Assert(lang != LANG_AUTO); + + kindDefinition* kind_def = getLanguageKindForName (lang, kind_str); + if (!kind_def) + return OPTSCRIPT_ERR_UNKNOWNKIND; + int kind_index = kind_def->id; + + if (es_null(prefix_obj)) + { + n_pop++; + if (opt_vm_ostack_count (vm) < 3) + return OPT_ERR_UNDERFLOW; + prefix_obj = opt_vm_ostack_peek (vm, 2); + } + if (es_object_get_type (prefix_obj) != OPT_TYPE_STRING) + return OPT_ERR_TYPECHECK; + const char *prefix = opt_string_get_cstr (prefix_obj); + + vString *anon_vstr = anonGenerateNewFull (prefix, lang, kind_index); + EsObject *anon_obj = opt_string_new_from_cstr (vStringValue(anon_vstr)); + vStringDelete(anon_vstr); + + for (; n_pop > 0; n_pop--) + opt_vm_ostack_pop (vm); + + opt_vm_ostack_push (vm, anon_obj); + es_object_unref (anon_obj); + return es_false; +} + static struct optscriptOperatorRegistration lropOperators [] = { { .name = "_matchstr", @@ -4487,7 +4547,14 @@ static struct optscriptOperatorRegistration lropOperators [] = { .arity = 1, .help_str = "tag:int|tag:tag|matchloc|[line:int]|[startline:int endline:int] _INTERVALTAB parent:int true%" "tag:int|tag:tag|matchloc|[startline:int endline:int] _INTERVALTAB false", - } + }, + { + .name = "_anongen", + .fn = lrop_anongen, + .arity = -1, + .help_str = "prefix:string kind:name _ANONGEN anon:string%" + "prefix:string lang:name kind:name _ANONGEN anon:string%", + }, }; extern void initRegexOptscript (void) diff --git a/main/parse.c b/main/parse.c index 202a3b138c..13c6bef8f7 100644 --- a/main/parse.c +++ b/main/parse.c @@ -2168,6 +2168,7 @@ static void pre_lang_def_flag_base_long (const char* const optflag, const char* langType cpreproc = getNamedLanguage ("CPreProcessor", 0); if (base == cpreproc) { + /* See Tmain/optscript-preludes-stack.d */ error (WARNING, "Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: %s", param); @@ -5109,15 +5110,15 @@ extern void anonHashString (const char *filename, char buf[9]) sprintf(buf, "%08x", anonHash((const unsigned char *)filename)); } - -extern void anonConcat (vString *buffer, int kind) +extern void anonConcatFull (vString *buffer, langType lang, int kind) { - anonGenerate (buffer, NULL, kind); + anonGenerateFull (buffer, NULL, lang, kind); } -extern void anonGenerate (vString *buffer, const char *prefix, int kind) +extern void anonGenerateFull (vString *buffer, const char *prefix, langType lang, int kind) { - parserObject* parser = LanguageTable + getInputLanguage (); + Assert(lang != LANG_IGNORE); + parserObject* parser = LanguageTable + ((lang == LANG_AUTO)? getInputLanguage (): lang); parser -> anonymousIdentiferId ++; char szNum[32]; @@ -5131,15 +5132,14 @@ extern void anonGenerate (vString *buffer, const char *prefix, int kind) vStringCatS(buffer,szNum); } -extern vString *anonGenerateNew (const char *prefix, int kind) +extern vString *anonGenerateNewFull (const char *prefix, langType lang, int kind) { vString *buffer = vStringNew (); - anonGenerate (buffer, prefix, kind); + anonGenerateFull (buffer, prefix, lang, kind); return buffer; } - extern bool applyLanguageParam (const langType language, const char *name, const char *args) { Assert (0 <= language && language < (int) LanguageCount); diff --git a/main/parse.h b/main/parse.h index 8656ef1f85..6f3051b619 100644 --- a/main/parse.h +++ b/main/parse.h @@ -201,9 +201,12 @@ extern void addLanguageTagMultiTableRegex(const langType language, extern void addLanguageOptscriptToHook (langType language, enum scriptHook hook, const char *const src); -extern void anonGenerate (vString *buffer, const char *prefix, int kind); -extern void anonConcat (vString *buffer, int kind); -extern vString *anonGenerateNew (const char *prefix, int kind); +extern void anonGenerateFull (vString *buffer, const char *prefix, langType lang, int kind); +#define anonGenerate(B,P,K) anonGenerateFull((B), (P), LANG_AUTO, (K)) +extern void anonConcatFull (vString *buffer, langType lang, int kind); +#define anonConcat(B,K) anonConcatFull((B), LANG_AUTO, (K)) +extern vString *anonGenerateNewFull (const char *prefix, langType lang, int kind); +#define anonGenerateNew(P,K) anonGenerateNewFull((P), LANG_AUTO, (K)) extern void anonHashString (const char *filename, char buf[9]); #endif /* CTAGS_MAIN_PARSE_H */