Пример #1
0
void symClose(sym_fd_t sd)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *forw;
	int				i;

	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Free all symbols in the hash table, then the hash table itself.
 */
	for (i = 0; i < tp->hash_size; i++) {
		for (sp = tp->hash_table[i]; sp; sp = forw) {
			forw = sp->forw;
			valueFree(&sp->name);
			valueFree(&sp->content);
			bfree(B_L, (void*) sp);
			sp = forw;
		}
	}
	bfree(B_L, (void*) tp->hash_table);

	symMax = hFree((void***) &sym, sd);
	bfree(B_L, (void*) tp);
}
Пример #2
0
/**
 * @param state		expression parser state
 */
static Value doAddSubtract(ParseState state)
{
  Value v1, v2 = NULL;

  DEBUG(printf("doAddSubtract()\n"));

  v1 = doMultiplyDivide(state);
  if (v1 == NULL)
    return NULL;

  while (state->nextToken == TOK_ADD || state->nextToken == TOK_MINUS) {
    int op = state->nextToken;

    if (rdToken(state))
      return NULL;

    if (v2) valueFree(v2);

    v2 = doMultiplyDivide(state);
    if (v2 == NULL)
      return NULL;

    if (! valueSameType(v1, v2)) {
      rpmlog(RPMLOG_ERR, _("types must match\n"));
      return NULL;
    }

    if (valueIsInteger(v1)) {
      int i1 = v1->data.i, i2 = v2->data.i;

      valueFree(v1);
      if (op == TOK_ADD)
	v1 = valueMakeInteger(i1 + i2);
      else
	v1 = valueMakeInteger(i1 - i2);
    } else {
      char *copy;

      if (op == TOK_MINUS) {
	rpmlog(RPMLOG_ERR, _("- not suported for strings\n"));
	return NULL;
      }

      copy = xmalloc(strlen(v1->data.s) + strlen(v2->data.s) + 1);
      (void) stpcpy( stpcpy(copy, v1->data.s), v2->data.s);

      valueFree(v1);
      v1 = valueMakeString(copy);
    }
  }

  if (v2) valueFree(v2);
  return v1;
}
Пример #3
0
int symDelete(sym_fd_t sd, char_t *name)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *last;
	char_t			*cp;
	int				hindex;

	a_assert(name && *name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Calculate the first daisy-chain from the hash table. If non-zero, then
 *	we have daisy-chain, so scan it and look for the symbol.
 */
	last = NULL;
	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for ( ; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
	}
	if (sp == (sym_t*) NULL) {				/* Not Found */
		return -1;
	}

/*
 *	Unlink and free the symbol. Last will be set if the element to be deleted
 *	is not first in the chain.
 */
	if (last) {
		last->forw = sp->forw;
	} else {
		tp->hash_table[hindex] = sp->forw;
	}
	valueFree(&sp->name);
	valueFree(&sp->content);
	bfree(B_L, (void*) sp);

	return 0;
}
Пример #4
0
/**
 * @param state		expression parser state
 */
static Value doLogical(ParseState state)
{
  Value v1, v2 = NULL;

  DEBUG(printf("doLogical()\n"));

  v1 = doRelational(state);
  if (v1 == NULL)
    return NULL;

  while (state->nextToken == TOK_LOGICAL_AND
	 || state->nextToken == TOK_LOGICAL_OR) {
    int op = state->nextToken;

    if (rdToken(state))
      return NULL;

    if (v2) valueFree(v2);

    v2 = doRelational(state);
    if (v2 == NULL)
      return NULL;

    if (! valueSameType(v1, v2)) {
      rpmlog(RPMLOG_ERR, _("types must match\n"));
      return NULL;
    }

    if (valueIsInteger(v1)) {
      int i1 = v1->data.i, i2 = v2->data.i;

      valueFree(v1);
      if (op == TOK_LOGICAL_AND)
	v1 = valueMakeInteger(i1 && i2);
      else
	v1 = valueMakeInteger(i1 || i2);
    } else {
      rpmlog(RPMLOG_ERR, _("&& and || not suported for strings\n"));
      return NULL;
    }
  }

  if (v2) valueFree(v2);
  return v1;
}
Пример #5
0
/**
 * @param state		expression parser state
 */
static Value doMultiplyDivide(ParseState state)
{
  Value v1, v2 = NULL;

  DEBUG(printf("doMultiplyDivide()\n"));

  v1 = doPrimary(state);
  if (v1 == NULL)
    return NULL;

  while (state->nextToken == TOK_MULTIPLY
	 || state->nextToken == TOK_DIVIDE) {
    int op = state->nextToken;

    if (rdToken(state))
      return NULL;

    if (v2) valueFree(v2);

    v2 = doPrimary(state);
    if (v2 == NULL)
      return NULL;

    if (! valueSameType(v1, v2)) {
      rpmlog(RPMLOG_ERR, _("types must match\n"));
      return NULL;
    }

    if (valueIsInteger(v1)) {
      int i1 = v1->data.i, i2 = v2->data.i;

      valueFree(v1);
      if (op == TOK_MULTIPLY)
	v1 = valueMakeInteger(i1 * i2);
      else
	v1 = valueMakeInteger(i1 / i2);
    } else {
      rpmlog(RPMLOG_ERR, _("* / not suported for strings\n"));
      return NULL;
    }
  }

  if (v2) valueFree(v2);
  return v1;
}
Пример #6
0
int parseExpressionBoolean(rpmSpec spec, const char *expr)
{
  struct _parseState state;
  int result = -1;
  Value v;

  DEBUG(printf("parseExprBoolean(?, '%s')\n", expr));

  /* Initialize the expression parser state. */
  state.p = state.str = xstrdup(expr);
  state.spec = spec;
  state.nextToken = 0;
  state.tokenValue = NULL;
  (void) rdToken(&state);

  /* Parse the expression. */
  v = doLogical(&state);
  if (!v) {
    state.str = _free(state.str);
    return -1;
  }

  /* If the next token is not TOK_EOF, we have a syntax error. */
  if (state.nextToken != TOK_EOF) {
    rpmlog(RPMLOG_ERR, _("syntax error in expression\n"));
    state.str = _free(state.str);
    return -1;
  }

  DEBUG(valueDump("parseExprBoolean:", v, stdout));

  switch (v->type) {
  case VALUE_TYPE_INTEGER:
    result = v->data.i != 0;
    break;
  case VALUE_TYPE_STRING:
    result = v->data.s[0] != '\0';
    break;
  default:
    break;
  }

  state.str = _free(state.str);
  valueFree(v);
  return result;
}
Пример #7
0
LONGBOW_TEST_CASE(Global, PARC_TreeRedBlack_Remove)
{
    PARCTreeRedBlack *tree1;
    PARCTreeRedBlack *tree2;

    tree1 = parcTreeRedBlack_Create(intComp, keyFree, NULL, intEquals, valueFree, NULL);
    tree2 = parcTreeRedBlack_Create(intComp, keyFree, NULL, intEquals, valueFree, NULL);

    for (int i = 31; i < 40; i++) {
        // Add some elements to the tree
        parcTreeRedBlack_Insert(tree1, keyNewInt(i), valueNewInt(i << 8));
        parcTreeRedBlack_Insert(tree2, keyNewInt(i), valueNewInt(i << 8));
    }

    parcTreeRedBlack_Insert(tree1, keyNewInt(30), valueNewInt(31 << 8));

    for (int i = 2; i < 10; i++) {
        // Add some elements to the tree
        parcTreeRedBlack_Insert(tree1, keyNewInt(i), valueNewInt(i << 8));
        parcTreeRedBlack_Insert(tree2, keyNewInt(i), valueNewInt(i << 8));
    }

    for (int i = 20; i < 30; i++) {
        // Add some elements to the tree
        parcTreeRedBlack_Insert(tree1, keyNewInt(i), valueNewInt(i << 8));
        parcTreeRedBlack_Insert(tree2, keyNewInt(i), valueNewInt(i << 8));
    }

    int searchKey = 30;

    void *data = parcTreeRedBlack_Remove(tree1, &searchKey);

    valueFree(&data);

    assertTrue(parcTreeRedBlack_Equals(tree1, tree2), "Trees dont match after remove");

    parcTreeRedBlack_Destroy(&tree1);
    parcTreeRedBlack_Destroy(&tree2);
}
Пример #8
0
sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *last;
	char_t			*cp;
	int				hindex;

	a_assert(name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Calculate the first daisy-chain from the hash table. If non-zero, then
 *	we have daisy-chain, so scan it and look for the symbol.
 */
	last = NULL;
	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for (; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
		if (sp) {
/*
 *			Found, so update the value
 *			If the caller stores handles which require freeing, they
 *			will be lost here. It is the callers responsibility to free
 *			resources before overwriting existing contents. We will here
 *			free allocated strings which occur due to value_instring().
 *			We should consider providing the cleanup function on the open rather
 *			than the close and then we could call it here and solve the problem.
 */
			if (sp->content.valid) {
				valueFree(&sp->content);
			}
			sp->content = v;
			sp->arg = arg;
			return sp;
		}
/*
 *		Not found so allocate and append to the daisy-chain
 */
		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		sp->name = valueString(name, VALUE_ALLOCATE);
		sp->content = v;
		sp->forw = (sym_t*) NULL;
		sp->arg = arg;
		last->forw = sp;

	} else {
/*
 *		Daisy chain is empty so we need to start the chain
 */
		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		tp->hash_table[hindex] = sp;
		tp->hash_table[hashIndex(tp, name)] = sp;

		sp->forw = (sym_t*) NULL;
		sp->content = v;
		sp->arg = arg;
		sp->name = valueString(name, VALUE_ALLOCATE);
	}
	return sp;
}
Пример #9
0
/**
 * @param state		expression parser state
 */
static Value doRelational(ParseState state)
{
  Value v1, v2 = NULL;

  DEBUG(printf("doRelational()\n"));

  v1 = doAddSubtract(state);
  if (v1 == NULL)
    return NULL;

  while (state->nextToken >= TOK_EQ && state->nextToken <= TOK_GE) {
    int op = state->nextToken;

    if (rdToken(state))
      return NULL;

    if (v2) valueFree(v2);

    v2 = doAddSubtract(state);
    if (v2 == NULL)
      return NULL;

    if (! valueSameType(v1, v2)) {
      rpmlog(RPMLOG_ERR, _("types must match\n"));
      return NULL;
    }

    if (valueIsInteger(v1)) {
      int i1 = v1->data.i, i2 = v2->data.i, r = 0;
      switch (op) {
      case TOK_EQ:
	r = (i1 == i2);
	break;
      case TOK_NEQ:
	r = (i1 != i2);
	break;
      case TOK_LT:
	r = (i1 < i2);
	break;
      case TOK_LE:
	r = (i1 <= i2);
	break;
      case TOK_GT:
	r = (i1 > i2);
	break;
      case TOK_GE:
	r = (i1 >= i2);
	break;
      default:
	break;
      }
      valueFree(v1);
      v1 = valueMakeInteger(r);
    } else {
      const char * s1 = v1->data.s;
      const char * s2 = v2->data.s;
      int r = 0;
      switch (op) {
      case TOK_EQ:
	r = (strcmp(s1,s2) == 0);
	break;
      case TOK_NEQ:
	r = (strcmp(s1,s2) != 0);
	break;
      case TOK_LT:
	r = (strcmp(s1,s2) < 0);
	break;
      case TOK_LE:
	r = (strcmp(s1,s2) <= 0);
	break;
      case TOK_GT:
	r = (strcmp(s1,s2) > 0);
	break;
      case TOK_GE:
	r = (strcmp(s1,s2) >= 0);
	break;
      default:
	break;
      }
      valueFree(v1);
      v1 = valueMakeInteger(r);
    }
  }

  if (v2) valueFree(v2);
  return v1;
}