clib/mktemp.c & shell/If: Fix checking for existing file.
[AROS.git] / workbench / c / shellcommands / If.c
blob890dc80c418c96727982681ffbe89224ed6fc144
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 AROS_SH10(If, 41.1,
102 AROS_SHA(BOOL, ,NOT,/S, FALSE),
103 AROS_SHA(BOOL, ,WARN,/S,FALSE),
104 AROS_SHA(BOOL, ,ERROR,/S, FALSE),
105 AROS_SHA(BOOL, ,FAIL,/S,FALSE),
106 AROS_SHA(STRPTR, , , ,NULL),
107 AROS_SHA(STRPTR, ,EQ,/K,NULL),
108 AROS_SHA(STRPTR, ,GT,/K,NULL),
109 AROS_SHA(STRPTR, ,GE,/K,NULL),
110 AROS_SHA(BOOL, ,VAL,/S,FALSE),
111 AROS_SHA(STRPTR, ,EXISTS,/K,NULL))
114 AROS_SHCOMMAND_INIT
116 BOOL result = FALSE;
117 struct UtilityBase *UtilityBase;
118 struct CommandLineInterface *cli = Cli();
120 UtilityBase = (struct UtilityBase *)OpenLibrary("utility.library", 39);
121 if (!UtilityBase)
122 return RETURN_FAIL;
125 if((cli != NULL) && (cli->cli_CurrentInput != cli->cli_StandardInput))
127 D(bug("Current input = %p, Standard input = %p\n",
128 cli->cli_CurrentInput, cli->cli_StandardInput));
130 if(SHArg(WARN))
132 if(cli->cli_ReturnCode >= RETURN_WARN)
133 result = TRUE;
135 else if(SHArg(ERROR))
137 if(cli->cli_ReturnCode >= RETURN_ERROR)
138 result = TRUE;
140 else if(SHArg(FAIL))
142 if(cli->cli_ReturnCode >= RETURN_FAIL)
143 result = TRUE;
145 else if(SHArg(EQ))
147 result = doeval(SHArg( ), SHArg(EQ), 0, SHArg(VAL), DOSBase, UtilityBase);
149 else if (SHArg(GT))
151 result = doeval(SHArg( ), SHArg(GT), 1, SHArg(VAL), DOSBase, UtilityBase);
153 else if (SHArg(GE))
155 result = doeval(SHArg( ), SHArg(GE), 2, SHArg(VAL), DOSBase, UtilityBase);
157 else if(SHArg(EXISTS))
159 BPTR lock = Lock(SHArg(EXISTS), SHARED_LOCK);
161 if((lock != BNULL) || (IoErr() == ERROR_OBJECT_IN_USE))
162 result = TRUE;
164 UnLock(lock);
167 if(SHArg(NOT)) /* NOT */
168 result = !result;
171 /* We have determined the result -- now we've got to act on it. */
173 if(!result)
175 int a = 0;
176 char buffer[256];
177 int level = 1; /* If block level */
178 BOOL found = FALSE; /* Have we found a matching Else or
179 EndIF? */
181 SelectInput(cli->cli_CurrentInput);
183 while(!found)
185 LONG status;
187 status = ReadItem(buffer, sizeof(buffer), NULL);
189 if(status == ITEM_ERROR)
190 break;
192 if(status == ITEM_NOTHING)
194 if (a == ENDSTREAMCH)
195 break;
196 else
197 goto next;
200 switch(FindArg("IF,ELSE,ENDIF", buffer))
202 case 0:
203 level++;
204 // printf("Found If\n");
205 break;
207 case 1:
208 if(level == 1)
209 found = TRUE;
210 break;
212 case 2:
213 level--;
215 if(level == 0)
216 found = TRUE;
217 break;
220 next:
221 /* Take care of long and empty lines */
224 a = FGetC(Input());
225 } while (a != '\n' && a != ENDSTREAMCH);
228 if(!found)
229 PrintFault(ERROR_NO_MATCHING_ELSEENDIF, "If");
232 else
234 Flush(Output());
235 PrintFault(ERROR_SCRIPT_ONLY, "If");
238 CloseLibrary((struct Library *)UtilityBase);
240 return RETURN_OK;
242 AROS_SHCOMMAND_EXIT
245 static BOOL doeval(STRPTR arg1, STRPTR arg2, BYTE op, IPTR numeric, APTR DOSBase, APTR UtilityBase)
247 STRPTR s1 = (STRPTR)arg1;
248 STRPTR s2 = (STRPTR)arg2;
249 BOOL result = FALSE;
251 if (s1 && s2)
253 if (numeric)
255 LONG val1, val2;
257 StrToLong(s1, &val1);
258 StrToLong(s2, &val2);
260 switch(op)
262 case 0:
263 result = (val1 == val2);
264 break;
266 case 1:
267 result = (val1 > val2);
268 break;
270 case 2:
271 result = (val1 >= val2);
272 break;
275 } /* if (numeric) */
276 else
278 LONG match;
280 match = Stricmp(s1, s2);
282 switch(op)
284 case 0:
285 result = (match == 0);
286 break;
288 case 1:
289 result = (match > 0);
290 break;
292 case 2:
293 result = (match >= 0);
294 break;
299 } /* if (s1 && s2) */
301 return result;