gwenhywfar  5.7.2
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 
25 static GWB_TARGET *_readTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
26 static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
27 static int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
28 static int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
29 static int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
30 static int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
31 
32 
33 
34 
35 
36 int 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 
74 GWB_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 
131 int _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, 1, 1);
149  else if (strcasecmp(name, "headers")==0)
150  rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n, 1, 0);
151  else if (strcasecmp(name, "data")==0)
152  rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n, 1, 0);
153  else if (strcasecmp(name, "extradist")==0)
154  rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n, 1, 0);
155  else if (strcasecmp(name, "useTargets")==0)
156  rv=_parseUsedTargets(currentContext, n);
157  else if (strcasecmp(name, "includes")==0)
158  rv=_parseIncludes(currentContext, n);
159  else if (strcasecmp(name, "define")==0)
160  rv=_parseDefines(currentContext, n);
161  else if (strcasecmp(name, "libraries")==0)
162  rv=_parseLibraries(currentContext, n);
163  else if (strcasecmp(name, "target")==0)
164  rv=GWB_ParseTarget(project, currentContext, n);
165  else if (strcasecmp(name, "buildFiles")==0)
166  rv=GWB_ParseBuildFiles(project, currentContext, n);
167  else
168  rv=GWB_Parser_ParseWellKnownElements(project, currentContext, n, _parseChildNodes);
169  if (rv<0) {
170  DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
171  return rv;
172  }
173  }
174 
176  }
177 
178  return 0;
179 }
180 
181 
182 
183 int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
184 {
185  GWB_TARGET *target;
186  int rv;
187  GWEN_STRINGLIST *targetNameList;
188 
189  target=GWB_Context_GetCurrentTarget(currentContext);
190  if (target==NULL) {
191  DBG_ERROR(NULL, "No target in current context, SNH!");
192  return GWEN_ERROR_INTERNAL;
193  }
194 
195  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
196  if (rv<0) {
197  DBG_INFO(NULL, "here (%d)", rv);
198  return rv;
199  }
200 
201  targetNameList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
202  if (targetNameList) {
204 
205  se=GWEN_StringList_FirstEntry(targetNameList);
206  while(se) {
207  const char *sTargetName;
208 
209  sTargetName=GWEN_StringListEntry_Data(se);
210  if (sTargetName && *sTargetName)
211  GWB_Target_AddUsedTargetName(target, sTargetName);
212 
214  }
215  GWEN_StringList_free(targetNameList);
216  }
217 
218  return 0;
219 }
220 
221 
222 
223 int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
224 {
225  GWB_TARGET *target;
226  int rv;
227  const char *builderType;
228  GWEN_STRINGLIST *entryList;
229 
230  target=GWB_Context_GetCurrentTarget(currentContext);
231  if (target==NULL) {
232  DBG_ERROR(NULL, "No target in current context, SNH!");
233  return GWEN_ERROR_INTERNAL;
234  }
235 
236  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
237  if (rv<0) {
238  DBG_INFO(NULL, "here (%d)", rv);
239  return rv;
240  }
241 
242  builderType=GWEN_XMLNode_GetProperty(xmlNode, "type", "c");
243 
244  entryList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
245  if (entryList) {
247 
248  se=GWEN_StringList_FirstEntry(entryList);
249  while(se) {
250  const char *sEntry;
251 
252  sEntry=GWEN_StringListEntry_Data(se);
253  if (sEntry && *sEntry)
254  GWB_Context_AddInclude(currentContext, builderType, sEntry);
255 
257  }
258  GWEN_StringList_free(entryList);
259  }
260 
261  return 0;
262 }
263 
264 
265 
266 int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
267 {
268  int rv;
269  const char *varName;
270  const char *value;
271  const char *quoted;
272 
273  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
274  if (rv<0) {
275  DBG_INFO(NULL, "here (%d)", rv);
276  return rv;
277  }
278 
279  quoted=GWEN_XMLNode_GetProperty(xmlNode, "quoted", "FALSE");
280  varName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
281  value=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
282  if (!(varName && *varName)) {
283  DBG_ERROR(NULL, "Missing variable name in DEFINE");
284  return GWEN_ERROR_GENERIC;
285  }
286  if (quoted && strcasecmp(quoted, "TRUE")==0) {
287  GWEN_BUFFER *dbuf;
288 
289  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
290  GWEN_Buffer_AppendString(dbuf, "\\\"");
291  if (value && *value)
292  GWEN_Buffer_AppendString(dbuf, value);
293  GWEN_Buffer_AppendString(dbuf, "\\\"");
294  GWB_Context_SetDefine(currentContext, varName, GWEN_Buffer_GetStart(dbuf));
295  GWEN_Buffer_free(dbuf);
296  }
297  else {
298  GWB_Context_SetDefine(currentContext, varName, value);
299  }
300 
301 
302  return 0;
303 }
304 
305 
306 
307 int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
308 {
309  GWB_TARGET *target;
310  int rv;
311  GWEN_STRINGLIST *entryList;
312 
313  target=GWB_Context_GetCurrentTarget(currentContext);
314  if (target==NULL) {
315  DBG_ERROR(NULL, "No target in current context, SNH!");
316  return GWEN_ERROR_INTERNAL;
317  }
318 
319  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
320  if (rv<0) {
321  DBG_INFO(NULL, "here (%d)", rv);
322  return rv;
323  }
324 
325  entryList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
326  if (entryList) {
328 
329  se=GWEN_StringList_FirstEntry(entryList);
330  while(se) {
331  const char *sEntry;
332 
333  sEntry=GWEN_StringListEntry_Data(se);
334  if (sEntry && *sEntry)
335  GWB_Target_AddUsedLibraryName(target, sEntry);
336 
338  }
339  GWEN_StringList_free(entryList);
340  }
341 
342  return 0;
343 }
344 
345 
346 
void GWB_Target_SetName(GWB_TARGET *target, const char *s)
Definition: target.c:77
void GWB_Target_SetTargetType(GWB_TARGET *target, GWBUILD_TARGETTYPE t)
Definition: target.c:115
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
const char * GWB_Target_GetName(const GWB_TARGET *target)
Definition: target.c:70
int GWB_Target_GetSoVersionRevision(const GWB_TARGET *target)
Definition: target.c:160
GWEN_STRINGLIST * GWB_Parser_ReadXmlDataIntoStringList(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:308
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
GWB_CONTEXT * GWB_Parser_CopyContextForTarget(const GWB_CONTEXT *sourceContext)
Definition: parser.c:142
#define NULL
Definition: binreloc.c:300
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
GWBUILD_TARGETTYPE GWBUILD_TargetType_fromString(const char *s)
Definition: gwenbuild.c:176
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWB_Context_AddInclude(GWB_CONTEXT *ctx, const char *genType, const char *incl)
Definition: context.c:367
GWBUILD_TARGETTYPE
Definition: gwenbuild.h:18
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWB_ParseBuildFiles(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_buildfiles.c:57
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
int GWB_Parser_ParseSubdirs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:392
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
void GWB_Target_SetSoVersion(GWB_TARGET *target, int vCurrent, int vAge, int vRevision)
Definition: target.c:137
int GWB_Parser_ParseWellKnownElements(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:940
void GWB_Target_SetContext(GWB_TARGET *target, GWB_CONTEXT *ctx)
Definition: target.c:174
void GWB_Target_SetId(GWB_TARGET *target, const char *s)
Definition: target.c:96
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name, int defaultValue)
Definition: xml.c:263
struct GWB_TARGET GWB_TARGET
Definition: target.h:17
void GWB_Context_SetDefine(GWB_CONTEXT *ctx, const char *name, const char *value)
Definition: context.c:399
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
GWB_TARGET * GWB_Target_new(GWB_PROJECT *project)
Definition: target.c:26
static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:131
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:712
void GWB_Target_SetInstallPath(GWB_TARGET *target, const char *s)
Definition: target.c:129
void GWB_Target_AddUsedTargetName(GWB_TARGET *target, const char *s)
Definition: target.c:203
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
int GWB_Target_GetSoVersionCurrent(const GWB_TARGET *target)
Definition: target.c:146
int GWEN_DB_SetCharValueFromInt(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1036
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:705
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
static int _parseDefines(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:266
static GWB_TARGET * _readTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:74
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
void GWB_Target_AddUsedLibraryName(GWB_TARGET *target, const char *s)
Definition: target.c:219
void GWB_Target_free(GWB_TARGET *target)
Definition: target.c:45
static int _parseLibraries(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:307
static int _parseIncludes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:223
GWB_TARGET * GWB_Context_GetCurrentTarget(const GWB_CONTEXT *ctx)
Definition: context.c:460
void GWB_Project_AddTarget(GWB_PROJECT *project, GWB_TARGET *target)
Definition: project.c:241
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition: xml.c:634
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
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
int GWB_Target_GetSoVersionAge(const GWB_TARGET *target)
Definition: target.c:153
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
static int _parseUsedTargets(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:183
int GWB_ParseTarget(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_target.c:36
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
int GWB_Parser_ParseSourcesOrHeaders(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, int alwaysDist, int isSource)
Definition: parser.c:977