use m4_normalize on the output strings to remove trailing spaces/tabs and consolidate...
[AROS.git] / workbench / c / Eval.c
bloba73f48f6021866a6d7a64b862e93b5bc36fbd6b3
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Eval CLI command
6 Lang: English
7 */
9 /******************************************************************************
11 NAME
13 Eval
15 SYNOPSIS
17 VALUE1/A,OP,VALUE2/M,TO/K,LFORMAT/K
19 LOCATION
23 FUNCTION
25 Evaluate an integer expression and print the result. The result is
26 written to standard output if not the TO switch are used which instead
27 prints the result to a file. Using the switch LFORMAT, it is
28 possible to direct how to write the result. Numbers prefixed by
29 0x or #x are interpreted as hexadecimal and those prefixed by # or 0
30 are interpreted as octals. Alphabetical characters are indicated
31 by a leading single quotation mark ('), and are evaluated as their
32 ASCII equivalent.
34 INPUTS
36 VALUE1,
37 OP,
38 VALUE2 -- The expression to evaluate. The following operators
39 are supported
41 Operator Symbols
42 ----------------------------------
43 addition +
44 subtraction -
45 multiplication *
46 division /
47 modulo mod, M, m, %
48 bitwise and &
49 bitwise or |
50 bitwise not ~
51 left shift lsh, L, l
52 right shift rsh, R, r
53 negation -
54 exclusive or xor, X, x
55 bitwise equivalence eqv, E, e
57 TO -- File to write the result to
58 LFORMAT -- printf-like specification of what to write.
59 The possible swiches are:
61 %xd -- hexadecimal output, width digit d
62 %od -- octal output, width digit d
63 %n -- decimal output
64 %c -- character output (the ANSI-character
65 corresponding to the result value)
67 By specifying *n in the LFORMAT string, a newline
68 is output.
70 RESULT
72 NOTES
74 EXAMPLE
76 BUGS
78 SEE ALSO
80 INTERNALS
82 HISTORY
84 04.05.2011 polluks width digit was missing
85 01.01.2001 SDuvan implemented (although a bit tired... happy new year!)
87 ******************************************************************************/
89 #define DEBUG 0
90 #include <aros/debug.h>
92 #include "evalParser.tab.c"
94 #include <exec/types.h>
95 #include <exec/memory.h>
96 #include <dos/dos.h>
97 #include <dos/dosextens.h>
98 #include <dos/rdargs.h>
99 #include <proto/dos.h>
100 #include <proto/exec.h>
101 #include <proto/alib.h>
103 const TEXT version[] = "$VER: Eval 41.2 (14.7.2011)\n";
105 #define ARG_TEMPLATE "VALUE1/A,OP,VALUE2/M,TO/K,LFORMAT/K"
106 enum
108 ARG_VALUE1 = 0,
109 ARG_OP,
110 ARG_VALUE2,
111 ARG_TO,
112 ARG_LFORMAT,
113 NOOFARGS
116 void printLformat(STRPTR format, int value);
117 STRPTR fixExpression(STRPTR val1, STRPTR op, STRPTR *vals);
120 int __nocommandline;
122 int main(void)
124 int retval = RETURN_OK;
126 IPTR args[] = { (IPTR)NULL,
127 (IPTR)NULL,
128 (IPTR)NULL,
129 (IPTR)NULL,
130 (IPTR)NULL };
132 struct RDArgs *rda;
134 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
136 if (rda == NULL)
138 PrintFault(IoErr(), "Eval");
139 retval = RETURN_FAIL;
141 else
143 STRPTR toFile = (STRPTR)args[ARG_TO];
144 STRPTR lFormat = (STRPTR)args[ARG_LFORMAT];
145 STRPTR value1 = (STRPTR)args[ARG_VALUE1];
146 STRPTR op = (STRPTR)args[ARG_OP];
147 STRPTR *value2 = (STRPTR *)args[ARG_VALUE2];
149 STRPTR argString;
151 BPTR oldout = BNULL; /* Former output stream if using TO */
152 BPTR file = BNULL; /* Output redirection stream */
154 /* The developer to use fixExpression had no high regard
155 of the Amiga Eval command, and at the same time considered
156 ReadArgs() not to be really suitable for these arguments.
157 To be compatible to the Amiga Eval command, the developer
158 felt it was necessary to patch the arguments back together. */
159 argString = fixExpression(value1, op, value2);
161 text = argString; /* Note: text is a global variable that is
162 modified, so we cannot free 'text' below */
164 D(bug("Put together text: %s\n", text));
166 if (text == NULL || yyparse() == 1)
168 retval= RETURN_ERROR;
170 else {
171 if (toFile != NULL)
173 file = Open(toFile, MODE_NEWFILE);
175 if (file == BNULL)
177 Printf("Cannot open output file %s\n", toFile);
179 retval= RETURN_FAIL;
181 else
183 oldout = SelectOutput(file);
187 if (toFile == NULL || file != BNULL) {
188 if (lFormat != NULL)
190 printLformat(lFormat, g_result);
192 else
194 Printf("%ld\n", g_result);
197 /* Reinstall output stream if we changed it */
198 if (oldout != BNULL)
200 SelectOutput(oldout);
202 /* Close the TO/K file */
203 Close(file);
207 FreeVec(argString);
210 FreeArgs(rda);
212 return retval;
217 extern int g_result; /* The result variable is global for now */
219 void printLformat(STRPTR format, int value)
221 ULONG i; /* Loop variable */
222 char s[10];
224 /* If it weren't for *n we could use VfWriteF() */
226 for (i = 0; format[i] != 0; i++)
228 switch (format[i])
230 case '*':
231 if (format[i] == 'n')
233 Printf("\n");
235 else
237 Printf("*");
240 break;
242 case '%':
243 i++;
245 switch (tolower(format[i]))
247 /* Hexadecimal display */
248 case 'x':
249 __sprintf(s, "%X", value);
250 s[format[++i] - '0'] = 0;
251 Printf("%s", s);
252 break;
254 /* Octal display */
255 case 'o':
256 __sprintf(s, "%o", value);
257 s[format[++i] - '0'] = 0;
258 Printf("%s", s);
259 break;
261 /* Integer display */
262 case 'n':
263 Printf("%ld", value);
264 break;
266 /* Character display */
267 case 'c':
268 Printf("%c", value);
269 break;
271 case '%':
272 Printf("%%"); /* AROS extension */
273 break;
275 /* Stupid user writes "...%" */
276 case 0:
277 i--;
278 break;
280 default:
281 Printf("%%%c", format[i]);
282 break;
284 } /* switch(%-command) */
286 break;
288 default:
289 Printf("%c", format[i]);
290 break;
291 } /* switch format character */
296 STRPTR fixExpression(STRPTR val1, STRPTR op, STRPTR *vals)
298 /* val1 must be != 0 as it's an /A argument */
299 int len;
300 int i; /* Loop variable */
301 STRPTR arg;
303 len = strlen(val1) + 1 + 1; /* One extra for the 0 byte to end
304 the string */
306 if (op != NULL)
308 len += strlen(op) + 1;
311 if (vals) for (i = 0; vals[i] != NULL; i++)
313 len += strlen(vals[i]) + 1;
316 arg = AllocVec(len, MEMF_ANY);
318 if (arg == NULL)
320 return NULL;
323 strcpy(arg, val1);
324 strcat(arg, " ");
326 if (op != NULL)
328 strcat(arg, op);
329 strcat(arg, " ");
332 if (vals) for (i = 0; vals[i] != NULL; i++)
334 strcat(arg, vals[i]);
335 strcat(arg, " ");
338 return arg;
341 /* For linking with the evalParser.y output
343 void *malloc(YYSIZE_T size)
345 return AllocVec(size, MEMF_ANY);
348 void free(void *ptr)
350 FreeVec(ptr);
353 int puts(const char *s)
355 PutStr(s);
356 return 0;