void *bank_server(void *args) { OpQueue queue; init_opqueue(&queue); int balance = 0; int locked_by = -1; while(1) { Operation *op = NULL; if(operation.status == 1) { pthread_mutex_lock(&operation.mutex); op = clone_op(&operation); operation.status = 0; pthread_mutex_unlock(&operation.mutex); fprintf(stderr, "[Thread %d], operation %s, new op", op->client_id, code_to_text(op->code)); } else if(locked_by == -1) { op = pop_op(&queue); if(op != NULL) { fprintf(stderr, "[Thread %d], operation %s, popped op", op->client_id, code_to_text(op->code)); } } else { continue; } if(op == NULL) { continue; } int is_performable = can_perform_op(op->code, op->client_id, locked_by); if(is_performable != 0) { pthread_mutex_lock(&op->put_answer_to->mutex); if(is_performable == 1) { switch(op->code) { case OP_LOOK: op->put_answer_to->comment = ""; break; case OP_LOCK: op->put_answer_to->comment = "successfully locked"; locked_by = op->client_id; break; case OP_UNLOCK: op->put_answer_to->comment = "successfully unlocked"; locked_by = -1; break; case OP_INC: balance += op->value; op->put_answer_to->comment = "successfuly added"; break; case OP_DEC: balance -= op->value; op->put_answer_to->comment = "successfully withdrawed"; break; } fprintf(stderr, " - completed\n"); } else { op->put_answer_to->comment = "balance not locked"; fprintf(stderr, " - declined\n"); } op->put_answer_to->status = is_performable; op->put_answer_to->value = balance; // free(op); pthread_cond_signal(&op->put_answer_to->cond); pthread_mutex_unlock(&op->put_answer_to->mutex); } else { push_op(&queue, op); fprintf(stderr, " - pushed to queue\n"); } } return NULL; }
static bool execute(char *buffer, bool *data) { char *token, **ops, *o1, *o2; bool *output, res; int n_o, n_q, sz_o, sz_q;; sz_o = 8192; sz_q = 8192; ops = malloc(sz_q * sizeof(char *)); output = malloc(sz_o * sizeof(bool)); n_o = n_q = 0; for (token = strtok(buffer, " "); token; token = strtok(NULL, " ")) { if (strncmp(token, "b", 1) == 0) { push_bit(data[atoi(token + 1)], &output, &n_o, &sz_o); } else if (is_function(token)) { push_op(token, &ops, &n_q, &sz_q); } else if (strncmp(token, ",", 1) == 0) { while (strncmp(peek_op(ops, n_q), "(", 1) != 0) { token = pop_op(ops, &n_q); if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } } else if (is_operator(token)) { o1 = token; while (peek_op(ops, n_q) && is_operator(peek_op(ops, n_q))) { o2 = peek_op(ops, n_q); if (operator_precedence(o1) <= operator_precedence(o2)) { push_bit(operator(pop_op(ops, &n_q), pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { break; } } push_op(o1, &ops, &n_q, &sz_q); } else if (strncmp(token, "(", 1) == 0) { push_op(token, &ops, &n_q, &sz_q); } else if (strncmp(token, ")", 1) == 0) { while (strncmp(peek_op(ops, n_q), "(", 1) != 0) { token = pop_op(ops, &n_q); if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } token = pop_op(ops, &n_q); /* pop the left bracket */ if (peek_op(ops, n_q) && is_function(peek_op(ops, n_q))) { push_bit(function(pop_op(ops, &n_q), output, &n_o), &output, &n_o, &sz_o); } } else { fprintf(stderr, "ERROR: unknown symbol: %s\n", token); exit(EXIT_FAILURE); } } while ((token = pop_op(ops, &n_q))) { if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } res = output[0]; free(output); free(ops); return res; }
int push_val(int type) { unsigned int mul, val; int op; char c; val = 0; c = *expr; switch (type) { /* program counter */ case T_PC: if (data_loccnt == -1) val = (loccnt + (page << 13)); else val = (data_loccnt + (page << 13)); expr++; break; /* char ascii value */ case T_CHAR: expr++; val = *expr++; if ((*expr != c) || (val == 0)) { error("Syntax Error!"); return (0); } expr++; break; /* symbol */ case T_SYMBOL: /* extract it */ if (!getsym()) return (0); /* an user function? */ if (func_look()) { if (!func_getargs()) return (0); expr_stack[func_idx++] = expr; expr = func_ptr->line; return (1); } /* a predefined function? */ op = check_keyword(); if (op) { if (!push_op(op)) return (0); else return (1); } /* search the symbol */ expr_lablptr = stlook(1); /* check if undefined, if not get its value */ if (expr_lablptr == NULL) return (0); else if (expr_lablptr->type == UNDEF) undef++; else if (expr_lablptr->type == IFUNDEF) undef++; else val = expr_lablptr->value; /* remember we have seen a symbol in the expression */ expr_lablcnt++; break; /* binary number %1100_0011 */ case T_BINARY: mul = 2; goto extract; /* hexa number $15AF */ case T_HEXA: mul = 16; goto extract; /* decimal number 48 (or hexa 0x5F) */ case T_DECIMAL: if ((c == '0') && (toupper(expr[1]) == 'X')) { mul = 16; expr++; } else { mul = 10; val = c - '0'; } /* extract a number */ extract: for (;;) { expr++; c = *expr; if (isdigit(c)) c -= '0'; else if (isalpha(c)) { c = toupper(c); if (c < 'A' && c > 'F') break; else { c -= 'A'; c += 10; } } else if (c == '_' && mul == 2) continue; else break; if (c >= mul) break; val = (val * mul) + c; } break; } /* check for too big expression */ if (val_idx == 63) { error("Expression too complex!"); return (0); } /* push the result on the value stack */ val_idx++; val_stack[val_idx] = val; /* next must be an operator */ need_operator = 1; /* ok */ return (1); }
static int evaluate( char * * line, long *val ) { long arg; char * ptr; char * str; char * endptr; int ercode; operator * op; int expr_oper; // looking for term or operator expr_oper = 0; coper = 0; cvalue = 0; nparens = 0; ptr = *line; while( *ptr ) { if( *ptr == ' ' ) { if( ignore_blanks ) { ptr++; continue; } else { break; } } switch( expr_oper ) { case 0: // look for term str = get_exp( ptr ); if( str == NULL ) { // nothing is error return( not_ok ); } op = get_op( str ); if( *(str +1) == NULC ) { if( NULL != op ) { push_op( op->operc ); ptr++; break; } if( (*str == '-' ) || (*str == '+' ) ) { push_op(*str); ++ptr; break; } } arg = strtol( str, &endptr, 10 ); if( (((arg == LONG_MIN) || (arg == LONG_MAX)) && errno == ERANGE) || (str == endptr) ) { return( not_ok ); } push_val( arg ); ptr += endptr - str; // to the next unprocessed char expr_oper = 1; // look for operator next break; case 1: // look for operator op = get_op( ptr ); if( NULL == op ) { return( not_ok ); } if( ')' == *ptr ) { ercode = do_paren(); if( ok > ercode ) { return( ercode ); } } else { while( coper && op->priority <= get_prio_m1() ) { do_expr(); } push_op( op->operc ); expr_oper = 0; // look for term next } ptr++; break; } } while( 1 < cvalue ) { ercode = do_expr(); if( ok > ercode ) return ercode; } if( !coper ) { *line = ptr; // next scan position return( pop_val( val ) ); // no operations left return result } else { return( not_ok ); } }
int evaluate(char *line, double *val) //-------------------------------------------------------------------- // Evaluates an ASCII mathematical expression // INPUT: line: String to evaluate // val: Storage to receive double result // // RETURN: SUCCESS = 0 if successful // E_ERROR = -1 if syntax error // R_ERROR = -2 if runtime error // DUV_ZERO= -3 Division by 0 // // Side effects: Removes all whitespace from the string and converts // it to U.C. //-------------------------------------------------------------------- { double arg; char *ptr = line, *str, *endptr; int ercode; struct operator *op; strupr(line); rmallws(line); state = op_sptr = arg_sptr = parens = 0; while (*ptr) { switch (state) { case 0: if (NULL != (str = get_exp(ptr))) { if (NULL != (op = get_op(str)) && strlen(str) == op->taglen) { push_op(op->token); ptr += op->taglen; break; } if (SUCCESS == strcmp(str, "-")) { push_op(*str); ++ptr; break; } if (SUCCESS == strcmp(str, "PI")) push_arg(Pi); else { if (0.0 == (arg = strtod(str, &endptr)) && NULL == strchr(str, '0')) { return E_ERROR; } push_arg(arg); } ptr += strlen(str); } else return E_ERROR; state = 1; break; case 1: if (NULL != (op = get_op(ptr))) { if (')' == *ptr) { if (SUCCESS > (ercode = do_paren())) return ercode; } else { while (op_sptr && op->precedence <= getTOSprec()) { do_op(); } push_op(op->token); state = 0; } ptr += op->taglen; } else return E_ERROR; break; } } while (1 < arg_sptr) { if (SUCCESS > (ercode = do_op())) return ercode; } if (!op_sptr) return pop_arg(val); else return E_ERROR; }
int evaluate(int *ip, char last_char) { int end, level; int op, type; int arg; int i; unsigned char c; end = 0; level = 0; undef = 0; op_idx = 0; val_idx = 0; value = 0; val_stack[0] = 0; need_operator = 0; expr_lablptr = NULL; expr_lablcnt = 0; op = OP_START; func_idx = 0; /* array index to pointer */ expr = &prlnbuf[*ip]; /* skip spaces */ cont: while (isspace(*expr)) expr++; /* search for a continuation char */ if (*expr == '\\') { /* skip spaces */ i = 1; while (isspace(expr[i])) i++; /* check if end of line */ if (expr[i] == ';' || expr[i] == '\0') { /* output */ if (!continued_line) { /* replace '\' with three dots */ strcpy(expr, "..."); /* store the current line */ strcpy(tmplnbuf, prlnbuf); } /* ok */ continued_line++; /* read a new line */ if (readline() == -1) return (0); /* rewind line pointer and continue */ expr = &prlnbuf[SFIELD]; goto cont; } } /* parser main loop */ while (!end) { c = *expr; /* number */ if (isdigit(c)) { if (need_operator) goto error; if (!push_val(T_DECIMAL)) return (0); } /* symbol */ else if (isalpha(c) || c == '_' || c == '.') { if (need_operator) goto error; if (!push_val(T_SYMBOL)) return (0); } /* operators */ else { switch (c) { /* function arg */ case '\\': if (func_idx == 0) { error("Syntax error in expression!"); return (0); } expr++; c = *expr++; if (c < '1' || c > '9') { error("Invalid function argument index!"); return (0); } arg = c - '1'; expr_stack[func_idx++] = expr; expr = func_arg[func_idx - 2][arg]; break; /* hexa prefix */ case '$': if (need_operator) goto error; if (!push_val(T_HEXA)) return (0); break; /* character prefix */ case '\'': if (need_operator) goto error; if (!push_val(T_CHAR)) return (0); break; /* round brackets */ case '(': if (need_operator) goto error; if (!push_op(OP_OPEN)) return (0); level++; expr++; break; case ')': if (!need_operator) goto error; if (level == 0) goto error; while (op_stack[op_idx] != OP_OPEN) { if (!do_op()) return (0); } op_idx--; level--; expr++; break; /* not equal, left shift, lower, lower or equal */ case '<': if (!need_operator) goto error; expr++; switch (*expr) { case '>': op = OP_NOT_EQUAL; expr++; break; case '<': op = OP_SHL; expr++; break; case '=': op = OP_LOWER_EQUAL; expr++; break; default: op = OP_LOWER; break; } if (!push_op(op)) return (0); break; /* right shift, higher, higher or equal */ case '>': if (!need_operator) goto error; expr++; switch (*expr) { case '>': op = OP_SHR; expr++; break; case '=': op = OP_HIGHER_EQUAL; expr++; break; default: op = OP_HIGHER; break; } if (!push_op(op)) return (0); break; /* equal */ case '=': if (!need_operator) goto error; if (!push_op(OP_EQUAL)) return (0); expr++; break; /* one complement */ case '~': if (need_operator) goto error; if (!push_op(OP_COM)) return (0); expr++; break; /* sub, neg */ case '-': if (need_operator) op = OP_SUB; else op = OP_NEG; if (!push_op(op)) return (0); expr++; break; /* not, not equal */ case '!': if (!need_operator) op = OP_NOT; else { op = OP_NOT_EQUAL; expr++; if (*expr != '=') goto error; } if (!push_op(op)) return (0); expr++; break; /* binary prefix, current PC */ case '%': case '*': if (!need_operator) { if (c == '%') type = T_BINARY; else type = T_PC; if (!push_val(type)) return (0); break; } /* modulo, mul, add, div, and, xor, or */ case '+': case '/': case '&': case '^': case '|': if (!need_operator) goto error; switch (c) { case '%': op = OP_MOD; break; case '*': op = OP_MUL; break; case '+': op = OP_ADD; break; case '/': op = OP_DIV; break; case '&': op = OP_AND; break; case '^': op = OP_XOR; break; case '|': op = OP_OR; break; } if (!push_op(op)) return (0); expr++; break; /* skip immediate operand prefix if in macro */ case '#': if (expand_macro) expr++; else end = 3; break; /* space or tab */ case ' ': case '\t': expr++; break; /* end of line */ case '\0': if (func_idx) { func_idx--; expr = expr_stack[func_idx]; break; } case ';': end = 1; break; case ',': end = 2; break; default: end = 3; break; } } } if (!need_operator) goto error; if (level != 0) goto error; while (op_stack[op_idx] != OP_START) { if (!do_op()) return (0); } /* get the expression value */ value = val_stack[val_idx]; /* any undefined symbols? trap that if in the last pass */ if (undef) { if (pass == LAST_PASS) error("Undefined symbol in operand field!"); } /* check if the last char is what the user asked for */ switch (last_char) { case ';': if (end != 1) goto error; expr++; break; case ',': if (end != 2) { error("Argument missing!"); return (0); } expr++; break; } /* convert back the pointer to an array index */ *ip = expr - prlnbuf; /* ok */ return (1); /* syntax error */ error: error("Syntax error in expression!"); return (0); }
static inline void push_increase_dlevel(op_stack_t *stack) { push_op(stack, INCREASE_DLEVEL); }
static inline void push_push(op_stack_t *stack) { push_op(stack, PUSH); }
static inline void push_propagate(op_stack_t *stack) { push_op(stack, PROPAGATE); }
/* Parse command-line options. */ static bool parse_options (int argc, char *argv[]) { int opt; operation_t op; int i_blocksize = 0; static const char helpText[] = "Usage: %s [OPTION...]\n" " Issues libcdio Multimedia commands. Operations occur in the order\n" " in which the options are given and a given operation may appear\n" " more than once to have it run more than once.\n" "options: \n" " -b, --blocksize[=INT] set blocksize. If no block size or a \n" " zero blocksize is given we return the\n" " current setting.\n" " -C, --drive-cap [6|10] print mode sense 2a data\n" " using 6-byte or 10-byte form\n" " -c, --close drive close drive via ALLOW_MEDIUM_REMOVAL\n" " -e, --eject [drive] eject drive via ALLOW_MEDIUM_REMOVAL\n" " and a MMC START/STOP command\n" " -I, --idle set CD-ROM to idle or power down\n" " via MMC START/STOP command\n" " -i, --inquiry print HW info via INQUIRY\n" " -m, --mcn get media catalog number (AKA UPC)\n" " -s, --speed-KB=INT Set drive speed to SPEED K bytes/sec\n" " Note: 1x = 176 KB/s \n" " -S, --speed-X=INT Set drive speed to INT X\n" " Note: 1x = 176 KB/s \n" " -V, --version display version and copyright information\n" " and exit\n" "\n" "Help options:\n" " -?, --help Show this help message\n" " --usage Display brief usage message\n"; static const char usageText[] = "Usage: %s [-b|--blocksize[=INT]] [-m|--mcn]\n" " [-I|--idle] [-I|inquiry] [-m[-s|--speed-KB INT]\n" " [-V|--version] [-?|--help] [--usage]\n"; /* Command-line options */ static const char optionsString[] = "b::c:C::e::Iis:V?"; const struct option optionsTable[] = { {"blocksize", optional_argument, &i_blocksize, 'b' }, {"close", required_argument, NULL, 'c'}, {"drive-cap", optional_argument, NULL, 'C'}, {"eject", optional_argument, NULL, 'e'}, {"idle", no_argument, NULL, 'I'}, {"inquiry", no_argument, NULL, 'i'}, {"mcn", no_argument, NULL, 'm'}, {"speed-KB", required_argument, NULL, 's'}, {"speed-X", required_argument, NULL, 'S'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, '?' }, {"usage", no_argument, NULL, OPT_USAGE }, { NULL, 0, NULL, 0 } }; while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0) switch (opt) { case 'b': op.op = OP_BLOCKSIZE; op.arg.i_num = i_blocksize; push_op(&op); break; case 'C': op.arg.i_num = optarg ? atoi(optarg) : 10; switch (op.arg.i_num) { case 10: op.op = OP_MODE_SENSE_2A; op.arg.i_num = 10; push_op(&op); break; case 6: op.op = OP_MODE_SENSE_2A; op.arg.i_num = 6; push_op(&op); break; default: report( stderr, "%s: Expecting 6 or 10 or nothing\n", program_name ); } break; case 'c': op.op = OP_CLOSETRAY; op.arg.psz = strdup(optarg); push_op(&op); break; case 'e': op.op = OP_EJECT; op.arg.psz=NULL; if (optarg) op.arg.psz = strdup(optarg); push_op(&op); break; case 'i': op.op = OP_INQUIRY; op.arg.psz=NULL; push_op(&op); break; case 'I': op.op = OP_IDLE; op.arg.psz=NULL; push_op(&op); break; case 'm': op.op = OP_MCN; op.arg.psz=NULL; push_op(&op); break; case 's': op.op = OP_SPEED; op.arg.i_num=atoi(optarg); push_op(&op); break; case 'S': op.op = OP_SPEED; op.arg.i_num=176 * atoi(optarg); push_op(&op); break; case 'V': print_version(program_name, VERSION, 0, true); free(program_name); exit (EXIT_SUCCESS); break; case '?': fprintf(stdout, helpText, program_name); free(program_name); exit(EXIT_INFO); break; case OPT_USAGE: fprintf(stderr, usageText, program_name); free(program_name); exit(EXIT_FAILURE); break; case OPT_HANDLED: break; i_blocksize = 0; } if (optind < argc) { const char *remaining_arg = argv[optind++]; if (source_name != NULL) { report( stderr, "%s: Source specified in option %s and as %s\n", program_name, source_name, remaining_arg ); free(program_name); exit (EXIT_FAILURE); } source_name = strdup(remaining_arg); if (optind < argc) { report( stderr, "%s: Source specified in previously %s and %s\n", program_name, source_name, remaining_arg ); free(program_name); exit (EXIT_FAILURE); } } return true; }
static int parse_token_list() { token_list *tok; tok = tl; ops = new_op_list(); while( tok != NULL ) { switch( tok->t ) { /* 3-register instructions */ case token_add: tok = three_reg_op(tok, op_add); break; case token_and: tok = three_reg_op(tok, op_and); break; case token_arccos: tok = three_reg_op(tok, op_arccos); break; case token_arcsin: tok = three_reg_op(tok, op_arcsin); break; case token_arctan: tok = three_reg_op(tok, op_arctan); break; case token_cos: tok = three_reg_op(tok, op_cos); break; case token_dist: tok = three_reg_op(tok, op_dist); break; case token_div: tok = three_reg_op(tok, op_div); break; case token_eq: tok = three_reg_op(tok, op_eq); break; case token_gt: tok = three_reg_op(tok, op_gt); break; case token_lt: tok = three_reg_op(tok, op_lt); break; case token_max: tok = three_reg_op(tok, op_max); break; case token_min: tok = three_reg_op(tok, op_min); break; case token_mod: tok = three_reg_op(tok, op_mod); break; case token_mul: tok = three_reg_op(tok, op_mul); break; case token_ne: tok = three_reg_op(tok, op_ne); break; case token_or: tok = three_reg_op(tok, op_or); break; case token_sin: tok = three_reg_op(tok, op_sin); break; case token_sub: tok = three_reg_op(tok, op_sub); break; case token_tan: tok = three_reg_op(tok, op_tan); break; case token_xor: tok = three_reg_op(tok, op_xor); break; /* 2-register instructions */ case token_abs: tok = two_reg_op(tok, op_abs); break; case token_chs: tok = two_reg_op(tok, op_chs); break; case token_mov: tok = two_reg_op(tok, op_mov); break; case token_not: tok = two_reg_op(tok, op_not); break; case token_setparam: tok = two_reg_op(tok, op_setparam); break; case token_sqrt: tok = two_reg_op(tok, op_sqrt); break; case token_vrecall: tok = two_reg_op(tok, op_vrecall); break; case token_vstore: tok = two_reg_op(tok, op_vstore); break; /* 1-register instructions */ case token_icon: tok = one_reg_op(tok, op_icon); break; case token_peek: tok = one_reg_op(tok, op_peek); break; case token_pop: tok = one_reg_op(tok, op_pop); break; case token_print: tok = one_reg_op(tok, op_print); break; case token_random: tok = one_reg_op(tok, op_random); break; case token_roll: tok = one_reg_op(tok, op_roll); break; case token_sound: tok = one_reg_op(tok, op_sound); break; case token_test: tok = one_reg_op(tok, op_test); break; case token_debug: tok = one_reg_op(tok, op_debug); break; /* 0-register instructions */ case token_beep: tok = zero_reg_op(tok, op_beep); break; case token_drop: tok = zero_reg_op(tok, op_drop); break; case token_dropall: tok = zero_reg_op(tok, op_dropall); break; case token_dup: tok = zero_reg_op(tok, op_dup); break; case token_end: tok = zero_reg_op(tok, op_end); break; case token_recall: tok = zero_reg_op(tok, op_recall); break; case token_return: tok = zero_reg_op(tok, op_return); break; case token_store: tok = zero_reg_op(tok, op_store); break; case token_swap: tok = zero_reg_op(tok, op_swap); break; case token_sync: tok = zero_reg_op(tok, op_sync); break; case token_nop: tok = zero_reg_op(tok, op_nop); break; /* Branching instructions */ case token_if: case token_ife: case token_ifg: case token_ifeg: case token_jump: case token_call: tok = branch_op(tok); break; /* Push instruction */ case token_push: tok = push_op(tok); break; /* Labels */ case token_label: tok = create_label(tok); break; /* Default: Syntax error */ default: /* TODO: error and die */ error_line = tok->line_number; error = err_unknown_token; return error; } } return error; }
/* Calcola e restituisce il risultato di un'espressione in forma infissa */ double EvalInfix(const char *strExpression, char * strError) { Token tok; Token tok_temp; double left, right; double dblRet; strcpy(strError, ""); tok_temp.Type = EOL; tok_temp.str[0] = '@'; tok_temp.str[1] = '\0'; push_op(tok_temp, strError); if ( strError[0] != '\0' ) return 0.0; left = right = 0.0; while ( (PreviousTokenType = GetNextToken(strExpression, &tok, TRUE)) != EOL ) { if ( tok.Type == UNKNOWN ) { sprintf(strError, "Error: invalid token: %s\n", tok.str); return 0.0; } else if ( tok.Type == VALUE ) { push_val(tok.Value, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == OPAREN || tok.Type == UMINUS || tok.Type == UPLUS ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == CPAREN ) { while ( top_op(strError).Type != OPAREN ) { if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( (tok_temp.Type == EOL) || (is_empty_op()) ) { sprintf(strError, "Error: unbalanced brackets.\n"); return 0.0; } right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type != UMINUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } else { while ( PREC_TABLE[ top_op(strError).Type ].topOfStack >= PREC_TABLE[ tok.Type ].inputSymbol ) { if ( strError[0] != '\0' ) return 0.0; if ( top_op(strError).Type != UMINUS && top_op(strError).Type != UPLUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { if ( top_op(strError).Type == UMINUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; pop_op(strError); if ( strError[0] != '\0' ) return 0.0; push_val(-1 * right, strError); if ( strError[0] != '\0' ) return 0.0; } else { pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } } } if ( tok.Type != EOL ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } } } while ( 1 ) { tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type == EOL ) break; if ( tok_temp.Type != UPLUS ) { right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; } if ( tok_temp.Type != UMINUS && tok_temp.Type != UPLUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } dblRet = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( is_empty_val() ) { return dblRet; } else { sprintf(strError, "Error: malformed expression.\n"); return 0.0; } }
// Solves the equation in 'str' // returns SUCCESS if equation was solved // returns FAIL if equation couldn't be solved // Solution returned in 'answer' int solve_equation(char* str, int *answer) { int j = 0; int ret; char curr; // intialize stack curr_num_stack = -1; curr_op_stack = -1; while (str[j] != 0) { curr = str[j]; // walk through the equation if (curr <= '9' && curr >= '0') { char t; int is_neg = 0; int val; // get the number (could be any number of spots) // this is a number, push it on the stack ret = peek_op(&t); if (ret == SUCCESS && t == '-') { if(pop_op(&t) != SUCCESS) return FAIL; push_op('+'); is_neg = 1; } int moved = 0; val = stoi(str+j, &moved); if (is_neg) val *= -1; is_neg = 0; push_num(val); //tmp = get_str_end(str+j); j += moved; continue; } if (curr == '(') { push_op(str[j]); j++; continue; } if (curr == ')') { if (satisfy_paren() != SUCCESS) return FAIL; j++; continue; } if (curr == '+' || curr == '-') { char p_op; ret = peek_op(&p_op); if (ret == SUCCESS && (p_op == '+' || p_op == '-' || p_op == '*' || p_op == '/')) { char prev_op; int larg, rarg, answer = 0; if (pop_num(&rarg)!= SUCCESS) return FAIL; if (pop_num(&larg)!= SUCCESS) return FAIL; if (pop_op(&prev_op)!= SUCCESS) return FAIL; if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL; push_num(answer); } push_op(str[j]); j++; continue; } if (curr == '*' || curr == '/') { char prev_op; ret = peek_op(&prev_op); if (ret == SUCCESS && (prev_op == '*' || prev_op == '/')) { int larg, rarg, answer = 0; if (pop_num(&rarg)!= SUCCESS) return FAIL; if (pop_num(&larg)!= SUCCESS) return FAIL; if (pop_op(&prev_op)!= SUCCESS) return FAIL; if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL; push_num(answer); } push_op(str[j]); j++; continue; } return FAIL; // Invalid input. } int b,a, tmp; pop_num(&b); while(curr_op_stack != -1) { if (pop_num(&a)!= SUCCESS) return FAIL; if (pop_op(&curr)!= SUCCESS) return FAIL; if (evaluate(a,curr,b, &tmp)!= SUCCESS) return FAIL; b = tmp; } *answer = b; return SUCCESS; }