From 2561923e8a40459ac0e7463b6f6389875403bec1 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 27 Oct 2024 06:38:31 +0900 Subject: [PATCH 1/3] dsl: fix a typo in help mesasge of substr? Signed-off-by: Masatake YAMATO --- dsl/dsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsl/dsl.c b/dsl/dsl.c index 6043d24969..d1d0f23785 100644 --- a/dsl/dsl.c +++ b/dsl/dsl.c @@ -165,7 +165,7 @@ static DSLProcBind pbinds [] = { { "suffix?", builtin_suffix, NULL, DSL_PATTR_CHECK_ARITY, 2, .helpstr = "(suffix? ) -> " }, { "substr?", builtin_substr, NULL, DSL_PATTR_CHECK_ARITY, 2, - .helpstr = "(substr? string:substr>) -> " }, + .helpstr = "(substr? ) -> " }, { "member", builtin_member, NULL, DSL_PATTR_CHECK_ARITY, 2, .helpstr = "(member ) -> #f|" }, { "downcase", builtin_downcase, NULL, DSL_PATTR_CHECK_ARITY, 1, From 0f780382f364c03a7ecfc2f13ac8f2b4f7820f7a Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 27 Oct 2024 06:41:28 +0900 Subject: [PATCH 2/3] dsl: raise ES_ERROR_MEMORY when malloc returns NULL Signed-off-by: Masatake YAMATO --- dsl/dsl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsl/dsl.c b/dsl/dsl.c index d1d0f23785..27121023c0 100644 --- a/dsl/dsl.c +++ b/dsl/dsl.c @@ -860,6 +860,8 @@ static EsObject* caseop (EsObject *o, int (*op)(int)) { const char *s = es_string_get (o); char *r = strdup (s); + if (r == NULL) + return ES_ERROR_MEMORY; for (char *tmp = r; *tmp != '\0'; tmp++) *tmp = op ((unsigned char) *tmp); From de2550906b8048159726a51a82c2a49ce157a496 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Sun, 27 Oct 2024 06:48:33 +0900 Subject: [PATCH 3/3] dsl: add tr operator Signed-off-by: Masatake YAMATO --- Tmain/readtags-formatter-op-tr.d/input.cpp | 2 + Tmain/readtags-formatter-op-tr.d/output.tags | 40 +++++++++++++++++ Tmain/readtags-formatter-op-tr.d/run.sh | 20 +++++++++ .../stderr-expected.txt | 4 ++ .../stdout-expected.txt | 1 + dsl/dsl.c | 45 +++++++++++++++++++ dsl/dsl.h | 1 + 7 files changed, 113 insertions(+) create mode 100644 Tmain/readtags-formatter-op-tr.d/input.cpp create mode 100644 Tmain/readtags-formatter-op-tr.d/output.tags create mode 100644 Tmain/readtags-formatter-op-tr.d/run.sh create mode 100644 Tmain/readtags-formatter-op-tr.d/stderr-expected.txt create mode 100644 Tmain/readtags-formatter-op-tr.d/stdout-expected.txt diff --git a/Tmain/readtags-formatter-op-tr.d/input.cpp b/Tmain/readtags-formatter-op-tr.d/input.cpp new file mode 100644 index 0000000000..2035077a27 --- /dev/null +++ b/Tmain/readtags-formatter-op-tr.d/input.cpp @@ -0,0 +1,2 @@ +// ctags -o output.tags input.cpp +int __foo(void) { return 0; } diff --git a/Tmain/readtags-formatter-op-tr.d/output.tags b/Tmain/readtags-formatter-op-tr.d/output.tags new file mode 100644 index 0000000000..7fc34103b3 --- /dev/null +++ b/Tmain/readtags-formatter-op-tr.d/output.tags @@ -0,0 +1,40 @@ +!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ +!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ +!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ +!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ +!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/ +!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ +!_TAG_FIELD_DESCRIPTION input /input file/ +!_TAG_FIELD_DESCRIPTION name /tag name/ +!_TAG_FIELD_DESCRIPTION pattern /pattern/ +!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ +!_TAG_FIELD_DESCRIPTION!C++ name /aliased names/ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_KIND_DESCRIPTION!C++ c,class /classes/ +!_TAG_KIND_DESCRIPTION!C++ d,macro /macro definitions/ +!_TAG_KIND_DESCRIPTION!C++ e,enumerator /enumerators (values inside an enumeration)/ +!_TAG_KIND_DESCRIPTION!C++ f,function /function definitions/ +!_TAG_KIND_DESCRIPTION!C++ g,enum /enumeration names/ +!_TAG_KIND_DESCRIPTION!C++ h,header /included header files/ +!_TAG_KIND_DESCRIPTION!C++ m,member /class, struct, and union members/ +!_TAG_KIND_DESCRIPTION!C++ n,namespace /namespaces/ +!_TAG_KIND_DESCRIPTION!C++ s,struct /structure names/ +!_TAG_KIND_DESCRIPTION!C++ t,typedef /typedefs/ +!_TAG_KIND_DESCRIPTION!C++ u,union /union names/ +!_TAG_KIND_DESCRIPTION!C++ v,variable /variable definitions/ +!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ +!_TAG_OUTPUT_FILESEP slash /slash or backslash/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_OUTPUT_VERSION 0.0 /current.age/ +!_TAG_PARSER_VERSION!C++ 0.0 /current.age/ +!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ +!_TAG_PROC_CWD /home/yamato/var/ctags-github/Tmain/readtags-qualifier-op-tr.d/ // +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 6.0.0 // +!_TAG_ROLE_DESCRIPTION!C++!header local /local header/ +!_TAG_ROLE_DESCRIPTION!C++!header system /system header/ +!_TAG_ROLE_DESCRIPTION!C++!macro undef /undefined/ +__foo input.cpp /^int __foo(void) { return 0; }$/;" f typeref:typename:int diff --git a/Tmain/readtags-formatter-op-tr.d/run.sh b/Tmain/readtags-formatter-op-tr.d/run.sh new file mode 100644 index 0000000000..ce5ecea2a3 --- /dev/null +++ b/Tmain/readtags-formatter-op-tr.d/run.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# Copyright: 2024 Masatake YAMATO +# License: GPL-2 + +READTAGS=$3 + +. ../utils.sh + +#V="valgrind --leak-check=full -v" +V= + +skip_if_no_readtags "$READTAGS" + +${V} ${READTAGS} -t output.tags -F '(list (tr $name "_$") #t)' -l + +${V} ${READTAGS} -t output.tags -F '(list (tr $name "_$x") #t)' -l +${V} ${READTAGS} -t output.tags -F '(list (tr $name "_") #t)' -l +${V} ${READTAGS} -t output.tags -F '(list (tr $name "") #t)' -l +${V} ${READTAGS} -t output.tags -F '(list (tr $name 2) #t)' -l diff --git a/Tmain/readtags-formatter-op-tr.d/stderr-expected.txt b/Tmain/readtags-formatter-op-tr.d/stderr-expected.txt new file mode 100644 index 0000000000..b48b8612ce --- /dev/null +++ b/Tmain/readtags-formatter-op-tr.d/stderr-expected.txt @@ -0,0 +1,4 @@ +GOT ERROR in FORMATTING: unexpected-string-length: tr +GOT ERROR in FORMATTING: unexpected-string-length: tr +GOT ERROR in FORMATTING: unexpected-string-length: tr +GOT ERROR in FORMATTING: string-required: tr diff --git a/Tmain/readtags-formatter-op-tr.d/stdout-expected.txt b/Tmain/readtags-formatter-op-tr.d/stdout-expected.txt new file mode 100644 index 0000000000..360bd124d8 --- /dev/null +++ b/Tmain/readtags-formatter-op-tr.d/stdout-expected.txt @@ -0,0 +1 @@ +$$foo diff --git a/dsl/dsl.c b/dsl/dsl.c index 27121023c0..0971a85187 100644 --- a/dsl/dsl.c +++ b/dsl/dsl.c @@ -74,6 +74,7 @@ static EsObject* builtin_substr (EsObject *args, DSLEnv *env); static EsObject* builtin_member (EsObject *args, DSLEnv *env); static EsObject* builtin_downcase (EsObject *args, DSLEnv *env); static EsObject* builtin_upcase (EsObject *args, DSLEnv *env); +static EsObject* builtin_tr (EsObject *args, DSLEnv *env); static EsObject* builtin_length (EsObject *args, DSLEnv *env); static EsObject* bulitin_debug_print (EsObject *args, DSLEnv *env); static EsObject* builtin_entry_ref (EsObject *args, DSLEnv *env); @@ -172,6 +173,8 @@ static DSLProcBind pbinds [] = { .helpstr = "(downcase |) -> |" }, { "upcase", builtin_upcase, NULL, DSL_PATTR_CHECK_ARITY, 1, .helpstr = "(upcase |) -> |" }, + { "tr", builtin_tr, NULL, DSL_PATTR_CHECK_ARITY, 2, + .helpstr = "(tr ) -> " }, { "length", builtin_length, NULL, DSL_PATTR_CHECK_ARITY, 1, .helpstr = "(length ) -> " }, { "+", builtin_add, NULL, DSL_PATTR_CHECK_ARITY, 2, @@ -921,6 +924,48 @@ static EsObject* builtin_upcase (EsObject *args, DSLEnv *env) return builtin_caseop0 (o, upcase); } +static EsObject* tr(const char *target, char from, char to) +{ + char *r = strdup(target); + if (r == NULL) + return ES_ERROR_MEMORY; + + for (char *tmp = r; *tmp != '\0'; tmp++) + { + if (*tmp == from) + *tmp = to; + } + + EsObject *q = es_object_autounref (es_string_new (r)); + free (r); + return q; +} + +static EsObject* builtin_tr (EsObject *args, DSLEnv *env) +{ + EsObject *o_target = es_car(args); + EsObject *o_c0c1 = es_car(es_cdr(args)); + + if (!es_string_p (o_target)) + return o_target; + + if (!es_string_p (o_c0c1)) + dsl_throw (STRING_REQUIRED, es_symbol_intern ("tr")); + + const char *cstr_target = es_string_get (o_target); + const char *cstr_c0c1 = es_string_get (o_c0c1); + + if (cstr_target[0] == '\0') + return o_target; + + size_t len_c0c1 = strlen (cstr_c0c1); + if (len_c0c1 != 2) + dsl_throw (UNEXPECTED_STRING_LENGTH, es_symbol_intern ("tr")); + + return tr (cstr_target, cstr_c0c1[0], cstr_c0c1[1]); +} + + static EsObject* builtin_length (EsObject *args, DSLEnv *env) { EsObject *o = es_car(args); diff --git a/dsl/dsl.h b/dsl/dsl.h index 49cba948d6..23320f3380 100644 --- a/dsl/dsl.h +++ b/dsl/dsl.h @@ -72,6 +72,7 @@ typedef struct sDSLCode DSLCode; #define DSL_ERR_WRONG_TYPE_ARGUMENT (es_error_intern("wrong-type-argument")) #define DSL_ERR_NO_ALT_ENTRY (es_error_intern("the-alternative-entry-unavailable")) #define DSL_ERR_WRONG_REGEX_GROUP (es_error_intern("wrong-regex-group")) +#define DSL_ERR_UNEXPECTED_STRING_LENGTH (es_error_intern("unexpected-string-length")) /* * MACROS