gwenhywfar  5.7.2
parser.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/syncio.h>
20 #include <gwenhywfar/process.h>
21 #include <gwenhywfar/directory.h>
22 #include <gwenhywfar/text.h>
23 
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <ctype.h>
29 
30 #include <sys/types.h> /* for stat, chmod */
31 #include <sys/stat.h>
32 #include <unistd.h>
33 
34 
35 
36 
37 static int _parseSubdir(GWB_PROJECT *project, GWB_CONTEXT *currentContext, const char *sFolder, GWB_PARSER_PARSE_ELEMENT_FN fn);
38 static int _parseSetVar(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
39 static int _parseIfVarMatches(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn);
40 static int _parseIfNotVarMatches(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn);
41 static int _parseIfVarHasValue(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn);
42 static int _parseIfNotVarHasValue(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn);
43 static int _varHasValue(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
44 
45 static int _parseWriteFile(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
46 static void _appendVarValue(GWEN_DB_NODE *db, const char *name, const char *newValue);
47 static int _readVersion(const char *s);
48 static int _readIntUntilPoint(const char **s);
49 
50 static int _getFilePermissions(const char *fname);
51 static int _setFilePermissions(const char *fname, int perms);
52 
53 
54 
55 
57  GWB_CONTEXT *currentContext,
58  const char *srcDir,
59  GWB_KEYVALUEPAIR_LIST *givenOptionList)
60 {
61  GWEN_XMLNODE *xmlNewFile;
62  GWEN_XMLNODE *xmlProject;
63  GWB_PROJECT *project;
64  GWB_FILE *file;
65  int rv;
66 
67  GWB_Context_SetInitialSourceDir(currentContext, srcDir);
68  GWB_Context_SetTopSourceDir(currentContext, srcDir);
69  GWB_Context_SetCurrentSourceDir(currentContext, srcDir);
70 
71  xmlNewFile=GWB_Parser_ReadBuildFile(gwbuild, currentContext, GWB_PARSER_FILENAME);
72  if (xmlNewFile==NULL) {
73  DBG_ERROR(NULL, "No valid node found in build file of folder \"%s\"", srcDir);
74  return NULL;
75  }
76 
77  xmlProject=GWEN_XMLNode_FindFirstTag(xmlNewFile, "project", NULL, NULL);
78  if (xmlProject==NULL) {
79  DBG_ERROR(NULL, "No project node found in build file of folder \"%s\"", srcDir);
80  GWEN_XMLNode_free(xmlNewFile);
81  return NULL;
82  }
83 
84  project=GWB_Project_new(gwbuild, currentContext);
86  GWB_Context_GetCurrentRelativeDir(currentContext),
89 
90  if (givenOptionList)
91  GWB_Project_SetGivenOptionList(project, givenOptionList);
92 
93  rv=GWB_ParseProject(project, currentContext, xmlProject);
94  if (rv<0) {
95  DBG_ERROR(NULL, "Error parsing build tree in folder \"%s\"", srcDir);
96  GWB_Project_free(project);
97  GWEN_XMLNode_free(xmlNewFile);
98  return NULL;
99  }
100 
101  GWEN_XMLNode_free(xmlNewFile);
102  return project;
103 }
104 
105 
106 
107 GWB_CONTEXT *GWB_Parser_CopyContextForSubdir(const GWB_CONTEXT *sourceContext, const char *folder)
108 {
109  GWB_CONTEXT *newContext;
110  GWEN_DB_NODE *db;
111 
112  newContext=GWB_Context_dup(sourceContext);
113 
114  GWB_Context_AddCurrentRelativeDir(newContext, folder);
115 
116  GWB_Context_InsertTopBuildDir(newContext, "..");
117  GWB_Context_InsertTopSourceDir(newContext, "..");
118 
119  GWB_Context_AddCurrentBuildDir(newContext, folder);
120 
121  GWB_Context_InsertCurrentSourceDir(newContext, "..");
122  GWB_Context_AddCurrentSourceDir(newContext, folder);
123 
125  GWB_Context_ClearIncludeList(newContext);
126  GWB_Context_ClearDefineList(newContext);
127 
128  db=GWB_Context_GetVars(newContext);
131  //GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "builddir", GWB_Context_GetCurrentBuildDir(newContext));
134 
135  GWEN_DB_DeleteGroup(db, "local");
136 
137  return newContext;
138 }
139 
140 
141 
143 {
144  GWB_CONTEXT *newContext;
145 
146  newContext=GWB_Context_dup(sourceContext);
147 
149  GWB_Context_ClearIncludeList(newContext);
150  GWB_Context_ClearDefineList(newContext);
151 
152  return newContext;
153 }
154 
155 
156 
157 GWEN_XMLNODE *GWB_Parser_ReadBuildFile(GWENBUILD *gwbuild, const GWB_CONTEXT *currentContext, const char *fileName)
158 {
159  GWEN_BUFFER *fileNameBuf;
160  const char *s;
161  int rv;
162  GWEN_XMLNODE *xmlDocNode;
163  GWEN_XMLNODE *xmlGwbuildNode;
164 
165  fileNameBuf=GWEN_Buffer_new(0, 256, 0, 1);
166  s=GWB_Context_GetCurrentSourceDir(currentContext);
167  if (s && *s) {
168  GWEN_Buffer_AppendString(fileNameBuf, s);
170  }
171  GWEN_Buffer_AppendString(fileNameBuf, fileName);
172 
173  xmlDocNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
174 
175  DBG_DEBUG(NULL, "Reading file %s", GWEN_Buffer_GetStart(fileNameBuf));
176  rv=GWEN_XML_ReadFile(xmlDocNode, GWEN_Buffer_GetStart(fileNameBuf), GWEN_XML_FLAGS_DEFAULT);
177  if (rv<0) {
178  DBG_ERROR(NULL, "Error in XML file \"%s\" (%d)", GWEN_Buffer_GetStart(fileNameBuf), rv);
179  GWEN_Buffer_free(fileNameBuf);
180  return NULL;
181  }
182 
183  xmlGwbuildNode=GWEN_XMLNode_FindFirstTag(xmlDocNode, "gwbuild", NULL, NULL);
184  if (xmlGwbuildNode==NULL) {
185  DBG_ERROR(NULL, "File \"%s\" does not contain an \"gwbuild\" element", GWEN_Buffer_GetStart(fileNameBuf));
186  GWEN_XMLNode_free(xmlDocNode);
187  GWEN_Buffer_free(fileNameBuf);
188  return NULL;
189  }
190  s=GWEN_XMLNode_GetProperty(xmlGwbuildNode, "requiredVersion", NULL);
191  if (s && *s) {
192  int vRequired;
193  int vCurrent;
194 
195  vCurrent=(int) ((GWENHYWFAR_VERSION_MAJOR<<16)+
198 
199  vRequired=_readVersion(s);
200  if (vRequired<0) {
201  DBG_ERROR(NULL, "Invalid required version \"%s\"", s);
202  GWEN_XMLNode_free(xmlDocNode);
203  GWEN_Buffer_free(fileNameBuf);
204  return NULL;
205  }
206  if (vCurrent<vRequired) {
207  DBG_ERROR(NULL, "Minimum GWENBUILD version required is %x", vRequired);
208  GWEN_XMLNode_free(xmlDocNode);
209  GWEN_Buffer_free(fileNameBuf);
210  return NULL;
211  }
212  }
213 
214  if (1) {
215  GWEN_BUFFER *buildFilenameBuffer;
216  const char *buildDir;
217  const char *initialSourceDir;
218 
219  initialSourceDir=GWB_Context_GetInitialSourceDir(currentContext);
220  buildDir=GWB_Context_GetCurrentBuildDir(currentContext);
221  buildFilenameBuffer=GWEN_Buffer_new(0, 256, 0, 1);
222  GWEN_Buffer_AppendString(buildFilenameBuffer, initialSourceDir);
223  if (buildDir) {
224  GWEN_Buffer_AppendString(buildFilenameBuffer, GWEN_DIR_SEPARATOR_S);
225  GWEN_Buffer_AppendString(buildFilenameBuffer, buildDir);
226  }
227  GWEN_Buffer_AppendString(buildFilenameBuffer, GWEN_DIR_SEPARATOR_S);
228  GWEN_Buffer_AppendString(buildFilenameBuffer, fileName);
229  GWBUILD_AddBuildFilename(gwbuild, GWEN_Buffer_GetStart(buildFilenameBuffer));
230  GWEN_Buffer_free(buildFilenameBuffer);
231  }
232 
233  GWEN_XMLNode_UnlinkChild(xmlDocNode, xmlGwbuildNode);
234  GWEN_XMLNode_free(xmlDocNode);
235  GWEN_Buffer_free(fileNameBuf);
236 
237  return xmlGwbuildNode;
238 }
239 
240 
241 
242 int _readVersion(const char *s)
243 {
244  const char *p;
245  unsigned int vmajor=0;
246  unsigned int vminor=0;
247  unsigned int vpatchlevel=0;
248  int rv;
249 
250  p=s;
251  while(*p && *p<33)
252  s++;
253  if (isdigit(*p)) {
254  rv=_readIntUntilPoint(&p);
255  if (rv<0) {
256  DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
257  return GWEN_ERROR_GENERIC;
258  }
259  vmajor=rv;
260  }
261  if (*p=='.') {
262  p++;
263  rv=_readIntUntilPoint(&p);
264  if (rv<0) {
265  DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
266  return GWEN_ERROR_GENERIC;
267  }
268  vminor=rv;
269  }
270  if (*p=='.') {
271  p++;
272  rv=_readIntUntilPoint(&p);
273  if (rv<0) {
274  DBG_ERROR(NULL, "Invalid version spec \"%s\"", s);
275  return GWEN_ERROR_GENERIC;
276  }
277  vpatchlevel=rv;
278  }
279 
280  return (int) ((vmajor<<16)+(vminor<<8)+(vpatchlevel));
281 }
282 
283 
284 
285 int _readIntUntilPoint(const char **s)
286 {
287  int i=0;
288  const char *p;
289 
290  p=*s;
291  while(*p && *p!='.') {
292  int c;
293 
294  c=(*p)-'0';
295  if (c<0 || c>9) {
296  DBG_ERROR(NULL, "Invalid version string \"%s\"", *s);
297  return GWEN_ERROR_GENERIC;
298  }
299  i=(i*10)+c;
300  p++;
301  }
302  *s=p;
303 
304  return i;
305 }
306 
307 
309 {
310  GWEN_BUFFER *buf;
311 
313  if (buf) {
314  GWEN_STRINGLIST *sl;
315 
317  if (sl==NULL) {
318  DBG_INFO(NULL, "Could not generate string list from data [%s]", GWEN_Buffer_GetStart(buf));
319  GWEN_Buffer_free(buf);
320  return NULL;
321  }
322  GWEN_Buffer_free(buf);
323 
324  return sl;
325  }
326 
327  return NULL;
328 }
329 
330 
331 
333 {
334  GWEN_XMLNODE *xmlData;
335 
336  xmlData=GWEN_XMLNode_GetFirstData(xmlNode);
337  if (xmlData) {
338  const char *s;
339 
340  s=GWEN_XMLNode_GetData(xmlData);
341  if (s && *s) {
342  int rv;
343  GWEN_BUFFER *buf;
344 
345  buf=GWEN_Buffer_new(0, 256, 0, 1);
346  if (db) {
347  rv=GWEN_DB_ReplaceVars(db, s, buf);
348  if(rv<0) {
349  DBG_INFO(NULL, "here (%d)", rv);
350  GWEN_Buffer_free(buf);
351  return NULL;
352  }
353  }
354  else
355  GWEN_Buffer_AppendString(buf, s);
356 
357  if (GWEN_Buffer_GetUsedBytes(buf)==0) {
358  GWEN_Buffer_free(buf);
359  return NULL;
360  }
361  return buf;
362  }
363  }
364 
365  return NULL;
366 }
367 
368 
369 
371 {
372 
373  GWEN_XMLNODE *n;
374 
375  n=GWEN_XMLNode_FindFirstTag(xmlNode, elem, NULL, NULL);
376  if (n) {
377  GWEN_BUFFER *buf;
378 
380  if (buf) {
381  if (GWEN_Buffer_GetUsedBytes(buf))
382  return buf;
383  GWEN_Buffer_free(buf);
384  }
385  }
386 
387  return NULL;
388 }
389 
390 
391 
393 {
394  GWEN_STRINGLIST *sl;
395 
396  sl=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
397  if (sl) {
399 
401  while(se) {
402  const char *sFolder;
403 
404  sFolder=GWEN_StringListEntry_Data(se);
405  if (sFolder && *sFolder) {
406  int rv;
407 
408  rv=GWEN_Directory_GetPath(sFolder, 0);
409  if (rv<0) {
410  DBG_ERROR(NULL, "Could not create folder \"%s\" in build tree", sFolder);
411  return rv;
412  }
413  if (chdir(sFolder)==-1) {
414  DBG_ERROR(NULL, "Could not enter folder \"%s\" in build tree (%s)",
415  sFolder, strerror(errno));
416  return GWEN_ERROR_GENERIC;
417  }
418  rv=_parseSubdir(project, currentContext, sFolder, fn);
419  chdir("..");
420  if (rv<0) {
421  DBG_INFO(NULL, "here (%d)", rv);
422  return rv;
423  }
424  }
426  }
428  }
429 
430  return 0;
431 }
432 
433 
434 
435 int _parseSubdir(GWB_PROJECT *project, GWB_CONTEXT *currentContext, const char *sFolder, GWB_PARSER_PARSE_ELEMENT_FN fn)
436 {
437 
438  GWB_CONTEXT *newContext;
439  GWEN_XMLNODE *xmlNewFile;
440  int rv;
441  GWB_FILE *file;
442 
443  newContext=GWB_Parser_CopyContextForSubdir(currentContext, sFolder);
444 
445  fprintf(stdout, "Entering folder \"%s\"\n", sFolder);
446  xmlNewFile=GWB_Parser_ReadBuildFile(GWB_Project_GetGwbuild(project), newContext, GWB_PARSER_FILENAME);
447  if (xmlNewFile==NULL) {
448  DBG_ERROR(NULL, "No valid node found in build file of subdir \"%s\"", sFolder);
449  GWB_Context_free(newContext);
450  return GWEN_ERROR_BAD_DATA;
451  }
452 
457 
458 
459  rv=fn(project, newContext, xmlNewFile);
460  if (rv<0) {
461  DBG_INFO(NULL, "here (%d)", rv);
462  GWEN_XMLNode_free(xmlNewFile);
463  GWB_Context_free(newContext);
464  return rv;
465  }
466  GWEN_XMLNode_free(xmlNewFile);
467 
468  GWB_Context_Tree2_AddChild(currentContext, newContext);
469  fprintf(stdout, "Leaving folder \"%s\"\n", sFolder);
470  return 0;
471 }
472 
473 
474 
475 int _parseSetVar(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
476 {
477  const char *sName;
478  const char *sMode;
479  GWEN_BUFFER *buf;
480  GWEN_DB_NODE *db;
481 
482  db=GWB_Context_GetVars(currentContext);
483 
484  sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
485  if (!(sName && *sName)) {
486  DBG_ERROR(NULL, "No name for <setVar>");
487  return GWEN_ERROR_GENERIC;
488  }
489 
490  if (GWEN_XMLNode_GetProperty(xmlNode, "value", NULL)) {
491  DBG_WARN(NULL,
492  "%s: Please dont use property \"value\", just store the value between <setVar> and </setVar>",
493  sName);
494  }
495 
496  sMode=GWEN_XMLNode_GetProperty(xmlNode, "mode", "replace");
497 
499  if (buf && GWEN_Buffer_GetUsedBytes(buf)) {
500  if (strcasecmp(sMode, "replace")==0)
502  else if (strcasecmp(sMode, "add")==0)
503  GWEN_DB_SetCharValue(db, 0, sName, GWEN_Buffer_GetStart(buf));
504  else if (strcasecmp(sMode, "append")==0)
505  _appendVarValue(db, sName, GWEN_Buffer_GetStart(buf));
506  GWEN_Buffer_free(buf);
507  }
508  else {
509  if (strcasecmp(sMode, "replace")==0) {
510  GWEN_DB_DeleteVar(db, sName);
511  }
512  }
513 
514  return 0;
515 }
516 
517 
518 
520 {
521  const char *sName;
522  const char *sPattern;
523  const char *sValueInDb;
524  GWEN_DB_NODE *db;
525  GWEN_XMLNODE *xmlThen;
526  GWEN_XMLNODE *xmlElse;
527  int rv;
528 
529  xmlThen=GWEN_XMLNode_FindFirstTag(xmlNode, "then", NULL, NULL);
530  xmlElse=GWEN_XMLNode_FindFirstTag(xmlNode, "else", NULL, NULL);
531 
532  db=GWB_Context_GetVars(currentContext);
533 
534  sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
535  if (!(sName && *sName)) {
536  DBG_ERROR(NULL, "No name for <ifVarMatches>");
537  return GWEN_ERROR_GENERIC;
538  }
539 
540  sPattern=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
541  if (!(sPattern && *sPattern)) {
542  DBG_ERROR(NULL, "No value for <ifVarMatches>");
543  return GWEN_ERROR_GENERIC;
544  }
545 
546  sValueInDb=GWEN_DB_GetCharValue(db, sName, 0, NULL);
547  if (!(sValueInDb && *sValueInDb)) {
548  DBG_ERROR(NULL, "No value for \"%s\" in db for <ifVarMatches>", sName);
549  return GWEN_ERROR_GENERIC;
550  }
551 
552  if (-1!=GWEN_Text_ComparePattern(sValueInDb, sPattern, 0)) {
553  rv=fn(project, currentContext, xmlThen?xmlThen:xmlNode);
554  if (rv<0) {
555  DBG_INFO(NULL, "here (%d)", rv);
556  return rv;
557  }
558  }
559  else {
560  if (xmlElse) {
561  rv=fn(project, currentContext, xmlElse);
562  if (rv<0) {
563  DBG_INFO(NULL, "here (%d)", rv);
564  return rv;
565  }
566  }
567  }
568 
569  return 0;
570 }
571 
572 
573 
575 {
576  const char *sName;
577  const char *sPattern;
578  const char *sValueInDb;
579  GWEN_DB_NODE *db;
580  GWEN_XMLNODE *xmlThen;
581  GWEN_XMLNODE *xmlElse;
582  int rv;
583 
584  xmlThen=GWEN_XMLNode_FindFirstTag(xmlNode, "then", NULL, NULL);
585  xmlElse=GWEN_XMLNode_FindFirstTag(xmlNode, "else", NULL, NULL);
586 
587  db=GWB_Context_GetVars(currentContext);
588 
589  sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
590  if (!(sName && *sName)) {
591  DBG_ERROR(NULL, "No name for <ifVarMatches>");
592  return GWEN_ERROR_GENERIC;
593  }
594 
595  sPattern=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
596  if (!(sPattern && *sPattern)) {
597  DBG_ERROR(NULL, "No value for <ifVarMatches>");
598  return GWEN_ERROR_GENERIC;
599  }
600 
601  sValueInDb=GWEN_DB_GetCharValue(db, sName, 0, NULL);
602  if (!(sValueInDb && *sValueInDb)) {
603  DBG_ERROR(NULL, "No value for \"%s\" in db for <ifVarMatches>", sName);
604  return GWEN_ERROR_GENERIC;
605  }
606 
607  if (-1==GWEN_Text_ComparePattern(sValueInDb, sPattern, 0)) {
608  rv=fn(project, currentContext, xmlThen?xmlThen:xmlNode);
609  if (rv<0) {
610  DBG_INFO(NULL, "here (%d)", rv);
611  return rv;
612  }
613  }
614  else {
615  if (xmlElse) {
616  rv=fn(project, currentContext, xmlElse);
617  if (rv<0) {
618  DBG_INFO(NULL, "here (%d)", rv);
619  return rv;
620  }
621  }
622  }
623 
624  return 0;
625 }
626 
627 
628 
630 {
631  int rv;
632  GWEN_XMLNODE *xmlThen;
633  GWEN_XMLNODE *xmlElse;
634 
635  xmlThen=GWEN_XMLNode_FindFirstTag(xmlNode, "then", NULL, NULL);
636  xmlElse=GWEN_XMLNode_FindFirstTag(xmlNode, "else", NULL, NULL);
637  rv=_varHasValue(currentContext, xmlNode);
638  if (rv<0)
639  return rv;
640  if (rv) {
641  return fn(project, currentContext, xmlThen?xmlThen:xmlNode);
642  }
643  else {
644  if (xmlElse)
645  return fn(project, currentContext, xmlElse);
646  }
647  return 0;
648 }
649 
650 
651 
653 {
654  int rv;
655  GWEN_XMLNODE *xmlThen;
656  GWEN_XMLNODE *xmlElse;
657 
658  xmlThen=GWEN_XMLNode_FindFirstTag(xmlNode, "then", NULL, NULL);
659  xmlElse=GWEN_XMLNode_FindFirstTag(xmlNode, "else", NULL, NULL);
660  rv=_varHasValue(currentContext, xmlNode);
661  if (rv<0)
662  return rv;
663  if (rv==0) {
664  return fn(project, currentContext, xmlThen?xmlThen:xmlNode);
665  }
666  else {
667  if (xmlElse)
668  return fn(project, currentContext, xmlElse);
669  }
670  return 0;
671 }
672 
673 
674 
675 int _varHasValue(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
676 {
677  const char *sName;
678  const char *sPattern;
679  GWEN_DB_NODE *db;
680  int i;
681 
682  db=GWB_Context_GetVars(currentContext);
683 
684  sName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
685  if (!(sName && *sName)) {
686  DBG_ERROR(NULL, "No name for <ifVarMatches>");
687  return GWEN_ERROR_GENERIC;
688  }
689 
690  sPattern=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
691  if (!(sPattern && *sPattern)) {
692  DBG_ERROR(NULL, "No value for <ifVarMatches>");
693  return GWEN_ERROR_GENERIC;
694  }
695 
696  for (i=0; i<100; i++) {
697  const char *sValueInDb;
698 
699  sValueInDb=GWEN_DB_GetCharValue(db, sName, i, NULL);
700  if (!sValueInDb)
701  break;
702  if (-1!=GWEN_Text_ComparePattern(sValueInDb, sPattern, 0))
703  return 1;
704  }
705 
706  return 0;
707 }
708 
709 
710 
711 int _parseWriteFile(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
712 {
713  const char *fileName;
714  const char *currentSrcDir;
715  GWEN_BUFFER *fileNameBuffer;
716  GWEN_BUFFER *fileBufferIn;
717  GWEN_BUFFER *fileBufferOut;
718  GWB_FILE *file;
719  int sourceFilePerms;
720  int rv;
721 
722  fileName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
723  if (!(fileName && *fileName)) {
724  DBG_ERROR(NULL, "No name for <writeFile>");
725  return GWEN_ERROR_GENERIC;
726  }
727 
728  currentSrcDir=GWB_Context_GetCurrentSourceDir(currentContext);
729 
730  fileNameBuffer=GWEN_Buffer_new(0, 256, 0, 1);
731  if (currentSrcDir && *currentSrcDir) {
732  GWEN_Buffer_AppendString(fileNameBuffer, currentSrcDir);
734  }
735  GWEN_Buffer_AppendString(fileNameBuffer, fileName);
736  GWEN_Buffer_AppendString(fileNameBuffer, ".in");
737 
738  rv=_getFilePermissions(GWEN_Buffer_GetStart(fileNameBuffer));
739  if (rv<0) {
740  DBG_ERROR(NULL, "Could not read permissions for \"%s\" (%d)", GWEN_Buffer_GetStart(fileNameBuffer), rv);
741  GWEN_Buffer_free(fileNameBuffer);
742  return rv;
743  }
744  sourceFilePerms=rv;
745 
746  fileBufferIn=GWEN_Buffer_new(0, 256, 0, 1);
747 
748  rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(fileNameBuffer), fileBufferIn);
749  if (rv<0) {
750  DBG_ERROR(NULL, "Could not read \"%s\" (%d)", GWEN_Buffer_GetStart(fileNameBuffer), rv);
751  GWEN_Buffer_free(fileBufferIn);
752  GWEN_Buffer_free(fileNameBuffer);
753  return rv;
754  }
755 
756  fileBufferOut=GWEN_Buffer_new(0, 256, 0, 1);
758  fileBufferOut,
759  GWB_Context_GetVars(currentContext));
760  if (rv<0) {
761  DBG_ERROR(NULL, "Error translating content of file \"%s\" (%d)", GWEN_Buffer_GetStart(fileNameBuffer), rv);
762  GWEN_Buffer_free(fileBufferOut);
763  GWEN_Buffer_free(fileBufferIn);
764  GWEN_Buffer_free(fileNameBuffer);
765  return rv;
766  }
767 
768  unlink(fileName);
769  rv=GWEN_SyncIo_Helper_WriteFile(fileName,
770  (const uint8_t*)GWEN_Buffer_GetStart(fileBufferOut),
771  GWEN_Buffer_GetUsedBytes(fileBufferOut));
772  if (rv<0) {
773  DBG_ERROR(NULL, "Could not write \"%s\" (%d)", fileName, rv);
774  GWEN_Buffer_free(fileBufferOut);
775  GWEN_Buffer_free(fileBufferIn);
776  GWEN_Buffer_free(fileNameBuffer);
777  return rv;
778  }
779 
780  rv=_setFilePermissions(fileName, sourceFilePerms);
781  if (rv<0) {
782  DBG_ERROR(NULL, "Could not set perms for \"%s\" (%d)", fileName, rv);
783  GWEN_Buffer_free(fileBufferOut);
784  GWEN_Buffer_free(fileBufferIn);
785  GWEN_Buffer_free(fileNameBuffer);
786  return rv;
787  }
788 
789  /* add output file */
791  GWB_Context_GetCurrentRelativeDir(currentContext),
792  fileName);
794 
795  /* add input file */
796  GWEN_Buffer_Reset(fileNameBuffer);
797  GWEN_Buffer_AppendString(fileNameBuffer, fileName);
798  GWEN_Buffer_AppendString(fileNameBuffer, ".in");
800  GWB_Context_GetCurrentRelativeDir(currentContext),
801  GWEN_Buffer_GetStart(fileNameBuffer));
803 
804  GWEN_Buffer_free(fileBufferOut);
805  GWEN_Buffer_free(fileBufferIn);
806  GWEN_Buffer_free(fileNameBuffer);
807 
808  return 0;
809 }
810 
811 
812 
813 int _getFilePermissions(const char *fname)
814 {
815  struct stat st;
816 
817  if (lstat(fname, &st) == -1) {
818  DBG_ERROR(NULL, "Error on stat(\"%s\"): %d (%s)", fname, errno, strerror(errno));
819  return GWEN_ERROR_IO;
820  }
821 
822  return (int)((st.st_mode & ~S_IFMT));
823 }
824 
825 
826 
827 int _setFilePermissions(const char *fname, int perms)
828 {
829  if (chmod(fname, perms) == -1) {
830  DBG_ERROR(NULL, "Error on chmod(\"%s\"): %d (%s)", fname, errno, strerror(errno));
831  return GWEN_ERROR_IO;
832  }
833 
834  return 0;
835 }
836 
837 
838 
839 void _appendVarValue(GWEN_DB_NODE *db, const char *name, const char *newValue)
840 {
841  const char *s;
842 
843  s=GWEN_DB_GetCharValue(db, name, 0, NULL);
844  if (s && *s) {
845  GWEN_BUFFER *buf;
846 
847  buf=GWEN_Buffer_new(0, 256, 0, 1);
848  GWEN_Buffer_AppendString(buf, s);
849  GWEN_Buffer_AppendString(buf, " ");
850  GWEN_Buffer_AppendString(buf, newValue);
852  GWEN_Buffer_free(buf);
853  }
854  else
856 }
857 
858 
859 
860 void GWB_Parser_SetItemValue(GWEN_DB_NODE *db, const char *sId, const char *suffix, const char *value)
861 {
862  GWEN_BUFFER *varNameBuffer;
863 
864  varNameBuffer=GWEN_Buffer_new(0, 64, 0, 1);
865  GWEN_Buffer_AppendString(varNameBuffer, sId);
866  GWEN_Buffer_AppendString(varNameBuffer, suffix);
869  GWEN_Buffer_GetStart(varNameBuffer),
870  value);
871  GWEN_Buffer_free(varNameBuffer);
872 }
873 
874 
875 
876 
878 {
879  const char *p;
880 
881 #if 0
882  DBG_ERROR(NULL, "Using vars:");
883  GWEN_DB_Dump(db, 2);
884 #endif
885 
886  p=s;
887  while (*p) {
888  if (*p=='@') {
889  p++;
890  if (*p=='@')
891  GWEN_Buffer_AppendByte(dbuf, '@');
892  else {
893  const char *pStart;
894 
895  pStart=p;
896  while (*p && *p!='@')
897  p++;
898  if (*p!='@') {
899  DBG_ERROR(GWEN_LOGDOMAIN, "Unterminated variable name in code");
900  return GWEN_ERROR_BAD_DATA;
901  }
902  else {
903  int len;
904  char *rawName;
905  const char *value;
906 
907  len=p-pStart;
908  if (len<1) {
909  DBG_ERROR(GWEN_LOGDOMAIN, "Empty variable name in code");
910  return GWEN_ERROR_BAD_DATA;
911  }
912  rawName=(char *) malloc(len+1);
913  assert(rawName);
914  memmove(rawName, pStart, len);
915  rawName[len]=0;
916 
917  /*DBG_ERROR(NULL, "Setting data from variable \"%s\"", rawName);*/
918  value=GWEN_DB_GetCharValue(db, rawName, 0, NULL);
919  if (value)
920  GWEN_Buffer_AppendString(dbuf, value);
921  else {
922  DBG_WARN(NULL, "Warning: Empty value for DB var \"%s\"", rawName);
923  }
924  free(rawName);
925  }
926  }
927  p++;
928  }
929  else {
930  GWEN_Buffer_AppendByte(dbuf, *p);
931  p++;
932  }
933  }
934 
935  return 0;
936 }
937 
938 
939 
941 {
942  const char *name;
943 
944  name=GWEN_XMLNode_GetData(n);
945  if (name && *name) {
946  int rv;
947 
948  DBG_DEBUG(NULL, "Handling element \"%s\"", name);
949 
950  if (strcasecmp(name, "writeFile")==0)
951  rv=_parseWriteFile(project, currentContext, n);
952  else if (strcasecmp(name, "setVar")==0)
953  rv=_parseSetVar(currentContext, n);
954  else if (strcasecmp(name, "ifVarMatches")==0)
955  rv=_parseIfVarMatches(project, currentContext, n, fn);
956  else if (strcasecmp(name, "ifNotVarMatches")==0)
957  rv=_parseIfNotVarMatches(project, currentContext, n, fn);
958  else if (strcasecmp(name, "ifVarHasValue")==0)
959  rv=_parseIfVarHasValue(project, currentContext, n, fn);
960  else if (strcasecmp(name, "ifNotVarHasValue")==0)
961  rv=_parseIfNotVarHasValue(project, currentContext, n, fn);
962  else {
963  DBG_DEBUG(NULL, "Element not handled here, ignoring");
964  rv=1;
965  }
966  if (rv<0) {
967  DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
968  return rv;
969  }
970  }
971 
972  return 0;
973 }
974 
975 
976 
978  GWB_CONTEXT *currentContext,
979  GWEN_XMLNODE *xmlNode,
980  int alwaysDist,
981  int isSource)
982 {
983  uint32_t flags=0;
984  int rv;
985  const char *s;
986  const char *installPath;
987  const char *fileType;
988  const char *currentFolder;
989  const char *builder;
990  GWEN_STRINGLIST *fileNameList;
991 
992  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
993  if (rv<0) {
994  DBG_INFO(NULL, "here (%d)", rv);
995  return rv;
996  }
997 
998  currentFolder=GWB_Context_GetCurrentRelativeDir(currentContext);
999 
1000  fileType=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL);
1001  builder=GWEN_XMLNode_GetProperty(xmlNode, "builder", NULL);
1002 
1003  installPath=GWEN_XMLNode_GetProperty(xmlNode, "install", NULL);
1004  if (installPath && *installPath)
1005  flags|=GWB_FILE_FLAGS_INSTALL;
1006 
1007  s=GWEN_XMLNode_GetProperty(xmlNode, "generated", "FALSE");
1008  if (s && *s && (strcasecmp(s, "true")==0 || strcasecmp(s, "yes")==0))
1009  flags|=GWB_FILE_FLAGS_GENERATED;
1010 
1011  s=GWEN_XMLNode_GetProperty(xmlNode, "dist", alwaysDist?"TRUE":"FALSE");
1012  if (s && *s && (strcasecmp(s, "true")==0 || strcasecmp(s, "yes")==0))
1013  flags|=GWB_FILE_FLAGS_DIST;
1014 
1015  fileNameList=GWB_Parser_ReadXmlDataIntoStringList(GWB_Context_GetVars(currentContext), xmlNode);
1016  if (fileNameList) {
1018 
1019  se=GWEN_StringList_FirstEntry(fileNameList);
1020  while(se) {
1021  const char *sFileName;
1022 
1023  sFileName=GWEN_StringListEntry_Data(se);
1024  if (sFileName && *sFileName) {
1025  GWB_FILE *file;
1026 
1027  file=GWB_File_List2_GetOrCreateFile(GWB_Project_GetFileList(project), currentFolder, sFileName);
1028  GWB_File_AddFlags(file, flags);
1029  if (installPath)
1030  GWB_File_SetInstallPath(file, installPath);
1031  if (fileType)
1032  GWB_File_SetFileType(file, fileType);
1033  if (builder)
1034  GWB_File_SetBuilder(file, builder);
1035  if (isSource)
1036  GWB_Context_AddSourceFile(currentContext, file);
1037  }
1038 
1040  }
1041  GWEN_StringList_free(fileNameList);
1042  }
1043 
1044  return 0;
1045 }
1046 
1047 
int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
Definition: db.c:1951
void GWB_Context_AddCurrentBuildDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:203
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
#define GWENHYWFAR_VERSION_MAJOR
Definition: version.h:33
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition: db.c:1420
GWEN_STRINGLIST * GWB_Parser_ReadXmlDataIntoStringList(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:308
void GWB_Project_free(GWB_PROJECT *project)
Definition: project.c:51
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define GWEN_XML_FLAGS_DEFAULT
Definition: xml.h:117
#define GWEN_DIR_SEPARATOR_S
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
int(* GWB_PARSER_PARSE_ELEMENT_FN)(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: parser.h:41
#define GWB_PARSER_FILENAME
Definition: parser.h:21
void GWB_File_SetInstallPath(GWB_FILE *f, const char *s)
Definition: file.c:194
GWENBUILD * GWB_Project_GetGwbuild(const GWB_PROJECT *project)
Definition: project.c:70
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition: xml.c:724
struct GWB_FILE GWB_FILE
Definition: file.h:18
GWB_CONTEXT * GWB_Parser_CopyContextForTarget(const GWB_CONTEXT *sourceContext)
Definition: parser.c:142
GWEN_BUFFER * GWB_Parser_ReadNamedXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode, const char *elem)
Definition: parser.c:370
GWB_CONTEXT * GWB_Parser_CopyContextForSubdir(const GWB_CONTEXT *sourceContext, const char *folder)
Definition: parser.c:107
#define NULL
Definition: binreloc.c:300
void GWB_File_AddFlags(GWB_FILE *f, uint32_t i)
Definition: file.c:111
int GWEN_SyncIo_Helper_ReadFile(const char *fName, GWEN_BUFFER *dbuf)
Definition: syncio.c:524
GWB_PROJECT * GWB_Project_new(GWENBUILD *gwbuild, GWB_CONTEXT *ctx)
Definition: project.c:30
GWB_FILE * GWB_File_List2_GetOrCreateFile(GWB_FILE_LIST2 *fileList, const char *folder, const char *fname)
Definition: file.c:364
GWENHYWFAR_API int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:1297
void GWB_File_SetFileType(GWB_FILE *f, const char *s)
Definition: file.c:213
void GWB_Context_ClearSourceFileList2(GWB_CONTEXT *ctx)
Definition: context.c:450
static int _readVersion(const char *s)
Definition: parser.c:242
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:124
#define GWENHYWFAR_VERSION_PATCHLEVEL
Definition: version.h:35
static int _parseSubdir(GWB_PROJECT *project, GWB_CONTEXT *currentContext, const char *sFolder, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:435
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
#define GWB_FILE_FLAGS_DIST
Definition: file.h:21
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
#define GWEN_ERROR_IO
Definition: error.h:123
int GWB_Parser_ParseSubdirs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:392
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
static int _parseIfNotVarHasValue(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:652
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
#define GWB_FILE_FLAGS_INSTALL
Definition: file.h:22
static int _parseIfVarMatches(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:519
GWEN_BUFFER * GWB_Parser_ReadXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:332
int GWB_Parser_ParseWellKnownElements(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:940
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
GWB_FILE_LIST2 * GWB_Project_GetFileList(const GWB_PROJECT *project)
Definition: project.c:205
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:776
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
void GWB_Project_SetGivenOptionList(GWB_PROJECT *project, GWB_KEYVALUEPAIR_LIST *kvpList)
Definition: project.c:366
void GWB_File_SetBuilder(GWB_FILE *f, const char *s)
Definition: file.c:179
static int _readIntUntilPoint(const char **s)
Definition: parser.c:285
static int _getFilePermissions(const char *fname)
Definition: parser.c:813
const char * GWB_Context_GetInitialSourceDir(const GWB_CONTEXT *ctx)
Definition: context.c:285
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
const char * GWB_Context_GetTopSourceDir(const GWB_CONTEXT *ctx)
Definition: context.c:154
void GWB_Context_AddCurrentRelativeDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:262
int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, const char *path)
Definition: db.c:922
static int _parseIfVarHasValue(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:629
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
GWEN_STRINGLIST * GWEN_StringList_fromString(const char *str, const char *delimiters, int checkDouble)
Definition: stringlist.c:746
void GWB_Context_SetInitialSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:292
int GWB_ParseProject(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_project.c:43
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:899
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
void GWEN_XMLNode_UnlinkChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:570
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWB_PROJECT * GWB_Parser_ReadBuildTree(GWENBUILD *gwbuild, GWB_CONTEXT *currentContext, const char *srcDir, GWB_KEYVALUEPAIR_LIST *givenOptionList)
Definition: parser.c:56
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
static int _setFilePermissions(const char *fname, int perms)
Definition: parser.c:827
void GWB_Context_InsertCurrentSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:232
void GWB_Context_SetCurrentSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:243
static int _parseSetVar(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: parser.c:475
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
GWEN_XMLNODE * GWB_Parser_ReadBuildFile(GWENBUILD *gwbuild, const GWB_CONTEXT *currentContext, const char *fileName)
Definition: parser.c:157
void GWB_Context_AddCurrentSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:221
static int _parseWriteFile(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: parser.c:711
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
Definition: text.c:1208
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWB_CONTEXT * GWB_Context_dup(const GWB_CONTEXT *originalCtx)
Definition: context.c:49
void GWB_Context_InsertTopBuildDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:143
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
static int _varHasValue(GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: parser.c:675
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
#define GWENHYWFAR_VERSION_MINOR
Definition: version.h:34
void GWB_Context_InsertTopSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:173
GWENHYWFAR_API int GWEN_Directory_GetPath(const char *path, unsigned int flags)
const char * GWB_Context_GetTopBuildDir(const GWB_CONTEXT *ctx)
Definition: context.c:124
void GWB_Parser_SetItemValue(GWEN_DB_NODE *db, const char *sId, const char *suffix, const char *value)
Definition: parser.c:860
int GWB_Parser_ReplaceVarsBetweenAtSigns(const char *s, GWEN_BUFFER *dbuf, GWEN_DB_NODE *db)
Definition: parser.c:877
static void _appendVarValue(GWEN_DB_NODE *db, const char *name, const char *newValue)
Definition: parser.c:839
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition: xml.c:634
const char * GWB_Context_GetCurrentRelativeDir(const GWB_CONTEXT *ctx)
Definition: context.c:255
struct GWENBUILD GWENBUILD
Definition: gwenbuild.h:15
void GWB_Context_ClearDefineList(GWB_CONTEXT *ctx)
Definition: context.c:417
void GWB_Context_free(GWB_CONTEXT *ctx)
Definition: context.c:93
void GWB_Context_AddSourceFile(GWB_CONTEXT *ctx, GWB_FILE *f)
Definition: context.c:441
void GWBUILD_AddBuildFilename(GWENBUILD *gwenbuild, const char *s)
Definition: gwenbuild.c:147
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
int GWEN_SyncIo_Helper_WriteFile(const char *fName, const uint8_t *ptrSource, uint64_t lenSource)
Definition: syncio.c:586
#define GWB_FILE_FLAGS_GENERATED
Definition: file.h:23
void GWB_Context_ClearIncludeList(GWB_CONTEXT *ctx)
Definition: context.c:382
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
const char * GWB_Context_GetCurrentSourceDir(const GWB_CONTEXT *ctx)
Definition: context.c:214
int GWB_Parser_ParseSourcesOrHeaders(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, int alwaysDist, int isSource)
Definition: parser.c:977
const char * GWB_Context_GetCurrentBuildDir(const GWB_CONTEXT *ctx)
Definition: context.c:184
static int _parseIfNotVarMatches(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:574
void GWB_Context_SetTopSourceDir(GWB_CONTEXT *ctx, const char *s)
Definition: context.c:161