This chapter lists the user-visible changes in Urbi SDK releases.
Released on 2010-09-28.
- Date.asFloat is restored.
- File.create empties existing files first.
- Lobby.lobby always returns the current lobby, even if invoked on another lobby.
- Object.inspect works properly, even if the target is a remote lobby.
- Regexp.matchs renamed as Regexp.matches.
- System.version Really returns the current version.
- Fix multiple race conditions in RTP handling code preventing proper initialization of
remote UObjects.
- Fix Windows deployment to have both debug and release UObjects installed.
- Fix urbi-sound in the liburbi examples.
- Fix server mode of ‘urbi-launch --remote’.
- The documentation of Urbi SDK Remote, our middleware layer to communicate with an
Urbi server — either by hand or via the UObjects —, is included in the binary packages
(in ‘share/doc/urbi-sdk/sdk-remote.htmldir/index.html’. It is also available on-line
at http://www.gostai.com/downloads/urbi-sdk/2.3/doc/sdk-remote.htmldir.
- In addition to Gostai Console 2.5, Windows installers of Urbi SDK now include the Gostai
Editor 2.4.1.
- By popular demand, all the Boost libraries (1.38) are included in the binary packages. We
used to provide only the headers and libraries Urbi SDK depends upon. Boost.Python,
because it has too many dependencies, is not included.
- When launched with no input (i.e., none of the options ‘-e’/‘--expression’, ‘-f’/‘--file’,
‘-P’/‘--port’ were given), the interpreter is interactive.
- Assignment operators such as ’+=’ are redefinable. See Section 19.1.8.2.
- Date.’-’ accepts a Duration (Section 20.13) or a Float (Section 20.19) in addition to
accepting a Date (Section 20.10).
- Float.fresh generates unique integers.
- InputStream.close.
- List.’+=’.
- Support for else in try blocks (Section 19.7.2). Run only when the try block completed
properly.
try { riskyFeature } catch { false } else { true };
[00004220] false
function riskyFeature() { throw "die" }|;
try { riskyFeature } catch { false } else { true };
[00004433] false
riskyFeature = function () { 42 }|;
try { riskyFeature } catch { false } else { true };
[00004447] true
- Support for finally in try blocks (Section 19.7.4). Use it for code that must be run whatever
the control flow can be. For instance:
try { echo(1) } catch { echo(2) } else { echo(3) } finally { echo(4) };
[00002670] *** 1
[00002670] *** 3
[00002670] *** 4
try { throw 1 } catch { echo(2) } else { echo(3) } finally { echo(4) };
[00002671] *** 2
[00002671] *** 4
- System.eval and System.load report syntax warnings.
eval("new Object");
[00001388:warning] !!! 1.1-10: ‘new Obj(x)’ is deprecated, use ‘Obj.new(x)’
[00001388:warning] !!! called from: eval
[00001388] Object_0x1001b2320
- New functions as and fill on UVar to ease access to the generic cast system.
- Add support to boost::unordered_map to UObject casting system.
- Optimize remote UObjects: notifies between two objects in the same process instance are
transmitted locally.
- Provide a CustomUVar class to ease encapsulation of custom data in UVar.
- Bind the constant property on UVar.
Released on 2010-08-23.
- Pressing C-c in the urbiscript shell (‘urbi -i’) interrupts the foreground job, and clears the
pending commands. A second C-c in a row invokes System.shutdown, giving a chance to
the system to shut down properly. A third C-c kills urbi/urbi-launch. See Section 18.3.2
for more details.
- Closing the standard input (e.g., by pressing C-d) in interactive sessions shuts down the
server.
- Remote UObjects now support the RTP protocol to exchange value with the engine
(Section 3.15).
- NotifyChange/access callbacks can now take any type as argument. UVar& still has the
previous behavior. For any other type, the system will try to convert the value within the
UVar to this type.
- CallMessage.eval.
- Float.ceil, Float.floor, Float.isInf, Float.isNan.
- Traceable (Section 20.63).
- Improved context (the call stacks) when error are reported. Especially when using
System.eval/System.load.
- at (expression) — as opposed to at (event?) — implementation has been improved:
the condition will now be reevaluated even if a parameter not directly in the expression
(in the body of a called function, for instance) is modified.
- Regexp.matchs.
- Date (Section 20.10) objects now have microsecond resolution and have bit slightly
revamped to not rely on Unix’s epoch.
- UVars now have the timestamp of their latest assignment.
Released on 2010-07-08.
- Lobby.connectionTag monitors the jobs launched from the lobby, but can no longer kill
the lobby itself.
- ‘123foo’ is no longer accepted as a synonym to ‘123 foo’. As a consequence, in case you
were using x = 123cos: 1, convert it to x = 123 cos: 1.
- Some old tools that no longer make sense in Urbi SDK 2.0 have been removed:
umake-engine, umake-fullengine, umake-lib, umake-remote. Instead, use umake, see
Section 18.7.
- On Windows urbi-launch could possibly miss module files to load if the extension
(‘.dll’) was not specified. One may now safely, run ‘urbi-launch my-module’ (instead of
‘urbi-launch my-module.dll’ or ‘urbi-launch my-module.so’) on all the platforms.
- Regexp.asPrintable, Regexp.asString, Regexp.has.
- System.Platform.host, System.Platform.hostAlias, System.Platform.hostCpu,
System.Platform.hostOs, System.Platform.hostVendor.
- UObject init method and methods bound by notifyChange no longer need to return an
int.
- Channel.Filter, a Channel (Section 20.5) that outputs text that can be parsed without
error by the liburbi.
- RangeIterable.all, RangeIterable.any, moved from List (Section 20.30).
- Support for ROS, the Robot Operating System. See Listing 13 for an introduction, and
Section 21 for the details.
- Lobby.lobby and Lobby.instances, bounced to from System.lobby and
System.lobbies.
- Tag.scope, bounced to from System.scopeTag.
- The main loop was reorganized to factor all socket polling in a single place: latency of
Socket (Section 20.56) is greatly reduced.
Released on 2010-05-28.
- Container (Section 20.8), prototype for Dictionary (Section 20.11), List
(Section 20.30) derive.
- e not in c is mapped onto c.hasNot(e) instead of !c.has(e).
- Float.limits (Section 20.20)
- Job.asString
- IoService (Section 20.26)
- Event.’<<’
- List.argMax, List.argMin, List.zip
- Tuple.’+’
- Tuple.’*’
- Assertion failures are more legible:
var one = 1|;
var two = 2|;
assert (one == two);
[00000002:error] !!! failed assertion: one == two (1 != 2)
instead of
assert (one == two);
[00000002:error] !!! failed assertion: one.’==’(two)
previously. As a consequence, System.assert_op is deprecated. The never documented following
slots have been removed from System (Section 20.58): assert_eq, assert_ge, assert_gt,
assert_le, assert_lt, assert_meq, assert_mne, assert_ne.
Released on 2010-05-06.
- ‘make install’ failures are addressed.
- freezeif can be used more than once inside a scope.
Released on 2010-05-03.
- Minor bug fixes.
- The short option ‘-v’ is reserved for ‘--verbose’. Tools that mistakenly used ‘-V’ for
‘--verbose’ and ‘-v’ for ‘--version’ have been corrected (short options are swapped).
Use long options in scripts, not short options.
- Lobby.echoEach: new.
- String.closest: new.
- Tuple.size: new.
- Closures enclose the lobby. Now slots of the lobby in which the closure has been defined
are visible in functions called from the closure.
Released on 2010-04-09.
- Dictionary can now be created with literals.
|
|
| Syntax | Semantics |
|
|
| [ => ] | Dictionary.new |
| ["a" => 1, "b" => 2, "c" => 3] | Dictionary.new("a", 1, "b", 2, "c", 3) |
|
|
| |
- Float.srandom
- List.subset
- Object.getLocalSlot.
- String escapes accept one- and two-digit octal numbers. For instance "\0", "\00" and "\000" all
denote the same value.
- Tuple can now be created with literals.
|
|
| Syntax | Semantics |
|
|
| () | Tuple.new([]) |
| (1,) | Tuple.new([1]) |
| (1, 2, 3) | Tuple.new([1, 2, 3]) |
|
|
| |
- Location.’==’.
- type replaces ’$type’
- Remote timers (USetUpdate, USetTimer) are now handled locally instead of by the kernel.
- UVars can be copied using the UVar.copy method.
- New UEvent class, similar to UVar. Can be used to emit events.
- Added support for dictionaries: new UDictionary structure in the UValue union.
Released on 2010-01-29.
- ’$id’ replaces id
- List derives from Orderable.
- The UObject API is now thread-safe: All UVar and UObject operations can be performed
from any thread.
- You can request bound functions to be executed asynchronously in a different thread by
using UBindThreadedFunction instead of UBindFunction.
Released on 2010-01-13.
- ‘local.u’ works as expected.
- Lobby.quit replaces System.quit.
- Socket.connect accepts integers.
- UObject remote notifyChange on USensor variable now works as expected.
- UObject timers can now be removed with UObject::removeTimer().
- Socket (Section 20.56) provides a complete example.
- The Naming Standard documents the support classes provided to ease creation of the
component hierarchy.
Released on 2009-11-30.
This release candidate includes many fixes and improvements that are not reported below. The
following list is by no means exhaustive.
The urbiscript engine was considerably optimized in both space and time.
- assert { claim1; claim2;... };
- every|
- break and continue are supported in every| loops.
- for(num) and for(var i: set) support the for&, for| and for; flavors.
- for(init; cond; inc) supports the for| and for; flavors.
- non-empty lists of expressions in list literals, in function calls, and non-empty lists of
function formal arguments may end with a trailing optional comma. For instance:
function binList(a, b,) { [a, b,] } | binList(1, 2,)
is equivalent to
function binList(a, b) { [a, b] } | binList(1, 2)
- consecutive string literals are joined into a unique string literal, as in C ++.
- at constructs do not leak local variables anymore.
- Each tag now has its enter and leave events.
- File.content reads the whole file.
- Invalid assignments such as f(x) = n are now refused as expected.
- Handle UObject destruction. To remove an UObject, call the urbiscript destroy method.
The corresponding C ++ instance will be deleted.
- Add UVar::unnotify(). When called, it removes all UNotifyChange registered with the
UVar.
- Bound functions using UBindFunction can now take arguments of type UVar& and
UObject*. The recommended method to pass UVars from urbiscript is now to use
‘camera.getSlot("val")’ instead of ‘"camera.val"’.
- Add a 0-copy mode for UVars: If ‘UVar::enableBypass(true)’ is called on an UVar,
notifyChange on this UVar can recover the not-copied data by using UVar.get(), returning
an UValue&. However, the data is only accessible from within notifyChange: reading the
UVar directly will return nil.
- Add support for the changed! event on UVars. Code like:
at (headTouch.val->changed? if headTouch.val)
tts.say("ouch");
will now work. This hook costs one at per UVar, and can be disabled by setting
UVar.hookChanged to false.
- Add a statistics-gathering tool. Enable it by calling ‘uobjects.enableStats(true)’. Reset
counters by calling ‘uobjects.clearStats’. ‘uobjects.getStats’ will return a dictionary of all
bound C ++ function called, including timer callbacks, along with the average, min, max call
durations, and the number of calls.
- When code registered by a notifyChange throws, the exception is intercepted to protect other
unrelated callbacks. The throwing callback gets removed from the callback list, unless the
removeThrowingCallbacks on the UVar is false.
- the environment variable URBI_UOBJECT_PATH is used by urbi-launch and urbiscript’s loadModule
to find uobjects.
- fixed multiple notifications of event trigger in remote UObjects.
- Many other bug fixes and performance improvements.
- an exception is now thrown if the C++ init method failed.
The documentation was fixed, completed, and extended. Its layout was also improved. Changes
include, but are not limited to:
- various programs: urbi, urbi-launch, urbi-send etc. (Section 18).
- environment variables: URBI_UOBJECT_PATH, URBI_PATH, URBI_ROOT (Section 18.1).
- special files ‘global.u’, ‘local.u’ (Section 18.2).
- k1-to-k2: Conversion idioms from urbiscript 1 to urbiscript 2 (Section 16).
- FAQ (Section 15)
- stack exhaustion
- at and waituntil: performance considerations
- Specifications:
- tutorial:
- Text files are converted to DOS end-of-lines for Windows packages.
- urbi-send supports ‘--quit’.
- The files ‘global.u’/‘local.u’ replace ‘URBI.INI’/‘CLIENT.INI’.
- urbi supports ‘--quiet’ to inhibit the banner.
Released on 2009-04-03.
- urbi-send no longer displays the server version banner, unless given ‘-b’/‘--banner’.
- urbi-console is now called simply urbi.
- urbi.bat should now work out of the box under windows.
The keyword emit is deprecated in favor of !.
|
|
| Deprecated | Updated |
|
|
| emit e; | e!; |
| emit e(a); | e!(a); |
| emit e ~ 1s; | e! ~ 1s; |
| emit e(a) ~ 1s; | e!(a) ~ 1s; |
|
|
| |
The ? construct is changed for symmetry.
|
|
| Deprecated | Updated |
|
|
| at (?e) | at (e?) |
| at (?e(var a)) | at (e?(var a)) |
| at (?e(var a) if 0 <= a) | at (e?(var a) if 0 <= a) |
| at (?e(2)) | at (e?(2)) |
| |
This syntax for sending and receiving is traditional and can be found in various programming
languages.
- Under some circumstances successful runs could report ”at job handler exited with
exception TerminateException”. This is fixed.
- Using waituntil on an event with no payload (i.e., waituntil(e?) ...;) will not cause
an internal error anymore.
The API for plugged-in UObjects is not thread safe, and never was: calls to the API must be done only
in the very same thread that runs the Urbi code. Assertions (run-time failures) are now triggered for
invalid calls.
Extended documentation on: Comparable (Section 20.7), Orderable (Section 20.38).
Released on 2009-03-03.
An initial sketch of documentation (a tutorial, and the language and library specifications) is
included.
- Bitwise operations.
The native ”long unsigned int” type is now used for all the bitwise operations (&, |, ^,
compl, <<, >>). As a consequence it is now an error to pass negative operands to these
operations.
- System.PackageInfo.
This new object provides version information about the Urbi package. It is also used to
ensure that the initialization process uses matching Urbi and C ++ files. This should prevent
accidental mismatches due to incomplete installation processes.
- Precedence of operator **.
In conformance with the usage in mathematics, the operator ** now has a stronger
precedence than the unary operators. Therefore, as in Perl, Python and others, ’-2 ** 2
== -4’ whereas it used to be equal to ’4’ before (as with GNU bc).
- whenever now properly executes the else branch when the condition is false. It used to
wait for the condition to be verified at least once before.
The environment variable URBI_ROOT denotes the directory which is the root of the tree
into which Urbi was installed. It corresponds to the ”prefix” in GNU Autoconf parlance,
and defaults to ‘/usr/local’ under Unix. urbiscript library files are expected to be in
ˇURBI_ROOTż/share/gostai/urbi.
The environment variable URBI_PATH, which allows to specify a colon-separated list of directories
into which urbiscript files are looked-up, may extend or override URBI_ROOT. Any superfluous colon
denotes the place where the URBI_ROOT path is taken into account.
To enable writing (batch) scripts seamlessly in Urbi, urbi-console ‘-f’/‘--fast’ is now renamed
as ‘-F’/‘--fast’. Please, never use short options in batch programs, as they are likely to
change.
Two new option pairs, ‘-e’/‘--expression’ and ‘-f’/‘--file’, plus the ability to reach the
command line arguments from Urbi make it possible to write simple batch Urbi programs. For
instance:
$ cat demo
cout << System.arguments;
shutdown;
$ ./demo 1 2 3 | grep output
[00000004:output] ["1", "2", "3"]
urbi-console is now a simple wrapper around urbi-launch. Running
urbi-console arg1 arg2...
is equivalent to running
urbi-launch --start -- arg1 arg2...
The command line interface of urbi-sendbin has been updated. urbi-send now supports
‘-e’/‘--expression’ and ‘-f’/‘--file’. For instance
$ urbi-send -e ’var x;’ -e "x = $value;" -e ’shutdown;’
Released on 2009-01-05.
A new document, ‘FAQ.txt’, addresses the questions most frequently asked by our users during the
beta-test period.
- If a file loaded from ‘URBI.INI’ cannot be found, it is now properly reported.
-
- new syntax revamped
The syntax ”new myObject(myArgs)” has been deprecated and now gives a warning. The
recommended ”myObject.new(myArgs)” is suggested.
-
- delete has been removed
delete was never the right thing to do. A local variable should not be deleted, and a
slot can be removed using Object.removeSlot. The construct ”delete object” has been
removed from the language.
-
- __HERE__
The new __HERE__ pseudo-symbol gives the current position. It features three self
explanatory slots: ”file”, ”line”, and ”column”.
-
- Operator ”()”
It is now possible to define the ”()” operator on objects and have it called as soon as at
least one parameter is given:
class A {
function ’()’ (x) { echo("A called with " + x) };
}|;
A;
[00000001] A
A();
[00000002] A
A(42);
[00000003] *** A called with 42
-
- catch(type name syntax removed
It was used to catch exceptions if and only if they inherited type. This behavior can be obtained
with the more general guard system:
catch (var e if e.isA(<type>))
{
...
}
-
- Pattern matching and guards in catch blocks
Exception can now be filtered thanks to pattern matching, just like events. Moreover, the pattern
can be followed by the ”if” keyword and an arbitrary guard. The block will catch the exception
only if the guard is true.
try
{ ... }
catch ("foo")
{ ... }
catch (var x if x.isA(Float) && x > 10)
{ ... }
catch (var e)
{ ... }
-
- Parsing of integer literals
The parser could not read integer literals greater than 2**31-1. This constraint has been
alleviated, and Urbi now accepts integer literals up to 2**63-1.
-
- Display of integer literals
Some large floating point values could not be displayed correctly at the top level of the
interpreter. This limitation has been removed.
-
- Variables binding in event matching
Parentheses around variables bindings (”var x”) are no longer required in event matching:
at (?myEvent(var x, var y, 1))
instead of:
at (?myEvent((var x), (var y), 1))
-
- Waituntil and bindings
Bindings performed in ”waituntil” constructs are now available in its context:
waituntil(?event(var x));
echo (x);
-
- ”List.insert” method
Now uses an index as its first argument and inserts the given element before the index
position:
["a", "b", "c"].insert(1, "foo");
[00000001] ["a", "foo", "b", "c"]
-
- ”List.sort” method
Now takes an optional argument, which is a function to call instead of the ”ˇ” operator. Here are
two examples illustrating how to sort strings, depending on whether we want to be case-sensitive
(the default) or not:
["foo", "bar", "Baz"].sort;
[00000001] ["Baz", "bar", "foo"]
["foo", "bar", "Baz"].sort(function(x, y) {x.toLower < y.toLower});
[00000002] ["bar", "Baz", "foo"]
-
- ”System.searchPath” method
It is now possible to get the search path for files such as ‘urbi.u’ or ‘URBI.INI’ by using
System.searchPath.
-
- ”System.getenv” method
Now returns ”nil” if a variable cannot be found in the environment instead of ”void”. This allows
you do to things such as:
var ne = System.getenv("nonexistent");
if (!ne.isNil) do_something(ne);
while previously you had to retrieve the environment variable twice, once to check for its
existence and once to get its content.
-
- ”Control.disown”
It is now possible to start executing code in background while dropping all the tags beforehand,
including the connection tag. The code will still continue to execute after the connection that
created it has died.
-
- ”Object.removeSlot”
Now silently accepts non-existing slot names instead of signaling an error.
-
- ”Semaphore.criticalSection”
It is now possible to define a critical section associated with a semaphore. The Semaphore.acquire
method will be called at the beginning, and if after that the operation is interrupted by any
means the Semaphore.release operation will be called before going on. If there are no
interruption, the Semaphore.release operation will also be called at the end of the
callback:
var s = \refSlot[Semaphore]{new}(1);
s.criticalSection(function () { echo ("In the critical section") });
-
- ”System.stats” Its output is now expressed in seconds rather than milliseconds, for consistency with
the rest of the kernel.
-
void
- The error message given to the user trying to cast a void UVar has been specialized.
Remote bound methods can now return void.
-
Coroutine interface
-
The functions yield(), yield_until(), and yield_until_things_changed() have been
added to the UObject API. They allow the user to write plugin UObject code that behaves
like any other coroutine in the kernel: if yield() is called regularly, the kernel can continue to
work while the user code runs. Meaningful implementation for these functions is provided
also in remote mode: calling yield() will allow the UObject remote library to process
pending messages from within the user callback.
-
Remote UObject initialization
-
Remote UObject instantiation is now atomic: the API now ensures that all variables and
functions bound from the UObject constructor and init are visible as soon as the UObject
itself is visible. Code like:
waituntil(uobjects.hasSlot("MyRemote")) | var m = \refSlot[MyRemote]{new}();
is now safe.
-
urbi-launch
- Now, options for urbi-launch are separated from options to give to the underlying
program (in remote and start modes) by using ‘--’. Use ‘urbi-launch --help’ to get the
full usage information.
Released on 2008-11-03.
-
- ”object” and ”from” as identifiers
”object” and ”from” are now regular identifiers and can be used as other names. For
example, it is now legal to declare:
var object = 1|;
var from = 1|;
-
- Hexadecimal literals It is now possible to enter (integral) hexadecimal numbers by prefixing them
with ”0x”, as in:
Only integral numbers are supported.
-
- String.asList
”String” now has a ”asList” method, which can be used transparently to iterate over the
characters of a string:
for (var c: "foo") echo (c);
[00000001] *** f
[00000002] *** o
[00000003] *** o
-
- String.split method Largely improved.
-
- ”min” and ”max”
It is now possible to call ”min” and ”max” on a list. By default, the ”ˇ” comparison operator is
used, but one explicit ‘lower than’ function can be provided as ”min” or ”max” argument should
one be needed. Here is an example on how to compare strings in case-sensitive and
case-insensitive modes:
["the", "brown", "Fox"].min;
[00000001] "Fox"
["the", "brown", "Fox"].min(function (l, r) { l.toLower < r.toLower });
[00000002] "brown"
Global functions ”min” and ”max” taking an arbitrary number of arguments have also been
defined. In this case, the default ”ˇ” operator is used for comparison:
min(3, 2, 17);
[00000001] 2
-
- Negative indices
It is now possible to use negative indices when taking list elements. For example, -1 designates
the last element, and -2 the one before that.
["a", "b", "c"][-1];
[00000001] "c"
-
- Tag names
Tags were displayed as Tag_0xADDR which did not make their ”name” slot apparent. They are
now displayed as ”Tagˇnameż”:
Tag.new;
[00000001] Tag<tag_1>
Tag.new("mytag");
[00000002] Tag<mytag>
-
- ”every” and exceptions
If an exception is thrown and not caught during the execution of an ”every” block, the ”every”
expression is stopped and the exception displayed.
-
- ”UVar::type()” method
It is now possible to get the type of a ”UVar” by calling its ”type()” method, which returns
a ”UDataType” (see ‘urbi/uvalue.hh’ for the types declarations).
-
- Stack exhaustion check on Windows
As was done on GNU/Linux already, stack exhaustion condition is detected on Windows,
for example in the case of an infinite recursion. In this case, SchedulingError will be raised
and can be caught.
-
- Errors from the trajectory generator are propagated
If the trajectory generator throws an exception, for example because it cannot assign
the result of its computation to a non-existent variable, the error is propagated and the
generator is stopped:
xx = 20 ampli:5 sin:10s;
[00002140:error] !!! lookup failed: xx
-
- Support for Windows shares
Previous versions of the kernel could not be launched from a Windows remote directory
whose name is starting with two slashes such as ‘//share/some/dir’.
-
- Implement ”UVar::syncValue()” in plugged uobjects
Calling ”syncValue()” on a ”UVar” from a plugged UObject resulted in a link error. This
method is now implemented, but does nothing as there is nothing to do. However, its
presence is required to be able to use the same UObject in both remote and engine modes.
-
- ”isdef” works again
The support for k1 compatibility function ”isdef” was broken in the case of composed
names or variables whose content was ”void”. Note that we do not recommend using ”isdef”
at all. Slots related methods such as ”getSlot”, ”hasSlot”, ”locateSlot”, or ”slotNames”
have much cleaner semantics.
-
- ”__name” macro
In some cases, the __name macro could not be used with plugged uobjects, for example in
the following expression:
send(__name + ".val = 1;");
This has been fixed. __name contains a valid slot name of uobjects.
The sample programs demonstrating the SDK Remote, i.e., how to write a client for the Urbi
server, have been renamed from urbi* to urbi-*. For instance urbisend is now spelled
urbi-send.
Besides, their interfaces are being overhauled to be more consistent with the Urbi command-line
tool-box. For instance while urbisend used to require exactly two arguments (host-name, file to send),
it now supports options (e.g., ‘--help’, ‘--port’ to specify the port etc.), and as many files as provided
on the command line.