mirror of
https://github.com/matrix-construct/construct
synced 2025-01-04 20:04:30 +01:00
61b517ca3c
* To benefit from the precompiled-header (PCH) it MUST provide "the first C token." Advantages: Never worry about the include stack again. Remember, this means one less thing for random module developers, community people learning C++, and new developers to deal with. It should reduce the learning curve and barrier for participation. Disadvantages: Makes overall compilation a bit slower, especially without any additional work to improve it again. There are several opportunities, places where the PCH is probably being ignored, etc that can be addressed.
313 lines
5.7 KiB
Text
313 lines
5.7 KiB
Text
/* This code is in the public domain.
|
|
* $Nightmare: nightmare/src/main/parser.y,v 1.2.2.1.2.1 2002/07/02 03:42:10 ejb Exp $
|
|
*/
|
|
|
|
%{
|
|
#define YY_NO_UNPUT
|
|
|
|
int yylex();
|
|
|
|
namespace ircd {
|
|
|
|
static time_t conf_find_time(char*);
|
|
|
|
static struct {
|
|
const char * name;
|
|
const char * plural;
|
|
time_t val;
|
|
} ircd_times[] = {
|
|
{"second", "seconds", 1},
|
|
{"minute", "minutes", 60},
|
|
{"hour", "hours", 60 * 60},
|
|
{"day", "days", 60 * 60 * 24},
|
|
{"week", "weeks", 60 * 60 * 24 * 7},
|
|
{"fortnight", "fortnights", 60 * 60 * 24 * 14},
|
|
{"month", "months", 60 * 60 * 24 * 7 * 4},
|
|
{"year", "years", 60 * 60 * 24 * 365},
|
|
/* ok-- we now do sizes here too. they aren't times, but
|
|
it's close enough */
|
|
{"byte", "bytes", 1},
|
|
{"kb", NULL, 1024},
|
|
{"kbyte", "kbytes", 1024},
|
|
{"kilobyte", "kilebytes", 1024},
|
|
{"mb", NULL, 1024 * 1024},
|
|
{"mbyte", "mbytes", 1024 * 1024},
|
|
{"megabyte", "megabytes", 1024 * 1024},
|
|
{NULL, NULL, 0},
|
|
};
|
|
|
|
time_t conf_find_time(char *name)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; ircd_times[i].name; i++)
|
|
{
|
|
if (rb_strcasecmp(ircd_times[i].name, name) == 0 ||
|
|
(ircd_times[i].plural && rb_strcasecmp(ircd_times[i].plural, name) == 0))
|
|
return ircd_times[i].val;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct
|
|
{
|
|
const char *word;
|
|
int yesno;
|
|
} yesno[] = {
|
|
{"yes", 1},
|
|
{"no", 0},
|
|
{"true", 1},
|
|
{"false", 0},
|
|
{"on", 1},
|
|
{"off", 0},
|
|
{NULL, 0}
|
|
};
|
|
|
|
static int conf_get_yesno_value(char *str)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; yesno[i].word; i++)
|
|
{
|
|
if (rb_strcasecmp(str, yesno[i].word) == 0)
|
|
{
|
|
return yesno[i].yesno;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static void free_cur_list(conf_parm_t* list)
|
|
{
|
|
if (list->type == CF_STRING || list->type == CF_QSTRING) {
|
|
rb_free(list->v.string);
|
|
} else if (list->type == CF_FLIST) {
|
|
/* Even though CF_FLIST is a flag, comparing with == is valid
|
|
* because conf_parm_t.type must be either a type or one flag.
|
|
*/
|
|
free_cur_list(list->v.list);
|
|
}
|
|
|
|
if (list->next) {
|
|
free_cur_list(list->next);
|
|
}
|
|
|
|
rb_free(list);
|
|
}
|
|
|
|
|
|
conf_parm_t * cur_list;
|
|
|
|
static void add_cur_list_cpt(conf_parm_t *new_)
|
|
{
|
|
if (cur_list == NULL)
|
|
{
|
|
cur_list = (conf_parm_t *)rb_malloc(sizeof(conf_parm_t));
|
|
cur_list->type = CF_FLIST;
|
|
cur_list->v.list = new_;
|
|
}
|
|
else
|
|
{
|
|
new_->next = cur_list->v.list;
|
|
cur_list->v.list = new_;
|
|
}
|
|
}
|
|
|
|
static void add_cur_list(int type, char *str, int number)
|
|
{
|
|
conf_parm_t *new_;
|
|
|
|
new_ = (conf_parm_t *)rb_malloc(sizeof(conf_parm_t));
|
|
new_->next = NULL;
|
|
new_->type = type;
|
|
|
|
switch(type)
|
|
{
|
|
case CF_INT:
|
|
case CF_TIME:
|
|
case CF_YESNO:
|
|
new_->v.number = number;
|
|
break;
|
|
case CF_STRING:
|
|
case CF_QSTRING:
|
|
new_->v.string = rb_strdup(str);
|
|
break;
|
|
}
|
|
|
|
add_cur_list_cpt(new_);
|
|
}
|
|
|
|
} // namespace ircd
|
|
|
|
%}
|
|
|
|
%union {
|
|
int number;
|
|
char string[1024];
|
|
ircd::conf_parm_t * conf_parm;
|
|
}
|
|
|
|
%token LOADMODULE TWODOTS
|
|
|
|
%token <string> QSTRING STRING
|
|
%token <number> NUMBER
|
|
|
|
%type <string> qstring string
|
|
%type <number> number timespec
|
|
%type <conf_parm> oneitem single itemlist
|
|
|
|
%start conf
|
|
|
|
%%
|
|
|
|
conf:
|
|
| conf conf_item
|
|
| error
|
|
;
|
|
|
|
conf_item: block
|
|
| loadmodule
|
|
;
|
|
|
|
block: string
|
|
{
|
|
ircd::conf_start_block($1, NULL);
|
|
}
|
|
'{' block_items '}' ';'
|
|
{
|
|
if (ircd::conf_cur_block)
|
|
ircd::conf_end_block(ircd::conf_cur_block);
|
|
}
|
|
| string qstring
|
|
{
|
|
ircd::conf_start_block($1, $2);
|
|
}
|
|
'{' block_items '}' ';'
|
|
{
|
|
if (ircd::conf_cur_block)
|
|
ircd::conf_end_block(ircd::conf_cur_block);
|
|
}
|
|
;
|
|
|
|
block_items: block_items block_item
|
|
| block_item
|
|
;
|
|
|
|
block_item: string '=' itemlist ';'
|
|
{
|
|
ircd::conf_call_set(ircd::conf_cur_block, $1, ircd::cur_list);
|
|
ircd::free_cur_list(ircd::cur_list);
|
|
ircd::cur_list = NULL;
|
|
}
|
|
;
|
|
|
|
itemlist: itemlist ',' single
|
|
| single
|
|
;
|
|
|
|
single: oneitem
|
|
{
|
|
ircd::add_cur_list_cpt($1);
|
|
}
|
|
| oneitem TWODOTS oneitem
|
|
{
|
|
/* "1 .. 5" meaning 1,2,3,4,5 - only valid for integers */
|
|
if ($1->type != CF_INT || $3->type != CF_INT)
|
|
{
|
|
ircd::conf_report_error("Both arguments in '..' notation must be integers.");
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
for (i = $1->v.number; i <= $3->v.number; i++)
|
|
{
|
|
ircd::add_cur_list(CF_INT, 0, i);
|
|
}
|
|
}
|
|
}
|
|
;
|
|
|
|
oneitem: qstring
|
|
{
|
|
$$ = (ircd::conf_parm_t *)rb_malloc(sizeof(ircd::conf_parm_t));
|
|
$$->type = CF_QSTRING;
|
|
$$->v.string = rb_strdup($1);
|
|
}
|
|
| timespec
|
|
{
|
|
$$ = (ircd::conf_parm_t *)rb_malloc(sizeof(ircd::conf_parm_t));
|
|
$$->type = CF_TIME;
|
|
$$->v.number = $1;
|
|
}
|
|
| number
|
|
{
|
|
$$ = (ircd::conf_parm_t *)rb_malloc(sizeof(ircd::conf_parm_t));
|
|
$$->type = CF_INT;
|
|
$$->v.number = $1;
|
|
}
|
|
| string
|
|
{
|
|
/* a 'string' could also be a yes/no value ..
|
|
so pass it as that, if so */
|
|
int val = ircd::conf_get_yesno_value($1);
|
|
|
|
$$ = (ircd::conf_parm_t *)rb_malloc(sizeof(ircd::conf_parm_t));
|
|
|
|
if (val != -1)
|
|
{
|
|
$$->type = CF_YESNO;
|
|
$$->v.number = val;
|
|
}
|
|
else
|
|
{
|
|
$$->type = CF_STRING;
|
|
$$->v.string = rb_strdup($1);
|
|
}
|
|
}
|
|
;
|
|
|
|
loadmodule:
|
|
LOADMODULE QSTRING
|
|
{
|
|
char *m_bn;
|
|
m_bn = rb_basename((char *) $2);
|
|
|
|
if (ircd::findmodule_byname(m_bn) == NULL)
|
|
{
|
|
ircd::load_one_module($2, MAPI_ORIGIN_EXTENSION, 0);
|
|
}
|
|
|
|
rb_free(m_bn);
|
|
}
|
|
';'
|
|
;
|
|
|
|
qstring: QSTRING { strcpy($$, $1); } ;
|
|
string: STRING { strcpy($$, $1); } ;
|
|
number: NUMBER { $$ = $1; } ;
|
|
|
|
timespec: number string
|
|
{
|
|
time_t t;
|
|
|
|
if ((t = ircd::conf_find_time($2)) == 0)
|
|
{
|
|
ircd::conf_report_error("Unrecognised time type/size '%s'", $2);
|
|
t = 1;
|
|
}
|
|
|
|
$$ = $1 * t;
|
|
}
|
|
| timespec timespec
|
|
{
|
|
$$ = $1 + $2;
|
|
}
|
|
| timespec number
|
|
{
|
|
$$ = $1 + $2;
|
|
}
|
|
;
|