ArgumentParser.h
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 
39 const char *nextArgument(BOOL getprog, const char *argptr, PULONG ndx, PULONG len, BOOL allocate)
40 {
41  PCHAR ret;
42  if (argptr[*ndx] == ' ') /* skip blanks of previous argument */
43  {
44  while ((argptr[*ndx] == ' ') && argptr[*ndx])
45  {
46  (*ndx)++;
47  }
48  }
49  *len = 0;
50  const char *tmp = &argptr[*ndx];
51 
52  if (!allocate)
53  {
54  while ((argptr[*ndx] != ' ') && argptr[*ndx])
55  {
56  if (argptr[*ndx] == '\"') do
57  {
58  if (argptr[*ndx] != '\"')
59  {
60  (*len)++;
61  }
62  (*ndx)++;
63  } while ((argptr[*ndx] != '\"') && argptr[*ndx]);
64  if (argptr[*ndx])
65  {
66  if (argptr[*ndx] != '\"')
67  {
68  (*len)++;
69  }
70  (*ndx)++;
71  }
72  }
73  }
74  /* get the program name for REXXHIDE */
75  else if (getprog)
76  {
77  if (argptr[*ndx] == '\"')
78  do
79  {
80  (*len)++;
81  (*ndx)++;
82  } while ((argptr[*ndx] != '\"') && argptr[*ndx]);
83  while (argptr[*ndx] && (argptr[*ndx] != ' '))
84  {
85  (*len)++;
86  (*ndx)++;
87  }
88  }
89  else
90  {
91  while (argptr[*ndx])
92  {
93  (*len)++;
94  (*ndx)++;
95  }
96  }
97 
98  if (*len)
99  {
100  if (allocate)
101  {
102  /* program name must not be enclosed within "" for REXXHIDE */
103  if (getprog && (tmp[0] == '\"'))
104  {
105  tmp++;(*len)-=2;
106  };
107 
108  ret = (PCHAR) GlobalAlloc(GMEM_FIXED, (*len)+1);
109  memcpy(ret, tmp, (*len)+1);
110  if (getprog)
111  {
112  ret[*len]='\0';
113  }
114  return ret;
115  }
116  else
117  {
118  return tmp;
119  }
120  }
121  else
122  {
123  return NULL;
124  }
125 }
126 
127 
128 
129 PCONSTRXSTRING getArguments(const char **program, const char *argptr, size_t *count, PCONSTRXSTRING retarr)
130 {
131  ULONG i, isave, len;
132  /* don't forget the break after program_name */
133 
134  i = 0;
135  if (program)
136  {
137  (*program) = nextArgument(TRUE, argptr, &i, &len, TRUE); /* for REXXHIDE script is first argument */
138  }
139  else {
140  nextArgument(FALSE, argptr, &i, &len, FALSE); /* skip REXX*.EXE */
141  const char *tmp = nextArgument(FALSE, argptr, &i, &len, FALSE); /* skip REXX script or -e switch */
142  /* the following test ensure that the -e switch on rexx.exe is not included in the arguments */
143  /* passed to the running program as specified on the command line. Unfortunately it also */
144  /* affects rexxhide, rexxpaws, etc, that all use this code; may not be important */
145  if (tmp && strlen(tmp) > 1 && (tmp[0] == '/' || tmp[0] == '-') && (tmp[1] == 'e' || tmp[1] == 'E') )
146  {
147  nextArgument(FALSE, argptr, &i, &len, FALSE); /* skip REXX code*/
148  }
149  }
150 
151  retarr->strptr = NULL;
152  isave = i;
153  *count = 0;
154  if (nextArgument(FALSE, argptr, &i, &len, FALSE))
155  {
156  (*count)++;
157  }
158 
159  if (*count)
160  {
161  i = isave;
162  retarr->strptr = nextArgument(FALSE, argptr, &i, &len, TRUE);
163  retarr->strlength = len;
164  }
165  return retarr;
166 }
167 
168 
169 void freeArguments(const char *program, PCONSTRXSTRING arguments)
170 {
171  if (arguments->strptr) GlobalFree((HGLOBAL)arguments->strptr);
172  if (program) GlobalFree((HGLOBAL)program);
173 }
174 
175 // Utility to parse out a command line string into the unix-style
176 // argv/argc format. Used for setting the array of arguments
177 // in .local
178 
179 PCHAR* CommandLineToArgvA(PCHAR CmdLine, int32_t* _argc)
180 {
181  char **argv;
182  char *_argv;
183  size_t len;
184  int32_t argc;
185  char a;
186  size_t i, j;
187 
188  BOOLEAN in_QM;
189  BOOLEAN in_TEXT;
190  BOOLEAN in_SPACE;
191 
192  len = strlen(CmdLine);
193  i = ((len+2)/2)*sizeof(void *) + sizeof(void *);
194 
195  argv = (char**)GlobalAlloc(GMEM_FIXED,
196  i + (len+2)*sizeof(char));
197 
198  _argv = (PCHAR)(((PUCHAR)argv)+i);
199 
200  argc = 0;
201  argv[argc] = _argv;
202  in_QM = FALSE;
203  in_TEXT = FALSE;
204  in_SPACE = TRUE;
205  i = 0;
206  j = 0;
207 
208  while ( a = CmdLine[i] )
209  {
210  if (in_QM)
211  {
212  if (a == '\"')
213  {
214  in_QM = FALSE;
215  }
216  else
217  {
218  _argv[j] = a;
219  j++;
220  }
221  }
222  else
223  {
224  switch (a)
225  {
226  case '\"':
227  in_QM = TRUE;
228  in_TEXT = TRUE;
229  if (in_SPACE)
230  {
231  argv[argc] = _argv+j;
232  argc++;
233  }
234  in_SPACE = FALSE;
235  break;
236  case ' ':
237  case '\t':
238  case '\n':
239  case '\r':
240  if (in_TEXT)
241  {
242  _argv[j] = '\0';
243  j++;
244  }
245  in_TEXT = FALSE;
246  in_SPACE = TRUE;
247  break;
248  default:
249  in_TEXT = TRUE;
250  if (in_SPACE)
251  {
252  argv[argc] = _argv+j;
253  argc++;
254  }
255  _argv[j] = a;
256  j++;
257  in_SPACE = FALSE;
258  break;
259  }
260  }
261  i++;
262  }
263  _argv[j] = '\0';
264  argv[argc] = NULL;
265 
266  (*_argc) = argc;
267  return argv;
268 }
PCONSTRXSTRING getArguments(const char **program, const char *argptr, size_t *count, PCONSTRXSTRING retarr)
PCHAR * CommandLineToArgvA(PCHAR CmdLine, int32_t *_argc)
void freeArguments(const char *program, PCONSTRXSTRING arguments)
const char * nextArgument(BOOL getprog, const char *argptr, PULONG ndx, PULONG len, BOOL allocate)
CONSTANT_RXSTRING * PCONSTRXSTRING
Definition: rexx.h:186
int int32_t