#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
*/
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;
}