From 817aa55011d9d685930fd59a42df807d8ba9b2c2 Mon Sep 17 00:00:00 2001 From: Clecio Jung Date: Sun, 16 Apr 2023 10:05:54 -0300 Subject: Simplifying the usage of the API --- README.md | 6 +-- examples/ini_file_read.c | 2 +- examples/ini_file_search.c | 2 +- ini_file.c | 60 ++++++++++++------------ ini_file.h | 66 +++++++++++++------------- main.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 68 deletions(-) create mode 100644 main.c diff --git a/README.md b/README.md index 3c460ad..5656231 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This library provides a set of functions for reading and writing INI files. Here #include "ini_file.h" int main(const int argc, const char **const argv) { - struct Ini_File *ini_file; + Ini_File *ini_file; size_t section_index, property_index; char *value; double number; @@ -56,10 +56,10 @@ int main(const int argc, const char **const argv) { /* You can iterate over the sections and keys */ for (section_index = 0; section_index < ini_file->sections_size; section_index++) { - struct Ini_Section *section = &ini_file->sections[section_index]; + Ini_Section *section = &ini_file->sections[section_index]; printf("[%s]\n", section->name); for (property_index = 0; property_index < section->properties_size; property_index++) { - struct Key_Value_Pair *property = §ion->properties[property_index]; + Key_Value_Pair *property = §ion->properties[property_index]; printf("%s = %s\n", property->key, property->value); } printf("\n"); diff --git a/examples/ini_file_read.c b/examples/ini_file_read.c index 1eeca5e..2b2093e 100644 --- a/examples/ini_file_read.c +++ b/examples/ini_file_read.c @@ -9,7 +9,7 @@ #include #include -int error_callback(const char *const filename, const size_t line_number, const size_t column, const char *const line, const enum Ini_File_Errors error) { +int error_callback(const char *const filename, size_t line_number, size_t column, char *line, Ini_File_Error error) { fprintf(stderr, "%s:%lu:%lu %s:\n%s\n", filename, line_number, column, ini_file_error_to_string(error), line); return 0; } diff --git a/examples/ini_file_search.c b/examples/ini_file_search.c index 674631f..9a95dc4 100644 --- a/examples/ini_file_search.c +++ b/examples/ini_file_search.c @@ -14,7 +14,7 @@ */ int main(const int argc, const char **const argv) { - enum Ini_File_Errors error; + enum Ini_File_Error error; struct Ini_File *ini_file; struct Ini_Section *ini_section; char *value; diff --git a/ini_file.c b/ini_file.c index 91082ee..0f8adf5 100644 --- a/ini_file.c +++ b/ini_file.c @@ -124,7 +124,7 @@ void ini_file_print_to(const struct Ini_File *const ini_file, FILE *const sink) } } -char *ini_file_error_to_string(const enum Ini_File_Errors error) { +char *ini_file_error_to_string(const Ini_File_Error error) { static char *const error_messages[] = { "No error has occured", "Couldn't allocate more memory", @@ -267,7 +267,7 @@ static void advance_string_until(char **const str, const char *const chars) { /* Remember to free the memory allocated for the returned ini file structure */ struct Ini_File *ini_file_parse(const char *const filename, Ini_File_Error_Callback callback) { - enum Ini_File_Errors error; + Ini_File_Error error; char line[MAX_LINE_SIZE]; size_t line_number; FILE *file; @@ -390,18 +390,18 @@ static int compare_sized_str_to_cstr(const char* str1, const char* str2, size_t *index = low; \ } while (0) -static enum Ini_File_Errors ini_file_find_section_index(struct Ini_File *const ini_file, const char *const section, const size_t section_len, size_t *const index) { +static Ini_File_Error ini_file_find_section_index(struct Ini_File *const ini_file, const char *const section, const size_t section_len, size_t *const index) { binary_search(ini_file->sections, name, section, section_len); return ini_no_such_section; } -static enum Ini_File_Errors ini_file_find_key_index(struct Ini_Section *const ini_section, const char *const key, const size_t key_len, size_t *const index) { +static Ini_File_Error ini_file_find_key_index(struct Ini_Section *const ini_section, const char *const key, const size_t key_len, size_t *const index) { binary_search(ini_section->properties, key, key, key_len); return ini_no_such_property; } -enum Ini_File_Errors ini_file_find_section(struct Ini_File *const ini_file, const char *const section, struct Ini_Section **ini_section) { - enum Ini_File_Errors error; +Ini_File_Error ini_file_find_section(struct Ini_File *const ini_file, const char *const section, Ini_Section **const ini_section) { + Ini_File_Error error; size_t section_index; if ((ini_file == NULL) || (ini_section == NULL)) { return ini_invalid_parameters; @@ -417,8 +417,8 @@ enum Ini_File_Errors ini_file_find_section(struct Ini_File *const ini_file, cons return error; } -enum Ini_File_Errors ini_section_find_property(struct Ini_Section *const ini_section, const char *const key, char **value) { - enum Ini_File_Errors error; +Ini_File_Error ini_section_find_property(struct Ini_Section *const ini_section, const char *const key, char **const value) { + Ini_File_Error error; size_t property_index; if ((ini_section == NULL) || (value == NULL)) { return ini_invalid_parameters; @@ -433,8 +433,8 @@ enum Ini_File_Errors ini_section_find_property(struct Ini_Section *const ini_sec return error; } -enum Ini_File_Errors ini_file_find_property(struct Ini_File *const ini_file, const char *const section, const char *const key, char **value) { - enum Ini_File_Errors error; +Ini_File_Error ini_file_find_property(struct Ini_File *const ini_file, const char *const section, const char *const key, char **const value) { + Ini_File_Error error; struct Ini_Section *ini_section; if ((ini_file == NULL) || (key == NULL) || (value == NULL)) { return ini_invalid_parameters; @@ -449,7 +449,7 @@ enum Ini_File_Errors ini_file_find_property(struct Ini_File *const ini_file, con return ini_section_find_property(ini_section, key, value); } -static enum Ini_File_Errors convert_to_integer(const char *const value, long *const integer) { +static Ini_File_Error convert_to_integer(const char *const value, long *const integer) { char *end; long i_value = strtol(value, &end, 10); if (*end != '\0') { @@ -459,9 +459,9 @@ static enum Ini_File_Errors convert_to_integer(const char *const value, long *co return ini_no_error; } -enum Ini_File_Errors ini_section_find_integer(struct Ini_Section *const ini_section, const char *const key, long *integer) { +Ini_File_Error ini_section_find_integer(struct Ini_Section *const ini_section, const char *const key, long *const integer) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (integer == NULL) { return ini_invalid_parameters; } @@ -472,9 +472,9 @@ enum Ini_File_Errors ini_section_find_integer(struct Ini_Section *const ini_sect return convert_to_integer(value, integer); } -enum Ini_File_Errors ini_file_find_integer(struct Ini_File *const ini_file, const char *const section, const char *const key, long *integer) { +Ini_File_Error ini_file_find_integer(struct Ini_File *const ini_file, const char *const section, const char *const key, long *const integer) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (integer == NULL) { return ini_invalid_parameters; } @@ -485,7 +485,7 @@ enum Ini_File_Errors ini_file_find_integer(struct Ini_File *const ini_file, cons return convert_to_integer(value, integer); } -static enum Ini_File_Errors convert_to_unsigned(const char *const value, unsigned long *const uint) { +static Ini_File_Error convert_to_unsigned(const char *const value, unsigned long *const uint) { char *end; unsigned long ui_value = strtoul(value, &end, 10); if (*end != '\0') { @@ -495,9 +495,9 @@ static enum Ini_File_Errors convert_to_unsigned(const char *const value, unsigne return ini_no_error; } -enum Ini_File_Errors ini_section_find_unsigned(struct Ini_Section *const ini_section, const char *const key, unsigned long *uint) { +Ini_File_Error ini_section_find_unsigned(struct Ini_Section *const ini_section, const char *const key, unsigned long *const uint) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (uint == NULL) { return ini_invalid_parameters; } @@ -508,9 +508,9 @@ enum Ini_File_Errors ini_section_find_unsigned(struct Ini_Section *const ini_sec return convert_to_unsigned(value, uint); } -enum Ini_File_Errors ini_file_find_unsigned(struct Ini_File *const ini_file, const char *const section, const char *const key, unsigned long *uint) { +Ini_File_Error ini_file_find_unsigned(struct Ini_File *const ini_file, const char *const section, const char *const key, unsigned long *const uint) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (uint == NULL) { return ini_invalid_parameters; } @@ -521,7 +521,7 @@ enum Ini_File_Errors ini_file_find_unsigned(struct Ini_File *const ini_file, con return convert_to_unsigned(value, uint); } -static enum Ini_File_Errors convert_to_double(const char *const value, double *const real) { +static Ini_File_Error convert_to_double(const char *const value, double *const real) { char *end; double d_value = strtod(value, &end); if (*end != '\0') { @@ -531,9 +531,9 @@ static enum Ini_File_Errors convert_to_double(const char *const value, double *c return ini_no_error; } -enum Ini_File_Errors ini_section_find_double(struct Ini_Section *const ini_section, const char *const key, double *real) { +Ini_File_Error ini_section_find_double(struct Ini_Section *const ini_section, const char *const key, double *const real) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (real == NULL) { return ini_invalid_parameters; } @@ -544,9 +544,9 @@ enum Ini_File_Errors ini_section_find_double(struct Ini_Section *const ini_secti return convert_to_double(value, real); } -enum Ini_File_Errors ini_file_find_double(struct Ini_File *const ini_file, const char *const section, const char *const key, double *real) { +Ini_File_Error ini_file_find_double(struct Ini_File *const ini_file, const char *const section, const char *const key, double *const real) { char *value; - enum Ini_File_Errors error; + Ini_File_Error error; if (real == NULL) { return ini_invalid_parameters; } @@ -574,7 +574,7 @@ static size_t max_size(const size_t a, const size_t b) { } \ } while (0) -enum Ini_File_Errors ini_file_add_section_sized(struct Ini_File *const ini_file, const char *const name, const size_t name_len) { +Ini_File_Error ini_file_add_section_sized(struct Ini_File *const ini_file, const char *const name, const size_t name_len) { size_t section_index; char *copied_name; if (ini_file == NULL) { @@ -605,14 +605,14 @@ enum Ini_File_Errors ini_file_add_section_sized(struct Ini_File *const ini_file, return ini_no_error; } -enum Ini_File_Errors ini_file_add_section(struct Ini_File *const ini_file, const char *const name) { +Ini_File_Error ini_file_add_section(struct Ini_File *const ini_file, const char *const name) { if (name == NULL) { return ini_section_not_provided; } return ini_file_add_section_sized(ini_file, name, strlen(name)); } -enum Ini_File_Errors ini_file_add_property_sized(struct Ini_File *const ini_file, const char *const key, const size_t key_len, const char *const value, const size_t value_len) { +Ini_File_Error ini_file_add_property_sized(struct Ini_File *const ini_file, const char *const key, const size_t key_len, const char *const value, const size_t value_len) { size_t property_index; struct Key_Value_Pair *property; char *copied_key, *copied_value; @@ -652,7 +652,7 @@ enum Ini_File_Errors ini_file_add_property_sized(struct Ini_File *const ini_file return ini_no_error; } -enum Ini_File_Errors ini_file_add_property(struct Ini_File *const ini_file, const char *const key, const char *const value) { +Ini_File_Error ini_file_add_property(struct Ini_File *const ini_file, const char *const key, const char *const value) { if (key == NULL) { return ini_key_not_provided; } @@ -662,7 +662,7 @@ enum Ini_File_Errors ini_file_add_property(struct Ini_File *const ini_file, cons return ini_file_add_property_sized(ini_file, key, strlen(key), value, strlen(value)); } -enum Ini_File_Errors ini_file_save(const struct Ini_File *const ini_file, const char *const filename) { +Ini_File_Error ini_file_save(const struct Ini_File *const ini_file, const char *const filename) { FILE *file; if (ini_file == NULL) { return ini_invalid_parameters; diff --git a/ini_file.h b/ini_file.h index a367661..f6f1240 100644 --- a/ini_file.h +++ b/ini_file.h @@ -73,20 +73,20 @@ struct String_Buffer { }; #endif -struct Key_Value_Pair { +typedef struct Key_Value_Pair { char *key; char *value; -}; +} Key_Value_Pair; -struct Ini_Section { +typedef struct Ini_Section { char *name; /* The properties of the section are stored in a dynamic array */ size_t properties_size; size_t properties_capacity; - struct Key_Value_Pair *properties; -}; + Key_Value_Pair *properties; +} Ini_Section; -struct Ini_File { +typedef struct Ini_File { #ifdef USE_CUSTOM_STRING_ALLOCATOR struct String_Buffer *strings; /* This index points to the next valid location in the buffer to store the string. */ @@ -97,12 +97,12 @@ struct Ini_File { /* The sections of the ini file are stored in a dynamic array */ size_t sections_size; size_t sections_capacity; - struct Ini_Section *sections; + Ini_Section *sections; /* Index of the section in which the properties should be inserted */ - struct Ini_Section *current_section; -}; + Ini_Section *current_section; +} Ini_File; -enum Ini_File_Errors { +typedef enum Ini_File_Error { ini_no_error = 0, ini_allocation, ini_invalid_parameters, @@ -120,48 +120,48 @@ enum Ini_File_Errors { ini_not_double, NUMBER_OF_INI_FILE_ERRORS -}; +} Ini_File_Error; /* Callback used to handle errors and warnings in the parsing of INI files (function ini_file_parse). * In case of an error, this callback is called, and if it returns an integer different from zero, * we end the parsing and return NULL. */ -typedef int (*Ini_File_Error_Callback)(const char *const filename, const size_t line_number, const size_t column, const char *const line, const enum Ini_File_Errors error); +typedef int (*Ini_File_Error_Callback)(const char *const filename, size_t line_number, size_t column, char *line, enum Ini_File_Error error); size_t get_file_size(FILE *const file); /* Remember to free the memory allocated for the returned string */ char *get_content_from_file(const char *const filename); -struct Ini_File *ini_file_new(void); -void ini_file_free(struct Ini_File *const ini_file); -void ini_section_print_to(const struct Ini_Section *const ini_section, FILE *const sink); -void ini_file_print_to(const struct Ini_File *const ini_file, FILE *const sink); -char *ini_file_error_to_string(const enum Ini_File_Errors error); +Ini_File *ini_file_new(void); +void ini_file_free(Ini_File *const ini_file); +void ini_section_print_to(const Ini_Section *const ini_section, FILE *const sink); +void ini_file_print_to(const Ini_File *const ini_file, FILE *const sink); +char *ini_file_error_to_string(const Ini_File_Error error); /* This function is usefull for debug purposes */ -void ini_file_info(const struct Ini_File *const ini_file); +void ini_file_info(const Ini_File *const ini_file); /* Remember to free the memory allocated for the returned ini file structure */ -struct Ini_File *ini_file_parse(const char *const filename, Ini_File_Error_Callback callback); +Ini_File *ini_file_parse(const char *const filename, Ini_File_Error_Callback callback); /* These functions use binary search algorithm to find the requested section and properties. * They return ini_no_error = 0 if everything worked correctly. * The found value will be stored at the memory address provided by the caller. * Note that the function may modify the value stored at the address provided even if the section/property isn't found. */ -enum Ini_File_Errors ini_file_find_section(struct Ini_File *const ini_file, const char *const section, struct Ini_Section **ini_section); -enum Ini_File_Errors ini_file_find_property(struct Ini_File *const ini_file, const char *const section, const char *const key, char **value); -enum Ini_File_Errors ini_file_find_integer(struct Ini_File *const ini_file, const char *const section, const char *const key, long *integer); -enum Ini_File_Errors ini_file_find_unsigned(struct Ini_File *const ini_file, const char *const section, const char *const key, unsigned long *uint); -enum Ini_File_Errors ini_file_find_double(struct Ini_File *const ini_file, const char *const section, const char *const key, double *real); -enum Ini_File_Errors ini_section_find_property(struct Ini_Section *const ini_section, const char *const key, char **value); -enum Ini_File_Errors ini_section_find_integer(struct Ini_Section *const ini_section, const char *const key, long *integer); -enum Ini_File_Errors ini_section_find_unsigned(struct Ini_Section *const ini_section, const char *const key, unsigned long *uint); -enum Ini_File_Errors ini_section_find_double(struct Ini_Section *const ini_section, const char *const key, double *real); +Ini_File_Error ini_file_find_section(Ini_File *const ini_file, const char *const section, Ini_Section **const ini_section); +Ini_File_Error ini_file_find_property(Ini_File *const ini_file, const char *const section, const char *const key, char **const value); +Ini_File_Error ini_file_find_integer(Ini_File *const ini_file, const char *const section, const char *const key, long *const integer); +Ini_File_Error ini_file_find_unsigned(Ini_File *const ini_file, const char *const section, const char *const key, unsigned long *const uint); +Ini_File_Error ini_file_find_double(Ini_File *const ini_file, const char *const section, const char *const key, double *const real); +Ini_File_Error ini_section_find_property(Ini_Section *const ini_section, const char *const key, char **const value); +Ini_File_Error ini_section_find_integer(Ini_Section *const ini_section, const char *const key, long *const integer); +Ini_File_Error ini_section_find_unsigned(Ini_Section *const ini_section, const char *const key, unsigned long *const uint); +Ini_File_Error ini_section_find_double(Ini_Section *const ini_section, const char *const key, double *const real); /* These functions returns ini_no_error = 0 if everything worked correctly */ -enum Ini_File_Errors ini_file_add_section_sized(struct Ini_File *const ini_file, const char *const name, const size_t name_len); -enum Ini_File_Errors ini_file_add_section(struct Ini_File *const ini_file, const char *const name); -enum Ini_File_Errors ini_file_add_property_sized(struct Ini_File *const ini_file, const char *const key, const size_t key_len, const char *const value, const size_t value_len); -enum Ini_File_Errors ini_file_add_property(struct Ini_File *const ini_file, const char *const key, const char *const value); -enum Ini_File_Errors ini_file_save(const struct Ini_File *const ini_file, const char *const filename); +Ini_File_Error ini_file_add_section_sized(Ini_File *const ini_file, const char *const name, const size_t name_len); +Ini_File_Error ini_file_add_section(Ini_File *const ini_file, const char *const name); +Ini_File_Error ini_file_add_property_sized(Ini_File *const ini_file, const char *const key, const size_t key_len, const char *const value, const size_t value_len); +Ini_File_Error ini_file_add_property(Ini_File *const ini_file, const char *const key, const char *const value); +Ini_File_Error ini_file_save(const Ini_File *const ini_file, const char *const filename); #endif /* __INI_FILE */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..f2a63c6 --- /dev/null +++ b/main.c @@ -0,0 +1,114 @@ +#if 0 +#include +#include +#include + +size_t strlen_utf8(const char *str) { + size_t len = 0; + for (; *str; str++) { + if ((*str & 0xc0) != 0x80) { + len++; + } + } + return len; +} + +int main(void) { + // Read a encoded string from a file + FILE *fp = fopen("text.txt", "r,ccs=utf16le"); + if (fp == NULL) { + perror("Error opening file"); + return EXIT_FAILURE; + } + char str[4096]; + if (fgets(str, sizeof(str), fp) == NULL) { + perror("Error in gets"); + //return EXIT_FAILURE; + } + printf("strlen=%ld, strlen_utf8=%ld, str=%s\n", strlen(str), strlen_utf8(str), str); + return EXIT_SUCCESS; +} +#elif 1 + +#include +#include +#include +#include +#include + +int main() { + // Set locale to support UTF-16LE encoding + char *local = setlocale(LC_ALL, "en_US.UTF-16"); + if (local == NULL) { + perror("setlocale"); + return EXIT_FAILURE; + } + printf("locale: %s\n", local); + + FILE* file = fopen("text.txt", "rb"); + if (file == NULL) { + perror("fopen"); + return EXIT_FAILURE; + } + fseek(file, 0, SEEK_END); + int file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + // Allocate buffer for file contents + wchar_t* file_contents = malloc(file_size); + if (file_contents == NULL) { + perror("malloc"); + return EXIT_FAILURE; + } + + printf("file_size=%d\n", file_size); + // Read file contents + size_t bytes_read = fread(file_contents, 1, file_size, file); + printf("bytes_read=%ld\n", bytes_read); + if (bytes_read != file_size) { + printf("Error: Failed to read file\n"); + return 1; + } + + // Close file + fclose(file); + + // Convert wide string to multibyte string in UTF-8 encoding + int buffer_size = wcstombs(NULL, file_contents, 0) + 1; + printf("buffer_size=%d\n", buffer_size); + char* buffer = malloc(buffer_size); + + // Print multibyte string to console + printf("%s", buffer); + + // Free buffers + free(file_contents); + free(buffer); + + return 0; +} + +#else + +/* wcstombs example */ +#include /* printf */ +#include /* wcstombs, wchar_t(C) */ +#include + +int main() { + const wchar_t str[] = L"ç ~^ âãáà êẽéè õôóò"; + char buffer[32]; + int ret; + + setlocale(LC_ALL, ""); + + printf ("wchar_t string: %ls \n",str); + + ret = wcstombs ( buffer, str, sizeof(buffer) ); + if (ret==32) buffer[31]='\0'; + if (ret) printf ("multibyte string: %s \n",buffer); + + return 0; +} + +#endif \ No newline at end of file -- cgit v1.2.3