diff options
Diffstat (limited to 'src/search.c')
-rw-r--r-- | src/search.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/search.c b/src/search.c index cf2eab9..a038cfb 100644 --- a/src/search.c +++ b/src/search.c @@ -1,5 +1,115 @@ #include "util.h" #include "search.h" +#include "pbg.h" + +static char * +form_string(const recipe * r, const char * s, int strict) +{ + char _s[4048] = ""; + int l = 0; + char buf[256] = ""; + + for (int i = 0; i < strlen(s); i++) { + if (s[i] == '(' || + s[i] == ')' || + s[i] == ' ') { + if (strlen(buf)) { + if (!strcmp(buf, "not") || + !strcmp(buf, "NOT") || + !strcmp(buf, "!")) { + _s[l++] = '!'; + } + else if (!strcmp(buf, "and") || + !strcmp(buf, "AND") || + !strcmp(buf, "&&") || + !strcmp(buf, "&")) { + _s[l++] = '&'; + } + else if (!strcmp(buf, "or") || + !strcmp(buf, "OR") || + !strcmp(buf, "||") || + !strcmp(buf, "|")) { + _s[l++] = '|'; + } + else { + fdebug("querying %s for %s\n", r->title, buf); + if (query_for_items(r, buf, strict)) { + strcat(_s, "TRUE"); + l+=4; + } + else { + strcat(_s, "FALSE"); + l+=5; + } + } + strcpy(buf, ""); + } + _s[l++] = s[i]; + } + else { + int k = strlen(buf); + buf[k] = s[i]; + buf[k+1] = '\0'; + } + } + _s[l] = '\0'; + + return strdup(_s); +} + +int +query_for_items_pbn(const recipe * r, const char * s, int strict) +{ + if (!strlen(s)) { + return 0; + } + + char * query = NULL; + + if (s[0] != '(') { + if (strstr(s, "and ") || + strstr(s, "or ") || + strstr(s, "not ")) { + query = (char *)malloc(sizeof(char) * strlen(s) + 3); + strcpy(query, "("); + strcat(query, s); + strcat(query, ")"); + } else { + return query_for_items(r, s, strict); + } + } else { + query = strdup(s); + } + + pbg_error err; + pbg_expr e; + int result; + + fdebug("PBG Query string: %s\n", query); + char* str = form_string(r, query, strict); + fdebug("PBG Query eval'd string: %s\n", str); + + /* Parse the expression string and check if + * there were any compilation errors. */ + pbg_parse(&e, &err, str); + if(pbg_iserror(&err)) { + fprintf(stderr, "Parsing error: %s => %s\n", s, str); + free(query); free(str); free(err._data); + return -1; + } + + /* Evaluate the expression string and check if + * there were any runtime errors. */ + result = pbg_evaluate(&e, &err, NULL); + if(pbg_iserror(&err)) { + fprintf(stderr, "Eval error: %s => %s\n", s, str); + free(query); free(str); pbg_free(&e); free(err._data); + return -1; + } + + free(query); free(str); pbg_free(&e); + return (result == PBG_TRUE) ? 1 : 0; +} /** * Query recipe `r` for input `s` and return 1 if found 0 otherwise @@ -17,3 +127,11 @@ query_for_items(const recipe * r, const char * s, int strict) } return 0; } + +int +check_hash(const recipe * r, const char * s) +{ + char _sha1[9]; + sprintf(_sha1, "%.*s", 8, r->sha1); + return (!strcmp(s, _sha1) || !strcmp(s, r->sha1)) ? 1 : 0; +} |