< prev index next >
src/java.base/share/native/libjli/args.c
Print this page
@@ -77,10 +77,15 @@
// Initialize to 1, as the first argument is the app name and not preprocessed
static size_t argsCount = 1;
static jboolean stopExpansion = JNI_FALSE;
static jboolean relaunch = JNI_FALSE;
+/*
+ * Prototypes for internal functions.
+ */
+static jboolean expand(JLI_List args, const char *str, const char *var_name);
+
JNIEXPORT void JNICALL
JLI_InitArgProcessing(jboolean hasJavaArgs, jboolean disableArgFile) {
// No expansion for relaunch
if (argsCount != 1) {
relaunch = JNI_TRUE;
@@ -374,13 +379,26 @@
}
return rv;
}
+/*
+ * expand a string into a list of words separated by whitespace.
+ */
+static JLI_List expandArg(const char *arg) {
+ JLI_List rv;
+
+ /* arbitrarily pick 8, seems to be a reasonable number of arguments */
+ rv = JLI_List_new(8);
+
+ expand(rv, arg, NULL);
+
+ return rv;
+}
+
JNIEXPORT JLI_List JNICALL
-JLI_PreprocessArg(const char *arg)
-{
+JLI_PreprocessArg(const char *arg, jboolean expandSourceOpt) {
JLI_List rv;
if (firstAppArgIndex > 0) {
// In user application arg, no more work.
return NULL;
@@ -390,10 +408,16 @@
// still looking for user application arg
checkArg(arg);
return NULL;
}
+ if (expandSourceOpt
+ && JLI_StrCCmp(arg, "--source") == 0
+ && JLI_StrChr(arg, ' ') != NULL) {
+ return expandArg(arg);
+ }
+
if (arg[0] != '@') {
checkArg(arg);
return NULL;
}
@@ -433,13 +457,10 @@
}
JNIEXPORT jboolean JNICALL
JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
char *env = getenv(var_name);
- char *p, *arg;
- char quote;
- JLI_List argsInFile;
if (firstAppArgIndex == 0) {
// Not 'java', return
return JNI_FALSE;
}
@@ -451,59 +472,83 @@
if (NULL == env) {
return JNI_FALSE;
}
JLI_ReportMessage(ARG_INFO_ENVVAR, var_name, env);
+ return expand(args, env, var_name);
+}
+
+/*
+ * Expand a string into a list of args.
+ * If the string is the result of looking up an environment variable,
+ * var_name should be set to the name of that environment variable,
+ * for use if needed in error messages.
+ */
+
+static jboolean expand(JLI_List args, const char *str, const char *var_name) {
+ jboolean inEnvVar = (var_name != NULL);
+
+ char *p, *arg;
+ char quote;
+ JLI_List argsInFile;
// This is retained until the process terminates as it is saved as the args
- p = JLI_MemAlloc(JLI_StrLen(env) + 1);
- while (*env != '\0') {
- while (*env != '\0' && isspace(*env)) {
- env++;
+ p = JLI_MemAlloc(JLI_StrLen(str) + 1);
+ while (*str != '\0') {
+ while (*str != '\0' && isspace(*str)) {
+ str++;
}
// Trailing space
- if (*env == '\0') {
+ if (*str == '\0') {
break;
}
arg = p;
- while (*env != '\0' && !isspace(*env)) {
- if (*env == '"' || *env == '\'') {
- quote = *env++;
- while (*env != quote && *env != '\0') {
- *p++ = *env++;
+ while (*str != '\0' && !isspace(*str)) {
+ if (inEnvVar && (*str == '"' || *str == '\'')) {
+ quote = *str++;
+ while (*str != quote && *str != '\0') {
+ *p++ = *str++;
}
- if (*env == '\0') {
+ if (*str == '\0') {
JLI_ReportMessage(ARG_ERROR8, var_name);
exit(1);
}
- env++;
+ str++;
} else {
- *p++ = *env++;
+ *p++ = *str++;
}
}
*p++ = '\0';
- argsInFile = JLI_PreprocessArg(arg);
+ argsInFile = JLI_PreprocessArg(arg, JNI_FALSE);
if (NULL == argsInFile) {
if (isTerminalOpt(arg)) {
+ if (inEnvVar) {
JLI_ReportMessage(ARG_ERROR9, arg, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR15, arg);
+ }
exit(1);
}
JLI_List_add(args, arg);
} else {
size_t cnt, idx;
char *argFile = arg;
cnt = argsInFile->size;
for (idx = 0; idx < cnt; idx++) {
arg = argsInFile->elements[idx];
if (isTerminalOpt(arg)) {
+ if (inEnvVar) {
JLI_ReportMessage(ARG_ERROR10, arg, argFile, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR16, arg, argFile);
+ }
exit(1);
}
JLI_List_add(args, arg);
}
// Shallow free, we reuse the string to avoid copy
@@ -515,15 +560,19 @@
* must always appear after expansion, as a main-class could be specified
* indirectly into environment variable via an @argfile, and it must be
* caught now.
*/
if (firstAppArgIndex != NOT_FOUND) {
+ if (inEnvVar) {
JLI_ReportMessage(ARG_ERROR11, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR17);
+ }
exit(1);
}
- assert (*env == '\0' || isspace(*env));
+ assert (*str == '\0' || isspace(*str));
}
return JNI_TRUE;
}
@@ -640,11 +689,11 @@
"c:\\partial quote\\lib" };
DO_CASE(escape_quote);
if (argc > 1) {
for (i = 0; i < argc; i++) {
- JLI_List tokens = JLI_PreprocessArg(argv[i]);
+ JLI_List tokens = JLI_PreprocessArg(argv[i], JNI_FALSE);
if (NULL != tokens) {
for (j = 0; j < tokens->size; j++) {
printf("Token[%lu]: <%s>\n", (unsigned long) j, tokens->elements[j]);
}
}
< prev index next >