jruby-launcher 1.1.1-java → 1.1.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +826 -826
- data/Makefile +122 -122
- data/README.md +64 -64
- data/Rakefile +51 -51
- data/argnames.h +35 -35
- data/argparser.cpp +668 -667
- data/argparser.h +78 -78
- data/extconf.rb +7 -7
- data/inc/Makefile-conf.mk +76 -76
- data/inc/Makefile-impl.mk +107 -107
- data/inc/Makefile-rules.mk +40 -40
- data/jruby.cpp +77 -77
- data/jrubyexe.cpp +84 -84
- data/jvmlauncher.cpp +459 -454
- data/jvmlauncher.h +143 -143
- data/lib/jruby-launcher.rb +3 -3
- data/lib/rubygems/defaults/jruby_native.rb +4 -4
- data/nbexecloader.h +43 -43
- data/ng.c +730 -730
- data/platformlauncher.cpp +252 -252
- data/platformlauncher.h +73 -73
- data/rb_w32_cmdvector.h +287 -287
- data/resources/jruby.rc +25 -25
- data/spec/launcher_spec.rb +262 -258
- data/spec/spec_helper.rb +81 -81
- data/strlcpy.c +72 -72
- data/unixlauncher.cpp +100 -100
- data/unixlauncher.h +22 -22
- data/utilsfuncs.cpp +279 -279
- data/utilsfuncs.h +85 -85
- data/utilsfuncswin.cpp +229 -229
- data/version.h +1 -1
- metadata +3 -3
data/platformlauncher.h
CHANGED
@@ -1,73 +1,73 @@
|
|
1
|
-
/*
|
2
|
-
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3
|
-
*
|
4
|
-
* Copyright 2009-2012 JRuby Team (www.jruby.org).
|
5
|
-
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
|
6
|
-
*
|
7
|
-
* The contents of this file are subject to the terms of either the GNU
|
8
|
-
* General Public License Version 2 only ("GPL") or the Common
|
9
|
-
* Development and Distribution License("CDDL") (collectively, the
|
10
|
-
* "License"). You may not use this file except in compliance with the
|
11
|
-
* License. You can obtain a copy of the License at
|
12
|
-
* http://www.netbeans.org/cddl-gplv2.html
|
13
|
-
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
14
|
-
* specific language governing permissions and limitations under the
|
15
|
-
* License. When distributing the software, include this License Header
|
16
|
-
* Notice in each file and include the License file at
|
17
|
-
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
|
18
|
-
* particular file as subject to the "Classpath" exception as provided
|
19
|
-
* by Sun in the GPL Version 2 section of the License file that
|
20
|
-
* accompanied this code. If applicable, add the following below the
|
21
|
-
* License Header, with the fields enclosed by brackets [] replaced by
|
22
|
-
* your own identifying information:
|
23
|
-
* "Portions Copyrighted [year] [name of copyright owner]"
|
24
|
-
*
|
25
|
-
* Contributor(s):
|
26
|
-
*
|
27
|
-
* The Original Software is NetBeans. The Initial Developer of the Original
|
28
|
-
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
|
29
|
-
* Microsystems, Inc. All Rights Reserved.
|
30
|
-
*
|
31
|
-
* If you wish your version of this file to be governed by only the CDDL
|
32
|
-
* or only the GPL Version 2, indicate your decision by adding
|
33
|
-
* "[Contributor] elects to include this software in this distribution
|
34
|
-
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
35
|
-
* single choice of license, a recipient has the option to distribute
|
36
|
-
* your version of this file under either the CDDL, the GPL Version 2 or
|
37
|
-
* to extend the choice of license to its licensees as provided above.
|
38
|
-
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
39
|
-
* Version 2 license, then the option applies only if the new code is
|
40
|
-
* made subject to such option by the copyright holder.
|
41
|
-
*
|
42
|
-
* Author: Tomas Holy
|
43
|
-
*/
|
44
|
-
|
45
|
-
#ifndef _PLATFORMLAUNCHER_H
|
46
|
-
#define _PLATFORMLAUNCHER_H
|
47
|
-
|
48
|
-
#include "jvmlauncher.h"
|
49
|
-
#include "argparser.h"
|
50
|
-
|
51
|
-
class PlatformLauncher : public ArgParser {
|
52
|
-
public:
|
53
|
-
PlatformLauncher();
|
54
|
-
virtual ~PlatformLauncher();
|
55
|
-
|
56
|
-
bool start(char* argv[], int argc, DWORD *retCode, const char *name);
|
57
|
-
void onExit();
|
58
|
-
|
59
|
-
void setSuppressConsole(bool val) {
|
60
|
-
suppressConsole = val;
|
61
|
-
}
|
62
|
-
|
63
|
-
private:
|
64
|
-
PlatformLauncher(const PlatformLauncher& orig);
|
65
|
-
bool run(DWORD *retCode);
|
66
|
-
bool checkJDKHome();
|
67
|
-
|
68
|
-
private:
|
69
|
-
bool suppressConsole;
|
70
|
-
JvmLauncher jvmLauncher;
|
71
|
-
};
|
72
|
-
|
73
|
-
#endif /* _PLATFORMLAUNCHER_H */
|
1
|
+
/*
|
2
|
+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3
|
+
*
|
4
|
+
* Copyright 2009-2012 JRuby Team (www.jruby.org).
|
5
|
+
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
|
6
|
+
*
|
7
|
+
* The contents of this file are subject to the terms of either the GNU
|
8
|
+
* General Public License Version 2 only ("GPL") or the Common
|
9
|
+
* Development and Distribution License("CDDL") (collectively, the
|
10
|
+
* "License"). You may not use this file except in compliance with the
|
11
|
+
* License. You can obtain a copy of the License at
|
12
|
+
* http://www.netbeans.org/cddl-gplv2.html
|
13
|
+
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
14
|
+
* specific language governing permissions and limitations under the
|
15
|
+
* License. When distributing the software, include this License Header
|
16
|
+
* Notice in each file and include the License file at
|
17
|
+
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
|
18
|
+
* particular file as subject to the "Classpath" exception as provided
|
19
|
+
* by Sun in the GPL Version 2 section of the License file that
|
20
|
+
* accompanied this code. If applicable, add the following below the
|
21
|
+
* License Header, with the fields enclosed by brackets [] replaced by
|
22
|
+
* your own identifying information:
|
23
|
+
* "Portions Copyrighted [year] [name of copyright owner]"
|
24
|
+
*
|
25
|
+
* Contributor(s):
|
26
|
+
*
|
27
|
+
* The Original Software is NetBeans. The Initial Developer of the Original
|
28
|
+
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
|
29
|
+
* Microsystems, Inc. All Rights Reserved.
|
30
|
+
*
|
31
|
+
* If you wish your version of this file to be governed by only the CDDL
|
32
|
+
* or only the GPL Version 2, indicate your decision by adding
|
33
|
+
* "[Contributor] elects to include this software in this distribution
|
34
|
+
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
35
|
+
* single choice of license, a recipient has the option to distribute
|
36
|
+
* your version of this file under either the CDDL, the GPL Version 2 or
|
37
|
+
* to extend the choice of license to its licensees as provided above.
|
38
|
+
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
39
|
+
* Version 2 license, then the option applies only if the new code is
|
40
|
+
* made subject to such option by the copyright holder.
|
41
|
+
*
|
42
|
+
* Author: Tomas Holy
|
43
|
+
*/
|
44
|
+
|
45
|
+
#ifndef _PLATFORMLAUNCHER_H
|
46
|
+
#define _PLATFORMLAUNCHER_H
|
47
|
+
|
48
|
+
#include "jvmlauncher.h"
|
49
|
+
#include "argparser.h"
|
50
|
+
|
51
|
+
class PlatformLauncher : public ArgParser {
|
52
|
+
public:
|
53
|
+
PlatformLauncher();
|
54
|
+
virtual ~PlatformLauncher();
|
55
|
+
|
56
|
+
bool start(char* argv[], int argc, DWORD *retCode, const char *name);
|
57
|
+
void onExit();
|
58
|
+
|
59
|
+
void setSuppressConsole(bool val) {
|
60
|
+
suppressConsole = val;
|
61
|
+
}
|
62
|
+
|
63
|
+
private:
|
64
|
+
PlatformLauncher(const PlatformLauncher& orig);
|
65
|
+
bool run(DWORD *retCode);
|
66
|
+
bool checkJDKHome();
|
67
|
+
|
68
|
+
private:
|
69
|
+
bool suppressConsole;
|
70
|
+
JvmLauncher jvmLauncher;
|
71
|
+
};
|
72
|
+
|
73
|
+
#endif /* _PLATFORMLAUNCHER_H */
|
data/rb_w32_cmdvector.h
CHANGED
@@ -1,287 +1,287 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright (c) 1993, Intergraph Corporation
|
3
|
-
*
|
4
|
-
* You may distribute under the terms of either the GNU General Public
|
5
|
-
* License or the Artistic License, as specified in the perl README file.
|
6
|
-
*
|
7
|
-
* Various Unix compatibility functions and NT specific functions.
|
8
|
-
*
|
9
|
-
* Some of this code was derived from the MSDOS port(s) and the OS/2 port.
|
10
|
-
*
|
11
|
-
*/
|
12
|
-
|
13
|
-
#include <windows.h>
|
14
|
-
|
15
|
-
#ifndef _RB_W32_CMDVECTOR_H
|
16
|
-
#define _RB_W32_CMDVECTOR_H
|
17
|
-
|
18
|
-
#ifdef __cplusplus
|
19
|
-
extern "C" {
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#define MAXPATHLEN 512
|
23
|
-
#define NTMALLOC 0x2 // string in element was malloc'ed
|
24
|
-
|
25
|
-
#define isascii(c) ( (c>=0x00&&c<=0x7f)?1:0 )
|
26
|
-
#define isspace(c) ( ((c>=0x09&&c<=0x0d)||c==0x20)?1:0 )
|
27
|
-
#define ISASCII(c) isascii((int)(unsigned char)(c))
|
28
|
-
#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))
|
29
|
-
|
30
|
-
static inline char * skipspace(char *ptr) {
|
31
|
-
while (ISSPACE(*ptr))
|
32
|
-
ptr++;
|
33
|
-
return ptr;
|
34
|
-
}
|
35
|
-
|
36
|
-
typedef struct _NtCmdLineElement {
|
37
|
-
struct _NtCmdLineElement *next;
|
38
|
-
char *str;
|
39
|
-
int len;
|
40
|
-
int flags;
|
41
|
-
} NtCmdLineElement;
|
42
|
-
|
43
|
-
|
44
|
-
int strlcpy(char *dst, const char *src, size_t siz);
|
45
|
-
|
46
|
-
// NOTE: this method is taken from MRI source basically verbatim,
|
47
|
-
// to preserve compatibility
|
48
|
-
int rb_w32_cmdvector(const char *cmd, char ***vec) {
|
49
|
-
int globbing, len;
|
50
|
-
int elements, strsz, done;
|
51
|
-
int slashes, escape;
|
52
|
-
char *ptr, *base, *buffer, *cmdline;
|
53
|
-
char **vptr;
|
54
|
-
char quote;
|
55
|
-
NtCmdLineElement *curr, **tail;
|
56
|
-
NtCmdLineElement *cmdhead = NULL, **cmdtail = &cmdhead;
|
57
|
-
|
58
|
-
//
|
59
|
-
// just return if we don't have a command line
|
60
|
-
//
|
61
|
-
|
62
|
-
while (ISSPACE(*cmd))
|
63
|
-
cmd++;
|
64
|
-
if (!*cmd) {
|
65
|
-
*vec = NULL;
|
66
|
-
return 0;
|
67
|
-
}
|
68
|
-
|
69
|
-
ptr = cmdline = strdup(cmd);
|
70
|
-
|
71
|
-
//
|
72
|
-
// Ok, parse the command line, building a list of CmdLineElements.
|
73
|
-
// When we've finished, and it's an input command (meaning that it's
|
74
|
-
// the processes argv), we'll do globing and then build the argument
|
75
|
-
// vector.
|
76
|
-
// The outer loop does one interation for each element seen.
|
77
|
-
// The inner loop does one interation for each character in the element.
|
78
|
-
//
|
79
|
-
|
80
|
-
while (*(ptr = skipspace(ptr))) {
|
81
|
-
base = ptr;
|
82
|
-
quote = slashes = globbing = escape = 0;
|
83
|
-
for (done = 0; !done && *ptr; ) {
|
84
|
-
//
|
85
|
-
// Switch on the current character. We only care about the
|
86
|
-
// white-space characters, the wild-card characters, and the
|
87
|
-
// quote characters.
|
88
|
-
//
|
89
|
-
|
90
|
-
switch (*ptr) {
|
91
|
-
case '\\':
|
92
|
-
if (quote != '\'') slashes++;
|
93
|
-
break;
|
94
|
-
|
95
|
-
case ' ':
|
96
|
-
case '\t':
|
97
|
-
case '\n':
|
98
|
-
//
|
99
|
-
// if we're not in a string, then we're finished with this
|
100
|
-
// element
|
101
|
-
//
|
102
|
-
|
103
|
-
if (!quote) {
|
104
|
-
*ptr = 0;
|
105
|
-
done = 1;
|
106
|
-
}
|
107
|
-
break;
|
108
|
-
|
109
|
-
case '*':
|
110
|
-
case '?':
|
111
|
-
case '[':
|
112
|
-
case '{':
|
113
|
-
//
|
114
|
-
// record the fact that this element has a wildcard character
|
115
|
-
// N.B. Don't glob if inside a single quoted string
|
116
|
-
//
|
117
|
-
|
118
|
-
if (quote != '\'')
|
119
|
-
globbing++;
|
120
|
-
slashes = 0;
|
121
|
-
break;
|
122
|
-
|
123
|
-
case '\'':
|
124
|
-
case '\"':
|
125
|
-
//
|
126
|
-
// if we're already in a string, see if this is the
|
127
|
-
// terminating close-quote. If it is, we're finished with
|
128
|
-
// the string, but not neccessarily with the element.
|
129
|
-
// If we're not already in a string, start one.
|
130
|
-
//
|
131
|
-
|
132
|
-
if (!(slashes & 1)) {
|
133
|
-
if (!quote)
|
134
|
-
quote = *ptr;
|
135
|
-
else if (quote == *ptr) {
|
136
|
-
if (quote == '"' && quote == ptr[1])
|
137
|
-
ptr++;
|
138
|
-
quote = '\0';
|
139
|
-
}
|
140
|
-
}
|
141
|
-
escape++;
|
142
|
-
slashes = 0;
|
143
|
-
break;
|
144
|
-
|
145
|
-
default:
|
146
|
-
ptr = CharNext(ptr);
|
147
|
-
slashes = 0;
|
148
|
-
continue;
|
149
|
-
}
|
150
|
-
ptr++;
|
151
|
-
}
|
152
|
-
|
153
|
-
//
|
154
|
-
// when we get here, we've got a pair of pointers to the element,
|
155
|
-
// base and ptr. Base points to the start of the element while ptr
|
156
|
-
// points to the character following the element.
|
157
|
-
//
|
158
|
-
|
159
|
-
len = ptr - base;
|
160
|
-
if (done) --len;
|
161
|
-
|
162
|
-
//
|
163
|
-
// if it's an input vector element and it's enclosed by quotes,
|
164
|
-
// we can remove them.
|
165
|
-
//
|
166
|
-
|
167
|
-
if (escape) {
|
168
|
-
char *p = base, c;
|
169
|
-
slashes = quote = 0;
|
170
|
-
while (p < base + len) {
|
171
|
-
switch (c = *p) {
|
172
|
-
case '\\':
|
173
|
-
p++;
|
174
|
-
if (quote != '\'') slashes++;
|
175
|
-
break;
|
176
|
-
|
177
|
-
case '\'':
|
178
|
-
case '"':
|
179
|
-
if (!(slashes & 1) && quote && quote != c) {
|
180
|
-
p++;
|
181
|
-
slashes = 0;
|
182
|
-
break;
|
183
|
-
}
|
184
|
-
memcpy(p - ((slashes + 1) >> 1), p + (~slashes & 1),
|
185
|
-
base + len - p);
|
186
|
-
len -= ((slashes + 1) >> 1) + (~slashes & 1);
|
187
|
-
p -= (slashes + 1) >> 1;
|
188
|
-
if (!(slashes & 1)) {
|
189
|
-
if (quote) {
|
190
|
-
if (quote == '"' && quote == *p)
|
191
|
-
p++;
|
192
|
-
quote = '\0';
|
193
|
-
}
|
194
|
-
else
|
195
|
-
quote = c;
|
196
|
-
}
|
197
|
-
else
|
198
|
-
p++;
|
199
|
-
slashes = 0;
|
200
|
-
break;
|
201
|
-
|
202
|
-
default:
|
203
|
-
p = CharNext(p);
|
204
|
-
slashes = 0;
|
205
|
-
break;
|
206
|
-
}
|
207
|
-
}
|
208
|
-
}
|
209
|
-
|
210
|
-
curr = (NtCmdLineElement *)calloc(sizeof(NtCmdLineElement), 1);
|
211
|
-
if (!curr) goto do_nothing;
|
212
|
-
curr->str = base;
|
213
|
-
curr->len = len;
|
214
|
-
|
215
|
-
// TODO: globbing!
|
216
|
-
// if (globbing && (tail = cmdglob(curr, cmdtail))) {
|
217
|
-
// cmdtail = tail;
|
218
|
-
// }
|
219
|
-
// else {
|
220
|
-
*cmdtail = curr;
|
221
|
-
cmdtail = &curr->next;
|
222
|
-
// }
|
223
|
-
}
|
224
|
-
|
225
|
-
//
|
226
|
-
// Almost done!
|
227
|
-
// Count up the elements, then allocate space for a vector of pointers
|
228
|
-
// (argv) and a string table for the elements.
|
229
|
-
//
|
230
|
-
|
231
|
-
for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->next) {
|
232
|
-
elements++;
|
233
|
-
strsz += (curr->len + 1);
|
234
|
-
}
|
235
|
-
|
236
|
-
len = (elements+1)*sizeof(char *) + strsz;
|
237
|
-
buffer = (char *)malloc(len);
|
238
|
-
if (!buffer) {
|
239
|
-
do_nothing:
|
240
|
-
while (curr = cmdhead) {
|
241
|
-
cmdhead = curr->next;
|
242
|
-
if (curr->flags & NTMALLOC) free(curr->str);
|
243
|
-
free(curr);
|
244
|
-
}
|
245
|
-
free(cmdline);
|
246
|
-
for (vptr = *vec; *vptr; ++vptr);
|
247
|
-
return vptr - *vec;
|
248
|
-
}
|
249
|
-
|
250
|
-
//
|
251
|
-
// make vptr point to the start of the buffer
|
252
|
-
// and ptr point to the area we'll consider the string table.
|
253
|
-
//
|
254
|
-
// buffer (*vec)
|
255
|
-
// |
|
256
|
-
// V ^---------------------V
|
257
|
-
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
258
|
-
// | | | .... | NULL | | ..... |\0 | | ..... |\0 |...
|
259
|
-
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
260
|
-
// |- elements+1 -| ^ 1st element ^ 2nd element
|
261
|
-
|
262
|
-
vptr = (char **) buffer;
|
263
|
-
|
264
|
-
ptr = buffer + (elements+1) * sizeof(char *);
|
265
|
-
|
266
|
-
while (curr = cmdhead) {
|
267
|
-
strlcpy(ptr, curr->str, curr->len + 1);
|
268
|
-
*vptr++ = ptr;
|
269
|
-
ptr += curr->len + 1;
|
270
|
-
cmdhead = curr->next;
|
271
|
-
if (curr->flags & NTMALLOC) free(curr->str);
|
272
|
-
free(curr);
|
273
|
-
}
|
274
|
-
*vptr = 0;
|
275
|
-
|
276
|
-
*vec = (char **) buffer;
|
277
|
-
free(cmdline);
|
278
|
-
return elements;
|
279
|
-
}
|
280
|
-
|
281
|
-
|
282
|
-
#ifdef __cplusplus
|
283
|
-
}
|
284
|
-
#endif
|
285
|
-
|
286
|
-
#endif /* _RB_W32_CMDVECTOR_H */
|
287
|
-
|
1
|
+
/*
|
2
|
+
* Copyright (c) 1993, Intergraph Corporation
|
3
|
+
*
|
4
|
+
* You may distribute under the terms of either the GNU General Public
|
5
|
+
* License or the Artistic License, as specified in the perl README file.
|
6
|
+
*
|
7
|
+
* Various Unix compatibility functions and NT specific functions.
|
8
|
+
*
|
9
|
+
* Some of this code was derived from the MSDOS port(s) and the OS/2 port.
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
|
13
|
+
#include <windows.h>
|
14
|
+
|
15
|
+
#ifndef _RB_W32_CMDVECTOR_H
|
16
|
+
#define _RB_W32_CMDVECTOR_H
|
17
|
+
|
18
|
+
#ifdef __cplusplus
|
19
|
+
extern "C" {
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#define MAXPATHLEN 512
|
23
|
+
#define NTMALLOC 0x2 // string in element was malloc'ed
|
24
|
+
|
25
|
+
#define isascii(c) ( (c>=0x00&&c<=0x7f)?1:0 )
|
26
|
+
#define isspace(c) ( ((c>=0x09&&c<=0x0d)||c==0x20)?1:0 )
|
27
|
+
#define ISASCII(c) isascii((int)(unsigned char)(c))
|
28
|
+
#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))
|
29
|
+
|
30
|
+
static inline char * skipspace(char *ptr) {
|
31
|
+
while (ISSPACE(*ptr))
|
32
|
+
ptr++;
|
33
|
+
return ptr;
|
34
|
+
}
|
35
|
+
|
36
|
+
typedef struct _NtCmdLineElement {
|
37
|
+
struct _NtCmdLineElement *next;
|
38
|
+
char *str;
|
39
|
+
int len;
|
40
|
+
int flags;
|
41
|
+
} NtCmdLineElement;
|
42
|
+
|
43
|
+
|
44
|
+
int strlcpy(char *dst, const char *src, size_t siz);
|
45
|
+
|
46
|
+
// NOTE: this method is taken from MRI source basically verbatim,
|
47
|
+
// to preserve compatibility
|
48
|
+
int rb_w32_cmdvector(const char *cmd, char ***vec) {
|
49
|
+
int globbing, len;
|
50
|
+
int elements, strsz, done;
|
51
|
+
int slashes, escape;
|
52
|
+
char *ptr, *base, *buffer, *cmdline;
|
53
|
+
char **vptr;
|
54
|
+
char quote;
|
55
|
+
NtCmdLineElement *curr, **tail;
|
56
|
+
NtCmdLineElement *cmdhead = NULL, **cmdtail = &cmdhead;
|
57
|
+
|
58
|
+
//
|
59
|
+
// just return if we don't have a command line
|
60
|
+
//
|
61
|
+
|
62
|
+
while (ISSPACE(*cmd))
|
63
|
+
cmd++;
|
64
|
+
if (!*cmd) {
|
65
|
+
*vec = NULL;
|
66
|
+
return 0;
|
67
|
+
}
|
68
|
+
|
69
|
+
ptr = cmdline = strdup(cmd);
|
70
|
+
|
71
|
+
//
|
72
|
+
// Ok, parse the command line, building a list of CmdLineElements.
|
73
|
+
// When we've finished, and it's an input command (meaning that it's
|
74
|
+
// the processes argv), we'll do globing and then build the argument
|
75
|
+
// vector.
|
76
|
+
// The outer loop does one interation for each element seen.
|
77
|
+
// The inner loop does one interation for each character in the element.
|
78
|
+
//
|
79
|
+
|
80
|
+
while (*(ptr = skipspace(ptr))) {
|
81
|
+
base = ptr;
|
82
|
+
quote = slashes = globbing = escape = 0;
|
83
|
+
for (done = 0; !done && *ptr; ) {
|
84
|
+
//
|
85
|
+
// Switch on the current character. We only care about the
|
86
|
+
// white-space characters, the wild-card characters, and the
|
87
|
+
// quote characters.
|
88
|
+
//
|
89
|
+
|
90
|
+
switch (*ptr) {
|
91
|
+
case '\\':
|
92
|
+
if (quote != '\'') slashes++;
|
93
|
+
break;
|
94
|
+
|
95
|
+
case ' ':
|
96
|
+
case '\t':
|
97
|
+
case '\n':
|
98
|
+
//
|
99
|
+
// if we're not in a string, then we're finished with this
|
100
|
+
// element
|
101
|
+
//
|
102
|
+
|
103
|
+
if (!quote) {
|
104
|
+
*ptr = 0;
|
105
|
+
done = 1;
|
106
|
+
}
|
107
|
+
break;
|
108
|
+
|
109
|
+
case '*':
|
110
|
+
case '?':
|
111
|
+
case '[':
|
112
|
+
case '{':
|
113
|
+
//
|
114
|
+
// record the fact that this element has a wildcard character
|
115
|
+
// N.B. Don't glob if inside a single quoted string
|
116
|
+
//
|
117
|
+
|
118
|
+
if (quote != '\'')
|
119
|
+
globbing++;
|
120
|
+
slashes = 0;
|
121
|
+
break;
|
122
|
+
|
123
|
+
case '\'':
|
124
|
+
case '\"':
|
125
|
+
//
|
126
|
+
// if we're already in a string, see if this is the
|
127
|
+
// terminating close-quote. If it is, we're finished with
|
128
|
+
// the string, but not neccessarily with the element.
|
129
|
+
// If we're not already in a string, start one.
|
130
|
+
//
|
131
|
+
|
132
|
+
if (!(slashes & 1)) {
|
133
|
+
if (!quote)
|
134
|
+
quote = *ptr;
|
135
|
+
else if (quote == *ptr) {
|
136
|
+
if (quote == '"' && quote == ptr[1])
|
137
|
+
ptr++;
|
138
|
+
quote = '\0';
|
139
|
+
}
|
140
|
+
}
|
141
|
+
escape++;
|
142
|
+
slashes = 0;
|
143
|
+
break;
|
144
|
+
|
145
|
+
default:
|
146
|
+
ptr = CharNext(ptr);
|
147
|
+
slashes = 0;
|
148
|
+
continue;
|
149
|
+
}
|
150
|
+
ptr++;
|
151
|
+
}
|
152
|
+
|
153
|
+
//
|
154
|
+
// when we get here, we've got a pair of pointers to the element,
|
155
|
+
// base and ptr. Base points to the start of the element while ptr
|
156
|
+
// points to the character following the element.
|
157
|
+
//
|
158
|
+
|
159
|
+
len = ptr - base;
|
160
|
+
if (done) --len;
|
161
|
+
|
162
|
+
//
|
163
|
+
// if it's an input vector element and it's enclosed by quotes,
|
164
|
+
// we can remove them.
|
165
|
+
//
|
166
|
+
|
167
|
+
if (escape) {
|
168
|
+
char *p = base, c;
|
169
|
+
slashes = quote = 0;
|
170
|
+
while (p < base + len) {
|
171
|
+
switch (c = *p) {
|
172
|
+
case '\\':
|
173
|
+
p++;
|
174
|
+
if (quote != '\'') slashes++;
|
175
|
+
break;
|
176
|
+
|
177
|
+
case '\'':
|
178
|
+
case '"':
|
179
|
+
if (!(slashes & 1) && quote && quote != c) {
|
180
|
+
p++;
|
181
|
+
slashes = 0;
|
182
|
+
break;
|
183
|
+
}
|
184
|
+
memcpy(p - ((slashes + 1) >> 1), p + (~slashes & 1),
|
185
|
+
base + len - p);
|
186
|
+
len -= ((slashes + 1) >> 1) + (~slashes & 1);
|
187
|
+
p -= (slashes + 1) >> 1;
|
188
|
+
if (!(slashes & 1)) {
|
189
|
+
if (quote) {
|
190
|
+
if (quote == '"' && quote == *p)
|
191
|
+
p++;
|
192
|
+
quote = '\0';
|
193
|
+
}
|
194
|
+
else
|
195
|
+
quote = c;
|
196
|
+
}
|
197
|
+
else
|
198
|
+
p++;
|
199
|
+
slashes = 0;
|
200
|
+
break;
|
201
|
+
|
202
|
+
default:
|
203
|
+
p = CharNext(p);
|
204
|
+
slashes = 0;
|
205
|
+
break;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
curr = (NtCmdLineElement *)calloc(sizeof(NtCmdLineElement), 1);
|
211
|
+
if (!curr) goto do_nothing;
|
212
|
+
curr->str = base;
|
213
|
+
curr->len = len;
|
214
|
+
|
215
|
+
// TODO: globbing!
|
216
|
+
// if (globbing && (tail = cmdglob(curr, cmdtail))) {
|
217
|
+
// cmdtail = tail;
|
218
|
+
// }
|
219
|
+
// else {
|
220
|
+
*cmdtail = curr;
|
221
|
+
cmdtail = &curr->next;
|
222
|
+
// }
|
223
|
+
}
|
224
|
+
|
225
|
+
//
|
226
|
+
// Almost done!
|
227
|
+
// Count up the elements, then allocate space for a vector of pointers
|
228
|
+
// (argv) and a string table for the elements.
|
229
|
+
//
|
230
|
+
|
231
|
+
for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->next) {
|
232
|
+
elements++;
|
233
|
+
strsz += (curr->len + 1);
|
234
|
+
}
|
235
|
+
|
236
|
+
len = (elements+1)*sizeof(char *) + strsz;
|
237
|
+
buffer = (char *)malloc(len);
|
238
|
+
if (!buffer) {
|
239
|
+
do_nothing:
|
240
|
+
while (curr = cmdhead) {
|
241
|
+
cmdhead = curr->next;
|
242
|
+
if (curr->flags & NTMALLOC) free(curr->str);
|
243
|
+
free(curr);
|
244
|
+
}
|
245
|
+
free(cmdline);
|
246
|
+
for (vptr = *vec; *vptr; ++vptr);
|
247
|
+
return vptr - *vec;
|
248
|
+
}
|
249
|
+
|
250
|
+
//
|
251
|
+
// make vptr point to the start of the buffer
|
252
|
+
// and ptr point to the area we'll consider the string table.
|
253
|
+
//
|
254
|
+
// buffer (*vec)
|
255
|
+
// |
|
256
|
+
// V ^---------------------V
|
257
|
+
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
258
|
+
// | | | .... | NULL | | ..... |\0 | | ..... |\0 |...
|
259
|
+
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
260
|
+
// |- elements+1 -| ^ 1st element ^ 2nd element
|
261
|
+
|
262
|
+
vptr = (char **) buffer;
|
263
|
+
|
264
|
+
ptr = buffer + (elements+1) * sizeof(char *);
|
265
|
+
|
266
|
+
while (curr = cmdhead) {
|
267
|
+
strlcpy(ptr, curr->str, curr->len + 1);
|
268
|
+
*vptr++ = ptr;
|
269
|
+
ptr += curr->len + 1;
|
270
|
+
cmdhead = curr->next;
|
271
|
+
if (curr->flags & NTMALLOC) free(curr->str);
|
272
|
+
free(curr);
|
273
|
+
}
|
274
|
+
*vptr = 0;
|
275
|
+
|
276
|
+
*vec = (char **) buffer;
|
277
|
+
free(cmdline);
|
278
|
+
return elements;
|
279
|
+
}
|
280
|
+
|
281
|
+
|
282
|
+
#ifdef __cplusplus
|
283
|
+
}
|
284
|
+
#endif
|
285
|
+
|
286
|
+
#endif /* _RB_W32_CMDVECTOR_H */
|
287
|
+
|