int main(int argc, const char *argv[]) { int np, idx, i, j, amt, num, given, remainder; char name_tmp[16]; FILE *fin = fopen("gift1.in", "r"); FILE *fout = fopen("gift1.out", "w"); while (fscanf(fin, "%d", &np) != EOF) { for (i = 0; i < np; ++i) fscanf(fin, "%s", name[i]); for (i = 0; i < np; ++i) { fscanf(fin, "%s", name_tmp); idx = name_cmp(name_tmp); fscanf(fin, "%d%d", &amt, &num); if (!num) continue; remainder = amt % num; given = amt / num; amount[idx] += remainder ? -(amt - remainder) : -amt; for (j = 0; j < num; ++j) { fscanf(fin, "%s", given_list[j]); amount[name_cmp(given_list[j])] += given; } } /* load done, print */ for (i = 0; i < np; ++i) { fprintf(fout, "%s %d\n", name[i], amount[i]); } } return 0; }
/* find the first string greater than or equal to 'prefix' */ static uint32_t find_first_match(const char* prefix, int (* name_cmp)(const char* c1, const char* c2)) { uint32_t start = 0; uint32_t end = global_symbol_count; /* search for the last string less than 'prefix' */ while (end >= start + 2) { uint32_t mid = (start + end)/2; if (name_cmp(global_symbols[mid].name, prefix) < 0) { start = mid; } else { end = mid; } } if (start == end) return start; if (name_cmp(global_symbols[start].name, prefix) < 0) { return start + 1; } else { return start; } }
/* Used for sorting the hash entry */ static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b) { const struct hash_entry *he_a = (const struct hash_entry *) a; const struct hash_entry *he_b = (const struct hash_entry *) b; int ret; if (he_a->hash > he_b->hash) ret = 1; else if (he_a->hash < he_b->hash) ret = -1; else { if (he_a->minor_hash > he_b->minor_hash) ret = 1; else if (he_a->minor_hash < he_b->minor_hash) ret = -1; else ret = name_cmp(a, b); } return ret; }
static int cmp_pname(const void *a, const void *b) { return name_cmp(*(const char **)a, *(const char **)b, sort_separator); }
static insn_list * insn_list_insert (insn_list **cur_insn_ptr, int *nr_insns, insn_entry * insn, opcode_bits *expanded_bits, opcode_field *opcodes, int nr_prefetched_words, duplicate_insn_actions duplicate_action) { /* insert it according to the order of the fields & bits */ for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next) { int cmp; /* key#1 sort according to the constant fields of each instruction */ cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words); if (cmp < 0) break; else if (cmp > 0) continue; /* key#2 sort according to the expanded bits of each instruction */ cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits); if (cmp < 0) break; else if (cmp > 0) continue; /* key#3 sort according to the non-constant fields of each instruction */ cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words); if (cmp < 0) break; else if (cmp > 0) continue; if (duplicate_action == merge_duplicate_insns) { /* key#4: If we're going to merge duplicates, also sort according to the format_name. Two instructions with identical decode patterns, but different names, are considered different when merging. Duplicates are only important when creating a decode table (implied by report_duplicate_insns) as such a table only has the instruction's bit code as a way of differentiating between instructions. */ int cmp = name_cmp (insn->format_name, (*cur_insn_ptr)->insn->format_name); if (cmp < 0) break; else if (cmp > 0) continue; } if (duplicate_action == merge_duplicate_insns) { /* key#5: If we're going to merge duplicates, also sort according to the name. See comment above for format_name. */ int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name); if (cmp < 0) break; else if (cmp > 0) continue; } /* duplicate keys, report problem */ switch (duplicate_action) { case report_duplicate_insns: /* It would appear that we have two instructions with the same constant field values across all words and bits. This error can also occure when insn_field_cmp() is failing to differentiate between two instructions that differ only in their conditional fields. */ warning (insn->line, "Two instructions with identical constant fields\n"); error ((*cur_insn_ptr)->insn->line, "Location of duplicate instruction\n"); case merge_duplicate_insns: /* Add the opcode path to the instructions list */ if (options.trace.insn_insertion) { notify ((*cur_insn_ptr)->insn->line, "%s.%s: insert merge %s.%s\n", (*cur_insn_ptr)->insn->format_name, (*cur_insn_ptr)->insn->name, insn->format_name, insn->name); } if (opcodes != NULL) { insn_opcodes **last = &(*cur_insn_ptr)->opcodes; while (*last != NULL) { last = &(*last)->next; } (*last) = ZALLOC (insn_opcodes); (*last)->opcode = opcodes; } /* Use the larger nr_prefetched_words */ if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words) (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words; return (*cur_insn_ptr); } } /* create a new list entry and insert it */ { insn_list *new_insn = ZALLOC (insn_list); if (options.trace.insn_insertion) { notify (insn->line, "%s.%s: insert new\n", insn->format_name, insn->name); } new_insn->insn = insn; new_insn->expanded_bits = expanded_bits; new_insn->next = (*cur_insn_ptr); new_insn->nr_prefetched_words = nr_prefetched_words; if (opcodes != NULL) { new_insn->opcodes = ZALLOC (insn_opcodes); new_insn->opcodes->opcode = opcodes; } (*cur_insn_ptr) = new_insn; } *nr_insns += 1; return (*cur_insn_ptr); }