Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

181 lines (156 sloc) 4.576 kB
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chaosvpn.h"
extern struct config *globalconfig; /* private from config.c */
extern int yyerror(char*);
extern int yylex (void);
static char* catandfree(char*, char*, int, int);
static char* concatias(int, char*, int);
static struct settings_list_entry* list_mkientry(int);
static struct settings_list_entry* list_mksentry(const char*);
static struct settings_list* list_add_elem(struct settings_list*, struct settings_list_entry*);
static struct settings_list* list_allocate(void);
extern int yylineno;
%}
%union {
int ival;
float fval;
char* sval;
void* pval;
bool bval;
struct settings_list* lval;
struct settings_list_entry* eval;
}
%token <pval> KEYWORD_S
%token <pval> KEYWORD_I
%token <pval> KEYWORD_F
%token <pval> KEYWORD_L
%token <pval> KEYWORD_B
%token <sval> STRING
%token <ival> INTVAL
%token <bval> BOOLVAL
%token <bval> YESNOVAL
%token <fval> FLOATVAL
%token <sval> ASSIGNMENT
%token <sval> SEPARATOR
%token <sval> STRINGMARKER
%token <pval> LISTOPEN
%token <pval> LISTSEP
%token <pval> LISTCLOSE
%type <sval> string
%type <lval> list
%type <eval> listentry
%%
parser: { } config
config:
| setting SEPARATOR config
;
setting: KEYWORD_I ASSIGNMENT INTVAL { *((int*)$1) = $3; }
| KEYWORD_B ASSIGNMENT BOOLVAL { *((bool*)$1) = $3; }
| KEYWORD_B ASSIGNMENT YESNOVAL { *((bool*)$1) = $3; }
| KEYWORD_B ASSIGNMENT INTVAL { *((bool*)$1) = $3; }
| KEYWORD_F ASSIGNMENT FLOATVAL { *((float*)$1) = $3; }
| KEYWORD_S ASSIGNMENT STRINGMARKER string STRINGMARKER { if (*(char**)$1) {free(*(char**)$1);} *((char**)$1) = $4; }
| KEYWORD_L ASSIGNMENT LISTOPEN list { *((struct settings_list**)$1) = $4; }
;
listentry: INTVAL { $$ = list_mkientry($1); }
| STRINGMARKER string STRINGMARKER { $$ = list_mksentry($2); }
list: listentry LISTCLOSE { $$ = list_add_elem(list_allocate(), $1); }
| listentry LISTSEP list { $$ = list_add_elem($3, $1); }
| LISTCLOSE { $$ = list_allocate(); }
;
string: { $$ = strdup(""); /* ugly */ }
| KEYWORD_S string {
if (*(char**)$1 == NULL) {
log_err("error: access to uninitialized configuration variable in line %d", yylineno);
exit(1);
}
$$ = catandfree(*(char**)$1, $2, 0, 1);
};
| KEYWORD_I string { $$ = concatias(*(int*)$1, $2, 1); };
| STRING string { $$ = catandfree($1, $2, 1, 1); }
;
%%
static struct settings_list*
list_allocate(void)
{
struct settings_list* sl = (struct settings_list*)
malloc(sizeof(struct settings_list));
if (sl == NULL) exit(111);
memset(sl, 0, sizeof(struct settings_list));
INIT_LIST_HEAD(&sl->list);
return sl;
}
static struct settings_list_entry*
list_mkientry(int i)
{
struct settings_list_entry* entry;
entry = malloc(sizeof(struct settings_list_entry));
if (entry == NULL) exit(111);
memset(entry, 0, sizeof(struct settings_list_entry));
entry->etype = LIST_INTEGER;
entry->evalue.i = i;
return entry;
}
static struct settings_list_entry*
list_mksentry(const char *s)
{
struct settings_list_entry* entry;
entry = malloc(sizeof(struct settings_list_entry));
if (entry == NULL) exit(111);
memset(entry, 0, sizeof(struct settings_list_entry));
entry->etype = LIST_STRING;
entry->evalue.s = strdup(s);
return entry;
}
static struct settings_list*
list_add_elem(struct settings_list* list, struct settings_list_entry* item)
{
struct settings_list* listitem;
listitem = (struct settings_list*) malloc(sizeof(struct settings_list));
if (listitem == NULL) exit(111);
memset(listitem, 0, sizeof(struct settings_list));
listitem->e = item;
list_add(&listitem->list, &list->list);
return list;
}
int
yyerror(char* msg)
{
log_err("parse error: %s in line %d", msg, yylineno);
exit(1);
}
static char*
concatias(int i, char* s, int frees)
{
char* buf;
size_t sl;
size_t tl;
sl = strlen(s);
tl = sl + 20;
buf = malloc(sl + tl);
if (!buf) exit(111);
snprintf(buf, sl + tl, "%d%s", i, s);
if (frees) free(s);
return buf;
}
static char*
catandfree(char* s1, char* s2, int frees1, int frees2)
{
size_t newlen;
size_t l1, l2;
char* buf;
l1 = strlen(s1);
l2 = strlen(s2);
newlen = l1 + l2 + 1;
buf = malloc(newlen);
if(!buf) exit(111);
memcpy(buf, s1, l1);
memcpy(buf + l1, s2, l2);
buf[newlen - 1] = 0;
if (frees1) free(s1);
if (frees2) free(s2);
return buf;
}
Jump to Line
Something went wrong with that request. Please try again.