Initial commit
[platform/upstream/ccid.git] / src / tokenparser.l
1 /*
2  * Reads lexical config files and updates database.
3  *
4  * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
5  *
6  * Copyright (C) 2001-2003
7  *  David Corcoran <corcoran@musclecard.com>
8  * Copyright (C) 2003-2010
9  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
10  *
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
13 are met:
14
15 1. Redistributions of source code must retain the above copyright
16    notice, this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18    notice, this list of conditions and the following disclaimer in the
19    documentation and/or other materials provided with the distribution.
20 3. The name of the author may not be used to endorse or promote products
21    derived from this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 /**
36  * @file
37  * @brief provides parsing functions for Info.plist files
38  * platforms
39  */
40
41 %{
42
43 #include "config.h"
44 #include <stdio.h>
45 #include <string.h>
46 #include <errno.h>
47 #ifndef NDEBUG
48 #define NDEBUG
49 #endif
50 #include <assert.h>
51
52 #include "simclist.h"
53 #include "debuglog.h"
54 #include "parser.h"
55
56 static void eval_key(char *pcToken, list_t *list_key);
57 static void eval_value(char *pcToken, list_t *list_values);
58 void tperrorCheck (char *pcToken_error);
59
60 static list_t *ListKeys;
61 static list_t *ListValues;
62
63 %}
64
65 %option nounput
66 %option noinput
67 %option noyywrap
68
69 %%
70
71 #.*                                             {}
72 "\n"                                            {}
73 \<key\>([A-Z]|[a-z]|[0-9]|[ \t])+\<\/key\>      { eval_key(yytext, ListKeys); }
74 [ \t]                                           {}
75 \<string\>.+\<\/string\> { eval_value(yytext, ListValues); }
76 .                                               { tperrorCheck(yytext); }
77 %%
78
79
80 static void eval_key(char *pcToken, list_t *list_key)
81 {
82         struct bundleElt *elt;
83         int r;
84         size_t len;
85
86         /* create a new list element */
87         elt = malloc(sizeof(*elt));
88         assert(elt);
89
90         /* <key>foobar</key>
91          * 012345 : 5 is the first key character index */
92
93         /* calculate the argument length */
94         for (len=0; pcToken[len+5] != '<'; len++)
95                 ;
96         len++;  /* final NULL byte */
97
98         elt->key = malloc(len);
99         memcpy(elt->key, &pcToken[5], len-1);
100         elt->key[len-1] = '\0';
101
102         r = list_init(&elt->values);
103         assert(r >= 0);
104         (void)r;
105
106         /* add the key/values */
107         list_append(list_key, elt);
108
109         /* set the list to store the values */
110         ListValues = &elt->values;
111 }
112
113 static void eval_value(char *pcToken, list_t *list_values)
114 {
115         int r;
116         size_t len;
117         char *value;
118         char *amp;
119
120         /* <string>foobar</string>
121          * 012345678 : 8 is the first string character index */
122
123         /* calculate the argument length */
124         for (len=0; pcToken[len+8] != '<'; len++)
125                 ;
126         len++;  /* final NULL byte */
127
128         value = malloc(len);
129         assert(value);
130
131         memcpy(value, &pcToken[8], len-1);
132         value[len-1] = '\0';
133
134         /* for all &amp; in the string */
135         amp = value;
136         while ((amp = strstr(amp, "&amp;")) != NULL)
137         {
138                 char *p;
139
140                 /* just skip "amp;" substring (4 letters) */
141                 for (p = amp+1; *(p+4); p++)
142                 {
143                         *p = *(p+4);
144                 }
145                 /* terminate the now shorter string */
146                 *p = '\0';
147
148                 /* skip the & and continue */
149                 amp++;
150         }
151
152         r = list_append(list_values, value);
153         assert(r >= 0);
154         (void)r;
155 }
156
157 void tperrorCheck (char *token_error)
158 {
159     (void)token_error;
160 }
161
162 /**
163  * Find an optional key in a configuration file
164  * No error is logged if the key is not found
165  *
166  * @param l list generated by bundleParse()
167  * @param key searched key
168  * @param[out] values list of token value (if key found)
169  * @retval 0 OK
170  * @retval 1 key not found
171  */
172 int LTPBundleFindValueWithKey(list_t *l, const char *key, list_t **values)
173 {
174         unsigned int i;
175         int ret = 1;
176
177         for (i=0; i < list_size(l); i++)
178         {
179                 struct bundleElt *elt;
180
181                 elt = list_get_at(l, i);
182                 assert(elt);
183
184                 if (0 == strcmp(elt->key, key))
185                 {
186                         *values = &elt->values;
187                         ret = 0;
188                 }
189         }
190
191         return ret;
192 }
193
194
195 /**
196  * Parse a Info.plist file and file a list
197  *
198  * @param fileName file name
199  * @param l list containing the results
200  * @retval -1 configuration file not found
201  * @retval 0 OK
202  */
203 int bundleParse(const char *fileName, list_t *l)
204 {
205         FILE *file = NULL;
206         int r;
207 #ifndef NDEBUG
208         int i;
209 #endif
210
211         file = fopen(fileName, "r");
212         if (!file)
213         {
214                 Log3(PCSC_LOG_CRITICAL, "Could not open bundle file %s: %s",
215                         fileName, strerror(errno));
216                 return 1;
217         }
218
219         r = list_init(l);
220         assert(r >= 0);
221         (void)r;
222
223         ListKeys = l;
224         yyin = file;
225
226         do
227         {
228                 (void)yylex();
229         } while (!feof(file));
230         yylex_destroy();
231
232         (void)fclose(file);
233
234 #ifndef NDEBUG
235         printf("size: %d\n", list_size(l));
236         for (i=0; i < list_size(l); i++)
237         {
238                 struct bundleElt *elt;
239                 unsigned int j;
240
241                 elt = list_get_at(l, i);
242                 assert(elt);
243                 printf("Key: %s\n", elt->key);
244
245                 for (j=0; j<list_size(&elt->values); j++)
246                 {
247                         char *v = list_get_at(&elt->values, j);
248                         printf(" value: %s\n", v);
249                 }
250         }
251 #endif
252
253         return 0;
254 }
255
256 /**
257  * Free the list created by bundleParse()
258  *
259  * @param l list containing the results
260  */
261 void bundleRelease(list_t *l)
262 {
263         unsigned int i;
264
265         for (i=0; i < list_size(l); i++)
266         {
267                 struct bundleElt *elt;
268                 unsigned int j;
269
270                 elt = list_get_at(l, i);
271                 assert(elt);
272
273                 /* free all the values */
274                 for (j=0; j<list_size(&elt->values); j++)
275                         free(list_get_at(&elt->values, j));
276                 list_destroy(&elt->values);
277
278                 /* free the key */
279                 free(elt->key);
280                 free(elt);
281         }
282
283         list_destroy(l);
284 }