summaryrefslogtreecommitdiff
path: root/src/config.c
blob: 2661f4c74cafe2792e4a4f1c5d4aa319b70b0e3d (plain)
    1 /**
    2  * A class to help with parsing standard config files
    3  *
    4  * Copyright (C) 2016 Aaron Ball <nullspoon@oper.io>
    5  *
    6  * Noteless is free software: you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation, either version 3 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * Noteless is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with noteless.  If not, see <http://www.gnu.org/licenses/>.
   18  */
   19 #include "config.h"
   20 
   21 /**
   22  * Constructor for the config class. Reads config file into a vector (one line
   23  * per index), then parses each line into a vector size 2x.
   24  *
   25  * @param const char* p Path to the config file to be read in
   26  */
   27 int config_load(config_t* conf, char* p) {
   28   // TODO
   29   strcpy(conf->path, p);
   30 
   31   int line_count = config_valid_line_count(p);
   32 
   33   // The file couldn't be opened or no valid lines found, return -1
   34   if(line_count == 0) { return -1; } 
   35 
   36   FILE* f;
   37   f = fopen(conf->path, "r");
   38 
   39   // Verify the file could be opened
   40   if(!f) {
   41     // printf("Could not open config file at %s.\n", conf->path);
   42     return -1;
   43   }
   44 
   45   // Set the maximum read width and read buffer array
   46   int len = config_line_len;
   47   char buf[config_line_len] = "";
   48 
   49   char key[32];
   50   char value[256];
   51 
   52   while(fgets(buf, len, f) != NULL) {
   53     int start = 0;
   54     // This loop allows for lines to not start at the beginning
   55     while(buf[start] != '\0') {
   56       if(buf[start] != ' ') {
   57         break;
   58       } else {
   59         start++;
   60       }
   61     }
   62 
   63     // Skip all lines starting with a comment char
   64     if(buf[start] == '#') { continue; }
   65     // Skip empty lines
   66     if(buf[start] == '\n') { continue; }
   67 
   68     int end = start;
   69     while(buf[end] != '\0') {
   70       // This allows for inline comment chars.  The line ends when the first
   71       // comment char is found.
   72       if(buf[end] == '#' || buf[end] == '\n') { break; }
   73       end++;
   74     }
   75 
   76     char tmp_line[config_line_len] = "";
   77     // Temp variable to store the text between index start and index end
   78     strncpy(tmp_line, &buf[start], end - start + 1);
   79     // Make sure it has a trailing newline so sscanf works
   80     strcat(tmp_line, "\n");
   81 
   82     // Parse the line into temp variables
   83     sscanf(tmp_line, "%s %s", key, value);
   84 
   85     // Set the config key/value
   86     config_set(conf, key, value);
   87   }
   88 
   89   fclose(f);
   90 
   91   return 0;
   92 }
   93 
   94 
   95 /**
   96  * Destructor for config struct.
   97  *
   98  * @param conf Config_t pointer to be freed from memory
   99  */
  100 void config_free(config_t* conf) {
  101   for(int i = 0; i < conf->count; i++) {
  102     free(conf->keys[i]);
  103     free(conf->values[i]);
  104   }
  105 }
  106 
  107 
  108 /**
  109  * Performs a line count of valid lines in the specified config file. This is
  110  * useful for determining the size of an array to store keys or values in.
  111  * A valid line is considered to be a line that is not empty or commented out.
  112  *
  113  * @param path Path to the config file to be parsed
  114  *
  115  * @return int Count of lines that are not commented out or empty
  116  */
  117 int config_valid_line_count(char* path) {
  118   int count = 0;
  119 
  120   FILE* f;
  121   f = fopen(path, "r");
  122   if(!f) { return -1; }
  123 
  124   int len = config_line_len;
  125   char buf[config_line_len];
  126 
  127   while(fgets(buf, len, f) != NULL) {
  128     int start = 0;
  129 
  130     // Find the first char
  131     while(buf[start] == ' ') { start++; }
  132 
  133     // Confirm the line is not a comment or empty
  134     if(buf[start] != '#' && buf[start] != '\n') { count++; }
  135   }
  136   fclose(f);
  137 
  138   return count;
  139 }
  140 
  141 
  142 /**
  143  * Checks the configuration struct for the given key's value.
  144  *
  145  * @param conf Config_t instance pointer containing keys and values to check
  146  * @param key Key to check if exists
  147  *
  148  * @return int Key value exists (1) or not (0)
  149  */
  150 int config_isset(config_t* conf, char* key) {
  151   for(int i = 0; i < conf->count; i++) {
  152     if(strcmp(conf->keys[i], key) == 0) {
  153       return 1;
  154     }
  155   }
  156   return 0;
  157 }
  158 
  159 
  160 /**
  161  * TODO
  162  */
  163 char* config_get(config_t* conf, char* key) {
  164   for(int i = 0; i < conf->count; i++) {
  165     if(strcmp(conf->keys[i], key) == 0) {
  166       return conf->values[i];
  167     }
  168   }
  169   return NULL;
  170 }
  171 
  172 
  173 /**
  174  * Sets the value of the specified key. If the key exists, its value is reset
  175  * to the value that is passed in. If the key does not exist, the key and value
  176  * are appended to the end of the key/value arrays.
  177  *
  178  * @param conf The config object containing the keys and values
  179  * @param key Key to set the value for
  180  * @param value Value to be set for the given key
  181  *
  182  * @return Index of the key/value that has been set
  183  */
  184 int config_set(config_t* conf, char* key, char* value) {
  185   for(int i = 0; i < conf->count; i++) {
  186     if(strcmp(conf->keys[i], key) == 0) {
  187       // Key exists, reset its value
  188       strcpy(conf->values[i], value);
  189       return i;
  190     }
  191   }
  192   // Key does not exist, create and add
  193   char* h_key = malloc(strlen(key) + 1);
  194   char* h_value = malloc(strlen(value) + 1);
  195   strcpy(h_key, key);
  196   strcpy(h_value, value);
  197   conf->keys[conf->count] = h_key;
  198   conf->values[conf->count] = h_value;
  199   conf->count++;
  200   return (conf->count - 1);
  201 }
  202 
  203 
  204 /**
  205  * TODO
  206  */
  207 int config_add(config_t* conf, char* key, char* value) {
  208   // Allocate the new key and value memory
  209   char* h_key = malloc(strlen(key) + 1);
  210   char* h_value = malloc(strlen(value) + 1);
  211   // Assign
  212   strcpy(h_key, key);
  213   strcpy(h_value, value);
  214 
  215   conf->count++;
  216   conf->keys[conf->count] = h_key;
  217   conf->values[conf->count] = h_value;
  218 
  219   return conf->count;
  220 }

Generated by cgit