static int do_concat(interp_t *interp, expr_t *e1, expr_t *e2) { char *out; unsigned int len = 0; int result = 0; var_t v1, v2; v1.type = v2.type = VAR_NULL; if (!cgc_eval_expression(interp, e1)) goto fail; move_var(&v1, &interp->result); if (!cgc_eval_expression(interp, e2)) goto fail; move_var(&v2, &interp->result); if (v1.type == VAR_STRING) len += cgc_strlen(v1.v_string.value) + 1; else if (v1.type == VAR_NUMBER || v1.type == VAR_NULL) len += 20; else goto fail; if (v2.type == VAR_STRING) len += cgc_strlen(v2.v_string.value) + 1; else if (v2.type == VAR_NUMBER || v2.type == VAR_NULL) len += 20; else goto fail; out = cgc_malloc(len); if (out == NULL) goto fail; if (v1.type == VAR_STRING) cgc_sprintf(out, "%s", v1.v_string.value); else if (v1.type == VAR_NUMBER) cgc_sprintf(out, "%d", v1.type == VAR_NUMBER ? v1.v_number.value : 0); else out[0] = 0; if (v2.type == VAR_STRING) cgc_sprintf(out + cgc_strlen(out), "%s", v2.v_string.value); else if (v2.type == VAR_NUMBER) cgc_sprintf(out + cgc_strlen(out), "%d", v2.type == VAR_NUMBER ? v2.v_number.value : 0); result = set_result_string(interp, out); fail: cgc_free_var(&v1); cgc_free_var(&v2); return result; }
void copyVariate() { int i; double **f = NULL; f = move_var(); state3_user(f); for (i = 0; i < lambda; i++) { free(f[i]); } free(f); }
static int do_print(interp_t *interp, stmt_t *stmt) { int result; unsigned int cnt, i; var_t *args, fmt; expr_t *e; if (stmt->s_print.fmt == NULL) { for (e = stmt->s_print.expr; e != NULL; e = e->next) { if (!cgc_eval_expression(interp, e)) return 0; if (interp->result.type == VAR_STRING) cgc_fdprintf(STDOUT, "%s", interp->result.v_string.value); else if (interp->result.type == VAR_NUMBER) cgc_fdprintf(STDOUT, "%d", interp->result.v_number.value); else if (interp->result.type != VAR_NULL) return 0; if (e->next != NULL) cgc_fdprintf(STDOUT, "%s", get_string(interp, "OFS")); } if (stmt->s_print.expr == NULL) { #ifdef PATCHED if (cgc_get_field(interp, 0) == NULL) return 0; else #endif cgc_fdprintf(STDOUT, "%s", cgc_get_field(interp, 0)); } cgc_fdprintf(STDOUT, "%s", get_string(interp, "ORS")); return 1; } if (!cgc_eval_expression(interp, stmt->s_print.fmt)) return 0; if (interp->result.type == VAR_NUMBER) { cgc_fdprintf(STDOUT, "%d", interp->result.v_number.value); return 1; } else if (interp->result.type != VAR_STRING) { return 1; } result = 0; move_var(&fmt, &interp->result); for (cnt = 0, e = stmt->s_print.expr; e != NULL; e = e->next) cnt++; args = cgc_calloc(sizeof(var_t), cnt); if (args == NULL) goto done; for (i = 0, e = stmt->s_print.expr; e != NULL; e = e->next, i++) { if (!cgc_eval_expression(interp, e)) goto done; move_var(&args[i], &interp->result); } if (cgc_eprintf(STDOUT, fmt.v_string.value, args, cnt) < 0) goto done; result = 1; done: if (args != NULL) { for (i = 0; i < cnt; i++) cgc_free_var(&args[i]); } cgc_free_var(&fmt); return result; }
static int cgc_eval_expression(interp_t *interp, expr_t *expr) { const char *s; int i, t1, t2; var_t tmp; #ifdef PATCHED if (expr == NULL) return 0; #endif switch(expr->op) { case OP_CONST_STRING: if (!set_result_string(interp, cgc_strdup(expr->e_cstring.value))) return 0; break; case OP_CONST_INT: if (!set_result_number(interp, expr->e_cint.value)) return 0; break; case OP_FIELD: s = cgc_get_field(interp, expr->e_cint.value); if (s == NULL) return 0; if (!set_result_string(interp, cgc_strdup(s))) return 0; break; case OP_FIELD_VAR: if (!get_number(interp, expr->e_var.name, &i)) return 0; s = cgc_get_field(interp, i); if (s == NULL) return 0; if (!set_result_string(interp, cgc_strdup(s))) return 0; break; case OP_VAR: if (!set_result_var(interp, get_var(interp, expr->e_var.name))) return 0; break; case OP_ASSIGN: if (!cgc_eval_expression(interp, expr->e_binop.rhs)) return 0; // set lhs to interp->result if (!cgc_assign_result(interp, expr->e_binop.lhs)) return 0; break; case OP_CONDITIONAL: if (!cgc_eval_expression(interp, expr->e_cond.cond)) return 0; if (coerce_bool(interp, &interp->result)) { if (!cgc_eval_expression(interp, expr->e_cond.vtrue)) return 0; } else { if (!cgc_eval_expression(interp, expr->e_cond.vfalse)) return 0; } break; case OP_OR: if (!cgc_eval_expression(interp, expr->e_binop.lhs)) return 0; if (coerce_bool(interp, &interp->result)) { if (!set_result_number(interp, TRUE)) return 0; } else { if (!cgc_eval_expression(interp, expr->e_binop.rhs)) return 0; if (!set_result_number(interp, coerce_bool(interp, &interp->result) ? TRUE : FALSE)) return 0; } break; case OP_AND: if (!cgc_eval_expression(interp, expr->e_binop.lhs)) return 0; if (!coerce_bool(interp, &interp->result)) { if (!set_result_number(interp, FALSE)) return 0; } else { if (!cgc_eval_expression(interp, expr->e_binop.rhs)) return 0; if (!set_result_number(interp, coerce_bool(interp, &interp->result) ? TRUE : FALSE)) return 0; } break; case OP_MATCH: case OP_NOT_MATCH: if (!cgc_do_match(interp, expr->e_binop.lhs, expr->e_binop.rhs)) return 0; if (expr->op == OP_NOT_MATCH) interp->result.v_number.value = interp->result.v_number.value == TRUE ? FALSE : TRUE; break; case OP_CONST_REGEXP: if (!cgc_do_match(interp, NULL, expr)) return 0; break; case OP_LT: case OP_GT: case OP_LTE: case OP_GTE: case OP_EQ: case OP_NEQ: if (!cgc_eval_expression(interp, expr->e_binop.lhs)) return 0; move_var(&tmp, &interp->result); if (!cgc_eval_expression(interp, expr->e_binop.rhs)) return 0; t1 = compare_value(&tmp, &interp->result); if ((expr->op == OP_LT && t1 < 0) || (expr->op == OP_GT && t1 > 0) || (expr->op == OP_LTE && t1 <= 0) || (expr->op == OP_GTE && t1 >= 0) || (expr->op == OP_EQ && t1 == 0) || (expr->op == OP_NEQ && t1 != 0)) { if (!set_result_number(interp, TRUE)) return 0; } else { if (!set_result_number(interp, FALSE)) return 0; } cgc_free_var(&tmp); break; case OP_ADD: case OP_ASSIGN_ADD: case OP_SUB: case OP_ASSIGN_SUB: case OP_MUL: case OP_ASSIGN_MUL: case OP_DIV: case OP_ASSIGN_DIV: case OP_MOD: case OP_ASSIGN_MOD: if (!cgc_eval_expression(interp, expr->e_binop.lhs)) return 0; t1 = coerce_number(interp, &interp->result); if (!cgc_eval_expression(interp, expr->e_binop.rhs)) return 0; t2 = coerce_number(interp, &interp->result); if (expr->op == OP_ADD || expr->op == OP_ASSIGN_ADD) t1 = t1 + t2; else if (expr->op == OP_SUB || expr->op == OP_ASSIGN_SUB) t1 = t1 - t2; else if (expr->op == OP_MUL || expr->op == OP_ASSIGN_MUL) t1 = t1 * t2; else if (expr->op == OP_DIV || expr->op == OP_ASSIGN_DIV) { if (t2 == 0) return 0; t1 = t1 / t2; } else if (expr->op == OP_MOD || expr->op == OP_ASSIGN_MOD) { if (t2 == 0) return 0; t1 = t1 % t2; } if (!set_result_number(interp, t1)) return 0; if (expr->op == OP_ASSIGN_ADD || expr->op == OP_ASSIGN_SUB || expr->op == OP_ASSIGN_MUL || expr->op == OP_ASSIGN_DIV || expr->op == OP_ASSIGN_MOD) { if (!cgc_assign_result(interp, expr->e_binop.lhs)) return 0; } break; case OP_INC_PRE: case OP_DEC_PRE: case OP_INC_POST: case OP_DEC_POST: if (!cgc_eval_expression(interp, expr->e_unop.expr)) return 0; move_var(&tmp, &interp->result); t1 = coerce_number(interp, &tmp); if (expr->op == OP_INC_PRE || expr->op == OP_INC_POST) t2 = t1 + 1; else t2 = t1 - 1; if (!set_result_number(interp, t2)) return 0; if (!cgc_assign_result(interp, expr->e_unop.expr)) return 0; if (expr->op == OP_INC_POST || expr->op == OP_DEC_POST) move_var(&interp->result, &tmp); else cgc_free_var(&tmp); break; case OP_NEGATE: case OP_NOT: if (!cgc_eval_expression(interp, expr->e_unop.expr)) return 0; t1 = coerce_number(interp, &interp->result); if (expr->op == OP_NEGATE) t2 = -t1; else t2 = coerce_bool(interp, &interp->result) == TRUE ? FALSE : TRUE; if (!set_result_number(interp, t2)) return 0; break; case OP_CONCAT: if (!do_concat(interp, expr->e_binop.lhs, expr->e_binop.rhs)) return 0; break; default: return 0; } return 1; }