283 lines
6.0 KiB
Plaintext
283 lines
6.0 KiB
Plaintext
/*
|
|
* Reads lexical config files and updates database.
|
|
*
|
|
* MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
|
|
*
|
|
* Copyright (C) 2001-2003
|
|
* David Corcoran <corcoran@musclecard.com>
|
|
* Copyright (C) 2003-2010
|
|
* Ludovic Rousseau <ludovic.rousseau@free.fr>
|
|
*
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
3. The name of the author may not be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief provides parsing functions for Info.plist files
|
|
* platforms
|
|
*/
|
|
|
|
%{
|
|
|
|
#include "config.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#define NDEBUG
|
|
#include <assert.h>
|
|
|
|
#include "simclist.h"
|
|
#include "debuglog.h"
|
|
#include "parser.h"
|
|
|
|
static void eval_key(char *pcToken, list_t *list_key);
|
|
static void eval_value(char *pcToken, list_t *list_values);
|
|
void tperrorCheck (char *pcToken_error);
|
|
|
|
static list_t *ListKeys;
|
|
static list_t *ListValues;
|
|
|
|
%}
|
|
|
|
%option nounput
|
|
%option noinput
|
|
%option noyywrap
|
|
|
|
%%
|
|
|
|
#.* {}
|
|
"\n" {}
|
|
\<key\>([A-Z]|[a-z]|[0-9]|[ \t])+\<\/key\> { eval_key(yytext, ListKeys); }
|
|
[ \t] {}
|
|
\<string\>([A-Z]|[a-z]|[0-9]|[ \t]|[!@#$%^&*()\-+/_\:?.,=~'";\[\]])+\<\/string\> { eval_value(yytext, ListValues); }
|
|
. { tperrorCheck(yytext); }
|
|
%%
|
|
|
|
|
|
static void eval_key(char *pcToken, list_t *list_key)
|
|
{
|
|
struct bundleElt *elt;
|
|
int r;
|
|
size_t len;
|
|
|
|
/* create a new list element */
|
|
elt = malloc(sizeof(*elt));
|
|
assert(elt);
|
|
|
|
/* <key>foobar</key>
|
|
* 012345 : 5 is the first key character index */
|
|
|
|
/* calculate the argument length */
|
|
for (len=0; pcToken[len+5] != '<'; len++)
|
|
;
|
|
len++; /* final NULL byte */
|
|
|
|
elt->key = malloc(len);
|
|
memcpy(elt->key, &pcToken[5], len-1);
|
|
elt->key[len-1] = '\0';
|
|
|
|
r = list_init(&elt->values);
|
|
assert(r >= 0);
|
|
(void)r;
|
|
|
|
/* add the key/values */
|
|
list_append(list_key, elt);
|
|
|
|
/* set the list to store the values */
|
|
ListValues = &elt->values;
|
|
}
|
|
|
|
static void eval_value(char *pcToken, list_t *list_values)
|
|
{
|
|
int r;
|
|
size_t len;
|
|
char *value;
|
|
char *amp;
|
|
|
|
/* <string>foobar</string>
|
|
* 012345678 : 8 is the first string character index */
|
|
|
|
/* calculate the argument length */
|
|
for (len=0; pcToken[len+8] != '<'; len++)
|
|
;
|
|
len++; /* final NULL byte */
|
|
|
|
value = malloc(len);
|
|
assert(value);
|
|
|
|
memcpy(value, &pcToken[8], len-1);
|
|
value[len-1] = '\0';
|
|
|
|
/* for all & in the string */
|
|
amp = value;
|
|
while ((amp = strstr(amp, "&")) != NULL)
|
|
{
|
|
char *p;
|
|
|
|
/* just skip "amp;" substring (4 letters) */
|
|
for (p = amp+1; *(p+4); p++)
|
|
{
|
|
*p = *(p+4);
|
|
}
|
|
/* terminate the now shorter string */
|
|
*p = '\0';
|
|
|
|
/* skip the & and continue */
|
|
amp++;
|
|
}
|
|
|
|
r = list_append(list_values, value);
|
|
assert(r >= 0);
|
|
(void)r;
|
|
}
|
|
|
|
void tperrorCheck (char *token_error)
|
|
{
|
|
(void)token_error;
|
|
}
|
|
|
|
/**
|
|
* Find an optional key in a configuration file
|
|
* No error is logged if the key is not found
|
|
*
|
|
* @param l list generated by bundleParse()
|
|
* @param key searched key
|
|
* @param[out] values list of token value (if key found)
|
|
* @retval 0 OK
|
|
* @retval 1 key not found
|
|
*/
|
|
int LTPBundleFindValueWithKey(list_t *l, const char *key, list_t **values)
|
|
{
|
|
unsigned int i;
|
|
int ret = 1;
|
|
|
|
for (i=0; i < list_size(l); i++)
|
|
{
|
|
struct bundleElt *elt;
|
|
|
|
elt = list_get_at(l, i);
|
|
assert(elt);
|
|
|
|
if (0 == strcmp(elt->key, key))
|
|
{
|
|
*values = &elt->values;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/**
|
|
* Parse a Info.plist file and file a list
|
|
*
|
|
* @param fileName file name
|
|
* @param l list containing the results
|
|
* @retval -1 configuration file not found
|
|
* @retval 0 OK
|
|
*/
|
|
int bundleParse(const char *fileName, list_t *l)
|
|
{
|
|
FILE *file = NULL;
|
|
int r;
|
|
#ifndef NDEBUG
|
|
int i;
|
|
#endif
|
|
|
|
file = fopen(fileName, "r");
|
|
if (!file)
|
|
{
|
|
Log3(PCSC_LOG_CRITICAL, "Could not open bundle file %s: %s",
|
|
fileName, strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
r = list_init(l);
|
|
assert(r >= 0);
|
|
(void)r;
|
|
|
|
ListKeys = l;
|
|
yyin = file;
|
|
|
|
do
|
|
{
|
|
(void)yylex();
|
|
} while (!feof(file));
|
|
yylex_destroy();
|
|
|
|
(void)fclose(file);
|
|
|
|
#ifndef NDEBUG
|
|
printf("size: %d\n", list_size(l));
|
|
for (i=0; i < list_size(l); i++)
|
|
{
|
|
struct bundleElt *elt;
|
|
unsigned int j;
|
|
|
|
elt = list_get_at(l, i);
|
|
assert(elt);
|
|
printf("Key: %s\n", elt->key);
|
|
|
|
for (j=0; j<list_size(&elt->values); j++)
|
|
{
|
|
char *v = list_get_at(&elt->values, j);
|
|
printf(" value: %s\n", v);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Free the list created by bundleParse()
|
|
*
|
|
* @param l list containing the results
|
|
*/
|
|
void bundleRelease(list_t *l)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i=0; i < list_size(l); i++)
|
|
{
|
|
struct bundleElt *elt;
|
|
unsigned int j;
|
|
|
|
elt = list_get_at(l, i);
|
|
assert(elt);
|
|
|
|
/* free all the values */
|
|
for (j=0; j<list_size(&elt->values); j++)
|
|
free(list_get_at(&elt->values, j));
|
|
list_destroy(&elt->values);
|
|
|
|
/* free the key */
|
|
free(elt->key);
|
|
free(elt);
|
|
}
|
|
|
|
list_destroy(l);
|
|
}
|