static int set_rexx_variable( char *name, int suffix, char *value, int value_length ) { SHVBLOCK shv; char variable_name[250]; int rc=0; shv.shvnext=NULL; /* only one block */ shv.shvcode=RXSHV_SET; /* use direct set */ sprintf( variable_name, "%s.%-d", name, suffix ); (void)make_upper( variable_name );/* make variable name uppercase */ /* * Now (attempt to) set the REXX variable * Add name/value to SHVBLOCK */ MAKERXSTRING( shv.shvname, variable_name, strlen( variable_name) ); MAKERXSTRING( shv.shvvalue, value, value_length ); /* * One or both of these is needed, too <sigh> */ shv.shvnamelen = strlen( variable_name ); shv.shvvaluelen = value_length; rc = RexxVariablePool( &shv ); /* Set the REXX variable */ if ( rc != RXSHV_OK && rc != RXSHV_NEWV) { rc = 1; } else rc = 0; return rc; }
wholenumber_t rexx_add_queue( RexxMethodContext *context, // the call context RexxStringObject queue_line, /* line to add */ int order ) /* queuing order */ { char buffer = 0; // buffer for an empty string CONSTRXSTRING rx_string; // rxstring to push RexxReturnCode rc; // queue return code if (queue_line == NULLOBJECT) /* no line given? */ { // just use a null string value MAKERXSTRING(rx_string, &buffer, 0); } else { MAKERXSTRING(rx_string, context->StringData(queue_line), context->StringLength(queue_line)); } /* get the queue name */ RexxObjectPtr queue_name = context->GetObjectVariable("NAMED_QUEUE"); /* move the line to the queue */ rc = RexxAddQueue(context->ObjectToStringValue(queue_name), &rx_string, order); if (rc != 0) /* stream error? */ { context->RaiseException1(Rexx_Error_System_service_service, context->NewStringFromAsciiz("SYSTEM QUEUE")); } return rc; /* return the result */ }
/** * Default virtual method for handling a run() methods on * an activity dispatcher. */ void TranslateInstoreDispatcher::run() { ProtectedSet savedObjects; RexxString *name = GlobalNames::NULLSTRING; // name of the invoked program if (programName != NULL) /* have an actual name? */ { /* get string version of the name */ name = new_string(programName); } savedObjects.add(name); /* protect from garbage collect */ RXSTRING instore[2]; MAKERXSTRING(instore[0], const_cast<char *>(source->strptr), source->strlength); MAKERXSTRING(instore[1], NULL, 0); /* go handle instore parms */ RoutineClass *program = LanguageParser::processInstore(instore, name); if (program == OREF_NULL) /* couldn't get it? */ { /* got an error here */ reportException(Error_Program_unreadable_name, name); } // copy the image information back image->strptr = instore[1].strptr; image->strlength = instore[1].strlength; }
CommandHandlerDispatcher::CommandHandlerDispatcher(Activity *a, REXXPFN e, RexxString *command) { activity = a; // needed for raising conditions entryPoint = e; // the call point // clear the state flags flags = 0; // set up a return code buffer MAKERXSTRING(retstr, default_return_buffer, DEFRXSTRING); // set up the command RXSTRING MAKERXSTRING(rxstrcmd, command->getStringData(), command->getLength()); }
char *FetchRexxVariable(char *name) //, char *value) { unsigned long rc; SHVBLOCK block; // memset(block, '\0', sizeof(block)); block.shvcode = RXSHV_SYFET; block.shvret = 0; block.shvnext = NULL; MAKERXSTRING(block.shvname, name, strlen(name)); block.shvnamelen = block.shvname.strlength; block.shvvalue.strptr = NULL; block.shvvalue.strlength = 0; rc = RexxVariablePool(&block); // value = block.shvvalue.strptr; // memcpy(value, block.shvvalue.strptr, block.shvvalue.strlength); // value[block.shvvalue.strlength+1] = '\0'; // DosFreeMem(block.shvvalue.strptr); // do I need this? return block.shvvalue.strptr; }
/* * SetRexxVariable - Set the value of a REXX variable * * Easy way to set stem variables * * name - stem name and index <ex: test.0> * value - value to set stem to */ unsigned long SetRexxVariable(char *name, char *value) { unsigned long rc; SHVBLOCK block; block.shvcode = RXSHV_SYSET; block.shvret = 0; block.shvnext = NULL; MAKERXSTRING(block.shvname, name, strlen(name)); MAKERXSTRING(block.shvvalue, value, strlen(value)); block.shvnamelen = block.shvname.strlength; block.shvvaluelen = block.shvvalue.strlength; rc = RexxVariablePool(&block); // DosFreeMem(block.shvvalue.strptr); // do I need this? return rc; }
int main (int argc, char **argv) { // our invocation information InstanceInfo instanceInfo; // fill in the structure for the invocation buildInfo(&instanceInfo, argc, argv); // this can be done using either RexxCreateInterpreter or RexxStart if (instanceInfo.callType == InstanceInfo::INSTANCE) { // go invoke this invokeProgram(&instanceInfo); } else { invokeRexxStart(&instanceInfo); } // if no error, then push the return result on to the queue if (instanceInfo.rc == 0) { CONSTRXSTRING result; MAKERXSTRING(result, instanceInfo.returnResult, strlen(instanceInfo.returnResult)); RexxAddQueue("TESTQUEUE", &result, RXQUEUE_LIFO); } else { CONSTRXSTRING result; char errorResult[50]; sprintf(errorResult, "%d %d", instanceInfo.rc, instanceInfo.code); MAKERXSTRING(result, errorResult, strlen(errorResult)); RexxAddQueue("TESTQUEUE", &result, RXQUEUE_LIFO); } return (int)instanceInfo.rc; // return the error indicator }
/* * assignedRxString builds a RXSTRING of a GCI_str. The RXSTRING is set * in the usual manner and a terminating zero is appended without notification * of the target. NULL-strings are converted to empty strings. * Returns 1 on error, 0 on success. */ static int assignRxString( void *hidden, PRXSTRING dest, const GCI_str *src ) { char *h; if ( RXNULLSTRING( *dest ) || ( RXSTRLEN( *dest ) < (ULONG) src->used+1 ) ) { if ( ( h = (char *) IfcAllocateMemory( (ULONG) (src->used+1) ) ) == NULL ) return 1; } else h = RXSTRPTR( *dest ); memcpy( h, src->val, src->used ); h[(int) (src->used)] = '\0'; MAKERXSTRING( *dest, h, (ULONG) src->used ); return 0; }
int ExecuteMacro(char *argv, int namelength) { RXSTRING rxRc; RXSTRING rxArg[2]; int rxArgCount = 0; char pszName[CCHMAXPATH]; char *rxArgStr; short sRc; long rc; if (namelength >= sizeof(pszName)) return 1; /* FIXME HBB 20010121: 3rd argument doesn't make sense. Either * this should be sizeof(pszName), or it shouldn't use * safe_strncpy(), here */ safe_strncpy(pszName, argv, namelength + 1); rxArgStr = &argv[namelength]; RXSTRPTR(rxRc) = NULL; #if 0 /* C-like calling of function: program name is first parameter. In REXX you would have to use Parse Arg param0, param1 to get the program name in param0 and the arguments in param1. Some versions before gnuplot 3.7pl1 used a similar approach but passed program name and arguments in a single string: (==> Parse Arg param0 param1) */ MAKERXSTRING(rxArg[0], pszName, strlen(pszName)); rxArgCount++; if (*rxArgStr) { MAKERXSTRING(rxArg[1], rxArgStr, strlen(rxArgStr)); rxArgCount++; } #else /* REXX standard calling (gnuplot 3.7pl1 and above): The program name is not supplied and so all actual arguments are in a single string: Parse Arg param We even handle blanks like cmd.exe when calling REXX programs. */ if (*rxArgStr) { MAKERXSTRING(rxArg[0], rxArgStr, strlen(rxArgStr)); rxArgCount++; } #endif CallFromRexx = TRUE; rc = RexxStart( rxArgCount, rxArg, pszName, NULL, "GNUPLOT", RXCOMMAND, NULL, &sRc, &rxRc); CallFromRexx = FALSE; /* am: a word WRT errors codes: the negative ones don't seem to have symbolic names, you can get them from the OREXX reference, they're not in REXX Programming Guide - no idea where to retrieve them from a Warp 3 reference ?? The positive ones are somehow referenced in REXXPG */ if (rc < 0) { /* REXX error */ } else if (rc > 0) { /* Interpreter couldn't be started */ if (rc == -4) /* run was cancelled, but don't give error message */ rc = 0; } else if (rc==0) { /* all was fine */ } /* We don't we try to use rxRc ? BTW, don't use free() instead since it's allocated inside RexxStart() and not in our executable using the EMX libraries */ if (RXSTRPTR(rxRc)) /* I guess it's NULL if something major went wrong, NULL strings are usually not part of the REXX language ... */ DosFreeMem(rxRc.strptr); return rc; }
MRESULT EXPENTRY Calculator( HWND hwnd, /* window handle */ ULONG msg, /* dispatched message id */ MPARAM mp1, /* first message parameter */ MPARAM mp2 ) /* second message parameter */ { ULONG action; /* Action to process */ switch (msg) { /* switch based on the message*/ /* received */ /* The initialization message has been received. We do some */ /* additional fixup of the dialog to make it look a little */ /* nicer. */ case WM_INITDLG: /* initialize accumulator */ MAKERXSTRING(accumulator, accbuff, 1); strcpy(accbuff, "0"); /* fill in a zero */ digits = 0; /* no digits in number */ hadperiod = NO; /* no period yet */ hadexponent = NO; /* no exponential yet */ oldaction = 0; /* no pending operations */ strcpy(precision, "9"); /* set default precision */ form = SCIENTIFIC; /* set default form */ SetDisplay(&accumulator); /* set initial display value */ /* update the calculator */ /* display */ WinSetWindowText(WinWindowFromID(hwnd, DISPLAY), display.strptr); /* register our external */ /* functions */ RexxRegisterFunctionExe("CalcPrecision", (PFN)CalcPrecision); RexxRegisterFunctionExe("CalcForm", (PFN)CalcForm); return FALSE; /* initialization complete */ /* We are going away, time to post a quit message to the */ /* message loop. */ case WM_CLOSE: /* Deregister our defined */ /* functions */ RexxDeregisterFunction("CalcPrecision"); RexxDeregisterFunction("CalcForm"); /* Standard Close processing */ WinPostMsg(hwnd, WM_QUIT, 0L, 0L); return FALSE; /* Exit now */ /* We've received a WM_CONTROL message. This was */ /* generated by the "Form" check blox. */ case WM_CONTROL: /* change current form */ action = SHORT1FROMMP(mp1); /* Extract message sub-type */ switch (action) { /* process the control */ case BUTTON_FORM: /* form switch button */ if (form == SCIENTIFIC) { /* current scientific? */ form = ENGINEERING; /* make it engineering */ /* update label */ WinSetWindowText(WinWindowFromID(hwnd, BUTTON_FORM), "Engineering"); } else { form = SCIENTIFIC; /* otherwise scientfic */ WinSetWindowText(WinWindowFromID(hwnd, BUTTON_FORM), "Scientific"); } return FALSE; /* all done */ default: /* Unknown, can't handle this */ return FALSE; } /* We've received a WM_COMMAND message. WM_COMMAND messages */ /* are generated by "pressing" buttons on the calculator. The */ /* additional parameters in the received message identify the */ /* button that was pressed */ case WM_COMMAND: action = SHORT1FROMMP(mp1); /* Extract message sub-type */ switch (action) { /* The following buttons will be processed by the actual */ /* calculator routine */ case BUTTON_CLEAR: /* Clear key */ /* initialize accumulator */ MAKERXSTRING(accumulator, accbuff, 1); strcpy(accbuff, "0"); /* fill in a zero */ /* initialize the display */ MAKERXSTRING(display, dispbuff, 1); strcpy(dispbuff, "0"); /* fill in a zero display */ digits = 0; /* no digits yet */ hadperiod = NO; /* turn off number processing */ hadexponent = NO; /* flags. */ oldaction = 0; /* and any pending operations */ /* update the calculator */ /* display */ WinSetWindowText(WinWindowFromID(hwnd, DISPLAY), display.strptr); return FALSE; /* All done */ case BUTTON_DIGITS: /* set new digits */ /* not a whole number? */ if (!CheckWhole(&display)) /* give an error beep */ WinAlarm(HWND_DESKTOP, WA_ERROR); else { /* process the number */ /* copy the number */ strcpy(precision, display.strptr); /* redisplay the accumlator */ SetDisplay(&accumulator); /* display */ WinSetWindowText(WinWindowFromID(hwnd, DISPLAY), display.strptr); } return FALSE; /* All done */ case BUTTON_0: /* Numeric keys */ case BUTTON_1: case BUTTON_2: case BUTTON_3: case BUTTON_4: case BUTTON_5: case BUTTON_6: case BUTTON_7: case BUTTON_8: case BUTTON_9: case BUTTON_PERIOD: /* decimal point */ case BUTTON_EXPONENT: /* exponent value */ case BUTTON_SIGN: /* sign change */ /* Add a digit to display */ AddDigit(action); /* update the accumulator */ /* display */ WinSetWindowText(WinWindowFromID(hwnd, DISPLAY), display.strptr); return FALSE; /* All done */ /* The arithmetic operation keys all have a deferred */ /* execution. When one of these is pressed, the previous*/ /* arithmetic operation is processed using the */ /* accumulator and the current display. The new operator*/ /* is saved for later execution. If no operator exists, */ /* then the current display is moved to the accumulator */ /* and no arithmetic is done */ case BUTTON_MULTIPLY: /* Multiply key */ case BUTTON_DIVIDE: /* Division key */ case BUTTON_PLUS: /* Addition key */ case BUTTON_MINUS: /* Subtraction key */ case BUTTON_IDIV: /* integer division */ case BUTTON_REMAINDER: /* remainder division */ case BUTTON_POWER: /* raise a number to power */ case BUTTON_ENTER: /* "Total" key */ case BUTTON_PROGRAM1: /* programmed Rexx function */ case BUTTON_PROGRAM2: /* programmed Rexx function */ /* Process pending operations */ ProcessArithmetic(action); SetDisplay(&accumulator);/* reset display buffer */ /* update the calculator */ /* display */ WinSetWindowText(WinWindowFromID(hwnd, DISPLAY), accumulator.strptr); return FALSE; /* All done */ default: /* Unknown, can't handle this */ return FALSE; } case WM_ERASEBACKGROUND: /* disable background erase */ return MRFROMLONG(TRUE); /* don't allow this */ /* Message not handled by us. PM gives us first chance at all */ /* messages. Those we don't want to process we pass on to the */ /* default dialog procedure. */ default: return WinDefWindowProc(hwnd, msg, mp1, mp2); } return FALSE; /* Should never reach here */ }
/* This Proc handles the on-the-fly data CD writing */ MRESULT EXPENTRY waveinfoStatusDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { char text[CCHMAXPATH*2 +10]; char title[CCHMAXPATH]; SWCNTRL swctl; PID pid; int a; switch (msg) { case WM_PAINT: { HPS hps; RECTL rcl, rclSource; POINTL ptl; LONG lTemp; BOOL bUseCustomPainting=TRUE; LONG lWidthX; LONG lWidthY; LONG lColor; ULONG attrFound; if(bUseCustomPainting) { // if(allBMPs[CTRLIDX_BG].hbm) { if(1) { hps=WinBeginPaint(hwnd, NULLHANDLE, &rcl); rclSource.xLeft=0; rclSource.yBottom=0; #if 0 rclSource.yTop=allBMPs[CTRLIDX_BG].bmpInfoHdr.cy; rclSource.xRight=allBMPs[CTRLIDX_BG].bmpInfoHdr.cx; lTemp=rcl.xLeft/rclSource.xRight; ptl.x=lTemp*rclSource.xRight; lTemp=rcl.yBottom/rclSource.yTop; lTemp*=rclSource.yTop; #endif // rcl.yBottom+=4; rclSource=rcl; rcl.yTop+=4; WinFillRect(hps, &rclSource, CLR_RED); /* Border */ lWidthX=WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER); lWidthY=WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER); GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL); #if 0 if ( (WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, 0, &attrFound, sizeof(attrFound), &lColor, QPF_PURERGBCOLOR)) == 0 ) lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0); #endif WinQueryWindowRect(hwnd, &rcl); ptl.x=1; ptl.y=0; GpiMove(hps, &ptl); GpiSetColor(hps, CLR_BLACK); ptl.x=rcl.xRight-1; GpiLine(hps,&ptl); ptl.y=rcl.yTop-1; GpiLine(hps,&ptl); GpiSetColor(hps, SYSCLR_SHADOW); ptl.x=rcl.xLeft; GpiLine(hps,&ptl); ptl.y=0; GpiLine(hps,&ptl); rcl.yTop-=1; rcl.yBottom+=1; rcl.xLeft+=1; rcl.xRight-=1; WinDrawBorder( hps,&rcl, 1, 1, 0, 0, 0x400); rcl.yTop-=1; rcl.yBottom+=1; rcl.xLeft+=1; rcl.xRight-=1; /* Get active border color */ if(WinQueryActiveWindow(HWND_DESKTOP)==hwnd) { if ( (WinQueryPresParam(hwnd, PP_BORDERCOLOR, 0, &attrFound, sizeof(attrFound), &lColor, QPF_PURERGBCOLOR)) == 0 ) lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0); } else { /* Inactive border color */ if ( (WinQueryPresParam(hwnd, PP_INACTIVECOLOR, 0, &attrFound, sizeof(attrFound), &lColor, QPF_PURERGBCOLOR)) == 0 ) lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0); } /* Get Border size */ WinSendMsg(hwnd, WM_QUERYBORDERSIZE, MPFROMP(&ptl),0); WinDrawBorder(hps,&rcl, ptl.x-2, ptl.y-2, lColor, 0, 0); #if 0 while(ptl.x<rcl.xRight) { ptl.y=lTemp; while(ptl.y<rcl.yTop) {/* y direction */ //DosBeep(5000,100); WinDrawBitmap(hps, allBMPs[CTRLIDX_BG].hbm, &rclSource, (PPOINTL)&ptl, 0, 0, DBM_IMAGEATTRS); ptl.y+=allBMPs[CTRLIDX_BG].bmpInfoHdr.cy; //DosSleep(200); }; ptl.x+=allBMPs[CTRLIDX_BG].bmpInfoHdr.cx; }; #endif WinEndPaint(hps); return (MRESULT)0; } } break; } case WM_DRAWITEM: switch(SHORT1FROMMP(mp1)) { case SLIDERID: return drawSlider(hwnd, msg, mp1, mp2, SHORT1FROMMP(mp1)); default: break; } break; case WM_INITDLG: /* Add switch entry */ memset(&swctl,0,sizeof(swctl)); WinQueryWindowProcess(hwnd,&pid,NULL); swctl.hwnd=hwnd; swctl.uchVisibility=SWL_VISIBLE; swctl.idProcess=pid; swctl.bProgType=PROG_DEFAULT; swctl.fbJump=SWL_JUMPABLE; WinAddSwitchEntry(&swctl); #if 0 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, "", "", 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); #endif // oldProc=WinSubclassWindow(WinWindowFromID(hwnd, IDST_TEXT), newProc); hwndNew=WinCreateWindow(hwnd, CLASS_NAME, "Title", WS_VISIBLE |WS_TABSTOP, 10,50, SLIDERID, 40, hwnd, HWND_TOP, SLIDERID, NULLHANDLE, NULLHANDLE); WinShowWindow(hwnd, TRUE); // WinQueryWindowPos(hwndNew,&swpSl); return (MRESULT) TRUE; /* WM_APPTERMINATENOTIFY messages are sent from the helper programs e.g. format checker. */ case WM_CLOSE: WinDismissDlg(hwnd,0); return FALSE; case WM_CONTROL: { switch(SHORT2FROMMP(mp1)) { case SLN_SLIDERTRACK: { switch(SHORT1FROMMP(mp1)) { case SLIDERID: DosBeep(5000, 10); break; default: break; }/* switch */ return (MRESULT) 0; break; } case SLN_CHANGE: { switch(SHORT1FROMMP(mp1)) { case SLIDERID: DosBeep(500, 100); break; default: break; }/* switch */ return (MRESULT)TRUE; } default: break; }/* switch */ break; }/* WM_CONTROL */ case WM_COMMAND: switch(SHORT1FROMMP(mp1)) { case DID_OK: /* User pressed the OK button */ WinPostMsg(hwnd,WM_CLOSE,0,0); break; case IDPB_RIGHT: WinPostMsg( WinWindowFromID(hwnd, SLIDERID), SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE), MPFROMLONG( (LONG) 70 )); break; case IDPB_LEFT: WinPostMsg( WinWindowFromID(hwnd, SLIDERID), SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE), MPFROMLONG( (LONG) 20 )); break; case IDPB_SIZE: { SWP swp; RXSTRING arg[2]; /* argument string for REXX */ RXSTRING rexxretval; /* return value from REXX */ APIRET rc; /* return code from REXX */ SHORT rexxrc = 0; /* return code from function */ char chrThis[20]; char chrHwnd[20]; char *str = "These words will be swapped"; /* text to swap */ #if 0 RexxRegisterFunctionExe("CWRXFunc1", (PFN)rexxFunc1); sprintf(chrThis, "%d",123); sprintf(chrHwnd, "%d", WinQueryWindow(hwnd,QW_PARENT)); /* By setting the strlength of the output RXSTRING to zero, we */ /* force the interpreter to allocate memory and return it to us. */ /* We could provide a buffer for the interpreter to use instead. */ rexxretval.strlength = 0L; /* initialize return to empty*/ MAKERXSTRING(arg[0], chrHwnd, strlen(chrHwnd));/* create input argument */ MAKERXSTRING(arg[1], chrThis, strlen(chrThis));/* create input argument */ /* 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((LONG) 2, /* number of arguments */ (PRXSTRING) &arg, /* array of arguments */ (PSZ) "G:\\Projects_working\\mmclasses-0.3.0\\testfunc.cwr",/* name of REXX file */ (PRXSTRING) 0, /* No INSTORE used */ (PSZ) "CWRXX", /* Command env. name */ (LONG) RXSUBROUTINE, /* Code for how invoked */ (PRXSYSEXIT) 0, /* No EXITs on this call */ (PSHORT) &rexxrc, /* Rexx program output */ (PRXSTRING) &rexxretval ); /* Rexx program output */ sprintf(text,"rc: %d, function return code: %d, %s ", rc, (int) rexxrc, rexxretval.strptr); WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text, "", 1234, MB_OK|MB_MOVEABLE); DosFreeMem(rexxretval.strptr); /* Release storage given to us by REXX. */ #endif // WinQueryWindowPos(hwndNew,&swp); // WinSetWindowPos(hwndNew, NULLHANDLE, 0, 0, swp.cx-30, swp.cy+10,SWP_SIZE); break; } default: break; } return (MRESULT) FALSE; default: break; }/* switch */ return WinDefDlgProc( hwnd, msg, mp1, mp2); }
// // MAIN program // int __cdecl main(int argc, char *argv[]) { RXSYSEXIT exit_list[9]; /* Exit list array */ short rexxrc = 0; /* return code from rexx */ int rc; /* actually running program RC */ CONSTRXSTRING argument; /* rexxstart argument */ RXSTRING rxretbuf; // program return buffer rc = 0; /* set default return */ /* just one argument is accepted by this program */ if ((argc < 2) || (argc > 3)) { printf("Wrong arguments: REXXEXIT program [argument]\n"); exit(-1); } /* * 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 */ /* By setting the strlength of the output RXSTRING to zero, we */ /* force the interpreter to allocate memory and return it to us. */ /* We could provide a buffer for the interpreter to use instead. */ rxretbuf.strlength = 0L; /* initialize return to empty*/ if (argc == 3) { MAKERXSTRING(argument, argv[2], strlen(argv[2]));/* create input argument */ } else MAKERXSTRING(argument, "", 0);/* create blank argument */ // register IO exit rc = RexxRegisterExitExe("MY_IOC", (REXXPFN)&MY_IOEXIT, NULL); /* run this via RexxStart */ exit_list[0].sysexit_name = "MY_IOC"; exit_list[0].sysexit_code = RXSIO; exit_list[1].sysexit_code = RXENDLST; /* Here we call the interpreter. */ rc=REXXSTART(1, /* number of arguments */ &argument, /* array of arguments */ argv[1], /* name of REXX file */ NULL, /* No INSTORE used */ "CMD", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ exit_list, /* exits for this call */ &rexxrc, /* Rexx program output */ &rxretbuf ); /* Rexx program output */ /* free memory allocated for the return result */ if (rc==0) { RexxFreeMemory(rxretbuf.strptr); } RexxDeregisterExit("MY_IOC",NULL); // remove the exit in exe exit list // return interpeter or rexx program return code return rc ? rc : rexxrc; }
int main(int argc, char **argv) { CONSTRXSTRING arg[4]; /* argument string for Rexx */ RXSTRING rexxretval; /* return value from Rexx */ RXSTRING instore[2]; /* in storage parms */ PFNREXXSTART FuncAddress; void *pLibHandle = NULL; /* Library handle */ RexxReturnCode rc = 0; /* return code from Rexx */ short rexxrc = 0; /* return code from function */ const char *pszLibraryName = "librexx.so"; /* define the library name */ char returnBuffer[100]; char val; const char *str1 = "Arg number one"; /* text to swap */ const char *str2 = "Arg number two"; /* text to swap */ const char *str3 = "Arg number three"; /* text to swap */ const char *str4 = "Arg number four"; /* text to swap */ const char *sync_tst = "call time 'Reset';" \ "object1 = .example~new;" \ "object2 = .example~new;" \ "object3 = .example~new;" \ "a.1 = object1~start('REPEAT', 4 , 'Object 1 running');" \ "say a.1~result;" \ "say 'The result method waits until the START message has completed:';" \ "a.2 = object2~start('REPEAT', 2, 'Object 2 running');" \ "a.3 = object3~start('REPEAT', 2, 'Object 3 running');" \ "say a.2~result;" \ "say a.3~result;" \ "say 'main ended';" \ "say 'Elapsed time: ' time('E');" \ "exit;" \ "::REQUIRES 'example.rex'"; if (!(pLibHandle = dlopen(pszLibraryName, RTLD_LAZY ))) { /* Load and resolve symbols immediately */ fprintf(stderr, " *** Unable to load library %s !\nError message: %s\n", pszLibraryName, dlerror()); return 99; } if(!(FuncAddress = (PFNREXXSTART) dlsym(pLibHandle, "RexxStart"))) { rc = 1; /* could not resolve */ fprintf(stderr, " *** Unable to load function %s !\nError message: %s\n", "RexxStart", dlerror()); return 99; } /* By setting the strlength of the Rexx output to zero, the */ /* interpreter allocates memory. */ /* We can provide a buffer for the interpreter to use instead. */ /* If the returned value does not fit into the buffer, */ /* Open Object Rexx creates a new one. */ system("clear"); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ printf("This is an easy sample of how to invoke the Rexx interpreter. \n"); printf("The Rexx commandfile which is started is named: startrx1.rex\n"); printf("Press Enter to continue\n"); scanf("%c", &val); /* This is the interpreter invocation. ------------------------------ */ rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "startrx1.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); if (rexxretval.strptr != NULL) { RexxFreeMemory(rexxretval.strptr); } printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("In this case a previously defined Resultstring is \n"); printf("delivered to Open Object Rexx, which is large enough to \n"); printf("hold the Return Value of the Rexx commandfile.\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = returnBuffer; rexxretval.strlength = sizeof(returnBuffer); rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "startrx1.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("rexxretval.strptr contains %s\n", rexxretval.strptr); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); /* if Rexx needed to allocate a new buffer, release that one */ if (rexxretval.strptr != returnBuffer) { RexxFreeMemory(rexxretval.strptr); } printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("In this case a previously defined Resultstring is \n"); printf("delivered to Open Object Rexx, which is too small to\n"); printf("hold the Return Value of the Rexx commandfile.\n"); printf("Rexx reallocates the buffer which needs to be freed.\n"); printf("in the calling program\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = (char *)returnBuffer; rexxretval.strlength = 2; printf("The length of the Resultstring is %d\n", rexxretval.strlength); rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "startrx1.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("The ResultString contains %s after call\n", rexxretval.strptr); printf("The length is now %d\n", rexxretval.strlength); /* if Rexx needed to allocate a new buffer, release that one */ if (rexxretval.strptr != returnBuffer) { RexxFreeMemory(rexxretval.strptr); } printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ printf("This is a sample with 4 arguments delivered to \n"); printf("REXXSTART\n"); printf("The Rexx commandfile which is started is named: startrx2.rex\n"); printf("Press Enter to continue\n"); scanf("%c", &val); MAKERXSTRING(arg[0], str1, strlen(str1)); /* create input argument 1 */ MAKERXSTRING(arg[1], str2, strlen(str2)); /* create input argument 2 */ MAKERXSTRING(arg[2], str3, strlen(str3)); /* create input argument 3 */ MAKERXSTRING(arg[3], str4, strlen(str4)); /* create input argument 4 */ rc = (*FuncAddress)( 4, /* number of arguments */ arg, /* array of arguments */ "startrx2.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("This is a sample with 2 arguments delivered to \n"); printf("REXXSTART\n"); printf("The Rexx commandfile which is started is named: startrx2.rex\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ rc = (*FuncAddress)( 2, /* number of arguments */ arg, /* array of arguments */ "startrx2.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("This is a sample where the directory listing of the \n"); printf("actual directory is returned by the Rexx program. The \n"); printf("returned ResultString is displayed\n"); printf("The Rexx commandfile which is started is named: startrx3.rex\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "startrx3.rex", /* name of Rexx file */ NULL, /* No INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("This is a sample where the instore parameter [0] is \n"); printf("tested. Instore parameter [0] is loaded with \n"); printf("a small Open Object Rexx script showing the concurrency feature.\n"); printf("Press Enter to continue\n"); scanf("%c", &val); instore[0].strptr = (const char *)sync_tst; instore[0].strlength = strlen(instore[0].strptr); instore[1].strptr = NULL; instore[1].strlength = 0; rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ NULL, /* no name for Rexx file */ instore, /* INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("Now instore[1] is loaded with the content of instore[0]. \n"); printf("It can be used on subsequent calls. instore[0] is set to NULL \n"); printf("Press Enter to continue\n"); scanf("%c", &val); instore[0].strptr = NULL; instore[0].strlength = 0; rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ NULL, /* no name for Rexx file */ instore, /* INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); free(instore[1].strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("This is a sample to show how to use the Rexx MacroSpace facility. \n"); printf("First of all load_macro.rex is called to load \n"); printf("the Rexx script macros.rex into Macrospace. The Macrospace- \n"); printf("name is upload.rex. \n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "load_macro.rex", /* name for Rexx macrospacefile*/ NULL, /* INSTORE not used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("Now the Open Object Rexx script macros.rex (named upload.rex) has been loaded\n"); printf("into Macrospace. It is now used in the name option of\n"); printf("the REXXSTART command. \n"); printf("It is very important that instore paramenter [0] and [1] are\n"); printf("initialized to NULL rsp. 0 and used as REXXSTART parameters\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rexxretval.strptr = NULL; /* initialize return-pointer to empty */ rexxretval.strlength = 0; /* initialize return-length to zero */ instore[1].strptr = NULL; instore[1].strlength = 0; instore[0].strptr = NULL; instore[0].strlength = 0; rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "upload.rex", /* name for Rexx macrospacefile */ instore, /* INSTORE used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); free(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); printf("Finally del_macro.rex is called to delete macros.rex (named upload.rex)\n"); printf("out of the Open Object Rexx Macrospace.\n"); printf("Press Enter to continue\n"); scanf("%c", &val); rc = (*FuncAddress)( 0, /* number of arguments */ NULL, /* array of arguments */ "del_macro.rex", /* name for Rexx macrospacefile */ NULL, /* INSTORE not used */ "ksh", /* Command env. name */ RXCOMMAND, /* Code for how invoked */ NULL, /* No EXITs on this call */ &rexxrc, /* Rexx program output */ &rexxretval ); /* Rexx program output */ printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc); printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength); printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr); RexxFreeMemory(rexxretval.strptr); printf("Press Enter to continue\n"); scanf("%c", &val); system("clear"); return 0; }
/** * Default virtual method for handling a run() methods on * an activity dispatcher. */ void RexxStartDispatcher::run() { ProtectedSet savedObjects; // set default return values rc = 0; retcode = 0; RexxString *name = OREF_NULLSTRING; // name of the invoked program RexxString *fullname = name; // default the fulllength name to the simple name if (programName != NULL) /* have an actual name? */ { /* get string version of the name */ name = new_string(programName); } savedObjects.add(name); /* protect from garbage collect */ // get an array version of the arguments and protect RexxArray *new_arglist = new_array(argcount + 1); // + 1 to store count of named arguments = 0 savedObjects.add(new_arglist); // for compatibility reasons, if this is a command invocation and there is a leading blank // on the only argument, then remove that leading blank from the argument if (calltype == RXCOMMAND && argcount == 1 && arglist[0].strlength > 1 && arglist[0].strptr != NULL && arglist[0].strptr[0] == ' ') { new_arglist->put(new_string(arglist[0].strptr + 1, arglist[0].strlength - 1), 1); } else { /* loop through the argument list */ for (size_t i = 0; i < argcount; i++) { /* have a real argument? */ if (arglist[i].strptr != NULL) { /* add to the argument array */ new_arglist->put(new_string(arglist[i]), i + 1); } } } // Counter of named arguments. To support correctly omitted positional arguments, don't use append! // Omitted positional arguments not applicable here, but better to have the same approach everywhere. // Here, no named arguments : Zero. new_arglist->put(IntegerZero, argcount + 1); RexxString *source_calltype; switch (calltype) /* turn calltype into a string */ { case RXCOMMAND: /* command invocation */ source_calltype = OREF_COMMAND; /* this is the 'COMMAND' string */ break; case RXFUNCTION: /* function invocation */ /* 'FUNCTION' string */ source_calltype = OREF_FUNCTIONNAME; break; case RXSUBROUTINE: /* subroutine invocation */ /* 'SUBROUTINE' string */ source_calltype = OREF_SUBROUTINE; break; default: source_calltype = OREF_COMMAND; /* this is the 'COMMAND' string */ break; } RoutineClass *program = OREF_NULL; if (instore == NULL) /* no instore request? */ { /* go resolve the name */ fullname = activity->resolveProgramName(name, OREF_NULL, OREF_NULL); if (fullname == OREF_NULL) /* not found? */ { /* got an error here */ reportException(Error_Program_unreadable_notfound, name); } savedObjects.add(fullname); /* try to restore saved image */ program = RoutineClass::fromFile(fullname); } else /* have an instore program */ { /* go handle instore parms */ program = RoutineClass::processInstore(instore, name); if (program == OREF_NULL) /* couldn't get it? */ { /* got an error here */ reportException(Error_Program_unreadable_name, name); } } RexxString *initial_address = activity->getInstance()->getDefaultEnvironment(); /* actually need to run this? */ if (program != OREF_NULL) { ProtectedObject program_result; // call the program program->runProgram(activity, source_calltype, initial_address, new_arglist->data(), argcount, program_result); if (result != NULL) /* if return provided for */ { /* actually have a result to return? */ if ((RexxObject *)program_result != OREF_NULL) { /* force to a string value */ program_result = ((RexxObject *)program_result)->stringValue(); // copy this into the result RXSTRING ((RexxString *)program_result)->copyToRxstring(*result); } else /* make this an invalid string */ { MAKERXSTRING(*result, NULL, 0); } } /* If there is a return val... */ if ((RexxObject *)program_result != OREF_NULL) { wholenumber_t return_code; /* if a whole number... */ if (((RexxObject *)program_result)->numberValue(return_code) && return_code <= SHRT_MAX && return_code >= SHRT_MIN) { /* ...copy to return code. */ retcode = (short)return_code; } } } }
/** * Default virtual method for handling a run() methods on * an activity dispatcher. */ void RexxStartDispatcher::run() { ProtectedSet savedObjects; // set default return values rc = 0; retcode = 0; RexxString *name = GlobalNames::NULLSTRING; // name of the invoked program RexxString *fullname = name; // default the fulllength name to the simple name // if we've been given an actual name, get the string version of it if (programName != NULL) { name = new_string(programName); savedObjects.add(name); } // get an array version of the arguments and protect ArrayClass *new_arglist = new_array(argcount); savedObjects.add(new_arglist); // for compatibility reasons, if this is a command invocation and there is a leading blank // on the only argument, then remove that leading blank from the argument if (calltype == RXCOMMAND && argcount == 1 && arglist[0].strlength > 1 && arglist[0].strptr != NULL && arglist[0].strptr[0] == ' ') { new_arglist->put(new_string(arglist[0].strptr + 1, arglist[0].strlength - 1), 1); } // we need to create an array argument list from the RXSTRINGs else { for (size_t i = 0; i < argcount; i++) { // only add real arguments if (arglist[i].strptr != NULL) { new_arglist->put(new_string(arglist[i]), i + 1); } } } RexxString *source_calltype; // now get the calltype as a character string to used in // the source string. . switch (calltype) { case RXCOMMAND: source_calltype = GlobalNames::COMMAND; break; case RXFUNCTION: source_calltype = GlobalNames::FUNCTION; break; case RXSUBROUTINE: source_calltype = GlobalNames::SUBROUTINE; break; // if not specified, call it a COMMAND. default: source_calltype = GlobalNames::COMMAND; break; } Protected<RoutineClass> program; // if not an instore request, we load this from a file. if (instore == NULL) { fullname = activity->resolveProgramName(name, OREF_NULL, OREF_NULL); if (fullname == OREF_NULL) { reportException(Error_Program_unreadable_notfound, name); } savedObjects.add(fullname); program = LanguageParser::createProgramFromFile(fullname); } // we either need to parse the instore source or restore from a // previous image. else { program = LanguageParser::processInstore(instore, name); if (program.isNull()) { reportException(Error_Program_unreadable_name, name); } } RexxString *initial_address = activity->getInstance()->getDefaultEnvironment(); // actually need to run this? if (!program.isNull()) { ProtectedObject program_result; // call the program program->runProgram(activity, source_calltype, initial_address, new_arglist->messageArgs(), argcount, program_result); // provided for a return result (that's optional) if (result != NULL) { // actually have a result to return? if (!program_result.isNull()) { // force to a string value program_result = program_result->stringValue(); // copy this into the result RXSTRING ((RexxString *)program_result)->copyToRxstring(*result); } // nothing to return else { MAKERXSTRING(*result, NULL, 0); } } // if we have a return result and it is an integer value, return that as a return code. if (!program_result.isNull()) { wholenumber_t return_code; if (program_result->numberValue(return_code) && return_code <= SHRT_MAX && return_code >= SHRT_MIN) { retcode = (short)return_code; } } } }