RexxStartDispatcher.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 
39 #include "RexxCore.h"
40 #include "RexxStartDispatcher.hpp"
41 #include "ProtectedObject.hpp"
42 #include "RoutineClass.hpp"
43 #include "SystemInterpreter.hpp"
44 #include "InterpreterInstance.hpp"
45 #include "RexxNativeActivation.hpp"
46 
47 
48 /**
49  * Default virtual method for handling a run() methods on
50  * an activity dispatcher.
51  */
53 {
54  ProtectedSet savedObjects;
55 
56  // set default return values
57  rc = 0;
58  retcode = 0;
59 
60  RexxString *name = OREF_NULLSTRING; // name of the invoked program
61  RexxString *fullname = name; // default the fulllength name to the simple name
62 
63  if (programName != NULL) /* have an actual name? */
64  {
65  /* get string version of the name */
66  name = new_string(programName);
67  }
68 
69  savedObjects.add(name); /* protect from garbage collect */
70  // get an array version of the arguments and protect
71  RexxArray *new_arglist = new_array(argcount);
72  savedObjects.add(new_arglist);
73 
74  // for compatibility reasons, if this is a command invocation and there is a leading blank
75  // on the only argument, then remove that leading blank from the argument
76  if (calltype == RXCOMMAND && argcount == 1 && arglist[0].strlength > 1 && arglist[0].strptr != NULL && arglist[0].strptr[0] == ' ')
77  {
78  new_arglist->put(new_string(arglist[0].strptr + 1, arglist[0].strlength - 1), 1);
79  }
80  else {
81  /* loop through the argument list */
82  for (size_t i = 0; i < argcount; i++)
83  {
84  /* have a real argument? */
85  if (arglist[i].strptr != NULL)
86  {
87  /* add to the argument array */
88  new_arglist->put(new_string(arglist[i]), i + 1);
89  }
90  }
91  }
92 
93  RexxString *source_calltype;
94 
95  switch (calltype) /* turn calltype into a string */
96  {
97  case RXCOMMAND: /* command invocation */
98  source_calltype = OREF_COMMAND; /* this is the 'COMMAND' string */
99  break;
100 
101  case RXFUNCTION: /* function invocation */
102  /* 'FUNCTION' string */
103  source_calltype = OREF_FUNCTIONNAME;
104  break;
105 
106  case RXSUBROUTINE: /* subroutine invocation */
107  /* 'SUBROUTINE' string */
108  source_calltype = OREF_SUBROUTINE;
109  break;
110 
111  default:
112  source_calltype = OREF_COMMAND; /* this is the 'COMMAND' string */
113  break;
114  }
115 
116  RoutineClass *program = OREF_NULL;
117 
118  if (instore == NULL) /* no instore request? */
119  {
120  /* go resolve the name */
121  fullname = activity->resolveProgramName(name, OREF_NULL, OREF_NULL);
122  if (fullname == OREF_NULL) /* not found? */
123  {
124  /* got an error here */
126  }
127  savedObjects.add(fullname);
128  /* try to restore saved image */
129  program = RoutineClass::fromFile(fullname);
130  }
131  else /* have an instore program */
132  {
133  /* go handle instore parms */
134  program = RoutineClass::processInstore(instore, name);
135  if (program == OREF_NULL) /* couldn't get it? */
136  {
137  /* got an error here */
139  }
140  }
141 
142  RexxString *initial_address = activity->getInstance()->getDefaultEnvironment();
143  /* actually need to run this? */
144  if (program != OREF_NULL)
145  {
146  ProtectedObject program_result;
147  // call the program
148  program->runProgram(activity, source_calltype, initial_address, new_arglist->data(), argcount, 0, program_result);
149  if (result != NULL) /* if return provided for */
150  {
151  /* actually have a result to return? */
152  if ((RexxObject *)program_result != OREF_NULL)
153  {
154  /* force to a string value */
155  program_result = ((RexxObject *)program_result)->stringValue();
156  // copy this into the result RXSTRING
157  ((RexxString *)program_result)->copyToRxstring(*result);
158  }
159  else /* make this an invalid string */
160  {
161  MAKERXSTRING(*result, NULL, 0);
162  }
163  }
164  /* If there is a return val... */
165  if ((RexxObject *)program_result != OREF_NULL)
166  {
167  wholenumber_t return_code;
168 
169  /* if a whole number... */
170  if (((RexxObject *)program_result)->numberValue(return_code) && return_code <= SHRT_MAX && return_code >= SHRT_MIN)
171  {
172  /* ...copy to return code. */
173  retcode = (short)return_code;
174  }
175  }
176  }
177 }
178 
179 
180 /**
181  * Default handler for any error conditions. This just sets the
182  * condition information in the dispatch unit.
183  *
184  * @param c The condition information for the error.
185  */
187 {
188  // use the base error handling and set our return code to the negated error code.
190  retcode = (short)rc;
191  // process the error to display the error message.
193 }
194 
195 
196 
197 /**
198  * Run a routine for a thread context API call.
199  */
201 {
202  if (arguments != OREF_NULL)
203  {
204  // we use a null string for the name when things are called directly
205  routine->call(activity, OREF_NULLSTRING, arguments->data(), arguments->size(), 0, result);
206  }
207  else
208  {
209  // we use a null string for the name when things are called directly
210  routine->call(activity, OREF_NULLSTRING, NULL, 0, 0, result);
211  }
212 }
213 
214 
215 
216 /**
217  * Run a routine for a thread context API call.
218  */
220 {
221  RexxString *targetName = new_string(program);
222  /* go resolve the name */
224  if (name == OREF_NULL) /* not found? */
225  {
226  /* got an error here */
228  }
229  ProtectedObject p(name);
230  // create a routine from this file
231  RoutineClass *routine = RoutineClass::fromFile(name);
232  p = routine;
233 
234  if (arguments != OREF_NULL)
235  {
236  size_t argumentsCount = arguments->size();
237  // use the provided name for the call name
238  routine->runProgram(activity, arguments->data(), argumentsCount, 0, result);
239  }
240  else
241  {
242  // we use a null string for the name when things are called directly
243  routine->runProgram(activity, NULL, 0, 0, result);
244  }
245 }
void reportException(wholenumber_t error)
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
#define OREF_NULL
Definition: RexxCore.h:60
#define Error_Program_unreadable_name
#define Error_Program_unreadable_notfound
RexxString * new_string(const char *s, stringsizeB_t bl, sizeC_t cl=-1)
virtual void handleError(wholenumber_t, RexxDirectory *)
RexxNativeActivation * activation
RexxDirectory * conditionData
RexxString * getDefaultEnvironment()
void add(RexxObject *)
wholenumber_t error()
InterpreterInstance * getInstance()
RexxString * resolveProgramName(RexxString *, RexxString *, RexxString *)
void put(RexxObject *eref, size_t pos)
Definition: ArrayClass.cpp:208
size_t size()
Definition: ArrayClass.hpp:202
RexxObject ** data()
Definition: ArrayClass.hpp:204
virtual void handleError(wholenumber_t, RexxDirectory *)
void runProgram(RexxActivity *activity, RexxString *calltype, RexxString *environment, RexxObject **arguments, size_t argCount, size_t named_argCount, ProtectedObject &result)
void call(RexxActivity *, RexxString *, RexxObject **, size_t, size_t, RexxString *, RexxString *, int, ProtectedObject &)
static RoutineClass * processInstore(PRXSTRING instore, RexxString *name)
static RoutineClass * fromFile(RexxString *filename)
ssize_t wholenumber_t
Definition: rexx.h:230
#define MAKERXSTRING(r, p, l)
Definition: rexx.h:182
#define RXSUBROUTINE
Definition: rexxapidefs.h:65
#define RXCOMMAND
Definition: rexxapidefs.h:64
#define RXFUNCTION
Definition: rexxapidefs.h:66