Kaydet (Commit) f651b49c authored tarafından Enrico Tröger's avatar Enrico Tröger

Parse also sections in configuration files.

Allow whitespace in keys and section names.
Remove unused LexConf.cxx.
Highlight also space separated key value pairs.		 


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1656 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 7cdacb9e
2007-07-02 Enrico Tröger <enrico.troeger@uvena.de>
* src/symbols.c, tagmanager/conf.c:
Parse also sections in configuration files.
Allow whitespace in keys and section names.
* scintilla/makefile.win32, scintilla/KeyWords.cxx,
scintilla/LexConf.cxx, scintilla/Makefile.am:
Remove unused LexConf.cxx.
* scintilla/LexOthers.cxx:
Highlight also space separated key value pairs.
2007-06-29 Enrico Tröger <enrico.troeger@uvena.de>
* src/dialogs.c:
......
......@@ -147,7 +147,6 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmFreeBasic);
LINK_LEXER(lmBatch);
LINK_LEXER(lmCaml);
LINK_LEXER(lmConf);
LINK_LEXER(lmCPP);
LINK_LEXER(lmCPPNoCase);
LINK_LEXER(lmCss);
......
// Scintilla source code edit control
/** @file LexConf.cxx
** Lexer for Apache Configuration Files.
**
** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
** i created this lexer because i needed something pretty when dealing
** when Apache Configuration files...
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_CONF_DEFAULT;
char chNext = styler[startPos];
int lengthDoc = startPos + length;
// create a buffer large enough to take the largest chunk...
char *buffer = new char[length];
int bufferCount = 0;
// this assumes that we have 2 keyword list in conf.properties
WordList &directives = *keywordLists[0];
WordList &params = *keywordLists[1];
// go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
styler.StartSegment(startPos);
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
continue;
}
switch(state) {
case SCE_CONF_DEFAULT:
if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
// whitespace is simply ignored here...
styler.ColourTo(i,SCE_CONF_DEFAULT);
break;
} else if( ch == '#' ) {
// signals the start of a comment...
state = SCE_CONF_COMMENT;
styler.ColourTo(i,SCE_CONF_COMMENT);
} else if( ch == '.' /*|| ch == '/'*/) {
// signals the start of a file...
state = SCE_CONF_EXTENSION;
styler.ColourTo(i,SCE_CONF_EXTENSION);
} else if( ch == '"') {
state = SCE_CONF_STRING;
styler.ColourTo(i,SCE_CONF_STRING);
} else if( ispunct(ch) ) {
// signals an operator...
// no state jump necessary for this
// simple case...
styler.ColourTo(i,SCE_CONF_OPERATOR);
} else if( isalpha(ch) ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = static_cast<char>(tolower(ch));
state = SCE_CONF_IDENTIFIER;
} else if( isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
//styler.ColourTo(i,SCE_CONF_NUMBER);
state = SCE_CONF_NUMBER;
} else {
// style it the default style..
styler.ColourTo(i,SCE_CONF_DEFAULT);
}
break;
case SCE_CONF_COMMENT:
// if we find a newline here,
// we simply go to default state
// else continue to work on it...
if( ch == '\n' || ch == '\r' ) {
state = SCE_CONF_DEFAULT;
} else {
styler.ColourTo(i,SCE_CONF_COMMENT);
}
break;
case SCE_CONF_EXTENSION:
// if we find a non-alphanumeric char,
// we simply go to default state
// else we're still dealing with an extension...
if( isalnum(ch) || (ch == '_') ||
(ch == '-') || (ch == '$') ||
(ch == '/') || (ch == '.') || (ch == '*') )
{
styler.ColourTo(i,SCE_CONF_EXTENSION);
} else {
state = SCE_CONF_DEFAULT;
chNext = styler[i--];
}
break;
case SCE_CONF_STRING:
// if we find the end of a string char, we simply go to default state
// else we're still dealing with an string...
if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
state = SCE_CONF_DEFAULT;
}
styler.ColourTo(i,SCE_CONF_STRING);
break;
case SCE_CONF_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_CONF_DEFAULT;
buffer[bufferCount] = '\0';
// check if the buffer contains a keyword, and highlight it if it is a keyword...
if(directives.InList(buffer)) {
styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
} else if(params.InList(buffer)) {
styler.ColourTo(i-1,SCE_CONF_PARAMETER );
} else if(strchr(buffer,'/') || strchr(buffer,'.')) {
styler.ColourTo(i-1,SCE_CONF_EXTENSION);
} else {
styler.ColourTo(i-1,SCE_CONF_DEFAULT);
}
// push back the faulty character
chNext = styler[i--];
}
break;
case SCE_CONF_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
if( isdigit(ch) || ch == '.') {
buffer[bufferCount++] = ch;
} else {
state = SCE_CONF_DEFAULT;
buffer[bufferCount] = '\0';
// Colourize here...
if( strchr(buffer,'.') ) {
// it is an IP address...
styler.ColourTo(i-1,SCE_CONF_IP);
} else {
// normal number
styler.ColourTo(i-1,SCE_CONF_NUMBER);
}
// push back a character
chNext = styler[i--];
}
break;
}
}
delete []buffer;
}
static const char * const confWordListDesc[] = {
"Directives",
"Parameters",
0
};
LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
......@@ -594,7 +594,8 @@ static void ColourisePropsLine(
while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
i++;
if (i < lengthLine) {
if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';' ||
(i < (lengthLine - 1) && lineBuffer[i] == '/' && lineBuffer[i+1] == '/')) {
styler.ColourTo(endPos, SCE_PROPS_COMMENT);
} else if (lineBuffer[i] == '[') {
styler.ColourTo(endPos, SCE_PROPS_SECTION);
......@@ -605,9 +606,9 @@ static void ColourisePropsLine(
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
} else {
// Search for the '=' character
while ((i < lengthLine) && (lineBuffer[i] != '='))
while ((i < lengthLine) && ! (lineBuffer[i] == '=' || isspacechar(lineBuffer[i])))
i++;
if ((i < lengthLine) && (lineBuffer[i] == '=')) {
if ((i < lengthLine) && (lineBuffer[i] == '=' || isspacechar(lineBuffer[i]))) {
styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
......
......@@ -14,7 +14,6 @@ LexBash.cxx \
LexOMS.cxx \
LexCPP.cxx \
LexCaml.cxx \
LexConf.cxx \
LexCrontab.cxx \
LexCSS.cxx \
LexD.cxx \
......
......@@ -60,7 +60,7 @@ MARSHALLER=scintilla-marshal.o
#++Autogenerated -- run src/LexGen.py to regenerate
#**LEXOBJS=\\\n\(\*.o \)
LEXOBJS=\
LexBash.o LexAsm.o LexCSS.o LexConf.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
LexBash.o LexAsm.o LexCSS.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
LexPerl.o LexPython.o LexSQL.o LexCaml.o LexOMS.o LexTCL.o LexRuby.o LexFortran.o LexVHDL.o \
LexD.o LexLua.o LexHaskell.o LexBasic.o
#--Autogenerated -- end of automatically generated section
......
......@@ -470,6 +470,12 @@ static void init_tag_list(gint idx)
&tv_iters.tag_function, _("Functions"),
NULL);
break;
case GEANY_FILETYPES_CONF:
tag_list_add_groups(tag_store,
&tv_iters.tag_namespace, _("Sections"),
&tv_iters.tag_macro, _("Keys"),
NULL);
break;
case GEANY_FILETYPES_LATEX:
{
tag_list_add_groups(tag_store,
......
......@@ -23,11 +23,13 @@
* DATA DEFINITIONS
*/
typedef enum {
K_NAMESPACE,
K_MACRO
} shKind;
} confKind;
static kindOption ConfKinds [] = {
{ TRUE, 'm', "macro", "macros"}
{ TRUE, 'n', "namespace", "sections"},
{ TRUE, 'm', "macro", "keys"}
};
/*
......@@ -36,7 +38,8 @@ static kindOption ConfKinds [] = {
static boolean isIdentifier (int c)
{
return (boolean)(isalnum (c) || c == '_');
// allow whitespace within keys and sections
return (boolean)(isalnum (c) || isspace (c) || c == '_');
}
static void findConfTags (void)
......@@ -46,42 +49,54 @@ static void findConfTags (void)
while ((line = fileReadLine ()) != NULL)
{
const unsigned char* cp = line;
boolean possible = TRUE;
const unsigned char* cp = line;
boolean possible = TRUE;
while (isspace ((int) *cp))
++cp;
if (*cp == '#')
continue;
while (isspace ((int) *cp))
++cp;
if (*cp == '#' || (*cp != '\0' && *cp == '/' && *(cp+1) == '/'))
continue;
while (*cp != '\0')
{
/* We look for any sequence of identifier characters following
* either a white space or a colon and followed by either = or :=
*/
if (possible && isIdentifier ((int) *cp))
{
while (isIdentifier ((int) *cp))
/* look for a section */
if (*cp != '\0' && *cp == '[')
{
vStringPut (name, (int) *cp);
++cp;
++cp;
while (*cp != '\0' && *cp != ']')
{
vStringPut (name, (int) *cp);
++cp;
}
vStringTerminate (name);
makeSimpleTag (name, ConfKinds, K_NAMESPACE);
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 == '=')
makeSimpleTag (name, ConfKinds, K_MACRO);
vStringClear (name);
}
else if (isspace ((int) *cp))
possible = TRUE;
else
possible = FALSE;
if (*cp != '\0')
++cp;
}
vStringTerminate (name);
while (isspace ((int) *cp))
++cp;
if ( *cp == ':')
++cp;
if ( *cp == '=')
makeSimpleTag (name, ConfKinds, K_MACRO);
vStringClear (name);
}
else if (isspace ((int) *cp) || *cp == ':')
possible = TRUE;
else
possible = FALSE;
if (*cp != '\0')
++cp;
}
}
vStringDelete (name);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment