add %f to printf
[calc.git] / calc.c
CommitLineData
ec15bdbc
LM
1/* depend: */
2/* cflags: */
01f02c41 3/* linker: atoi.o fdprintf.o */
ec15bdbc 4
01f02c41
LM
5//#include <malloc.h>
6#include <stddef.h>
ec15bdbc 7#include <stdio.h>
ec15bdbc
LM
8#include <unistd.h>
9
01f02c41
LM
10#include "atoi.h"
11#include "fdprintf.h"
12
ec15bdbc
LM
13/* constants */
14
15//#define BUFFER_SIZE 4096
16#define BUFFER_SIZE 256
17
18/* macros */
19
20#define CEIL(x, y) (((x) + (y) - 1) / (y))
21#define MIN(x, y) (((x) < (y)) ? (x) : (y))
22#define MAX(x, y) (((x) > (y)) ? (x) : (y))
23
24/* verbose */
25
26#define ERROR 0
27#define WARNING 1
28#define INFO 2
29#define DEBUG 3
30
31#define VERBOSE(level, statement...) do { if (level <= verbose) { statement; } } while(0)
32
33/* gobal variables */
34
35char *progname = NULL;
01f02c41 36int verbose = 2;
ec15bdbc
LM
37
38/* help function */
39
01f02c41 40int usage (int ret)
ec15bdbc 41{
01f02c41
LM
42 int fd = ret ? stdfderr : stdfdout;
43 fdprintf (fd, "usage: %s\n", progname);
44 fdprintf (fd, " -h : help message\n");
45 fdprintf (fd, " -v : verbose level (%d)\n", verbose);
ec15bdbc 46
01f02c41 47 return ret;
ec15bdbc
LM
48}
49
50/* main function */
51
52int main (int argc, char *argv[])
53{
54 char buffer[BUFFER_SIZE + 1] = {0};
55 char *pt = buffer;
01f02c41
LM
56 int i = 0, j = 0, n;
57
58 /* program name */
ec15bdbc
LM
59
60 progname = argv[0];
01f02c41
LM
61 while (progname[i] != '\0') {
62 if ((progname[i] == '/') || (progname[i] == '\\')) {
63 progname += i + 1;
64 i = 0;
65 } else {
66 i++;
67 }
68 }
69
70 /* argument processing */
ec15bdbc 71
01f02c41
LM
72 while (argc-- > 1) {
73 char *arg = *(++argv);
74 if (arg[0] != '-') {
75 PRINTERR ("%s: invalid option -- %s\n", progname, arg);
76 return usage (1);
77 }
78 char c = arg[1];
ec15bdbc
LM
79 switch (c) {
80 case 'v':
01f02c41
LM
81 arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
82 if (arg == NULL) {
83 PRINTERR ("%s: missing verbose level\n", progname);
84 return usage (1);
85 }
86 verbose = atoi (arg);
ec15bdbc
LM
87 break;
88 case 'h':
ec15bdbc 89 default:
01f02c41 90 return usage (c != 'h');
ec15bdbc
LM
91 }
92 }
ec15bdbc
LM
93
94 /* read from input stream */
01f02c41
LM
95
96 while ((n = read (stdfdin, pt, BUFFER_SIZE - (pt - buffer))) != 0) {
97 VERBOSE (DEBUG, PRINTOUT ("read %d bytes\n", n));
ec15bdbc
LM
98 n += (pt - buffer);
99
100 /* look for end of line */
101 for (i = 0, j = 0; i < n; i++) {
102 if (buffer[i] == '\n') {
103 buffer[i] = 0;
01f02c41
LM
104 VERBOSE (DEBUG, PRINTOUT ("line(%d): %s\n", j, buffer + j));
105 //fsync (stdfdout);
106 fflush (stdout);
ec15bdbc
LM
107 j = i + 1;
108 }
109 }
110
111 /* keep remainding */
112 if (j < n) {
113 for (i = 0; i < n - j; i++) {
114 buffer[i] = buffer[i + j];
115 }
116 pt = buffer + n - j;
117 for (i = n - j; i < BUFFER_SIZE; i++) {
118 buffer[i] = 0;
119 }
120 }
121 }
122
ec15bdbc
LM
123 return 0;
124}
125
126// test: calc.exe -h
127// test: calc.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
128// test: calc.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
129// test: calc.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
130// test: echo "foo\nbar\nfoobar" | calc.exe -v3
131
132/* vim: set ts=4 sw=4 et: */