This commit begins work on adding more templating features.
const SDArchiverLinkedList *required;
} C_SIMPLE_HTTP_INTERNAL_RequiredCheck;
+void c_simple_http_cleanup_config_value(
+ C_SIMPLE_HTTP_ConfigValue *config_value) {
+ if (config_value) {
+ if (config_value->next) {
+ c_simple_http_cleanup_config_value(config_value->next);
+ }
+ if(config_value->value) {
+ free(config_value->value);
+ }
+ free(config_value);
+ }
+}
+
+void c_simple_http_cleanup_config_value_void_ptr(void *config_value) {
+ c_simple_http_cleanup_config_value(config_value);
+}
+
int c_simple_http_required_iter_fn(void *data, void *ud) {
C_SIMPLE_HTTP_INTERNAL_RequiredIter *req_iter_struct = ud;
uint32_t data_str_length = (uint32_t)strlen(data) + 1;
SDArchiverHashMap *hash_map = simple_archiver_hash_map_init();
unsigned char *key = malloc(separating_key_size);
strncpy((char*)key, separating_key, separating_key_size);
- unsigned char *value = malloc(*value_idx);
- memcpy(value, *value_buf, (*value_idx));
- if (simple_archiver_hash_map_insert(hash_map,
- value,
- key,
- separating_key_size,
- NULL,
- NULL) != 0) {
+ C_SIMPLE_HTTP_ConfigValue *config_value =
+ malloc(sizeof(C_SIMPLE_HTTP_ConfigValue));
+ config_value->value = malloc(*value_idx);
+ config_value->next = NULL;
+ memcpy(config_value->value, *value_buf, (*value_idx));
+ if (simple_archiver_hash_map_insert(
+ hash_map,
+ config_value,
+ key,
+ separating_key_size,
+ c_simple_http_cleanup_config_value_void_ptr,
+ NULL) != 0) {
fprintf(stderr,
"ERROR: Failed to create hash map for new separating_key "
"block!\n");
c_simple_http_clean_up_parsed_config(config);
config->hash_map = NULL;
free(key);
- free(value);
+ free(config_value->value);
+ free(config_value);
return 1;
}
if (simple_archiver_hash_map_insert(
config->hash_map,
wrapper,
- value,
+ config_value->value,
(*value_idx),
c_simple_http_hash_map_wrapper_cleanup_hashmap_fn,
simple_archiver_helper_datastructure_cleanup_nop) != 0) {
c_simple_http_hash_map_wrapper_cleanup(wrapper);
return 1;
}
- simple_archiver_list_add(paths, value,
+ simple_archiver_list_add(paths, config_value->value,
simple_archiver_helper_datastructure_cleanup_nop);
} else if (!(*current_separating_key_value)) {
fprintf(
unsigned char *value = malloc(*value_idx);
memcpy(value, *value_buf, (*value_idx));
- if (simple_archiver_hash_map_insert(hash_map_wrapper->paths,
- value,
- key,
- *key_idx,
- NULL,
- NULL) != 0) {
- fprintf(stderr,
- "ERROR: Internal error failed to insert into hash map with path "
- "\"%s\"!", (*current_separating_key_value));
- c_simple_http_clean_up_parsed_config(config);
- config->hash_map = NULL;
- free(key);
- free(value);
- return 1;
+ // Check if key already exists in wrapped hash-map.
+ C_SIMPLE_HTTP_ConfigValue *config_value =
+ simple_archiver_hash_map_get(hash_map_wrapper->paths, key, *key_idx);
+ if (config_value) {
+ while(config_value->next) {
+ config_value = config_value->next;
+ }
+ config_value->next = malloc(sizeof(C_SIMPLE_HTTP_ConfigValue));
+ config_value->next->value = (char*)value;
+ config_value->next->next = NULL;
+ } else {
+ config_value = malloc(sizeof(C_SIMPLE_HTTP_ConfigValue));
+ config_value->value = (char*)value;
+ config_value->next = NULL;
+ if (simple_archiver_hash_map_insert(
+ hash_map_wrapper->paths,
+ config_value,
+ key,
+ *key_idx,
+ c_simple_http_cleanup_config_value_void_ptr,
+ NULL) != 0) {
+ fprintf(stderr,
+ "ERROR: Internal error failed to insert into hash map with path "
+ "\"%s\"!", (*current_separating_key_value));
+ c_simple_http_clean_up_parsed_config(config);
+ config->hash_map = NULL;
+ free(key);
+ free(value);
+ return 1;
+ }
}
}
(*key_idx) = 0;
/// KEY: "/", VALUE: HashMapWrapper struct
/// KEY: "/inner", VALUE: HashMapWrapper struct
/// KEY: "/inner/further", VALUE: HashMapWrapper struct
+ ///
+ /// Each HashMapWrapper struct's hash-map has the following:
+ /// KEY: VAR_NAME, VALUE: ConfigValue struct
union {
SDArchiverHashMap *paths;
SDArchiverHashMap *hash_map;
typedef C_SIMPLE_HTTP_ParsedConfig C_SIMPLE_HTTP_HashMapWrapper;
+typedef struct C_SIMPLE_HTTP_ConfigValue {
+ char *value;
+ struct C_SIMPLE_HTTP_ConfigValue *next;
+} C_SIMPLE_HTTP_ConfigValue;
+
+void c_simple_http_cleanup_config_value(
+ C_SIMPLE_HTTP_ConfigValue *config_value);
+void c_simple_http_cleanup_config_value_void_ptr(void *config_value);
+
/// Each line in the config should be a key-value pair separated by an equals
/// sign "=". All whitespace is ignored unless if the value is "quoted". A part
/// of a string can be "quoted" if it is surrounded by three single-quotes or
#include <SimpleArchiver/src/helpers.h>
// Local includes.
+#include "config.h"
#include "helpers.h"
/// Returns 0 if "c_string" ends with "_FILE".
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *html_buf = NULL;
size_t html_buf_size = 0;
- const char *html_filename =
+ C_SIMPLE_HTTP_ConfigValue *html_file_value =
simple_archiver_hash_map_get(wrapped_hash_map->hash_map, "HTML_FILE", 10);
- if (html_filename) {
+ if (html_file_value && html_file_value->value) {
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *f = fopen(html_filename, "r");
+ FILE *f = fopen(html_file_value->value, "r");
if (!f) {
return NULL;
}
html_buf[html_file_size] = 0;
html_buf_size = (size_t)html_file_size;
if (files_list_out) {
- char *html_filename_copy = malloc(strlen(html_filename) + 1);
- strcpy(html_filename_copy, html_filename);
+ char *html_filename_copy = malloc(strlen(html_file_value->value) + 1);
+ strcpy(html_filename_copy, html_file_value->value);
simple_archiver_list_add(*files_list_out, html_filename_copy, NULL);
}
} else {
- char *stored_html =
+ C_SIMPLE_HTTP_ConfigValue *stored_html_config_value =
simple_archiver_hash_map_get(wrapped_hash_map->hash_map, "HTML", 5);
- if (!stored_html) {
+ if (!stored_html_config_value || !stored_html_config_value->value) {
return NULL;
}
- size_t stored_html_size = strlen(stored_html) + 1;
+ size_t stored_html_size = strlen(stored_html_config_value->value) + 1;
html_buf = malloc(stored_html_size);
- memcpy(html_buf, stored_html, stored_html_size);
+ memcpy(html_buf, stored_html_config_value->value, stored_html_size);
html_buf_size = stored_html_size - 1;
}
html_buf + last_part->extra,
var_size);
var[var_size] = 0;
- const char *value_c_str =
+ C_SIMPLE_HTTP_ConfigValue *config_value =
simple_archiver_hash_map_get(
wrapped_hash_map->hash_map,
var,
(uint32_t)var_size + 1);
- if (value_c_str) {
+ if (config_value && config_value->value) {
if (c_simple_http_internal_ends_with_FILE(var) == 0) {
- // Load from file specified by "value_c_str".
+ // Load from file specified by "config_value->value".
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
- FILE *f = fopen(value_c_str, "r");
+ FILE *f = fopen(config_value->value, "r");
if (!f) {
fprintf(stderr, "ERROR Failed to open file \"%s\"!\n",
- value_c_str);
+ config_value->value);
return NULL;
} else if (fseek(f, 0, SEEK_END) != 0) {
fprintf(stderr, "ERROR Failed to seek to end of file \"%s\"!\n",
- value_c_str);
+ config_value->value);
return NULL;
}
long file_size = ftell(f);
if (file_size <= 0) {
fprintf(stderr, "ERROR Size of file \"%s\" is invalid!\n",
- value_c_str);
+ config_value->value);
return NULL;
} else if (fseek(f, 0, SEEK_SET) != 0) {
fprintf(stderr, "ERROR Failed to seek to start of file "
"\"%s\"!\n",
- value_c_str);
+ config_value->value);
return NULL;
}
string_part.size = (size_t)file_size + 1;
f)
!= 1) {
fprintf(stderr, "ERROR Failed to read from file \"%s\"!\n",
- value_c_str);
+ config_value->value);
return NULL;
}
string_part.buf[string_part.size - 1] = 0;
if (files_list_out) {
- char *variable_filename = malloc(strlen(value_c_str) + 1);
- strcpy(variable_filename, value_c_str);
+ char *variable_filename = malloc(strlen(config_value->value) + 1);
+ strcpy(variable_filename, config_value->value);
simple_archiver_list_add(
*files_list_out, variable_filename, NULL);
}
} else {
- // Variable data is "value_c_str".
- string_part.size = strlen(value_c_str) + 1;
+ // Variable data is "config_value->value".
+ string_part.size = strlen(config_value->value) + 1;
string_part.buf = malloc(string_part.size);
- memcpy(string_part.buf, value_c_str, string_part.size);
+ memcpy(string_part.buf, config_value->value, string_part.size);
string_part.buf[string_part.size - 1] = 0;
string_part.extra = idx + 1;
}
simple_archiver_hash_map_get(templates.paths, "/", 2);
ASSERT_TRUE(first_path_map_wrapper);
- const char *value =
+ C_SIMPLE_HTTP_ConfigValue *value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "PATH", 5);
ASSERT_TRUE(value);
- ASSERT_STREQ(value, "/");
+ ASSERT_TRUE(value->value);
+ ASSERT_STREQ(value->value, "/");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "HTML", 5);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, " one two three ");
+ ASSERT_STREQ(value->value, " one two three ");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST", 5);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, " \"one two \"three ");
+ ASSERT_STREQ(value->value, " \"one two \"three ");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST2", 6);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, "'\"onetwo\"three''");
+ ASSERT_STREQ(value->value, "'\"onetwo\"three''");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST3", 6);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, " \"one two \"three ''");
+ ASSERT_STREQ(value->value, " \"one two \"three ''");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST4", 6);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, " \"\"\"one two \"\"\"three ");
+ ASSERT_STREQ(value->value, " \"\"\"one two \"\"\"three ");
value =
simple_archiver_hash_map_get(first_path_map_wrapper->paths, "TEST5", 6);
ASSERT_TRUE(value);
+ ASSERT_TRUE(value->value);
// printf("%s\n", value);
- ASSERT_STREQ(value, " '''one two '''three ");
+ ASSERT_STREQ(value->value, " '''one two '''three ");
simple_archiver_list_free(&required_names);
required_names = simple_archiver_list_init();