Refactor package module into C #6
2 changed files with 47 additions and 107 deletions
|
|
@ -33,7 +33,7 @@ typedef struct pkg_info {
|
|||
} PkgInfo;
|
||||
|
||||
PkgInfo *package_info_init();
|
||||
int package_info_parse(PkgInfo *pkg_info, char *pkg_info_str);
|
||||
void package_info_parse(PkgInfo *pkg_info, char *pkg_info_str);
|
||||
void package_info_free(PkgInfo *pkg_info);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,6 +2,31 @@
|
|||
|
||||
#include "package_info.h"
|
||||
|
||||
#define PKG_INFO_STRING(key_ptr, field) if ((value_ptr = strstr(value_ptr, key_ptr)) != NULL) { \
|
||||
value_ptr += strlen(key_ptr);\
|
||||
tail_ptr = strchr(value_ptr, '\n');\
|
||||
tail_ptr[0] = '\0'; \
|
||||
pkg_info->field = strdup(value_ptr); \
|
||||
tail_ptr[0] = '\n'; \
|
||||
} value_ptr = tail_ptr;
|
||||
|
||||
#define PKG_INFO_INT(key_ptr, field) value_ptr = strstr(value_ptr, key_ptr) + strlen(key_ptr);\
|
||||
tail_ptr = strchr(value_ptr, '\n');\
|
||||
tail_ptr[0] = '\0'; \
|
||||
pkg_info->field = atoi(value_ptr); \
|
||||
tail_ptr[0] = '\n'; \
|
||||
value_ptr = tail_ptr;
|
||||
|
||||
#define PKG_INFO_ARRAY(key_ptr, field) while((value_ptr = strstr(value_ptr, key_ptr)) != NULL){ \
|
||||
value_ptr = value_ptr + strlen(key_ptr);\
|
||||
tail_ptr = strchr(value_ptr, '\n'); \
|
||||
tail_ptr[0] = '\0'; \
|
||||
if(pkg_info->field == NULL) { pkg_info->field = dynarray_init(4); } \
|
||||
dynarray_add(pkg_info->field, value_ptr); \
|
||||
tail_ptr[0] = '\n'; \
|
||||
value_ptr = tail_ptr;\
|
||||
} value_ptr = tail_ptr;
|
||||
|
||||
PkgInfo *package_info_init() {
|
||||
return calloc(1, sizeof(PkgInfo));
|
||||
}
|
||||
|
|
@ -29,111 +54,26 @@ void package_info_free(PkgInfo *pkg_info) {
|
|||
free(pkg_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) { \
|
||||
if (pkg_info->field == NULL) { pkg_info->field = dynarray_init(4); } \
|
||||
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;
|
||||
void package_info_parse(PkgInfo *pkg_info, char *pkg_info_str) {
|
||||
char *value_ptr = pkg_info_str, *tail_ptr;
|
||||
|
||||
PKG_INFO_STRING("\npkgname = ", name);
|
||||
PKG_INFO_STRING("\npkgbase = ", base);
|
||||
PKG_INFO_STRING("\npkgver = ", version);
|
||||
PKG_INFO_STRING("\npkgdesc = ", description);
|
||||
PKG_INFO_STRING("\nurl = ", url);
|
||||
PKG_INFO_INT("\nbuilddate = ", build_date);
|
||||
PKG_INFO_STRING("\npackager = ", packager);
|
||||
PKG_INFO_INT("\nsize = ", size);
|
||||
PKG_INFO_STRING("\narch = ", arch);
|
||||
PKG_INFO_ARRAY("\nlicense = ", licenses);
|
||||
PKG_INFO_ARRAY("\nreplaces = ", replaces);
|
||||
PKG_INFO_ARRAY("\ngroup = ", groups);
|
||||
PKG_INFO_ARRAY("\nconflict = ", conflicts);
|
||||
PKG_INFO_ARRAY("\nprovides = ", provides);
|
||||
PKG_INFO_ARRAY("\ndepend = ", depends);
|
||||
PKG_INFO_ARRAY("\noptdepend = ", optdepends);
|
||||
PKG_INFO_ARRAY("\nmakedepend = ", makedepends);
|
||||
PKG_INFO_ARRAY("\ncheckdepend = ", checkdepends);
|
||||
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue