void b_error_set(b_error *err, enum b_error_type type, int _errno, char *message, b_string *path) { if (err == NULL) return; err->type = type; err->_errno = _errno; if ( type == B_ERROR_FATAL ) { err->status = -1; } b_string_free(err->message); b_string_free(err->path); if ((err->message = b_string_new(message)) == NULL) { goto error_string_dup_message; } if ((err->path = b_string_dup(path)) == NULL) { goto error_string_dup_path; } if (err->callback) { err->callback(err); } return; error_string_dup_path: b_string_free(err->message); err->message = NULL; error_string_dup_message: return; }
void b_trie_foreach(b_trie_t *trie, void (*func)(const char *key, void *data)) { if (trie->root == NULL) return; b_string_t *str = b_string_new(); b_trie_foreach_node(trie->root, str, func); }
static void b_trie_foreach_node(b_trie_node_t *node, b_string_t *str, void (*func)(const char *key, void *data)) { if (node == NULL) return; if (node->key == '\0') { func(str->str, node->data); b_string_free(str, true); } if (node->child != NULL) { b_string_t *child = b_string_new(); child = b_string_append(child, str->str); child = b_string_append_c(child, node->key); b_trie_foreach_node(node->child, child, func); } if (node->next != NULL) b_trie_foreach_node(node->next, str, func); if (node->child != NULL && node->next == NULL) b_string_free(str, true); }
char* blogc_render(b_slist_t *tmpl, b_slist_t *sources, b_trie_t *config, bool listing) { if (tmpl == NULL || sources == NULL) return NULL; b_slist_t *current_source = NULL; b_slist_t *listing_start = NULL; b_string_t *str = b_string_new(); b_trie_t *tmp_source = NULL; const char *config_value = NULL; const char *config_var = NULL; char *config_value2 = NULL; char *defined = NULL; unsigned int if_count = 0; unsigned int if_skip = 0; bool if_not = false; bool inside_block = false; bool evaluate = false; int cmp = 0; b_slist_t *tmp = tmpl; while (tmp != NULL) { blogc_template_stmt_t *stmt = tmp->data; switch (stmt->type) { case BLOGC_TEMPLATE_CONTENT_STMT: if (stmt->value != NULL) b_string_append(str, stmt->value); break; case BLOGC_TEMPLATE_BLOCK_STMT: inside_block = true; if_count = 0; if (0 == strcmp("entry", stmt->value)) { if (listing) { // we can just skip anything and walk until the next // 'endblock' while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) { tmp = tmp->next; stmt = tmp->data; } break; } current_source = sources; tmp_source = current_source->data; } else if ((0 == strcmp("listing", stmt->value)) || (0 == strcmp("listing_once", stmt->value))) { if (!listing) { // we can just skip anything and walk until the next // 'endblock' while (stmt->type != BLOGC_TEMPLATE_ENDBLOCK_STMT) { tmp = tmp->next; stmt = tmp->data; } break; } } if (0 == strcmp("listing", stmt->value)) { if (current_source == NULL) { listing_start = tmp; current_source = sources; } tmp_source = current_source->data; } break; case BLOGC_TEMPLATE_VARIABLE_STMT: if (stmt->value != NULL) { config_var = NULL; if (0 == strcmp(stmt->value, "DATE_FORMATTED")) config_var = "DATE"; else if (0 == strcmp(stmt->value, "DATE_FIRST_FORMATTED")) config_var = "DATE_FIRST"; else if (0 == strcmp(stmt->value, "DATE_LAST_FORMATTED")) config_var = "DATE_LAST"; if (config_var != NULL) { config_value2 = blogc_format_date( blogc_get_variable(config_var, config, inside_block ? tmp_source : NULL), config, inside_block ? tmp_source : NULL); if (config_value2 != NULL) { b_string_append(str, config_value2); free(config_value2); config_value2 = NULL; break; } } else { config_value = blogc_get_variable(stmt->value, config, inside_block ? tmp_source : NULL); if (config_value != NULL) b_string_append(str, config_value); } } break; case BLOGC_TEMPLATE_ENDBLOCK_STMT: inside_block = false; if (listing_start != NULL && current_source != NULL) { current_source = current_source->next; if (current_source != NULL) { tmp = listing_start; continue; } else listing_start = NULL; } break; case BLOGC_TEMPLATE_IFNDEF_STMT: if_not = true; case BLOGC_TEMPLATE_IF_STMT: case BLOGC_TEMPLATE_IFDEF_STMT: defined = NULL; if (stmt->value != NULL) { config_var = NULL; if (0 == strcmp(stmt->value, "DATE_FORMATTED")) config_var = "DATE"; else if (0 == strcmp(stmt->value, "DATE_FIRST_FORMATTED")) config_var = "DATE_FIRST"; else if (0 == strcmp(stmt->value, "DATE_LAST_FORMATTED")) config_var = "DATE_LAST"; if (config_var != NULL) { config_value2 = blogc_format_date( blogc_get_variable(config_var, config, inside_block ? tmp_source : NULL), config, inside_block ? tmp_source : NULL); if (config_value2 != NULL) { defined = config_value2; config_value2 = NULL; } } else defined = b_strdup(blogc_get_variable(stmt->value, config, inside_block ? tmp_source : NULL)); } evaluate = false; if (stmt->op != 0) { if (defined != NULL && stmt->value2 != NULL) { cmp = strcmp(defined, stmt->value2); if (cmp != 0 && stmt->op & BLOGC_TEMPLATE_OP_NEQ) evaluate = true; else if (cmp == 0 && stmt->op & BLOGC_TEMPLATE_OP_EQ) evaluate = true; else if (cmp < 0 && stmt->op & BLOGC_TEMPLATE_OP_LT) evaluate = true; else if (cmp > 0 && stmt->op & BLOGC_TEMPLATE_OP_GT) evaluate = true; } } else { if (if_not && defined == NULL) evaluate = true; if (!if_not && defined != NULL) evaluate = true; } if (!evaluate) { if_skip = if_count; // at this point we can just skip anything, counting the // number of 'if's, to know how many 'endif's we need to // skip as well. while (1) { tmp = tmp->next; stmt = tmp->data; if ((stmt->type == BLOGC_TEMPLATE_IF_STMT) || (stmt->type == BLOGC_TEMPLATE_IFDEF_STMT) || (stmt->type == BLOGC_TEMPLATE_IFNDEF_STMT)) { if_count++; continue; } if (stmt->type == BLOGC_TEMPLATE_ENDIF_STMT) { if (if_count > if_skip) { if_count--; continue; } if (if_count == if_skip) break; } } } free(defined); defined = NULL; if_not = false; break; case BLOGC_TEMPLATE_ENDIF_STMT: if_count--; break; } tmp = tmp->next; } return b_string_free(str, false); }