#include #include #include #include #include #include #include /*void test_destructor(object* ptr) { printf("die\n"); }*/ void _rng_object_destructor(object* obj) { rng_free(obj->state); } RNG rng_object(S_LEXENV, RNG rng) { object proto = OBJ_PROTO; proto.state = rng; proto.destructor = &_rng_object_destructor; return snew_obj(proto)->state; } void shuffle(RNG with, array_t data) { printf(" -> shuffling %d objects...", (int)ar_size(data)); for(int i=ar_size(data)-1;i>0;i--) { int j = rng_next_int(with, i); ar_swap(data, i, j); } printf(" Okay\n"); } void unshuffle(RNG with, array_t data) { int rng_values[ar_size(data)-1]; int k=0; printf(" -> unshuffling %d objects...", (int)ar_size(data)); for(int i=ar_size(data)-1;i>0;i--) rng_values[k++] = rng_next_int(with, i); for(int i=1;i *max) *max = ar_get_v(data, long, i); if(ar_get_v(data, long, i) < *min) *min = ar_get_v(data, long, i); } } int valid_float(float f) { return !( (f!=f) || (f< -FLT_MAX || f> FLT_MAX)); } void minmax_floats(float* min, float* max, const array_t data) { for(register int i=0;i *max) *max = ar_get_v(data, float, i); if(ar_get_v(data, float, i) < *min) *min = ar_get_v(data, float, i); } } void minmax_sbytes(signed char* min, signed char* max, const array_t data) { for(register int i=0;i *max) *max = ar_get_v(data, signed char, i); if(ar_get_v(data, signed char, i) < *min) *min = ar_get_v(data, signed char, i); } } void print_array(const array_t data) { printf("---%d elements---\n", (int)ar_size(data)); for(register int i=0;i []\nUsage: %s -[b]u []\n", argv[0], argv[0]); printf(" \t\tFile to shuffle\n"); printf(" \tOutput file (only valid for buffered mode)\n"); printf("\ts\tShuffle\n"); printf("\tu\tReverse shuffle\n"); printf("\n\tb\tUse buffered mode instead of shuffling in place (must specify output file)\n"); } array_t read_whole_file(S_NAMED_LEXENV(base), FILE* fp) { fseek(fp,0,SEEK_END); long sz = ftell(fp); fseek(fp,0,SEEK_SET); array_t ar; MANAGED({ void* buf = smalloc(sz); fread(buf, 1, sz, fp); ar = ar_create_memory_from(base, buf, 1, sz); }); return ar; } int main(int argc, char** argv) { int is_buffered=0; int i=1; int is_unshuffling =0; if(!argv[1] || !argv[2] || argv[1][0] != '-') { print_usage(argv); return 1; } else { do_switch: switch(argv[1][i]) { case 'b': if(is_buffered) { print_usage(argv); return 1; } is_buffered = 1; i+=1; goto do_switch; case 'u': is_unshuffling=1; break; case 's': break; default: print_usage(argv); return 1; } } if(is_buffered && !argv[3]) { printf("Buffered option requires an output file\n"); return 1; } MANAGED_RETURNABLE(int ,{ array_t array; if(is_buffered) { FILE* infile = fopen(argv[2], "rb"); if(!infile) { printf("! could not open file for reading\n"); MANAGED_RETURN(1); } array = read_whole_file(LEXENV, infile); fclose(infile); printf(" buffered file (%ld bytes)\n", ar_size(array)); } else { FILE* infile = fopen(argv[2], "r+b"); if(!infile) { printf("! could not open file for reading+writing\n"); MANAGED_RETURN(1); } array = ar_create_file(LEXENV, infile, 1, 1); } //print_array(array); if(is_unshuffling) unshuffle3(LEXENV, array); else shuffle3(LEXENV, array); if(is_buffered) { FILE* outfile = fopen(argv[3], "wb"); if(!outfile) { printf("! could not open outfile for writing\n"); MANAGED_RETURN(1); } void* wbuf = smalloc(ar_full_size(array)); if(!ar_ndump(array, wbuf, ar_full_size(array), 0, ar_size(array))) printf("W memory dump failed, continuing anyway\n"); fwrite(wbuf, 1, ar_full_size(array), outfile); fclose(outfile); printf(" write completed (%d bytes)\n", (int)ar_size(array)); } }); return 0; }