Advertisement
Guest User

Untitled

a guest
May 1st, 2017
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.29 KB | None | 0 0
  1. #include "config.h"
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <assert.h>
  8.  
  9. //deletes unwanted chars
  10. static char* trim(char* toTrim, const char * toIgnore)
  11. {
  12.     if (strlen(toTrim) < 1) return 0;
  13.     //delete from backwards
  14.     for(int i = strlen(toTrim);; i--)
  15.     {
  16.         if(isspace(toTrim[i]) || strchr(toIgnore, toTrim[i]))
  17.         {
  18.             toTrim[i] = '\0';
  19.         }
  20.         else
  21.         {
  22.             break;
  23.         }
  24.     }
  25.    
  26.     //delete from start
  27.     while (*toTrim && (isspace(*toTrim) || strchr(toIgnore, *toTrim)))
  28.         toTrim++;
  29.  
  30.     return toTrim;
  31. }
  32.  
  33. //reads config
  34. int configRead(struct config *cfg, const char *name)
  35. {
  36.     assert(cfg != NULL);
  37.     assert(name != NULL);
  38.  
  39.     //open file
  40.     FILE* file = fopen(name, "r");
  41.     //check if opened
  42.     if (file == NULL) {
  43.         return 1;
  44.     }
  45.  
  46.     struct section * sect = malloc(sizeof(struct section) * 255);
  47.     struct keysnvalues * keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
  48.     int num_section = -1;
  49.     int num_keysnvalues = 0;
  50.  
  51.     for(; !feof(file);)
  52.     {
  53.         int lineEmpty = 1;
  54.         //read line
  55.         int CUR_MAX = 4095;
  56.         char *buffer = (char*) malloc(sizeof(char) * CUR_MAX); // allocate buffer.
  57.         int length = 0;
  58.         int validSection = -1; // section doesn't start on the beggining
  59.         int section = 0; // checks if after [*] line is empty
  60.         int equals = 0;
  61.  
  62.         for (int ch = fgetc(file); ch != '\0' && ch != '\n' && ch != EOF; ch = fgetc(file))
  63.         {
  64.             if(length == CUR_MAX) { // time to expand ?
  65.                 CUR_MAX *= 2; // expand to double the current size of anything similar.
  66.                 buffer = realloc(buffer, CUR_MAX); // re allocate memory.
  67.             }
  68.             validSection++;
  69.            
  70.            
  71.             if(section == 2 && !(isspace(ch)) != 0) // checks if after [*] line is empty
  72.             {
  73.                 fclose(file);
  74.                 return 2;
  75.             }
  76.             //(ch == '[' && length == 0) ? (section = 1) : (section = 0); // checks if after [*] line is empty
  77.             if(ch == '[' && length == 0)
  78.             {
  79.                 section = 1;
  80.             }
  81.             if(ch == ']' && section == 1) section = 2; // checks if after [*] line is empty
  82.  
  83.             if(ch == '[' && (validSection != length) && lineEmpty == 1) // section doesn't start on the beggining
  84.             {
  85.                 fclose(file);
  86.                 return 2;
  87.             }
  88.            
  89.             if(lineEmpty == 1 && !(isspace(ch))) lineEmpty = 0; //checks if empty line
  90.  
  91.             if(lineEmpty == 1 && (isspace(ch))) continue; //doesn't save white-characters before first valid
  92.  
  93.             if(equals == 1 && ch == '=') equals = 2;
  94.             if(length == 0 && ch != '[') equals = 1;
  95.  
  96.             buffer[length] = ch; // stuff in buffer.
  97.             length++;
  98.         }
  99.        
  100.         if(feof(file) && (lineEmpty || buffer[0] == ';'))
  101.         {
  102.             if(num_keysnvalues != -1)
  103.             {
  104.                 sect[num_section].keysnvalues = keysnvalue;
  105.                 sect[num_section].keysnvalues_ammount = num_keysnvalues;
  106.             }
  107.             if (num_section != -1)
  108.             {
  109.                 cfg -> section_ammount++;
  110.                 cfg -> sections = sect;
  111.             }
  112.             fclose(file);
  113.             break;
  114.         }
  115.         //skip comented line
  116.         if(buffer[0] == ';' || lineEmpty) continue;
  117.         if(equals == 1)
  118.         {
  119.             fclose(file);
  120.             return 2;
  121.         }
  122.         buffer[length] = '\0';
  123.  
  124.         /*_____________________________________________
  125.  
  126.                         Case SECTION
  127.         _____________________________________________*/
  128.         if (buffer[0] == '[')
  129.         {
  130.             buffer = trim(buffer, "[]");
  131.             //checks if section is valid
  132.             for (int i=0; buffer[i]; i++)
  133.             {
  134.                 //    const char * valid_characters = "-_:";
  135.                 if (!((buffer[i] == '-' || buffer[i] == '_' || buffer[i] == ':') || (isalpha(buffer[i])) || (isdigit(buffer[i])))) {
  136.                     fclose(file);
  137.                     return 2;
  138.                 }
  139.             }
  140.  
  141.             //saves section name
  142.             if (num_section == -1)
  143.             {
  144.                 //sect[++num_section].name = (char *)malloc(strlen(buffer));
  145.                 sect[++num_section].name = buffer;
  146.                 //strcpy(sect[num_section].name, buffer);
  147.             }
  148.             else
  149.             {
  150.                 //check if section not duplication
  151.                 for (int i = 0; i < num_section; i++) {
  152.                     if (strcmp(sect[i].name, buffer) == 0) {
  153.                         fclose(file);
  154.                         return 2;
  155.                     }
  156.                 }
  157.                 //sect[num_section].keysnvalues = malloc(sizeof(*keysnvalue));
  158.                 sect[num_section].keysnvalues = keysnvalue;
  159.                 sect[num_section].keysnvalues_ammount = num_keysnvalues;
  160.                 cfg -> section_ammount++;
  161.  
  162.                 //start with new keysnvalue
  163.                 num_keysnvalues = 0;
  164.                 keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
  165.                 sect[++num_section].name = buffer;
  166.                 sect[num_section].keysnvalues = 0;
  167.             }
  168.         }
  169.         else
  170.             /*_____________________________________________
  171.  
  172.                             Case key==value
  173.             _____________________________________________*/
  174.         {
  175.             if (num_section == -1)
  176.             {
  177.                 fclose(file);
  178.                 return 2;
  179.             }
  180.             char *key = strtok(buffer, "="); //saves key
  181.             char *value = strtok(NULL, "");   //saves value
  182.             if (value == NULL) value = "";
  183.             key = trim(key, "");
  184.             value = trim(value, "");
  185.            
  186.             //checks if key is valid
  187.             for (int i = 0; key[i]; i++)
  188.             {
  189.                 if (((isalpha(key[i])) == 0 && (isdigit(key[i])) == 0)) {
  190.                     fclose(file);
  191.                     return 2;
  192.                 }
  193.             }
  194.  
  195.             //save key and value
  196.             keysnvalue[num_keysnvalues].key = key;
  197.             keysnvalue[num_keysnvalues++].value = value;
  198.         }
  199.  
  200.         if(feof(file))
  201.         {
  202.             if(num_keysnvalues != -1)
  203.             {
  204.                 sect[num_section].keysnvalues = keysnvalue;
  205.                 sect[num_section].keysnvalues_ammount = num_keysnvalues;
  206.             }
  207.             if (num_section != -1)
  208.             {
  209.                 cfg -> section_ammount++;
  210.                 cfg -> sections = sect;
  211.             }
  212.             fclose(file);
  213.             break;
  214.         }
  215.     }
  216.  
  217.     return 0;
  218. }
  219.  
  220.  
  221. int configValue(const struct config * cfg,
  222.                 const char * section,
  223.                 const char * key,
  224.                 enum configValueType type,
  225.                 void * value) {
  226.  
  227.     assert(cfg != NULL);
  228.     assert(section != NULL);
  229.     assert(key != NULL);
  230.     assert(value != NULL);
  231.  
  232.     for (int i = 0; i < cfg -> section_ammount; i++) {
  233.         if (strcmp(cfg -> sections[i].name, section) == 0) {
  234.             for (int j = 0; j < cfg -> sections[i].keysnvalues_ammount; j++) {
  235.                 if (strcmp(cfg -> sections[i].keysnvalues[j].key, key) == 0) {
  236.                     //CfgString
  237.                     if (type == CfgString) {
  238.                         *(char**) value = cfg -> sections[i].keysnvalues[j].value;
  239.                         return 0;
  240.                     }
  241.                     //CfgInteger
  242.                     if (type == CfgInteger) {
  243.                         if(strcmp(cfg -> sections[i].keysnvalues[j].value, ""))
  244.                         {
  245.                             return 3;
  246.                         }
  247.                         char *ptr;
  248.                         if (strtol(cfg -> sections[i].keysnvalues[j].value, &ptr, 10))
  249.                         {
  250.                             *(int*) value = strtol(cfg -> sections[i].keysnvalues[j].value, &ptr, 10);
  251.                             return 0;
  252.                         }
  253.                         else return 3;
  254.                     }
  255.                     //CfgBool
  256.                     if (type == CfgBool) {
  257.                         if(strcmp(cfg -> sections[i].keysnvalues[j].value, ""))
  258.                         {
  259.                             return 3;
  260.                         }
  261.                        
  262.                         char* str = cfg -> sections[i].keysnvalues[j].value;
  263.  
  264.                         for(int i = 0; str[i]; i++) {
  265.                             str[i] = tolower(str[i]);
  266.                         }
  267.  
  268.                         if (strcmp(str, "yes") == 0 || strcmp(str, "true") == 0 || strcmp(str, "1") == 0)
  269.                         {
  270.                             *(int*) value = 1;
  271.                             return 0;
  272.                         }
  273.                         if(strcmp(str, "no") == 0 || strcmp(str, "false") == 0 || strcmp(str, "0") == 0)
  274.                         {
  275.                             *(int*) value = 0;
  276.                             return 0;
  277.                         }
  278.                         return 3;
  279.                     }
  280.                     return 4; // requested type unknown
  281.                 }
  282.             }
  283.             return 2; //key not found
  284.         }
  285.     }
  286.     return 1; //section not found
  287. }
  288.  
  289.  
  290. void configClean(struct config *cfg)
  291. {
  292.     assert(cfg);
  293.    
  294.     //???
  295. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement