gwenhywfar  5.14.1
p_options.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 #include "gwenbuild/types/option.h"
18 
19 #include <gwenhywfar/debug.h>
20 #include <gwenhywfar/text.h>
21 
22 #include <ctype.h>
23 
24 
25 
26 int _checkAgainstGivenOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWB_OPTION *option);
27 int _checkStringOption(GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue);
28 int _checkStringListOption(GWB_PROJECT *project, GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue);
29 
30 
31 
32 
33 
34 
35 int GWB_ParseOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
36 {
37  const char *sId;
38  int otype;
39  GWB_OPTION *option;
40  const char *s;
41  GWEN_XMLNODE *n;
42  int rv;
43 
44  rv=GWEN_XMLNode_ExpandProperties(xmlNode, GWB_Context_GetVars(currentContext));
45  if (rv<0) {
46  DBG_INFO(NULL, "here (%d)", rv);
47  return rv;
48  }
49 
50  sId=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL);
51  if (!(sId && *sId)) {
52  DBG_ERROR(NULL, "Option has no id");
53  GWEN_XMLNode_Dump(xmlNode, 2);
54  return GWEN_ERROR_GENERIC;
55  }
56 
57  otype=GWB_OptionType_fromString(GWEN_XMLNode_GetProperty(xmlNode, "type", "string"));
58  if (!(otype>GWB_OptionType_None)) {
59  DBG_ERROR(NULL, "Invalid option type (id=%s)", sId);
60  GWEN_XMLNode_Dump(xmlNode, 2);
61  return GWEN_ERROR_GENERIC;
62  }
63 
64  option=GWB_Option_new(sId);
65  GWB_Option_SetOptionType(option, otype);
66 
67  if (1) {
68  GWEN_BUFFER *buf;
69 
70  buf=GWB_Parser_ReadNamedXmlDataIntoBufferAndExpand(GWB_Context_GetVars(currentContext), xmlNode, "default");
71  if (buf) {
72  if (GWEN_Buffer_GetUsedBytes(buf))
74  GWEN_Buffer_free(buf);
75  }
76  }
77 
78  s=GWEN_XMLNode_GetProperty(xmlNode, "definePrefix", NULL);
79  if (s)
80  GWB_Option_SetDefinePrefix(option, s);
81 
82  s=GWEN_XMLNode_GetCharValue(xmlNode, "choices", NULL);
83  if (s) {
84  GWEN_STRINGLIST *sl;
85 
87  if (sl) {
90  }
91  }
92 
93  /* <alias> entries can be used for string values to define a name which contains multiple strings.
94  * An example from AqBanking:
95  *
96  * <option id="backends" type="stringlist" definePrefix="AQBANKING_WITH_PLUGIN_BACKEND_" >
97  * <choices>aqhbci aqofxconnect aqebics aqpaypal aqfints aqnone</choices>
98  * <alias name="all">aqhbci aqofxconnect aqebics aqpaypal aqnone</alias>
99  * <default>all</default>
100  * </option>
101  *
102  * Here "all" can be given as alias for "aqhbci aqofxconnect aqebics aqpaypal aqnone" so that the user can
103  * just specify "-O backends=all" to include all backends instead of having to specify every single one.
104  */
105  n=GWEN_XMLNode_FindFirstTag(xmlNode, "alias", NULL, NULL);
106  while(n) {
107  const char *sName;
108  GWEN_BUFFER *valueBuffer;
109 
110  sName=GWEN_XMLNode_GetProperty(n, "name", NULL);
111  valueBuffer=GWB_Parser_ReadXmlDataIntoBufferAndExpand(GWB_Context_GetVars(currentContext), n);
112  if (valueBuffer) {
113  GWB_Option_AddAlias(option, sName, GWEN_Buffer_GetStart(valueBuffer));
114  GWEN_Buffer_free(valueBuffer);
115  }
116  n=GWEN_XMLNode_FindNextTag(n, "alias", NULL, NULL);
117  }
118 
119  _checkAgainstGivenOption(project, currentContext, option);
120 
121  GWB_Project_AddOption(project, option);
122  return 0;
123 }
124 
125 
126 
127 int _checkAgainstGivenOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWB_OPTION *option)
128 {
129  const char *optionId;
130  GWB_KEYVALUEPAIR *kvp;
131  const char *givenValue=NULL;
132 
133  optionId=GWB_Option_GetId(option);
135  if (kvp)
136  givenValue=GWB_KeyValuePair_GetValue(kvp);
137  if (givenValue==NULL)
138  givenValue=GWB_Option_GetDefaultValue(option);
139  if (givenValue) {
140  int rv=GWEN_ERROR_GENERIC;
141 
142  switch(GWB_Option_GetOptionType(option)) {
144  case GWB_OptionType_None:
145  DBG_ERROR(NULL, "Bad option type in option %s", optionId);
147  break;
149  rv=_checkStringOption(option, currentContext, givenValue);
150  break;
152  rv=_checkStringListOption(project, option, currentContext, givenValue);
153  break;
154  }
155  if (rv<0)
156  return rv;
157  }
158 
159  if (kvp) {
160  GWB_KeyValuePair_List_Del(kvp);
162  }
163 
164  return 0;
165 }
166 
167 
168 
169 int _checkStringOption(GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
170 {
171  const char *optionId;
172 
173  optionId=GWB_Option_GetId(option);
174  fprintf(stdout, " option %s: ", optionId);
175  if (givenValue) {
176  const char *s;
177  GWEN_BUFFER *nameBuffer;
178 
179  s=GWB_Option_GetAlias(option, givenValue);
180  if (s==NULL)
181  s=givenValue;
182 
183  if (!GWB_Option_IsValidChoice(option, s)) {
184  DBG_ERROR(NULL,
185  "Value \"%s\" (given value \"%s\") is not a valid choice for option \"%s\"",
186  s, givenValue, optionId);
187  return GWEN_ERROR_INVALID;
188  }
189 
190  nameBuffer=GWEN_Buffer_new(0, 256, 0, 1);
191  GWEN_Buffer_AppendString(nameBuffer, "option_");
192  GWEN_Buffer_AppendString(nameBuffer, optionId);
195  GWEN_Buffer_GetStart(nameBuffer), s);
196  GWEN_Buffer_free(nameBuffer);
197  fprintf(stdout, "%s\n", s);
198  }
199 
200  return 0;
201 }
202 
203 
204 
205 int _checkStringListOption(GWB_PROJECT *project, GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
206 {
207  const char *optionId;
208  const char *definePrefix;
209 
210  optionId=GWB_Option_GetId(option);
211  definePrefix=GWB_Option_GetDefinePrefix(option);
212  fprintf(stdout, " option %s: ", optionId);
213  if (givenValue) {
214  const char *s;
215  GWEN_STRINGLIST *sl;
216 
217  s=GWB_Option_GetAlias(option, givenValue);
218  if (s==NULL)
219  s=givenValue;
220 
222  if (sl) {
224  GWEN_BUFFER *nameBuffer;
225 
226  nameBuffer=GWEN_Buffer_new(0, 256, 0, 1);
227  GWEN_Buffer_AppendString(nameBuffer, "option_");
228  GWEN_Buffer_AppendString(nameBuffer, optionId);
229 
231  while(se) {
232  const char *sCurrentGivenValue;
233 
234  sCurrentGivenValue=GWEN_StringListEntry_Data(se);
235  if (sCurrentGivenValue) {
236  if (!GWB_Option_IsValidChoice(option, sCurrentGivenValue)) {
237  DBG_ERROR(NULL,
238  "Value \"%s\" is not a valid choice for option \"%s\"",
239  sCurrentGivenValue, optionId);
240  GWEN_Buffer_free(nameBuffer);
242  return GWEN_ERROR_INVALID;
243  }
245  0,
246  GWEN_Buffer_GetStart(nameBuffer), sCurrentGivenValue);
247  fprintf(stdout, "%s ", sCurrentGivenValue);
248  if (definePrefix) {
249  GWEN_BUFFER *dbuf;
250 
251  dbuf=GWEN_Buffer_new(0, 64, 0, 1);
252  GWEN_Buffer_AppendString(dbuf, definePrefix);
253  s=sCurrentGivenValue;
254  while(*s)
255  GWEN_Buffer_AppendByte(dbuf, toupper(*(s++)));
256  GWB_Project_SetDefine(project, GWEN_Buffer_GetStart(dbuf), "1");
257  GWEN_Buffer_free(dbuf);
258  }
259  }
260 
262  } /* while */
263  GWEN_Buffer_free(nameBuffer);
265  } /* if sl */
266 
267  } /* if givenValue */
268  fprintf(stdout, "\n");
269  return 0;
270 }
271 
272 
273 
274 
275 
276 
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition: stringlist.c:818
#define DBG_ERROR(dbg_logger, format,...)
Definition: debug.h:97
void GWB_Option_AddAlias(GWB_OPTION *option, const char *name, const char *value)
Definition: option.c:106
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
int GWB_Option_GetOptionType(const GWB_OPTION *option)
Definition: option.c:70
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
int _checkAgainstGivenOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWB_OPTION *option)
Definition: p_options.c:127
#define GWEN_ERROR_INVALID
Definition: error.h:67
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
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:794
struct GWB_OPTION GWB_OPTION
Definition: option.h:17
GWEN_BUFFER * GWB_Parser_ReadNamedXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode, const char *elem)
Definition: parser.c:345
#define NULL
Definition: binreloc.c:300
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
void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
Definition: xml.c:472
int _checkStringListOption(GWB_PROJECT *project, GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
Definition: p_options.c:205
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
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
GWEN_BUFFER * GWB_Parser_ReadXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition: parser.c:307
int _checkStringOption(GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
Definition: p_options.c:169
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
GWEN_STRINGLIST * GWB_Option_GetChoiceList(const GWB_OPTION *option)
Definition: option.c:123
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_AddOption(GWB_PROJECT *project, GWB_OPTION *option)
Definition: project.c:348
int GWB_ParseOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition: p_options.c:35
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:812
GWB_OPTION * GWB_Option_new(const char *id)
Definition: option.c:30
void GWB_Option_SetDefaultValue(GWB_OPTION *option, const char *s)
Definition: option.c:91
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
int GWB_Option_IsValidChoice(const GWB_OPTION *option, const char *s)
Definition: option.c:137
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:393
const char * GWB_Option_GetDefinePrefix(const GWB_OPTION *option)
Definition: option.c:156
void GWEN_StringList_AppendStringList(GWEN_STRINGLIST *slDest, const GWEN_STRINGLIST *slSource, int checkDouble)
Definition: stringlist.c:915
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
void GWB_Option_SetOptionType(GWB_OPTION *option, int i)
Definition: option.c:77
void GWB_KeyValuePair_free(GWB_KEYVALUEPAIR *kvp)
Definition: keyvaluepair.c:68
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
const char * GWB_Option_GetDefaultValue(const GWB_OPTION *option)
Definition: option.c:84
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
struct GWB_KEYVALUEPAIR GWB_KEYVALUEPAIR
Definition: keyvaluepair.h:19
void GWB_Option_SetDefinePrefix(GWB_OPTION *option, const char *s)
Definition: option.c:163
#define GWEN_TEXT_FLAGS_DEL_QUOTES
Definition: text.h:49
GWB_KEYVALUEPAIR_LIST * GWB_Project_GetGivenOptionList(const GWB_PROJECT *project)
Definition: project.c:374
GWB_KEYVALUEPAIR * GWB_KeyValuePair_List_GetFirstByKey(const GWB_KEYVALUEPAIR_LIST *kvpList, const char *key)
Definition: keyvaluepair.c:144
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition: xml.c:634
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
Definition: text.h:50
const char * GWB_KeyValuePair_GetValue(const GWB_KEYVALUEPAIR *kvp)
Definition: keyvaluepair.c:97
const char * GWB_Option_GetAlias(const GWB_OPTION *option, const char *name)
Definition: option.c:116
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
int GWB_OptionType_fromString(const char *s)
Definition: option.c:205
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:992
const char * GWB_Option_GetId(const GWB_OPTION *option)
Definition: option.c:63