aboutsummaryrefslogtreecommitdiff
path: root/stdu.c
blob: f7f55110f6f0642254bb6c4f36c6b817a7e41ec4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>

#include "intmath.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;
	if (conf->human_readable) printf("human readable\n");

	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;

	while (1) {
		/* output */
		printf("\r%u", bytes_read);
		if (fflush(stdin) == 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");

	return 0;
}