CommandHandler.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2006 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 /* REXX Kernel */
40 /* */
41 /* Handlers for subcom callbacks */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include <string.h>
46 #include "RexxCore.h"
47 #include "CommandHandler.hpp"
48 #include "RexxNativeActivation.hpp"
49 #include "RexxInternalApis.h"
50 #include "ProtectedObject.hpp"
51 #include "SystemInterpreter.hpp"
52 #include "DirectoryClass.hpp"
53 
54 
55 /**
56  * Create a new command handler instance
57  *
58  * @param size The size of the handler
59  *
60  * @return The allocated object.
61  */
62 void *CommandHandler::operator new(size_t size)
63 {
64  return new_object(size, T_CommandHandler); // Get new object
65 }
66 
67 
68 /**
69  * Resolve a classic-style exit handler to the actual target
70  * entry point address and invocation style.
71  *
72  * @param name The registered exit name.
73  */
74 void CommandHandler::resolve(const char *handlerName)
75 {
76  {
77  UnsafeBlock releaser;
78  RexxResolveSubcom(handlerName, &entryPoint);
79  }
80  // only resolved if we got something back
81  if (entryPoint != NULL)
82  {
84  }
85 }
86 
87 
88 /**
89  * Call a command handler
90  *
91  * @param activity The current activity.
92  * @param activation The top-most activation.
93  * @param address The address name.
94  * @param command The command string.
95  * @param result The returned RC value.
96  * @param condition A potential returned condition object.
97  */
98 void CommandHandler::call(RexxActivity *activity, RexxActivation *activation, RexxString *address, RexxString *command, ProtectedObject &result, ProtectedObject &condition)
99 {
100  if (type == REGISTERED_NAME)
101  {
102  CommandHandlerDispatcher dispatcher(activity, entryPoint, command);
103 
104  // run this and give back the return code
105  activity->run(dispatcher);
106  dispatcher.complete(command, result, condition);
107  }
108  else
109  {
110  ContextCommandHandlerDispatcher dispatcher(entryPoint, address, command, result, condition);
111 
112  // run this and give back the return code
113  activity->run(dispatcher);
114  }
115 }
116 
118 {
119  activity = a; // needed for raising conditions
120  entryPoint = e; // the call point
121  // clear the state flags
122  flags = 0;
123 
124  // set up a return code buffer
126  // set up the command RXSTRING
127  MAKERXSTRING(rxstrcmd, command->getStringData(), command->getLength());
128 }
129 
130 
131 /**
132  * Process a callout to a system exit function.
133  */
135 {
137  sbrc = (*subcom_addr )(&rxstrcmd, &flags, &retstr);
138 }
139 
140 
141 /**
142  * Do post-callout processing of a command dispatch. This
143  * code runs after re-entering the interpreter, so all
144  * interpreter facilities are available.
145  *
146  * @param result The return RC result.
147  * @param condition A potential condition return.
148  */
150 {
151  if (sbrc != 0) /* have a numeric return code? */
152  {
153  result = new_integer(sbrc); /* just use the binary return code */
154  }
155  else if (!RXNULLSTRING(retstr)) /* we have something in retstr? */
156  {
157  /* make into a return string */
159  // try to get this as a numeric value
160  ((RexxObject *)result)->numberValue(sbrc);
161  /* user give us a new buffer? */
163  {
164  /* free it */
166  }
167  }
168  else
169  {
170  result = IntegerZero; /* got a zero return code */
171  }
172 
173  /****************************************************************************/
174  /* Check error flags from subcom handler and if needed, stick condition */
175  /* into result array. */
176  /****************************************************************************/
177 
178  if (flags & (unsigned short)RXSUBCOM_FAILURE)/* If failure flag set */
179  {
180  /* send failure condition back */
181  // raise the condition when things are done
182  condition = (RexxObject *)activity->createConditionObject(OREF_FAILURENAME, (RexxObject *)result, command, OREF_NULL, OREF_NULL);
183  }
184  /* If error flag set */
185  else if (flags & (unsigned short)RXSUBCOM_ERROR)
186  {
187  // raise the condition when things are done
188  condition = (RexxObject *)activity->createConditionObject(OREF_ERRORNAME, (RexxObject *)result, command, OREF_NULL, OREF_NULL);
189  }
190 }
191 
192 
193 
194 /**
195  * Process a callout to a system exit function.
196  */
198 {
200 
201  ExitContext context;
202 
203  // build a context pointer to pass out
205 
206  result = (RexxObject *)(*handler_address)(&context.threadContext, (RexxStringObject)address, (RexxStringObject)command);
207 }
208 
209 
210 /**
211  * Default handler for any error conditions. This just sets the
212  * condition information in the dispatch unit.
213  *
214  * @param c The condition information for the error.
215  */
217 {
218  // this only gets added if there is a condition
219  // NB: This is called by the native activation after re-entering the
220  // kernel code, so this has full access to kernel calls.
221  if (c != OREF_NULL)
222  {
223  // check to see if this is an error or failure situation
224  RexxString *conditionName = (RexxString *)c->at(OREF_CONDITION);
225  // if this is not a syntax error, this is likely an error
226  // or failure condition, and the return value is taken from
227  // the condition object.
228  if (!conditionName->strCompare(CHAR_SYNTAX))
229  {
230  // just set the condition now...additional processing will be
231  // done on return to the command issuer
232  condition = c;
233  }
234  else
235  {
236  // raise this as a normal error by default
238  }
239  }
240 }
@ T_CommandHandler
RexxInteger * new_integer(wholenumber_t v)
#define OREF_NULL
Definition: RexxCore.h:61
#define IntegerZero
Definition: RexxCore.h:199
RexxReturnCode REXXENTRY RexxResolveSubcom(const char *name, REXXPFN *)
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:436
RexxString * new_string(const char *s, stringsize_t l)
RexxNativeActivation * activation
CommandHandlerDispatcher(RexxActivity *a, REXXPFN e, RexxString *c)
char default_return_buffer[DEFRXSTRING]
void complete(RexxString *command, ProtectedObject &result, ProtectedObject &condition)
void call(RexxActivity *activity, RexxActivation *activation, RexxString *address, RexxString *command, ProtectedObject &rc, ProtectedObject &condition)
HandlerType type
void resolve(const char *name)
virtual void handleError(RexxDirectory *)
void createExitContext(ExitContext &context, RexxNativeActivation *owner)
RexxDirectory * createConditionObject(RexxString *, RexxObject *, RexxString *, RexxObject *, RexxObject *)
RexxObject * at(RexxString *)
size_t getLength()
const char * getStringData()
bool strCompare(const char *s)
static void releaseResultMemory(void *)
RexxObjectPtr REXXENTRY RexxContextCommandHandler(RexxExitContext *, RexxStringObject, RexxStringObject)
Definition: oorexxapi.h:395
RexxReturnCode REXXENTRY RexxSubcomHandler(PCONSTRXSTRING, unsigned short *, PRXSTRING)
Definition: rexx.h:339
struct _RexxStringObject * RexxStringObject
Definition: rexx.h:128
#define RXNULLSTRING(r)
Definition: rexx.h:177
#define MAKERXSTRING(r, p, l)
Definition: rexx.h:182
#define RXSUBCOM_ERROR
Definition: rexxapidefs.h:79
#define RXSUBCOM_FAILURE
Definition: rexxapidefs.h:80
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158
RexxExitContext threadContext
#define DEFRXSTRING
void * REXXPFN