Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "config.h"
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <assert.h>
- //deletes unwanted chars
- static char* trim(char* toTrim, const char * toIgnore)
- {
- if (strlen(toTrim) < 1) return 0;
- //delete from backwards
- for(int i = strlen(toTrim);; i--)
- {
- if(isspace(toTrim[i]) || strchr(toIgnore, toTrim[i]))
- {
- toTrim[i] = '\0';
- }
- else
- {
- break;
- }
- }
- //delete from start
- while (*toTrim && (isspace(*toTrim) || strchr(toIgnore, *toTrim)))
- toTrim++;
- return toTrim;
- }
- //reads config
- int configRead(struct config *cfg, const char *name)
- {
- assert(cfg != NULL);
- assert(name != NULL);
- //open file
- FILE* file = fopen(name, "r");
- //check if opened
- if (file == NULL) {
- return 1;
- }
- struct section * sect = malloc(sizeof(struct section) * 255);
- struct keysnvalues * keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
- int num_section = -1;
- int num_keysnvalues = 0;
- for(; !feof(file);)
- {
- int lineEmpty = 1;
- //read line
- int CUR_MAX = 4095;
- char *buffer = (char*) malloc(sizeof(char) * CUR_MAX); // allocate buffer.
- int length = 0;
- int validSection = -1; // section doesn't start on the beggining
- int section = 0; // checks if after [*] line is empty
- int equals = 0;
- for (int ch = fgetc(file); ch != '\0' && ch != '\n' && ch != EOF; ch = fgetc(file))
- {
- if(length == CUR_MAX) { // time to expand ?
- CUR_MAX *= 2; // expand to double the current size of anything similar.
- buffer = realloc(buffer, CUR_MAX); // re allocate memory.
- }
- validSection++;
- if(section == 2 && !(isspace(ch)) != 0) // checks if after [*] line is empty
- {
- fclose(file);
- return 2;
- }
- //(ch == '[' && length == 0) ? (section = 1) : (section = 0); // checks if after [*] line is empty
- if(ch == '[' && length == 0)
- {
- section = 1;
- }
- if(ch == ']' && section == 1) section = 2; // checks if after [*] line is empty
- if(ch == '[' && (validSection != length) && lineEmpty == 1) // section doesn't start on the beggining
- {
- fclose(file);
- return 2;
- }
- if(lineEmpty == 1 && !(isspace(ch))) lineEmpty = 0; //checks if empty line
- if(lineEmpty == 1 && (isspace(ch))) continue; //doesn't save white-characters before first valid
- if(equals == 1 && ch == '=') equals = 2;
- if(length == 0 && ch != '[') equals = 1;
- buffer[length] = ch; // stuff in buffer.
- length++;
- }
- if(feof(file) && (lineEmpty || buffer[0] == ';'))
- {
- if(num_keysnvalues != -1)
- {
- sect[num_section].keysnvalues = keysnvalue;
- sect[num_section].keysnvalues_ammount = num_keysnvalues;
- }
- if (num_section != -1)
- {
- cfg -> section_ammount++;
- cfg -> sections = sect;
- }
- fclose(file);
- break;
- }
- //skip comented line
- if(buffer[0] == ';' || lineEmpty) continue;
- if(equals == 1)
- {
- fclose(file);
- return 2;
- }
- buffer[length] = '\0';
- /*_____________________________________________
- Case SECTION
- _____________________________________________*/
- if (buffer[0] == '[')
- {
- buffer = trim(buffer, "[]");
- //checks if section is valid
- for (int i=0; buffer[i]; i++)
- {
- // const char * valid_characters = "-_:";
- if (!((buffer[i] == '-' || buffer[i] == '_' || buffer[i] == ':') || (isalpha(buffer[i])) || (isdigit(buffer[i])))) {
- fclose(file);
- return 2;
- }
- }
- //saves section name
- if (num_section == -1)
- {
- //sect[++num_section].name = (char *)malloc(strlen(buffer));
- sect[++num_section].name = buffer;
- //strcpy(sect[num_section].name, buffer);
- }
- else
- {
- //check if section not duplication
- for (int i = 0; i < num_section; i++) {
- if (strcmp(sect[i].name, buffer) == 0) {
- fclose(file);
- return 2;
- }
- }
- //sect[num_section].keysnvalues = malloc(sizeof(*keysnvalue));
- sect[num_section].keysnvalues = keysnvalue;
- sect[num_section].keysnvalues_ammount = num_keysnvalues;
- cfg -> section_ammount++;
- //start with new keysnvalue
- num_keysnvalues = 0;
- keysnvalue = malloc(sizeof(struct keysnvalues) * 255);
- sect[++num_section].name = buffer;
- sect[num_section].keysnvalues = 0;
- }
- }
- else
- /*_____________________________________________
- Case key==value
- _____________________________________________*/
- {
- if (num_section == -1)
- {
- fclose(file);
- return 2;
- }
- char *key = strtok(buffer, "="); //saves key
- char *value = strtok(NULL, ""); //saves value
- if (value == NULL) value = "";
- key = trim(key, "");
- value = trim(value, "");
- //checks if key is valid
- for (int i = 0; key[i]; i++)
- {
- if (((isalpha(key[i])) == 0 && (isdigit(key[i])) == 0)) {
- fclose(file);
- return 2;
- }
- }
- //save key and value
- keysnvalue[num_keysnvalues].key = key;
- keysnvalue[num_keysnvalues++].value = value;
- }
- if(feof(file))
- {
- if(num_keysnvalues != -1)
- {
- sect[num_section].keysnvalues = keysnvalue;
- sect[num_section].keysnvalues_ammount = num_keysnvalues;
- }
- if (num_section != -1)
- {
- cfg -> section_ammount++;
- cfg -> sections = sect;
- }
- fclose(file);
- break;
- }
- }
- return 0;
- }
- int configValue(const struct config * cfg,
- const char * section,
- const char * key,
- enum configValueType type,
- void * value) {
- assert(cfg != NULL);
- assert(section != NULL);
- assert(key != NULL);
- assert(value != NULL);
- for (int i = 0; i < cfg -> section_ammount; i++) {
- if (strcmp(cfg -> sections[i].name, section) == 0) {
- for (int j = 0; j < cfg -> sections[i].keysnvalues_ammount; j++) {
- if (strcmp(cfg -> sections[i].keysnvalues[j].key, key) == 0) {
- //CfgString
- if (type == CfgString) {
- *(char**) value = cfg -> sections[i].keysnvalues[j].value;
- return 0;
- }
- //CfgInteger
- if (type == CfgInteger) {
- if(strcmp(cfg -> sections[i].keysnvalues[j].value, ""))
- {
- return 3;
- }
- char *ptr;
- if (strtol(cfg -> sections[i].keysnvalues[j].value, &ptr, 10))
- {
- *(int*) value = strtol(cfg -> sections[i].keysnvalues[j].value, &ptr, 10);
- return 0;
- }
- else return 3;
- }
- //CfgBool
- if (type == CfgBool) {
- if(strcmp(cfg -> sections[i].keysnvalues[j].value, ""))
- {
- return 3;
- }
- char* str = cfg -> sections[i].keysnvalues[j].value;
- for(int i = 0; str[i]; i++) {
- str[i] = tolower(str[i]);
- }
- if (strcmp(str, "yes") == 0 || strcmp(str, "true") == 0 || strcmp(str, "1") == 0)
- {
- *(int*) value = 1;
- return 0;
- }
- if(strcmp(str, "no") == 0 || strcmp(str, "false") == 0 || strcmp(str, "0") == 0)
- {
- *(int*) value = 0;
- return 0;
- }
- return 3;
- }
- return 4; // requested type unknown
- }
- }
- return 2; //key not found
- }
- }
- return 1; //section not found
- }
- void configClean(struct config *cfg)
- {
- assert(cfg);
- //???
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement