Hint added.
[AROS.git] / workbench / rexxc / RX.c
blob649b06375c9f5684e322b5aa29ece8fc15cac78d
1 /*
2 Copyright © 2007-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Run REXX scripts
6 */
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
10 #include <dos/dostags.h>
11 #include <rexx/storage.h>
12 #include <rexx/errors.h>
13 #include <workbench/startup.h>
15 #include <proto/exec.h>
16 #include <proto/dos.h>
17 #include <proto/rexxsyslib.h>
18 #include <proto/alib.h>
20 #include <string.h>
21 #include <ctype.h>
23 #ifndef __AROS__
24 #define IPTR void *
25 #endif
27 static struct RexxMsg *msg = NULL;
28 static struct MsgPort *rexxport = NULL, *replyport = NULL;
29 static BPTR out;
30 static BOOL closestdout = FALSE;
31 static BPTR olddir = (BPTR)-1;
33 static BOOL init(void)
35 #ifdef __AROS__
36 out = ErrorOutput();
37 if (out == BNULL)
38 #endif
39 out = Output();
41 rexxport = FindPort("REXX");
42 if (rexxport == NULL)
44 if (SystemTags("RexxMast", SYS_Asynch, TRUE,
45 SYS_Input, BNULL, SYS_Output, BNULL,
46 TAG_DONE
47 ) >= 0
50 SystemTags("WaitForPort REXX", TAG_DONE);
53 rexxport = FindPort("REXX");
54 if (rexxport == NULL)
56 FPuts(out, "Could not start RexxMast; no Rexx interpreter seems to be installed\n");
57 return FALSE;
60 replyport = CreatePort(NULL, 0);
61 if (replyport == NULL)
63 FPuts(out, "Could not create a port\n");
64 return FALSE;
67 msg = CreateRexxMsg(replyport, NULL, NULL);
68 if (msg == NULL)
70 FPuts(out, "Could not create RexxMsg\n");
71 return FALSE;
73 msg->rm_Action = RXCOMM | RXFF_RESULT;
74 msg->rm_Stdin = Input();
75 Flush(msg->rm_Stdin); /* Remove command line arguments */
76 msg->rm_Stdout = Output();
78 return TRUE;
81 void cleanup(void)
83 if (closestdout)
84 Close(msg->rm_Stdout);
85 if (msg)
86 DeleteRexxMsg(msg);
87 if (replyport)
88 DeletePort(replyport);
89 if (olddir != (BPTR)-1)
90 CurrentDir(olddir);
93 int main(int argc, char **argv)
95 struct RexxMsg *reply;
96 int ret;
98 if (!init())
100 cleanup();
101 return RC_ERROR;
104 if (argc == 1)
106 FPuts(out, "Usage: RX <filename> [arguments]\n"
107 " RX \"commands\"\n");
108 cleanup();
109 return RC_ERROR;
112 if (argc == 0)
114 struct WBStartup *startup = (struct WBStartup *) argv;
115 char *s = startup->sm_ArgList[1].wa_Name;
117 if (startup->sm_NumArgs < 2)
119 cleanup();
120 return RC_ERROR;
123 olddir = CurrentDir(startup->sm_ArgList[1].wa_Lock);
124 out = msg->rm_Stdout = Open("CON:////RX Output/CLOSE/WAIT/AUTO", MODE_READWRITE);
125 closestdout = TRUE;
127 msg->rm_Args[0] = (IPTR)CreateArgstring(s, strlen(s));
128 msg->rm_Action |= 1;
130 else
132 UBYTE *s;
133 struct Process *me = (struct Process *)FindTask(NULL);
134 ULONG length = 0;
136 s = me->pr_Arguments;
137 while(isspace(*s)) s++;
139 if (*s == '"')
141 s++;
142 while((s[length] != '"') && (s[length] != '\0')) length++;
143 if (length == 0)
145 FPuts(out, "Empty command\n");
146 cleanup();
147 return RC_ERROR;
149 /* Lazy string termination like ARexx */
150 #if 0
151 if (s[length] == '\0')
153 FPuts(out, "Unterminated string\n");
154 cleanup();
155 return RC_ERROR;
157 #endif
159 msg->rm_Args[0] = (IPTR)CreateArgstring(s, length);
160 /* It is a literal command with 1 argument */
161 msg->rm_Action |= (RXFF_STRING | 1);
163 else if (*s == '\'')
165 s++;
166 while((s[length] != '\'')
167 && (s[length] != '\0')
168 && (s[length] != '\n')
170 length++;
172 msg->rm_Args[0] = (IPTR)CreateArgstring(s, length);
173 /* It is a literal command with 1 argument */
174 msg->rm_Action |= (RXFF_STRING | 1);
176 else
178 if (s[strlen(s)-1] == '\n')
179 s[strlen(s)-1] = '\0';
181 msg->rm_Args[0] = (IPTR)CreateArgstring(s, strlen(s));
182 msg->rm_Action |= 1;
187 PutMsg(rexxport, (struct Message *)msg);
188 do {
189 reply = (struct RexxMsg *)WaitPort(replyport);
190 } while (reply != msg);
192 ret = msg->rm_Result1;
193 if (msg->rm_Result1 == RC_OK)
194 /* Less verbosity like ARexx, use "get Result2" */
195 #if 0
196 FPrintf(out, "Script executed and returned: %ld\n", msg->rm_Result2);
197 #else
199 #endif
200 else
201 FPrintf(out, "Error executing script %ld/%ld\n",
202 msg->rm_Result1, msg->rm_Result2
205 ClearRexxMsg(msg, msg->rm_Action & RXARGMASK);
206 cleanup();
208 return ret;