From 2854ad6d7758d2dd883c5178219ef6e02c51ed53 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Thu, 14 Jun 2018 03:27:00 +0900 Subject: [PATCH] [INCOMPATIBLE][SELF-INCOMPATIBLE] main,docs: don't allow to use numerical char as the first letter in a kind name SELF-INCOMPATIBLE aspect: When defining a kind with --kinddef-, Universal-ctags accepted both an alphabetical and a numerical characters as the initial letter. With this change, Universal-ctags accepts only an alphabetical. INCOMPATIBLE aspect: Universal-ctags accepts numerical characters as the rest letters (other than initial letter) in a kind name. This violates the tags v2 format. This commit documents it as an EXCEPTION. We must convert the EXCEPTION to planed v3 format. Exuberant-ctags doesn't have --kinddef-. However, a kind can be defined with --regex-. This commit doesn't deal with the option. Re-wording is suggsted by @ploxiln. Revising the error message is suggested by @ploxiln. A wrong sentence is pointed out by @ploxiln. Signed-off-by: Masatake YAMATO --- Tmain/kinddef.d/run.sh | 6 ++++ Tmain/kinddef.d/stderr-expected.txt | 9 ++++-- Tmain/kinddef.d/stdout-expected.txt | 6 ++++ docs/format.rst | 9 ++++++ main/parse.c | 46 ++++++++++++++++++++-------- man/ctags-incompatibilities.7.rst.in | 13 ++++++++ man/ctags-optlib.7.rst.in | 12 ++++++-- 7 files changed, 83 insertions(+), 18 deletions(-) diff --git a/Tmain/kinddef.d/run.sh b/Tmain/kinddef.d/run.sh index 4bbc4c822a..8f6ceec4cf 100644 --- a/Tmain/kinddef.d/run.sh +++ b/Tmain/kinddef.d/run.sh @@ -92,6 +92,12 @@ ${CTAGS} --kinddef-MYTEST='x,kind,desc\{' --list-kinds-full=MYTEST title '# use a { in description (2)' ${CTAGS} --kinddef-MYTEST='x,kind,desc\{}' --list-kinds-full=MYTEST +title '# use a number char as the initial letter' +${CTAGS} --kinddef-MYTEST='x,0kind,desc' --list-kinds-full=MYTEST + +title '# use a number char within the body' +${CTAGS} --kinddef-MYTEST='x,k0ind,desc' --list-kinds-full=MYTEST + # title '# use a { and \t in description' # ${CTAGS} --kinddef-MYTEST='x,kind,desc\{}\t' --list-kinds-full=MYTEST diff --git a/Tmain/kinddef.d/stderr-expected.txt b/Tmain/kinddef.d/stderr-expected.txt index 68d67f1fe1..aa11a27fd6 100644 --- a/Tmain/kinddef.d/stderr-expected.txt +++ b/Tmain/kinddef.d/stderr-expected.txt @@ -23,10 +23,10 @@ ctags: the kind name in "--kinddef-MYTEST" option is empty ctags: the kind name in "--kinddef-MYTEST" option is empty # wrong letter in name 1 -ctags: unacceptable char as part of kind name in "--kinddef-MYTEST" option +ctags: non-alphanumeric char is used as part of kind name: 'a x' in "--kinddef-MYTEST" option # wrong letter in name 2 -ctags: unacceptable char as part of kind name in "--kinddef-MYTEST" option +ctags: non-alphanumeric char is used as part of kind name: 'a x' in "--kinddef-MYTEST" option # wrong letter in name 3 ctags: no kind description specified in "--kinddef-MYTEST" option @@ -70,6 +70,11 @@ ctags: Warning: long flags specifier opened with `{' is not closed `}': "{" # use a { in description (2) +# use a number char as the initial letter +ctags: a kind name doesn't start with an alphabetical character: '0kind' in "--kinddef-MYTEST" option + +# use a number char within the body + # use a \ in description # description started from { diff --git a/Tmain/kinddef.d/stdout-expected.txt b/Tmain/kinddef.d/stdout-expected.txt index c1f01d993f..53bf50f6d0 100644 --- a/Tmain/kinddef.d/stdout-expected.txt +++ b/Tmain/kinddef.d/stdout-expected.txt @@ -61,6 +61,12 @@ x kind yes no 0 NONE desc{ #LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION x kind yes no 0 NONE desc{} +# use a number char as the initial letter + +# use a number char within the body +#LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION +x k0ind yes no 0 NONE desc + # use a \ in description #LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION x kind yes no 0 NONE desc\backslash diff --git a/docs/format.rst b/docs/format.rst index 09168649db..99ad1311b6 100644 --- a/docs/format.rst +++ b/docs/format.rst @@ -260,6 +260,9 @@ A tagfield has a name, a colon, and a value: "name:value". are allowed. Lower case is recommended. Case matters ("kind:" and "Kind: are different tagfields). + EXCEPTION: Universal-ctags allows users to use a numerical character + in the name other than its initial letter. + * The value may be empty. It cannot contain a . @@ -482,6 +485,12 @@ Exceptions exceptions. See {tagname} of Proposal section for more detail about the conversion. +.. NOT REVIEWED YET + +#. "name" part of {tagfield} in a tag generated by Universal-ctags may + contain numeric characters, but the first character of the "name" + must be alphabetic. + .. _compat-output: Compatible output and weakness diff --git a/main/parse.c b/main/parse.c index 3fec26af1d..1bbd62474d 100644 --- a/main/parse.c +++ b/main/parse.c @@ -2388,9 +2388,9 @@ static bool processLangDefineKind(const langType language, const char * p = parameter; char *name; char *description; - const char *tmp_start; - const char *tmp_end; - size_t tmp_len; + const char *name_start; + const char *marker_end; + size_t name_len; const char *flags; @@ -2423,28 +2423,48 @@ static bool processLangDefineKind(const langType language, p += 2; if (p[0] == '\0') error (FATAL, "no kind name specified in \"--%s\" option", option); - tmp_end = strchr (p, ','); - if (!tmp_end) + marker_end = strchr (p, ','); + if (!marker_end) error (FATAL, "no kind description specified in \"--%s\" option", option); - tmp_start = p; - while (p != tmp_end) + name_start = p; + while (p != marker_end) { - if (!isalnum (*p)) - error (FATAL, "unacceptable char as part of kind name in \"--%s\" option", option); + if (p == name_start) + { + if (!isalpha(*p)) + { + char *name_in_msg = eStrndup (name_start, marker_end - name_start); + error (FATAL, + "a kind name doesn't start with an alphabetical character: " + "'%s' in \"--%s\" option", + name_in_msg, option); + } + } + else + { + if (!isalnum (*p)) + { + char *name_in_msg = eStrndup (name_start, marker_end - name_start); + error (FATAL, + "non-alphanumeric char is used as part of kind name: " + "'%s' in \"--%s\" option", + name_in_msg, option); + } + } p++; } - if (tmp_end == tmp_start) + if (marker_end == name_start) error (FATAL, "the kind name in \"--%s\" option is empty", option); - tmp_len = tmp_end - tmp_start; - if (strncmp (tmp_start, KIND_FILE_DEFAULT_NAME, tmp_len) == 0) + name_len = marker_end - name_start; + if (strncmp (name_start, KIND_FILE_DEFAULT_NAME, name_len) == 0) error (FATAL, "the kind name " KIND_FILE_DEFAULT_NAME " in \"--%s\" option is reserved", option); - name = eStrndup (tmp_start, tmp_len); + name = eStrndup (name_start, name_len); if (getKindForName (parser->kindControlBlock, name)) { error (WARNING, "the kind for name `%s' specified in \"--%s\" option is already defined.", diff --git a/man/ctags-incompatibilities.7.rst.in b/man/ctags-incompatibilities.7.rst.in index 49203feefe..5d1149f3de 100644 --- a/man/ctags-incompatibilities.7.rst.in +++ b/man/ctags-incompatibilities.7.rst.in @@ -107,6 +107,19 @@ accepts only an alphabetical character. Incompatibilities in tags file format ------------------------------------------------------------- +Using numerical character in the name part of tag tagfield +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The version 2 tags file format, the default output format of +Exuberant-ctags, accepts only alphabetical characters in the name part +of tag tagfield. + +Universal-ctags introduces an exception to this specification; it may +use numerical characters in addition to alphabetical characters as the +letters other than initial letter of the name part. + +The kinds "heading1", "heading2", and "heading3" in the HTML parser +are the examples. Option files loading at starting up time (preload files) ------------------------------------------------------------- diff --git a/man/ctags-optlib.7.rst.in b/man/ctags-optlib.7.rst.in index f522332bd1..1395191cee 100644 --- a/man/ctags-optlib.7.rst.in +++ b/man/ctags-optlib.7.rst.in @@ -173,9 +173,15 @@ OPTION ITEMS other than "F". "F" has been reserved for representing a file since Exuberant-ctags. - *name* also must come from alphabetical characters ('[0-9a-zA-Z]+'). - Do not use "file" as *name*. It has been reserved for representing - a file since Exuberant-ctags. + *name* must start with an alphabetic character, and the rest + must be alphanumeric ('[a-zA-Z][a-zA-Z0-9]*'). Do not use + "file" as *name*. It has been reserved for representing a file + since Exuberant-ctags. + + Note that using a number character in a *name* violates the + version 2 of tags file format. The version 3 revised by + Universal-ctags project allows using the number character as an + initial in a kind name. *description* comes from any printable ASCII characters. The exception is "{" and "\". "{" is reserved for adding flags