Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / c / shellcommands / If.c
blobd97678a65beb521707c00a1afc293c7be63ff3eb
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
22 Workbench:C
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 #define SH_GLOBAL_DOSBASE 1
98 struct UtilityBase *UtilityBase;
100 #include <aros/shcommands.h>
102 static BOOL doeval(STRPTR arg1, STRPTR arg2, BYTE op, IPTR numeric);
104 AROS_SH10(If, 41.1,
105 AROS_SHA(BOOL, ,NOT,/S, FALSE),
106 AROS_SHA(BOOL, ,WARN,/S,FALSE),
107 AROS_SHA(BOOL, ,ERROR,/S, FALSE),
108 AROS_SHA(BOOL, ,FAIL,/S,FALSE),
109 AROS_SHA(STRPTR, , , ,NULL),
110 AROS_SHA(STRPTR, ,EQ,/K,NULL),
111 AROS_SHA(STRPTR, ,GT,/K,NULL),
112 AROS_SHA(STRPTR, ,GE,/K,NULL),
113 AROS_SHA(BOOL, ,VAL,/S,FALSE),
114 AROS_SHA(STRPTR, ,EXISTS,/K,NULL))
117 AROS_SHCOMMAND_INIT
119 BOOL result = FALSE;
121 struct CommandLineInterface *cli = Cli();
123 UtilityBase = (struct UtilityBase *)OpenLibrary("utility.library", 39);
124 if (!UtilityBase)
125 return RETURN_FAIL;
128 if((cli != NULL) && (cli->cli_CurrentInput != cli->cli_StandardInput))
130 D(bug("Current input = %p, Standard input = %p\n",
131 cli->cli_CurrentInput, cli->cli_StandardInput));
133 if(SHArg(WARN))
135 if(cli->cli_ReturnCode >= RETURN_WARN)
136 result = TRUE;
138 else if(SHArg(ERROR))
140 if(cli->cli_ReturnCode >= RETURN_ERROR)
141 result = TRUE;
143 else if(SHArg(FAIL))
145 if(cli->cli_ReturnCode >= RETURN_FAIL)
146 result = TRUE;
148 else if(SHArg(EQ))
150 result = doeval(SHArg( ), SHArg(EQ), 0, SHArg(VAL));
152 else if (SHArg(GT))
154 result = doeval(SHArg( ), SHArg(GT), 1, SHArg(VAL));
156 else if (SHArg(GE))
158 result = doeval(SHArg( ), SHArg(GE), 2, SHArg(VAL));
160 else if(SHArg(EXISTS))
162 BPTR lock = Lock(SHArg(EXISTS), SHARED_LOCK);
164 if(lock != NULL)
165 result = TRUE;
167 UnLock(lock);
170 if(SHArg(NOT)) /* NOT */
171 result = !result;
174 /* We have determined the result -- now we've got to act on it. */
176 if(!result)
178 char a = 0;
179 char buffer[256];
180 int level = 1; /* If block level */
181 BOOL found = FALSE; /* Have we found a matching Else or
182 EndIF? */
184 SelectInput(cli->cli_CurrentInput);
186 while(!found)
188 LONG status;
190 status = ReadItem(buffer, sizeof(buffer), NULL);
192 if(status == ITEM_ERROR)
193 break;
195 if(status == ITEM_NOTHING)
197 if (a == ENDSTREAMCH)
198 break;
199 else
200 continue;
203 switch(FindArg("IF,ELSE,ENDIF", buffer))
205 case 0:
206 level++;
207 // printf("Found If\n");
208 break;
210 case 1:
211 if(level == 1)
212 found = TRUE;
213 break;
215 case 2:
216 level--;
218 if(level == 0)
219 found = TRUE;
220 break;
223 /* Take care of long 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)
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;