/* * check_equation_result() * * Check the result returned by solve_equations(). * * @matrix: the matrix * @ret: the results * @mx: the number of columns of the matrix * @my: the number of rows of the matrix */ bool check_equation_result(fact **matrix, exp *ret, int mx, int my) { fact *ptr_equ, **ptr_matrix; exp *rpptr, step; /* Check results */ for (ptr_matrix = matrix; ptr_matrix < matrix + my; ptr_matrix++) { /* Calculate the result of the equation */ step = expression_create(0, 1); for (ptr_equ = *ptr_matrix, rpptr = ret; ptr_equ < (*ptr_matrix) + mx - 1; ptr_equ++, rpptr++) if (!expression_double_operation(&step, fraction_plus, *rpptr, fraction_multiplination, *ptr_equ)) { free_expression(&step); return(false); } if (!simplify_expression_node(&step)) { free_expression(&step); return(false); } /* Compare it with the constant of the equation */ if (!(step.count == 0 && fraction_compare(step.cst, *((*ptr_matrix) + mx - 1)) == 0)) { free_expression(&step); return(false); } free_expression(&step); } return(true); }
static int evaluate_binary_expression(struct expression *in, struct expression *out, char **error) { int result = STATUS_ERR; assert(in->type == EXPR_BINARY); assert(in->value.binary); out->type = EXPR_INTEGER; struct expression *lhs = NULL; struct expression *rhs = NULL; if (evaluate(in->value.binary->lhs, &lhs, error)) goto error_out; if (evaluate(in->value.binary->rhs, &rhs, error)) goto error_out; if (strcmp("|", in->value.binary->op) == 0) { if (lhs->type != EXPR_INTEGER) { asprintf(error, "left hand side of | not an integer"); } else if (rhs->type != EXPR_INTEGER) { asprintf(error, "right hand side of | not an integer"); } else { out->value.num = lhs->value.num | rhs->value.num; result = STATUS_OK; } } else { asprintf(error, "bad binary operator '%s'", in->value.binary->op); } error_out: free_expression(rhs); free_expression(lhs); return result; }
void free_bool_expression(bool_expression *expr) { free_expression(expr->left); if (expr->op) free(expr->op); if (expr->right) free_expression(expr->right); free(expr); }
void free_expression(expression *expr) { if (expr->op == 0) { free_value((value*)expr->left); } else { free_expression((expression*) expr->left); free_expression(expr->right); } free(expr); }
/* * free memory allocated by a rule */ void free_rule(rule *r) { if (!r) return; if (r->left) free_expression(r->left); if (r->left_exceptions) free_expression(r->left_exceptions); if (r->right) free_expression(r->right); if (r->right_exceptions) free_expression(r->right_exceptions); if (r->next) free_rule(r->next); pkg_free(r); }
void free_instruction(struct instruction *i) { switch (i->kind) { case assignment: free_expression(i->instr.assignment->e1); free_expression(i->instr.assignment->e2); free(i->instr.assignment); break; case switchcase: free_caseblocklist(i->instr.switchcase->caseblocklist); free_instructions(i->instr.switchcase->otherwiseblock); free_expression(i->instr.switchcase->cond); free(i->instr.switchcase); break; case dowhile: free_expression(i->instr.dowhile->cond); free_instructions(i->instr.dowhile->instructions); free(i->instr.dowhile); break; case whiledo: free_expression(i->instr.whiledo->cond); free_instructions(i->instr.whiledo->instructions); free(i->instr.whiledo); break; case forloop: free_expression(i->instr.forloop->assignment->e1); free_expression(i->instr.forloop->assignment->e2); free(i->instr.forloop->assignment); free_instructions(i->instr.forloop->instructions); free_expression(i->instr.forloop->upto); free(i->instr.forloop); break; case funcall: free_args(i->instr.funcall->args); free(i->instr.funcall->fun_ident); free(i->instr.funcall); break; case ifthenelse: free_expression(i->instr.ifthenelse->cond); free_instructions(i->instr.ifthenelse->instructions); free_instructions(i->instr.ifthenelse->elseblock); free(i->instr.ifthenelse); break; case returnstmt: free_expression(i->instr.returnstmt->expr); free(i->instr.returnstmt); break; } free(i); }
int add_column(screen_t* const s, char* header, char* format, char* desc, char* expr) { int col_width, err=0; int n = s->num_columns; expression* e = parser_expression(expr); if (e == NULL || e->type == ERROR) { free_expression(e); error_printf("Invalid expression in column '%s', screen '%s': column ignored\n", header, s->name); return -1; } check_counters_used(e, s, &err); if( err > 0 ) { free_expression(e); return -1; } if (n == s->num_alloc_columns) { s->columns = realloc(s->columns, sizeof(column_t) * (n + alloc_chunk)); s->num_alloc_columns += alloc_chunk; } init_column(&s->columns[n]); s->columns[n].expression = e; s->columns[n].header = strdup(header); s->columns[n].format = strdup(format); col_width = strlen(header); /* setup an empty field with proper width */ s->columns[n].empty_field = malloc(col_width + 1); memset(s->columns[n].empty_field, ' ', col_width - 1); s->columns[n].empty_field[col_width - 1] = '-'; s->columns[n].empty_field[col_width] = '\0'; /* setup an error field with proper width */ s->columns[n].error_field = malloc(col_width + 1); memset(s->columns[n].error_field, ' ', col_width - 1); s->columns[n].error_field[col_width - 1] = '?'; s->columns[n].error_field[col_width] = '\0'; if (desc) s->columns[n].description = strdup(desc); else s->columns[n].description = strdup("(unknown)"); s->num_columns++; return n; }
void free_expression(expression *expr) { expression *c; if (NULL == expr) return; free_qname(expr->qn); free(expr->str); free(expr->ident); free(expr->orig); free_expression(expr->r.test); free_expression(expr->r.left); free_expression(expr->r.right); free_expression(expr->r.name_avt); free_expression(expr->r.value_avt); free_expression(expr->r.namespace_avt); for (c = expr->r.children; c; c = c->next) free_expression(c); for (c = expr->r.attributes; c; c = c->next) free_expression(c); free(expr); }
static void test_reduce_different_currency() { Expression *two_franc = franc( 2 ); Expression *one_dollar = dollar( 1 ); add_rate( CHF, USD, 2 ); Money *result = reduce( two_franc, USD ); assert_true( equal( result, money_from( one_dollar ) ) ); free_expression( two_franc ); free_expression( one_dollar ); free_money( result ); delete_all_rates(); }
static void test_plus_returns_sum() { Expression *five = dollar( 5 ); Expression *addend_five = dollar( 5 ); Expression *result = plus( five, addend_five ); Sum *sum = ( Sum * ) result->value; assert_true( equal( money_from( five ), money_from( sum->augend ) ) ); assert_true( equal( money_from( addend_five ), money_from( sum->addend ) ) ); free_expression( five ); free_expression( addend_five ); free_expression( result ); delete_all_rates(); }
static void test_multiply_dollar_5x2() { Expression *five = dollar( 5 ); Expression *product = multiply( five, 2 ); Expression *ten = dollar( 10 ); Money *reduced = reduce( product, USD ); assert_true( equal( reduced, money_from( ten ) ) ); free_expression( five ); free_expression( product ); free_expression( ten ); free_money( reduced ); delete_all_rates(); }
static void test_multiply_dollar_5x3x3() { Expression *five = dollar( 5 ); Expression *product1 = multiply( five, 3 ); Expression *product2 = multiply( product1, 3 ); Expression *fortyfive = dollar( 45 ); Money *reduced = reduce( product2, USD ); assert_true( equal( reduced, money_from( fortyfive ) ) ); free_expression( five ); free_expression( product1 ); free_expression( product2 ); free_expression( fortyfive ); free_money( reduced ); delete_all_rates(); }
static void test_equal() { Expression *five_dollar1 = dollar( 5 ); Expression *five_dollar2 = dollar( 5 ); Expression *six_dollar = dollar( 6 ); Expression *five_franc = franc( 5 ); assert_true( equal( money_from( five_dollar1 ), money_from( five_dollar2 ) ) ); assert_false( equal( money_from( five_dollar1 ), money_from( six_dollar ) ) ); assert_false( equal( money_from( five_dollar1 ), money_from( five_franc ) ) ); free_expression( five_dollar1 ); free_expression( five_dollar2 ); free_expression( six_dollar ); free_expression( five_franc ); delete_all_rates(); }
void expr_put(struct expression *expr) { assert(expr->refcount > 0); expr->refcount--; if (expr->refcount == 0) free_expression(expr); }
/* * free memory allocated by an expression */ void free_expression(expression *e) { if (!e) return; if (e->next) free_expression(e->next); regfree(e->reg_value); pkg_free(e); }
static void test_simple_addition() { Expression *five = dollar( 5 ); Expression *addend_five = dollar( 5 ); Expression *ten = dollar( 10 ); Expression *sum = plus( five, addend_five ); Money *reduced = reduce( sum, USD ); assert_true( equal( money_from( ten ), reduced ) ); free_expression( five ); free_expression( addend_five ); free_expression( sum ); free_money( reduced ); free_expression( ten ); delete_all_rates(); }
static void test_reduce_sum() { Expression *three_usd = dollar( 3 ); Expression *four_usd = dollar( 4 ); Expression *seven_usd = dollar( 7 ); Expression *exp = plus( three_usd, four_usd ); Money *result = reduce( exp , USD ); assert_true( equal( result , money_from( seven_usd ) ) ); free_expression( three_usd ); free_expression( four_usd ); free_expression( seven_usd ); free_expression( exp ); free_money( result ); delete_all_rates(); }
static void test_mixed_addition() { Expression *five_bucks = dollar( 5 ); Expression *ten_francs = franc( 10 ); Expression *ten_usd = dollar( 10 ); add_rate( CHF, USD, 2 ); Expression *exp = plus( five_bucks, ten_francs ); Money *result = reduce( exp, USD ); assert_true( equal( money_from( ten_usd ), result ) ); free_expression( five_bucks ); free_expression( ten_francs ); free_expression( ten_usd ); free_expression( exp ); free_money( result ); delete_all_rates(); }
void free_expression_list(struct expression_list *list) { while (list != NULL) { free_expression(list->expression); struct expression_list *dead = list; list = list->next; free(dead); } }
void free_args(arglist_t args) { for (unsigned i = 0; i < args.size; ++i) { free_expression(args.data[i]->e); free(args.data[i]); } list_free(args); }
int parse_expression(tk_expr_t **expr_p, const char *buf, size_t size, int debug) { void *ybuf; ybuf = yy_scan_bytes(buf, size); if(!ybuf) { assert(ybuf); return -1; } if(expr_p) *expr_p = 0; tk_expr_t *expr = 0; int ret = yyparse((void *)&expr); yy_delete_buffer(ybuf); if(ret == 0) { assert(expr); if(expr->type == EXPR_DATA) { /* Trivial expression found, should exactly match input. */ assert(expr->u.data.size == size); assert(memcmp(expr->u.data.data, buf, size) == 0); if(expr_p) *expr_p = expr; else free_expression(expr); return 0; /* No expression found */ } else { if(expr_p) *expr_p = expr; else free_expression(expr); return 1; } } else { char tmp[PRINTABLE_DATA_SUGGESTED_BUFFER_SIZE(size)]; DEBUG("Failed to parse \"%s\"\n", printable_data(tmp, sizeof(tmp), buf, size, 1)); free_expression(expr); return -1; } }
/* * parse a complex expression list like a, b, c EXCEPT d, e * return 0 on success, -1 on error * parsed expressions are returned in **e, and exceptions are returned in **e_exceptions */ static int parse_expression(char *str, expression **e, expression **e_exceptions) { char *except, str2[LINE_LENGTH]; int i=0, l; if (!str || !e || !e_exceptions) return -1; except = strstr(str, " EXCEPT "); if (except) { /* exception found */ l = except-str; if (l >= LINE_LENGTH) { /* error */ LOG(L_ERR, "ERROR: parse_expression(): too long config line, increase LINE_LENGTH\n"); goto error; } strncpy(str2, str, l); str2[l] = '\0'; /* except+8 points to the exception */ if (parse_expression_list(except+8, e_exceptions)) { /* error */ goto error; } } else { /* no exception */ l = strlen(str); if (l >= LINE_LENGTH) { /* error */ LOG(L_ERR, "ERROR: parse_expression(): too long config line, increase LINE_LENGTH\n"); goto error; } strncpy(str2, str, l); str2[l] = '\0'; *e_exceptions = NULL; } while ((str2[i] == ' ') || (str2[i] == '\t')) i++; if (strncmp("ALL", str2+i, 3) == 0) { *e = NULL; } else { if (parse_expression_list(str2+i, e)) { /* error */ if (*e_exceptions) free_expression(*e_exceptions); goto error; } } return 0; error: *e = *e_exceptions = NULL; return -1; }
static void test_multiple_addition() { Expression *five_bucks = dollar( 5 ); Expression *ten_francs = franc( 10 ); Expression *fifteen_bucks = dollar( 15 ); add_rate( CHF, USD, 2 ); Expression *exp1 = plus( five_bucks, ten_francs ); Expression *exp2 = plus( exp1, five_bucks ); Money *result = reduce( exp2, USD ); assert_true( equal( money_from( fifteen_bucks ), result ) ); free_expression( five_bucks ); free_expression( ten_francs ); free_expression( fifteen_bucks ); free_expression( exp1 ); free_expression( exp2 ); free_money( result ); delete_all_rates(); }
void free_intlist(intlist_t dims) { for (unsigned i = 0; i < dims.size; ++i) { if(dims.data[i] != NULL) free_expression(dims.data[i]); } list_free(dims); }
void free_expression(tk_expr_t *expr) { if(expr) { switch(expr->type) { case EXPR_DATA: free((void *)expr->u.data.data); break; case EXPR_MODULO: free_expression((void *)expr->u.modulo.expr); break; case EXPR_CONCAT: free_expression(expr->u.concat.expr[0]); free_expression(expr->u.concat.expr[1]); break; case EXPR_CONNECTION_PTR: case EXPR_CONNECTION_UID: break; } } }
struct expr *infix(struct expr *left, char *expect) { exprlist_t args; int toktype = tok->type; char *ident; switch (toktype) { case PLUS: case MINUS: case STAR: case SLASH: case OR: case XOR: case LT: case LE: case GT: case GE: case NEQ: case EQ: case AND: return binopexpr(left, toktype, expression(lbp(toktype))); case LPAREN: if (left->exprtype != identtype) syntaxerror("calling non-callable expression"); args = empty_exprlist(); if (lookahead[0]->type != COMMA && lookahead[0]->type != RPAREN) list_push_back(args, expression(0)); while (lookahead[0]->type == COMMA) { eat(COMMA); list_push_back(args, expression(0)); } eat(RPAREN); ident = strdup(left->val.ident); left->type = NULL; // To prevent segfaults when freeing the expr free_expression(left); return funcallexpr(ident, args); case LSQBRACKET: args = empty_exprlist(); list_push_back(args, expression(0)); while (lookahead[0]->type == COMMA) { eat(COMMA); list_push_back(args, expression(0)); } eat(RSQBRACKET); return arrayexpr(left, args); case DOT: eat(IDENTIFIER); char *ident = strdup(tok->val); return record_access(left, ident); case DEREF: return make_deref(left); default: syntaxerror("expected %s, not %s", expect, tok->val); next(); switch (tok->type) { case ENDOFFILE: return expr_from_val(0); default: return infix(left, "expression"); } } }
static void delete_column(column_t* t) { if(t->expression) free_expression(t->expression); if(t->description) free(t->description); if(t->format) free(t->format); if (t->header) free(t->header); free(t->error_field); free(t->empty_field); }
/* Adding a new counter in counters list */ int add_counter(screen_t* const s, char* alias, char* config, char* type) { uint64_t int_conf = 0; uint32_t int_type = 0; int err=0; int n; expression* expr = NULL; if (s->num_counters >= MAX_EVENTS) { error_printf("Too many counters (max %d) in screen '%s', ignoring '%s'\n" "(change MAX_EVENTS and recompile)\n", MAX_EVENTS, s->name, alias); return -1; } int_type = get_counter_type(type, &err); if (err > 0) { /* error*/ error_printf("Bad type '%s': ignoring counter '%s'\n", type, alias); return -1; } /* Parse the configuration */ expr = parser_expression(config); err=0; int_conf = evaluate_counter_expression(expr, &err); free_expression(expr); if (err > 0) { /* error*/ error_printf("Bad config '%s': ignoring counter '%s'\n", config, alias); return -1; } n = s->num_counters; /* check max available hw counter */ if (n == s->num_alloc_counters) { s->counters = realloc(s->counters, sizeof(counter_t) * (n + alloc_chunk)); s->num_alloc_counters += alloc_chunk; } /* initialisation */ s->counters[n].used = 0; s->counters[n].type = int_type; s->counters[n].config = int_conf; s->counters[n].alias = strdup(alias); s->num_counters++; return n; }
int get_value_calculated(DC_ITEM *dc_item, AGENT_RESULT *result) { const char *__function_name = "get_value_calculated"; expression_t exp; int ret; char error[MAX_STRING_LEN]; double value; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s' expression:'%s'", __function_name, dc_item->key_orig, dc_item->params); memset(&exp, 0, sizeof(exp)); if (SUCCEED != (ret = calcitem_parse_expression(dc_item, &exp, error, sizeof(error)))) { SET_MSG_RESULT(result, strdup(error)); goto clean; } if (SUCCEED != (ret = calcitem_evaluate_expression(dc_item, &exp, error, sizeof(error)))) { SET_MSG_RESULT(result, strdup(error)); goto clean; } if (SUCCEED != evaluate(&value, exp.exp, error, sizeof(error))) { SET_MSG_RESULT(result, strdup(error)); ret = NOTSUPPORTED; goto clean; } zabbix_log(LOG_LEVEL_DEBUG, "%s() value:" ZBX_FS_DBL, __function_name, value); if (ITEM_VALUE_TYPE_UINT64 == dc_item->value_type && 0 > value) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Received value [" ZBX_FS_DBL "]" " is not suitable for value type [%s].", value, zbx_item_value_type_string(dc_item->value_type))); ret = NOTSUPPORTED; goto clean; } SET_DBL_RESULT(result, value); clean: free_expression(&exp); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/* * parse a complex expression list like a, b, c EXCEPT d, e * return 0 on success, -1 on error * parsed expressions are returned in **e, and exceptions are returned in **e_exceptions */ static int parse_expression(char *sv, expression **e, expression **e_exceptions) { char *except, str2[LINE_LENGTH+1]; int i,j; if (!sv || !e || !e_exceptions) return -1; if(strlen(sv)>=LINE_LENGTH) { LM_ERR("expression string is too long (%s)\n", sv); return -1; } except = strstr(sv, " EXCEPT "); if (except) { /* exception found */ strncpy(str2, sv, except-sv); str2[except-sv] = '\0'; /* except+8 points to the exception */ if (parse_expression_list(except+8, e_exceptions)) { /* error */ *e = *e_exceptions = NULL; return -1; } } else { /* no exception */ strcpy(str2, sv); *e_exceptions = NULL; } for( i=0; isspace((int)str2[i]) ; i++); for( j=strlen(str2)-1 ; isspace((int)str2[j]) ; str2[j--]=0); if (strcmp("ALL", str2+i) == 0) { *e = NULL; } else { if (parse_expression_list(str2+i, e)) { /* error */ if (*e_exceptions) free_expression(*e_exceptions); *e = *e_exceptions = NULL; return -1; } } return 0; }