initial commit
[ascii.git] / calc.c
1 /* depend: */
2 /* cflags: */
3 /* linker: */
4
5 #include <assert.h>
6 #include <getopt.h>
7 #include <malloc.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 /* constants */
13
14 //#define BUFFER_SIZE 4096
15 #define BUFFER_SIZE 256
16
17 /* macros */
18
19 #define CEIL(x, y) (((x) + (y) - 1) / (y))
20 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
21 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
22
23 /* verbose */
24
25 #define ERROR 0
26 #define WARNING 1
27 #define INFO 2
28 #define DEBUG 3
29
30 #define VERBOSE(level, statement...) do { if (level <= verbose) { statement; } } while(0)
31
32 /* gobal variables */
33
34 char *progname = NULL;
35 int verbose = 0;
36
37 /* help function */
38
39 void usage (int ret)
40 {
41 FILE *fd = ret ? stderr : stdout;
42 fprintf (fd, "usage: %s\n", progname);
43 fprintf (fd, " -h : help message\n");
44 fprintf (fd, " -v : verbose level (%d)\n", verbose);
45
46 exit (ret);
47 }
48
49 /* main function */
50
51 int main (int argc, char *argv[])
52 {
53 char buffer[BUFFER_SIZE + 1] = {0};
54 char *pt = buffer;
55 int i, j = 0, n;
56
57 progname = argv[0];
58
59 int c;
60 while ((c = getopt(argc, argv, "hv:")) != EOF) {
61 switch (c) {
62 case 'v':
63 verbose = atoi (optarg);
64 break;
65 case 'h':
66 VERBOSE (INFO, usage (0));
67 break;
68 default:
69 VERBOSE (ERROR, usage (1));
70 }
71 }
72 if (argc - optind != 0) {
73 VERBOSE (ERROR, fprintf (stderr, "%s: invalid option -- %s\n", progname, argv[optind]));
74 VERBOSE (ERROR, usage (1));
75 }
76
77 /* read from input stream */
78 while ((n = read (STDIN_FILENO, pt, BUFFER_SIZE - (pt - buffer))) != 0) {
79 VERBOSE (DEBUG, fprintf (stdout, "read %d bytes\n", n));
80 n += (pt - buffer);
81
82 /* look for end of line */
83 for (i = 0, j = 0; i < n; i++) {
84 if (buffer[i] == '\n') {
85 buffer[i] = 0;
86 VERBOSE (DEBUG, fprintf (stdout, "line(%d): %s\n", j, buffer + j));
87 j = i + 1;
88 }
89 }
90
91 /* keep remainding */
92 if (j < n) {
93 for (i = 0; i < n - j; i++) {
94 buffer[i] = buffer[i + j];
95 }
96 pt = buffer + n - j;
97 for (i = n - j; i < BUFFER_SIZE; i++) {
98 buffer[i] = 0;
99 }
100 }
101 }
102
103 /* check that nothing is left behind */
104
105 VERBOSE (DEBUG, fprintf (stdout, "last\n"));
106 VERBOSE (DEBUG, fprintf (stdout, "line(%d): %s\n", j, buffer + j));
107
108 return 0;
109 }
110
111 // test: calc.exe -h
112 // test: calc.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
113 // test: calc.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
114 // test: calc.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
115 // test: echo "foo\nbar\nfoobar" | calc.exe -v3
116
117 /* vim: set ts=4 sw=4 et: */