gwenhywfar 5.12.0
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);
29static int _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
44static void _replaceControlCharsWithBlanks(char *ptr);
45static int _retrieveVariables(GWB_CONTEXT *currentContext, GWEN_DB_NODE *db, const char *sId, const char *sName, GWEN_XMLNODE *xmlNode);
46static int _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, "prefix", NULL);
119 if (!(sId && *sId))
120 sId=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
121
122 sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
123 if (!(sName && *sName)) {
124 DBG_ERROR(NULL, "Dependency has no name");
125 return GWEN_ERROR_GENERIC;
126 }
127
128 if (!(sId && *sId)) /* use name if no id/prefix given */
129 sId=sName;
130
131 s=GWEN_XMLNode_GetProperty(xmlNode, "required", "FALSE");
132 required=(strcasecmp(s, "TRUE")==0)?1:0;
133
134 sMinVersion=GWEN_XMLNode_GetProperty(xmlNode, "minversion", NULL);
135 sMaxVersion=GWEN_XMLNode_GetProperty(xmlNode, "maxversion", NULL);
136
137 rv=_checkVersion(GWB_Context_GetVars(currentContext),
138 sId,
139 sName,
140 sMinVersion,
141 sMaxVersion);
142 if (rv==0) {
143 GWEN_XMLNODE *n;
144
145 rv=_retrieveCflags(GWB_Context_GetVars(currentContext), sId, sName);
146 if (rv<0) {
147 DBG_INFO(NULL, "here (%d)", rv);
148 return rv;
149 }
150 rv=_retrieveLdflags(GWB_Context_GetVars(currentContext), sId, sName);
151 if (rv<0) {
152 DBG_INFO(NULL, "here (%d)", rv);
153 return rv;
154 }
155
156 n=GWEN_XMLNode_FindFirstTag(xmlNode, "variables", NULL, NULL);
157 if (n) {
158 rv=_retrieveVariables(currentContext, GWB_Context_GetVars(currentContext), sId, sName, n);
159 if (rv<0) {
160 DBG_INFO(NULL, "here (%d)", rv);
161 return rv;
162 }
163 }
164 }
165 else if (rv==GWEN_ERROR_NOT_FOUND) {
166 if (required) {
167 DBG_ERROR(NULL, "Dependency \"%s\" not found but required", sName);
168 return rv;
169 }
170 }
171 else {
172 DBG_INFO(NULL, "here (%d)", rv);
173 return rv;
174 }
175
176 return 0;
177}
178
179
180
181int _retrieveVariables(GWB_CONTEXT *currentContext, GWEN_DB_NODE *db, const char *sId, const char *sName, GWEN_XMLNODE *xmlNode)
182{
183 GWEN_STRINGLIST *slVariables;
184
185 slVariables=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode, 1);
186 if (slVariables) {
188
189 se=GWEN_StringList_FirstEntry(slVariables);
190 while(se) {
191 const char *s;
192
194 if (s && *s) {
195 int rv;
196
197 rv=_retrieveVariable(db, sId, sName, s);
198 if (rv<0) {
199 DBG_ERROR(NULL, "Error retrieving variable \"%s\" for dependency \"%s\"", s, sId);
200 GWEN_StringList_free(slVariables);
201 return rv;
202 }
203 }
205 }
206 }
207
208 return 0;
209}
210
211
212
214 const char *sId,
215 const char *sName,
216 const char *sMinVersion,
217 const char *sMaxVersion)
218{
219 GWEN_BUFFER *argBuffer;
220 GWEN_BUFFER *stdOutBuffer;
221 GWEN_BUFFER *stdErrBuffer;
222 int rv;
223
224 stdOutBuffer=GWEN_Buffer_new(0, 256, 0, 1);
225 stdErrBuffer=GWEN_Buffer_new(0, 256, 0, 1);
226 argBuffer=GWEN_Buffer_new(0, 256, 0, 1);
227
228 if (sMinVersion) {
229 GWEN_Buffer_AppendString(argBuffer, " --atleast-version=");
230 GWEN_Buffer_AppendString(argBuffer, sMinVersion);
231 GWEN_Buffer_AppendString(argBuffer, " ");
232 }
233 if (sMaxVersion) {
234 GWEN_Buffer_AppendString(argBuffer, " --max-version=");
235 GWEN_Buffer_AppendString(argBuffer, sMaxVersion);
236 GWEN_Buffer_AppendString(argBuffer, " ");
237 }
238 GWEN_Buffer_AppendString(argBuffer, sName);
239
240 DBG_DEBUG(NULL, "Running command with args: [%s]", GWEN_Buffer_GetStart(argBuffer));
242 stdOutBuffer, stdErrBuffer);
243 if (rv<0) {
244 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
245 GWEN_Buffer_free(argBuffer);
246 GWEN_Buffer_free(stdErrBuffer);
247 GWEN_Buffer_free(stdOutBuffer);
248 return rv;
249 }
250 GWEN_Buffer_free(argBuffer);
251 GWEN_Buffer_free(stdErrBuffer);
252 GWEN_Buffer_free(stdOutBuffer);
253
254 GWB_Parser_SetItemValue(db, sId, "_EXISTS", (rv==0)?"TRUE":"FALSE");
255 fprintf(stdout, " dep %s: %s\n", sId, (rv==0)?"found":"not found");
256
257 return (rv==0)?0:GWEN_ERROR_NOT_FOUND;
258}
259
260
261
262int _retrieveCflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
263{
264 int rv;
265
266 rv=_callPkgConfig(db, sId, sName, "_CFLAGS", "--cflags");
267 if (rv<0) {
268 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
269 return rv;
270 }
271
272 return 0;
273}
274
275
276
277int _retrieveLdflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
278{
279 int rv;
280
281 rv=_callPkgConfig(db, sId, sName, "_LIBS", "--libs");
282 if (rv<0) {
283 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
284 return rv;
285 }
286
287 return 0;
288}
289
290
291
292int _retrieveVariable(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *variableName)
293{
294 int rv;
295 GWEN_BUFFER *varArgBuffer;
296 GWEN_BUFFER *varSuffixBuffer;
297 const char *s;
298
299 varArgBuffer=GWEN_Buffer_new(0, 256, 0, 1);
300 GWEN_Buffer_AppendString(varArgBuffer, "--variable=");
301 GWEN_Buffer_AppendString(varArgBuffer, variableName);
302
303 varSuffixBuffer=GWEN_Buffer_new(0, 256, 0, 1);
304 GWEN_Buffer_AppendString(varSuffixBuffer, "_");
305 s=variableName;
306 while(*s)
307 GWEN_Buffer_AppendByte(varSuffixBuffer, toupper(*(s++)));
308
309 rv=_callPkgConfig(db, sId, sName, GWEN_Buffer_GetStart(varSuffixBuffer), GWEN_Buffer_GetStart(varArgBuffer));
310 GWEN_Buffer_free(varSuffixBuffer);
311 GWEN_Buffer_free(varArgBuffer);
312 if (rv<0) {
313 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
314 return rv;
315 }
316
317 return 0;
318}
319
320
321
323 const char *sId,
324 const char *sName,
325 const char *suffix,
326 const char *args)
327{
328 GWEN_BUFFER *argBuffer;
329 GWEN_BUFFER *stdOutBuffer;
330 GWEN_BUFFER *stdErrBuffer;
331 int rv;
332
333 stdOutBuffer=GWEN_Buffer_new(0, 256, 0, 1);
334 stdErrBuffer=GWEN_Buffer_new(0, 256, 0, 1);
335 argBuffer=GWEN_Buffer_new(0, 256, 0, 1);
336
337 GWEN_Buffer_AppendString(argBuffer, args);
338 GWEN_Buffer_AppendString(argBuffer, " ");
339 GWEN_Buffer_AppendString(argBuffer, sName);
340
341 DBG_DEBUG(NULL, "Running command with args: [%s]", GWEN_Buffer_GetStart(argBuffer));
342 rv=GWEN_Process_RunCommandWaitAndGather("pkg-config", GWEN_Buffer_GetStart(argBuffer), stdOutBuffer, stdErrBuffer);
343 if (rv<0) {
344 DBG_ERROR(NULL, "Error running pkg-config (%d)", rv);
345 GWEN_Buffer_free(argBuffer);
346 GWEN_Buffer_free(stdErrBuffer);
347 GWEN_Buffer_free(stdOutBuffer);
348 return rv;
349 }
350 GWEN_Buffer_free(argBuffer);
351
353 GWEN_Text_CondenseBuffer(stdOutBuffer);
354 GWB_Parser_SetItemValue(db, sId, suffix, GWEN_Buffer_GetStart(stdOutBuffer));
355
356 GWEN_Buffer_free(stdErrBuffer);
357 GWEN_Buffer_free(stdOutBuffer);
358 return 0;
359}
360
361
362
364{
365 while(ptr && *ptr) {
366 if (*ptr<32)
367 *ptr=32;
368 ptr++;
369 }
370}
371
372
373
#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:992
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
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_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
#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
static int _parseChildNodes(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
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)
static void _replaceControlCharsWithBlanks(char *ptr)
static int _retrieveLdflags(GWEN_DB_NODE *db, const char *sId, const char *sName)
static 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)
static int _parseDep(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
static int _retrieveVariable(GWEN_DB_NODE *db, const char *sId, const char *sName, const char *variableName)
GWEN_STRINGLIST * GWB_Parser_ReadXmlDataIntoStringList(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode, int ignoreDupes)
Definition parser.c:283
int GWB_Parser_ParseSubdirs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition parser.c:367
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