From 9de3d788e11465d97e913a9815c963966a784de5 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Thu, 13 May 2021 05:49:30 +0900 Subject: [PATCH 01/19] operator: fix a typo in the help message of advanceto Signed-off-by: Masatake YAMATO --- main/lregex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/lregex.c b/main/lregex.c index 9e22047142..8e329271fe 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -3861,7 +3861,7 @@ static struct optscriptOperatorRegistration lropOperators [] = { .name = "_advanceto", .fn = lrop_advanceto, .arity = 1, - .help_str = "matchloc _ADVIANCETO -%" + .help_str = "matchloc _ADVANCETO -%" }, { .name = "_traced", From 16782130c411207a4e2fb6eef07f33ef830f0468 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:51:23 +0900 Subject: [PATCH 02/19] main,consmetic: delete an empty line Signed-off-by: Masatake YAMATO --- main/field.c | 1 - 1 file changed, 1 deletion(-) diff --git a/main/field.c b/main/field.c index c20baafc76..412a1978a6 100644 --- a/main/field.c +++ b/main/field.c @@ -1667,7 +1667,6 @@ static EsObject* checkFieldValueForScope (const fieldDefinition *fdef, const EsO static EsObject* getFieldValueForExtras (const tagEntryInfo *tag, const fieldDefinition *fdef) { - if (!isTagExtra (tag)) return es_nil; From e02e1d1f5ce934a18c42a41214b74be28744e765 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:52:26 +0900 Subject: [PATCH 03/19] operator: fix a pontential memory leak Signed-off-by: Masatake YAMATO --- main/lregex.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main/lregex.c b/main/lregex.c index 8e329271fe..43bd116d75 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -3297,7 +3297,10 @@ static EsObject* lrop_get_match_loc (OptVM *vm, EsObject *name) EsObject * mlocobj = es_pointer_new (OPT_TYPE_MATCHLOC, mloc); if (es_error_p (mlocobj)) + { + eFree (mloc); return mlocobj; + } if (group != tmp) opt_vm_ostack_pop (vm); From 8c8223f5fad335ce477c76deabc2afe7edd212bc Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 03:15:32 +0900 Subject: [PATCH 04/19] main: introduce a function converting a tag a placeholder Signed-off-by: Masatake YAMATO --- main/entry.c | 7 ++++++- main/entry.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/main/entry.c b/main/entry.c index 4438a9a4a2..4fee79f503 100644 --- a/main/entry.c +++ b/main/entry.c @@ -1652,12 +1652,17 @@ extern size_t countEntryInCorkQueue (void) return ptrArrayCount (TagFile.corkQueue); } +extern void markTagPlaceholder (tagEntryInfo *e, bool placeholder) +{ + e->placeholder = placeholder; +} + extern int makePlaceholder (const char *const name) { tagEntryInfo e; initTagEntry (&e, name, KIND_GHOST_INDEX); - e.placeholder = 1; + markTagPlaceholder(&e, true); /* * makePlaceholder may be called even before reading any bytes diff --git a/main/entry.h b/main/entry.h index b79a431fe0..2b38a722a4 100644 --- a/main/entry.h +++ b/main/entry.h @@ -261,6 +261,7 @@ extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char extern const char* getParserFieldValueForType (tagEntryInfo *const tag, fieldType ftype); extern int makePlaceholder (const char *const name); +extern void markTagPlaceholder (tagEntryInfo *e, bool placeholder); /* Marking all tag entries entries under the scope specified * with index recursively. From d0d07afb8eff20b05a4d2216a4adf67107cdd459 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 03:16:17 +0900 Subject: [PATCH 05/19] operator: introduce _markplaceholder Signed-off-by: Masatake YAMATO --- .../op-markplaceholder.d/args.ctags | 11 ++++++++ .../op-markplaceholder.d/expected.tags | 4 +++ .../op-markplaceholder.d/input.unknown | 6 +++++ main/lregex.c | 27 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 Units/optscript.r/op-markplaceholder.d/args.ctags create mode 100644 Units/optscript.r/op-markplaceholder.d/expected.tags create mode 100644 Units/optscript.r/op-markplaceholder.d/input.unknown diff --git a/Units/optscript.r/op-markplaceholder.d/args.ctags b/Units/optscript.r/op-markplaceholder.d/args.ctags new file mode 100644 index 0000000000..9a45a6c374 --- /dev/null +++ b/Units/optscript.r/op-markplaceholder.d/args.ctags @@ -0,0 +1,11 @@ +--sort=no +--langdef=UnknownX +--map-UnknownX=.unknown + +--kinddef-UnknownX=d,def,definitions + +--regex-UnknownX=/([ \t]*)def +([a-zA-Z]):/\2/d/{{ + \1 length 5 gt { + . _markplaceholder + } if +}} diff --git a/Units/optscript.r/op-markplaceholder.d/expected.tags b/Units/optscript.r/op-markplaceholder.d/expected.tags new file mode 100644 index 0000000000..b1a16377eb --- /dev/null +++ b/Units/optscript.r/op-markplaceholder.d/expected.tags @@ -0,0 +1,4 @@ +a input.unknown /^def a:$/;" d +b input.unknown /^ def b:$/;" d +A input.unknown /^def A:$/;" d +B input.unknown /^ def B:$/;" d diff --git a/Units/optscript.r/op-markplaceholder.d/input.unknown b/Units/optscript.r/op-markplaceholder.d/input.unknown new file mode 100644 index 0000000000..0b90a9a900 --- /dev/null +++ b/Units/optscript.r/op-markplaceholder.d/input.unknown @@ -0,0 +1,6 @@ +def a: + def b: + def c: +def A: + def B: + def C: diff --git a/main/lregex.c b/main/lregex.c index 43bd116d75..8039786f6c 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -3732,6 +3732,27 @@ static EsObject *lrop_advanceto (OptVM *vm, EsObject *name) return es_true; } +static EsObject *lrop_markplaceholder (OptVM *vm, EsObject *name) +{ + EsObject *tag = opt_vm_ostack_top (vm); + + if (!es_integer_p (tag)) + return OPT_ERR_TYPECHECK; + + int n = es_integer_get (tag); + if (! (CORK_NIL < n && n < countEntryInCorkQueue())) + return OPT_ERR_RANGECHECK; + + tagEntryInfo *e = getEntryInCorkQueue (n); + if (e == NULL) + return OPTSCRIPT_ERR_NOTAGENTRY; + + markTagPlaceholder (e, true); + + opt_vm_ostack_pop (vm); + return es_false; +} + static struct optscriptOperatorRegistration lropOperators [] = { { .name = "_matchstr", @@ -3872,6 +3893,12 @@ static struct optscriptOperatorRegistration lropOperators [] = { .arity = 0, .help_str = "- _TRACED true|false", }, + { + .name = "_markplaceholder", + .fn = lrop_markplaceholder, + .arity = 1, + .help_str = "tag:int _MARKPLACEHOLDER -", + } }; extern void initRegexOptscript (void) From 36d4a5d4d3ca1ef97174c3307744f4b9cc7971e4 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 11:58:11 +0900 Subject: [PATCH 06/19] operator (line:): fill filePosition member of tag entry The original code updates only the lineNumber member of the tag entry. Signed-off-by: Masatake YAMATO --- main/field.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/main/field.c b/main/field.c index 412a1978a6..fb83b6c6c2 100644 --- a/main/field.c +++ b/main/field.c @@ -1770,6 +1770,13 @@ static EsObject* setFieldValueForLineCommon (tagEntryInfo *tag, const fieldDefin l = es_integer_get (obj); if (l < 1) return OPT_ERR_RANGECHECK; + + /* If the new line number is too large, + we cannot fill tag->filePosition wit + getInputFilePositionForLine(); */ + if (fdef->ftype == FIELD_LINE_NUMBER + && l < getInputLineNumber()) + return OPT_ERR_RANGECHECK; } else return OPT_ERR_TYPECHECK; @@ -1777,7 +1784,10 @@ static EsObject* setFieldValueForLineCommon (tagEntryInfo *tag, const fieldDefin if (fdef->ftype == FIELD_END_LINE) tag->extensionFields.endLine = l; else + { tag->lineNumber = l; + tag->filePosition = getInputFilePositionForLine (l); + } return es_false; } From 20b300fe1359dc65b058e467bcd1b575a7fdd3e5 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 02:01:38 +0900 Subject: [PATCH 07/19] operator: introduce _tagloc _tagloc takes a corkQueue index and pushes a mloc object locating the tag object identified by the corkQueue index. Signed-off-by: Masatake YAMATO --- Units/optscript.r/op-tagloc.d/args.ctags | 12 ++++++ Units/optscript.r/op-tagloc.d/expected.tags | 4 ++ Units/optscript.r/op-tagloc.d/input.foo | 2 + main/lregex.c | 45 +++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 Units/optscript.r/op-tagloc.d/args.ctags create mode 100644 Units/optscript.r/op-tagloc.d/expected.tags create mode 100644 Units/optscript.r/op-tagloc.d/input.foo diff --git a/Units/optscript.r/op-tagloc.d/args.ctags b/Units/optscript.r/op-tagloc.d/args.ctags new file mode 100644 index 0000000000..4a21e9e6a9 --- /dev/null +++ b/Units/optscript.r/op-tagloc.d/args.ctags @@ -0,0 +1,12 @@ +--langdef=FOO +--map-FOO=.foo +--kinddef-FOO=d,def,definitions +--_extradef-FOO=withprefix,name with prefix +--extras-FOO=+{withprefix} +--fields=+{extras} +--regex-FOO=/def +([a-zA-Z]+)/\1/d/{{ + mark () . :name _buildstring + . :kind + . _tagloc _tag _commit + /FOO.withprefix _markextra +}} diff --git a/Units/optscript.r/op-tagloc.d/expected.tags b/Units/optscript.r/op-tagloc.d/expected.tags new file mode 100644 index 0000000000..f93b390e2b --- /dev/null +++ b/Units/optscript.r/op-tagloc.d/expected.tags @@ -0,0 +1,4 @@ +x input.foo /^def x$/;" d extras:withprefix +y input.foo /^def y$/;" d extras:withprefix +x input.foo /^def x$/;" d +y input.foo /^def y$/;" d diff --git a/Units/optscript.r/op-tagloc.d/input.foo b/Units/optscript.r/op-tagloc.d/input.foo new file mode 100644 index 0000000000..ca2de50a6a --- /dev/null +++ b/Units/optscript.r/op-tagloc.d/input.foo @@ -0,0 +1,2 @@ +def x +def y diff --git a/main/lregex.c b/main/lregex.c index 8039786f6c..955127145f 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -3310,6 +3310,45 @@ static EsObject* lrop_get_match_loc (OptVM *vm, EsObject *name) return es_false; } +static matchLoc* make_mloc_from_tagEntryInfo(tagEntryInfo *e) +{ + matchLoc *mloc = xMalloc (1, matchLoc); + mloc->delta = 0; + mloc->line = e->lineNumber; + mloc->pos = e->filePosition; + + return mloc; +} + +static EsObject* lrop_get_tag_loc (OptVM *vm, EsObject *name) +{ + EsObject *nobj = opt_vm_ostack_top (vm); + + if (es_object_get_type (nobj) != ES_TYPE_INTEGER) + return OPT_ERR_TYPECHECK; + + int n = es_integer_get(nobj); + if (! (CORK_NIL < n && n < countEntryInCorkQueue())) + return OPT_ERR_RANGECHECK; + + tagEntryInfo *e = getEntryInCorkQueue (n); + if (e == NULL) + return OPT_ERR_TYPECHECK; /* ??? */ + + matchLoc *mloc = make_mloc_from_tagEntryInfo (e); + EsObject * mlocobj = es_pointer_new (OPT_TYPE_MATCHLOC, mloc); + if (es_error_p (mlocobj)) + { + eFree (mloc); + return mlocobj; + } + + opt_vm_ostack_pop (vm); + opt_vm_ostack_push (vm, mlocobj); + es_object_unref (mlocobj); + return es_false; +} + static EsObject* lrop_get_match_string_common (OptVM *vm, int i, int npop) { struct lregexControlBlock *lcb = opt_vm_get_app_data (vm); @@ -3768,6 +3807,12 @@ static struct optscriptOperatorRegistration lropOperators [] = { .help_str = "group:int /start|/end _MATCHLOC matchloc%" "group:int _MATCHLOC matchloc", }, + { + .name = "_tagloc", + .fn = lrop_get_tag_loc, + .arity = 1, + .help_str = "index:int _TAGLOC matchloc", + }, { .name = "_tag", .fn = lrop_make_tag, From 3773fd9491be436445ce42891fceb9a7fccde3e7 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 16:23:34 +0900 Subject: [PATCH 08/19] optscript: fix the way to handle meta characters at the end of ? char notation Signed-off-by: Masatake YAMATO --- Tmain/optscript.d/read-and-print.expected | 3 +++ Tmain/optscript.d/read-and-print.ps | Bin 1553 -> 1595 bytes dsl/optscript.c | 24 +++++++++++----------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Tmain/optscript.d/read-and-print.expected b/Tmain/optscript.d/read-and-print.expected index a7c5d0ee3b..63f4fd147b 100644 --- a/Tmain/optscript.d/read-and-print.expected +++ b/Tmain/optscript.d/read-and-print.expected @@ -83,3 +83,6 @@ efg /B [0 1 2] >> ] >> ] +char after metachar +[97] +[10] diff --git a/Tmain/optscript.d/read-and-print.ps b/Tmain/optscript.d/read-and-print.ps index 0d179fdc6d55c2d3c835e5c98e7d7061623ba288..504da17912407c56f20d174036483af14a97bc85 100644 GIT binary patch delta 50 xcmbQpvzupwAe$DKMsh}CkwRixNotWoZfZ#)h^wh!%N1>(7^`3lqGR&F3;>D}4z2(I delta 7 OcmdnZGm&S5AR7P*sRAqj diff --git a/dsl/optscript.c b/dsl/optscript.c index 1b22efee15..d092aa594d 100644 --- a/dsl/optscript.c +++ b/dsl/optscript.c @@ -976,6 +976,16 @@ vm_read_skip_comment(OptVM *vm) } } +#define is_meta_char(c) ((c) == '%' \ + || (c) == '/' \ + || (c) == '(' \ + || (c) == '{' \ + || (c) == '}' \ + || (c) == '[' \ + || (c) == ']' \ + || (c) == '<' \ + || (c) == '>') + static EsObject* vm_read_char (OptVM *vm) { @@ -1016,7 +1026,7 @@ vm_read_char (OptVM *vm) return OPT_ERR_SYNTAX; } c = mio_getc (vm->in); - if (!(c == EOF || isspace (c))) + if (!(c == EOF || isspace (c) || is_meta_char (c))) return OPT_ERR_SYNTAX; mio_ungetc (vm->in, c); return es_integer_new (i); @@ -1026,7 +1036,7 @@ vm_read_char (OptVM *vm) i = c; c = mio_getc (vm->in); - if (!(c == EOF || isspace (c))) + if (!(c == EOF || isspace (c) || is_meta_char (c))) return OPT_ERR_SYNTAX; mio_ungetc (vm->in, c); @@ -1100,16 +1110,6 @@ vm_read_string (OptVM *vm) } } -#define is_meta_char(c) ((c) == '%' \ - || (c) == '/' \ - || (c) == '(' \ - || (c) == '{' \ - || (c) == '}' \ - || (c) == '[' \ - || (c) == ']' \ - || (c) == '<' \ - || (c) == '>') - static EsObject* vm_read_generic(OptVM *vm, int c, EsObject * (* make_object) (const char *, void *), From 6998fc11f368a2acf6e4d135b9b93cf723ce38fb Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:41:58 +0900 Subject: [PATCH 09/19] optscript,refactor: refactor the common code within forall backends forall operators has array, dict, and string backends. Unify the similar code in the backends into one. Signed-off-by: Masatake YAMATO --- dsl/optscript.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/dsl/optscript.c b/dsl/optscript.c index d092aa594d..bdd90e917e 100644 --- a/dsl/optscript.c +++ b/dsl/optscript.c @@ -4061,9 +4061,6 @@ op__forall_array (OptVM *vm, EsObject *name, if (((int)c) < 0) return OPT_ERR_INTERNALERROR; /* TODO: integer overflow */ - ptrArrayRemoveLast (vm->ostack); - ptrArrayRemoveLast (vm->ostack); - EsObject *e = es_false; for (int i = 0; i < c; i++) { @@ -4076,8 +4073,6 @@ op__forall_array (OptVM *vm, EsObject *name, break; } - es_object_unref (proc); - es_object_unref (obj); return e; } @@ -4127,15 +4122,9 @@ op__forall_dict (OptVM *vm, EsObject *name, .proc = proc }; - ptrArrayRemoveLast (vm->ostack); - ptrArrayRemoveLast (vm->ostack); - if (!hashTableForeachItem (ht, dict_forall_cb, &data)) r = data.err; - es_object_unref (proc); - es_object_unref (obj); - return r; } @@ -4148,9 +4137,6 @@ op__forall_string (OptVM *vm, EsObject *name, if (((int)c) < 0) return OPT_ERR_INTERNALERROR; /* TODO: integer overflow */ - ptrArrayRemoveLast (vm->ostack); - ptrArrayRemoveLast (vm->ostack); - EsObject *e = es_false; for (int i = 0; i < c; i++) { @@ -4163,9 +4149,6 @@ op__forall_string (OptVM *vm, EsObject *name, break; } - es_object_unref (proc); - es_object_unref (obj); - return e; } @@ -4180,14 +4163,24 @@ op_forall (OptVM *vm, EsObject *name) EsObject *obj = ptrArrayItemFromLast (vm->ostack, 1); int t = es_object_get_type (obj); + EsObject * (* proc_driver) (OptVM *, EsObject *, + EsObject *, EsObject *) = NULL; if (t == OPT_TYPE_ARRAY) - return op__forall_array (vm, name, proc, obj); + proc_driver = op__forall_array; else if (t == OPT_TYPE_DICT) - return op__forall_dict (vm, name, proc, obj); + proc_driver = op__forall_dict; else if (t == OPT_TYPE_STRING) - return op__forall_string (vm, name, proc, obj); + proc_driver = op__forall_string; + else + return OPT_ERR_TYPECHECK; - return OPT_ERR_TYPECHECK; + ptrArrayRemoveLast (vm->ostack); + ptrArrayRemoveLast (vm->ostack); + EsObject *e = (*proc_driver) (vm, name, proc, obj); + es_object_unref (proc); + es_object_unref (obj); + + return e; } static EsObject* From a4af4778b5c5da11eecd12fc25e46ab67056681d Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:47:22 +0900 Subject: [PATCH 10/19] optscript: handle exit in for and forall Signed-off-by: Masatake YAMATO --- Tmain/optscript.d/control.expected | 8 ++++++++ Tmain/optscript.d/control.ps | Bin 1542 -> 2074 bytes dsl/optscript.c | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/Tmain/optscript.d/control.expected b/Tmain/optscript.d/control.expected index 30bd89d582..c75931ac73 100644 --- a/Tmain/optscript.d/control.expected +++ b/Tmain/optscript.d/control.expected @@ -26,6 +26,14 @@ 5 7 9 +exit in for: +=> passed +exit in forall string: +=> passed +exit in forall array: +=> passed +exit in forall dict: +=> passed (---------------- countexecstack ----------------) 3 (---------------- execstack ----------------) diff --git a/Tmain/optscript.d/control.ps b/Tmain/optscript.d/control.ps index 5ed5c4899659f5d88e7e1965f9a25c5e8bb4b7d0..22bae4da00ae0e7a9475f24254bcd5f4e3fea3b5 100644 GIT binary patch delta 518 zcmcJKJ!-=+7=}r*i3~l$yVaiThR~t-=L9`L$e_ql5E$E)ZDerror, OPT_KEY_newerror, es_false); + r = es_false; + break; + } if (es_error_p (r)) break; } @@ -4180,6 +4186,11 @@ op_forall (OptVM *vm, EsObject *name) es_object_unref (proc); es_object_unref (obj); + if (es_object_equal (e, OPT_ERR_INVALIDEXIT)) + { + dict_op_def (vm->error, OPT_KEY_newerror, es_false); + e = es_false; + } return e; } From bf0cb18d7e1454c1bcefe750617857119a111c58 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:49:35 +0900 Subject: [PATCH 11/19] optscript: clear newerror member in error dict when repeat receives exit Signed-off-by: Masatake YAMATO --- dsl/optscript.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsl/optscript.c b/dsl/optscript.c index 0d1e89a65f..ee390401fb 100644 --- a/dsl/optscript.c +++ b/dsl/optscript.c @@ -3713,6 +3713,7 @@ op_repeat (OptVM *vm, EsObject *name) e = vm_call_proc (vm, proc); if (es_object_equal (e, OPT_ERR_INVALIDEXIT)) { + dict_op_def (vm->error, OPT_KEY_newerror, es_false); e = es_false; break; } From c22d990c8ed0a89082e04ecfe46269e20a5513fb Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 02:10:17 +0900 Subject: [PATCH 12/19] prelude: introduce _amember Signed-off-by: Masatake YAMATO --- Tmain/common-prelude.d/amember.expected | 12 ++++++++++++ Tmain/common-prelude.d/amember.ps | Bin 0 -> 325 bytes Tmain/common-prelude.d/stdout-expected.txt | 1 + main/CommonPrelude.c | 18 ++++++++++++++++++ main/CommonPrelude.ps | Bin 2891 -> 3205 bytes 5 files changed, 31 insertions(+) create mode 100644 Tmain/common-prelude.d/amember.expected create mode 100644 Tmain/common-prelude.d/amember.ps diff --git a/Tmain/common-prelude.d/amember.expected b/Tmain/common-prelude.d/amember.expected new file mode 100644 index 0000000000..4fc4cb666f --- /dev/null +++ b/Tmain/common-prelude.d/amember.expected @@ -0,0 +1,12 @@ +[/a /b /c] +true +true +true +false +[1 true (abc)] +true +false +true +false +true +false diff --git a/Tmain/common-prelude.d/amember.ps b/Tmain/common-prelude.d/amember.ps new file mode 100644 index 0000000000000000000000000000000000000000..5638c09d9e36a62476857f56abdefd82b6f1c625 GIT binary patch literal 325 zcma#nPgKxPQqWJ1Rj{??ibn8&toX#-)ZC=hB6OJ~oHEHcWl~UO3>8X>N>ddy5|ffO oAvU9m7~)fIgijJ|E{e-hO-@V9DNe;_0N71<6{M!6YoaIs0A!nA#sB~S literal 0 HcmV?d00001 diff --git a/Tmain/common-prelude.d/stdout-expected.txt b/Tmain/common-prelude.d/stdout-expected.txt index 1038e52380..ee7e7d8469 100644 --- a/Tmain/common-prelude.d/stdout-expected.txt +++ b/Tmain/common-prelude.d/stdout-expected.txt @@ -1,3 +1,4 @@ +amember.ps...0 buildstring.ps...0 dedup.ps...0 dedup_spaces.ps...0 diff --git a/main/CommonPrelude.c b/main/CommonPrelude.c index c6102fa343..8def2544cf 100644 --- a/main/CommonPrelude.c +++ b/main/CommonPrelude.c @@ -141,4 +141,22 @@ const char ctagsCommonPrelude []= " pop false\n" " } ifelse\n" "} __bddef\n" +"\n" +"(array key _AMEMBER true|fales)\n" +"/_amember {\n" +" false 3 1 roll\n" +" % false array key\n" +" exch {\n" +" % false key elt\n" +" 1 index\n" +" % false key elt key\n" +" eq {\n" +" % false key\n" +" exch pop true exch\n" +" exit\n" +" } if\n" +" % false key\n" +" } forall\n" +" pop\n" +"} __bddef\n" ; diff --git a/main/CommonPrelude.ps b/main/CommonPrelude.ps index e1fd95b4c73ae06c1fa5ef37b5e02a6e0bf8d310..10b0e39abaa3bc4a58a5c3f2ada170eb89a88ba2 100644 GIT binary patch delta 324 zcmX>t)+)Kdo4cM%BeAF`u~H#BwNfG8(bv`2$u&r!q^LBtCM_{1wOEr&KRz)xH8&}> zNTHfb0SJJ?#i=iH%O*#|e0vnLxT7}FsxHOVG!D6)v YY57HoP@e)#JOk55WTNloJd0PN0Hg8%>k delta 7 OcmZpbJT11tn;QTNKmvvU From ee235db80b296c1c4ca51d6e7a9cbae52cbb515d Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sat, 15 May 2021 16:20:13 +0900 Subject: [PATCH 13/19] main: revise and fix the way to propagate inputStart/End events The original code has code a bug; the inputStart and inputEnd events propagate only to direct sub parsers. Thes event never propagate to sub sub parsers. This change fixe this. The events are propagated recursively in base/sub parser relations. The ways to run prelude/sequel codes and propagate inputStart/End events are unified. As the result a optlib parser running as a sub parser of another optlib parser can run its prelude/sequel codes. Signed-off-by: Masatake YAMATO --- Tmain/optscript-preludes-stack.d/args-c.ctags | 33 ++++++++++++++++++ .../args-cpreprocessor.ctags | 33 ++++++++++++++++++ .../optscript-preludes-stack.d/args-dts.ctags | 33 ++++++++++++++++++ .../exit-expected.txt | 1 + Tmain/optscript-preludes-stack.d/input.c | 1 + Tmain/optscript-preludes-stack.d/input.dts | 0 Tmain/optscript-preludes-stack.d/input.i | 0 Tmain/optscript-preludes-stack.d/run.sh | 29 ++++++++++++++++ .../stderr-expected.txt | 24 +++++++++++++ .../stdout-expected.txt | 0 main/dependency.c | 34 ++++++++++--------- main/parse.c | 11 ++++-- 12 files changed, 181 insertions(+), 18 deletions(-) create mode 100644 Tmain/optscript-preludes-stack.d/args-c.ctags create mode 100644 Tmain/optscript-preludes-stack.d/args-cpreprocessor.ctags create mode 100644 Tmain/optscript-preludes-stack.d/args-dts.ctags create mode 100644 Tmain/optscript-preludes-stack.d/exit-expected.txt create mode 100644 Tmain/optscript-preludes-stack.d/input.c create mode 100644 Tmain/optscript-preludes-stack.d/input.dts create mode 100644 Tmain/optscript-preludes-stack.d/input.i create mode 100644 Tmain/optscript-preludes-stack.d/run.sh create mode 100644 Tmain/optscript-preludes-stack.d/stderr-expected.txt create mode 100644 Tmain/optscript-preludes-stack.d/stdout-expected.txt diff --git a/Tmain/optscript-preludes-stack.d/args-c.ctags b/Tmain/optscript-preludes-stack.d/args-c.ctags new file mode 100644 index 0000000000..734a798401 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/args-c.ctags @@ -0,0 +1,33 @@ +--langdef=C10{base=C} +--_prelude-C10={{ + (prelude C10) == +}} +--_sequel-C10={{ + (sequel C10) == +}} + + +--langdef=C11{base=C} +--_prelude-C11={{ + (prelude C11) == +}} +--_sequel-C11={{ + (sequel C11) == +}} + +--langdef=C20{base=C10} +--_prelude-C20={{ + (prelude C20) == +}} +--_sequel-C20={{ + (sequel C20) == +}} + + +--langdef=C30{base=C20} +--_prelude-C30={{ + (prelude C30) == +}} +--_sequel-C30={{ + (sequel C30) == +}} diff --git a/Tmain/optscript-preludes-stack.d/args-cpreprocessor.ctags b/Tmain/optscript-preludes-stack.d/args-cpreprocessor.ctags new file mode 100644 index 0000000000..85d4e5823a --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/args-cpreprocessor.ctags @@ -0,0 +1,33 @@ +--langdef=CPreProcessor10{base=CPreProcessor} +--_prelude-CPreProcessor10={{ + (prelude CPreProcessor10) == +}} +--_sequel-CPreProcessor10={{ + (sequel CPreProcessor10) == +}} + + +--langdef=CPreProcessor11{base=CPreProcessor} +--_prelude-CPreProcessor11={{ + (prelude CPreProcessor11) == +}} +--_sequel-CPreProcessor11={{ + (sequel CPreProcessor11) == +}} + +--langdef=CPreProcessor20{base=CPreProcessor10} +--_prelude-CPreProcessor20={{ + (prelude CPreProcessor20) == +}} +--_sequel-CPreProcessor20={{ + (sequel CPreProcessor20) == +}} + + +--langdef=CPreProcessor30{base=CPreProcessor20} +--_prelude-CPreProcessor30={{ + (prelude CPreProcessor30) == +}} +--_sequel-CPreProcessor30={{ + (sequel CPreProcessor30) == +}} diff --git a/Tmain/optscript-preludes-stack.d/args-dts.ctags b/Tmain/optscript-preludes-stack.d/args-dts.ctags new file mode 100644 index 0000000000..1638a72846 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/args-dts.ctags @@ -0,0 +1,33 @@ +--langdef=DTS10{base=DTS} +--_prelude-DTS10={{ + (prelude DTS10) == +}} +--_sequel-DTS10={{ + (sequel DTS10) == +}} + + +--langdef=DTS11{base=DTS} +--_prelude-DTS11={{ + (prelude DTS11) == +}} +--_sequel-DTS11={{ + (sequel DTS11) == +}} + +--langdef=DTS20{base=DTS10} +--_prelude-DTS20={{ + (prelude DTS20) == +}} +--_sequel-DTS20={{ + (sequel DTS20) == +}} + + +--langdef=DTS30{base=DTS20} +--_prelude-DTS30={{ + (prelude DTS30) == +}} +--_sequel-DTS30={{ + (sequel DTS30) == +}} diff --git a/Tmain/optscript-preludes-stack.d/exit-expected.txt b/Tmain/optscript-preludes-stack.d/exit-expected.txt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/exit-expected.txt @@ -0,0 +1 @@ +0 diff --git a/Tmain/optscript-preludes-stack.d/input.c b/Tmain/optscript-preludes-stack.d/input.c new file mode 100644 index 0000000000..936ffd8809 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/input.c @@ -0,0 +1 @@ +/* EMPTY */ diff --git a/Tmain/optscript-preludes-stack.d/input.dts b/Tmain/optscript-preludes-stack.d/input.dts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tmain/optscript-preludes-stack.d/input.i b/Tmain/optscript-preludes-stack.d/input.i new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tmain/optscript-preludes-stack.d/run.sh b/Tmain/optscript-preludes-stack.d/run.sh new file mode 100644 index 0000000000..f0bc862611 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/run.sh @@ -0,0 +1,29 @@ +# Copyright: 2021 Masatake YAMATO +# License: GPL-2 + +CTAGS=$1 + +. ../utils.sh +: && + ${CTAGS} --quiet --options=NONE\ + --_prelude-C='{{ (enter C) == }}' \ + --_sequel-C='{{ (leave C) == }}' \ + --options=./args-c.ctags -o - input.c && + ${CTAGS} --quiet --options=NONE \ + --_prelude-DTS='{{ (enter DTS) == }}' \ + --_sequel-DTS='{{ (leave DTS) == }}' \ + --options=./args-dts.ctags -o - input.dts && + ${CTAGS} --quiet --options=NONE --map-CPreProcessor=+.i \ + --_prelude-CPreProcessor='{{ (enter CPreProcessor) == }}' \ + --_sequel-CPreProcessor='{{ (leave CPreProcessor) == }}' \ + --options=./args-cpreprocessor.ctags -o - input.i + +# +# BUGS: The following two don't work because in-use marker is not set to +# the subparsers of the CPreprocessor parser. The CPreprocessor parser must +# mark in-use on its sub parsers to call the inputStart and inputEnd methods +# in the foreachSubparser loop. +# +# ${CTAGS} --quiet --options=NONE --options=./args-cpreprocessor.ctags -o - input.c +# ${CTAGS} --quiet --options=NONE --options=./args-cpreprocessor.ctags -o - input.dts +# diff --git a/Tmain/optscript-preludes-stack.d/stderr-expected.txt b/Tmain/optscript-preludes-stack.d/stderr-expected.txt new file mode 100644 index 0000000000..dd8d7cb864 --- /dev/null +++ b/Tmain/optscript-preludes-stack.d/stderr-expected.txt @@ -0,0 +1,24 @@ +(enter C) +(prelude C10) +(prelude C20) +(prelude C30) +(prelude C11) +(sequel C30) +(sequel C20) +(sequel C10) +(sequel C11) +(leave C) +(enter DTS) +(prelude DTS10) +(prelude DTS20) +(prelude DTS30) +(prelude DTS11) +(sequel DTS30) +(sequel DTS20) +(sequel DTS10) +(sequel DTS11) +(leave DTS) +ctags: Warning: Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: CPreProcessor +ctags: Warning: Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: CPreProcessor +(enter CPreProcessor) +(leave CPreProcessor) diff --git a/Tmain/optscript-preludes-stack.d/stdout-expected.txt b/Tmain/optscript-preludes-stack.d/stdout-expected.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/main/dependency.c b/main/dependency.c index af800feef8..9f4767cb22 100644 --- a/main/dependency.c +++ b/main/dependency.c @@ -145,17 +145,18 @@ extern void notifyInputStart (void) { subparser *s; - foreachSubparser(s, false) - { - langType lang = getSubparserLanguage (s); - notifyLanguageRegexInputStart (lang); + /* for running prelude of optlib */ + langType lang = getInputLanguage (); + notifyLanguageRegexInputStart (lang); + foreachSubparser(s, true) + { + enterSubparser(s); if (s->inputStart) - { - enterSubparser(s); s->inputStart (s); - leaveSubparser(); - } + /* propagate the event recursively */ + notifyInputStart (); + leaveSubparser(); } } @@ -163,18 +164,19 @@ extern void notifyInputEnd (void) { subparser *s; - foreachSubparser(s, false) + foreachSubparser(s, true) { + enterSubparser(s); + /* propagate the event recursively */ + notifyInputEnd (); if (s->inputEnd) - { - enterSubparser(s); s->inputEnd (s); - leaveSubparser(); - } - - langType lang = getSubparserLanguage (s); - notifyLanguageRegexInputEnd (lang); + leaveSubparser(); } + + /* for running sequel of optlib */ + langType lang = getInputLanguage (); + notifyLanguageRegexInputEnd (lang); } extern void notifyMakeTagEntry (const tagEntryInfo *tag, int corkIndex) diff --git a/main/parse.c b/main/parse.c index f75ac5f043..5583ebfbe9 100644 --- a/main/parse.c +++ b/main/parse.c @@ -2044,6 +2044,15 @@ static void pre_lang_def_flag_base_long (const char* const optflag, const char* } + langType cpreproc = getNamedLanguage ("CPreProcessor", 0); + if (base == cpreproc) + { + error (WARNING, + "Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: %s", + param); + return; + } + flag_data->base = eStrdup(param); } @@ -3708,7 +3717,6 @@ static rescanReason createTagsForFile (const langType language, Assert (lang->parser || lang->parser2); - notifyLanguageRegexInputStart (language); notifyInputStart (); if (lang->parser != NULL) @@ -3717,7 +3725,6 @@ static rescanReason createTagsForFile (const langType language, rescan = lang->parser2 (passCount); notifyInputEnd (); - notifyLanguageRegexInputEnd (language); return rescan; } From d813f9ed1c77682bfab26de083c7e1ce14299930 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Thu, 13 May 2021 07:20:46 +0900 Subject: [PATCH 14/19] operator: revise the accessor for typeref field Signed-off-by: Masatake YAMATO --- Units/optscript.r/op-typeref.d/args.ctags | 30 ++++++++- Units/optscript.r/op-typeref.d/expected.tags | 8 ++- Units/optscript.r/op-typeref.d/input.unknown | 8 +++ main/field.c | 64 +++++++++++++++----- 4 files changed, 91 insertions(+), 19 deletions(-) diff --git a/Units/optscript.r/op-typeref.d/args.ctags b/Units/optscript.r/op-typeref.d/args.ctags index 64a94ff9f8..28b9a52ce3 100644 --- a/Units/optscript.r/op-typeref.d/args.ctags +++ b/Units/optscript.r/op-typeref.d/args.ctags @@ -1,7 +1,35 @@ --langdef=X --map-X=.unknown --kinddef-X=d,def,definitions +--kinddef-X=t,type,type definitions +--_prelude-X={{ + /typedict 5 dict def +}} + +--regex-X=/^type[ ]+([A-Z]+)$/\1/t/{{ + typedict \1 cvn . put +}} + +# [string string] --regex-X=/def[ ]+([a-z]+)[ ]*:[ ]*([a-z]+)/\1/d/{{ - . [ (typename) \2 ] typeref: + . [ (postfix) \2 ] typeref: +}} + +# string +--regex-X=/def[ ]+<([a-z]+)>[ ]*([a-z]+)/\2/d/{{ + . \1 typeref: +}} + +# index +--regex-X=/def[ ]+([A-Z]+)\^([a-z]+)/\2/d/{{ + typedict \1 cvn known { + . typedict \1 cvn get typeref: + } if +}} + +# false +--regex-X=/def[ ]+([a-z]+)\^!([a-z]+)/\2/d/{{ + . \1 typeref: + . false typeref: }} diff --git a/Units/optscript.r/op-typeref.d/expected.tags b/Units/optscript.r/op-typeref.d/expected.tags index f9a9bebdd8..f6f23bacfb 100644 --- a/Units/optscript.r/op-typeref.d/expected.tags +++ b/Units/optscript.r/op-typeref.d/expected.tags @@ -1,2 +1,6 @@ -a input.unknown /^def a:int = 1$/;" d typeref:typename:int -b input.unknown /^def b:str = "abc"$/;" d typeref:typename:str +T input.unknown /^type T$/;" t +a input.unknown /^def a:int = 1$/;" d typeref:postfix:int +b input.unknown /^def b:str = "abc"$/;" d typeref:postfix:str +c input.unknown /^def c = true$/;" d typeref:typename:boolean +d input.unknown /^def T^d = 1.0$/;" d typeref:type:T +e input.unknown /^def float^!e = 1.0$/;" d diff --git a/Units/optscript.r/op-typeref.d/input.unknown b/Units/optscript.r/op-typeref.d/input.unknown index 6fcfdafbb8..3e08171af4 100644 --- a/Units/optscript.r/op-typeref.d/input.unknown +++ b/Units/optscript.r/op-typeref.d/input.unknown @@ -1,2 +1,10 @@ def a:int = 1 def b:str = "abc" + +def c = true + +type T + +def T^d = 1.0 + +def float^!e = 1.0 diff --git a/main/field.c b/main/field.c index fb83b6c6c2..10701e5bb7 100644 --- a/main/field.c +++ b/main/field.c @@ -295,9 +295,9 @@ static fieldDefinition fieldDefinitionsExuberant [] = { .doesContainAnyChar = NULL, .isValueAvailable = isTyperefFieldAvailable, .dataType = FIELDTYPE_STRING, - .getterValueType = "[string|false string|false]", + .getterValueType = "[string string]", .getValueObject = getFieldValueForTyperef, - .setterValueType = "[string|false string|false]|false", + .setterValueType = "[string string]|string|index:int|false", .checkValueForSetter= checkFieldValueForTyperef, .setValueObject = setFieldValueForTyperef, }, @@ -1573,18 +1573,21 @@ static EsObject* getFieldValueForTyperef (const tagEntryInfo *tag, const fieldDe static EsObject* setFieldValueForTyperef (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj) { + const char *tmp[2] = {NULL, NULL}; + + for (int i = 0 ; i < 2; i++) + { + if (tag->extensionFields.typeRef [i]) + tmp [i] = tag->extensionFields.typeRef [i]; + } + if (es_boolean_p (obj)) { for (int i = 0 ; i < 2; i++) { if (tag->extensionFields.typeRef [i]) - { - /* TODO: (void *) */ - eFree ((void *)tag->extensionFields.typeRef [i]); tag->extensionFields.typeRef [i] = NULL; - } } - return es_false; } else if (es_object_get_type (obj) == OPT_TYPE_ARRAY) { @@ -1594,23 +1597,44 @@ static EsObject* setFieldValueForTyperef (tagEntryInfo *tag, const fieldDefiniti if (es_boolean_p (e)) { if (tag->extensionFields.typeRef [i]) - { - /* TODO: (void *) */ - eFree ((void *)tag->extensionFields.typeRef [i]); tag->extensionFields.typeRef [i] = NULL; - } } else if (es_object_get_type (e) == OPT_TYPE_STRING) { - if (tag->extensionFields.typeRef [i]) - eFree ((void *)tag->extensionFields.typeRef [i]); /* TODO: (void *) */ tag->extensionFields.typeRef [i] = eStrdup (opt_string_get_cstr (e)); } } - return es_false; } - AssertNotReached(); - return OPT_ERR_TYPECHECK; + else if (es_object_get_type (obj) == OPT_TYPE_STRING) + { + const char *str = opt_string_get_cstr (obj); + tag->extensionFields.typeRef [0] = eStrdup ("typename"); + tag->extensionFields.typeRef [1] = eStrdup (str); + } + else if (es_integer_p (obj)) + { + int index = es_integer_get (obj); + tagEntryInfo *e = getEntryInCorkQueue (index); + if (e) + { + const char *name = e->name; + const char *kindName = getLanguageKindName (e->langType, e->kindIndex); + + tag->extensionFields.typeRef [0] = eStrdup (kindName); + tag->extensionFields.typeRef [1] = eStrdup (name); + } + } + else + { + AssertNotReached(); + return OPT_ERR_TYPECHECK; + } + + for (int i = 0; i < 2; i++) + if (tmp [i]) + eFree ((char*)tmp[i]); + + return es_false; } static EsObject* checkFieldValueForTyperef (const fieldDefinition *fdef, const EsObject *obj) @@ -1632,6 +1656,14 @@ static EsObject* checkFieldValueForTyperef (const fieldDefinition *fdef, const E return OPT_ERR_TYPECHECK; } } + else if (es_object_get_type (obj) == OPT_TYPE_STRING) + ; + else if (es_integer_p (obj)) + { + int index = es_integer_get (obj); + if (index >= countEntryInCorkQueue ()) + return OPTSCRIPT_ERR_NOTAGENTRY; + } else return OPT_ERR_TYPECHECK; return es_false; From 3c63479c56b9b0592427dcb638e7c2bf84be8e86 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 14 May 2021 22:56:40 +0900 Subject: [PATCH 15/19] operator: introduce getter for the input field Signed-off-by: Masatake YAMATO --- .../stdout-expected.txt | 24 +++++++++---------- .../stdout-expected.txt | 8 +++---- Tmain/list-fields.d/stdout-expected.txt | 2 +- main/field.c | 11 +++++++++ 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Tmain/fixed-field-handling.d/stdout-expected.txt b/Tmain/fixed-field-handling.d/stdout-expected.txt index 84dadf9e24..b2d68385dd 100644 --- a/Tmain/fixed-field-handling.d/stdout-expected.txt +++ b/Tmain/fixed-field-handling.d/stdout-expected.txt @@ -1,49 +1,49 @@ # writer=default N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern # writer=u-ctags N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern # writer=e-ctags N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern # writer=etags -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=xref -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=json -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=xref N -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name no NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=xref F -F input no NONE s-- no -- input file +F input no NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=xref P -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern no NONE s-b no -- pattern # writer=json N -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name no NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=json F -F input no NONE s-- no -- input file +F input no NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern yes NONE s-b no -- pattern # writer=json P -F input yes NONE s-- no -- input file +F input yes NONE s-- no r- input file N name yes NONE s-- no rw tag name P pattern no NONE s-b no -- pattern # writer=json --fields=-N diff --git a/Tmain/list-fields-fixed-field-handling.d/stdout-expected.txt b/Tmain/list-fields-fixed-field-handling.d/stdout-expected.txt index 270fa10bc2..cde4cf8a8e 100644 --- a/Tmain/list-fields-fixed-field-handling.d/stdout-expected.txt +++ b/Tmain/list-fields-fixed-field-handling.d/stdout-expected.txt @@ -1,7 +1,7 @@ # --output-format=u-ctags --fields=n --list-fields #LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern C compact no NONE s-- no -- compact input line (used only in xref output) E extras no NONE s-- no r- Extra tag type information @@ -27,7 +27,7 @@ z kind no NONE s-- no r- [tags output] pr # --fields=n --output-format=u-ctags --list-fields #LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern C compact no NONE s-- no -- compact input line (used only in xref output) E extras no NONE s-- no r- Extra tag type information @@ -54,7 +54,7 @@ z kind no NONE s-- no r- [tags output] pr #LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION C compact no NONE s-- no -- compact input line (used only in xref output) E extras no NONE s-- no r- Extra tag type information -F input no NONE s-- no -- input file +F input no NONE s-- no r- input file K NONE no NONE s-- no -- Kind of tag in long-name form N name no NONE s-- no rw tag name P pattern no NONE s-b no -- pattern @@ -80,7 +80,7 @@ z kind no NONE s-- no r- [tags output] pr #LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION C compact no NONE s-- no -- compact input line (used only in xref output) E extras no NONE s-- no r- Extra tag type information -F input no NONE s-- no -- input file +F input no NONE s-- no r- input file K NONE no NONE s-- no -- Kind of tag in long-name form N name no NONE s-- no rw tag name P pattern no NONE s-b no -- pattern diff --git a/Tmain/list-fields.d/stdout-expected.txt b/Tmain/list-fields.d/stdout-expected.txt index 6d80ab6cec..4f799142d2 100644 --- a/Tmain/list-fields.d/stdout-expected.txt +++ b/Tmain/list-fields.d/stdout-expected.txt @@ -1,6 +1,6 @@ #LETTER NAME ENABLED LANGUAGE JSTYPE FIXED OP DESCRIPTION N name yes NONE s-- yes rw tag name -F input yes NONE s-- yes -- input file +F input yes NONE s-- yes r- input file P pattern yes NONE s-b yes -- pattern C compact no NONE s-- no -- compact input line (used only in xref output) E extras no NONE s-- no r- Extra tag type information diff --git a/main/field.c b/main/field.c index 10701e5bb7..31d3a244c5 100644 --- a/main/field.c +++ b/main/field.c @@ -89,6 +89,7 @@ static bool isEpochAvailable (const tagEntryInfo *const tag); static EsObject* getFieldValueForName (const tagEntryInfo *, const fieldDefinition *); static EsObject* setFieldValueForName (tagEntryInfo *, const fieldDefinition *, const EsObject *); +static EsObject* getFieldValueForInput (const tagEntryInfo *, const fieldDefinition *); static EsObject* getFieldValueForKind (const tagEntryInfo *, const fieldDefinition *); static EsObject* getFieldValueForTyperef (const tagEntryInfo *, const fieldDefinition *); static EsObject* setFieldValueForTyperef (tagEntryInfo *, const fieldDefinition *, const EsObject *); @@ -134,6 +135,11 @@ static fieldDefinition fieldDefinitionsFixed [] = { .doesContainAnyChar = doesContainAnyCharInInput, .isValueAvailable = NULL, .dataType = FIELDTYPE_STRING, + .getterValueType = NULL, + .getValueObject = getFieldValueForInput, + .setterValueType = NULL, + .checkValueForSetter= NULL, + .setValueObject = NULL, }, [FIELD_PATTERN] = { .letter = 'P', @@ -1545,6 +1551,11 @@ static EsObject* setFieldValueForName (tagEntryInfo *tag, const fieldDefinition return es_false; } +static EsObject* getFieldValueForInput (const tagEntryInfo *tag, const fieldDefinition *fdef) +{ + return opt_string_new_from_cstr (tag->inputFileName); +} + static EsObject* getFieldValueForKind (const tagEntryInfo *tag, const fieldDefinition *fdef) { const char *kind_name = getLanguageKindName (tag->langType, tag->kindIndex); From 77bd99b5f13c84db1e345ceb43a4294f34b31306 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 14 May 2021 23:50:13 +0900 Subject: [PATCH 16/19] lregex: introduce a helper function for getting the match string from the window Signed-off-by: Masatake YAMATO --- main/lregex.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/main/lregex.c b/main/lregex.c index 955127145f..ef0bd0bb5d 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -275,6 +275,8 @@ static EsObject* scriptEval (OptVM *vm, EsObject *optscript); static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum hook hook); static void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb); +static char* make_match_string (scriptWindow *window, int group); + static void deleteTable (void *ptrn) { struct regexTable *t = ptrn; @@ -3353,21 +3355,14 @@ static EsObject* lrop_get_match_string_common (OptVM *vm, int i, int npop) { struct lregexControlBlock *lcb = opt_vm_get_app_data (vm); scriptWindow *window = lcb->window; - if (window == NULL - || 0 >= i - || window->nmatch <= i - || window->pmatch [i].rm_so == -1) + const char *cstr = make_match_string (window, i); + if (!cstr) { for (; npop > 0; npop--) opt_vm_ostack_pop (vm); opt_vm_ostack_push (vm, es_false); return es_false; } - - const int len = window->pmatch [i].rm_eo - window->pmatch [i].rm_so; - const char *start = window->line + window->pmatch [i].rm_so; - - const char *cstr = eStrndup (start, len); EsObject *str = opt_string_new_from_cstr (cstr); eFree ((void *)cstr); @@ -3408,6 +3403,20 @@ static EsObject* lrop_get_match_string_gorup_on_stack (OptVM *vm, EsObject *name return es_false; } +static char* make_match_string (scriptWindow *window, int group) +{ + if (window == NULL + || 0 >= group + || window->nmatch <= group + || window->pmatch [group].rm_so == -1) + return NULL; + + const int len = window->pmatch [group].rm_eo - window->pmatch [group].rm_so; + const char *start = window->line + window->pmatch [group].rm_so; + + return eStrndup (start, len); +} + static EsObject* lrop_set_scope (OptVM *vm, EsObject *name) { EsObject *corkIndex = opt_vm_ostack_top (vm); From cf6b3bb981bc1678633b2958dbc9b0dda5af9916 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sat, 15 May 2021 18:07:18 +0900 Subject: [PATCH 17/19] lregex: introduce a helper function for getting the match location from the window Signed-off-by: Masatake YAMATO --- main/lregex.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/main/lregex.c b/main/lregex.c index ef0bd0bb5d..c936ecd8d2 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -276,6 +276,7 @@ static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum hook static void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb); static char* make_match_string (scriptWindow *window, int group); +static matchLoc *make_mloc (scriptWindow *window, int group, bool start); static void deleteTable (void *ptrn) { @@ -3275,28 +3276,10 @@ static EsObject* lrop_get_match_loc (OptVM *vm, EsObject *name) struct lregexControlBlock *lcb = opt_vm_get_app_data (vm); scriptWindow *window = lcb->window; - if (window == NULL - || window->nmatch <= g - || window->pmatch [g].rm_so == -1) + matchLoc *mloc = make_mloc (window, g, start); + if (mloc == NULL) return OPT_ERR_RANGECHECK; - matchLoc *mloc = xMalloc (1, matchLoc); - if (window->patbuf->regptype == REG_PARSER_SINGLE_LINE) - { - mloc->delta = 0; - mloc->line = getInputLineNumber (); - mloc->pos = getInputFilePosition (); - } - else - { - mloc->delta = (start - ? window->pmatch [g].rm_so - : window->pmatch [g].rm_eo); - off_t offset = (window->line + mloc->delta) - window->start; - mloc->line = getInputLineNumberForFileOffset (offset); - mloc->pos = getInputFilePositionForLine (mloc->line); - } - EsObject * mlocobj = es_pointer_new (OPT_TYPE_MATCHLOC, mloc); if (es_error_p (mlocobj)) { @@ -3417,6 +3400,33 @@ static char* make_match_string (scriptWindow *window, int group) return eStrndup (start, len); } +static matchLoc *make_mloc (scriptWindow *window, int group, bool start) +{ + if (window == NULL + || 0 > group + || window->nmatch <= group + || window->pmatch [group].rm_so == -1) + return NULL; + + matchLoc *mloc = xMalloc (1, matchLoc); + if (window->patbuf->regptype == REG_PARSER_SINGLE_LINE) + { + mloc->delta = 0; + mloc->line = getInputLineNumber (); + mloc->pos = getInputFilePosition (); + } + else + { + mloc->delta = (start + ? window->pmatch [group].rm_so + : window->pmatch [group].rm_eo); + off_t offset = (window->line + mloc->delta) - window->start; + mloc->line = getInputLineNumberForFileOffset (offset); + mloc->pos = getInputFilePositionForLine (mloc->line); + } + return mloc; +} + static EsObject* lrop_set_scope (OptVM *vm, EsObject *name) { EsObject *corkIndex = opt_vm_ostack_top (vm); From d619a4cc034ff69c62d0a2c0e80a85855e1873c9 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 16 May 2021 01:58:06 +0900 Subject: [PATCH 18/19] main: consider dynamically allocated xtags when iterating all xtags defintions A for loop was used for the iteration. The original code used XTAG_COUNT as the limit of the loop counter. However, the contestant doesn't consider dynamically allocated parser-specific xtags. The new code uses countXtags() that considers dynamically allocated parser-specific xtags. Signed-off-by: Masatake YAMATO --- Tmain/getter-extras-field.d/stderr-expected.txt | 3 ++- main/entry.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Tmain/getter-extras-field.d/stderr-expected.txt b/Tmain/getter-extras-field.d/stderr-expected.txt index de1ad29c94..1fae71809a 100644 --- a/Tmain/getter-extras-field.d/stderr-expected.txt +++ b/Tmain/getter-extras-field.d/stderr-expected.txt @@ -2,6 +2,7 @@ true [/reference] true [/qualified /reference] -false +true +[/X.foo] true [/reference /X.foo] diff --git a/main/entry.c b/main/entry.c index 4fee79f503..efa6f9792a 100644 --- a/main/entry.c +++ b/main/entry.c @@ -1935,7 +1935,7 @@ extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra) extern bool isTagExtra (const tagEntryInfo *const tag) { - for (unsigned int i = 0; i < XTAG_COUNT; i++) + for (unsigned int i = 0; i < countXtags(); i++) if (isTagExtraBitMarked (tag, i)) return true; return false; From b6124a60ca4730ea006b0411f9909cd38f8bd257 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Fri, 14 May 2021 10:29:50 +0900 Subject: [PATCH 19/19] lregex: generalize prelude and sequel mechanism to allow adding more hooks Signed-off-by: Masatake YAMATO --- main/lregex.c | 31 ++++++++++--------------------- main/lregex_p.h | 5 +++-- main/parse.c | 17 ++++++----------- main/parse.h | 10 ++++++++-- misc/optlib2c | 4 ++-- optlib/markdown.c | 2 +- optlib/pod.c | 2 +- optlib/puppetManifest.c | 2 +- 8 files changed, 32 insertions(+), 41 deletions(-) diff --git a/main/lregex.c b/main/lregex.c index c936ecd8d2..fad3e6388e 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -223,12 +223,6 @@ typedef struct { unsigned int advanceto_delta; } scriptWindow; -enum hook { - HOOK_PRELUDE, - HOOK_SEQUEL, - HOOK_MAX, -}; - struct lregexControlBlock { int currentScope; ptrArray *entries [2]; @@ -240,8 +234,8 @@ struct lregexControlBlock { EsObject *local_dict; - ptrArray *hook[HOOK_MAX]; - ptrArray *hook_code[HOOK_MAX]; + ptrArray *hook[SCRIPT_HOOK_MAX]; + ptrArray *hook_code[SCRIPT_HOOK_MAX]; langType owner; @@ -272,7 +266,7 @@ static void guestRequestSubmit (struct guestRequest *); static EsObject *scriptRead (OptVM *vm, const char *src); static void scriptSetup (OptVM *vm, struct lregexControlBlock *lcb, int corkIndex, scriptWindow *window); static EsObject* scriptEval (OptVM *vm, EsObject *optscript); -static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum hook hook); +static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum scriptHook hook); static void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb); static char* make_match_string (scriptWindow *window, int group); @@ -352,7 +346,7 @@ extern struct lregexControlBlock* allocLregexControlBlock (parserDefinition *par lcb->guest_req = guestRequestNew (); lcb->local_dict = es_nil; - for (int i = 0; i< HOOK_MAX; i++) + for (int i = 0; i< SCRIPT_HOOK_MAX; i++) { lcb->hook[i] = ptrArrayNew (eFree); lcb->hook_code[i] = ptrArrayNew ((ptrArrayDeleteFunc)es_object_unref); @@ -383,7 +377,7 @@ extern void freeLregexControlBlock (struct lregexControlBlock* lcb) es_object_unref (lcb->local_dict); lcb->local_dict = es_nil; - for (int i = 0; i < HOOK_MAX; i++) + for (int i = 0; i < SCRIPT_HOOK_MAX; i++) { ptrArrayDelete (lcb->hook[i]); lcb->hook[i] = NULL; @@ -2020,12 +2014,12 @@ extern void notifyRegexInputStart (struct lregexControlBlock *lcb) lcb->local_dict = opt_dict_new (23); opt_vm_dstack_push (optvm, lcb->local_dict); opt_vm_set_app_data (optvm, lcb); - scriptEvalHook (optvm, lcb, HOOK_PRELUDE); + scriptEvalHook (optvm, lcb, SCRIPT_HOOK_PRELUDE); } extern void notifyRegexInputEnd (struct lregexControlBlock *lcb) { - scriptEvalHook (optvm, lcb, HOOK_SEQUEL); + scriptEvalHook (optvm, lcb, SCRIPT_HOOK_SEQUEL); opt_vm_set_app_data (optvm, NULL); opt_vm_clear (optvm); opt_dict_clear (lcb->local_dict); @@ -3000,7 +2994,7 @@ extern EsObject* scriptEval (OptVM *vm, EsObject *optscript) return optscriptEval (vm, optscript); } -static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum hook hook) +static void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum scriptHook hook) { if (ptrArrayCount (lcb->hook_code[hook]) == 0) { @@ -3036,14 +3030,9 @@ static void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb) lcb->window = NULL; } -extern void addOptscriptPrelude (struct lregexControlBlock *lcb, const char *code) -{ - ptrArrayAdd (lcb->hook[HOOK_PRELUDE], eStrdup (code)); -} - -extern void addOptscriptSequel (struct lregexControlBlock *lcb, const char *code) +extern void addOptscriptToHook (struct lregexControlBlock *lcb, enum scriptHook hook, const char *code) { - ptrArrayAdd (lcb->hook[HOOK_SEQUEL], eStrdup (code)); + ptrArrayAdd (lcb->hook[hook], eStrdup (code)); } /* Return true if available. */ diff --git a/main/lregex_p.h b/main/lregex_p.h index 708f632886..d8b57f6d15 100644 --- a/main/lregex_p.h +++ b/main/lregex_p.h @@ -21,6 +21,7 @@ #include "general.h" #include "kind_p.h" #include "lregex.h" +#include "parse.h" /* * DATA DECLARATIONS @@ -74,8 +75,8 @@ extern void extendRegexTable (struct lregexControlBlock *lcb, const char *src, c extern void initRegexOptscript (void); extern void listRegexOpscriptOperators (FILE *fp); -extern void addOptscriptPrelude (struct lregexControlBlock *lcb, const char *code); -extern void addOptscriptSequel (struct lregexControlBlock *lcb, const char *code); + +extern void addOptscriptToHook (struct lregexControlBlock *lcb, enum scriptHook hook, const char *code); extern void printMultitableStatistics (struct lregexControlBlock *lcb); diff --git a/main/parse.c b/main/parse.c index 5583ebfbe9..f7cb297a0a 100644 --- a/main/parse.c +++ b/main/parse.c @@ -5017,18 +5017,13 @@ extern void addLanguageTagMultiTableRegex(const langType language, name, kinds, flags, disabled); } -extern void addLanguageOptscriptPrelude (langType language, const char *const src) +extern void addLanguageOptscriptToHook (langType language, enum scriptHook hook, const char *const src) { - addOptscriptPrelude (LanguageTable [language].lregexControlBlock, src); -} - -extern void addLanguageOptscriptSequel (langType language, const char *const src) -{ - addOptscriptSequel (LanguageTable [language].lregexControlBlock, src); + addOptscriptToHook (LanguageTable [language].lregexControlBlock, hook, src); } static bool processHookOption (const char *const option, const char *const parameter, const char *prefix, - void (* add) (langType, const char *)) + enum scriptHook hook) { langType language = getLanguageComponentInOption (option, prefix); if (language == LANG_IGNORE) @@ -5040,19 +5035,19 @@ static bool processHookOption (const char *const option, const char *const param const char * code = flagsEval (parameter, NULL, 0, NULL); if (code == NULL) error (FATAL, "Cannot recognized a code block surrounded by `{{' and `}}' after \"%s\" option", option); - (* add) (language, code); + addLanguageOptscriptToHook (language, hook, code); return true; } extern bool processPreludeOption (const char *const option, const char *const parameter) { - return processHookOption (option, parameter, "_prelude-", addLanguageOptscriptPrelude); + return processHookOption (option, parameter, "_prelude-", SCRIPT_HOOK_PRELUDE); } extern bool processSequelOption (const char *const option, const char *const parameter) { - return processHookOption (option, parameter, "_sequel-", addLanguageOptscriptSequel); + return processHookOption (option, parameter, "_sequel-", SCRIPT_HOOK_SEQUEL); } extern bool processPretendOption (const char *const option, const char *const parameter) diff --git a/main/parse.h b/main/parse.h index 67c7f9669a..853302d0a4 100644 --- a/main/parse.h +++ b/main/parse.h @@ -70,6 +70,13 @@ typedef enum { CORK_SYMTAB = (1 << 1), } corkUsage; +/* optlib2c requires the declaration here. */ +enum scriptHook { + SCRIPT_HOOK_PRELUDE, + SCRIPT_HOOK_SEQUEL, + SCRIPT_HOOK_MAX, +}; + struct sParserDefinition { /* defined by parser */ char* name; /* name of language */ @@ -170,8 +177,7 @@ extern void addLanguageTagMultiTableRegex(const langType language, const char* const name, const char* const kinds, const char* const flags, bool *disabled); -extern void addLanguageOptscriptPrelude (langType language, const char *const src); -extern void addLanguageOptscriptSequel (langType language, const char *const src); +extern void addLanguageOptscriptToHook (langType language, enum scriptHook hook, const char *const src); extern void anonGenerate (vString *buffer, const char *prefix, int kind); extern vString *anonGenerateNew (const char *prefix, int kind); diff --git a/misc/optlib2c b/misc/optlib2c index 707d430073..a1f2bb6648 100755 --- a/misc/optlib2c +++ b/misc/optlib2c @@ -614,7 +614,7 @@ EOF : '\n"'); } print <{'sequel'}}) { @@ -625,7 +625,7 @@ EOF : '\n"'); } print <{'tablenames'}) { diff --git a/optlib/markdown.c b/optlib/markdown.c index 75ac560af9..730c72792a 100644 --- a/optlib/markdown.c +++ b/optlib/markdown.c @@ -20,7 +20,7 @@ typedef enum { static void initializeMarkdownParser (const langType language) { - addLanguageOptscriptPrelude (language, + addLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE, "{{ % group:int SCOPEPOPWITHADJUSTMENT -\n" " /scopePopWithAdjustment {\n" " _scopetop {\n" diff --git a/optlib/pod.c b/optlib/pod.c index 43ada4d3ca..c77a035154 100644 --- a/optlib/pod.c +++ b/optlib/pod.c @@ -10,7 +10,7 @@ static void initializePodParser (const langType language CTAGS_ATTR_UNUSED) { - addLanguageOptscriptPrelude (language, + addLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE, "{{ /kindTable\n" " [ /chapter /section /subsection /subsubsection ] def\n" "}}"); diff --git a/optlib/puppetManifest.c b/optlib/puppetManifest.c index cb17c9bc37..f7c4a916ca 100644 --- a/optlib/puppetManifest.c +++ b/optlib/puppetManifest.c @@ -22,7 +22,7 @@ typedef enum { static void initializePuppetManifestParser (const langType language) { - addLanguageOptscriptPrelude (language, + addLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE, "{{ % spec:dict TRYMAKETAG tag:int true\n" " % spec:dict TRYMAKETAG false\n" " /trymaketag {\n"