Commit c9d396b4 authored by Stephanie Gawroriski's avatar Stephanie Gawroriski
Browse files

Add new API base for the ability to launch commands with system properties and...

Add new API base for the ability to launch commands with system properties and console redirection as well.
parent 30da1dd0
......@@ -33,6 +33,9 @@ More detailed changes:
* `net.multiphasicapps.classfile.ExecutableCode`, not used.
* Additions
* `java.util.Vector`, was missing.
* Added proprietary `ExtendedTaskManager` interface which can be used
to specify arguments, system properties, and console output alternatives
to launched tasks.
* Programs and Libraries
* `demo-hello`
* Made the system properties array `final`.
......@@ -54,6 +57,8 @@ More detailed changes:
* Allow properties to be obtained from internally passed system
properties.
* Added string representation for the stack map table.
* Add ability to start tasks with command line arguments, system
properties, and alternative console redirection (to capture output).
* SpringCoat
* Add support for system properties being based to virtual machine
instances.
......
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package cc.squirreljme.runtime.cldc.asm;
import java.io.IOException;
/**
* This is the callback used for the console.
*
* @since 2019/02/02
*/
public interface ConsoleCallback
{
/**
* This is called when the stream has been closed.
*
* @return {@code false} if an {@link IOException} occurred.
* @since 2019/02/02
*/
public abstract boolean close();
/**
* This is called when the callback is flushed.
*
* @return {@code false} if an {@link IOException} occurred.
* @since 2019/02/02
*/
public abstract boolean flush();
/**
* Writes the specified bytes to the output.
*
* @param __b The bytes to write.
* @param __o The offset.
* @param __l The length.
* @return {@code false} if an {@link IOException} occurred.
* @since 2019/02/02
*/
public abstract boolean write(byte[] __b, int __o, int __l);
}
......@@ -97,6 +97,27 @@ public final class TaskAccess
public static final native int startTask(String[] __cp, String __main,
String[] __args);
/**
* Starts the specified task.
*
* @param __cp The classpath used.
* @param __main The main entry point.
* @param __args Arguments to start the task with.
* @param __sprops System properties in key/value pairs to pass to the
* target environment.
* @param __stdout Callback to receive standard output data, may be
* {@code null} to ignore.
* @param __stderr Callback to receive standard error data, may be
* {@code null} to ignore.
* @return The task identifier or a negative number if the task could
* not start.
* @since 2019/02/02
*/
@Api(ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV)
public static final native int startTask(String[] __cp, String __main,
String[] __args, String[] __sprops, ConsoleCallback __stdout,
ConsoleCallback __stderr);
/**
* Starts the given thread.
*
......
......@@ -66,5 +66,17 @@ public final class ApiLevel
__l % 1000,
2000 + ((__l / 1000) % 100));
}
/**
* Checks if the runtime API level is at a minimum this given level.
*
* @param __l The level to check.
* @return If the minimum level is met.
* @since 2019/02/02
*/
public static boolean minimumLevel(int __l)
{
return (SystemProperties.apiLevel() >= __l);
}
}
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package cc.squirreljme.runtime.swm;
import java.io.OutputStream;
import java.util.Map;
import javax.microedition.swm.Suite;
import javax.microedition.swm.Task;
/**
* This interface is used for providing the ability to launch tasks.
*
* @since 2019/02/02
*/
public interface ExtendedTaskManager
{
/**
* Attempts to create a task which runs the given suite.
*
* The task is created and is initially in the {@link TaskStatus#STARTING}
* state. If starting fails then it enters the
* {@link TaskStatus#START_FAILED} state.
*
* A suite may only be active once and cannot have multiple copies running
* at the same time. In the event that an application is already running it
* must be sent an event specifying an application re-launch.
*
* This is an extended method which allows more advanced control over the
* task such as including arguments, system properties, and potential
* output redirection.
*
* @param __s The suite to start, must be an application.
* @param __cn The class which extends
* {@link javax.microedition.midlet.MIDlet} and acts as the main entry
* point for the program.
* @param __sprops System properties to pass to the started task.
* @param __args Arguments to pass to the called program.
* @param __stdout Alternative {@link System#out}.
* @param __stderr Alternative {@link System#err}.
* @return The task which was created.
* @throws IllegalArgumentException If the suite is a library, the given
* class does not exist, or the given class does not extend
* {@link javax.microedition.midlet.MIDlet}.
* @throws IllegalStateException If the suite has been removed.
* @throws NullPointerException On null arguments.
* @since 2019/02/02
*/
public abstract Task startTask(Suite __s, String __cn,
Map<String, String> __sprops, String[] __args, OutputStream __stdout,
OutputStream __stderr)
throws IllegalArgumentException, IllegalStateException,
NullPointerException;
}
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
// Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------
package javax.microedition.swm;
import cc.squirreljme.runtime.cldc.asm.ConsoleCallback;
import java.io.IOException;
import java.io.OutputStream;
/**
* This is a wrapper for when a task writes to its console, this will be
* called which just forwards to the output stream specified.
*
* @since 2019/02/02
*/
final class __CCWrapper__
implements ConsoleCallback
{
/** The stream to forward to. */
protected final OutputStream out;
/**
* Initializes the wrapper to the given stream.
*
* @param __out The stream to write to.
* @throws NullPointerException On null arguments.
* @since 2019/02/02
*/
__CCWrapper__(OutputStream __out)
throws NullPointerException
{
if (__out == null)
throw new NullPointerException("NARG");
this.out = __out;
}
/**
* {@inheritDoc}
* @since 2019/02/02
*/
@Override
public final boolean close()
{
try
{
this.out.close();
return true;
}
catch (IOException e)
{
return false;
}
}
/**
* {@inheritDoc}
* @since 2019/02/02
*/
@Override
public final boolean flush()
{
try
{
this.out.flush();
return true;
}
catch (IOException e)
{
return false;
}
}
/**
* {@inheritDoc}
* @since 2019/02/02
*/
@Override
public final boolean write(byte[] __b, int __o, int __l)
{
try
{
this.out.write(__b, __o, __l);
return true;
}
catch (IOException e)
{
return false;
}
}
}
......@@ -11,9 +11,12 @@
package javax.microedition.swm;
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.runtime.cldc.lang.ApiLevel;
import cc.squirreljme.runtime.swm.DependencyInfo;
import cc.squirreljme.runtime.swm.ExtendedTaskManager;
import cc.squirreljme.runtime.swm.MatchResult;
import cc.squirreljme.runtime.swm.ProvidedInfo;
import java.io.OutputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
......@@ -21,6 +24,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
......@@ -33,7 +37,7 @@ import java.util.Set;
* @since 2017/12/07
*/
final class __SystemTaskManager__
implements TaskManager
implements ExtendedTaskManager, TaskManager
{
/** Mapping of task IDs to tasks. */
static final Map<Integer, Task> _TASKS =
......@@ -133,10 +137,42 @@ final class __SystemTaskManager__
public Task startTask(Suite __s, String __cn)
throws IllegalArgumentException, IllegalStateException,
NullPointerException
{
// Forward to the extended task start
return this.startTask(__s, __cn, null, null, null, null);
}
/**
* {@inheritDoc}
* @since 2019/02/02
*/
@Override
public final Task startTask(Suite __s, String __cn,
Map<String, String> __sprops, String[] __args, OutputStream __stdout,
OutputStream __stderr)
throws IllegalArgumentException, IllegalStateException,
NullPointerException
{
if (__s == null || __cn == null)
throw new NullPointerException("NARG");
// Defensive copies
__args = (__args == null ? new String[0] : __args.clone());
__sprops = (__sprops == null ? new HashMap<String, String>() :
new HashMap<String, String>(__sprops));
// Make sure values are actually valid
for (int i = 0, n = __args.length; i < n; i++)
if (__args[i] == null)
throw new NullPointerException("NARG");
for (Map.Entry<String, String> e : __sprops.entrySet())
{
String k = e.getKey(),
v = e.getValue();
if (k == null || v == null)
throw new NullPointerException("NARG");
}
// {@squirreljme.error DG0w Cannot start a non-application suite.}
if (__s.getSuiteType() != SuiteType.APPLICATION)
throw new IllegalArgumentException("DG0w");
......@@ -162,8 +198,33 @@ final class __SystemTaskManager__
// Debug
todo.DEBUG.note("Suites: %s", Arrays.<String>asList(names));
// Setup new task internally
int tid = TaskAccess.startTask(names, __cn, new String[0]);
// SquirrelJME 0.3.0 allows system properties and alternative output
// streams to be specified as well
int tid;
if (ApiLevel.minimumLevel(ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV))
{
// Copy system properties to key/value pair array
int spn = __sprops.size();
String[] xprops = new String[spn * 2];
Iterator<Map.Entry<String, String>> eit = __sprops.entrySet().
iterator();
for (int i = 0, o = 0; i < spn; i++, o += 2)
{
Map.Entry<String, String> e = eit.next();
xprops[o] = e.getKey();
xprops[o + 1] = e.getValue();
}
// Forward launch
tid = TaskAccess.startTask(names, __cn, __args, xprops,
(__stdout == null ? null : new __CCWrapper__(__stdout)),
(__stderr == null ? null : new __CCWrapper__(__stderr)));
}
else
tid = TaskAccess.startTask(names, __cn, __args);
// It did not work
if (tid < 0)
{
// {@squirreljme.error DG0x Invalid entry point was specified
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment