Compare commits

..

No commits in common. "e458c6e87bb84d39d923def4ea4a47e7f88d9ce8" and "1d5fb6bbbd220471160fa684ca139d12e408e4c3" have entirely different histories.

3 changed files with 180 additions and 212 deletions

View file

@ -76,145 +76,6 @@
} \ } \
} }
#define CHECK_ADD_VALUE() \
if (value_idx < C_SIMPLE_HTTP_CONFIG_BUF_SIZE) { \
value_buf[value_idx++] = 0; \
} else { \
fprintf(stderr, \
"ERROR: config file \"value\" is larger than %u bytes!\n", \
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1); \
c_simple_http_clean_up_parsed_config(&config); \
config.hash_map = NULL; \
return config; \
} \
state &= 0xFFFFFFFE; \
\
/* Check if key is separating_key. */ \
if (strcmp((char*)key_buf, separating_key) == 0) { \
if (current_separating_key_value) { \
if (required_names) { \
C_SIMPLE_HTTP_HashMapWrapper *hash_map_wrapper = \
simple_archiver_hash_map_get( \
config.hash_map, \
current_separating_key_value, \
current_separating_key_value_size); \
C_SIMPLE_HTTP_INTERNAL_RequiredIter req_iter_struct; \
req_iter_struct.hash_map = hash_map_wrapper->hash_map; \
if (paths->count != 0) { \
req_iter_struct.path = paths->tail->prev->data; \
} else { \
req_iter_struct.path = NULL; \
} \
const char *missing_key = simple_archiver_list_get( \
required_names, \
c_simple_http_required_iter_fn, \
&req_iter_struct); \
if (missing_key) { \
fprintf(stderr, \
"WARNING: config file did not have required key \"%s\"!" \
" Returning NULL map!\n", \
missing_key); \
c_simple_http_clean_up_parsed_config(&config); \
config.hash_map = NULL; \
return config; \
} \
} \
\
state &= 0xFFFFFFFD; \
free(current_separating_key_value); \
} \
current_separating_key_value = malloc(value_idx); \
memcpy(current_separating_key_value, value_buf, value_idx); \
current_separating_key_value_size = value_idx; \
/* At this point, key is separating_key. */ \
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) { \
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); \
return config; \
} \
\
C_SIMPLE_HTTP_HashMapWrapper *wrapper = malloc(sizeof(C_SIMPLE_HTTP_HashMapWrapper)); \
wrapper->paths = hash_map; \
\
if (simple_archiver_hash_map_insert( \
&config.hash_map, \
wrapper, \
value, \
value_idx, \
c_simple_http_hash_map_wrapper_cleanup_hashmap_fn, \
simple_archiver_helper_datastructure_cleanup_nop) != 0) { \
fprintf(stderr, \
"ERROR: Failed to insert new hash map for new PATH block!\n"); \
c_simple_http_clean_up_parsed_config(&config); \
config.hash_map = NULL; \
c_simple_http_hash_map_wrapper_cleanup(wrapper); \
return config; \
} \
simple_archiver_list_add(paths, value, \
simple_archiver_helper_datastructure_cleanup_nop); \
} else if (!current_separating_key_value) { \
fprintf( \
stderr, \
"ERROR: config file has invalid key: No preceding \"%s\" " \
"key!\n", separating_key); \
c_simple_http_clean_up_parsed_config(&config); \
config.hash_map = NULL; \
return config; \
} else { \
/* Non-separating_key key. */ \
C_SIMPLE_HTTP_HashMapWrapper *hash_map_wrapper = \
simple_archiver_hash_map_get( \
config.hash_map, \
current_separating_key_value, \
current_separating_key_value_size); \
if (!hash_map_wrapper) { \
fprintf(stderr, \
"ERROR: Internal error failed to get existing hash map with path " \
"\"%s\"!", current_separating_key_value); \
c_simple_http_clean_up_parsed_config(&config); \
config.hash_map = NULL; \
return config; \
} \
\
unsigned char *key = malloc(key_idx); \
memcpy(key, key_buf, key_idx); \
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 config; \
} \
} \
key_idx = 0; \
value_idx = 0;
void c_simple_http_hash_map_wrapper_cleanup_hashmap_fn(void *data) { void c_simple_http_hash_map_wrapper_cleanup_hashmap_fn(void *data) {
C_SIMPLE_HTTP_HashMapWrapper *wrapper = data; C_SIMPLE_HTTP_HashMapWrapper *wrapper = data;
simple_archiver_hash_map_free(&wrapper->paths); simple_archiver_hash_map_free(&wrapper->paths);
@ -418,18 +279,188 @@ C_SIMPLE_HTTP_ParsedConfig c_simple_http_parse_config(
return config; return config;
} }
} else { } else {
CHECK_ADD_VALUE() if (value_idx < C_SIMPLE_HTTP_CONFIG_BUF_SIZE) {
value_buf[value_idx++] = 0;
} else {
fprintf(stderr,
"ERROR: config file \"value\" is larger than %u bytes!\n",
C_SIMPLE_HTTP_CONFIG_BUF_SIZE - 1);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
state &= 0xFFFFFFFE;
// Check if key is separating_key.
if (strcmp((char*)key_buf, separating_key) == 0) {
if (current_separating_key_value) {
if (required_names) {
C_SIMPLE_HTTP_HashMapWrapper *hash_map_wrapper =
simple_archiver_hash_map_get(
config.hash_map,
current_separating_key_value,
current_separating_key_value_size);
C_SIMPLE_HTTP_INTERNAL_RequiredIter req_iter_struct;
req_iter_struct.hash_map = hash_map_wrapper->hash_map;
if (paths->count != 0) {
req_iter_struct.path = paths->tail->prev->data;
} else {
req_iter_struct.path = NULL;
}
const char *missing_key = simple_archiver_list_get(
required_names,
c_simple_http_required_iter_fn,
&req_iter_struct);
if (missing_key) {
fprintf(stderr,
"WARNING: config file did not have required key \"%s\"!"
" Returning NULL map!\n",
missing_key);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
}
state &= 0xFFFFFFFD;
free(current_separating_key_value);
}
current_separating_key_value = malloc(value_idx);
memcpy(current_separating_key_value, value_buf, value_idx);
current_separating_key_value_size = value_idx;
// At this point, key is separating_key.
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) {
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);
return config;
}
C_SIMPLE_HTTP_HashMapWrapper *wrapper = malloc(sizeof(C_SIMPLE_HTTP_HashMapWrapper));
wrapper->paths = hash_map;
if (simple_archiver_hash_map_insert(
&config.hash_map,
wrapper,
value,
value_idx,
c_simple_http_hash_map_wrapper_cleanup_hashmap_fn,
simple_archiver_helper_datastructure_cleanup_nop) != 0) {
fprintf(stderr,
"ERROR: Failed to insert new hash map for new PATH block!\n");
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
c_simple_http_hash_map_wrapper_cleanup(wrapper);
return config;
}
simple_archiver_list_add(paths, value,
simple_archiver_helper_datastructure_cleanup_nop);
} else if (!current_separating_key_value) {
fprintf(
stderr,
"ERROR: config file has invalid key: No preceding \"%s\" "
"key!\n", separating_key);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
} else {
// Non-separating_key key.
C_SIMPLE_HTTP_HashMapWrapper *hash_map_wrapper =
simple_archiver_hash_map_get(
config.hash_map,
current_separating_key_value,
current_separating_key_value_size);
if (!hash_map_wrapper) {
fprintf(stderr,
"ERROR: Internal error failed to get existing hash map with path "
"\"%s\"!", current_separating_key_value);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
unsigned char *key = malloc(key_idx);
memcpy(key, key_buf, key_idx);
unsigned char *value;
if (strcmp((char*)key_buf, "HTML_FILE") == 0) {
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
FILE *html_file = fopen((char*)value_buf, "r");
if (!html_file) {
fprintf(stderr,
"ERROR: Internal error failed to open HTML_FILE \"%s\"!",
value_buf);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
fseek(html_file, 0, SEEK_END);
long file_size = ftell(html_file);
if (file_size <= 0) {
fprintf(stderr,
"ERROR: Internal error HTML_FILE \"%s\" is invalid size!",
value_buf);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
fseek(html_file, 0, SEEK_SET);
unsigned long file_size_u = file_size;
unsigned char *read_buf = malloc(file_size_u);
size_t read_amount = 0;
read_amount = fread(read_buf, 1, file_size_u, html_file);
if (read_amount != file_size_u) {
fprintf(stderr, "ERROR: Failed to read HTML_FILE \"%s\"!\n",
value_buf);
free(read_buf);
c_simple_http_clean_up_parsed_config(&config);
config.hash_map = NULL;
return config;
}
value = read_buf;
} else {
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 config;
}
}
key_idx = 0;
value_idx = 0;
} }
} }
} }
simple_archiver_helper_cleanup_FILE(&f); simple_archiver_helper_cleanup_FILE(&f);
if ((state & 0x1) == 1 && (state & 0xC) == 0 && value_idx != 0) {
// Leftover "value" not added yet.
CHECK_ADD_VALUE()
}
if (!current_separating_key_value) { if (!current_separating_key_value) {
fprintf(stderr, "ERROR: Never got \"PATH\" key in config!\n"); fprintf(stderr, "ERROR: Never got \"PATH\" key in config!\n");
c_simple_http_clean_up_parsed_config(&config); c_simple_http_clean_up_parsed_config(&config);

View file

@ -248,7 +248,7 @@ char *c_simple_http_path_to_generated(
return NULL; return NULL;
} }
C_SIMPLE_HTTP_INTERNAL_Template_Node to_fill; C_SIMPLE_HTTP_INTERNAL_Template_Node to_fill;
to_fill.html = malloc(final_size + 1); to_fill.html = malloc(final_size);
to_fill.html_size = 0; to_fill.html_size = 0;
to_fill.html_capacity = final_size; to_fill.html_capacity = final_size;
if (simple_archiver_list_get( if (simple_archiver_list_get(
@ -259,7 +259,6 @@ char *c_simple_http_path_to_generated(
free(to_fill.html); free(to_fill.html);
return NULL; return NULL;
} }
to_fill.html[final_size] = 0;
return to_fill.html; return to_fill.html;
} else { } else {
// Prevent cleanup fn from "free"ing html_buf and return it verbatim. // Prevent cleanup fn from "free"ing html_buf and return it verbatim.

View file

@ -120,11 +120,9 @@ int main(void) {
ASSERT_TRUE( ASSERT_TRUE(
fwrite("TEST3=something\n", 1, 16, test_file) fwrite("TEST3=something\n", 1, 16, test_file)
== 16); == 16);
// No endline at the end of file to check for case where the config file
// has no endline.
ASSERT_TRUE( ASSERT_TRUE(
fwrite("TEST2=' \"one two \"three ''", 1, 26, test_file) fwrite("TEST2=' \"one two \"three ''\n", 1, 27, test_file)
== 26); == 27);
simple_archiver_helper_cleanup_FILE(&test_file); simple_archiver_helper_cleanup_FILE(&test_file);
__attribute__((cleanup(simple_archiver_list_free))) __attribute__((cleanup(simple_archiver_list_free)))
@ -281,66 +279,6 @@ int main(void) {
"<h1> Some text. </h1><br><h2> More text. </h2>") "<h1> Some text. </h1><br><h2> More text. </h2>")
== 0); == 0);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
const char *test_http_template_filename3 =
"/tmp/c_simple_http_template_test3.config";
const char *test_http_template_html_filename =
"/tmp/c_simple_http_template_test.html";
test_file = fopen(test_http_template_filename3, "w");
ASSERT_TRUE(test_file);
ASSERT_TRUE(
fwrite(
"PATH=/\nHTML_FILE=/tmp/c_simple_http_template_test.html\n",
1,
55,
test_file)
== 55);
ASSERT_TRUE(
fwrite(
"testVar=''' testVar text. '''\ntestVar2=''' testVar2 text. '''\n",
1,
62,
test_file)
== 62);
simple_archiver_helper_cleanup_FILE(&test_file);
test_file = fopen(test_http_template_html_filename, "w");
ASSERT_TRUE(test_file);
ASSERT_TRUE(
fwrite(
"<h1>{{{testVar}}}</h1><br><h2>{{{testVar2}}}</h2>",
1,
49,
test_file)
== 49);
simple_archiver_helper_cleanup_FILE(&test_file);
simple_archiver_list_free(&required_names);
required_names = simple_archiver_list_init();
simple_archiver_list_add(
required_names,
"HTML_FILE",
simple_archiver_helper_datastructure_cleanup_nop);
c_simple_http_clean_up_parsed_config(&config);
config = c_simple_http_parse_config(
test_http_template_filename3,
"PATH",
required_names
);
ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated("/", &config);
ASSERT_TRUE(buf != NULL);
printf("%s\n", buf);
ASSERT_TRUE(
strcmp(
buf,
"<h1> testVar text. </h1><br><h2> testVar2 text. </h2>")
== 0);
simple_archiver_helper_cleanup_c_string(&buf);
} }
RETURN() RETURN()