/*- Author: Brian Tiffin Dedicated to the public domain Date started: December 2016 Modified: 2016-12-16/23:13-0500 +*/ /* Unicon integration with Open Object Rexx, C++ API sample */ /* tectonics: g++ -o oorexx.so -shared -fPIC oorexx.cpp -lrexx -lrexxapi */ #include #include bool checkForCondition(RexxThreadContext *c, bool clear); extern "C" { #include "icall.h" int oorexx(int argc, descriptor argv[]) { RexxInstance *interpreter; RexxThreadContext *threadContext; RexxOption *options = NULL; int rc; /* Create a Rexx Interpreter */ rc = RexxCreateInterpreter(&interpreter, &threadContext, options); fprintf(stderr, "rc = %d\n", rc); fflush(stderr); if (rc == 0) { fprintf(stderr, "Failed to create Rexx interpreter\n"); exit(1); } /* Expect program name from Unicon */ ArgString(1); /* Call a program */ RexxArrayObject args = NULL; RexxObjectPtr result = threadContext->CallProgram(StringVal(argv[1]), args); /* See if any conditions were raised */ if (threadContext->CheckCondition()) { checkForCondition(threadContext, true); } else { if (result != NULLOBJECT) { fprintf(stderr, "\nProgram result = %s\n\n", threadContext->ObjectToStringValue(result)); fflush(stderr); } } /* this test just returns an integer code */ interpreter->Terminate(); RetInteger(rc); } } /* end extern C */ /* Support routines */ inline wholenumber_t conditionSubCode(RexxCondition *condition) { return (condition->code - (condition->rc * 1000)); } void standardConditionMsg(RexxThreadContext *c, RexxDirectoryObject condObj, RexxCondition *condition) { RexxObjectPtr list = c->SendMessage0(condObj, "TRACEBACK"); if ( list != NULLOBJECT ) { RexxArrayObject a = (RexxArrayObject)c->SendMessage0(list, "ALLITEMS"); if ( a != NULLOBJECT ) { size_t count = c->ArrayItems(a); for ( size_t i = 1; i <= count; i++ ) { RexxObjectPtr o = c->ArrayAt(a, i); if ( o != NULLOBJECT ) { fprintf(stderr, "%s\n", c->ObjectToStringValue(o)); fflush(stderr); } } } } fprintf(stderr, "Error %d running %s line %ld: %s\n", (int)condition->rc, c->CString(condition->program), condition->position, c->CString(condition->errortext)); fprintf(stderr, "Error %d.%03d: %s\n", (int)condition->rc, (int)conditionSubCode(condition), c->CString(condition->message)); fflush(stderr); } bool checkForCondition(RexxThreadContext *c, bool clear) { if ( c->CheckCondition() ) { RexxCondition condition; RexxDirectoryObject condObj = c->GetConditionInfo(); if ( condObj != NULLOBJECT ) { c->DecodeConditionInfo(condObj, &condition); standardConditionMsg(c, condObj, &condition); if ( clear ) { c->ClearCondition(); } return true; } } return false; }