/* * power */ double ExpParser::parse_level6() { int op_id; double ans; ans = parse_level7(); op_id = get_operator_id(token); while (op_id == POW) { getToken(); ans = eval_operator(op_id, ans, parse_level7()); op_id = get_operator_id(token); } return ans; }
/* * add or subtract */ double ExpParser::parse_level4() { int op_id; double ans; ans = parse_level5(); op_id = get_operator_id(token); while (op_id == PLUS || op_id == MINUS) { getToken(); ans = eval_operator(op_id, ans, parse_level5()); op_id = get_operator_id(token); } return ans; }
/* * multiply, divide, modulus, xor */ double ExpParser::parse_level5() { int op_id; double ans; ans = parse_level6(); op_id = get_operator_id(token); while (op_id == MULTIPLY || op_id == DIVIDE || op_id == MODULUS || op_id == XOR) { getToken(); ans = eval_operator(op_id, ans, parse_level6()); op_id = get_operator_id(token); } return ans; }
/* * conditional operators */ double ExpParser::parse_level3() { int op_id; double ans; ans = parse_level4(); op_id = get_operator_id(token); while (op_id == EQUAL || op_id == UNEQUAL || op_id == SMALLER || op_id == LARGER || op_id == SMALLEREQ || op_id == LARGEREQ) { getToken(); ans = eval_operator(op_id, ans, parse_level4()); op_id = get_operator_id(token); } return ans; }
/* * conditional operators and bitshift */ double ExpParser::parse_level2() { int op_id; double ans; ans = parse_level3(); op_id = get_operator_id(token); while (op_id == AND || op_id == OR || op_id == BITSHIFTLEFT || op_id == BITSHIFTRIGHT) { getToken(); ans = eval_operator(op_id, ans, parse_level3()); op_id = get_operator_id(token); } return ans; }
/* * Factorial */ double ExpParser::parse_level7() { int op_id; double ans; ans = parse_level8(); op_id = get_operator_id(token); while (op_id == FACTORIAL) { getToken(); // factorial does not need a value right from the // operator, so zero is filled in. ans = eval_operator(op_id, ans, 0.0); op_id = get_operator_id(token); } return ans; }
void log_batch_operation(PGconn *conn, unsigned int batch_number, enum batch_op opcode, int data1, int data2) { char *operator_id = get_operator_id(); char *timestamp = generate_sortable_timestamp(); SQL_command(conn, "INSERT INTO batch_history" "(batch_number,operator_id, time_stamp, op_code,data1,data2) " "values(%u, '%s', '%s', %u, %u, %u);", batch_number, operator_id, timestamp, opcode, data1, data2); free(operator_id); free(timestamp); }
/* * Unary minus */ double ExpParser::parse_level8() { double ans; int op_id = get_operator_id(token); if (op_id == MINUS) { getToken(); ans = parse_level9(); ans = -ans; } else { ans = parse_level9(); } return ans; }
extern void update_active_entries(PGconn *conn, unsigned int batch_number, unsigned int paper_index, int preferred_entry_to_replace, const char *electorate_name) { int temp; unsigned int num_entries,match_code,entry_to_replace; int paper_id; paper_id = SQL_singleton_int(conn, "SELECT id " "FROM %s_paper " "WHERE batch_number = %u " "AND index = %u; ", electorate_name, batch_number,paper_index); num_entries= (unsigned int) SQL_singleton_int(conn, "SELECT MAX(e.index) " "FROM %s_entry e,%s_paper p " "WHERE p.batch_number = %u " "AND e.paper_id = p.id " "AND p.id = %u; ", electorate_name,electorate_name, batch_number,paper_id); /* if only 1 or two entries, make new entry active */ if (num_entries < 3) { entry_to_replace = num_entries; if (entry_to_replace == 1) { temp = (unsigned int) SQL_singleton_int(conn, "SELECT MAX(e.index) " "FROM %s_entry e, %s_paper p " "WHERE p.batch_number = %u " "AND e.paper_id = p.id " "AND e.operator_id = '%s';", electorate_name, electorate_name, batch_number, get_operator_id()); if (temp == 2) { entry_to_replace = temp; } } } else { /* returns either matching active entry OR 3 = both matched, 4 = neither matched*/ match_code = match_active_entries(conn, (char *)electorate_name, paper_id); if (match_code == 1 || match_code == 2) { /* only one active entry matched; replace the other */ entry_to_replace=(3-match_code); } else { if (strncmp(get_operator_id(),"super",5) ==0) { /* user is SUPER and either both or neither matched: */ /* replace 1st active entry (arbitrary choice) */ if (preferred_entry_to_replace < 0) entry_to_replace = (unsigned int) (-1 * preferred_entry_to_replace); else entry_to_replace = (unsigned int) preferred_entry_to_replace; } else { /* normal user and both or neither matched: */ /* leave active entries unchanged */ entry_to_replace = 0; } } } if (preferred_entry_to_replace < 0) { /* When preferred_entry_to_replace is less than zero, then abs(preferred_entry_to_be_replace) is to be used as the entry index. */ /* SIPL 2011-09-26 Add parentheses to adjust the "order" of evaluation. In fact, it makes no difference because of two's complement arithmetic. But it is now consistent with the previous similar assignment statement. */ entry_to_replace = (unsigned int) (-1 * preferred_entry_to_replace); } /* do the replacement if required */ if (entry_to_replace > 0) replace_active_entry(conn, batch_number, paper_index, electorate_name, paper_id, entry_to_replace, num_entries); }
void append_entry(PGconn *conn, struct entry *newentry, unsigned int batch_number, unsigned int paper_index) /* Insert the entry into the database. */ { char *electorate_name, *entry_table_name, *paper_table_name; int paper_id=-1; int temp; unsigned int i,entry_index; /* SIPL 2011-09-26 Increase array size by one to allow space for null at end, to cope with the case where there really are PREFNUM_MAX preferences in the vote. */ char pref_string[DIGITS_PER_PREF * PREFNUM_MAX + 1]; char *pref_ptr, *p; struct predefined_batch *batch; /* get electorate code */ batch =resolve_batch_source(conn, batch_number); electorate_name = resolve_electorate_name(conn, batch->electorate_code); if (batch->electorate_code < 0) bailout("append_entry could not find batch number %u.\n", batch_number); /* get electorate name in order to access that Electorates' paper and entry tables */ paper_table_name = sprintf_malloc("%s_paper",electorate_name); entry_table_name = sprintf_malloc("%s_entry",electorate_name); /* Start the transaction */ begin(conn); /* check paper exists */ paper_id = SQL_singleton_int(conn, "SELECT id " "FROM %s_paper " "WHERE batch_number = %u " "AND index = %u; ", electorate_name, batch_number,paper_index); /* Insert new paper if necessary */ if (paper_id < 0) { SQL_command(conn, "INSERT INTO " "%s(batch_number,index) " "VALUES(%u,%u);", paper_table_name,batch_number,paper_index); entry_index = 1; paper_id = SQL_singleton_int(conn,"SELECT CURRVAL('%s_id_seq');", paper_table_name); } else { /* Get last (archived) entry index for this paper */ entry_index = SQL_singleton_int(conn, "SELECT MAX(index) FROM %s " "WHERE paper_id = %d;", entry_table_name, paper_id); if (entry_index < 0) entry_index = 1; /* It must be the first one */ else entry_index++; } if (entry_index == 1) { /* Check for the case there this is actually entry_index=2, and where there is no entry_index=1. */ temp = (unsigned int) SQL_singleton_int(conn, "SELECT MAX(e.index) " "FROM %s_entry e, %s_paper p " "WHERE p.batch_number = %u " "AND e.paper_id = p.id " "AND e.operator_id = '%s';", electorate_name, electorate_name, batch_number, get_operator_id()); if (temp == 2) { /* This paper's belongs to entry index 2, not 1. */ entry_index = 2; } } /* Format the preferences into a string */ pref_string[0]='\0'; pref_ptr = &pref_string[0]; for (i=0;i<newentry->e.num_preferences;i++) { p = sprintf_malloc("%02u%02u%02u", newentry->preferences[i].prefnum, newentry->preferences[i].group_index, newentry->preferences[i].db_candidate_index ); strcpy(pref_ptr,p); pref_ptr += (sizeof(char)*(DIGITS_PER_PREF)); free(p); } /* Insert new entry into archive */ SQL_command(conn, "INSERT INTO %s(index,operator_id," "paper_id,num_preferences,paper_version,preference_list) " "VALUES(%u,'%s',%u,%u,%u,'%s');", entry_table_name, entry_index, newentry->e.operator_id, paper_id,newentry->e.num_preferences, newentry->e.paper_version_num, &pref_string[0]); /* update active entries */ update_active_entries(conn, batch_number, paper_index, 1, // arbitrary, could be 2 (const char *) electorate_name); free(electorate_name); free(paper_table_name); free(entry_table_name); free(batch); /* Complete the transaction */ commit(conn); }