.\"Copyright(C) 1990, Marcus J. Ranum,  All rights reserved.
.\"The author would like to thank Andrew Molitor for proof-reading and
.\"critical evaluation.
.\" macros
.\" example start
.de EX
.sp
.ft B
.fl
.nf
.na
..
.\" example end
.de XE
.sp
.ft R
.fi
.ad
..
.\" end macros
.hy 0
.EH 'U Programming Language
.OH '\(C)Copyright, Marcus J. Ranum, 1990
.TL
The U Programming Language
.SH
Introduction.
.PP
The U programming language (hereafter referred to as simply \fIU\fR) is
a simple language reminiscent of C or awk. This document is intended
as a 'quick start' guide, rather than a formal language definition,
since it is expected that the language will be constantly changing and
evolving.
.NH 0
Hello World
.PP
The primary means of sending text output to a user's terminal in U
is via the \fIecho\fR command and its relative \fIechoto\fR. Echo
echoes its arguments back to the caller, performing type conversion
on numeric values, etc. C-like escape sequences are recognized:
.EX
echo("hello world!\\n");
.XE
will print "hello world!" followed by a newline. Unlike C, there is
no need for a main() function to call. Commands can be executed
inside or outside of a function.
.EX
echo("two plus two = ",2 + 2);
.XE
will print "two plus two = 4", with echo converting the numeric value
generated by the arithmetic expression into a text string automatically.
echo places no reasonable limit on the number of parameters that can
be passed to it in one call; everything is printed in order, left to
right.
.NH 1
Variables
.NH 2
Variable Types and Data Types
.PP
Variables in U can be of several types. The interpreter hides the
details of the types from the user to the greatest possible extent.
Currently, the existing types are as follows:
.sp
\(bu Numbers - the basic numeric type in U is the integer. In fact,
there is no provision for floating point numbers at all. Typical
numerical operations such as division, multiplication, addition &c
can be performed on numbers.
.sp
\(bu Strings - the string type in U is a simple chunk of text, with
the interpreter handling storage allocation (unlike C) for the 
programmer. Numeric operations are \fBNOT\fR permitted on strings,
with the exception of the \fIequality\fR operator.
.sp
\(bu NULL - the data value NULL in U is a special data type of its
own. Unlike C, it does not mean zero - it means \fInonexistence\fR.
NULL is provided for many reasons, primarily being error checking,
and to provide a fixed 'magic' value that programmers can use.
Many of U's internal operators return NULL in the event of an error,
or invalid argument. In reality there is an error value that can
be attached to NULL, and accessed by the user, allowing a user to
determine exactly why their operation resulted in a NULL. Examples
of operations that can result in NULL are: calling a non-function 
as if it were a function, attempting to access a non-existent
variable, and attempting to use a function parameter that was not
passed to a function.
.sp
\(bu Objects - an object in U is a numbered entity to which smaller
variables (called \fIelements\fR) can be bound. It is the
basic "star stuff" of a Ubermud universe. Objects are always referred
to by number, preceded with a sharp, or \fI'#'\fR symbol. There is
a special object - the \fIsystem\fR object, which can be abbreviated
with the \fI'@'\fR symbol. This is always object #0, but using
the '@' syntax is preferred, since it is clearer.
.sp
\(bu Lists - a list is an array of object numbers. There are functions
that manipulate, search, add to, and delete from lists. The list is
used heavily in implementing a universe, since lists contain contents
of rooms, player inventories, and so forth. There is no heterogenous
array type in U (due to the complexity of implementing it), so lists
may only consist of object numbers. This is less of a drawback than
it may seem, since arrays of strings can easily be gotten at indirectly
through the object number.
.sp
\(bu Functions - a function or procedure is actually a primary data
type in U. This permits assigning of functions to variables, and
calling the function through that variable. This can lead to confusing
or very powerful code, depending on how wisely it is used. There are
some restrictions on the use of functions and their declaration, that
are discussed later. Functions can be passed as parameters to other
functions, assigned to temporary variables, or assigned to object
elements, which are described in greater detail later.
.NH 2
Temporary Variables
.PP
In U, a temporary variable can be used to store volatile information.
The temporary disappears after the function that it is in is terminated.
The advantages of temporaries is that they are quick and allocation and
deallocation of them is handled by the system. Due to their ephemeral
nature, however, they cannot be used outside of functions, without
disappearing immediately. Temporaries CAN be made to last outside of
functions by enclosing the desired block of code in curly braces:
.EX
{
	$tmp = strtime();
	echo("$tmp is:",$tmp,"\\n");
}
.XE
Here $tmp is set to whatever the function \fIstrtime\fR returns (a string
form of the system clock), and is later handed to echo for printing.
.NH 2
Function Parameters
.PP
In U, a function can be passed an arbitrary number of parameters.
Unlike C, where the parameters are named, the parameters in a U
function are accessed with $-number syntax, similar to the Bourne
shell's. A second function parameter variable $# contains the
parameter count (zero being none). This allows a function to access
its parameters without having to name or type variables:
.EX
func @.foo
{
	if($# > 0)
		echo("the first parameter is \\"",$1,"\\"\\n");
}

@.foo("bar!");
.XE
Here a function is called with one parameter. A check against the 
parameter count is made, and if there is a parameter, the first
one is printed. The example above produces the following output:
.EX
the first parameter is "bar!"
.XE
note the escaped quotes preceded by the '\\' character in the
parameters to echo.
.PP
It is forbidden to use the parameter variables outside a function;
attempting to do so will abort compilation of the program at that
point.
.NH 2
Elements
.PP
The element is the most important type of variable in U, and will
be gone into in greater depth later. Elements are formed of an 
object number, and the name of a variable stored in that object.
An object can have any number of elements stored in it, provided 
they are all uniquely named. Some examples of elements are:
.EX
	#44.foo;
	@.fuzzy;
	#55.this.that;
.XE
The \fI@.fuzzy\fR syntax is an example of using '@' to specify the
system object. It could be written as \fI#0.fuzzy\fR as well.
In the case of \fI#55.this.that\fR, there is a level of indirection
added. When the value is presented to the interpreter, the interpreter
will first check the contents of \fI#55.this\fR. If \fI#55.this\fR is
itself an object number, it will then search the contents of that
object for variable name \fIthat\fR. This can be done to any number
of levels, though there will not likely be need for more than one or
two levels of indirection. If a variable in an indirection is not
an object number, or does not exist, then a "badly formed object specifier"
error is generated. For example:
.EX
	#55.foo = 666;
	#44.bar = #55;
	echo("indirecting:",#44.bar.foo,"\\n");
.XE
Will print:
.EX
	indirecting:666
.XE
Since the object number #55 is stored in #44.bar, which is looked
up first, reducing #44.bar.foo to #55.foo, which is in turn looked
up, giving the number 666.
.PP
An element can be a value of the type of any of the data types permitted
in U. Elements are treated essentially as variables in expressions:
.EX
	#44.foo = 12;
	$tmp = 2; 
	#55.bar = #44.foo * $tmp;
.XE
But they can just as easily be treated as functions:
.EX
	#33.bar("this is a test\\n");

	$tmp = #33.bar;
	$tmp("this is a test\\n");
.XE
In both of the examples above, the function stored in \fI#33.bar\fR is
called with the message: "this is a test\\n".
.NH 2
Accessing Elements Via Strings
.PP
Elements can be accessed by coercing a string into the name of an
object's element. This is done by providing an arbitrary expression
which returns a string in the object element specifier:
.EX
	#33.("foo") = 55;
.XE
The program above would convert the string value \fI"foo"\fR into
an element name and search #33 for it. Parenthesized expressions can
be mixed at will with other element names:
.EX
	#33.foo.("bar") = 55;
	$array = 1;
	echo(#33.(str("foo",$array)));
.XE
In the examples above, \fI#33.foo.bar\fR would be set to 55, and in the
second \fI#33.foo1\fR would be echoed. Note that there are some restrictions
on string to variable coercion. The maximum length of an element name is
less than the maximum length of a string, and attempts to coerce a name
that is too long will automatically set the value to NULL. If the expression
fails to return a string, the element name formation fails, and the value
is set to NULL.
.PP
While string-to-variable coercion is a powerful function, it is also
an indicator of a failing in the design of the language that encompasses it.
In the case of U, string-to-variable coercion is incorporated to get
around the lack of support for heterogenous arrays. Programmers are
urged to use string-to-variable coercion sparingly, if at all, and
primarly to use it as a means of examining things from the command line.
.NH 2
Making Elements Go Away
.PP
Elements attached to an object can be de-assigned (annihilated) by
assigning them to NULL. This frees their storage in the database, and
removes them from the index. Objects themselves cannot be destroyed
in this simple manner.
.NH 1
Functions
.NH 2
Basics of Functions
.PP
A U function is similar to a C function in that it can take a list of
parameters of varying types, and return a single value. \fIUn\fRlike
C, U does not have a notion of pointers as parameters, so it is
difficult for a U function to modify something passed as a parameter.
Furthermore, unlike C, U functions cannot modify the values of their
numbered parameters. Assignments to \fI$1-N\fR or \fI$#\fR are syntax
errors, and abort compilation. Functions that do not explicitly return
a value return NULL(function returned no value) to the caller, if
the value of the function is taken. Functions can return any legitimate
U data type, including other functions.
.NH 2
Declaring a Function
.PP
A function is declared in the form of:
.EX
func #object-number . name
{
	statements;
}
.XE
The object-number may be '@', if the function is to be attached to the
system object, but otherwise it must be the number of an existing object
that the programmer has permission to write to. The curly braces are
optional, and may be omitted if the function is a single
statement. Take this simple function:
.EX
func #33.days
{
	$tmp = $1 * 24 * 60 * 60;
	echo("in ",$1," days, it will be ",strtime($tmp),"\\n");
}
.XE
which prints what it will be in a number of days passed to the
function as a parameter. Obviously, the function should check for
the existence of a parameter, since $1 will be NULL if it was
called with no parameters.
.NH 2
Returning From a Function
.PP
In the example of \fI#33.days\fR above, the function "drops off the end"
of the code. This causes the function to return to the caller, and leaves
the value NULL for the calling function to access, should it so desire.
A specific value can be returned to the caller using the return operator,
or NULL can be specifically returned to indicate an error. To simplify
this instance, the return operator can be used without a value, implicitly
returning NULL.
.EX
func #33.bad
{
	if($# != 3) {
		echo("three arguments expected!\\n");
		return;
	}
	return($1 + $2 + $3);
}

echo(#33.bad(4,5),"\\n");

echo(#33.bad(4,5,6),"\\n");
.XE
This overly simplistic example checks its argument count, and 
returns its parameters added together. In the first case where it
is called above with two parameters, the error message will be
printed, and NULL will be returned. \fIecho\fR quietly refuses to
print NULL (since NULL does not exist), so there would be be a
newline printed, but no other output than the error message.
In the second call, the function returns 15, which is passed
to \fIecho\fR, and is printed, with the newline.
.NH 1
Conditionals
.PP
U's conditionals are the \fIif\fR and \fIelse\fR syntax so
familiar to C programmers. Conditionals take the form of:
.EX
if ( expression )
	statements;

if ( expression )
	statements1;
else
	statements2;
.XE
The expression can be any legal U expression. If the expression evaluates
to a non-empty string, or a non-zero numeric value, the statement following
is executed. In the \fIif-else\fR syntax, the second set of statements
are executed in the case that the condition of the first failed. U has
the C-like boolean operators \fI'&&'\fR and \fI'||'\fR, \fIand\fR
and \fIor\fR, respectively. As in C, \fIif\fR statements can be cascaded
and nested.
.PP
One crucial difference exists between C and U if statements: unlike in
C, \fBall\fR the clauses in the conditional are evaluated (C stops when
the condition is manifestly true or false). Thus:
.EX
if(foo() && bar()) {
	...
}
.XE
will evaluate foo() and bar() \fIboth\fR, while in C, bar() will never be
called if foo() returns 0.
.NH 1
For Statements
.NH 2
Problems With For Statements, While Loops, and Recursion
.PP
U does not have C-like \fIfor\fR and \fIwhile\fR statments, since they
permit a programmer to write code that loops eternally. This is
intolerable in a multi-user game, and, in fact, they turn out to be
unnecessary. Another problem is recursive functions, or functions
that call each other endlessly back and forth. The U interpreter
handles these simply by permitting recursion until the reasonably
large internal stack is overflowed, and then returning NULL when
any further function calls are attempted. This effectively halts
the recursion, causing it to "unwind" itself normally. Obviously, a
function that recursively generates a huge amount of text output
will still be a tremendous annoyance, but controlling such things
cannot be done within the software.
.NH 2
Syntax of For Statements
.PP
Since a MUD deals primarily with lists of things, U
has syntax for iterating across lists, and across the parameters
to a function. The syntax of for loops takes two forms:
.EX
	for $tmp in ( expression-returning a list)
		statements;

	foreacharg $tmp
		statements;
.XE
In the first case, the temporary variable \fI$tmp\fR is successively
set to each element number for every element on the list. If the expression
fails to return a list, or returns an empty list, the statements are
not executed at all. In the \fIforeacharg\fR loop, the value
of \fI$tmp\fR is successively set to each parameter that the
function was called with. \fIforeacharg\fR cannot be used outside of
a function, as this is a syntax error. In the following example:
.EX
	#11.str = "string 1";
	#22.str = "string 2";
	#33.str = "string 3";
	#33.list = listnew(#11,#22,#33);

	foreach $tmp in (#33.list) {
		echo($tmp,".str is:",$tmp.str);
	}
.XE
This creates a list containing the object numbers #11, #22, and #33, and
iterates across the list, printing (successively) the values of #11.str,
#22.str, and #33.str. In the next example:
.EX
func #33.bar
{
	$cnt = 0;
	foreacharg $tmp {
		$cnt = $cnt + 1;
		echo("parameter ",$cnt,"=",$tmp,"\\n");
	}
	echo("total parameters:",$cnt,"\\n");
}

#33.bar(4,"foo",strtime());
.XE
The following is printed:
.EX
parameter 1=4
parameter 2=foo
parameter 3=Fri May 11 16:24:21 EDT 1990
total parameters:3
.XE
.NH 1
References
.NH 2
Generating References
.PP
U stores all objects and object elements except for those in the system
table (#0) in a database with an index. A reference is used in U to make
two or more index entries that "point" at the same basic object. This
allows objects that wish to share the same element values to do it
easily, and provides performance advantages as well as saving storage
space. Additionally, references are used in some internal built-in
functions to manipulate index entries for permissions and ownership
purposes. A reference to an object element is generated by placing
and ampersand \fI'&'\fR character before the name of the element. EG:
.EX
	&#33.foo;
	&$tmp.foo;
	&#44.bar.baz;
	&@.froz;
.XE
All of these are examples of legal references. It is not legal syntax
to take a reference of anything but an object element. IE:
.EX
	!
	&$tmp;
	&@;
.XE
are all illegal references, producing syntax errors at compile-time.
.NH 2
Assigning to References
.PP
When an assignment is made to a reference, instead of saving a copy of
the data, a pointer to the copy of the data is saved. It must be
emphasized that this is NOT a performance expensive operation, rather
the contrary. For all intents and purposes, a referenced object is
exactly the same as any other stored object. When an assignment is
made to a referenced element, the contents of the reference are NOT
overwritten, the reference is broken, and new storage is allocated
for the assigned element. For example:
.EX
	#33.foo = "foo!";
	#44.foop = &#33.foo;
	echo(#33.foo,#44.foop,"\\n");

	#44.foop = "bar!";
	echo(#33.foo,#44.foop,"\\n");
.XE
The first time echo prints: "foo!foo!" followed by a newline. The second
call to echo prints "foo!bar!" followed by a newline. In certain cases it
may be desirable to change to \fIcontents\fR of a reference. This can
be done by prefixing the assignment operator with an asterisk. This
causes the contents of the reference to be set, changing the value for
every element that "points" to it.
.EX
	#33.foo = "foo!";
	#44.foop = &#33.foo;
	echo(#33.foo,#44.foop,"\\n");

	*#44.foop = "bar!";
	echo(#33.foo,#44.foop,"\\n");
.XE
As in the previous example, the first call to echo prints "foo!foo!" and
the newline. The second prints "bar!bar!" and the newline. This can be
invaluable for implementing objects that change their appearance
globally, but a programmer does not want to have to maintain individually,
such as a destination list for a teleporter system.
.NH 2
Restrictions on References
.PP
It is illegal to make a reference to object elements in #0, the system
object. This is because the entire system object is stored only in
main memory, not on disk (it is the repository of that which must be
fast). Thus, a reference to something in #0 would become "stale" as
soon as the server was shut down. Assigning the contents of a reference
to NULL is a special case, and causes only that one link to the
referenced object to be broken. This is due to the fact that there is
no idea how many object elements actually "point" to that referenced
element.
.NH 1
Run-Time User Contexts
.NH 2
User-Id and Effective User-Id
.PP
When a U program is executing, there are several special values
attached to the running program. Primarily these consist of
the \fIuser-id\fR and the \fIeffective user-id\fR. These values
are used as the basis for all permissions in U. At any time
when a player is connected to the U-server, their login has
a user-id associated with it. Typically this will be the object
number of their 'self' in the game (though it need not be).
The effective user-id is almost always the same as the user-id,
but it can be changed under certain circumstances (see Setuid
Function below) or if the person's connection is flagged with
a "Wizard Bit" in the password file. In the case of a connection
with the "Wizard Bit" set, the players user-id will be their
object number, but their effective user-id will be that of #0,
the \fICreator\fR, who has absolute power over all things in
the universe. At runtime, built-in functions may also alter
a connections effective user-id, though it is impossible to
alter the user-id, and for good reason, since the user-id
determines where any textual output intended for a player
should go. Should two objects somehow share the same user-id,
they would both get each other's output.
.NH 2
Selves and Actors
.PP
At run-time, certain special object number variables are
defined, and can be used in functions to reference the
player who triggered the current function calls, or the
object number of the current function's root object. These
values are \fI#actor\fR, \fI#caller\fR and \fI#self\fR.
When a function uses #actor as an object number, it is
replaced with the object
number of the player whose input is currently being processed.
This is very, very useful:
.EX
func @.take
{
	...
	foreach $who in (#actor.location.players)
		echoto($who,#actor.name," picks up ",$thing.name,"\\n");
	...
}
.XE
Suppose the object number of the person who typed the 'take' command
in were #44. This function would iterate across the list of players
in #44.location.players, echoing the player's name, and so forth to
them. This permits functions to be written in a manner that is
fairly independent of who or what calls them. The \fI#self\fR special
object identifier is similar, but identifies the object number of
the \fIcurrent\fR function's root object. This allows a function
to modify its proper root object. Suppose we have a radio that we
wish to have alter its description depending on whether or not it
is turned on. We might write:
.EX
func #44.turnon
{
	...
	if(#self.on == NULL) {
		#self.on = 1;
		#self.description = "a blaring ghetto-blaster...";
	}
	...
}
.XE
Granted, #44 could be substituted for #self in this example, but
using #self makes it easier to make programs that are object number
independent. Another crucial facet of #self arises when a function
that is called is acually a function called with a reference. In
such a case, using #44 would set the wrong value in the wrong radio
depending on which radio's function were called. Using #self
guarantees that the correct root object number is applied. Using
the function above:
.EX
	#55.turnon = &#44.turnon;
	#55.turnon();
	#44.turnon();
.XE
The first call, to #55.turnon() would modify #55.on, and #55.description
since #self would be object number #55. In the second call, the value
of #self would be correctly set to #44.
.PP
The \fI#caller\fR special object variable is replaced at run-time with
the object number of the object that has \fIinvoked\fR the current
function. If the current function has been called directly from a
player, or the monitor, \fI#caller\fR is identical to \fI#actor\fR.
.EX
func #33.bar
{
	echo("self is ",#self,"\\tcaller is ",#caller,"\\n");
}

func #44.bar
{
	echo("self is ",#self,"\\tcaller is ",#caller,"\\n");
	#33.bar();
}

#44.bar();
.XE
In the example above, there are two functions, one of which calls the
other, and is in turn called from the monitor directly. If this code
were run with the user-id #55, the results would look like:
.EX
self is #44	caller is #55
self is #33	caller is #44
.XE
Since the first call to #44.bar was executed directly by object #55,
the \fI#caller\fR value is exactly the same as \fI#actor\fR.
.NH 1
Permissions
.PP
In U, all objects have a variety of permissions associated with them.
Each object has an owner, and a masked set of permissions flags,
somewhat reminiscent of the permissions bits on a UNIX file.
Permissions can be granted for read or write. The concept of execute
permission is meaningless, since functions are a primary data type,
and being able to read them implies being able to execute them.
There are three classes of permissions: owner permissions, indirect
permissions, and world permissions. Owner permissions are checked
when the owner of a on object or object element attempts to modify
or access it. Indirect permissions are checked when a function that
is running with the effective user-id of the owner, but a different
real user-id tries to modify or
access an object, and world permissions are checked in all other
cases. The purpose of the indirect mode is to prevent objects from
seriously damaging a player or his internal data, as a result of
the player's action. There is no notion of 'groups' per se in U,
since there are really no classes of objects to group things by.
.NH 2
Permissions on a Root Object
.PP
When the system built-in function \fIobjectnew\fR is called, it
allocates a new empty object, and returns its object number. This
empty object can have elements (data values) added to it as part
of the usual assignment process described earlier. Whenever an
assignment is made to an object element that does not already
exist, the permissions on the root object are checked, and
must be in a mode to permit writing before the element can be
created. If an attempt is made to destroy the root object, a
check is made to see if it is writeable. This makes it easy for
an object to be created that can have new elements added to it
by other than the player, by simply making the root object
world-writeable. This also makes it feasible to create objects
that can be destroyed by people other than the owner, which
is sometimes desirable. Read permission on a root object
is (currently) meaningless.
.NH 2
Permissions on an Object Element
.PP
The same permissions bits exist for an object element as for a
root object, but some of the effects of permissions bits are
interpreted differently. If an assignment is made to an element,
the existing element must be in a mode that permits writing
by the caller, based on the effective user-id. This applies even
if the assignment is to NULL, so it is possible to create an
object element in someone else's
root object that they cannot destroy. This is a feature rather
than a bug, as it permits the universe rules designers to make
some values outside the user's control. If, however, a root
object is destroyed, all elements are destroyed, regardless of
ownership. There is an additional feature to aid in designing
universes: \fIonly\fR the universe \fICreator\fR can create an element
which has a name beginning with an underscore '_' character.
This is to reserve a set of names for universe-implementations,
without forcing the \fICreator\fR to always set values and permissions
to "hold" the variable names.
.NH 2
Permissions on a Function - the Setuid Bit
.PP
A special permissions mode can be applied to functions, which
causes the function that is being executed to run with its
effective user-id to be that of the owner of the function.
This provides a controlled means for giving access to objects
without having to make the object world-writeable. Setuid
functions owned by the \fICreator\fR are especially useful for 
implementing universe rules, since the \fICreator\fR may
want to reserve some privileges for itseslf (such as moving
objects in rooms). Setuid is a very powerful capability, but
can also cause serious problems if not used with care. Any
functions that are called by a setuid function inherit their
effective user-id from the setuid function. Thus, the writer
of a setuid function must be careful to control sub-functions
that are called, since a joker might take advantage of 
permissions to destroy objects, or change their permissions
and ownerships.
.PP
The setuid model of permissions will be immediately familiar
to anyone who has more than a nodding acquaintance with UNIX.
Such a user will also know that 95% of the security loopholes
in UNIX are as a result of an incorrectly applied setuid
program. An Ubermud \fICreator\fR will want to exercise some
caution, since a flaw in the universe rules will allow players
to assume the powers of a wizard. On the other hand, Ubermud
being a game, this can be fun - or at least less serious than
having a multi-user computer broken into. The possibility of
destructive Uber-virusses is not to be ignored, however.
.NH 2
Changing Permissions
.PP
Permissions on object elements and root objects can be altered
with the built-in chmod() function. Chmod can be given either
the number of an object (to affect the root object's permissions),
or a reference to an object element. Chmod takes a second parameter,
which is a string specifying the permissions modes for the three
types: Owner, Indirect, World. The types are signified with
upper-case letters, followed by a colon and a list of lower-case
letters indicating the desired mode for that type of permission.
.EX
	chmod(#33,"O:rw");
	chmod(&#33.bar,"O:rw,I:r,W:r");
	chmod(&#33.somefunc,"O:rw,I:r,W:rs");
.XE
The first example sets the permissions for the root object of \fI#33\fR
to be owner read and owner write. Since the permissions for indirect
and world are not specified, no operations are permitted to anyone
but the owner. Since the object is a root object, the read permission
does not mean much, but the lack of world or indirect write permission
means that nobody but the owner can create new elements in that
object. The second example shows a reference to \fI#33.bar\fR being
passed to chmod, with a request to set that element only as owner
readable and writeable, indirect and world readable. This is, in fact,
the default permissions mode, which is automatically set when an object
or element is initially created or assigned to. The third example
shows a function being marked as owner read and writeable, indirect
and world readable, and \fIsetuid\fR. To flag an element as setuid,
the \fI's'\fR must be marked within the \fIworld\fR group of
permissions, as a reminder to the programmer that world access is
being given to the owner's permissions.
.NH 2
Changing Ownership
.PP
Objects can be given away in U, as can individual object elements.
Only the owner of an object or element (or the \fICreator\fR) can
give an object away. Giving the root object away does \fInot\fR
automatically change the ownership of all the object elements
in that object, nor does giving away a single object element
give any other permissions within that object. The only change
other than ownership that occurrs when an object is given away
is that the setuid bit is cleared if it is set in the gift. This
is to prevent the obvious security loophole. Calls to the 
built-in function that manages changing ownerships are done
similarly to setting permissions.
An object number, or a reference to an object element is given,
and the object number of the recipient is provided as a second
parameter:
.EX
	chown(#33,#44);
	chown(&#44.name,#44);
.XE
The first example above shows a root object \fI#33\fR being given
to \fI#44\fR. Note that #44 does \fInot\fR have to be a player. In
fact, the recipient does not even have to exist. Object elements
within the system object (#0) can be given away by the \fICreator\fR
if so desired, but the system object itself cannot be given away.
Typically ownership changing is useful in creating universe rules,
where a creator may wish to create a base object that will be a
player, and then give it to itself. In some universes, or in some
cases, the \fICreator\fR may \fInot\fR want a player to own their
base object. Such issues are outside of the scope of this document.
.NH 1
Built-In Functions
.PP
U has a fairly powerful set of built-in functions, which can be
called exactly like user-defined functions, and return (or do not)
values as appropriate. For the purposes of documenting them,
they are listed below, in a manner intended to be somewhat 
reminiscent of the manner in which C functions are usually
declared, with the return value, and parameter types. Some U
built-ins take arbitrary lists of parameters, some take
specific parameters of given types. In the case of the latter,
NULL is returned when the parameter count is incorrect, or
the wrong data type is provided as a parameter.
.NH 2
General Functions
.sp
NUM \fBatoi\fR(STR) - returns a numerical representation of the string,
or zero. If a NUM or OBJ is passed to the function by accident or on
purpose, a type conversion will be performed, and the corresponding
NUM value will be returned. NULL is returned if more than one parameter
is given, or the parameter is a function, list, or other type.
.sp
OBJ \fBatoobj\fR(STR) - converts a string to an object number, with the
same caveats and type conversions at atoi.
.sp
NUM \fBcatfile\fR(object#,STR) - sends the contents of the file named in
the string parameter to the output buffer of the player object listed as
the first parameter. Files are searched for in a subdirectory of the
U-server's current directory named \fI"files"\fR for security reasons.
If the file cannot be opened, the player is informed
as to the reason. Files with a leading '/' character or a '..' in them
are forbidden, and will not be printed. In the event of a failure,
the function returns NULL; a successful call is indicated with a numeric
zero return value.
.sp
INT \fBdisconnect\fR(object#1,object#2,object#N) - disconnects the
specified object numbers from the server if they are connected. This
function must be run with user-id or effective-user-id of \fICreator\fR.
Note that since this is a built-in command, the caller must generate
their \fBown\fR call to @._quit(), or whatever is necessary to cleanly
disconnect the player.
.sp
NULL \fBecho\fR(arg1,arg2,argN) - echos its parameters to \fI#actor\fR
in sequence, performing type conversion as necessary. NUM values are
converted to a text format, strings are printed as such, and object
numbers are printed preceeded with a sharp '#' character. NULL values
are not printed, and attempts to print functions and lists prints
either \fB"<function>"\fR or \fB"<list>"\fR respectively.
.sp
NULL \fBechoto\fR(object#,arg1,arg2,argN) - echoes its parameters
just like echo, except that the output it sent to the player
matching \fIobject#\fR if that player is connected. If the destination
object number is not connected, the output is thrown away.
.sp
NUM \fBerrno\fR(NULL) - returns a numeric representation of an error
attached to a particular NULL value. Error values are:
.in 1i
.br
0 - No error.
.br
1 - Error. This is produced when a user program returns NULL.
.br
2 - Out of memory. This indicates a memory allocation condition
within the server.
.br
3 - Numeric operation on non-number. This indicates an attempt
was made to perform a numerical operation on a non-numeric value.
The only numerical operator that is permitted on non-numbers is
the equality ("==") operator, which functions between NULLs and
strings.
.br
4 - Division by zero. This indicates a numerical division by zero
was attempted.
.br
5 - Badly formed element specifier. This indicates an attempt was
made to create an element out of something invalid. For example,
trying to make an element out of a string value and an element
name. (EG: \fI$foo.bar\fR where \fI$foo = "foo"\fR).
.br
6 - Bad parameter type. A built-in function was called with an
incorrect parameter type, or a missing or extra parameter.
.br
7 - Nonexistent object. An attempt was made to access an object or
object element that does not exist. \fBIn the event that an object
is not readable by a person, this value is returned, not a permission
denied value\fR. This is to make non-readable values completely and
utterly "invisible".
.br
8 - Cannot reference object. An attempt was made to take a reference
of an object that cannot be referenced. This usually results from
an attempt to take a reference of a badly formed element specifier.
(EG: \fI&$foo\fR where \fI$foo = "bar"\fR).
.br
9 - Function returned no value. An attempt to use a return code
from a function that returned no value results in the return
code being NULL, with this value. There are many cases where this
is perfectly acceptable.
.br
10 - No such parameter. An attempt to use a function parameter
that was not passed returns this NULL. (EG: \fI$4\fR in a function
that was only called with two parameters).
.br
11 - I/O error (this is bad!). Something failed in the disk-based
database routines. This is very, very, very bad. Run about in a
panic.
.br
12 - Permission denied. An attempt was made to operate on an object
which has permissions set against the operation.
.br
13 - Not owner. An attempt was made to change the ownership of an
object or object element that the caller does not own.
.br
14 - Stack over/underflow. Some form of recursive or looping call
was made, resulting in an eventual failed function call.
.in
.sp
STR \fBerror\fR(NULL) - returns a string representation of an error
message attached to a particular NULL value. This is useful for
debugging or explaining why an operation failed.
.EX
	$ret = #33.bar = "this is a test";
	if($ret == NULL)
		echo("operation failed: ",error($ret),"\\n");
.XE
The above example is a typical means of performing error-checking
withing a U function.
.sp
NUM \fBislist\fR(arg) - returns a numerical value of one if the
parameter is a list. Numerical zero is returned otherwise.
.sp
NUM \fBisnum\fR(arg) - returns a numerical value of one if the
parameter is a number. Numerical zero is returned otherwise.
.sp
NUM \fBisobj\fR(arg) - returns a numerical value of one if the
parameter is an object number. Numerical zero is returned otherwise.
.sp
NUM \fBisstr\fR(arg) - returns a numerical value of one if the
parameter is a string. Numerical zero is returned otherwise.
.sp
NUM \fBrand\fR(optional arg) - returns a random number from zero
to the maximum numeric value allowed on the system. If a single
numeric parameter is given, the range of the number returned
will be between zero and the parameter. If a parameter that is
non-numeric is provided, numeric zero is always returned.
.EX
	echo("1d6=",rand(6) + 1,"\\n");
.XE
The above would produce a random number as if rolled on a six-sided
die.
.sp
NUM \fBregcmp\fR(string1,string2) - returns a one or a zero, depending
on whether or not string1 contains text matched by the regular expression
in string2. If the regular expression in string2 is malformed, or a
parameter is mis-matched, zero is returned.
.sp
STR \fBregexp\fR(string1,string2) - returns a string consisting of the
first completely matching substring in string1, using the regular
expression in string2. If there is no match, a parameter is missing
or mismatched, or the regular expression
is malformed, the function returns NULL. Regular expressions are
similar to those used in \fIegrep\fR, and include the '|' operator.
.EX
echo(regexp("this is a test","this[ \t][a-z]"));
.XE
In the example above, the string \fI"this is"\fR would be returned by
regexp, and echoed.
.sp
INT \fBshutdown\fR() - shuts the server down gracefully. This
function must be run with user-id or effective-user-id of \fICreator\fR.
.sp
STR \fBstr\fR(arg1,arg2,argN) - returns a string assembled from
the parameters given. Conversion on the parameters by type is
performed in the same manner as in echo. This function is very
useful for producing concatenated values for assignments:
.EX
	#33.time = str("the time is:",strtime());
.XE
The above appends the returned value of \fIstrtime\fR to the end
of the string, and assigns it to \fI#33.time\fR.
.sp
NUM \fBstrlen\fR(STR) - returns the length of the string passed as
a parameter. If the value is not given, or is not a string, numeric
zero is returned.
.sp
STR \fBstrtime\fR(optional arg1) - returns a text string
representation of the system's current notion of the time. If a numeric
parameter is provided, the time string returned is the notion of the
time as if it were at the given number of seconds GMT since
January 1, 1970.
.sp
NUM \fBtime\fR() - returns the system's notion of how many seconds
it has been GMT since January 1, 1970.
.NH 2
List Manipulation Functions
.sp
OBJLIST \fBlistadd\fR(OBJLIST,object#1,object#2,object#N)
.sp
OBJLIST \fBlistprepend\fR(OBJLIST,object#1,object#2,object#N) - prepends
the given object numbers to the list provided as a first parameter, and
returns the new list. In the event of an parameter type mismatch in the
first parameter, NULL is returned. If any of the object number parameters
are incorrect, the new value is silently ignored. If a new value already
exists in the old list, it is not prepended again, and retains its old
position in the list. These two functions are actually the same, under
different names, listadd being included for brevity's sake.
.sp
OBJLIST \fBlistappend\fR(OBJLIST,object#1,object#2,object#N) - appends
the given object numbers, in the same manner as listappend.
.sp
NUM \fBlistcount\fR(OBJLIST) - returns a numerical count of the number
of element numbers in the list provided. In the event that parameter
one is missing, or is not a list, NULL is returned.
.sp
OBJLIST \fBlistdrop\fR(OBJLIST,object#1,object#2,object#N) - returns
a new list, consisting of the object numbers from the list in the
first parameter, with any occurrences of the object numbers given 
as parameters omitted. In the case of a call to listdrop completely
emptying a list, an empty list is returned.
.sp
OBJNUM \fBlistelem\fR(OBJLIST,NUM) - returns the object number of the
N-th element in the list. Unlike C, U lists are indexed with the
first element being element number 1. If the index number given is
higher than the total number of object numbers in the list, or
the first parameter is not a list, NULL is returned.
.sp
OBJLIST \fBlistmerge\fR(OBJLIST,OBJLIST) - returns a new object list,
consisting of the union of the lists provided as parameters. Duplicates
are suppressed. As a special case, either of the two lists provided
as parameters can be NULL, which will effectively return the other
list.
.sp
OBJLIST \fBlistnew\fR(object#1,object#2,object#N) - returns a new
object list, consisting of the object numbers given. If no parameters
are given, or all the provided parameters are invalid, an empty
list is returned.
.sp
NUM \fBlistsearch\fR(OBJLIST,object#) - returns the index offset of
the given object number in the list, or NULL if the object number is
not in the list. NULL is returned if a parameter is missing, or is
of the wrong type. Since list element offsets start at one, locating
an object number in the first 'slot' of the list returns numeric '1'.
.sp
OBJLIST \fBlistsetelem\fR(OBJLIST,object#,NUM) - returns a list,
with the object number at the numeric index set to the provided
object number. If there are not that many object numbers in the
list, the original list is returned unchanged. NULL is returned
in the case of a missing parameter, or incorrect parameter type.
.NH 2
Object Manipulation Functions
.sp
NUM \fBobjectdestroy\fR(object#) - destroys the numbered object,
if the caller has permission, destroying any object elements bound
to that object as well. NULL is returned in the event that permission
is denied. In the event of a successful annihilation, numeric zero
is returned. In some implementations, this permission requires
that the caller's effective user-id or real user-id be \fICreator\fR.
This is to avoid problems with players destroying objects that
people are holding, etc, and is the default case.
.sp
NULL \fBobjectelements\fR(object #) - lists the elements defined in an
object to the caller's terminal. The caller must have read permission
on the base object, in order to invoke this function.
.sp
OBJNUM \fBobjectnew\fR() - creates a new object and returns its
number. The new object is the property of the caller, and is
created empty, with default permissions.
.sp
OBJNUM \fBobjectowner\fR(object#, or reference to object element) -
returns the object number of the object owning the root object or
object element
provided. In the event of the object or element's non-existence,
NULL is returned.
.NH 2
Permissions and Environment Manipulation Functions
.sp
NUM \fBchmod\fR(object#,or reference to object element,STR) - sets
the permissions of the root object or object element, if the caller
is the owner of the root object or object element. The string
can contain a coding of permissions values consisting of any
of: 'O', signifying owner, 'I', signifying indirect, and 'W' signifying
world, followed by a colon, and any of 'w' for write, or 'r' for read.
Functions may have a setuid specifier applied to the world permissions
set, by using 's'. For examples, see above. In the event of failure,
NULL or returned; numeric zero is returned if the operation was a 
success.
.sp
NUM \fBchown\fR(object # or reference to object element,OBJNUM) - sets
the ownership of the specified root object or object element to the
object number provided. The call will fail if the caller is not the
owner of the object being given away. If a setuid bit is marked in
the object's permissions it is cleared as part of this process. In
the event of failure, NULL is returned; numeric zero is returned if the
operation is successful.
.sp
OBJNUM \fBgeteuid\fR() - returns the object number of the current caller's
effective user-id.
.sp
OBJNUM \fBgetuid\fR() - returns the object number of the current caller's
real user-id.
.sp
NUM \fBsetruid\fR(OBJNUM) - sets the real user-id of the current
calling function to the object number specified as a parameter.
This should only be used with extreme caution in rare circumstances,
as it affects the value returned by #actor (unlike setuid). Its
effect ends when the current call is completed. If called directly
from the monitor, the real user-id is \fInot\fR permanently changed.
This function can only be called if the real or effective user-id
of the caller is the \fICreator\fR. Successful calls return numeric
zero; failed calls return numeric one.
.sp
NUM \fBsetuid\fR(OBJNUM) - sets the effective user-id of the current
calling function to the object number specified as a parameter.
This call will
only succeed if the \fIreal\fR user-id of the caller is the number
being set to, or the caller is \fICreator\fR. In the event of failure,
NULL is returned; numeric zero is returned if the operation succeeds.
.NH 2
Matching Functions
.sp
OBJNUM \fBmatch\fR(STR,OBJNUM or OBJLIST,STR,[OBJNUM or OBJLIST,STR]..) -
match scans the object list, accessing each object number in the list
for an element name matching the provided string. An arbitrary number of
object list/string pairs can be provided. Once each element is accessed,
it is compared against the first string given. The object number of the
best match found is returned. In the event of multiple matches, the
returned object is selected based on the order in which the lists were
passed to the function (priority given the the first list). If a
complete match is made at any point, no further searching is done.
This is an especially useful function for matching a user's input with
objects in the surroundings:
.EX
	...
	$nam = match("foo",#actor.carr,"name",#actor.loc,"name");
	if($nam != NULL) {
	...
.XE
In the example above, a search is being made for things that match
the word \fI"foo"\fR. The first list searched is the \fI#actor.carr\fR
list - each object in that list is checked for a string element
named \fI"name"\fR. After \fI#actor.carr\fR is searched, \fI#actor.loc\fR
is searched, also for string elements named \fI"name"\fR. In the example
above, if \fI#actor.carr\fR had the object numbers \fI#44\fR and \fI#55\fR
in the list, match would check to see if there was a string stored
in element \fI#44.name\fR, then \fI#55.name\fR, and so on.
.PP
Individual root object numbers can be passed to match, as well, so
that:
.EX
	...
	$nam = match("foo",#99,"name");
	if($nam != NULL) {
	...
.XE
will return \fI#99\fR if there is an element named \fI"name"\fR in \fI#99\fR
that is \fI"foo"\fR, or begins with \fI"foo"\fR. Individual root object
numbers can be freely combined with lists in calls to match.
.PP
An additional aspect of matching is the magic match character, which
can be used in strings to effect an "alias" of sorts. The match character
is inserted in a string with an escaped semicolon: \fI'\\;'\fR. This
causes match to re-start matching a string whenever it encounters the
semicolon. This is useful in many ways.
.EX
	...
	#99.name = "Rusty\\;doofus";
	$nam = match("doof",#99,"name");
	if($nam != NULL) {
	...
.XE
In the above example, match will retrieve \fI#99.name\fR and compare "doof"
with "Rusty", generating a failure. The match character is then detected,
which causes match to re-match against "doofus", which succeeds and
returns \fI#99\fR.
.NH 1
Programming Hints, Traps, and Pitfalls.
.PP
The mistake most commonly made by the author is to store a variable
within an object, which has the same name as a function within
that object. The net effect of this is to destroy the function
when it is called. This is surprisingly easy to do:
.EX
/* a function to turn #44 on, whatever #44 is */
func	#44.on
{
	...
	/* if the thing is turned off, turn it on.. */
	if(#44.on == NULL) {
		#44.on = 1;
	}
	...
}
.XE
The function runs perfectly, the first time. Subsequent calls
try to call #44.on (which is now the numeric value one) and
return NULL (no such function). Realizing that one has done
this in a program is infuriating in the extreme.
.PP
Using a temporary variable name or element name that matches the
name of a builtin function will produce a syntax error:
.EX
#33.echo();	/* error */
.XE
This is annoying, but is part of the price to pay for packing
strings the way the U compiler does.
.NH 1
Annotated Programming Examples
.NH 2
A Room With Lights
.PP
The following is an example of a room with a light switch that works.
Assuming here that room #1 has already been created, and so on, the
programmer binds a function to it as a light switch:
.EX
func #1.lights {
	if(#self.on == NULL) {
		$tmp = #self.on = 1;
		if($tmp == NULL) {
			echo("the switch is broken\n");
			return;
		}
		@.emote("turns on the lights");
		#self.desc = "You see a dusty room, [...]";
		return;
	}
	#self.desc = "It is pitch dark in here";
	#self.on = NULL;
	@.emote("turns off the lights");
}
chmod(&#1.lights,"W:rs");
.XE
The function checks to see if object element #self.on is set - using
that as a boolean value for the state of the lights. Note that here, it
is set and unset to NULL rather than a value. When no value is desired,
using NULL and non-NULL is faster and saves database space besides.
If the rooms lights are off (#self.on == NULL), an attempt is made to
set the lights on. The value of the assign is checked to make sure
that the operation was successful ($tmp == NULL implies a broken
switch). If that operation was successful, a call is made to one of
the universe's functions 'emote' (@.emote) which presumably sends a
string to anyone else who happens to be in the room. The room then
alters its description to adapt for the lights being on, and returns.
If the lights were already on, the first case fails, and the lights
are turned off by resetting the description of the room and setting
the value of #self.on to NULL.
.NH 2
More to come.
.PP
More good examples to be added, when people create small nifty
objects.