From 65a756da48942f4052ad2c8f515b82115f7870ff Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 20 Nov 2022 16:32:46 +0100 Subject: [PATCH 1/2] refactor: moved dynarray back to package model --- src/{util => package}/c/dynarray.c | 0 src/{util => package}/c/dynarray.h | 0 src/package/package.c.v | 1 + src/util/util.c.v | 7 ------- src/util/v.mod | 3 --- 5 files changed, 1 insertion(+), 10 deletions(-) rename src/{util => package}/c/dynarray.c (100%) rename src/{util => package}/c/dynarray.h (100%) delete mode 100644 src/util/util.c.v delete mode 100644 src/util/v.mod diff --git a/src/util/c/dynarray.c b/src/package/c/dynarray.c similarity index 100% rename from src/util/c/dynarray.c rename to src/package/c/dynarray.c diff --git a/src/util/c/dynarray.h b/src/package/c/dynarray.h similarity index 100% rename from src/util/c/dynarray.h rename to src/package/c/dynarray.h diff --git a/src/package/package.c.v b/src/package/package.c.v index a9c4784..25272f8 100644 --- a/src/package/package.c.v +++ b/src/package/package.c.v @@ -5,6 +5,7 @@ module package // We need to specify *every* C file here. Otherwise, Vieter doesn't compile. #flag @VMODROOT/c/package.o #flag @VMODROOT/c/package_info.o +#flag @VMODROOT/c/dynarray.o #include "package.h" diff --git a/src/util/util.c.v b/src/util/util.c.v deleted file mode 100644 index 997a18d..0000000 --- a/src/util/util.c.v +++ /dev/null @@ -1,7 +0,0 @@ -module util - -#flag -I @VMODROOT/c - -// This makes the V compiler include this object file when linking, allowing -// all other C parts of the codebase to use it as well. -#flag @VMODROOT/c/dynarray.o diff --git a/src/util/v.mod b/src/util/v.mod deleted file mode 100644 index 39a57af..0000000 --- a/src/util/v.mod +++ /dev/null @@ -1,3 +0,0 @@ -Module{ - name: 'util' -} From 3c0422b998b73227f4eed3f5d6f4390bd2c827bc Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 20 Nov 2022 18:00:13 +0100 Subject: [PATCH 2/2] feat(package): first version of parse function in C --- src/package/c/package_info.c | 106 ++++++++++++++++++++++++++++++++++- src/package/c/package_info.h | 2 +- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/package/c/package_info.c b/src/package/c/package_info.c index a8959ff..79d8720 100644 --- a/src/package/c/package_info.c +++ b/src/package/c/package_info.c @@ -1,3 +1,5 @@ +#include + #include "package_info.h" PkgInfo *package_info_init() { @@ -41,6 +43,108 @@ void package_info_free(PkgInfo **ptp) { *ptp = NULL; } -void package_info_parse(PkgInfo *pkg_info, const char *pkg_info_str) { +/** + * Advance the pointer until all spaces are skipped. + */ +static inline char *trim_spaces_front(char *ptr) { + while (ptr[0] == ' ') { + ptr++; + } + return ptr; +} + +/** + * Given a string pointer in the middle of a string, move over all spaces in the + * given direction. The final space is replaced with a NULL-byte. + */ +static inline void trim_spaces_back(char *ptr) { + if (ptr[0] != ' ') { + return; + } + + while (ptr[-1] == ' ') { + ptr--; + } + + ptr[0] = '\0'; +} + +#define PKG_INFO_STRING(key, field) if (strcmp(key_ptr, key) == 0) { pkg_info->field = strdup(value_ptr); goto advance; } +#define PKG_INFO_INT(key, field) if (strcmp(key_ptr, key) == 0) { pkg_info->field = atoi(value_ptr); goto advance; } +#define PKG_INFO_ARRAY(key, field) if (strcmp(key_ptr, key) == 0) { dynarray_add(pkg_info->field, value_ptr); goto advance; } + +int package_info_parse(PkgInfo *pkg_info, char *pkg_info_str) { + char *offset_ptr, *equals_ptr, *key_ptr, *value_ptr; + + bool end = false; + + // Iterate over all lines in file + while (!end) { + // This pointer will always point to the final character of the + // current line, be it the position of a newline or the NULL byte at + // the end of the entire string + offset_ptr = strchr(pkg_info_str, '\n'); + + // We replace the newline with a NULL byte. Now we know the line runs + // until the next NULL byte. + if (offset_ptr != NULL) { + offset_ptr[0] = '\0'; + } else { + // Advance pointer to the NULL byte of the string + offset_ptr = pkg_info_str + 1; + + while (*offset_ptr != '\0') { + offset_ptr++; + } + + end = true; + } + + // Skip comment lines + if (pkg_info_str[0] == '#') { + goto advance; + } + + equals_ptr = strchr(pkg_info_str, '='); + + // If a line doesn't contain an equals sign, the file is invalid + if (equals_ptr == NULL) { + return 1; + } + + // Trim whitespace from key + key_ptr = trim_spaces_front(pkg_info_str); + trim_spaces_back(equals_ptr - 1); + + // Trim spaces from value + value_ptr = trim_spaces_front(equals_ptr + 1); + trim_spaces_back(offset_ptr - 1); + + // Match key + PKG_INFO_STRING("pkgname", name); + PKG_INFO_STRING("pkgbase", base); + PKG_INFO_STRING("pkgver", version); + PKG_INFO_STRING("pkgdesc", description); + PKG_INFO_INT("size", size); + PKG_INFO_STRING("url", url); + PKG_INFO_STRING("arch", arch); + PKG_INFO_INT("builddate", build_date); + PKG_INFO_STRING("packager", packager); + PKG_INFO_STRING("pgpsig", pgpsig); + PKG_INFO_INT("pgpsigsize", pgpsigsize); + PKG_INFO_ARRAY("group", groups); + PKG_INFO_ARRAY("license", licenses); + PKG_INFO_ARRAY("replaces", replaces); + PKG_INFO_ARRAY("depend", depends); + PKG_INFO_ARRAY("optdepend", optdepends); + PKG_INFO_ARRAY("makedepend", makedepends); + PKG_INFO_ARRAY("checkdepend", checkdepends); + +advance: + pkg_info_str = offset_ptr + 1; + continue; + } + + return 0; } diff --git a/src/package/c/package_info.h b/src/package/c/package_info.h index 7e16f4b..c3df790 100644 --- a/src/package/c/package_info.h +++ b/src/package/c/package_info.h @@ -33,7 +33,7 @@ typedef struct pkg_info { } PkgInfo; PkgInfo *package_info_init(); -void package_info_parse(PkgInfo *pkg_info, const char *pkg_info_str); +int package_info_parse(PkgInfo *pkg_info, char *pkg_info_str); void package_info_free(PkgInfo **ptp); #endif