gwenhywfar  5.7.2
p_project.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 
25 
27 
28 #include <gwenhywfar/debug.h>
29 
30 #include <unistd.h>
31 
32 
33 
34 static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
35 static int _writeConfigH(const GWB_PROJECT *project);
36 static int _parseDefine(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode);
37 
38 
39 
40 
41 
42 
43 int GWB_ParseProject(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
44 {
45  const char *s;
46  int rv;
47  GWEN_DB_NODE *db;
48  uint32_t flags=GWEN_DB_FLAGS_OVERWRITE_VARS;
49 
50  s=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
51  if (!(s && *s)) {
52  DBG_ERROR(NULL, "Project has no name");
53  return GWEN_ERROR_BAD_DATA;
54  }
55 
56  GWB_Project_SetProjectName(project, s);
57 
58  s=GWEN_XMLNode_GetProperty(xmlNode, "write_config_h", "TRUE");
59  if (s && strcasecmp(s, "TRUE")==0)
61 
62  GWB_Project_SetVersion(project,
63  GWEN_XMLNode_GetIntProperty(xmlNode, "vmajor", 0),
64  GWEN_XMLNode_GetIntProperty(xmlNode, "vminor", 0),
65  GWEN_XMLNode_GetIntProperty(xmlNode, "vpatchlevel", 0),
66  GWEN_XMLNode_GetIntProperty(xmlNode, "vbuild", 0),
67  GWEN_XMLNode_GetProperty(xmlNode, "vtag", NULL));
68 
70  GWEN_XMLNode_GetIntProperty(xmlNode, "so_current", 0),
71  GWEN_XMLNode_GetIntProperty(xmlNode, "so_age", 0),
72  GWEN_XMLNode_GetIntProperty(xmlNode, "so_revision", 0));
73 
74  db=GWB_Context_GetVars(currentContext);
75 
76  GWEN_DB_SetCharValue(db, flags, "project_name", GWB_Project_GetProjectName(project));
77  GWEN_DB_SetCharValueFromInt(db, flags, "project_vmajor", GWB_Project_GetVersionMajor(project));
78  GWEN_DB_SetCharValueFromInt(db, flags, "project_vminor", GWB_Project_GetVersionMinor(project));
79  GWEN_DB_SetCharValueFromInt(db, flags, "project_vpatchlevel", GWB_Project_GetVersionPatchlevel(project));
80  GWEN_DB_SetCharValueFromInt(db, flags, "project_vbuild", GWB_Project_GetVersionBuild(project));
81  s=GWB_Project_GetVersionTag(project);
82  GWEN_DB_SetCharValue(db, flags, "project_vtag", s);
83 
84 
85  GWEN_DB_SetCharValueFromInt(db, flags, "project_so_current", GWB_Project_GetSoVersionCurrent(project));
86  GWEN_DB_SetCharValueFromInt(db, flags, "project_so_age", GWB_Project_GetSoVersionAge(project));
87  GWEN_DB_SetCharValueFromInt(db, flags, "project_so_revision", GWB_Project_GetSoVersionRevision(project));
88  GWEN_DB_SetCharValueFromInt(db, flags, "project_so_effective",
90 
91 
92  rv=_parseChildNodes(project, currentContext, xmlNode);
93  if (rv<0) {
94  DBG_INFO(NULL, "here (%d)", rv);
95  return rv;
96  }
97 
99  int rv;
100 
101  rv=_writeConfigH(project);
102  if (rv<0) {
103  DBG_ERROR(GWEN_LOGDOMAIN, "Error writing config.h, aborting");
104  return rv;
105  }
106  }
107 
108  return 0;
109 }
110 
111 
112 
113 int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
114 {
115  GWEN_XMLNODE *n;
116 
117  n=GWEN_XMLNode_GetFirstTag(xmlNode);
118  while (n) {
119  const char *name;
120 
121  DBG_DEBUG(NULL, "- Reading child node");
122  name=GWEN_XMLNode_GetData(n);
123  if (name && *name) {
124  int rv;
125 
126  DBG_DEBUG(NULL, "Handling element \"%s\"", name);
127 
128  if (strcasecmp(name, "option")==0)
129  rv=GWB_ParseOption(project, currentContext, n);
130  else if (strcasecmp(name, "dependencies")==0)
131  rv=GWB_ParseDependencies(project, currentContext, n);
132  else if (strcasecmp(name, "checkheaders")==0)
133  rv=GWB_ParseCheckHeaders(project, currentContext, n);
134  else if (strcasecmp(name, "checkfunctions")==0)
135  rv=GWB_ParseCheckFunctions(project, currentContext, n);
136  else if (strcasecmp(name, "checklibs")==0)
137  rv=GWB_ParseCheckLibs(project, currentContext, n);
138  else if (strcasecmp(name, "checkprogs")==0)
139  rv=GWB_ParseCheckProgs(project, currentContext, n);
140  else if (strcasecmp(name, "checkCompiler")==0)
141  rv=GWB_ParseCheckCompiler(project, currentContext, n);
142  else if (strcasecmp(name, "target")==0)
143  rv=GWB_ParseTarget(project, currentContext, n);
144  else if (strcasecmp(name, "define")==0)
145  rv=_parseDefine(project, currentContext, n);
146  else if (strcasecmp(name, "buildFiles")==0)
147  rv=GWB_ParseBuildFiles(project, currentContext, n);
148  else if (strcasecmp(name, "extradist")==0)
149  rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n, 1, 0);
150  else if (strcasecmp(name, "data")==0)
151  rv=GWB_Parser_ParseSourcesOrHeaders(project, currentContext, n, 1, 0);
152  else if (strcasecmp(name, "subdirs")==0)
153  rv=GWB_Parser_ParseSubdirs(project, currentContext, n, _parseChildNodes);
154  else
155  rv=GWB_Parser_ParseWellKnownElements(project, currentContext, n, _parseChildNodes);
156  if (rv<0) {
157  DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
158  return rv;
159  }
160  }
161 
163  }
164 
165  return 0;
166 }
167 
168 
169 
170 int _writeConfigH(const GWB_PROJECT *project)
171 {
172  GWB_KEYVALUEPAIR_LIST *defineList;
173  GWEN_BUFFER *fileBuffer;
174  int rv;
175 
176  defineList=GWB_Project_GetDefineList(project);
177  fileBuffer=GWEN_Buffer_new(0, 256, 0, 1);
178 
179  GWEN_Buffer_AppendString(fileBuffer, "/* config.h generated by gwenbuild */\n\n");
180  if (defineList)
181  GWB_KeyValuePair_List_WriteAllPairsToBuffer(defineList, "#define ", " ", "\n", fileBuffer);
182  GWEN_Buffer_AppendString(fileBuffer, "\n");
183 
184  unlink("config.h");
185  rv=GWEN_SyncIo_Helper_WriteFile("config.h",
186  (const uint8_t*)GWEN_Buffer_GetStart(fileBuffer),
187  GWEN_Buffer_GetUsedBytes(fileBuffer));
188  if (rv<0) {
189  DBG_ERROR(NULL, "Could not write \"config.h\" (%d)", rv);
190  GWEN_Buffer_free(fileBuffer);
191  return rv;
192  }
193 
194  GWEN_Buffer_free(fileBuffer);
195 
196  return 0;
197 }
198 
199 
200 
201 int _parseDefine(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
202 {
203  int rv;
204  const char *varName;
205  const char *value;
206  const char *quoted;
207 
208  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
209  if (rv<0) {
210  DBG_INFO(NULL, "here (%d)", rv);
211  return rv;
212  }
213 
214  quoted=GWEN_XMLNode_GetProperty(xmlNode, "quoted", "FALSE");
215  varName=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
216  value=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
217  if (!(varName && *varName)) {
218  DBG_ERROR(NULL, "Missing variable name in DEFINE");
219  return GWEN_ERROR_GENERIC;
220  }
221  if (quoted && strcasecmp(quoted, "TRUE")==0) {
222  GWEN_BUFFER *dbuf;
223 
224  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
225  GWEN_Buffer_AppendString(dbuf, "\"");
226  if (value && *value)
227  GWEN_Buffer_AppendString(dbuf, value);
228  GWEN_Buffer_AppendString(dbuf, "\"");
229  GWB_Project_SetDefine(project, varName, GWEN_Buffer_GetStart(dbuf));
230  GWEN_Buffer_free(dbuf);
231  }
232  else {
233  GWB_Project_SetDefine(project, varName, value);
234  }
235 
236 
237  return 0;
238 }
239 
240 
241 
242 
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
int GWB_ParseCheckFunctions(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
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
const char * GWB_Project_GetVersionTag(const GWB_PROJECT *project)
Definition: project.c:136
GWB_KEYVALUEPAIR_LIST * GWB_Project_GetDefineList(const GWB_PROJECT *project)
Definition: project.c:291
#define NULL
Definition: binreloc.c:300
void GWB_Project_AddFlags(GWB_PROJECT *project, uint32_t fl)
Definition: project.c:187
static int _parseChildNodes(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_project.c:113
int GWB_ParseCheckHeaders(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
void GWB_Project_SetDefine(GWB_PROJECT *project, const char *name, const char *value)
Definition: project.c:298
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWB_Project_GetVersionBuild(const GWB_PROJECT *project)
Definition: project.c:129
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
int GWB_Parser_ParseSubdirs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:392
static int _parseDefine(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_project.c:201
void GWB_Project_SetVersion(GWB_PROJECT *project, int vMajor, int vMinor, int vPatchlevel, int vBuild, const char *vTag)
Definition: project.c:96
int GWB_Parser_ParseWellKnownElements(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *n, GWB_PARSER_PARSE_ELEMENT_FN fn)
Definition: parser.c:940
int GWB_Project_GetVersionPatchlevel(const GWB_PROJECT *project)
Definition: project.c:122
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
void GWB_Project_SetSoVersion(GWB_PROJECT *project, int vCurrent, int vAge, int vRevision)
Definition: project.c:143
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
const char * GWB_Project_GetProjectName(const GWB_PROJECT *project)
Definition: project.c:77
int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name, int defaultValue)
Definition: xml.c:263
int GWB_ParseOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_options.c:35
int GWB_Project_GetSoVersionRevision(const GWB_PROJECT *project)
Definition: project.c:166
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
int GWB_Project_GetVersionMajor(const GWB_PROJECT *project)
Definition: project.c:108
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:712
static int _writeConfigH(const GWB_PROJECT *project)
Definition: p_project.c:170
#define GWEN_ERROR_GENERIC
Definition: error.h:62
int GWB_ParseCheckLibs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_checklibs.c:32
int GWB_ParseProject(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_project.c:43
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 GWB_PROJECT_FLAGS_CONFIG_H
Definition: project.h:27
int GWB_ParseDependencies(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
#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 GWB_Project_GetVersionMinor(const GWB_PROJECT *project)
Definition: project.c:115
void GWB_Project_SetProjectName(GWB_PROJECT *project, const char *s)
Definition: project.c:84
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
uint32_t GWB_Project_GetFlags(const GWB_PROJECT *project)
Definition: project.c:173
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition: xml.c:634
int GWB_ParseCheckProgs(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_checkprogs.c:34
int GWB_KeyValuePair_List_WriteAllPairsToBuffer(const GWB_KEYVALUEPAIR_LIST *kvpList, const char *prefix, const char *assignmentString, const char *delim, GWEN_BUFFER *destBuf)
Definition: keyvaluepair.c:199
int GWB_Project_GetSoVersionCurrent(const GWB_PROJECT *project)
Definition: project.c:152
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
int GWB_ParseCheckCompiler(GWEN_UNUSED GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
int GWEN_SyncIo_Helper_WriteFile(const char *fName, const uint8_t *ptrSource, uint64_t lenSource)
Definition: syncio.c:586
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_Project_GetSoVersionAge(const GWB_PROJECT *project)
Definition: project.c:159
int GWB_Parser_ParseSourcesOrHeaders(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode, int alwaysDist, int isSource)
Definition: parser.c:977