/** * Print out a comprehensive version string which includes the interpreter * version, date and time built, etc. This requires starting up the interpreter * and ending it. May be over-kill. * * If we fail to start the interpreter, we just ignore it and print out the * standard version string. */ static void printFullVersion(void) { RexxThreadContext *c; RexxInstance *interpreter; if ( RexxCreateInterpreter(&interpreter, &c, NULL) ) { char *buf = getCompleteVersion(c); if ( buf ) { printf(buf); LocalFree(buf); } else { printStandardVersion(); } interpreter->Terminate(); return; } printStandardVersion(); return; }
void REXXENTRY invokeProgram(InstanceInfo *instanceInfo) { RexxInstance *instance; RexxThreadContext *context; instanceInfo->code = 0; instanceInfo->rc = 0; strcpy(instanceInfo->returnResult, ""); createInstance(instanceInfo, instance, context); RexxArrayObject args = context->NewArray(instanceInfo->argCount); for (size_t i = 0; i < instanceInfo->argCount; i++) { if (instanceInfo->arguments[i] != NULL) { context->ArrayPut(args, context->String(instanceInfo->arguments[i]), i + 1); } } RexxObjectPtr result = context->CallProgram(instanceInfo->programName, args); // if an exception occurred, get the decoded exception information if (context->CheckCondition()) { RexxCondition condition; RexxDirectoryObject cond = context->GetConditionInfo(); context->DecodeConditionInfo(cond, &condition); instanceInfo->code = condition.code; instanceInfo->rc = condition.rc; } else { if (result != NULLOBJECT) { CSTRING resultString = context->CString(result); strncpy(instanceInfo->returnResult, resultString, sizeof(instanceInfo->returnResult)); } } // make sure we terminate this first instance->Terminate(); deregisterExits(); deregisterSubcomHandler(); }
void POREXX1::application() { log( "I", "Application POREXX1 starting." << endl ) ; int i ; int j ; bool found ; size_t version ; string rxsource ; string path ; RexxInstance *instance ; RexxThreadContext *threadContext ; RexxArrayObject args ; RexxCondition condition ; RexxDirectoryObject cond ; RexxObjectPtr result ; RexxContextEnvironment environments[ 2 ] ; RexxOption options[ 3 ] ; environments[ 0 ].handler = lspfServiceHandler ; environments[ 0 ].name = "ISPEXEC" ; environments[ 1 ].handler = NULL ; environments[ 1 ].name = "" ; options[ 0 ].optionName = APPLICATION_DATA ; options[ 0 ].option = (void *)this ; options[ 1 ].optionName = DIRECT_ENVIRONMENTS ; options[ 1 ].option = (void *)environments ; options[ 2 ].optionName = "" ; rxsource = word( PARM, 1 ) ; PARM = subword( PARM, 2 ) ; found = false ; if ( rxsource.size() > 0 && rxsource[ 0 ] == '%' ) { rxsource.erase( 0, 1 ) ; } if ( rxsource == "" ) { log( "E", "POREXX1 error. No REXX passed" << endl ) ; ZRC = 16 ; ZRSN = 4 ; ZRESULT = "No REXX passed" ; cleanup() ; return ; } if ( rxsource[ 0 ] == '/' ) { rexxName = rxsource ; } else { j = getpaths( ZORXPATH ) ; for ( i = 1 ; i <= j ; i++ ) { path = getpath( ZORXPATH, i ) ; if ( path.back() != '/' ) { path += "/" ; } rexxName = path + rxsource ; if ( !exists( rexxName ) ) { continue ; } if ( is_regular_file( rexxName ) ) { found = true ; break ; } log( "E", "POREXX1 error. " << rxsource << " found but is not a regular file" << endl ) ; setmsg( "PSYS012B" ) ; ZRC = 16 ; ZRSN = 12 ; ZRESULT = "Invalid REXX passed" ; cleanup() ; return ; } if ( !found ) { log( "E", "POREXX1 error. " << rxsource << " not found in ZORXPATH concatination" << endl ) ; setmsg( "PSYS012C" ) ; ZRC = 16 ; ZRSN = 8 ; ZRESULT = "REXX not found" ; cleanup() ; return ; } } if ( RexxCreateInterpreter( &instance, &threadContext, options ) ) { args = threadContext->NewArray( 1 ) ; threadContext->ArrayPut(args, threadContext->String( PARM.c_str() ), 1 ) ; version = threadContext->InterpreterVersion() ; log( "I", "Starting OOREXX Interpreter Version. .: " << version << endl ) ; log( "I", "Running program. . . . . . . . . . . .: " << rxsource << endl ) ; log( "I", "With parameters. . . . . . . . . . . .: " << PARM << endl ) ; result = threadContext->CallProgram( rexxName.c_str(), args) ; if ( threadContext->CheckCondition() ) { cond = threadContext->GetConditionInfo() ; threadContext->DecodeConditionInfo( cond, &condition ) ; log( "E", "POREXX1 error running REXX.: " << rxsource << endl ) ; log( "E", " Condition Code . . . . .: " << condition.code << endl ) ; log( "E", " Condition Error Text . .: " << threadContext->CString( condition.errortext ) << endl ) ; log( "E", " Condition Message. . . .: " << threadContext->CString( condition.message ) << endl ) ; setmsg( "PSYS011M" ) ; ZRC = 20 ; ZRSN = condition.code ; ZRESULT = threadContext->CString( condition.message ) ; } else { if ( result != NULLOBJECT ) { CSTRING resultString = threadContext->CString( result ) ; } } instance->Terminate() ; } cleanup() ; return ; }
// // MAIN program // int __cdecl main(int argc, char *argv[]) { short rexxrc = 0; /* return code from rexx */ int i; /* loop counter */ int rc; /* actually running program RC */ const char *program_name; /* name to run */ char arg_buffer[8192]; /* starting argument buffer */ char *cp; /* option character pointer */ CONSTRXSTRING arguments; /* rexxstart argument */ size_t argcount; RXSTRING rxretbuf; // program return buffer BOOL from_string = FALSE; /* running from command line string? */ BOOL real_argument = TRUE; /* running from command line string? */ RXSTRING instore[2]; RexxInstance *pgmInst; RexxThreadContext *pgmThrdInst; RexxArrayObject rxargs, rxcargs; RexxDirectoryObject dir; RexxObjectPtr result; rc = 0; /* set default return */ /* * Convert the input array into a single string for the Object REXX * argument string. Initialize the RXSTRING variable to point to this * string. Keep the string null terminated so we can print it for debug. * First argument is name of the REXX program * Next argument(s) are parameters to be passed */ arg_buffer[0] = '\0'; /* default to no argument string */ program_name = NULL; /* no program to run yet */ for (i = 1; i < argc; i++) /* loop through the arguments */ { /* is this an option switch? */ if ((*(cp=*(argv+i)) == '-' || *cp == '/')) { switch (*++cp) { case 'e': case 'E': /* execute from string */ if (from_string == FALSE) { /* only treat 1st -e differently */ from_string = TRUE; if ( argc == i+1 ) { break; } program_name = "INSTORE"; instore[0].strptr = argv[i+1]; instore[0].strlength = strlen(instore[0].strptr); instore[1].strptr = NULL; instore[1].strlength = 0; real_argument = FALSE; } break; case 'v': case 'V': { /* version display */ char *ptr = RexxGetVersionInformation(); if (ptr) { fprintf(stdout, ptr); fprintf(stdout, "\n"); RexxFreeMemory(ptr); } return 0; } default: /* ignore other switches */ break; } } else /* convert into an argument string */ { if (program_name == NULL) { /* no name yet? */ program_name = argv[i]; /* program is first non-option */ break; /* end parsing after program_name has been resolved */ } else if ( real_argument ) { /* part of the argument string */ if (arg_buffer[0] != '\0') { /* not the first one? */ strcat(arg_buffer, " "); /* add an blank */ } strcat(arg_buffer, argv[i]); /* add this to the argument string */ } real_argument = TRUE; } } if (program_name == NULL) { /* give a simple error message */ #undef printf printf("\n"); fprintf(stderr,"Syntax is \"rexx filename [arguments]\"\n"); fprintf(stderr,"or \"rexx -e program_string [arguments]\"\n"); fprintf(stderr,"or \"rexx -v\".\n"); return -1; } else { /* real program execution */ getArguments(NULL, GetCommandLine(), &argcount, &arguments); rxretbuf.strlength = 0L; /* initialize return to empty */ #ifdef REXXC_DEBUG printf("program_name = %s\n", program_name); printf("argv 0 = %s\n", argv[0]); printf("argv 1 = %s\n", argv[1]); printf("argv 2 = %s\n", argv[2]); printf("argument.strptr = %s\n", argument.strptr); printf("argument.strlenth = %lu\n", argument.strlength); #endif if (from_string) { /* Here we call the interpreter. We don't really need to use */ /* all the casts in this call; they just help illustrate */ /* the data types used. */ rc=REXXSTART(argcount, /* number of arguments */ &arguments, /* array of arguments */ program_name, /* name of REXX file */ instore, /* rexx code from command line */ "CMD", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, &rexxrc, /* Rexx program output */ &rxretbuf ); /* Rexx program output */ /* rexx procedure executed*/ if ((rc==0) && rxretbuf.strptr) { RexxFreeMemory(rxretbuf.strptr); /* Release storage only if */ } freeArguments(NULL, &arguments); } else { RexxCreateInterpreter(&pgmInst, &pgmThrdInst, NULL); // configure the traditional single argument string if ( arguments.strptr != NULL ) { rxargs = pgmThrdInst->NewArray(1); pgmThrdInst->ArrayPut(rxargs, pgmThrdInst->String(arguments.strptr), 1); } else { rxargs = pgmThrdInst->NewArray(0); } // set up the C args into the .local environment dir = (RexxDirectoryObject)pgmThrdInst->GetLocalEnvironment(); if ( argc > 2 ) { rxcargs = pgmThrdInst->NewArray(argc - 2); } else { rxcargs = pgmThrdInst->NewArray(0); } for (i = 2; i < argc; i++) { pgmThrdInst->ArrayPut(rxcargs, pgmThrdInst->NewStringFromAsciiz(argv[i]), i - 1); } pgmThrdInst->DirectoryPut(dir, rxcargs, "SYSCARGS"); // call the interpreter result = pgmThrdInst->CallProgram(program_name, rxargs); // display any error message if there is a condition. // if there was an error, then that will be our return code. // Although the return is a wholenumber_t we know there is no error // code too big to fit in an int. rc = (int)pgmThrdInst->DisplayCondition(); if (rc != 0) { pgmInst->Terminate(); return -rc; // well, the negation of the error number is the return code } // now handle any potential return value if (result != NULL) { pgmThrdInst->ObjectToInt32(result, &rc); } pgmInst->Terminate(); return rc; } } return rc ? rc : rexxrc; // rexx program return cd }