Commit 35456ab1 authored by Pietro Fezzardi's avatar Pietro Fezzardi

configuration: added ARG_TIME config argument

and all the data structures needed to set configuration options
about time.
In ppsi.h added struct pp_cfg_time a platform independent timespec-like
data structure.
union pp_cfg_arg is extended with a pp_cfg_time field.
enum pp_argtype is extended with ARG_TIME.
In lib/conf.c a case ARG_TIME is added to handle it.
parent eac7e370
......@@ -256,12 +256,19 @@ extern int pp_close_globals(struct pp_globals *ppg);
extern int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv);
/* platform independent timespec-like data structure */
struct pp_cfg_time {
long tv_sec;
long tv_nsec;
};
/* Data structure used to pass just a single argument to configuration
* functions. Any future new type for any new configuration function can be just
* added inside here, without redefining cfg_handler prototype */
union pp_cfg_arg {
int i;
char *s;
struct pp_cfg_time ts;
};
/*
......@@ -278,6 +285,7 @@ enum pp_argtype {
ARG_INT,
ARG_STR,
ARG_NAMES,
ARG_TIME,
};
struct pp_argline {
cfg_handler f;
......
......@@ -149,12 +149,17 @@ struct pp_argline pp_ext_arglines[] __attribute__((weak)) = {
{}
};
/* local implementation of isblank() for bare-metal users */
/* local implementation of isblank() and isdigit() for bare-metal users */
static int blank(int c)
{
return c == ' ' || c == '\t' || c == '\n';
}
static int digit(char c)
{
return (('0' <= c) && (c <= '9'));
}
static char *first_word(char *line, char **rest)
{
char *ret;
......@@ -179,6 +184,59 @@ static char *first_word(char *line, char **rest)
return ret;
}
static int parse_time(struct pp_cfg_time *ts, char *s)
{
long sign = 1;
long num;
int i;
/* skip leading blanks */
while (*s && blank(*s))
s++;
/* detect sign */
if (*s == '-') {
sign = -1;
s++;
} else if (*s == '+') {
s++;
}
if (!*s)
return -1;
/* parse integer part */
num = 0;
while (*s && digit(*s)) {
num *= 10;
num += *s - '0';
s++;
}
ts->tv_sec = sign * num;
ts->tv_nsec = 0;
if (*s == '\0')
return 0; // no decimals
// else
if (*s != '.')
return -1;
/* parse decimals */
s++; // skip '.'
num = 0;
for (i = 0; (i < 9) && *s && digit(*s); i++) {
num *= 10;
num += *s - '0';;
s++;
}
if (*s) // more than 9 digits or *s is not a digit
return -1;
for (; i < 9; i++) // finish to scale nanoseconds
num *=10;
ts->tv_nsec = sign * num;
return 0;
}
static int pp_config_line(struct pp_globals *ppg, char *line, int lineno)
{
union pp_cfg_arg cfg_arg;
......@@ -255,6 +313,18 @@ static int pp_config_line(struct pp_globals *ppg, char *line, int lineno)
if (l->f(lineno, &cfg_arg))
return -1;
break;
case ARG_TIME:
if(parse_time(&cfg_arg.ts, line)) {
pp_diag(NULL, config, 1, "line %i: wrong arg \"%s\" for "
"\"%s\"\n", lineno, line, word);
return -1;
}
if (l->f(lineno, &cfg_arg))
return -1;
break;
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment