use m4_normalize on the output strings to remove trailing spaces/tabs and consolidate...
[AROS.git] / workbench / c / shellcommands / If.c
blob3225ad673322b983eb15493485efea1d441231a0
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
8 #include <aros/debug.h>
9 /******************************************************************************
12 NAME
16 SYNOPSIS
18 NOT/S,WARN/S,ERROR/S,FAIL/S,,EQ/K,GT/K,GE/K,VAL/S,EXISTS/K
20 LOCATION
24 FUNCTION
26 Carry out all the commands in a block if a given conditional is true.
27 (A block is a run of command lines ended with an Else or EndIf
28 command.) For every If command there must be a corresponding EndIf.
29 If the condition is false, command execution will skip to the
30 corresponding Else of EndIf command.
32 INPUTS
34 NOT -- Negates the value of the condition
36 WARN -- True if the previous return code was greater
37 than or equal to 5.
38 ERROR -- True if the previous return code was greater
39 than or equal to 10.
40 FAIL -- True if the previous return code was greater
41 than or equal to 20.
43 EQ, GE, GT -- True if the first value is equal, greater than
44 or equal respectively greater than the second.
46 VAL -- Indicate that the comparison should treat the
47 strings as numerical values.
49 EXISTS <string> -- True if the file or directory <string> exists.
52 RESULT
54 NOTES
56 ERROR and FAIL will only be appropriate if the fail level of the
57 script is set via FailAt (the standard fail level is 10 and if any
58 return code exceeds or equals this value, the script will be aborted).
60 EXAMPLE
62 If 500 GT 200 VAL
63 echo "500 is greater than 200"
64 Else
65 If EXISTS S:User-Startup
66 echo "User-Startup script found in S:"
67 Execute S:User-Startup
68 EndIf
69 EndIf
71 BUGS
73 SEE ALSO
75 Else, EndIf, FailAt
77 INTERNALS
79 HISTORY
81 10.01.2000 SDuvan implemented
83 ******************************************************************************/
85 #define DEBUG 0
86 #include <aros/debug.h>
88 #include <dos/dos.h>
89 #include <dos/dosextens.h>
90 #include <dos/rdargs.h>
91 #include <dos/stdio.h>
92 #include <proto/dos.h>
93 #include <proto/utility.h>
94 #include <proto/exec.h>
95 #include "dos_commanderrors.h"
97 #include <aros/shcommands.h>
99 static BOOL doeval(STRPTR arg1, STRPTR arg2, BYTE op, IPTR numeric, APTR DOSBase, APTR UtilityBase);
101 #undef NOT /* In case <intuition/intuition.h> got included */
103 AROS_SH10(If, 41.1,
104 AROS_SHA(BOOL, ,NOT,/S, FALSE),
105 AROS_SHA(BOOL, ,WARN,/S,FALSE),
106 AROS_SHA(BOOL, ,ERROR,/S, FALSE),
107 AROS_SHA(BOOL, ,FAIL,/S,FALSE),
108 AROS_SHA(STRPTR, , , ,NULL),
109 AROS_SHA(STRPTR, ,EQ,/K,NULL),
110 AROS_SHA(STRPTR, ,GT,/K,NULL),
111 AROS_SHA(STRPTR, ,GE,/K,NULL),
112 AROS_SHA(BOOL, ,VAL,/S,FALSE),
113 AROS_SHA(STRPTR, ,EXISTS,/K,NULL))
116 AROS_SHCOMMAND_INIT
118 BOOL result = FALSE;
119 struct UtilityBase *UtilityBase;
120 struct CommandLineInterface *cli = Cli();
122 UtilityBase = (struct UtilityBase *)OpenLibrary("utility.library", 39);
123 if (!UtilityBase)
124 return RETURN_FAIL;
127 if((cli != NULL) && (cli->cli_CurrentInput != cli->cli_StandardInput))
129 D(bug("Current input = %p, Standard input = %p\n",
130 cli->cli_CurrentInput, cli->cli_StandardInput));
132 if(SHArg(WARN))
134 if(cli->cli_ReturnCode >= RETURN_WARN)
135 result = TRUE;
137 else if(SHArg(ERROR))
139 if(cli->cli_ReturnCode >= RETURN_ERROR)
140 result = TRUE;
142 else if(SHArg(FAIL))
144 if(cli->cli_ReturnCode >= RETURN_FAIL)
145 result = TRUE;
147 else if(SHArg(EQ))
149 result = doeval(SHArg( ), SHArg(EQ), 0, SHArg(VAL), DOSBase, UtilityBase);
151 else if (SHArg(GT))
153 result = doeval(SHArg( ), SHArg(GT), 1, SHArg(VAL), DOSBase, UtilityBase);
155 else if (SHArg(GE))
157 result = doeval(SHArg( ), SHArg(GE), 2, SHArg(VAL), DOSBase, UtilityBase);
159 else if(SHArg(EXISTS))
161 BPTR lock = Lock(SHArg(EXISTS), SHARED_LOCK);
163 if((lock != BNULL) || (IoErr() == ERROR_OBJECT_IN_USE))
164 result = TRUE;
166 UnLock(lock);
169 if(SHArg(NOT)) /* NOT */
170 result = !result;
173 /* We have determined the result -- now we've got to act on it. */
175 if(!result)
177 int a = 0;
178 char buffer[256];
179 int level = 1; /* If block level */
180 BOOL found = FALSE; /* Have we found a matching Else or
181 EndIF? */
183 SelectInput(cli->cli_CurrentInput);
185 while(!found)
187 LONG status;
189 status = ReadItem(buffer, sizeof(buffer), NULL);
191 if(status == ITEM_ERROR)
192 break;
194 if(status == ITEM_NOTHING)
196 if (a == ENDSTREAMCH)
197 break;
198 else
199 goto next;
202 switch(FindArg("IF,ELSE,ENDIF", buffer))
204 case 0:
205 level++;
206 // printf("Found If\n");
207 break;
209 case 1:
210 if(level == 1)
211 found = TRUE;
212 break;
214 case 2:
215 level--;
217 if(level == 0)
218 found = TRUE;
219 break;
222 next:
223 /* Take care of long and empty lines */
226 a = FGetC(Input());
227 } while (a != '\n' && a != ENDSTREAMCH);
230 if(!found)
231 PrintFault(ERROR_NO_MATCHING_ELSEENDIF, "If");
234 else
236 Flush(Output());
237 PrintFault(ERROR_SCRIPT_ONLY, "If");
240 CloseLibrary((struct Library *)UtilityBase);
242 return RETURN_OK;
244 AROS_SHCOMMAND_EXIT
247 static BOOL doeval(STRPTR arg1, STRPTR arg2, BYTE op, IPTR numeric, APTR DOSBase, APTR UtilityBase)
249 STRPTR s1 = (STRPTR)arg1;
250 STRPTR s2 = (STRPTR)arg2;
251 BOOL result = FALSE;
253 if (s1 && s2)
255 if (numeric)
257 LONG val1, val2;
259 StrToLong(s1, &val1);
260 StrToLong(s2, &val2);
262 switch(op)
264 case 0:
265 result = (val1 == val2);
266 break;
268 case 1:
269 result = (val1 > val2);
270 break;
272 case 2:
273 result = (val1 >= val2);
274 break;
277 } /* if (numeric) */
278 else
280 LONG match;
282 match = Stricmp(s1, s2);
284 switch(op)
286 case 0:
287 result = (match == 0);
288 break;
290 case 1:
291 result = (match > 0);
292 break;
294 case 2:
295 result = (match >= 0);
296 break;
301 } /* if (s1 && s2) */
303 return result;