Dereference symlinks when copying.
[tangerine.git] / workbench / c / Eval.c
blobd734b11d96d0485e4d3f1ffe501f66f346f3310e
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
21 Workbench:C
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 %x -- hexadecimal output
62 %o -- octal output
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 01.01.2001 SDuvan implemented (although a bit tired... happy new year!)
86 ******************************************************************************/
88 #define DEBUG 0
89 #include <aros/debug.h>
91 #include "evalParser.tab.c"
93 #include <exec/types.h>
94 #include <exec/memory.h>
95 #include <dos/dos.h>
96 #include <dos/dosextens.h>
97 #include <dos/rdargs.h>
98 #include <proto/dos.h>
99 #include <proto/exec.h>
102 const TEXT version[] = "$VER: Eval 41.1 (1.1.2001)\n";
104 #define ARG_TEMPLATE "VALUE1/A,OP,VALUE2/M,TO/K,LFORMAT/K"
105 enum
107 ARG_VALUE1 = 0,
108 ARG_OP,
109 ARG_VALUE2,
110 ARG_TO,
111 ARG_LFORMAT,
112 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_FAIL;
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 STRPTR toFile = (STRPTR)args[ARG_TO];
139 STRPTR lFormat = (STRPTR)args[ARG_LFORMAT];
140 STRPTR value1 = (STRPTR)args[ARG_VALUE1];
141 STRPTR op = (STRPTR)args[ARG_OP];
142 STRPTR *value2 = (STRPTR *)args[ARG_VALUE2];
144 STRPTR argString;
146 BPTR oldout = NULL; /* Former output stream if using TO */
147 BPTR file = NULL; /* Output redirection stream */
149 /* The Amiga Eval command is totally brain-dead and, at the same time,
150 ReadArgs() is not really suitable for these arguments. To be
151 compatible to the Amiga Eval command, we have to patch the arguments
152 together to get something useful out of this. */
153 argString = fixExpression(value1, op, value2);
155 text = argString; /* Note: text is a global variable that is
156 modified, so we cannot free 'text' below */
158 D(bug("Put together text: %s\n", text));
160 if (text == NULL || yyparse() == 1)
162 FreeVec(argString);
163 FreeArgs(rda);
165 return RETURN_ERROR;
168 FreeVec(argString);
170 if (toFile != NULL)
172 file = Open(toFile, MODE_NEWFILE);
174 if (file != NULL)
176 oldout = SelectOutput(file);
178 else
180 printf("Cannot open output file %s\n", toFile);
181 FreeArgs(rda);
183 return RETURN_FAIL;
187 if (lFormat != NULL)
189 printLformat(lFormat, g_result);
191 else
193 printf("%i\n", g_result);
196 /* Reinstall output stream if we changed it */
197 if (oldout != NULL)
199 SelectOutput(oldout);
201 /* Close the TO/K file */
202 Close(file);
205 else
207 PrintFault(IoErr(), "Eval");
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("%x", value);
249 break;
251 /* Octal display */
252 case 'o':
253 printf("%o", 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;