InterpreterAPI.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 /* REXX Kernel */
40 /* */
41 /* Startup */
42 /* */
43 /******************************************************************************/
44 #include <string.h>
45 #include <signal.h>
46 #include <stdlib.h>
47 
48 #include "RexxCore.h"
49 #include "RexxMemory.hpp"
50 #include "StringClass.hpp"
51 #include "DirectoryClass.hpp"
52 #include "RexxActivity.hpp"
53 #include "ActivityManager.hpp"
54 #include "MethodClass.hpp"
55 #include "StackClass.hpp"
56 #include "Interpreter.hpp"
57 #include "TranslateDispatcher.hpp"
58 #include "RexxStartDispatcher.hpp"
59 #include "InterpreterInstance.hpp"
60 #include "RexxNativeActivation.hpp"
61 #include "RexxInternalApis.h"
62 #include "SystemInterpreter.hpp"
63 
64 
66 /******************************************************************************/
67 /* Function: Terminate the REXX interpreter...will only terminate if the */
68 /* call nesting level has reached zero. */
69 /******************************************************************************/
70 {
71  // terminate and clean up the interpreter runtime. This only works
72  // if there are no active instances
73  return Interpreter::terminateInterpreter() ? 0 : 1;
74 }
75 
77 /******************************************************************************/
78 /* Function: Perform main kernel initializations */
79 /******************************************************************************/
80 {
81  // start this up for normal execution
83  // this always returns true
84  return true;
85 }
86 
87 
88 /**
89  * Create the Rexx saved image during build processing.
90  *
91  * @return Nothing
92  */
93 void REXXENTRY RexxCreateInterpreterImage(const char *target)
94 {
95  // start this up and save the image. This never returns to here
97 }
98 
99 
100 
101 /******************************************************************************/
102 /* Name: RexxMain */
103 /* */
104 /* Arguments: argcount - Number of args in arglist */
105 /* arglist - Array of args (array of RXSTRINGs) */
106 /* programname - REXX program to run */
107 /* instore - Instore array (array of 2 RXSTRINGs) */
108 /* envname - Initial cmd environment */
109 /* calltype - How the program is called */
110 /* exits - Array of system exit names (array of RXSTRINGs) */
111 /* */
112 /* Returned: result - Result returned from program */
113 /* rc - Return code from program */
114 /* */
115 /* Notes: Primary path into Object REXX. Makes sure Object REXX is up */
116 /* and runs the requested program. */
117 /* */
118 /******************************************************************************/
120  size_t argcount, /* Number of args in arglist */
121  PCONSTRXSTRING arglist, /* Array of args */
122  const char *programname, /* REXX program to run */
123  PRXSTRING instore, /* Instore array */
124  const char *envname, /* Initial cmd environment */
125  int calltype, /* How the program is called */
126  PRXSYSEXIT exits, /* Array of system exit names */
127  short * retcode, /* Integer form of result */
128  PRXSTRING result) /* Result returned from program */
129 {
130  if (calltype == RXCOMMAND && argcount == 1 && arglist[0].strptr != NULL && arglist[0].strlength > 0 &&
131  StringUtil::caselessCompare(arglist[0].strptr, "//T", arglist[0].strlength) == 0)
132  {
133  TranslateDispatcher arguments;
134  arguments.programName = programname;
135  arguments.instore = instore;
136  // this just translates and gives the error, potentially returning
137  // the instore image
138  arguments.outputName = NULL;
139  // go run this program
140  arguments.invoke(exits, envname);
141 
142  return (int)arguments.rc; /* return the error code (negated) */
143  }
144 
145 
146  // this is the dispatcher that handles the actual
147  // interpreter call. This gets all of the RexxStart arguments, then
148  // gets dispatched on the other side of the interpreter boundary
149  RexxStartDispatcher arguments;
150  /* copy all of the arguments into */
151  /* the info control block, which is */
152  /* passed across the kernel boundary */
153  /* into the real RexxStart method */
154  /* this is a real execution */
155  arguments.argcount = argcount;
156  arguments.arglist = arglist;
157  arguments.programName = programname;
158  arguments.instore = instore;
159  arguments.calltype = calltype;
160  arguments.retcode = 0;
161  arguments.result = result;
162 
163  // go run this program
164  arguments.invoke(exits, envname);
165  *retcode = arguments.retcode;
166 
167  // terminate and clean up the interpreter runtime. This only works
168  // if there are no active instances
170 
171  return (int)arguments.rc; /* return the error code (negated) */
172 }
173 
174 
175 /**
176  * Translate a program and store the translated results in an
177  * external file.
178  *
179  * @param inFile The input source file.
180  * @param outFile The output source.
181  * @param exits The exits to use during the translation process.
182  *
183  * @return The error return code (if any).
184  */
185 RexxReturnCode REXXENTRY RexxTranslateProgram(const char *inFile, const char *outFile, PRXSYSEXIT exits)
186 {
187  TranslateDispatcher arguments;
188  // this gets processed from disk, always.
189  arguments.programName = inFile;
190  arguments.instore = NULL;
191  // this just translates and gives the error, potentially returning
192  // the instore image
193  arguments.outputName = outFile;
194  // go run this program
195  arguments.invoke(exits, NULL);
196 
197  // terminate and clean up the interpreter runtime. This only works
198  // if there are no active instances
200 
201  return (RexxReturnCode)arguments.rc; /* return the error code (negated) */
202 }
203 
204 
205 /**
206  * Translate a program and store the translated results in an
207  * external file.
208  *
209  * @param inFile The input name.
210  * @param source The source RXSTRING
211  * @param image The returned image RXSTRING
212  *
213  * @return The error return code (if any).
214  */
216 {
217  TranslateInstoreDispatcher arguments;
218  // this gets processed from disk, always.
219  arguments.programName = inFile;
220  arguments.source = source;
221  arguments.image = image;
222  // go run this program
223  arguments.invoke(NULL, NULL);
224  return (RexxReturnCode)arguments.rc; /* return the error code (negated) */
225 }
226 
227 
228 /**
229  * Retrieve the interpreter version information.
230  *
231  * @return
232  */
234 {
235  char ver[100];
236  sprintf( ver, " %d.%d.%d", ORX_VER, ORX_REL, ORX_MOD );
237  char header[] = "Open Object Rexx Version";
238  #ifdef _DEBUG
239  char build[] = " - Internal Test Version\nBuild date: ";
240  #else
241  char build[] = "\nBuild date: ";
242  #endif
243  #ifdef __REXX64__
244  char mode[] = "\nAddressing Mode: 64";
245  #else
246  char mode[] = "\nAddressing Mode: 32";
247  #endif
248  char copy1[] = "\n\nCopyright (c) IBM Corporation 1995, 2004.\nCopyright (c) RexxLA " OOREXX_COPY_YEAR ".\nAll Rights Reserved.";
249  char copy2[] = "\nThis program and the accompanying materials are made available under";
250  char copy3[] = "\nthe terms of the Common Public License v1.0 which accompanies this";
251  char copy4[] = "\ndistribution or at";
252  char copy5[] = "\nhttp://www.oorexx.org/license.html";
253  char *ptr = (char *)SystemInterpreter::allocateResultMemory(strlen(header) + strlen(ver) + strlen(build) + strlen(__DATE__) +
254  strlen(mode) + strlen(copy1) + strlen(copy2) + strlen(copy3) + strlen(copy4) + strlen(copy5) + 1);
255  if (ptr != NULL)
256  {
257  sprintf(ptr, "%s%s%s%s%s%s%s%s%s%s", header, ver, build, __DATE__, mode, copy1, copy2, copy3, copy4, copy5);
258  }
259  return ptr;
260 }
261 
262 
263 /**
264  * Raise a halt condition for a target thread.
265  *
266  * @param threadid The target threadid.
267  *
268  * @return RXARI_OK if this worked, RXARI_NOT_FOUND if the thread isn't
269  * active.
270  */
272 {
273  if (Interpreter::isActive())
274  { /* Are we up? */
276  {
277  return (RXARI_NOT_FOUND); /* Couldn't find threadid */
278  }
279  return (RXARI_OK);
280  }
281  return RXARI_NOT_FOUND; /* REXX not running, error... */
282 }
283 
284 
285 /**
286  * Compatibility function for doing a RexxHaltThread().
287  *
288  * @param procid The process id (ignored).
289  * @param threadid The target threadid
290  *
291  * @return the success/failure return code.
292  */
294 {
295  return RexxHaltThread(threadid);
296 }
297 
298 
299 /**
300  * Turn on tracing for a given interpreter thread.
301  *
302  * @param threadid The target thread identifier.
303  *
304  * @return the success/failure return code.
305  */
307 {
308  if (Interpreter::isActive())
309  {
310  if (!ActivityManager::setActivityTrace(threadid, true))
311  {
312  return (RXARI_NOT_FOUND); /* Couldn't find threadid */
313  }
314  return (RXARI_OK);
315  }
316  return RXARI_NOT_FOUND; /* REXX not running, error... */
317 }
318 
319 
320 /**
321  * Reset the external trace for a target thread.
322  *
323  * @param threadid The target thread id.
324  *
325  * @return The success/failure indicator.
326  */
328 {
329  if (Interpreter::isActive())
330  {
331  if (!ActivityManager::setActivityTrace(threadid, false))
332  {
333  return (RXARI_NOT_FOUND); /* Couldn't find threadid */
334  }
335  return (RXARI_OK);
336  }
337  return RXARI_NOT_FOUND; /* REXX not running, error... */
338 }
339 
340 
341 /**
342  * Compatibility stub for the old signature of RexxSetTrace.
343  *
344  * @param procid The process id (ignored).
345  * @param threadid The target thread identifier.
346  *
347  * @return the success/failure return code.
348  */
350 {
351  return RexxSetThreadTrace(threadid);
352 }
353 
354 
355 /**
356  * The compatibility stub for the reset trace API.
357  *
358  * @param procid The target process id (ignored).
359  * @param threadid The thread id of the target thread.
360  *
361  * @return The success/failure indicator.
362  */
364 {
365  return RexxResetThreadTrace(threadid);
366 }
367 
368 
369 /**
370  * Create an interpreter instance at the API level.
371  *
372  * @param instance The returned instance pointer.
373  * @param context The initial thread context for this instance.
374  * @param exits A list of user exits to be used for this context.
375  * @param userData A pointer to a user defined data area.
376  *
377  * @return RXAPI_OK if the instance was created, RXAPI_MEMFAIL for any
378  * creation errors.
379  */
381 {
382  return Interpreter::createInstance(*instance, *context, options) ? RXAPI_OK : RXAPI_MEMFAIL;
383 }
384 
385 /**
386  * Main entry point for processing variable pool requests
387  *
388  * @param pshvblock The shaved variable block chain for the request.
389  *
390  * @return The composite request return code.
391  */
393 {
394  NativeContextBlock context;
395  // the variable pool interface handles its own try/catches.
396  return context.self->variablePoolInterface(pshvblock);
397 }
398 
399 /**
400  * Process a stemsort call for the rexxutil SysStemSort function.
401  *
402  * @param stemname The name of the stem.
403  * @param order The sort order.
404  * @param type The type of sort (case sensitivity).
405  * @param start The starting element number.
406  * @param end The end element number.
407  * @param firstcol The first sort column.
408  * @param lastcol The last sort column.
409  *
410  * @return The sort return code result.
411  */
412 RexxReturnCode RexxEntry RexxStemSort(const char *stemname, int order, int type,
413  size_t start, size_t end, size_t firstcol, size_t lastcol)
414 {
415  NativeContextBlock context;
416  // the variable pool interface handles its own try/catches.
417  return context.self->stemSort(stemname, order, type, start, end, firstcol, lastcol);
418 }
419 
420 /**
421  * Wait for Rexx termination. This is a nop in 4.0 since
422  * the APIs do the proper thing with respect to threading
423  * termination. This is maintained solely for binary
424  * compatibility.
425  *
426  * @return
427  */
429 {
430 }
431 
432 
433 /**
434  * Test if the interpreter environment has terminated. This is
435  * a nop in 4.0 since the APIs do the proper thing with respect
436  * to threading termination. This is maintained solely for
437  * binary compatibility.
438  *
439  * @return always returns true
440  */
442 {
443  return true;
444 }
RexxObject * build(RexxString *variable_name, bool direct)
char *REXXENTRY RexxGetVersionInformation()
RexxReturnCode RexxEntry RexxVariablePool(PSHVBLOCK pshvblock)
RexxReturnCode RexxEntry RexxStemSort(const char *stemname, int order, int type, size_t start, size_t end, size_t firstcol, size_t lastcol)
RexxReturnCode REXXENTRY RexxTranslateProgram(const char *inFile, const char *outFile, PRXSYSEXIT exits)
void REXXENTRY RexxCreateInterpreterImage(const char *target)
RexxReturnCode REXXENTRY RexxTranslateInstoreProgram(const char *inFile, CONSTRXSTRING *source, RXSTRING *image)
int REXXENTRY RexxStart(size_t argcount, PCONSTRXSTRING arglist, const char *programname, PRXSTRING instore, const char *envname, int calltype, PRXSYSEXIT exits, short *retcode, PRXSTRING result)
int REXXENTRY RexxInitialize()
RexxReturnCode REXXENTRY RexxResetTrace(process_id_t procid, thread_id_t threadid)
RexxReturnCode REXXENTRY RexxResetThreadTrace(thread_id_t threadid)
RexxReturnCode REXXENTRY RexxSetThreadTrace(thread_id_t threadid)
void RexxEntry RexxWaitForTermination()
RexxReturnCode REXXENTRY RexxSetTrace(process_id_t procid, thread_id_t threadid)
RexxReturnCode REXXENTRY RexxHaltThread(thread_id_t threadid)
RexxReturnCode REXXENTRY RexxSetHalt(process_id_t procid, thread_id_t threadid)
RexxReturnCode RexxEntry RexxCreateInterpreter(RexxInstance **instance, RexxThreadContext **context, RexxOption *options)
RexxReturnCode RexxEntry RexxDidRexxTerminate()
int REXXENTRY RexxTerminate()
#define OREF_NULL
Definition: RexxCore.h:60
static bool setActivityTrace(thread_id_t thread_id, bool on_or_off)
static bool haltActivity(thread_id_t thread_id, RexxString *description)
static void startInterpreter(InterpreterStartupMode mode, const char *imageTarget)
static bool terminateInterpreter()
static bool isActive()
Definition: Interpreter.hpp:92
static int createInstance(RexxInstance *&instance, RexxThreadContext *&threadContext, RexxOption *options)
RexxNativeActivation * self
RexxReturnCode variablePoolInterface(PSHVBLOCK requests)
int stemSort(const char *stemname, int order, int type, size_t start, size_t end, size_t firstcol, size_t lastcol)
static int caselessCompare(const char *, const char *, sizeB_t)
Definition: StringUtil.cpp:580
static void * allocateResultMemory(sizeB_t)
int type
Definition: cmdparse.cpp:383
CONSTANT_RXSTRING * PCONSTRXSTRING
Definition: rexx.h:186
int RexxReturnCode
Definition: rexx.h:73
#define RexxEntry
Definition: rexx.h:412
#define RXCOMMAND
Definition: rexxapidefs.h:64
#define RXARI_OK
Definition: rexxapidefs.h:212
#define RXAPI_MEMFAIL
Definition: rexxapidefs.h:61
#define RXARI_NOT_FOUND
Definition: rexxapidefs.h:213
#define RXAPI_OK
Definition: rexxapidefs.h:60
pid_t process_id_t
#define REXXENTRY
pthread_t thread_id_t