Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libjli/cmdtoargs.c
41119 views
1
/*
2
* Copyright (c) 2012, 2018, 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 arguments, and
30
* these rules are embodied in the regression tests below, and duplicated
31
* in the jdk regression tests.
32
*/
33
34
#include <assert.h>
35
36
#ifndef IDE_STANDALONE
37
#include "java.h"
38
#include "jni.h"
39
#include "jli_util.h"
40
#else /* IDE_STANDALONE */
41
// The defines we need for stand alone testing
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <Windows.h>
45
#define JNI_TRUE TRUE
46
#define JNI_FALSE FALSE
47
#define JLI_MemRealloc realloc
48
#define JLI_StringDup _strdup
49
#define JLI_MemFree free
50
#define jboolean boolean
51
typedef struct {
52
char* arg;
53
boolean has_wildcard;
54
} StdArg ;
55
#endif
56
static StdArg *stdargs;
57
static int stdargc;
58
59
static int copyCh(USHORT ch, char* dest) {
60
if (HIBYTE(ch) == 0) {
61
*dest = (char)ch;
62
return 1;
63
} else {
64
*((USHORT *)dest) = ch;
65
return 2;
66
}
67
}
68
69
static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) {
70
71
char* src = cmdline;
72
char* dest = arg;
73
jboolean separator = JNI_FALSE;
74
int quotes = 0;
75
int slashes = 0;
76
77
// "prev"/"ch" may contain either a single byte, or a double byte
78
// character encoded in CP_ACP.
79
USHORT prev = 0;
80
USHORT ch = 0;
81
int i;
82
jboolean done = JNI_FALSE;
83
ptrdiff_t charLength;
84
85
*wildcard = JNI_FALSE;
86
while (!done) {
87
charLength = CharNextExA(CP_ACP, src, 0) - src;
88
if (charLength == 0) {
89
break;
90
} else if (charLength == 1) {
91
ch = (USHORT)(UCHAR)src[0];
92
} else {
93
ch = ((USHORT *)src)[0];
94
}
95
96
switch (ch) {
97
case L'"':
98
if (separator) {
99
done = JNI_TRUE;
100
break;
101
}
102
if (prev == L'\\') {
103
for (i = 1; i < slashes; i += 2) {
104
dest += copyCh(prev, dest);
105
}
106
if (slashes % 2 == 1) {
107
dest += copyCh(ch, dest);
108
} else {
109
quotes++;
110
}
111
} else if (prev == L'"' && quotes % 2 == 0) {
112
quotes++;
113
dest += copyCh(ch, dest); // emit every other consecutive quote
114
} else if (quotes == 0) {
115
quotes++; // starting quote
116
} else {
117
quotes--; // matching quote
118
}
119
slashes = 0;
120
break;
121
122
case L'\\':
123
slashes++;
124
if (separator) {
125
done = JNI_TRUE;
126
separator = JNI_FALSE;
127
}
128
break;
129
130
case L' ':
131
case L'\t':
132
if (prev == L'\\') {
133
for (i = 0 ; i < slashes; i++) {
134
dest += copyCh(prev, dest);
135
}
136
}
137
if (quotes % 2 == 1) {
138
dest += copyCh(ch, dest);
139
} else {
140
separator = JNI_TRUE;
141
}
142
slashes = 0;
143
break;
144
145
case L'*':
146
case L'?':
147
if (separator) {
148
done = JNI_TRUE;
149
separator = JNI_FALSE;
150
break;
151
}
152
if (quotes % 2 == 0) {
153
*wildcard = JNI_TRUE;
154
}
155
if (prev == L'\\') {
156
for (i = 0 ; i < slashes ; i++) {
157
dest += copyCh(prev, dest);
158
}
159
}
160
dest += copyCh(ch, dest);
161
slashes = 0;
162
break;
163
164
default:
165
if (prev == L'\\') {
166
for (i = 0 ; i < slashes ; i++) {
167
dest += copyCh(prev, dest);
168
}
169
dest += copyCh(ch, dest);
170
} else if (separator) {
171
done = JNI_TRUE;
172
} else {
173
dest += copyCh(ch, dest);
174
}
175
slashes = 0;
176
}
177
178
if (!done) {
179
prev = ch;
180
src += charLength;
181
}
182
}
183
if (prev == L'\\') {
184
for (i = 0; i < slashes; i++) {
185
dest += copyCh(prev, dest);
186
}
187
}
188
*dest = 0;
189
return done ? src : NULL;
190
}
191
192
JNIEXPORT int JNICALL
193
JLI_GetStdArgc() {
194
return stdargc;
195
}
196
197
JNIEXPORT StdArg* JNICALL
198
JLI_GetStdArgs() {
199
return stdargs;
200
}
201
202
JNIEXPORT void JNICALL
203
JLI_CmdToArgs(char* cmdline) {
204
int nargs = 0;
205
StdArg* argv = NULL;
206
jboolean wildcard = JNI_FALSE;
207
char* src = cmdline, *arg = NULL;
208
JLI_List argsInFile;
209
size_t i, cnt;
210
211
JLI_List envArgs = JLI_List_new(1);
212
if (JLI_AddArgsFromEnvVar(envArgs, JDK_JAVA_OPTIONS)) {
213
// JLI_SetTraceLauncher is not called yet
214
// Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
215
if (getenv(JLDEBUG_ENV_ENTRY)) {
216
char *tmp = getenv("_JAVA_OPTIONS");
217
if (NULL != tmp) {
218
JLI_ReportMessage(ARG_INFO_ENVVAR, "_JAVA_OPTIONS", tmp);
219
}
220
}
221
}
222
cnt = envArgs->size + 1;
223
argv = JLI_MemAlloc(cnt * sizeof(StdArg));
224
225
// allocate arg buffer with sufficient space to receive the largest arg
226
arg = JLI_StringDup(cmdline);
227
228
src = next_arg(src, arg, &wildcard);
229
// first argument is the app name, do not preprocess and make sure remains first
230
argv[0].arg = JLI_StringDup(arg);
231
argv[0].has_wildcard = wildcard;
232
nargs++;
233
234
for (i = 1; i < cnt; i++) {
235
argv[i].arg = envArgs->elements[i - 1];
236
// wildcard is not supported in argfile
237
argv[i].has_wildcard = JNI_FALSE;
238
nargs++;
239
}
240
JLI_MemFree(envArgs->elements);
241
JLI_MemFree(envArgs);
242
243
assert ((size_t) nargs == cnt);
244
*arg = '\0';
245
246
// iterate through rest of command line
247
while (src != NULL) {
248
src = next_arg(src, arg, &wildcard);
249
argsInFile = JLI_PreprocessArg(arg, JNI_TRUE);
250
if (argsInFile != NULL) {
251
// resize to accommodate another Arg
252
cnt = argsInFile->size;
253
argv = (StdArg*) JLI_MemRealloc(argv, (nargs + cnt) * sizeof(StdArg));
254
for (i = 0; i < cnt; i++) {
255
argv[nargs].arg = argsInFile->elements[i];
256
// wildcard is not supported in argfile
257
argv[nargs].has_wildcard = JNI_FALSE;
258
nargs++;
259
}
260
// Shallow free, we reuse the string to avoid copy
261
JLI_MemFree(argsInFile->elements);
262
JLI_MemFree(argsInFile);
263
} else {
264
// resize to accommodate another Arg
265
argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg));
266
argv[nargs].arg = JLI_StringDup(arg);
267
argv[nargs].has_wildcard = wildcard;
268
*arg = '\0';
269
nargs++;
270
}
271
*arg = '\0';
272
}
273
274
JLI_MemFree(arg);
275
276
stdargc = nargs;
277
stdargs = argv;
278
}
279
280
#ifdef IDE_STANDALONE
281
void doexit(int rv) {
282
printf("Hit any key to quit\n");
283
int c = getchar();
284
exit(rv);
285
}
286
287
void doabort() {
288
doexit(1);
289
}
290
291
class Vector {
292
public:
293
char* cmdline;
294
int argc;
295
char* argv[10];
296
boolean wildcard[10];
297
boolean enabled;
298
299
Vector(){}
300
// Initialize our test vector with the program name, argv[0]
301
// and the single string command line.
302
Vector(char* pname, char* cline) {
303
argv[0] = pname;
304
wildcard[0] = FALSE;
305
cmdline = cline;
306
argc = 1;
307
enabled = TRUE;
308
}
309
310
// add our expected strings, the program name has already been
311
// added so ignore that
312
void add(char* arg, boolean w) {
313
argv[argc] = arg;
314
wildcard[argc] = w;
315
argc++;
316
}
317
318
void disable() {
319
enabled = FALSE;
320
}
321
322
// validate the returned arguments with the expected arguments, using the
323
// new CmdToArgs method.
324
bool check() {
325
// "pgmname" rest of cmdline ie. pgmname + 2 double quotes + space + cmdline from windows
326
char* cptr = (char*) malloc(strlen(argv[0]) + sizeof(char) * 3 + strlen(cmdline) + 1);
327
_snprintf(cptr, MAX_PATH, "\"%s\" %s", argv[0], cmdline);
328
JLI_CmdToArgs(cptr);
329
free(cptr);
330
StdArg *kargv = JLI_GetStdArgs();
331
int kargc = JLI_GetStdArgc();
332
bool retval = true;
333
printf("\n===========================\n");
334
printf("cmdline=%s\n", cmdline);
335
if (argc != kargc) {
336
printf("*** argument count does not match\n");
337
printme();
338
printtest(kargc, kargv);
339
doabort();
340
}
341
for (int i = 0 ; i < argc && retval == true ; i++) {
342
if (strcmp(argv[i], kargv[i].arg) != 0) {
343
printf("*** argument at [%d] don't match\n got: %s\n exp: %s\n",
344
i, kargv[i].arg, argv[i]);
345
doabort();
346
}
347
}
348
for (int i = 0 ; i < argc && retval == true ; i++) {
349
if (wildcard[i] != kargv[i].has_wildcard) {
350
printf("*** expansion flag at [%d] doesn't match\n got: %d\n exp: %d\n",
351
i, kargv[i].has_wildcard, wildcard[i]);
352
doabort();
353
}
354
}
355
for (int i = 0 ; i < kargc ; i++) {
356
printf("k[%d]=%s\n", i, kargv[i].arg);
357
printf(" [%d]=%s\n", i, argv[i]);
358
}
359
return retval;
360
}
361
void printtest(int kargc, StdArg* kargv) {
362
for (int i = 0 ; i < kargc ; i++) {
363
printf("k[%d]=%s\n", i, kargv[i].arg);
364
}
365
}
366
void printme() {
367
for (int i = 0 ; i < argc ; i++) {
368
printf(" [%d]=%s\n", i, argv[i]);
369
}
370
}
371
};
372
373
void dotest(Vector** vectors) {
374
Vector* v = vectors[0];
375
for (int i = 0 ; v != NULL;) {
376
if (v->enabled) {
377
v->check();
378
}
379
v = vectors[++i];
380
}
381
}
382
383
#define MAXV 128
384
int main(int argc, char* argv[]) {
385
386
int n;
387
for (n=1; n < argc; n++) {
388
printf("%d %s\n", n, argv[n]);
389
}
390
if (n > 1) {
391
JLI_CmdToArgs(GetCommandLine());
392
for (n = 0; n < stdargc; n++) {
393
printf(" [%d]=%s\n", n, stdargs[n].arg);
394
printf(" [%d]=%s\n", n, stdargs[n].has_wildcard ? "TRUE" : "FALSE");
395
}
396
doexit(0);
397
}
398
399
Vector *vectors[MAXV];
400
401
memset(vectors, 0, sizeof(vectors));
402
int i = 0;
403
Vector* v = new Vector(argv[0], "abcd");
404
v->add("abcd", FALSE);
405
// v->disable();
406
vectors[i++] = v;
407
408
409
v = new Vector(argv[0], "\"a b c d\"");
410
v->add("a b c d", FALSE);
411
// v->disable();
412
vectors[i++] = v;
413
414
415
v = new Vector(argv[0], "a\"b c d\"e");
416
v->add("ab c de", FALSE);
417
// v->disable();
418
vectors[i++] = v;
419
420
421
v = new Vector(argv[0], "ab\\\"cd");
422
v->add("ab\"cd", FALSE);
423
// v->disable();
424
vectors[i++] = v;
425
426
427
v = new Vector(argv[0], "\"a b c d\\\\\"");
428
v->add("a b c d\\", FALSE);
429
// v->disable();
430
vectors[i++] = v;
431
432
433
v = new Vector(argv[0], "ab\\\\\\\"cd");
434
v->add("ab\\\"cd", FALSE);
435
// v->disable();
436
vectors[i++] = v;
437
438
439
// Windows tests
440
v = new Vector(argv[0], "a\\\\\\c");
441
v->add("a\\\\\\c", FALSE);
442
// v->disable();
443
vectors[i++] = v;
444
445
446
v = new Vector(argv[0], "\"a\\\\\\d\"");
447
v->add("a\\\\\\d", FALSE);
448
// v->disable();
449
vectors[i++] = v;
450
451
452
v = new Vector(argv[0], "\"a b c\" d e");
453
v->add("a b c", FALSE);
454
v->add("d", FALSE);
455
v->add("e", FALSE);
456
// v->disable();
457
vectors[i++] = v;
458
459
460
v = new Vector(argv[0], "\"ab\\\"c\" \"\\\\\" d");
461
v->add("ab\"c", FALSE);
462
v->add("\\", FALSE);
463
v->add("d", FALSE);
464
// v->disable();
465
vectors[i++] = v;
466
467
468
v = new Vector(argv[0], "a\\\\\\c d\"e f\"g h");
469
v->add("a\\\\\\c", FALSE);
470
v->add("de fg", FALSE);
471
v->add("h", FALSE);
472
// v->disable();
473
vectors[i++] = v;
474
475
476
v = new Vector(argv[0], "a\\\\\\\"b c d");
477
v->add("a\\\"b", FALSE); // XXX "a\\\\\\\"b"
478
v->add("c", FALSE);
479
v->add("d", FALSE);
480
// v->disable();
481
vectors[i++] = v;
482
483
484
v = new Vector(argv[0], "a\\\\\\\\\"g c\" d e"); // XXX "a\\\\\\\\\"b c\" d e"
485
v->add("a\\\\\g c", FALSE); // XXX "a\\\\\\\\\"b c"
486
v->add("d", FALSE);
487
v->add("e", FALSE);
488
// v->disable();
489
vectors[i++] = v;
490
491
492
// Additional tests
493
v = new Vector(argv[0], "\"a b c\"\"");
494
v->add("a b c\"", FALSE);
495
// v->disable();
496
vectors[i++] = v;
497
498
499
v = new Vector(argv[0], "\"\"a b c\"\"");
500
v->add("a", FALSE);
501
v->add("b", FALSE);
502
v->add("c", FALSE);
503
// v->disable();
504
vectors[i++] = v;
505
506
507
v = new Vector(argv[0], "\"\"\"a b c\"\"\"");
508
v->add("\"a b c\"", FALSE);
509
// v->disable();
510
vectors[i++] = v;
511
512
513
v = new Vector(argv[0], "\"\"\"\"a b c\"\"\"\"");
514
v->add("\"a", FALSE);
515
v->add("b", FALSE);
516
v->add("c\"", FALSE);
517
// v->disable();
518
vectors[i++] = v;
519
520
521
v = new Vector(argv[0], "\"\"\"\"\"a b c\"\"\"\"\"");
522
v->add("\"\"a b c\"\"", FALSE);
523
// v->disable();
524
vectors[i++] = v;
525
526
527
v = new Vector(argv[0], "\"C:\\TEST A\\\\\"");
528
v->add("C:\\TEST A\\", FALSE);
529
// v->disable();
530
vectors[i++] = v;
531
532
533
v = new Vector(argv[0], "\"\"C:\\TEST A\\\\\"\"");
534
v->add("C:\\TEST", FALSE);
535
v->add("A\\", FALSE);
536
// v->disable();
537
vectors[i++] = v;
538
539
540
// test if a wildcard is present
541
v = new Vector(argv[0], "abc*def");
542
v->add("abc*def", TRUE);
543
// v->disable();
544
vectors[i++] = v;
545
546
547
v = new Vector(argv[0], "\"abc*def\"");
548
v->add("abc*def", FALSE);
549
// v->disable();
550
vectors[i++] = v;
551
552
553
v = new Vector(argv[0], "*.abc");
554
v->add("*.abc", TRUE);
555
// v->disable();
556
vectors[i++] = v;
557
558
559
v = new Vector(argv[0], "\"*.abc\"");
560
v->add("*.abc", FALSE);
561
// v->disable();
562
vectors[i++] = v;
563
564
565
v = new Vector(argv[0], "x.???");
566
v->add("x.???", TRUE);
567
// v->disable();
568
vectors[i++] = v;
569
570
571
v = new Vector(argv[0], "\"x.???\"");
572
v->add("x.???", FALSE);
573
// v->disable();
574
vectors[i++] = v;
575
576
577
v = new Vector(argv[0], "Debug\\*");
578
v->add("Debug\\*", TRUE);
579
// v->disable();
580
vectors[i++] = v;
581
582
583
v = new Vector(argv[0], "Debug\\f?a");
584
v->add("Debug\\f?a", TRUE);
585
// v->disable();
586
vectors[i++] = v;
587
588
589
v = new Vector(argv[0], "Debug\\?a.java");
590
v->add("Debug\\?a.java", TRUE);
591
// v->disable();
592
vectors[i++] = v;
593
594
595
v = new Vector(argv[0], "foo *.noexts");
596
v->add("foo", FALSE);
597
v->add("*.noexts", TRUE);
598
// v->disable();
599
vectors[i++] = v;
600
601
602
v = new Vector(argv[0], "X\\Y\\Z");
603
v->add("X\\Y\\Z", FALSE);
604
// v->disable();
605
vectors[i++] = v;
606
607
608
v = new Vector(argv[0], "\\X\\Y\\Z");
609
v->add("\\X\\Y\\Z", FALSE);
610
// v->disable();
611
vectors[i++] = v;
612
613
614
v = new Vector(argv[0], "a b");
615
v->add("a", FALSE);
616
v->add("b", FALSE);
617
// v->disable();
618
vectors[i++] = v;
619
620
621
v = new Vector(argv[0], "a\tb");
622
v->add("a", FALSE);
623
v->add("b", FALSE);
624
// v->disable();
625
vectors[i++] = v;
626
627
628
v = new Vector(argv[0], "a \t b");
629
v->add("a", FALSE);
630
v->add("b", FALSE);
631
// v->disable();
632
vectors[i++] = v;
633
634
v = new Vector(argv[0], "*\\");
635
v->add("*\\", TRUE);
636
// v->disable();
637
vectors[i++] = v;
638
639
v = new Vector(argv[0], "*/");
640
v->add("*/", TRUE);
641
// v->disable();
642
vectors[i++] = v;
643
644
v = new Vector(argv[0], ".\\*");
645
v->add(".\\*", TRUE);
646
// v->disable();
647
vectors[i++] = v;
648
649
v = new Vector(argv[0], "./*");
650
v->add("./*", TRUE);
651
// v->disable();
652
vectors[i++] = v;
653
654
v = new Vector(argv[0], ".\\*");
655
v->add(".\\*", TRUE);
656
// v->disable();
657
vectors[i++] = v;
658
659
v = new Vector(argv[0], ".//*");
660
v->add(".//*", TRUE);
661
// v->disable();
662
vectors[i++] = v;
663
664
v = new Vector(argv[0], "..\\..\\*");
665
v->add("..\\..\\*", TRUE);
666
// v->disable();
667
vectors[i++] = v;
668
669
v = new Vector(argv[0], "../../*");
670
v->add("../../*", TRUE);
671
// v->disable();
672
vectors[i++] = v;
673
674
v = new Vector(argv[0], "..\\..\\");
675
v->add("..\\..\\", FALSE);
676
// v->disable();
677
vectors[i++] = v;
678
679
v = new Vector(argv[0], "../../");
680
v->add("../../", FALSE);
681
// v->disable();
682
vectors[i++] = v;
683
684
v= new Vector(argv[0], "a b\\\\ d");
685
v->add("a", FALSE);
686
v->add("b\\\\", FALSE);
687
v->add("d", FALSE);
688
vectors[i++] = v;
689
690
v= new Vector(argv[0], "\\\\?");
691
v->add("\\\\?", TRUE);
692
vectors[i++] = v;
693
694
v= new Vector(argv[0], "\\\\*");
695
v->add("\\\\*", TRUE);
696
vectors[i++] = v;
697
698
dotest(vectors);
699
printf("All tests pass [%d]\n", i);
700
doexit(0);
701
}
702
#endif /* IDE_STANDALONE */
703
704