Sync ctags with upstream so that most parsers can be copied from uctags (#2018)

* Use latest version of htable

* Use latest version of mio

* Use latest version of objpool

* Use latest version of ptrarray

* Use latest version of vstring

This also requires adding trashbox.c/h which is now used by vstring and
inline macros from inline.h.

* Rename fieldSpec to fieldDefinition

See b56bd065123d69087acd6f202499d71a86a7ea7a upstream.

* Rename kindOption to kindDefinition

See e112e8ab6e0933b5bd7922e0dfb969b1f28c60fa upstream

* Rename kinds field in parserDefinition to kindTable

See 09ae690face8b5cde940e2d7cf40f8860381067b upstream.

* Rename structure fields about field in parserDefinition

See a739fa5fb790bc349a66b2bee0bf42cf289994e8 upstream.

* Use kindIndex instead of kindDefinition

This patch replaces kindDefinition related entries from sTagEntryInfo
with kindIndex so kinds are referenced indirectly using the index. For
more info please refer to commits:

16a2541c0698bd8ee03c1be8172ef3191f6e695a
f92e6bf2aeb21fd6b04756487f98d0eefa16d9ce

Some other changes had to be made to make the sources compile (without
bringing all the diffs from upstream). At some places, which aren't used
by Geany, only stub implementations have been created.

In particular, the regex parser has been disabled (for now?) because its
current implementation doesn't allow accessing kindDefinitions using
index and allowing this would require big changes in its implementation.
The affected parsers are Cobol, ActionScript and HTML. For HTML we can
use the token-based parser from upstream, and we should consider
whether Cobol and ActionScript are worth the effort to maintain a separate
regex implementation using GRegex (IMO these languages are dead enough
not to justify the extra effort).

The patch also disables tests for languages using regex parsers.

* Rename roleDesc to roleDefinition

See 1345725842c196cc0523ff60231192bcd588961b upstream. Since we don't care
about roles in Geany, we don't have to do the additional stuff the upstream
patch does.

* Add XTAG_ANONYMOUS used by jscript

See 0e4c5d4a0461bc8d9616fe3b97d75b91d014246e upstream.

* Include stdint.h in entry.h

* Don't use hash value as an Anonymous field identifier

Instead of something like "Anonymous0ab283cd9402" use sequential integer
values like "Anonymous1".

* Call anonReset in main part

See 3c91b1ea509df238feb86c9cbd552b621e462653 upstream.

* Use upstream javascript parser

* Use upstream css parser

* Create correctly sized MIO for 0 size

See https://github.com/universal-ctags/ctags/pull/1951

* Always enable promise API and subparsers for Geany

* Support subparsers in Geany and add HTML parser demonstrating this feature

This feature requires several changes:

1. Propagating language of the tag from ctags to Geany so we know whether
the tag comes from a master parser or a subparser.

2. We need to address the problem that tag types from a subparsers can
clash with tag types from master parsers or other subparsers used by the
master parser. For instance, HTML and both its css and javascript
subparsers use tm_tag_class_t but HTML uses it for <h2> headings, and
css and javascript for classes. Representing all of them using
tm_tag_class_t would lead to complete mess where all of these types would
for instance be listed in the same branch of the tree in the sidebar.

To avoid this problem, this patch adds another mapping for subparsers where
each tag type can be mapped to another tag type (which isn't used neither
by master parser or other subparsers). To avoid unwanted clashes with other
parsers, only tags explicitly mentioned in such mappings are added to tag
manager; other subparser tags are discarded.

For HTML this patch introduces mapping only for tm_tag_function_t (which
in this case maps to the same type) to mimick the previous HTML parser
behavior but other javascript and css tag types can be added this way
in the future too.

3. Since in most of the code Geany and tag manager assume that tags from
one file use the same language, subparser's tags are modified to have the
same language like the master parser.

4. HTML parser itself was copied from upstream without any modifications.
Tests were fixed as the parser now correctly ignores comments.

* Rename truncateLine field of tagEntryInfo

See 0e70b22791877322598f03ecbe3eb26a6b661001 upstream. Needed for Fortran
parser.

* Add dummy mbcs.h and trace.h

Included by javascript parser.

* Introduce an accessor to `locate' field of `Option'

See fb5ef68859f71ff2949f1d9a7cab7515f523532f upstream. Needed for Fortran.

* Add numarray.c/h

Needed by various parsers.

* Add getLanguageForFilename() and getLanguageForCommand()

See

416c5e6b8807feaec318d7f8addbb4107370c187
334e072f9d6d9954ebd3eb89bbceb252c20ae9dd

upstream. Needed for Sh parser.

* txt2tags: Fix scope separator definition and re-enable tests

* Rename rest.c to rst.c to match upstream filename

* Use upstream asciidoc and rst parsers

* Add asciidoc and rst unit tests

* Rename conf.c to iniconf.c to match upstream filename

* Add tests of conf, diff, md parsers from universal ctags

* Add more ctags unit tests

This patch adds unit tests for: nsis, docbook, haskell, haxe, abaqus, vala,
abc.

The only missing unit tests are for GLSL and Ferite parsers which
however share the implementation with the C parser and should be
reasonably well covered by other C-like language tests.

The tests were put together from various tutorials and help of the
languages in order to cover the tags these parsers generate. No guarantee
they'd compile with real parsers.

* Rename latex.c to tex.c to match upstream filename

* Rename entry points of parsers to match upstream names

* Initialize trashbox

* Add newline to the end of file
This commit is contained in:
Jiří Techet 2019-04-06 04:14:30 +02:00 committed by elextr
parent b8cdfddf98
commit a1cf475fcf
119 changed files with 4789 additions and 1180 deletions

View File

@ -17,7 +17,7 @@ parsers = \
parsers/basic.c \
parsers/c.c \
parsers/cobol.c \
parsers/conf.c \
parsers/iniconf.c \
parsers/css.c \
parsers/diff.c \
parsers/docbook.c \
@ -29,7 +29,6 @@ parsers = \
parsers/html.c \
parsers/jscript.c \
parsers/json.c \
parsers/latex.c \
parsers/lua.c \
parsers/make.c \
parsers/markdown.c \
@ -42,12 +41,13 @@ parsers = \
parsers/powershell.c \
parsers/python.c \
parsers/r.c \
parsers/rest.c \
parsers/rst.c \
parsers/ruby.c \
parsers/rust.c \
parsers/sh.c \
parsers/sql.c \
parsers/tcl.c \
parsers/tex.c \
parsers/txt2tags.c \
parsers/verilog.c \
parsers/vhdl.c
@ -77,6 +77,7 @@ libctags_la_SOURCES = \
main/general.h \
main/htable.c \
main/htable.h \
main/inline.h \
main/keyword.c \
main/keyword.h \
main/kind.c \
@ -88,10 +89,13 @@ libctags_la_SOURCES = \
main/lxpath.c \
main/main.c \
main/main.h \
main/mbcs.h \
main/mio.c \
main/mio.h \
main/nestlevel.c \
main/nestlevel.h \
main/numarray.c \
main/numarray.h \
main/objpool.c \
main/objpool.h \
main/options.c \
@ -121,6 +125,9 @@ libctags_la_SOURCES = \
main/sort.h \
main/strlist.c \
main/strlist.h \
main/trace.h \
main/trashbox.c \
main/trashbox.h \
main/types.h \
main/vstring.c \
main/vstring.h \

View File

@ -18,6 +18,7 @@
#include "output.h"
#include "parse.h"
#include "options.h"
#include "trashbox.h"
#include <stdio.h>
#include <string.h>
@ -51,6 +52,8 @@ extern void ctagsInit(void)
initializeParsing ();
initOptions ();
initDefaultTrashBox ();
/* make sure all parsers are initialized */
initializeParser (LANG_AUTO);
}
@ -92,7 +95,7 @@ extern const char *ctagsGetLangKinds(int lang)
static char kinds[257];
for (i = 0; i < def->kindCount; i++)
kinds[i] = def->kinds[i].letter;
kinds[i] = def->kindTable[i].letter;
kinds[i] = '\0';
return kinds;
@ -106,8 +109,8 @@ extern const char *ctagsGetKindName(char kind, int lang)
for (i = 0; i < def->kindCount; i++)
{
if (def->kinds[i].letter == kind)
return def->kinds[i].name;
if (def->kindTable[i].letter == kind)
return def->kindTable[i].name;
}
return "unknown";
}
@ -120,8 +123,8 @@ extern char ctagsGetKindFromName(const char *name, int lang)
for (i = 0; i < def->kindCount; i++)
{
if (strcmp(def->kinds[i].name, name) == 0)
return def->kinds[i].letter;
if (strcmp(def->kindTable[i].name, name) == 0)
return def->kindTable[i].letter;
}
return '-';
}

View File

@ -27,6 +27,7 @@ typedef struct {
char kindLetter;
bool isFileScope;
unsigned long lineNumber;
int lang;
} ctagsTag;
/* Callback invoked for every tag found by the parser. The return value is

View File

@ -18,9 +18,9 @@
#include <string.h>
static void linkKinds (kindOption *masterKind, kindOption *slaveKind)
static void linkKinds (kindDefinition *masterKind, kindDefinition *slaveKind)
{
kindOption *tail;
kindDefinition *tail;
slaveKind->master = masterKind;
@ -39,16 +39,16 @@ static void linkKindDependency (parserDefinition *const masterParser,
parserDefinition *const slaveParser)
{
unsigned int k_slave, k_master;
kindOption *kind_slave, *kind_master;
kindDefinition *kind_slave, *kind_master;
for (k_slave = 0; k_slave < slaveParser->kindCount; k_slave++)
{
if (slaveParser->kinds [k_slave].syncWith == LANG_AUTO)
if (slaveParser->kindTable [k_slave].syncWith == LANG_AUTO)
{
kind_slave = slaveParser->kinds + k_slave;
kind_slave = slaveParser->kindTable + k_slave;
for (k_master = 0; k_master < masterParser->kindCount; k_master++)
{
kind_master = masterParser->kinds + k_master;
kind_master = masterParser->kindTable + k_master;
if ((kind_slave->letter == kind_master->letter)
&& (strcmp (kind_slave->name, kind_master->name) == 0))
{

View File

@ -188,7 +188,7 @@ extern void makeFileTag (const char *const fileName)
if (xtag != XTAG_UNKNOWN)
{
tagEntryInfo tag;
kindOption *kind;
kindDefinition *kind;
kind = getInputLanguageFileKind();
Assert (kind);
@ -196,7 +196,7 @@ extern void makeFileTag (const char *const fileName)
/* TODO: you can return here if enabled == false. */
initTagEntry (&tag, baseFilename (fileName), kind);
initTagEntry (&tag, baseFilename (fileName), KIND_FILE_INDEX);
tag.isFileEntry = true;
tag.lineNumberEntry = true;
@ -736,7 +736,8 @@ extern void truncateTagLine (
static char* getFullQualifiedScopeNameFromCorkQueue (const tagEntryInfo * inner_scope)
{
const kindOption *kind = NULL;
int kindIndex = KIND_GHOST_INDEX;
langType lang;
const tagEntryInfo *scope = inner_scope;
stringList *queue = stringListNew ();
vString *v;
@ -748,16 +749,17 @@ static char* getFullQualifiedScopeNameFromCorkQueue (const tagEntryInfo * inner_
{
if (!scope->placeholder)
{
if (kind)
if (kindIndex != KIND_GHOST_INDEX)
{
sep = scopeSeparatorFor (kind, scope->kind->letter);
sep = scopeSeparatorFor (lang, kindIndex, scope->kindIndex);
v = vStringNewInit (sep);
stringListAdd (queue, v);
}
/* TODO: scope field of SCOPE can be used for optimization. */
v = vStringNewInit (scope->name);
stringListAdd (queue, v);
kind = scope->kind;
kindIndex = scope->kindIndex;
lang = scope->langType;
}
scope = getEntryInCorkQueue (scope->extensionFields.scopeIndex);
}
@ -783,7 +785,7 @@ extern void getTagScopeInformation (tagEntryInfo *const tag,
if (name)
*name = NULL;
if (tag->extensionFields.scopeKind == NULL
if (tag->extensionFields.scopeKindIndex == KIND_GHOST_INDEX
&& tag->extensionFields.scopeName == NULL
&& tag->extensionFields.scopeIndex != CORK_NIL
&& TagFile.corkQueue.count > 0)
@ -796,15 +798,23 @@ extern void getTagScopeInformation (tagEntryInfo *const tag,
Assert (full_qualified_scope_name);
/* Make the information reusable to generate full qualified entry, and xformat output*/
tag->extensionFields.scopeKind = scope->kind;
tag->extensionFields.scopeLangType = scope->langType;
tag->extensionFields.scopeKindIndex = scope->kindIndex;
tag->extensionFields.scopeName = full_qualified_scope_name;
}
if (tag->extensionFields.scopeKind != NULL &&
if (tag->extensionFields.scopeKindIndex != KIND_GHOST_INDEX &&
tag->extensionFields.scopeName != NULL)
{
if (kind)
*kind = tag->extensionFields.scopeKind->name;
{
langType lang = (tag->extensionFields.scopeLangType == LANG_AUTO)
? tag->langType
: tag->extensionFields.scopeLangType;
kindDefinition *kdef = getLanguageKind (lang,
tag->extensionFields.scopeKindIndex);
*kind = kdef->name;
}
if (name)
*name = tag->extensionFields.scopeName;
}
@ -831,21 +841,21 @@ extern int makePatternStringCommon (const tagEntryInfo *const tag,
static vString *cached_pattern;
static MIOPos cached_location;
if (TagFile.patternCacheValid
&& (! tag->truncateLine)
&& (! tag->truncateLineAfterTag)
&& (memcmp (&tag->filePosition, &cached_location, sizeof(MIOPos)) == 0))
return puts_func (vStringValue (cached_pattern), output);
line = readLineFromBypass (TagFile.vLine, tag->filePosition, NULL);
if (line == NULL)
error (FATAL, "could not read tag line from %s at line %lu", getInputFileName (),tag->lineNumber);
if (tag->truncateLine)
if (tag->truncateLineAfterTag)
truncateTagLine (line, tag->name, false);
line_len = strlen (line);
searchChar = Option.backward ? '?' : '/';
terminator = (bool) (line [line_len - 1] == '\n') ? "$": "";
if (!tag->truncateLine)
if (!tag->truncateLineAfterTag)
{
making_cache = true;
cached_pattern = vStringNewOrClear (cached_pattern);
@ -960,8 +970,6 @@ static void recordTagEntryInQueue (const tagEntryInfo *const tag, tagEntryInfo*
slot->extensionFields.xpath = eStrdup (slot->extensionFields.xpath);
#endif
if (slot->sourceLanguage)
slot->sourceLanguage = eStrdup (slot->sourceLanguage);
if (slot->sourceFileName)
slot->sourceFileName = eStrdup (slot->sourceFileName);
@ -999,8 +1007,6 @@ static void clearTagEntryInQueue (tagEntryInfo* slot)
eFree ((char *)slot->extensionFields.implementation);
if (slot->extensionFields.inheritance)
eFree ((char *)slot->extensionFields.inheritance);
if (slot->extensionFields.scopeKind)
slot->extensionFields.scopeKind = NULL;
if (slot->extensionFields.scopeName)
eFree ((char *)slot->extensionFields.scopeName);
if (slot->extensionFields.signature)
@ -1018,8 +1024,6 @@ static void clearTagEntryInQueue (tagEntryInfo* slot)
eFree ((char *)slot->extensionFields.xpath);
#endif
if (slot->sourceLanguage)
eFree ((char *)slot->sourceLanguage);
if (slot->sourceFileName)
eFree ((char *)slot->sourceFileName);
@ -1098,9 +1102,10 @@ static void initCtagsTag(ctagsTag *tag, const tagEntryInfo *info)
tag->varType = info->extensionFields.varType;
tag->access = info->extensionFields.access;
tag->implementation = info->extensionFields.implementation;
tag->kindLetter = info->kind->letter;
tag->kindLetter = getLanguageKind(info->langType, info->kindIndex)->letter;
tag->isFileScope = info->isFileScope;
tag->lineNumber = info->lineNumber;
tag->lang = info->langType;
}
#endif
@ -1194,7 +1199,7 @@ extern void uncorkTagFile(void)
writeTagEntry (tag);
if (doesInputLanguageRequestAutomaticFQTag ()
&& isXtagEnabled (XTAG_QUALIFIED_TAGS)
&& tag->extensionFields.scopeKind
&& (tag->extensionFields.scopeKindIndex != KIND_GHOST_INDEX)
&& tag->extensionFields.scopeName
&& tag->extensionFields.scopeIndex)
makeQualifiedTagEntry (tag);
@ -1281,15 +1286,15 @@ extern int makeQualifiedTagEntry (const tagEntryInfo *const e)
if (e->extensionFields.scopeName)
{
vStringCatS (fqn, e->extensionFields.scopeName);
xk = e->extensionFields.scopeKind->letter;
sep = scopeSeparatorFor (e->kind, xk);
xk = e->extensionFields.scopeKindIndex;
sep = scopeSeparatorFor (e->langType, e->kindIndex, xk);
vStringCatS (fqn, sep);
}
else
{
/* This is an top level item. prepend a root separator
if the kind of the item has. */
sep = scopeSeparatorFor (e->kind, KIND_NULL);
sep = scopeSeparatorFor (e->langType, e->kindIndex, KIND_GHOST_INDEX);
if (sep == NULL)
{
/* No root separator. The name of the
@ -1316,59 +1321,64 @@ extern int makeQualifiedTagEntry (const tagEntryInfo *const e)
}
extern void initTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind)
int kindIndex)
{
initTagEntryFull(e, name,
getInputLineNumber (),
getInputLanguageName (),
getInputLanguage (),
getInputFilePosition (),
getInputFileTagPath (),
kind,
kindIndex,
ROLE_INDEX_DEFINITION,
getSourceFileTagPath(),
getSourceLanguageName(),
getSourceLanguage(),
getSourceLineNumber() - getInputLineNumber ());
}
extern void initRefTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind, int roleIndex)
int kindIndex, int roleIndex)
{
initTagEntryFull(e, name,
getInputLineNumber (),
getInputLanguageName (),
getInputLanguage (),
getInputFilePosition (),
getInputFileTagPath (),
kind,
kindIndex,
roleIndex,
getSourceFileTagPath(),
getSourceLanguageName(),
getSourceLanguage(),
getSourceLineNumber() - getInputLineNumber ());
}
extern void initTagEntryFull (tagEntryInfo *const e, const char *const name,
unsigned long lineNumber,
const char* language,
langType langType_,
MIOPos filePosition,
const char *inputFileName,
const kindOption *kind,
int kindIndex,
int roleIndex,
const char *sourceFileName,
const char* sourceLanguage,
langType sourceLangType,
long sourceLineNumberDifference)
{
int i;
Assert (getInputFileName() != NULL);
memset (e, 0, sizeof (tagEntryInfo));
e->lineNumberEntry = (bool) (Option.locate == EX_LINENUM);
e->lineNumber = lineNumber;
e->boundaryInfo = getNestedInputBoundaryInfo (lineNumber);
e->language = language;
e->langType = langType_;
e->filePosition = filePosition;
e->inputFileName = inputFileName;
e->name = name;
e->extensionFields.scopeLangType = LANG_AUTO;
e->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;
e->extensionFields.scopeIndex = CORK_NIL;
e->kind = kind;
Assert (kindIndex < 0 || kindIndex < (int)countLanguageKinds(langType_));
e->kindIndex = kindIndex;
Assert (roleIndex >= ROLE_INDEX_DEFINITION);
Assert (kind == NULL || roleIndex < kind->nRoles);
@ -1376,7 +1386,7 @@ extern void initTagEntryFull (tagEntryInfo *const e, const char *const name,
if (roleIndex > ROLE_INDEX_DEFINITION)
markTagExtraBit (e, XTAG_REFERENCE_TAGS);
e->sourceLanguage = sourceLanguage;
e->sourceLangType = sourceLangType;
e->sourceFileName = sourceFileName;
e->sourceLineNumberDifference = sourceLineNumberDifference;

View File

@ -15,6 +15,7 @@
#include "general.h" /* must always come first */
#include "types.h"
#include <stdint.h>
#include <stdio.h>
#include "field.h"
@ -45,7 +46,7 @@ struct sTagEntryInfo {
unsigned int lineNumberEntry:1; /* pattern or line number entry */
unsigned int isFileScope :1; /* is tag visible only within input file? */
unsigned int isFileEntry :1; /* is this just an entry for a file name? */
unsigned int truncateLine :1; /* truncate tag line at end of tag name? */
unsigned int truncateLineAfterTag :1; /* truncate tag line at end of tag name? */
unsigned int placeholder :1; /* This is just a part of scope context.
Put this entry to cork queue but
don't print it to tags file. */
@ -55,10 +56,10 @@ struct sTagEntryInfo {
* (may be NULL if not present) *//* */
unsigned int boundaryInfo; /* info about nested input stream */
MIOPos filePosition; /* file position of line containing tag */
const char* language; /* language of input file */
langType langType; /* language of input file */
const char *inputFileName; /* name of input file */
const char *name; /* name of the tag */
const kindOption *kind; /* kind descriptor */
int kindIndex; /* kind descriptor */
unsigned char extra[ ((XTAG_COUNT) / 8) + 1 ];
struct {
@ -67,7 +68,11 @@ struct sTagEntryInfo {
const char* implementation;
const char* inheritance;
const kindOption* scopeKind;
/* Which scopeKindIndex belong to. If the value is LANG_AUTO,
the value for langType field of this structure is used as default value.
LANG_AUTO is set automatically in initTagEntryInfo. */
langType scopeLangType;
int scopeKindIndex;
const char* scopeName;
int scopeIndex; /* cork queue entry for upper scope tag.
This field is meaningful if the value
@ -99,7 +104,7 @@ struct sTagEntryInfo {
/* Following source* fields are used only when #line is found
in input and --line-directive is given in ctags command line. */
const char* sourceLanguage;
langType sourceLangType;
const char *sourceFileName;
unsigned long sourceLineNumberDifference;
};
@ -121,18 +126,18 @@ extern void setupWriter (void);
extern void teardownWriter (const char *inputFilename);
extern int makeTagEntry (const tagEntryInfo *const tag);
extern void initTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind);
int kindIndex);
extern void initRefTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind, int roleIndex);
int kindIndex, int roleIndex);
extern void initTagEntryFull (tagEntryInfo *const e, const char *const name,
unsigned long lineNumber,
const char* language,
langType langType_,
MIOPos filePosition,
const char *inputFileName,
const kindOption *kind,
int kindIndex,
int roleIndex,
const char *sourceFileName,
const char* sourceLanguage,
langType sourceLangType,
long sourceLineNumberDifference);
extern int makeQualifiedTagEntry (const tagEntryInfo *const e);

View File

@ -27,7 +27,7 @@
struct sFieldDesc {
fieldSpec *spec;
fieldDefinition *spec;
unsigned int fixed: 1; /* fields which cannot be disabled. */
vString *buffer;
const char* nameWithPrefix;
@ -84,7 +84,7 @@ static bool isEndFieldAvailable (const tagEntryInfo *const tag);
#define WITH_DEFUALT_VALUE(str) ((str)?(str):"-")
static fieldSpec fieldSpecsFixed [] = {
static fieldDefinition fieldDefinitionsFixed [] = {
/* FIXED FIELDS */
DEFINE_FIELD_SPEC ('N', "name", true,
"tag name (fixed field)",
@ -97,7 +97,7 @@ static fieldSpec fieldSpecsFixed [] = {
renderFieldPattern),
};
static fieldSpec fieldSpecsExuberant [] = {
static fieldDefinition fieldDefinitionsExuberant [] = {
DEFINE_FIELD_SPEC ('C', "compact", false,
"compact input line (fixed field, only used in -x option)",
renderFieldCompactInputLine),
@ -143,7 +143,7 @@ static fieldSpec fieldSpecsExuberant [] = {
renderFieldKindName),
};
static fieldSpec fieldSpecsUniversal [] = {
static fieldDefinition fieldDefinitionsUniversal [] = {
DEFINE_FIELD_SPEC_FULL ('r', "role", false,
"Role",
renderFieldRole, isRoleFieldAvailable),
@ -182,43 +182,43 @@ extern void initFieldDescs (void)
Assert (fieldDescs == NULL);
fieldDescAllocated
= ARRAY_SIZE (fieldSpecsFixed)
+ ARRAY_SIZE (fieldSpecsExuberant)
+ ARRAY_SIZE (fieldSpecsUniversal);
= ARRAY_SIZE (fieldDefinitionsFixed)
+ ARRAY_SIZE (fieldDefinitionsExuberant)
+ ARRAY_SIZE (fieldDefinitionsUniversal);
fieldDescs = xMalloc (fieldDescAllocated, fieldDesc);
fieldDescUsed = 0;
for (i = 0; i < ARRAY_SIZE (fieldSpecsFixed); i++)
for (i = 0; i < ARRAY_SIZE (fieldDefinitionsFixed); i++)
{
fdesc = fieldDescs + i + fieldDescUsed;
fdesc->spec = fieldSpecsFixed + i;
fdesc->spec = fieldDefinitionsFixed + i;
fdesc->fixed = 1;
fdesc->buffer = NULL;
fdesc->nameWithPrefix = fdesc->spec->name;
fdesc->language = LANG_IGNORE;
fdesc->sibling = FIELD_UNKNOWN;
}
fieldDescUsed += ARRAY_SIZE (fieldSpecsFixed);
fieldDescUsed += ARRAY_SIZE (fieldDefinitionsFixed);
for (i = 0; i < ARRAY_SIZE (fieldSpecsExuberant); i++)
for (i = 0; i < ARRAY_SIZE (fieldDefinitionsExuberant); i++)
{
fdesc = fieldDescs + i + fieldDescUsed;
fdesc->spec = fieldSpecsExuberant +i;
fdesc->spec = fieldDefinitionsExuberant +i;
fdesc->fixed = 0;
fdesc->buffer = NULL;
fdesc->nameWithPrefix = fdesc->spec->name;
fdesc->language = LANG_IGNORE;
fdesc->sibling = FIELD_UNKNOWN;
}
fieldDescUsed += ARRAY_SIZE (fieldSpecsExuberant);
fieldDescUsed += ARRAY_SIZE (fieldDefinitionsExuberant);
for (i = 0; i < ARRAY_SIZE (fieldSpecsUniversal); i++)
for (i = 0; i < ARRAY_SIZE (fieldDefinitionsUniversal); i++)
{
char *nameWithPrefix;
fdesc = fieldDescs + i + fieldDescUsed;
fdesc->spec = fieldSpecsUniversal + i;
fdesc->spec = fieldDefinitionsUniversal + i;
fdesc->fixed = 0;
fdesc->buffer = NULL;
@ -235,7 +235,7 @@ extern void initFieldDescs (void)
fdesc->language = LANG_IGNORE;
fdesc->sibling = FIELD_UNKNOWN;
}
fieldDescUsed += ARRAY_SIZE (fieldSpecsUniversal);
fieldDescUsed += ARRAY_SIZE (fieldDefinitionsUniversal);
Assert ( fieldDescAllocated == fieldDescUsed );
}
@ -401,9 +401,10 @@ static const char *renderEscapedName (const char* s,
int c = *s;
if ((c > 0x00 && c <= 0x1F) || c == 0x7F)
{
char letter = getLanguageKind(tag->langType, tag->kindIndex)->letter;
verbose ("Unexpected character (0 < *c && *c < 0x20) included in a tagEntryInfo: %s\n", base);
verbose ("File: %s, Line: %lu, Lang: %s, Kind: %c\n",
tag->inputFileName, tag->lineNumber, tag->language, tag->kind->letter);
tag->inputFileName, tag->lineNumber, getLanguageName(tag->langType), letter);
verbose ("Escape the character\n");
break;
}
@ -518,7 +519,8 @@ static const char* renderCompactInputLine (vString *b, const char *const line)
static const char *renderFieldKindName (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)
{
return renderAsIs (b, tag->kind->name);
kindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);
return renderAsIs (b, kdef->name);
}
static const char *renderFieldCompactInputLine (const tagEntryInfo *const tag,
@ -564,15 +566,12 @@ static const char *renderFieldRole (const tagEntryInfo *const tag,
vString* b)
{
int rindex = tag->extensionFields.roleIndex;
const roleDesc * role;
if (rindex == ROLE_INDEX_DEFINITION)
vStringClear (b);
else
{
Assert (rindex < tag->kind->nRoles);
role = & (tag->kind->roles [rindex]);
return renderRole (role, b);
return "TODO";
}
return vStringValue (b);
@ -582,10 +581,12 @@ static const char *renderFieldLanguage (const tagEntryInfo *const tag,
const char *value CTAGS_ATTR_UNUSED,
vString* b)
{
const char *l = tag->language;
const char *l;
if (Option.lineDirectives && tag->sourceLanguage)
l = tag->sourceLanguage;
if (Option.lineDirectives && (tag->sourceLangType != LANG_IGNORE))
l = getLanguageName(tag->sourceLangType);
else
l = getLanguageName(tag->langType);
return renderAsIs (b, WITH_DEFUALT_VALUE(l));
}
@ -601,11 +602,7 @@ static const char *renderFieldKindLetter (const tagEntryInfo *const tag,
const char *value CTAGS_ATTR_UNUSED,
vString* b)
{
static char c[2] = { [1] = '\0' };
c [0] = tag->kind->letter;
return renderAsIs (b, c);
return "TODO";
}
static const char *renderFieldImplementation (const tagEntryInfo *const tag,
@ -712,7 +709,7 @@ static const char *renderFieldEnd (const tagEntryInfo *const tag,
static bool isLanguageFieldAvailable (const tagEntryInfo *const tag)
{
return (tag->language != NULL)? true: false;
return (tag->langType == LANG_IGNORE)? false: true;
}
static bool isTyperefFieldAvailable (const tagEntryInfo *const tag)
@ -789,7 +786,7 @@ static bool isFieldFixed (fieldType type)
extern bool enableField (fieldType type, bool state, bool warnIfFixedField)
{
fieldSpec *spec = getFieldDesc(type)->spec;
fieldDefinition *spec = getFieldDesc(type)->spec;
bool old = spec->enabled? true: false;
if (isFieldFixed (type))
{
@ -877,7 +874,7 @@ static const char* defaultRenderer (const tagEntryInfo *const tag,
return value;
}
extern int defineField (fieldSpec *spec, langType language)
extern int defineField (fieldDefinition *spec, langType language)
{
fieldDesc *fdesc;
char *nameWithPrefix;

View File

@ -58,7 +58,7 @@ typedef const char* (* renderEscaped) (const tagEntryInfo *const tag,
typedef bool (* isValueAvailable) (const struct sTagEntryInfo *const tag);
#define FIELD_LETTER_NO_USE '\0'
typedef struct sFieldSpec {
typedef struct sFieldDefinition {
/* lettern, and ftype are initialized in the main part,
not in a parser. */
#define NUL_FIELD_LETTER '\0'
@ -70,7 +70,7 @@ typedef struct sFieldSpec {
isValueAvailable isValueAvailable;
unsigned int ftype; /* Given from the main part */
} fieldSpec;
} fieldDefinition;
extern fieldType getFieldTypeForOption (char letter);
@ -105,7 +105,7 @@ extern int countFields (void);
/* language should be typed to langType.
Use int here to avoid circular dependency */
extern int defineField (fieldSpec *spec, langType language);
extern int defineField (fieldDefinition *spec, langType language);
extern fieldType nextSiblingField (fieldType type);
#endif /* CTAGS_MAIN_FIELD_H */

View File

@ -85,7 +85,7 @@ static void entry_reclaim (hentry* entry,
entry = entry_destroy (entry, keyfreefn, valfreefn);
}
static void *entry_find (hentry* entry, void* key, hashTableEqualFunc equalfn)
static void *entry_find (hentry* entry, const void* const key, hashTableEqualFunc equalfn)
{
while (entry)
{
@ -141,6 +141,17 @@ extern hashTable *hashTableNew (unsigned int size,
}
extern void hashTableDelete (hashTable *htable)
{
if (!htable)
return;
hashTableClear (htable);
eFree (htable->table);
eFree (htable);
}
extern void hashTableClear (hashTable *htable)
{
unsigned int i;
if (!htable)
@ -154,8 +165,6 @@ extern void hashTableDelete (hashTable *htable)
entry_reclaim (entry, htable->keyfreefn, htable->valfreefn);
htable->table[i] = NULL;
}
eFree (htable->table);
eFree (htable);
}
extern void hashTablePutItem (hashTable *htable, void *key, void *value)
@ -166,7 +175,7 @@ extern void hashTablePutItem (hashTable *htable, void *key, void *value
htable->table[i] = entry_new(key, value, htable->table[i]);
}
extern void* hashTableGetItem (hashTable *htable, void *key)
extern void* hashTableGetItem (hashTable *htable, const void * key)
{
unsigned int i;
@ -183,7 +192,7 @@ extern bool hashTableDeleteItem (hashTable *htable, void *key)
htable->equalfn, htable->keyfreefn, htable->valfreefn);
}
extern bool hashTableHasItem (hashTable *htable, void *key)
extern bool hashTableHasItem (hashTable *htable, const void *key)
{
return hashTableGetItem (htable, key)? true: false;
}
@ -208,19 +217,20 @@ extern int hashTableCountItem (hashTable *htable)
hashTableForeachItem (htable, count, &c);
return c;
}
unsigned int hashPtrhash (void * x)
unsigned int hashPtrhash (const void * const x)
{
union {
void *ptr;
const void * ptr;
unsigned int ui;
} v;
v.ui = 0;
v.ptr = x;
return v.ui;
}
bool hashPtreq (void *a, void *b)
bool hashPtreq (const void *const a, const void *const b)
{
return (a == b)? true: false;
}
@ -228,7 +238,7 @@ bool hashPtreq (void *a, void *b)
/* http://www.cse.yorku.ca/~oz/hash.html */
static unsigned long
djb2(unsigned char *str)
djb2(const unsigned char *str)
{
unsigned long hash = 5381;
int c;
@ -239,18 +249,35 @@ djb2(unsigned char *str)
return hash;
}
unsigned int hashCstrhash (void * x)
static unsigned long
casedjb2(const unsigned char *str)
{
char *s = x;
return (unsigned int)djb2((unsigned char *)s);
unsigned long hash = 5381;
int c;
while ((c = *str++))
{
if (('a' <= c) && (c <= 'z'))
c += ('A' - 'a');
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash;
}
bool hashCstreq (void *a, void *b)
unsigned int hashCstrhash (const void *const x)
{
const char *const s = x;
return (unsigned int)djb2((const unsigned char *)s);
}
bool hashCstreq (const void * const a, const void *const b)
{
return !!(strcmp (a, b) == 0);
}
unsigned int hashInthash (void *x)
unsigned int hashInthash (const void *const x)
{
union tmp {
unsigned int u;
@ -262,10 +289,22 @@ unsigned int hashInthash (void *x)
return x0.u;
}
bool hashInteq (void *a, void *b)
bool hashInteq (const void *const a, const void *const b)
{
int ai = *(int *)a;
int bi = *(int *)b;
return !!(ai == bi);
}
unsigned int hashCstrcasehash (const void *const x)
{
const char *const s = x;
return (unsigned int)casedjb2((const unsigned char *)s);
}
bool hashCstrcaseeq (const void *const a, const void *const b)
{
return !!(strcasecmp (a, b) == 0);
}

View File

@ -14,19 +14,22 @@
#include "general.h"
typedef struct sHashTable hashTable;
typedef unsigned int (* hashTableHashFunc) (void * key);
typedef bool (* hashTableEqualFunc) (void* a, void* b);
typedef unsigned int (* hashTableHashFunc) (const void * const key);
typedef bool (* hashTableEqualFunc) (const void* a, const void* b);
typedef void (* hashTableFreeFunc) (void * ptr);
typedef void (* hashTableForeachFunc) (void *key, void *value, void* user_data);
unsigned int hashPtrhash (void * x);
bool hashPtreq (void *a, void *b);
unsigned int hashPtrhash (const void * x);
bool hashPtreq (const void * a, const void * constb);
unsigned int hashCstrhash (void * x);
bool hashCstreq (void *a, void *b);
unsigned int hashCstrhash (const void * x);
bool hashCstreq (const void * a, const void * b);
unsigned int hashInthash (void *x);
bool hashInteq (void *a, void *b);
unsigned int hashCstrcasehash (const void * x);
bool hashCstrcaseeq (const void * a, const void * b);
unsigned int hashInthash (const void * x);
bool hashInteq (const void * a, const void * b);
extern hashTable* hashTableNew (unsigned int size,
hashTableHashFunc hashfn,
@ -34,9 +37,10 @@ extern hashTable* hashTableNew (unsigned int size,
hashTableFreeFunc keyfreefn,
hashTableFreeFunc valfreefn);
extern void hashTableDelete (hashTable *htable);
extern void hashTableClear (hashTable *htable);
extern void hashTablePutItem (hashTable *htable, void *key, void *value);
extern void* hashTableGetItem (hashTable *htable, void *key);
extern bool hashTableHasItem (hashTable *htable, void *key);
extern void* hashTableGetItem (hashTable *htable, const void * key);
extern bool hashTableHasItem (hashTable * htable, const void * key);
extern bool hashTableDeleteItem (hashTable *htable, void *key);
extern void hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data);
extern int hashTableCountItem (hashTable *htable);

26
ctags/main/inline.h Normal file
View File

@ -0,0 +1,26 @@
/*
*
* Copyright (c) 2016, 2017 Matthew Brush
*
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
*/
#ifndef CTAGS_MAIN_INLINE_H
#define CTAGS_MAIN_INLINE_H
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define CTAGS_INLINE static inline
#elif defined(_MSC_VER)
# define CTAGS_INLINE static __inline
#elif defined(__GNUC__) || defined(__clang__)
# define CTAGS_INLINE static __inline__
// #elif ... other compilers/tests here ...
// # define CTAGS_INLINE ...
#else
# define CTAGS_INLINE static
#endif
#endif /* CTAGS_MAIN_INLINE_H */

View File

@ -17,13 +17,13 @@
#include "kind.h"
#include "parse.h"
extern void printRole (const roleDesc* const role)
extern void printRole (const roleDefinition* const role)
{
if (role)
printf ("%s\t%s\t%s\n", role->name, role->description, role->enabled? "on": "off");
}
extern const char *renderRole (const roleDesc* const role, vString* b)
extern const char *renderRole (const roleDefinition* const role, vString* b)
{
vStringCatS (b, role->name);
return vStringValue (b);
@ -78,7 +78,7 @@ extern void printKindListHeader (bool indent, bool tabSeparated)
#undef KIND_HEADER_COMMON_FMT
}
extern void printKind (const kindOption* const kind, bool allKindFields, bool indent,
extern void printKind (const kindDefinition* const kind, bool allKindFields, bool indent,
bool tabSeparated)
{
#define KIND_FMT MAKE_KIND_FMT("", c, d)
@ -109,11 +109,10 @@ extern void printKind (const kindOption* const kind, bool allKindFields, bool in
#undef KIND_FMT
}
const char *scopeSeparatorFor (const kindOption *kind, char parentLetter)
const char *scopeSeparatorFor (langType lang, int kindIndex, int parentKindIndex)
{
scopeSeparator *table;
Assert (kind);
table = kind->separators;
kindDefinition *kind = getLanguageKind (lang, kindIndex);
scopeSeparator *table = kind->separators;
/* If no table is given, use the default generic separator ".".
The exception is if a root separator is looked up. In this case,
@ -121,7 +120,7 @@ const char *scopeSeparatorFor (const kindOption *kind, char parentLetter)
if (table == NULL)
{
if (parentLetter == KIND_NULL)
if (parentKindIndex == KIND_GHOST_INDEX)
return NULL;
else
return ".";
@ -131,21 +130,21 @@ const char *scopeSeparatorFor (const kindOption *kind, char parentLetter)
{
/* KIND_WILDCARD cannot be used as a key for finding
a root separator.*/
if ( (table->parentLetter == KIND_WILDCARD
&& parentLetter != KIND_NULL)
|| table->parentLetter == parentLetter)
if ( (table->parentKindIndex == KIND_WILDCARD_INDEX
&& parentKindIndex != KIND_GHOST_INDEX)
|| table->parentKindIndex == parentKindIndex)
return table->separator;
table++;
}
if (parentLetter == KIND_NULL)
if (parentKindIndex == KIND_GHOST_INDEX)
return NULL;
else
return ".";
}
extern void enableKind (kindOption *kind, bool enable)
extern void enableKind (kindDefinition *kind, bool enable)
{
kindOption *slave;
kindDefinition *slave;
if (kind->master)
enableKind (kind->master, enable);

View File

@ -13,14 +13,14 @@
#include "routines.h" /* for STRINGIFY */
#include "vstring.h"
typedef struct sRoleDesc {
typedef struct sRoleDefinition {
bool enabled;
const char* name; /* role name */
const char* description; /* displayed in --help output */
} roleDesc;
} roleDefinition;
extern void printRole (const roleDesc* const role); /* for --help */
extern const char *renderRole (const roleDesc* const role, vString* b);
extern void printRole (const roleDefinition* const role); /* for --help */
extern const char *renderRole (const roleDefinition* const role, vString* b);
/*
* Predefined kinds
@ -32,9 +32,11 @@ extern const char *renderRole (const roleDesc* const role, vString* b);
#define KIND_NULL '\0'
#define KIND_GHOST_INDEX -1
#define KIND_GHOST ' '
#define KIND_GHOST_LONG "ghost"
#define KIND_FILE_INDEX -2
#define KIND_FILE_DEFAULT 'F'
#define KIND_FILE_DEFAULT_LONG "file"
@ -43,21 +45,22 @@ extern const char *renderRole (const roleDesc* const role, vString* b);
#define KIND_GENERIC_REFERENCE '@'
#define KIND_GENERIC_REFERENCE_DEFAULT_LONG "reference"
#define KIND_WILDCARD_INDEX -3
#define KIND_WILDCARD '*'
typedef struct sScopeSeparator {
char parentLetter;
int parentKindIndex;
const char *separator;
} scopeSeparator;
struct sKindOption {
struct sKindDefinition {
bool enabled; /* are tags for kind enabled? */
char letter; /* kind letter */
const char* name; /* kind name */
const char* description; /* displayed in --help output */
bool referenceOnly;
int nRoles; /* The number of role elements. */
roleDesc *roles;
roleDefinition *roles;
scopeSeparator *separators;
unsigned int separatorCount;
@ -71,20 +74,20 @@ struct sKindOption {
If the value other than `LANG_AUTO' is specified,
the main part does nothing. */
langType syncWith;
kindOption *slave;
kindOption *master;
kindDefinition *slave;
kindDefinition *master;
};
#define ATTACH_ROLES(RS) .nRoles = ARRAY_SIZE(RS), .roles = RS
#define ATTACH_SEPARATORS(S) .separators = S, .separatorCount = ARRAY_SIZE(S)
/* The value of `tabSeparated' is meaningfull only when `allKindFields' is true. */
extern void printKind (const kindOption* const kind, bool allKindFields, bool indent,
extern void printKind (const kindDefinition* const kind, bool allKindFields, bool indent,
bool tabSeparated);
extern void printKindListHeader (bool indent, bool tabSeparated);
extern const char *scopeSeparatorFor (const kindOption *kind, char parentLetter);
extern const char *scopeSeparatorFor (langType lang, int kindIndex, int parentKindIndex);
extern void enableKind (kindOption *kind, bool enable);
extern void enableKind (kindDefinition *kind, bool enable);
#define PR_KIND_STR(X) PR_KIND_WIDTH_##X
#define PR_KIND_FMT(X,T) "%-" STRINGIFY(PR_KIND_STR(X)) STRINGIFY(T)

View File

@ -66,7 +66,7 @@ typedef struct sCppState {
bool resolveRequired; /* must resolve if/else/elif/endif branch */
bool hasAtLiteralStrings; /* supports @"c:\" strings */
bool hasCxxRawLiteralStrings; /* supports R"xxx(...)xxx" strings */
const kindOption *defineMacroKind;
int defineMacroKindIndex;
struct sDirective {
enum eState state; /* current directive being processed */
bool accept; /* is a directive syntactically permitted? */
@ -92,7 +92,7 @@ static cppState Cpp = {
false, /* resolveRequired */
false, /* hasAtLiteralStrings */
false, /* hasCxxRawLiteralStrings */
NULL, /* defineMacroKind */
-1, /* defineMacroKindIndex */
{
DRCTV_NONE, /* state */
false, /* accept */
@ -118,7 +118,7 @@ extern unsigned int cppGetDirectiveNestLevel (void)
extern void cppInit (const bool state, const bool hasAtLiteralStrings,
const bool hasCxxRawLiteralStrings,
const kindOption *defineMacroKind)
int defineMacroKindIndex)
{
BraceFormat = state;
@ -127,7 +127,7 @@ extern void cppInit (const bool state, const bool hasAtLiteralStrings,
Cpp.resolveRequired = false;
Cpp.hasAtLiteralStrings = hasAtLiteralStrings;
Cpp.hasCxxRawLiteralStrings = hasCxxRawLiteralStrings;
Cpp.defineMacroKind = defineMacroKind;
Cpp.defineMacroKindIndex = defineMacroKindIndex;
Cpp.directive.state = DRCTV_NONE;
Cpp.directive.accept = true;
@ -326,22 +326,22 @@ static int makeDefineTag (const char *const name, bool parameterized, bool undef
{
const bool isFileScope = (bool) (! isInputHeaderFile ());
if (!Cpp.defineMacroKind)
if (Cpp.defineMacroKindIndex == -1)
return CORK_NIL;
if (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))
return CORK_NIL;
if ( /* condition for definition tag */
((!undef) && Cpp.defineMacroKind->enabled)
((!undef) && isLanguageKindEnabled (getInputLanguage(), Cpp.defineMacroKindIndex))
|| /* condition for reference tag */
(undef && isXtagEnabled(XTAG_REFERENCE_TAGS)))
{
tagEntryInfo e;
initTagEntry (&e, name, Cpp.defineMacroKind);
initTagEntry (&e, name, Cpp.defineMacroKindIndex);
e.lineNumberEntry = (bool) (Option.locate == EX_LINENUM);
e.isFileScope = isFileScope;
e.truncateLine = true;
e.truncateLineAfterTag = true;
if (parameterized)
e.extensionFields.signature = cppGetSignature ();
makeTagEntry (&e);

View File

@ -64,7 +64,7 @@ extern unsigned int cppGetDirectiveNestLevel (void);
extern void cppInit (const bool state,
const bool hasAtLiteralStrings,
const bool hasCxxRawLiteralStrings,
const kindOption *defineMacroKind);
int defineMacroKindIndex);
extern void cppTerminate (void);
extern void cppBeginStatement (void);
extern void cppEndStatement (void);

View File

@ -75,7 +75,7 @@ typedef struct {
union {
struct {
char *name_pattern;
kindOption *kind;
kindDefinition *kind;
} tag;
struct {
regexCallback function;
@ -139,9 +139,14 @@ static void clearPatternSet (const langType language)
*/
static int makeRegexTag (
const vString* const name, const kindOption* const kind, int scopeIndex, int placeholder)
const vString* const name, const kindDefinition* const kind, int scopeIndex, int placeholder)
{
Assert (kind != NULL);
/* TODO: Disable regex tag generation for now. We would need to pass kindIndex
* to initTagEntry() but currently we don't have kinds indexable because
* they are stored in hash table. Consider whether we want to support
* regex parsers at all in Geany. */
#if 0
if (kind->enabled)
{
tagEntryInfo e;
@ -152,6 +157,7 @@ static int makeRegexTag (
return makeTagEntry (&e);
}
else
#endif
return CORK_NIL;
}
@ -299,9 +305,9 @@ static flagDefinition scopePtrnFlagDef[] = {
NULL, "don't put this tag to tags file."},
};
static kindOption *kindNew ()
static kindDefinition *kindNew ()
{
kindOption *kind = xCalloc (1, kindOption);
kindDefinition *kind = xCalloc (1, kindDefinition);
kind->letter = '\0';
kind->name = NULL;
kind->description = NULL;
@ -314,7 +320,7 @@ static kindOption *kindNew ()
static void kindFree (void *data)
{
kindOption *kind = data;
kindDefinition *kind = data;
kind->letter = '\0';
if (kind->name)
{
@ -335,7 +341,7 @@ static regexPattern* addCompiledTagCommon (const langType language,
{
patternSet* set;
regexPattern *ptrn;
kindOption *kind = NULL;
kindDefinition *kind = NULL;
if (language > SetUpper)
{
@ -865,14 +871,14 @@ extern bool processRegexOption (const char *const option,
}
struct kindCbHelperData {
bool (*func) (kindOption *, void *);
bool (*func) (kindDefinition *, void *);
void *func_data;
bool result;
};
static void kindCbHelper (void *key, void *value, void* user_data)
{
kindOption *kind = value;
kindDefinition *kind = value;
struct kindCbHelperData *helper_data = user_data;
if (helper_data->result)
@ -882,7 +888,7 @@ static void kindCbHelper (void *key, void *value, void* user_data)
}
extern void foreachRegexKinds (const langType language,
bool (*func) (kindOption *, void *),
bool (*func) (kindDefinition *, void *),
void *data)
{
initializeParser (language);
@ -900,7 +906,7 @@ extern void foreachRegexKinds (const langType language,
}
static bool kind_reset_cb (kindOption *kind, void *data)
static bool kind_reset_cb (kindDefinition *kind, void *data)
{
kind->enabled = *(bool *)data;
return false; /* continue */
@ -919,7 +925,7 @@ struct kind_and_mode_and_result
bool result;
};
static bool enable_kind_cb (kindOption *kind, void *data)
static bool enable_kind_cb (kindDefinition *kind, void *data)
{
struct kind_and_mode_and_result *kmr = data;
if ((kmr->kind != KIND_NULL
@ -967,7 +973,7 @@ struct kind_and_result
bool result;
};
static bool is_kind_enabled_cb (kindOption *kind, void *data)
static bool is_kind_enabled_cb (kindDefinition *kind, void *data)
{
bool r = false;
struct kind_and_result *kr = data;
@ -981,7 +987,7 @@ static bool is_kind_enabled_cb (kindOption *kind, void *data)
return r;
}
static bool does_kind_exist_cb (kindOption *kind, void *data)
static bool does_kind_exist_cb (kindDefinition *kind, void *data)
{
bool r = false;
struct kind_and_result *kr = data;
@ -1026,7 +1032,7 @@ struct printRegexKindCBData{
bool tabSeparated;
};
static bool printRegexKind (kindOption *kind, void *user_data)
static bool printRegexKind (kindDefinition *kind, void *user_data)
{
struct printRegexKindCBData *data = user_data;
if (kind->letter != KIND_GHOST)

View File

@ -116,7 +116,7 @@ typedef struct {
} address;
const kindOption* kind;
const kindDefinition* kind;
/* is tag of file-limited scope? */
short fileScope;
@ -134,7 +134,7 @@ typedef struct {
typedef struct {
vString *path;
kindOption *kinds;
kindDefinition *kinds;
unsigned int n_kinds;
bool available;
unsigned int id; /* not used yet */
@ -166,7 +166,7 @@ static void clearPathSet (const langType language)
p->available = false;
for (k = 0; k < p->n_kinds; k++)
{
kindOption* kind = &(p->kinds[k]);
kindDefinition* kind = &(p->kinds[k]);
eFree ((void *)kind->name);
kind->name = NULL;
@ -191,7 +191,7 @@ static bool loadPathKind (xcmdPath *const path, char* line, char *args[])
const char* backup = line;
char* off;
vString *desc;
kindOption *kind;
kindDefinition *kind;
if (line[0] == '\0')
return false;
@ -201,7 +201,7 @@ static bool loadPathKind (xcmdPath *const path, char* line, char *args[])
return false;
}
path->kinds = xRealloc (path->kinds, path->n_kinds + 1, kindOption);
path->kinds = xRealloc (path->kinds, path->n_kinds + 1, kindDefinition);
kind = &path->kinds [path->n_kinds];
memset (kind, 0, sizeof (*kind));
kind->enabled = true;
@ -405,7 +405,7 @@ static bool loadPathKinds (xcmdPath *const path, const langType language)
extern void foreachXcmdKinds (const langType language,
bool (*func) (kindOption *, void *),
bool (*func) (kindDefinition *, void *),
void *data)
{
#ifdef HAVE_COPROC
@ -428,7 +428,7 @@ extern void foreachXcmdKinds (const langType language,
#endif
}
static bool kind_reset_cb (kindOption *kind, void *data)
static bool kind_reset_cb (kindDefinition *kind, void *data)
{
kind->enabled = *(bool *)data;
return false; /* continue */
@ -447,7 +447,7 @@ struct kind_and_mode_and_result
bool result;
};
static bool enable_kind_cb (kindOption *kind, void *data)
static bool enable_kind_cb (kindDefinition *kind, void *data)
{
struct kind_and_mode_and_result *kmr = data;
if ((kmr->kind != KIND_NULL
@ -500,7 +500,7 @@ struct kind_and_result
bool result;
};
static bool is_kind_enabled_cb (kindOption *kind, void *data)
static bool is_kind_enabled_cb (kindDefinition *kind, void *data)
{
bool r = false;
struct kind_and_result *kr = data;
@ -514,7 +514,7 @@ static bool is_kind_enabled_cb (kindOption *kind, void *data)
return r;
}
static bool does_kind_exist_cb (kindOption *kind, void *data)
static bool does_kind_exist_cb (kindDefinition *kind, void *data)
{
bool r = false;
struct kind_and_result *kr = data;
@ -560,7 +560,7 @@ struct printXcmdKindCBData {
};
#ifdef HAVE_COPROC
static bool printXcmdKind (kindOption *kind, void *user_data)
static bool printXcmdKind (kindDefinition *kind, void *user_data)
{
struct printXcmdKindCBData *data = user_data;
@ -732,10 +732,10 @@ extern bool processXcmdOption (const char *const option, const char *const param
}
#ifdef HAVE_COPROC
static const kindOption* lookupKindFromLetter (const xcmdPath* const path, char kind_letter)
static const kindDefinition* lookupKindFromLetter (const xcmdPath* const path, char kind_letter)
{
unsigned int k;
kindOption *kind;
kindDefinition *kind;
for (k = 0; k < path->n_kinds; k++)
{
@ -747,10 +747,10 @@ static const kindOption* lookupKindFromLetter (const xcmdPath* const path, char
}
static const kindOption* lookupKindFromName (const xcmdPath* const path, const char* const kind_name)
static const kindDefinition* lookupKindFromName (const xcmdPath* const path, const char* const kind_name)
{
unsigned int k;
kindOption *kind;
kindDefinition *kind;
for (k = 0; k < path->n_kinds; k++)
{
@ -799,7 +799,7 @@ static const char* entryGetAnyUnpulledField (tagEntry *const entry, const char *
static bool isKindEnabled (xcmdPath* path, const char* value)
{
unsigned int k;
kindOption *kind;
kindDefinition *kind;
Assert (path->kinds);
Assert (value);
@ -857,7 +857,7 @@ static bool parseExtensionFields (tagEntry *const entry, char *const string, xcm
entry->kind = lookupKindFromLetter (path, field[0]);
if (entry->kind == NULL)
{
kindOption *fileKind = getInputLanguageFileKind ();
kindDefinition *fileKind = getInputLanguageFileKind ();
if (fileKind && fileKind->letter == field[0])
/* ctags will make a tag for file. */
goto reject;
@ -889,7 +889,7 @@ static bool parseExtensionFields (tagEntry *const entry, char *const string, xcm
entry->kind = lookupKindFromName (path, value);
if (entry->kind == NULL)
{
kindOption *fileKind = getInputLanguageFileKind ();
kindDefinition *fileKind = getInputLanguageFileKind ();
if (fileKind && (strcmp(fileKind->name, value) == 0))
/* ctags will make a tag for file. */
goto reject;

View File

@ -23,25 +23,22 @@
static void simpleXpathMakeTag (xmlNode *node,
const tagXpathMakeTagSpec *spec,
const kindOption* const kinds,
const kindDefinition* const kinds,
void *userData)
{
tagEntryInfo tag;
xmlChar* str;
const kindOption *kind;
char *path;
str = xmlNodeGetContent(node);
if (str == NULL)
return;
kind = kinds + spec->kind;
if (spec->role == ROLE_INDEX_DEFINITION)
initTagEntry (&tag, (char *)str, kind);
initTagEntry (&tag, (char *)str, spec->kind);
else if (isXtagEnabled(XTAG_REFERENCE_TAGS))
initRefTagEntry (&tag, (char *)str,
kind,
spec->kind,
spec->role);
else
goto out;
@ -77,7 +74,7 @@ extern void addTagXpath (const langType language CTAGS_ATTR_UNUSED, tagXpathTabl
static void findXMLTagsCore (xmlXPathContext *ctx, xmlNode *root,
const tagXpathTableTable *xpathTableTable,
const kindOption* const kinds,void *userData)
const kindDefinition* const kinds,void *userData)
{
unsigned int i;
int j;
@ -156,7 +153,7 @@ static xmlDocPtr makeXMLDoc (void)
extern void findXMLTags (xmlXPathContext *ctx, xmlNode *root,
const tagXpathTableTable *xpathTableTable,
const kindOption* const kinds,void *userData)
const kindDefinition* const kinds,void *userData)
{
bool usedAsEntryPoint = false;
xmlDocPtr doc = NULL;
@ -210,7 +207,7 @@ extern void addTagXpath (const langType language, tagXpathTable *xpathTable)
extern void findXMLTags (xmlXPathContext *ctx, xmlNode *root,
const tagXpathTableTable *xpathTableTable,
const kindOption* const kinds, void *userData)
const kindDefinition* const kinds, void *userData)
{
}

1
ctags/main/mbcs.h Normal file
View File

@ -0,0 +1 @@
/* Dummy header - only included by some parsers */

View File

@ -48,7 +48,7 @@
#define xCalloc(n,Type) (Type *)eCalloc((size_t)(n), sizeof (Type))
#define xRealloc(p,n,Type) (Type *)eRealloc((p), (n) * sizeof (Type))
extern void *eMalloc (const size_t size)
static void *eMalloc (const size_t size)
{
void *buffer = malloc (size);
@ -61,7 +61,7 @@ extern void *eMalloc (const size_t size)
return buffer;
}
extern void *eCalloc (const size_t count, const size_t size)
static void *eCalloc (const size_t count, const size_t size)
{
void *buffer = calloc (count, size);
@ -74,7 +74,7 @@ extern void *eCalloc (const size_t count, const size_t size)
return buffer;
}
extern void *eRealloc (void *const ptr, const size_t size)
static void *eRealloc (void *const ptr, const size_t size)
{
void *buffer;
if (ptr == NULL)
@ -91,13 +91,13 @@ extern void *eRealloc (void *const ptr, const size_t size)
return buffer;
}
extern void eFree (void *const ptr)
static void eFree (void *const ptr)
{
free (ptr);
}
# define Assert(c)
# define AssertNotReached()
# define Assert(c) do {} while(0)
# define AssertNotReached() do {} while(0)
#endif
/* minimal reallocation chunk size */
@ -361,12 +361,12 @@ MIO *mio_new_memory (unsigned char *data,
* @size: the length of the data copied from @base to new mio
*
* Creates a new #MIO object by copying data from existing #MIO (@base).
* The range for copying are given with @start and @size.
* The range for copying is given with @start and @size.
* Copying data at the range from @start to the end of @base is
* done if 0 is given as @size.
* done if -1 is given as @size.
*
* If @size(!= 0) is larger than the length from @start to the end of
* @base, %NULL is return.
* If @size is larger than the length from @start to the end of
* @base, %NULL is returned.
*
* The function doesn't move the file position of @base.
*
@ -374,7 +374,7 @@ MIO *mio_new_memory (unsigned char *data,
*
*/
MIO *mio_new_mio (MIO *base, long start, size_t size)
MIO *mio_new_mio (MIO *base, long start, long size)
{
unsigned char *data;
long original_pos;
@ -383,15 +383,15 @@ MIO *mio_new_mio (MIO *base, long start, size_t size)
original_pos = mio_tell (base);
if (size == 0)
if (size == -1)
{
long end;
if (mio_seek (base, 0, SEEK_END) != 0)
return NULL;
end = mio_tell (base);
Assert (end >= start);
size = end - start;
Assert (size >= 0);
}
if (mio_seek (base, start, SEEK_SET) != 0)
@ -732,7 +732,7 @@ size_t mio_write (MIO *mio,
* Writes a character to a #MIO stream. This function behaves the same as
* fputc().
*
* Returns: The written wharacter, or %EOF on error.
* Returns: The written character, or %EOF on error.
*/
int mio_putc (MIO *mio, int c)
{
@ -796,7 +796,7 @@ int mio_puts (MIO *mio, const char *s)
/**
* mio_vprintf:
* @mio: A #MIO object
* @format: A printf fomrat string
* @format: A printf format string
* @ap: The variadic argument list for the format
*
* Writes a formatted string into a #MIO stream. This function behaves the same
@ -1100,7 +1100,7 @@ int mio_error (MIO *mio)
* SEEK_CUR from the current position and SEEK_SET from the end of the
* stream.
*
* Sets the curosr position on a #MIO stream. This functions behaves the same as
* Sets the cursor position on a #MIO stream. This functions behaves the same as
* fseek(). See also mio_tell() and mio_setpos().
*
* Returns: 0 on success, -1 otherwise, in which case errno should be set to

View File

@ -123,7 +123,7 @@ MIO *mio_new_memory (unsigned char *data,
MIOReallocFunc realloc_func,
MIODestroyNotify free_func);
MIO *mio_new_mio (MIO *base, long start, size_t size);
MIO *mio_new_mio (MIO *base, long start, long size);
MIO *mio_ref (MIO *mio);
int mio_free (MIO *mio);

175
ctags/main/numarray.c Normal file
View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 1999-2002, Darren Hiebert
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* This module contains functions managing resizable pointer arrays.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "debug.h"
#include "numarray.h"
#include "routines.h"
#include <stdlib.h>
#include <string.h>
#define impNumArray(prefix,Prefix,type) \
\
struct s##Prefix##Array { \
unsigned int max; \
unsigned int count; \
type *array; \
}; \
\
extern prefix##Array *prefix##ArrayNew (void) \
{ \
prefix##Array* const result = xMalloc (1, prefix##Array); \
result->max = 8; \
result->count = 0; \
result->array = xMalloc (result->max, type); \
return result; \
} \
\
extern void prefix##ArrayAdd (prefix##Array *const current, type num) \
{ \
Assert (current != NULL); \
if (current->count == current->max) \
{ \
current->max *= 2; \
current->array = xRealloc (current->array, current->max, type); \
} \
current->array [current->count++] = num; \
} \
\
extern void prefix##ArrayRemoveLast (prefix##Array *const current) \
{ \
Assert (current != NULL); \
Assert (current->count > 0); \
--current->count; \
} \
\
extern void prefix##ArrayCombine (prefix##Array *const current, prefix##Array *const from) \
{ \
unsigned int i; \
Assert (current != NULL); \
Assert (from != NULL); \
for (i = 0 ; i < from->count ; ++i) \
prefix##ArrayAdd (current, from->array [i]); \
from->count = 0; \
prefix##ArrayDelete (from); \
} \
\
extern unsigned int prefix##ArrayCount (const prefix##Array *const current) \
{ \
Assert (current != NULL); \
return current->count; \
} \
\
extern type prefix##ArrayItem (const prefix##Array *const current, const unsigned int indx) \
{ \
Assert (current != NULL); \
return current->array [indx]; \
} \
\
extern type prefix##ArrayLast (const prefix##Array *const current) \
{ \
Assert (current != NULL); \
Assert (current->count > 0); \
return current->array [current->count - 1]; \
} \
\
extern void prefix##ArrayClear (prefix##Array *const current) \
{ \
Assert (current != NULL); \
current->count = 0; \
} \
\
extern void prefix##ArrayDelete (prefix##Array *const current) \
{ \
if (current != NULL) \
{ \
prefix##ArrayClear (current); \
eFree (current->array); \
eFree (current); \
} \
} \
\
extern bool prefix##ArrayHasTest (const prefix##Array *const current, \
bool (*test)(const type num, void *userData), \
void *userData) \
{ \
bool result = false; \
unsigned int i; \
Assert (current != NULL); \
for (i = 0 ; ! result && i < current->count ; ++i) \
result = (*test)(current->array [i], userData); \
return result; \
} \
\
static bool prefix##Eq (const type num, void *userData) \
{ \
type *num0 = userData; \
return (num == *num0); \
} \
\
extern bool prefix##ArrayHas (const prefix##Array *const current, type num) \
{ \
return prefix##ArrayHasTest (current, prefix##Eq, &num); \
} \
\
extern void prefix##ArrayReverse (const prefix##Array *const current) \
{ \
unsigned int i, j; \
type tmp; \
\
Assert (current != NULL); \
for (i = 0, j = current->count - 1 ; i < (current->count / 2); ++i, --j) \
{ \
tmp = current->array[i]; \
current->array[i] = current->array[j]; \
current->array[j] = tmp; \
} \
} \
\
extern void prefix##ArrayDeleteItem (prefix##Array* const current, unsigned int indx) \
{ \
memmove (current->array + indx, current->array + indx + 1, \
(current->count - indx) * sizeof (*current->array)); \
--current->count; \
} \
static int prefix##GreaterThan(const void *a, const void *b) \
{ \
type an = *(type *)a; \
type bn = *(type *)b; \
if (an > bn) \
return 1; \
else if (an == bn) \
return 0; \
else \
return -1; \
} \
static int prefix##LessThan(const void *a, const void *b) \
{ \
return prefix##GreaterThan (b, a); \
} \
extern void prefix##ArraySort (prefix##Array *const current, bool descendingOrder) \
{ \
if (descendingOrder) \
qsort (current->array, current->count, sizeof (type), prefix##GreaterThan); \
else \
qsort (current->array, current->count, sizeof (type), prefix##LessThan); \
}
/* We expect the linker we use is enough clever to delete dead code. */
impNumArray(char, Char, char);
impNumArray(uchar, Uchar, unsigned char);
impNumArray(int, Int, int);
impNumArray(uint, Uint, unsigned int);
impNumArray(long, Long, long);
impNumArray(ulong, Ulong, unsigned long);

48
ctags/main/numarray.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 1999-2002, Darren Hiebert
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* Defines external interface to resizable pointer arrays.
*/
#ifndef CTAGS_MAIN_NUMARRAY_H
#define CTAGS_MAIN_NUMARRAY_H
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#define declNumArray(prefix,Prefix,type) \
\
struct s##Prefix##Array; \
typedef struct s##Prefix##Array prefix##Array; \
\
extern prefix##Array *prefix##ArrayNew (void); \
extern void prefix##ArrayAdd (prefix##Array *const current, type num); \
extern void prefix##ArrayRemoveLast (prefix##Array *const current); \
extern void prefix##ArrayCombine (prefix##Array *const current, prefix##Array *const from); \
extern void prefix##ArrayClear (prefix##Array *const current); \
extern unsigned int prefix##ArrayCount (const prefix##Array *const current); \
extern type prefix##ArrayItem (const prefix##Array *const current, const unsigned int indx); \
extern type prefix##ArrayLast (const prefix##Array *const current); \
extern void prefix##ArrayDelete (prefix##Array *const current); \
extern bool prefix##ArrayHasTest (const prefix##Array *const current, \
bool (*test)(const type num, void *userData), \
void *userData); \
extern bool prefix##ArrayHas (const prefix##Array *const current, type num); \
extern void prefix##ArrayReverse (const prefix##Array *const current); \
extern void prefix##ArrayDeleteItem (prefix##Array* const current, unsigned int indx); \
\
extern void prefix##ArraySort (prefix##Array *const current, bool descendingOrder);
declNumArray(char, Char, char);
declNumArray(uchar, Uchar, unsigned char);
declNumArray(int, Int, int);
declNumArray(uint, Uint, unsigned int);
declNumArray(long, Long, long);
declNumArray(ulong, Ulong, unsigned long);
#endif /* CTAGS_MAIN_NUMARRAY_H */

View File

@ -26,13 +26,15 @@ struct sObjPool {
objPoolCreateFunc createFunc;
objPoolDeleteFunc deleteFunc;
objPoolClearFunc clearFunc;
void *createArg;
};
/*
* FUNCTION DEFINITIONS
*/
extern objPool *objPoolNew (unsigned int size,
objPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc)
objPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc,
void *createArg)
{
objPool* const result = xMalloc (1, objPool);
result->array = ptrArrayNew (deleteFunc);
@ -40,6 +42,7 @@ extern objPool *objPoolNew (unsigned int size,
result->createFunc = createFunc;
result->deleteFunc = deleteFunc;
result->clearFunc = clearFunc;
result->createArg = createArg;
return result;
}
@ -59,7 +62,7 @@ extern void *objPoolGet (objPool *pool)
ptrArrayRemoveLast (pool->array);
}
else
obj = pool->createFunc ();
obj = pool->createFunc (pool->createArg);
if (pool->clearFunc)
pool->clearFunc (obj);

View File

@ -20,7 +20,7 @@
/*
* DATA DECLARATIONS
*/
typedef void * (*objPoolCreateFunc) (void);
typedef void * (*objPoolCreateFunc) (void *createArg);
typedef void (*objPoolDeleteFunc) (void *data);
typedef void (*objPoolClearFunc) (void *data);
@ -31,7 +31,8 @@ typedef struct sObjPool objPool;
* FUNCTION PROTOTYPES
*/
extern objPool *objPoolNew (unsigned int size,
objPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc);
objPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc,
void *createArg);
extern void objPoolDelete (objPool *pool);
extern void *objPoolGet (objPool *pool);
extern void objPoolPut (objPool *pool, void *obj);

View File

@ -1759,7 +1759,7 @@ static void processListExtraOption (
exit (0);
}
static void processListFileKindOption (
static void processListFileKindDefinition (
const char *const option, const char *const parameter)
{
if (parameter [0] == '\0' || strcasecmp (parameter, "all") == 0)
@ -2556,7 +2556,7 @@ static parametricOption ParametricOptions [] = {
{ "list-extra", processListExtraOption, true, STAGE_ANY },
{ "list-features", processListFeaturesOption, true, STAGE_ANY },
{ "list-fields", processListFieldsOption, true, STAGE_ANY },
{ "list-file-kind", processListFileKindOption, true, STAGE_ANY },
{ "list-file-kind", processListFileKindDefinition, true, STAGE_ANY },
{ "list-kinds", processListKindsOption, true, STAGE_ANY },
{ "list-kinds-full", processListKindsOption, true, STAGE_ANY },
{ "list-languages", processListLanguagesOption, true, STAGE_ANY },
@ -2816,7 +2816,7 @@ static void processLongOption (
;
else if (processParametricOption (option, parameter))
;
else if (processKindOption (option, parameter))
else if (processKindDefinition (option, parameter))
;
else if (processAliasOption (option, parameter))
;
@ -3484,3 +3484,8 @@ extern void verbose (const char *const format, ...)
{
}
/* GEANY DIFF END */
extern bool canUseLineNumberAsLocator (void)
{
return (Option.locate != EX_PATTERN);
}

View File

@ -180,7 +180,7 @@ extern langType getLanguageComponentInOption (const char *const option,
extern void processLanguageDefineOption (const char *const option, const char *const parameter);
extern bool processMapOption (const char *const option, const char *const parameter);
extern bool processKindOption (const char *const option, const char *const parameter);
extern bool processKindDefinition (const char *const option, const char *const parameter);
extern bool processCorpusOption (const char *const option, const char *const parameter);
extern bool processAliasOption (const char *const option, const char *const parameter);
#ifdef HAVE_ICONV
@ -192,4 +192,7 @@ extern bool processXcmdOption (const char *const option, const char *const param
typedef void (* mainLoopFunc) (cookedArgs *args, void *data);
extern void setMainLoop (mainLoopFunc func, void *data);
/* This is for emitting a tag for a commnn block of Fortran parser*/
extern bool canUseLineNumberAsLocator (void);
#endif /* CTAGS_MAIN_OPTIONS_H */

View File

@ -27,6 +27,7 @@
#include "ptag.h"
#include "read.h"
#include "routines.h"
#include "trashbox.h"
#include "vstring.h"
#ifdef HAVE_ICONV
# include "mbcs.h"
@ -53,6 +54,8 @@ typedef struct {
enum specType specType;
} parserCandidate;
static ptrArray *parsersUsedInCurrentInput;
/*
* FUNCTION PROTOTYPES
*/
@ -63,6 +66,8 @@ static void addParserPseudoTags (langType language);
static void installKeywordTable (const langType language);
static void installTagRegexTable (const langType language);
static void installTagXpathTable (const langType language);
static void anonResetMaybe (parserDefinition *lang);
static void clearParsersUsedInCurrentInput (void);
/*
* DATA DEFINITIONS
@ -88,7 +93,7 @@ static parserDefinitionFunc* BuiltInParsers[] = {
};
static parserDefinition** LanguageTable = NULL;
static unsigned int LanguageCount = 0;
static kindOption defaultFileKind = {
static kindDefinition defaultFileKind = {
.enabled = false,
.letter = KIND_FILE_DEFAULT,
.name = KIND_FILE_DEFAULT_LONG,
@ -105,21 +110,21 @@ extern unsigned int countParsers (void)
}
extern int makeSimpleTag (
const vString* const name, kindOption* const kinds, const int kind)
const vString* const name, const int kindIndex)
{
int r = CORK_NIL;
if (kinds [kind].enabled && name != NULL && vStringLength (name) > 0)
if (isInputLanguageKindEnabled(kindIndex) && name != NULL && vStringLength (name) > 0)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), & kinds [kind]);
initTagEntry (&e, vStringValue (name), kindIndex);
r = makeTagEntry (&e);
}
return r;
}
extern int makeSimpleRefTag (const vString* const name, kindOption* const kinds, const int kind,
extern int makeSimpleRefTag (const vString* const name, const int kindIndex,
int roleIndex)
{
int r = CORK_NIL;
@ -127,12 +132,13 @@ extern int makeSimpleRefTag (const vString* const name, kindOption* const kinds,
if (! isXtagEnabled (XTAG_REFERENCE_TAGS))
return r;
Assert (roleIndex < kinds[kind].nRoles);
Assert (roleIndex < countInputLanguageRoles(kindIndex));
if (kinds[kind].roles[roleIndex].enabled)
/* do not check for kind being disabled - that happens later in makeTagEntry() */
if (name != NULL && vStringLength (name) > 0)
{
tagEntryInfo e;
initRefTagEntry (&e, vStringValue (name), & kinds [kind], roleIndex);
initRefTagEntry (&e, vStringValue (name), kindIndex, roleIndex);
r = makeTagEntry (&e);
}
@ -151,7 +157,7 @@ extern bool isLanguageEnabled (const langType language)
if ((lang->method & METHOD_XCMD) &&
(!(lang->method & METHOD_XCMD_AVAILABLE)) &&
(lang->kinds == NULL) &&
(lang->kindTable == NULL) &&
(!(lang->method & METHOD_REGEX)) &&
(!(lang->method & METHOD_XPATH)))
return false;
@ -168,11 +174,11 @@ extern parserDefinition* parserNew (const char* name)
return parserNewFull (name, 0);
}
static kindOption* fileKindNew (char letter)
static kindDefinition* fileKindNew (char letter)
{
kindOption *fileKind;
kindDefinition *fileKind;
fileKind = xMalloc (1, kindOption);
fileKind = xMalloc (1, kindDefinition);
*(fileKind) = defaultFileKind;
fileKind->letter = letter;
return fileKind;
@ -216,9 +222,9 @@ extern const char *getLanguageName (const langType language)
return result;
}
extern kindOption* getLanguageFileKind (const langType language)
extern kindDefinition* getLanguageFileKind (const langType language)
{
kindOption* kind;
kindDefinition* kind;
Assert (0 <= language && language < (int) LanguageCount);
@ -229,6 +235,13 @@ extern kindOption* getLanguageFileKind (const langType language)
return kind;
}
extern kindDefinition* getLanguageKind (const langType language, int kindIndex)
{
Assert (0 <= language && language < (int) LanguageCount);
return (LanguageTable [language]->kindTable) + kindIndex;
}
extern langType getNamedLanguage (const char *const name, size_t len)
{
langType result = LANG_IGNORE;
@ -724,7 +737,7 @@ struct getLangCtx {
(mio_memory_get_data((_glc_)->input, NULL) == NULL)) \
{ \
MIO *tmp_ = (_glc_)->input; \
(_glc_)->input = mio_new_mio (tmp_, 0, 0); \
(_glc_)->input = mio_new_mio (tmp_, 0, -1); \
mio_free (tmp_); \
if (!(_glc_)->input) { \
(_glc_)->err = true; \
@ -1148,6 +1161,28 @@ extern langType getFileLanguage (const char *const fileName)
return getFileLanguageAndKeepMIO(fileName, NULL);
}
extern langType getLanguageForCommand (const char *const command, langType startFrom)
{
const char *const tmp_command = baseFilename (command);
char *tmp_spec;
enum specType tmp_specType;
return getNameOrAliasesLanguageAndSpec (tmp_command, startFrom,
(const char **const)&tmp_spec,
&tmp_specType);
}
extern langType getLanguageForFilename (const char *const filename, langType startFrom)
{
const char *const tmp_filename = baseFilename (filename);
char *tmp_spec;
enum specType tmp_specType;
return getPatternLanguageAndSpec (tmp_filename, startFrom,
(const char **const)&tmp_spec,
&tmp_specType);
}
typedef void (*languageCallback) (langType language, void* user_data);
static void foreachLanguage(languageCallback callback, void *user_data)
{
@ -1384,21 +1419,21 @@ static bool doesParserUseKind (const parserDefinition *const parser, char letter
}
#endif
static void installFieldSpec (const langType language)
static void installFieldDefinition (const langType language)
{
unsigned int i;
parserDefinition * parser;
Assert (0 <= language && language < (int) LanguageCount);
parser = LanguageTable [language];
if (parser->fieldSpecCount > PRE_ALLOCATED_PARSER_FIELDS)
if (parser->fieldCount > PRE_ALLOCATED_PARSER_FIELDS)
error (FATAL,
"INTERNAL ERROR: in a parser, fields are defined more than PRE_ALLOCATED_PARSER_FIELDS\n");
if (parser->fieldSpecs != NULL)
if (parser->fieldTable != NULL)
{
for (i = 0; i < parser->fieldSpecCount; i++)
defineField (& parser->fieldSpecs [i], language);
for (i = 0; i < parser->fieldCount; i++)
defineField (& parser->fieldTable [i], language);
}
}
@ -1415,7 +1450,7 @@ static void initializeParserOne (langType lang)
installKeywordTable (lang);
installTagRegexTable (lang);
installTagXpathTable (lang);
installFieldSpec (lang);
installFieldDefinition (lang);
if (hasScopeActionInRegex (lang)
|| parser->requestAutomaticFQTag)
@ -1613,45 +1648,36 @@ extern void processLanguageDefineOption (
}
}
static kindOption *langKindOption (const langType language, const int flag)
static kindDefinition *langKindDefinition (const langType language, const int flag)
{
unsigned int i;
kindOption* result = NULL;
kindDefinition* result = NULL;
const parserDefinition* lang;
Assert (0 <= language && language < (int) LanguageCount);
lang = LanguageTable [language];
for (i=0 ; i < lang->kindCount && result == NULL ; ++i)
if (lang->kinds [i].letter == flag)
result = &lang->kinds [i];
if (lang->kindTable [i].letter == flag)
result = &lang->kindTable [i];
return result;
}
static kindOption *langKindLongOption (const langType language, const char *kindLong)
static kindDefinition *langKindLongOption (const langType language, const char *kindLong)
{
unsigned int i;
kindOption* result = NULL;
kindDefinition* result = NULL;
const parserDefinition* lang;
Assert (0 <= language && language < (int) LanguageCount);
lang = LanguageTable [language];
for (i=0 ; i < lang->kindCount && result == NULL ; ++i)
if (strcmp (lang->kinds [i].name, kindLong) == 0)
result = &lang->kinds [i];
if (strcmp (lang->kindTable [i].name, kindLong) == 0)
result = &lang->kindTable [i];
return result;
}
extern bool isLanguageKindEnabled (const langType language, char kind)
extern bool isLanguageKindEnabled (const langType language, int kindIndex)
{
const kindOption *kindOpt;
if (hasRegexKind (language, kind))
return isRegexKindEnabled (language, kind);
else if (hasXcmdKind (language, kind))
return isXcmdKindEnabled (language, kind);
kindOpt = langKindOption (language, kind);
Assert (kindOpt);
return kindOpt->enabled;
kindDefinition * kdef = getLanguageKind (language, kindIndex);
return kdef->enabled;
}
@ -1666,7 +1692,7 @@ static void resetLanguageKinds (const langType language, const bool mode)
{
unsigned int i;
for (i = 0 ; i < lang->kindCount ; ++i)
enableKind (lang->kinds + i, mode);
enableKind (lang->kindTable + i, mode);
}
}
@ -1674,7 +1700,7 @@ static bool enableLanguageKind (
const langType language, const int kind, const bool mode)
{
bool result = false;
kindOption* const opt = langKindOption (language, kind);
kindDefinition* const opt = langKindDefinition (language, kind);
if (opt != NULL)
{
enableKind (opt, mode);
@ -1689,7 +1715,7 @@ static bool enableLanguageKindLong (
const langType language, const char * const kindLong, const bool mode)
{
bool result = false;
kindOption* const opt = langKindLongOption (language, kindLong);
kindDefinition* const opt = langKindLongOption (language, kindLong);
if (opt != NULL)
{
enableKind (opt, mode);
@ -1700,7 +1726,7 @@ static bool enableLanguageKindLong (
return result;
}
static void processLangKindOption (
static void processLangKindDefinition (
const langType language, const char *const option,
const char *const parameter)
{
@ -1777,25 +1803,25 @@ static void processLangKindOption (
}
}
struct langKindOptionStruct {
struct langKindDefinitionStruct {
const char *const option;
const char *const parameter;
};
static void processLangKindOptionEach(
static void processLangKindDefinitionEach(
langType lang, void* user_data)
{
struct langKindOptionStruct *arg = user_data;
processLangKindOption (lang, arg->option, arg->parameter);
struct langKindDefinitionStruct *arg = user_data;
processLangKindDefinition (lang, arg->option, arg->parameter);
}
extern bool processKindOption (
extern bool processKindDefinition (
const char *const option, const char *const parameter)
{
#define PREFIX "kinds-"
#define PREFIX_LEN strlen(PREFIX)
bool handled = false;
struct langKindOptionStruct arg = {
struct langKindDefinitionStruct arg = {
.option = option,
.parameter = parameter,
};
@ -1808,7 +1834,7 @@ extern bool processKindOption (
size_t len = dash - option;
if ((len == 1) && (*option == '*'))
foreachLanguage(processLangKindOptionEach, &arg);
foreachLanguage(processLangKindDefinitionEach, &arg);
else
{
vString* langName = vStringNew ();
@ -1817,7 +1843,7 @@ extern bool processKindOption (
if (language == LANG_IGNORE)
error (WARNING, "Unknown language \"%s\" in \"%s\" option", vStringValue (langName), option);
else
processLangKindOption (language, option, parameter);
processLangKindDefinition (language, option, parameter);
vStringDelete (langName);
}
handled = true;
@ -1833,7 +1859,7 @@ extern bool processKindOption (
error (WARNING, "No language given in \"%s\" option", option);
else if (len == 1 && lang[0] == '*')
{
foreachLanguage(processLangKindOptionEach, &arg);
foreachLanguage(processLangKindDefinitionEach, &arg);
handled = true;
}
else
@ -1843,7 +1869,7 @@ extern bool processKindOption (
error (WARNING, "Unknown language \"%s\" in \"%s\" option", lang, option);
else
{
processLangKindOption (language, option, parameter);
processLangKindDefinition (language, option, parameter);
handled = true;
}
}
@ -1865,15 +1891,15 @@ static void printRoles (const langType language, const char* letters, bool allow
for (c = letters; *c != '\0'; c++)
{
unsigned int i;
const kindOption *k;
const kindDefinition *k;
for (i = 0; i < lang->kindCount; ++i)
{
k = lang->kinds + i;
k = lang->kindTable + i;
if (*c == KIND_WILDCARD || k->letter == *c)
{
int j;
const roleDesc *r;
const roleDefinition *r;
for (j = 0; j < k->nRoles; j++)
{
@ -1925,14 +1951,14 @@ static void printKinds (langType language, bool allKindFields, bool indent)
initializeParser (language);
lang = LanguageTable [language];
if (lang->kinds != NULL)
if (lang->kindTable != NULL)
{
unsigned int i;
for (i = 0 ; i < lang->kindCount ; ++i)
{
if (allKindFields && indent)
printf (Option.machinable? "%s": PR_KIND_FMT (LANG,s), lang->name);
printKind (lang->kinds + i, allKindFields, indent, Option.machinable);
printKind (lang->kindTable + i, allKindFields, indent, Option.machinable);
}
}
printRegexKinds (language, allKindFields, indent, Option.machinable);
@ -2095,7 +2121,7 @@ static void printLanguage (const langType language, parserDefinition** ltable)
if (lang->method & METHOD_XCMD)
initializeParser (lang->id);
if (lang->kinds != NULL || (lang->method & METHOD_REGEX) || (lang->method & METHOD_XCMD))
if (lang->kindTable != NULL || (lang->method & METHOD_REGEX) || (lang->method & METHOD_XCMD))
printf ("%s%s\n", lang->name, isLanguageEnabled (lang->id) ? "" : " [disabled]");
}
@ -2153,6 +2179,8 @@ static bool createTagsWithFallback1 (const langType language)
addParserPseudoTags (language);
tagFilePosition (&tagfpos);
anonResetMaybe (LanguageTable [language]);
while ( ( whyRescan =
createTagsForFile (language, ++passCount) )
!= RESCAN_NONE)
@ -2199,6 +2227,8 @@ static bool createTagsWithFallback1 (const langType language,
if (LanguageTable [language]->useCork)
corkTagFile();
anonResetMaybe (LanguageTable [language]);
passCallback(userData);
while ( ( whyRescan =
createTagsForFile (language, ++passCount) )
@ -2284,10 +2314,13 @@ extern void createTagsWithFallback(unsigned char *buffer, size_t bufferSize,
if ((!buffer && openInputFile (fileName, language, NULL)) ||
(buffer && bufferOpen (fileName, language, buffer, bufferSize)))
{
initParserTrashBox ();
clearParsersUsedInCurrentInput ();
setTagEntryFunction(tagCallback, userData);
createTagsWithFallback1 (language, passCallback, userData);
forcePromises ();
closeInputFile ();
finiParserTrashBox ();
}
else
error (WARNING, "Unable to open %s", fileName);
@ -2459,6 +2492,9 @@ extern bool parseFile (const char *const fileName)
#endif
setupWriter ();
clearParsersUsedInCurrentInput ();
#ifndef CTAGS_LIB
tagFileResized = createTagsWithFallback (fileName, language, mio);
#endif
@ -2581,7 +2617,7 @@ extern bool makeKindSeparatorsPseudoTags (const langType language,
const ptagDesc *pdesc)
{
parserDefinition* lang;
kindOption *kinds;
kindDefinition *kinds;
unsigned int kindCount;
unsigned int i, j;
@ -2589,7 +2625,7 @@ extern bool makeKindSeparatorsPseudoTags (const langType language,
Assert (0 <= language && language < (int) LanguageCount);
lang = LanguageTable [language];
kinds = lang->kinds;
kinds = lang->kindTable;
kindCount = lang->kindCount;
if (kinds == NULL)
@ -2605,17 +2641,17 @@ extern bool makeKindSeparatorsPseudoTags (const langType language,
for (j = 0; j < kinds[i].separatorCount; ++j)
{
char name[5] = {[0] = '/', [3] = '/', [4] = '\0'};
const kindOption *upperKind;
const kindDefinition *upperKind;
const scopeSeparator *sep;
sep = kinds[i].separators + j;
if (sep->parentLetter == KIND_WILDCARD)
if (sep->parentKindIndex == KIND_WILDCARD_INDEX)
{
name[1] = KIND_WILDCARD;
name[2] = kinds[i].letter;
}
else if (sep->parentLetter == KIND_NULL)
else if (sep->parentKindIndex == KIND_GHOST_INDEX)
{
/* This is root separator: no upper item is here. */
name[1] = kinds[i].letter;
@ -2624,8 +2660,8 @@ extern bool makeKindSeparatorsPseudoTags (const langType language,
}
else
{
upperKind = langKindOption (language,
sep->parentLetter);
upperKind = langKindDefinition (language,
sep->parentKindIndex);
if (!upperKind)
continue;
@ -2651,7 +2687,7 @@ struct makeKindDescriptionPseudoTagData {
bool written;
};
static bool makeKindDescriptionPseudoTag (kindOption *kind,
static bool makeKindDescriptionPseudoTag (kindDefinition *kind,
void *user_data)
{
struct makeKindDescriptionPseudoTagData *data = user_data;
@ -2685,13 +2721,13 @@ extern bool makeKindDescriptionsPseudoTags (const langType language,
{
parserDefinition* lang;
kindOption *kinds;
kindDefinition *kinds;
unsigned int kindCount, i;
struct makeKindDescriptionPseudoTagData data;
Assert (0 <= language && language < (int) LanguageCount);
lang = LanguageTable [language];
kinds = lang->kinds;
kinds = lang->kindTable;
kindCount = lang->kindCount;
data.langName = lang->name;
@ -2716,12 +2752,25 @@ extern bool makeKindDescriptionsPseudoTags (const langType language,
* Anonymous name generator
*/
extern void anonReset (void)
static void clearParsersUsedInCurrentInput (void)
{
parserDefinition* lang = LanguageTable [getInputLanguage ()];
lang -> anonumousIdentiferId = 0;
if (parsersUsedInCurrentInput)
ptrArrayClear (parsersUsedInCurrentInput);
else
parsersUsedInCurrentInput = ptrArrayNew (NULL);
}
static void anonResetMaybe (parserDefinition *lang)
{
if (ptrArrayHas (parsersUsedInCurrentInput, lang))
return;
lang -> anonumousIdentiferId = 0;
ptrArrayAdd (parsersUsedInCurrentInput, lang);
}
/* GEANY DIFF */
#if 0
static unsigned int anonHash(const unsigned char *str)
{
unsigned int hash = 5381;
@ -2732,6 +2781,8 @@ static unsigned int anonHash(const unsigned char *str)
return hash ;
}
#endif
/* GEANY DIFF END */
extern void anonGenerate (vString *buffer, const char *prefix, int kind)
{
@ -2742,8 +2793,12 @@ extern void anonGenerate (vString *buffer, const char *prefix, int kind)
vStringCopyS(buffer, prefix);
unsigned int uHash = anonHash((const unsigned char *)getInputFileName());
sprintf(szNum,"%08x%02x%02x",uHash,lang -> anonumousIdentiferId, kind);
/* GEANY DIFF */
/* unsigned int uHash = anonHash((const unsigned char *)getInputFileName());
sprintf(szNum,"%08x%02x%02x",uHash,lang -> anonumousIdentiferId, kind); */
sprintf(szNum,"%u", lang -> anonumousIdentiferId);
/* GEANY DIFF END */
vStringCatS(buffer,szNum);
}
@ -2760,11 +2815,11 @@ typedef enum {
R_BROKEN_REF,
} CTST_BrokenRole;
static roleDesc CTST_BrokenRoles [] = {
static roleDefinition CTST_BrokenRoles [] = {
{true, "broken", "broken" },
};
static kindOption CTST_Kinds[KIND_COUNT] = {
static kindDefinition CTST_Kinds[KIND_COUNT] = {
{true, 'b', "broken tag", "name with unwanted characters",
.referenceOnly = false, ATTACH_ROLES (CTST_BrokenRoles) },
};
@ -2785,7 +2840,7 @@ static void createCTSTTags (void)
switch (i)
{
case K_BROKEN:
initTagEntry (&e, "one\nof\rbroken\tname", &CTST_Kinds[i]);
initTagEntry (&e, "one\nof\rbroken\tname", i);
e.extensionFields.scopeKind = & (CTST_Kinds [K_BROKEN]);
e.extensionFields.scopeName = "\\Broken\tContext";
makeTagEntry (&e);
@ -2801,7 +2856,7 @@ static parserDefinition *CTagsSelfTestParser (void)
static const char *const extensions[] = { NULL };
parserDefinition *const def = parserNew ("CTagsSelfTest");
def->extensions = extensions;
def->kinds = CTST_Kinds;
def->kindTable = CTST_Kinds;
def->kindCount = KIND_COUNT;
def->parser = createCTSTTags;
def->invisible = true;

View File

@ -127,9 +127,9 @@ typedef struct {
struct sParserDefinition {
/* defined by parser */
char* name; /* name of language */
kindOption* kinds; /* tag kinds handled by parser */
kindDefinition* kindTable; /* tag kinds handled by parser */
unsigned int kindCount; /* size of `kinds' list */
kindOption* fileKind; /* kind for overriding the default fileKind */
kindDefinition* fileKind; /* kind for overriding the default fileKind */
const char *const *extensions; /* list of default extensions */
const char *const *patterns; /* list of default file name patterns */
const char *const *aliases; /* list of default aliases (alternative names) */
@ -149,8 +149,8 @@ struct sParserDefinition {
tagXpathTableTable *tagXpathTableTable;
unsigned int tagXpathTableCount;
bool invisible;
fieldSpec *fieldSpecs;
unsigned int fieldSpecCount;
fieldDefinition *fieldTable;
unsigned int fieldCount;
parserDependency * dependencies;
unsigned int dependencyCount;
@ -204,19 +204,22 @@ extern parserDefinitionFunc YAML_PARSER_LIST;
/* Language processing and parsing */
extern int makeSimpleTag (const vString* const name, kindOption* const kinds, const int kind);
extern int makeSimpleRefTag (const vString* const name, kindOption* const kinds, const int kind,
extern int makeSimpleTag (const vString* const name, const int kind);
extern int makeSimpleRefTag (const vString* const name, const int kindIndexS,
int roleIndex);
extern parserDefinition* parserNew (const char* name);
extern parserDefinition* parserNewFull (const char* name, char fileKind);
extern kindDefinition* getLanguageKind(const langType language, int kindIndex);
extern bool doesLanguageAllowNullTag (const langType language);
extern bool doesLanguageRequestAutomaticFQTag (const langType language);
extern const char *getLanguageName (const langType language);
extern kindOption* getLanguageFileKind (const langType language);
extern kindDefinition* getLanguageFileKind (const langType language);
extern langType getNamedLanguage (const char *const name, size_t len);
extern langType getFileLanguage (const char *const fileName);
extern langType getLanguageForCommand (const char *const command, langType startFrom);
extern langType getLanguageForFilename (const char *const filename, langType startFrom);
extern bool isLanguageEnabled (const langType language);
extern bool isLanguageKindEnabled (const langType language, char kind);
extern bool isLanguageKindEnabled (const langType language, int kindIndex);
extern void installLanguageMapDefault (const langType language);
extern void installLanguageMapDefaults (void);
@ -282,7 +285,7 @@ extern bool isRegexKindEnabled (const langType language, const int kind);
extern bool hasRegexKind (const langType language, const int kind);
extern void printRegexKinds (const langType language, bool allKindFields, bool indent,
bool tabSeparated);
extern void foreachRegexKinds (const langType language, bool (* func) (kindOption*, void*), void *data);
extern void foreachRegexKinds (const langType language, bool (* func) (kindDefinition*, void*), void *data);
extern void freeRegexResources (void);
extern bool checkRegex (void);
extern void useRegexMethod (const langType language);
@ -301,7 +304,7 @@ extern bool isXcmdKindEnabled (const langType language, const int kind);
extern bool hasXcmdKind (const langType language, const int kind);
extern void printXcmdKinds (const langType language, bool allKindFields, bool indent,
bool tabSeparated);
extern void foreachXcmdKinds (const langType language, bool (* func) (kindOption*, void*), void *data);
extern void foreachXcmdKinds (const langType language, bool (* func) (kindDefinition*, void*), void *data);
extern void freeXcmdResources (void);
extern void useXcmdMethod (const langType language);
extern void notifyAvailabilityXcmdMethod (const langType language);
@ -309,7 +312,7 @@ extern void notifyAvailabilityXcmdMethod (const langType language);
/* Xpath interface */
extern void findXMLTags (xmlXPathContext *ctx, xmlNode *root,
const tagXpathTableTable *xpathTableTable,
const kindOption* const kinds, void *userData);
const kindDefinition* const kinds, void *userData);
extern void addTagXpath (const langType language, tagXpathTable *xpathTable);
@ -318,7 +321,6 @@ extern bool makeKindSeparatorsPseudoTags (const langType language,
extern bool makeKindDescriptionsPseudoTags (const langType language,
const ptagDesc *pdesc);
extern void anonReset (void);
extern void anonGenerate (vString *buffer, const char *prefix, int kind);
#endif /* CTAGS_MAIN_PARSE_H */

View File

@ -23,7 +23,7 @@
PerlParser, \
PhpParser, \
PythonParser, \
LaTeXParser, \
TexParser, \
AsmParser, \
ConfParser, \
SqlParser, \
@ -42,13 +42,13 @@
JavaScriptParser, \
HaskellParser, \
CsharpParser, \
FreeBasicParser,\
BasicParser,\
HaxeParser,\
RestParser, \
RstParser, \
HtmlParser, \
F77Parser, \
GLSLParser, \
MatlabParser, \
MatLabParser, \
ValaParser, \
ActionScriptParser, \
NsisParser, \

View File

@ -38,8 +38,12 @@ int makePromise (const char *parser,
int r;
langType lang;
/* GEANY DIFF */
/*
if (!isXtagEnabled (XTAG_TAGS_GENERATED_BY_SUB_PARSERS))
return -1;
*/
/* GEANY DIFF END */
lang = getNamedLanguage (parser, 0);
if (lang == LANG_IGNORE)

View File

@ -13,9 +13,11 @@
#include "general.h" /* must always come first */
#include <string.h>
#include <stdlib.h>
#include "debug.h"
#include "ptrarray.h"
#include "routines.h"
/*
* DATA DECLARATIONS
@ -125,6 +127,16 @@ extern bool ptrArrayHasTest (const ptrArray *const current,
return result;
}
static bool ptrEq (const void *ptr, void *userData)
{
return (ptr == userData);
}
extern bool ptrArrayHas (const ptrArray *const current, void *ptr)
{
return ptrArrayHasTest (current, ptrEq, ptr);
}
extern void ptrArrayReverse (const ptrArray *const current)
{
unsigned int i, j;
@ -150,3 +162,19 @@ extern void ptrArrayDeleteItem (ptrArray* const current, unsigned int indx)
(current->count - indx) * sizeof (*current->array));
--current->count;
}
static int (*ptrArraySortCompareVar)(const void *, const void *);
static int ptrArraySortCompare(const void *a0, const void *b0)
{
void *const *a = (void *const *)a0;
void *const *b = (void *const *)b0;
return ptrArraySortCompareVar (*a, *b);
}
extern void ptrArraySort (ptrArray *const current, int (*compare)(const void *, const void *))
{
ptrArraySortCompareVar = compare;
qsort (current->array, current->count, sizeof (void *), ptrArraySortCompare);
}

View File

@ -13,6 +13,7 @@
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "types.h"
/*
* DATA DECLARATIONS
@ -21,7 +22,6 @@
typedef void (*ptrArrayDeleteFunc) (void *data);
struct sPtrArray;
typedef struct sPtrArray ptrArray;
/*
* FUNCTION PROTOTYPES
@ -36,11 +36,13 @@ extern unsigned int ptrArrayCount (const ptrArray *const current);
extern void* ptrArrayItem (const ptrArray *const current, const unsigned int indx);
extern void* ptrArrayLast (const ptrArray *const current);
extern void ptrArrayDelete (ptrArray *const current);
extern bool ptrArrayHasInsensitive (const ptrArray *const current, const void *const ptr);
extern bool ptrArrayHasTest (const ptrArray *const current,
bool (*test)(const void *ptr, void *userData),
void *userData);
extern bool ptrArrayHas (const ptrArray *const current, void *ptr);
extern void ptrArrayReverse (const ptrArray *const current);
extern void ptrArrayDeleteItem (ptrArray* const current, unsigned int indx);
extern void ptrArraySort (ptrArray *const current, int (*compare)(const void *, const void *));
#endif /* CTAGS_MAIN_PTRARRAY_H */

View File

@ -108,6 +108,7 @@ typedef struct sInputFile {
inputLineFposMap lineFposMap;
} inputFile;
static langType sourceLang;
/*
* FUNCTION DECLARATIONS
@ -183,9 +184,9 @@ extern bool isInputHeaderFile (void)
return File.input.isHeader;
}
extern bool isInputLanguageKindEnabled (char c)
extern bool isInputLanguageKindEnabled (int kindIndex)
{
return isLanguageKindEnabled (getInputLanguage (), c);
return isLanguageKindEnabled (getInputLanguage (), kindIndex);
}
extern bool doesInputLanguageAllowNullTag (void)
@ -193,7 +194,7 @@ extern bool doesInputLanguageAllowNullTag (void)
return doesLanguageAllowNullTag (getInputLanguage ());
}
extern kindOption *getInputLanguageFileKind (void)
extern kindDefinition *getInputLanguageFileKind (void)
{
return getLanguageFileKind (getInputLanguage ());
}
@ -208,9 +209,9 @@ extern const char *getSourceFileTagPath (void)
return vStringValue (File.source.tagPath);
}
extern const char *getSourceLanguageName (void)
extern langType getSourceLanguage (void)
{
return getLanguageName (File.source.langInfo.type);
return sourceLang;
}
extern unsigned long getSourceLineNumber (void)
@ -370,6 +371,7 @@ static void setSourceFileParameters (vString *const fileName, const langType lan
setInputFileParametersCommon (&File.source, fileName,
language, setLangToType,
File.sourceTagPathHolder);
sourceLang = language;
}
static bool setSourceFileName (vString *const fileName)

View File

@ -64,9 +64,9 @@ extern const char *getInputLanguageName (void);
extern const char *getInputFileTagPath (void);
extern bool isInputLanguage (langType lang);
extern bool isInputHeaderFile (void);
extern bool isInputLanguageKindEnabled (char c);
extern bool isInputLanguageKindEnabled (int kindIndex);
extern bool doesInputLanguageAllowNullTag (void);
extern kindOption *getInputLanguageFileKind (void);
extern kindDefinition *getInputLanguageFileKind (void);
extern bool doesInputLanguageRequestAutomaticFQTag (void);
extern void freeInputFileResources (void);
@ -100,7 +100,7 @@ enum nestedInputBoundaryFlag {
extern unsigned int getNestedInputBoundaryInfo (unsigned long lineNumber);
extern const char *getSourceFileTagPath (void);
extern const char *getSourceLanguageName (void);
extern langType getSourceLanguage (void);
extern unsigned long getSourceLineNumber (void);
/* Raw: reading from given a parameter, fp */

1
ctags/main/trace.h Normal file
View File

@ -0,0 +1 @@
/* Dummy header - only included by some parsers */

246
ctags/main/trashbox.c Normal file
View File

@ -0,0 +1,246 @@
/*
*
* Copyright (c) 2014, Red Hat, Inc.
* Copyright (c) 2014, Masatake YAMATO
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
*/
#include "general.h"
#include "debug.h"
#include "routines.h"
#include "trashbox.h"
typedef TrashBoxDestroyItemProc TrashDestroyItemProc;
typedef struct sTrash {
void* item;
struct sTrash* next;
TrashDestroyItemProc destrctor;
} Trash;
struct sTrashBox {
Trash *trash;
};
static TrashBox* defaultTrashBox;
static TrashBox* parserTrashBox;
static Trash* trashPut (Trash* trash, void* item,
TrashDestroyItemProc destrctor);
static Trash* trashTakeBack (Trash* trash, void* item, TrashDestroyItemProc* destrctor);
static Trash* trashMakeEmpty (Trash* trash);
extern TrashBox* trashBoxNew (void)
{
TrashBox *t = xMalloc (1, TrashBox);
t->trash = NULL;
return t;
}
extern TrashBox* trashBoxStack (TrashBox* trash_box)
{
TrashBox *t = trashBoxNew();
if (!trash_box)
trash_box = defaultTrashBox;
trashBoxPut (trash_box, t, (TrashBoxDestroyItemProc) trashBoxDelete);
return t;
}
extern void trashBoxDelete (TrashBox* trash_box)
{
if (!trash_box)
trash_box = defaultTrashBox;
trashBoxMakeEmpty(trash_box);
eFree (trash_box);
}
extern void* trashBoxPut (TrashBox* trash_box, void* item, TrashBoxDestroyItemProc destroy)
{
if (!trash_box)
trash_box = defaultTrashBox;
trash_box->trash = trashPut(trash_box->trash, item, destroy);
return item;
}
extern TrashBoxDestroyItemProc trashBoxTakeBack (TrashBox* trash_box, void* item)
{
TrashBoxDestroyItemProc d;
if (!trash_box)
trash_box = defaultTrashBox;
trash_box->trash = trashTakeBack(trash_box->trash, item, &d);
return d;
}
extern void trashBoxMakeEmpty (TrashBox* trash_box)
{
if (!trash_box)
trash_box = defaultTrashBox;
trash_box->trash = trashMakeEmpty (trash_box->trash);
}
extern void trashBoxFree (TrashBox* trash_box, void* item)
{
TrashBoxDestroyItemProc d;
if (!trash_box)
trash_box = defaultTrashBox;
d = trashBoxTakeBack (trash_box, item);
d (item);
}
static Trash* trashPut (Trash* trash, void* item,
TrashDestroyItemProc destrctor)
{
Trash* t = xMalloc (1, Trash);
t->next = trash;
t->item = item;
t->destrctor = destrctor? destrctor: eFree;
return t;
}
static TrashBoxDestroyItemProc trashTakeBack0 (Trash** trash, void* item)
{
TrashBoxDestroyItemProc removed;
Trash* tmp;
removed = NULL;
while (*trash)
{
if ( (*trash)->item == item )
{
tmp = *trash;
*trash = (*trash)->next;
tmp->next = NULL;
tmp->item = NULL;
removed = tmp->destrctor;
eFree (tmp);
tmp = NULL;
break;
}
else
trash = &(*trash)->next;
}
Assert (removed);
return removed;
}
static Trash* trashTakeBack (Trash* trash, void* item, TrashDestroyItemProc *destrctor)
{
TrashDestroyItemProc d;
d = trashTakeBack0 (&trash, item);
if (destrctor)
*destrctor = d;
return trash;
}
static Trash* trashMakeEmpty (Trash* trash)
{
Trash* tmp;
while (trash)
{
tmp = trash;
trash = trash->next;
tmp->destrctor (tmp->item);
tmp->item = NULL;
tmp->destrctor = NULL;
eFree (tmp);
}
return NULL;
}
extern void initDefaultTrashBox (void)
{
defaultTrashBox = trashBoxNew ();
}
extern void finiDefaultTrashBox (void)
{
trashBoxDelete (defaultTrashBox);
defaultTrashBox = NULL;
}
extern void initParserTrashBox (void)
{
parserTrashBox = trashBoxNew ();
}
extern void finiParserTrashBox (void)
{
trashBoxDelete (parserTrashBox);
parserTrashBox = NULL;
}
extern void* parserTrashBoxPut (void* item, TrashBoxDestroyItemProc destroy)
{
return trashBoxPut(parserTrashBox, item, destroy);
}
extern TrashBoxDestroyItemProc parserTrashBoxTakeBack (void* item)
{
return trashBoxTakeBack(parserTrashBox, item);
}
#ifdef TRASH_TEST
#include <stdio.h>
int main (void)
{
Trash* trash = NULL;
Trash* tmp;
char* d = eStrdup ("d");
char* b = eStrdup ("b");
trash = trashPut (trash, eStrdup ("a"));
trash = trashPut (trash, b);
trash = trashPut (trash, eStrdup ("c"));
trash = trashPut (trash, d);
trash = trashTakeBack (trash, b, NULL);
eFree (b);
fputs("expects: dca\nactual: ", stderr);
for (tmp = trash; tmp; tmp = tmp->next)
fputs(tmp->item, stderr);
fputc('\n', stderr);
trash = trashTakeBack (trash, d, NULL);
eFree (d);
fputs("expects: ca\nactual: ", stderr);
for (tmp = trash; tmp; tmp = tmp->next)
fputs(tmp->item, stderr);
fputc('\n', stderr);
trash = trashMakeEmpty (trash);
fputs("expects: \nactual: ", stderr);
for (tmp = trash; tmp; tmp = tmp->next)
fputs(tmp->item, stderr);
fputc('\n', stderr);
return 0;
}
#include <stdlib.h>
void eFree (void *ptr) { free(ptr); }
void *eMalloc (const size_t size) { return malloc(size); }
char *eStrdup (const char* str) { return strdup(str); }
#endif

41
ctags/main/trashbox.h Normal file
View File

@ -0,0 +1,41 @@
/*
*
* Copyright (c) 2017, Red Hat, Inc.
* Copyright (c) 2017, Masatake YAMATO
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* Facility for delayed memory releasing, inspired from AutoreleasePool
* of OpenStep.
*/
#ifndef CTAGS_MAIN_TRASH_H
#define CTAGS_MAIN_TRASH_H
typedef void (* TrashBoxDestroyItemProc) (void *);
typedef struct sTrashBox TrashBox;
extern TrashBox* trashBoxNew (void);
extern TrashBox* trashBoxStack (TrashBox* trash_box);
extern void trashBoxDelete (TrashBox* trash_box);
extern void* trashBoxPut (TrashBox* trash_box, void* item, TrashBoxDestroyItemProc destroy);
extern TrashBoxDestroyItemProc trashBoxTakeBack (TrashBox* trash_box, void* item);
extern void trashBoxFree (TrashBox* trash_box, void* item);
extern void trashBoxMakeEmpty (TrashBox* trash_box);
#define DEFAULT_TRASH_BOX(PTR,PROC) trashBoxPut(NULL,PTR,(TrashBoxDestroyItemProc)PROC)
#define DEFAULT_TRASH_BOX_TAKE_BACK(PTR) trashBoxTakeBack(NULL,PTR)
#define PARSER_TRASH_BOX(PTR,PROC) parserTrashBoxPut(PTR,(TrashBoxDestroyItemProc)PROC)
#define PARSER_TRASH_BOX_TAKE_BACK(PTR) parserTrashBoxTakeBack(PTR)
extern void initDefaultTrashBox (void);
extern void finiDefaultTrashBox (void);
extern void initParserTrashBox (void);
extern void finiParserTrashBox (void);
extern void* parserTrashBoxPut (void* item, TrashBoxDestroyItemProc destroy);
extern TrashBoxDestroyItemProc parserTrashBoxTakeBack (void* item);
#endif /* CTAGS_MAIN_TRASH_H */

View File

@ -21,9 +21,13 @@ typedef struct sFieldDesc fieldDesc;
struct sPtagDesc;
typedef struct sPtagDesc ptagDesc;
struct sKindOption;
typedef struct sKindOption kindOption;
struct sKindDefinition;
typedef struct sKindDefinition kindDefinition;
struct sParserDefinition;
typedef struct sParserDefinition parserDefinition;
struct sPtrArray;
typedef struct sPtrArray ptrArray;
#endif /* CTAGS_MAIN_TYPES_H */

View File

@ -19,6 +19,7 @@
#include "debug.h"
#include "routines.h"
#include "vstring.h"
#include "trashbox.h"
/*
* DATA DEFINITIONS
@ -79,18 +80,6 @@ extern vString *vStringNew (void)
return string;
}
#ifndef VSTRING_PUTC_MACRO
extern void vStringPut (vString *const string, const int c)
{
if (string->length + 1 == string->size) /* check for buffer overflow */
vStringResize (string, string->size * 2);
string->buffer [string->length] = c;
if (c != '\0')
string->buffer [++string->length] = '\0';
}
#endif
extern vString *vStringNewCopy (const vString *const string)
{
vString *vs = vStringNew ();
@ -105,13 +94,20 @@ extern vString *vStringNewInit (const char *const s)
return vs;
}
extern vString *vStringNewNInit (const char *const s, const size_t length)
{
vString *vs = vStringNew ();
vStringNCatS (vs, s, length);
return vs;
}
static void stringCat (
vString *const string, const char *const s, const size_t length)
{
if (string->length + length + 1 > string->size)
vStringResize (string, string->length + length + 1);
strncpy (string->buffer + string->length, s, length);
memcpy (string->buffer + string->length, s, length);
string->length += length;
vStringPut (string, '\0');
}
@ -168,13 +164,14 @@ extern void vStringStripNewline (vString *const string)
*/
extern void vStringStripLeading (vString *const string)
{
while (isspace ((int) string->buffer [0]) && string->length > 0)
size_t n = 0;
while (n < string->length && isspace ((int) string->buffer [n]))
n++;
if (n > 0)
{
size_t i;
for (i = 1 ; i < string->length ; ++i)
string->buffer [i - 1] = string->buffer [i];
--string->length;
string->buffer [string->length] = '\0';
memmove (string->buffer, string->buffer + n, string->length - n);
vStringTruncate (string, string->length - n);
}
}
@ -364,3 +361,27 @@ extern vString *vStringNewOrClear (vString *const string)
else
return vStringNew ();
}
extern vString *vStringNewOrClearWithAutoRelease (vString *const string)
{
vString *r;
bool autoRelease = false;
if (!string)
autoRelease = true;
r = vStringNewOrClear(string);
if (autoRelease)
DEFAULT_TRASH_BOX(r, vStringDelete);
return r;
}
extern void vStringTranslate(vString *const string, char fromC, char toC)
{
for (unsigned int i = 0; i < vStringLength(string); i++)
{
if (string->buffer[i] == fromC)
string->buffer[i] = toC;
}
}

View File

@ -20,25 +20,18 @@
#include <stdio.h>
#include "inline.h"
#include "mio.h"
/*
* MACROS
*/
#ifndef DEBUG
# define VSTRING_PUTC_MACRO 1
#endif
#ifdef VSTRING_PUTC_MACRO
#define vStringPut(s,c) \
(void)(((s)->length + 1 == (s)->size ? vStringResize ((s), (s)->size * 2) : 0), \
((s)->buffer [(s)->length] = (c)), \
((c) == '\0' ? 0 : ((s)->buffer [++(s)->length] = '\0')))
#endif
#define vStringValue(vs) ((vs)->buffer)
#define vStringItem(vs,i) ((vs)->buffer[i])
#define vStringLast(vs) ((vs)->buffer[(vs)->length - 1])
#define vStringLength(vs) ((vs)->length)
#define vStringIsEmpty(vs) ((vs)->length == 0)
#define vStringSize(vs) ((vs)->size)
#define vStringChar(vs,i) ((vs)->buffer[i])
#define vStringLower(vs) toLowerString((vs)->buffer)
@ -66,9 +59,6 @@ typedef struct sVString {
extern void vStringResize (vString *const string, const size_t newSize);
extern vString *vStringNew (void);
extern void vStringDelete (vString *const string);
#ifndef VSTRING_PUTC_MACRO
extern void vStringPut (vString *const string, const int c);
#endif
extern void vStringStripNewline (vString *const string);
extern void vStringStripLeading (vString *const string);
extern void vStringChop (vString *const string);
@ -79,6 +69,7 @@ extern void vStringNCat (vString *const string, const vString *const s, const si
extern void vStringNCatS (vString *const string, const char *const s, const size_t length);
extern vString *vStringNewCopy (const vString *const string);
extern vString *vStringNewInit (const char *const s);
extern vString *vStringNewNInit (const char *const s, const size_t length);
extern void vStringCopy (vString *const string, const vString *const s);
extern void vStringCopyS (vString *const string, const char *const s);
extern void vStringNCopy (vString *const string, const vString *const s, const size_t length);
@ -86,8 +77,10 @@ extern void vStringNCopyS (vString *const string, const char *const s, const siz
extern void vStringCopyToLower (vString *const dest, const vString *const src);
extern void vStringSetLength (vString *const string);
extern void vStringTruncate (vString *const string, const size_t length);
extern void vStringTranslate(vString *const string, char fromC, char toC);
extern vString *vStringNewOrClear (vString *const string);
extern vString *vStringNewOrClearWithAutoRelease (vString *const string);
extern vString *vStringNewOwn (char *s);
extern char *vStringDeleteUnwrap (vString *const string);
@ -95,4 +88,18 @@ extern char *vStringDeleteUnwrap (vString *const string);
extern void vStringCatSWithEscaping (vString* b, const char *s);
extern void vStringCatSWithEscapingAsPattern (vString *output, const char* input);
/*
* INLINE FUNCTIONS
*/
CTAGS_INLINE void vStringPut (vString *const string, const int c)
{
if (string->length + 1 == string->size) /* check for buffer overflow */
vStringResize (string, string->size * 2);
string->buffer [string->length] = c;
if (c != '\0')
string->buffer [++string->length] = '\0';
}
#endif /* CTAGS_MAIN_VSTRING_H */

View File

@ -39,6 +39,8 @@ static xtagDesc xtagDescs [] = {
"Include reference tags", NULL},
{ false, 's', "subparser",
"Include tags generated by sub parsers", NULL},
{ true, '\0', "anonymous",
"Include tags for non-named objects like lambda"},
};
extern xtagDesc* getXtagDesc (xtagType type)

View File

@ -23,6 +23,7 @@ typedef enum eXtagType { /* extra tag content control */
XTAG_QUALIFIED_TAGS,
XTAG_REFERENCE_TAGS,
XTAG_TAGS_GENERATED_BY_SUB_PARSERS,
XTAG_ANONYMOUS,
XTAG_COUNT
} xtagType;

View File

@ -28,7 +28,7 @@ typedef enum {
K_STEP
} AbaqusKind;
static kindOption AbaqusKinds[] = {
static kindDefinition AbaqusKinds[] = {
{ true, 'c', "class", "Parts" },
{ true, 'm', "member", "Assembly" },
{ true, 'n', "namespace", "Steps" }
@ -71,7 +71,7 @@ static void createTag(AbaqusKind kind, const char *buf)
vStringPut(name, (int) *buf);
++buf;
} while ((*buf != '\0') && (*buf != ','));
makeSimpleTag(name, AbaqusKinds, kind);
makeSimpleTag(name, kind);
vStringDelete(name);
}
@ -118,7 +118,7 @@ extern parserDefinition* AbaqusParser (void)
{
static const char *const extensions [] = { "inp", NULL };
parserDefinition * def = parserNew ("Abaqus");
def->kinds = AbaqusKinds;
def->kindTable = AbaqusKinds;
def->kindCount = ARRAY_SIZE (AbaqusKinds);
def->extensions = extensions;
def->parser = findAbaqusTags;

View File

@ -27,7 +27,7 @@
* DATA DEFINITIONS
*/
static kindOption AbcKinds[] = {
static kindDefinition AbcKinds[] = {
{ true, 'm', "member", "sections" },
{ true, 's', "struct", "header1"}
};
@ -53,7 +53,7 @@ static kindOption AbcKinds[] = {
static void makeAbcTag (const vString* const name, bool name_before)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue(name), &(AbcKinds[0]));
initTagEntry (&e, vStringValue(name), 0);
if (name_before)
e.lineNumber--; /* we want the line before the underline chars */
@ -114,7 +114,7 @@ extern parserDefinition* AbcParser (void)
static const char *const extensions [] = { "abc", NULL };
parserDefinition* const def = parserNew ("Abc");
def->kinds = AbcKinds;
def->kindTable = AbcKinds;
def->kindCount = ARRAY_SIZE (AbcKinds);
def->patterns = patterns;
def->extensions = extensions;

View File

@ -1,47 +1,62 @@
/*
*
* Copyright (c) 2012, Lex Trotman
* Based on Rest code by Nick Treleaven, see rest.c
*
* 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 asciidoc files.
*/
*
* Copyright (c) 2007-2011, Nick Treleaven
* Copyright (c) 2012, Lex Trotman
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* This module contains functions for generating tags for asciidoc files.
*
* Based on Rest code by Nick Treleaven, see rest.c
*
* This code was ported from geany git commit 40396a3 at:
* https://github.com/geany/geany/blob/master/ctags/parsers/asciidoc.c
* with the changes in geany's PR #1263, with some changes to work in uctags.
*/
/*
* INCLUDE FILES
*/
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include <ctype.h>
#include <string.h>
#include "debug.h"
#include "entry.h"
#include "parse.h"
#include "read.h"
#include "vstring.h"
#include "nestlevel.h"
#include "routines.h"
#include "entry.h"
/*
* DATA DEFINITIONS
*/
* DATA DEFINITIONS
*/
typedef enum {
K_CHAPTER = 0,
K_SECTION,
K_SUBSECTION,
K_SUBSUBSECTION,
K_LEVEL5SECTION,
SECTION_COUNT
K_LEVEL4SECTION,
/* level-5 section not in here because it only works for one-line */
SECTION_COUNT, /* this is the same as level-5 kind number */
K_ANCHOR
} asciidocKind;
static kindOption AsciidocKinds[] = {
{ true, 'n', "namespace", "chapters"},
{ true, 'm', "member", "sections" },
{ true, 'd', "macro", "level2sections" },
{ true, 'v', "variable", "level3sections" },
{ true, 's', "struct", "level4sections" }
/*
* The following kind letters are based on the markdown parser kinds,
* and thus different than geany's.
*/
static kindDefinition AsciidocKinds[] = {
{ true, 'c', "chapter", "chapters"},
{ true, 's', "section", "sections" },
{ true, 'S', "subsection", "level 2 sections" },
{ true, 't', "subsubsection", "level 3 sections" },
{ true, 'T', "l4subsection", "level 4 sections" },
{ true, 'u', "l5subsection", "level 5 sections" },
{ true, 'a', "anchor", "anchors" }
};
static char kindchars[SECTION_COUNT]={ '=', '-', '~', '^', '+' };
@ -52,7 +67,7 @@ static NestingLevels *nestingLevels = NULL;
* FUNCTION DEFINITIONS
*/
static void popNestingLevelToKind(const int kind)
static NestingLevel *getNestingLevel(const int kind)
{
NestingLevel *nl;
tagEntryInfo *e;
@ -61,30 +76,60 @@ static void popNestingLevelToKind(const int kind)
{
nl = nestingLevelsGetCurrent(nestingLevels);
e = getEntryOfNestingLevel (nl);
if ((nl && (e == NULL)) || (e && (e->kind - AsciidocKinds) >= kind))
if ((nl && (e == NULL)) || (e && (e->kindIndex >= kind)))
nestingLevelsPop(nestingLevels);
else
break;
}
return nl;
}
static void makeAsciidocTag (const vString* const name, const int kind)
static int makeAsciidocTag (const vString* const name, const int kind, const bool two_line)
{
const NestingLevel *const nl = getNestingLevel(kind);
int r = CORK_NIL;
popNestingLevelToKind(kind);
if (vStringLength (name) > 0)
{
tagEntryInfo *parent = getEntryOfNestingLevel (nl);
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), &(AsciidocKinds [kind]));
initTagEntry (&e, vStringValue (name), kind);
e.lineNumber--; /* we want the line before the '---' underline chars */
if (two_line)
{
/* we want the line before the '---' underline chars */
const unsigned long line = getInputLineNumber();
Assert (line > 0);
if (line > 0)
{
e.lineNumber--;
e.filePosition = getInputFilePositionForLine(line - 1);
}
}
if (parent && (parent->kindIndex < kind))
{
/*
* This doesn't use Cork, but in this case I think this is better,
* because Cork would record the scopes of all parents in the chain
* which is weird for text section identifiers, and also this is
* what the rst.c reStructuredText parser does.
*/
e.extensionFields.scopeKindIndex = parent->kindIndex;
e.extensionFields.scopeName = parent->name;
}
r = makeTagEntry (&e);
}
return r;
}
static int makeSectionAsciidocTag (const vString* const name, const int kind, const bool two_line)
{
int r = makeAsciidocTag(name, kind, two_line);
nestingLevelsPush(nestingLevels, r);
return r;
}
@ -101,6 +146,137 @@ static int get_kind(char c)
}
static bool is_anchor(const unsigned char *line)
{
/* must be at least "[#a]" */
return line[0] == '[' && (line[1] == '#' || line[1] == '[');
}
static int capture_anchor(const unsigned char *const orig, int* captured_len)
{
vString *name = vStringNew ();
int r = CORK_NIL;
const bool shorthand = orig[1] == '#' ? true : false;
bool is_valid = false;
bool seen_comma = false;
const unsigned char *line = orig;
Assert (line[0] == '[');
Assert (line[1] == '#' || line[1] == '[');
if (captured_len) *captured_len = 0;
line += 2;
while (*line != '\0')
{
if (*line == ']')
{
if (shorthand || line[1] == ']')
{
is_valid = true;
if (shorthand) line++;
else line += 2;
break;
}
/* otherwise it's not the end, keep going */
}
if (*line == ',')
seen_comma = true;
if (!seen_comma)
vStringPut (name, *line);
line++;
}
if (is_valid && vStringLength (name) != 0)
{
r = makeAsciidocTag (name, K_ANCHOR, false);
if (captured_len)
{
*captured_len = line - orig;
}
}
vStringDelete (name);
return r;
}
/* skips any leading anchor(s) in a one-line title, generating tags for them */
static int process_leading_anchors(const unsigned char *const begin)
{
int captured_len = 0;
const unsigned char *current = begin;
while (is_anchor(current) && capture_anchor(current, &captured_len) != CORK_NIL)
{
/* minimum is "[#a]" */
Assert (captured_len >= 4);
current += captured_len;
while (isspace(*current)) ++current;
}
return current - begin;
}
static int process_trailing_anchor(const unsigned char *const begin,
const unsigned char *const end)
{
int captured_len = 0;
const unsigned char *found = NULL;
/* minimum is "[#a]" */
if (*end == ']' && (end - begin) >= 4)
{
found = (const unsigned char*) strrchr((const char*) begin , '[');
if (found && ((end - found) >= 4))
{
/* see if it's not shorthand [#a] but instead [[a]] */
if (end[-1] == ']' && found > begin && found[-1] == '[')
--found;
if (is_anchor (found))
capture_anchor(found, &captured_len);
}
}
return captured_len;
}
static void process_name(vString *const name, const int kind,
const unsigned char *line, const int line_len)
{
int start = kind + 1;
int end = line_len - 1;
Assert (kind >= 0 && kind < K_ANCHOR);
Assert (line_len > start);
vStringClear(name);
while (line[end] == line[0]) --end;
while (isspace(line[start])) ++start;
while (isspace(line[end])) --end;
if (start < end)
{
/* pop nesting levels, so that anchors get the parent's scope */
getNestingLevel(kind);
end -= process_trailing_anchor(line + start, line + end);
start += process_leading_anchors(line + start);
}
while (isspace(line[end])) --end;
if (start < end)
vStringNCatS(name, (const char*)(&(line[start])), end - start + 1);
}
/* computes the length of an UTF-8 string
* if the string doesn't look like UTF-8, return -1
* FIXME consider East_Asian_Width Unicode property */
@ -141,6 +317,15 @@ static void findAsciidocTags(void)
while ((line = readLineFromInputFile()) != NULL)
{
if (is_anchor (line))
{
if (capture_anchor (line, NULL) != CORK_NIL)
{
vStringClear (name);
continue;
}
}
int line_len = strlen((const char*) line);
int name_len_bytes = vStringLength(name);
int name_len = utf8_strlen(vStringValue(name), name_len_bytes);
@ -175,7 +360,7 @@ static void findAsciidocTags(void)
int kind = get_kind((char)(line[0]));
if (kind >= 0)
{
makeAsciidocTag(name, kind);
makeSectionAsciidocTag(name, kind, true);
continue;
}
}
@ -191,18 +376,12 @@ static void findAsciidocTags(void)
}
/* otherwise is it a one line title */
else if (line[0] == '=' && n_same <= 5 && isspace(line[n_same]) &&
else if (line[0] == '=' && n_same <= 6 && isspace(line[n_same]) &&
!in_block)
{
int kind = n_same - 1;
int start = n_same;
int end = line_len - 1;
while (line[end] == line[0])--end;
while (isspace(line[start]))++start;
while (isspace(line[end]))--end;
vStringClear(name);
vStringNCatS(name, (const char*)(&(line[start])), end - start + 1);
makeAsciidocTag(name, kind);
process_name(name, kind, line, line_len);
makeSectionAsciidocTag(name, kind, false);
continue;
}
}
@ -216,16 +395,17 @@ static void findAsciidocTags(void)
extern parserDefinition* AsciidocParser (void)
{
static const char *const patterns [] = { "*.asciidoc", NULL };
static const char *const extensions [] = { "asciidoc", NULL };
static const char *const patterns [] = { "*.asc", "*.adoc", "*.asciidoc", NULL };
static const char *const extensions [] = { "asc", "adoc", "asciidoc", NULL };
parserDefinition* const def = parserNew ("Asciidoc");
def->kinds = AsciidocKinds;
def->kindTable = AsciidocKinds;
def->kindCount = ARRAY_SIZE (AsciidocKinds);
def->patterns = patterns;
def->extensions = extensions;
def->parser = findAsciidocTags;
/* do we even need to use Cork? */
def->useCork = true;
return def;

View File

@ -60,7 +60,7 @@ typedef struct {
*/
static langType Lang_asm;
static kindOption AsmKinds [] = {
static kindDefinition AsmKinds [] = {
{ true, 'd', "define", "defines" },
{ true, 'l', "label", "labels" },
{ true, 'm', "macro", "macros" },
@ -152,7 +152,7 @@ static bool readPreProc (const unsigned char *const line)
vStringPut (name, *cp);
++cp;
}
makeSimpleTag (name, AsmKinds, K_DEFINE);
makeSimpleTag (name, K_DEFINE);
}
vStringDelete (name);
return result;
@ -201,18 +201,18 @@ static void makeAsmTag (
if (found)
{
if (kind != K_NONE)
makeSimpleTag (name, AsmKinds, kind);
makeSimpleTag (name, kind);
}
else if (isDefineOperator (operator))
{
if (! nameFollows)
makeSimpleTag (name, AsmKinds, K_DEFINE);
makeSimpleTag (name, K_DEFINE);
}
else if (labelCandidate)
{
operatorKind (name, &found);
if (! found)
makeSimpleTag (name, AsmKinds, K_LABEL);
makeSimpleTag (name, K_LABEL);
}
}
}
@ -352,7 +352,7 @@ extern parserDefinition* AsmParser (void)
NULL
};
parserDefinition* def = parserNew ("Asm");
def->kinds = AsmKinds;
def->kindTable = AsmKinds;
def->kindCount = ARRAY_SIZE (AsmKinds);
def->extensions = extensions;
def->patterns = patterns;

View File

@ -39,7 +39,7 @@ typedef struct {
BasicKind kind;
} KeyWord;
static kindOption BasicKinds[] = {
static kindDefinition BasicKinds[] = {
{true, 'c', "constant", "constants"},
{true, 'f', "function", "functions"},
{true, 'l', "label", "labels"},
@ -119,7 +119,7 @@ static int extract_dim (char const *pos, vString * name, BasicKind kind)
for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ',' && *pos != '='; pos++)
vStringPut (name, *pos);
makeSimpleTag (name, BasicKinds, kind);
makeSimpleTag (name, kind);
/* if the line contains a ',', we have multiple declarations */
while (*pos && strchr (pos, ','))
@ -140,7 +140,7 @@ static int extract_dim (char const *pos, vString * name, BasicKind kind)
vStringClear (name);
for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ',' && *pos != '='; pos++)
vStringPut (name, *pos);
makeSimpleTag (name, BasicKinds, kind);
makeSimpleTag (name, kind);
}
vStringDelete (name);
@ -192,7 +192,7 @@ static int match_keyword (const char *p, KeyWord const *kw)
{
p = extract_name (p, name);
}
makeSimpleTag (name, BasicKinds, kw->kind);
makeSimpleTag (name, kw->kind);
vStringDelete (name);
return 1;
}
@ -207,7 +207,7 @@ static void match_colon_label (char const *p)
{
vString *name = vStringNew ();
vStringNCatS (name, p, end - p);
makeSimpleTag (name, BasicKinds, K_LABEL);
makeSimpleTag (name, K_LABEL);
vStringDelete (name);
}
}
@ -240,11 +240,11 @@ static void findBasicTags (void)
}
}
parserDefinition *FreeBasicParser (void)
parserDefinition *BasicParser (void)
{
static char const *extensions[] = { "bas", "bi", "bb", "pb", NULL };
parserDefinition *def = parserNew ("FreeBasic");
def->kinds = BasicKinds;
def->kindTable = BasicKinds;
def->kindCount = ARRAY_SIZE (BasicKinds);
def->extensions = extensions;
def->parser = findBasicTags;

View File

@ -281,7 +281,7 @@ typedef enum
CK_EXTERN_VARIABLE
} cKind;
static kindOption CKinds [] = {
static kindDefinition CKinds [] = {
{ true, 'c', "class", "classes"},
{ true, 'd', "macro", "macro definitions"},
{ true, 'e', "enumerator", "enumerators (values inside an enumeration)"},
@ -307,7 +307,7 @@ typedef enum
DK_EXTERN_VARIABLE
} dKind;
static kindOption DKinds [] = {
static kindDefinition DKinds [] = {
{ true, 'c', "class", "classes"},
{ true, 'e', "enumerator", "enumerators (values inside an enumeration)"},
{ true, 'f', "function", "function definitions"},
@ -331,7 +331,7 @@ typedef enum
JK_PACKAGE, JK_ENUMERATOR, JK_ENUMERATION
} javaKind;
static kindOption JavaKinds [] = {
static kindDefinition JavaKinds [] = {
{ true, 'c', "class", "classes"},
{ true, 'f', "field", "fields"},
{ true, 'i', "interface", "interfaces"},
@ -349,7 +349,7 @@ typedef enum
CSK_NAMESPACE, CSK_PROPERTY, CSK_STRUCT, CSK_TYPEDEF
} csharpKind;
static kindOption CsharpKinds [] = {
static kindDefinition CsharpKinds [] = {
{ true, 'c', "class", "classes"},
{ true, 'd', "macro", "macro definitions"},
{ true, 'e', "enumerator", "enumerators (values inside an enumeration)"},
@ -372,7 +372,7 @@ typedef enum {
VK_NAMESPACE, VK_PROPERTY, VK_SIGNAL, VK_STRUCT
} valaKind;
static kindOption ValaKinds [] = {
static kindDefinition ValaKinds [] = {
{ true, 'c', "class", "classes"},
{ true, 'd', "macro", "macro definitions"},
{ true, 'e', "enumerator", "enumerators (values inside an enumeration)"},
@ -1093,19 +1093,19 @@ static javaKind javaTagKind (const tagType type)
return result;
}
static const kindOption *tagKind (const tagType type)
static int kindIndexForType (const tagType type)
{
const kindOption* result;
int result;
if (isInputLanguage (Lang_java))
result = &JavaKinds [javaTagKind (type)];
result = javaTagKind (type);
else if (isInputLanguage (Lang_csharp))
result = &CsharpKinds [csharpTagKind (type)];
result = csharpTagKind (type);
else if (isInputLanguage (Lang_d))
result = &DKinds [dTagKind (type)];
result = dTagKind (type);
else if (isInputLanguage (Lang_vala))
result = &ValaKinds [valaTagKind (type)];
result = valaTagKind (type);
else
result = &CKinds [cTagKind (type)];
result = cTagKind (type);
return result;
}
@ -1184,10 +1184,10 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
(isMember (st) || st->parent->declaration == DECL_NAMESPACE))
{
if (isType (st->context, TOKEN_NAME))
tag->extensionFields.scopeKind = tagKind (TAG_CLASS);
tag->extensionFields.scopeKindIndex = kindIndexForType (TAG_CLASS);
else
tag->extensionFields.scopeKind =
tagKind (declToTagType (parentDecl (st)));
tag->extensionFields.scopeKindIndex =
kindIndexForType (declToTagType (parentDecl (st)));
tag->extensionFields.scopeName = vStringValue (scope);
}
if ((type == TAG_CLASS || type == TAG_INTERFACE ||
@ -1435,7 +1435,7 @@ static void makeTag (const tokenInfo *const token,
return;
}
initTagEntry (&e, vStringValue (token->name), tagKind (type));
initTagEntry (&e, vStringValue (token->name), kindIndexForType (type));
e.lineNumber = token->lineNumber;
e.filePosition = token->filePosition;
@ -3131,7 +3131,7 @@ static rescanReason findCTags (const unsigned int passCount)
Assert (passCount < 3);
cppInit ((bool) (passCount > 1), isInputLanguage (Lang_csharp), isInputLanguage(Lang_cpp),
CKinds+CK_DEFINE);
CK_DEFINE);
exception = (exception_t) setjmp (Exception);
rescan = RESCAN_NONE;
@ -3238,7 +3238,7 @@ extern parserDefinition* CParser (void)
{
static const char *const extensions [] = { "c", "pc", "sc", NULL };
parserDefinition* def = parserNew ("C");
def->kinds = CKinds;
def->kindTable = CKinds;
def->kindCount = ARRAY_SIZE (CKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3257,7 +3257,7 @@ extern parserDefinition* CppParser (void)
NULL
};
parserDefinition* def = parserNew ("C++");
def->kinds = CKinds;
def->kindTable = CKinds;
def->kindCount = ARRAY_SIZE (CKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3269,7 +3269,7 @@ extern parserDefinition* JavaParser (void)
{
static const char *const extensions [] = { "java", NULL };
parserDefinition* def = parserNew ("Java");
def->kinds = JavaKinds;
def->kindTable = JavaKinds;
def->kindCount = ARRAY_SIZE (JavaKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3281,7 +3281,7 @@ extern parserDefinition* DParser (void)
{
static const char *const extensions [] = { "d", "di", NULL };
parserDefinition* def = parserNew ("D");
def->kinds = DKinds;
def->kindTable = DKinds;
def->kindCount = ARRAY_SIZE (DKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3293,7 +3293,7 @@ extern parserDefinition* GLSLParser (void)
{
static const char *const extensions [] = { "glsl", "frag", "vert", NULL };
parserDefinition* def = parserNew ("GLSL");
def->kinds = CKinds;
def->kindTable = CKinds;
def->kindCount = ARRAY_SIZE (CKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3305,7 +3305,7 @@ extern parserDefinition* FeriteParser (void)
{
static const char *const extensions [] = { "fe", NULL };
parserDefinition* def = parserNew ("Ferite");
def->kinds = CKinds;
def->kindTable = CKinds;
def->kindCount = ARRAY_SIZE (CKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3317,7 +3317,7 @@ extern parserDefinition* CsharpParser (void)
{
static const char *const extensions [] = { "cs", NULL };
parserDefinition* def = parserNew ("C#");
def->kinds = CsharpKinds;
def->kindTable = CsharpKinds;
def->kindCount = ARRAY_SIZE (CsharpKinds);
def->extensions = extensions;
def->parser2 = findCTags;
@ -3329,7 +3329,7 @@ extern parserDefinition* ValaParser (void)
{
static const char *const extensions [] = { "vala", NULL };
parserDefinition* def = parserNew ("Vala");
def->kinds = ValaKinds;
def->kindTable = ValaKinds;
def->kindCount = ARRAY_SIZE (ValaKinds);
def->extensions = extensions;
def->parser2 = findCTags;

View File

@ -14,11 +14,26 @@
#include "read.h"
#include "routines.h"
#define isSelectorChar(c) \
/* attribute selectors are handled separately */ \
(isalnum (c) || \
(c) == '_' || /* allowed char */ \
(c) == '-' || /* allowed char */ \
(c) == '+' || /* allow all sibling in a single tag */ \
(c) == '>' || /* allow all child in a single tag */ \
(c) == '|' || /* allow namespace separator */ \
(c) == '(' || /* allow pseudo-class arguments */ \
(c) == ')' || \
(c) == '.' || /* allow classes and selectors */ \
(c) == ':' || /* allow pseudo classes */ \
(c) == '*' || /* allow globs as P + * */ \
(c) == '#') /* allow ids */
typedef enum eCssKinds {
K_CLASS, K_SELECTOR, K_ID
} cssKind;
static kindOption CssKinds [] = {
static kindDefinition CssKinds [] = {
{ true, 'c', "class", "classes" },
{ true, 's', "selector", "selectors" },
{ true, 'i', "id", "identities" }
@ -37,23 +52,6 @@ typedef struct {
} tokenInfo;
static bool isSelectorChar (const int c)
{
/* attribute selectors are handled separately */
return (isalnum (c) ||
c == '_' || // allowed char
c == '-' || // allowed char
c == '+' || // allow all sibling in a single tag
c == '>' || // allow all child in a single tag
c == '|' || // allow namespace separator
c == '(' || // allow pseudo-class arguments
c == ')' ||
c == '.' || // allow classes and selectors
c == ':' || // allow pseudo classes
c == '*' || // allow globs as P + *
c == '#'); // allow ids
}
static void parseSelector (vString *const string, const int firstChar)
{
int c = firstChar;
@ -226,7 +224,7 @@ static void findCssTags (void)
if (CssKinds[kind].enabled)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (selector), &(CssKinds[kind]));
initTagEntry (&e, vStringValue (selector), kind);
e.lineNumber = lineNumber;
e.filePosition = filePosition;
@ -258,10 +256,9 @@ extern parserDefinition* CssParser (void)
{
static const char *const extensions [] = { "css", NULL };
parserDefinition* def = parserNew ("CSS");
def->kinds = CssKinds;
def->kindTable = CssKinds;
def->kindCount = ARRAY_SIZE (CssKinds);
def->extensions = extensions;
def->parser = findCssTags;
return def;
}

View File

@ -28,7 +28,7 @@ typedef enum {
K_FUNCTION
} diffKind;
static kindOption DiffKinds [] = {
static kindDefinition DiffKinds [] = {
{ true, 'f', "function", "functions"}
};
@ -109,7 +109,7 @@ static void findDiffTags (void)
tmp++;
}
makeSimpleTag (filename, DiffKinds, K_FUNCTION);
makeSimpleTag (filename, K_FUNCTION);
vStringClear (filename);
}
@ -125,7 +125,7 @@ extern parserDefinition* DiffParser (void)
static const char *const patterns [] = { "*.diff", "*.patch", NULL };
static const char *const extensions [] = { "diff", NULL };
parserDefinition* const def = parserNew ("Diff");
def->kinds = DiffKinds;
def->kindTable = DiffKinds;
def->kindCount = ARRAY_SIZE (DiffKinds);
def->patterns = patterns;
def->extensions = extensions;

View File

@ -34,7 +34,7 @@ typedef enum {
K_APPENDIX
} docbookKind;
static kindOption DocBookKinds [] = {
static kindDefinition DocBookKinds [] = {
{ true, 'f', "function", "chapters"},
{ true, 'c', "class", "sections"},
{ true, 'm', "member", "sect1"},
@ -77,7 +77,7 @@ static void createTag(docbookKind kind, const char *buf)
vStringPut(name, (int) *buf);
++buf;
} while ((*buf != '\0') && (*buf != '"'));
makeSimpleTag(name, DocBookKinds, kind);
makeSimpleTag(name, kind);
}
@ -143,7 +143,7 @@ extern parserDefinition* DocBookParser (void)
static const char *const extensions [] = { "sgml", "docbook", NULL };
parserDefinition* def = parserNew ("Docbook");
def->extensions = extensions;
def->kinds = DocBookKinds;
def->kindTable = DocBookKinds;
def->kindCount = ARRAY_SIZE (DocBookKinds);
def->parser = findDocBookTags;
return def;

View File

@ -28,7 +28,7 @@ typedef enum {
K_MACRO, K_FUNCTION, K_MODULE, K_RECORD, K_TYPE
} erlangKind;
static kindOption ErlangKinds[] = {
static kindDefinition ErlangKinds[] = {
{true, 'd', "macro", "macro definitions"},
{true, 'f', "function", "functions"},
{true, 'm', "module", "modules"},
@ -78,11 +78,11 @@ static void makeMemberTag (
if (ErlangKinds [kind].enabled && vStringLength (identifier) > 0)
{
tagEntryInfo tag;
initTagEntry (&tag, vStringValue (identifier), &(ErlangKinds[kind]));
initTagEntry (&tag, vStringValue (identifier), kind);
if (module != NULL && vStringLength (module) > 0)
{
tag.extensionFields.scopeKind = &(ErlangKinds [K_MODULE]);
tag.extensionFields.scopeKindIndex = K_MODULE;
tag.extensionFields.scopeName = vStringValue (module);
}
makeTagEntry (&tag);
@ -93,7 +93,7 @@ static void parseModuleTag (const unsigned char *cp, vString *const module)
{
vString *const identifier = vStringNew ();
parseIdentifier (cp, identifier);
makeSimpleTag (identifier, ErlangKinds, K_MODULE);
makeSimpleTag (identifier, K_MODULE);
/* All further entries go in the new module */
vStringCopy (module, identifier);
@ -104,7 +104,7 @@ static void parseSimpleTag (const unsigned char *cp, erlangKind kind)
{
vString *const identifier = vStringNew ();
parseIdentifier (cp, identifier);
makeSimpleTag (identifier, ErlangKinds, kind);
makeSimpleTag (identifier, kind);
vStringDelete (identifier);
}
@ -181,7 +181,7 @@ extern parserDefinition *ErlangParser (void)
{
static const char *const extensions[] = { "erl", "ERL", "hrl", "HRL", NULL };
parserDefinition *def = parserNew ("Erlang");
def->kinds = ErlangKinds;
def->kindTable = ErlangKinds;
def->kindCount = ARRAY_SIZE (ErlangKinds);
def->extensions = extensions;
def->parser = findErlangTags;

View File

@ -208,7 +208,7 @@ static bool NewLine = true;
static unsigned int contextual_fake_count = 0;
/* indexed by tagType */
static kindOption FortranKinds [TAG_COUNT] = {
static kindDefinition FortranKinds [TAG_COUNT] = {
{ true, 'b', "blockData", "block data"},
{ true, 'c', "common", "common blocks"},
{ true, 'e', "entry", "entry points"},
@ -487,22 +487,22 @@ static void makeFortranTag (tokenInfo *const token, tagType tag)
const char *const name = vStringValue (token->string);
tagEntryInfo e;
initTagEntry (&e, name, &(FortranKinds [token->tag]));
initTagEntry (&e, name, token->tag);
if (token->tag == TAG_COMMON_BLOCK)
e.lineNumberEntry = (bool) (Option.locate != EX_PATTERN);
e.lineNumberEntry = canUseLineNumberAsLocator();
e.lineNumber = token->lineNumber;
e.filePosition = token->filePosition;
e.isFileScope = isFileScope (token->tag);
e.truncateLine = (bool) (token->tag != TAG_LABEL);
e.truncateLineAfterTag = (bool) (token->tag != TAG_LABEL);
if (ancestorCount () > 0)
{
const tokenInfo* const scope = ancestorScope ();
if (scope != NULL)
{
e.extensionFields.scopeKind = &(FortranKinds [scope->tag]);
e.extensionFields.scopeKindIndex = scope->tag;
e.extensionFields.scopeName = vStringValue (scope->string);
}
}
@ -2322,7 +2322,7 @@ extern parserDefinition* FortranParser (void)
NULL
};
parserDefinition* def = parserNew ("Fortran");
def->kinds = FortranKinds;
def->kindTable = FortranKinds;
def->kindCount = ARRAY_SIZE (FortranKinds);
def->extensions = extensions;
def->parser2 = findFortranTags;
@ -2342,7 +2342,7 @@ extern parserDefinition* F77Parser (void)
NULL
};
parserDefinition* def = parserNew ("F77");
def->kinds = FortranKinds;
def->kindTable = FortranKinds;
def->kindCount = ARRAY_SIZE (FortranKinds);
def->extensions = extensions;
def->parser2 = findFortranTags;

View File

@ -90,7 +90,7 @@ typedef enum {
GOTAG_MEMBER
} goKind;
static kindOption GoKinds[] = {
static kindDefinition GoKinds[] = {
{true, 'p', "package", "packages"},
{true, 'f', "func", "functions"},
{true, 'c', "const", "constants"},
@ -521,7 +521,7 @@ static void makeTag (tokenInfo *const token, const goKind kind,
const char *const name = vStringValue (token->string);
tagEntryInfo e;
initTagEntry (&e, name, &(GoKinds [kind]));
initTagEntry (&e, name, kind);
if (!GoKinds [kind].enabled)
return;
@ -535,7 +535,7 @@ static void makeTag (tokenInfo *const token, const goKind kind,
if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL)
{
e.extensionFields.scopeKind = &(GoKinds[parent_kind]);
e.extensionFields.scopeKindIndex = parent_kind;
e.extensionFields.scopeName = vStringValue (parent_token->string);
}
makeTagEntry (&e);
@ -820,7 +820,7 @@ extern parserDefinition *GoParser (void)
{
static const char *const extensions[] = { "go", NULL };
parserDefinition *def = parserNew ("Go");
def->kinds = GoKinds;
def->kindTable = GoKinds;
def->kindCount = ARRAY_SIZE (GoKinds);
def->extensions = extensions;
def->parser = findGoTags;

View File

@ -37,7 +37,7 @@ typedef enum {
K_TYPE, K_CONSTRUCTOR, K_FUNCTION, K_MODULE
} haskellKind;
static kindOption HaskellKinds [] = {
static kindDefinition HaskellKinds [] = {
{ true, 't', "typedef", "types" },
{ true, 'c', "macro", "type constructors" },
{ true, 'f', "function", "functions" },
@ -104,7 +104,7 @@ static void add_tag(const char *token, haskellKind kind, vString *name)
for (i = 0; token[i] != '\0'; ++i)
vStringPut(name, token[i]);
makeSimpleTag(name, HaskellKinds, kind);
makeSimpleTag(name, kind);
vStringClear(name);
}
@ -336,7 +336,7 @@ extern parserDefinition* HaskellParser (void)
static const char *const extensions [] = { "hs", NULL };
parserDefinition* def = parserNew ("Haskell");
def->kinds = HaskellKinds;
def->kindTable = HaskellKinds;
def->kindCount = ARRAY_SIZE(HaskellKinds);
def->extensions = extensions;
def->parser = findNormalHaskellTags;
@ -347,7 +347,7 @@ extern parserDefinition* LiterateHaskellParser (void)
{
static const char *const extensions [] = { "lhs", NULL };
parserDefinition* def = parserNew ("Literate Haskell");
def->kinds = HaskellKinds;
def->kindTable = HaskellKinds;
def->kindCount = ARRAY_SIZE(HaskellKinds);
def->extensions = extensions;
def->parser = findLiterateHaskellTags;

View File

@ -47,7 +47,7 @@ typedef enum {
HXTAG_COUNT
} hxKind;
static kindOption HxKinds [] = {
static kindDefinition HxKinds [] = {
{ true, 'm', "method", "methods" },
{ true, 'c', "class", "classes" },
{ true, 'e', "enum", "enumerations" },
@ -90,7 +90,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_VARIABLE);
makeSimpleTag (name, HXTAG_VARIABLE);
vStringClear (name);
}
@ -108,7 +108,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_METHODS);
makeSimpleTag (name, HXTAG_METHODS);
vStringClear (name);
}
@ -125,7 +125,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_CLASS);
makeSimpleTag (name, HXTAG_CLASS);
vStringCopy(clsName,name);
vStringClear (name);
}
@ -142,7 +142,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_ENUM);
makeSimpleTag (name, HXTAG_ENUM);
vStringClear (name);
} else if (strncmp ((const char*) cp, "public", (size_t) 6) == 0 &&
isspace((int) cp [6]))
@ -171,7 +171,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_INTERFACE);
makeSimpleTag (name, HXTAG_INTERFACE);
vStringClear (name);
} else if (strncmp ((const char *) cp,"typedef",(size_t) 7) == 0 && isspace(((int) cp[7]))) {
cp += 7;
@ -183,7 +183,7 @@ another:
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, HxKinds, HXTAG_TYPEDEF);
makeSimpleTag (name, HXTAG_TYPEDEF);
vStringClear (name);
}
@ -207,7 +207,7 @@ extern parserDefinition* HaxeParser (void)
/*
* New definitions for parsing instead of regex
*/
def->kinds = HxKinds;
def->kindTable = HxKinds;
def->kindCount = ARRAY_SIZE (HxKinds);
def->parser = findHxTags;
/*def->initialize = initialize;*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, Darren Hiebert
* Copyright (c) 2016, Jiri Techet
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
@ -8,53 +8,513 @@
* files.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "general.h"
#include <string.h>
#include <ctype.h>
#include "entry.h"
#include "parse.h"
#include "read.h"
#include "routines.h"
#include "keyword.h"
#include "promise.h"
static tagRegexTable htmlTagRegexTable [] = {
#define POSSIBLE_ATTRIBUTES "([ \t]+[a-z]+=\"?[^>\"]*\"?)*"
{"<a"
POSSIBLE_ATTRIBUTES "[ \t]+name=\"?([^>\"]+)\"?" POSSIBLE_ATTRIBUTES
"[ \t]*>", "\\2",
"a,anchor,named anchors", "i", NULL},
{"^[ \t]*function[ \t]*([A-Za-z0-9_]+)[ \t]*\\(", "\\1",
"f,function,JavaScript functions", NULL, NULL},
/* The max. number of nested elements - prevents further recursion if the limit
* is exceeded and avoids stack overflow for invalid input containing too many
* open tags */
#define MAX_DEPTH 1000
/* the following matches headings with tags inside like
* <h1><a href="#id109"><i>Some Text</i></a></h1>
* and
* <h1>Some Text</h1> */
#define SPACES "[ \t]*"
#define ATTRS "[^>]*"
#define INNER_HEADING \
ATTRS ">" SPACES "(<" ATTRS ">" SPACES ")*([^<]+).*"
{"<h1" INNER_HEADING "</h1>", "\\2",
"n,namespace,H1 heading", "i", NULL},
typedef enum {
K_ANCHOR,
K_HEADING1,
K_HEADING2,
K_HEADING3
} htmlKind;
{"<h2" INNER_HEADING "</h2>", "\\2",
"c,class,H2 heading", "i", NULL},
{"<h3" INNER_HEADING "</h3>", "\\2",
"v,variable,H3 heading", "i", NULL},
static kindDefinition HtmlKinds [] = {
{ true, 'a', "anchor", "named anchors" },
{ true, 'h', "heading1", "H1 headings" },
{ true, 'i', "heading2", "H2 headings" },
{ true, 'j', "heading3", "H3 headings" }
};
/*
* FUNCTION DEFINITIONS
*/
typedef enum {
KEYWORD_h1,
KEYWORD_h2,
KEYWORD_h3,
KEYWORD_a,
KEYWORD_script,
KEYWORD_style,
KEYWORD_name,
/* Create parser definition structure */
/* void elements */
KEYWORD_area,
KEYWORD_base,
KEYWORD_br,
KEYWORD_col,
KEYWORD_command,
KEYWORD_embed,
KEYWORD_hr,
KEYWORD_img,
KEYWORD_input,
KEYWORD_keygen,
KEYWORD_link,
KEYWORD_meta,
KEYWORD_param,
KEYWORD_source,
KEYWORD_track,
KEYWORD_wbr
} keywordId;
static const keywordTable HtmlKeywordTable[] = {
{"h1", KEYWORD_h1},
{"h2", KEYWORD_h2},
{"h3", KEYWORD_h3},
{"a", KEYWORD_a},
{"script", KEYWORD_script},
{"style", KEYWORD_style},
{"name", KEYWORD_name},
/* void elements */
{"area", KEYWORD_area},
{"base", KEYWORD_base},
{"br", KEYWORD_br},
{"col", KEYWORD_col},
{"command", KEYWORD_command},
{"embed", KEYWORD_embed},
{"hr", KEYWORD_hr},
{"img", KEYWORD_img},
{"input", KEYWORD_input},
{"keygen", KEYWORD_keygen},
{"link", KEYWORD_link},
{"meta", KEYWORD_meta},
{"param", KEYWORD_param},
{"source", KEYWORD_source},
{"track", KEYWORD_track},
{"wbr", KEYWORD_wbr},
};
typedef enum {
TOKEN_EOF,
TOKEN_NAME, /* tag and attribute names */
TOKEN_STRING, /* single- or double-quoted attribute value */
TOKEN_TEXT,
TOKEN_TAG_START, /* < */
TOKEN_TAG_START2, /* </ */
TOKEN_TAG_END, /* > */
TOKEN_TAG_END2, /* /> */
TOKEN_EQUAL,
TOKEN_COMMENT,
TOKEN_OTHER
} tokenType;
#ifdef DEBUG
const char *tokenTypes[] = {
#define E(X) [TOKEN_##X] = #X
E(EOF),
E(NAME),
E(STRING),
E(TEXT),
E(TAG_START),
E(TAG_START2),
E(TAG_END),
E(TAG_END2),
E(EQUAL),
E(COMMENT),
E(OTHER),
#undef E
};
#endif
typedef struct {
tokenType type;
vString *string;
} tokenInfo;
static int Lang_html;
static void readTag (tokenInfo *token, vString *text, int depth);
#ifdef DEBUG
static void dumpToken (tokenInfo *token, const char *context, const char* extra_context)
{
fprintf (stderr, "[%7s] %-20s@%s.%s\n",
tokenTypes[token->type], vStringValue(token->string),
context, extra_context? extra_context: "_");
}
#endif
static void readTokenText (tokenInfo *const token, bool collectText)
{
int c;
int lastC = 'X'; /* whatever non-space character */
vStringClear (token->string);
getNextChar:
c = getcFromInputFile ();
switch (c)
{
case EOF:
token->type = TOKEN_EOF;
break;
case '<':
ungetcToInputFile (c);
token->type = TOKEN_TEXT;
break;
default:
if (collectText)
{
if (isspace (c))
c = ' ';
if (c != ' ' || lastC != ' ')
{
vStringPut (token->string, c);
lastC = c;
}
}
goto getNextChar;
}
}
static void readToken (tokenInfo *const token, bool skipComments)
{
int c;
vStringClear (token->string);
getNextChar:
c = getcFromInputFile ();
while (isspace (c))
c = getcFromInputFile ();
switch (c)
{
case EOF:
token->type = TOKEN_EOF;
break;
case '<':
{
int d = getcFromInputFile ();
if (d == '!')
{
d = getcFromInputFile ();
if (d == '-')
{
d = getcFromInputFile ();
if (d == '-')
{
int e = ' ';
int f = ' ';
do
{
d = e;
e = f;
f = getcFromInputFile ();
}
while (f != EOF && ! (d == '-' && e == '-' && f == '>'));
if (skipComments)
goto getNextChar;
else
{
token->type = TOKEN_COMMENT;
break;
}
}
}
ungetcToInputFile (d);
token->type = TOKEN_OTHER;
}
else if (d == '?')
token->type = TOKEN_OTHER;
else if (d == '/')
token->type = TOKEN_TAG_START2;
else
{
ungetcToInputFile (d);
token->type = TOKEN_TAG_START;
}
break;
}
case '/':
{
int d = getcFromInputFile ();
if (d == '>')
token->type = TOKEN_TAG_END2;
else
{
ungetcToInputFile (d);
token->type = TOKEN_OTHER;
}
break;
}
case '>':
token->type = TOKEN_TAG_END;
break;
case '=':
token->type = TOKEN_EQUAL;
break;
case '"':
case '\'':
{
const int delimiter = c;
c = getcFromInputFile ();
while (c != EOF && c != delimiter)
{
vStringPut (token->string, c);
c = getcFromInputFile ();
}
token->type = TOKEN_STRING;
break;
}
default:
{
do
{
vStringPut (token->string, tolower (c));
c = getcFromInputFile ();
}
while (!isspace (c) && c != '<' && c != '>' && c != '/' &&
c != '=' && c != '\'' && c != '"' && c != EOF);
if (c != EOF)
ungetcToInputFile (c);
token->type = TOKEN_NAME;
break;
}
}
}
static void appendText (vString *text, vString *appendedText)
{
if (text != NULL && vStringLength (appendedText) > 0)
{
if (vStringLength (text) > 0 && vStringLast (text) == ' ' &&
vStringLength (appendedText) > 0 && vStringChar (appendedText, 0) == ' ')
{
vStringStripTrailing (text);
}
vStringCat (text, appendedText);
}
}
static bool readTagContent (tokenInfo *token, vString *text, long *line, long *lineOffset, int depth)
{
tokenType type;
readTokenText (token, text != NULL);
appendText (text, token->string);
do
{
*line = getInputLineNumber ();
*lineOffset = getInputLineOffset ();
readToken (token, false);
type = token->type;
if (type == TOKEN_TAG_START)
readTag (token, text, depth + 1);
if (type == TOKEN_COMMENT || type == TOKEN_TAG_START)
{
readTokenText (token, text != NULL);
appendText (text, token->string);
}
}
while (type == TOKEN_COMMENT || type == TOKEN_TAG_START);
return type == TOKEN_TAG_START2;
}
static bool skipScriptContent (tokenInfo *token, long *line, long *lineOffset)
{
bool found_start = false;
bool found_script = false;
long line_tmp[2];
long lineOffset_tmp[2];
tokenType type;
do
{
line_tmp[0] = getInputLineNumber ();
lineOffset_tmp[0] = getInputLineOffset ();
readToken (token, false);
type = token->type;
if (type == TOKEN_TAG_START2)
{
found_start = true;
line_tmp[1] = line_tmp[0];
lineOffset_tmp[1] = lineOffset_tmp[0];
}
else if (found_start
&& type == TOKEN_NAME
&& lookupKeyword (vStringValue (token->string), Lang_html) == KEYWORD_script)
{
found_script = true;
*line = line_tmp[1];
*lineOffset = lineOffset_tmp[1];
}
else
found_start = false;
}
while ((type != TOKEN_EOF) && (!found_script));
return found_script;
}
static void readTag (tokenInfo *token, vString *text, int depth)
{
bool textCreated = false;
readToken (token, true);
if (token->type == TOKEN_NAME)
{
keywordId startTag;
bool isHeading;
bool isVoid;
startTag = lookupKeyword (vStringValue (token->string), Lang_html);
isHeading = (startTag == KEYWORD_h1 || startTag == KEYWORD_h2 || startTag == KEYWORD_h3);
isVoid = (startTag >= KEYWORD_area && startTag <= KEYWORD_wbr);
if (text == NULL && isHeading)
{
text = vStringNew ();
textCreated = true;
}
do
{
readToken (token, true);
if (startTag == KEYWORD_a && token->type == TOKEN_NAME)
{
keywordId attribute = lookupKeyword (vStringValue (token->string), Lang_html);
if (attribute == KEYWORD_name)
{
readToken (token, true);
if (token->type == TOKEN_EQUAL)
{
readToken (token, true);
if (token->type == TOKEN_STRING || token->type == TOKEN_NAME)
makeSimpleTag (token->string, K_ANCHOR);
}
}
}
}
while (token->type != TOKEN_TAG_END && token->type != TOKEN_TAG_END2 &&
token->type != TOKEN_EOF);
if (!isVoid && token->type == TOKEN_TAG_END && depth < MAX_DEPTH)
{
long startSourceLineNumber = getSourceLineNumber ();
long startLineNumber = getInputLineNumber ();
long startLineOffset = getInputLineOffset ();
long endLineNumber;
long endLineOffset;
bool tag_start2;
if (startTag == KEYWORD_script)
{
bool script = skipScriptContent (token, &endLineNumber, &endLineOffset);
if (script)
makePromise ("JavaScript", startLineNumber, startLineOffset,
endLineNumber, endLineOffset, startSourceLineNumber);
readToken (token, true);
goto out;
}
tag_start2 = readTagContent (token, text, &endLineNumber, &endLineOffset, depth);
if (tag_start2)
{
readToken (token, true);
if (isHeading && textCreated && vStringLength (text) > 0)
{
keywordId endTag = lookupKeyword (vStringValue (token->string), Lang_html);
if (startTag == endTag)
{
htmlKind headingKind;
if (startTag == KEYWORD_h1)
headingKind = K_HEADING1;
else if (startTag == KEYWORD_h2)
headingKind = K_HEADING2;
else
headingKind = K_HEADING3;
vStringStripLeading (text);
vStringStripTrailing (text);
makeSimpleTag (text, headingKind);
}
}
else if (startTag == KEYWORD_style)
{
keywordId endTag = lookupKeyword (vStringValue (token->string), Lang_html);
if (startTag == endTag)
makePromise ("CSS", startLineNumber, startLineOffset,
endLineNumber, endLineOffset, startSourceLineNumber);
}
readToken (token, true);
}
}
}
out:
if (textCreated)
vStringDelete (text);
}
static void findHtmlTags (void)
{
tokenInfo token;
token.string = vStringNew ();
do
{
readToken (&token, true);
if (token.type == TOKEN_TAG_START)
readTag (&token, NULL, 0);
}
while (token.type != TOKEN_EOF);
vStringDelete (token.string);
}
static void initialize (const langType language)
{
Lang_html = language;
}
/* parser definition */
extern parserDefinition* HtmlParser (void)
{
static const char *const extensions [] = { "htm", "html", NULL };
parserDefinition *const def = parserNew ("HTML");
def->extensions = extensions;
def->tagRegexTable = htmlTagRegexTable;
def->tagRegexCount = ARRAY_SIZE (htmlTagRegexTable);
def->method = METHOD_NOT_CRAFTED|METHOD_REGEX;
parserDefinition* def = parserNew ("HTML");
def->kindTable = HtmlKinds;
def->kindCount = ARRAY_SIZE (HtmlKinds);
def->extensions = extensions;
def->parser = findHtmlTags;
def->initialize = initialize;
def->keywordTable = HtmlKeywordTable;
def->keywordCount = ARRAY_SIZE (HtmlKeywordTable);
return def;
}

View File

@ -29,7 +29,7 @@ typedef enum {
K_KEY
} confKind;
static kindOption ConfKinds [] = {
static kindDefinition ConfKinds [] = {
{ true, 'n', "namespace", "sections"},
{ true, 'm', "macro", "keys"}
};
@ -67,7 +67,7 @@ static void findConfTags (void)
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, ConfKinds, K_SECTION);
makeSimpleTag (name, K_SECTION);
/* remember section name */
vStringCopy (scope, name);
vStringClear (name);
@ -90,11 +90,11 @@ static void findConfTags (void)
if (*cp == '=')
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), &(ConfKinds [K_KEY]));
initTagEntry (&e, vStringValue (name), K_KEY);
if (vStringLength (scope) > 0)
{
e.extensionFields.scopeKind = &(ConfKinds [K_SECTION]);
e.extensionFields.scopeKindIndex = K_SECTION;
e.extensionFields.scopeName = vStringValue(scope);
}
makeTagEntry (&e);
@ -119,7 +119,7 @@ extern parserDefinition* ConfParser (void)
static const char *const patterns [] = { "*.ini", "*.conf", NULL };
static const char *const extensions [] = { "conf", NULL };
parserDefinition* const def = parserNew ("Conf");
def->kinds = ConfKinds;
def->kindTable = ConfKinds;
def->kindCount = ARRAY_SIZE (ConfKinds);
def->patterns = patterns;
def->extensions = extensions;

File diff suppressed because it is too large Load Diff

View File

@ -69,7 +69,7 @@ typedef enum {
static langType Lang_json;
static kindOption JsonKinds [] = {
static kindDefinition JsonKinds [] = {
{ true, 'o', "object", "objects" },
{ true, 'a', "array", "arrays" },
{ true, 'n', "number", "numbers" },
@ -116,7 +116,7 @@ static void makeJsonTag (tokenInfo *const token, const jsonKind kind)
if (! JsonKinds[kind].enabled)
return;
initTagEntry (&e, vStringValue (token->string), &(JsonKinds[kind]));
initTagEntry (&e, vStringValue (token->string), kind);
e.lineNumber = token->lineNumber;
e.filePosition = token->filePosition;
@ -125,7 +125,7 @@ static void makeJsonTag (tokenInfo *const token, const jsonKind kind)
{
Assert (token->scopeKind > TAG_NONE && token->scopeKind < TAG_COUNT);
e.extensionFields.scopeKind = &(JsonKinds[token->scopeKind]);
e.extensionFields.scopeKindIndex = token->scopeKind;
e.extensionFields.scopeName = vStringValue (token->scope);
}
@ -379,7 +379,7 @@ extern parserDefinition* JsonParser (void)
static const char *const extensions [] = { "json", NULL };
parserDefinition *const def = parserNew ("JSON");
def->extensions = extensions;
def->kinds = JsonKinds;
def->kindTable = JsonKinds;
def->kindCount = ARRAY_SIZE (JsonKinds);
def->parser = findJsonTags;
def->initialize = initialize;

View File

@ -26,7 +26,7 @@ typedef enum {
K_FUNCTION
} luaKind;
static kindOption LuaKinds [] = {
static kindDefinition LuaKinds [] = {
{ true, 'f', "function", "functions" }
};
@ -72,7 +72,7 @@ static void extract_name (const char *begin, const char *end, vString *name)
for (cp = begin ; cp != end; cp++)
vStringPut (name, (int) *cp);
makeSimpleTag (name, LuaKinds, K_FUNCTION);
makeSimpleTag (name, K_FUNCTION);
vStringClear (name);
}
}
@ -112,7 +112,7 @@ extern parserDefinition* LuaParser (void)
{
static const char* const extensions [] = { "lua", NULL };
parserDefinition* def = parserNew ("Lua");
def->kinds = LuaKinds;
def->kindTable = LuaKinds;
def->kindCount = ARRAY_SIZE (LuaKinds);
def->extensions = extensions;
def->parser = findLuaTags;

View File

@ -30,7 +30,7 @@ typedef enum {
K_MACRO, K_TARGET
} shKind;
static kindOption MakeKinds [] = {
static kindDefinition MakeKinds [] = {
{ true, 'm', "macro", "macros"},
{ true, 't', "target", "targets"}
};
@ -97,12 +97,12 @@ static void newTarget (vString *const name)
{
return;
}
makeSimpleTag (name, MakeKinds, K_TARGET);
makeSimpleTag (name, K_TARGET);
}
static void newMacro (vString *const name)
{
makeSimpleTag (name, MakeKinds, K_MACRO);
makeSimpleTag (name, K_MACRO);
}
static void readIdentifier (const int first, vString *const id)
@ -225,7 +225,7 @@ extern parserDefinition* MakefileParser (void)
static const char *const patterns [] = { "[Mm]akefile", "GNUmakefile", NULL };
static const char *const extensions [] = { "mak", "mk", NULL };
parserDefinition* const def = parserNew ("Make");
def->kinds = MakeKinds;
def->kindTable = MakeKinds;
def->kindCount = ARRAY_SIZE (MakeKinds);
def->patterns = patterns;
def->extensions = extensions;

View File

@ -26,7 +26,7 @@
* DATA DEFINITIONS
*/
static kindOption MarkdownKinds[] = {
static kindDefinition MarkdownKinds[] = {
{ true, 'v', "variable", "sections" }
};
@ -50,7 +50,7 @@ static bool issame(const char *str)
static void makeMarkdownTag (const vString* const name, bool name_before)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue(name), &(MarkdownKinds [0]));
initTagEntry (&e, vStringValue(name), 0);
if (name_before)
e.lineNumber--; /* we want the line before the underline chars */
@ -93,7 +93,7 @@ extern parserDefinition* MarkdownParser (void)
static const char *const extensions [] = { "md", NULL };
parserDefinition* const def = parserNew ("Markdown");
def->kinds = MarkdownKinds;
def->kindTable = MarkdownKinds;
def->kindCount = ARRAY_SIZE (MarkdownKinds);
def->patterns = patterns;
def->extensions = extensions;

View File

@ -30,7 +30,7 @@ typedef enum {
K_STRUCT
} MatlabKind;
static kindOption MatlabKinds [] = {
static kindDefinition MatlabKinds [] = {
{ true, 'f', "function", "Functions" },
{ true, 's', "struct", "Structures" },
};
@ -107,7 +107,7 @@ static void findMatlabTags (void)
}
}
makeSimpleTag (name, MatlabKinds, K_FUNCTION);
makeSimpleTag (name, K_FUNCTION);
vStringClear (name);
}
@ -128,18 +128,18 @@ static void findMatlabTags (void)
++cp;
}
makeSimpleTag (name, MatlabKinds, K_STRUCT);
makeSimpleTag (name, K_STRUCT);
vStringClear (name);
}
}
vStringDelete (name);
}
extern parserDefinition* MatlabParser (void)
extern parserDefinition* MatLabParser (void)
{
static const char *const extensions [] = { "m", NULL };
parserDefinition* def = parserNew ("Matlab");
def->kinds = MatlabKinds;
def->kindTable = MatlabKinds;
def->kindCount = ARRAY_SIZE (MatlabKinds);
def->extensions = extensions;
def->parser = findMatlabTags;

View File

@ -30,7 +30,7 @@ typedef enum {
K_VARIABLE
} NsisKind;
static kindOption NsisKinds [] = {
static kindDefinition NsisKinds [] = {
{ true, 'n', "namespace", "sections"},
{ true, 'f', "function", "functions"},
{ true, 'v', "variable", "variables"}
@ -68,7 +68,7 @@ static void findNsisTags (void)
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, NsisKinds, K_FUNCTION);
makeSimpleTag (name, K_FUNCTION);
vStringClear (name);
}
/* variables */
@ -93,7 +93,7 @@ static void findNsisTags (void)
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, NsisKinds, K_VARIABLE);
makeSimpleTag (name, K_VARIABLE);
vStringClear (name);
}
/* sections */
@ -122,7 +122,7 @@ static void findNsisTags (void)
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, NsisKinds, K_SECTION);
makeSimpleTag (name, K_SECTION);
vStringClear (name);
}
}
@ -135,7 +135,7 @@ extern parserDefinition* NsisParser (void)
"nsi", "nsh", NULL
};
parserDefinition* def = parserNew ("NSIS");
def->kinds = NsisKinds;
def->kindTable = NsisKinds;
def->kindCount = ARRAY_SIZE (NsisKinds);
def->extensions = extensions;
def->parser = findNsisTags;

View File

@ -38,7 +38,7 @@ typedef enum {
K_MACRO
} objcKind;
static kindOption ObjcKinds[] = {
static kindDefinition ObjcKinds[] = {
{true, 'i', "interface", "class interface"},
{true, 'I', "implementation", "class implementation"},
{true, 'P', "protocol", "Protocol"},
@ -423,11 +423,11 @@ static objcKind parentType = K_INTERFACE;
* add additional information to the tag. */
static void prepareTag (tagEntryInfo * tag, vString const *name, objcKind kind)
{
initTagEntry (tag, vStringValue (name), &(ObjcKinds[kind]));
initTagEntry (tag, vStringValue (name), kind);
if (parentName != NULL)
{
tag->extensionFields.scopeKind = &(ObjcKinds[parentType]);
tag->extensionFields.scopeKindIndex = parentType;
tag->extensionFields.scopeName = vStringValue (parentName);
}
}
@ -1110,7 +1110,7 @@ extern parserDefinition *ObjcParser (void)
{
static const char *const extensions[] = { "m", "h", NULL };
parserDefinition *def = parserNewFull ("ObjectiveC", KIND_FILE_ALT);
def->kinds = ObjcKinds;
def->kindTable = ObjcKinds;
def->kindCount = ARRAY_SIZE (ObjcKinds);
def->extensions = extensions;
def->parser = findObjcTags;

View File

@ -28,7 +28,7 @@ typedef enum {
K_FUNCTION, K_PROCEDURE
} pascalKind;
static kindOption PascalKinds [] = {
static kindDefinition PascalKinds [] = {
{ true, 'f', "function", "functions"},
{ true, 'p', "procedure", "procedures"}
};
@ -43,14 +43,16 @@ static void createPascalTag (tagEntryInfo* const tag,
{
if (PascalKinds [kind].enabled && name != NULL && vStringLength (name) > 0)
{
initTagEntry (tag, vStringValue (name), &(PascalKinds [kind]));
initTagEntry (tag, vStringValue (name), kind);
tag->extensionFields.signature = arglist;
tag->extensionFields.varType = vartype;
}
else
{
/* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */
initTagEntry (tag, NULL, NULL);
/* initTagEntry (tag, NULL, NULL); */
}
}
static void makePascalTag (const tagEntryInfo* const tag)
@ -349,7 +351,7 @@ extern parserDefinition* PascalParser (void)
static const char *const extensions [] = { "p", "pas", NULL };
parserDefinition* def = parserNew ("Pascal");
def->extensions = extensions;
def->kinds = PascalKinds;
def->kindTable = PascalKinds;
def->kindCount = ARRAY_SIZE (PascalKinds);
def->parser = findPascalTags;
return def;

View File

@ -39,7 +39,7 @@ typedef enum {
K_SUBROUTINE_DECLARATION
} perlKind;
static kindOption PerlKinds [] = {
static kindDefinition PerlKinds [] = {
{ true, 'c', "constant", "constants" },
{ true, 'f', "format", "formats" },
{ true, 'l', "label", "labels" },
@ -319,12 +319,12 @@ static void findPerlTags (void)
* isSubroutineDeclaration() may consume several lines. So
* we record line positions.
*/
initTagEntry(&e, vStringValue(name), &(PerlKinds[kind]));
initTagEntry(&e, vStringValue(name), kind);
if (true == isSubroutineDeclaration(cp)) {
if (true == PerlKinds[K_SUBROUTINE_DECLARATION].enabled) {
kind = K_SUBROUTINE_DECLARATION;
e.kind = &(PerlKinds[kind]);
e.kindIndex = kind;
} else {
vStringClear (name);
continue;
@ -345,7 +345,7 @@ static void findPerlTags (void)
}
} else if (vStringLength (name) > 0)
{
makeSimpleTag (name, PerlKinds, kind);
makeSimpleTag (name, kind);
if (isXtagEnabled(XTAG_QUALIFIED_TAGS) && qualified &&
K_PACKAGE != kind &&
package != NULL && vStringLength (package) > 0)
@ -353,7 +353,7 @@ static void findPerlTags (void)
vString *const qualifiedName = vStringNew ();
vStringCopy (qualifiedName, package);
vStringCat (qualifiedName, name);
makeSimpleTag (qualifiedName, PerlKinds, kind);
makeSimpleTag (qualifiedName, kind);
vStringDelete (qualifiedName);
}
}
@ -371,7 +371,7 @@ extern parserDefinition* PerlParser (void)
{
static const char *const extensions [] = { "pl", "pm", "plx", "perl", NULL };
parserDefinition* def = parserNew ("Perl");
def->kinds = PerlKinds;
def->kindTable = PerlKinds;
def->kindCount = ARRAY_SIZE (PerlKinds);
def->extensions = extensions;
def->parser = findPerlTags;

View File

@ -113,7 +113,7 @@ typedef enum {
COUNT_KIND
} phpKind;
static kindOption PhpKinds[COUNT_KIND] = {
static kindDefinition PhpKinds[COUNT_KIND] = {
{ true, 'c', "class", "classes" },
{ true, 'd', "define", "constant definitions" },
{ true, 'f', "function", "functions" },
@ -280,7 +280,7 @@ static void initPhpEntry (tagEntryInfo *const e, const tokenInfo *const token,
parentKind = K_NAMESPACE;
}
initTagEntry (e, vStringValue (token->string), &(PhpKinds[kind]));
initTagEntry (e, vStringValue (token->string), kind);
e->lineNumber = token->lineNumber;
e->filePosition = token->filePosition;
@ -298,7 +298,7 @@ static void initPhpEntry (tagEntryInfo *const e, const tokenInfo *const token,
{
Assert (parentKind >= 0);
e->extensionFields.scopeKind = &(PhpKinds[parentKind]);
e->extensionFields.scopeKindIndex = parentKind;
e->extensionFields.scopeName = vStringValue (fullScope);
}
}
@ -321,7 +321,7 @@ static void makeNamespacePhpTag (const tokenInfo *const token, const vString *co
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), &(PhpKinds[K_NAMESPACE]));
initTagEntry (&e, vStringValue (name), K_NAMESPACE);
e.lineNumber = token->lineNumber;
e.filePosition = token->filePosition;
@ -1453,7 +1453,7 @@ extern parserDefinition* PhpParser (void)
{
static const char *const extensions [] = { "php", "php3", "php4", "php5", "phtml", NULL };
parserDefinition* def = parserNew ("PHP");
def->kinds = PhpKinds;
def->kindTable = PhpKinds;
def->kindCount = ARRAY_SIZE (PhpKinds);
def->extensions = extensions;
def->parser = findPhpTags;
@ -1467,7 +1467,7 @@ extern parserDefinition* ZephirParser (void)
{
static const char *const extensions [] = { "zep", NULL };
parserDefinition* def = parserNew ("Zephir");
def->kinds = PhpKinds;
def->kindTable = PhpKinds;
def->kindCount = ARRAY_SIZE (PhpKinds);
def->extensions = extensions;
def->parser = findZephirTags;

View File

@ -42,7 +42,7 @@ typedef enum {
COUNT_KIND
} powerShellKind;
static kindOption PowerShellKinds[COUNT_KIND] = {
static kindDefinition PowerShellKinds[COUNT_KIND] = {
{ true, 'f', "function", "functions" },
{ true, 'v', "variable", "variables" }
};
@ -98,7 +98,7 @@ static const char *findValidAccessType (const char *const access)
static void initPowerShellEntry (tagEntryInfo *const e, const tokenInfo *const token,
const powerShellKind kind, const char *const access)
{
initTagEntry (e, vStringValue (token->string), &(PowerShellKinds[kind]));
initTagEntry (e, vStringValue (token->string), kind);
e->lineNumber = token->lineNumber;
e->filePosition = token->filePosition;
@ -110,7 +110,7 @@ static void initPowerShellEntry (tagEntryInfo *const e, const tokenInfo *const t
int parentKind = token->parentKind;
Assert (parentKind >= 0);
e->extensionFields.scopeKind = &(PowerShellKinds[parentKind]);
e->extensionFields.scopeKindIndex = parentKind;
e->extensionFields.scopeName = vStringValue (token->scope);
}
}
@ -600,7 +600,7 @@ extern parserDefinition* PowerShellParser (void)
{
static const char *const extensions [] = { "ps1", "psm1", NULL };
parserDefinition* def = parserNew ("PowerShell");
def->kinds = PowerShellKinds;
def->kindTable = PowerShellKinds;
def->kindCount = ARRAY_SIZE (PowerShellKinds);
def->extensions = extensions;
def->parser = findPowerShellTags;

View File

@ -42,7 +42,7 @@ typedef enum {
K_CLASS, K_FUNCTION, K_METHOD, K_VARIABLE, K_IMPORT
} pythonKind;
static kindOption PythonKinds[] = {
static kindDefinition PythonKinds[] = {
{true, 'c', "class", "classes"},
{true, 'f', "function", "functions"},
{true, 'm', "member", "class members"},
@ -131,18 +131,18 @@ static struct corkInfo makeFunctionTag (vString *const function,
{
if (is_class_parent)
{
initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_METHOD]));
tag.extensionFields.scopeKind = &(PythonKinds[K_CLASS]);
initTagEntry (&tag, vStringValue (function), K_METHOD);
tag.extensionFields.scopeKindIndex = K_CLASS;
}
else
{
initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_FUNCTION]));
tag.extensionFields.scopeKind = &(PythonKinds[K_FUNCTION]);
initTagEntry (&tag, vStringValue (function), K_FUNCTION);
tag.extensionFields.scopeKindIndex = K_FUNCTION;
}
tag.extensionFields.scopeName = vStringValue (parent);
}
else
initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_FUNCTION]));
initTagEntry (&tag, vStringValue (function), K_FUNCTION);
tag.extensionFields.signature = arglist;
@ -162,17 +162,17 @@ static int makeClassTag (vString *const class, vString *const inheritance,
vString *const parent, int is_class_parent)
{
tagEntryInfo tag;
initTagEntry (&tag, vStringValue (class), &(PythonKinds[K_CLASS]));
initTagEntry (&tag, vStringValue (class), K_CLASS);
if (vStringLength (parent) > 0)
{
if (is_class_parent)
{
tag.extensionFields.scopeKind = &(PythonKinds[K_CLASS]);
tag.extensionFields.scopeKindIndex = K_CLASS;
tag.extensionFields.scopeName = vStringValue (parent);
}
else
{
tag.extensionFields.scopeKind = &(PythonKinds[K_FUNCTION]);
tag.extensionFields.scopeKindIndex = K_FUNCTION;
tag.extensionFields.scopeName = vStringValue (parent);
}
}
@ -186,10 +186,10 @@ static void makeVariableTag (vString *const var, vString *const parent,
bool is_class_parent)
{
tagEntryInfo tag;
initTagEntry (&tag, vStringValue (var), &(PythonKinds[K_VARIABLE]));
initTagEntry (&tag, vStringValue (var), K_VARIABLE);
if (vStringLength (parent) > 0)
{
tag.extensionFields.scopeKind = &(PythonKinds[K_CLASS]);
tag.extensionFields.scopeKindIndex = K_CLASS;
tag.extensionFields.scopeName = vStringValue (parent);
}
addAccessFields (&tag, var, K_VARIABLE, vStringLength (parent) > 0,
@ -371,7 +371,7 @@ static void parseImports (const char *cp)
if (strcmp (vStringValue (name_next), "as") != 0 &&
strcmp (vStringValue (name), "as") != 0)
{
makeSimpleTag (name, PythonKinds, K_IMPORT);
makeSimpleTag (name, K_IMPORT);
}
}
vStringDelete (name);
@ -456,7 +456,7 @@ static bool constructParentString(NestingLevels *nls, int indent,
if (e)
{
vStringCatS(result, e->name);
is_class = ((e->kind - PythonKinds) == K_CLASS);
is_class = (e->kindIndex == K_CLASS);
}
else
is_class = false;
@ -853,7 +853,7 @@ extern parserDefinition *PythonParser (void)
{
static const char *const extensions[] = { "py", "pyx", "pxd", "pxi" ,"scons", NULL };
parserDefinition *def = parserNew ("Python");
def->kinds = PythonKinds;
def->kindTable = PythonKinds;
def->kindCount = ARRAY_SIZE (PythonKinds);
def->extensions = extensions;
def->parser = findPythonTags;

View File

@ -34,7 +34,7 @@ typedef enum {
KIND_COUNT
} rKind;
static kindOption RKinds [KIND_COUNT] = {
static kindDefinition RKinds [KIND_COUNT] = {
{true, 'f', "function", "functions"},
{true, 'l', "library", "libraries"},
{true, 's', "source", "sources"},
@ -43,7 +43,7 @@ static kindOption RKinds [KIND_COUNT] = {
static void makeRTag (const vString * const name, rKind kind)
{
tagEntryInfo e;
initTagEntry(&e, vStringValue(name), &(RKinds[kind]));
initTagEntry(&e, vStringValue(name), kind);
Assert (kind < KIND_COUNT);
@ -168,7 +168,7 @@ extern parserDefinition *RParser (void)
*/
static const char *const extensions [] = { "r", "s", "q", NULL };
parserDefinition *const def = parserNew ("R");
def->kinds = RKinds;
def->kindTable = RKinds;
def->kindCount = ARRAY_SIZE (RKinds);
def->extensions = extensions;
def->parser = createRTags;

View File

@ -1,207 +0,0 @@
/*
*
* Copyright (c) 2007-2011, Nick Treleaven
*
* 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 reStructuredText (reST) files.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include <ctype.h>
#include <string.h>
#include "parse.h"
#include "read.h"
#include "vstring.h"
#include "nestlevel.h"
#include "routines.h"
#include "entry.h"
/*
* DATA DEFINITIONS
*/
typedef enum {
K_CHAPTER = 0,
K_SECTION,
K_SUBSECTION,
K_SUBSUBSECTION,
SECTION_COUNT
} restKind;
static kindOption RestKinds[] = {
{ true, 'n', "namespace", "chapters"},
{ true, 'm', "member", "sections" },
{ true, 'd', "macro", "subsections" },
{ true, 'v', "variable", "subsubsections" }
};
static char kindchars[SECTION_COUNT];
static NestingLevels *nestingLevels = NULL;
/*
* FUNCTION DEFINITIONS
*/
static void popNestingLevelToKind(const int kind)
{
NestingLevel *nl;
tagEntryInfo *e;
while (1)
{
nl = nestingLevelsGetCurrent(nestingLevels);
e = getEntryOfNestingLevel (nl);
if ((nl && (e == NULL)) || (e && (e->kind - RestKinds) >= kind))
nestingLevelsPop(nestingLevels);
else
break;
}
}
static void makeRestTag (const vString* const name, const int kind)
{
int r = CORK_NIL;
popNestingLevelToKind(kind);
if (vStringLength (name) > 0)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), &(RestKinds [kind]));
e.lineNumber--; /* we want the line before the '---' underline chars */
r = makeTagEntry (&e);
}
nestingLevelsPush(nestingLevels, r);
}
/* checks if str is all the same character */
static bool issame(const char *str)
{
char first = *str;
while (*str)
{
char c;
str++;
c = *str;
if (c && c != first)
return false;
}
return true;
}
static int get_kind(char c)
{
int i;
for (i = 0; i < SECTION_COUNT; i++)
{
if (kindchars[i] == c)
return i;
if (kindchars[i] == 0)
{
kindchars[i] = c;
return i;
}
}
return -1;
}
/* computes the length of an UTF-8 string
* if the string doesn't look like UTF-8, return -1 */
static int utf8_strlen(const char *buf, int buf_len)
{
int len = 0;
const char *end = buf + buf_len;
for (len = 0; buf < end; len ++)
{
/* perform quick and naive validation (no sub-byte checking) */
if (! (*buf & 0x80))
buf ++;
else if ((*buf & 0xe0) == 0xc0)
buf += 2;
else if ((*buf & 0xf0) == 0xe0)
buf += 3;
else if ((*buf & 0xf8) == 0xf0)
buf += 4;
else /* not a valid leading UTF-8 byte, abort */
return -1;
if (buf > end) /* incomplete last byte */
return -1;
}
return len;
}
/* TODO: parse overlining & underlining as distinct sections. */
static void findRestTags (void)
{
vString *name = vStringNew ();
const unsigned char *line;
memset(kindchars, 0, sizeof kindchars);
nestingLevels = nestingLevelsNew(0);
while ((line = readLineFromInputFile ()) != NULL)
{
int line_len = strlen((const char*) line);
int name_len_bytes = vStringLength(name);
int name_len = utf8_strlen(vStringValue(name), name_len_bytes);
/* if the name doesn't look like UTF-8, assume one-byte charset */
if (name_len < 0)
name_len = name_len_bytes;
/* underlines must be the same length or more */
if (line_len >= name_len && name_len > 0 &&
ispunct(line[0]) && issame((const char*) line))
{
char c = line[0];
int kind = get_kind(c);
if (kind >= 0)
{
makeRestTag(name, kind);
continue;
}
}
vStringClear (name);
if (! isspace(*line))
vStringCatS(name, (const char*) line);
}
vStringDelete (name);
nestingLevelsFree(nestingLevels);
}
extern parserDefinition* RestParser (void)
{
static const char *const patterns [] = { "*.rest", "*.reST", NULL };
static const char *const extensions [] = { "rest", NULL };
parserDefinition* const def = parserNew ("reStructuredText");
def->kinds = RestKinds;
def->kindCount = ARRAY_SIZE (RestKinds);
def->patterns = patterns;
def->extensions = extensions;
def->parser = findRestTags;
def->useCork = true;
return def;
}

379
ctags/parsers/rst.c Normal file
View File

@ -0,0 +1,379 @@
/*
*
* Copyright (c) 2007-2011, Nick Treleaven
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* This module contains functions for generating tags for reStructuredText (reST) files.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include <ctype.h>
#include <string.h>
#include "parse.h"
#include "read.h"
#include "vstring.h"
#include "nestlevel.h"
#include "entry.h"
#include "routines.h"
#include "field.h"
/*
* DATA DEFINITIONS
*/
typedef enum {
K_EOF = -1,
K_CHAPTER = 0,
K_SECTION,
K_SUBSECTION,
K_SUBSUBSECTION,
K_TARGET,
SECTION_COUNT
} rstKind;
static kindDefinition RstKinds[] = {
{ true, 'c', "chapter", "chapters"},
{ true, 's', "section", "sections" },
{ true, 'S', "subsection", "subsections" },
{ true, 't', "subsubsection", "subsubsections" },
{ true, 'T', "target", "targets" },
};
typedef enum {
F_SECTION_MARKER,
} rstField;
static fieldDefinition RstFields [] = {
{
.name = "sectionMarker",
.description = "character used for declaring section",
.enabled = false,
},
};
static char kindchars[SECTION_COUNT];
static NestingLevels *nestingLevels = NULL;
/*
* FUNCTION DEFINITIONS
*/
static NestingLevel *getNestingLevel(const int kind)
{
NestingLevel *nl;
tagEntryInfo *e;
int d = 0;
if (kind > K_EOF)
{
d++;
/* 1. we want the line before the '---' underline chars */
d++;
/* 2. we want the line before the next section/chapter title. */
}
while (1)
{
nl = nestingLevelsGetCurrent(nestingLevels);
e = getEntryOfNestingLevel (nl);
if ((nl && (e == NULL)) || (e && e->kindIndex >= kind))
{
if (e)
e->extensionFields.endLine = (getInputLineNumber() - d);
nestingLevelsPop(nestingLevels);
}
else
break;
}
return nl;
}
static int makeTargetRstTag(const vString* const name)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name), K_TARGET);
const NestingLevel *nl = nestingLevelsGetCurrent(nestingLevels);
tagEntryInfo *parent = NULL;
if (nl)
parent = getEntryOfNestingLevel (nl);
if (parent)
{
e.extensionFields.scopeKindIndex = parent->kindIndex;
e.extensionFields.scopeName = parent->name;
}
return makeTagEntry (&e);
}
static void makeSectionRstTag(const vString* const name, const int kind, const MIOPos filepos,
char marker)
{
const NestingLevel *const nl = getNestingLevel(kind);
tagEntryInfo *parent;
int r = CORK_NIL;
if (vStringLength (name) > 0)
{
tagEntryInfo e;
char m [2] = { [1] = '\0' };
initTagEntry (&e, vStringValue (name), kind);
e.lineNumber--; /* we want the line before the '---' underline chars */
e.filePosition = filepos;
parent = getEntryOfNestingLevel (nl);
if (parent && (parent->kindIndex < kind))
{
#if 1
e.extensionFields.scopeKindIndex = parent->kindIndex;
e.extensionFields.scopeName = parent->name;
#else
/* TODO
Following code makes the scope information full qualified form.
Do users want the full qualified form?
--- ./Units/rst.simple.d/expected.tags 2015-12-18 01:32:35.574255617 +0900
+++ /home/yamato/var/ctags-github/Units/rst.simple.d/FILTERED.tmp 2016-05-05 03:05:38.165604756 +0900
@@ -5,2 +5,2 @@
-Subsection 1.1.1 input.rst /^Subsection 1.1.1$/;" S section:Section 1.1
-Subsubsection 1.1.1.1 input.rst /^Subsubsection 1.1.1.1$/;" t subsection:Subsection 1.1.1
+Subsection 1.1.1 input.rst /^Subsection 1.1.1$/;" S section:Chapter 1.Section 1.1
+Subsubsection 1.1.1.1 input.rst /^Subsubsection 1.1.1.1$/;" t subsection:Chapter 1.Section 1.1.Subsection 1.1.1
*/
e.extensionFields.scopeIndex = nl->corkIndex;
#endif
}
m[0] = marker;
attachParserField (&e, RstFields [F_SECTION_MARKER].ftype, m);
r = makeTagEntry (&e);
}
nestingLevelsPush(nestingLevels, r);
}
/* checks if str is all the same character */
static bool issame(const char *str)
{
char first = *str;
while (*str)
{
char c;
str++;
c = *str;
if (c && c != first)
return false;
}
return true;
}
static int get_kind(char c)
{
int i;
for (i = 0; i < SECTION_COUNT; i++)
{
if (kindchars[i] == c)
return i;
if (kindchars[i] == 0)
{
kindchars[i] = c;
return i;
}
}
return -1;
}
/* computes the length of an UTF-8 string
* if the string doesn't look like UTF-8, return -1 */
static int utf8_strlen(const char *buf, int buf_len)
{
int len = 0;
const char *end = buf + buf_len;
for (len = 0; buf < end; len ++)
{
/* perform quick and naive validation (no sub-byte checking) */
if (! (*buf & 0x80))
buf ++;
else if ((*buf & 0xe0) == 0xc0)
buf += 2;
else if ((*buf & 0xf0) == 0xe0)
buf += 3;
else if ((*buf & 0xf8) == 0xf0)
buf += 4;
else /* not a valid leading UTF-8 byte, abort */
return -1;
if (buf > end) /* incomplete last byte */
return -1;
}
return len;
}
static const unsigned char *is_target_line (const unsigned char *line)
{
if ((line [0] == '.') && (line [1] == '.') && (line [2] == ' ')
&& (line [3] == '_'))
return line + 4;
return NULL;
}
static int capture_target (const unsigned char *target_line)
{
vString *name = vStringNew ();
unsigned char terminator;
int r = CORK_NIL;
if (*target_line == '`')
terminator = '`';
else if (!isspace (*target_line) && *target_line != '\0')
{
/* "Simple reference names are single words consisting of
* alphanumerics plus isolated (no two adjacent) internal
* hyphens, underscores, periods, colons and plus signs; no
* whitespace or other characters are allowed."
* -- http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#reference-names
*/
vStringPut (name, *target_line);
terminator = ':';
}
else
goto out;
target_line++;
bool escaped = false;
while (*target_line != '\0')
{
if (escaped)
{
vStringPut (name, *target_line);
escaped = false;
}
else
{
if (*target_line == '\\')
{
vStringPut (name, *target_line);
escaped = true;
}
else if (*target_line == terminator)
break;
else
vStringPut (name, *target_line);
}
target_line++;
}
if (vStringLength (name) == 0)
goto out;
r = makeTargetRstTag (name);
out:
vStringDelete (name);
return r;
}
/* TODO: parse overlining & underlining as distinct sections. */
static void findRstTags (void)
{
vString *name = vStringNew ();
MIOPos filepos;
const unsigned char *line;
const unsigned char *target_line;
memset(&filepos, 0, sizeof(filepos));
memset(kindchars, 0, sizeof kindchars);
nestingLevels = nestingLevelsNew(0);
while ((line = readLineFromInputFile ()) != NULL)
{
/* Handle .. _target:
* http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#hyperlink-targets
*/
if ((target_line = is_target_line (line)) != NULL)
{
if (capture_target (target_line) != CORK_NIL)
{
vStringClear (name);
continue;
}
}
int line_len = strlen((const char*) line);
int name_len_bytes = vStringLength(name);
/* FIXME: this isn't right, actually we need the real display width,
* taking into account double-width characters and stuff like that.
* But duh. */
int name_len = utf8_strlen(vStringValue(name), name_len_bytes);
/* if the name doesn't look like UTF-8, assume one-byte charset */
if (name_len < 0)
name_len = name_len_bytes;
/* underlines must be the same length or more */
if (line_len >= name_len && name_len > 0 &&
ispunct(line[0]) && issame((const char*) line))
{
char c = line[0];
int kind = get_kind(c);
if (kind >= 0)
{
makeSectionRstTag(name, kind, filepos, c);
continue;
}
}
vStringClear (name);
if (!isspace(*line))
{
vStringCatS(name, (const char*)line);
filepos = getInputFilePosition();
}
}
/* Force popping all nesting levels */
getNestingLevel (K_EOF);
vStringDelete (name);
nestingLevelsFree(nestingLevels);
}
extern parserDefinition* RstParser (void)
{
static const char *const extensions [] = { "rest", "reST", "rst", NULL };
parserDefinition* const def = parserNew ("ReStructuredText");
def->kindTable = RstKinds;
def->kindCount = ARRAY_SIZE (RstKinds);
def->extensions = extensions;
def->parser = findRstTags;
def->fieldTable = RstFields;
def->fieldCount = ARRAY_SIZE (RstFields);
def->useCork = true;
return def;
}

View File

@ -35,7 +35,7 @@ typedef enum {
/*
* DATA DEFINITIONS
*/
static kindOption RubyKinds [] = {
static kindDefinition RubyKinds [] = {
{ true, 'c', "class", "classes" },
{ true, 'f', "method", "methods" },
{ true, 'm', "module", "modules" },
@ -196,7 +196,7 @@ static void emitRubyTag (vString* name, rubyKind kind)
lvl = nestingLevelsGetCurrent (nesting);
parent = getEntryOfNestingLevel (lvl);
if (parent)
parent_kind = parent->kind - RubyKinds;
parent_kind = parent->kindIndex;
qualified_name = vStringValue (name);
unqualified_name = strrchr (qualified_name, SCOPE_SEPARATOR);
@ -216,12 +216,12 @@ static void emitRubyTag (vString* name, rubyKind kind)
else
unqualified_name = qualified_name;
initTagEntry (&tag, unqualified_name, &(RubyKinds [kind]));
initTagEntry (&tag, unqualified_name, kind);
if (vStringLength (scope) > 0) {
Assert (0 <= parent_kind &&
(size_t) parent_kind < (ARRAY_SIZE (RubyKinds)));
tag.extensionFields.scopeKind = &(RubyKinds [parent_kind]);
tag.extensionFields.scopeKindIndex = parent_kind;
tag.extensionFields.scopeName = vStringValue (scope);
}
r = makeTagEntry (&tag);
@ -378,7 +378,7 @@ static void enterUnnamedScope (void)
if (e_parent)
{
tagEntryInfo e;
initTagEntry (&e, "", e_parent->kind);
initTagEntry (&e, "", e_parent->kindIndex);
e.placeholder = 1;
r = makeTagEntry (&e);
}
@ -484,7 +484,7 @@ static void findRubyTags (void)
* end
* end
*/
if (e && (e->kind - RubyKinds) == K_CLASS && strlen (e->name) == 0)
if (e && e->kindIndex == K_CLASS && strlen (e->name) == 0)
kind = K_SINGLETON;
readAndEmitTag (&cp, kind);
}
@ -555,7 +555,7 @@ extern parserDefinition* RubyParser (void)
{
static const char *const extensions [] = { "rb", "ruby", NULL };
parserDefinition* def = parserNewFull ("Ruby", KIND_FILE_ALT);
def->kinds = RubyKinds;
def->kindTable = RubyKinds;
def->kindCount = ARRAY_SIZE (RubyKinds);
def->extensions = extensions;
def->parser = findRubyTags;

View File

@ -47,7 +47,7 @@ typedef enum {
K_NONE
} RustKind;
static kindOption rustKinds[] = {
static kindDefinition rustKinds[] = {
{true, 'n', "module", "module"},
{true, 's', "struct", "structural type"},
{true, 'i', "interface", "trait interface"},
@ -439,7 +439,7 @@ static void addTag (vString* ident, const char* type, const char* arg_list, int
if (kind == K_NONE)
return;
tagEntryInfo tag;
initTagEntry(&tag, ident->buffer, &(rustKinds[kind]));
initTagEntry(&tag, ident->buffer, kind);
tag.lineNumber = line;
tag.filePosition = pos;
@ -449,7 +449,7 @@ static void addTag (vString* ident, const char* type, const char* arg_list, int
tag.extensionFields.varType = type;
if (parent_kind != K_NONE)
{
tag.extensionFields.scopeKind = &(rustKinds[parent_kind]);
tag.extensionFields.scopeKindIndex = parent_kind;
tag.extensionFields.scopeName = scope->buffer;
}
makeTagEntry(&tag);
@ -974,7 +974,7 @@ extern parserDefinition *RustParser (void)
{
static const char *const extensions[] = { "rs", NULL };
parserDefinition *def = parserNewFull ("Rust", KIND_FILE_ALT);
def->kinds = rustKinds;
def->kindTable = rustKinds;
def->kindCount = ARRAY_SIZE (rustKinds);
def->extensions = extensions;
def->parser = findRustTags;

View File

@ -28,7 +28,7 @@ typedef enum {
K_FUNCTION
} shKind;
static kindOption ShKinds [] = {
static kindDefinition ShKinds [] = {
{ true, 'f', "function", "functions"}
};
@ -90,7 +90,7 @@ static void findShTags (void)
functionFound = true;
}
if (functionFound)
makeSimpleTag (name, ShKinds, K_FUNCTION);
makeSimpleTag (name, K_FUNCTION);
vStringClear (name);
}
vStringDelete (name);
@ -102,7 +102,7 @@ extern parserDefinition* ShParser (void)
"sh", "SH", "bsh", "bash", "ksh", "zsh", "ash", NULL
};
parserDefinition* def = parserNew ("Sh");
def->kinds = ShKinds;
def->kindTable = ShKinds;
def->kindCount = ARRAY_SIZE (ShKinds);
def->extensions = extensions;
def->parser = findShTags;

View File

@ -200,7 +200,7 @@ typedef enum {
SQLTAG_COUNT
} sqlKind;
static kindOption SqlKinds [] = {
static kindDefinition SqlKinds [] = {
{ true, 'c', "cursor", "cursors" },
{ false, 'd', "prototype", "prototypes" },
{ true, 'f', "function", "functions" },
@ -437,7 +437,7 @@ static void makeSqlTag (tokenInfo *const token, const sqlKind kind)
{
const char *const name = vStringValue (token->string);
tagEntryInfo e;
initTagEntry (&e, name, &(SqlKinds [kind]));
initTagEntry (&e, name, kind);
e.lineNumber = token->lineNumber;
e.filePosition = token->filePosition;
@ -445,7 +445,7 @@ static void makeSqlTag (tokenInfo *const token, const sqlKind kind)
if (vStringLength (token->scope) > 0)
{
Assert (token->scopeKind < SQLTAG_COUNT);
e.extensionFields.scopeKind = &(SqlKinds [token->scopeKind]);
e.extensionFields.scopeKindIndex = token->scopeKind;
e.extensionFields.scopeName = vStringValue (token->scope);
}
@ -2339,7 +2339,7 @@ extern parserDefinition* SqlParser (void)
{
static const char *const extensions [] = { "sql", NULL };
parserDefinition* def = parserNewFull ("SQL", KIND_FILE_ALT);
def->kinds = SqlKinds;
def->kindTable = SqlKinds;
def->kindCount = ARRAY_SIZE (SqlKinds);
def->extensions = extensions;
def->parser = findSqlTags;

View File

@ -26,7 +26,7 @@ typedef enum {
K_CLASS, K_METHOD, K_PROCEDURE, K_MODULE
} tclKind;
static kindOption TclKinds [] = {
static kindDefinition TclKinds [] = {
{ true, 'c', "class", "classes" },
{ true, 'm', "method", "methods" },
{ true, 'p', "procedure", "procedures" },
@ -48,7 +48,7 @@ static const unsigned char *makeTclTag (
vStringPut (name, (int) *cp);
++cp;
}
makeSimpleTag (name, TclKinds, kind);
makeSimpleTag (name, kind);
return cp;
}
@ -137,7 +137,7 @@ extern parserDefinition* TclParser (void)
{
static const char *const extensions [] = { "tcl", "tk", "wish", "itcl", NULL };
parserDefinition* def = parserNew ("Tcl");
def->kinds = TclKinds;
def->kindTable = TclKinds;
def->kindCount = ARRAY_SIZE (TclKinds);
def->extensions = extensions;
def->parser = findTclTags;

View File

@ -35,7 +35,7 @@ typedef enum {
K_LABEL
} TeXKind;
static kindOption TeXKinds[] = {
static kindDefinition TeXKinds[] = {
{ true, 'f', "function", "command definitions" },
{ true, 'c', "class", "environment definitions" },
{ true, 'm', "member", "labels, sections and bibliography" },
@ -106,7 +106,7 @@ static void createTag(int flags, TeXKind kind, const char * l)
++l;
} while ((*l != '\0') && (*l != '}'));
if (name->buffer[0] != '}')
makeSimpleTag(name, TeXKinds, kind);
makeSimpleTag(name, kind);
}
else if (isalpha((int) *l) || *l == '@')
{
@ -115,12 +115,12 @@ static void createTag(int flags, TeXKind kind, const char * l)
vStringPut (name, (int) *l);
++l;
} while (isalpha((int) *l) || *l == '@');
makeSimpleTag(name, TeXKinds, kind);
makeSimpleTag(name, kind);
}
else
{
vStringPut(name, (int) *l);
makeSimpleTag(name, TeXKinds, kind);
makeSimpleTag(name, kind);
}
no_tag:
@ -230,11 +230,11 @@ static void findTeXTags(void)
}
}
extern parserDefinition* LaTeXParser (void)
extern parserDefinition* TexParser (void)
{
static const char *const extensions [] = { "tex", "sty", "idx", NULL };
parserDefinition * def = parserNew ("LaTeX");
def->kinds = TeXKinds;
def->kindTable = TeXKinds;
def->kindCount = ARRAY_SIZE (TeXKinds);
def->extensions = extensions;
def->parser = findTeXTags;

View File

@ -38,10 +38,10 @@ typedef enum {
} Txt2tagsKind;
static scopeSeparator Txt2TagsSeparators [] = {
{ KIND_WILDCARD, SCOPE_SEPARATOR }
{ KIND_WILDCARD_INDEX, SCOPE_SEPARATOR }
};
static kindOption Txt2tagsKinds[] = {
static kindDefinition Txt2tagsKinds[] = {
{ true, 'm', "member", "sections",
ATTACH_SEPARATORS(Txt2TagsSeparators) },
};
@ -61,8 +61,7 @@ static int makeTxt2tagsTag (const vString* const name,
{
tagEntryInfo e;
NestingLevel *nl;
kindOption *kind = &Txt2tagsKinds[type];
initTagEntry (&e, vStringValue(name), kind);
initTagEntry (&e, vStringValue(name), type);
nl = nestingLevelsGetCurrent (nls);
if (nl)
@ -184,7 +183,7 @@ extern parserDefinition* Txt2tagsParser (void)
static const char *const extensions [] = { "t2t", NULL };
parserDefinition* const def = parserNew ("Txt2tags");
def->kinds = Txt2tagsKinds;
def->kindTable = Txt2tagsKinds;
def->kindCount = ARRAY_SIZE (Txt2tagsKinds);
def->patterns = patterns;
def->extensions = extensions;

View File

@ -55,7 +55,7 @@ static int Ungetc;
static int Lang_verilog;
static jmp_buf Exception;
static kindOption VerilogKinds [] = {
static kindDefinition VerilogKinds [] = {
{ true, 'c', "constant", "constants (define, parameter, specparam)" },
{ true, 'e', "event", "events" },
{ true, 'f', "function", "functions" },
@ -215,7 +215,7 @@ static void tagNameList (const verilogKind kind, int c)
if (isIdentifierCharacter (c))
{
readIdentifier (name, c);
makeSimpleTag (name, VerilogKinds, kind);
makeSimpleTag (name, kind);
}
else
break;
@ -255,7 +255,7 @@ static void findTag (vString *const name)
/* Bug #961001: Verilog compiler directives are line-based. */
int c = skipWhite (vGetc ());
readIdentifier (name, c);
makeSimpleTag (name, VerilogKinds, kind);
makeSimpleTag (name, kind);
/* Skip the rest of the line. */
do {
c = vGetc();
@ -323,7 +323,7 @@ extern parserDefinition* VerilogParser (void)
{
static const char *const extensions [] = { "v", NULL };
parserDefinition* def = parserNew ("Verilog");
def->kinds = VerilogKinds;
def->kindTable = VerilogKinds;
def->kindCount = ARRAY_SIZE (VerilogKinds);
def->extensions = extensions;
def->parser = findVerilogTags;

View File

@ -61,7 +61,7 @@ static vString* Lastname=NULL;
static vString* Keyword=NULL;
static vString* TagName=NULL;
static kindOption VhdlKinds [] = {
static kindDefinition VhdlKinds [] = {
{ true, 'c', "variable", "constants" },
{ true, 't', "typedef", "types" },
{ true, 'v', "variable", "variables" },
@ -177,7 +177,7 @@ static void tagNameList (const vhdlKind kind, int c)
if (isIdentifierCharacter (c))
{
readIdentifier (TagName, c);
makeSimpleTag (TagName, VhdlKinds, kind);
makeSimpleTag (TagName, kind);
}
}
@ -202,7 +202,7 @@ static void findTag (vString *const name)
kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl);
if (kind == K_PROCESS || kind == K_BLOCK || kind == K_PORT)
{
makeSimpleTag (Lastname, VhdlKinds, kind);
makeSimpleTag (Lastname, kind);
}
}
} else {
@ -225,7 +225,7 @@ static void findTag (vString *const name)
}
else if (kind == K_PROCESS || kind == K_BLOCK) {
vStringCopyS(TagName,"unnamed");
makeSimpleTag (TagName, VhdlKinds, kind);
makeSimpleTag (TagName, kind);
} else {
c = skipWhite (vGetc ());
if (c=='\"')
@ -278,7 +278,7 @@ extern parserDefinition* VhdlParser (void)
{
static const char *const extensions [] = { "vhdl", "vhd", NULL };
parserDefinition* def = parserNew ("Vhdl");
def->kinds = VhdlKinds;
def->kindTable = VhdlKinds;
def->kindCount = ARRAY_SIZE (VhdlKinds);
def->extensions = extensions;
def->parser = findVhdlTags;

View File

@ -30,6 +30,20 @@ typedef struct
TMTagType type;
} TMParserMapEntry;
/* Allows remapping a subparser tag type to another type if there's a clash with
* the master parser tag type. Only subparser tag types explicitly listed within
* TMSubparserMapEntry maps are added to tag manager - tags with types not listed
* are discarded to prevent uncontrolled merging of tags from master parser and
* subparsers. */
typedef struct
{
TMTagType orig_type;
TMTagType new_type;
} TMSubparserMapEntry;
static GHashTable *subparser_map = NULL;
static TMParserMapEntry map_C[] = {
{'c', tm_tag_class_t},
@ -242,6 +256,7 @@ static TMParserMapEntry map_JAVASCRIPT[] = {
{'p', tm_tag_member_t},
{'C', tm_tag_macro_t},
{'v', tm_tag_variable_t},
{'g', tm_tag_function_t},
};
/* not in universal-ctags */
@ -287,20 +302,23 @@ static TMParserMapEntry map_HAXE[] = {
{'t', tm_tag_typedef_t},
};
/* not in universal-ctags */
static TMParserMapEntry map_REST[] = {
{'n', tm_tag_namespace_t},
{'m', tm_tag_member_t},
{'d', tm_tag_macro_t},
{'v', tm_tag_variable_t},
{'c', tm_tag_namespace_t},
{'s', tm_tag_member_t},
{'S', tm_tag_macro_t},
{'t', tm_tag_variable_t},
{'T', tm_tag_undef_t},
};
static TMParserMapEntry map_HTML[] = {
{'a', tm_tag_member_t},
{'f', tm_tag_function_t},
{'n', tm_tag_namespace_t},
{'c', tm_tag_class_t},
{'v', tm_tag_variable_t},
{'h', tm_tag_namespace_t},
{'i', tm_tag_class_t},
{'j', tm_tag_variable_t},
};
static TMSubparserMapEntry subparser_HTML_javascript_map[] = {
{tm_tag_function_t, tm_tag_function_t},
};
static TMParserMapEntry map_F77[] = {
@ -428,13 +446,14 @@ static TMParserMapEntry map_OBJC[] = {
{'M', tm_tag_macro_t},
};
/* not in universal-ctags */
static TMParserMapEntry map_ASCIIDOC[] = {
{'n', tm_tag_namespace_t},
{'m', tm_tag_member_t},
{'d', tm_tag_macro_t},
{'v', tm_tag_variable_t},
{'s', tm_tag_struct_t},
{'c', tm_tag_namespace_t},
{'s', tm_tag_member_t},
{'S', tm_tag_macro_t},
{'t', tm_tag_variable_t},
{'T', tm_tag_struct_t},
{'u', tm_tag_undef_t},
{'a', tm_tag_undef_t},
};
/* not in universal-ctags */
@ -587,6 +606,65 @@ gchar tm_parser_get_tag_kind(TMTagType type, TMParserType lang)
}
static void add_subparser(TMParserType lang, TMParserType sublang, TMSubparserMapEntry *map, guint map_size)
{
guint i;
GPtrArray *mapping;
GHashTable *lang_map = g_hash_table_lookup(subparser_map, GINT_TO_POINTER(lang));
if (!lang_map)
{
lang_map = g_hash_table_new(g_direct_hash, g_direct_equal);
g_hash_table_insert(subparser_map, GINT_TO_POINTER(lang), lang_map);
}
mapping = g_ptr_array_new();
for (i = 0; i < map_size; i++)
g_ptr_array_add(mapping, &map[i]);
g_hash_table_insert(lang_map, GINT_TO_POINTER(sublang), mapping);
}
#define SUBPARSER_MAP_ENTRY(lang, sublang, map) add_subparser(TM_PARSER_##lang, TM_PARSER_##sublang, map, G_N_ELEMENTS(map))
static void init_subparser_map()
{
SUBPARSER_MAP_ENTRY(HTML, JAVASCRIPT, subparser_HTML_javascript_map);
}
TMTagType tm_parser_get_subparser_type(TMParserType lang, TMParserType sublang, TMTagType type)
{
guint i;
GHashTable *lang_map;
GPtrArray *mapping;
if (!subparser_map)
{
subparser_map = g_hash_table_new(g_direct_hash, g_direct_equal);
init_subparser_map();
}
lang_map = g_hash_table_lookup(subparser_map, GINT_TO_POINTER(lang));
if (!lang_map)
return tm_tag_undef_t;
mapping = g_hash_table_lookup(lang_map, GINT_TO_POINTER(sublang));
if (!mapping)
return tm_tag_undef_t;
for (i = 0; i < mapping->len; i++)
{
TMSubparserMapEntry *entry = mapping->pdata[i];
if (entry->orig_type == type)
return entry->new_type;
}
return tm_tag_undef_t;
}
void tm_parser_verify_type_mappings(void)
{
TMParserType lang;

View File

@ -119,6 +119,8 @@ TMTagType tm_parser_get_tag_type(gchar kind, TMParserType lang);
gchar tm_parser_get_tag_kind(TMTagType type, TMParserType lang);
TMTagType tm_parser_get_subparser_type(TMParserType lang, TMParserType sublang, TMTagType type);
const gchar *tm_parser_context_separator(TMParserType lang);
gboolean tm_parser_has_full_context(TMParserType lang);

View File

@ -181,7 +181,13 @@ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const ctagsTag *tag_ent
if (!tag_entry)
return FALSE;
type = tm_parser_get_tag_type(tag_entry->kindLetter, file->lang);
type = tm_parser_get_tag_type(tag_entry->kindLetter, tag_entry->lang);
if (file->lang != tag_entry->lang) /* this is a tag from a subparser */
{
/* check for possible re-definition of subparser type */
type = tm_parser_get_subparser_type(file->lang, tag_entry->lang, type);
}
if (!tag_entry->name || type == tm_tag_undef_t)
return FALSE;
@ -206,6 +212,8 @@ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const ctagsTag *tag_ent
if ((tm_tag_macro_t == tag->type) && (NULL != tag->arglist))
tag->type = tm_tag_macro_with_arg_t;
tag->file = file;
/* redefine lang also for subparsers because the rest of Geany assumes that
* tags from a single file are from a single language */
tag->lang = file->lang;
return TRUE;
}

View File

@ -1,6 +1,9 @@
dist_check_SCRIPTS = runner.sh
# Disabled tests:
# simple.cbl
NULL =
test_sources = \
1795612.js \
@ -154,6 +157,7 @@ test_sources = \
fortran_associate.f90 \
fortran_line_continuation.f90 \
func_typedef.h \
geany.nsi \
general.cs \
hex2dec.sql \
implied_program.f \
@ -268,22 +272,32 @@ test_sources = \
semicolon.f90 \
shebang.js \
signature.cpp \
simple.abc \
simple.asciidoc \
simple.bas \
simple.cbl \
simple.conf \
simple.d \
simple.diff \
simple.docbook \
simple.hs \
simple.hx \
simple.html \
simple.inp \
simple.js \
simple.json \
simple.ksh \
simple.lua \
simple.mak \
simple.md \
simple.php \
simple.pl \
simple.ps1 \
simple.py \
simple.rb \
simple.rst \
simple.sh \
simple.tcl \
simple.vala \
simple.zep \
size_t_wchar_t_alias.d \
size_t_wchar_t_typedef.c \

View File

@ -1,4 +1,6 @@
# format=tagmanager
AnonymousFunction1Ì16Í()Îclass2.c2m1Ö0
AnonymousFunction2Ì16Í(n)Îclass3.c3m1Ö0
c2m1Ì128Í()Îclass2Ö0
c2m2Ì128Í(f)Îclass2Ö0
c2m3Ì128Í(f)Îclass2Ö0

470
tests/ctags/geany.nsi Normal file
View File

@ -0,0 +1,470 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; geany.nsi - this file is part of Geany, a fast and lightweight IDE
;
; Copyright 2007-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
; Copyright 2007-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)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.
;
;
; Installer script for Geany (Windows Installer)
; (Script originally generated by the HM NIS Edit Script Wizard)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Do a Cyclic Redundancy Check to make sure the installer was not corrupted by the download
CRCCheck force
RequestExecutionLevel highest ; set execution level for Windows Vista
;;;;;;;;;;;;;;;;;;;
; helper defines ;
;;;;;;;;;;;;;;;;;;;
!define PRODUCT_NAME "Geany"
!define PRODUCT_VERSION "1.35"
!define PRODUCT_VERSION_ID "1.35.0.0"
!define PRODUCT_PUBLISHER "The Geany developer team"
!define PRODUCT_WEB_SITE "https://www.geany.org/"
!define PRODUCT_DIR_REGKEY "Software\Geany"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_EXE "$INSTDIR\bin\Geany.exe"
!define PRODUCT_REGNAME "Geany.ProjectFile"
!define PRODUCT_EXT ".geany"
!define RESOURCEDIR "geany-${PRODUCT_VERSION}"
!define GTK_VERSION 2.24.30
;;;;;;;;;;;;;;;;;;;;;
; Version resource ;
;;;;;;;;;;;;;;;;;;;;;
VIProductVersion "${PRODUCT_VERSION_ID}"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}"
VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}"
VIAddVersionKey "LegalCopyright" "Copyright 2005-2018 by the Geany developer team"
VIAddVersionKey "FileDescription" "${PRODUCT_NAME} Installer"
BrandingText "$(^NAME) installer (NSIS 2.51)"
InstallDir "$PROGRAMFILES\Geany"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
SetCompressor /SOLID lzma
ShowInstDetails hide
ShowUnInstDetails hide
XPStyle on
!ifdef INCLUDE_GTK
OutFile "geany-${PRODUCT_VERSION}_setup.exe"
!else
OutFile "geany-${PRODUCT_VERSION}_nogtk_setup.exe"
!endif
Var Answer
Var UserName
Var StartmenuFolder
Var UNINSTDIR
;;;;;;;;;;;;;;;;
; MUI Settings ;
;;;;;;;;;;;;;;;;
!include "MUI2.nsh"
;Reserve files used in .onInit, for faster start-up
ReserveFile "${NSISDIR}\Plugins\System.dll"
ReserveFile "${NSISDIR}\Plugins\UserInfo.dll"
ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
ReserveFile "${NSISDIR}\Plugins\LangDLL.dll"
!define MUI_ABORTWARNING
!define MUI_ICON "icons\geany.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall-full.ico"
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; License page
;!define MUI_LICENSEPAGE_RADIOBUTTONS
!insertmacro MUI_PAGE_LICENSE "${RESOURCEDIR}\Copying.txt"
; Components page
!insertmacro MUI_PAGE_COMPONENTS
; Directory page
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE OnDirLeave
!insertmacro MUI_PAGE_DIRECTORY
; Start menu page
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Geany"
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} "$StartmenuFolder"
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\News.txt"
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Show Release Notes"
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
!define MUI_FINISHPAGE_RUN "$INSTDIR\bin\Geany.exe"
!define MUI_FINISHPAGE_RUN_NOTCHECKED
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_INSTFILES ; Uninstaller page
!insertmacro MUI_LANGUAGE "English" ; Language file
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sections and InstTypes ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
InstType "Full"
InstType "Minimal"
Section "!Program Files" SEC01
SectionIn RO 1 2
SetOverwrite ifnewer
SetOutPath "$INSTDIR"
File "${RESOURCEDIR}\*.txt"
SetOutPath "$INSTDIR\bin"
File "${RESOURCEDIR}\bin\Geany.exe"
File "${RESOURCEDIR}\bin\*Geany*.dll"
# non-GTK dependencies
File "gtk\bin\libgcc_s_dw*.dll"
File "gtk\bin\libstdc++-*.dll"
File "gtk\bin\libwinpthread*.dll"
SetOutPath "$INSTDIR\libexec"
File /r "${RESOURCEDIR}\libexec\*"
SetOutPath "$INSTDIR\data"
File "${RESOURCEDIR}\data\GPL-2"
File "${RESOURCEDIR}\data\filetype_extensions.conf"
File "${RESOURCEDIR}\data\geany.glade"
!if ${GTK_VERSION} >= 3
File "${RESOURCEDIR}\data\geany-3.20.css"
File "${RESOURCEDIR}\data\geany.css"
!else
File "${RESOURCEDIR}\data\geany.gtkrc"
!endif
File "${RESOURCEDIR}\data\snippets.conf"
File "${RESOURCEDIR}\data\ui_toolbar.xml"
SetOutPath "$INSTDIR\data\filedefs"
File /r "${RESOURCEDIR}\data\filedefs\*"
SetOutPath "$INSTDIR\data\templates"
File /r "${RESOURCEDIR}\data\templates\*"
SetOutPath "$INSTDIR\data\colorschemes"
File /r "${RESOURCEDIR}\data\colorschemes\*"
# Geany color schemes project, don't bail out if they are missing
File /nonfatal /r "..\geany-themes\colorschemes\*.conf"
SetOutPath "$INSTDIR\share\icons"
File /r "${RESOURCEDIR}\share\icons\*"
SetOutPath "$INSTDIR"
CreateShortCut "$INSTDIR\Geany.lnk" "$INSTDIR\bin\Geany.exe"
!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}
CreateDirectory "$SMPROGRAMS\$StartmenuFolder"
CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Geany.lnk" "$INSTDIR\bin\Geany.exe"
!insertmacro MUI_STARTMENU_WRITE_END
; register the extension .geany
; write information about file type
WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}" "" "${PRODUCT_NAME} Project File"
WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}\DefaultIcon" "" "${PRODUCT_EXE},0"
WriteRegStr SHCTX "Software\Classes\${PRODUCT_REGNAME}\Shell\open\command" "" '"${PRODUCT_EXE}" "%1"'
; write information about file extensions
WriteRegStr SHCTX "Software\Classes\${PRODUCT_EXT}" "" "${PRODUCT_REGNAME}"
; refresh shell
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) (0x08000000, 0, 0, 0)'
SectionEnd
Section "Plugins" SEC02
SectionIn 1
SetOverwrite ifnewer
SetOutPath "$INSTDIR\lib\geany"
File "${RESOURCEDIR}\lib\geany\*.dll"
SectionEnd
Section "Language Files" SEC03
SectionIn 1
SetOutPath "$INSTDIR\share\locale"
File /r "${RESOURCEDIR}\share\locale\*"
!ifdef INCLUDE_GTK
SetOutPath "$INSTDIR\share\locale"
File /r "gtk\share\locale\*"
!endif
SectionEnd
Section "Documentation" SEC04
SectionIn 1
SetOverwrite ifnewer
SetOutPath "$INSTDIR\share\doc"
File /r "${RESOURCEDIR}\share\doc\*"
WriteIniStr "$INSTDIR\Documentation.url" "InternetShortcut" "URL" "$INSTDIR\share\doc\geany\html\index.html"
!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}
CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Documentation.lnk" "$INSTDIR\Documentation.url"
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
Section "Autocompletion Tags" SEC05
SectionIn 1
SetOverwrite ifnewer
SetOutPath "$INSTDIR\data\tags"
File /r "${RESOURCEDIR}\data\tags\*"
SectionEnd
; Include GTK runtime library but only if desired from command line
!ifdef INCLUDE_GTK
Section "GTK ${GTK_VERSION} Runtime Environment" SEC06
SectionIn 1
SetOverwrite ifnewer
SetOutPath "$INSTDIR"
File "gtk\ReadMe.Dependencies.Geany.txt"
SetOutPath "$INSTDIR\bin"
File /r "gtk\bin\*"
SetOutPath "$INSTDIR\etc"
File /r "gtk\etc\*"
SetOutPath "$INSTDIR\lib"
File /r "gtk\lib\*"
SetOutPath "$INSTDIR\share"
File /r "gtk\share\*"
SectionEnd
!endif
Section "Context Menus" SEC07
SectionIn 1
WriteRegStr HKCR "*\shell\OpenWithGeany" "" "Open with Geany"
WriteRegStr HKCR "*\shell\OpenWithGeany" "Icon" "$INSTDIR\bin\geany.exe"
WriteRegStr HKCR "*\shell\OpenWithGeany\command" "" '"$INSTDIR\bin\geany.exe" "%1"'
SectionEnd
Section "Desktop Shortcuts" SEC08
SectionIn 1
CreateShortCut "$DESKTOP\Geany.lnk" "$INSTDIR\bin\Geany.exe"
CreateShortCut "$QUICKLAUNCH\Geany.lnk" "$INSTDIR\bin\Geany.exe"
SectionEnd
; Development files
Section "Development files" SEC09
SetOverwrite ifnewer
SetOutPath "$INSTDIR\include"
File /r "${RESOURCEDIR}\include\*"
SetOutPath "$INSTDIR\lib\pkgconfig"
File "${RESOURCEDIR}\lib\pkgconfig\geany.pc"
SectionEnd
Section -AdditionalIcons
SetOutPath $INSTDIR
!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}
WriteIniStr "$INSTDIR\Website.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Website.lnk" "$INSTDIR\Website.url"
CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Uninstall.lnk" "$INSTDIR\uninst.exe"
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
Section -Post
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" Path "$INSTDIR"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "StartMenu" "$SMPROGRAMS\$StartmenuFolder"
${if} $Answer == "yes" ; if user is admin
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Geany.exe"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "URLUpdateInfo" "${PRODUCT_WEB_SITE}"
WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoModify" 0x00000001
WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoRepair" 0x00000001
${endif}
SectionEnd
Section Uninstall
Delete "$INSTDIR\Website.url"
Delete "$INSTDIR\Documentation.url"
Delete "$INSTDIR\uninst.exe"
Delete "$INSTDIR\News.txt"
Delete "$INSTDIR\ReadMe.txt"
Delete "$INSTDIR\ReadMe.Dependencies.Geany.txt"
Delete "$INSTDIR\Thanks.txt"
Delete "$INSTDIR\ToDo.txt"
Delete "$INSTDIR\Authors.txt"
Delete "$INSTDIR\ChangeLog.txt"
Delete "$INSTDIR\Copying.txt"
Delete "$INSTDIR\Geany.lnk"
; delete start menu entry
ReadRegStr $0 SHCTX "${PRODUCT_UNINST_KEY}" "StartMenu"
RMDir /r "$0"
Delete "$QUICKLAUNCH\Geany.lnk"
Delete "$DESKTOP\Geany.lnk"
RMDir /r "$INSTDIR\bin"
RMDir /r "$INSTDIR\data"
RMDir /r "$INSTDIR\etc"
RMDir /r "$INSTDIR\include"
RMDir /r "$INSTDIR\lib"
RMDir /r "$INSTDIR\libexec"
RMDir /r "$INSTDIR\share"
RMDir "$INSTDIR"
; remove .geany file extension
ReadRegStr $R0 SHCTX "Software\Classes\${PRODUCT_EXT}" ""
${if} $R0 == "${PRODUCT_REGNAME}"
DeleteRegKey SHCTX "${PRODUCT_EXT}"
DeleteRegKey HKCR "${PRODUCT_EXT}"
DeleteRegKey SHCTX "${PRODUCT_REGNAME}"
DeleteRegKey HKCR "${PRODUCT_REGNAME}"
${endif}
DeleteRegKey HKCR "*\shell\OpenWithGeany"
DeleteRegKey SHCTX "${PRODUCT_UNINST_KEY}"
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
DeleteRegKey SHCTX "${PRODUCT_DIR_REGKEY}"
DeleteRegKey HKCU "${PRODUCT_DIR_REGKEY}"
SetAutoClose true
SectionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;
; Section descriptions ;
;;;;;;;;;;;;;;;;;;;;;;;;;
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Required program files. You cannot skip these files."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Available plugins like 'Version Diff', 'Class Builder' and 'Insert Special Characters'."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "Various translations of Geany's interface."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC04} "Manual in Text and HTML format."
!insertmacro MUI_DESCRIPTION_TEXT ${SEC05} "Symbol lists necessary for auto completion of symbols."
!ifdef INCLUDE_GTK
!insertmacro MUI_DESCRIPTION_TEXT ${SEC06} "You need these files to run Geany. If you have already installed a GTK Runtime Environment (${GTK_VERSION} or higher), you can skip it."
!endif
!insertmacro MUI_DESCRIPTION_TEXT ${SEC07} "Add context menu item 'Open With Geany'"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC08} "Create shortcuts for Geany on the desktop and in the Quicklaunch Bar"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC09} "You need these files only if you want to develop own plugins for Geany. If unsure, you can skip it."
!insertmacro MUI_FUNCTION_DESCRIPTION_END
;;;;;;;;;;;;;;;;;;;;;
; helper functions ;
;;;;;;;;;;;;;;;;;;;;;
; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi)
!macro IsUserAdmin Result UName
ClearErrors
UserInfo::GetName
IfErrors Win9x
Pop $0
StrCpy ${UName} $0
UserInfo::GetAccountType
Pop $1
${if} $1 == "Admin"
StrCpy ${Result} "yes"
${else}
StrCpy ${Result} "no"
${endif}
Goto done
Win9x:
StrCpy ${Result} "yes"
done:
!macroend
Function .onInit
StrCpy "$StartmenuFolder" "Geany"
; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi)
; If the user does *not* have administrator privileges, abort
StrCpy $Answer ""
StrCpy $UserName ""
!insertmacro IsUserAdmin $Answer $UserName ; macro from LyXUtils.nsh
${if} $Answer == "yes"
SetShellVarContext all ; set that e.g. shortcuts will be created for all users
${else}
SetShellVarContext current
; TODO is this really what we want? $PROGRAMFILES is not much better because
; probably the unprivileged user can't write it anyways
StrCpy $INSTDIR "$PROFILE\$(^Name)"
${endif}
; prevent running multiple instances of the installer
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "geany_installer") i .r1 ?e'
Pop $R0
StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." /SD IDOK
Abort
; warn about a new install over an existing installation
ReadRegStr $R0 SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString"
StrCmp $R0 "" finish
MessageBox MB_YESNO|MB_ICONEXCLAMATION \
"Geany has already been installed. $\nDo you want to remove the previous version before installing $(^Name) ?" \
/SD IDYES IDYES remove IDNO finish
remove:
; run the uninstaller
ClearErrors
; we read the installation path of the old installation from the Registry
ReadRegStr $UNINSTDIR SHCTX "${PRODUCT_DIR_REGKEY}" "Path"
IfSilent dosilent nonsilent
dosilent:
ExecWait '$R0 /S _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file
Goto finish
nonsilent:
ExecWait '$R0 _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file
finish:
FunctionEnd
Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." \
/SD IDOK
FunctionEnd
Function un.onInit
; If the user does *not* have administrator privileges, abort
StrCpy $Answer ""
!insertmacro IsUserAdmin $Answer $UserName
${if} $Answer == "yes"
SetShellVarContext all
${else}
; check if the Geany has been installed with admin permisions
ReadRegStr $0 HKLM "${PRODUCT_UNINST_KEY}" "Publisher"
${if} $0 != ""
MessageBox MB_OK|MB_ICONSTOP "You need administrator privileges to uninstall Geany!" \
/SD IDOK
Abort
${endif}
SetShellVarContext current
${endif}
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" \
/SD IDYES IDYES +2
Abort
FunctionEnd
Function OnDirLeave
ClearErrors
SetOutPath "$INSTDIR" ; what about IfError creating $INSTDIR?
GetTempFileName $1 "$INSTDIR" ; creates tmp file (or fails)
FileOpen $0 "$1" "w" ; error to open?
FileWriteByte $0 "0"
IfErrors notPossible possible
notPossible:
RMDir "$INSTDIR" ; removes folder if empty
MessageBox MB_OK "The given directory is not writeable. Please choose another one!" /SD IDOK
Abort
possible:
FileClose $0
Delete "$1"
FunctionEnd

View File

@ -0,0 +1,21 @@
# format=tagmanager
!Program FilesÌ256Ö0
-AdditionalIconsÌ256Ö0
-PostÌ256Ö0
.onInitÌ16Ö0
AnswerÌ16384Ö0
Autocompletion TagsÌ256Ö0
Context MenusÌ256Ö0
Desktop ShortcutsÌ256Ö0
Development filesÌ256Ö0
DocumentationÌ256Ö0
GTK Ì256Ö0
Language FilesÌ256Ö0
OnDirLeaveÌ16Ö0
PluginsÌ256Ö0
StartmenuFolderÌ16384Ö0
UNINSTDIRÌ16384Ö0
UninstallÌ256Ö0
UserNameÌ16384Ö0
un.onInitÌ16Ö0
un.onUninstSuccessÌ16Ö0

View File

@ -3,8 +3,9 @@ A
Bフ1ヘ(a, b)ホClsヨ0
Cフ1ヘ()ホClsヨ0
Clsフ1ヨ0
Sub<EFBFBD>1<EFBFBD>0
Subフ1ヘ()ホCls.Bヨ0
dyn1フ128ホCls.B.Subヨ0
dyn1<EFBFBD>128<EFBFBD>Sub<EFBFBD>0
m1フ128ヘ(a)ホCls.Bヨ0
m2フ128ヘ(b)ホCls.Bヨ0
m3フ128ヘ(c)ホCls.Bヨ0

View File

@ -2,7 +2,7 @@
aフ16384ヨ0
bフ16384ヨ0
funcフ16ヘ()ヨ0
groupフ16384ヨ0
groupフ1ヨ0
xフ64ホgroupヨ0
yフ64ホgroupヨ0
zフ64ホgroupヨ0

View File

@ -1,6 +1,6 @@
# format=tagmanager
firstÌ128Í()ÎoÖ0
fourthÌ128Í()ÎoÖ0
o<EFBFBD>16384<EFBFBD>0
oフ1ヨ0
secondÌ128Í()ÎoÖ0
thirdÌ128Í()ÎoÖ0

View File

@ -27,7 +27,7 @@ addSalaryFunction
addSalaryFunctionDT9Ì1Í(addition)Ö0
ball0Ì16384Ö0
ball1Ì16384Ö0
ball2フ16384ヨ0
ball2フ1ヨ0
ball3Ì16384Ö0
ball4Ì16384Ö0
ball5Ì16384Ö0
@ -59,11 +59,11 @@ myFunction6A
myFunction6AEÌ16Í()Ö0
myFunction6BÌ16Í()Ö0
myFunction6EÌ16Í()Ö0
myObjectフ16384ヨ0
myObjectフ1ヨ0
my_global_var1Ì16384Ö0
object1フ16384ヨ0
object2フ16384ヨ0
object3フ16384ヨ0
object1フ1ヨ0
object2フ1ヨ0
object3フ1ヨ0
priceÌ128ÎPT2Ö0
savedFunc6BÌ16Í()Ö0
sayName4AÌ16Í(name)Ö0

78
tests/ctags/simple.abc Normal file
View File

@ -0,0 +1,78 @@
% A Selection of Scotch, English, Irish and Foreign
% Airs adapted to the Fife, Violin, or German-Flute
% Glasgow
% Printed and Sold by James Aird
% Volume First
% 1778 (often cited as 1782)
X:0001
T:The Ranting Highlandman.
T:The White Cockade
M:C|
L:1/8
Q:1/2=112
I: :: ::
%% G A B c d e ^f g a
Z:Jack Campin * www.campin.me.uk * 2009
K:G
AG|B2B2 B2AG|B2B2 B2g2|B2B2 B2AG|AGAB A2
GA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2::
Bc|d2B2 g2B2|d2d2 d2e2|d2cB g2fg|a2A2 A2
GA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2:|
X:0002
T:Quick Step. 25th Regt.
N:bars of quavers are all beamed together in the original
M:2/4
L:1/16
Q:1/4=89
I: :: ::
%% D ^F G A B c d e f ^f g a
Z:Jack Campin * www.campin.me.uk * 2009
K:G
g2d2 d2c2|(BcdB) G2D2 |G2B2 (ABcd)| B2``G2 G2d2|
e2c2 c2e2| d2B2 B2d2 |g2d2 c2B2 | B4 A4 :|
F2A2 A2dc| B2G2 G4 |B2d2 d2=f2|(ed)(cB) c4 |
e2a2 a2g2|(gfed) g2c2 |B2AG A2D2 | G2``G2 G4 :|
X:0003
T:The Lads of the Village.
M:2/4
L:1/8
Q:1/4=104
I: :: ::
%% D ^F G A B c d e ^f g a
Z:Jack Campin * www.campin.me.uk * 2009
K:G
G2g>d|ecBG|a>cBG|FA`FD|G2 gd|ecBG|A>cBG|(D/G/``F/A/) G2:|
g>fgd|ecBG|g>fge|a>gfd|g>fgd|ecBG|A>cBG|(D/G/)(F/A/) G2:|
X:0004
T:I'll Touzle your Kurchy.
M:6/8
L:1/8
Q:3/8=120
I: :: ::
%% D E ^F G A B c d e ^f g
Z:Jack Campin * www.campin.me.uk * 2009
K:E Minor
B |E>GE GEG|B>AB e2f|g>fe dgB|A>GA BG
E |E>GE GEG|B>AB e2f|g>fe dcB|AGF E2:|
B |E>GE B2B|GEG B2B|E>GE A2G|FDF A2
G/F/|E>GE B2B|GEG e2f|gfe dcB|AGF E2:|
X:0005
T:The Lady's play thing, or Gen Howe's March.
M:6/8
L:1/8
Q:3/8=120
I: :: ::
%% D G A B c d e g
N:last note printed as G3
Z:Jack Campin * www.campin.me.uk * 2009
K:G
d/c/|B2B Bcd|A2A A2d|G2G GAB|B3 A2
e |dgd BdB|GBG Ddc|BcB AGA|G2G G2:|
d |dBd dBd|e2e e2c|cAc cAc|d2d d2
c |BGB BGB|c2c cBA|Bcd dcB|B3 A2
e |dgd BdB|GBG Ddc|BcB AGA|G2G G2:|

View File

@ -0,0 +1,7 @@
# format=tagmanager
X:0001 / T:The Ranting Highlandman.Ì64Ö0
X:0001 / T:The Ranting Highlandman. / T:The White CockadeÌ64Ö0
X:0002 / T:Quick Step. 25th Regt.Ì64Ö0
X:0003 / T:The Lads of the Village.Ì64Ö0
X:0004 / T:I'll Touzle your Kurchy.Ì64Ö0
X:0005 / T:The Lady's play thing, or Gen Howe's March.Ì64Ö0

View File

@ -0,0 +1,59 @@
= Chapter 1 (Level 0)
Intro text of chapter 1
== Section 1.1
Text of section 1.1
=== Subsection 1.1.1
Text of subsection 1.1.1
==== Level 3 Section 1.1.1.1 Title
Text of subsection 1.1.1.1
===== Level 4 Section 1.1.1.1.1 Title
Text of subsection 1.1.1.1.1
====== Level 5 Section 1.1.1.1.1.1 Title
Text of subsection 1.1.1.1.1.1
== Section 1.2
Text of section 1.2
// and now two-line titles:
Chapter 2
=========
Intro text of chapter 2
Section 2.1
------------
Text of section 2.1
Subsection 2.1.1
~~~~~~~~~~~~~~~
Level 3 Section 2.1.1.1 Title
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Text of subsection 2.1.1.1
Level 4 Section 2.1.1.1.1 Title
+++++++++++++++++++++++++++++++
Text of subsection 2.1.1.1.1
Section 2.2
-----------
Text of section 2.2

View File

@ -0,0 +1,13 @@
# format=tagmanager
Chapter 1 (Level 0)Ì256Ö0
Chapter 2Ì256Ö0
Level 3 Section 1.1.1.1 TitleÌ16384ÎSubsection 1.1.1Ö0
Level 3 Section 2.1.1.1 TitleÌ16384ÎSubsection 2.1.1Ö0
Level 4 Section 1.1.1.1.1 TitleÌ2048ÎLevel 3 Section 1.1.1.1 TitleÖ0
Level 4 Section 2.1.1.1.1 TitleÌ2048ÎLevel 3 Section 2.1.1.1 TitleÖ0
Section 1.1Ì64ÎChapter 1 (Level 0)Ö0
Section 1.2Ì64ÎChapter 1 (Level 0)Ö0
Section 2.1Ì64ÎChapter 2Ö0
Section 2.2Ì64ÎChapter 2Ö0
Subsection 1.1.1Ì65536ÎSection 1.1Ö0
Subsection 2.1.1Ì65536ÎSection 2.1Ö0

33
tests/ctags/simple.conf Normal file
View File

@ -0,0 +1,33 @@
#
# TAKEN FROM https://docs.python.org/2/library/logging.config.html
#
[loggers]
keys=root,parser
[handlers]
keys=hand01
[formatters]
keys=form01
[logger_root]
level=NOTSET
handlers=hand01
[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)
[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter

Some files were not shown because too many files have changed in this diff Show More