From: <mie...@us...> - 2009-03-19 00:22:07
|
Revision: 4294 http://oorexx.svn.sourceforge.net/oorexx/?rev=4294&view=rev Author: miesfeld Date: 2009-03-19 00:21:55 +0000 (Thu, 19 Mar 2009) Log Message: ----------- Start of some 4.0.0 API examples Added Paths: ----------- incubator/4.0.0.examples/ incubator/4.0.0.examples/api/ incubator/4.0.0.examples/api/reader.writer/ incubator/4.0.0.examples/api/reader.writer/Makefile.lin incubator/4.0.0.examples/api/reader.writer/Makefile.win incubator/4.0.0.examples/api/reader.writer/backward.fnc incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.cpp incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.rex incubator/4.0.0.examples/api/reader.writer/nutshell_1b.rex incubator/4.0.0.examples/api/reader.writer/simpleRW.cpp incubator/4.0.0.examples/api/reader.writer/simpleRW.rex incubator/4.0.0.examples/api/reader.writer/simplestRW.cpp Added: incubator/4.0.0.examples/api/reader.writer/Makefile.lin =================================================================== --- incubator/4.0.0.examples/api/reader.writer/Makefile.lin (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/Makefile.lin 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,62 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + + +# + +DLL_LFLAGS = --export-dynamic -shared -nostartfiles +EXE_LFLAGS = -L. -ldl +OOREXX_CFLAGS = -fPIC + + +# What we want to build. +all: simple_rw + +simple_rw.o: simpleRW.cpp + gcc -c $(OOREXX_CFLAGS) -o simple_rw.o simpleRW.cpp + +simple_rw: simple_rw.o + gcc $(EXE_LFLAGS) -lrexx -lrexxapi simple_rw.o -o simple_rw + +# Build a shared library +#liborxinvocation.so: orxinvocation.o +# gcc $(ORXLFLAGS) $(REXX_LIBS) -lrexx -lrexxapi -L. -lorxexits -o liborxinvocation.so orxinvocation.o +# + +clean: + rm -f *.so *.o simple_rw + Added: incubator/4.0.0.examples/api/reader.writer/Makefile.win =================================================================== --- incubator/4.0.0.examples/api/reader.writer/Makefile.win (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/Makefile.win 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,90 @@ +#/*----------------------------------------------------------------------------*/ +#/* */ +#/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +#/* */ +#/* This program and the accompanying materials are made available under */ +#/* the terms of the Common Public License v1.0 which accompanies this */ +#/* distribution. A copy is also available at the following address: */ +#/* http://www.oorexx.org/license.html */ +#/* */ +#/* Redistribution and use in source and binary forms, with or */ +#/* without modification, are permitted provided that the following */ +#/* conditions are met: */ +#/* */ +#/* Redistributions of source code must retain the above copyright */ +#/* notice, this list of conditions and the following disclaimer. */ +#/* Redistributions in binary form must reproduce the above copyright */ +#/* notice, this list of conditions and the following disclaimer in */ +#/* the documentation and/or other materials provided with the distribution. */ +#/* */ +#/* Neither the name of Rexx Language Association nor the names */ +#/* of its contributors may be used to endorse or promote products */ +#/* derived from this software without specific prior written permission. */ +#/* */ +#/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +#/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +#/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +#/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +#/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +#/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +#/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +#/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +#/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +#/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#/* */ +#/*----------------------------------------------------------------------------*/ + + +# This is a Visual C++, nMake compatible make file for the reader / writer +# samples. +# +# The compiler needs to be able to find the ooRexx native API headers and +# libraries. If REXX_HOME is set on the system, the correct directory will be +# automatically added to the LIB and INCLUDE environment variables by this make +# file. +# +# Otherwise, either uncomment the next line and define the correct REXX_HOME, or +# be sure the LIB and INCLUDE environment variables allow the compiler to find +# the ooRexx native API headers and libraries. + +# REXX_HOME = <your directory path> + +!IF DEFINED(REXX_HOME) +INCLUDE = $(INCLUDE);$(REXX_HOME)\api +LIB = $(LIB);$(REXX_HOME)\api +!ENDIF + +REXX_LIBS = rexx.lib rexxapi.lib + +WARNINGFLAGS = /W3 /Wp64 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE + +OOREXX_CFLAGS = /nologo /DWINDOWS /EHsc /Zi /Od /Gr /MTd $(WARNINGFLAGS) /c + +EXE_LFLAGS = /NOLOGO /DEBUG -debugtype:cv /SUBSYSTEM:Console $(REXX_LIBS) user32.lib comdlg32.lib gdi32.lib kernel32.lib +DLL_LFLAGS = /NOLOGO /DEBUG -debugtype:cv /SUBSYSTEM:Windows $(REXX_LIBS) /DLL + +# What we want to build. +all: simplestRW.exe simpleRW.exe lessSimpleRW.exe + +simplestRW.obj: simplestRW.cpp + cl $(OOREXX_CFLAGS) simplestRW.cpp + +simplestRW.exe: simplestRW.obj + link $(EXE_LFLAGS) simplestRW.obj -out:$(@B).exe + +simpleRW.obj: simpleRW.cpp + cl $(OOREXX_CFLAGS) simpleRW.cpp + +simpleRW.exe: simpleRW.obj + link $(EXE_LFLAGS) simpleRW.obj -out:$(@B).exe + +lessSimpleRW.obj: lessSimpleRW.cpp + cl $(OOREXX_CFLAGS) lessSimpleRW.cpp + +lessSimpleRW.exe: lessSimpleRW.obj + link $(EXE_LFLAGS) lessSimpleRW.obj -out:$(@B).exe + +clean: + del *.exe *.dll *.obj *.ilk *.pdb *.lib *.exp *.suo 1>nul 2>&1 + Added: incubator/4.0.0.examples/api/reader.writer/backward.fnc =================================================================== --- incubator/4.0.0.examples/api/reader.writer/backward.fnc (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/backward.fnc 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,70 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */ +/* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ +/*********************************************************************/ +/* */ +/* backward.fnc - Reverse the words in a string */ +/* */ +/* This program is from the traditional, classic API example, */ +/* callrxnt. Here it is used by the simpleRW example to demonstrate */ +/* calling a program using the new native APIs. */ +/* */ +/* Input: A string of words */ +/* */ +/* Output: A string containing the same words but in opposite order */ +/* */ +/*********************************************************************/ + +say; say "backward.fnc --> start @" .DateTime~new~string +Parse Arg Data /* get argument string */ +say 'The string:' +say ' ' Data +OutString = '' /* initialize output to empty */ +Count = Words(Data) /* find number of words */ +Do i = Count To 1 By -1 /* for each word in string */ + OutString = OutString Word(Data,i) /* add word to output string */ + End /* end do */ + +OutString = Strip(OutString) /* remove any blanks on the */ + /* front or back. */ +say 'when reversed is:' +say ' ' OutString +say "backward.fnc --> finished @" .DateTime~new~string; say + +Return OutString /* return reversed string, */ + + Added: incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.cpp =================================================================== --- incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.cpp (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.cpp 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,256 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYright HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYright */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * This example is similar to the simplestRW and simpleRW examples. It uses the + * same .worker .fifo classes and the same basic program code. However, the + * program code has been placed in a routine (::routine) rather than as the. + * + * This example starts the same basic reader / writer program as simplestRW does + * by calling the routine containing the program code. In addition, it + * instantiates and starts a third worker from this C++ code so that there are 3 + * workers, in 3 different threads reading and writing to the fifo buffer. The + * output to the console shows the interleaving of the writes from the 3 + * threads. It also shows that the reads are interleaved with the writes + * because the reads start before the writes have finished. + * + * There are a couple of other miscellaneous examples shown in the C++ code. + * + * 1.) The fifo buffer object is created in the called routine and placed in the + * .local environment. The C++ code retrieves this buffer from .local for use + * in the C++ worker. + * + * 2.) The nutshell_1b.rex code package places an 'interpreter' ID string in the + * .local envrionment. The C++ code changes the value of the ID string from + * [# 0] to [# 1] which is visible in the console output. + * + * Note that the error handling is very primitive in that the C++ code basically + * just quits on any error. In addition, there are a few places where a check + * for NULLOBJECT is skipped. + * + * This example is designed to work correctly with nutshell_1b.rex as the + * package code. When this program is invoked with no arguments, it + * automatically uses nutshell_1b.rex. To allow the programmer to experiment a + * little with changing the Rexx code, this program will accept as the first + * argument the name of an alternative file to use as the package code. There + * is nothing fancy with the argument checking, the program simply uses it. + * This means of course that this program will fail if you pass in an incorrect + * argument. + */ + +#include "oorexxapi.h" +#include <stdio.h> + +/* Prototypes for several simple helper functions. The functions themselves are + * at the bottom of the file. + */ +inline wholenumber_t conditionSubCode(RexxCondition); +bool checkCondition(RexxThreadContext *, const char *); +void printInterpreterVersion(RexxInstance *); + +int main (int argc, char **argv) +{ + char *packageName = "nutshell_1b.rex"; // Not correct package, just used to get error. + if ( argc == 2 ) + { + // Nothing fancy here, if there is an argument, then use it. + packageName = argv[1]; + } + + // The arguments to RexxCreateInterpreter. An array of any number of Rexx + // options can be passed in, but for this example we do not need any + // options. So, we use NULL as the options argument. + RexxInstance *interpreter; + RexxThreadContext *threadContext; + RexxOption *options = NULL; + + if ( RexxCreateInterpreter(&interpreter, &threadContext, options) == 0 ) + { + printf("Failed to create interpreter, aborting.\n"); + exit(1); + } + printInterpreterVersion(interpreter); + + // Load the package containing our needed classes and routine. + // LoadPackage() behaves in essentially the same way as a ::requires + // directive in Rexx code would. The objects defined by directives are + // created and then any code preceding the first directive is executed. + RexxPackageObject nutshellPkg = threadContext->LoadPackage(packageName); + if ( nutshellPkg == NULLOBJECT ) + { + // Some problem. If there is a condition pending, checkCondition() will + // print the information. If there is not a condition pending, then + // print something here. + if ( ! checkCondition(threadContext, "LoadPackage()") ) + { + printf("Failed to load the %s package\n", packageName); + } + exit(1); + } + + // We will locate our routine object in a directory. The name needs to be + // upper-case or the routine will not be found. Try it, lower case the name + // and see the results. + char *routineName = "STARTWORKERS"; + + // Get the routine object we are going to call. + RexxDirectoryObject pkgRoutines = threadContext->GetPackageRoutines(nutshellPkg); + RexxRoutineObject nutshellRoutine = (RexxRoutineObject)threadContext->DirectoryAt(pkgRoutines, routineName); + if ( nutshellRoutine == NULLOBJECT ) + { + printf("Failed to locate %s routine object.\n", routineName); + exit(1); + } + + // Set up the various Rexx objects we will use from this C++ code. + + // Get the .local environment directory. + RexxDirectoryObject dotLocal = threadContext->GetLocalEnvironment(); + + // Get the .worker class object so we can instantiate a third worker object + // to run from this C++ code. + RexxClassObject workerCls = threadContext->FindPackageClass(nutshellPkg, "WORKER"); + if ( workerCls == NULLOBJECT ) + { + printf("Failed to locate the .worker class object.\n"); + exit(1); + } + + // Create a worker object, and 2 of the 3 args we will pass to the write() + // method of the object. The third arg, the buffer is retrieved from the + // .local environment where it is placed by the startWorkers() routine. + RexxObjectPtr worker = threadContext->SendMessage0(workerCls, "NEW"); + RexxStringObject msg = threadContext->String("from_C++"); + RexxObjectPtr repetions = threadContext->WholeNumber(7); + + // Create a string object to use to change a .local variable. + RexxStringObject instanceID = threadContext->String("[# 1]"); + + // Now start our basic program by calling the routine with the executable + // code. + printf("Using interpreter to call %s\n\n", routineName); + RexxObjectPtr result = threadContext->CallRoutine(nutshellRoutine, NULL); + + // If the routine raised a condition, print some information about it. + // Otherwise do some work from this C++ code. + if (threadContext->CheckCondition()) + { + checkCondition(threadContext, routineName); + } + else + { + // I don't do any error checking here. As long as no one changes the + // nutshell package code, this should work without errors. + + // Get the fifo buffer which is the third argument to the write() method + // that we need. Then change the interpreter.info variable. + RexxObjectPtr fifoBuffer = threadContext->DirectoryAt(dotLocal, "BUFFER"); + threadContext->DirectoryPut(dotLocal, instanceID, "INTERPRETER.INFO"); + + // And finally, start our third worker object writing from this C++ + // code. + RexxArrayObject writeArgs = threadContext->ArrayOfThree(fifoBuffer, msg, repetions); + threadContext->SendMessage(worker, "WRITE", writeArgs); + } + + // Be sure the interpreter instance terminates before we end this process. + // The Terminate() call will wait for all threads to end. + interpreter->Terminate(); + + return 0; +} + +/** + * Below are several helper functions that are not really needed for this simple + * example. There are just used to print some informative messages to the + * screen. + */ + +/** + * Given an interpreter instance, prints out the interpreter version and + * language version. The documentation in the ooRexx programming guide explains + * the byte encoding of the version numbers. + */ +void printInterpreterVersion(RexxInstance *interpreter) +{ + wholenumber_t ver = interpreter->InterpreterVersion(); + wholenumber_t lang = interpreter->LanguageLevel(); + printf("Created interpreter instance version=%d.%d.%d language level=%d.%02d\n\n", + (ver & 0xff0000) >> 16, (ver & 0x00ff00) >> 8, ver & 0x0000ff, (lang & 0xff00) >> 8, lang & 0x00ff); +} + +/** + * Given a condition object, extracts and returns as a whole number the subcode + * of the condition. + */ +inline wholenumber_t conditionSubCode(RexxCondition condition) { return (condition.code - (condition.rc * 1000)); } + +/** + * Given a thread context, prints out some condition information, if there is a + * pending condition. + * + * This function then clears the condition, if one is pending, which is not + * necessary for this simple example. In a more sophisticated application, the + * programmer would need to decide what was appropriate. Checking then clearing + * a condition in the C++ code is very similar to trapping a condition and then + * continuing in Rexx code. + * + * @return True if there is a pending condition, otherwise false. + */ +bool checkCondition(RexxThreadContext *context, const char *name) +{ + bool haveCondition = false; + if (context->CheckCondition()) + { + RexxDirectoryObject cond = context->GetConditionInfo(); + + // There is a condition pending, cond should not be null, check anyway. + if ( cond != NULLOBJECT ) + { + haveCondition = true; + + RexxCondition condition; + context->DecodeConditionInfo(cond, &condition); + + printf("\n%s raised an exception:\n", name); + printf("Error: %d.%03d: %s\n\n", condition.rc, conditionSubCode(condition), + context->CString(condition.message)); + } + context->ClearCondition(); + } + return haveCondition; +} Added: incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.rex =================================================================== --- incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.rex (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/lessSimpleRW.rex 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,146 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * This is the Rexx program code used by both the lessSimpleRW and the ??? + * example programs. These examples show how to use the new C++ native APIs + * to create and work with the ooRexx interpreter from C++. + * + * This file contains two class definitions. A worker class that has methods + * to read and write from a supplied buffer and a fifo buffer class that is + * used to supply a buffer for the worker class. The RW in most of the file + * names for these examples comes from reader / writer. + * + * lessSimple.rex is based on simpleRW.rex and is essentially the same, with + * the exception that the executable code to create two worker objects and + * start them working is moved into a ::routine. + * + * Since these examples are intended for the C / C++ programmer interested in + * using the C++ native APIs, most of the comment is in the C++ files. + */ + + -- info of interpreter instance running, maybe changed by C++ nutshell +.local~interpreter.info="[# 0]" + +::routine startWorkers +a=.worker~new -- used to read & write messages to buffer +b=.worker~new -- used to write messages to buffer + +.local~buffer=.fifo~new -- buffer that gets shared + +a~write(.buffer, "from_a", 5) -- write 5 messages +b~write(.buffer, "FROM_B", 6) -- write 6 messages + + -- how much got written asynchroneously so far? +say .interpreter.info "... 'a' has written" a~i "messages so far" +say .interpreter.info "... 'b' has written" b~i "messages so far" + + -- let the main program sleep a little bit +sleepTime=.001 +say .interpreter.info "sleeping" sleepTime "seconds" +call sysSleep sleepTime + + -- how much got written asynchroneously so far? +say .interpreter.info "... 'a' has written" a~i "messages so far" +say .interpreter.info "... 'b' has written" b~i "messages so far" + + -- now read asynchroneously from the buffer +say .interpreter.info "... now starting to read from buffer" +a~read(.buffer) -- read all messages from buffer +say .interpreter.info "--> main program finished @" .DateTime~new~string + + +/* Read and write messages from/to given buffer asynchroneously */ +::class Worker +::method init class + expose activeWriter + activeWriter=0 -- number of active writers + +::attribute activeWriter class + +::method init + expose i + i=0 -- initialize variable + +::attribute i get unguarded + +::method write + expose i + use arg buffer, msg, repetitions + self~class~activeWriter+=1 -- increase counter + REPLY -- start asynchroneous execution + do i=1 to repetitions + buffer~write(i msg~left(8) "@" .DateTime~new~string) + call sysSleep random(1, 9)/1000 + end + + buffer~write("--> writing message ["msg"] finished @" .DateTime~new~string) + self~class~activeWriter-=1 -- decrease counter + +::method read unguarded + use arg buffer + REPLY -- start asynchroneous execution + do while buffer~items>0 | self~class~activeWriter>0 for 50 + msg=buffer~read + if msg == .nil then + call sysSleep .001 + else + say .interpreter.info "just read from buffer: ["|| buffer~identityHash"] message: ["msg"]" + end + say .interpreter.info "--> read(): finished @" .DateTime~new~string + + + +/* FIFO buffer, backed by a Rexx .Queue */ +::class FIFO + +::method init + expose buffer + buffer=.queue~new + +::method write + expose buffer + use arg tmp + buffer~queue(tmp) + +::method read + expose buffer + return buffer~pull + +::method items + expose buffer + return buffer~items Added: incubator/4.0.0.examples/api/reader.writer/nutshell_1b.rex =================================================================== --- incubator/4.0.0.examples/api/reader.writer/nutshell_1b.rex (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/nutshell_1b.rex 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,3 @@ + + + say 'mathRound:' 3/0 Added: incubator/4.0.0.examples/api/reader.writer/simpleRW.cpp =================================================================== --- incubator/4.0.0.examples/api/reader.writer/simpleRW.cpp (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/simpleRW.cpp 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,226 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYright HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYright */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * A simple example that creates an instance of the interpreter and uses that + * instance to execute some Rexx programs. + * + * After the interpreter instance is created, it is used to execute the + * simpleRW.rex program, which uses concurrency to read and write to a buffer + * asynchronously. That program returns before the reader and writers finish + * their work. + * + * The interpreter instance is then used to run the backward.fnc Rexx program + * which comes from an old example of using the classic native API. The + * interpreter instance passes the program a string, the program returns the + * string in reverse word order. This is printed to the screen from this C++ + * code. + * + * The simpleRW.rex program prints its output to the screen from the Rexx code + * using 'say' statements. Note the backward.fnc output printed in the middle + * of the simpleRW.rex output. + */ + +#include "oorexxapi.h" +#include <stdio.h> + +/* Prototypes for several simple helper functions. The functions themselves are + * at the bottom of the file. + */ +inline wholenumber_t conditionSubCode(RexxCondition); +void checkCondition(RexxThreadContext *, const char *); +void printInterpreterVersion(RexxInstance *); + +int main (int argc, char **argv) +{ + char *programName = "simpleRW.rex"; + if ( argc == 2 ) + { + programName = argv[1]; + } + + // These are the arguments to RexxCreateInterpreter(). An array of any + // number of Rexx options can be passed in, but for this example we do not + // need any options. So, we use NULL. + RexxInstance *interpreter; + RexxThreadContext *threadContext; + RexxOption *options = NULL; + + if ( RexxCreateInterpreter(&interpreter, &threadContext, options) == 0 ) + { + printf("Failed to create interpreter, aborting.\n"); + exit(1); + } + printInterpreterVersion(interpreter); + + // This string objects will be used as arguments to the backward.fnc + // program. They are created here, before either of the programs are + // executed, so that it is more obvious from the output that there are + // multiple activities running at the same time. + char *inputString = "Object Rexx was great, but Open Object Rexx is greater."; + RexxArrayObject args1 = threadContext->ArrayOfOne(threadContext->String(inputString)); + RexxArrayObject args2 = threadContext->ArrayOfOne(threadContext->String("One if by sea, two if by land")); + + // Execute the program and get the result returned to us. + printf("Using interpreter to execute %s\n\n", programName); + RexxObjectPtr result = threadContext->CallProgram(programName, NULL); + + // During the program execution, a condition can be raised if there is an + // unexpected error. If an exception occurred and is pending, + // CheckCondtion() will return true. In this case we print out some + // information on the condition, otherwise we print out the return, if any, + // from the program. (We know that simpleRW.rex does not return anything.) + // + // To see some condition output from this, temporarily rename simpleRW.rex + // to some other name. + if (threadContext->CheckCondition()) + { + checkCondition(threadContext, programName); + } + else + { + // We know the simpleRW.rex program does not return anything, so this + // result will always be null and nothing prints. + // + // Note that we use ObjectToStringValue(). That is guarenteed to return + // the ASCII-Z string representation of the object. If we passed in, say + // an .array object to the CString() function, we would get a crash. + if (result != NULLOBJECT) + { + printf("\nProgram result=%s\n\n", threadContext->ObjectToStringValue(result)); + } + } + + // Now execute the backward.fnc program with the first argument string. + programName = "backward.fnc"; + result = threadContext->CallProgram(programName, args1); + + // if an exception occurred, print some information to the screen. + if ( threadContext->CheckCondition() ) + { + checkCondition(threadContext, programName); + } + else + { + if (result != NULLOBJECT) + { + // backward.fnc returns a string object. We know that for sure, so + // I use CString(). But, to be extra safe, we could use + // ObjectToStringValue(). + printf("C++ got result -->%s\n", threadContext->CString(result)); + } + } + + // This next section is just a repeat of the above, but using the second + // string argument. + result = threadContext->CallProgram(programName, args2); + if ( threadContext->CheckCondition() ) + { + checkCondition(threadContext, programName); + } + else + { + if (result != NULLOBJECT) + { + printf("C++ got result -->%s\n\n", threadContext->CString(result)); + } + } + + // Now wait for the interpreter to terminate and we are done. + interpreter->Terminate(); + + return 0; +} + +/** + * Below are several helper functions that are not really needed for this simple + * example. There are just used to print some informative messages to the + * screen. + */ + +/** + * Given an interpreter instance, prints out the interpreter version and + * language version. The documentation in the ooRexx programming guide explains + * the byte encoding of the version numbers. + */ +void printInterpreterVersion(RexxInstance *interpreter) +{ + wholenumber_t ver = interpreter->InterpreterVersion(); + wholenumber_t lang = interpreter->LanguageLevel(); + printf("Created interpreter instance version=%d.%d.%d language level=%d.%02d\n\n", + (ver & 0xff0000) >> 16, (ver & 0x00ff00) >> 8, ver & 0x0000ff, (lang & 0xff00) >> 8, lang & 0x00ff); +} + +/** + * Given a condition object, extracts and returns as a whole number the subcode + * of the condition. + */ +inline wholenumber_t conditionSubCode(RexxCondition condition) { return (condition.code - (condition.rc * 1000)); } + +/** + * Given a thread context, prints out some condition information, if there is a + * pending condition. + * + * This function then clears the condition, if one is pending, which is not + * necessary for this simple example. In a more sophisticated application, the + * programmer would need to decide what was appropriate. Checking then clearing + * a condition in the C++ code is very similar to trapping a condition and then + * continuing in Rexx code. + */ +void checkCondition(RexxThreadContext *context, const char *name) +{ + // Note that we make sure there is a condition pending, even though in this + // example the caller has already checked. That lets us use the function in + // some of the other examples without changing it. + if (context->CheckCondition()) + { + RexxCondition condition; + + RexxDirectoryObject cond = context->GetConditionInfo(); + + // There is a condition pending, cond should not be null, check anyway. + if ( cond != NULLOBJECT ) + { + context->DecodeConditionInfo(cond, &condition); + + printf("\n%s raised an exception:\n", name); + printf("Error: %d.%03d: %s\n\n", condition.rc, conditionSubCode(condition), + context->CString(condition.message)); + } + context->ClearCondition(); + } +} Added: incubator/4.0.0.examples/api/reader.writer/simpleRW.rex =================================================================== --- incubator/4.0.0.examples/api/reader.writer/simpleRW.rex (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/simpleRW.rex 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,146 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * This is the Rexx program code used by both the simplestRW and the simpleRW + * example programs. These examples show how to use the new C++ native APIs + * to create and work with the ooRexx interpreter from C++. + * + * This file contains two class definitions. A worker class that has methods + * to read and write from a supplied buffer and a fifo buffer class that is + * used to supply a buffer for the worker class. The RW in most of the file + * names comes from reader / writer. + * + * This file also contains some executable code to create two worker objects + * and start them working. + * + * Since these examples are intended for the C / C++ programmer interested in + * using the C++ native APIs, most of the comment is in the C++ files. + */ + + -- info of interpreter instance running, maybe changed by C++ nutshell +.local~interpreter.info="[# 0]" + +a=.worker~new -- used to read & write messages to buffer +b=.worker~new -- used to write messages to buffer + +.local~buffer=.fifo~new -- buffer that gets shared + +a~write(.buffer, "from_a", 5) -- write 5 messages +b~write(.buffer, "FROM_B", 6) -- write 6 messages + + -- how much got written asynchroneously so far? +say .interpreter.info "... 'a' has written" a~i "messages so far" +say .interpreter.info "... 'b' has written" b~i "messages so far" + + -- let the main program sleep a little bit +sleepTime=.001 +say .interpreter.info "sleeping" sleepTime "seconds" +call sysSleep sleepTime + + -- how much got written asynchroneously so far? +say .interpreter.info "... 'a' has written" a~i "messages so far" +say .interpreter.info "... 'b' has written" b~i "messages so far" + + -- now read asynchroneously from the buffer +say .interpreter.info "... now starting to read from buffer" +a~read(.buffer) -- read all messages from buffer +say .interpreter.info "--> main program finished @" .DateTime~new~string + + +/* Read and write messages from/to given buffer asynchroneously */ +::class Worker +::method init class + expose activeWriter + activeWriter=0 -- number of active writers + +::attribute activeWriter class + +::method init + expose i + i=0 -- initialize variable + +::attribute i get unguarded + +::method write + expose i + use arg buffer, msg, repetitions + self~class~activeWriter+=1 -- increase counter + REPLY -- start asynchroneous execution + do i=1 to repetitions + buffer~write(i msg "@" .DateTime~new~string) + call sysSleep random(1, 9)/1000 + end + + buffer~write("--> writing message ["msg"] finished @" .DateTime~new~string) + self~class~activeWriter-=1 -- decrease counter + +::method read unguarded + use arg buffer + REPLY -- start asynchroneous execution + do while buffer~items>0 | self~class~activeWriter>0 for 50 + msg=buffer~read + if msg == .nil then + call sysSleep .001 + else + say .interpreter.info "just read from buffer: ["|| buffer~identityHash"] message: ["msg"]" + end + say .interpreter.info "--> read(): finished @" .DateTime~new~string + + + +/* FIFO buffer, backed by a Rexx .Queue */ +::class FIFO + +::method init + expose buffer + buffer=.queue~new + +::method write + expose buffer + use arg tmp + buffer~queue(tmp) + +::method read + expose buffer + return buffer~pull + +::method items + expose buffer + return buffer~items + + Added: incubator/4.0.0.examples/api/reader.writer/simplestRW.cpp =================================================================== --- incubator/4.0.0.examples/api/reader.writer/simplestRW.cpp (rev 0) +++ incubator/4.0.0.examples/api/reader.writer/simplestRW.cpp 2009-03-19 00:21:55 UTC (rev 4294) @@ -0,0 +1,183 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2008-2009 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in */ +/* the documentation and/or other materials provided with the distribution. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYright HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ +/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYright */ +/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ +/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */ +/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*----------------------------------------------------------------------------*/ + +/** + * A simple example that creates an instance of the interpreter and uses that + * instance to execute a Rexx program. + * + * After the interpreter instance is created, it is used to execute the + * simpleRW.rex program, which uses concurrency to read and write to a buffer + * asynchronously. That program returns before the reader and writers finish + * their work. + * + * This example is designed to work correctly with simpleRW.rex as the program + * code. When this program is invoked with no arguments, it automatically uses + * simpleRW.rex. + * + * To allow the programmer to experiment a little with changing the Rexx code, + * this program will accept as the first argument the name of an alternative + * file to use as the program code. There is nothing fancy with the argument + * checking, the program simply uses it. This means of course that this program + * will fail if you pass in an incorrect argument. + */ + +#include "oorexxapi.h" +#include <stdio.h> + +/* Prototypes for several simple helper functions. The functions themselves are + * at the bottom of the file. + */ +inline wholenumber_t conditionSubCode(RexxCondition); +void checkCondition(RexxThreadContext *, const char *); +void printInterpreterVersion(RexxInstance *); + +int main (int argc, char **argv) +{ + char *programName = "simpleRW.rex"; + if ( argc == 2 ) + { + programName = argv[1]; + } + + // These are the arguments to RexxCreateInterpreter(). An array of any + // number of Rexx options can be passed in, but for this example we do not + // need any options. So, we use NULL. + RexxInstance *interpreter; + RexxThreadContext *threadContext; + RexxOption *options = NULL; + + if ( RexxCreateInterpreter(&interpreter, &threadContext, options) == 0 ) + { + printf("Failed to create interpreter, aborting.\n"); + exit(1); + } + printInterpreterVersion(interpreter); + + // Execute the program and get the result returned to us. + printf("Using interpreter to execute %s\n\n", programName); + RexxObjectPtr result = threadContext->CallProgram(programName, NULL); + + // During the program execution, a condition can be raised if there is an + // unexpected error. If an exception occurred and is pending, + // CheckCondtion() will return true. In this case we print out some + // information on the condition, otherwise we print out the return, if any, + // from the program. (We know that simpleRW.rex does not return anything.) + // + // To see some condition output from this, temporarily rename simpleRW.rex + // to some other name. + if (threadContext->CheckCondition()) + { + checkCondition(threadContext, programName); + } + else + { + // We know the simpleRW.rex program does not return anything, so this + // result will always be null and nothing prints. + // + // Note that we use ObjectToStringValue(). That is guarenteed to return + // the ASCII-Z string representation of the object. If we passed in, say + // an .array object to the CString() function, we would get a crash. + if (result != NULLOBJECT) + { + printf("\nProgram result=%s\n\n", threadContext->ObjectToStringValue(result)); + } + } + + // Now wait for the interpreter to terminate and we are done. + interpreter->Terminate(); + + return 0; +} + +/** + * Below are several helper functions that are not really needed for this simple + * example. There are just used to print some informative messages to the + * screen. + */ + +/** + * Given an interpreter instance, prints out the interpreter version and + * language version. The documentation in the ooRexx programming guide explains + * the byte encoding of the version numbers. + */ +void printInterpreterVersion(RexxInstance *interpreter) +{ + wholenumber_t ver = interpreter->InterpreterVersion(); + wholenumber_t lang = interpreter->LanguageLevel(); + printf("Created interpreter instance version=%d.%d.%d language level=%d.%02d\n\n", + (ver & 0xff0000) >> 16, (ver & 0x00ff00) >> 8, ver & 0x0000ff, (lang & 0xff00) >> 8, lang & 0x00ff); +} + +/** + * Given a condition object, extracts and returns as a whole number the subcode + * of the condition. + */ +inline wholenumber_t conditionSubCode(RexxCondition condition) { return (condition.code - (condition.rc * 1000)); } + +/** + * Given a thread context, prints out some condition information, if there is a + * pending condition. + * + * This function then clears the condition, if one is pending, which is not + * necessary for this simple example. In a more sophisticated application, the + * programmer would need to decide what was appropriate. Checking then clearing + * a condition in the C++ code is very similar to trapping a condition and then + * continuing in Rexx code. + */ +void checkCondition(RexxThreadContext *context, const char *name) +{ + // Note that we make sure there is a condition pending, even ... [truncated message content] |