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
18
19#include <gwenhywfar/debug.h>
20#include <gwenhywfar/text.h>
21
22#include <ctype.h>
23
24
25
26int _checkAgainstGivenOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWB_OPTION *option);
27int _checkStringOption(GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue);
28int _checkStringListOption(GWB_PROJECT *project, GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue);
29
30
31
32
33
34
35int 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) {
75 }
76 }
77
78 s=GWEN_XMLNode_GetProperty(xmlNode, "definePrefix", NULL);
79 if (s)
81
82 s=GWEN_XMLNode_GetCharValue(xmlNode, "choices", NULL);
83 if (s) {
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);
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
127int _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)) {
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
169int _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)) {
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
205int _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)) {
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
#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
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
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
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition db.h:121
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_GENERIC
Definition error.h:62
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
const char * GWB_KeyValuePair_GetValue(const GWB_KEYVALUEPAIR *kvp)
void GWB_KeyValuePair_free(GWB_KEYVALUEPAIR *kvp)
GWB_KEYVALUEPAIR * GWB_KeyValuePair_List_GetFirstByKey(const GWB_KEYVALUEPAIR_LIST *kvpList, const char *key)
struct GWB_KEYVALUEPAIR GWB_KEYVALUEPAIR
GWB_OPTION * GWB_Option_new(const char *id)
Definition option.c:30
const char * GWB_Option_GetId(const GWB_OPTION *option)
Definition option.c:63
void GWB_Option_SetOptionType(GWB_OPTION *option, int i)
Definition option.c:77
int GWB_Option_GetOptionType(const GWB_OPTION *option)
Definition option.c:70
void GWB_Option_SetDefinePrefix(GWB_OPTION *option, const char *s)
Definition option.c:163
int GWB_OptionType_fromString(const char *s)
Definition option.c:205
const char * GWB_Option_GetDefinePrefix(const GWB_OPTION *option)
Definition option.c:156
int GWB_Option_IsValidChoice(const GWB_OPTION *option, const char *s)
Definition option.c:137
const char * GWB_Option_GetDefaultValue(const GWB_OPTION *option)
Definition option.c:84
void GWB_Option_AddAlias(GWB_OPTION *option, const char *name, const char *value)
Definition option.c:106
void GWB_Option_SetDefaultValue(GWB_OPTION *option, const char *s)
Definition option.c:91
const char * GWB_Option_GetAlias(const GWB_OPTION *option, const char *name)
Definition option.c:116
GWEN_STRINGLIST * GWB_Option_GetChoiceList(const GWB_OPTION *option)
Definition option.c:123
@ GWB_OptionType_String
Definition option.h:24
@ GWB_OptionType_StringList
Definition option.h:25
@ GWB_OptionType_Unknown
Definition option.h:22
@ GWB_OptionType_None
Definition option.h:23
struct GWB_OPTION GWB_OPTION
Definition option.h:17
int _checkStringOption(GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
Definition p_options.c:169
int GWB_ParseOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWEN_XMLNODE *xmlNode)
Definition p_options.c:35
int _checkAgainstGivenOption(GWB_PROJECT *project, GWB_CONTEXT *currentContext, GWB_OPTION *option)
Definition p_options.c:127
int _checkStringListOption(GWB_PROJECT *project, GWB_OPTION *option, GWB_CONTEXT *currentContext, const char *givenValue)
Definition p_options.c:205
GWEN_BUFFER * GWB_Parser_ReadNamedXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode, const char *elem)
Definition parser.c:345
GWEN_BUFFER * GWB_Parser_ReadXmlDataIntoBufferAndExpand(GWEN_DB_NODE *db, GWEN_XMLNODE *xmlNode)
Definition parser.c:307
void GWB_Project_AddOption(GWB_PROJECT *project, GWB_OPTION *option)
Definition project.c:348
GWB_KEYVALUEPAIR_LIST * GWB_Project_GetGivenOptionList(const GWB_PROJECT *project)
Definition project.c:374
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_StringList_free(GWEN_STRINGLIST *sl)
Definition stringlist.c:62
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition stringlist.c:818
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
void GWEN_StringList_AppendStringList(GWEN_STRINGLIST *slDest, const GWEN_STRINGLIST *slSource, int checkDouble)
Definition stringlist.c:915
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
#define GWEN_TEXT_FLAGS_DEL_QUOTES
Definition text.h:49
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
Definition text.h:50
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
void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
Definition xml.c:472
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition xml.c:794
const char * GWEN_XMLNode_GetCharValue(const GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition xml.c:812
int GWEN_XMLNode_ExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars)
Definition xml.c:634
struct GWEN__XMLNODE GWEN_XMLNODE
Definition xml.h:156