int main(int argc, char *argv[]) { int max_used_memory; int allocation_factor; int memory_required; SEQLIST *test_sequence; max_used_memory = 2000; allocation_factor = 11; printf("running with MAX_USED_MEMORY=%d and ALLOCATION_FACTOR=%d\n", max_used_memory, allocation_factor); test_sequence = generate_sequence(max_used_memory, allocation_factor); if (VERBOSE) seq_print(test_sequence); // check that allocation can actually do something. // This becomes upper bound on binary search. if (try_sequence(test_sequence, max_used_memory * allocation_factor * 2)) { // binary search for smallest MEMORY_SIZE which can accommodate memory_required = binary_search_required_memory(test_sequence, max_used_memory - 1, max_used_memory * allocation_factor * 2); // run it one more time at the identified size. // this makes sure that the data is set from a successful run. if (try_sequence(test_sequence, memory_required)) { // check if data contents are intact if (check_data(test_sequence)) { printf("Data integrity FAIL.\n"); } else { printf("Data integrity PASS.\n"); } // print statistics printf("Memory utilization: (%d/%d)=%f\n", max_used_memory, memory_required, ((double) max_used_memory / (double) memory_required)); } else { printf("Consistency problem: binary_search_reqruired_memory " "returned %d, but final test failed\n", memory_required); } } else { printf("Requires more memory than the no-free case.\n"); } }
// check all still allocated blocks in a test sequence // contain the data originally placed into them // i.e. have not been corrupted int check_data(SEQLIST *test_sequence) { int result; SEQLIST *current; result = 0; // stays zero if no errors for (current = test_sequence; !seq_null(current); current = seq_next(current)) { // only check if an allocate which has not been freed if (seq_alloc(current) && !seq_freed(current)) { if (!same_data(seq_ref_block(current), seq_myalloc_block(current), seq_size(current))) { if (VERBOSE) { printf("Mismatch in sequence starting at:\n"); seq_print(current); } // returning a 1 means it failed result = 1; } } } return result; }
int main (int argc, char **argv) { int addsw = 0, deletesw = 0, debugsw = 0; int listsw = 0, publicsw = -1, zerosw = 0, msgnum; unsigned int seqp = 0; char *cp, *maildir, *folder = NULL, buf[BUFSIZ]; char **argp, **arguments; svector_t seqs = svector_create (0); struct msgs_array msgs = { 0, 0, NULL }; struct msgs *mp; if (nmh_init(argv[0], 1)) { return 1; } arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; /* * Parse arguments */ while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { case AMBIGSW: ambigsw (cp, switches); done (1); case UNKWNSW: adios (NULL, "-%s unknown\n", cp); case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name); print_help (buf, switches, 1); done (0); case VERSIONSW: print_version(invo_name); done (0); case ADDSW: addsw++; deletesw = listsw = 0; continue; case DELSW: deletesw++; addsw = listsw = 0; continue; case LSTSW: listsw++; addsw = deletesw = 0; continue; case SEQSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); svector_push_back (seqs, cp); seqp++; continue; case PUBLSW: publicsw = 1; continue; case NPUBLSW: publicsw = 0; continue; case DEBUGSW: debugsw++; continue; case ZEROSW: zerosw++; continue; case NZEROSW: zerosw = 0; continue; } } if (*cp == '+' || *cp == '@') { if (folder) adios (NULL, "only one folder at a time!"); else folder = pluspath (cp); } else app_msgarg(&msgs, cp); } /* * If we haven't specified -add, -delete, or -list, * then use -add if a sequence was specified, else * use -list. */ if (!addsw && !deletesw && !listsw) { if (seqp) addsw++; else listsw++; } if (!context_find ("path")) free (path ("./", TFOLDER)); if (!msgs.size) app_msgarg(&msgs, listsw ? "all" :"cur"); if (!folder) folder = getfolder (1); maildir = m_maildir (folder); if (chdir (maildir) == NOTOK) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* print some general debugging info */ if (debugsw) print_debug(mp); /* check for empty folder */ if (mp->nummsg == 0) adios (NULL, "no messages in %s", folder); /* parse all the message ranges/sequences and set SELECTED */ for (msgnum = 0; msgnum < msgs.size; msgnum++) if (!m_convert (mp, msgs.msgs[msgnum])) done (1); if (publicsw == 1 && is_readonly(mp)) adios (NULL, "folder %s is read-only, so -public not allowed", folder); /* * Make sure at least one sequence has been * specified if we are adding or deleting. */ if (seqp == 0 && (addsw || deletesw)) adios (NULL, "-%s requires at least one -sequence argument", addsw ? "add" : "delete"); /* Adding messages to sequences */ if (addsw) { for (seqp = 0; seqp < svector_size (seqs); seqp++) if (!seq_addsel (mp, svector_at (seqs, seqp), publicsw, zerosw)) done (1); } /* Deleting messages from sequences */ if (deletesw) { for (seqp = 0; seqp < svector_size (seqs); seqp++) if (!seq_delsel (mp, svector_at (seqs, seqp), publicsw, zerosw)) done (1); } /* Listing messages in sequences */ if (listsw) { if (seqp) { /* print the sequences given */ for (seqp = 0; seqp < svector_size (seqs); seqp++) seq_print (mp, svector_at (seqs, seqp)); } else { /* else print them all */ seq_printall (mp); } /* print debugging info about SELECTED messages */ if (debugsw) seq_printdebug (mp); } svector_free (seqs); seq_save (mp); /* synchronize message sequences */ context_replace (pfolder, folder); /* update current folder */ context_save (); /* save the context file */ folder_free (mp); /* free folder/message structure */ done (0); return 1; }