int parse_object(const char** input, JzonValue* output, bool root_object, JzonAllocator* allocator) { if (current(input) == '{') next(input); else if (!root_object) return -1; output->is_object = true; // Empty object. if (current(input) == '}') { output->size = 0; return 0; } Array object_values = { 0 }; while (current(input)) { JzonKeyValuePair* pair = (JzonKeyValuePair*)allocator->allocate(sizeof(JzonKeyValuePair)); skip_whitespace(input); char* key = parse_keyname(input, allocator); skip_whitespace(input); if (key == NULL || current(input) != ':') return -1; next(input); JzonValue* value = (JzonValue*)allocator->allocate(sizeof(JzonValue)); memset(value, 0, sizeof(JzonValue)); int error = parse_value(input, value, allocator); if (error != 0) return error; pair->key = key; pair->key_hash = hash_str(key); pair->value = value; arr_insert(&object_values, pair, find_object_pair_insertion_index((JzonKeyValuePair**)object_values.arr, object_values.size, pair->key_hash), allocator); skip_whitespace(input); if (current(input) == '}') { next(input); break; } } output->size = object_values.size; output->object_values = (JzonKeyValuePair**)object_values.arr; return 0; }
/* Parses a config file into a config_t struct. @param config The config struct to parse the config too. @param file is the config file path to load. @return 1 if everthing went fine, 0 if there was a problem. */ int parse_config(config_t* config, char* file) { FILE* fid = fopen(file, "r"); if(fid == NULL) { log_error("Could not open file (%s): %s\n", file, strerror(errno)); return 0; } entry_t* mapping; char buffer[MAX_BUFFER]; unsigned int linenum = 0; char section[MAX_SECTION] = ""; char* key = NULL; char* value = NULL; while(fgets(buffer, MAX_BUFFER, fid)) { linenum++; trim(buffer); if(strlen(buffer) == 0 || buffer[0] == '#') { continue; } if(buffer[0] == '[' && buffer[strlen(buffer)-1] == ']') { // Parse new section strncpy(section, buffer + 1, sizeof(section)); section[strlen(section)-1] = '\0'; log_debug("config: new section: '%s'\n", section); if(!strlen(section)) { log_error("config: line %d: bad section name\n", linenum); return 0; } if(strcmp(section, "options")) { // start a new mapping record mapping = malloc(sizeof(entry_t)); if(mapping == NULL) { log_error("Could not malloc: %s\n", strerror(errno)); return 0; } mapping->key = parse_keyname(section); mapping->command = NULL; mapping->duration = 0; mapping->blocker = 0; add_mapping(config, mapping); } } else { // Parse parameters if(!strlen(section)) { log_error("config: line %d: all directives must belong to a section\n", linenum); return 0; } value = buffer; key = strsep(&value, "="); if(key == NULL) { log_error("config: line %d: syntax error\n", linenum); return 0; } trim(key); key = strtoupper(key); if(value == NULL) { // Non value parameter keys if(!strcmp(section, "options")) { if(!strcmp(key,"DEBUG")) { log_debug("config: %s: debug: true\n", section); config->debug = 1; } else { log_error("config: line %d: syntax error\n", linenum); return 0; } } else { if(!strcmp(key, "BLOCKER")) { mapping->blocker = 1; log_debug("config: %s: blocker: true\n", section); } else { log_error("config: line %d: syntax error\n", linenum); return 0; } } } else { trim(value); if(!strcmp(section, "options")) { // Parse option parameter if(!strcmp(key, "LOGFILE")) { strncpy(config->logfile, value, PATH_MAX-1); config->logfile[PATH_MAX-1] = '\0'; log_debug("config: log file: %s\n", config->logfile); } else if(!strcmp(key, "PIDFILE")) { strncpy(config->pidfile, value, PATH_MAX-1); config->pidfile[PATH_MAX-1] = '\0'; log_debug("config: pid file: %s\n", config->pidfile); } else if(!strcmp(key, "DEVICE")) { strncpy(config->device, value, PATH_MAX-1); config->device[PATH_MAX-1] = '\0'; log_debug("config: device: %s\n", config->device); } else { log_error("config: line %d: syntax error\n", linenum); return 0; } } else { // Parse mapping parameter if(!strcmp(key, "COMMAND")) { mapping->command = malloc((strlen(value) + 1) * sizeof(char)); if(mapping->command == NULL) { log_error("Could not malloc: %s\n", strerror(errno)); return 0; } strcpy(mapping->command, value); log_debug("config: %s: command: %s\n", section, mapping->command); } else if(!strcmp(key, "DURATION")) { mapping->duration = atoi(value); log_debug("config: %s: duration: %d\n", section, mapping->duration); } else { log_error("config: line %d: syntax error\n", linenum); return 0; } } // end of mapping value parsing } // enf of value parsing } // end of section/parameter parsing buffer[0] = '\0'; // ToDo: Do I need this? } // end of while fclose(fid); return 1; }