Cleanup and moving of NanoCoat VM specific headers to their own include directory...
[SquirrelJME.git] / nanocoat / src / boot.c
blob52380f6e8b1b46fd055bb73d71dbceb3f895d504
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 #include <stdio.h>
11 #include <string.h>
13 #include "sjme/nvm/allocSizeOf.h"
14 #include "sjme/nvm/boot.h"
15 #include "sjme/debug.h"
16 #include "sjme/nvm/nvm.h"
17 #include "sjme/nvm/task.h"
18 #include "sjme/charSeq.h"
19 #include "sjme/native.h"
20 #include "sjme/cleanup.h"
21 #include "sjme/path.h"
23 #if defined(SJME_PATH_SHORT)
24 /** The name of the SquirrelJME Jar. */
25 #define SJME_JAR_NAME "sjme.jar"
27 /** The name of the SquirrelJME directory. */
28 #define SJME_DIRECTORY_NAME "sjme"
29 #else
30 /** The name of the SquirrelJME Jar. */
31 #define SJME_JAR_NAME "squirreljme.jar"
33 /** The name of the SquirrelJME directory. */
34 #define SJME_DIRECTORY_NAME "squirreljme"
35 #endif
37 /**
38 * Help parameter storage.
40 * @since 2024/08/08
42 typedef struct sjme_nvm_helpParam
44 /** The argument. */
45 sjme_lpcstr arg;
47 /** Description of the parameter. */
48 sjme_lpcstr desc;
49 } sjme_nvm_helpParam;
51 static const sjme_nvm_helpParam sjme_nvm_helpParams[] =
53 {"-Xclutter:<release|debug>",
54 "If available, selects the given clutter level."},
55 {"-Xdebug",
56 "Starts debugging with the built-in debugger."},
57 {"-Xemulator:<vm>",
58 "Ignored, this will always be \"nanocoat\"."},
59 {"-Xentry:id",
60 "If launching a MIDlet, choose a MIDlet entry."},
61 {"-Xjdwp:[hostname]:port",
62 "Listens or connects to a JDWP debugger."},
63 {"-Xlibraries:<class:path:...>",
64 "Libraries to include in the library path, not the classpath."},
65 {"-Xscritchui:<ui>",
66 "Default interface to choose for ScritchUI."},
67 {"-Xsnapshot:<path-to-nps>",
68 "Write a VisualVM snapshot (.nps) to the given path."},
69 {"-Xthread:<single|coop|multi|smt>",
70 "The threading model to use."},
71 {"-Xtrace:<flag|...>",
72 "Trace flags to permanently set on by default."},
73 {"-Xint",
74 "Force pure interpreter, do not JIT/AOT compilation."},
75 {"-D<sysprop>=<value>",
76 "Declare system property <sysprop> and set to <value>."},
77 {"-classpath <class:path:...>",
78 "The additional classpath to use for the application."},
79 {"-client",
80 "Ignored."},
81 {"-? -h -help",
82 "Hopefully what you are reading currently, to StdErr."},
83 {"--help",
84 "Hopefully what you are reading currently, to StdOut."},
85 {"-jar <Jar>",
86 "Launch the specified Jar."},
87 {"-server",
88 "Ignored."},
89 {"-version",
90 "SquirrelJME version information, to StdErr."},
91 {"--version",
92 "SquirrelJME version information, to StdOut."},
93 {"-zero",
94 "Same as -Xint."},
96 {NULL, NULL}
99 sjme_errorCode sjme_nvm_allocReservedPool(
100 sjme_attrInNotNull sjme_alloc_pool* mainPool,
101 sjme_attrOutNotNull sjme_alloc_pool** outReservedPool)
103 sjme_errorCode error;
104 sjme_pointer reservedBase;
105 sjme_alloc_pool* reservedPool;
106 sjme_jint reservedSize;
108 if (mainPool == NULL || outReservedPool == NULL)
109 return SJME_ERROR_NULL_ARGUMENTS;
111 /* Determine how big the reserved pool should be... */
112 reservedBase = NULL;
113 reservedSize = -1;
114 if (sjme_error_is(error = sjme_alloc_sizeOf(
115 SJME_ALLOC_SIZEOF_RESERVED_POOL, 0, &reservedSize)))
116 return sjme_error_default(error);
117 if (sjme_error_is(error = sjme_alloc(mainPool,
118 reservedSize, (sjme_pointer*)&reservedBase) ||
119 reservedBase == NULL))
120 return sjme_error_default(error);
122 /* Initialize a reserved pool where all of our own data structures go. */
123 reservedPool = NULL;
124 if (sjme_error_is(error = sjme_alloc_poolInitStatic(
125 &reservedPool, reservedBase, reservedSize)) ||
126 reservedPool == NULL)
127 return sjme_error_default(error);
129 /* Use the resultant pool. */
130 *outReservedPool = reservedPool;
131 return SJME_ERROR_NONE;
134 sjme_errorCode sjme_nvm_boot(
135 sjme_attrInNotNull sjme_alloc_pool* mainPool,
136 sjme_attrInNotNull sjme_alloc_pool* reservedPool,
137 sjme_attrInNotNull const sjme_nvm_bootParam* param,
138 sjme_attrOutNotNull sjme_nvm* outState)
140 #define FIXED_SUITE_COUNT 16
141 sjme_errorCode error;
142 sjme_exceptTrace* trace;
143 sjme_jint i, n;
144 sjme_nvm result;
145 sjme_rom_suite mergeSuites[FIXED_SUITE_COUNT];
146 sjme_jint numMergeSuites;
147 sjme_task_startConfig initTaskConfig;
148 sjme_nvm_task initTask;
149 sjme_list_sjme_rom_library* classPath;
151 if (param == NULL || outState == NULL)
152 return SJME_ERROR_NULL_ARGUMENTS;
154 /* Set up a reserved pool where all the data structures for the VM go... */
155 /* But only if one does not exist. */
156 if (reservedPool == NULL)
157 if (sjme_error_is(error = sjme_nvm_allocReservedPool(mainPool,
158 &reservedPool)) || reservedPool == NULL)
159 goto fail_reservedPoolAlloc;
161 /* Allocate resultant state. */
162 result = NULL;
163 if (sjme_error_is(error = sjme_alloc_weakNew(reservedPool,
164 sizeof(*result), sjme_nvm_enqueueHandler, SJME_NVM_ENQUEUE_IDENTITY,
165 (sjme_pointer*)&result, NULL)) || result == NULL)
166 goto fail_resultAlloc;
168 /* Initialize. */
169 if (sjme_error_is(error = sjme_nvm_objectInit(
170 SJME_AS_COMMON(result),
171 SJME_NVM_STRUCTTYPE_STATE)))
172 goto fail_resultInit;
174 /* Make a defensive copy of the boot parameters. */
175 if (sjme_error_is(error = sjme_alloc_copyWeak(reservedPool,
176 sizeof(sjme_nvm_bootParam),
177 sjme_nvm_enqueueHandler, SJME_NVM_ENQUEUE_IDENTITY,
178 (sjme_pointer*)&result->bootParamCopy, param, NULL)) ||
179 result == NULL)
180 goto fail_bootParamCopy;
182 /* Can only use one or the other to get the class path. */
183 if (result->bootParamCopy->mainClassPathById != NULL &&
184 result->bootParamCopy->mainClassPathByName != NULL)
185 goto fail_bothIdAndName;
187 /* Set parameters accordingly. */
188 result->allocPool = mainPool;
189 result->reservedPool = reservedPool;
191 /* Initialize base for suite merging. */
192 memset(mergeSuites, 0, sizeof(mergeSuites));
193 numMergeSuites = 0;
195 /* Process payload suites. */
196 if (result->bootParamCopy->payload != NULL)
198 /* Scan accordingly. */
199 if (sjme_error_is(error = sjme_rom_suiteFromPayload(reservedPool,
200 &mergeSuites[numMergeSuites],
201 result->bootParamCopy->payload)))
202 goto fail_payloadRom;
204 /* Was a suite generated? */
205 if (mergeSuites[numMergeSuites] != NULL)
206 numMergeSuites++;
209 /* Is there a pre-existing boot suite to use? */
210 if (result->bootParamCopy->bootSuite != NULL)
211 if (numMergeSuites < FIXED_SUITE_COUNT)
212 mergeSuites[numMergeSuites++] =
213 (sjme_rom_suite)result->bootParamCopy->bootSuite;
215 /* Is there a library suite to use? */
216 if (result->bootParamCopy->librarySuite != NULL)
217 if (numMergeSuites < FIXED_SUITE_COUNT)
218 mergeSuites[numMergeSuites++] =
219 (sjme_rom_suite)result->bootParamCopy->librarySuite;
221 /* No suites at all? Running with absolutely nothing??? */
222 if (numMergeSuites <= 0)
224 /* Debug. */
225 sjme_message("No suites are available, cannot run.");
227 goto fail_noSuites;
230 /* Use the single suite only. */
231 else if (numMergeSuites == 1)
232 result->suite = mergeSuites[0];
234 /* Merge everything into one. */
235 else
237 /* Merge all the suites together into one. */
238 if (sjme_error_is(error = sjme_rom_suiteFromMerge(reservedPool,
239 &result->suite, mergeSuites,
240 numMergeSuites)) || result->suite == NULL)
241 goto fail_suiteMerge;
244 /* Resolve class path libraries. */
245 classPath = NULL;
246 error = SJME_ERROR_NO_SUITES;
247 if (result->bootParamCopy->mainClassPathById != NULL)
248 error = sjme_rom_resolveClassPathById(result->suite,
249 result->bootParamCopy->mainClassPathById,
250 &classPath);
251 else if (result->bootParamCopy->mainClassPathByName != NULL)
252 error = sjme_rom_resolveClassPathByName(result->suite,
253 result->bootParamCopy->mainClassPathByName,
254 &classPath);
256 /* Failed to resolve? */
257 if (sjme_error_is(error) || classPath == NULL)
259 /* Debug. */
260 sjme_message("Classpath resolve failure: %d %p %s",
261 error, classPath,
262 (result->bootParamCopy->mainClassPathById != NULL ?
263 "byId" : "byName"));
265 goto fail_badClassPath;
268 /* Setup task details. */
269 initTaskConfig.stdOut = SJME_TASK_PIPE_REDIRECT_TYPE_TERMINAL;
270 initTaskConfig.stdErr = SJME_TASK_PIPE_REDIRECT_TYPE_TERMINAL;
271 initTaskConfig.classPath = classPath;
272 initTaskConfig.mainClass = result->bootParamCopy->mainClass;
273 initTaskConfig.mainArgs = result->bootParamCopy->mainArgs;
274 initTaskConfig.sysProps = result->bootParamCopy->sysProps;
276 /* Spawn initial task which uses the main arguments. */
277 initTask = NULL;
278 if (sjme_error_is(error = sjme_task_start(result,
279 &initTaskConfig, &initTask)) || initTask == NULL)
280 goto fail_initTask;
282 /* Return newly created VM. */
283 *outState = result;
284 return SJME_ERROR_NONE;
286 /* Failed at specific points... */
287 fail_initTask:
288 fail_badClassPath:
289 fail_suiteMerge:
290 fail_noSuites:
291 fail_payloadRom:
292 fail_bothIdAndName:
293 fail_bootParamCopy:
294 if (result != NULL && result->bootParamCopy != NULL)
295 sjme_alloc_free(result->bootParamCopy);
297 fail_resultInit:
298 fail_resultAlloc:
299 if (result != NULL)
300 sjme_alloc_free(result);
302 fail_reservedPoolAlloc:
304 /* Use whatever error code. */
305 return sjme_error_defaultOr(error, SJME_ERROR_BOOT_FAILURE);
308 sjme_errorCode sjme_nvm_defaultBootSuite(
309 sjme_attrInNotNull sjme_alloc_pool* inPool,
310 sjme_attrInNotNull const sjme_nal* nal,
311 sjme_attrOutNotNull sjme_rom_suite* outSuite)
313 sjme_errorCode error;
314 sjme_cchar dataPath[SJME_MAX_PATH];
315 sjme_seekable rom;
316 sjme_rom_suite result;
318 if (inPool == NULL || nal == NULL || outSuite == NULL)
319 return SJME_ERROR_NULL_ARGUMENTS;
321 /* We cannot load if filesystem access is not supported. */
322 if (nal->fileOpen == NULL)
323 return SJME_ERROR_NOT_IMPLEMENTED;
325 /* Initialize. */
326 memset(&dataPath, 0, sizeof(dataPath));
328 /* Get default data directory. */
329 if (sjme_error_is(error = sjme_nvm_defaultDir(
330 SJME_NVM_DEFAULT_DIRECTORY_DATA, nal,
331 dataPath, SJME_MAX_PATH - 1)))
332 return sjme_error_default(error);
334 /* Use ROM from here. */
335 if (sjme_error_is(error = sjme_path_resolveAppend(
336 dataPath, SJME_MAX_PATH - 1,
337 SJME_JAR_NAME, INT32_MAX)))
338 return sjme_error_default(error);
340 /* Open main ROM file. */
341 rom = NULL;
342 if (sjme_error_is(error = nal->fileOpen(inPool, dataPath,
343 &rom)) || rom == NULL)
344 return sjme_error_default(error);
346 /* Load suite from the ZIP. */
347 result = NULL;
348 if (sjme_error_is(error = sjme_rom_suiteFromZipSeekable(inPool,
349 &result, rom)) || result == NULL)
351 /* Make sure to close the file. */
352 sjme_closeable_close(SJME_AS_CLOSEABLE(rom));
354 /* Fail. */
355 return sjme_error_default(error);
358 /* Success! */
359 *outSuite = result;
360 return SJME_ERROR_NONE;
363 sjme_errorCode sjme_nvm_defaultDir(
364 sjme_attrInValue sjme_nvm_defaultDirectoryType type,
365 sjme_attrInNotNull const sjme_nal* nal,
366 sjme_attrOutNotNull sjme_lpstr outPath,
367 sjme_attrInPositiveNonZero sjme_jint outPathLen)
369 sjme_errorCode error;
370 sjme_lpcstr useEnv, insteadSub;
371 sjme_jint limit;
372 sjme_lpstr work;
374 if (nal == NULL || outPath == NULL)
375 return SJME_ERROR_NULL_ARGUMENTS;
377 if (type <= SJME_NVM_DEFAULT_DIRECTORY_UNKNOWN ||
378 type >= SJME_NVM_NUM_DEFAULT_DIRECTORY_TYPE)
379 return SJME_ERROR_INVALID_ARGUMENT;
381 if (outPathLen <= 0)
382 return SJME_ERROR_INDEX_OUT_OF_BOUNDS;
384 if (nal->getEnv == NULL)
385 return sjme_error_notImplemented(0);
387 /* Initialize. */
388 limit = (SJME_MAX_PATH > outPathLen ? SJME_MAX_PATH : outPathLen);
389 work = sjme_alloca(sizeof(*work) * limit);
390 if (work == NULL)
391 return SJME_ERROR_OUT_OF_MEMORY;
392 memset(work, 0, sizeof(*work) * limit);
394 #if defined(SJME_CONFIG_HAS_WINDOWS)
395 if (1)
396 sjme_todo("Impl?");
397 #elif defined(SJME_CONFIG_HAS_DOS)
398 if (1)
399 sjme_todo("Impl?");
401 #elif defined(SJME_CONFIG_HAS_LINUX) || \
402 defined(SJME_CONFIG_HAS_BSD) || \
403 defined(SJME_CONFIG_HAS_MACOS) || \
404 defined(SJME_CONFIG_HAS_CYGWIN)
406 /* Which are we interested in? */
407 useEnv = NULL;
408 insteadSub = NULL;
409 switch (type)
411 case SJME_NVM_DEFAULT_DIRECTORY_CACHE:
412 useEnv = "XDG_CACHE_HOME";
413 insteadSub = ".cache";
414 break;
416 case SJME_NVM_DEFAULT_DIRECTORY_CONFIG:
417 useEnv = "XDG_CONFIG_HOME";
418 insteadSub = ".config";
419 break;
421 case SJME_NVM_DEFAULT_DIRECTORY_DATA:
422 useEnv = "XDG_DATA_HOME";
423 insteadSub = ".local/share";
424 break;
426 case SJME_NVM_DEFAULT_DIRECTORY_STATE:
427 useEnv = "XDG_STATE_HOME";
428 insteadSub = ".local/state";
429 break;
431 /* Unknown. */
432 default:
433 return SJME_ERROR_INVALID_ARGUMENT;
436 /* Check if environment variable is available. */
437 if (sjme_error_is(error = nal->getEnv(
438 work, limit - 1, useEnv)))
440 /* This is not considered an error, we just try something else. */
441 if (error != SJME_ERROR_NO_SUCH_ELEMENT)
442 return sjme_error_default(error);
444 /* Get home variable instead, to add onto. */
445 memset(work, 0, sizeof(work));
446 if (sjme_error_is(error = nal->getEnv(
447 work, limit - 1, "HOME")))
448 return sjme_error_default(error);
450 /* Append subdirectory path. */
451 if (sjme_error_is(error = sjme_path_resolveAppend(work,
452 limit - 1, insteadSub, INT32_MAX)))
453 return sjme_error_default(error);
456 #else
457 return sjme_error_notImplemented(0);
458 #endif
460 /* Append SquirrelJME on top. */
461 if (sjme_error_is(error = sjme_path_resolveAppend(work,
462 limit - 1, SJME_DIRECTORY_NAME, INT32_MAX)))
463 return sjme_error_default(error);
465 /* Is there enough room to fit? */
466 limit = strlen(work) + 1;
467 if (limit > outPathLen)
468 return SJME_ERROR_PATH_TOO_LONG;
470 /* Copy it over. */
471 memmove(outPath, work, sizeof(*outPath) * limit);
472 return SJME_ERROR_NONE;
475 sjme_errorCode sjme_nvm_destroy(sjme_nvm state, sjme_jint* exitCode)
477 if (state == NULL)
478 return SJME_ERROR_NULL_ARGUMENTS;
480 /* Free sub-structures. */
481 if (SJME_JNI_TRUE)
482 sjme_todo("sjme_nvm_destroy()");
484 /* Free main structure. */
485 if (SJME_JNI_TRUE)
486 sjme_todo("sjme_nvm_destroy()");
488 /* Set exit code, if requested. */
489 if (SJME_JNI_TRUE)
490 sjme_todo("sjme_nvm_destroy()");
492 /* Finished. */
493 sjme_todo("sjme_nvm_destroy()");
494 return SJME_ERROR_NOT_IMPLEMENTED;
497 sjme_errorCode sjme_nvm_parseCommandLine(
498 sjme_attrInNotNull sjme_alloc_pool* inPool,
499 sjme_attrInNotNull const sjme_nal* nal,
500 sjme_attrInOutNotNull sjme_nvm_bootParam* outParam,
501 sjme_attrInPositiveNonZero sjme_jint argc,
502 sjme_attrInNotNull sjme_lpcstr* argv)
504 sjme_errorCode error;
505 sjme_jint argAt;
506 sjme_charSeq argSeq;
507 sjme_jboolean jarSpecified;
508 const sjme_nvm_helpParam* help;
509 sjme_nal_stdFFunc helpOut;
511 if (inPool == NULL || nal == NULL || outParam == NULL || argv == NULL)
512 return SJME_ERROR_NULL_ARGUMENTS;
514 if (argc <= 0)
515 return SJME_ERROR_INVALID_ARGUMENT;
517 /* Command line format is: */
518 jarSpecified = SJME_JNI_FALSE;
519 for (argAt = 1; argAt < argc; argAt++)
521 /* Setup sequence to wrap argument for parsing. */
522 memset(&argSeq, 0, sizeof(argSeq));
523 if (sjme_error_is(error = sjme_charSeq_newUtfStatic(
524 &argSeq, argv[argAt])))
525 return sjme_error_default(error);
527 /* -version */
528 if (sjme_charSeq_equalsUtfR(&argSeq,
529 "-version") ||
530 sjme_charSeq_equalsUtfR(&argSeq,
531 "--version"))
533 /* Where is this information going? */
534 helpOut = nal->stdErrF;
535 if (sjme_charSeq_equalsUtfR(&argSeq, "--version"))
536 helpOut = nal->stdOutF;
538 /* Print version information to stdout. */
539 /* https://www.oracle.com/java/technologies/javase/ */
540 /* versioning-naming.html */
541 helpOut(
542 "java version \"1.8.0\"\n");
543 helpOut(
544 "SquirrelJME Class Library, Micro Edition (build %s)\n",
545 SQUIRRELJME_VERSION);
546 helpOut(
547 "SquirrelJME NanoCoat VM (build %s, %s)\n",
548 SQUIRRELJME_VERSION, SQUIRRELJME_VERSION_NANOCOAT);
550 /* Exit. */
551 return SJME_ERROR_EXIT;
554 /* -help */
555 else if (sjme_charSeq_equalsUtfR(&argSeq,
556 "-?") ||
557 sjme_charSeq_equalsUtfR(&argSeq,
558 "-h") ||
559 sjme_charSeq_equalsUtfR(&argSeq,
560 "-help") ||
561 sjme_charSeq_equalsUtfR(&argSeq,
562 "--help"))
564 /* Where is this information going? */
565 helpOut = nal->stdErrF;
566 if (sjme_charSeq_equalsUtfR(&argSeq, "--help"))
567 helpOut = nal->stdOutF;
569 /* Normal usage. */
570 helpOut(
571 "Usage: %s [Options] <MainClass> [Args...]\n", argv[0]);
572 helpOut(
573 "Usage: %s [Options] -jar <Jar> [Args...]\n", argv[0]);
574 helpOut("\n");
576 /* And all the help parameters. */
577 helpOut("Options are:\n");
578 for (help = &sjme_nvm_helpParams[0]; help->arg != NULL; help++)
580 helpOut(" %s\n",
581 help->arg);
582 helpOut(" %s\n",
583 help->desc);
586 /* Exit. */
587 return SJME_ERROR_EXIT;
590 /* -Xclutter:(release|debug) */
591 else if (sjme_charSeq_startsWithUtfR(&argSeq,
592 "-Xclutter:"))
594 sjme_todo("Impl? %s", argv[argAt]);
597 /* -Xdebug */
598 else if (sjme_charSeq_equalsUtfR(&argSeq,
599 "-Xdebug"))
601 sjme_todo("Impl? %s", argv[argAt]);
604 /* -Xemulator:(vm) */
605 else if (sjme_charSeq_startsWithUtfR(&argSeq,
606 "-Xemulator:"))
608 sjme_todo("Impl? %s", argv[argAt]);
611 /* -Xentry:id */
612 else if (sjme_charSeq_startsWithUtfR(&argSeq,
613 "-Xentry:"))
615 sjme_todo("Impl? %s", argv[argAt]);
618 /* -Xjdwp:[hostname]:port */
619 else if (sjme_charSeq_startsWithUtfR(&argSeq,
620 "-Xjdwp:"))
622 sjme_todo("Impl? %s", argv[argAt]);
625 /* -Xlibraries:(class:path:...) */
626 else if (sjme_charSeq_startsWithUtfR(&argSeq,
627 "-Xlibraries:"))
629 sjme_todo("Impl? %s", argv[argAt]);
632 /* -Xscritchui:(ui) */
633 else if (sjme_charSeq_startsWithUtfR(&argSeq,
634 "-Xscritchui:"))
636 sjme_todo("Impl? %s", argv[argAt]);
639 /* -Xsnapshot:(path-to-nps) */
640 else if (sjme_charSeq_startsWithUtfR(&argSeq,
641 "-Xsnapshot:"))
643 sjme_todo("Impl? %s", argv[argAt]);
646 /* -Xthread:(single|coop|multi|smt) */
647 else if (sjme_charSeq_startsWithUtfR(&argSeq,
648 "-Xthread:"))
650 sjme_todo("Impl? %s", argv[argAt]);
653 /* -Xtrace:(flag|...) */
654 else if (sjme_charSeq_startsWithUtfR(&argSeq,
655 "-Xtrace:"))
657 sjme_todo("Impl? %s", argv[argAt]);
660 /* -Dsysprop=value */
661 else if (sjme_charSeq_startsWithUtfR(&argSeq,
662 "-D"))
664 sjme_todo("Impl? %s", argv[argAt]);
667 /* -classpath (class:path:...) */
668 else if (sjme_charSeq_equalsUtfR(&argSeq,
669 "-classpath"))
671 sjme_todo("Impl? %s", argv[argAt]);
674 /* -zero/-Xint */
675 else if (sjme_charSeq_equalsUtfR(&argSeq, "-zero") ||
676 sjme_charSeq_equalsUtfR(&argSeq, "-Xint"))
678 sjme_todo("Impl? %s", argv[argAt]);
681 /* -client/-server. */
682 else if (sjme_charSeq_equalsUtfR(&argSeq,
683 "-client") ||
684 sjme_charSeq_equalsUtfR(&argSeq, "-server"))
686 sjme_todo("Impl? %s", argv[argAt]);
689 /* -jar */
690 else if (sjme_charSeq_equalsUtfR(&argSeq, "-jar"))
692 /* We are using a Jar now. */
693 jarSpecified = SJME_JNI_TRUE;
695 sjme_todo("Impl? %s", argv[argAt]);
698 /* Invalid, fail. */
699 else
701 sjme_message("Invalid command line: %s",
702 argv[argAt]);
704 return SJME_ERROR_INVALID_ARGUMENT;
707 sjme_todo("impl?");
710 /* Launching a specific Jar? */
711 if (argAt < argc)
713 /* Main-class, if not -jar */
714 if (!jarSpecified)
716 sjme_todo("impl?");
719 /* Arguments... */
720 if (SJME_JNI_TRUE)
722 sjme_todo("impl?");
726 /* Default launching. */
727 else
729 outParam->mainArgs = NULL;
730 outParam->mainClass = NULL;
733 /* Success! */
734 return SJME_ERROR_NONE;