From 0af5fc4090403044a4c95351a398b1f5c3e693a4 Mon Sep 17 00:00:00 2001 From: omdxp Date: Sun, 24 Mar 2024 20:02:46 +0100 Subject: [PATCH 1/5] add README.md for C library --- README.md | 1 + c/README.md | 29 +++++++++++++++++++++++++++++ c/example/main.c | 35 ++++++++++++++++++----------------- 3 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 c/README.md diff --git a/README.md b/README.md index b21e82b..922a6da 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ You can find more about each language by clicking on the language name | [Java](./java) | n/a | n/a | n/a | n/a | | [C#](./csharp) | n/a | n/a | n/a | n/a | | [Rust](./rust) | WIP | WIP | WIP | n/a | +| [C](./c) | WIP | WIP | WIP | n/a | ## Contributing diff --git a/c/README.md b/c/README.md new file mode 100644 index 0000000..f5e3e42 --- /dev/null +++ b/c/README.md @@ -0,0 +1,29 @@ +# kuliya for C + +Algeria's college hierarchy dataset as a C library + +# Get started + +Make sure you have both `kuliya.h` and `data.h` files in your path. + +```c +#include +#include "kuliya.h" + +int main(void) +{ + kuliya_init(); + kuliya_schema *res = get_node_by_path("umkb/fst/dee/sec"); + if (res != NULL) + { + printf("%s\n", res->name.en); + } + kuliya_deinit(); +} +``` + +Check practical example usage [here](./example/main.c). + +# Contribute + +Feel free to ask for help in [#kuliya](https://dzcode.slack.com/archives/C01C0155CKC) group chat diff --git a/c/example/main.c b/c/example/main.c index 35ece7d..4d87f6e 100644 --- a/c/example/main.c +++ b/c/example/main.c @@ -30,31 +30,32 @@ const char *match_node_type(const node_type type) } /** - * Print kuliya schema with JSON format in `stdout`. + * Print kuliya schema with JSON format to a file (.e.g `stdout`). + * @param out File output. * @param schema Kuliya node schema. */ -void print_kuliya_schema(const kuliya_schema *schema) +void print_kuliya_schema(FILE *out, const kuliya_schema *schema) { - printf("{\n"); - printf("\t\"name\": {\n"); - printf("\t\t\"ar\": \"%s\",\n", schema->name.ar); - printf("\t\t\"en\": \"%s\",\n", schema->name.en); - printf("\t\t\"fr\": \"%s\"\n", schema->name.fr); - printf("\t},\n"); - printf("\t\"type\": \"%s\"%s\n", match_node_type(schema->type), schema->terms != NULL ? "," : ""); + fprintf(out, "{\n"); + fprintf(out, "\t\"name\": {\n"); + fprintf(out, "\t\t\"ar\": \"%s\",\n", schema->name.ar); + fprintf(out, "\t\t\"en\": \"%s\",\n", schema->name.en); + fprintf(out, "\t\t\"fr\": \"%s\"\n", schema->name.fr); + fprintf(out, "\t},\n"); + fprintf(out, "\t\"type\": \"%s\"%s\n", match_node_type(schema->type), schema->terms != NULL ? "," : ""); if (schema->terms != NULL) { - printf("\t\"terms\": {\n"); - printf("\t\t\"perYear\": %d,\n", schema->terms->per_year); - printf("\t\t\"slots\": [%d", schema->terms->slots[0]); + fprintf(out, "\t\"terms\": {\n"); + fprintf(out, "\t\t\"perYear\": %d,\n", schema->terms->per_year); + fprintf(out, "\t\t\"slots\": [%d", schema->terms->slots[0]); for (size_t i = 1; i < schema->terms->number_of_slots; i++) { - printf(", %d", schema->terms->slots[i]); + fprintf(out, ", %d", schema->terms->slots[i]); } - printf("]\n"); - printf("\t}\n"); + fprintf(out, "]\n"); + fprintf(out, "\t}\n"); } - printf("}\n"); + fprintf(out, "}\n"); } int main(void) @@ -63,7 +64,7 @@ int main(void) kuliya_schema *res = get_node_by_path("umkb/fst/dee/sec"); if (res != NULL) { - print_kuliya_schema(res); + print_kuliya_schema(stdout, res); } kuliya_deinit(); } From c24694f151c7553a12098363588370b8df520527 Mon Sep 17 00:00:00 2001 From: omdxp Date: Sun, 31 Mar 2024 21:21:16 +0200 Subject: [PATCH 2/5] update c readme --- c/README.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/c/README.md b/c/README.md index f5e3e42..073ae5c 100644 --- a/c/README.md +++ b/c/README.md @@ -2,13 +2,33 @@ Algeria's college hierarchy dataset as a C library -# Get started - -Make sure you have both `kuliya.h` and `data.h` files in your path. +# Prerequisites + +- [CMake](https://cmake.org/download/) build system (minimum required version 3.19) +- [Conan](https://conan.io/downloads) package manager +- [Clang](https://clang.llvm.org/get_started.html) or [GCC](https://gcc.gnu.org/releases.html) compiler (on macOS clang comes with the developer tools) +- Any IDE out there, preferably [VSCode](https://code.visualstudio.com/download) with the following extensions: + - [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) + - [CMake](https://marketplace.visualstudio.com/items?itemName=twxs.cmake) + - [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) + - [conan-extension](https://marketplace.visualstudio.com/items?itemName=konicy.conan-extension) + +# Get Started + +- Install build dependencies: + ```sh + conan install . --output-folder=build --build=missing + ``` +- Click on CMake Tools icon in the extensions sidebar (Open [CMakeLists.txt](./CMakeLists.txt) if it doesn't appear for some reason). +- Follow these steps: + +https://github.com/dzcode-io/kuliya/assets/48713070/3f693a1c-050d-4ee2-bfce-9ade59e772ed + +# Usage ```c #include -#include "kuliya.h" +#include int main(void) { From ba0031063c8162da8d534e8b6261eb3a7f110555 Mon Sep 17 00:00:00 2001 From: omdxp Date: Sun, 31 Mar 2024 23:46:04 +0200 Subject: [PATCH 3/5] add cpp example and deal with some warning compiler messages --- c/CMakeLists.txt | 2 ++ c/build.c | 24 ++++++++++++------------ c/data.h | 4 ++-- c/example/main.cpp | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 c/example/main.cpp diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index e717146..12b955b 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(test test/test.c) # Create the example executable add_executable(example example/main.c) +add_executable(example1 example/main.cpp) # Create the build executable add_executable(build build.c) @@ -25,6 +26,7 @@ add_executable(build build.c) # Link the test and example executables with the "kuliya" library target_link_libraries(test kuliya) target_link_libraries(example kuliya) +target_link_libraries(example1 kuliya) # Link the build and test executables with the "helpers" library target_link_libraries(build helpers) diff --git a/c/build.c b/c/build.c index b7456eb..15ca922 100644 --- a/c/build.c +++ b/c/build.c @@ -181,10 +181,10 @@ void append_to_data_file() for (size_t i = 0; i < kuliya_with_terms_idx; ++i) { __s_kuliya_schema schema = kuliyas_with_terms[i]; - fprintf(data_file, "\t%s.terms = malloc(sizeof(kuliya_terms));\n", schema.__varname); + fprintf(data_file, "\t%s.terms = (kuliya_terms *)malloc(sizeof(kuliya_terms));\n", schema.__varname); fprintf(data_file, "\t%s.terms->per_year = %d;\n", schema.__varname, schema.terms.per_year); fprintf(data_file, "\t%s.terms->number_of_slots = %zu;\n", schema.__varname, schema.__slots_length); - fprintf(data_file, "\t%s.terms->slots = malloc(%zu * sizeof(int));\n", schema.__varname, schema.__slots_length); + fprintf(data_file, "\t%s.terms->slots = (int *)malloc(%zu * sizeof(int));\n", schema.__varname, schema.__slots_length); for (size_t j = 0; j < schema.__slots_length; ++j) { fprintf(data_file, "\t%s.terms->slots[%zu] = %d;\n", schema.__varname, j, schema.terms.slots[j]); @@ -318,7 +318,7 @@ void parse_info_json(const unsigned char *json_path) unsigned char data[length + 1]; memcpy(data, &buf[token->start], length); data[length] = '\0'; - if (STR_EQ("ar", data)) + if (STR_EQ("ar", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -328,7 +328,7 @@ void parse_info_json(const unsigned char *json_path) schema->name->ar = calloc(1, length + 1); memcpy(schema->name->ar, data, length + 1); } - if (STR_EQ("en", data)) + if (STR_EQ("en", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -338,7 +338,7 @@ void parse_info_json(const unsigned char *json_path) schema->name->en = calloc(1, length + 1); memcpy(schema->name->en, data, length + 1); } - if (STR_EQ("fr", data)) + if (STR_EQ("fr", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -348,7 +348,7 @@ void parse_info_json(const unsigned char *json_path) schema->name->fr = calloc(1, length + 1); memcpy(schema->name->fr, data, length + 1); } - if (STR_EQ("type", data)) + if (STR_EQ("type", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -358,11 +358,11 @@ void parse_info_json(const unsigned char *json_path) schema->type = calloc(1, length + 1); memcpy(schema->type, data, length + 1); } - if (STR_EQ("terms", data)) + if (STR_EQ("terms", (char *)data)) { schema->terms = calloc(1, sizeof(kuliya_terms)); } - if (STR_EQ("perYear", data)) + if (STR_EQ("perYear", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -371,7 +371,7 @@ void parse_info_json(const unsigned char *json_path) data[length] = '\0'; schema->terms->per_year = atoi(data); } - if (STR_EQ("slots", data)) + if (STR_EQ("slots", (char *)data)) { token = &tokens[i + 1]; unsigned int length = token->end - token->start; @@ -380,13 +380,13 @@ void parse_info_json(const unsigned char *json_path) data[length] = '\0'; remove_chars(data, '[', ']', ' '); unsigned char *rest = data; - unsigned char *ptr = u8_strtok(data, ",", &rest); + unsigned char *ptr = u8_strtok(data, (unsigned char *)",", &rest); int tmp_slots[50]; while (ptr != NULL) { - int val = atoi(ptr); + int val = atoi((const char *)ptr); tmp_slots[s_idx++] = val; - ptr = u8_strtok(NULL, ",", &rest); + ptr = u8_strtok(NULL, (unsigned char *)",", &rest); } schema->terms->slots = calloc(1, s_idx * sizeof(*schema->terms->slots)); memcpy(schema->terms->slots, tmp_slots, s_idx * sizeof(int)); diff --git a/c/data.h b/c/data.h index 574774e..ee43d09 100644 --- a/c/data.h +++ b/c/data.h @@ -248,10 +248,10 @@ kuliya_schema ua2aks_falaol_dala = {.name = {.ar = "قسم اللغة العرب void __kuliya_init() { - umkb_fst_dee_sec.terms = malloc(sizeof(kuliya_terms)); + umkb_fst_dee_sec.terms = (kuliya_terms *)malloc(sizeof(kuliya_terms)); umkb_fst_dee_sec.terms->per_year = 2; umkb_fst_dee_sec.terms->number_of_slots = 4; - umkb_fst_dee_sec.terms->slots = malloc(4 * sizeof(int)); + umkb_fst_dee_sec.terms->slots = (int *)malloc(4 * sizeof(int)); umkb_fst_dee_sec.terms->slots[0] = 7; umkb_fst_dee_sec.terms->slots[1] = 8; umkb_fst_dee_sec.terms->slots[2] = 9; diff --git a/c/example/main.cpp b/c/example/main.cpp new file mode 100644 index 0000000..e68e06e --- /dev/null +++ b/c/example/main.cpp @@ -0,0 +1,32 @@ +#include +#include + +class Kuliya +{ +public: + Kuliya(); + ~Kuliya(); + kuliya_schema *GetNodeByPath(const char *path); +}; + +Kuliya::Kuliya() +{ + kuliya_init(); +} + +Kuliya::~Kuliya() +{ + kuliya_deinit(); +} + +kuliya_schema *Kuliya::GetNodeByPath(const char *path) +{ + return get_node_by_path(path); +} + +int main(void) +{ + Kuliya *kuliya = new Kuliya(); + auto schema = kuliya->GetNodeByPath("umkb/fst/dee/sec"); + std::cout << schema->name.en << "\n"; +} From 9a3bc9b2676a9e9b4eb4b36ca92d5da78867307e Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 1 Apr 2024 09:34:21 +0200 Subject: [PATCH 4/5] Update CMakeLists.txt --- c/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index 12b955b..7c3a4ef 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -26,7 +26,7 @@ add_executable(build build.c) # Link the test and example executables with the "kuliya" library target_link_libraries(test kuliya) target_link_libraries(example kuliya) -target_link_libraries(example1 kuliya) +target_link_libraries(example2 kuliya) # Link the build and test executables with the "helpers" library target_link_libraries(build helpers) From 3de669cf1e3359aff028c67c659d43206c024d17 Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 1 Apr 2024 09:35:57 +0200 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Zakaria Mansouri --- c/CMakeLists.txt | 2 +- c/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index 7c3a4ef..9455f87 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -18,7 +18,7 @@ add_executable(test test/test.c) # Create the example executable add_executable(example example/main.c) -add_executable(example1 example/main.cpp) +add_executable(example2 example/main.cpp) # Create the build executable add_executable(build build.c) diff --git a/c/README.md b/c/README.md index 073ae5c..3fb2863 100644 --- a/c/README.md +++ b/c/README.md @@ -17,7 +17,7 @@ Algeria's college hierarchy dataset as a C library - Install build dependencies: ```sh - conan install . --output-folder=build --build=missing + cd c && conan install . --output-folder=build --build=missing ``` - Click on CMake Tools icon in the extensions sidebar (Open [CMakeLists.txt](./CMakeLists.txt) if it doesn't appear for some reason). - Follow these steps: