diff --git a/configure.ac b/configure.ac index a7da482fe5..5b907e9750 100644 --- a/configure.ac +++ b/configure.ac @@ -7,6 +7,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) + +dnl You must update PROGRAM_VERSION in main/ctags.h, too. AC_INIT([universal-ctags],[6.0.0]) if ! test -e "${srcdir}/config.h.in"; then diff --git a/extra-cmds/utiltest.c b/extra-cmds/utiltest.c index dfba0442b1..c468fed57c 100644 --- a/extra-cmds/utiltest.c +++ b/extra-cmds/utiltest.c @@ -11,6 +11,7 @@ #include "fname.h" #include "htable.h" #include "routines.h" +#include "vstring.h" #include static void test_fname_absolute(void) @@ -238,6 +239,58 @@ static void test_routines_strrstr(void) TEST_CHECK(strcmp(strrstr("abcdcdb", "cd"), "cdb") == 0); } +static void test_vstring_ncats(void) +{ + vString *vstr = vStringNew (); + + vStringCatS (vstr, "abc"); + vStringNCatS (vstr, "def", 0); + TEST_CHECK(strcmp (vStringValue (vstr), "abc") == 0); + vStringClear (vstr); + + vStringCatS (vstr, "abc"); + vStringNCatS (vstr, "def", 1); + TEST_CHECK(strcmp (vStringValue (vstr), "abcd") == 0); + vStringClear (vstr); + + vStringCatS (vstr, "abc"); + vStringNCatS (vstr, "def", 2); + TEST_CHECK(strcmp (vStringValue (vstr), "abcde") == 0); + vStringClear (vstr); + + vStringCatS (vstr, "abc"); + vStringNCatS (vstr, "def", 3); + TEST_CHECK(strcmp (vStringValue (vstr), "abcdef") == 0); + vStringClear (vstr); + + vStringCatS (vstr, "abc"); + vStringNCatS (vstr, "def", 4); + TEST_CHECK(strcmp (vStringValue (vstr), "abcdef") == 0); + vStringClear (vstr); + + vStringDelete (vstr); +} + +static void test_vstring_truncate_leading(void) +{ + vString *vstr = vStringNewInit (" abcdefg"); + TEST_CHECK(vstr != NULL); + + vStringStripLeading (vstr); + TEST_CHECK(strcmp(vStringValue(vstr), "abcdefg") == 0); + + vStringTruncateLeading (vstr, 3); + TEST_CHECK(strcmp(vStringValue(vstr), "defg") == 0); + + vStringTruncateLeading (vstr, 0); + TEST_CHECK(strcmp(vStringValue(vstr), "defg") == 0); + + vStringTruncateLeading (vstr, 100); + TEST_CHECK(strcmp(vStringValue(vstr), "") == 0); + + vStringDelete (vstr); +} + TEST_LIST = { { "fname/absolute", test_fname_absolute }, { "fname/absolute+cache", test_fname_absolute_with_cache }, @@ -245,5 +298,7 @@ TEST_LIST = { { "htable/update", test_htable_update }, { "htable/grow", test_htable_grow }, { "routines/strrstr", test_routines_strrstr }, + { "vstring/ncats", test_vstring_ncats }, + { "vstring/truncate_leading", test_vstring_truncate_leading }, { NULL, NULL } /* zeroed record marking the end of the list */ }; diff --git a/main/ctags.h b/main/ctags.h index db169bd538..e915d56b4c 100644 --- a/main/ctags.h +++ b/main/ctags.h @@ -39,6 +39,7 @@ For implementation changes like bug fixes, increment PATCH. */ #if defined (HAVE_CONFIG_H) +/* You must update PACKAGE_VERSION in configure.ac, too. */ # define PROGRAM_VERSION PACKAGE_VERSION #else # define PROGRAM_VERSION "6.0.0" diff --git a/main/entry.c b/main/entry.c index 1a8fa59ce2..97ca9e72f4 100644 --- a/main/entry.c +++ b/main/entry.c @@ -1803,8 +1803,9 @@ extern int makeTagEntry (const tagEntryInfo *const tag) if (tag->name [0] == '\0' && (!tag->placeholder)) { if (!doesInputLanguageAllowNullTag()) - error (WARNING, "ignoring null tag in %s(line: %lu)", - getInputFileName (), tag->lineNumber); + error (NOTICE, "ignoring null tag in %s(line: %lu, language: %s)", + getInputFileName (), tag->lineNumber, + getLanguageName (tag->langType)); goto out; } diff --git a/main/options.c b/main/options.c index bf52e3039f..1ca8ae06f5 100644 --- a/main/options.c +++ b/main/options.c @@ -1486,12 +1486,11 @@ static int excludesCompare (struct colprintLine *a, struct colprintLine *b) static void processListExcludesOption(const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED) { - int i; struct colprintTable *table = colprintTableNew ("L:NAME", NULL); - const int max = Excluded ? stringListCount (Excluded) : 0; + const unsigned int max = Excluded ? stringListCount (Excluded) : 0; - for (i = 0; i < max; ++i) + for (unsigned int i = 0; i < max; ++i) { struct colprintLine * line = colprintTableGetNewLine (table); colprintLineAppendColumnVString (line, stringListItem (Excluded, i)); @@ -1501,7 +1500,8 @@ static void processListExcludesOption(const char *const option CTAGS_ATTR_UNUSED colprintTablePrint (table, 0, localOption.withListHeader, localOption.machinable, stdout); colprintTableDelete (table); - if (i == 0) + /* No line is printed. */ + if (max == 0) putchar ('\n'); exit (0); @@ -2307,9 +2307,7 @@ static void freeSearchPathList (searchPathList** pathList) static vString* expandOnSearchPathList (searchPathList *pathList, const char* leaf, bool (* check) (const char *const)) { - unsigned int i; - - for (i = stringListCount (pathList); i > 0; --i) + for (unsigned int i = stringListCount (pathList); i > 0; --i) { const char* const body = vStringValue (stringListItem (pathList, i - 1)); char* tmp = combinePathAndFile (body, leaf); @@ -2581,9 +2579,8 @@ static void addIgnoreListFromFile (langType lang, const char *const fileName) error (FATAL | PERROR, "cannot open \"%s\"", fileName); int c = stringListCount(tokens); - int i; - for(i=0;ilength && isspace ((unsigned char) string->buffer [n])) n++; + vStringTruncateLeading (string, n); +} + +extern void vStringTruncateLeading (vString *const string, const size_t length) +{ + size_t n = vStringLength (string); + if (n > length) + n = length; if (n > 0) { memmove (string->buffer, string->buffer + n, string->length - n); diff --git a/main/vstring.h b/main/vstring.h index 568b289e8d..87fb8c790c 100644 --- a/main/vstring.h +++ b/main/vstring.h @@ -64,10 +64,10 @@ extern void vStringCat (vString *const string, const vString *const s); extern void vStringCatS (vString *const string, const char *const s); extern void vStringNCat (vString *const string, const vString *const s, const size_t length); -/* vStringNCatS calls strlen(S) thought it takes LENGTH because - * the handle the case that strlen(S) is smaller than LENGTH. +/* vStringNCatS calls strnlen(S,LENGTH) thought it takes LENGTH because + * the handle the case that the length of S is smaller than LENGTH. * - * In the case a caller knows strlen(S) equals to or is greater than LENGTH, + * In the case a caller knows the length equals to or is greater than LENGTH, * calling strlen is just overhead. vStringNCatSUnsafe doesn't call strlen. */ extern void vStringNCatS (vString *const string, const char *const s, const size_t length); extern void vStringNCatSUnsafe (vString *const string, const char *const s, const size_t length); @@ -82,6 +82,8 @@ extern void vStringNCopyS (vString *const string, const char *const s, const siz extern void vStringCopyToLower (vString *const dest, const vString *const src); extern void vStringSetLength (vString *const string); extern void vStringTruncate (vString *const string, const size_t length); +#define vStringTruncateTrailing vStringTruncate +extern void vStringTruncateLeading (vString *const string, const size_t length); extern void vStringTranslate(vString *const string, char fromC, char toC); extern vString *vStringNewOrClear (vString *const string); diff --git a/misc/ctags-optlib-mode.el b/misc/ctags-optlib-mode.el index 241d4d76f0..c6e05bdf9d 100644 --- a/misc/ctags-optlib-mode.el +++ b/misc/ctags-optlib-mode.el @@ -32,51 +32,51 @@ '(;; ;; Language ;; - ("^--\\(langdef\\)=\\([a-zA-Z0-9]+\\)" + ("^[[:space:]]*--\\(langdef\\)=\\([a-zA-Z0-9]+\\)" (1 font-lock-keyword-face t) (2 font-lock-type-face t)) - ("^--\\(map\\|alias\\|_?prelude\\|_?scopesep\\)-\\([a-zA-Z0-9]+\\)=.*" + ("^[[:space:]]*--\\(map\\|alias\\|_?prelude\\|_?scopesep\\)-\\([a-zA-Z0-9]+\\)=.*" (1 font-lock-keyword-face t) (2 font-lock-type-face t)) ;; ;; Kinds ;; - ("^--\\(kinddef\\)-\\([^=]+\\)=\\([a-zA-Z]\\),\\([a-zA-Z0-9]+\\),\\(.*\\)$" + ("^[[:space:]]*--\\(kinddef\\)-\\([^=]+\\)=\\([a-zA-Z]\\),\\([a-zA-Z0-9]+\\),\\(.*\\)$" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-constant-face t) (4 font-lock-variable-name-face t) (5 font-lock-doc-face t)) - ("^--\\(kinds\\)-\\([^=]+\\)=[+-]?\\([a-zA-Z]+\\)" + ("^[[:space:]]*--\\(kinds\\)-\\([^=]+\\)=[+-]?\\([a-zA-Z]+\\)" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-constant-face t)) ;; ;; Singe line regex ;; - ("^--\\(regex\\)-\\([^=]+\\)=" + ("^[[:space:]]*--\\(regex\\)-\\([^=]+\\)=" (1 font-lock-keyword-face t) (2 font-lock-type-face t)) ;; ;; Mline regex ;; - ("^--\\(mline-regex\\)-\\([^=]+\\)=" + ("^[[:space:]]*--\\(mline-regex\\)-\\([^=]+\\)=" (1 font-lock-keyword-face t) (2 font-lock-type-face t)) ;; ;; Mtable regex ;; - ("^--\\(_tabledef\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)" + ("^[[:space:]]*--\\(_tabledef\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-function-name-face t) ) - ("^--\\(_mtable-regex\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)/\\(.*\\)$" + ("^[[:space:]]*--\\(_mtable-regex\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)/\\(.*\\)$" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-function-name-face t) (4 nil t)) - ("^--\\(_mtable-extend\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)\\+\\([a-zA-Z0-9_]+\\)" + ("^[[:space:]]*--\\(_mtable-extend\\)-\\([^=]+\\)=\\([a-zA-Z0-9_]+\\)\\+\\([a-zA-Z0-9_]+\\)" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-function-name-face t) @@ -84,19 +84,19 @@ ;; ;; Fields ;; - ("^--\\(_fielddef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" + ("^[[:space:]]*--\\(_fielddef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-variable-name-face t) (4 font-lock-doc-face t)) - ("^--\\(fields\\)-\\([a-zA-Z0-9]+\\)=.?{\\([a-zA-Z0-9]+\\)}" + ("^[[:space:]]*--\\(fields\\)-\\([a-zA-Z0-9]+\\)=.?{\\([a-zA-Z0-9]+\\)}" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-variable-name-face t)) ;; ;; Roles ;; - ("^[ \t]*--\\(_roledef\\)-\\([a-zA-Z0-9]+\\)\\.\\(?:\\([a-zA-Z]\\)\\|{\\([a-zA-Z0-9]+\\)}\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" + ("^[[:space:]]*--\\(_roledef\\)-\\([a-zA-Z0-9]+\\)\\.\\(?:\\([a-zA-Z]\\)\\|{\\([a-zA-Z0-9]+\\)}\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-constant-face t t) @@ -106,19 +106,19 @@ ;; ;; Extras ;; - ("^--\\(_extradef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" + ("^[[:space:]]*--\\(_extradef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)$" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-variable-name-face t) (4 font-lock-doc-face t)) - ("^--\\(extras\\)-\\([a-zA-Z0-9]+\\)=.?{\\([a-zA-Z0-9]+\\)}" + ("^[[:space:]]*--\\(extras\\)-\\([a-zA-Z0-9]+\\)=.?{\\([a-zA-Z0-9]+\\)}" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-variable-name-face t)) ;; ;; Parameters ;; - ("^--\\(_?paramdef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)" + ("^[[:space:]]*--\\(_?paramdef\\)-\\([a-zA-Z0-9]+\\)=\\([a-zA-Z0-9]+\\),\\(.*\\)" (1 font-lock-keyword-face t) (2 font-lock-type-face t) (3 font-lock-variable-name-face t)