summaryrefslogblamecommitdiffstats
path: root/src/search.c
blob: a038cfb5f9628ad30fd699ef97f7fc01458b53a1 (plain) (tree)
1
2

                   













































































































                                                                 
















                                                                   







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