manual: added documentation about replacement of 'untitled.ext' with filename (#1804)
[geany-mirror.git] / ctags / parsers / conf.c
blob5b6c1e17aaa045921a0b9270f2042ad6d1f7c5ea
1 /*
3 * Copyright (c) 2000-2001, Darren Hiebert
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License.
8 * This module contains functions for generating tags for config files.
9 */
12 * INCLUDE FILES
14 #include "general.h" /* must always come first */
16 #include <ctype.h>
18 #include "parse.h"
19 #include "read.h"
20 #include "vstring.h"
21 #include "routines.h"
24 * DATA DEFINITIONS
26 typedef enum {
27 K_SECTION,
28 K_KEY
29 } confKind;
31 static kindOption ConfKinds [] = {
32 { true, 'n', "namespace", "sections"},
33 { true, 'm', "macro", "keys"}
37 * FUNCTION DEFINITIONS
40 static bool isIdentifier (int c)
42 /* allow whitespace within keys and sections */
43 return (bool)(isalnum (c) || isspace (c) || c == '_');
46 static void findConfTags (void)
48 vString *name = vStringNew ();
49 vString *scope = vStringNew ();
50 const unsigned char *line;
52 while ((line = readLineFromInputFile ()) != NULL)
54 const unsigned char* cp = line;
55 bool possible = true;
57 if (isspace ((int) *cp) || *cp == '#' || (*cp != '\0' && *cp == '/' && *(cp+1) == '/'))
58 continue;
60 /* look for a section */
61 if (*cp != '\0' && *cp == '[')
63 ++cp;
64 while (*cp != '\0' && *cp != ']')
66 vStringPut (name, (int) *cp);
67 ++cp;
69 makeSimpleTag (name, ConfKinds, K_SECTION);
70 /* remember section name */
71 vStringCopy (scope, name);
72 vStringClear (name);
73 continue;
76 while (*cp != '\0')
78 /* We look for any sequence of identifier characters following a white space */
79 if (possible && isIdentifier ((int) *cp))
81 while (isIdentifier ((int) *cp))
83 vStringPut (name, (int) *cp);
84 ++cp;
86 vStringStripTrailing (name);
87 while (isspace ((int) *cp))
88 ++cp;
89 if (*cp == '=')
91 tagEntryInfo e;
92 initTagEntry (&e, vStringValue (name), &(ConfKinds [K_KEY]));
94 if (vStringLength (scope) > 0)
96 e.extensionFields.scopeKind = &(ConfKinds [K_SECTION]);
97 e.extensionFields.scopeName = vStringValue(scope);
99 makeTagEntry (&e);
101 vStringClear (name);
103 else if (isspace ((int) *cp))
104 possible = true;
105 else
106 possible = false;
108 if (*cp != '\0')
109 ++cp;
112 vStringDelete (name);
113 vStringDelete (scope);
116 extern parserDefinition* ConfParser (void)
118 static const char *const patterns [] = { "*.ini", "*.conf", NULL };
119 static const char *const extensions [] = { "conf", NULL };
120 parserDefinition* const def = parserNew ("Conf");
121 def->kinds = ConfKinds;
122 def->kindCount = ARRAY_SIZE (ConfKinds);
123 def->patterns = patterns;
124 def->extensions = extensions;
125 def->parser = findConfTags;
126 return def;