gwenhywfar 5.10.1
p_target.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Mon Feb 08 2021
3 copyright : (C) 2021 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14
19
20#include <gwenhywfar/debug.h>
21#include <gwenhywfar/text.h>
22
23
24
25static GWB_TARGET *_readTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
26static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
27static int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
28static int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
29static int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
30static int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
31
32
33
34
35
36int GWB_ParseTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
37{
38 int rv;
39 GWB_TARGET *target;
40 GWB_CONTEXT *newContext;
41
42 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
43 if (rv<0) {
44 DBG_INFO(NULL, "here (%d)", rv);
45 return rv;
46 }
47
48 target=_readTarget(project, currentContext, xmlNode);
49 if (target==NULL) {
50 DBG_INFO(NULL, "No target created");
51 return GWEN_ERROR_GENERIC;
52 }
53
54 newContext=GWB_Parser_CopyContextForTarget(currentContext);
55 GWB_Context_SetCurrentTarget(newContext, target);
56 GWB_Target_SetContext(target, newContext);
57
58 rv=_parseChildNodes(project, newContext, xmlNode);
59 if (rv<0) {
60 DBG_INFO(NULL, "here (%d)", rv);
61 GWB_Context_free(newContext);
62 GWB_Target_free(target);
63 return rv;
64 }
65
66 GWB_Project_AddTarget(project, target);
67 GWB_Context_Tree2_AddChild(currentContext, newContext);
68
69 return 0;
70}
71
72
73
74GWB_TARGET *_readTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
75{
76 GWB_TARGET *target;
77 const char *s;
78 GWBUILD_TARGETTYPE targetType;
79 uint32_t flags=GWEN_DB_FLAGS_OVERWRITE_VARS;
80 GWEN_DB_NODE *db;
81
82 target=GWB_Target_new(project);
83
84 s=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
85 if (!(s && *s)) {
86 DBG_ERROR(NULL, "Target has no name");
87 return NULL;
88 }
89 GWB_Target_SetName(target, s);
90 GWB_Target_SetId(target, s);
91
92 s=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
93 if (s && *s)
94 GWB_Target_SetId(target, s);
95
96 s=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
97 if (!(s && *s)) {
98 DBG_ERROR(NULL, "Target has no type");
99 GWB_Target_free(target);
100 return NULL;
101 }
102 targetType=GWBUILD_TargetType_fromString(s);
103 if (targetType==GWBUILD_TargetType_Invalid) {
104 DBG_ERROR(NULL, "Bad target type \"%s\"", s?s:"<empty>");
105 GWB_Target_free(target);
106 return NULL;
107 }
108 GWB_Target_SetTargetType(target, targetType);
109
110 s=GWEN_XMLNode_GetProperty(xmlNode, "install", NULL);
111 GWB_Target_SetInstallPath(target, s);
112
114 GWEN_XMLNode_GetIntProperty(xmlNode, "so_current", 0),
115 GWEN_XMLNode_GetIntProperty(xmlNode, "so_age", 0),
116 GWEN_XMLNode_GetIntProperty(xmlNode, "so_revision", 0));
117
118 db=GWB_Context_GetVars(currentContext);
119 GWEN_DB_SetCharValue(db, flags, "target_name", GWB_Target_GetName(target));
120 GWEN_DB_SetCharValueFromInt(db, flags, "target_so_current", GWB_Target_GetSoVersionCurrent(target));
121 GWEN_DB_SetCharValueFromInt(db, flags, "target_so_age", GWB_Target_GetSoVersionAge(target));
122 GWEN_DB_SetCharValueFromInt(db, flags, "target_so_revision", GWB_Target_GetSoVersionRevision(target));
123 GWEN_DB_SetCharValueFromInt(db, flags, "target_so_effective",
125
126 return target;
127}
128
129
130
131int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
132{
133 GWEN_XMLNODE *n;
134
135 n=GWEN_XMLNode_GetFirstTag(xmlNode);
136 while (n) {
137 const char *name;
138
139 name=GWEN_XMLNode_GetData(n);
140 if (name && *name) {
141 int rv;
142
143 DBG_DEBUG(NULL, "Handling element \"%s\"", name);
144
145 if (strcasecmp(name, "subdirs")==0)
146 rv=GWB_Parser_ParseSubdirs(project, currentContext, n, _parseChildNodes);
147 else if (strcasecmp(name, "sources")==0)
148 rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n,
150 NULL, NULL);
151 else if (strcasecmp(name, "headers")==0)
153 else if (strcasecmp(name, "data")==0)
155 else if (strcasecmp(name, "extradist")==0)
157 else if (strcasecmp(name, "useTargets")==0)
158 rv=_parseUsedTargets(currentContext, n);
159 else if (strcasecmp(name, "includes")==0)
160 rv=_parseIncludes(currentContext, n);
161 else if (strcasecmp(name, "define")==0)
162 rv=_parseDefines(currentContext, n);
163 else if (strcasecmp(name, "libraries")==0)
164 rv=_parseLibraries(currentContext, n);
165 else if (strcasecmp(name, "target")==0)
166 rv=GWB_ParseTarget(project, currentContext, n);
167 else if (strcasecmp(name, "buildFiles")==0)
168 rv=GWB_ParseBuildFiles(project, currentContext, n);
169 else
170 rv=GWB_Parser_ParseWellKnownElements(project, currentContext, n, _parseChildNodes);
171 if (rv<0) {
172 DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
173 return rv;
174 }
175 }
176
178 }
179
180 return 0;
181}
182
183
184
185int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
186{
187 GWB_TARGET *target;
188 int rv;
189 GWEN_STRINGLIST *targetNameList;
190
191 target=GWB_Context_GetCurrentTarget(currentContext);
192 if (target==NULL) {
193 DBG_ERROR(NULL, "No target in current context, SNH!");
194 return GWEN_ERROR_INTERNAL;
195 }
196
197 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
198 if (rv<0) {
199 DBG_INFO(NULL, "here (%d)", rv);
200 return rv;
201 }
202
203 targetNameList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
204 if (targetNameList) {
206
207 se=GWEN_StringList_FirstEntry(targetNameList);
208 while(se) {
209 const char *sTargetName;
210
211 sTargetName=GWEN_StringListEntry_Data(se);
212 if (sTargetName && *sTargetName)
213 GWB_Target_AddUsedTargetName(target, sTargetName);
214
216 }
217 GWEN_StringList_free(targetNameList);
218 }
219
220 return 0;
221}
222
223
224
225int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
226{
227 GWB_TARGET *target;
228 int rv;
229 const char *builderType;
230 GWEN_STRINGLIST *entryList;
231
232 target=GWB_Context_GetCurrentTarget(currentContext);
233 if (target==NULL) {
234 DBG_ERROR(NULL, "No target in current context, SNH!");
235 return GWEN_ERROR_INTERNAL;
236 }
237
238 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
239 if (rv<0) {
240 DBG_INFO(NULL, "here (%d)", rv);
241 return rv;
242 }
243
244 builderType=GWEN_XMLNode_GetProperty(xmlNode, "type", "c");
245
246 entryList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
247 if (entryList) {
249
250 se=GWEN_StringList_FirstEntry(entryList);
251 while(se) {
252 const char *sEntry;
253
254 sEntry=GWEN_StringListEntry_Data(se);
255 if (sEntry && *sEntry)
256 GWB_Context_AddInclude(currentContext, builderType, sEntry);
257
259 }
260 GWEN_StringList_free(entryList);
261 }
262
263 return 0;
264}
265
266
267
268int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
269{
270 int rv;
271 const char *varName;
272 const char *value;
273 const char *quoted;
274
275 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
276 if (rv<0) {
277 DBG_INFO(NULL, "here (%d)", rv);
278 return rv;
279 }
280
281 quoted=GWEN_XMLNode_GetProperty(xmlNode, "quoted", "FALSE");
282 varName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
283 value=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
284 if (!(varName && *varName)) {
285 DBG_ERROR(NULL, "Missing variable name in DEFINE");
286 return GWEN_ERROR_GENERIC;
287 }
288 if (quoted && strcasecmp(quoted, "TRUE")==0) {
289 GWEN_BUFFER *dbuf;
290
291 dbuf=GWEN_Buffer_new(0, 256, 0, 1);
292 GWEN_Buffer_AppendString(dbuf, "\\\"");
293 if (value && *value)
294 GWEN_Buffer_AppendString(dbuf, value);
295 GWEN_Buffer_AppendString(dbuf, "\\\"");
296 GWB_Context_SetDefine(currentContext, varName, GWEN_Buffer_GetStart(dbuf));
297 GWEN_Buffer_free(dbuf);
298 }
299 else {
300 GWB_Context_SetDefine(currentContext, varName, value);
301 }
302
303
304 return 0;
305}
306
307
308
309int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
310{
311 GWB_TARGET *target;
312 int rv;
313 GWEN_STRINGLIST *entryList;
314
315 target=GWB_Context_GetCurrentTarget(currentContext);
316 if (target==NULL) {
317 DBG_ERROR(NULL, "No target in current context, SNH!");
318 return GWEN_ERROR_INTERNAL;
319 }
320
321 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
322 if (rv<0) {
323 DBG_INFO(NULL, "here (%d)", rv);
324 return rv;
325 }
326
327 entryList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
328 if (entryList) {
330
331 se=GWEN_StringList_FirstEntry(entryList);
332 while(se) {
333 const char *sEntry;
334
335 sEntry=GWEN_StringListEntry_Data(se);
336 if (sEntry && *sEntry)
337 GWB_Target_AddUsedLibraryName(target, sEntry);
338
340 }
341 GWEN_StringList_free(entryList);
342 }
343
344 return 0;
345}
346
347
348
#define NULL
Definition: binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
GWB_TARGET * GWB_Context_GetCurrentTarget(const GWB_CONTEXT *ctx)
Definition: context.c:460
void GWB_Context_AddInclude(GWB_CONTEXT *ctx, const char *genType, const char *incl)
Definition: context.c:367
void GWB_Context_SetCurrentTarget(GWB_CONTEXT *ctx, GWB_TARGET *target)
Definition: context.c:466
void GWB_Context_free(GWB_CONTEXT *ctx)
Definition: context.c:93
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
void GWB_Context_SetDefine(GWB_CONTEXT *ctx, const char *name, const char *value)
Definition: context.c:399
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
int GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1036
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
#define GWEN_ERROR_GENERIC
Definition: error.h:62
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWBUILD_TARGETTYPE GWBUILD_TargetType_fromString(const char *s)
Definition: gwenbuild.c:176
GWBUILD_TARGETTYPE
Definition: gwenbuild.h:18
@ GWBUILD_TargetType_Invalid
Definition: gwenbuild.h:19
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWB_ParseBuildFiles(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_buildfiles.c:62
static GWB_TARGET * _readTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:74
static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:131
static int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:185
int GWB_ParseTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:36
static int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:268
static int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:309
static int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:225
GWB_CONTEXT * GWB_Parser_CopyContextForTarget(const GWB_CONTEXT *sourceContext)
Definition: parser.c:153
int GWB_Parser_ParseSubdirs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:367
GWEN_STRINGLIST * GWB_Parser_ReadXmlDataIntoStringList(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:283
int GWB_Parser_ParseWellKnownElements(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:942
int GWB_Parser_ParseSourcesOrHeaders(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, uint32_t fileFlags, const char *defaultTypeName, const char *defaultBuilder)
Definition: parser.c:979
#define GWB_PARSER_SRCFILEFLAGS_ALWAYSDIST
Definition: parser.h:25
#define GWB_PARSER_SRCFILEFLAGS_ISSOURCE
Definition: parser.h:26
void GWB_Project_AddTarget(GWB_PROJECT *project, GWB_TARGET *target)
Definition: project.c:241
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
void GWB_Target_SetTargetType(GWB_TARGET *target, GWBUILD_TARGETTYPE t)
Definition: target.c:135
void GWB_Target_SetSoVersion(GWB_TARGET *target, int vCurrent, int vAge, int vRevision)
Definition: target.c:157
void GWB_Target_SetInstallPath(GWB_TARGET *target, const char *s)
Definition: target.c:149
GWB_TARGET * GWB_Target_new(GWB_PROJECT *project)
Definition: target.c:26
void GWB_Target_SetContext(GWB_TARGET *target, GWB_CONTEXT *ctx)
Definition: target.c:194
int GWB_Target_GetSoVersionRevision(const GWB_TARGET *target)
Definition: target.c:180
void GWB_Target_SetId(GWB_TARGET *target, const char *s)
Definition: target.c:116
void GWB_Target_AddUsedTargetName(GWB_TARGET *target, const char *s)
Definition: target.c:223
int GWB_Target_GetSoVersionCurrent(const GWB_TARGET *target)
Definition: target.c:166
void GWB_Target_AddUsedLibraryName(GWB_TARGET *target, const char *s)
Definition: target.c:239
void GWB_Target_SetName(GWB_TARGET *target, const char *s)
Definition: target.c:78
const char * GWB_Target_GetName(const GWB_TARGET *target)
Definition: target.c:71
int GWB_Target_GetSoVersionAge(const GWB_TARGET *target)
Definition: target.c:173
void GWB_Target_free(GWB_TARGET *target)
Definition: target.c:45
struct GWB_TARGET GWB_TARGET
Definition: target.h:17
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:705
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:712
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition: xml.c:634
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name, int defaultValue)
Definition: xml.c:263
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156