unix/rexx.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 2012-2012 Rexx Language Association. All rights reserved. */
4 /* */
5 /* This program and the accompanying materials are made available under */
6 /* the terms of the Common Public License v1.0 which accompanies this */
7 /* distribution. A copy is also available at the following address: */
8 /* http://www.oorexx.org/license.html */
9 /* */
10 /* Redistribution and use in source and binary forms, with or */
11 /* without modification, are permitted provided that the following */
12 /* conditions are met: */
13 /* */
14 /* Redistributions of source code must retain the above copyright */
15 /* notice, this list of conditions and the following disclaimer. */
16 /* Redistributions in binary form must reproduce the above copyright */
17 /* notice, this list of conditions and the following disclaimer in */
18 /* the documentation and/or other materials provided with the distribution. */
19 /* */
20 /* Neither the name of Rexx Language Association nor the names */
21 /* of its contributors may be used to endorse or promote products */
22 /* derived from this software without specific prior written permission. */
23 /* */
24 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
25 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
26 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
27 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
28 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
29 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
30 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
31 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
32 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
33 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
34 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
35 /* */
36 /*----------------------------------------------------------------------------*/
37 /******************************************************************************/
38 /* */
39 /* main entry point to REXX for LINUX and AIX */
40 /* */
41 /******************************************************************************/
42 
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 
47 #include "oorexxapi.h"
48 
49 #if defined(AIX)
50 #define SYSINITIALADDRESS "ksh"
51 #elif defined(OPSYS_SUN)
52 #define SYSINITIALADDRESS "sh"
53 #else
54 #define SYSINITIALADDRESS "bash"
55 #endif
56 
57 int main (int argc, char **argv) {
58  int i; /* loop counter */
59  int rc = 0; /* actually running program RC */
60  const char *program_name = NULL; /* name to run */
61  char arg_buffer[8192]; /* starting argument buffer */
62  const char *cp; /* option character pointer */
63  CONSTRXSTRING argument; /* rexxstart argument */
64  size_t argCount = 0;
65  char *ptr;
66  short rexxrc = 0; /* exit List array */
67  bool from_string = false; /* running from command line string? */
68  bool real_argument = true; /* running from command line string? */
69  RXSTRING instore[2];
70 
71  RexxInstance *pgmInst;
72  RexxThreadContext *pgmThrdInst;
73  RexxArrayObject rxargs, rxcargs;
75  RexxObjectPtr result;
76 
77  arg_buffer[0] = '\0'; /* default to no argument string */
78  for (i = 1; i < argc; i++) { /* loop through the arguments */
79  /* is this option a switch? */
80  if (program_name == NULL && (*(cp=*(argv+i)) == '-')) {
81  switch (*++cp) {
82  case 'e': case 'E': /* execute from string */
83  from_string = true; /* hit the startup flags */
84  if ( argc == i+1 ) {
85  break;
86  }
87  program_name = "INSTORE";
88  instore[0].strptr = argv[i+1];
89  instore[0].strlength = strlen(instore[0].strptr);
90  instore[1].strptr = NULL;
91  instore[1].strlength = 0;
92  real_argument = false;
93  break;
94 
95  case 'v': case 'V': /* display version string */
97  fprintf(stdout, ptr);
98  fprintf(stdout, "\n");
99  RexxFreeMemory(ptr);
100  return 0;
101 
102  default: /* ignore other switches */
103  break;
104  }
105  } else { /* convert into an argument string */
106  if (program_name == NULL) { /* no name yet? */
107  program_name = argv[i]; /* program is first non-option */
108  } else if (real_argument) {
109  if (arg_buffer[0] != '\0') /* not the first one? */
110  strcat(arg_buffer, " "); /* add an blank */
111  strcat(arg_buffer, argv[i]); /* add this to the arg string */
112  ++argCount;
113  }
114  real_argument = true;
115  }
116  }
117  /* missing a program name? */
118  if (program_name == NULL) {
119  /* give a simple error message */
120  fprintf(stderr,"\n");
121  fprintf(stderr,"Syntax is \"rexx filename [arguments]\"\n");
122  fprintf(stderr,"or \"rexx -e program_string [arguments]\"\n");
123  fprintf(stderr,"or \"rexx -v\".\n");
124  return -1;
125  }
126 
127  argCount = (argCount==0) ? 0 : 1; /* is there an argument ? */
128  /* make an argument */
129  MAKERXSTRING(argument, arg_buffer, strlen(arg_buffer));
130  /* run this via RexxStart */
131 
132  if (from_string) {
133  rc = RexxStart(argCount, /* number of arguments */
134  &argument, /* array of arguments */
135  program_name, /* INSTORE */
136  instore, /* rexx code from -e */
137  SYSINITIALADDRESS,/* command env. name */
138  RXCOMMAND, /* code for how invoked */
139  NULL,
140  &rexxrc, /* REXX program output */
141  NULL); /* REXX program output */
142  }
143  else {
144  RexxCreateInterpreter(&pgmInst, &pgmThrdInst, NULL);
145  // configure the traditional single argument string
146  if (argCount > 0) {
147  rxargs = pgmThrdInst->NewArray(1);
148  pgmThrdInst->ArrayPut(rxargs,
149  pgmThrdInst->NewStringFromAsciiz(arg_buffer), 1);
150  } else {
151  rxargs = pgmThrdInst->NewArray(0);
152  }
153  // set up the C args into the .local environment
154  dir = (RexxDirectoryObject)pgmThrdInst->GetLocalEnvironment();
155  if ( argc > 2 )
156  {
157  rxcargs = pgmThrdInst->NewArray(argc - 2);
158  }
159  else
160  {
161  rxcargs = pgmThrdInst->NewArray(0);
162  }
163  for (i = 2; i < argc; i++) {
164  pgmThrdInst->ArrayPut(rxcargs,
165  pgmThrdInst->NewStringFromAsciiz(argv[i]),
166  i - 1);
167  }
168  pgmThrdInst->DirectoryPut(dir, rxcargs, "SYSCARGS");
169  // call the interpreter
170  result = pgmThrdInst->CallProgram(program_name, rxargs);
171  // display any error message if there is a condition.
172  // if there was an error, then that will be our return code
173  rc = pgmThrdInst->DisplayCondition();
174  if (rc != 0) {
175  pgmInst->Terminate();
176  return -rc; // well, the negation of the error number is the return code
177  }
178  if (result != NULL) {
179  pgmThrdInst->ObjectToInt32(result, &rc);
180  }
181 
182  pgmInst->Terminate();
183 
184  return rc;
185  }
186  return rc ? rc : rexxrc;
187 
188 }
189 
char *REXXENTRY RexxGetVersionInformation()
int REXXENTRY RexxStart(size_t argcount, PCONSTRXSTRING arglist, const char *programname, PRXSTRING instore, const char *envname, int calltype, PRXSYSEXIT exits, short *retcode, PRXSTRING result)
RexxReturnCode RexxEntry RexxCreateInterpreter(RexxInstance **instance, RexxThreadContext **context, RexxOption *options)
RexxReturnCode REXXENTRY RexxFreeMemory(void *)
struct _RexxArrayObject * RexxArrayObject
Definition: rexx.h:130
struct _RexxObjectPtr * RexxObjectPtr
Definition: rexx.h:127
#define MAKERXSTRING(r, p, l)
Definition: rexx.h:182
struct _RexxDirectoryObject * RexxDirectoryObject
Definition: rexx.h:137
#define RXCOMMAND
Definition: rexxapidefs.h:64
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158
int main(int argc, char **argv)
Definition: unix/rexx.cpp:57
#define SYSINITIALADDRESS
Definition: unix/rexx.cpp:54