VirtualBox

source: kBuild/trunk/src/kmk/kbuild-read.c@ 2548

Last change on this file since 2548 was 2548, checked in by bird, 13 years ago

kmk: hacking on a new kmk/kBuild language extension.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.0 KB
Line 
1/* $Id: kbuild-read.c 2548 2011-11-08 21:28:16Z bird $ */
2/** @file
3 * kBuild specific make functionality related to read.c.
4 */
5
6/*
7 * Copyright (c) 2011 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
23 *
24 */
25
26/* No GNU coding style here! */
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "make.h"
32#include "filedef.h"
33#include "variable.h"
34#include "dep.h"
35#include "debug.h"
36#include "kbuild.h"
37
38#include <assert.h>
39
40
41/*******************************************************************************
42* Defined Constants And Macros *
43*******************************************************************************/
44#define WORD_IS(a_pszWord, a_cchWord, a_szWord2) \
45 ( (a_cchWord) == sizeof(a_szWord2) - 1 && memcmp((a_pszWord), a_szWord2, sizeof(a_szWord2) - 1) == 0)
46
47
48/*******************************************************************************
49* Structures and Typedefs *
50*******************************************************************************/
51/** Indicate which kind of kBuild define we're working on. */
52enum kBuildDef
53{
54 kBuildDef_Invalid,
55 kBuildDef_Target,
56 kBuildDef_Template,
57 kBuildDef_Tool,
58 kBuildDef_Sdk,
59 kBuildDef_Unit
60};
61
62enum kBuildExtendBy
63{
64 kBuildExtendBy_NoParent,
65 kBuildExtendBy_Overriding,
66 kBuildExtendBy_Appending,
67 kBuildExtendBy_Prepending
68};
69
70
71/**
72 * The data we stack during eval.
73 */
74struct kbuild_eval_data
75{
76 /** The kind of define. */
77 enum kBuildDef enmKind;
78 /** Pointer to the element below us on the stack. */
79 struct kbuild_eval_data *pDown;
80
81 /** The bare name of the define. */
82 char *pszName;
83
84 /** The parent name, NULL if none. */
85 char *pszParent;
86 /** The inheritance method. */
87 enum kBuildExtendBy enmExtendBy;
88
89 /** The template, NULL if none. Only applicable to targets. */
90 char *pszTemplate;
91
92 /** The variable prefix*/
93 char *pszVarPrefix;
94 /** The length of the variable prefix. */
95 size_t cchVarPrefix;
96};
97
98
99static const char *
100eval_kbuild_kind_to_string(enum kBuildDef enmKind)
101{
102 switch (enmKind)
103 {
104 case kBuildDef_Target: return "target";
105 case kBuildDef_Template: return "template";
106 case kBuildDef_Tool: return "tool";
107 case kBuildDef_Sdk: return "sdk";
108 case kBuildDef_Unit: return "unit";
109 default:
110 case kBuildDef_Invalid: return "invalid";
111 }
112}
113
114
115static int
116eval_kbuild_define_xxxx(struct kbuild_eval_data **ppData, const struct floc *pFileLoc,
117 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildDef enmKind)
118{
119 unsigned int cch;
120 char *psz;
121 struct kbuild_eval_data *pData;
122
123 /*
124 * Create a new kBuild eval data item unless we're in ignore-mode.
125 */
126 if (fIgnoring)
127 return 0;
128
129 pData = xmalloc(sizeof(*pData));
130 pData->enmKind = enmKind;
131 pData->pszName = NULL;
132 pData->pszParent = NULL;
133 pData->enmExtendBy = kBuildExtendBy_NoParent;
134 pData->pszTemplate = NULL;
135 pData->pszVarPrefix = NULL;
136 pData->cchVarPrefix = 0;
137 pData->pDown = *ppData;
138 *ppData = pData;
139
140 /*
141 * The first word is the name.
142 */
143 pData->pszName = find_next_token_eos(&pszLine, pszEos, &cch);
144 if (!pData->pszName)
145 {
146 error(pFileLoc, _("The kBuild define requires a name"));
147 return 0;
148 }
149 pData->pszName = allocated_variable_expand_2(pData->pszName, cch, &cch);
150
151 /*
152 * Parse subsequent words.
153 */
154 psz = find_next_token_eos(&pszLine, pszEos, &cch);
155 while (psz)
156 {
157 if (WORD_IS(psz, cch, "extending"))
158 {
159 /* Inheritance directive. */
160 if (pData->pszParent != NULL)
161 fatal(pFileLoc, _("'extending' can only occure once"));
162 pData->pszParent = find_next_token_eos(&pszLine, pszEos, &cch);
163 if (pData->pszParent)
164 pData->pszParent = allocated_variable_expand_2(pData->pszParent, cch, &cch);
165 if (!pData->pszParent || !*pData->pszParent)
166 fatal(pFileLoc, _("'extending' requires a parent name"));
167
168 pData->enmExtendBy = kBuildExtendBy_Overriding;
169
170 /* optionally 'by overriding|prepending|appending' */
171 psz = find_next_token_eos(&pszLine, pszEos, &cch);
172 if (psz && WORD_IS(psz, cch, "by"))
173 {
174 cch = 0;
175 psz = find_next_token_eos(&pszLine, pszEos, &cch);
176 if (WORD_IS(psz, cch, "overriding"))
177 pData->enmExtendBy = kBuildExtendBy_Overriding;
178 else if (WORD_IS(psz, cch, "appending"))
179 pData->enmExtendBy = kBuildExtendBy_Appending;
180 else if (WORD_IS(psz, cch, "prepending"))
181 pData->enmExtendBy = kBuildExtendBy_Prepending;
182 else
183 fatal(pFileLoc, _("Unknown 'extending by' method '%.*s'"), (int)cch, psz);
184
185 /* next token */
186 psz = find_next_token_eos(&pszLine, pszEos, &cch);
187 }
188 }
189 else if ( WORD_IS(psz, cch, "using")
190 && enmKind == kBuildDef_Tool)
191 {
192 /* Template directive. */
193 if (pData->pszTemplate != NULL )
194 fatal(pFileLoc, _("'using' can only occure once"));
195 pData->pszTemplate = find_next_token_eos(&pszLine, pszEos, &cch);
196 if (pData->pszTemplate)
197 pData->pszTemplate = allocated_variable_expand_2(pData->pszTemplate, cch, &cch);
198 if (!pData->pszTemplate || !*pData->pszTemplate)
199 fatal(pFileLoc, _("'using' requires a template name"));
200
201 /* next token */
202 psz = find_next_token_eos(&pszLine, pszEos, &cch);
203 }
204 else
205 fatal(pFileLoc, _("Don't know what '%.*s' means"), (int)cch, psz);
206 }
207
208 /*
209 * Calc the variable prefix.
210 */
211
212 /** @todo continue here... */
213
214
215 return 0;
216}
217
218static int
219eval_kbuild_endef_xxxx(struct kbuild_eval_data **ppData, const struct floc *pFileLoc,
220 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildDef enmKind)
221{
222 struct kbuild_eval_data *pData;
223 unsigned int cchName;
224 char *pszName;
225
226 if (fIgnoring)
227 return 0;
228
229 /*
230 * Is there something to pop?
231 */
232 pData = *ppData;
233 if (!pData)
234 {
235 error(pFileLoc, _("kBuild-endef-%s is missing kBuild-define-%s"),
236 eval_kbuild_kind_to_string(enmKind), eval_kbuild_kind_to_string(enmKind));
237 return 0;
238 }
239
240 /*
241 * ... and does it have a matching kind?
242 */
243 if (pData->enmKind != enmKind)
244 {
245 error(pFileLoc, _("'kBuild-endef-%s' does not match 'kBuild-define-%s %s'"),
246 eval_kbuild_kind_to_string(enmKind), eval_kbuild_kind_to_string(pData->enmKind), pData->pszName);
247 return 0;
248 }
249
250 /*
251 * The endef-kbuild may optionally be followed by the target name.
252 * It should match the name given to the kBuild-define.
253 */
254 pszName = find_next_token_eos(&pszLine, pszEos, &cchName);
255 if (pszName)
256 {
257 pszName = allocated_variable_expand_2(pszName, cchName, &cchName);
258 if (strcmp(pszName, pData->pszName))
259 error(pFileLoc, _("'kBuild-endef-%s %s' does not match 'kBuild-define-%s %s'"),
260 eval_kbuild_kind_to_string(enmKind), pszName,
261 eval_kbuild_kind_to_string(pData->enmKind), pData->pszName);
262 free(pszName);
263 }
264
265 /*
266 * Pop a define off the stack.
267 */
268 *ppData = pData->pDown;
269 free(pData->pszName);
270 free(pData->pszParent);
271 free(pData->pszTemplate);
272 free(pData->pszVarPrefix);
273 free(pData);
274
275 return 0;
276}
277
278int eval_kbuild_define(struct kbuild_eval_data **kdata, const struct floc *flocp,
279 const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring)
280{
281 assert(memcmp(word, "kBuild-define", sizeof("kBuild-define") - 1) == 0);
282 word += sizeof("kBuild-define") - 1;
283 wlen -= sizeof("kBuild-define") - 1;
284 if ( wlen > 1
285 && word[0] == '-')
286 {
287 if (WORD_IS(word, wlen, "-target"))
288 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Target);
289 if (WORD_IS(word, wlen, "-template"))
290 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Template);
291 if (WORD_IS(word, wlen, "-tool"))
292 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Tool);
293 if (WORD_IS(word, wlen, "-sdk"))
294 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Sdk);
295 if (WORD_IS(word, wlen, "-unit"))
296 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Unit);
297 }
298
299 error(flocp, _("Unknown syntax 'kBuild-define%.*s'"), (int)wlen, word);
300 return 0;
301}
302
303int eval_kbuild_endef(struct kbuild_eval_data **kdata, const struct floc *flocp,
304 const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring)
305{
306 assert(memcmp(word, "kBuild-endef", sizeof("kBuild-endef") - 1) == 0);
307 word += sizeof("kBuild-endef") - 1;
308 wlen -= sizeof("kBuild-endef") - 1;
309 if ( wlen > 1
310 && word[0] == '-')
311 {
312 if (WORD_IS(word, wlen, "-target"))
313 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Target);
314 if (WORD_IS(word, wlen, "-template"))
315 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Template);
316 if (WORD_IS(word, wlen, "-tool"))
317 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Tool);
318 if (WORD_IS(word, wlen, "-sdk"))
319 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Sdk);
320 if (WORD_IS(word, wlen, "-unit"))
321 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Unit);
322 }
323
324 error(flocp, _("Unknown syntax 'kBuild-endef%.*s'"), (int)wlen, word);
325 return 0;
326}
327
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette