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 
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,
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 
185 int _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 
225 int _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 
268 int _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 
309 int _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 
void GWB_Target_SetName(GWB_TARGET *target, const char *s)
Definition: target.c:78
void GWB_Target_SetTargetType(GWB_TARGET *target, GWBUILD_TARGETTYPE t)
Definition: target.c:135
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:71
int GWB_Target_GetSoVersionRevision(const GWB_TARGET *target)
Definition: target.c:180
GWEN_STRINGLIST * GWB_Parser_ReadXmlDataIntoStringList(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:283
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:153
#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:62
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:367
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:157
#define GWB_PARSER_SRCFILEFLAGS_ISSOURCE
Definition: parser.h:26
int GWB_Parser_ParseWellKnownElements(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:942
void GWB_Target_SetContext(GWB_TARGET *target, GWB_CONTEXT *ctx)
Definition: target.c:194
void GWB_Target_SetId(GWB_TARGET *target, const char *s)
Definition: target.c:116
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:214
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
#define GWB_PARSER_SRCFILEFLAGS_ALWAYSDIST
Definition: parser.h:25
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:149
void GWB_Target_AddUsedTargetName(GWB_TARGET *target, const char *s)
Definition: target.c:223
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:166
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
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:268
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:181
void GWB_Target_AddUsedLibraryName(GWB_TARGET *target, const char *s)
Definition: target.c:239
void GWB_Target_free(GWB_TARGET *target)
Definition: target.c:45
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_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:173
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
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
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989