summaryrefslogtreecommitdiff
path: root/keyword.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2022-07-26 18:05:51 -0300
committermrb0nk500 <b0nk@b0nk.xyz>2022-07-26 18:05:51 -0300
commitb0470f2db735f4dffda742fe38a7f9488a5ebc08 (patch)
treef6beff8370eb440d96074fd58ffdbdc0ec198699 /keyword.c
parent8c633723964993a2ce6fb1717823caf46514a167 (diff)
keyword: Added `keyword` type
This will allow for easy parsing of stuff like the PR `info`, PR `comments`, and config files.
Diffstat (limited to 'keyword.c')
-rw-r--r--keyword.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/keyword.c b/keyword.c
new file mode 100644
index 0000000..8b92191
--- /dev/null
+++ b/keyword.c
@@ -0,0 +1,81 @@
+#include <time.h>
+#include "keyword.h"
+
+keyword_val get_keyword_value(const keyword *key, char *value, int *error) {
+ keyword_val val = {0};
+ int dummy = 0;
+ error = (error != NULL) ? error : &dummy;
+ *error = 0;
+
+ switch (key->type) {
+ case TYPE_INT :
+ case TYPE_BOOL : val.i = strtol(value, NULL, 0); break;
+ case TYPE_TIME :
+ if (key->time_fmt != NULL) {
+ struct tm tm = {0};
+ if (strptime(value, key->time_fmt, &tm) != NULL) {
+ val.t = mktime(&tm);
+ } else {
+ *error = 3;
+ }
+ } else {
+ *error = 4;
+ }
+ break;
+ case TYPE_STRING: val.str = make_str(value); break;
+ case TYPE_FLOAT : val.f = strtof(value, NULL); break;
+ default : *error = 2; break;
+ }
+ return val;
+}
+
+void set_keyword(const keyword *key, keyword_val val, void *ret, void *ctx) {
+ if (key->callback != NULL) {
+ key->callback(ctx, ret, key, val);
+ } else {
+ char *tmp_ret = (char *)ret;
+ size_t offset = -1;
+ for (int i = 0; (int64_t)key->offsets[i] >= 0; ++i) {
+ if ((int64_t)offset >= 0) {
+ tmp_ret = *(char **)(tmp_ret+key->offsets[i]);
+ }
+ offset = key->offsets[i];
+ }
+
+ switch (type) {
+ case TYPE_INT :
+ case TYPE_BOOL : *(int *)(tmp_ret+offset) = val.i; break;
+ case TYPE_TIME : *(time_t *)(tmp_ret+offset) = val.t; break;
+ case TYPE_STRING: *(char **)(tmp_ret+offset) = val.str; break;
+ case TYPE_FLOAT : *(float *)(tmp_ret+offset) = val.f; break;
+ default : break;
+ }
+ }
+}
+
+keyword_val parse_keyword(const keyword *key, char *key_str, char *value, int *error) {
+ int dummy = 0;
+ error = (error != NULL) ? error : &dummy;
+ if (!strcmp(key->key, key_str)) {
+ return get_keyword_value(key, value, error);
+ } else {
+ *error = 1;
+ return (keyword_val){0};
+ }
+}
+
+
+int parse_keywords(const keyword **keys, char *key, char *value, void *ret, void *ctx) {
+ keyword_val val = {0};
+ int error = 0;
+
+ for (int i = 0; keys[i] != NULL; ++i) {
+ val = parse_keyword(keys[i], key, value, &error);
+
+ if (!error) {
+ set_keyword(keys[i], val, ret, ctx);
+ return 0;
+ }
+ }
+ return error;
+}