ctags/0001-Mixing-with-anjuta-tags-https-git.gnome.org-browse-a.patch

2869 lines
81 KiB
Diff

From 504c9e52393b1a3620de00878043271812adb887 Mon Sep 17 00:00:00 2001
From: Federico Fissore <federico@fissore.org>
Date: Fri, 23 Jan 2015 15:36:29 +0100
Subject: [PATCH 01/19] Mixing with anjuta-tags
https://git.gnome.org/browse/anjuta/tree/plugins/symbol-db/anjuta-tags
---
.gitignore | 5 +
acconfig.h | 127 +++++++++++++++++
ant.c | 4 +-
c.c | 145 +++++++++++++++++--
config.h | 275 ++++++++++++++++++++++++++++++++++++
ctags-utils.c | 41 ++++++
ctags-utils.h | 38 +++++
ctags-visitor.vala | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++++
ctags.h | 2 +-
eiffel.c | 20 ++-
entry.c | 6 +
entry.h | 3 +-
falcon.c | 149 ++++++++++++++++++++
flex.c | 55 +++++++-
gir.c | 216 +++++++++++++++++++++++++++++
lregex.c | 4 +-
make.c | 4 +-
options.c | 6 +-
options.h | 1 +
parsers.h | 47 +++++++
php.c | 24 ++--
python.c | 8 +-
sort.c | 4 +-
sql.c | 278 ++++++++++++++++++++++++++++++++-----
test-cmd-line | 1 +
tex.c | 35 ++---
vala.c | 103 ++++++++++++++
verilog.c | 3 +-
28 files changed, 1900 insertions(+), 104 deletions(-)
create mode 100644 .gitignore
create mode 100644 acconfig.h
create mode 100644 config.h
create mode 100644 ctags-utils.c
create mode 100644 ctags-utils.h
create mode 100644 ctags-visitor.vala
create mode 100644 falcon.c
create mode 100644 gir.c
create mode 100644 test-cmd-line
create mode 100644 vala.c
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..868b69d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.o
+Makefile
+config.log
+config.status
+ctags
diff --git a/acconfig.h b/acconfig.h
new file mode 100644
index 0000000..8431027
--- /dev/null
+++ b/acconfig.h
@@ -0,0 +1,127 @@
+/*
+* $Id: acconfig.h 318 2003-04-01 05:02:21Z darren $
+*
+* Copyright (c) 1998-2003, Darren Hiebert
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License.
+*
+* This module contains input source for generating config.h.in
+*/
+
+/* Package name.
+ */
+#undef PACKAGE
+
+/* Package version.
+ */
+#undef VERSION
+
+/* Define to the appropriate type if <time.h> does not define this.
+ */
+#undef clock_t
+
+/* Define to long if <stdio.h> does not define this.
+ */
+#undef fpos_t
+
+/* Define to the appropriate size for tmpnam() if <stdio.h> does not define
+ * this.
+ */
+#undef L_tmpnam
+
+/* Define this macro if the field "st_ino" exists in struct stat in
+ * <sys/stat.h>.
+ * */
+#undef HAVE_STAT_ST_INO
+
+/* Define remove to unlink if you have unlink(), but not remove().
+ */
+#undef remove
+
+/* Define this value used by fseek() appropriately if <stdio.h>
+ * (or <unistd.h> on SunOS 4.1.x) does not define them.
+ */
+#undef SEEK_SET
+
+/* Define as the maximum integer on your system if not defined <limits.h>.
+ */
+#undef INT_MAX
+
+/* You can define this label to be a string containing the name of a
+ * site-specific configuration file containing site-wide default options. The
+ * files /etc/ctags.conf and /usr/local/etc/ctags.conf are already checked,
+ * so only define one here if you need a file somewhere else.
+ */
+#undef CUSTOM_CONFIGURATION_FILE
+
+/* Define this label if you want macro tags (defined lables) to use patterns
+ * in the EX command by default (original ctags behavior is to use line
+ * numbers).
+ */
+#undef MACROS_USE_PATTERNS
+
+/* Define this as desired.
+ * 1: Original ctags format
+ * 2: Extended ctags format with extension flags in EX-style comment.
+ */
+#define DEFAULT_FILE_FORMAT 2
+
+/* Define this label if your system supports starting scripts with a line of
+ * the form "#! /bin/sh" to select the interpreter to use for the script.
+ */
+#undef SYS_INTERPRETER
+
+/* Define this label if your system uses case-insensitive file names
+ */
+#undef CASE_INSENSITIVE_FILENAMES
+
+/* Define this label to use the system sort utility (which is probably more
+ * efficient) over the internal sorting algorithm.
+ */
+#ifndef INTERNAL_SORT
+# undef EXTERNAL_SORT
+#endif
+
+/* If you wish to change the directory in which temporary files are stored,
+ * define this label to the directory desired.
+ */
+#undef TMPDIR
+
+/* Define this label if regcomp() is broken.
+ */
+#undef REGCOMP_BROKEN
+
+/* Define this label if you wish to check the regcomp() function at run time
+ * for correct behavior. This function is currently broken on Cygwin.
+ */
+#undef CHECK_REGCOMP
+
+/* This corrects the problem of missing prototypes for certain functions
+ * in some GNU installations (e.g. SunOS 4.1.x).
+ */
+#undef __USE_FIXED_PROTOTYPES__
+
+/* Define this is you have a prototype for putenv() in <stdlib.h>, but
+ * doesn't declare its argument as "const char *".
+ */
+#undef NON_CONST_PUTENV_PROTOTYPE
+
+/* If you receive error or warning messages indicating that you are missing
+ * a prototype for, or a type mismatch using, one of the following functions,
+ * define the appropriate label and remake.
+ */
+#undef NEED_PROTO_REMOVE
+#undef NEED_PROTO_UNLINK
+#undef NEED_PROTO_MALLOC
+#undef NEED_PROTO_GETENV
+#undef NEED_PROTO_FGETPOS
+#undef NEED_PROTO_STAT
+#undef NEED_PROTO_LSTAT
+#undef NEED_PROTO_TRUNCATE
+#undef NEED_PROTO_FTRUNCATE
+
+/*----------------------------------------------------------------------------
+- Lines below this are automatically generated by autoheader
+----------------------------------------------------------------------------*/
+/* @TOP@ */
diff --git a/ant.c b/ant.c
index eedfcec..bd01de4 100644
--- a/ant.c
+++ b/ant.c
@@ -24,9 +24,9 @@
static void installAntRegex (const langType language)
{
addTagRegex (language,
- "^[ \t]*<[ \t]*project.*name=\"([^\"]+)\".*", "\\1", "p,project,projects", NULL);
+ "^[ \t]*<[ \t]*project[^>]+name=\"([^\"]+)\".*", "\\1", "p,project,projects", NULL);
addTagRegex (language,
- "^[ \t]*<[ \t]*target.*name=\"([^\"]+)\".*", "\\1", "t,target,targets", NULL);
+ "^[ \t]*<[ \t]*target[^>]+name=\"([^\"]+)\".*", "\\1", "t,target,targets", NULL);
}
extern parserDefinition* AntParser ()
diff --git a/c.c b/c.c
index 0cf0a14..ccca3a4 100644
--- a/c.c
+++ b/c.c
@@ -48,7 +48,7 @@
* DATA DECLARATIONS
*/
-enum { NumTokens = 3 };
+enum { NumTokens = 15 };
typedef enum eException {
ExceptionNone, ExceptionEOF, ExceptionFormattingError,
@@ -119,6 +119,8 @@ typedef enum eTokenType {
TOKEN_PAREN_NAME, /* a single name in parentheses */
TOKEN_SEMICOLON, /* the semicolon character */
TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */
+ TOKEN_STAR, /* pointer * detection */
+ TOKEN_AMPERSAND, /* ampersand & detection */
TOKEN_COUNT
} tokenType;
@@ -259,6 +261,7 @@ static langType Lang_java;
static langType Lang_vera;
static vString *Signature;
static boolean CollectingSignature;
+static vString *ReturnType;
/* Number used to uniquely identify anonymous structs and unions. */
static int AnonymousID = 0;
@@ -564,7 +567,7 @@ static const char *implementationString (const impType imp)
/*
* Debugging functions
*/
-
+#define DEBUG
#ifdef DEBUG
#define boolString(c) ((c) ? "TRUE" : "FALSE")
@@ -573,7 +576,7 @@ static const char *tokenString (const tokenType type)
{
static const char *const names [] = {
"none", "args", "}", "{", "colon", "comma", "double colon", "keyword",
- "name", "package", "paren-name", "semicolon", "specifier"
+ "name", "package", "paren-name", "semicolon", "specifier", "star", "ampersand"
};
Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT);
Assert ((int) type < TOKEN_COUNT);
@@ -637,13 +640,13 @@ static void __unused__ pt (tokenInfo *const token)
static void __unused__ ps (statementInfo *const st)
{
unsigned int i;
- printf ("scope: %s decl: %s gotName: %s gotParenName: %s\n",
+ printf ("scope: %s decl: %s gotName: %s gotParenName: %s isPointer: %s\n",
scopeString (st->scope), declString (st->declaration),
- boolString (st->gotName), boolString (st->gotParenName));
+ boolString (st->gotName), boolString (st->gotParenName), boolString (st->isPointer));
printf ("haveQualifyingName: %s\n", boolString (st->haveQualifyingName));
printf ("access: %s default: %s\n", accessString (st->member.access),
accessString (st->member.accessDefault));
- printf ("token : ");
+ printf ("active token : ");
pt (activeToken (st));
for (i = 1 ; i < (unsigned int) NumTokens ; ++i)
{
@@ -982,8 +985,15 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
case TAG_FUNCTION:
case TAG_METHOD:
case TAG_PROTOTYPE:
- if (vStringLength (Signature) > 0)
+ if (vStringLength (Signature) > 0)
+ {
tag->extensionFields.signature = vStringValue (Signature);
+ }
+
+ if (vStringLength (ReturnType) > 0)
+ {
+ tag->extensionFields.returnType = vStringValue (ReturnType);
+ }
case TAG_CLASS:
case TAG_ENUM:
case TAG_ENUMERATOR:
@@ -1156,7 +1166,7 @@ static void makeTag (const tokenInfo *const token,
findScopeHierarchy (scope, st);
addOtherFields (&e, type, st, scope, typeRef);
-
+
makeTagEntry (&e);
makeExtraTagEntry (type, &e, scope);
vStringDelete (scope);
@@ -1377,6 +1387,8 @@ static void skipToMatch (const char *const pair)
{
if (CollectingSignature)
vStringPut (Signature, c);
+
+
if (c == begin)
{
++matchLevel;
@@ -2073,7 +2085,7 @@ static void processAngleBracket (void)
cppUngetc (c);
}
} else {
- cppUngetc (c);
+ cppUngetc (c);
}
}
@@ -2102,6 +2114,106 @@ static void parseJavaAnnotation (statementInfo *const st)
}
}
+static void parseReturnType (statementInfo *const st)
+{
+ int i;
+ int lower_bound;
+ tokenInfo * finding_tok;
+
+ /* FIXME TODO: if java language must be supported then impement this here
+ * removing the current FIXME */
+ if (!isLanguage (Lang_c) && !isLanguage (Lang_cpp))
+ {
+ return;
+ }
+
+ vStringClear (ReturnType);
+
+ finding_tok = prevToken (st, 1);
+
+ if (isType (finding_tok, TOKEN_NONE))
+ return;
+
+ finding_tok = prevToken (st, 2);
+
+ if (finding_tok->type == TOKEN_DOUBLE_COLON)
+ {
+ /* get the total number of double colons */
+ int j;
+ int num_colons = 0;
+
+ /* we already are at 2nd token */
+ /* the +=2 means that colons are usually found at even places */
+ for (j = 2; j < NumTokens; j+=2)
+ {
+ tokenInfo *curr_tok;
+ curr_tok = prevToken (st, j);
+ if (curr_tok->type == TOKEN_DOUBLE_COLON)
+ num_colons++;
+ else
+ break;
+ }
+
+ /*printf ("FOUND colons %d\n", num_colons);*/
+ lower_bound = 2 * num_colons + 1;
+ }
+ else
+ lower_bound = 1;
+
+ for (i = (unsigned int) NumTokens; i > lower_bound; i--)
+ {
+ tokenInfo * curr_tok;
+ curr_tok = prevToken (st, i);
+
+ switch (curr_tok->type)
+ {
+ case TOKEN_PAREN_NAME:
+ case TOKEN_NONE:
+ continue;
+ break;
+
+ case TOKEN_DOUBLE_COLON:
+ /* usually C++ class scope */
+ vStringCatS (ReturnType, "::");
+ break;
+
+ case TOKEN_STAR:
+ /* pointers */
+ vStringPut (ReturnType, '*');
+ break;
+
+ case TOKEN_AMPERSAND:
+ /* references */
+ vStringPut (ReturnType, '&');
+ break;
+
+ case TOKEN_KEYWORD:
+ vStringPut (ReturnType, ' ');
+
+ default:
+ vStringCat (ReturnType, curr_tok->name);
+ break;
+ }
+ }
+
+ /* clear any white space from the front */
+ vStringStripLeading (ReturnType);
+
+ /* .. and from the tail too */
+ vStringStripTrailing (ReturnType);
+
+ /* put and end marker */
+ vStringTerminate (ReturnType);
+
+ /*/
+ printf ("~~~~~ statement ---->\n");
+ ps (st);
+ printf ("NumTokens: %d\n", NumTokens);
+ printf ("FOUND ReturnType: %s\n", vStringValue (ReturnType));
+ printf ("<~~~~~\n");
+ //*/
+}
+
static int parseParens (statementInfo *const st, parenInfo *const info)
{
tokenInfo *const token = activeToken (st);
@@ -2301,6 +2413,7 @@ static void analyzeParens (statementInfo *const st)
initParenInfo (&info);
parseParens (st, &info);
+ parseReturnType (st);
c = skipToNonWhite ();
cppUngetc (c);
if (info.invalidContents)
@@ -2536,9 +2649,15 @@ static void nextToken (statementInfo *const st)
switch (c)
{
case EOF: longjmp (Exception, (int) ExceptionEOF); break;
- case '(': analyzeParens (st); break;
+ /* analyze functions and co */
+ case '(': analyzeParens (st); break;
case '<': processAngleBracket (); break;
- case '*': st->haveQualifyingName = FALSE; break;
+ case '*':
+ st->haveQualifyingName = FALSE;
+ setToken (st, TOKEN_STAR);
+ break;
+ case '&': setToken (st, TOKEN_AMPERSAND); break;
+
case ',': setToken (st, TOKEN_COMMA); break;
case ':': processColon (st); break;
case ';': setToken (st, TOKEN_SEMICOLON); break;
@@ -2654,6 +2773,7 @@ static void nest (statementInfo *const st, const unsigned int nestLevel)
case DECL_FUNCTION:
case DECL_TASK:
st->inFunction = TRUE;
+
/* fall through */
default:
if (includeTag (TAG_LOCAL, FALSE))
@@ -2765,6 +2885,7 @@ static void createTags (const unsigned int nestLevel,
nextToken (st);
token = activeToken (st);
+
if (isType (token, TOKEN_BRACE_CLOSE))
{
if (nestLevel > 0)
@@ -2801,6 +2922,7 @@ static boolean findCTags (const unsigned int passCount)
Assert (passCount < 3);
cppInit ((boolean) (passCount > 1), isLanguage (Lang_csharp));
Signature = vStringNew ();
+ ReturnType = vStringNew ();
exception = (exception_t) setjmp (Exception);
retry = FALSE;
@@ -2817,6 +2939,7 @@ static boolean findCTags (const unsigned int passCount)
}
}
vStringDelete (Signature);
+ vStringDelete (ReturnType);
cppTerminate ();
return retry;
}
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..d33e48b
--- /dev/null
+++ b/config.h
@@ -0,0 +1,275 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+/*
+* $Id: acconfig.h 318 2003-04-01 05:02:21Z darren $
+*
+* Copyright (c) 1998-2003, Darren Hiebert
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License.
+*
+* This module contains input source for generating config.h.in
+*/
+
+/* Package name.
+ */
+/* #undef PACKAGE */
+
+/* Package version.
+ */
+/* #undef VERSION */
+
+/* Define to the appropriate type if <time.h> does not define this.
+ */
+/* #undef clock_t */
+
+/* Define to long if <stdio.h> does not define this.
+ */
+/* #undef fpos_t */
+
+/* Define to the appropriate size for tmpnam() if <stdio.h> does not define
+ * this.
+ */
+/* #undef L_tmpnam */
+
+/* Define this macro if the field "st_ino" exists in struct stat in
+ * <sys/stat.h>.
+ * */
+#define HAVE_STAT_ST_INO 1
+
+/* Define remove to unlink if you have unlink(), but not remove().
+ */
+/* #undef remove */
+
+/* Define this value used by fseek() appropriately if <stdio.h>
+ * (or <unistd.h> on SunOS 4.1.x) does not define them.
+ */
+/* #undef SEEK_SET */
+
+/* Define as the maximum integer on your system if not defined <limits.h>.
+ */
+/* #undef INT_MAX */
+
+/* You can define this label to be a string containing the name of a
+ * site-specific configuration file containing site-wide default options. The
+ * files /etc/ctags.conf and /usr/local/etc/ctags.conf are already checked,
+ * so only define one here if you need a file somewhere else.
+ */
+/* #undef CUSTOM_CONFIGURATION_FILE */
+
+/* Define this label if you want macro tags (defined lables) to use patterns
+ * in the EX command by default (original ctags behavior is to use line
+ * numbers).
+ */
+/* #undef MACROS_USE_PATTERNS */
+
+/* Define this as desired.
+ * 1: Original ctags format
+ * 2: Extended ctags format with extension flags in EX-style comment.
+ */
+#define DEFAULT_FILE_FORMAT 2
+
+/* Define this label if your system supports starting scripts with a line of
+ * the form "#! /bin/sh" to select the interpreter to use for the script.
+ */
+#define SYS_INTERPRETER 1
+
+/* Define this label if your system uses case-insensitive file names
+ */
+/* #undef CASE_INSENSITIVE_FILENAMES */
+
+/* Define this label to use the system sort utility (which is probably more
+ * efficient) over the internal sorting algorithm.
+ */
+#ifndef INTERNAL_SORT
+# define EXTERNAL_SORT 1
+#endif
+
+/* If you wish to change the directory in which temporary files are stored,
+ * define this label to the directory desired.
+ */
+#define TMPDIR "/tmp"
+
+/* Define this label if regcomp() is broken.
+ */
+/* #undef REGCOMP_BROKEN */
+
+/* Define this label if you wish to check the regcomp() function at run time
+ * for correct behavior. This function is currently broken on Cygwin.
+ */
+/* #undef CHECK_REGCOMP */
+
+/* This corrects the problem of missing prototypes for certain functions
+ * in some GNU installations (e.g. SunOS 4.1.x).
+ */
+/* #undef __USE_FIXED_PROTOTYPES__ */
+
+/* Define this is you have a prototype for putenv() in <stdlib.h>, but
+ * doesn't declare its argument as "const char *".
+ */
+/* #undef NON_CONST_PUTENV_PROTOTYPE */
+
+/* If you receive error or warning messages indicating that you are missing
+ * a prototype for, or a type mismatch using, one of the following functions,
+ * define the appropriate label and remake.
+ */
+/* #undef NEED_PROTO_REMOVE */
+/* #undef NEED_PROTO_UNLINK */
+/* #undef NEED_PROTO_MALLOC */
+/* #undef NEED_PROTO_GETENV */
+/* #undef NEED_PROTO_FGETPOS */
+/* #undef NEED_PROTO_STAT */
+/* #undef NEED_PROTO_LSTAT */
+/* #undef NEED_PROTO_TRUNCATE */
+/* #undef NEED_PROTO_FTRUNCATE */
+
+/*----------------------------------------------------------------------------
+- Lines below this are automatically generated by autoheader
+----------------------------------------------------------------------------*/
+
+/* Define to 1 if you have the `chmod' function. */
+/* #undef HAVE_CHMOD */
+
+/* Define to 1 if you have the `chsize' function. */
+/* #undef HAVE_CHSIZE */
+
+/* Define to 1 if you have the `clock' function. */
+#define HAVE_CLOCK 1
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fgetpos' function. */
+#define HAVE_FGETPOS 1
+
+/* Define to 1 if you have the `findfirst' function. */
+/* #undef HAVE_FINDFIRST */
+
+/* Define to 1 if you have the `fnmatch' function. */
+#define HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#define HAVE_FNMATCH_H 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+/* #undef HAVE_FTRUNCATE */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define to 1 if you have the `putenv' function. */
+/* #undef HAVE_PUTENV */
+
+/* Define to 1 if you have the `regcomp' function. */
+#define HAVE_REGCOMP 1
+
+/* Define to 1 if you have the `remove' function. */
+#define HAVE_REMOVE 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the <stat.h> header file. */
+/* #undef HAVE_STAT_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strnicmp' function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the <sys/dir.h> header file. */
+#define HAVE_SYS_DIR_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `tempnam' function. */
+/* #undef HAVE_TEMPNAM */
+
+/* Define to 1 if you have the `times' function. */
+/* #undef HAVE_TIMES */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the `truncate' function. */
+#define HAVE_TRUNCATE 1
+
+/* Define to 1 if you have the <types.h> header file. */
+/* #undef HAVE_TYPES_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `_findfirst' function. */
+/* #undef HAVE__FINDFIRST */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/ctags-utils.c b/ctags-utils.c
new file mode 100644
index 0000000..0db7745
--- /dev/null
+++ b/ctags-utils.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Massimo Cora' 2010 <maxcvs@email.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+
+#include "ctags-utils.h"
+
+void
+get_file_pos (gint line, fpos_t *fpos, FILE *f)
+{
+ vString * str = vStringNew ();
+ gint i;
+ g_assert (fseek (f, 0, SEEK_SET) == 0);
+
+ for (i = 0;i < line - 1; i++)
+ {
+ if (readLine (str, f) == NULL)
+ {
+ vStringDelete (str);
+ return;
+ }
+ }
+
+ vStringDelete (str);
+ g_assert (fgetpos (f, fpos) == 0);
+}
+
+
diff --git a/ctags-utils.h b/ctags-utils.h
new file mode 100644
index 0000000..41283bf
--- /dev/null
+++ b/ctags-utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Massimo Cora' 2010 <maxcvs@email.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
+ */
+
+#include "general.h" /* must always come first */
+#include "read.h"
+#include <assert.h>
+#include <glib.h>
+#include <string.h>
+
+
+/**
+ * IMPORTANT NOTE
+ *
+ * This file should contain functions/helpers that aren't strictly
+ * ctags-standardized and that can be used in extra parsers (i.e. parser
+ * not included with ctags distribution).
+ * Doing so and keeping separate standard/extra files should make
+ * an upgrade of ctags easier.
+ */
+
+
+void get_file_pos (gint line, fpos_t *fpos, FILE *f);
+
diff --git a/ctags-visitor.vala b/ctags-visitor.vala
new file mode 100644
index 0000000..f7c050a
--- /dev/null
+++ b/ctags-visitor.vala
@@ -0,0 +1,400 @@
+/*
+ * ctags-visitor.vala
+ *
+ * Copyright 2008, 2010 Abderrahim Kitouni <a.kitouni@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+using Vala;
+
+public struct CTagsEntry {
+ public int line_number;
+ public string name;
+ public string kind_name;
+ public char kind;
+ public string access;
+ public string implementation;
+ public string inheritance;
+ public string scope[2];
+ public string signature;
+ public string typeref;
+ public string returntype;
+}
+
+class DummyReport : Report {
+ public override void warn (SourceReference? source, string message) {}
+ public override void err (SourceReference? source, string message) {}
+}
+
+[CCode (has_target=false)]
+public delegate void CTagsEntryMaker (CTagsEntry entry);
+
+public class CTagsVisitor : CodeVisitor {
+ Parser vala_parser;
+ Genie.Parser genie_parser;
+ GLib.List<CTagsEntry?> taglist;
+ public CTagsVisitor () {
+ vala_parser = new Parser();
+ genie_parser = new Genie.Parser();
+ }
+ /* helper functions */
+ static string get_access (Symbol sym) {
+ switch (sym.access) {
+ case SymbolAccessibility.PRIVATE : return "private";
+ case SymbolAccessibility.INTERNAL : return "internal";
+ case SymbolAccessibility.PROTECTED : return "protected";
+ case SymbolAccessibility.PUBLIC : return "public";
+ }
+ assert_not_reached ();
+ }
+ static string to_string (Iterable<DataType> seq, string sep = ",") {
+ var str = new StringBuilder();
+ var first = true;
+ foreach (var type in seq) {
+ if(first) {
+ first = false;
+ } else {
+ str.append(sep);
+ }
+ str.append(type.to_qualified_string());
+ }
+ return str.str;
+ }
+ static string? implementation (Symbol sym) {
+ var list = new GLib.List<string>();
+
+ if (sym is Vala.Signal) {
+ var sig = (Vala.Signal)sym;
+ if (sig.is_virtual)
+ list.append("virtual");
+ } else if (sym is Class) {
+ var cls = (Class)sym;
+ if (cls.is_abstract)
+ list.append("abstract");
+ } else if (sym is Method) {
+ var meth = (Method)sym;
+ if (meth.is_abstract)
+ list.append("abstract");
+ else if (meth.is_virtual)
+ list.append("virtual");
+ } else if (sym is Property) {
+ var prop = (Property)sym;
+ if (prop.is_abstract)
+ list.append("abstract");
+ else if (prop.is_virtual)
+ list.append("virtual");
+ } else
+ return_val_if_reached(null);
+
+ var ret = new StringBuilder();
+ var first = true;
+ foreach (var str in list) {
+ if(first) {
+ first = false;
+ } else {
+ ret.append(",");
+ }
+ ret.append(str);
+ }
+ return ret.str;
+ }
+ static string signature (Vala.List<Vala.Parameter> parameter) {
+ var ret = new StringBuilder("(");
+ var first = true;
+ foreach (var p in parameter) {
+ if(first) {
+ first = false;
+ } else {
+ ret.append(",");
+ }
+ if (p.ellipsis) {
+ ret.append("...");
+ } else {
+ ret.append (p.variable_type.to_qualified_string());
+ ret.append (" ");
+ ret.append (p.name);
+ }
+ }
+ ret.append (")");
+ return ret.str;
+ }
+ static string[] scope (Symbol s) {
+ string scope[2];
+ var par = s.parent_symbol;
+ if (par != null && par.name != null) {
+ if (par is Class)
+ scope[0] = "class";
+ else if (par is Struct)
+ scope[0] = "struct";
+ else if (par is Interface)
+ scope[0] = "interface";
+ else
+ return scope;
+ scope[1] = par.name;
+ }
+ return scope;
+ }
+ /*static void print_tag(CTagsEntry en) {
+ stdout.printf("%s: %s at %d\n", en.name, en.kind_name, en.line_number);
+ }*/
+
+ public override void visit_source_file (SourceFile source_file) {
+ source_file.accept_children (this);
+ }
+
+ public override void visit_class (Class cl) {
+ var entry = CTagsEntry();
+
+ entry.line_number = cl.source_reference.begin.line;
+ entry.name = cl.name;
+ entry.kind_name = "class";
+ entry.kind = 'c';
+ entry.access = get_access (cl);
+ entry.implementation = implementation(cl);
+ entry.inheritance = to_string(cl.get_base_types(), ",");
+ entry.scope = scope (cl);
+
+ taglist.append(entry);
+// print_tag(entry);
+ cl.accept_children(this);
+ }
+ public override void visit_struct (Struct st) {
+ var entry = CTagsEntry();
+ entry.line_number = st.source_reference.begin.line;
+ entry.name = st.name;
+ entry.kind_name = "struct";
+ entry.kind = 's';
+ entry.access = get_access (st);
+ entry.scope = scope (st);
+
+ taglist.append(entry);
+// print_tag(entry);
+ st.accept_children(this);
+ }
+ public override void visit_interface (Interface iface) {
+ var entry = CTagsEntry();
+
+ entry.line_number = iface.source_reference.begin.line;
+ entry.name = iface.name;
+ entry.kind_name = "interface";
+ entry.kind = 'i';
+ entry.access = get_access (iface);
+ entry.inheritance = to_string(iface.get_prerequisites());
+ entry.scope = scope (iface);
+
+ taglist.append(entry);
+// print_tag(entry);
+ iface.accept_children(this);
+ }
+
+ public override void visit_enum (Vala.Enum en) {
+ var entry = CTagsEntry();
+
+ entry.line_number = en.source_reference.begin.line;
+ entry.name = en.name;
+ entry.kind_name = "enum";
+ entry.kind = 'e';
+ entry.access = get_access (en);
+ entry.scope = scope (en);
+
+ taglist.append(entry);
+// print_tag(entry);
+ en.accept_children(this);
+ }
+ public override void visit_error_domain (ErrorDomain edomain) {
+ var entry = CTagsEntry();
+
+ entry.line_number = edomain.source_reference.begin.line;
+ entry.name = edomain.name;
+ entry.kind_name = "errordomain";
+ entry.kind = 'E';
+ entry.access = get_access (edomain);
+ entry.scope = scope (edomain);
+
+ taglist.append(entry);
+// print_tag(entry);
+ edomain.accept_children(this);
+ }
+
+ public override void visit_enum_value (Vala.EnumValue ev) {
+ var entry = CTagsEntry();
+
+ entry.line_number = ev.source_reference.begin.line;
+ entry.name = ev.name;
+ entry.kind_name = "enumvalue";
+ entry.kind = 'v';
+ entry.access = get_access (ev);
+ entry.scope = scope (ev);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_error_code (ErrorCode ecode) {
+ var entry = CTagsEntry();
+
+ //entry.line_number = ecode.source_reference.begin.line;
+ entry.name = ecode.name;
+ entry.kind_name = "errorcode";
+ entry.kind = 'r';
+ entry.access = get_access (ecode);
+ entry.scope = scope (ecode);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_delegate (Delegate d) {
+ var entry = CTagsEntry();
+
+ entry.line_number = d.source_reference.begin.line;
+ entry.name = d.name;
+ entry.kind_name = "delegate";
+ entry.kind = 'd';
+ entry.access = get_access (d);
+ entry.scope = scope (d);
+ entry.returntype = d.return_type.to_qualified_string();
+ entry.signature = signature(d.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_signal (Vala.Signal sig) {
+ var entry = CTagsEntry();
+
+ entry.line_number = sig.source_reference.begin.line;
+ entry.name = sig.name;
+ entry.kind_name = "signal";
+ entry.kind = 'S';
+ entry.access = get_access (sig);
+ entry.implementation = implementation(sig);
+ entry.scope = scope (sig);
+ entry.returntype = sig.return_type.to_qualified_string();
+ entry.signature = signature(sig.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_field (Field f) {
+ var entry = CTagsEntry();
+
+ entry.line_number = f.source_reference.begin.line;
+ entry.name = f.name;
+ entry.kind_name = "field";
+ entry.kind = 'f';
+ entry.access = get_access (f);
+ entry.scope = scope (f);
+ entry.typeref = f.variable_type.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_constant (Constant c) {
+ var entry = CTagsEntry();
+
+ entry.line_number = c.source_reference.begin.line;
+ entry.name = c.name;
+ entry.kind_name = "field";
+ entry.kind = 'f';
+ entry.access = get_access (c);
+ entry.scope = scope (c);
+ entry.typeref = c.type_reference.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_property (Property prop) {
+ var entry = CTagsEntry();
+
+ entry.line_number = prop.source_reference.begin.line;
+ entry.name = prop.name;
+ entry.kind_name = "property";
+ entry.kind = 'p';
+ entry.access = get_access (prop);
+ entry.implementation = implementation(prop);
+ entry.scope = scope (prop);
+ entry.typeref = prop.property_type.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_method (Method m) {
+ var entry = CTagsEntry();
+
+ entry.line_number = m.source_reference.begin.line;
+ entry.name = m.name;
+ entry.kind_name = "method";
+ entry.kind = 'm';
+ entry.access = get_access (m);
+ entry.implementation = implementation(m);
+ entry.scope = scope (m);
+ entry.returntype = m.return_type.to_qualified_string();
+ entry.signature = signature(m.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_local_variable (LocalVariable local) {
+ var entry = CTagsEntry();
+
+ entry.line_number = local.source_reference.begin.line;
+ entry.name = local.name;
+ entry.kind_name = "local";
+ entry.kind = 'l';
+ entry.access = get_access (local);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public void parse_vala (string filename, CTagsEntryMaker maker ) {
+ taglist = new GLib.List<CTagsEntry?>();
+ /* We create a context for every source file so that Parser.parse(context)
+ * don't parse a file multiple times causing errors. Parser.parse_file(source_file)
+ * assumes that Parser.context is the same as source_file.context anyway */
+ var context = new CodeContext();
+ context.report = new DummyReport();
+ var source_file = new SourceFile(context, filename.has_suffix("vapi") ? SourceFileType.PACKAGE : SourceFileType.SOURCE, filename);
+
+ CodeContext.push(context);
+ context.add_source_file(source_file);
+ vala_parser.parse(context);
+ context.accept(this);
+ foreach (var tagentry in taglist) {
+ maker(tagentry);
+ }
+ taglist = null;
+ CodeContext.pop();
+ }
+ public void parse_genie (string filename, CTagsEntryMaker maker ) {
+ taglist = new GLib.List<CTagsEntry?>();
+ var context = new CodeContext();
+ context.report = new DummyReport();
+ var source_file = new SourceFile(context, SourceFileType.SOURCE, filename);
+ context.add_source_file(source_file);
+
+ CodeContext.push(context);
+ genie_parser.parse(context);
+ context.accept(this);
+ foreach (var tagentry in taglist) {
+ maker(tagentry);
+ }
+ taglist = null;
+ CodeContext.pop();
+ }
+}
diff --git a/ctags.h b/ctags.h
index f8884af..fb5ca5b 100644
--- a/ctags.h
+++ b/ctags.h
@@ -15,7 +15,7 @@
* MACROS
*/
#ifndef PROGRAM_VERSION
-# define PROGRAM_VERSION "5.8"
+# define PROGRAM_VERSION "Development"
#endif
#define PROGRAM_NAME "Exuberant Ctags"
#define PROGRAM_URL "http://ctags.sourceforge.net"
diff --git a/eiffel.c b/eiffel.c
index b504ac3..e2f5a5c 100644
--- a/eiffel.c
+++ b/eiffel.c
@@ -1,5 +1,5 @@
/*
-* $Id: eiffel.c 706 2009-06-28 23:09:30Z dhiebert $
+* $Id: eiffel.c 748 2009-11-06 02:44:42Z dhiebert $
*
* Copyright (c) 1998-2002, Darren Hiebert
*
@@ -53,13 +53,15 @@ typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
*/
typedef enum eKeywordId {
KEYWORD_NONE = -1,
- KEYWORD_alias, KEYWORD_all, KEYWORD_and, KEYWORD_as, KEYWORD_assign,
+ KEYWORD_alias, KEYWORD_all, KEYWORD_and,
+ KEYWORD_as, KEYWORD_assign, KEYWORD_attached,
KEYWORD_check, KEYWORD_class, KEYWORD_convert, KEYWORD_create,
KEYWORD_creation, KEYWORD_Current,
- KEYWORD_debug, KEYWORD_deferred, KEYWORD_do, KEYWORD_else,
- KEYWORD_elseif, KEYWORD_end, KEYWORD_ensure, KEYWORD_expanded,
- KEYWORD_export, KEYWORD_external, KEYWORD_false, KEYWORD_feature,
- KEYWORD_from, KEYWORD_frozen, KEYWORD_if, KEYWORD_implies,
+ KEYWORD_debug, KEYWORD_deferred, KEYWORD_detachable, KEYWORD_do,
+ KEYWORD_else, KEYWORD_elseif, KEYWORD_end, KEYWORD_ensure,
+ KEYWORD_expanded, KEYWORD_export, KEYWORD_external,
+ KEYWORD_false, KEYWORD_feature, KEYWORD_from, KEYWORD_frozen,
+ KEYWORD_if, KEYWORD_implies,
KEYWORD_indexing, KEYWORD_infix, KEYWORD_inherit, KEYWORD_inspect,
KEYWORD_invariant, KEYWORD_is, KEYWORD_like, KEYWORD_local,
KEYWORD_loop, KEYWORD_not, KEYWORD_obsolete, KEYWORD_old, KEYWORD_once,
@@ -154,6 +156,7 @@ static const keywordDesc EiffelKeywordTable [] = {
{ "and", KEYWORD_and },
{ "as", KEYWORD_as },
{ "assign", KEYWORD_assign },
+ { "attached", KEYWORD_attached },
{ "check", KEYWORD_check },
{ "class", KEYWORD_class },
{ "convert", KEYWORD_convert },
@@ -162,6 +165,7 @@ static const keywordDesc EiffelKeywordTable [] = {
{ "current", KEYWORD_Current },
{ "debug", KEYWORD_debug },
{ "deferred", KEYWORD_deferred },
+ { "detachable", KEYWORD_detachable },
{ "do", KEYWORD_do },
{ "else", KEYWORD_else },
{ "elseif", KEYWORD_elseif },
@@ -870,7 +874,9 @@ static boolean parseType (tokenInfo *const token)
}
else
{
- if (isKeyword (id, KEYWORD_expanded))
+ if (isKeyword (id, KEYWORD_attached) ||
+ isKeyword (id, KEYWORD_detachable) ||
+ isKeyword (id, KEYWORD_expanded))
{
copyToken (id, token);
readToken (token);
diff --git a/entry.c b/entry.c
index 3890e50..28bfe07 100644
--- a/entry.c
+++ b/entry.c
@@ -761,6 +761,11 @@ static int addExtensionFields (const tagEntryInfo *const tag)
length += fprintf (TagFile.fp, "%s\tsignature:%s", sep,
tag->extensionFields.signature);
+ if (Option.extensionFields.returnType &&
+ tag->extensionFields.returnType != NULL)
+ length += fprintf (TagFile.fp, "%s\treturntype:%s", sep,
+ tag->extensionFields.returnType);
+
return length;
#undef sep
}
@@ -836,6 +841,7 @@ extern void initTagEntry (tagEntryInfo *const e, const char *const name)
{
Assert (File.source.name != NULL);
memset (e, 0, sizeof (tagEntryInfo));
+
e->lineNumberEntry = (boolean) (Option.locate == EX_LINENUM);
e->lineNumber = getSourceLineNumber ();
e->language = getSourceLanguageName ();
diff --git a/entry.h b/entry.h
index 2365c50..323c1c5 100644
--- a/entry.h
+++ b/entry.h
@@ -72,7 +72,8 @@ typedef struct sTagEntryInfo {
const char* inheritance;
const char* scope [2]; /* value and key */
const char* signature;
-
+ const char* returnType;
+
/* type (union/struct/etc.) and name for a variable or typedef. */
const char* typeRef [2]; /* e.g., "struct" and struct name */
diff --git a/falcon.c b/falcon.c
new file mode 100644
index 0000000..2730462
--- /dev/null
+++ b/falcon.c
@@ -0,0 +1,149 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2011, 2012 Steven Oliver <oliver.steven@gmail.com>
+ *
+ * This source code is released for free distribution under the terms of the
+ * GNU General Public License.
+ *
+ * This module contains functions for generating tags for Falcon language
+ * files.
+ */
+
+
+/*
+ * INCLUDE FILES
+ */
+#include "general.h"
+
+#include <string.h>
+#include <ctype.h>
+
+#include "parse.h"
+#include "read.h"
+
+/*
+ * Data Definitions
+ */
+typedef enum eFalconKinds {
+ K_CLASS,
+ K_FUNCTION,
+ K_MEMBER,
+ K_VARIABLE,
+ K_NAMESPACE
+} falconKind;
+
+static kindOption FalconKinds [] = {
+ {TRUE, 'c', "class", "classes" },
+ {TRUE, 'f', "function", "functions"},
+ {TRUE, 'm', "member", "class members"},
+ {TRUE, 'v', "variable", "variables"},
+ {TRUE, 'i', "namespace", "imports"}
+};
+
+/*
+ * Function Definitions
+ */
+
+static boolean isIdentifierChar (int c)
+{
+ return (boolean) (isalnum (c) || c == '_');
+}
+
+static const char *skipSpace (const char *cp)
+{
+ while (isspace ((int) *cp))
+ ++cp;
+
+ return cp;
+}
+
+static const char *skipString (const char *cp)
+{
+ const char *start = cp;
+ int escaped = 0;
+
+ for (cp++; *cp; cp++)
+ {
+ if (escaped)
+ escaped--;
+ else if (*cp == '\\')
+ escaped++;
+ else if (*cp == *start)
+ return cp + 1;
+ }
+
+ return cp;
+}
+
+static void findFalconTags (void)
+{
+ vString *name = vStringNew ();
+ const unsigned char *line;
+
+ while ((line = fileReadLine ()) != NULL)
+ {
+ const unsigned char *cp = line;
+
+ if (*cp == '#')
+ continue;
+
+ if (strncmp ((const char*) cp, "function", (size_t) 8) == 0)
+ {
+ cp += 8;
+ cp = skipSpace (cp);
+
+ while (isIdentifierChar ((int) *cp))
+ {
+ vStringPut (name, (int) *cp);
+ ++cp;
+ }
+ vStringTerminate (name);
+ makeSimpleTag (name, FalconKinds, K_FUNCTION);
+ vStringClear (name);
+ }
+ else if (strncmp ((const char*) cp, "class", (size_t) 5) == 0)
+ {
+ cp += 5;
+ cp = skipSpace (cp);
+
+ while (isIdentifierChar ((int) *cp))
+ {
+ vStringPut (name, (int) *cp);
+ ++cp;
+ }
+ vStringTerminate (name);
+ makeSimpleTag (name, FalconKinds, K_CLASS);
+ vStringClear (name);
+ }
+ else if (strncmp ((const char*) cp, "load", (size_t) 4) == 0)
+ {
+ cp += 4;
+ cp = skipSpace (cp);
+
+ while (isIdentifierChar ((int) *cp))
+ {
+ vStringPut (name, (int) *cp);
+ ++cp;
+ }
+ vStringTerminate (name);
+ makeSimpleTag (name, FalconKinds, K_NAMESPACE);
+ vStringClear (name);
+ }
+ }
+ vStringDelete (name);
+}
+
+/*
+ * Parser definition structure
+ */
+extern parserDefinition* FalconParser (void)
+{
+ static const char *const extensions [] = { "fal", "ftd", NULL };
+ parserDefinition *def = parserNew ("Falcon");
+ def->kinds = FalconKinds;
+ def->kindCount = KIND_COUNT (FalconKinds);
+ def->extensions = extensions;
+ def->parser = findFalconTags;
+ return def;
+}
diff --git a/flex.c b/flex.c
index 06ca243..038ac4e 100644
--- a/flex.c
+++ b/flex.c
@@ -80,7 +80,8 @@ typedef enum eKeywordId {
KEYWORD_id,
KEYWORD_script,
KEYWORD_cdata,
- KEYWORD_mx
+ KEYWORD_mx,
+ KEYWORD_override
} keywordId;
/* Used to determine whether keyword is valid for the token language and
@@ -184,7 +185,8 @@ static const keywordDesc FlexKeywordTable [] = {
{ "id", KEYWORD_id },
{ "script", KEYWORD_script },
{ "cdata", KEYWORD_cdata },
- { "mx", KEYWORD_mx }
+ { "mx", KEYWORD_mx },
+ { "override", KEYWORD_override }
};
/*
@@ -726,7 +728,7 @@ static void skipArgumentList (tokenInfo *const token)
* Other databases can have arguments with fully declared
* datatypes:
* ( name varchar(30), text binary(10) )
- * So we must check for nested open and closing parantheses
+ * So we must check for nested open and closing parentheses
*/
if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */
@@ -1780,7 +1782,7 @@ static boolean parseStatement (tokenInfo *const token)
if (isType (token, TOKEN_CLOSE_CURLY))
{
/*
- * Assume the closing parantheses terminates
+ * Assume the closing parenthesis terminates
* this statements.
*/
is_terminated = TRUE;
@@ -2154,6 +2156,33 @@ static boolean parseActionScript (tokenInfo *const token)
{
if (isType(token, TOKEN_KEYWORD))
{
+ if (isKeyword (token, KEYWORD_private) ||
+ isKeyword (token, KEYWORD_public) ||
+ isKeyword (token, KEYWORD_override) )
+ {
+ /*
+ * Methods can be defined as:
+ * private function f_name
+ * public override function f_name
+ * override private function f_name
+ * Ignore these keywords if present.
+ */
+ readToken (token);
+ }
+ if (isKeyword (token, KEYWORD_private) ||
+ isKeyword (token, KEYWORD_public) ||
+ isKeyword (token, KEYWORD_override) )
+ {
+ /*
+ * Methods can be defined as:
+ * private function f_name
+ * public override function f_name
+ * override private function f_name
+ * Ignore these keywords if present.
+ */
+ readToken (token);
+ }
+
switch (token->keyword)
{
case KEYWORD_function: parseFunction (token); break;
@@ -2178,11 +2207,14 @@ static void parseFlexFile (tokenInfo *const token)
{
parseMXML (token);
}
- if (isType (token, TOKEN_LESS_THAN))
+ else if (isType (token, TOKEN_LESS_THAN))
{
readToken (token);
if (isType (token, TOKEN_QUESTION_MARK))
{
+ /*
+ * <?xml version="1.0" encoding="utf-8"?>
+ */
readToken (token);
while (! isType (token, TOKEN_QUESTION_MARK) )
{
@@ -2190,6 +2222,19 @@ static void parseFlexFile (tokenInfo *const token)
}
readToken (token);
}
+ else if (isKeyword (token, KEYWORD_NONE))
+ {
+ /*
+ * This is a simple XML tag, read until the closing statement
+ * <something .... >
+ * </something>
+ */
+ readToken (token);
+ while (! isType (token, TOKEN_GREATER_THAN) )
+ {
+ readToken (token);
+ }
+ }
}
else
{
diff --git a/gir.c b/gir.c
new file mode 100644
index 0000000..517472b
--- /dev/null
+++ b/gir.c
@@ -0,0 +1,216 @@
+#include "general.h" /* must always come first */
+#include "debug.h"
+#include "entry.h"
+#include "keyword.h"
+#include "parse.h"
+#include "read.h"
+#include "routines.h"
+#include "string.h"
+#include "vstring.h"
+#include <glib.h>
+#include <assert.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "ctags-utils.h"
+
+static kindOption Kinds [] = {
+ { TRUE, 'f', "function", "functions"},
+ { TRUE, 'c', "class", "classes"},
+ { TRUE, 'm', "method", "methods"},
+ { TRUE, 'p', "property", "properties"},
+ { TRUE, 'v', "variable", "global variables"}
+};
+
+static void
+initialize (const langType language)
+{
+}
+
+static void
+parse_function (xmlNode *node, const gchar *parent)
+{
+ xmlNode *i, *k;
+ gchar *name;
+ tagEntryInfo *tag;
+
+ g_assert (node != NULL);
+
+ name = (gchar*)xmlGetProp (node, (xmlChar*)"name");
+ if (!name)
+ return;
+
+ tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
+ initTagEntry (tag, name);
+ get_file_pos (node->line, &tag->filePosition, File.fp);
+ tag->lineNumber = node->line;
+ tag->isFileScope = 1;
+ tag->kindName = "function";
+ tag->kind = 'f';
+ if (parent) {
+ tag->kindName = "member";
+ tag->kind = 'm';
+ tag->extensionFields.scope[0] = "class";
+ tag->extensionFields.scope[1] = parent;
+ }
+
+ for (i = node->children; i; i = i->next)
+ {
+ if (!i->name)
+ continue;
+ if (strcmp ((const gchar*)i->name, "return-value") == 0)
+ {
+ for (k = i->children; k; k = k->next)
+ {
+ const gchar *tmp;
+ if (!k->name)
+ continue;
+ tmp = (const gchar*)xmlGetProp (k, (const xmlChar*)"name");
+ if (!tmp)
+ continue;
+ tag->extensionFields.returnType = tmp;
+ }
+ }
+ if (strcmp ((const gchar*)i->name, "parameters") == 0)
+ {
+ for (k = i->children; k; k = k->next)
+ {
+/*TODO: const gchar *name;
+ if (!k->name)
+ continue;
+ name = (const gchar*)xmlGetProp (node, (const xmlChar*)"name");
+ if (!name)
+ continue;
+ tmp = g_new (Argument, 1);
+ tmp->name = g_strdup (name);
+ tmp->types = NULL;
+ ret->args = g_list_append (ret->args, tmp);*/
+ }
+ }
+ }
+ makeTagEntry (tag);
+}
+
+static void makeTags (xmlNode *node, const gchar *parent);
+
+static void
+parse_class (xmlNode *node)
+{
+ xmlNode *i;
+ gchar *name;
+
+ g_assert (node);
+
+ name = (gchar*)xmlGetProp (node, (const xmlChar*)"name");
+ if (!name)
+ return;
+
+ tagEntryInfo *tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
+ initTagEntry (tag, name);
+ tag->isFileScope = 1;
+ tag->kindName = "class";
+ tag->kind = 'c';
+ get_file_pos (node->line, &tag->filePosition, File.fp);
+ tag->lineNumber = node->line;
+ makeTagEntry (tag);
+
+ for (i = node->children; i; i = i->next)
+ {
+ makeTags (i, name);
+ }
+}
+
+static void
+makeTags (xmlNode *node, const gchar *parent)
+{
+ g_assert (node != NULL);
+ g_assert (node->name != NULL);
+
+ if (strcmp ((const gchar*)node->name, "text") == 0
+ || strcmp ((const gchar*)node->name, "implements") == 0)
+ return;
+ if (strcmp ((const gchar*)node->name, "enumeration") == 0
+ || strcmp ((const gchar*)node->name, "union") == 0
+ || strcmp ((const gchar*)node->name, "namespace") == 0
+ || strcmp ((const gchar*)node->name, "class") == 0
+ || strcmp ((const gchar*)node->name, "record") == 0
+ || strcmp ((const gchar*)node->name, "bitfield") == 0
+ || strcmp ((const gchar*)node->name, "interface") == 0)
+ {
+ parse_class (node);
+ return;
+ }
+ if (strcmp ((const gchar*)node->name, "function") == 0 || strcmp ((const gchar*)node->name, "method") == 0
+ || strcmp ((const gchar*)node->name, "callback") == 0
+ || strcmp ((const gchar*)node->name, "constructor") == 0)
+ {
+ parse_function (node, parent);
+ return;
+ }
+ if (strcmp ((const gchar*)node->name, "alias") == 0 ||
+ strcmp ((const gchar*)node->name, "constant") == 0 ||
+ strcmp ((const gchar*)node->name, "signal") == 0 ||
+ strcmp ((const gchar*)node->name, "field") == 0 ||
+ strcmp ((const gchar*)node->name, "property") == 0 ||
+ strcmp ((const gchar*)node->name, "member") == 0)
+ {
+ gchar *name = (gchar*)xmlGetProp (node, (const xmlChar*)"name");
+ if (!name)
+ return;
+ tagEntryInfo *tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
+ initTagEntry (tag, name);
+ tag->isFileScope = 1;
+ tag->kindName = "variable";
+ tag->kind = 'v';
+ get_file_pos (node->line, &tag->filePosition, File.fp);
+ tag->lineNumber = node->line;
+ if (parent) {
+ tag->kindName = "member";
+ tag->kind = 'm';
+ tag->extensionFields.scope[0] = "class";
+ tag->extensionFields.scope[1] = parent;
+ }
+ makeTagEntry (tag);
+ return;
+ }
+}
+
+static void
+findTags (void)
+{
+ xmlNode *i;
+ xmlDocPtr doc = xmlParseFile(getInputFileName());
+ xmlNode *root;
+
+ if (doc == NULL) {
+ g_warning ("could not parse file");
+ }
+ root = xmlDocGetRootElement(doc);
+ for (i = root->children; i; i = i->next)
+ {
+ xmlNode *j;
+ if (!i->name)
+ continue;
+ if (strcmp ((const char*)i->name, "namespace") !=0)
+ continue;
+ for (j = i->children; j; j = j->next)
+ {
+ makeTags (j, NULL);
+ }
+ }
+}
+
+extern parserDefinition*
+GirParser (void)
+{
+ static const char *const extensions [] = { "gir", NULL };
+ parserDefinition *const def = parserNew ("GObject-Introspection");
+ def->extensions = extensions;
+
+ def->kinds = Kinds;
+ def->kindCount = KIND_COUNT (Kinds);
+ def->parser = findTags;
+ def->initialize = initialize;
+
+ return def;
+}
diff --git a/lregex.c b/lregex.c
index 59f5df6..37d7ea0 100644
--- a/lregex.c
+++ b/lregex.c
@@ -1,5 +1,5 @@
/*
-* $Id: lregex.c 576 2007-06-30 04:16:23Z elliotth $
+* $Id: lregex.c 747 2009-11-06 02:33:37Z dhiebert $
*
* Copyright (c) 2000-2003, Darren Hiebert
*
@@ -408,7 +408,7 @@ static void processLanguageRegex (const langType language,
const char* regexfile = parameter + 1;
FILE* const fp = fopen (regexfile, "r");
if (fp == NULL)
- error (WARNING | PERROR, regexfile);
+ error (WARNING | PERROR, "%s", regexfile);
else
{
vString* const regex = vStringNew ();
diff --git a/make.c b/make.c
index f468b5a..7b56830 100644
--- a/make.c
+++ b/make.c
@@ -1,5 +1,5 @@
/*
-* $Id: make.c 681 2008-10-12 22:43:00Z dhiebert $
+* $Id: make.c 751 2010-02-27 17:41:57Z elliotth $
*
* Copyright (c) 2000-2005, Darren Hiebert
*
@@ -100,7 +100,7 @@ static void skipToMatch (const char *const pair)
++matchLevel;
else if (c == end)
--matchLevel;
- else if (c == '\n')
+ else if (c == '\n' || c == EOF)
break;
}
if (c == EOF)
diff --git a/options.c b/options.c
index d26627f..1bee61d 100644
--- a/options.c
+++ b/options.c
@@ -119,6 +119,7 @@ optionValues Option = {
FALSE, /* -fields=n */
TRUE, /* -fields=s */
FALSE, /* -fields=S */
+ FALSE, /* -fields=T */
TRUE /* -fields=t */
},
NULL, /* -I */
@@ -208,7 +209,7 @@ static optionDescription LongOptionDescription [] = {
{1," --extra=[+|-]flags"},
{1," Include extra tag entries for selected information (flags: \"fq\")."},
{1," --fields=[+|-]flags"},
- {1," Include selected extension fields (flags: \"afmikKlnsStz\") [fks]."},
+ {1," Include selected extension fields (flags: \"afmikKlnsStTz\") [fks]."},
{1," --file-scope=[yes|no]"},
{1," Should tags scoped only for a single file (e.g. \"static\" tags"},
{1," be included in the output [yes]?"},
@@ -291,7 +292,7 @@ static const char* const License2 =
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
-"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n";
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n";
/* Contains a set of strings describing the set of "features" compiled into
* the code.
@@ -859,6 +860,7 @@ static void processFieldsOption (
case 'S': field->signature = mode; break;
case 'z': field->kindKey = mode; break;
case 't': field->typeRef = mode; break;
+ case 'T': field->returnType = mode; break;
default: error(WARNING, "Unsupported parameter '%c' for \"%s\" option",
c, option);
diff --git a/options.h b/options.h
index 34150e7..28b276f 100644
--- a/options.h
+++ b/options.h
@@ -77,6 +77,7 @@ struct sExtFields { /* extension field content control */
boolean lineNumber;
boolean scope;
boolean signature;
+ boolean returnType;
boolean typeRef;
};
diff --git a/parsers.h b/parsers.h
index 3dcc8ae..e4a50e1 100644
--- a/parsers.h
+++ b/parsers.h
@@ -15,6 +15,7 @@
#define _PARSERS_H
/* Add the name of any new parser definition function here */
+#ifndef ENABLE_VALA
#define PARSER_LIST \
AntParser, \
AsmParser, \
@@ -57,6 +58,52 @@
VhdlParser, \
VimParser, \
YaccParser
+#else
+#define PARSER_LIST \
+ AntParser, \
+ AsmParser, \
+ AspParser, \
+ AwkParser, \
+ BasicParser, \
+ BetaParser, \
+ CParser, \
+ CppParser, \
+ CsharpParser, \
+ CobolParser, \
+ DosBatchParser, \
+ EiffelParser, \
+ ErlangParser, \
+ FlexParser, \
+ FortranParser, \
+ GenieParser, \
+ HtmlParser, \
+ JavaParser, \
+ JavaScriptParser, \
+ LispParser, \
+ LuaParser, \
+ MakefileParser, \
+ MatLabParser, \
+ OcamlParser, \
+ PascalParser, \
+ PerlParser, \
+ PhpParser, \
+ PythonParser, \
+ RexxParser, \
+ RubyParser, \
+ SchemeParser, \
+ ShParser, \
+ SlangParser, \
+ SmlParser, \
+ SqlParser, \
+ TclParser, \
+ TexParser, \
+ ValaParse, \
+ VeraParser, \
+ VerilogParser, \
+ VhdlParser, \
+ VimParser, \
+ YaccParser
+#endif
#endif /* _PARSERS_H */
diff --git a/php.c b/php.c
index 0dd60c5..90e096a 100644
--- a/php.c
+++ b/php.c
@@ -1,5 +1,5 @@
/*
-* $Id: php.c 624 2007-09-15 22:53:31Z jafl $
+* $Id: php.c 734 2009-08-20 23:33:54Z jafl $
*
* Copyright (c) 2000, Jesus Castagnetto <jmcastagnetto@zkey.com>
*
@@ -64,17 +64,17 @@ static kindOption PhpKinds [] = {
static void installPHPRegex (const langType language)
{
- addTagRegex(language, "(^|[ \t])class[ \t]+([" ALPHA "_][" ALNUM "_]*)",
- "\\2", "c,class,classes", NULL);
- addTagRegex(language, "(^|[ \t])interface[ \t]+([" ALPHA "_][" ALNUM "_]*)",
- "\\2", "i,interface,interfaces", NULL);
- addTagRegex(language, "(^|[ \t])define[ \t]*\\([ \t]*['\"]?([" ALPHA "_][" ALNUM "_]*)",
- "\\2", "d,define,constant definitions", NULL);
- addTagRegex(language, "(^|[ \t])function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)",
- "\\2", "f,function,functions", NULL);
- addTagRegex(language, "(^|[ \t])(\\$|::\\$|\\$this->)([" ALPHA "_][" ALNUM "_]*)[ \t]*=",
- "\\3", "v,variable,variables", NULL);
- addTagRegex(language, "(^|[ \t])(var|public|protected|private|static)[ \t]+\\$([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]",
+ addTagRegex(language, "^[ \t]*((final|abstract)[ \t]+)*class[ \t]+([" ALPHA "_][" ALNUM "_]*)",
+ "\\3", "c,class,classes", NULL);
+ addTagRegex(language, "^[ \t]*interface[ \t]+([" ALPHA "_][" ALNUM "_]*)",
+ "\\1", "i,interface,interfaces", NULL);
+ addTagRegex(language, "^[ \t]*define[ \t]*\\([ \t]*['\"]?([" ALPHA "_][" ALNUM "_]*)",
+ "\\1", "d,define,constant definitions", NULL);
+ addTagRegex(language, "^[ \t]*((static|public|protected|private)[ \t]+)*function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)",
+ "\\3", "f,function,functions", NULL);
+ addTagRegex(language, "^[ \t]*(\\$|::\\$|\\$this->)([" ALPHA "_][" ALNUM "_]*)[ \t]*=",
+ "\\2", "v,variable,variables", NULL);
+ addTagRegex(language, "^[ \t]*((var|public|protected|private|static)[ \t]+)+\\$([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]",
"\\3", "v,variable,variables", NULL);
/* function regex is covered by PHP regex */
diff --git a/python.c b/python.c
index 5fdf31b..a90d072 100644
--- a/python.c
+++ b/python.c
@@ -1,5 +1,5 @@
/*
-* $Id: python.c 720 2009-07-07 03:55:23Z dhiebert $
+* $Id: python.c 752 2010-02-27 17:52:46Z elliotth $
*
* Copyright (c) 2000-2003, Darren Hiebert
*
@@ -240,7 +240,7 @@ static const char *skipEverything (const char *cp)
{
for (; *cp; cp++)
{
- if (*cp == '"' || *cp == '\'')
+ if (*cp == '"' || *cp == '\'' || *cp == '#')
{
cp = skipString(cp);
if (!*cp) break;
@@ -398,7 +398,9 @@ static void parseFunction (const char *cp, vString *const def,
cp = parseIdentifier (cp, def);
arglist = parseArglist (cp);
makeFunctionTag (def, parent, is_class_parent, arglist);
- eFree (arglist);
+ if (arglist != NULL) {
+ eFree (arglist);
+ }
}
/* Get the combined name of a nested symbol. Classes are separated with ".",
diff --git a/sort.c b/sort.c
index 09ba87a..c58defc 100644
--- a/sort.c
+++ b/sort.c
@@ -1,5 +1,5 @@
/*
-* $Id: sort.c 498 2007-02-17 22:43:15Z dhiebert $
+* $Id: sort.c 747 2009-11-06 02:33:37Z dhiebert $
*
* Copyright (c) 1996-2002, Darren Hiebert
*
@@ -109,7 +109,7 @@ static void failedSort (FILE *const fp, const char* msg)
if (fp != NULL)
fclose (fp);
if (msg == NULL)
- error (FATAL | PERROR, cannotSort);
+ error (FATAL | PERROR, "%s", cannotSort);
else
error (FATAL, "%s: %s", msg, cannotSort);
}
diff --git a/sql.c b/sql.c
index efe7e5d..6c0c76a 100644
--- a/sql.c
+++ b/sql.c
@@ -1,5 +1,5 @@
/*
- * $Id: sql.c 703 2009-03-14 22:06:12Z dfishburn $
+ * $Id: sql.c 745 2009-10-27 02:42:55Z dfishburn $
*
* Copyright (c) 2002-2003, Darren Hiebert
*
@@ -65,9 +65,14 @@ typedef enum eKeywordId {
KEYWORD_end,
KEYWORD_function,
KEYWORD_if,
+ KEYWORD_else,
+ KEYWORD_elseif,
+ KEYWORD_endif,
KEYWORD_loop,
+ KEYWORD_while,
KEYWORD_case,
KEYWORD_for,
+ KEYWORD_do,
KEYWORD_call,
KEYWORD_package,
KEYWORD_pragma,
@@ -114,6 +119,7 @@ typedef enum eKeywordId {
KEYWORD_ml_conn_dnet,
KEYWORD_ml_conn_java,
KEYWORD_ml_conn_chk,
+ KEYWORD_ml_prop,
KEYWORD_local,
KEYWORD_temporary,
KEYWORD_drop,
@@ -140,6 +146,7 @@ typedef enum eTokenType {
TOKEN_BLOCK_LABEL_END,
TOKEN_CHARACTER,
TOKEN_CLOSE_PAREN,
+ TOKEN_COLON,
TOKEN_SEMICOLON,
TOKEN_COMMA,
TOKEN_IDENTIFIER,
@@ -154,7 +161,8 @@ typedef enum eTokenType {
TOKEN_OPEN_SQUARE,
TOKEN_CLOSE_SQUARE,
TOKEN_TILDE,
- TOKEN_FORWARD_SLASH
+ TOKEN_FORWARD_SLASH,
+ TOKEN_EQUAL
} tokenType;
typedef struct sTokenInfoSQL {
@@ -198,6 +206,7 @@ typedef enum {
SQLTAG_SYNONYM,
SQLTAG_MLTABLE,
SQLTAG_MLCONN,
+ SQLTAG_MLPROP,
SQLTAG_COUNT
} sqlKind;
@@ -223,7 +232,8 @@ static kindOption SqlKinds [] = {
{ TRUE, 'V', "view", "views" },
{ TRUE, 'n', "synonym", "synonyms" },
{ TRUE, 'x', "mltable", "MobiLink Table Scripts" },
- { TRUE, 'y', "mlconn", "MobiLink Conn Scripts" }
+ { TRUE, 'y', "mlconn", "MobiLink Conn Scripts" },
+ { TRUE, 'z', "mlprop", "MobiLink Properties " }
};
static const keywordDesc SqlKeywordTable [] = {
@@ -237,9 +247,14 @@ static const keywordDesc SqlKeywordTable [] = {
{ "end", KEYWORD_end },
{ "function", KEYWORD_function },
{ "if", KEYWORD_if },
+ { "else", KEYWORD_else },
+ { "elseif", KEYWORD_elseif },
+ { "endif", KEYWORD_endif },
{ "loop", KEYWORD_loop },
+ { "while", KEYWORD_while },
{ "case", KEYWORD_case },
{ "for", KEYWORD_for },
+ { "do", KEYWORD_do },
{ "call", KEYWORD_call },
{ "package", KEYWORD_package },
{ "pragma", KEYWORD_pragma },
@@ -286,6 +301,7 @@ static const keywordDesc SqlKeywordTable [] = {
{ "ml_add_dnet_connection_script", KEYWORD_ml_conn_dnet },
{ "ml_add_java_connection_script", KEYWORD_ml_conn_java },
{ "ml_add_lang_conn_script_chk", KEYWORD_ml_conn_chk },
+ { "ml_add_property", KEYWORD_ml_prop },
{ "local", KEYWORD_local },
{ "temporary", KEYWORD_temporary },
{ "drop", KEYWORD_drop },
@@ -303,6 +319,7 @@ static const keywordDesc SqlKeywordTable [] = {
/* Recursive calls */
static void parseBlock (tokenInfo *const token, const boolean local);
+static void parseDeclare (tokenInfo *const token, const boolean local);
static void parseKeywords (tokenInfo *const token);
static void parseSqlFile (tokenInfo *const token);
@@ -541,6 +558,7 @@ getNextChar:
case EOF: longjmp (Exception, (int)ExceptionEOF); break;
case '(': token->type = TOKEN_OPEN_PAREN; break;
case ')': token->type = TOKEN_CLOSE_PAREN; break;
+ case ':': token->type = TOKEN_COLON; break;
case ';': token->type = TOKEN_SEMICOLON; break;
case '.': token->type = TOKEN_PERIOD; break;
case ',': token->type = TOKEN_COMMA; break;
@@ -549,6 +567,7 @@ getNextChar:
case '~': token->type = TOKEN_TILDE; break;
case '[': token->type = TOKEN_OPEN_SQUARE; break;
case ']': token->type = TOKEN_CLOSE_SQUARE; break;
+ case '=': token->type = TOKEN_EQUAL; break;
case '\'':
case '"':
@@ -770,7 +789,7 @@ static void skipArgumentList (tokenInfo *const token)
* Other databases can have arguments with fully declared
* datatypes:
* ( name varchar(30), text binary(10) )
- * So we must check for nested open and closing parantheses
+ * So we must check for nested open and closing parentheses
*/
if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */
@@ -848,7 +867,7 @@ static void parseSubProgram (tokenInfo *const token)
/*
* Read token after which could be the
* command terminator if a prototype
- * or an open parantheses
+ * or an open parenthesis
*/
readToken (token);
if (isType (token, TOKEN_OPEN_PAREN))
@@ -870,6 +889,7 @@ static void parseSubProgram (tokenInfo *const token)
isKeyword (token, KEYWORD_internal) ||
isKeyword (token, KEYWORD_external) ||
isKeyword (token, KEYWORD_url) ||
+ isType (token, TOKEN_EQUAL) ||
isCmdTerm (token)
)
)
@@ -900,6 +920,12 @@ static void parseSubProgram (tokenInfo *const token)
vStringClear (token->scope);
}
+ if ( isType (token, TOKEN_EQUAL) )
+ readToken (token);
+
+ if ( isKeyword (token, KEYWORD_declare) )
+ parseDeclare (token, FALSE);
+
if (isKeyword (token, KEYWORD_is) ||
isKeyword (token, KEYWORD_begin) )
{
@@ -1066,18 +1092,18 @@ static void parseDeclare (tokenInfo *const token, const boolean local)
case KEYWORD_type: parseType (token); break;
default:
- if (isType (token, TOKEN_IDENTIFIER))
- {
- if (local)
- {
- makeSqlTag (token, SQLTAG_LOCAL_VARIABLE);
- }
- else
- {
- makeSqlTag (token, SQLTAG_VARIABLE);
- }
- }
- break;
+ if (isType (token, TOKEN_IDENTIFIER))
+ {
+ if (local)
+ {
+ makeSqlTag (token, SQLTAG_LOCAL_VARIABLE);
+ }
+ else
+ {
+ makeSqlTag (token, SQLTAG_VARIABLE);
+ }
+ }
+ break;
}
findToken (token, TOKEN_SEMICOLON);
readToken (token);
@@ -1164,12 +1190,13 @@ static void parseLabel (tokenInfo *const token)
}
}
-static void parseStatements (tokenInfo *const token)
+static void parseStatements (tokenInfo *const token, const boolean exit_on_endif )
{
boolean isAnsi = TRUE;
boolean stmtTerm = FALSE;
do
{
+
if (isType (token, TOKEN_BLOCK_LABEL_BEGIN))
parseLabel (token);
else
@@ -1210,6 +1237,7 @@ static void parseStatements (tokenInfo *const token)
*/
while (! isKeyword (token, KEYWORD_then))
readToken (token);
+
readToken (token);
continue;
@@ -1220,6 +1248,15 @@ static void parseStatements (tokenInfo *const token)
* IF...THEN
* END IF;
*
+ * IF...THEN
+ * ELSE
+ * END IF;
+ *
+ * IF...THEN
+ * ELSEIF...THEN
+ * ELSE
+ * END IF;
+ *
* or non-ANSI
* IF ...
* BEGIN
@@ -1248,7 +1285,22 @@ static void parseStatements (tokenInfo *const token)
else
{
readToken (token);
- parseStatements (token);
+
+ while( ! (isKeyword (token, KEYWORD_end ) ||
+ isKeyword (token, KEYWORD_endif ) )
+ )
+ {
+ if ( isKeyword (token, KEYWORD_else) ||
+ isKeyword (token, KEYWORD_elseif) )
+ readToken (token);
+
+ parseStatements (token, TRUE);
+
+ if ( isCmdTerm(token) )
+ readToken (token);
+
+ }
+
/*
* parseStatements returns when it finds an END, an IF
* should follow the END for ANSI anyway.
@@ -1258,7 +1310,13 @@ static void parseStatements (tokenInfo *const token)
if( isKeyword (token, KEYWORD_end ) )
readToken (token);
- if( ! isKeyword (token, KEYWORD_if ) )
+ if( isKeyword (token, KEYWORD_if ) || isKeyword (token, KEYWORD_endif ) )
+ {
+ readToken (token);
+ if ( isCmdTerm(token) )
+ stmtTerm = TRUE;
+ }
+ else
{
/*
* Well we need to do something here.
@@ -1284,14 +1342,64 @@ static void parseStatements (tokenInfo *const token)
* END CASE;
*
* FOR loop_name AS cursor_name CURSOR FOR ...
+ * DO
* END FOR;
*/
+ if( isKeyword (token, KEYWORD_for ) )
+ {
+ /* loop name */
+ readToken (token);
+ /* AS */
+ readToken (token);
+
+ while ( ! isKeyword (token, KEYWORD_is) )
+ {
+ /*
+ * If this is not an AS keyword this is
+ * not a proper FOR statement and should
+ * simply be ignored
+ */
+ return;
+ }
+
+ while ( ! isKeyword (token, KEYWORD_do) )
+ readToken (token);
+ }
+
+
readToken (token);
- parseStatements (token);
+ while( ! isKeyword (token, KEYWORD_end ) )
+ {
+ /*
+ if ( isKeyword (token, KEYWORD_else) ||
+ isKeyword (token, KEYWORD_elseif) )
+ readToken (token);
+ */
+
+ parseStatements (token, FALSE);
+
+ if ( isCmdTerm(token) )
+ readToken (token);
+ }
+
if( isKeyword (token, KEYWORD_end ) )
readToken (token);
+ /*
+ * Typically ended with
+ * END LOOP [loop name];
+ * END CASE
+ * END FOR [loop name];
+ */
+ if ( isKeyword (token, KEYWORD_loop) ||
+ isKeyword (token, KEYWORD_case) ||
+ isKeyword (token, KEYWORD_for) )
+ readToken (token);
+
+ if ( isCmdTerm(token) )
+ stmtTerm = TRUE;
+
break;
case KEYWORD_create:
@@ -1324,11 +1432,36 @@ static void parseStatements (tokenInfo *const token)
*
* So we must read to the first semi-colon or an END block
*/
- while ( ! stmtTerm &&
- ! ( isKeyword (token, KEYWORD_end) ||
- (isCmdTerm(token)) )
+ while ( ! stmtTerm &&
+ ! ( isKeyword (token, KEYWORD_end) ||
+ (isCmdTerm(token)) )
)
{
+ if ( isKeyword (token, KEYWORD_endif) &&
+ exit_on_endif )
+ return;
+
+ if (isType (token, TOKEN_COLON) )
+ {
+ /*
+ * A : can signal a loop name
+ * myloop:
+ * LOOP
+ * LEAVE myloop;
+ * END LOOP;
+ * Unfortunately, labels do not have a
+ * cmd terminator, therefore we have to check
+ * if the next token is a keyword and process
+ * it accordingly.
+ */
+ readToken (token);
+ if ( isKeyword (token, KEYWORD_loop) ||
+ isKeyword (token, KEYWORD_while) ||
+ isKeyword (token, KEYWORD_for) )
+ /* parseStatements (token); */
+ return;
+ }
+
readToken (token);
if (isType (token, TOKEN_OPEN_PAREN) ||
@@ -1336,6 +1469,20 @@ static void parseStatements (tokenInfo *const token)
isType (token, TOKEN_OPEN_SQUARE) )
skipToMatched (token);
+ /*
+ * Since we know how to parse various statements
+ * if we detect them, parse them to completion
+ */
+ if (isType (token, TOKEN_BLOCK_LABEL_BEGIN) ||
+ isKeyword (token, KEYWORD_exception) ||
+ isKeyword (token, KEYWORD_loop) ||
+ isKeyword (token, KEYWORD_case) ||
+ isKeyword (token, KEYWORD_for) ||
+ isKeyword (token, KEYWORD_begin) )
+ parseStatements (token, FALSE);
+ else if (isKeyword (token, KEYWORD_if))
+ parseStatements (token, TRUE);
+
}
}
/*
@@ -1343,11 +1490,12 @@ static void parseStatements (tokenInfo *const token)
* See comment above, now, only read if the current token
* is not a command terminator.
*/
- if ( isCmdTerm(token) )
- {
- readToken (token);
- }
- } while (! isKeyword (token, KEYWORD_end) && ! stmtTerm );
+ if ( isCmdTerm(token) && ! stmtTerm )
+ stmtTerm = TRUE;
+
+ } while (! isKeyword (token, KEYWORD_end) &&
+ ! (exit_on_endif && isKeyword (token, KEYWORD_endif) ) &&
+ ! stmtTerm );
}
static void parseBlock (tokenInfo *const token, const boolean local)
@@ -1378,7 +1526,10 @@ static void parseBlock (tokenInfo *const token, const boolean local)
token->begin_end_nest_lvl++;
while (! isKeyword (token, KEYWORD_end))
{
- parseStatements (token);
+ parseStatements (token, FALSE);
+
+ if ( isCmdTerm(token) )
+ readToken (token);
}
token->begin_end_nest_lvl--;
@@ -1994,6 +2145,70 @@ static void parseMLConn (tokenInfo *const token)
deleteToken (event);
}
+static void parseMLProp (tokenInfo *const token)
+{
+ tokenInfo *const component = newToken ();
+ tokenInfo *const prop_set_name = newToken ();
+ tokenInfo *const prop_name = newToken ();
+
+ /*
+ * This deals with these formats
+ * ml_add_property (
+ * 'comp_name',
+ * 'prop_set_name',
+ * 'prop_name',
+ * 'prop_value'
+ * )
+ */
+
+ readToken (token);
+ if ( isType (token, TOKEN_OPEN_PAREN) )
+ {
+ readToken (component);
+ readToken (token);
+ while (!(isType (token, TOKEN_COMMA) ||
+ isType (token, TOKEN_CLOSE_PAREN)
+ ))
+ {
+ readToken (token);
+ }
+
+ if (isType (token, TOKEN_COMMA))
+ {
+ readToken (prop_set_name);
+ readToken (token);
+ while (!(isType (token, TOKEN_COMMA) ||
+ isType (token, TOKEN_CLOSE_PAREN)
+ ))
+ {
+ readToken (token);
+ }
+
+ if (isType (token, TOKEN_COMMA))
+ {
+ readToken (prop_name);
+
+ if (isType (component, TOKEN_STRING) &&
+ isType (prop_set_name, TOKEN_STRING) &&
+ isType (prop_name, TOKEN_STRING) )
+ {
+ addToScope(component, prop_set_name->string);
+ addToScope(component, prop_name->string);
+ makeSqlTag (component, SQLTAG_MLPROP);
+ }
+ }
+ if( !isType (token, TOKEN_CLOSE_PAREN) )
+ findToken (token, TOKEN_CLOSE_PAREN);
+ }
+ }
+
+ findCmdTerm (token, TRUE);
+
+ deleteToken (component);
+ deleteToken (prop_set_name);
+ deleteToken (prop_name);
+}
+
static void parseComment (tokenInfo *const token)
{
/*
@@ -2039,7 +2254,7 @@ static void parseKeywords (tokenInfo *const token)
case KEYWORD_drop: parseDrop (token); break;
case KEYWORD_event: parseEvent (token); break;
case KEYWORD_function: parseSubProgram (token); break;
- case KEYWORD_if: parseStatements (token); break;
+ case KEYWORD_if: parseStatements (token, FALSE); break;
case KEYWORD_index: parseIndex (token); break;
case KEYWORD_ml_table: parseMLTable (token); break;
case KEYWORD_ml_table_lang: parseMLTable (token); break;
@@ -2051,6 +2266,7 @@ static void parseKeywords (tokenInfo *const token)
case KEYWORD_ml_conn_dnet: parseMLConn (token); break;
case KEYWORD_ml_conn_java: parseMLConn (token); break;
case KEYWORD_ml_conn_chk: parseMLConn (token); break;
+ case KEYWORD_ml_prop: parseMLProp (token); break;
case KEYWORD_package: parsePackage (token); break;
case KEYWORD_procedure: parseSubProgram (token); break;
case KEYWORD_publication: parsePublication (token); break;
diff --git a/test-cmd-line b/test-cmd-line
new file mode 100644
index 0000000..980f6b9
--- /dev/null
+++ b/test-cmd-line
@@ -0,0 +1 @@
+./anjuta_tags --sort=no --fields=afmiKlnsStTz --c++-kinds=+p foo.cpp ; cat tags
diff --git a/tex.c b/tex.c
index a285797..0c6714e 100644
--- a/tex.c
+++ b/tex.c
@@ -53,7 +53,8 @@ typedef enum eKeywordId {
KEYWORD_subsubsection,
KEYWORD_part,
KEYWORD_paragraph,
- KEYWORD_subparagraph
+ KEYWORD_subparagraph,
+ KEYWORD_include
} keywordId;
/* Used to determine whether keyword is valid for the token language and
@@ -68,27 +69,15 @@ typedef enum eTokenType {
TOKEN_UNDEFINED,
TOKEN_CHARACTER,
TOKEN_CLOSE_PAREN,
- TOKEN_SEMICOLON,
- TOKEN_COLON,
TOKEN_COMMA,
TOKEN_KEYWORD,
TOKEN_OPEN_PAREN,
- TOKEN_OPERATOR,
TOKEN_IDENTIFIER,
TOKEN_STRING,
- TOKEN_PERIOD,
TOKEN_OPEN_CURLY,
TOKEN_CLOSE_CURLY,
- TOKEN_EQUAL_SIGN,
- TOKEN_EXCLAMATION,
- TOKEN_FORWARD_SLASH,
TOKEN_OPEN_SQUARE,
TOKEN_CLOSE_SQUARE,
- TOKEN_OPEN_MXML,
- TOKEN_CLOSE_MXML,
- TOKEN_CLOSE_SGML,
- TOKEN_LESS_THAN,
- TOKEN_GREATER_THAN,
TOKEN_QUESTION_MARK,
TOKEN_STAR
} tokenType;
@@ -118,6 +107,7 @@ typedef enum {
TEXTAG_PART,
TEXTAG_PARAGRAPH,
TEXTAG_SUBPARAGRAPH,
+ TEXTAG_INCLUDE,
TEXTAG_COUNT
} texKind;
@@ -128,7 +118,8 @@ static kindOption TexKinds [] = {
{ TRUE, 'b', "subsubsection", "subsubsections" },
{ TRUE, 'p', "part", "parts" },
{ TRUE, 'P', "paragraph", "paragraphs" },
- { TRUE, 'G', "subparagraph", "subparagraphs" }
+ { TRUE, 'G', "subparagraph", "subparagraphs" },
+ { TRUE, 'i', "include", "includes" }
};
static const keywordDesc TexKeywordTable [] = {
@@ -139,7 +130,8 @@ static const keywordDesc TexKeywordTable [] = {
{ "subsubsection", KEYWORD_subsubsection },
{ "part", KEYWORD_part },
{ "paragraph", KEYWORD_paragraph },
- { "subparagraph", KEYWORD_subparagraph }
+ { "subparagraph", KEYWORD_subparagraph },
+ { "include", KEYWORD_include }
};
/*
@@ -150,7 +142,7 @@ static boolean isIdentChar (const int c)
{
return (boolean)
(isalpha (c) || isdigit (c) || c == '$' ||
- c == '_' || c == '#');
+ c == '_' || c == '#' || c == '-' || c == '.');
}
static void buildTexKeywordHash (void)
@@ -297,16 +289,11 @@ getNextChar:
case EOF: longjmp (Exception, (int)ExceptionEOF); break;
case '(': token->type = TOKEN_OPEN_PAREN; break;
case ')': token->type = TOKEN_CLOSE_PAREN; break;
- case ';': token->type = TOKEN_SEMICOLON; break;
case ',': token->type = TOKEN_COMMA; break;
- case '.': token->type = TOKEN_PERIOD; break;
- case ':': token->type = TOKEN_COLON; break;
case '{': token->type = TOKEN_OPEN_CURLY; break;
case '}': token->type = TOKEN_CLOSE_CURLY; break;
- case '=': token->type = TOKEN_EQUAL_SIGN; break;
case '[': token->type = TOKEN_OPEN_SQUARE; break;
case ']': token->type = TOKEN_CLOSE_SQUARE; break;
- case '?': token->type = TOKEN_QUESTION_MARK; break;
case '*': token->type = TOKEN_STAR; break;
case '\'':
@@ -427,7 +414,8 @@ static boolean parseTag (tokenInfo *const token, texKind kind)
readToken (token);
while (! isType (token, TOKEN_CLOSE_CURLY) )
{
- if (isType (token, TOKEN_IDENTIFIER) && useLongName)
+ /* if (isType (token, TOKEN_IDENTIFIER) && useLongName) */
+ if (useLongName)
{
if (fullname->length > 0)
vStringCatS (fullname, " ");
@@ -479,6 +467,9 @@ static void parseTexFile (tokenInfo *const token)
case KEYWORD_subparagraph:
parseTag (token, TEXTAG_SUBPARAGRAPH);
break;
+ case KEYWORD_include:
+ parseTag (token, TEXTAG_INCLUDE);
+ break;
default:
break;
}
diff --git a/vala.c b/vala.c
new file mode 100644
index 0000000..555ffc5
--- /dev/null
+++ b/vala.c
@@ -0,0 +1,103 @@
+/*
+ * vala.c
+ *
+ * Copyright 2008 Abderrahim Kitouni <a.kitouni@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * INCLUDE FILES
+ */
+#include "general.h" /* must always come first */
+#include "parse.h"
+#include "read.h"
+
+#include "entry.h"
+#include "ctags-vala.h"
+
+CTagsVisitor *visitor;
+/* using different data structure because fpos_t isn't available in Vala*/
+static void make_ctags_entry (CTagsEntry* entry) {
+ tagEntryInfo tag;
+ initTagEntry(&tag, entry->name);
+
+ tag.lineNumberEntry = TRUE;
+ tag.lineNumber = entry->line_number;
+ tag.kindName = entry->kind_name;
+ tag.kind = entry->kind;
+ /* FIXME: add filePosition */
+ tag.extensionFields.access = entry->access;
+ tag.extensionFields.implementation = entry->implementation;
+ tag.extensionFields.inheritance = entry->inheritance;
+ tag.extensionFields.scope[0] = entry->scope[0];
+ tag.extensionFields.scope[1] = entry->scope[1];
+ tag.extensionFields.typeRef[0] = entry->typeref;
+ tag.extensionFields.returnType = entry->returntype;
+ tag.extensionFields.signature = entry->signature;
+ makeTagEntry(&tag);
+}
+
+static kindOption ValaKinds [] = {
+ { TRUE, 'c', "class", "Classes" },
+ { TRUE, 's', "struct", "Structures" },
+ { TRUE, 'i', "interface", "Interfaces" },
+ { TRUE, 'e', "enum", "Enumerations" },
+ { TRUE, 'v', "enumvalue", "Enumeration Values" },
+ { TRUE, 'E', "errordomain", "Error domains" },
+ { TRUE, 'r', "errorcode", "Error codes" },
+ { TRUE, 'd', "delegate", "Delegates" },
+ { TRUE, 'S', "signal", "Signals" },
+ { TRUE, 'f', "field", "Fields" },
+ { TRUE, 'p', "property", "Properties" },
+ { TRUE, 'm', "method", "Methods" },
+ { FALSE, 'l', "local", "Local variables" },
+};
+
+static void findValaTags (void) {
+ if (visitor == NULL) {
+ visitor = ctags_visitor_new();
+ }
+ ctags_visitor_parse_vala (visitor, getSourceFileName(), (CTagsEntryMaker) make_ctags_entry);
+}
+
+extern parserDefinition *ValaParse(void) {
+ g_type_init();
+ static const char *const extensions [] = { "vala", "vapi", NULL };
+ parserDefinition* def = parserNew ("Vala");
+ def->kinds = ValaKinds;
+ def->kindCount = KIND_COUNT (ValaKinds);
+ def->extensions = extensions;
+ def->parser = findValaTags;
+ return def;
+}
+
+static void findGenieTags (void) {
+ if (visitor == NULL) {
+ visitor = ctags_visitor_new();
+ }
+ ctags_visitor_parse_genie (visitor, getSourceFileName(), (CTagsEntryMaker) make_ctags_entry);
+}
+
+extern parserDefinition *GenieParser(void) {
+ static const char *const extensions [] = { "gs", NULL };
+ parserDefinition* def = parserNew ("Genie");
+ def->kinds = ValaKinds;
+ def->kindCount = KIND_COUNT (ValaKinds);
+ def->extensions = extensions;
+ def->parser = findGenieTags;
+ return def;
+}
diff --git a/verilog.c b/verilog.c
index 814f5b0..52afc31 100644
--- a/verilog.c
+++ b/verilog.c
@@ -1,5 +1,5 @@
/*
-* $Id: verilog.c 573 2007-06-26 05:41:27Z elliotth $
+* $Id: verilog.c 753 2010-02-27 17:53:32Z elliotth $
*
* Copyright (c) 2003, Darren Hiebert
*
@@ -232,6 +232,7 @@ static void tagNameList (const verilogKind kind, int c)
c = skipWhite (c);
if (c == '=')
{
+ c = skipWhite (vGetc ());
if (c == '{')
skipPastMatch ("{}");
else
--
2.11.0