Making "inline" behave like an attribute. Fixes #1
[arduino-ctags.git] / make.c
blob7b5683061d37c6ad1d99be5aa7d1cbbc483137fb
1 /*
2 * $Id: make.c 751 2010-02-27 17:41:57Z elliotth $
4 * Copyright (c) 2000-2005, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for makefiles.
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #include <string.h>
18 #include <ctype.h>
20 #include "options.h"
21 #include "parse.h"
22 #include "read.h"
23 #include "vstring.h"
26 * DATA DEFINITIONS
28 typedef enum {
29 K_MACRO
30 } shKind;
32 static kindOption MakeKinds [] = {
33 { TRUE, 'm', "macro", "macros"}
37 * FUNCTION DEFINITIONS
40 static int nextChar (void)
42 int c = fileGetc ();
43 if (c == '\\')
45 c = fileGetc ();
46 if (c == '\n')
47 c = fileGetc ();
49 return c;
52 static void skipLine (void)
54 int c;
56 c = nextChar ();
57 while (c != EOF && c != '\n');
58 if (c == '\n')
59 fileUngetc (c);
62 static int skipToNonWhite (void)
64 int c;
66 c = nextChar ();
67 while (c != '\n' && isspace (c));
68 return c;
71 static boolean isIdentifier (int c)
73 return (boolean)(c != '\0' && (isalnum (c) || strchr (".-_", c) != NULL));
76 static void readIdentifier (const int first, vString *const id)
78 int c = first;
79 vStringClear (id);
80 while (isIdentifier (c))
82 vStringPut (id, c);
83 c = nextChar ();
85 fileUngetc (c);
86 vStringTerminate (id);
89 static void skipToMatch (const char *const pair)
91 const int begin = pair [0], end = pair [1];
92 const unsigned long inputLineNumber = getInputLineNumber ();
93 int matchLevel = 1;
94 int c = '\0';
96 while (matchLevel > 0)
98 c = nextChar ();
99 if (c == begin)
100 ++matchLevel;
101 else if (c == end)
102 --matchLevel;
103 else if (c == '\n' || c == EOF)
104 break;
106 if (c == EOF)
107 verbose ("%s: failed to find match for '%c' at line %lu\n",
108 getInputFileName (), begin, inputLineNumber);
111 static void findMakeTags (void)
113 vString *name = vStringNew ();
114 boolean newline = TRUE;
115 boolean in_define = FALSE;
116 boolean in_rule = FALSE;
117 boolean variable_possible = TRUE;
118 int c;
120 while ((c = nextChar ()) != EOF)
122 if (newline)
124 if (in_rule)
126 if (c == '\t')
128 skipLine (); /* skip rule */
129 continue;
131 else
132 in_rule = FALSE;
134 variable_possible = (boolean)(!in_rule);
135 newline = FALSE;
137 if (c == '\n')
138 newline = TRUE;
139 else if (isspace (c))
140 continue;
141 else if (c == '#')
142 skipLine ();
143 else if (c == '(')
144 skipToMatch ("()");
145 else if (c == '{')
146 skipToMatch ("{}");
147 else if (c == ':')
149 variable_possible = TRUE;
150 in_rule = TRUE;
152 else if (variable_possible && isIdentifier (c))
154 readIdentifier (c, name);
155 if (strcmp (vStringValue (name), "endef") == 0)
156 in_define = FALSE;
157 else if (in_define)
158 skipLine ();
159 else if (strcmp (vStringValue (name), "define") == 0 &&
160 isIdentifier (c))
162 in_define = TRUE;
163 c = skipToNonWhite ();
164 readIdentifier (c, name);
165 makeSimpleTag (name, MakeKinds, K_MACRO);
166 skipLine ();
168 else {
169 if (strcmp(vStringValue (name), "export") == 0 &&
170 isIdentifier (c))
172 c = skipToNonWhite ();
173 readIdentifier (c, name);
175 c = skipToNonWhite ();
176 if (strchr (":?+", c) != NULL)
178 boolean append = (boolean)(c == '+');
179 if (c == ':')
180 in_rule = TRUE;
181 c = nextChar ();
182 if (c != '=')
183 fileUngetc (c);
184 else if (append)
186 skipLine ();
187 continue;
190 if (c == '=')
192 makeSimpleTag (name, MakeKinds, K_MACRO);
193 in_rule = FALSE;
194 skipLine ();
198 else
199 variable_possible = FALSE;
201 vStringDelete (name);
204 extern parserDefinition* MakefileParser (void)
206 static const char *const patterns [] = { "[Mm]akefile", "GNUmakefile", NULL };
207 static const char *const extensions [] = { "mak", "mk", NULL };
208 parserDefinition* const def = parserNew ("Make");
209 def->kinds = MakeKinds;
210 def->kindCount = KIND_COUNT (MakeKinds);
211 def->patterns = patterns;
212 def->extensions = extensions;
213 def->parser = findMakeTags;
214 return def;
217 /* vi:set tabstop=4 shiftwidth=4: */