Sync from SUSE:SLFO:Main ctags revision 54c266584b1171503298880781f3af63

This commit is contained in:
Adrian Schröter 2024-05-03 11:56:31 +02:00
commit 4ecea757b7
26 changed files with 5941 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
From 9362fa70eaa37250afd5b36adb68295b54ae5c99 Mon Sep 17 00:00:00 2001
From: Federico Fissore <federico@fissore.org>
Date: Mon, 5 Oct 2015 11:27:36 +0200
Subject: [PATCH 02/19] Making "inline" behave like an attribute. Fixes #1
---
c.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/c.c b/c.c
index ccca3a4..af46dc4 100644
--- a/c.c
+++ b/c.c
@@ -1732,7 +1732,8 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_NONE: processName (st); break;
case KEYWORD_ABSTRACT: st->implementation = IMP_ABSTRACT; break;
- case KEYWORD_ATTRIBUTE: skipParens (); initToken (token); break;
+ case KEYWORD_ATTRIBUTE:
+ case KEYWORD_INLINE: skipParens (); initToken (token); break;
case KEYWORD_BIND: st->declaration = DECL_BASE; break;
case KEYWORD_BIT: st->declaration = DECL_BASE; break;
case KEYWORD_CATCH: skipParens (); skipBraces (); break;
--
2.11.0

View File

@ -0,0 +1,28 @@
From 8c205231b591e954f763df794fc59a9f6a7e983b Mon Sep 17 00:00:00 2001
From: Chris--A <chris@genx.biz>
Date: Thu, 8 Oct 2015 22:38:26 +1000
Subject: [PATCH 03/19] Treat 'typename' as an attribute.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Relates to #1
---
c.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/c.c b/c.c
index af46dc4..ef81067 100644
--- a/c.c
+++ b/c.c
@@ -1733,6 +1733,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_NONE: processName (st); break;
case KEYWORD_ABSTRACT: st->implementation = IMP_ABSTRACT; break;
case KEYWORD_ATTRIBUTE:
+ case KEYWORD_TYPENAME:
case KEYWORD_INLINE: skipParens (); initToken (token); break;
case KEYWORD_BIND: st->declaration = DECL_BASE; break;
case KEYWORD_BIT: st->declaration = DECL_BASE; break;
--
2.11.0

View File

@ -0,0 +1,57 @@
From 3b6e9256061bfcb70d2540c49b074b4be0ace4be Mon Sep 17 00:00:00 2001
From: Federico Fissore <federico@fissore.org>
Date: Wed, 4 Nov 2015 12:48:02 +0100
Subject: [PATCH 04/19] parseReturnType should start from the first non-brace
token
---
c.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/c.c b/c.c
index ef81067..727d6bb 100644
--- a/c.c
+++ b/c.c
@@ -567,7 +567,6 @@ static const char *implementationString (const impType imp)
/*
* Debugging functions
*/
-#define DEBUG
#ifdef DEBUG
#define boolString(c) ((c) ? "TRUE" : "FALSE")
@@ -2120,6 +2119,7 @@ static void parseReturnType (statementInfo *const st)
{
int i;
int lower_bound;
+ int upper_bound;
tokenInfo * finding_tok;
/* FIXME TODO: if java language must be supported then impement this here
@@ -2161,8 +2161,21 @@ static void parseReturnType (statementInfo *const st)
}
else
lower_bound = 1;
-
- for (i = (unsigned int) NumTokens; i > lower_bound; i--)
+
+ upper_bound = -1;
+ for (i = 0; i < NumTokens; i++) {
+ tokenInfo *curr_tok;
+ curr_tok = prevToken (st, i);
+ if (curr_tok->type == TOKEN_BRACE_CLOSE || curr_tok->type == TOKEN_BRACE_OPEN) {
+ upper_bound = i - 1;
+ break;
+ }
+ }
+ if (upper_bound < 0) {
+ upper_bound = NumTokens - 1;
+ }
+
+ for (i = upper_bound; i > lower_bound; i--)
{
tokenInfo * curr_tok;
curr_tok = prevToken (st, i);
--
2.11.0

View File

@ -0,0 +1,32 @@
From b27f1a9c3468618eb6b2a02b33a9058f3ca567e6 Mon Sep 17 00:00:00 2001
From: Federico Fissore <federico@fissore.org>
Date: Mon, 23 Nov 2015 10:47:18 +0100
Subject: [PATCH 05/19] Ensuring a space is printed in return type AFTER the
keyword
---
c.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/c.c b/c.c
index 727d6bb..c40cc42 100644
--- a/c.c
+++ b/c.c
@@ -2202,11 +2202,11 @@ static void parseReturnType (statementInfo *const st)
vStringPut (ReturnType, '&');
break;
- case TOKEN_KEYWORD:
- vStringPut (ReturnType, ' ');
-
default:
vStringCat (ReturnType, curr_tok->name);
+ if (curr_tok->type == TOKEN_KEYWORD) {
+ vStringPut (ReturnType, ' ');
+ }
break;
}
}
--
2.11.0

View File

@ -0,0 +1,42 @@
From ef67b47e61a1a5f6258e7034ddb520a57b0a477e Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <igrokhotkov@gmail.com>
Date: Wed, 20 Jan 2016 12:19:13 +0300
Subject: [PATCH 06/19] Prevent C++ static_assert from stopping parsing
Manual cherry-pick of https://github.com/geany/geany/commit/fa0f92def2bf584ed1f6ae836e509f38324f8b6c
---
c.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/c.c b/c.c
index c40cc42..6bc8b76 100644
--- a/c.c
+++ b/c.c
@@ -83,7 +83,7 @@ typedef enum eKeywordId {
KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
KEYWORD_REGISTER, KEYWORD_RETURN,
KEYWORD_SHADOW, KEYWORD_STATE,
- KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING,
+ KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STATIC_ASSERT, KEYWORD_STRING,
KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED,
KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW,
KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION,
@@ -437,6 +437,7 @@ static const keywordDesc KeywordTable [] = {
{ "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0 } },
{ "state", KEYWORD_STATE, { 0, 0, 0, 0, 1 } },
{ "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1 } },
+ { "static_assert", KEYWORD_STATIC_ASSERT, { 0, 1, 0, 0, 0} },
{ "string", KEYWORD_STRING, { 0, 0, 1, 0, 1 } },
{ "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0 } },
{ "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0 } },
@@ -1764,6 +1765,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_RETURN: skipStatement (st); break;
case KEYWORD_SHORT: st->declaration = DECL_BASE; break;
case KEYWORD_SIGNED: st->declaration = DECL_BASE; break;
+ case KEYWORD_STATIC_ASSERT: skipParens(); break;
case KEYWORD_STRING: st->declaration = DECL_BASE; break;
case KEYWORD_STRUCT: st->declaration = DECL_STRUCT; break;
case KEYWORD_TASK: st->declaration = DECL_TASK; break;
--
2.11.0

View File

@ -0,0 +1,42 @@
From 3a843374f200b80b7e155059cd4e73171597880d Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <igrokhotkov@gmail.com>
Date: Wed, 20 Jan 2016 12:21:26 +0300
Subject: [PATCH 07/19] c++: Handle C++11 noexcept
Manual cherry-pick of https://github.com/geany/geany/commit/f60b31385e4da74d3b926c8e0c8f97c00a508d7b
---
c.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/c.c b/c.c
index 6bc8b76..0dd84d7 100644
--- a/c.c
+++ b/c.c
@@ -77,7 +77,7 @@ typedef enum eKeywordId {
KEYWORD_LOCAL, KEYWORD_LONG,
KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS,
KEYWORD_MUTABLE,
- KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE,
+ KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, KEYWORD_NOEXCEPT,
KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE,
KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE,
KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
@@ -419,6 +419,7 @@ static const keywordDesc KeywordTable [] = {
{ "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0 } },
{ "new", KEYWORD_NEW, { 0, 1, 1, 1, 0 } },
{ "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1 } },
+ { "noexcept", KEYWORD_NOEXCEPT, { 0, 1, 0, 0, 0 } },
{ "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0 } },
{ "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1 } },
{ "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0 } },
@@ -1967,6 +1968,7 @@ static boolean skipPostArgumentStuff (
case KEYWORD_NAMESPACE:
case KEYWORD_NEW:
case KEYWORD_NEWCOV:
+ case KEYWORD_NOEXCEPT:
case KEYWORD_OPERATOR:
case KEYWORD_OVERLOAD:
case KEYWORD_PRIVATE:
--
2.11.0

View File

@ -0,0 +1,56 @@
From ce27db2946ae2ebc2766138af451d7d981201134 Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <igrokhotkov@gmail.com>
Date: Wed, 20 Jan 2016 12:25:18 +0300
Subject: [PATCH 08/19] c++: Properly parse C++11 override and final members
Manual cherry-pick of
- https://github.com/geany/geany/commit/95a0d4db7e2188a62cf7770496ee2a51591f1962
- https://github.com/geany/geany/commit/641863c2647c21abb36aedc40ac93e6cc478f920
---
c.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/c.c b/c.c
index 0dd84d7..6e8b5aa 100644
--- a/c.c
+++ b/c.c
@@ -1986,7 +1986,13 @@ static boolean skipPostArgumentStuff (
break;
default:
- if (isType (token, TOKEN_NONE))
+ /* "override" and "final" are only keywords in the declaration of a virtual
+ * member function, so need to be handled specially, not as keywords */
+ if (isLanguage(Lang_cpp) && isType (token, TOKEN_NAME) &&
+ (strcmp ("override", vStringValue (token->name)) == 0 ||
+ strcmp ("final", vStringValue (token->name)) == 0))
+ ;
+ else if (isType (token, TOKEN_NONE))
;
else if (info->isKnrParamList && info->parameterCount > 0)
++elementCount;
@@ -2839,8 +2845,20 @@ static void tagCheck (statementInfo *const st)
st->declaration == DECL_NAMESPACE ||
st->declaration == DECL_PROGRAM)
{
- if (isType (prev, TOKEN_NAME))
+ tokenInfo *name_token = (tokenInfo *)prev;
+
+ /* C++ 11 allows class <name> final { ... } */
+ if (isLanguage (Lang_cpp) && isType (prev, TOKEN_NAME) &&
+ strcmp("final", vStringValue(prev->name)) == 0 &&
+ isType(prev2, TOKEN_NAME))
+ {
+ name_token = (tokenInfo *)prev2;
+ copyToken (st->blockName, name_token);
+ }
+ else if (isType (name_token, TOKEN_NAME))
+ {
copyToken (st->blockName, prev);
+ }
else
{
/* For an anonymous struct or union we use a unique ID
--
2.11.0

View File

@ -0,0 +1,33 @@
From cf9442ccad73448ff22ee96fa743893b29df5cfc Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <igrokhotkov@gmail.com>
Date: Thu, 4 Feb 2016 19:36:35 +0300
Subject: [PATCH 09/19] Parse C++11 enums with type specifier
Manual cherry-pick of https://github.com/geany/geany/commit/f2f22d34ab9063852279bc6c5a45c8d3cfafdc0a
---
c.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/c.c b/c.c
index 6e8b5aa..ff7aa24 100644
--- a/c.c
+++ b/c.c
@@ -2528,6 +2528,15 @@ static void processColon (statementInfo *const st)
else if (c == ';')
setToken (st, TOKEN_SEMICOLON);
}
+ else if (isLanguage (Lang_cpp) && st->declaration == DECL_ENUM)
+ {
+ /* skip enum's base type */
+ c = skipToOneOf ("{;");
+ if (c == '{')
+ setToken (st, TOKEN_BRACE_OPEN);
+ else if (c == ';')
+ setToken (st, TOKEN_SEMICOLON);
+ }
else
{
const tokenInfo *const prev = prevToken (st, 1);
--
2.11.0

View File

@ -0,0 +1,48 @@
From 688ba978ea2394eb7144c964811e2c531e5c9c19 Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <igrokhotkov@gmail.com>
Date: Thu, 4 Feb 2016 19:40:15 +0300
Subject: [PATCH 10/19] Parse C++11 classed enums
Manual cherry-pick of https://github.com/geany/geany/commit/6c7f69578d8e142f5994cc9cf0e0abc83a606a1b
---
c.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/c.c b/c.c
index ff7aa24..40db0e5 100644
--- a/c.c
+++ b/c.c
@@ -1725,6 +1725,12 @@ static void processInterface (statementInfo *const st)
st->declaration = DECL_INTERFACE;
}
+static void checkIsClassEnum (statementInfo *const st, const declType decl)
+{
+ if (! isLanguage (Lang_cpp) || st->declaration != DECL_ENUM)
+ st->declaration = decl;
+}
+
static void processToken (tokenInfo *const token, statementInfo *const st)
{
switch (token->keyword) /* is it a reserved word? */
@@ -1740,7 +1746,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_BIT: st->declaration = DECL_BASE; break;
case KEYWORD_CATCH: skipParens (); skipBraces (); break;
case KEYWORD_CHAR: st->declaration = DECL_BASE; break;
- case KEYWORD_CLASS: st->declaration = DECL_CLASS; break;
+ case KEYWORD_CLASS: checkIsClassEnum (st, DECL_CLASS); break;
case KEYWORD_CONST: st->declaration = DECL_BASE; break;
case KEYWORD_DOUBLE: st->declaration = DECL_BASE; break;
case KEYWORD_ENUM: st->declaration = DECL_ENUM; break;
@@ -1768,7 +1774,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_SIGNED: st->declaration = DECL_BASE; break;
case KEYWORD_STATIC_ASSERT: skipParens(); break;
case KEYWORD_STRING: st->declaration = DECL_BASE; break;
- case KEYWORD_STRUCT: st->declaration = DECL_STRUCT; break;
+ case KEYWORD_STRUCT: checkIsClassEnum (st, DECL_STRUCT); break;
case KEYWORD_TASK: st->declaration = DECL_TASK; break;
case KEYWORD_THROWS: discardTypeList (token); break;
case KEYWORD_UNION: st->declaration = DECL_UNION; break;
--
2.11.0

View File

@ -0,0 +1,62 @@
From e304e5ffff9718d99ab5767c8399225b79204c1f Mon Sep 17 00:00:00 2001
From: Daniel Garcia <danielgarcia@gmail.com>
Date: Tue, 23 Feb 2016 17:16:58 -0800
Subject: [PATCH 11/19] Handle template expressions that may use the << or >>
operators
---
c.c | 34 ++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/c.c b/c.c
index 40db0e5..b975453 100644
--- a/c.c
+++ b/c.c
@@ -1392,20 +1392,34 @@ static void skipToMatch (const char *const pair)
if (c == begin)
{
- ++matchLevel;
- if (braceFormatting && getDirectiveNestLevel () != initialLevel)
- {
- skipToFormattedBraceMatch ();
- break;
+ // watch out for '<<' in template arguments
+ int x = cppGetc ();
+ if(c == '<' && x == '<') {
+ // we've found a << - do nothing
+ } else {
+ cppUngetc (x);
+ ++matchLevel;
+ if (braceFormatting && getDirectiveNestLevel () != initialLevel)
+ {
+ skipToFormattedBraceMatch ();
+ break;
+ }
}
}
else if (c == end)
{
- --matchLevel;
- if (braceFormatting && getDirectiveNestLevel () != initialLevel)
- {
- skipToFormattedBraceMatch ();
- break;
+ // watch out for '>>' in template arguments
+ int x = cppGetc ();
+ if(c == '>' && x == '>') {
+ // we've found a >> in a template - skip it
+ } else {
+ cppUngetc (x);
+ --matchLevel;
+ if (braceFormatting && getDirectiveNestLevel () != initialLevel)
+ {
+ skipToFormattedBraceMatch ();
+ break;
+ }
}
}
}
--
2.11.0

View File

@ -0,0 +1,39 @@
From fe0ba956daf1f3940543e3dce8ec0befcab4d386 Mon Sep 17 00:00:00 2001
From: Daniel Garcia <danielgarcia@gmail.com>
Date: Wed, 24 Feb 2016 00:59:15 -0800
Subject: [PATCH 12/19] Make sure we don't throw things away while collecting
the signature, though
---
c.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/c.c b/c.c
index b975453..386af29 100644
--- a/c.c
+++ b/c.c
@@ -1395,7 +1395,9 @@ static void skipToMatch (const char *const pair)
// watch out for '<<' in template arguments
int x = cppGetc ();
if(c == '<' && x == '<') {
- // we've found a << - do nothing
+ // we've found a << - do nothing except record the signature
+ if (CollectingSignature)
+ vStringPut(Signature, x);
} else {
cppUngetc (x);
++matchLevel;
@@ -1411,7 +1413,9 @@ static void skipToMatch (const char *const pair)
// watch out for '>>' in template arguments
int x = cppGetc ();
if(c == '>' && x == '>') {
- // we've found a >> in a template - skip it
+ // we've found a >> - do nothing except record the signature
+ if (CollectingSignature)
+ vStringPut(Signature, x);
} else {
cppUngetc (x);
--matchLevel;
--
2.11.0

View File

@ -0,0 +1,35 @@
From f928218c753e54968289a73285bf7c4345a8d553 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Tue, 23 Feb 2016 12:58:40 +0100
Subject: [PATCH 13/19] C++: mitigate matching error on generics containing an
expression
backport of https://github.com/geany/geany/commit/d40932ce4d05e57573a6d6c8f89f4aea8c42d4f3
---
c.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/c.c b/c.c
index 386af29..1386ddd 100644
--- a/c.c
+++ b/c.c
@@ -1426,6 +1426,16 @@ static void skipToMatch (const char *const pair)
}
}
}
+ /* early out if matching "<>" and we encounter a ";" or "{" to mitigate
+ * match problems with C++ generics containing a static expression like
+ * foo<X<Y> bar;
+ * normally neither ";" nor "{" could appear inside "<>" anyway. */
+ else if (isLanguage (Lang_cpp) && begin == '<' &&
+ (c == ';' || c == '{'))
+ {
+ cppUngetc (c);
+ break;
+ }
}
if (c == EOF)
{
--
2.11.0

View File

@ -0,0 +1,44 @@
From 5dbd71201f79e976a728802ca8638b14db0728dc Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Wed, 9 Mar 2016 15:03:07 +0100
Subject: [PATCH 14/19] fix wrongly interpreted >> in template
---
c.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/c.c b/c.c
index 1386ddd..6add5f3 100644
--- a/c.c
+++ b/c.c
@@ -1410,20 +1410,14 @@ static void skipToMatch (const char *const pair)
}
else if (c == end)
{
- // watch out for '>>' in template arguments
+ // don't care if you find a '>>' (the important thing is closing the brackets)
int x = cppGetc ();
- if(c == '>' && x == '>') {
- // we've found a >> - do nothing except record the signature
- if (CollectingSignature)
- vStringPut(Signature, x);
- } else {
- cppUngetc (x);
- --matchLevel;
- if (braceFormatting && getDirectiveNestLevel () != initialLevel)
- {
- skipToFormattedBraceMatch ();
- break;
- }
+ cppUngetc (x);
+ --matchLevel;
+ if (braceFormatting && getDirectiveNestLevel () != initialLevel)
+ {
+ skipToFormattedBraceMatch ();
+ break;
}
}
/* early out if matching "<>" and we encounter a ";" or "{" to mitigate
--
2.11.0

View File

@ -0,0 +1,41 @@
From 83aa36d14a6b82e10b3ac55d54e0641648c56fcf Mon Sep 17 00:00:00 2001
From: Eric Sorton <esorton@gmail.com>
Date: Mon, 1 Aug 2016 23:04:35 -0400
Subject: [PATCH 15/19] Added constexpr as keyword.
---
c.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/c.c b/c.c
index 6add5f3..105bfa8 100644
--- a/c.c
+++ b/c.c
@@ -62,7 +62,7 @@ typedef enum eKeywordId {
KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS,
KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT,
- KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,
+ KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST, KEYWORD_CONSTEXPR,
KEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF,
KEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DELETE, KEYWORD_DO,
KEYWORD_DOUBLE,
@@ -377,6 +377,7 @@ static const keywordDesc KeywordTable [] = {
{ "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0 } },
{ "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1 } },
{ "const", KEYWORD_CONST, { 1, 1, 1, 1, 0 } },
+ { "constexpr", KEYWORD_CONSTEXPR, { 0, 1, 0, 0, 0 } },
{ "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1 } },
{ "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1 } },
{ "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1 } },
@@ -1770,6 +1771,7 @@ static void processToken (tokenInfo *const token, statementInfo *const st)
case KEYWORD_CHAR: st->declaration = DECL_BASE; break;
case KEYWORD_CLASS: checkIsClassEnum (st, DECL_CLASS); break;
case KEYWORD_CONST: st->declaration = DECL_BASE; break;
+ case KEYWORD_CONSTEXPR: st->declaration = DECL_BASE; break;
case KEYWORD_DOUBLE: st->declaration = DECL_BASE; break;
case KEYWORD_ENUM: st->declaration = DECL_ENUM; break;
case KEYWORD_EXTENDS: readParents (st, '.');
--
2.11.0

98
0016-CVE-2014-7204.patch Normal file
View File

@ -0,0 +1,98 @@
From 7f6e3f1177f0ed53cf2a66ac207f6834591c568c Mon Sep 17 00:00:00 2001
From: dfishburn <dfishburn@sf.net>
Date: Wed, 24 Oct 2012 01:13:00 +0000
Subject: [PATCH 16/19] CVE-2014-7204
git-svn-id: svn://svn.code.sf.net/p/ctags/code/trunk@791 c5d04d22-be80-434c-894e-aa346cc9e8e8
Signed-off-by: Petr Uzel <petr.uzel@suse.cz>
---
jscript.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 51 insertions(+), 3 deletions(-)
diff --git a/jscript.c b/jscript.c
index c4e5b1a..901641a 100644
--- a/jscript.c
+++ b/jscript.c
@@ -215,6 +215,7 @@ static void deleteToken (tokenInfo *const token)
* Tag generation functions
*/
+/*
static void makeConstTag (tokenInfo *const token, const jsKind kind)
{
if (JsKinds [kind].enabled && ! token->ignoreTag )
@@ -238,12 +239,13 @@ static void makeJsTag (tokenInfo *const token, const jsKind kind)
if (JsKinds [kind].enabled && ! token->ignoreTag )
{
- /*
+ *
* If a scope has been added to the token, change the token
* string to include the scope when making the tag.
- */
+ *
if ( vStringLength(token->scope) > 0 )
{
+ *
fulltag = vStringNew ();
vStringCopy(fulltag, token->scope);
vStringCatS (fulltag, ".");
@@ -251,8 +253,54 @@ static void makeJsTag (tokenInfo *const token, const jsKind kind)
vStringTerminate(fulltag);
vStringCopy(token->string, fulltag);
vStringDelete (fulltag);
+ *
+ jsKind parent_kind = JSTAG_CLASS;
+
+ *
+ * if we're creating a function (and not a method),
+ * guess we're inside another function
+ *
+ if (kind == JSTAG_FUNCTION)
+ parent_kind = JSTAG_FUNCTION;
+
+ e.extensionFields.scope[0] = JsKinds [parent_kind].name;
+ e.extensionFields.scope[1] = vStringValue (token->scope);
+ }
+ * makeConstTag (token, kind); *
+ makeTagEntry (&e);
+ }
+}
+*/
+
+static void makeJsTag (tokenInfo *const token, const jsKind kind)
+{
+ if (JsKinds [kind].enabled && ! token->ignoreTag )
+ {
+ const char *const name = vStringValue (token->string);
+ tagEntryInfo e;
+ initTagEntry (&e, name);
+
+ e.lineNumber = token->lineNumber;
+ e.filePosition = token->filePosition;
+ e.kindName = JsKinds [kind].name;
+ e.kind = JsKinds [kind].letter;
+
+ if ( vStringLength(token->scope) > 0 )
+ {
+ jsKind parent_kind = JSTAG_CLASS;
+
+ /*
+ * If we're creating a function (and not a method),
+ * guess we're inside another function
+ */
+ if (kind == JSTAG_FUNCTION)
+ parent_kind = JSTAG_FUNCTION;
+
+ e.extensionFields.scope[0] = JsKinds [parent_kind].name;
+ e.extensionFields.scope[1] = vStringValue (token->scope);
}
- makeConstTag (token, kind);
+
+ makeTagEntry (&e);
}
}
--
2.11.0

View File

@ -0,0 +1,731 @@
From 829234bfb8d481413bf0466562fe87e8c396defd Mon Sep 17 00:00:00 2001
From: Graham Anderson <graham@andtech.eu>
Date: Thu, 16 Aug 2012 12:04:00 +0000
Subject: [PATCH 17/19] Go language support
---
go.c | 670 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
parsers.h | 2 +
source.mak | 2 +
3 files changed, 674 insertions(+)
create mode 100644 go.c
diff --git a/go.c b/go.c
new file mode 100644
index 0000000..6bd3a36
--- /dev/null
+++ b/go.c
@@ -0,0 +1,670 @@
+/*
+* INCLUDE FILES
+*/
+#include "general.h" /* must always come first */
+#include <setjmp.h>
+
+#include "debug.h"
+#include "entry.h"
+#include "keyword.h"
+#include "read.h"
+#include "main.h"
+#include "routines.h"
+#include "vstring.h"
+#include "options.h"
+
+/*
+ * MACROS
+ */
+#define isType(token,t) (boolean) ((token)->type == (t))
+#define isKeyword(token,k) (boolean) ((token)->keyword == (k))
+
+/*
+ * DATA DECLARATIONS
+ */
+
+typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
+
+typedef enum eKeywordId {
+ KEYWORD_NONE = -1,
+ KEYWORD_package,
+ KEYWORD_import,
+ KEYWORD_const,
+ KEYWORD_type,
+ KEYWORD_var,
+ KEYWORD_func,
+ KEYWORD_struct,
+ KEYWORD_interface,
+ KEYWORD_map,
+ KEYWORD_chan
+} keywordId;
+
+/* Used to determine whether keyword is valid for the current language and
+ * what its ID is.
+ */
+typedef struct sKeywordDesc {
+ const char *name;
+ keywordId id;
+} keywordDesc;
+
+typedef enum eTokenType {
+ TOKEN_NONE = -1,
+ TOKEN_CHARACTER,
+ // Don't need TOKEN_FORWARD_SLASH
+ TOKEN_FORWARD_SLASH,
+ TOKEN_KEYWORD,
+ TOKEN_IDENTIFIER,
+ TOKEN_STRING,
+ TOKEN_OPEN_PAREN,
+ TOKEN_CLOSE_PAREN,
+ TOKEN_OPEN_CURLY,
+ TOKEN_CLOSE_CURLY,
+ TOKEN_OPEN_SQUARE,
+ TOKEN_CLOSE_SQUARE,
+ TOKEN_SEMICOLON,
+ TOKEN_STAR,
+ TOKEN_LEFT_ARROW,
+ TOKEN_DOT,
+ TOKEN_COMMA
+} tokenType;
+
+typedef struct sTokenInfo {
+ tokenType type;
+ keywordId keyword;
+ vString *string; /* the name of the token */
+ unsigned long lineNumber; /* line number of tag */
+ fpos_t filePosition; /* file position of line containing name */
+} tokenInfo;
+
+/*
+* DATA DEFINITIONS
+*/
+
+static int Lang_go;
+static jmp_buf Exception;
+static vString *scope;
+
+typedef enum {
+ GOTAG_UNDEFINED = -1,
+ GOTAG_PACKAGE,
+ GOTAG_FUNCTION,
+ GOTAG_CONST,
+ GOTAG_TYPE,
+ GOTAG_VAR,
+} goKind;
+
+static kindOption GoKinds[] = {
+ {TRUE, 'p', "package", "packages"},
+ {TRUE, 'f', "func", "functions"},
+ {TRUE, 'c', "const", "constants"},
+ {TRUE, 't', "type", "types"},
+ {TRUE, 'v', "var", "variables"}
+};
+
+static keywordDesc GoKeywordTable[] = {
+ {"package", KEYWORD_package},
+ {"import", KEYWORD_import},
+ {"const", KEYWORD_const},
+ {"type", KEYWORD_type},
+ {"var", KEYWORD_var},
+ {"func", KEYWORD_func},
+ {"struct", KEYWORD_struct},
+ {"interface", KEYWORD_interface},
+ {"map", KEYWORD_map},
+ {"chan", KEYWORD_chan}
+};
+
+/*
+* FUNCTION DEFINITIONS
+*/
+
+// XXX UTF-8
+static boolean isIdentChar (const int c)
+{
+ return (boolean)
+ (isalpha (c) || isdigit (c) || c == '$' ||
+ c == '@' || c == '_' || c == '#' || c > 128);
+}
+
+static void initialize (const langType language)
+{
+ size_t i;
+ const size_t count =
+ sizeof (GoKeywordTable) / sizeof (GoKeywordTable[0]);
+ Lang_go = language;
+ for (i = 0; i < count; ++i)
+ {
+ const keywordDesc *const p = &GoKeywordTable[i];
+ addKeyword (p->name, language, (int) p->id);
+ }
+}
+
+static tokenInfo *newToken (void)
+{
+ tokenInfo *const token = xMalloc (1, tokenInfo);
+ token->type = TOKEN_NONE;
+ token->keyword = KEYWORD_NONE;
+ token->string = vStringNew ();
+ token->lineNumber = getSourceLineNumber ();
+ token->filePosition = getInputFilePosition ();
+ return token;
+}
+
+static void deleteToken (tokenInfo * const token)
+{
+ if (token != NULL)
+ {
+ vStringDelete (token->string);
+ eFree (token);
+ }
+}
+
+/*
+ * Parsing functions
+ */
+
+static void parseString (vString *const string, const int delimiter)
+{
+ boolean end = FALSE;
+ while (!end)
+ {
+ int c = fileGetc ();
+ if (c == EOF)
+ end = TRUE;
+ else if (c == '\\' && delimiter != '`')
+ {
+ c = fileGetc (); /* This maybe a ' or ". */
+ vStringPut (string, c);
+ }
+ else if (c == delimiter)
+ end = TRUE;
+ else
+ vStringPut (string, c);
+ }
+ vStringTerminate (string);
+}
+
+static void parseIdentifier (vString *const string, const int firstChar)
+{
+ int c = firstChar;
+ //Assert (isIdentChar (c));
+ do
+ {
+ vStringPut (string, c);
+ c = fileGetc ();
+ } while (isIdentChar (c));
+ vStringTerminate (string);
+ fileUngetc (c); /* always unget, LF might add a semicolon */
+}
+
+static void readToken (tokenInfo *const token)
+{
+ int c;
+ static tokenType lastTokenType = TOKEN_NONE;
+
+ token->type = TOKEN_NONE;
+ token->keyword = KEYWORD_NONE;
+ vStringClear (token->string);
+
+getNextChar:
+ do
+ {
+ c = fileGetc ();
+ token->lineNumber = getSourceLineNumber ();
+ token->filePosition = getInputFilePosition ();
+ if (c == '\n' && (lastTokenType == TOKEN_IDENTIFIER ||
+ lastTokenType == TOKEN_STRING ||
+ lastTokenType == TOKEN_CLOSE_PAREN ||
+ lastTokenType == TOKEN_CLOSE_CURLY ||
+ lastTokenType == TOKEN_CLOSE_SQUARE))
+ {
+ token->type = TOKEN_SEMICOLON;
+ goto done;
+ }
+ }
+ while (c == '\t' || c == ' ' || c == '\r' || c == '\n');
+
+ switch (c)
+ {
+ case EOF:
+ longjmp (Exception, (int)ExceptionEOF);
+ break;
+
+ case '/':
+ {
+ boolean hasNewline = FALSE;
+ int d = fileGetc ();
+ switch (d)
+ {
+ case '/':
+ fileSkipToCharacter ('\n');
+ /* Line comments start with the
+ * character sequence // and
+ * continue through the next
+ * newline. A line comment acts
+ * like a newline. */
+ fileUngetc ('\n');
+ goto getNextChar;
+ case '*':
+ do
+ {
+ int d;
+ do
+ {
+ d = fileGetc ();
+ if (d == '\n')
+ {
+ hasNewline = TRUE;
+ }
+ } while (d != EOF && d != '*');
+
+ c = fileGetc ();
+ if (c == '/')
+ break;
+ else
+ fileUngetc (c);
+ } while (c != EOF && c != '\0');
+
+ fileUngetc (hasNewline ? '\n' : ' ');
+ goto getNextChar;
+ default:
+ token->type = TOKEN_FORWARD_SLASH;
+ fileUngetc (d);
+ break;
+ }
+ }
+ break;
+
+ case '"':
+ case '\'':
+ case '`':
+ token->type = TOKEN_STRING;
+ parseString (token->string, c);
+ token->lineNumber = getSourceLineNumber ();
+ token->filePosition = getInputFilePosition ();
+ break;
+
+ case '<':
+ {
+ int d = fileGetc ();
+ if (d == '-')
+ {
+ token->type = TOKEN_LEFT_ARROW;
+ break;
+ }
+ else
+ goto getNextChar;
+ }
+
+ case '(':
+ token->type = TOKEN_OPEN_PAREN;
+ break;
+
+ case ')':
+ token->type = TOKEN_CLOSE_PAREN;
+ break;
+
+ case '{':
+ token->type = TOKEN_OPEN_CURLY;
+ break;
+
+ case '}':
+ token->type = TOKEN_CLOSE_CURLY;
+ break;
+
+ case '[':
+ token->type = TOKEN_OPEN_SQUARE;
+ break;
+
+ case ']':
+ token->type = TOKEN_CLOSE_SQUARE;
+ break;
+
+ case '*':
+ token->type = TOKEN_STAR;
+ break;
+
+ case '.':
+ token->type = TOKEN_DOT;
+ break;
+
+ case ',':
+ token->type = TOKEN_COMMA;
+ break;
+
+ default:
+ parseIdentifier (token->string, c);
+ token->lineNumber = getSourceLineNumber ();
+ token->filePosition = getInputFilePosition ();
+ token->keyword = lookupKeyword (vStringValue (token->string), Lang_go);
+ if (isKeyword (token, KEYWORD_NONE))
+ token->type = TOKEN_IDENTIFIER;
+ else
+ token->type = TOKEN_KEYWORD;
+ break;
+ }
+
+done:
+ lastTokenType = token->type;
+}
+
+static void skipToMatched (tokenInfo *const token)
+{
+ int nest_level = 0;
+ tokenType open_token;
+ tokenType close_token;
+
+ switch (token->type)
+ {
+ case TOKEN_OPEN_PAREN:
+ open_token = TOKEN_OPEN_PAREN;
+ close_token = TOKEN_CLOSE_PAREN;
+ break;
+ case TOKEN_OPEN_CURLY:
+ open_token = TOKEN_OPEN_CURLY;
+ close_token = TOKEN_CLOSE_CURLY;
+ break;
+ case TOKEN_OPEN_SQUARE:
+ open_token = TOKEN_OPEN_SQUARE;
+ close_token = TOKEN_CLOSE_SQUARE;
+ break;
+ default:
+ return;
+ }
+
+ /*
+ * This routine will skip to a matching closing token.
+ * It will also handle nested tokens like the (, ) below.
+ * ( name varchar(30), text binary(10) )
+ */
+ if (isType (token, open_token))
+ {
+ nest_level++;
+ while (!(isType (token, close_token) && (nest_level == 0)))
+ {
+ readToken (token);
+ if (isType (token, open_token))
+ {
+ nest_level++;
+ }
+ if (isType (token, close_token))
+ {
+ if (nest_level > 0)
+ {
+ nest_level--;
+ }
+ }
+ }
+ readToken (token);
+ }
+}
+
+static void skipType (tokenInfo *const token)
+{
+again:
+ // Type = TypeName | TypeLit | "(" Type ")" .
+ if (isType (token, TOKEN_OPEN_PAREN))
+ {
+ skipToMatched (token);
+ return;
+ }
+
+ // TypeName = QualifiedIdent.
+ // QualifiedIdent = [ PackageName "." ] identifier .
+ // PackageName = identifier .
+ if (isType (token, TOKEN_IDENTIFIER))
+ {
+ readToken (token);
+ if (isType (token, TOKEN_DOT))
+ {
+ readToken (token);
+ Assert (isType (token, TOKEN_IDENTIFIER));
+ readToken (token);
+ }
+ return;
+ }
+
+ // StructType = "struct" "{" { FieldDecl ";" } "}"
+ // InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
+ if (isKeyword (token, KEYWORD_struct) || isKeyword (token, KEYWORD_interface))
+ {
+ readToken (token);
+ Assert (isType (token, TOKEN_OPEN_CURLY));
+ skipToMatched (token);
+ return;
+ }
+
+ // ArrayType = "[" ArrayLength "]" ElementType .
+ // SliceType = "[" "]" ElementType .
+ // ElementType = Type .
+ if (isType (token, TOKEN_OPEN_SQUARE))
+ {
+ skipToMatched (token);
+ goto again;
+ }
+
+ // PointerType = "*" BaseType .
+ // BaseType = Type .
+ // ChannelType = ( "chan" [ "<-" ] | "<-" "chan" ) ElementType .
+ if (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))
+ {
+ readToken (token);
+ goto again;
+ }
+
+ // MapType = "map" "[" KeyType "]" ElementType .
+ // KeyType = Type .
+ if (isKeyword (token, KEYWORD_map))
+ {
+ readToken (token);
+ Assert (isType (token, TOKEN_OPEN_SQUARE));
+ skipToMatched (token);
+ goto again;
+ }
+
+ // FunctionType = "func" Signature .
+ // Signature = Parameters [ Result ] .
+ // Result = Parameters | Type .
+ // Parameters = "(" [ ParameterList [ "," ] ] ")" .
+ if (isKeyword (token, KEYWORD_func))
+ {
+ readToken (token);
+ Assert (isType (token, TOKEN_OPEN_PAREN));
+ // Parameters
+ skipToMatched (token);
+ // Result is parameters or type or nothing. skipType treats anything
+ // surrounded by parentheses as a type, and does nothing if what
+ // follows is not a type.
+ goto again;
+ }
+}
+
+// Skip to the next semicolon, skipping over matching brackets.
+static void skipToTopLevelSemicolon (tokenInfo *const token)
+{
+ while (!isType (token, TOKEN_SEMICOLON))
+ {
+ readToken (token);
+ skipToMatched (token);
+ }
+}
+
+static void makeTag (tokenInfo *const token, const goKind kind)
+{
+ const char *const name = vStringValue (token->string);
+
+ tagEntryInfo e;
+ initTagEntry (&e, name);
+
+ if (!GoKinds [kind].enabled)
+ return;
+
+ e.lineNumber = token->lineNumber;
+ e.filePosition = token->filePosition;
+ e.kindName = GoKinds [kind].name;
+ e.kind = GoKinds [kind].letter;
+
+ makeTagEntry (&e);
+
+ if (scope && Option.include.qualifiedTags)
+ {
+ vString *qualifiedName = vStringNew ();
+ vStringCopy (qualifiedName, scope);
+ vStringCatS (qualifiedName, ".");
+ vStringCat (qualifiedName, token->string);
+ e.name = vStringValue (qualifiedName);
+ makeTagEntry (&e);
+ vStringDelete (qualifiedName);
+ }
+}
+
+static void parsePackage (tokenInfo *const token)
+{
+ tokenInfo *const name = newToken ();
+
+ readToken (name);
+ Assert (isType (name, TOKEN_IDENTIFIER));
+ makeTag (name, GOTAG_PACKAGE);
+ if (!scope && Option.include.qualifiedTags)
+ {
+ scope = vStringNew ();
+ vStringCopy (scope, name->string);
+ }
+
+ deleteToken (name);
+}
+
+static void parseFunctionOrMethod (tokenInfo *const token)
+{
+ // FunctionDecl = "func" identifier Signature [ Body ] .
+ // Body = Block.
+ //
+ // MethodDecl = "func" Receiver MethodName Signature [ Body ] .
+ // Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
+ // BaseTypeName = identifier .
+ tokenInfo *const name = newToken ();
+
+ // Skip over receiver.
+ readToken (name);
+ if (isType (name, TOKEN_OPEN_PAREN))
+ skipToMatched (name);
+
+ Assert (isType (name, TOKEN_IDENTIFIER));
+
+ // Skip over parameters.
+ readToken (token);
+ skipToMatched (token);
+
+ // Skip over result.
+ skipType (token);
+
+ // Skip over function body.
+ if (isType (token, TOKEN_OPEN_CURLY))
+ skipToMatched (token);
+
+ makeTag (name, GOTAG_FUNCTION);
+
+ deleteToken (name);
+}
+
+static void parseConstTypeVar (tokenInfo *const token, goKind kind)
+{
+ // ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
+ // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
+ // IdentifierList = identifier { "," identifier } .
+ // ExpressionList = Expression { "," Expression } .
+ // TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
+ // TypeSpec = identifier Type .
+ // VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
+ // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
+ tokenInfo *const name = newToken ();
+ boolean usesParens = FALSE;
+
+ readToken (name);
+
+ if (isType (name, TOKEN_OPEN_PAREN))
+ {
+ usesParens = TRUE;
+ readToken (name);
+ }
+
+again:
+ while (1)
+ {
+ makeTag (name, kind);
+ readToken (token);
+ if (!isType (token, TOKEN_COMMA) && !isType (token, TOKEN_CLOSE_PAREN))
+ break;
+ readToken (name);
+ }
+
+ skipType (token);
+ skipToTopLevelSemicolon (token);
+
+ if (usesParens)
+ {
+ readToken (name);
+ if (!isType (name, TOKEN_CLOSE_PAREN))
+ goto again;
+ }
+
+ deleteToken (name);
+}
+
+static void parseGoFile (tokenInfo *const token)
+{
+ do
+ {
+ readToken (token);
+
+ if (isType (token, TOKEN_KEYWORD))
+ {
+ switch (token->keyword)
+ {
+ case KEYWORD_package:
+ parsePackage (token);
+ break;
+ case KEYWORD_func:
+ parseFunctionOrMethod (token);
+ break;
+ case KEYWORD_const:
+ parseConstTypeVar (token, GOTAG_CONST);
+ break;
+ case KEYWORD_type:
+ parseConstTypeVar (token, GOTAG_TYPE);
+ break;
+ case KEYWORD_var:
+ parseConstTypeVar (token, GOTAG_VAR);
+ break;
+ default:
+ break;
+ }
+ }
+ } while (TRUE);
+}
+
+static void findGoTags (void)
+{
+ tokenInfo *const token = newToken ();
+ exception_t exception;
+
+ exception = (exception_t) (setjmp (Exception));
+ while (exception == ExceptionNone)
+ parseGoFile (token);
+
+ deleteToken (token);
+ vStringDelete (scope);
+ scope = NULL;
+}
+
+extern parserDefinition *GoParser (void)
+{
+ static const char *const extensions[] = { "go", NULL };
+ parserDefinition *def = parserNew ("Go");
+ def->kinds = GoKinds;
+ def->kindCount = KIND_COUNT (GoKinds);
+ def->extensions = extensions;
+ def->parser = findGoTags;
+ def->initialize = initialize;
+ return def;
+}
diff --git a/parsers.h b/parsers.h
index e4a50e1..b150506 100644
--- a/parsers.h
+++ b/parsers.h
@@ -32,6 +32,7 @@
ErlangParser, \
FlexParser, \
FortranParser, \
+ GoParser, \
HtmlParser, \
JavaParser, \
JavaScriptParser, \
@@ -76,6 +77,7 @@
FlexParser, \
FortranParser, \
GenieParser, \
+ GoParser, \
HtmlParser, \
JavaParser, \
JavaScriptParser, \
diff --git a/source.mak b/source.mak
index 3e5f740..d4c4c26 100644
--- a/source.mak
+++ b/source.mak
@@ -24,6 +24,7 @@ SOURCES = \
flex.c \
fortran.c \
get.c \
+ go.c \
html.c \
jscript.c \
keyword.c \
@@ -86,6 +87,7 @@ OBJECTS = \
flex.$(OBJEXT) \
fortran.$(OBJEXT) \
get.$(OBJEXT) \
+ go.$(OBJEXT) \
html.$(OBJEXT) \
jscript.$(OBJEXT) \
keyword.$(OBJEXT) \
--
2.11.0

View File

@ -0,0 +1,76 @@
From e63684e0d8924dd6a56bda52ebfc81fb6c35811b Mon Sep 17 00:00:00 2001
From: Stepan Kasal <kasal@suse.cz>
Date: Mon, 31 Jan 2000 12:41:54 +0100
Subject: [PATCH 18/19] SUSE man page changes
---
ctags.1 | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/ctags.1 b/ctags.1
index 2d89006..138e6ce 100644
--- a/ctags.1
+++ b/ctags.1
@@ -9,12 +9,29 @@ ctags \- Generate tag files for source code
.TP 6
\fBctags\fP [\fBoptions\fP] [\fIfile(s)\fP]
.TP 6
-\fBetags\fP [\fBoptions\fP] [\fIfile(s)\fP]
-
+\fBctags\fP \fB-e\fP [\fBoptions\fP] [\fIfile(s)\fP]
+
+.SH NOTE
+There are three different versions of the
+\fBctags\fP program on SuSE Linux.
+Besides this one you might want to use either
+.BR gnuctags (1),
+supporting wide variety of programming languages
+and originaly distributed with emacs, or
+.BR gctags (1),
+which comes with
+.BR global (1)
+and supports for example Yacc.
+
+For use with
+.BR emacs (1)
+the best choice is perhaps
+.BR etags (1),
+but it's also possible to use \fBctags\ \-e\fP,
+as described herein, since it supports for example Eiffel.
.SH "DESCRIPTION"
-The \fBctags\fP and \fBetags\fP programs (hereinafter collectively referred to
-as \fBctags\fP, except where distinguished) generate an index (or "tag") file
+The \fBctags\fP program generates an index (or "tag") file
for a variety of language objects found in \fIfile(s)\fP.
This tag file allows these items to be quickly and easily located by a text
editor or other utility. A "tag" signifies a language object for which an
@@ -1081,7 +1098,7 @@ embedded space. If this is a problem, use a configuration file instead.
.TP 8
.B ETAGS
Similar to the \fBCTAGS\fP variable above, this variable, if found, will be
-read when \fBetags\fP starts. If this variable is not found, \fBetags\fP will
+read when \fBctags\ \-e\fP starts. If this variable is not found, \fBctags\ \-e\fP will
try to use \fBCTAGS\fP instead.
.TP 8
@@ -1136,9 +1153,15 @@ lines to indicate separate command-line arguments.
The default tag file created by \fBctags\fP.
.TP
.I TAGS
-The default tag file created by \fBetags\fP.
+The default tag file created by \fBctags -e\fP.
.SH "SEE ALSO"
+.BR etags (1),
+.BR gctags (1),
+.BR global (1),
+.BR gnuctags (1).
+
+.PP
The official Exuberant Ctags web site at:
.RS
--
2.11.0

View File

@ -0,0 +1,47 @@
From 2814d01a6cdb52a336dc6d6243ecc3cad44e60f1 Mon Sep 17 00:00:00 2001
From: Unknown Lost in OBS Migration <unk@nown.net>
Date: Sun, 26 Feb 2017 05:34:04 +0100
Subject: [PATCH 19/19] Do not include build time in binary.
---
main.c | 11 -----------
options.c | 1 -
2 files changed, 12 deletions(-)
diff --git a/main.c b/main.c
index 79948fe..8bca242 100644
--- a/main.c
+++ b/main.c
@@ -93,17 +93,6 @@
*/
static struct { long files, lines, bytes; } Totals = { 0, 0, 0 };
-#ifdef AMIGA
-# include "ctags.h"
- static const char *VERsion = "$VER: "PROGRAM_NAME" "PROGRAM_VERSION" "
-# ifdef __SASC
- __AMIGADATE__
-# else
- __DATE__
-# endif
- " "AUTHOR_NAME" $";
-#endif
-
/*
* FUNCTION PROTOTYPES
*/
diff --git a/options.c b/options.c
index 1bee61d..0fc8e0c 100644
--- a/options.c
+++ b/options.c
@@ -926,7 +926,6 @@ static void printProgramIdentification (void)
printf ("%s %s, %s %s\n",
PROGRAM_NAME, PROGRAM_VERSION,
PROGRAM_COPYRIGHT, AUTHOR_NAME);
- printf (" Compiled: %s, %s\n", __DATE__, __TIME__);
printf (" Addresses: <%s>, %s\n", AUTHOR_EMAIL, PROGRAM_URL);
printFeatureList ();
}
--
2.11.0

209
CVE-2022-4515.patch Normal file
View File

@ -0,0 +1,209 @@
Based on
From e00c55d7a0204dc1d0ae316141323959e1e16162 Mon Sep 17 00:00:00 2001
From: Masatake YAMATO <yamato@redhat.com>
Date: Mon, 24 Oct 2016 23:52:23 +0900
Subject: [PATCH] main: quote output file name before passing it to system(3)
function
Following command line doesn't work:
$ ctags -o 'a b' ...
because a shell lauched from system(3) deals a whitespace between 'a'
and 'b' as a separator. The output file name is passed to system(3)
to run external sort command.
This commit adds code to put double and single quoets around the output
file name before passing it to system(3).
The issue is reported by Lorenz Hipp <lhipp@idealbonn.de> in a private mail.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
---
Tmain/abnormal-output-file-names.d/input.c | 1 +
Tmain/abnormal-output-file-names.d/run.sh | 39 ++++++++++
.../stderr-expected.txt | 0
.../stdout-expected.txt | 8 +++
main/sort.c | 72 ++++++++++++++-----
5 files changed, 102 insertions(+), 18 deletions(-)
create mode 100644 Tmain/abnormal-output-file-names.d/input.c
create mode 100644 Tmain/abnormal-output-file-names.d/run.sh
create mode 100644 Tmain/abnormal-output-file-names.d/stderr-expected.txt
create mode 100644 Tmain/abnormal-output-file-names.d/stdout-expected.txt
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/input.c
===================================================================
--- /dev/null
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/input.c
@@ -0,0 +1 @@
+int x;
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/run.sh
===================================================================
--- /dev/null
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/run.sh
@@ -0,0 +1,39 @@
+# Copyright: 2016 Masatake YAMATO
+# License: GPL-2
+
+CTAGS=$1
+
+rm -f ./"'"
+rm -f ./'"'
+rm -f ./'$(ls)'
+rm -f ./'a b'
+
+${CTAGS} --options=NONE -o ./"'" --extra=-pF input.c
+${CTAGS} --options=NONE -o ./'"' --extra=-pF input.c
+${CTAGS} --options=NONE -o ./'$(ls)' --extra=-pF input.c
+${CTAGS} --options=NONE -o ./'a b' --extra=-pF input.c
+
+echo '#' SINGLE QUOTE
+if [ -e "'" ]; then
+ cat "'"
+fi
+
+echo '#' DOUBLE QUOTES
+if [ -e '"' ]; then
+ cat '"'
+fi
+
+echo '#' PROCESS SUBSTITUTION
+if [ -e '$(ls)' ]; then
+ cat '$(ls)'
+fi
+
+echo '#' SPACE
+if [ -e 'a b' ]; then
+ cat 'a b'
+fi
+
+rm -f ./"'"
+rm -f ./'"'
+rm -f ./'$(ls)'
+rm -f ./'a b'
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/stdout-expected.txt
===================================================================
--- /dev/null
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/stdout-expected.txt
@@ -0,0 +1,8 @@
+# SINGLE QUOTE
+x input.c /^int x;$/;" v typeref:typename:int
+# DOUBLE QUOTES
+x input.c /^int x;$/;" v typeref:typename:int
+# PROCESS SUBSTITUTION
+x input.c /^int x;$/;" v typeref:typename:int
+# SPACE
+x input.c /^int x;$/;" v typeref:typename:int
Index: ctags-5.8/sort.c
===================================================================
--- ctags-5.8.orig/sort.c
+++ ctags-5.8/sort.c
@@ -19,6 +19,7 @@
#endif
#include <string.h>
#include <stdio.h>
+#include <unistd.h>
#include "debug.h"
#include "entry.h"
@@ -53,41 +54,83 @@ extern void catFile (const char *const n
# define PE_CONST const
#endif
+/*
+ Output file name should not be evaluated in system(3) function.
+ The name must be used as is. Quotations are required to block the
+ evaluation.
+
+ Normal single-quotes are used to quote a cstring:
+ a => 'a'
+ " => '"'
+
+ If a single-quote is included in the cstring, use double quotes for quoting it.
+ ' => ''"'"''
+*/
+static void appendCstringWithQuotes (vString *dest, const char* cstr)
+{
+ const char* o;
+
+ vStringPut (dest, '\'');