Commit | Line | Data |
---|---|---|
ec15bdbc LM |
1 | /* depend: */ |
2 | /* cflags: */ | |
efdfb543 | 3 | /* linker: atoi.o debug.o fdprintf.o parser.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 | 10 | #include "atoi.h" |
bc97a989 | 11 | #include "debug.h" |
01f02c41 | 12 | #include "fdprintf.h" |
bc97a989 | 13 | #include "parser.h" |
01f02c41 | 14 | |
ec15bdbc LM |
15 | /* constants */ |
16 | ||
17 | //#define BUFFER_SIZE 4096 | |
18 | #define BUFFER_SIZE 256 | |
19 | ||
20 | /* macros */ | |
21 | ||
22 | #define CEIL(x, y) (((x) + (y) - 1) / (y)) | |
23 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) | |
24 | #define MAX(x, y) (((x) > (y)) ? (x) : (y)) | |
25 | ||
ec15bdbc LM |
26 | /* gobal variables */ |
27 | ||
28 | char *progname = NULL; | |
ec15bdbc LM |
29 | |
30 | /* help function */ | |
31 | ||
01f02c41 | 32 | int usage (int ret) |
ec15bdbc | 33 | { |
01f02c41 LM |
34 | int fd = ret ? stdfderr : stdfdout; |
35 | fdprintf (fd, "usage: %s\n", progname); | |
36 | fdprintf (fd, " -h : help message\n"); | |
37 | fdprintf (fd, " -v : verbose level (%d)\n", verbose); | |
ec15bdbc | 38 | |
01f02c41 | 39 | return ret; |
ec15bdbc LM |
40 | } |
41 | ||
42 | /* main function */ | |
43 | ||
44 | int main (int argc, char *argv[]) | |
45 | { | |
46 | char buffer[BUFFER_SIZE + 1] = {0}; | |
47 | char *pt = buffer; | |
01f02c41 | 48 | int i = 0, j = 0, n; |
efdfb543 | 49 | int ret = 0; |
01f02c41 LM |
50 | |
51 | /* program name */ | |
ec15bdbc LM |
52 | |
53 | progname = argv[0]; | |
01f02c41 LM |
54 | while (progname[i] != '\0') { |
55 | if ((progname[i] == '/') || (progname[i] == '\\')) { | |
56 | progname += i + 1; | |
57 | i = 0; | |
58 | } else { | |
59 | i++; | |
60 | } | |
61 | } | |
62 | ||
63 | /* argument processing */ | |
ec15bdbc | 64 | |
01f02c41 LM |
65 | while (argc-- > 1) { |
66 | char *arg = *(++argv); | |
67 | if (arg[0] != '-') { | |
68 | PRINTERR ("%s: invalid option -- %s\n", progname, arg); | |
69 | return usage (1); | |
70 | } | |
71 | char c = arg[1]; | |
ec15bdbc LM |
72 | switch (c) { |
73 | case 'v': | |
01f02c41 LM |
74 | arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; |
75 | if (arg == NULL) { | |
76 | PRINTERR ("%s: missing verbose level\n", progname); | |
77 | return usage (1); | |
78 | } | |
79 | verbose = atoi (arg); | |
ec15bdbc LM |
80 | break; |
81 | case 'h': | |
ec15bdbc | 82 | default: |
01f02c41 | 83 | return usage (c != 'h'); |
ec15bdbc LM |
84 | } |
85 | } | |
ec15bdbc LM |
86 | |
87 | /* read from input stream */ | |
01f02c41 LM |
88 | |
89 | while ((n = read (stdfdin, pt, BUFFER_SIZE - (pt - buffer))) != 0) { | |
49223129 | 90 | VERBOSE (INFO, PRINTOUT ("read %d bytes\n", n)); |
ec15bdbc | 91 | n += (pt - buffer); |
bc97a989 LM |
92 | if ((n == 2) && (buffer[0] == '.')) { |
93 | return 0; | |
94 | } | |
ec15bdbc LM |
95 | |
96 | /* look for end of line */ | |
97 | for (i = 0, j = 0; i < n; i++) { | |
98 | if (buffer[i] == '\n') { | |
99 | buffer[i] = 0; | |
49223129 | 100 | VERBOSE (INFO, PRINTOUT ("line(%d): %s\n", j, buffer + j)); |
0b489a77 | 101 | element_t *element = parser (buffer, NULL); |
bc97a989 LM |
102 | if (element == (void *)(-1)) { |
103 | VERBOSE (WARNING, PRINTOUT ("error while parsing: %s\n", buffer)); | |
efdfb543 | 104 | ret = 1; |
bc97a989 LM |
105 | } else { |
106 | print_element (element, 0); | |
efdfb543 | 107 | ret = 0; |
bc97a989 | 108 | } |
01f02c41 | 109 | //fsync (stdfdout); |
ec15bdbc LM |
110 | j = i + 1; |
111 | } | |
112 | } | |
113 | ||
114 | /* keep remainding */ | |
115 | if (j < n) { | |
116 | for (i = 0; i < n - j; i++) { | |
117 | buffer[i] = buffer[i + j]; | |
118 | } | |
119 | pt = buffer + n - j; | |
120 | for (i = n - j; i < BUFFER_SIZE; i++) { | |
121 | buffer[i] = 0; | |
122 | } | |
123 | } | |
124 | } | |
125 | ||
efdfb543 | 126 | return ret; |
ec15bdbc LM |
127 | } |
128 | ||
129 | // test: calc.exe -h | |
130 | // test: calc.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }' | |
131 | // test: calc.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }' | |
132 | // test: calc.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }' | |
efdfb543 LM |
133 | // test: echo "1 + 2" | calc.exe |
134 | // test: echo "1 - 2" | calc.exe | |
135 | // test: echo "1 * 2" | calc.exe | |
136 | // test: echo "1 / 2" | calc.exe | |
137 | // test: echo "2 ^ 3" | calc.exe | |
138 | // test: echo "1e-1 + 2.34e5" | calc.exe | |
139 | // test: echo "sqrt (2)" | calc.exe | |
140 | // test: echo "pow (2, 3)" | calc.exe | |
141 | // test: echo "cos (2)" | calc.exe | |
142 | // test: echo "sin (2)" | calc.exe | |
143 | // test: echo "atan (2)" | calc.exe | |
144 | // test: echo "exp (2)" | calc.exe | |
145 | // test: echo "log (2)" | calc.exe | |
146 | // test: echo "1 + 2 - 3" | calc.exe | |
147 | // test: echo "1 + cos (2 - 3)" | calc.exe | |
148 | // test: echo "1 + 4 * (2 - 3)" | calc.exe | |
149 | // test: echo "(2 - 3) / 4" | calc.exe | |
150 | // test: echo "pow (2 - 3, 8 / 3)" | calc.exe | |
151 | // test: echo "1 + -2" | calc.exe | |
152 | // test: echo "1 - +2" | calc.exe | |
153 | // test: echo "-1 + +2" | calc.exe | |
154 | // test: echo "-1 +2" | calc.exe | |
ec15bdbc LM |
155 | |
156 | /* vim: set ts=4 sw=4 et: */ |