#include "Utility.h" #include "../Scraping/Scraping.h" #include #include #include #include int hex_to_int(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } char *get_theme(const char *default_theme) { char *cookie = get_cookie("theme"); if (cookie && (strcmp(cookie, "light") == 0 || strcmp(cookie, "dark") == 0)) { return cookie; } free(cookie); return strdup(default_theme); } char *get_locale(const char *default_locale) { char *cookie = get_cookie("locale"); if (cookie && beaker_get_locale_meta(cookie) != NULL) { return cookie; } free(cookie); return strdup(default_locale); } static int engine_id_casecmp(const char *a, const char *b) { while (*a && *b) { char la = *a; char lb = *b; if (la >= 'A' && la <= 'Z') la = la - 'A' + 'a'; if (lb >= 'A' && lb <= 'Z') lb = lb - 'A' + 'a'; if (la != lb) return 0; a++; b++; } return *a == *b; } int is_engine_id_enabled(const char *engine_id) { if (!engine_id) return 0; for (int i = 0; i < ENGINE_COUNT; i++) { if (ENGINE_REGISTRY[i].enabled && engine_id_casecmp(ENGINE_REGISTRY[i].id, engine_id)) { return 1; } } return 0; } int get_user_engines(char ***out_ids, int *out_count) { *out_ids = NULL; *out_count = 0; char *cookie = get_cookie("engines"); if (!cookie || cookie[0] == '\0') { free(cookie); return -1; } char **ids = NULL; int count = 0; char *copy = strdup(cookie); if (!copy) { free(cookie); return -1; } char *saveptr; char *token = strtok_r(copy, ",", &saveptr); while (token) { while (*token == ' ' || *token == '\t') token++; if (token[0] != '\0' && is_engine_id_enabled(token)) { char **new_ids = realloc(ids, sizeof(char *) * (count + 1)); if (new_ids) { ids = new_ids; ids[count] = strdup(token); count++; } } token = strtok_r(NULL, ",", &saveptr); } free(copy); free(cookie); if (count == 0) { free(ids); return -1; } *out_ids = ids; *out_count = count; return 0; } int user_engines_contains(const char *engine_id, char **ids, int count) { if (!engine_id || !ids) return 0; for (int i = 0; i < count; i++) { if (engine_id_casecmp(ids[i], engine_id)) return 1; } return 0; } int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count) { char ***old_collection = *collection; int *old_inner_counts = *inner_counts; char ***new_collection = (char ***)malloc(sizeof(char **) * (current_count + 1)); int *new_inner_counts = (int *)malloc(sizeof(int) * (current_count + 1)); if (!new_collection || !new_inner_counts) { free(new_collection); free(new_inner_counts); return current_count; } if (*collection && current_count > 0) { memcpy(new_collection, *collection, sizeof(char **) * current_count); } if (*inner_counts && current_count > 0) { memcpy(new_inner_counts, *inner_counts, sizeof(int) * current_count); } *collection = new_collection; *inner_counts = new_inner_counts; (*collection)[current_count] = (char **)malloc(sizeof(char *) * LINK_FIELD_COUNT); if (!(*collection)[current_count]) { *collection = old_collection; *inner_counts = old_inner_counts; free(new_collection); free(new_inner_counts); return current_count; } (*collection)[current_count][0] = strdup(href ? href : ""); (*collection)[current_count][1] = strdup(label ? label : ""); (*collection)[current_count][2] = strdup(class_name ? class_name : ""); if (!(*collection)[current_count][0] || !(*collection)[current_count][1] || !(*collection)[current_count][2]) { free((*collection)[current_count][0]); free((*collection)[current_count][1]); free((*collection)[current_count][2]); free((*collection)[current_count]); *collection = old_collection; *inner_counts = old_inner_counts; free(new_collection); free(new_inner_counts); return current_count; } (*inner_counts)[current_count] = LINK_FIELD_COUNT; free(old_collection); free(old_inner_counts); return current_count + 1; } int build_pagination(int page, char *(*href_builder)(int page, void *data), void *data, char ****out_matrix, int **out_inner_counts) { enum { PAGER_WINDOW_SIZE = 5 }; *out_matrix = NULL; *out_inner_counts = NULL; int count = 0; int pager_start = page <= 3 ? 1 : page - 2; int pager_end = pager_start + PAGER_WINDOW_SIZE - 1; if (page > 1) { char *href = href_builder(page - 1, data); count = add_link_to_collection(href, "<", "pagination-btn prev", out_matrix, out_inner_counts, count); free(href); } for (int i = pager_start; i <= pager_end; i++) { char label[16]; snprintf(label, sizeof(label), "%d", i); char *href = href_builder(i, data); count = add_link_to_collection( href, label, i == page ? "pagination-btn pagination-current" : "pagination-btn", out_matrix, out_inner_counts, count); free(href); } char *href = href_builder(page + 1, data); count = add_link_to_collection(href, ">", "pagination-btn next", out_matrix, out_inner_counts, count); free(href); return count; }