Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/bin/cmdtoargs.c
32285 views
1
/*
2
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
27
/*
28
* Converts a single string command line to the traditional argc, argv.
29
* There are rules which govern the breaking of the the arguments, and
30
* these rules are embodied in the regression tests below, and duplicated
31
* in the jdk regression tests.
32
*/
33
34
#ifndef IDE_STANDALONE
35
#include "java.h"
36
#include "jli_util.h"
37
#else /* IDE_STANDALONE */
38
// The defines we need for stand alone testing
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <Windows.h>
42
#define JNI_TRUE TRUE
43
#define JNI_FALSE FALSE
44
#define JLI_MemRealloc realloc
45
#define JLI_StringDup _strdup
46
#define JLI_MemFree free
47
#define jboolean boolean
48
typedef struct {
49
char* arg;
50
boolean has_wildcard;
51
} StdArg ;
52
#endif
53
static StdArg *stdargs;
54
static int stdargc;
55
56
static int copyCh(USHORT ch, char* dest) {
57
if (HIBYTE(ch) == 0) {
58
*dest = (char)ch;
59
return 1;
60
} else {
61
*((USHORT *)dest) = ch;
62
return 2;
63
}
64
}
65
66
static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) {
67
68
char* src = cmdline;
69
char* dest = arg;
70
jboolean separator = JNI_FALSE;
71
int quotes = 0;
72
int slashes = 0;
73
74
// "prev"/"ch" may contain either a single byte, or a double byte
75
// character encoded in CP_ACP.
76
USHORT prev = 0;
77
USHORT ch = 0;
78
int i;
79
jboolean done = JNI_FALSE;
80
int charLength;
81
82
*wildcard = JNI_FALSE;
83
while (!done) {
84
charLength = CharNextExA(CP_ACP, src, 0) - src;
85
if (charLength == 0) {
86
break;
87
} else if (charLength == 1) {
88
ch = (USHORT)(UCHAR)src[0];
89
} else {
90
ch = ((USHORT *)src)[0];
91
}
92
93
switch (ch) {
94
case L'"':
95
if (separator) {
96
done = JNI_TRUE;
97
break;
98
}
99
if (prev == L'\\') {
100
for (i = 1; i < slashes; i += 2) {
101
dest += copyCh(prev, dest);
102
}
103
if (slashes % 2 == 1) {
104
dest += copyCh(ch, dest);
105
} else {
106
quotes++;
107
}
108
} else if (prev == L'"' && quotes % 2 == 0) {
109
quotes++;
110
dest += copyCh(ch, dest); // emit every other consecutive quote
111
} else if (quotes == 0) {
112
quotes++; // starting quote
113
} else {
114
quotes--; // matching quote
115
}
116
slashes = 0;
117
break;
118
119
case L'\\':
120
slashes++;
121
if (separator) {
122
done = JNI_TRUE;
123
separator = JNI_FALSE;
124
}
125
break;
126
127
case L' ':
128
case L'\t':
129
if (prev == L'\\') {
130
for (i = 0 ; i < slashes; i++) {
131
dest += copyCh(prev, dest);
132
}
133
}
134
if (quotes % 2 == 1) {
135
dest += copyCh(ch, dest);
136
} else {
137
separator = JNI_TRUE;
138
}
139
slashes = 0;
140
break;
141
142
case L'*':
143
case L'?':
144
if (separator) {
145
done = JNI_TRUE;
146
separator = JNI_FALSE;
147
break;
148
}
149
if (quotes % 2 == 0) {
150
*wildcard = JNI_TRUE;
151
}
152
if (prev == L'\\') {
153
for (i = 0 ; i < slashes ; i++) {
154
dest += copyCh(prev, dest);
155
}
156
}
157
dest += copyCh(ch, dest);
158
slashes = 0;
159
break;
160
161
default:
162
if (prev == L'\\') {
163
for (i = 0 ; i < slashes ; i++) {
164
dest += copyCh(prev, dest);
165
}
166
dest += copyCh(ch, dest);
167
} else if (separator) {
168
done = JNI_TRUE;
169
} else {
170
dest += copyCh(ch, dest);
171
}
172
slashes = 0;
173
}
174
175
if (!done) {
176
prev = ch;
177
src += charLength;
178
}
179
}
180
if (prev == L'\\') {
181
for (i = 0; i < slashes; i++) {
182
dest += copyCh(prev, dest);
183
}
184
}
185
*dest = 0;
186
return done ? src : NULL;
187
}
188
189
int JLI_GetStdArgc() {
190
return stdargc;
191
}
192
193
StdArg* JLI_GetStdArgs() {
194
return stdargs;
195
}
196
197
void JLI_CmdToArgs(char* cmdline) {
198
int nargs = 0;
199
StdArg* argv = NULL;
200
jboolean wildcard = JNI_FALSE;
201
char* src = cmdline;
202
203
// allocate arg buffer with sufficient space to receive the largest arg
204
char* arg = JLI_StringDup(cmdline);
205
206
do {
207
src = next_arg(src, arg, &wildcard);
208
// resize to accommodate another Arg
209
argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg));
210
argv[nargs].arg = JLI_StringDup(arg);
211
argv[nargs].has_wildcard = wildcard;
212
*arg = NULL;
213
nargs++;
214
} while (src != NULL);
215
216
stdargc = nargs;
217
stdargs = argv;
218
}
219
220
#ifdef IDE_STANDALONE
221
void doexit(int rv) {
222
printf("Hit any key to quit\n");
223
int c = getchar();
224
exit(rv);
225
}
226
227
void doabort() {
228
doexit(1);
229
}
230
231
class Vector {
232
public:
233
char* cmdline;
234
int argc;
235
char* argv[10];
236
boolean wildcard[10];
237
boolean enabled;
238
239
Vector(){}
240
// Initialize our test vector with the program name, argv[0]
241
// and the single string command line.
242
Vector(char* pname, char* cline) {
243
argv[0] = pname;
244
wildcard[0] = FALSE;
245
cmdline = cline;
246
argc = 1;
247
enabled = TRUE;
248
}
249
250
// add our expected strings, the program name has already been
251
// added so ignore that
252
void add(char* arg, boolean w) {
253
argv[argc] = arg;
254
wildcard[argc] = w;
255
argc++;
256
}
257
258
void disable() {
259
enabled = FALSE;
260
}
261
262
// validate the returned arguments with the expected arguments, using the
263
// new CmdToArgs method.
264
bool check() {
265
// "pgmname" rest of cmdline ie. pgmname + 2 double quotes + space + cmdline from windows
266
char* cptr = (char*) malloc(strlen(argv[0]) + sizeof(char) * 3 + strlen(cmdline) + 1);
267
_snprintf(cptr, MAX_PATH, "\"%s\" %s", argv[0], cmdline);
268
JLI_CmdToArgs(cptr);
269
free(cptr);
270
StdArg *kargv = JLI_GetStdArgs();
271
int kargc = JLI_GetStdArgc();
272
bool retval = true;
273
printf("\n===========================\n");
274
printf("cmdline=%s\n", cmdline);
275
if (argc != kargc) {
276
printf("*** argument count does not match\n");
277
printme();
278
printtest(kargc, kargv);
279
doabort();
280
}
281
for (int i = 0 ; i < argc && retval == true ; i++) {
282
if (strcmp(argv[i], kargv[i].arg) != 0) {
283
printf("*** argument at [%d] don't match\n got: %s\n exp: %s\n",
284
i, kargv[i].arg, argv[i]);
285
doabort();
286
}
287
}
288
for (int i = 0 ; i < argc && retval == true ; i++) {
289
if (wildcard[i] != kargv[i].has_wildcard) {
290
printf("*** expansion flag at [%d] doesn't match\n got: %d\n exp: %d\n",
291
i, kargv[i].has_wildcard, wildcard[i]);
292
doabort();
293
}
294
}
295
for (int i = 0 ; i < kargc ; i++) {
296
printf("k[%d]=%s\n", i, kargv[i].arg);
297
printf(" [%d]=%s\n", i, argv[i]);
298
}
299
return retval;
300
}
301
void printtest(int kargc, StdArg* kargv) {
302
for (int i = 0 ; i < kargc ; i++) {
303
printf("k[%d]=%s\n", i, kargv[i].arg);
304
}
305
}
306
void printme() {
307
for (int i = 0 ; i < argc ; i++) {
308
printf(" [%d]=%s\n", i, argv[i]);
309
}
310
}
311
};
312
313
void dotest(Vector** vectors) {
314
Vector* v = vectors[0];
315
for (int i = 0 ; v != NULL;) {
316
if (v->enabled) {
317
v->check();
318
}
319
v = vectors[++i];
320
}
321
}
322
323
#define MAXV 128
324
int main(int argc, char* argv[]) {
325
326
int n;
327
for (n=1; n < argc; n++) {
328
printf("%d %s\n", n, argv[n]);
329
}
330
if (n > 1) {
331
JLI_CmdToArgs(GetCommandLine());
332
for (n = 0; n < stdargc; n++) {
333
printf(" [%d]=%s\n", n, stdargs[n].arg);
334
printf(" [%d]=%s\n", n, stdargs[n].has_wildcard ? "TRUE" : "FALSE");
335
}
336
doexit(0);
337
}
338
339
Vector *vectors[MAXV];
340
341
memset(vectors, 0, sizeof(vectors));
342
int i = 0;
343
Vector* v = new Vector(argv[0], "abcd");
344
v->add("abcd", FALSE);
345
// v->disable();
346
vectors[i++] = v;
347
348
349
v = new Vector(argv[0], "\"a b c d\"");
350
v->add("a b c d", FALSE);
351
// v->disable();
352
vectors[i++] = v;
353
354
355
v = new Vector(argv[0], "a\"b c d\"e");
356
v->add("ab c de", FALSE);
357
// v->disable();
358
vectors[i++] = v;
359
360
361
v = new Vector(argv[0], "ab\\\"cd");
362
v->add("ab\"cd", FALSE);
363
// v->disable();
364
vectors[i++] = v;
365
366
367
v = new Vector(argv[0], "\"a b c d\\\\\"");
368
v->add("a b c d\\", FALSE);
369
// v->disable();
370
vectors[i++] = v;
371
372
373
v = new Vector(argv[0], "ab\\\\\\\"cd");
374
v->add("ab\\\"cd", FALSE);
375
// v->disable();
376
vectors[i++] = v;
377
378
379
// Windows tests
380
v = new Vector(argv[0], "a\\\\\\c");
381
v->add("a\\\\\\c", FALSE);
382
// v->disable();
383
vectors[i++] = v;
384
385
386
v = new Vector(argv[0], "\"a\\\\\\d\"");
387
v->add("a\\\\\\d", FALSE);
388
// v->disable();
389
vectors[i++] = v;
390
391
392
v = new Vector(argv[0], "\"a b c\" d e");
393
v->add("a b c", FALSE);
394
v->add("d", FALSE);
395
v->add("e", FALSE);
396
// v->disable();
397
vectors[i++] = v;
398
399
400
v = new Vector(argv[0], "\"ab\\\"c\" \"\\\\\" d");
401
v->add("ab\"c", FALSE);
402
v->add("\\", FALSE);
403
v->add("d", FALSE);
404
// v->disable();
405
vectors[i++] = v;
406
407
408
v = new Vector(argv[0], "a\\\\\\c d\"e f\"g h");
409
v->add("a\\\\\\c", FALSE);
410
v->add("de fg", FALSE);
411
v->add("h", FALSE);
412
// v->disable();
413
vectors[i++] = v;
414
415
416
v = new Vector(argv[0], "a\\\\\\\"b c d");
417
v->add("a\\\"b", FALSE); // XXX "a\\\\\\\"b"
418
v->add("c", FALSE);
419
v->add("d", FALSE);
420
// v->disable();
421
vectors[i++] = v;
422
423
424
v = new Vector(argv[0], "a\\\\\\\\\"g c\" d e"); // XXX "a\\\\\\\\\"b c\" d e"
425
v->add("a\\\\\g c", FALSE); // XXX "a\\\\\\\\\"b c"
426
v->add("d", FALSE);
427
v->add("e", FALSE);
428
// v->disable();
429
vectors[i++] = v;
430
431
432
// Additional tests
433
v = new Vector(argv[0], "\"a b c\"\"");
434
v->add("a b c\"", FALSE);
435
// v->disable();
436
vectors[i++] = v;
437
438
439
v = new Vector(argv[0], "\"\"a b c\"\"");
440
v->add("a", FALSE);
441
v->add("b", FALSE);
442
v->add("c", FALSE);
443
// v->disable();
444
vectors[i++] = v;
445
446
447
v = new Vector(argv[0], "\"\"\"a b c\"\"\"");
448
v->add("\"a b c\"", FALSE);
449
// v->disable();
450
vectors[i++] = v;
451
452
453
v = new Vector(argv[0], "\"\"\"\"a b c\"\"\"\"");
454
v->add("\"a", FALSE);
455
v->add("b", FALSE);
456
v->add("c\"", FALSE);
457
// v->disable();
458
vectors[i++] = v;
459
460
461
v = new Vector(argv[0], "\"\"\"\"\"a b c\"\"\"\"\"");
462
v->add("\"\"a b c\"\"", FALSE);
463
// v->disable();
464
vectors[i++] = v;
465
466
467
v = new Vector(argv[0], "\"C:\\TEST A\\\\\"");
468
v->add("C:\\TEST A\\", FALSE);
469
// v->disable();
470
vectors[i++] = v;
471
472
473
v = new Vector(argv[0], "\"\"C:\\TEST A\\\\\"\"");
474
v->add("C:\\TEST", FALSE);
475
v->add("A\\", FALSE);
476
// v->disable();
477
vectors[i++] = v;
478
479
480
// test if a wildcard is present
481
v = new Vector(argv[0], "abc*def");
482
v->add("abc*def", TRUE);
483
// v->disable();
484
vectors[i++] = v;
485
486
487
v = new Vector(argv[0], "\"abc*def\"");
488
v->add("abc*def", FALSE);
489
// v->disable();
490
vectors[i++] = v;
491
492
493
v = new Vector(argv[0], "*.abc");
494
v->add("*.abc", TRUE);
495
// v->disable();
496
vectors[i++] = v;
497
498
499
v = new Vector(argv[0], "\"*.abc\"");
500
v->add("*.abc", FALSE);
501
// v->disable();
502
vectors[i++] = v;
503
504
505
v = new Vector(argv[0], "x.???");
506
v->add("x.???", TRUE);
507
// v->disable();
508
vectors[i++] = v;
509
510
511
v = new Vector(argv[0], "\"x.???\"");
512
v->add("x.???", FALSE);
513
// v->disable();
514
vectors[i++] = v;
515
516
517
v = new Vector(argv[0], "Debug\\*");
518
v->add("Debug\\*", TRUE);
519
// v->disable();
520
vectors[i++] = v;
521
522
523
v = new Vector(argv[0], "Debug\\f?a");
524
v->add("Debug\\f?a", TRUE);
525
// v->disable();
526
vectors[i++] = v;
527
528
529
v = new Vector(argv[0], "Debug\\?a.java");
530
v->add("Debug\\?a.java", TRUE);
531
// v->disable();
532
vectors[i++] = v;
533
534
535
v = new Vector(argv[0], "foo *.noexts");
536
v->add("foo", FALSE);
537
v->add("*.noexts", TRUE);
538
// v->disable();
539
vectors[i++] = v;
540
541
542
v = new Vector(argv[0], "X\\Y\\Z");
543
v->add("X\\Y\\Z", FALSE);
544
// v->disable();
545
vectors[i++] = v;
546
547
548
v = new Vector(argv[0], "\\X\\Y\\Z");
549
v->add("\\X\\Y\\Z", FALSE);
550
// v->disable();
551
vectors[i++] = v;
552
553
554
v = new Vector(argv[0], "a b");
555
v->add("a", FALSE);
556
v->add("b", FALSE);
557
// v->disable();
558
vectors[i++] = v;
559
560
561
v = new Vector(argv[0], "a\tb");
562
v->add("a", FALSE);
563
v->add("b", FALSE);
564
// v->disable();
565
vectors[i++] = v;
566
567
568
v = new Vector(argv[0], "a \t b");
569
v->add("a", FALSE);
570
v->add("b", FALSE);
571
// v->disable();
572
vectors[i++] = v;
573
574
v = new Vector(argv[0], "*\\");
575
v->add("*\\", TRUE);
576
// v->disable();
577
vectors[i++] = v;
578
579
v = new Vector(argv[0], "*/");
580
v->add("*/", TRUE);
581
// v->disable();
582
vectors[i++] = v;
583
584
v = new Vector(argv[0], ".\\*");
585
v->add(".\\*", TRUE);
586
// v->disable();
587
vectors[i++] = v;
588
589
v = new Vector(argv[0], "./*");
590
v->add("./*", TRUE);
591
// v->disable();
592
vectors[i++] = v;
593
594
v = new Vector(argv[0], ".\\*");
595
v->add(".\\*", TRUE);
596
// v->disable();
597
vectors[i++] = v;
598
599
v = new Vector(argv[0], ".//*");
600
v->add(".//*", TRUE);
601
// v->disable();
602
vectors[i++] = v;
603
604
v = new Vector(argv[0], "..\\..\\*");
605
v->add("..\\..\\*", TRUE);
606
// v->disable();
607
vectors[i++] = v;
608
609
v = new Vector(argv[0], "../../*");
610
v->add("../../*", TRUE);
611
// v->disable();
612
vectors[i++] = v;
613
614
v = new Vector(argv[0], "..\\..\\");
615
v->add("..\\..\\", FALSE);
616
// v->disable();
617
vectors[i++] = v;
618
619
v = new Vector(argv[0], "../../");
620
v->add("../../", FALSE);
621
// v->disable();
622
vectors[i++] = v;
623
624
v= new Vector(argv[0], "a b\\\\ d");
625
v->add("a", FALSE);
626
v->add("b\\\\", FALSE);
627
v->add("d", FALSE);
628
vectors[i++] = v;
629
630
v= new Vector(argv[0], "\\\\?");
631
v->add("\\\\?", TRUE);
632
vectors[i++] = v;
633
634
v= new Vector(argv[0], "\\\\*");
635
v->add("\\\\*", TRUE);
636
vectors[i++] = v;
637
638
dotest(vectors);
639
printf("All tests pass [%d]\n", i);
640
doexit(0);
641
}
642
#endif /* IDE_STANDALONE */
643
644