geany/tagmanager/conf.c
Enrico Tröger 00bc23cec4 Backport recent changes from Scintilla CVS to add partial support for RFC2822 styled text using the Properties lexer.
Ignore leading whitespace for config files and RFC2822 text.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3669 ea778897-0a13-0410-b9d1-a72fbfd435f5
2009-03-30 17:49:40 +00:00

127 lines
2.7 KiB
C

/*
*
* Copyright (c) 2000-2001, Darren Hiebert
*
* 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 config files.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include <ctype.h>
#include "parse.h"
#include "read.h"
#include "vstring.h"
/*
* DATA DEFINITIONS
*/
typedef enum {
K_SECTION,
K_KEY
} confKind;
static kindOption ConfKinds [] = {
{ TRUE, 'n', "namespace", "sections"},
{ TRUE, 'm', "macro", "keys"}
};
/*
* FUNCTION DEFINITIONS
*/
static boolean isIdentifier (int c)
{
/* allow whitespace within keys and sections */
return (boolean)(isalnum (c) || isspace (c) || c == '_');
}
static void findConfTags (void)
{
vString *name = vStringNew ();
vString *scope = vStringNew ();
const unsigned char *line;
while ((line = fileReadLine ()) != NULL)
{
const unsigned char* cp = line;
boolean possible = TRUE;
if (isspace ((int) *cp) || *cp == '#' || (*cp != '\0' && *cp == '/' && *(cp+1) == '/'))
continue;
/* look for a section */
if (*cp != '\0' && *cp == '[')
{
++cp;
while (*cp != '\0' && *cp != ']')
{
vStringPut (name, (int) *cp);
++cp;
}
vStringTerminate (name);
makeSimpleTag (name, ConfKinds, K_SECTION);
/* remember section name */
vStringCopy (scope, name);
vStringTerminate (scope);
vStringClear (name);
continue;
}
while (*cp != '\0')
{
/* We look for any sequence of identifier characters following a white space */
if (possible && isIdentifier ((int) *cp))
{
while (isIdentifier ((int) *cp))
{
vStringPut (name, (int) *cp);
++cp;
}
vStringTerminate (name);
while (isspace ((int) *cp))
++cp;
if (*cp == '=')
{
if (vStringLength (scope) > 0)
makeSimpleScopedTag (name, ConfKinds, K_KEY,
"section", vStringValue(scope), NULL);
else
makeSimpleTag (name, ConfKinds, K_KEY);
}
vStringClear (name);
}
else if (isspace ((int) *cp))
possible = TRUE;
else
possible = FALSE;
if (*cp != '\0')
++cp;
}
}
vStringDelete (name);
vStringDelete (scope);
}
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->kindCount = KIND_COUNT (ConfKinds);
def->patterns = patterns;
def->extensions = extensions;
def->parser = findConfTags;
return def;
}
/* vi:set tabstop=8 shiftwidth=4: */