| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/config/parameters/parse_config_file.c')
| -rw-r--r-- | src/config/parameters/parse_config_file.c | 348 | 
1 files changed, 348 insertions, 0 deletions
| diff --git a/src/config/parameters/parse_config_file.c b/src/config/parameters/parse_config_file.c new file mode 100644 index 0000000..a6920b4 --- /dev/null +++ b/src/config/parameters/parse_config_file.c @@ -0,0 +1,348 @@ +/**** POSIX *******************************************************************/ +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include <sys/time.h> + +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> + +#include <relabsd/config/parameters.h> + +#include <relabsd/device/axis.h> + +#include <relabsd/util/string.h> + + +/* TODO: move this to relabsd/config.h */ +#ifndef RELABSD_OPTION_MAX_SIZE +   #define RELABSD_OPTION_MAX_SIZE 64 +#endif + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +/* + * Returns -1 on error, + *          0 on EOF, + *          1 on newline. + */ +static int read_axis_options +( +   FILE file [const restrict static 1], +   const char axis_name [const restrict static 1], +   struct relabsd_axis axis [const restrict static 1] +) +{ +   char option[(RELABSD_OPTION_MAX_SIZE + 1)]; +   int i; +   char c; + +   option[RELABSD_OPTION_MAX_SIZE] = '\0'; + +   i = 0; + +   while (i <= RELABSD_OPTION_MAX_SIZE) +   { +      c = (char) getc(file); + +      if (c == EOF) +      { +         if (ferror(file)) +         { +            RELABSD_FATAL +            ( +               "Reading error while parsing an option in the configuration file" +               " (axis '%s').", +               axis_name +            ); +         } +         else +         { +            RELABSD_FATAL +            ( +               "End of file reached while parsing an option in the" +               " configuration file (axis '%s').", +               axis_name +            ); +         } + +         return -1; +      } + +      switch (c) +      { +         case ' ': +         case '\t': +            break; + +         case ',': +            i = 0; +            option[i] = '\n'; +            /* We parsed a new option and there is a least another. */ +            (void) +               relabsd_axis_enable_option_from_name(option, axis_name, axis); + +            break; + +         case '\n': +            option[i] = '\n'; +            (void) +               relabsd_axis_enable_option_from_name(option, axis_name, axis); + +            return 1; + +         case EOF: +            option[i] = '\n'; +            (void) +               relabsd_axis_enable_option_from_name(option, axis_name, axis); + +            return 0; + +         default: +            option[i] = c; +            i++; + +            break; +      } +   } + +   RELABSD_FATAL +   ( +      "[CONFIG] Option name '%s[...]' (axis '%s') is too long (%d chars max).", +      option, +      axis_name, +      RELABSD_OPTION_MAX_SIZE +   ); + +   return -1; +} + +/* +static int parse_timeout_option +( +   struct relabsd_config * const conf, +   const char * const param +) +{ +   int timeout_msec; +   const int prev_errno = errno; + +   conf->enable_timeout = 1; + +   errno = 0; + +   timeout_msec = atoi(param); + +   if (timeout_msec <= 0) +   { +      RELABSD_FATAL +      ( +         "Illegal value for timeout \"%d\": accepted range is [1, %d].", +         timeout_msec, +         INT_MAX +      ); + +      return -1; +   } + +   memset((void *) &(conf->timeout), 0, sizeof(struct timeval)); + +   conf->timeout.tv_sec = (time_t) (timeout_msec / 1000); + +   conf->timeout.tv_usec = +      ( +         ((suseconds_t) timeout_msec) +         * ((suseconds_t) 1000) +      ); + +   return 0; +} +*/ + +/* + * Returns -1 on (fatal) error, + *          0 on succes. + */ +static int parse_axis_configuration_line +( +   FILE file [const restrict static 1], +   const char axis_name [const restrict static 1], +   struct relabsd_parameters parameters [const static 1] +) +{ +   int read_count; +   enum relabsd_axis_name axis_index; +   struct relabsd_axis * axis; + +   axis_index = relabsd_axis_parse_name(axis_name); + +   if (axis_index == RELABSD_UNKNOWN) +   { +      RELABSD_FATAL("Unknown axis '%s' in the configuration file.", axis_name); + +      return -1; + +   } + +   axis = (parameters->axes + axis_index); + +   errno = 0; + +   read_count = +      fscanf +      ( +         file, +         "%d%d%d%d%d", +         &(axis->min), +         &(axis->max), +         &(axis->fuzz), +         &(axis->flat), +         &(axis->resolution) +      ); + +   if (read_count == EOF) +   { +      if (errno == 0) +      { +         RELABSD_FATAL +         ( +            "Unexpected end of file while reading the '%s' axis' parameters in" +            " the configuration file.", +            axis_name +         ); +      } +      else +      { +         RELABSD_FATAL +         ( +            "An error occured while reading the '%s' axis' parameters in the" +            " configuration file: %s.", +            axis_name, +            strerror(errno) +         ); +      } + +      return -1; +   } +   else if (read_count < 5) +   { +      RELABSD_FATAL +      ( +         "Invalid parameter count for the '%s' axis in the configuration file.", +         axis_name +      ); + +      return -1; +   } + +   relabsd_axis_enable(axis); + +   return read_axis_options(file, axis_name, axis); +} + +/* + * Returns -1 on (fatal) error, + *          0 on EOF, + *          1 on newline. + */ +static int read_config_line +( +   FILE file [const restrict static 1], +   const char prefix [const restrict static 1], +   struct relabsd_parameters parameters [const restrict static 1] +) +{ +   if (RELABSD_IS_PREFIX("#", prefix)) +   { +      return relabsd_util_reach_next_line_or_eof(file); +   } + +   return parse_axis_configuration_line(file, prefix, parameters); +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_parameters_parse_config_file +( +   const char filename [const restrict static 1], +   struct relabsd_parameters parameters [const restrict static 1] +) +{ +   FILE * file; +   char buffer[(RELABSD_CONF_AXIS_CODE_SIZE + 1)]; +   int continue_reading; + +   buffer[RELABSD_CONF_AXIS_CODE_SIZE] = '\0'; + +   errno = 0; +   file = fopen(filename, "r"); + +   if (file == (FILE *) NULL) +   { +      RELABSD_FATAL("Could not open file %s: %s.", filename, strerror(errno)); + +      return -1; +   } + +   errno = 0; +   continue_reading = 1; + +   while +   ( +      (continue_reading == 1) +      && +      ( +         fscanf +         ( +            file, +            "%" RELABSD_TO_STRING(RELABSD_CONF_AXIS_CODE_SIZE) "s", +            buffer +         ) +         != EOF +      ) +   ) +   { +      switch (read_config_line(file, buffer, parameters)) +      { +         case 1: +            /* Everything is going well. */ +            break; + +         case 0: +            /* EOF reached. */ +            continue_reading = 0; +            break; + +         case -1: +            /* A fatal error occured. */ +            fclose(file); +            return -1; +      } +   } + +   if (errno != 0) +   { +      /* An error happened in the while loop condition. */ +      RELABSD_FATAL +      ( +         "[CONFIG] Error while reading file: %s, last read '%s'.", +         strerror(errno), +         buffer +      ); + +      fclose(file); + +      return -1; +   } + +   fclose(file); + +   return 0; +} | 


