Prevent partitions from extending beyond end of container partition.
[AROS.git] / workbench / c / Eval.c
blob19bad902d7a6e9781bf3794be796bf9618f51f9e
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>
103 const TEXT version[] = "$VER: Eval 41.2 (4.5.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
117 void printLformat(STRPTR format, int value);
118 STRPTR fixExpression(STRPTR val1, STRPTR op, STRPTR *vals);
121 int __nocommandline;
123 int main(void)
125 int retval = RETURN_OK;
127 IPTR args[] = { (IPTR)NULL,
128 (IPTR)NULL,
129 (IPTR)NULL,
130 (IPTR)NULL,
131 (IPTR)NULL };
133 struct RDArgs *rda;
135 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
137 if (rda == NULL)
139 PrintFault(IoErr(), "Eval");
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("%i\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 */
223 /* If it weren't for *n we could use VfWriteF() */
225 for (i = 0; format[i] != 0; i++)
227 switch (format[i])
229 case '*':
230 if (format[i] == 'n')
232 printf("\n");
234 else
236 printf("*");
239 break;
241 case '%':
242 i++;
244 switch (tolower(format[i]))
246 /* Hexadecimal display */
247 case 'x':
248 printf("%0*x", format[++i] - '0', value);
249 break;
251 /* Octal display */
252 case 'o':
253 printf("%0*o", format[++i] - '0', value);
254 break;
256 /* Integer display */
257 case 'n':
258 printf("%i", value);
259 break;
261 /* Character display */
262 case 'c':
263 printf("%c", value);
264 break;
266 case '%':
267 printf("%%");
268 break;
270 /* Stupid user writes "...%" */
271 case 0:
272 i--;
273 break;
275 default:
276 printf("%%%c", format[i]);
277 break;
279 } /* switch(%-command) */
281 break;
283 default:
284 printf("%c", format[i]);
285 break;
286 } /* switch format character */
291 STRPTR fixExpression(STRPTR val1, STRPTR op, STRPTR *vals)
293 /* val1 must be != 0 as it's an /A argument */
294 int len;
295 int i; /* Loop variable */
296 STRPTR arg;
298 len = strlen(val1) + 1 + 1; /* One extra for the 0 byte to end
299 the string */
301 if (op != NULL)
303 len += strlen(op) + 1;
306 if (vals) for (i = 0; vals[i] != NULL; i++)
308 len += strlen(vals[i]) + 1;
311 arg = AllocVec(len, MEMF_ANY);
313 if (arg == NULL)
315 return NULL;
318 strcpy(arg, val1);
319 strcat(arg, " ");
321 if (op != NULL)
323 strcat(arg, op);
324 strcat(arg, " ");
327 if (vals) for (i = 0; vals[i] != NULL; i++)
329 strcat(arg, vals[i]);
330 strcat(arg, " ");
333 return arg;