#include #include #include #include #include #include "intmath.h" #include "formatting.h" #include "config-parser.h" int tests_run = 0; int tests_failed = 0; int main (int argc, char* argv[]) { Result res = parse_config(argc, argv); if (res.success == false) { char* err_msg = (char*) res.result; fprintf( stderr, "Error parsing command line: %s\n", err_msg ); return 1; } Config* conf = (Config*) res.result; unsigned int base = 10; if (conf->human_readable && conf->precision == 0) { conf->precision = 1; base = 1024; } int blocksize = 1; size_t bufsize = 1; unsigned int bytes_read = 0; size_t new_read_bytes = 0; if (conf->precision != 0) { blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( bytes_read + 1, conf->precision, base)) - bytes_read; bufsize = 1024; } size_t max_bufsize = 1048576; char* buf = malloc(bufsize); char* tmpbuf; size_t stdout_buffer_size = 16; char* stdout_buffer = malloc(stdout_buffer_size); int previous_line_strlen = 0; while (1) { /* output */ if (conf->human_readable && base == 10) { int res = int_floored_with_prefix( &stdout_buffer, &stdout_buffer_size, bytes_read, conf->precision ); if (res < 0) { printf("\r%u \ (error when getting prefix)", bytes_read); continue; } printf( "\r%*sB", previous_line_strlen, stdout_buffer ); previous_line_strlen = int_max(res, previous_line_strlen); } else if (conf->human_readable && base == 1024) { int success = int_floored_with_binary_prefix( &stdout_buffer, &stdout_buffer_size, bytes_read ); if (success < 0) { printf("\r%u \ (error when getting prefix)", bytes_read); } printf( "\r%*sB", 4 + (bytes_read > 1024), stdout_buffer ); } else { printf("\r%u", bytes_read); } if (fflush(stdout) == EOF) { printf("\n"); perror("error during fflush"); return 1; } /* reading */ new_read_bytes = fread( buf, 1, int_min(blocksize, bufsize)/* + (blocksize == 0)*/, stdin ); if (new_read_bytes == 0) { int err = ferror(stdin); if (err != 0) { printf("\n"); fprintf(stderr, "error reading stdin"); return err; } break; } bytes_read += new_read_bytes; /* resizing buffer and blocksize to read as much as possible * at once */ if (conf->precision == 0) continue; blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( bytes_read + 1, conf->precision, base)) - bytes_read; if (blocksize > bufsize) { tmpbuf = malloc(bufsize * 2); if (tmpbuf == NULL) { free(tmpbuf); } else { free(buf); buf = tmpbuf; bufsize *= 2; } } } printf("\n"); free(stdout_buffer); return 0; }