Yeah, somehow I totally glossed over that when I was reading the code. I guess I just assumed that "two very similar things" were more similar than they were. A less pretty version of your var args is to have an explicit parameter list for the read/process function, and just pass in dummy params (changes in green):
Originally Posted by quzah
I admit, it's ugly, but it serves the purpose without the mess of var args. Actually, I just realized that this doesn't return n_stocks, so you'd have to have an extra parameter that is handled specially if process_file is being called with the stock file, or bundle up the stocks array and count of items into a simple struct. So much for a clean, template-y solution.
void *process_file(char *filename, size_t element_size, int (read_func)(FILE *, void *, void *, int), void *extra_data, int extra_int, int (cmp_func)(const void *, const void *))
n_elements = read_func(file, data, extra_data, extra_int);
qsort(data, n_elements, element_size, cmp_func);
stocks = process_file(argv, sizeof(stock), read_stocks, NULL, 0, stock_cmp);
trades = process_file(argv, sizeof(trade), process_trades, stocks, n_stocks, trade_cmp);