#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); pbg_error_print(&err); free(query); free(str); pbg_error_free(&err); 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); pbg_error_print(&err); free(query); free(str); pbg_free(&e); pbg_error_free(&err); return -1; } free(query); free(str); pbg_free(&e); pbg_error_free(&err); return (result == PBG_TRUE) ? 1 : 0; } /** * Query recipe `r` for input `s` and return 1 if found 0 otherwise */ int query_for_items(const recipe * r, const char * s, int strict) { for (int i = 0; i < r->in; i++) if (strict) { if (!strcmp(r->i[i]->name, s)) return 1; } else { if (strstr(r->i[i]->name, s) != NULL) return 1; } 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; }