gwenhywfar 5.10.1
p_dependencies.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
17
18#include <gwenhywfar/debug.h>
19#include <gwenhywfar/process.h>
20#include <gwenhywfar/text.h>
21#include <gwenhywfar/syncio.h>
22
23#include <unistd.h>
24#include <ctype.h>
25
26
27
28static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
29int _parseDep(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
30
31static int _checkVersion(GWEN_DB_NODE *db,
32 const char *sId,
33 const char *sName,
34 const char *sMinVersion,
35 const char *sMaxVersion);
36static int _retrieveCflags(GWEN_DB_NODE *db, const char *sId, const char *sName);
37static int _retrieveLdflags(GWEN_DB_NODE *db, const char *sId, const char *sName);
38static int _callPkgConfig(GWEN_DB_NODE *db,
39 const char *sId,
40 const char *sName,
41 const char *suffix,
42 const char *args);
43
44void _replaceControlCharsWithBlanks(char *ptr);
45int _retrieveVariables(GWB_CONTEXT *currentContext, GWEN_DB_NODE *db, const char *sId, const char *sName, GWEN_XMLNODE *xmlNode);
46int _retrieveVariable(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *variableName);
47
48
49
50
51
52
53int GWB_ParseDependencies(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
54{
55 int rv;
56
57 rv=_parseChildNodes(project, currentContext, xmlNode);
58 if (rv<0) {
59 DBG_INFO(NULL, "here (%d)", rv);
60 return rv;
61 }
62
63 return 0;
64}
65
66
67
68int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
69{
70 GWEN_XMLNODE *n;
71
72 n=GWEN_XMLNode_GetFirstTag(xmlNode);
73 while (n) {
74 const char *name;
75
77 if (name && *name) {
78 int rv;
79
80 DBG_DEBUG(NULL, "Handling element \"%s\"", name);
81
82 if (strcasecmp(name, "subdirs")==0)
83 rv=GWB_Parser_ParseSubdirs(project, currentContext, n, _parseChildNodes);
84 else if (strcasecmp(name, "dep")==0)
85 rv=_parseDep(currentContext, n);
86 else
87 rv=GWB_Parser_ParseWellKnownElements(project, currentContext, n, _parseChildNodes);
88 if (rv<0) {
89 DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
90 return rv;
91 }
92 }
93
95 }
96
97 return 0;
98}
99
100
101
102int _parseDep(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
103{
104 int rv;
105 const char *s;
106 const char *sId;
107 const char *sName;
108 const char *sMinVersion;
109 const char *sMaxVersion;
110 int required;
111
112 rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
113 if (rv<0) {
114 DBG_INFO(NULL, "here (%d)", rv);
115 return rv;
116 }
117
118 sId=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
119 if (!(sId && *sId)) {
120 DBG_ERROR(NULL, "Dependency has no id");
121 return GWEN_ERROR_GENERIC;
122 }
123
124 sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
125 if (!(sName && *sName)) {
126 DBG_ERROR(NULL, "Dependency has no name");
127 return GWEN_ERROR_GENERIC;
128 }
129
130 s=GWEN_XMLNode_GetProperty(xmlNode, "required", "FALSE");
131 required=(strcasecmp(s, "TRUE")==0)?1:0;
132
133 sMinVersion=GWEN_XMLNode_GetProperty(xmlNode, "minversion", NULL);
134 sMaxVersion=GWEN_XMLNode_GetProperty(xmlNode, "maxversion", NULL);
135
136 rv=_checkVersion(GWB_Context_GetVars(currentContext),
137 sId,
138 sName,
139 sMinVersion,
140 sMaxVersion);
141 if (rv==0) {
142 GWEN_XMLNODE *n;
143
144 rv=_retrieveCflags(GWB_Context_GetVars(currentContext), sId, sName);
145 if (rv<0) {
146 DBG_INFO(NULL, "here (%d)", rv);
147 return rv;
148 }
149 rv=_retrieveLdflags(GWB_Context_GetVars(currentContext), sId, sName);
150 if (rv<0) {
151 DBG_INFO(NULL, "here (%d)", rv);
152 return rv;
153 }
154
155 n=GWEN_XMLNode_FindFirstTag(xmlNode, "variables", NULL, NULL);
156 if (n) {
157 rv=_retrieveVariables(currentContext, GWB_Context_GetVars(currentContext), sId, sName, n);
158 if (rv<0) {
159 DBG_INFO(NULL, "here (%d)", rv);
160 return rv;
161 }
162 }
163 }
164 else if (rv==GWEN_ERROR_NOT_FOUND) {
165 if (required) {
166 DBG_ERROR(NULL, "Dependency \"%s\" not found but required", sName);
167 return rv;
168 }
169 }
170 else {
171 DBG_INFO(NULL, "here (%d)", rv);
172 return rv;
173 }
174
175 return 0;
176}
177
178
179
180int _retrieveVariables(GWB_CONTEXT *currentContext, GWEN_DB_NODE *db, const char *sId, const char *sName, GWEN_XMLNODE *xmlNode)
181{
182 GWEN_STRINGLIST *slVariables;
183
184 slVariables=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
185 if (slVariables) {
187
188 se=GWEN_StringList_FirstEntry(slVariables);
189 while(se) {
190 const char *s;
191
193 if (s && *s) {
194 int rv;
195
196 rv=_retrieveVariable(db, sId, sName, s);
197 if (rv<0) {
198 DBG_ERROR(NULL, "Error retrieving variable \"%s\" for dependency \"%s\"", s, sId);
199 GWEN_StringList_free(slVariables);
200 return rv;
201 }
202 }
204 }
205 }
206
207 return 0;
208}
209
210
211
213 const char *sId,
214 const char *sName,
215 const char *sMinVersion,
216 const char *sMaxVersion)
217{
218 GWEN_BUFFER *argBuffer;
219 GWEN_BUFFER *stdOutBuffer;
220 GWEN_BUFFER *stdErrBuffer;
221 int rv;
222
223 stdOutBuffer=GWEN_Buffer_new(0, 256, 0, 1);
224 stdErrBuffer=GWEN_Buffer_new(0, 256, 0, 1);
225 argBuffer=GWEN_Buffer_new(0, 256, 0, 1);
226
227 if (sMinVersion) {
228 GWEN_Buffer_AppendString(argBuffer, " --atleast-version=");
229 GWEN_Buffer_AppendString(argBuffer, sMinVersion);
230 GWEN_Buffer_AppendString(argBuffer, " ");
231 }
232 if (sMaxVersion) {
233 GWEN_Buffer_AppendString(argBuffer, " --max-version=");
234 GWEN_Buffer_AppendString(argBuffer, sMaxVersion);
235 GWEN_Buffer_AppendString(argBuffer, " ");
236 }
237 GWEN_Buffer_AppendString(argBuffer, sName);
238
239 DBG_DEBUG(NULL, "Running command with args: [%s]", GWEN_Buffer_GetStart(argBuffer));
241 stdOutBuffer, stdErrBuffer);
242 if (rv<0) {
243 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
244 GWEN_Buffer_free(argBuffer);
245 GWEN_Buffer_free(stdErrBuffer);
246 GWEN_Buffer_free(stdOutBuffer);
247 return rv;
248 }
249 GWEN_Buffer_free(argBuffer);
250 GWEN_Buffer_free(stdErrBuffer);
251 GWEN_Buffer_free(stdOutBuffer);
252
253 GWB_Parser_SetItemValue(db, sId, "_EXISTS", (rv==0)?"TRUE":"FALSE");
254 fprintf(stdout, " dep %s: %s\n", sId, (rv==0)?"found":"not found");
255
256 return (rv==0)?0:GWEN_ERROR_NOT_FOUND;
257}
258
259
260
261int _retrieveCflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
262{
263 int rv;
264
265 rv=_callPkgConfig(db, sId, sName, "_CFLAGS", "--cflags");
266 if (rv<0) {
267 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
268 return rv;
269 }
270
271 return 0;
272}
273
274
275
276int _retrieveLdflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
277{
278 int rv;
279
280 rv=_callPkgConfig(db, sId, sName, "_LIBS", "--libs");
281 if (rv<0) {
282 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
283 return rv;
284 }
285
286 return 0;
287}
288
289
290
291int _retrieveVariable(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *variableName)
292{
293 int rv;
294 GWEN_BUFFER *varArgBuffer;
295 GWEN_BUFFER *varSuffixBuffer;
296 const char *s;
297
298 varArgBuffer=GWEN_Buffer_new(0, 256, 0, 1);
299 GWEN_Buffer_AppendString(varArgBuffer, "--variable=");
300 GWEN_Buffer_AppendString(varArgBuffer, variableName);
301
302 varSuffixBuffer=GWEN_Buffer_new(0, 256, 0, 1);
303 GWEN_Buffer_AppendString(varSuffixBuffer, "_");
304 s=variableName;
305 while(*s)
306 GWEN_Buffer_AppendByte(varSuffixBuffer, toupper(*(s++)));
307
308 rv=_callPkgConfig(db, sId, sName, GWEN_Buffer_GetStart(varSuffixBuffer), GWEN_Buffer_GetStart(varArgBuffer));
309 GWEN_Buffer_free(varSuffixBuffer);
310 GWEN_Buffer_free(varArgBuffer);
311 if (rv<0) {
312 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
313 return rv;
314 }
315
316 return 0;
317}
318
319
320
322 const char *sId,
323 const char *sName,
324 const char *suffix,
325 const char *args)
326{
327 GWEN_BUFFER *argBuffer;
328 GWEN_BUFFER *stdOutBuffer;
329 GWEN_BUFFER *stdErrBuffer;
330 int rv;
331
332 stdOutBuffer=GWEN_Buffer_new(0, 256, 0, 1);
333 stdErrBuffer=GWEN_Buffer_new(0, 256, 0, 1);
334 argBuffer=GWEN_Buffer_new(0, 256, 0, 1);
335
336 GWEN_Buffer_AppendString(argBuffer, args);
337 GWEN_Buffer_AppendString(argBuffer, " ");
338 GWEN_Buffer_AppendString(argBuffer, sName);
339
340 DBG_DEBUG(NULL, "Running command with args: [%s]", GWEN_Buffer_GetStart(argBuffer));
341 rv=GWEN_Process_RunCommandWaitAndGather("pkg-config", GWEN_Buffer_GetStart(argBuffer), stdOutBuffer, stdErrBuffer);
342 if (rv<0) {
343 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
344 GWEN_Buffer_free(argBuffer);
345 GWEN_Buffer_free(stdErrBuffer);
346 GWEN_Buffer_free(stdOutBuffer);
347 return rv;
348 }
349 GWEN_Buffer_free(argBuffer);
350
352 GWEN_Text_CondenseBuffer(stdOutBuffer);
353 GWB_Parser_SetItemValue(db, sId, suffix, GWEN_Buffer_GetStart(stdOutBuffer));
354
355 GWEN_Buffer_free(stdErrBuffer);
356 GWEN_Buffer_free(stdOutBuffer);
357 return 0;
358}
359
360
361
363{
364 while(ptr && *ptr) {
365 if (*ptr<32)
366 *ptr=32;
367 ptr++;
368 }
369}
370
371
372
#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
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
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_GENERIC
Definition: error.h:62
#define GWEN_ERROR_NOT_FOUND
Definition: error.h:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWB_ParseDependencies(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
static int _callPkgConfig(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *suffix, const char *args)
static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
static int _retrieveCflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
void _replaceControlCharsWithBlanks(char *ptr)
static int _retrieveLdflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
int _retrieveVariables(GWB_CONTEXT *currentContext, GWEN_DB_NODE *db, const char *sId, const char *sName, GWEN_XMLNODE *xmlNode)
static int _checkVersion(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *sMinVersion, const char *sMaxVersion)
int _parseDep(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
int _retrieveVariable(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *variableName)
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
void GWB_Parser_SetItemValue(GWEN_DB_NODE *db, const char *sId, const char *suffix, const char *value)
Definition: parser.c:856
GWENHYWFAR_API int GWEN_Process_RunCommandWaitAndGather(const char *prg, const char *args, GWEN_BUFFER *stdOutBuffer, GWEN_BUFFER *stdErrBuffer)
Definition: process_all.c:31
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 GWEN_Text_CondenseBuffer(GWEN_BUFFER *buf)
Definition: text.c:1620
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:776
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
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156