Skip to content
Snippets Groups Projects
Select Git revision
  • feddffa1c6540c7af848586f02cfc4ed19db4ab4
  • master default protected
  • 9.0
  • 8.0
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • nt-tools
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.2000
  • v8.0.1998
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
  • v8.0.1982
  • v8.0.1980
  • v8.0.1978
  • v8.0.1976
  • v8.0.1974
  • v8.0.1972
  • v8.0.1970
  • v8.0.1968
  • v8.0.1966
41 results

tutorial.wmml

Blame
  • tutorial.wmml 484.90 KiB
    <head>
    <title>Pike tutorial</title>
    </head>
    
    <!-- Allmänt: Sök på "'" och byt ut nästan alla 'foo' mot <i>foo</i>
         Ändra alla kommandon under SEE ALSO till <tt>foo</tt> 
         Det står "return" på miljoner ställen där det ska stå "returns" -->
    
    <firstpage>
    <p>
    <center>
    <h1>
    Programming, using and understanding
    <p>
    <img src=pike.gif>
    <p>
    <font size=+7>Pike</font>
    <p>
    </h1>
    <h2>by Fredrik Hübinette</h2>
    </center>
    
    </firstpage>
    
    <preface title="Preface">
    
    This book was written with the intention to make anybody with a little
    programming experience able to use Pike. It should also be possible to
    gain a deep understanding of how Pike works and to some extent why it works
    the way does from this book. It will teach you how to write your own
    extensions to Pike. I have been trying for years to get someone else to
    write this book, but since it seems impossible without paying a fortune for
    it I will have to do it myself. 
    A big thanks goes to
    <a href="http://www.emit.com.pl/ian.html">Ian Carr-de Avelon</a> for helping
    me iron out some of the rough spots. 
    
    The book assumes that
    you have programmed some other programming language before and that you
    have some experience of UNIX.
    </preface>
    
    <table-of-contents title="Table of contents">
    
    <introduction title="Introduction">
    
    This introduction will give you some background about Pike and this book
    and also compare Pike with other languages. If you want to start
    learning Pike immediately you can skip this chapter.
    
    <section title="Overview">
    This book is designed for people who want to
    learn Pike fast. Since Pike is a simple language to learn, especially
    if you have some prior programming experience, this should benefit most people.
    <p>
    Chapter one is devoted to background information about Pike and this book.
    It is not really necessary to read this chapter to learn how to use and
    program Pike, but it might help explain why some things work th way they do.
    It might be more interesting to re-read the chapter after you have
    learned the basics of Pike programming.
    Chapter two is where the action starts. It is a crash course in Pike with
    examples and explanations about some of the basics. It explains the
    fundamentals of the Pike data types and control structures
    The systematic documentation of all Pike capabilities starts in chapter three
    with a description of all control structures in Pike. It then continues with
    all the data types in chapter four and operators in chapter five. Chapter
    six deals with object orientation in Pike, which is slightly different than
    what you might be used to.
    <!-- FIX ME (finish this overview) -->
    </section>
    
    <anchor name=uLPC>
    <section title="The history of Pike">
    In the beginning, there was Zork. Then a bunch of people decided to make
    multi-player adventure games. One of those people was Lars Pensjö at the
    Chalmers university in Gothenburg, Sweden. For his game he needed a simple,
    memory-efficient language, and thus LPC (Lars Pensjö C) was born. About a
    year later I started playing one of these games and found that the language
    was the most easy-to-use language I had ever encountered. I liked the language
    so much that I started improving it and before long I had made my own LPC
    dialect called LPC4. LPC4 was still geared towards writing adventure games,
    but was quite useful for writing other things with as well. A major problem
    with LPC4 was the copyright. Since it was based on Lars Pensjö's code, it
    came with a license that did not allow it to be used for commercial gain.
    So, in 1994 I started writing µLPC, which was a new but similar LPC interpreter.
    I got financial backing from Signum Support AB for writing µLPC. Signum
    is a company dedicated to supporting GNU and GPL software and they wanted
    to create more GPL software.
    <p>
    When µLPC became usable, InformationsVävarna AB started using it for
    their web-server. Before then, Roxen (then called Spinner) was non-commercial
    and written in LPC4. Then in 1996 I started working for InformationsVävarna
    developing µLPC for them. We also changed the name of µLPC to Pike to
    get a more commercially viable name.
    </section>
    </anchor>
    
    <section title="A comparison with other languages">
    <dl>
    
    <dt> Python
    <dd> Python is probably the language that is most like Pike. Pike is faster
         and has better object orientation. It also has a syntax similar to
         C++, which makes it more familiar for people who know C++. Python on
         the other hand, has a lot more libraries available.
    
    <dt> C++
    <dd> Pike's syntax is almost the same as for C++. A huge difference is that
         Pike is interpreted. This makes the code slower, but reduces compile times
         to almost nothing. For those few applications which require the speed of
         C or C++, it is often easier to write a Pike extension than to write the
         whole thing in C or C++.
    
    <dt> Lisp and Scheme
    <dd> Internally Pike has a lot in common with Lisp and Scheme. They are both
         stack based, byte-compiled, interpreted languages. Pike is also
         a 'one-cell' language, just like Scheme.
    
    <dt> Pascal
    <dd> Pike has nothing in common with Pascal.
    
    <dt> Tcl/Tk
    <dd> Pike is similar to Tcl/Tk in intent and they both have good string
         handling. Pike has better data types and is much faster however.
         On the other hand Tcl/Tk has X windows system support.
    <!-- The idea from the beginning was similar but the implementation is very different.-->
    </dl>
    </section>
    
    <section title="What is Pike">
    
    Pike is:
    <ul>
    <li> A programming language
    <li> Object oriented
    <li> Interpreted
    <li> Fast
    <li> Dynamic
    <li> High-level
    <li> similar to C++
    <li> easy to extend
    <li> (a fish)
    </ul>
    
    Pike has:
    <ul>
    <li> Garbage collection
    <li> Advanced string functions
    <li> 5 years of development behind it
    <li> Advanced data types such as associative arrays
    <li> Support for bignums
    <li> Builtin socket support
    </ul>
    </section>
    
    <section title="How to read this manual">
    This manual uses a couple of different typefaces to describe different
    things:
    <dl>
    <dt><i>italics</i>
    <dd>Italics is used as a placeholder for other things. If it says <i>a word</i>
        in the text it means that you should put your own word there.
    <dt><b>bold</b>
    <dd>Bold is just used to emphasize that this word is not merely what it sounds
        like. It is actually a <b>term</b>.
    <dt><tt>fixed size</tt>
    <dd>Fixed size is used to for examples and text directly from the computer.
    </dl>
    Also, please beware that the word <b>program</b> is also a builtin Pike
    data type.
    
    </section>
    </introduction>
    
    
    <chapter title="Getting started">
    <p>
    First you need to have Pike installed on your computer. See <ref to=install>
    "how to install Pike" if this is not already done. It is also vital
    for the first of the following examples that the Pike binary is in your UNIX search
    path. If you have problems with this, consult the manual for your shell
    or go buy a beginners book about UNIX.
    <p>
    
    <section title="Your first Pike program">
    
    <example language=pike>
    	int main()
    	{
    	  write("hello world\n");
    	  return 0;
    	}
    </example>
    Let's call this file hello_world.pike, and then we try to run it:
    <p>
    <pre>
    	$ pike hello_world.pike
    	hello world
    	$ 
    </pre>
    Pretty simple, Let's see what everything means:
    <example language=pike>
    	int main()
    </example>
    This begins the function <tt>main</tt>. Before the function name the type of value
    it returns is declared, in this case <tt>int</tt> which is the name of the
    integer number type in Pike. The empty space between the
    parenthesis indicates that this function takes no arguments.
    A Pike program has to contain at least one function, the <tt>main</tt> function. This function is where program execution starts and thus the function from which every other function is called, directly or indirectly. We can say that this function is called by the operating system.
    Pike is, as many other programming languages, built upon the concept of functions, i.e. what the program does is separated into small portions, or functions, each performing one (perhaps very complex) task. A function declaration consists of certain essential components; the type of the value it will return, the <i>name</i> of the function, the <i>parameters</i>, if any, it takes and the body of the function. A function is also a part of something greater; an object. You can program in Pike without caring about objects, but the programs you write will in fact be objects themselves anyway.
    Now let's examine the body of <tt>main</tt>;
    <p>
    <example language=pike>
    	{
    	  write("hello world\n");
    	  return 0;
    	}
    </example>
    Within the function body, programming instructions, statements, are grouped together in blocks. A block is a series of statements placed between curly brackets. Every statement has to end in a semicolon. This group of statements will
    be executed every time the function is called.
    <p>
    <example language=pike>
    	write("hello world\n");
    </example>
    The first statement is a call to the builtin function <tt>write</tt>. This will
    execute the code in the function <tt>write</tt> with the arguments as input data.
    In this case, the constant string <tt>hello world\n</tt> is sent.
    Well, not quite. The <tt>\n</tt> combination corresponds to the newline
    character.
    <tt>write</tt> then writes this string to stdout when executed. Stdout is the standard Unix output channel, usually the screen.
    <p>
    <example language=pike>
    	return 0;
    </example>
    This statement exits the function and returns the value zero. Any statements
    following the return statements will not be executed.
    <p>
    </section>
    
    
    <section title="Improving hello_world.pike">
    Typing <tt>pike hello_world.pike</tt> to run our program may seem a bit
    unpractical. Fortunately, Unix provides us with a way of automating this
    somewhat. If we modify hello_world.pike to look like this:
    <p>
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	int main()
    	{
    	  write("hello world\n");
    	  return 0;
    	}
    </example>
    And then we tell UNIX that hello_world.pike is executable so we can run
    hello_world.pike without having to bother with running Pike:
    <p>
    <pre>
    	$ chmod +x hello_world.pike
    	$ ./hello_world.pike
    	hello world
    	$ 
    </pre>
    N.B.: The hash bang (#!) must be first in the file, not even whitespace is allowed to precede it!
    The file name after the hash bang must also be the complete file name to the Pike binary, and it may not exceed 30 characters.
    <p>
    
    </section>
    
    <section title="Further improvements">
    
    Now, wouldn't it be nice if it said <tt>Hello world!</tt> instead of <tt>hello world</tt> ?
    But of course we don't want to make our program "incompatible" with the old
    version. Someone might need the program to work like it used to. 
    Therefore we'll add a <i>command line option</i> that will make it type the old
    <tt>hello world</tt>. We also have to give the program the ability to choose
    what it should output based on the command line option.
    This is what it could look like:
    <p>
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	int main(int argc, string *argv)
    	{
    	  if(argc &gt; 1 &amp;&amp; argv[1]=="--traditional")
    	  {
    	    write("hello world\n"); // old style
    	  }else{
    	    write("Hello world!\n"); // new style
    	  }
    	  return 0;
    	}
    </example>
    Let's run it:
    <p>
    <pre>
    	$ chmod +x hello_world.pike
    	$ ./hello_world.pike
    	Hello world!
    	$ ./hello_world.pike --traditional
    	hello world
    	$ 
    </pre>
    What is new in this version, then?
    <example language=pike>
    	int main(int argc, string *argv)
    </example>
    In this version the space between the parenthesis has been filled.
    What it means is that <tt>main</tt> now takes two arguments.
    One is called <tt>argc</tt>, and is of the type <tt>int</tt>.
    The other is called <tt>argv</tt> and is a an array of strings.
    A perhaps better way to represent an array of strings would be
    <tt>array(string)</tt> which is exactly the same as <tt>string *</tt>
    and probably easier to understand. The syntax <tt>string *</tt>
    is more like the syntax in C/C++ however.
    <p>
    The arguments to <tt>main</tt> are taken from the command line when the
    Pike program is executed. The first argument, <tt>argc</tt>, is how many
    words were written on the command line (including the command itself) and
    <tt>argv</tt> is an array formed by these words.
    <p>
    <example language=pike>
    	  if(argc &gt; 1 &amp;&amp; argv[1] == "--traditional")
    	  {
    	    write("hello world\n"); // old style
    	  }else{
    	    write("Hello world!\n"); // new style
    	  }
    </example>
    This is an if-else statement, it will execute what's between the first set
    of brackets if the expression between the parenthesis evaluate to something
    other than zero. Otherwise what's between the second set of brackets will
    be executed. Let's look at that expression:
    <p>
    <example language=pike>
    	argc &gt; 1 &amp;&amp; argv[1] == "--traditional"
    </example>
    Loosely translated, this means: argc is greater than one,  and the second
    element in the array argv is equal to the string <tt>--traditional</tt>. Since
    argc is the number of words on the command line the first part is true only
    if there was anything after the program invocation.
    <p>
    Also note the comments:
    <p>
    <example language=pike>
    	    write("hello world\n"); // old style
    </example>
    The <tt>//</tt> begins a comment which continues to the end of the line.
    Comments will be ignore by the computer when it reads the code.
    This allows to inform whoever might read your code (like yourself) of
    what the program does to make it easier to understand.
    Comments are also allowed to look like C-style comments, ie. <tt>/* ... */</tt>, which can extend over several lines. The <tt>//</tt> comment only extends to the end of the line.
    <p>
    </section>
    
    <section title="Control structures">
    The first thing to understand about Pike is that just like any other
    programming language it executes one piece of code at a time. Most of
    the time it simply executes code line by line working its way downwards.
    Just executing a long list of instructions is not enough to make an interesting
    program however. Therefore we have <b>control structures</b> to make Pike
    execute pieces of code in more interesting orders than from top to bottom.
    <p>
    We have already seen an example of the <tt>if</tt> statement:
    <pre>
    	if( <i>expression </i> )
    		<i>statement1 </i> ;
    	else
    		<i>statement2 </i> ;
    </pre>
    <!-- FIX ME: should if have a capital letter or not? -->
    <tt>if</tt> simply evaluates the expression and if the result is true it
    executes <i>statement1</i>, otherwise it executes <i>statement2</i>. If you have no need for
    statement2 you can leave out the whole else<!-- FIX ME: tt/italics --> part like this:
    <pre>
    	if( <i>expression </i> )
    		<i>statement1 </i> ;
    </pre>
    In this case <i>statement1</i> is evaluated if <i>expression</i> is true, otherwise
    nothing is evaluated.
    <p>
    <b>Note for beginners: go back to our first example and make sure you
       understand what <tt>if</tt> does.</b>
    <p>
    Another very simple control structure is the <tt>while</tt> statement:
    <pre>
    	while( <i>expression </i> )
    		<i>statement </i> ;
    </pre>
    This statement evaluates <i>expression</i> and if it is found to be true it
    evaluates <i>statement</i>. After that it starts over and evaluates <i>expression</i>
    again. This continues until <i>expression</i> is no longer true. This type of
    control structure is called a <b>loop </b> and is fundamental to all
    interesting programming.
    <p>
    </section>
    
    <section title="Functions">
    Another control structure we have already seen is the function.
    A function is simply a block of Pike code that can be executed with different arguments from different places in the program.
    A function is declared like this:
    <pre>
    	<i>modifiers type name </i> ( <i>type name1 </i>, <i>type name2 </i>, <i>... </i> )
    	{
    	  <i> statements </i>
    	}
    </pre>
    The <i>modifiers</i> are optional. See <ref to=modifiers> for more details about
    modifiers. The <i>type </i> specifies what kind of data the function returns.
    For example, the word <tt>int</tt> would signify that the function returns
    an integer number. The <i>name </i> is used to identify the function when
    calling it. The names between the parenthesis are the arguments to the
    function. They will be defined as local variables inside the function. Each
    variable will be declared to contain values of the preceding type.
    The three dots signifies that you can have anything from zero to 256 arguments
    to a function. The <i> statements </i> between the brackets are the function
    body. Those statements will be executed whenever the function is called.
    <p>
    <b>Example:</b>
    <example language=pike>
    	int sqr(int x) { return x*x; }
    </example>
    This line defines a function called <tt>sqr</tt> to take one argument of the
    type <tt>int</tt> and also returns an <tt>int</tt>. The code itself returns
    the argument multiplied by itself. To call this function from somewhere in the code
    you could simply put: <tt>sqr(17)</tt> and that would return the integer value
    289.
    <p>
    As the example above shows, <tt>return</tt> is used to specify the
    return value of a function. The value after <tt>return</tt> must be of the
    type specified before the function name. If the function is specified to
    return <tt>void</tt>, nothing at all should be written after <tt>return</tt>.
    Note that when a return statement is executed, the function will finish
    immediately. Any statements following the return will be ignored.
    <p>
    There are many more control structures, they will all be described in a
    later chapter devoted only to control structures.
    <p>
    </section>
    
    <section title="True and false">
    Throughout this chapter the words <b>true</b> and <b>false</b> have been used
    without any explanation to what they mean. Pike has a fairly simple way of
    looking at this. The number 0 is false and everything else is true.
    (Except when using operator overloading as I will discuss in a later chapter.)
    <p>
    </section>
    
    <section title="Data Types">
    As you saw in our first examples we have to indicate the type of value returned by a functions or contained in a variable. We used integers (<tt>int</tt>.), strings (<tt>string</tt>), and arrays (with the * notation).
    The others are <tt>mapping</tt>, <tt>mixed</tt>, <tt>void</tt>, <tt>float</tt>, <tt>multiset</tt>, <tt>function</tt>, <tt>object</tt> and <tt>program</tt>.
    Neither <tt>mixed</tt> nor <tt>void</tt> are really types, <tt>void</tt> signifies that no value should be returned and <tt>mixed</tt> that the return value can be of any type, or that the variable can contain any type of value.
    <tt>Function</tt>, <tt>object</tt> and <tt>program</tt> are all types related to object orientation. We will not discuss the last three in any great detail here,
    
    <dl>
    <dt>Int
    <dd>The integer type stores an integer.
    <dt>Float
    <dd>This variable type stores a floating point number.
    <dt>Array
    <dd>Arrays are basically a place to store a number of other values.
    Arrays in Pike are allocated blocks of values.
    They are dynamically allocated and do not need to be declared as in C.
    The values in the array can be set when creating the array like this:
    <example language=pike>
    	arr=({1,2,3});
    </example>
    Or, if you have already created an array, you can change the values
    in the array like this:
    <example language=pike>
    	<i>arr</i> [ <i>ind</i> ] = <i>data</i>;
    </example>
    This sets entry number <i>ind</i> in the array <i>arr</i> to <i>data</i>.
    <i>ind</i> must be an integer.
    The first index of an array is 0 (zero). A negative index will count from the end of the array rather than from the beginning, -1 being the last element.
    
    To declare that a variable is an array we simply type <tt>array</tt> in
    front of the variable name we want:
    <example language=pike>
    	array i;
    </example>
    
    We can also declare several array variables on the same line:
    <example language=pike>
    	string i, j;
    </example>
    If we want to specify that the variable should hold an array of strings,
    we would write:
    <example language=pike>
    	array (string) i;
    </example>
    
    <dt>String
    <dd>A string contains a sequence of characters, a text, i.e. a word, a sentence or a book.
    Note that this is not simply the letters A to Z; special characters, null characters, newlines and so on can all be stored in a string.
    Any 8-bit character is allowed.
    String is a basic type in Pike, it is not an array of char like it is in C.
    This means that you cannot assign new values to individual characters in a string.
    Also, all strings are "shared", i.e. if the same string is used in several places, it will be stored in memory only once.
    When writing a string in a program, you enclose it in double quotes. To write special characters you need to use the following syntax:
    <table>
    <tr><td><li>\n</td><td>newline</td></tr>
    <tr><td><li>\r</td><td>carriage return</td></tr>
    <tr><td><li>\t</td><td>tab</td></tr>
    <tr><td><li>\b</td><td>backspace</td></tr>
    <tr><td><li>\"</td><td>" (quotation character)</td></tr>
    <tr><td><li>\\</td><td>\ (literal backslash)</td></tr>
    </table>
    <dt>Mapping
    <dd>A mapping is basically an array that can be indexed on any type, not just integers. It can also be seen as a way of linking data (usually strings) together. It consists of a lot of index-data pairs which are linked together in such a way that map[index1] returns data1.
    A mapping can be created in a way similar to arrays:
    <example language=pike>
    	map=([five:good, ten:excellent]);
    </example>
    You can also set that data by writing map[five]=good.
    If you try to set an index in a mapping that isn't already present in the mapping it will be added as well.
    <dt>Multiset
    <dd>A multiset is basically a mapping without data values. When referring to an index in the multiset a 1 (one) will be returned if the index is present and 0 (zero) otherwise.
    </dl>
    
    </section>
    </chapter>
    
    <chapter title="A more elaborate example">
    <!-- FIX ME: explain things AFTER showing the code? -->
    To illustrate several of the fundamental points of Pike we will now
    introduce an example program, that will be extended as we go.
    We will build a database program that keeps track of a record
    collection and the songs on the records. In the first version we
    hard-code our "database" into the program. The database is a mapping
    where the index is the record name and the data is an array of strings.
    The strings are of course the song names. The default register consists
    of one record.
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	mapping (string:array(string)) records =
    	([
    	  "Star Wars Trilogy" : ({
    	    "Fox Fanfare",
    	    "Main Title",
    	    "Princess Leia's Theme",
    	    "Here They Come",
    	    "The Asteroid Field",
    	    "Yoda's Theme",
    	    "The Imperial March",
    	    "Parade of the Ewoks",
    	    "Luke and Leia",
    	    "Fight with Tie Fighters",
    	    "Jabba the Hut",
    	    "Darth Vader's Death",
    	    "The Forest Battle",
    	    "Finale"
    	  })
    	]);
    </example>
    We want to be able to get a simple list of the records in our database. The function <tt>list_records</tt> just goes through the mapping <tt>records</tt> and puts the indices, i.e. the record names, in an array of strings, record_names. By using the builtin function <tt>sort</tt> we put the record names into the array in alphabetical order which might be a nice touch.
    For the printout we just print a header, "Records:", followed by a newline. Then we use the loop control structure for to traverse the array and print every item in it, including the number of the record, by counting up from zero to the last item of the array. The builtin function <tt>sizeof</tt> gives the number of items in an array. The printout is formatted through the use of <tt>sprintf</tt> which works more or less like the C function of the same name.
    <example language=pike>
    	void list_records()
    	{
    	  int i;
    	  array (string) record_names=sort(indices(records));
    
    	  write("Records:\n");
    	  for(i=0;i&lt;sizeof(record_names);i++)
    	    write(sprintf("%3d: %s\n", i+1, record_names[i]));
    	}
    </example>
    If the command line contained a number our program will find the record of that number and print its name along with the songs of this record. First we create the same array of record names as in the previous function, then we find the name of the record whose number (num) we gave as an argument to this function. Next we put the songs of this record in the array <tt>songs</tt> and print the record name followed by the songs, each song on a separate line.
    <example language=pike>
    	void show_record(int num)
    	{
    	  int i;
    	  array (string) record_names =	sort(indices (records));
    	  string name=record_names[num-1];
    	  array (string) songs=records[name];
      
    	  write(sprintf("Record %d, %s\n",num,name));
    	  for(i=0;i&lt;sizeof(songs);i++)
    	    write(sprintf("%3d: %s\n", i+1, songs[i]));
    	}
    </example>
    The main function doesn't do much; it checks whether there was anything on the command line after the invocation.
    If this is not the case it calls the list_records function, otherwise it sends the given argument to the show_record function.
    When the called function is done the program just quits.
    <example language=pike>
    	int main(int argc, array (string) argv)
    	{
    	  if(argc &lt;= 1)
    	  {
    	    list_records();
    	  } else {
    	    show_record((int) argv[1]);
    	  }
    	}
    </example>
    
    <section title="Taking care of input">
    Now, it would be better and more general if we could enter more records into our database. Let's add such a function and modify the <tt>main()</tt> function to accept "commands".
    <p>
    
    <section title="add_record()">
    
    Using the builtin function <tt>readline()</tt> we wait for input which will be put into the variable <tt>record_name</tt>. The argument to <tt>readline()</tt> is printed as a prompt in front of the user's input. Readline takes everything up to a newline character.
    Now we use the control structure <tt>while</tt> to check whether we should continue inputting songs.
    The <tt>while(1)</tt> means "loop forever", because 1 is always <b>true</b>.
    This program does not in fact loop forever, because it uses <tt>return</tt>
    to exit the function from within the loop when you type a period.
    When something has been read into the variable song it is checked.
    If it is a "." we return a null value that will be used in the while statement to indicate that it is not ok to continue asking for song names.
    If it is not a dot, the string will be added to the array of songs for this record, unless it's an empty string.
    Note the <tt>+=</tt> operator. It is the same as saying
    <tt>records[record_name]=records[record_name]+({song})</tt>.
    <example language=pike>
    	void add_record()
    	{
    	  string record_name=readline("Record name: ");
    	  records[record_name]=({});
    	  write("Input song names, one per line. End with '.' on its own line.\n");
    	  while(1)
    	  {
    	    string song;
    	    song=readline(sprintf("Song %2d: ",
    	                          sizeof(records[record_name])+1));
    	    if(song==".")
    	       return;
    	    if (strlen(song))
    	      records[record_name]+=({song});
    	  }
    	}
    </example>
    
    </section>
    
    <section title="main()">
    The main function now does not care about any command line arguments.
    Instead we use <tt>readline()</tt> to prompt the user for instructions
    and arguments. The available instructions are "add", "list" and "quit".
    What you enter into the variables cmd and args is checked in the
    <tt>switch()</tt> block. If you enter something that is not covered
    in any of the case statements the program just silently ignores it and
    asks for a new command.
    In a <tt>switch()</tt> the argument (in this case cmd) is checked in the case statements. The first case where the expression equals cmd (the argument) then executes the statement after the colon. If no expression is equal, we just fall through without any action.
    
    The only command that takes an argument is "list" which works like the first version of the program.
    If "list" receives an argument that record is shown along with all the songs
    on it. If there is no argument it shows a list of the records in the database.
    
     When the program returns from either of the listing functions, the break instruction tells the program to jump out of the <tt>switch()</tt> block.
    "Add" of course turns control over to the function described above.
    If the command given is "quit" the <tt>exit(0)</tt> statement stops the execution of the program and returns 0 (zero) to the operating systems, telling it that everything was ok.
    <example language=pike>
    	int main(int argc, array(string) argv)
    	{
    	  string cmd;
    	  while(cmd=readline("Command: "))
    	  {
    	    string args;
    	    sscanf(cmd,"%s %s",cmd,args);
    
    	    switch(cmd)
    	    {
    	    case "list":
    	      if((int)args)
    	      {
    	        show_record((int)args);
    	      } else {
    	        list_records();
    	      }
    	      break;
    
    	    case "quit":
    	      exit(0);
    
    	    case "add":
    	      add_record();
    	      break;
    	    }
    	  }
    	}
    </example>
    
    </section>
    </section>
    
    <section title="Communicating with files">
    Now if we want to save the database and also be able to retrieve previously stored data we have to communicate with the environment, i.e. with files on disk.
    Now we will introduce you to programming with objects.
    To open a file for reading or writing we will use one of the programs which is builtin in Pike called <tt>Stdio.File</tt>.
    To Pike, a program is a data type which contains code, functions and variables.
    A program can be <i>cloned</i> which means that Pike creates a data area
     in memory for the program, place a reference to the program in the data area, and initialize it to act on the data file in question. The methods (ie. functions in the object) and variables in the object Stdio.File enables us to perform actions on the associated data file.
    The methods we need to use are open, read, write and close. See <ref to=io>
    for more details. <!-- Does this link work? -->
    <p>
    
    <section title="save()">
    First we clone a <tt>Stdio.File</tt> program to the object <tt>o</tt>.
    Then we use it to open the file whose<!-- FIX ME: which instead of whose? --> name is given in the string file_name for writing.
    We use the fact that if there is an error during opening, open() will return a false value which we can detect and act upon by exiting.
    The arrow operator (-&gt;) is what you use to access methods and variables in an object.
    If there is no error we use yet another control structure, <tt>foreach</tt>, to go through the mapping <tt>records</tt> one record at a time.
    We precede record names with the string "Record: " and song names with "Song: ".
    We also put every entry, be it song or record, on its own line by adding a newline to everything we write to the file.<br>
    Finally, remember to close the file.
    <example language=pike>
    	void save(string file_name)
    	{
    	  string name, song;
    	  object o;
    	  o=Stdio.File();
    
    	  if(!o-&gt;open(file_name,"wct"))
    	  {
    	    write("Failed to open file.\n");
    	    return;
    	  }
    
    	  foreach(indices(records),name)
    	  {
    	     o-&gt;write("Record: "+name+"\n");
    	     foreach(records[name],song)
    	       o-&gt;write("Song: "+song+"\n");
    	  }
    
    	  o-&gt;close();
    	}
    </example>
    
    </section>
    
    <section title="load()">
    
    The <tt>load</tt> function begins much the same, except we open the file named <tt>file</tt> for reading instead.
    When receiving data from the file we put it in the string <tt>file_contents</tt>.
    The absence of arguments to the method o-&gt;read means that the reading should not end until the end of the file.
    After having closed the file we initialize our database, i.e. the mapping records. Then we have to put <tt>file_contents</tt> into the mapping and we do this by splitting the string on newlines (cf. the split operator in Perl) using the division operator. Yes, that's right: by dividing one string with another we can obtain an array consisting of parts from the first. And by using a <tt>foreach</tt> statement we can take the string <tt>file_contents</tt> apart piece by piece, putting each piece back in its proper place in the mapping records.
    <example language=pike>
    	void load(string file_name)
    	{
    	  object o;
    	  string name="ERROR";
    	  string file_contents,line;
    
    	  o=Stdio.File();
    	  if(!o-&gt;open(file_name,"r"))
    	  {
    	    write("Failed to open file.\n");
    	    return;
    	  }
    
    	  file_contents=o-&gt;read();
    	  o-&gt;close();
    
    	  records=([]);
    
    	  foreach(file_contents/"\n",line)
    	  {
    	    string cmd, arg;
    	    if(sscanf(line,"%s: %s",cmd,arg))
    	    {
    	      switch(lower_case(cmd))
    	      {
    	      case "record":
    	        name=arg;
    	        records[name]=({});
    	        break;
    
    	       case "song":
    	         records[name]+=({arg});
    	         break;
    	      }
    	    }
    	  }
    	}
    </example>
    </section>
    
    <section title="main() revisited">
    
    <tt>main()</tt> remains almost unchanged, except for the addition of two case statements with which we now can call the load and save functions. Note that you must provide a filename to load and save, respectively, otherwise they will return an error which will crash the program.
    <example language=pike>
    	case "save":
    	  save(args);
    	  break;
    
    	case "load":
    	  load(args);
    	  break;
    </example>
    <p>
    </section>
    </section>
    
    <section title="Completing the program">
    Now let's add the last functions we need to make this program useful: the ability to delete entries and search for songs.
    <p>
    
    <section title="delete()">
    If you sell one of your records it might be nice to able to delete that entry from the database. The delete function is quite simple.
    First we set up an array of record names (cf. the <tt>list_records</tt> function).
    Then we find the name of the record of the number <tt>num</tt> and use the builtin function <tt>m_delete()</tt> to remove that entry from <tt>records</tt>.
    <example language=pike>
    	void delete_record(int num)
    	{
    	  array(string) record_names=sort(indices(records));
    	  string name=record_names[num-1];
    
    	  m_delete(records,name);
    	}
    </example>
    </section>
    
    <section title="search()">
    Searching for songs is quite easy too. To count the number of <tt>hits</tt> we declare the variable hits. Note that it's not necessary to initialize variables, that is done automatically when the variable is declared if you do not do it explicitly. To be able to use the builtin function <tt>search()</tt>, which searches for the presence of a given string inside another, we put the search string in lowercase and compare it with the lowercase version of every song. The use of <tt>search()</tt> enables us to search for partial song titles as well.
    When a match is found it is immediately written to standard output with the record name followed by the name of the song where the search string was found and a newline.
    If there were no hits at all, the function prints out a message saying just that.
    <example language=pike>
    	void find_song(string title)
    	{
    	  string name, song;
    	  int hits;
    
    	  title=lower_case(title);
    
    	  foreach(indices(records),name)
    	  {
    	    foreach(records[name],song)
    	    {
    	      if(search(lower_case(song), title) != -1)
    	      {
    	        write(name+"; "+song+"\n");
    	        hits++;
    	      }
    	    }
    	  }
    
    	  if(!hits) write("Not found.\n");
    	}
    </example>
    </section>
    
    <section title="main() again">
    Once again <tt>main()</tt> is left unchanged, except for yet another two case statements used to call the <tt>search()</tt> and <tt>delete</tt> functions, respectively. Note that you must provide an argument to delete or it will not work properly.
    <example language=pike>
    	case "delete":
    	  delete_record((int)args);
    	  break;
    
    	case "search":
    	  find_song(args);
    	  break;
    </example>
    </section>
    </section>
    
    <section title="Then what?">
    Well that's it! The example is now a complete working example of a Pike program. But of course there are plenty of details that we haven't attended to. Error checking is for example extremely sparse in our program. This is left for you
    to do as you continue to read this book. The complete listing of this example can be found in <ref to=register_program>. Read it, study it and enjoy!
    <p>
    
    </section>
    
    <section title="Simple exercises">
    <box>
    <ul>
    <li> Make a program which writes hello world 10 times.
    <li> Modify hello_world.pike to write the first argument to the program.
    <li> Make a program that writes a hello_world program to stdout
         when executed.
    <li> Modify the register program to store data about programs and diskettes
         instead of songs and records.
    <li> Add code to the register program that checks that the user typed
         an argument when required. The program should notify the user and
         wait to receive more commands instead of exiting with an error message.
    <li> Add code to the register program to check that the arguments to
         <tt>show_record</tt> and <tt>delete_records</tt> are numbers. Also
         make sure that the number isn't less than one or bigger than the
         available number of records.
    <li> Rewrite the register program and put all the code in main().
    </ul>
    </box>
    </section>
    </chapter>
    
    <chapter title="Control Structures">
    
    In this chapter all the control structures in Pike will be explained. As
    mentioned earlier, control structures are used to control the flow of the
    program execution. Note that functions that make the program pause and
    simple function calls are not qualified as control structures.
    
    <section title="Conditions">
    Pike only has two major condition control structures. We have already seen
    examples of both of them in Chapter two. But for completeness they will be
    described again in this chapter.
    <p>
    
    <section title="if">
    
    The simplest one is called the <b>if statement</b>. It can be written anywhere
    where a statement is expected and it looks like this:
    <pre>
    	if ( <i>expression</i> )
    	  <i>statement1</i> ;
    	else
    	  <i>statement2</i> ;
    </pre>
    Please note that there is no semicolon after the parenthesis or after the
    <tt>else</tt>. Step by step, <tt>if</tt> does the following:
    <ol>
    <li>First it evaluates <i>expression</i>.<br>
    <li>If the result was <b>false</b> go to point 5.
    <li>Execute <i>statement1</i>.
    <li>Jump to point 6.
    <li>Execute <i>statement2</i>.
    <li>Done.
    </ol>
    
    This is actually more or less how the interpreter executes the if statement.
    In short, <i>statement1</i> is executed if <i>expression</i> is <b>true</b>
    otherwise <i>statement2</i> is executed. If you are not interested in
    having something executed if the expression is false you can drop the
    whole else part like this:
    <pre>
    	if ( <i>expression</i> )
    	  <i>statement1</i> ;
    </pre>
    If on the other hand you are not interested in evaluating something if the
    expression is <b>false</b> you should use the <b>not</b> operator to negate
    the true/false value of the expression. See chapter 5 for more information
    about the <b>not</b> operator. It would look like this:
    <pre>
    	if ( ! <i>expression</i> )
    	  <i>statement2</i> ;
    </pre>
    Any of the statements here and in the rest of this chapter can
    also be a <b>block</b> of statements. A block is a list of statements,
    separated by semicolons and enclosed by brackets. Note that you should
    never put a semicolon after a block of statements. The example above
    would look like this;
    <pre>
    	if ( ! <i>expression</i> )
    	{
    	  <i>statement</i> ;
    	  <i>statement</i> ;
    	  <i>statement</i> ;
    	}
    </pre>
    </section>
    
    <section title="Switch">
    
    A more sophisticated condition control structure is the <b>switch
    statement</b>.
    A switch lets you select one of many choices depending on the value of an
    expression and it can look something like this:
    <pre>
    	switch ( <i>expression</i> )
    	{
    	  case <i>constant1</i>:
    	    <i>expressions1</i> ;
    	    break;
    
     	  case <i>constant2</i>:
    	    <i>expressions2</i> ;
    	    break;
    
     	  case <i>constant3</i> .. <i>constant4</i>:
    	    <i>expressions3</i> ;
    	    break;
    
    	  default:
    	    <i>expressions5</i> ;
    	}
    </pre>
    As you can see, a switch statement is a bit more complicated than an
    if statement. It is still fairly simple however. It starts by evaluating
    the expression it then searches all the <tt>case</tt> statements in the
    following block. If one is found to be equal to the value returned by
    the expression, Pike will continue executing the code directly following
    that <tt>case</tt> statement. When a <tt>break</tt> is encountered Pike
    will skip the rest of the code in the switch block and continue executing
    after the block. Note that it is not strictly necessary to have a break
    before the next case statement. If there is no break before the next case
    statement Pike will simply continue executing and execute the code after
    that case statement as well.
    <p>
    One of the case statements in the above example differs in that it is
    a <b>range</b>. In this case, any value between <i>constant3</i> and
    <i>constant4</i> will cause Pike to jump to <i>expressions3</i>. Note
    that the ranges are inclusive, so the values <i>constant3</i> and
    <i>constant4</i> are also valid.
    
    </section>
    </section>
    
    <section title="Loops">
    
    Loops are used to execute a piece of code more than once. Since this can
    be done in quite a few different ways there are four different loop
    control structures. They may all seem very similar, but using the right
    one at the right time makes the code a lot shorter and simpler.
    
    <section title="while">
    <tt>While</tt> is the simplest of the loop control structures. It looks
    just like an <tt>if</tt> statement without the else part:
    <pre>
    	while ( <i>expression</i> )
    	  <i>statement</i> ;
    </pre>
    The difference in how it works isn't that big either, the statement is
    executed if the expression is true. Then the expression is evaluated
    again, and if it is true the statement is executed again. Then it
    evaluates the expression again and so forth... Here is an example of
    how it could be used:
    <example language=pike>
    	int e=1;
    	while(e&lt;5)
    	{
    	  show_record(e);
    	  e=e+1;
    	}
    </example>
    This would call show_record with the values 1, 2, 3 and 4.
    </section>
    
    <section title="for">
    
    <tt>For</tt> is simply an extension of <tt>while</tt>. It provides an
    even shorter and more compact way of writing loops. The syntax looks
    like this:
    <pre>
    	for ( <i>initializer statement</i> ; <i>expression</i> ; <i>incrementor expression</i> )
    	  <i>statement</i> ;
    </pre>
    For does the following steps:
    <ol>
    <li> Executes the the <i>initializer statement</i>. The initializer statement
         is executed only once and is most commonly used to initialize the loop
          variable.
    <li> Evaluates <i>expression</i>
    <li> If the result was false it exits the loop and continues with the
         program after the loop.
    <li> Executes <i>statement</i>.
    <li> Executes the <i>incrementor expression</i>.
    <li> Starts over from 2.
    </ol>
    This means that the example in the while section can be written like this:
    <example language=pike>
    	for(int e=1; e&lt;5; e=e+1)
    	  show_record(e);
    </example>
    </section>
    
    <section title="do-while">
    
    Sometimes it is unpractical that the expression is always evaluated before
    the first time the loop is executed. Quite often you want to execute
    something, and then do it over and over until some condition is satisfied.
    This is exactly when you should use the do-while statement.
    <pre>
    	do
    	  <i>statement</i> ;
    	while ( <i>expression</i> );
    </pre>
    As usual, the <i>statement</i> can also be a block of statements, and then
    you do not need a semicolon after it. To clarify, this statement executes
    <i>statement</i> first, and then evaluates the <i>expression</i>. If the
    expression is <b>true</b> it executes the loop again. For instance, if you
    want to make a program that lets your modem dial your Internet provider,
    it could look something like this:
    <!-- Can someone come up with a better example? -->
    <example language=pike>
    	do {
    	  modem-&gt;write("ATDT441-9109\n"); // Dial 441-9109
            } while(modem-&gt;gets()[..6]] != "CONNECT");
    </example>
    This example assumes you have written something that can communicate with
    the modem by using the functions <tt>write</tt> and <tt>gets</tt>.
    
    </section>
    
    <section title="foreach">
    
    <tt>Foreach</tt> is unique in that it does not have an explicit test expression
    evaluated for each iteration in the loop. Instead, <tt>foreach</tt> executes
    the statement once for each element in an array. <tt>Foreach</tt> looks like
    this:
    <pre>
    	foreach ( <i>array expression</i>, <i>variable</i> )
    	  <i>statement</i> ;
    </pre>
    We have already seen an example of <tt>foreach</tt> in the <tt>find_song</tt>
    function in chapter 2. What foreach does is:
    <ol>
    <li> It evaluates the <i>array expression</i> which must return an array.
    <li> If the array is empty, exit the loop.
    <li> It then assigns the first element from the array to the <i>variable</i>.
    <li> Then it executes the <i>statement</i>.
    <li> If there are more elements in the array, the next one is assigned to
         the <i>variable</i>, otherwise exit the loop.
    <li> Go to point 4.
    </ol>
    <tt>Foreach</tt> is not really necessary, but it is faster and clearer than
    doing the same thing with a <tt>for</tt> loop, as shown here:
    <pre>
    	array tmp1= <i>array expression</i> ;
    	for ( tmp2 = 0; tmp2 &lt; sizeof(tmp1); tmp2++ )
    	{
    	  <i>variable</i> = tmp1 [ tmp2 ];
    	  <i>statement</i> ;
    	}
    </pre>
    <p>
    </section>
    </section>
    
    <section title="Breaking out of loops">
    The loop control structures above are enough to solve any problem, but
    they are not enough to provide an easy solution to all problems. One thing
    that is still missing is the ability to exit a loop in the middle of it.
    There are three ways to do this:
    
    <section title="break">
    <tt>Break</tt><!-- FIX ME: liten bokstav? --> exits a loop or switch statement immediately and continues
    executing after the loop. <tt>Break</tt> can not be used outside of a loop or
    switch. It is quite useful in conjunction with <tt>while(1)</tt> to
    construct command parsing loops for instance:
    <example language=pike>
    	while(1)
    	{
    	  string command=readline("&gt; ");
    	  if(command=="quit") break;
    	  do_command(command);
    	}
    </example>
    </section>
    
    <section title="continue">
    <tt>Continue</tt> does almost the same thing as <tt>break</tt>, except instead of
    breaking out of the loop it only breaks out of the loop body. It then continues
    to execute the next iteration in the loop. For a <tt>while</tt> loop, this
    means it jumps up to the top again. For a <tt>for</tt> loop, it jumps to the
    incrementor expression. For a <tt>do-while</tt> loop it jumps down to the
    expression at the end. To continue our example above, <tt>continue</tt> can be used
    like this:
    <example language=pike>
    	while(1)
    	{
    	  string command=readline("&gt; ");
    	  if(strlen(command) == 0) continue;
    	  if(command=="quit") break;
    	  do_command(command);
    	}
    </example>
    This way, <tt>do_command</tt> will never be called with an empty string as
    argument.
    </section>
    
    <section title="return">
    
    <tt>Return</tt> doesn't just exit the loop, it exits the whole function. We have seen
    several examples how to use it chapter 2. None of the functions in chapter
    two returned anything in particular however. To do that you just put the return
    value right after <tt>return</tt>. Of course the type of the return value
    must match the type in the function declaration. If your function declaration
    is <tt>int main()</tt> the value after <tt>return</tt> must be an <b>int</b>.
    For instance, if we wanted to make a program that always returns an error
    code to the system, just like the UNIX command <tt>false</tt> this is how
    it would be done:
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	int main()
    	{
    	  return 1;
    	}
    </example>
    This would return the error code <tt>1</tt> to the system when the program
    is run.
    </section>
    </section>
    
    <section title=Exercises>
    
    <box>
    <ul>
    <li> End all functions in the examples in chapter two with a return statement.
    <li> Change all <tt>foreach</tt> loops to <tt>for</tt> or <tt>while</tt> loops.
    <li> Make the <tt>find_song</tt> function in chapter 2 return when the first
         matching song is found.
    <li> Make the <tt>find_song</tt> function write the number of the record
         the song is on.
    <li> If you failed to get the program to work properly in the last exercise
         of chapter 2, try it again now.
    <li> Make a program that writes all the numbers from 1 to 1000.
    <li> Modify the program in the previous exercise to NOT write numbers dividable by 3, 7 or 17.
    <li> Make a program that writes all the prime numbers between 1 to 1000.
    </ul>
    </box>
    </section>
    </chapter>
    
    <chapter title="Data types">
    
    In this chapter we will discuss all the different ways to store data
    in Pike in detail. We have seen examples of many of these, but we haven't
    really gone into how they work. In this chapter we will also see which
    operators and functions work with the different types.
    There are two categories of data types in Pike: <b>basic types</b>, and
    <b>pointer types</b>. The difference is that basic types are copied when
    assigned to variable. With pointer types, merely the pointer is copied,
    that way you get two variables pointing to the same thing.
    <p>
    
    <section title="Basic types">
    The basic types are <tt>int</tt>, <tt>float</tt> and <tt>string</tt>.
    For you who are accustomed to C or C++, it may seem odd that a string
    is a basic type as opposed to an array of char, but it is surprisingly
    easy to get used to.
    
    <section title="int">
    <tt>Int</tt> is short for integer, or integer number. They are normally
    32 bit integers, which means that they are in the range -2147483648 to
    2147483647. Note that on some machines an <tt>int</tt> might be larger
    than 32 bits. Since they are integers, no decimals are allowed. An integer
    constant can be written in several ways:
    <pre>
    	78	// decimal number
    	0116	// octal number
    	0x4e	// hexadecimal number
    	'N'	// Ascii character
    </pre>
    All of the above represent the number 78. Octal notation means that
    each digit is worth 8 times as much as the one after. Hexadecimal notation
    means that each digit is worth 16 times as much as the one after.
    Hexadecimal notation uses the letters a, b, c, d, e and f to represent the
    numbers 10, 11, 12, 13, 14 and 15. The ASCII notation gives the ASCII
    value of the character between the single quotes. In this case the character
    is <tt>N</tt> which just happen to be 78 in ASCII.
    <p>
    Integers are coded in 2-complement and overflows are silently ignored
    by Pike. This means that if your integers are 32-bit and you add 1 to
    the number 2147483647 you get the number -2147483648. This works exactly
    as in C or C++.
    <p>
    All the arithmetic, bitwise and comparison operators can be used on integers.
    Also note these functions:
    <dl>
    <dt><tt>int intp(mixed <i>x</i>)</tt>
    <dd> This function returns 1 if <i>x</i> is an int, 0 otherwise.
    <dt><tt>int random(int <i>x</i>)</tt>
    <dd>This function returns a random number greater or equal to zero and smaller than <i>x</i>.
    <dt><tt>int reverse(int <i>x</i>)</tt>
    <dd>This function reverses the order of the bits in <i>x</i> and returns the new number. It is not very useful.
    <dt><tt>int sqrt(int <i>x</i>)</tt>
    <dd>This computes the square root of <i>x</i>. The value is always rounded down.
    </dl>
    </section>
    
    <section title="float">
    <!-- FIX ME: Du borde skriva något om att float och int inte är kompatibla och ingen 
    implicit casting sker som i C++ -->
    Although most programs only use integers, they are unpractical when doing
    trigonometric calculations, transformations or anything else where you
    need decimals. For this purpose you use <tt>float</tt>. Floats are normally
    32 bit floating point numbers, which means that they can represent very large
    and very small numbers, but only with 9 accurate digits. To write a floating
    point constant, you just put in the decimals or write it in the exponential
    form:
    <pre>
    	3.14159265358979323846264338327950288419716939937510 // Pi
    	1.0e9  // A billion
    	1.0e-9 // A billionth
    </pre>
    Of course you do not need this many decimals, but it doesn't hurt either.
    Usually digits after the ninth digit are ignored, but on some architectures
    <tt>float</tt> might have higher accuracy than that. In the exponential form,
    <tt>e</tt> means "times 10 to the power of", so <tt>1.0e9</tt> is equal to
    "1.0 times 10 to the power of 9".
    <p>
    All the arithmetic and comparison operators can be used on floats.
    Also, these functions operates on floats:
    <dl>
    <dt>trigonometric functions
    <dd> The trigonometric functions are: <tt>sin</tt>, <tt>asin</tt>,
         <tt>cos</tt>, <tt>acos</tt>, <tt>tan</tt> and <tt>atan</tt>.
         If you do not know what these functions do you probably don't
         need them. Asin, acos and atan are of course short for
         arc sine, arc cosine and arc tangent. On a calculator they
         are often known as inverse sine, inverse cosine and
         inverse tangent.
    
    <dt><tt>float log(float <i>x</i>)</tt>
    <dd>This function computes the natural logarithm of <i>x</i>,
    
    <dt><tt>float exp(float <i>x</i>)</tt>
    <dd>This function computes <b>e</b> raised to the power of <i>x</i>.
    
    <dt><tt>float pow(float <i>x</i>, float <i>y</i>)</tt>
    <dd>This function computes <i>x</i> raised to the power of <i>y</i>.
    
    <dt><tt>float sqrt(float <i>x</i>)</tt>
    <dd>This computes the square root of <i>x</i>.
    
    <dt><tt>float floor(float <i>x</i>)</tt>
    <dd>This function computes the highest integer value lower or equal to <i>x</i>. Note that the value is returned as a <tt>float</tt>, not an <tt>int</tt>.
    
    <dt><tt>float ceil(float <i>x</i>)</tt>, 
    <dd>This function computes the lowest integer value higher or equal to <i>x</i> and returns it as a <tt>float</tt>.
    </dl>
    </section>
    
    <section title="string">
    A <tt>string</tt> can be seen as an array of values from 0 to 255.
    Usually a string contains text such as a word, a sentence, a page or
    even a whole book. But it can also contain parts of a binary file,
    compressed data or other binary data. Strings in Pike are <b>shared</b>,
    which means that identical strings share the same memory space. This
    reduces memory usage very much for most applications and also speeds
    up string comparisons. We have already seen how to write a constant
    string:
    <pre>
    	"hello world" // hello world
    	"he" "llo"    // hello
    	"\116"        // N (116 is the octal ASCII value for N)
    	"\t"          // A tab character
    	"\n"          // A newline character
    	"\r"          // A carriage return character
    	"\b"          // A backspace character
    	"\0"          // A null character
    	"\""          // A double quote character
    	"\\"          // A singe backslash
    	"hello world\116\t\n\r\b\0\"\\" // All of the above
    </pre>
    As you can see, any sequence of characters within double quotes is a string.
    The backslash character is used to escape characters that are not allowed or
    impossible to type. As you can see, <tt>\t</tt> is the sequence to produce
    a tab character, <tt>\\</tt> is used when you want one backslash and
    <tt>\"</tt> is used when you want a double quote to be a part of the string
    instead of ending it. Also, <tt>\<i>XXX</i></tt> where <i>XXX</i> is an
    octal number from 000 to 377 lets you write any character you want in the
    string, even null characters. If you write two constant strings after each
    other, they will be concatenated into one string.
    <p>
    Although a string is an array, you can not change the individual characters in the string. Instead you have to construct a new string, here is an example
    of how:
    <example language=pike>
    	string s = "hello torld";
    	s=s[..5]+"w"+s[7..];
    </example>
    <p>
    All the comparison operators plus the operators listed here can be used on strings:
    <dl>
    <dt> Summation
    <dd> Adding strings together will simply concatenate them.
         <tt>"foo"+"bar"</tt> becomes <tt>"foobar"</tt>.
    <dt> Subtraction
    <dd> Subtracting one string from another will remove all occurrences
         of the second string from the first one. So 
         <tt>"foobarfoogazonk" - "foo"</tt> results in <tt>"bargazonk"</tt>.
    <dt> Indexing
    <dd> Indexing will let you get the ascii value of any character in a string.
         The first character is index zero.
    <dt> Range
    <dd> The range operator will let you copy any part of the string into a
         new string. Example: <tt>"foobar"[2..4]</tt> will return <tt>"oba"</tt>.
    <dt> Division
    <dd> Division will let you divide a string at every occurrence of a word or
         character. For instance if you do <tt>"foobargazonk" / "o"</tt> the
         result would be <tt>({"f","","bargaz","nk"})</tt>.
    <dt> Multiplication
    <dd> The reverse of the division operator can be accomplished by multiplying
         an array with a string. So if you evaluate
         <tt>({"f","","bargaz","nk"}) * "o"</tt> the result would be
         <tt>"foobargazonk"</tt>.
    </dl>
    <p>
    Also, these functions operates on strings:
    <dl>
    <dt><tt>string String.capitalize(string <i>s</i>)</tt>
    <dd>Returns <i>s</i> with the first character converted to upper case.
    
    <dt><tt>string lower_case(string <i>s</i>)</tt>
    <dd>Returns <i>s</i> with all the upper case characters converted to lower case.
    
    <dt><tt>string replace(string <i>s</i>, string <i>from</i>, string <i>to</i>)</tt>
    <dd>This function replaces all occurrences of the string <i>from</i> in <i>s</i> with <i>to</i> and returns the new string.
    
    <dt><tt>string reverse(string <i>s</i>)</tt>
    <dd>This function returns a copy of <i>s</i> with the last byte from <i>s</i>
        first, the second last in second place and so on.
    
    <dt><tt>string search(string <i>haystack</i>, string <i>needle</i>)</tt>
    <dd>This function finds the first occurrence of <i>needle</i> in <i>haystack</i>.
    
    <dt><tt>string sizeof(string <i>s</i>)</tt>
    <dd>Same as <tt>strlen(<i>s</i>)</tt>, returns the length of the string.
    
    <dt><tt>int stringp(mixed <i>s</i>)</tt>
    <dd>This function returns 1 if <i>s</i> is a string, 0 otherwise.
    
    <dt><tt>string strlen(string <i>s</i>)</tt>
    <dd>Returns the length of the string <i>s</i>.
    
    <dt><tt>string upper_case(string <i>s</i>)</tt>
    <dd>This function returns <i>s</i> with all lower case characters converted
        to upper case.
    </dl>
    </section>
    </section>
    
    <section title="Pointer types">
    The basic types are, as the name implies, very basic. They are foundation,
    most of the pointer types are merely interesting ways to store the basic
    types. The pointer types are <tt>array</tt>, <tt>mapping</tt>,
    <tt>multiset</tt>, <tt>program</tt>, <tt>object</tt> and <tt>function</tt>.
    They are all <b>pointers</b> which means that they point to something
    in memory. This "something" is freed when there are no more pointers to it.
    Assigning a variable with a value of a pointer type will not copy this
    "something" instead it will only generate a new reference to it. Special care
    sometimes has to be taken when giving one of these types as arguments to
    a function; the function can in fact modify the "something". If this effect
    is not wanted you have to explicitly copy the value. More about this will
    be explained later in this chapter.
    
    <section title="array">
    Arrays are the simplest of the pointer types. An array is merely a block of
    memory with a fixed size containing a number of slots which can hold any
    type of value. These slots are called <b>elements</b> and are accessible
    through the index operator. To write a constant array you enclose the
    values you want in the array with <tt>({ })</tt> like this:
    <pre>
    	({ })      // Empty array
    	({ 1 })    // Array containing one element of type int
    	({ "" })   // Array containing a string
    	({ "", 1, 3.0 }) // Array of three elements, each of different type
    </pre>
    As you can see, each element in the array can contain any type of value.
    Indexing and ranges on arrays works just like on strings, except with
    arrays you can change values inside the array with the index operator.
    However, there is no way to change the size of the array, so if you want
    to append values to the end you still have to add it to another array
    which creates a new array. Figure 4.1 shows how the schematics of an array.
    As you can see, it is a very simple memory structure.
    <p>
    <center>
    <image xfig=array><br>
    fig 4.1
    </center>
    <p>
    Operators and functions usable with arrays:
    <dl>
    <dt> indexing ( <tt><i>arr</i> [ <i>c</i> ]</tt> )
    <dd> Indexing an array retrieves or sets a given element in the array.
         The index <i>c</i> has to be an integer. To set an index, simply put
         the whole thing on the left side of an assignment, like this:
         <tt><i>arr</i> [ <i>c</i> ] = <i>new_value</i></tt>
    
    <dt> range ( <tt><i>arr</i> [ <i>from</i> .. <i>to</i> ]</tt> )
    <dd> The range copies the elements <i>from</i>, <i>from</i>+1, , <i>from</i>+2 ... <i>to</i> into a new array. The new array will have the size <i>to</i>-<i>from</i>+1.
    
    <dt> comparing (<tt><i>a</i> == <i>b</i></tt> and <tt><i>a</i> != <i>b</i></tt>)
    <dd> The equal operator returns 1 if <i>a</i> and <i>b</i> are the <b>same</b> arrays. It is not enough that they have the same size and same data. They must
     be the same array. For example: <tt>({1}) == ({1})</tt> would return 0, while
    <tt>array(int) a=({1}); return a==a;</tt> would return 1. Note that you cannot
    use the operators <tt>&gt;</tt>, <tt>&gt;=</tt>, <tt>&lt;</tt> or <tt>&lt;=</tt> on arrays.
    
    <dt> Summation (<tt><i>a</i> + <i>b</i></tt>)
    <dd> As with strings, summation concatenates arrays. <tt>({1})+({2})</tt> returns <tt>({1,2})</tt>.
    
    <dt> Subtractions (<tt><i>a</i> - <i>b</i></tt>)
    <dd> Subtracting one array from another returns a copy of
        <i>a</i> with all the elements that are also present in <i>b</i> removed.
        So <tt>({1,3,8,3,2}) - ({3,1})</tt> returns <tt>({8,2})</tt>.
    
    <dt> Intersection (<tt><i>a</i> &amp; <i>b</i></tt>)
    <dd> Intersection returns an array with all values that are present in both
         <i>a</i> and <i>b</i>. The order of the elements will be the same as
         the the order of the elements in <i>a</i>. Example:
         <tt>({1,3,7,9,11,12}) &amp; ({4,11,8,9,1})</tt> will return:
         <tt>({1,9,11})</tt>.
    
    <dt> Union (<tt><i>a</i> | <i>b</i></tt>)
    <dd> Union works almost as summation, but it only concatenates elements not
         already present in <i>a</i>. So, <tt>({1,2,3}) | ({1,3,5})</tt> will
         return <tt>({1,2,3,5})</tt>.
    
    <dt> Xor (<tt><i>a</i> ^ <i>b</i></tt>)
    <dd>  This is also called symmetric difference. It returns an array with all
         elements present in <i>a</i> or <i>b</i> but the element must NOT
         be present in both. Example: <tt>({1,3,5,6}) ^ ({4,5,6,7})</tt> will
         return <tt>({1,3,4,7})</tt>.
    
    <dt><tt>array aggregate(mixed ... <i>elems</i>)</tt>
    <dd> This function does the same as the <tt>({ })</tt> operator; it creates an
         array from all arguments given to it. In fact, writing <tt>({1,2,3})</tt>
         is the same as writing <tt>aggregate(1,2,3)</tt>.
    
    <dt><tt>array allocate(int <i>size</i>)</tt>
    <dd>This function allocates a new array of size <tt>size</tt>. All the elements
        in the new array will be zeroes.
    
    <dt><tt>int arrayp(mixed <i>a</i>)</tt>
    <dd>This function returns 1 if <i>a</i> is an array, 0 otherwise.
    
    <dt><tt>array column(array(mixed) <i>a</i>, mixed <i>ind</i>)</tt>
    <dd>This function goes through the array <i>a</i> and indexes every element
        in it on <i>ind</i> and builds an array of the results. So if you have
        an array <i>a</i> in which each element is a also an array. This function
        will take a cross section, by picking out element <i>ind</i> from each
        of the arrays in <i>a</i>. Example:
        <tt>column( ({ ({1,2,3}), ({4,5,6}), ({7,8,9}) }), 2)</tt> will return
        <tt>({3,6,9})</tt>.
    
    <dt><tt>int equal(mixed <i>a</i>, mixed <i>b</i>)</tt>
    <dd> This function returns 1 if if <i>a</i> and <i>b</i> look the same. They
         do not have to be pointers to the same array, as long as they are the same
         size and contain equal data.
    
    <dt><tt>array Array.filter(array <i>a</i>, mixed <i>func</i>, mixed ... <i>args</i>)</tt>
    <dd> <tt>filter</tt> returns every element in <i>a</i> for which <i>func</i> returns <b>true</b> when called with that element as first argument, and <i>args</i> for the second, third, etc. arguments.
    
    <dt><tt>array Array.map(array <i>a</i>, mixed <i>func</i>, mixed ... <i>args</i>)</tt>
    <dd> This function works similar to <tt>Array.filter</tt> but returns the results
         of the function <i>func</i> instead of returning the elements from <i>a</i> for which <i>func</i> returns <b>true</b>.
    
    <dt><tt>array replace(array <i>a</i>, mixed <i>from</i>, mixed <i>to</i>)</tt>
    <dd>This function will create a copy of <i>a</i> with all elements equal to
        <i>from</i> replaced by <i>to</i>.
    
    <dt><tt>array reverse(array <i>a</i>)</tt>
    <dd><tt>Reverse</tt> will create a copy of <i>a</i> with the last element first, the last but one second, and so on.
    
    <dt><tt>array rows(array <i>a</i>, array <i>indexes</i>)</tt>
    <dd>This function is similar to <tt>column</tt>. It indexes <i>a</i> with
     each element from <i>indexes</i> and returns the results in an array.
    For example: <tt>rows( ({"a","b","c"}), ({ 2,1,2,0}) ) </tt> will return
    <tt>({"c","b","c","a"})</tt>.
    
    <dt><tt>int search(array <i>haystack</i>, mixed <i>needle</i>)</tt>
    <dd>This function returns the index of the first occurrence of an element
        equal (tested with <tt>==</tt>) to <i>needle</i> in the array
        <i>haystack</i>. 
    
    
    <dt><tt>int sizeof(mixed <i>arr</i>)</tt>
    <dd>This function returns the number of elements in the array <i>arr</i>
    
    <dt><tt>array sort(array <i>arr</i>, array ... <i>rest</i>)</tt>
    <dd>This function sorts <i>arr</i> in smaller-to-larger order. Numbers, floats
        and strings can be sorted. If there are any additional arguments, they
        will be permutated in the same manner as <i>arr</i>. See
        <ref to=functions> for more details.
    
    <dt><tt>array uniq(array <i>a</i>)</tt>
    <dd>This function returns a copy of the array <i>a</i> with all duplicate
        elements removed. Note that that this function can return the elements
        in any order.
    </dl>
    </section>
    
    <section title="mapping">
    Mappings are are really just more generic arrays. However, they are slower
    and use more memory than arrays, so they cannot replace arrays completely.
    What makes mappings special is that they can be indexed on other things than
    integers. We can imagine that a mapping looks like this:
    <p>
    <center>
    <image xfig=mapping><br>
    fig 4.2
    </center>
    <p>
    Each index-value pair is floating around freely inside the mapping. There is
    exactly one value for each index. We also have a (magical) lookup function.
    This lookup function can find any index in the mapping very quickly. Now, if
    the mapping is called <i>m</i> and we index it like this:
    <tt><i>m</i> [ <i>i</i> ]</tt> the lookup function will quickly find the index
    <i>i</i> in the mapping and return the corresponding value. If the index is 
    not found, zero is returned instead. 
    If we on the other hand assign an index in the mapping the value will
    instead be overwritten with the new value. If the index is not found when
    assigning, a new index-value pair will be added to the mapping.
    Writing a constant mapping is easy:
    <pre>
    	([ ])       // Empty mapping
    	([ 1:2 ])   // Mapping with one index-value pair, the 1 is the index
    	([ "one":1, "two":2 ]) // Mapping which maps words to numbers
    	([ 1:({2.0}), "":([]), ]) // Mapping with lots of different types
    </pre>
    <p>
    As with arrays, mappings can contain any type. The main difference is that
    the index can be any type too. Also note that the index-value pairs in a
    mapping are not stored in a specific order. You can not refer to the
    fourteenth key-index pair, since there is no way of telling which one is
    the fourteenth. Because of this, you cannot use the range operator on
    mappings.
    <p>
    The following operators and functions are important to use mappings:
    <dl>
    <dt> indexing ( <tt><i>m</i> [ <i>ind</i> ]</tt> )
    <dd> As discussed above, indexing is used to retrieve, store and add values
         to the mapping.
    <dt> addition, subtraction, union, intersection and xor
    <dd> All these operators works exactly as on arrays, with the difference that
         they operate on the indexes. In those cases when the value can come from
         either mapping, it will be taken from the right side of the operator.
         This is to make it easier to add new values to a mapping with <tt>+=</tt>.
         Some examples:<br>
         <tt>([1:3, 3:1]) + ([2:5, 3:7])</tt> returns <tt>([1:3, 2:5, 3:7 ])</tt><br>
         <tt>([1:3, 3:1]) - ([2:5, 3:7])</tt> returns <tt>([1:3])</tt><br>
         <tt>([1:3, 3:1]) | ([2:5, 3:7])</tt> returns <tt>([1:3, 2:5, 3:7 ])</tt><br>
         <tt>([1:3, 3:1]) &amp; ([2:5, 3:7])</tt> returns <tt>([3:7])</tt><br>
         <tt>([1:3, 3:1]) ^ ([2:5, 3:7])</tt> returns <tt>([1:3, 2:5])</tt><br>
    
    <dt> same ( <tt><i>a</i> == <i>b</i></tt> )
    <dd> Returns 1 if <i>a</i> is <b>the same</b> mapping as <i>b</i>, 0 otherwise.
    
    <dt> not same <tt><i>a</i> != <i>b</i></tt> )
    <dd> Returns 0 if <i>a</i> is <b>the same</b> mapping as <i>b</i>, 1 otherwise.
    
    <dt><tt>array indices(mapping <i>m</i>)</tt>
    <dd><tt>Indices</tt> returns an array containing all the indexes in the mapping <i>m</i>.
    
    <dt><tt>void m_delete(mapping <i>m</i>, mixed <i>ind</i>)</tt>
    <dd>This function removes the index-value pair with the index <i>ind</i> from the mapping <i>m</i>.
    
    <dt><tt>int mappingp(mixed <i>m</i>)</tt>
    <dd>This function returns 1 if <i>m</i> is a mapping, 0 otherwise.
    
    <dt><tt>mapping mkmapping(array <i>ind</i>, array <i>val</i>)</tt>
    <dd>This function constructs a mapping from the two arrays <i>ind</i> and
        <i>val</i>. Element 0 in <i>ind</i> and element 0 in <i>val</i> becomes
        one index-value pair. Element 1 in <i>ind</i> and element 1 in <i>val</i>
        becomes another index-value pair, and so on..
    
    <dt><tt>mapping replace(mapping <i>m</i>, mixed <i>from</i>, mixed <i>to</i>)</tt>
    <dd>This function creates a copy of the mapping <i>m</i> with all values equal to <i>from</i> replaced by <i>to</i>.
    
    <dt><tt>mixed search(mapping <i>m</i>, mixed <i>val</i>)</tt>
    <dd>This function returns the index of the 'first' index-value pair which has the value <i>val</i>.
    
    <dt><tt>int sizeof(mapping <i>m</i>)</tt>
    <dd><tt>Sizeof</tt> returns how many index-value pairs there are in the mapping.
    
    <dt><tt>array values(mapping <i>m</i>)</tt>
    <dd>This function does the same as <tt>indices</tt>, but returns an array with all the values instead. If <tt>indices</tt> and <tt>values</tt> are called on the same mapping after each other, without any other mapping operations in between, the returned arrays will be in the same order. They can in turn be used as arguments to <tt>mkmapping</tt> to rebuild the mapping <i>m</i> again.
    
    <dt><tt>int zero_type(mixed t)</tt>
    <dd>When indexing a mapping and the index is not found, zero is returned. However, problems can arise if you have also stored zeroes in the mapping. This function allows you to see the difference between the two cases. If <tt>zero_type(<i>m</i> [ <i>ind</i> ])</tt> returns 1, it means that the value was not present
    in the mapping. If the value was present in the mapping, <tt>zero_type</tt> will return something else than 1.
    </dl>
    </section>
    
    
    <section title="multiset">
    
    A multiset is almost the same thing as a mapping. The difference is that there
    are no values:
    <p>
    <center>
    <image xfig=multiset><br>
    fig 4.3
    </center>
    <p>
    Instead, the index operator will return 1 if the value was found
    in the multiset and 0 if it was not. When assigning an index to a multiset like
    this: <tt><i>mset</i>[ <i>ind</i> ] = <i>val</i></tt> the index <i>ind</i>
    will be added to the multiset <i>mset</i> if <i>val</i> is <b>true</b>.
    Otherwise <i>ind</i> will be removed from the multiset instead.
    <p>
    Writing a constant multiset is similar to writing an array:
    <pre>
    	(&lt; &gt;)      // Empty multiset
    	(&lt; 17 &gt;)  // Multiset with one index: 17
    	(&lt; "", 1, 3.0, 1 &gt;) // Multiset with 3 indexes
    </pre>
    Note that you can actually have two of the same index in a multiset. This is
    normally not used, but can be practical at times.
    </section>
    
    <section title="program" name=programs>
    
    Normally, when we say <b>program</b> we mean something we can execute from
    a shell prompt. However, Pike has another meaning for the same word. In Pike
    a <tt>program</tt> is the same as a <b>class</b> in C++. A <tt>program</tt>
    holds a table of what functions and variables are defined in that program.
    It also holds the code itself, debug information and references to other
    programs in the form of inherits. A <tt>program</tt> does not hold space
    to store any data however.
    All the information in a <tt>program</tt> is
    gathered when a file or string is run through the Pike compiler. The variable
    space needed to execute the code in the program is stored in an <tt>object</tt>
    which is the next data type we will discuss. 
    <p>
    <center>
      <image xfig=program><br>
    fig 4.4
    </center>
    Writing a <tt>program</tt> is easy, in fact, every example we have tried so
    far has been a <tt>program</tt>. To load such a program into memory, we can
    use <tt>compile_file</tt> which takes a file name, compiles the file
    and returns the compiled program. It could look something like this:
    <example language=pike>
    	program p = compile_file("hello_world.pike");
    </example>
    You can also use the <b>cast</b> operator like this:
    <example language=pike>
    	program p = (program) "hello_world";
    </example>
    This will also load the program <tt>hello_world.pike</tt>, the only difference
    is that it will cache the result so that next time you do <tt>(program)"hello_world"</tt> you will receive the _same_ program. If you call
    <tt>compile_file("hello_world.pike")</tt> repeatedly you will get a new program
    for each time.
    <p>
    There is also a way to write programs inside programs with the help of the
    <tt>class</tt> keyword:
    <pre>
    	class <i>class_name</i> {
    	  <i>inherits, variables and functions </i>
    	}
    </pre>
    The <tt>class</tt> keyword can be written as a separate entity
    outside of all functions, but it is also an expression which returns the
    <tt>program</tt> written between the brackets. The <i>class_name</i> is
    optional. If used you can later refer to that <tt>program</tt> by the name
    <i>class_name</i>.
    This is very similar to how classes are written in C++ and can be used
    in much the same way. It can also be used to create <b>structs</b>
    (or records if you program Pascal).
     Let's look at an example:
    <example language=pike>
    	class record {
    	  string title;
    	  string artist;
    	  array(string) songs;
    	}
    
    	array(object(record)) records = ({});
    
    	void add_empty_record()
    	{
    	  records+=({ record() });
    	}
    
    	void show_record(object(record) rec)
    	{
    	  write("Record name: "+rec-&gt;title+"\n");
    	  write("Artist: "+rec-&gt;artist+"\n");
    	  write("Songs:\n");
    	  foreach(rec-&gt;songs, string song)
    	    write("   "+song+"\n");
    	}
    </example>
    This could be a small part of a better record register program. It is not
    a complete executable program in itself.  In this example we create a
    <tt>program</tt> called <tt>record</tt> which has three identifiers.
    In <tt>add_empty_record</tt> a new object is created
    by calling <tt>record</tt>. This is called <b>cloning</b> and it
    allocates space to store the variables defined in the <tt>class record</tt>.
    <tt>Show_record</tt> takes one of the records created in
    <tt>add_empty_record</tt> and shows the contents of it. As you can see, the arrow operator
    is used to access the data allocated in <tt>add_empty_record</tt>.
    If you do not understand this section I suggest you go on and read the
    next section about <tt>objects</tt> and then come back and read this
    section again.
    <p>
    
    <dl>
    <dt> cloning
    <dd> To create a data area for a <tt>program</tt> you need to instantiate or
         <b>clone</b> the program. This is accomplished by using a pointer
         to the <tt>program</tt> as if it was a function and call it. That
         creates a new object and calls the function <tt>create</tt> in the
         new object with the arguments. It is also possible to use the
         functions <tt>new()</tt> and <tt>clone()</tt> which do exactly the
         same thing except you can use a string to specify what program you
         want to clone.
    <dt> compiling
    <dd> All programs are generated by compiling a file or a string. For this
         purpose there are two functions:
    <pre>
    	program compile_file(string <i>filename</i>);
    	program compile_string(string <i>p</i>, string <i>filename</i>);
    </pre>
         <tt>Compile_file</tt> simply reads the file given as argument, compiles
         it and returns the resulting program. <tt>Compile_string</tt> instead
         compiles whatever is in the string <i>p</i>. The second argument,
         <i>filename</i>, is only used in debug printouts when an error occurs
         in the newly made program.
    
    <dt> casting
    <dd> Another way of compiling files to program is to use the <b>cast</b>
         operator. Casting a string to the type <tt>program</tt> calls a function
         in the master object which will compile the program in question for you.
         The master also keeps the program in a cache, so if you later need the
         same program again it will not be re-compiled.
    <dt> <tt>int programp(mixed <i>p</i>)</tt>
    <dd> This function returns 1 if <i>p</i> is a program, 0 otherwise.
    <dt> comparisons
    <dd> As with all data types <tt>==</tt> and <tt>!=</tt> can be used to
         see if two programs are the same or not.
    </dl>
    </section>
    
    
    <section title="object">
    Although programs are absolutely necessary for any application you might
    want to write, they are not enough. A <tt>program</tt> doesn't have anywhere
    to store data, it just merely outlines how to store data. To actually store
    the data you need an <tt>object</tt>. Objects are basically a chunk of memory
    with a reference to the program from which it was cloned. Many objects can
    be made from one program. The <tt>program</tt> outlines where in the object
    different variables are stored.
    <center>
      <image xfig=object><br>
    fig 4.5
    </center>
    Each object has its own set of variables, and when calling a function in that
    object, that function will operate on those variables. If we take a look at
    the short example in the section about programs, we see that it would be
    better to write it like this:
    <example language=pike>
    	class record {
    	  string title;
    	  string artist;
    	  array(string) songs;
    
    	  void show()
    	  {
    	    write("Record name: "+title+"\n");
    	    write("Artist: "+artist+"\n");
                write("Songs:\n");
                foreach(songs, string song)
    	      write("   "+song+"\n");
    	  }
    	}
    
    	array(object(record)) records = ({});
    
    	void add_empty_record()
    	{
    	  records+=({ record() });
    	}
    
    	void show_record(object rec)
    	{
    	  rec-&gt;show();
    	}
    </example>
    Here we can clearly see how the function <tt>show</tt> prints the
    contents of the variables in that object. In essence, instead of accessing
    the data in the object with the <tt>-&gt;</tt> operator, we call a function
    in the object and have it write the information itself. This type of
    programming is very flexible, since we can later change how <tt>record</tt>
    stores its data, but we do not have to change anything outside of
    the <tt>record</tt> program.
    <p>
    Functions and operators relevant to objects:
    <dl>
    <dt> indexing
    <dd> Objects can be indexed on strings to access identifiers. If the identifier
         is a variable, the value can also be set using indexing. If the identifier
         is a function, a pointer to that function will be returned. If the
         identifier is a constant, the value of that constant will be returned.
         Note that the <tt>-&gt;</tt> operator is actually the same as indexing.
         This means that <tt>o-&gt;foo</tt> is the same as <tt>o["foo"]</tt>
    <dt> cloning
    <dd> As discussed in the section about programs, cloning a program can be done
         in two different ways:
         <ol>
         <li> Use a pointer to the program as a function and call it.
         <li> Use the functions <tt>new</tt> or <tt>clone</tt>. (They are the same function.)
         </ol>
         Whenever you clone an object, all the global variables will be
         initialized. After that the function <tt>create</tt> will be called
         with any arguments you call the program with.
    <dt> <tt>void destruct(object <i>o</i>)</tt>
    <dd> This function invalidates all references to the object <i>o</i> and
         frees all variables in that object. This function is also called when
         <i>o</i> runs out of references. If there is a function named
         <tt>destroy</tt> in the object, it will be called before the actual
         destruction of the object.
    <dt> <tt>array(string) indices(object <i>o</i>)</tt>
    <dd> This function returns a list of all identifiers in the object <i>o</i>.
    <dt> <tt>program object_program(object <i>o</i>)</tt>
    <dd> This function returns the program from which <i>o</i> was cloned.
    <dt> <tt>int objectp(mixed <i>o</i>)</tt>
    <dd> This function returns 1 if <i>o</i> is an object, 0 otherwise.
         Note that if <i>o</i> has been destructed, this function will return 0.
    <dt> <tt>object this_object()</tt>
    <dd> This function returns the object in which the interpreter is currently
         executing.
    <dt> <tt>array values(object <i>o</i>)</tt>
    <dd> This function returns the same as <tt>rows(o,indices(o))</tt>.
         That means it returns all the values of the identifiers in the
         object <i>o</i>.
    <dt> comparing
    <dd> As with all data types <tt>==</tt> and <tt>!=</tt> can be used to
         check if two objects are the same or not.
    </dl>
    </section>
    
    <section title="function">
    
    When indexing an object on a string, and that string is the name of a function
    in the object a <tt>function</tt> is returned. Despite its name, a
    <tt>function</tt> is really a <b>function pointer</b>.
    <center>
      <image xfig=function><br>
    fig 4.6
    </center>
    
    When the function pointer is called, the interpreter sets
    <tt>this_object()</tt> to the object in which the function is located and
    proceeds to execute the function it points to. Also note that function pointers
    can be passed around just like any other data type:
    <example language=pike>
    	int foo() { return 1; }
    	function bar() { return foo; }
    	int gazonk() { return foo(); }
    	int teleledningsanka() { return bar()(); }
    </example>
    In this example, the function bar returns a pointer to the function
    <tt>foo</tt>. No indexing is necessary since the function <tt>foo</tt> is
    located in the same object. The function <tt>gazonk</tt> simply calls
    <tt>foo</tt>. However, note that the word <tt>foo</tt> in that function
    is an expression returning a function pointer that is then called. To
    further illustrate this, <tt>foo</tt> has been replaced by <tt>bar()</tt>
    in the function <tt>teleledningsanka</tt>.
    <p>
    For convenience, there is also a simple way to write a function inside another
    function. To do this you use the <tt>lambda</tt> keyword.  The
    syntax is the same as for a normal function, except you write
    <tt>lambda</tt> instead of the function name:
    <pre>
    	lambda ( <i>types</i> ) { <i>statements</i> }
    </pre>
    The major difference is that this is an expression that can be used inside
    other function. Example:
    <example language=pike>
    	function bar() { return lambda() { return 1; }; )
    </example>
    This is the same as the first two lines in the previous example, the keyword
    <tt>lambda</tt> allows you to write the function inside <tt>bar</tt>.
    <p>
    Note that unlike C++ and Java you can not use function overloading in Pike.
    This means that you cannot have one function called 'foo' which takes an
    integer argument and another function 'foo' which takes a float argument.
    <p>
    This is what you can do with a function pointer.
    <dl>
    <dt> calling ( <i>f</i> ( mixed ... <i>args</i> ) )
    <dd> As mentioned earlier, all function pointers can be called. In this example
         the function <i>f</i> is called with the arguments <i>args</i>.
    
    <dt> <tt>string function_name(function <i>f</i>)</tt>
    <dd> This function returns the name of the function <i>f</i> is pointing at.
    
    <dt> <tt>object function_object(function <i>f</i>)</tt>
    <dd> This function returns the object the function <i>f</i> is located in.
    
    <dt> <tt>int functionp(mixed <i>f</i>)</tt>
    <dd> This function returns 1 if <i>f</i> is a <tt>function</tt>, 0 otherwise.
         If <i>f</i> is located in a destructed object, 0 is returned.
    
    <dt> <tt>function this_function()</tt>
    <dd> This function returns a pointer to the function it is called from.
         This is normally only used with <b>lambda</b> functions because they
         do not have a name.
    </dl>
    </section>
    </section>
    
    <section title="Sharing data">
    As mention in the beginning of this chapter, the assignment operator
    (<tt>=</tt>) does not copy anything when you use it on a pointer type.
    Instead it just creates another reference to the memory object.
    In most situations this does not present a problem, and it speeds up
    Pike's performance. However, you must be aware of this when programming.
    This can be illustrated with an example:
    <example language=pike>
    	int main(int argc, array(string) argv)
    	{
    	  array(string) tmp;
    	  tmp=argv;
    	  argv[0]="Hello world.\n";
    	  write(tmp[0]);
    	}
    </example>
    This program will of course write <tt>Hello world.</tt>
    <p>
    Sometimes you want to create a copy of a mapping, array or object. To
    do so you simply call <tt>copy_value</tt> with whatever you want to copy
    as argument. Copy_value is recursive, which means that if you have an
    array containing arrays, copies will be made of all those arrays.
    <p>
    If you don't want to copy recursively, or you know you don't have to
    copy recursively, you can use the plus operator instead. For instance,
    to create a copy of an array you simply add an empty array to it, like this:
    <tt>copy_of_arr = arr + ({});</tt> If you need to copy a mapping you use
    an empty mapping, and for a multiset you use an empty multiset.
    </section>
    
    
    <section title="Writing data types">
    
    When declaring a variable, you also have to specify what type of variable
    it is. For most types, such as <tt>int</tt> and <tt>string</tt> this is
    very easy. But there are much more interesting ways to declare variables
    than that, let's look at a few examples:
    <pre>
    	int x; // x is an integer
    	int|string x; // x is a string or an integer
    	array(string) x; // x is an array of strings
    	array x; // x is an array of mixed
    	mixed x; // x can be any type
    	string *x; // x is an array of strings
    	mapping(string:int) x; // x is a mapping mapping from int to string
    	object(Stdio.File) x; // x is a clone of Stdio.File
    
    	// x is a function that takes two integer arguments and returns a string
    	function(int,int:string) x;
    
    	// x is a function taking any amount of integer arguments and returns nothing.
    	function(int...:void) x;
    
    	// x is ... complicated
    	mapping(string:function(string|int...:mapping(string:string*))) x;
    </pre>
    As you can see there are some interesting ways to specify types.
    Here is a list of what is possible:
    <dl>
    <dt> <tt>mixed</tt>
    <dt> This means that the variable can contain any type, or the
    	function return any value
    <dt> <tt>array( <i>type</i> )</tt>
    <dd> This means an array of <i>type</i>.
    <dt> <tt><i>type</i> *</tt>
    <dd> This also means an array of <i>type</i>.
    <dt> <tt>mapping( <i>key type</i> : <i>value type</i> )</tt>
    <dd> This is a mapping where the keys are of type <i>key type</i> and the
          values of <i>value type</i>.
    <dt> <tt>multiset ( <i>type</i> )</tt>
    <dd> This means a multiset containing values of type <i>type</i>.
    <dt> <tt>object ( <i>program</i> )</tt>
    <dd> This means an object cloned from the specified program. The
         <i>program</i> can be a class, a constant, or a string. If the program
         is a string it will be casted to a program first. See the documentation
         for <tt>inherit</tt> for more information about this casting.
    <dt> <tt>function( <i>argument types</i> : <i>return type</i> )</tt>
    <dd> This is a function taking the specified arguments and returning
         <i>return type</i>. The <i>argument types</i> is a comma separated
         list of types that specify the arguments. The argument list can also
         end with <tt>...</tt> to signify that there can be any amount of the
         last type.
    <dt> <tt><i>type1</i> | <i>type2</i></tt>
    <dd> This means either <i>type1</i> or <i>type2</i>
    <dt> <tt>void</tt>
    <dd> Void can only be used in certain places, if used as return type for a
         function it means that the function does not return a value. If used
         in the argument list for a function it means that that argument can
         be omitted. Example: <tt>function(int|void:void)</tt> this means a
         function that may or may not take an integer argument and does not
         return a value.
    </dl>
    
    </section>
    
    <!-- FIX ME: insert some things for the reader to do here -->
    
    </chapter>
    
    <chapter title="Operators" name=operators>
    
    To make it easier to write Pike, and to make the code somewhat shorter,
    some functions can be called with just one or two characters in the code.
    These functions are called <b>operators</b> and we have already seen how
    they work in plenty of examples. In this chapter I will describe in detail
    what they do. The operators are divided into categories depending on their
    function, but beware that some operators have meanings that go way beyond
    the scope of the category they are in.
    
    <section title="Arithmetic operators">
    The arithmetic operators are the simplest ones, since they work just like
    you remember from math in school. The arithmetic operators are:
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>	<th>Syntax</th>	<th>Identifier</th> <th>Returns</th></tr>
    <tr><td>Addition</td>	<td>a + b</td>	<td>`+</td>	<td>the sum of a and b</td></tr>
    <tr><td>Subtraction</td><td>a - b</td>	<td>`-</td>	<td>b subtracted from a</td></tr>
    <tr><td>Negation</td>	<td>- a</td>	<td>`-</td>	<td>minus a</td></tr>
    <tr><td>Multiplication</td><td>a * b</td><td>`*</td>	<td>a multiplied by b</td></tr>
    <tr><td>Division</td>	<td>a / b</td>	<td>`/</td>	<td>a divided by b</td></tr>
    <tr><td>Modulo</td>	<td>a % b</td>	<td>`%</td>	<td>the remainder of a division between a and b</td></tr>
    </table>
    </center>
    <p>
    The third column, "Identifier" is the name of the function that actually
    evaluates the operation. For instance, <tt>a + b</tt> can also be written
    as <tt>`+(a, b)</tt>. I will show you how useful this can be at the end
    of this chapter.
    <p>
    When applied to integers or floats these operators do exactly what they
    are supposed to do. The only operator in the list not known from basic
    math is the <b>modulo</b> operator. The modulo operator returns the
    rest of an integer division. It is the same as calculating
    <tt>a - floor(a / b) * b</tt>. <tt>floor</tt> rounds the value down to
    closest lower integer value. Note that the call to <tt>floor</tt> isn't
    needed when operating on integers, since dividing two integers will return
    the result as an integer and it is always rounded down. For instance,
    <tt>8 / 3</tt> would return <tt>2</tt>.
    <p>
    If all arguments to the operator are integers, the
    result will also be an integer. If one is a float and the other is
    an integer, the result will be a float. If both arguments are float,
    the result will of course be a float.
    <p>
    However, there are more types in Pike than integers and floats. Here is
    the complete list of combinations of types you can use with these operators:
    
    <center>
    <table border=1>
    
    <tr>
    <th>Operation</th><th>Returned type</th><th>Returned value</th>
    </tr>
    
    <tr>
    <td><tt><i>int</i>&nbsp;+&nbsp;<i>int</i></tt></td><td>int</td><td>the sum of the two values</td>
    </tr>
    
    <tr>
    <td><tt><i>float</i>&nbsp;+&nbsp;<i>int</i><br>
      <i>int</i>&nbsp;+&nbsp;<i>float</i><br>
      <i>float</i>&nbsp;+&nbsp;<i>float</i></tt></td><td>float</td><td>the sum of the two values</td>
    </tr>
    
    <tr>
    <td><tt><i>string</i>&nbsp;+&nbsp;<i>string</i><br>
      <i>int</i>&nbsp;+&nbsp;<i>string</i><br>
      <i>float</i>&nbsp;+&nbsp;<i>string</i><br>
      <i>string</i>&nbsp;+&nbsp;<i>int</i><br>
      <i>string</i>&nbsp;+&nbsp;<i>float</i></tt></td><td>string</td><td>In this case, any int or float is first converted to a string. Then the two strings are concatenated and the resulting string is returned.</td>
    </tr>
    
    <tr>
    <td><tt><i>array</i>&nbsp;+&nbsp;<i>array</i></tt></td><td>array</td><td>The two arrays are concatenated into a new array and that new array is returned.</td>
    </tr>
    
    <tr>
    <td><tt><i>mapping</i>&nbsp;+&nbsp;<i>mapping</i></tt></td><td>mapping</td><td>A mapping with all the index-value pairs from both mappings is returned. If an index is present in both mappings the index-value pair from the right mapping will be used.</td>
    </tr>
    
    <tr>
    <td><tt><i>multiset</i>&nbsp;+&nbsp;<i>multiset</i></tt></td><td>multiset</td><td>A multiset with all the indices from both muiltisets is returned.</td>
    </tr>
    
    <tr>
    <td><tt><i>int</i>&nbsp;-&nbsp;<i>int</i></tt></td><td>int</td><td>The right value subtracted from the left.</td>
    </tr>
    
    <tr>
    <td><tt><i>float</i>&nbsp;-&nbsp;<i>int</i><br>
      <i>int</i>&nbsp;-&nbsp;<i>float</i><br>
      <i>float</i>&nbsp;-&nbsp;<i>float</i></tt></td><td>float</td><td>The right value subtracted from the left.</td>
    </tr>
    
    <tr>
    <td><tt><i>string</i>&nbsp;-&nbsp;<i>string</i></tt></td><td>string</td><td>A copy of the left string with all occurrences of the right string removed.</td>
    </tr>
    
    <tr>
    <td><tt><i>array</i>&nbsp;-&nbsp;<i>array</i></tt></td><td>array</td><td>A copy of the right array with all elements present in the right array removed. Example: <tt>({2,1,4,5,3,6,7}) - ({3,5,1})</tt> will return <tt>({2,4,6,7})</tt>.</td>
    </tr>
    
    <tr>
    <td><tt><i>mapping</i>&nbsp;-&nbsp;<i>mapping</i></tt></td><td>mapping</td><td>A new mapping with all index-value pairs from the left mapping, except those indexes that are also present in the right mapping.</td>
    </tr>
    
    <tr>
    <td><tt><i>multiset</i>&nbsp;-&nbsp;<i>multiset</i></tt></td><td>multiset</td><td>A copy of the left multiset without any index present in the left multiset.</td>
    </tr>
    
    <tr>
    <td><tt>-&nbsp;<i>int</i></tt></td><td>int</td><td>Same as 0 - <i>int</i>.</td>
    </tr>
    
    <tr>
    <td><tt>-&nbsp;<i>float</i></tt></td><td>float</td><td>Same as 0 - <i>float</i>.</td>
    </tr>
    
    <tr>
    <td><tt><i>int</i>&nbsp;*&nbsp;<i>int</i></tt></td><td>int</td><td>the product of the two values</td>
    </tr>
    
    <tr>
    <td><tt><i>float</i>&nbsp;*&nbsp;<i>int</i><br>
      <i>int</i>&nbsp;*&nbsp;<i>float</i><br>
      <i>float</i>&nbsp;*&nbsp;<i>float</i></tt></td><td>float</td><td>the product of the two values</td>
    </tr>
    
    <tr>
    <td><tt><i>array(string)</i>&nbsp;*&nbsp;<i>string</i></tt></td><td>string</td><td>All the strings in the array are concatenated with the string on the right in between each string. Example: <tt>({"foo,"bar})*"-"</tt> will return <tt>"foo-bar".</tt></td>
    </tr>
    
    <tr>
    <td><tt><i>int</i>&nbsp;/&nbsp;<i>int</i></tt></td><td>int</td><td>The right integer divided by the left integer rounded towards zero.</td>
    </tr>
    
    <tr>
    <td><tt><i>float</i>&nbsp;/&nbsp;<i>int</i><br>
      <i>int</i>&nbsp;/&nbsp;<i>float</i><br>
      <i>float</i>&nbsp;/&nbsp;<i>float</i></tt></td><td>float</td><td>The right value divided by the left value.</td>
    </tr>
    
    <tr>
    <td><tt><i>string</i>&nbsp;/&nbsp;<i>string</i></tt></td><td>array(string)</td><td>In symmetry with the multiplication operator, the division operator can split a string into pieces. The right string will be split at every occurrence of the right string and an array containing the results will be returned. Example:
    <tt>"foo-bar"/"-"</tt> will return <tt>({"foo","bar"})</tt></td>
    </tr>
    
    <tr>
    <td><tt><i>int</i>&nbsp;%&nbsp;<i>int</i></tt></td><td>int</td><td>The rest of a division. If <tt>a</tt> and <tt>b</tt> are integers, <tt>a%b</tt> is the same as <tt>a-(a/b)*b</tt></td>
    </tr>
    
    <tr>
    <td><tt>
    <i>float</i>&nbsp;%&nbsp;<i>float</i><br>
    <i>int</i>&nbsp;%&nbsp;<i>float</i><br>
    <i>float</i>&nbsp;%&nbsp;<i>int</i></tt></td><td>float</td><td>The rest of a division. If <tt>a</tt> and <tt>b</tt> are floats, <tt>a%b</tt> is the same as <tt>a-floor(a/b)*b</tt></td>
    </tr>
    
    
    
    </table>
    </center>
    </section>
    
    <section title="Comparison operators">
    The arithmetic operators would be hard to use for something interesting
    without the ability to compare the results to each other.
    For this purpose there are six comparison operators:
    
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>	<th>Syntax</th>	<th>Identifier</th> <th>Returns</th></tr>
    <tr><td>Same</td>                    <td>a == b</td>   <td>`==</td>   <td>1 if a is the same value as b, 0 otherwise</td></tr>
    <tr><td>Not same</td>                <td>a != b</td>   <td>`!=</td>   <td>0 if a is the same value as b, 1 otherwise</td></tr>
    <tr><td>Greater than</td>            <td>a &gt; b</td> <td>`&gt; </td><td>1 if a is greater than b, 0 otherwise</td></tr>
    <tr><td>Greater than or equal to</td><td>a &gt;= b</td><td>`&gt;=</td><td>1 if a is greater to or equal to b, 0 otherwise</td></tr>
    <tr><td>Lesser than</td>             <td>a &lt; b</td> <td>`&lt; </td><td>1 if a is lesser than b, 0 otherwise</td></tr>
    <tr><td>Lesser than or equal to</td> <td>a &lt;= b</td><td>`&lt;=</td><td>1 if a is lesser than or equal to b, 0 otherwise</td></tr>
    </table>
    <p>
    </center>
    
    The <tt>==</tt> and <tt>!=</tt> operators can be used on any type. For two
    values to be <b>same</b> they must be the same type. Therefor 1 and 1.0 are
    not <b>same</b>. Also, for two values of <b>pointer types</b> to be the same
    the two values must be pointers to the same object. It is not enough that
    the two objects are of the same size and contain the same data.
    <p>
    The other operators in the table above can only be used with integers, floats
    and strings. If you compare an integer with a float, the int will be promoted
    to a float before the comparison. When comparing strings, lexical order is
    used and the value of the environment variables <tt>LC_CTYPE</tt> and
    <tt>LC_LANG</tt> is respected.
    </section>
    
    <section title="Logical operators">
    Logical operators are operators that operate with truth values. In Pike any value
    except zero is considered <b>true</b>. Logical operators are a very basic part
    of Pike. They can also decide which arguments to evaluate and which not to
    evaluate. Because of this the logical operators do not have any identifiers and
    can not be called as normal functions. There are four logical operators:
    
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>	<th>Syntax</th>	<th>Returns</th></tr>
    <tr><td>And</td>	<td>a &amp;&amp; b</td> <td>If a is false, a is returned and b is not evaluated. Otherwise, b is returned.</td></tr>
    <tr><td>Or</td>		<td>a || b</td> 	<td>If a is true, a is returned and b is not evaluated. Otherwise, b is returned.</td></tr>
    <tr><td>Not</td>	<td>! a</td>		<td>Returns 0 if a is true, 1 otherwise.</td></tr>
    <tr><td>If-else</td>	<td>a ? b : c</td>	<td>If a is true, b is returned and c is not evaluated. Otherwise c is returned and b is not evaluated.</td></tr>
    </table>
    </center>
    </section>
    
    <section title="Bitwise/set operators">
    These operators are used to manipulate bits as members in sets.
    They can also manipulate arrays, multisets and mappings as sets.
    
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>		<th>Syntax</th>	<th>Identifier</th> <th>Returns</th></tr>
    <tr><td>Shift left</td>		<td>a &lt;&lt; b</td>	<td>`&lt;&lt;</td>	<td>Multiplies a by 2 b times.</td></tr>
    <tr><td>Shift right</td>	<td>a &gt;&gt; b</td>	<td>`&gt;&gt;</td>	<td>Divides a by 2 b times.</td></tr>
    <tr><td>Inverse (not)</td>	<td>~ a</td>		<td>`~</td>		<td>Returns -1-a.</td></tr>
    <tr><td>Intersection (and)</td>	<td>a &amp; b</td>	<td>`&amp;</td>		<td>All elements present in both a and b.</td></tr>
    <tr><td>Union (or)</td>		<td>a | b</td>		<td>`|</td>		<td>All elements present in a or b.</td></tr>
    <tr><td>Symmetric difference (xor)</td><td>a ^ b</td>	<td>`^</td>		<td>All elements present in a or b, but not present in both.</td></tr>
    </table>
    <p>
    </center>
    
    The first three operators can only be used with integers and should be
    pretty obvious.
    
    The other three, intersection, union and symmetric difference, can be used with
    integers, arrays, multisets and mappings. When used with integers, these
    operators considers each bit in the integer a separate element. If you do
    not know about how bits in integers I suggest you go look it up in some other
    programming book or just don't use these operators on integers.
    <p>
    When intersection, union or symmetric difference is used on an array each element
    in the array is considered by itself. So intersecting two arrays will result
    in an array with all elements that are present in both arrays. Example:
    <tt>({7,6,4,3,2,1}) &amp; ({1, 23, 5, 4, 7})</tt> will return
    <tt>({7,4,1})</tt>. The order of the elements in the returned array will
    always be taken from the left array. Elements in multisets are treated
    the same as elements in arrays. When doing a set operator on a mapping
    however, only the indices are considered. The values are just copied with
    the indexes. If a particular index is present in both the right and left
    argument to a set operator, the one from the right side will be used.
    Example: <tt>([1:2]) | ([1:3])</tt> will return <tt>([1:3])</tt>.
    </section>
    
    <section title="Indexing">
    The index and range operators are used to retrieve information from a
    complex data type.
    
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>		<th>Syntax</th>	<th>Identifier</th> <th>Returns</th></tr>
    <tr><td>Index</td>		<td>a [ b ]</td><td>`[]</td>	<td>Returns the index b from a.</td></tr>
    <tr><td>Lookup</td>	<td>a -&gt;<i>identifier</i></td>	<td>`-&gt;</td>	<td>Looks up the identifier. Same as a["<i>identifier</i>"].</td></tr>
    <tr><td>Assign index</td>	<td>a [ b ] = c</td><td>`[]=;</td><td>Sets the index b in a to c.</td></tr>
    <tr><td>Assign index</td>	<td>a -&gt;<i>identifier</i> = c</td><td>`-&gt;=</td><td>Sets the index "<i>identifier</i>" in a to c.</td></tr>
    <tr><td>Range</td>	<td>a [ b .. c]</td>		<td>`[..]</td>		<td>Returns a slice of a starting at the index b and ending at c.</td></tr>
    <tr><td>Range</td>	<td>a [ .. c]</td>		<td>`[..]</td>		<td>Returns a slice of a starting at the beginning of a and ending at c.</td></tr>
    <tr><td>Range</td>	<td>a [ b .. ]</td>		<td>`[..]</td>		<td>Returns a slice of a from the index b to the end of a.</td></tr>
    </table>
    <p>
    </center>
    
    The index operator can be written in two different ways. It can be
    written as <tt><i>ob</i> [ <i>index</i> ]</tt> or
    <tt><i>ob</i>-&gt;<i>identifier</i></tt>. However, the latter syntax is
    equal to <tt><i>ob</i> [ "<i>identifier</i>" ]</tt>.
    
    You can only
    index strings, arrays, mapping, multisets and objects, and some of these
    can only be indexed on certain things as shown in this list:
    <p>
    <center>
    <table border=1>
    <tr>
    <th>Operation</th> <th>Returns</th>
    </tr>
    
    <tr>
    <td><tt><i>string</i>[<i>int</i>]</tt></td><td>Returns the ascii value of the Nth character in the string.</td>
    </tr>
    
    <tr>
    <td><tt><i>array</i>[<i>int</i>]</tt></td><td>Return the element in the array corresponding to the integer.</td>
    </tr>
    
    
    <tr>
    <td><tt><i>array</i>[<i>int</i>]=<i>mixed</i></tt></td><td>Sets the element in the array to the mixed value.</td>
    </tr>
    
    <tr>
    <td><tt>
      <i>multiset</i>[<i>mixed</i>]<br>
      <i>multiset</i>-&gt;<i>identifier</i>
         </tt></td><td>Returns 1 if the index (the value between the brackets) is present in the multiset, 0 otherwise.</td>
    </tr>
    
    
    <tr>
    <td><tt>
      <i>multiset</i>[<i>mixed</i>]=<i>mixed</i><br>
      <i>multiset</i>-&gt;<i>identifier=<i>mixed</i></i>
         </tt></td><td>If the mixed value is <b>true</b> the index is added to the multiset. Otherwise the index is removed from the multiset.</td>
    </tr>
    
    
    <tr>
    <td><tt>
      <i>mapping</i>[<i>mixed</i>]<br>
      <i>mapping</i>-&gt;<i>identifier</i>
         </tt></td><td>Returns the value associated with the index, 0 if it is not found.</td>
    </tr>
    
    
    <tr>
    <td><tt>
      <i>mapping</i>[<i>mixed</i>]=<i>mixed</i><br>
      <i>mapping</i>-&gt;<i>identifier</i>=<i>mixed</i>
         </tt></td><td>Associate the second mixed value with the first mixed value.</td>
    </tr>
    
    <tr>
    <td><tt>
      <i>object</i>[<i>string</i>]<br>
      <i>object</i>-&gt;<i>identifier</i><br>
        </tt></td><td>Returns the value of the named identifier in the object.</td>
    </tr>
    
    
    <tr>
    <td><tt>
      <i>object</i>[<i>string</i>]=<i>mixed</i><br>
      <i>object</i>-&gt;<i>identifier</i>=<i>mixed</i><br>
        </tt></td><td>Set the given identifier in the object to the mixed value. Only works if the identifier references a variable in the object.</td>
    </tr>
    
    <tr>
    <td><tt><i>string</i>[<i>int</i>..<i>int</i>]</tt></td><td>Returns a piece of the string.</td>
    </tr>
    
    <tr>
    <td><tt><i>array</i>[<i>int</i>..<i>int</i>]</tt></td><td>Returns a slice of the array.</td>
    </tr>
    </table>
    
    <p>
    When indexing an <tt>array</tt> or <tt>string</tt> it is sometimes convenient
    to access index from the end instead of from the beginning. This function
    can be performed by using a negative index. Thus <tt> arr[-i] </tt> is the
    same as <tt>arr[sizeof(arr)-i]</tt>. Note however that this behavior does
    not apply to the range operator. Instead the range operator clamps it's
    arguments to a suitable range. This means that
    <tt><i>a</i>[<i>b</i>..<i>c</i>]</tt> will be treated as follows:
    
    <ul>
    <li> If <i>b</i> i less than zero, the range will begin at the start
         of the array as if <i>b</i> had been zero.
    <li> If <i>b</i> is greater or equal to sizeof(<i>a</i>) an empty array/string
         will be returned.
    <li> If <i>c</i> is less than <i>b</i>, an empty array/string will be
         returned.
    <li> If <i>c</i> is greater or equal to sizeof(<i>a</i>) the range will
         continue to the end of the array/string.
    <li> No errors are generated in any of the above cases.
    </ul>
    
    </center>
    </section>
    
    <!-- FIX ME: tell more about indexing and ranges -->
    
    <section title="The assignment operators">
    There is really only one assignment operator, but it can be combined with
    lots of other operators to make the code shorter. An assignment looks
    like this:
    <pre>
    	<i>variable</i> = <i>expression</i> ;
    </pre>
    The <i>variable</i> can be a local variable, a global variable or an index
    in an array, object, multiset or mapping. This will of course set the
    value stored in <i>variable</i> to <i>expression</i>. Note that the above
    is also an expression which returns the value of the <i>expression</i>.
    This can be used in some interesting ways:
    <pre>
    	<i>variable1</i> = <i>variable2</i> = 1; // Assign 1 to both variables
    	<i>variable1</i> =(<i>variable2</i> = 1); // Same as above
    
    	// Write the value of the expression, if any
    	if(<i>variable</i> = <i>expression</i>)
    	  write(variable);
    </pre>
    Using assignments like this can however be confusing to novice users, or users
    who come from a Pascal or Basic background. Especially the if statement
    can be mistaken for <tt>if(<i>variable</i> == <i>expression</i>)</tt> which
    would mean something completely different. As I mentioned earlier, the
    assignment operator can be combined with another operator to form operators
    that modify the contents of a variable instead of just assigning it.
    Here is a list of all the combinations:
    <p>
    <center>
    <table border=1>
    <tr><th>Syntax</th> <th>Same as</th> <th>Function</th></tr>
    <tr><td><tt><i>variable</i> += <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> + <i>expression</i></td><td>Add <i>expression</i> to <i>variable</i></td></tr>
    <tr><td><tt><i>variable</i> -= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> - <i>expression</i></td><td>Subtract <i>expression</i> from <i>variable</i></td></tr>
    <tr><td><tt><i>variable</i> *= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> * <i>expression</i></td><td>Multiply <i>variable</i> with <i>expression</i></td></tr>
    <tr><td><tt><i>variable</i> /= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> / <i>expression</i></td><td>Divide <i>variable</i> by <i>expression</i></td></tr>
    <tr><td><tt><i>variable</i> %= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> % <i>expression</i></td><td>Modulo <i>variable</i> by <i>expression</i></td></tr>
    <tr><td><tt><i>variable</i> &lt;&lt;= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> &lt;&lt; <i>expression</i></td><td>Shift <i>variable</i> <i>expression</i> bits left</td></tr>
    <tr><td><tt><i>variable</i> &gt;&gt;= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> &gt;&gt; <i>expression</i></td><td>Shift <i>variable</i> <i>expression</i> bits right</td></tr>
    <tr><td><tt><i>variable</i> |= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> | <i>expression</i></td><td>Or <i>variable</i> with <i>expression</i></td></tr>
    <tr><td><tt><i>variable</i> &amp;= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> &amp; <i>expression</i></td><td>And <i>variable</i> with <i>expression</i></td></tr>
    <tr><td><tt><i>variable</i> ^= <i>expression</i></tt></td><td> <i>variable</i> = <i>variable</i> ^ <i>expression</i></td><td>Xor <i>variable</i> with <i>expression</i></td></tr>
    </table>
    </center>
    <p>
    In all of the above expression <i>variable</i> can also be an index in an 
    array, mapping or multiset.
    </section>
    
    <section title="The rest of the operators">
    Now there are only a couple of operators left. I have grouped them together
    in this section, not because they are not important, but because they do
    not fit in any particular categories.
    
    <center>
    <p>
    <table border=1>
    <tr><th>Function</th>		<th>Syntax</th>	<th>Identifier</th> <th>Returns</th></tr>
    <tr><td>Calling</td>	<td>a ( arguments ) </td><td>`()</td>	<td>Calls the function a.</td></tr>
    <tr><td>splice</td>	<td>@ <i>a</i></td><td>none</td>	<td>Sends each element in the array a as an individual argument to a function call.</td></tr>
    <tr><td>Increment</td>	<td>++ a</td>		<td>none</td>	<td>Increments a and returns the new value for a.</td></tr>
    <tr><td>Decrement</td>	<td>-- a</td>		<td>none</td>	<td>Decrements a and returns the new value for a.</td></tr>
    <tr><td>Post increment</td><td>a ++</td>	<td>none</td>	<td>Increments a and returns the old value for a.</td></tr>
    <tr><td>Post decrement</td><td>a --</td>	<td>none</td>	<td>Decrements a and returns the old value for a.</td></tr>
    <tr><td>casting</td>	<td>(<i>type</i>) a</td><td>none</td>	<td>Tries to convert a into a value of the specified type.</td></tr>
    <tr><td>Null</td>	<td>a, b</td>		<td>none</td>	<td>Evaluates a and b, then returns b.</td></tr>
    </table>
    <p>
    </center>
    
    The most important of these operators is the calling operator. It is used
    to call functions. The operator itself is just a set of parenthesis placed
    after the expression that returns the function. Any arguments to the function
    should be placed between the parenthesis, separated by commas. We have
    already seen many examples of this operator, although you might not have
    realized it was an operator at the time. The function call operator can
    do more than just calling functions though; if the 'function' is in fact
    an array, the operator will loop over the array and call each element in
    the array and returns an array with the results.
    <!-- In fact, <tt>({ foo, bar, gazonk }) (1, 2, 3)</tt> is the same as <tt>map(({ foo, bar, gazonk }), call_function, 1, 2, 3)</tt>. -->
    If on the other hand, the 'function' is a program, the operator will
    clone an object from the program and call create() in the new object
    with the arguments given. In fact, the function <tt>clone</tt> is
    implemented like this:
    <p>
    <example language=pike>
    	object clone(mixed p, mixed ... args) { ( (program)p )(@args); }
    </example>
    <p>
    On the subject of function calls, the splice operator should also be mentioned.
    The splice operator is an at sign in front of an expression. The expression
    should always be an array. The splice operator sends each of the elements
    in the array as a separate argument to the function call. The splice operator
    can only be used in an argument list for a function call.
    <p>
    Then there are the increment and decrement operators. The increment and
    decrement operators are somewhat limited: they can only be used on
    integers. They provide a short and fast way to add or subtract one
    to an integer. If the operator is written before the variable
    (<tt>++<i>a</i></tt>) the returned value will be what the variable
    is after the operator has added/subtracted one to it. If the operator
    is after the variable (<tt><i>a</i>++</tt>) it will instead return the
    value of the variable before it was incremented/decremented.
    <p>
    Casting is used to convert one type to another, not all casts are
    possible. Here is a list of all casts that actually _do_ anything:
    <p>
    <center>
    <table border=1>
    <tr><th>casting from</th><th>to</th><th>operation</th></tr>
    <tr><td>int</td><td>string</td><td>Convert the int to ASCII representation</td></tr>
    <tr><td>float</td><td>string</td><td>Convert the float to ASCII representation</td></tr>
    <tr><td>string</td><td>int</td><td>Convert decimal, octal or hexadecimal number to an int.</td></tr>
    <tr><td>string</td><td>float</td><td>Convert ASCII number to a float.</td></tr>
    <tr><td>string</td><td>program</td><td>String is a filename, compile the file and return the program. Results are cached.</td></tr>
    <tr><td>string</td><td>object</td><td>This first casts the string to a program, (see above) and then clones the result. Results are cached.</td></tr>
    </table>
    </center>
    <p>
    You can also use the cast operator to tell the compiler things.
    If <tt>a</tt> is a variable of type mixed  containing an int, then the
    expression <tt>(int)a</tt> can be used instead of <tt>a</tt> and that will
    tell the compiler that the type of that expression is <tt>int</tt>.
    <p>
    Last, and in some respect least, is the comma operator. It doesn't do
    much. In fact, it simply evaluates the two arguments and then returns
    the right hand one. This operator is mostly useful to produce smaller code,
    or to make defines that can be used in expressions.
    <p>
    </section>
    
    <section title="Operator precedence">
    When evaluating an expression, you can always use parenthesis to tell
    the compiler in which order to evaluate things. Normally, the compiler
    will evaluate things from left to right, but it will evaluate operators
    with higher priority before those will lower. The following table shows
    how the relative priority of all the operators in descending order:
    <p>
    <center>
    <table border=1 halign=center>
    <tr><th>Operators</th></tr>
    <tr><td><center><tt>(a) a() a[b] a-&gt;b a[b..c] ({}) ([]) (&lt;&gt;)</tt></center></td></tr>
    <tr><td><center><tt>a++ a--</tt></center></td></tr>
    <tr><td><center><tt>!a ~a (type)a ++a --a</tt></center></td></tr>
    <tr><td><center><tt>a*b a/b a%b</tt></center></td></tr>
    <tr><td><center><tt>a+b a-b</tt></center></td></tr>
    <tr><td><center><tt>a&gt;&gt;b a&lt;&lt;b</tt></center></td></tr>
    <tr><td><center><tt>a&gt;b a&gt;=b a&lt;b a&lt;=b</tt></center></td></tr>
    <tr><td><center><tt>a==b a!=b</tt></center></td></tr>
    <tr><td><center><tt>a&amp;b</tt></center></td></tr>
    <tr><td><center><tt>a^b</tt></center></td></tr>
    <tr><td><center><tt>a|b</tt></center></td></tr>
    <tr><td><center><tt>&amp;&amp;</tt></center></td></tr>
    <tr><td><center><tt>||</tt></center></td></tr>
    <tr><td><center><tt>a?b:c</tt></center></td></tr>
    <tr><td><center><tt>=</tt></center></td></tr>
    <tr><td><center><tt>@a</tt></center></td></tr>
    <tr><td><center><tt>,</tt></center></td></tr>
    </table>
    </center>
    <p>
    
    Examples:
    <center>
    <table border=1>
    <tr><th>The expression</th><th>is evaluated in this order:</th></tr>
    <tr><td><tt> 1+2*2 </tt></td><td><tt> 1+(2*2) </tt></td></tr>
    <tr><td><tt> 1+2*2*4 </tt></td><td><tt> 1+((2*2)*4) </tt></td></tr>
    <tr><td><tt> (1+2)*2*4 </tt></td><td><tt> ((1+2)*2)*4 </tt></td></tr>
    <tr><td><tt> 1+4,c=2|3+5 </tt></td><td><tt> (1+4),(c=(2|3)+5) </tt></td></tr>
    <tr><td><tt> 1+5 &amp; 4 == 3 </tt></td><td><tt> (1+(5 &amp; 4)) == 3 </tt></td></tr>
    <tr><td><tt> c=1,99 </tt></td><td><tt> (c=1),99 </tt></td></tr>
    <tr><td><tt> !a++ + ~--a()</tt></td><td><tt> (!(a++)) + (~((--a)())) </tt></td></tr>
    </table>
    </center>
    </section>
    
    <section title="Operator functions">
    As mentioned earlier <tt>a + b</tt> can just as well be written as
    <tt>`+(a, b)</tt>. Together with the function <tt>map</tt> which
    calls a function for every index in an array and the splice operator
    this can be used to create some very very fast and compact code. Let's
    look at some examples:
    <dl>
    <dt> <tt>map(arr, `-)</tt>
    <dd> This will return an array with each element negated.
    <dt> <tt>map(text/"\n",`/," ")</tt>
    <dd> This will divide a text into lines, each line will then be mapped
         through <tt>`/</tt> and divided into an array of words.
    <dt> <tt>`+(0, @arr)</tt>
    <dd> This will add all the integers in the array <tt>arr</tt> together.
    <dt> <tt>int abs(int a) { return ( a>0 ? `+ : `-)(a); }</tt>
    <dd> This is a rather absurd but working function which will return the
         absolute value of a.
    </dl>
    
    </section>
    </chapter>
    
    <chapter title="Object orientation">
    As mention several times, Pike is object oriented. This does not mean that
    it is identical to C++ in any way. Pike uses a less strict approach to
    object orientation which creates a more relaxed programming style. If you
    have never come in contact with object oriented programming before, be
    warned that the ideas expressed in Pike and in this chapter are my own and
    do not necessarily reflect what other people think about object
    orientated programming.
    
    <section title="Terminology">
    As mentioned before, Pike uses a different terminology than C++ does.
    This has historic reasons, but might be changed in the future. In
    the meantime, you might benefit from this mini-dictionary which translates
    C++-ish to Pike-ish:
    <dl>
    <dt> a <i>class</i> <dd> a class
    <dt> a <i>clone</i> <dd> an instance of a class
    <dt> to <i>clone</i> <dd> to create an instance
    <dt> an <i>object</i> <dd> an instance of a class
    <dt> a <i>program</i> <dd> a class
    </dl>
    </section>
    
    <section title="The approach">
    Think of the data type program as an executable file. Then we clone this
    program and create an object. The object is then a running program. The
    object has its own data and its own functions, however, it can work
    together with other programs by calling functions in those objects.
    The functions can be thought of as message carriers, TCP sockets or
    just a way for programs to communicate.
    
    <!-- FIX ME: do something about the following sentence? -->
    Now we have a running system with
    many running programs, each performing only the task it was designed for.
    <p>
    This analogy has one major flaw, when running programs in UNIX they actually
    run simultaneously. UNIX is <i>multitasking</i>, Pike is not. When one
    object is executing code, all the other objects has to wait until they
    are called. An exception is if you are using <b>threads</b> as will be
    discussed in a later chapter.
    </section>
    
    <section title="How does this help?">
    Ok, why is it a good idea to use object oriented programming? Well
    if you believe what you hear, the biggest advantage is that you can re-use
    your code in several projects. In my experience this is not the case.
    <p>
    In my experience, the advantages of object oriented programming are:
    <dl>
    <dt>Modular programming made easy
    <dd>Using <b>The approach</b> makes it easy to divide a project into smaller
        pieces, these pieces are usually easier to write than the whole.
    
    <dt>Local data scope
    <dd>This is a very nifty with object oriented programs. If your program
        uses several files, windows, stacks, TCP connections or whatever, you
        simply write a <tt>program</tt> that handles one such file, window,
        stack or TCP connection. If correctly written, you can then just create
        many clones of that program. 
    
    <dt>Using the same interface to different objects
    <dd>I can write a function that takes a stream as an argument and writes
        data to this stream. Later I might wish to write this data to a window
        instead. I can then create an object that has the same methods as a stream
        (specifically the <tt>write</tt> method) and send that to the function
        that outputs the data.
    </dl>
    
    Most of these things can be done without object orientation, but it is
    object orientation that makes them easy.
    </section>
    
    <section title="Pike and Object Orientation">
    In most object oriented languages there is a way to write functions outside
    of all classes. Some readers might think this is what we have been doing
    until now. However, in Pike, all functions have to reside within a program.
    When you write a simple script in Pike, the file is first compiled into a
    <b>program</b> then cloned and then main() is called in that clone. All
    this is done by the <b>master object</b>, which is compiled and cloned before
    before all other objects. What the <b>master object</b> actually does is:
    <pre>
    	program scriptclass=compile_file(argv[0]); // Load script
    	object script=scriptclass();               // clone script
    	int ret=script->main(sizeof(argv), argv);  // call main()
    </pre>
    
    Similarly, if you want to load another file and call functions in it, you
    can do it with compile_file(), or you can use the cast operator and cast
    the filename to a string. You can also use the module system, which we
    will discuss further in the next chapter.
    <p>
    If you don't want to put each program in a separate file, you can use the
    <tt>class</tt> keyword to write all your classes in one file. We have
    already seen an example how this in chapter 4, but let's go over it in
    more detail. The syntax looks like this:
    <pre>
    	class <i>class_name</i> {
    	  <i>class definition</i>
    	}
    </pre>
    This construction can be used almost anywhere within a normal program.
    It can be used outside all functions, but it can also be used as an expression
    in which case the defined class will be returned. In this case you may also
    leave out the <i>class_name</i> and leave the class unnamed. The
    <i>class definition</i> is simply the functions and programs you want to add
    to the class. It is important to know that although the class is defined in
    the same file as other classes and functions it can not immediately access
    data in its surroundings. Only constants defined before the class in the
    same file can be used. Example:
    <example language=pike>
    	constant x = 17;
    	class foobar {
    	   int test() { return x; }
    	};
    </example>
    This works because <tt>x</tt> is a <b>constant</b>. If x had been a variable
    or function it would not have worked. In future versions of Pike it may be
    possible to do this with variables as well. To make it easier to program,
    defining a class is also to define a
    constant with that name. Essentially, these two lines of code do the same
    thing:
    <example language=pike>
    	class foo {};
    	constant foo = class {};
    </example>
    Because classes defined as constants, it is possible to use a class defined
    inside classes you define later, like this:
    <example language=pike>
    	class foo
    	{
    	  int test() { return 17; }
    	};
    
    	class bar
    	{
    	  program test2() { return foo; }
    	};
    </example>
    
    <!-- FIX ME: tell more -->
    </section>
    
    <section title="Inherit">
    A big part of writing object oriented code is the ability to add functionality
    to a program without changing (or even understanding) the original code.
    This is what <tt>inherit</tt> is all about.
    Let's say I want to change the <tt>hello_world</tt> program to write a version number
    before it writes hello world, using <tt>inherit</tt> I could do this like
    this:
    <example language=pike>
    	inherit "hello_world";
    	int main(int argc, array(string) argv)
    	{
    	  write("Hello world version 1.0\n");
    	  return ::main(argc,argv);
    	}
    </example>
    What inherit does is that it copies all the variables and functions from the
    inherited program into the current one. You can then re-define any function
    or variable you want, and you can call the original one by using a <tt>::</tt>
    in front of the function name. The argument to inherit can be one of the following:
    <dl>
    <dt> A string
    <dd> This will have the same effect as casting the string to a program and then
         doing inherit on this program.
    <dt> A constant containing a program.
    <dd> Any constant from this program, module or inherited program that contains a
         program can be inherited.
    <dt> A class name
    <dd> A class defined with the <tt>class</tt> keyword is in fact added as a constant,
         so the same rule as above applies.
    </dl>
    <p>
    
    Let's look at an example. We'll split up an earlier example into three parts
    and let each inherit the previous part. It would look something like this:
    <center>
    <image xfig=inherit><br>
    </center>
    Note that the actual code is not copied, only the list of references.
    Also note that the list of inherits is copied when you inherit a program
    this does not mean you can access those copied inherit with the <tt>::</tt>
    operator, it is merely an implementation detail. Although this example does
    not show an example of a re-defined function, it should be easy to see how
    that works by just changing what an identifier is pointing at.
    
    </section>
    
    <section title="Multiple inherit">
    You can inherit any number of programs in one program, you can even inherit the
    same thing more than once. If you do this you will a separate set of functions
    and variables for each inherit. To access a specific function you need to name
    your inherits. Here is an example of named inherits:
    <example language=pike>
    	inherit Stdio.File;   // This inherit is named File
    	inherit Stdio.FILE;   // This inherit is named FILE
    	inherit "hello_word"; // This inherit is named hello_world
    	inherit Stdio.File : test1; // This inherit is named test1
    	inherit "hello_world" : test2; // This inherit is named test2
    
    	void test()
    	{
    	  File::read(); // Read data from the first inherit
    	  FILE::read(); // Read data from the second inherit
    	  hello_world::main(0,({})); // Call main in third inherit
    	  test1::read(); // Read data from fourth inherit
    	  test2::main(0,({})); // Call main in fourth inherit
    	  ::read();  // Read data from all inherits
    	}
    </example>
    
    As you can see it would be impossible to separate the different read and
    main functions without using inherit names. If you tried calling
    just <tt>read</tt> without any <tt>::</tt> or inherit name in front of it
    Pike will call the last read defined, in this case it will call read in
    the fourth inherit.
    <p>
    If you leave the inherit name blank and just call <tt>::read</tt> Pike will
    call all inherited read() functions. If there is more than one inherited
    read function the results will be returned in an array.
    <p>
    Let's look at another example:
    <example language=pike>
    	#!/usr/local/bin/pike
    	
    	inherit Stdio.File : input;
    	inherit Stdio.File : output;
    	
    	int main(int argc, array(string) argv)
    	{
    	  output::create("stdout");
    	  for(int e=1;e&lt;sizeof(argv);e++)
    	  {
    	    input::open(argv[e],"r");
                while(output::write(input::read(4096)) == 4096);
    	  }
    	}
    </example>
    This short piece of code works a lot like the UNIX command <tt>cat</tt>.
    It reads all the files given on the command line and writes them to
    stdout. As an example, I have inherited Stdio.File twice to show you
    that both files are usable from my program.
    </section>
    <section title="Pike Inherit compared to other languages">
    Many other languages assign special meaning to inherit. Most common is the
    notion that if you inherit a class, it means that your class should obey
    the same rules as the inherited class. In Pike, this is not necessarily so.
    You may wish to use inherit in Pike like this, but you can just as well
    choose not to. This may confuse some programmers with previous experience
    in object oriented programming.
    </section>
    
    <section title="Modifiers" name=modifiers>
    Sometimes, you may wish to hide things from inheriting programs, or
    prevent functions from being called from other objects. To do so you use
    <b>modifiers</b>. A modifier is simply a word written before a variable
    definition, function definition, class definition or an inherit that
    specifies how this identifier should interact with other objects and programs.
    These modifiers are available:
    <dl>
    <dt><tt>static</tt>
    <dd>Static hides this identifier from the index and arrow operators, which
        makes it impossible for other objects to call this function unless a
        function pointer to it is returned from inside this program.
    <dt><tt>nomask</tt>
    <dd>This prevents other objects from re-defining this identifier in
        programs that inherit this program.
    <dt><tt>private</tt>
    <dd>This prevents inheriting programs from accessing this identifier.
        Note that inheriting program can still re-define the identifier.
        Also note that <tt>private</tt> does not imply <tt>static</tt>.
    <dt><tt>public</tt>
    <dd>This is the opposite of <tt>private</tt>. This is the default for
        all identifiers. <tt>public</tt> can be used to override the effects
        of a private inherit.
    <dt><tt>protected</tt>
    <dd>Reserved for future use.
    </dl>
    When modifiers are used in conjunction with inherit, all the variables,
    functions and classes copied from the inherited class will be modified
    with the keywords used. For instance, <tt>private inherit</tt> means that
    the identifiers from this inherit will not be available to program inheriting
    this program. <tt>static private inherit</tt> will also hide those identifiers
    from the index and arrow operators, making the inherit available only to the
    code in this program.
    </section>
    
    <section title="Operator Overloading">
    Sometimes you want an object to act as if it was a string, an integer or some
    other data type. It is especially interesting to be able to use the normal
    operators on objects to allow short and readable syntax. In Pike, special
    methods are called when an operator is used with an object. To some extent,
    this is work in progress, but what has been done so far is very useful and
    will not be subject to change.
    <p>
    The following table assumes that a and b are objects and shows what will be
    evaluated if you use that particular operation on an object. Note that some
    of these operators, notably <tt>==</tt> and <tt>!</tt> have default behavior
    which will be used if the corresponding method is not defined in the object.
    Other operators will simply fail if called with objects. Refer to
    <ref to=operators> for information on which operators can operate on objects
    without operator overloading.
    <center>
    <table border=1>
    <tr><th>Operation</th><th>Will call</th></tr>
    <tr><td>a+b</td><td>a-&gt;`+(b)</td></tr>
    <tr><td>a+b+c+d</td><td>a-&gt;`+(b,c,d)</td></tr>
    <tr><td>a-b</td><td>a-&gt;`-(b)</td></tr>
    <tr><td>a&amp;b</td><td>a-&gt;`&amp;(b)</td></tr>
    <tr><td>a|b</td><td>a-&gt;`|(b)</td></tr>
    <tr><td>a^b</td><td>a-&gt;`^(b)</td></tr>
    <tr><td>a&gt;&gt;b</td><td>a-`&gt;&gt;(b)</td></tr>
    <tr><td>a&lt;&lt;b</td><td>a-`&lt;&lt;(b)</td></tr>
    <tr><td>a*b</td><td>a-&gt;`*(b)</td></tr>
    <tr><td>a*b*c*d</td><td>a-&gt;`*(b,c,d)</td></tr>
    <tr><td>a/b</td><td>a-&gt;`/(b)</td></tr>
    <tr><td>a%b</td><td>a-&gt;`%(b)</td></tr>
    <tr><td>~a</td><td>a-&gt;`~()</td></tr>
    <tr><td>a==b</td><td>a-&gt;`==(b) or b-&gt;`==(a)</td></tr>
    <tr><td>a!=b</td><td>!( a-&gt;`==(b) ) or !( b-&gt;`==(a) )</td></tr>
    <tr><td>a&lt;b</td><td>a-&gt;`&lt;(b)</td></tr>
    <tr><td>a&gt;b</td><td>a-&gt;`&gt;(b)</td></tr>
    <tr><td>a&lt;=b</td><td>!( b-&gt;`&gt;(a) )</td></tr>
    <tr><td>a&gt;=b</td><td>!( b-&gt;`&lt;(a) )</td></tr>
    <tr><td>(int)a</td><td>a-&gt;cast("int")</td></tr>
    <tr><td>!a</td><td>a-&gt;`!()</td></tr>
    <tr><td>if(a) { ... } </td><td>!( a-&gt;`!() )</td></tr>
    <tr><td>a[b]</td><td>a-&gt;`[](b)</td></tr>
    <tr><td>a[b]=c</td><td>a-&gt;`[]=(b,c)</td></tr>
    <tr><td>a-&gt;foo</td><td>a-&gt;`-&gt;("foo")</td></tr>
    <tr><td>a-&gt;foo=b</td><td>a-&gt;`-&gt;=("foo",b)</td></tr>
    <tr><td>sizeof(a)</td><td>a-&gt;_sizeof()</td></tr>
    <tr><td>indices(a)</td><td>a-&gt;_indices()</td></tr>
    <tr><td>values(a)</td><td>a-&gt;_values()</td></tr>
    <tr><td>a(b)</td><td>a-&gt;`()(b)</td></tr>
    </table>
    </center>
    <p>
    
    Here is a really silly example of a program that will write 10
    to stdout when executed.
    
    <example language=pike>
    	#!/usr/local/bin/pike
    	class three {
    	  int `+(int foo) { return 3+foo; }
    	};
    
    	int main()
    	{
    	  write(sprintf("%d\n",three()+7));
    	}
    </example>
    
    It is important to know that some optimizations are still performed even
    when operator overloading is in effect. If you define a multiplication operator
    and multiply your object with one, you should not be surprised if the
    multiplication operator is never called. This might not always be what you
    expect, in which case you are better off not using operator overloading.
    </section>
    
    <section title="Simple exercises">
    <box>
    <ul>
    <li> Make a program that clones 10 hello world and then runs main() in
         each one of them.
    <li> Modify the register program to use an object for each record.
    <li> Modify the register program to use the following search function:
    <example language=pike>
    	void find_song(string title)
    	{
    	  string name, song;
    	  int hits;
    
    	  title=lower_case(title);
    
    	  foreach(indices(records),name)
    	  {
    	    if(string song=records[name][title])
                {
                  write(name+"; "+song+"\n");
                  hits++;
    	    }
    	  }
    
    	  if(!hits) write("Not found.\n");
    	}
    </example>
    	
    </ul>
    </box>
    <!-- FIX ME add more examples above -->
    </section>
    </chapter>
    
    <chapter title="Miscellaneous functions" name=misc>
    
    There are some 'functions' in Pike that are not really functions at all but
    just as builtin as operators. These special functions can do things that no
    other functions can do, but they can not be re-defined or overloaded.
    In this chapter I will describe these functions and why they are implemented
    as special functions.
    
    <anchor name=sscanf>
    <section title="sscanf">
    Sscanf may look exactly like a normal function, but normal functions
    can not set the variables you send to it. The purpose of sscanf is to
    match one string against a format string and place the matching results
    into a list of variables. The syntax looks like this:
    <pre>
    	int sscanf(string <i>str</i>, string <I>fmt</I>, <i>lvalue</i> ...)
    </pre>
    The string <i>str</i> will be matched against the format string <i>fmt</i>.
    <i>fmt</i> can contain strings
    separated by %d,%s,%c and %f. Every % corresponds to one <i>lvalue</i>.
    An lvalue is the name of a variable, a name of a local variable, an index
    in an array, mapping or object. It is because of these lvalues that sscanf
    can not be implemented as a normal function.
    <p>
    Whenever a percent is found in the format string, a match is according
    to the following table:
    <table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> %d </td><td> reads an integer </td></tr>
    <tr valign=top><td> %o </td><td> reads an octal integer </td></tr>
    <tr valign=top><td> %x </td><td> reads a hexadecimal integer </td></tr>
    <tr valign=top><td> %D </td><td> reads an integer that is either octal (leading zero), hexadecimal (leading 0x) or decimal. </td></tr>
    <tr valign=top><td> %f </td><td> reads a float </td></tr>
    <tr valign=top><td> %c </td><td> matches one char and returns it as an integer </td></tr>
    <tr valign=top><td> %2c </td><td> matches two chars and returns them as an integer (short) </td></tr>
    <tr valign=top><td> %s </td><td> reads a string. If followed by %d, %s will
     read any non-numerical characters. If followed by a %[], %s will read any
     characters not present in the set. If followed by normal text, %s will match
     all characters up to but not including the first occurrence of that text. </td></tr>
    <tr valign=top><td> %5s </td><td> gives a string of 5 characters (5 can be any number) </td></tr>
    <tr valign=top><td> %[set] </td><td> matches a string containing a given set of characters (those given inside the brackets). %[^set] means any character except those inside brackets. Example: %[0-9H] means any number or 'H'. </td></tr>
    </table>
    
    <p>If a * is put between the percent and the operator, the operator
    will only match its argument, not assign any variables.
    <p>
    Sscanf does not use backtracking. Sscanf simply looks at the format string
    up to the next % and tries to match that with the string. It then proceeds
    to look at the next part. If a part does not match, sscanf immediately
    returns how many % were matched. If this happens, the lvalues for % that
    were not matched will not be changed.
    <p>
    Let's look at a couple of examples:
    <example language=pike>
    	// a will be assigned "oo" and 1 will be returned
    	sscanf("foo","f%s",a);
    
    	// a will be 4711 and b will be "bar", 2 will be returned
    	sscanf("4711bar","%d%s",a,b);
    
    	// a will become "test"
    	sscanf(" \t test","%*[ \t]%s",a)
    
    	// Remove "the " from the beginning of a string
    	// If 'str' does not begin with "the " it will not be changed
    	sscanf(str,"the %s",str);
    </example>
    <p>
    <encaps>SEE ALSO</encaps>: <link to=sprintf>sprintf</link>
    </section>
    </anchor>
    
    <anchor name=catch>
    <anchor name=exceptions>
    <section title="catch & throw">
    Catch is used to trap errors and other exceptions in Pike.
    It works by making a block of code into an expression, like this:
    <pre>
    	catch { <i>statements</i> }
    </pre>
    If an error occurs, catch will return a description of the error.
    The description of the error has the following format:
    <pre>
    	({
    	   "<i>error description</i>",
    	   backtrace()
    	})
    </pre>
    If no error occurs, catch will return zero. You may emulate your own errors
    using the function throw, described in <ref to=functions>.
    <p>
    Example:
    <example language=pike>
    	int x,y;
    	// This might generate "division by zero"
    	mixed error=catch { x/=y; };
    </example>
    </section>
    </anchor>
    </anchor>
    
    <anchor name=gauge>
    <section title="gauge">
    The syntax for gauge is the same as the syntax for catch:
    <pre>
    	gauge { <i>statements</i> }
    </pre>
    However, gauge simply returns how many milliseconds the code took to execute.
    This can be used to find out how fast your code actually is.. :)
    Only CPU time used by the Pike process is measured. This means that if it takes
    two seconds to execute but only uses 50% CPU, this function will return 1000.
    </section>
    </anchor>
    
    <anchor name=typeof>
    <section title="typeof">
    This function returns the type of an expression as a string. It does not
    evaluate the expression at all, which might be somewhat confusing. Example:
    <example language=pike>
    	typeof( exit(1) )
    </example>
    This will return the string <tt>"void"</tt> since exit is a function that
    returns void.
    It will not execute the function <tt>exit</tt> and exit the process as you
    might expect.
    </section>
    </anchor>
    
    </chapter>
    
    <chapter title="Modules" name=modules>
    
    A module is a software package that plugs into the Pike programming
    environment. They provide you with simple interfaces to system routines
    and they also constitute a neat way to use your own C/C++ code from
    within Pike. Pike comes with a number of modules that are ready to use.
    In this chapter I will explain the basics of modules and how to use them.
    <p>
    here is a list of the basic Pike modules:
    <dl>
    <dt>Stdio
    <dd>This module contains file I/O routines.
    <dt>Array
    <dd>This function contains functions that operate on arrays.
    <dt>Gdbm *
    <dd>This module contains support for Gdbm databases.
    <dt>Getopt
    <dd>Routines to parse command line options
    <dt>Gmp *
    <dd>Support for large numbers.
    <dt>Gz *
    <dd>Deflate packing algorithms.
    <dt>Image
    <dd>Image manipulation routines.
    <dt>LR
    <dd>LALR(1) parser generator.
    <dt>Msql *
    <dd>Sql database support for the mini-SQL database server.
    <dt>MIME
    <dd>Support for coding and decoding MIME.
    <dt>Mysql *
    <dd>Sql database support for the mySQL database server.
    <dt>Process
    <dd>Functions to start and control other processes.
    <dt>Regexp
    <dd>Regexp matching routines.
    <dt>Simulate
    <dd>Routines to emulate old Pike routines.
    <dt>String
    <dd>Routines that operate on strings.
    <dt>Sql *
    <dd>Generic SQL database support.
    <dt>System
    <dd>Support for system specific functions
    <dt>Thread *
    <dd>Thread support functions.
    <dt>Yp *
    <dd>Network Information System support.
    </dl>
    <p>
    * These modules might not be available depending on how Pike was compiled
      and whether support for these functions exist on your system.<br>
    <p>
    
    <section title="How to use modules">
    A module is a bunch of functions, programs or other modules collected in
    one symbol. For instance, the module <tt>Stdio</tt> contains the objects
    <tt>stdin</tt>, <tt>stdout</tt> and <tt>stderr</tt>. To access these objects
    you can write <tt>Stdio.stdin</tt>, <tt>Stdio.stdout</tt> or
    <tt>Stdio.stderr</tt> anywhere in your program where an object of that type
    is acceptable. If you use <tt>Stdio</tt> a lot you can use put
    <tt>import Stdio;</tt> in the beginning of your program. This will import
    all the identifiers from the module Stdio into your program, making it
    possible to write just <tt>stdin</tt> instead of <tt>Stdio.stdin</tt>.
    </section>
    
    <section title="Where do modules come from?">
    Modules are not loaded until you use them, which saves memory unless you use
    all the modules. However, if you want to write your own modules it is important
    to know how modules are located and loaded.
    <p>
    When you use <tt>Stdio</tt> Pike will look for that module:
    <ol>
    <li> In the same directory as the source.
    <li> In directories added with add_module_path()
    <li> In directories specified with -M on the command line.
    <li> In directories in the environment variable PIKE_MODULE_PATH
    <li> In the directory with builtin modules, usually /usr/local/lib/pike/modules/
    </ol>
    
    For each of these directories, Pike will do the following:
    <ol>
    <li> If there is a file called Stdio.pmod.pike, Pike will load this
         Pike program, clone it and use that as a module.
    <li> If there is a file called Stdio.pmod.so, Pike will load this
         with load_module(), clone it and use that as a module.
    <li> If there is a directory called Stdio.pmod, Pike will create a module
         containing all the modules in that directory as identifiers. If there is
         a module called <tt>module</tt> in that directory, all identifiers
         from that module will overload any modules actually present in the
         directory.
    </ol>
    
    
    As you can see, quite a lot of work goes into finding the modules, this
    makes it possible to choose the most convenient way to build your own Pike
    modules.
    </section>
    
    <section title="The . operator">
    The period operator is not really an operator, as it is always evaluated
    during the compilation. It works similarly to the index and arrow operators,
    but can only be used on constant values such as modules. In most cases,
    modules are simply a clone of a program, in which case the identifiers in
    the module will be the same as those in the program. But some modules,
    like those created from directories, overload the index operator so that
    the identifiers in the module can be something other than those in the program.
    For directory modules, the index operator looks in the directory it was
    cloned for to find the identifiers.
    </section>
    
    <section title="How to write a module">
    Here is an example of a simple module:
    <example language=pike>
    	constant PI = 3.15;
    	float cos2(float f) { return pow(cos(f),2.0); }
    </example>
    if we save this short file as <tt>Trig.pike.pmod</tt> we can now use this
    module like this:
    <example language=pike>
    	int main()
    	{
    	  write(sprintf("%f\n",Trig.cos2(Trig.PI));
    	}
    </example>
    or like this:
    <example language=pike>
    	import Trig;
    
    	int main() 
    	{
    	  write(sprintf("%f\n",cos2(PI));
    	}
    </example>
    </section>
    
    <section title="Simple exercises">
    <box>
    <ul>
    <li> Save the hello_world.pike program as hello_world.pike.pmod, then make
         a program that loads this module and calls its main().
    <li> Make a directory called <tt>Programs.pmod</tt> and put all the examples you
         have written so far in it. Make a program that runs one of those
         programs. Make sure the program can be modified to run another of
         your examples by changing what module it loads.
    <li> Copy the file hello_world.pike.pmod to programs/module.pike.pmod and
         then write a program that runs hello_world without actually using the
         identifier <tt>hello_world</tt>.
    <li> Try putting <tt>Programs.pmod</tt> in another directory and then try to
         run the programs from the last two examples. 
    </ul>
    </box>
    </section>
    </chapter>
    
    
    
    <module name=Stdio>
    <chapter title="File I/O" name=io>
    Programming without reading and writing data from files, sockets, keyboard
    etc. would be quite pointless. Luckily enough, Pike provides you with an
    object oriented interface to files, pipes and TCP sockets. All I/O functions
    and classes are collected in the module <tt>Stdio</tt>.
    
    <class name=File>
    <section title="Stdio.File">
    This is the basic I/O object, it provides socket communication as well
    as file access. It does not buffer reads and writes or provide line-by-line
    reading, that is done in the FILE object. <tt>Stdio.File</tt> is completely
    written in C. What follows is a description of all the functions in
    <tt>Stdio.File</tt>.
    
    <method name=create title="init file struct">
    <man_syntax>
    object(Stdio.File) Stdio.File();<br>
    object(Stdio.File) Stdio.File(string <I>fd</I>);<br>
    object(Stdio.File) Stdio.File(string <i>file</i>, string <i>mode</i>);<br>
    </man_syntax>
    <man_description>
    There are three different ways to clone a File.
    The first is to clone it without any arguments, in which case the you
    have to call open(), connect() or some other method which connects
    the File object with a stream.
    <p>
    However, instead of cloning and then calling open(), you can clone
    the File with a filename and open mode. This is the same thing as
    cloning and then calling open, except shorter and faster.
    <p>
    Alternatively, you can clone a File with "stdin", "stdout" or
    "stderr" as argument. This will open the specified standard
    stream.
    </man_description>
    <man_see>clone, Stdio.File-&gt;open</man_see>
    </method>
    
    <method name=open title="open a file">
    <man_syntax>
    int open(string <I>filename</I>, string <I>how</I>);<br>
    </man_syntax>
    <man_description>
    Open a file for read, write or append. The variable <i>how</i> should
    contain one or more of the following letters:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> 'r' </td><td> open file for reading </td></tr>
    <tr valign=top><td> 'w' </td><td> open file for writing </td></tr>
    <tr valign=top><td> 'a' </td><td> open file for append (use with 'w') </td></tr>
    <tr valign=top><td> 't' </td><td> truncate file at open (use with 'w') </td></tr>
    <tr valign=top><td> 'c' </td><td> create file if it doesn't exist (use with 'w') </td></tr>
    <tr valign=top><td> 'x' </td><td> fail if file already exist (use with 'c') </td></tr>
    </table>
    
    <p><i>How</i> should _always_ contain at least one of 'r' or 'w'.
    <p>Returns 1 on success, 0 otherwise.
    </man_description>
    <man_see>Stdio.File-&gt;close</man_see>
    </method>
    
    
    <method name=close title="close a file">
    <man_syntax>
    int close(string <I>how</I>);<br>
    int close();<br>
    </man_syntax>
    <man_description>
    Close the file. Optionally, specify "r", "w" or "rw" to close just
    the read, just the write or both read and write part of the file
    respectively. Note that this function will not call the
    close_callback.
    </man_description>
    <man_see>Stdio.File-&gt;open</man_see>
    </method>
    
    
    <method name=read title="read data from a file or stream">
    <man_syntax>
    string read(int <I>nbytes</I>);<br>
    string read(int <I>nbytes</I>, int <I>notall</I>);<br>
    string read();<br>
    </man_syntax>
    <man_description>
    Read tries to read <i>nbytes</i> bytes from the file, and return it as a
    string. If something goes wrong, zero is returned.
    <p>If a one is given as second argument to read(), read will not try
    its best to read as many bytes as you asked it to read, it will
    merely try to read as many bytes as the system read function will
    return. This mainly useful with stream devices which can return
    exactly one row or packet at a time.
    <p>
    If no arguments are given, read will read to the end of the file/stream.
    </man_description>
    <man_see>Stdio.File-&gt;write</man_see>
    </method>
    
    
    <method name=write title="write data to a file or stream">
    <man_syntax>
    int write(string <I>data</I>);<br>
    </man_syntax>
    <man_description>
    Write data to file or stream and return how many bytes that was
    actually written. -1 is returned if something went wrong and no
    bytes had been written.
    </man_description>
    <man_see>Stdio.File-&gt;read</man_see>
    </method>
    
    
    <method name=seek title="seek to a position in a file">
    <man_syntax>
    int seek(int <I>pos</I>);<br>
    </man_syntax>
    <man_description>
    Seek to a position in a file, if pos is less than zero, seek to
    position pos relative end of file. Returns -1 for failure, or
    the old position in the file when successful.
    </man_description>
    <man_see>Stdio.File-&gt;tell</man_see>
    </method>
    
    
    <method name=tell title="tell where we are in a file">
    <man_syntax>
    int tell();<br>
    </man_syntax>
    <man_description>
    Returns the current position in the file.
    </man_description>
    <man_see>Stdio.File-&gt;seek</man_see>
    </method>
    
    
    <method name=stat title="do file_stat on an open file">
    <man_syntax>
    int *stat();<br>
    </man_syntax>
    <man_description>
    This function returns the same information as the function file_stat,
    but for the file it is called in. If file is not an open file,
    zero will be returned. Zero is also returned if file is a pipe or
    socket.
    </man_description>
    <man_see>file_stat</man_see>
    </method>
    
    <method name=errno title="what was last error?">
    <man_syntax>
    int errno();<br>
    </man_syntax>
    <man_description>
    Returns the error code for the last command on this file.
    Error code is normally cleared when a command is successful.
    </man_description>
    </method>
    
    
    <method name=set_buffer title="set internal socket buffer">
    <man_syntax>
    void set_buffer(int <I>bufsize</I>, string <I>mode</I>);<br>
    void set_buffer(int <I>bufsize</I>);<br>
    </man_syntax>
    <man_description>
    This function sets the internal buffer size of a socket or stream.
    The second argument allows you to set the read or write buffer by
    specifying "r" or "w". It is not guaranteed that this function
    actually does anything, but it certainly helps to increase data
    transfer speed when it does.
    </man_description>
    <man_see>Stdio.File-&gt;open_socket, Stdio.Port-&gt;accept</man_see>
    </method>
    
    
    <method name=set_nonblocking title="make stream nonblocking">
    <man_syntax>
    void set_nonblocking(function read_callback,<br>
    <dl><dt><dd>function write_callback,<br>
    function close_callback);<br>
    </dl>
    or<br>
    void set_nonblocking();<br>
    </man_syntax>
    <man_description>
    This function sets a stream to nonblocking mode. When data arrives on
    the stream, read_callback will be called with some or all of this data.
    When the stream has buffer space over for writing, write_callback is
    called so you can write more data to it. If the stream is closed at
    the other end, close_callback is called. All callbacks will have the
    id of file as first argument when called.
    <p>
    If no arguments are given, the callbacks are not changed. The
    stream is just set to nonblocking mode.
    </man_description>
    <man_see>Stdio.File-&gt;set_blocking</man_see>
    </method>
    
    <method name=set_read_callback title="set the read callback">
    <man_syntax>
    void set_read_callback(function read_callback)<br>
    </man_syntax>
    <man_description>
    This function sets the read callback for the file. The read callback
    is called whenever there is data to read from the file. Note that
    this function does not set the file nonblocking.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking</man_see>
    </method>
    
    
    <method name=set_write_callback title="set the write callback">
    <man_syntax>
    void set_write_callback(function write_callback)<br>
    </man_syntax>
    <man_description>
    This function sets the write callback for the file. The write callback
    is called whenever there is buffer space available to write to for
    the file. Note that this function does not set the file nonblocking.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking</man_see>
    </method>
    
    
    <method name=set_close_callback title="set the close callback">
    <man_syntax>
    void set_close_callback(function close_callback)<br>
    </man_syntax>
    <man_description>
    This function sets the close callback for the file. The close callback
    is called when the remote end of a socket or pipe is closed. Note that
    this function does not set the file nonblocking.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking</man_see>
    </method>
    
    
    <method name=set_blocking title="make stream blocking">
    <man_syntax>
    void set_blocking();<br>
    </man_syntax>
    <man_description>
    This function sets a stream to blocking mode. ie. all reads and writes
    will wait until data has been written before returning.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking</man_see>
    </method>
    
    
    <method name=set_id title="set id of this file">
    <man_syntax>
    void set_id(mixed <I>id</I>);<br>
    </man_syntax>
    <man_description>
    This function sets the id of this file. The id is mainly used as an
    identifier that is sent as the first arguments to all callbacks. The
    default id is 0. Another possible use of the id is to hold all data
    related to this file in a mapping or array.
    </man_description>
    <man_see>Stdio.File-&gt;query_id</man_see>
    </method>
    
    
    <method name=query_id title="get id of this file">
    <man_syntax>
    mixed query_id();<br>
    </man_syntax>
    <man_description>
    This function returns the id of this file.
    </man_description>
    <man_see>Stdio.File-&gt;set_id</man_see>
    </method>
    
    
    <method name=query_read_callback title="return the read callback function">
    <man_syntax>
    function query_read_callback();<br>
    </man_syntax>
    <man_description>
    This function returns the read_callback, which is set with
    set_nonblocking or set_read_callback.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking, Stdio.File-&gt;set_read_callback</man_see>
    </method>
    
    
    <method name=query_write_callback title="return the write callback function">
    <man_syntax>
    function query_write_callback();<br>
    </man_syntax>
    <man_description>
    This function returns the write_callback, which is set with
    set_nonblocking or set_write_callback.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking, Stdio.File-&gt;set_write_callback</man_see>
    </method>
    
    
    <method name=query_close_callback title="return the close callback function">
    <man_syntax>
    function query_close_callback();<br>
    </man_syntax>
    <man_description>
    This function returns the close_callback, which is set with
    set_nonblocking or set_close_callback.
    </man_description>
    <man_see>Stdio.File-&gt;set_nonblocking, Stdio.File-&gt;set_close_callback</man_see>
    </method>
    
    <method name=dup title="duplicate a file">
    <man_syntax>
    object(Stdio.File) dup();<br>
    </man_syntax>
    <man_description>
    This function returns a clone of Stdio.File with all variables
    copied from this file. Note that all variables, even id, is copied.
    </man_description>
    <man_see>Stdio.File-&gt;assign</man_see>
    </method>
    
    
    <method name=dup2 title="duplicate a file over another">
    <man_syntax>
    int dup2(object(Stdio.File) <I>to</I>);<br>
    </man_syntax>
    <man_description>
    This function works similarly to Stdio.File-&gt;assign, but instead of making
    the argument a reference to the same file, it creates a new file
    with the same properties and places it in the argument.
    </man_description>
    <man_example>
    <example language=pike>
    	/* Redirect stdin to come from the file 'foo' */
    	object o=Stdio.File();
    	o-&gt;open("foo","r");
    	o-&gt;dup2(Stdio.File("stdin"));
    </example>
    </man_example>
    <man_see>Stdio.File-&gt;assign, Stdio.File-&gt;dup</man_see>
    </method>
    
    <method name=assign title="assign a file">
    <man_syntax>
    void assign(object <I>f</I>);<br>
    </man_syntax>
    <man_description>
    This function takes a clone of Stdio.File and assigns all
    variables of this file from it. It can be used together with file-&gt;dup
    to move files around.
    </man_description>
    <man_see>Stdio.File-&gt;dup</man_see>
    </method>
    
    
    <method name=open_socket title="open a socket">
    <man_syntax>
    int open_socket(int|void port, int|void address);<br>
    </man_syntax>
    <man_description>
    This makes this file into a socket ready for connection. The reason
    for this function is so that you can set the socket to nonblocking
    or blocking (default is blocking) before you call Stdio.File-&gt;connect()
    This function returns 1 for success, 0 otherwise.
    <p>
    If you give a port number to this function, the socket will be bound to
    this port locally before connecting anywhere. This is only useful for
    some silly protocols like FTP. You may also specify an address to bind to
    if your machine has many IP numbers.
    </man_description>
    <man_see>Stdio.File-&gt;connect, Stdio.File-&gt;set_nonblocking</man_see>
    </method>
    
    <method name=connect title="connect a socket to something">
    <man_syntax>
    int connect(string <I>IP</I>,int <I>port</I>);<br>
    </man_syntax>
    <man_description>
    This function connects a socket previously created with
    Stdio.File-&gt;open_socket to a remote socket. The argument is the IP name
    or number for he remote machine.
    <p>This function returns 1 for success, 0 otherwise. Note that if the
    socket is in nonblocking mode, you have to wait for a write or close
    callback before you know if the connection failed or not.
    </man_description>
    <man_see>Stdio.File-&gt;query_address</man_see>
    </method>
    
    
    <method name=query_address title="get addresses">
    <man_syntax>
    string query_address();<br>
    string query_address(1);<br>
    </man_syntax>
    <man_description>
    This function returns the remote or local address of a socket on the
    form "x.x.x.x port". Without argument, the remote address is returned,
    with argument the local address is returned. If this file is not a
    socket, not connected or some other error occurs, zero is returned.
    </man_description>
    <man_see>Stdio.File-&gt;connect</man_see>
    </method>
    
    
    <method name=pipe title="create a two-way pipe">
    <man_syntax>
    object pipe();<br>
    </man_syntax>
    <man_description>
    This function creates a pipe between the object it was called in
    and an object that is returned. The two ends of the pipe are
    indistinguishable. If the File object this function is called in
    was open to begin with, it is closed before the pipe is created.
    </man_description>
    <man_see>fork</man_see>
    </method>
    
    
    <method name=set_close_on_exec title="set / clear the close on exec flag">
    <man_syntax>
    void set_close_on_exec(int <I>onoff</I>);<br>
    </man_syntax>
    <man_description>
    This function determines whether this file will be closed when
    calling exece. Default is that the file WILL be closed on exec
    except for stdin, stdout and stderr.
    </man_description>
    <man_see>exece</man_see>
    </method>
    
    
    <!-- FIX ME might be good to have a plain and simple example of Stdio.File here -->
    
    <p>
    Here is an example of how to use the TCP functions in Stdio.File in blocking
    mode. This short program takes a URL as first argument, connects to the
    WWW server, sends a HEAD request and writes the reply to stdout. For clarity,
    all calls to Stdio.File use <tt>File::</tt> even if that is not strictly
    necessary.
    
    <example language=pike>
    	import Stdio;
    	inherit File;
    
    	int main(int argc, array(string) argv)
    	{
    	  string host;
    	  string path="";
    	  int port=80;
    	  sscanf(argv[1],"http://%s",argv[1]);
    	  sscanf(argv[1],"%s/%s",host,path);
    	  sscanf(host,"%s:%d",host,port);
    
    	  if(!File::open_socket())
    	  {
    	    perror("Open socket failed");
    	    exit(1);
    	  }
    
    	  if(!File::connect(host,port))
    	  {
    	    perror("Failed to connect to remote host");
    	    exit(1);
    	  }
    
    	  File::write(sprintf("HEAD /%s HTTP/1.0\n",path));
    	  stdout::write(File::read());
    	}
    </example>
    
    
    </section>
    </class>
    
    
    <class name=FILE>
    <section title="Stdio.FILE">
    Stdio.FILE is a buffered version of Stdio.File, it inherits Stdio.File and
    has most of the functionality of Stdio.File. However, it has an input buffer
    that allows line-by-line input. Note that the output part of Stdio.FILE is
    not buffered at this moment. The added functionality of Stdio.FILE is
    described here:
    
    <hr noshade size=1>
    <method name=gets title="get one line">
    <man_syntax>
    string gets();<br>
    </man_syntax>
    <man_description>
    This function returns one line from the FILE, it returns zero if
    no more lines are available.
    </man_description>
    </method>
    
    
    <method name=printf title="formatted print">
    <man_syntax>
    string printf(string <I>format</I>, mixed ... <I>data</I>);<br>
    </man_syntax>
    <man_description>
    This function does approximately the same as:
    write(sprintf(format,@data))
    </man_description>
    <man_see>sprintf</man_see>
    </method>
    
    
    <method name=ungets title="put a string back in the buffer">
    <man_syntax>
    string ungets(string <I>s</I>);<br>
    </man_syntax>
    <man_description>
    This function puts a string back in the input buffer. The string
    can then be read with read, gets or getchar.
    </man_description>
    </method>
    
    
    <method name=getchar title="get one character from the input stream">
    <man_syntax>
    int getchar();<br>
    </man_syntax>
    <man_description>
    This function returns one character from the input stream. Note
    that the return value is the ascii value of the character, not
    a string containing one character.
    </man_description>
    </method>
    
    <!-- FIX ME, example of how to use Stdio.FILE here -->
    
    </section>
    </class>
    
    
    <anchor name=Stdio.stdin>
    <anchor name=Stdio.stdout>
    <anchor name=Stdio.stderr>
    <section title="Standard streams">
    Any UNIX program has three files open from the beginning. These are called
    standard input, standard output and standard error stream. These streams
    are available from Pike as well. They are called <tt>Stdio.stdin</tt>,
    <tt>Stdio.stdout</tt> and <tt>Stdio.stderr</tt> respectively. Standard
    input is a clone of <tt>Stdio.FILE</tt>, which means you can use the line
    oriented functions. <tt>Stdio.stdout</tt> and <tt>Stdio.stderr</tt> are
    simply clones of <tt>Stdio.File</tt>.
    <p>
    Example:
    <example language=pike>
    	int main()
    	{
    	  int line;
    	  while(string s=Stdio.stdin.gets())
    	    write(sprintf("%5d: %s\n",line++,s));
    	}
    </example>
    This example will read lines from standard input for as long as there
    are more lines to read. Each line will then be written to stdout together
    with the line number. We could use <tt>Stdio.stdout.write</tt> instead
    of just <tt>write</tt> because they are the same function.
    </section>
    </anchor>
    </anchor>
    </anchor>
    
    <section title="Other Stdio functions">
    The Stdio module also contains a collection of high level IO functions
    to make it easy to write short and readable Pike programs. Most of these
    functions are implemented using Stdio.File and Stdio.FILE.
    
    <hr>
    
    <function name=file_size title="return the size of a file in bytes">
    <man_syntax>
    int file_size(string <I>file</I>);<br>
    </man_syntax>
    <man_description>
    Give the size of a file. Size -1 indicates that the file either
    does not exist, or that it is not readable by you. Size -2
    indicates that it is a directory.
    </man_description>
    
    <man_see>Stdio.write_file, Stdio.read_bytes</man_see>
    </function>
    
    
    <function name=perror title="print error">
    <man_syntax>
    void perror(string <I>s</I>);<br>
    </man_syntax>
    <man_description>
    This function prints a message to stderr along with a description
    of what went wrong if available. It uses the system errno to find
    out what went wrong, so it is only applicable to IO errors.
    </man_description>
    <man_see>Stdio.werror</man_see>
    </function>
    
    
    <function name=read_bytes title="read a number of bytes into a string from a file">
    <man_syntax>
    string read_bytes(string <I>file</I>,int <I>start</I>,int <I>len</I>);<br>
    string read_bytes(string <I>file</I>,int <I>start</I>);<br>
    string read_bytes(string <I>file</I>);<br>
    </man_syntax>
    <man_description>
    Read <i>len</i> number of bytes from file <i>file</i> staring at byte <i>start</i> and
    return it as a string. If <i>len</i> is omitted, the rest of the file
    will be returned. If <i>start</i> is also omitted, the entire file will
    be returned.
    </man_description>
    <man_see>Stdio.write_file</man_see>
    </function>
    
    
    <function name=read_file title="read a number of lines into a string from file">
    <man_syntax>
    string read_file(string <I>file</I>, int <I>start</I>, int <I>len</I>);<br>
    string read_file(string <I>file</I>);<br>
    </man_syntax>
    <man_description>
    Read <i>len</i> lines from the file <i>file</i> after skipping <i>start</i> lines
    and return those lines as a string. If <i>start</i> and <i>len</i> are omitted
    the whole file is read.
    </man_description>
    <man_see>Stdio.read_bytes, Stdio.write_file</man_see>
    </function>
    
    
    <function name=readline title="read a line from stdin">
    <man_syntax>
    string readline(string <I>prompt</I>);<br>
    </man_syntax>
    <man_description>
    This function writes the string <i>prompt</i> and then waits until the
    user has entered a line from the keyboard. If the readline library
    was available when Pike was compiled the user will have history and
    line editing at his/her disposal when entering the line.
    </man_description>
    <man_see>Stdio.File</man_see>
    </function>
    
    
    <function name=werror title="write to stderr">
    <man_syntax>
    void werror(string <I>s</I>);<br>
    </man_syntax>
    <man_description>
    Writes a message to stderr. Stderr is normally the console, even if
    the process output has been redirected to a file or pipe.
    </man_description>
    </function>
    
    
    <function name=write_file title="append a string to a file">
    <man_syntax>
    int write_file(string <i>file</i>, string <i>str</i>)<br>
    </man_syntax>
    <man_description>
    Append the string <i>str</i> onto the file <i>file</i>. Returns number of bytes written.
    </man_description>
    <man_see>Stdio.read_bytes</man_see>
    </function>
    
    </section>
    
    <class name=Port>
    <section title="Listening to sockets">
    Stdio.File can handle connections to any TCP socket, but it can not listen
    to a local TCP port. For this purpose there is a special class called
    <tt>Stdio.Port</tt>. <tt>Stdio.Port</tt> cannot read or write any data, but
    it can accept connections which will be returned as clones of Stdio.File.
    These are the methods available in <tt>Stdio.Port</tt>:
    
    <hr>
    
    <method name=bind title="open socket and bind it to a port">
    <man_syntax>
    int bind(int <I>port</I>);<br>
    int bind(int <I>port</I>,function <I>accept_callback</I>);<br>
    int bind(int <I>port</I>,function <I>accept_callback</I>, string <I>IP</I>);<br>
    </man_syntax>
    <man_description>
    Bind opens a sockets and binds it to port number on the local machine.
    If the second argument is present, the socket is set to nonblocking
    and the callback function is called whenever something connects to
    the socket. The callback will receive the id for this port as argument.
    Bind returns 1 on success, and zero on failure.
    <p>
    If the optional argument <i>IP</i> is given, bind will try to bind to
    this IP name (or number).
    </man_description>
    <man_see>Stdio.Port-&gt;accept</man_see>
    </method>
    
    
    
    <method name=listen_fd title="listen to an already open port">
    <man_syntax>
    int listen_fd(int <I>fd</I>);<br>
    int listen_fd(int <I>fd</I>,function <I>accept_callback</I>);<br>
    </man_syntax>
    <man_description>
    This function does the same as Stdio.Port-&gt;bind, except that instead
    of creating a new socket and bind it to a port, it expects that
    the file descriptor <i>fd</i> is an already open port.
    </man_description>
    <man_nb>
    This function is only for the advanced user, and is generally used
    when sockets are passed to Pike at exec time.
    </man_nb>
    <man_see>Stdio.Port-&gt;bind, Stdio.Port-&gt;accept</man_see>
    </method>
    
    
    <method name=create title="create and/or setup a port">
    <man_syntax>
    object(Stdio.Port) Stdio.Port("stdin")<br>
    object(Stdio.Port) Stdio.Port("stdin",function <i>accept_callback</i>)<br>
    object(Stdio.Port) Stdio.Port("stdin",function <i>accept_callback</i>)<br>
    object(Stdio.Port) Stdio.Port(int <i>port</i>)<br>
    object(Stdio.Port) Stdio.Port(int <i>port</i>,function <i>accept_callback</i>)<br>
    object(Stdio.Port) Stdio.Port(int <i>port</i>,function <i>accept_callback</i>, string <i>ip</i>)<br>
    </man_syntax>
    <man_description>
    When create is called with <tt>"stdin"</tt> as argument, a socket is created
    out of the file descriptor 0. This is only useful if that actually
    is a socket to begin with. When create is called with an int as first
    argument, it does the same as bind() would do with the same arguments.
    The second and third argument has the same function as in the bind()
    call.
    </man_description>
    <man_see>clone, Stdio.Port-&gt;bind</man_see>
    </method>
    
    
    
    <method name=set_id title="set the id of a port">
    <man_syntax>
    void set_id(mixed <I>id</I>);<br>
    </man_syntax>
    <man_description>
    This function sets the id used for accept_callback by this port.
    The default id is this_object().
    </man_description>
    <man_see>Stdio.Port-&gt;query_id</man_see>
    </method>
    
    
    <method name=query_id title="Return the id for this port.">
    <man_syntax>
    mixed query_id();<br>
    </man_syntax>
    <man_description>
    This function returns the id for this port. The id is normally the
    first argument to accept_callback.
    </man_description>
    <man_see>Stdio.Port-&gt;set_id</man_see>
    </method>
    
    
    <method name=errno title="return the last error">
    <man_syntax>
    int errno();<br>
    </man_syntax>
    <man_description>
    If the last call done on this port failed, errno will return an
    integer describing what went wrong. Refer to your Unix manual for
    further information.
    </man_description>
    <man_see>Stdio.Port-&gt;errno</man_see>
    </method>
    
    
    <method name=accept title="accept a connection">
    <man_syntax>
    object accept();<br>
    </man_syntax>
    <man_description>
    This function completes a connection made from a remote machine to
    this port. It returns a two-way stream in the form of a copy of
    Stdio.File. The new file is by default set to blocking.
    </man_description>
    <man_see>Stdio.File</man_see>
    </method>
    
    </section>
    </class>
    
    <section title="A more complex example - a simple WWW server">
    
    As most of you know, WWW  WWW (World Wide Web), works by using a
    client program which will fetch files from remote servers when asked.
    Usually by clicking a picture or text. This example is a program for the
    server which will send files to any computer that requests them. The
    protocol used to send the file is called HTTP. (Hyper-Text Transfer Protocol)
    <p>
    Usually WWW involves HTML. HTML (Hyper-Text Markup Language) is a way to
    write documents with embedded pictures and links to other pages. These
    links are normally displayed underlined and if you click them your WWW-
    browser will load whatever document that link leads to.
    <p>
    <example language=pike>
    	#!/usr/local/bin/pike
    	
    	/* A very small httpd capable of fetching files only.
    	 * Written by Fredrik Hübinette as a demonstration of Pike.
    	 */
    	
    	inherit Stdio.Port;
    </example>
    We inherit Stdio.Port into this program so we can bind a TCP socket to accept
    incoming connection.  A socket is simply a number to separate communications
    to and from different programs on the same computer.
    <p>
    Next are some constants that will affect how uHTTPD will operate. This uses
    the preprocessor directive #define. The preprocessor is the first stage in
    the compiling process and can make textual processing of the code before
    it is compiled. As an example, after the first define below, all occurrences
    of 'BLOCK' will be replaced with 16060.
    <example language=pike>
    	
    	/* Amount of data moved in one operation */
    	#define BLOCK 16060
    	
    	/* Where do we have the html files ? */
    	#define BASE "/usr/local/html/"
    	
    	/* File to return when we can't find the file requested */
    	#define NOFILE "/user/local/html/nofile.html"
    	
    	/* Port to open */
    	#define PORT 1905
    </example>
    A port is a destination for a TCP connection. It is simply a number on the
    local computer. 1905 is not the standard port for HTTP connections though,
    which means that if you want to access this WWW server from a browser you
    need to specify the port like this: http://my.host.my.domain:1905/
    <p>
    Next we declare a class called output_class. Later we will clone one
    instance of this class for each incoming HTTP connection.
    <p>
    <example language=pike>
    	class output_class
    	{
    	  inherit Stdio.File : socket;
    	  inherit Stdio.File : file;
    </example>
    Our new class inherits Stdio.File twice. To be able to separate them
    they are then named 'socket' and 'file'.
    <p>
    <example language=pike>
    	  int offset=0;
    </example>
    Then there is a global variable called offset which is initialized to zero.
    (Each instance of this class will have its own instance of this variable,
     so it is not truly global, but...) 
    Note that the initialization is done when the class is cloned (or
    instantiated if you prefer C++ terminology).
    <p>
    Next we define the function write_callback(). Later the program will go
    into a 'waiting' state, until something is received to process, or until
    there is buffer space available to write output to. When that happens a
    callback will be called to do this. The write_callback() is called when
    there is buffer space available. In the following lines 'void' means that
    it does not return a value. Write callback will be used further down as a
    callback and will be called whenever there is room in the socket output
    buffer.
    <example language=pike>
    	
    	  void write_callback()
    	  {
    	    int written;
    	    string data;
    </example>
    The following line means: call seek in the inherited program 'file'.
    <example language=pike>
    	
    	    file::seek(offset);
    </example>
    Move the file pointer to the where we want to the position we want to read
    from. The file pointer is simply a location in the file, usually it is where
    the last read() ended and the next will begin. seek() can move this pointer
    to where we want it though.
    <p>
    <example language=pike>
    	    data=file::read(BLOCK);
    </example>
    Read BLOCK (16060) bytes from the file. If there are less that that left to
    read only that many bytes will be returned.
    <p>
    <example language=pike>
    	    if(strlen(data))
    	    {
    </example>
     If we managed to read something...
    <p>
    <example language=pike>
    	      written=socket::write(data);
    </example>
     ... we try to write it to the socket.
    <p>
    <example language=pike>
    	      if(written &gt;= 0)
    	      {
    		offset+=written;
    		return;
    	      }
    </example>
     Update offset if we managed to write to the socket without errors.
    <p>
    <example language=pike>
    	      werror("Error: "+socket::errno()+".\n");
    	    }
    </example>
     If something went wrong during writing, or there was nothing left to read
     we destruct this instance of this class.
    <p>
    <example language=pike>
    	    destruct(this_object());
    	  }
    </example>
     That was the end of write_callback()
    <p>
    
     Next we need a variable to buffer the input received in. We initialize it
     to an empty string.
    <example language=pike>
    	
    	  string input="";
    </example>
     And then we define the function that will be called when there is something
     in the socket input buffer. The first argument 'id' is declared as mixed,
     which means that it can contain any type of value. The second argument is
     the contents of the input buffer.
    <p>
    <example language=pike>
    	  void read_callback(mixed id,string data)
    	  {
    	    string cmd;
    	
    	    input+=data;
    </example>
    Append data to the string input. Then we check if we have received a
    a complete line yet. If so we parse this and start outputting the file.
    <p>
    <example language=pike>
    	    if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input)&gt;2)
    	    {
    </example>
    This sscanf is pretty complicated, but in essence it means: put the
    first word in 'input' in 'cmd' and the second in 'input' and return 2
    if successful, 0 otherwise.
    <p>
    <example language=pike>
    	      if(cmd!="GET")
    	      {
    		werror("Only method GET is supported.\n");
    		destruct(this_object());
    		return;
    	      }
    </example>
    If the first word isn't GET print an error message and terminate
    this instance of the program. (and thus the connection)
    <example language=pike>
    	
    	      sscanf(input,"%*[/]%s",input);
    </example>
    Remove the leading slash.
    <p>
    <example language=pike>
    	      input=combine_path(BASE,input);
    </example>
    Combine the requested file with the base of the HTML tree, this gives
    us a full filename beginning with a slash. The HTML tree is the
    directory on the server in which the HTML files are located. Normally
    all files in this directory can be accessed by anybody by using a WWW
    browser. So if a user requests 'index.html' then that file name is first
    added to BASE (/home/hubbe/www/html/ in this case) and if that file exists
    it will be returned to the browser.
    <example language=pike>
    	      
    	      if(!file::open(input,"r"))
    	      {
    </example>
    Try opening the file in read-only mode. If this fails, try opening NOFILE
    instead. Opening the file will enable us to read it later.
    <p>
    <example language=pike>
    		if(!file::open(NOFILE,"r"))
    		{
    </example>
    If this fails too. Write an error message and destruct this object.
    <p>
    <example language=pike>
    		  werror("Couldn't find default file.\n");
    		  destruct(this_object());
    		  return;
    		}
    	      }
    </example>
    Ok, now we set up the socket so we can write the data back.
    <example language=pike>
    	
    	      socket::set_buffer(65536,"w");
    </example>
    Set the buffer size to 64 kilobytes.
    <p>
    <example language=pike>
    	      socket::set_nonblocking(0,write_callback,0);
    </example>
    Make it so that write_callback is called when it is time to write more
    data to the socket.
    <p>
    <example language=pike>
    	      write_callback();
    </example>
    Jump-start the writing.
    <example language=pike>
    	    }
    	  }
    </example>
    That was the end of read_callback().
    <p>
    
    This function is called if the connection is closed while we are reading
    from the socket.
    <example language=pike>
    	  void selfdestruct() { destruct(this_object()); }
    
    </example>
    This function is called when the program is instantiated. It is used
    to set up data the way we want it. Extra arguments to clone() will be
    sent to this function. In this case it is the object representing the
    new connection.
    <p>
    <example language=pike>
    	  void create(object f)
    	  {
    	    socket::assign(f);
    </example>
    We insert the data from the file f into 'socket'.
    <p>
    <example language=pike>
    	    socket::set_nonblocking(read_callback,0,selfdestruct);
    </example>
    Then we set up the callback functions and sets the file nonblocking.
    Nonblocking mode means that read() and write() will rather return that
    wait for I/O to finish. Then we sit back and wait for read_callback to
    be called.
    <p>
    <example language=pike>
    	  }
    </example>
    End of create()
    <p>
    <example language=pike>
    	};
    </example>
    End of the new class.
    <pre>
    	
    </pre>
    Next we define the function called when someone connects.
    <p>
    <example language=pike>
    	void accept_callback()
    	{
    	  object tmp_output;
    </example>
    This creates a local variable of type 'object'. An object variable can
    contain a clone of any program. Pike does not consider clones of different
    programs different types. This also means that function calls to objects
    have to be resolved at run time.
    <p>
    <example language=pike>
    	  tmp_output=accept();
    </example>
    The function accept  clones a Stdio.File and makes this equal to the
    newly connected socket.
    <p>
    <example language=pike>
    	  if(!tmp_output) return;
    </example>
    If it failed we just return.
    <p>
    <example language=pike>
    	  output_class(tmp_output);
    </example>
    Otherwise we clone an instance of 'output_class' and let it take care of the
    connection. Each clone of output_class will have its own set of global
    variables, which will enable many connections to be active at the same
    time without data being mixed up. Note that the programs will not actually
    run simultaneously though.
    <p>
    <example language=pike>
    	  destruct(tmp_output);
    </example>
    Destruct the object returned by accept(), output_class has already copied
    the contents of this object.
    <p>
    <example language=pike>
    	}
    
    </example>
    Then there is main, the function that gets it all started.
    	
    <example language=pike>
    	int main(int argc, array(string) argv)
    	{
    	  werror("Starting minimal httpd\n");
    </example>
    Write an encouraging message to stderr.
    <example language=pike>
    	
    	  if(!bind(PORT, accept_callback))
    	  {
    	    werror("Failed to open socket (already bound?)\n");
    	    return 17;
    	  }
    
    </example>
    Bind PORT and set it up to call accept_callback as soon as someone connects
    to it. If the bind() fails we write an error message and return the 17 to
    indicate failure.
    <example language=pike>
    	
    	  return - 17; /* Keep going */
    </example>
    If everything went ok, we return -17, any negative value returned by main()
    means that the program WON'T exit, it will hang around waiting for events
    instead. (like someone connecting)
    <example language=pike>
    	}
    </example>
    That's it, this simple program can be used as the basis for a simple
    WWW-server. Note that today most WWW servers are very complicated programs,
    and the above program can never replace a modern WWW server.
    However, it is very fast if you only want a couple of web pages and have
    a slow machine available for the server.
    <p>
    </section>
    </chapter>
    </module>
    
    <anchor name=Threads>
    <chapter title="Threads">
    Threads are used to run several Pike functions at the same time without having to start
    several Pike processes. Using threads often simplifies coding and because the
    threads are within the same process, data can be shared or sent to other threads
    very fast. Threads are not supported on all systems, you may test if you have
    thread support with the preprocessor construction <tt>#if constant(thread_create)</tt>.
    Pike needs POSIX or UNIX thread support when compiled to support threads.
    <p>
    
    <section title="Starting a thread">
    Starting a thread is very easy. You simply call <tt>thread_create</tt> with a function
    pointer and any arguments it needs and that function will be executed in a
    separate thread. The function <tt>thread_create</tt> will return immediately and both
    the calling function and the called function will execute at the same time. Example:
    <example language=pike>
    	void foo(int x)
    	{
    	  for(int e=0;e&lt;5;e++)
    	  {
    	    sleep(1);
    	    write("Hello from thread "+x+".\n");
    	  }
    	}
    
    	int main()
    	{
    	  thread_create(foo, 2);
    	  thread_create(foo, 3);
    	  foo(1);
    	}
    </example>
    This may all seem very simple, but there are a few complications to
    watch out for:
    <dl>
    <dt> Accessing unlocked data
    <dd> Look at this code:
    <example language=pike>
    	void mapadd(mapping m, int i, int j)
    	{
    	  if(map[i])
    	     map[i]+=({j});
    	  else
    	     map[i]=({j});
    	}
    </example>
    This is quite harmless as long as it is only used from one thread at a time,
    but if two threads call it it at the same time, there is a slight chance that
    both threads will discover that <tt>map[i]</tt> is zero and both threads will
    then do <tt>map[i]=({j});</tt> and one value of <tt>j</tt> will be lost.
    This type of bug can be extremely hard to debug.
    
    The above problem can be solved with the help of Mutexes and Condition
    variables. Mutexes are basically a way to keep other threads out while a task
    is being performed. Conditions, or <b>condition variables</b>, are used to inform
    other threads that they don't have to wait any longer. Pike also provides
    two different kinds of pipelines to send data from one thread to another, which
    makes it very simple to write threaded programs. Let's look at an example:
    <example language=pike>
    	#!/usr/local/bin/pike
    	import Thread;			// We need fifos
    	inherit Fifo;			// Fifo used to supply workers
    	inherit Fifo : ended;		// Fifo used to wait for workers
    
    	void worker(string lookfor)
    	{
    	  while(string file=Fifo::read())
    	  {
    	    int linenum=1;
    	    object o=Stdio.FILE(file,"r");
    	    while(string line=o-&gt;gets())
    	    {
    	      if(search(line, lookfor) &gt;=0)
    		write(sprintf("%s:%d: %s\n",file, linenum, line));
    
    	      linenum++;
    	    }
    	  }
    	  ended::write(0);
    	}
    
    	int main(int argc, array(string) argv)
    	{
    	  for(int e=0;e&lt;4;e++)          // Start workers
    	    thread_create(worker,argv[1]);
    	  for(int e=2;e&lt;argc;e++)       // Feed workers
    	    Fifo::write(argv[1]);
    	  for(int e=0;e&lt;4;e++)          // Tell workers to die
    	    Fifo::write(0);
    	  for(int e=0;e&lt;4;e++)          // Wait for workers to die
    	     ended::read();
    	  exit(0);
    	}
    </example>
    
    This is an example of a simple grep-like program. It looks for the string
    given as first argument to the program in the files given as the rest
    of the arguments. Don't worry if you do not understand it yet. Read the
    descriptions of the functions and classes below and come back and read
    this example again.
    
    <dt> Deadlocks
    <dd> Deadlocks arise when two threads are waiting for each other to do something.
         This bug can often arise when several threads need access to a number of
         resources such as files or other I/O devices. What may happen is that one
         thread has locked device #1 and is trying to lock device #2 while another
         thread has locked device #2 and is trying to lock device #1. This type
         of bug is generally easier to find, but may require a lot of work to fix.
    </dl>
    
    </section>
    
    
    <section title="Threads reference section">
    This section describes all thread-related functions and classes.
    
    <hr noshade size=1>
    <anchor name=Thread.thread_create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.thread_create</tt> - create a thread
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object thread_create(function <I>f</I>, mixed ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function creates a new thread which will run simultaneously
    to the rest of the program. The new thread will call the function
    <i>f</i> with the arguments <i>args</i>. When f returns the thread will cease
    to exist. All Pike functions are 'thread safe' meaning that running
    a function at the same time from different threads will not corrupt
    any internal data in the Pike process. The returned value will be
    the same as the return value of this_thread() for the new thread.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function is only available on systems with POSIX or UNIX threads support.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.Mutex>Thread.Mutex</link>, <link to=Thread.Condition>Thread.Condition</link> and <link to=Thread.this_thread>Thread.this_thread</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Thread.this_thread>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.this_thread</tt> - return thread id
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object thread_id();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the object that identifies this thread.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.thread_create>Thread.thread_create</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Mutex>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Mutex</tt> - mutex locks
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Thread.Mutex is a pre-compiled Pike program that implements
    mutual exclusion locks. Mutex locks are used to prevent multiple
    threads from simultaneously execute sections of code which access
    or change shared data. The basic operations for a mutex is locking
    and unlocking, if a thread attempts to lock an already locked mutex
    the thread will sleep until the mutex is unlocked.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Mutex locks are only available on systems with POSIX or UNIX threads support.
    <p>
    In POSIX threads, mutex locks can only be unlocked by the same thread
    locked them. In Pike any thread can unlock a locked mutex.
    <p>
    
    <dt><encaps>EXAMPLE</encaps><dd>
    This simple program can be used to exchange data between two
    programs. It is similar to Thread.Fifo, but can only hold one
    element of data.
    <example language=pike>
    inherit Thread.Mutex : r_mutex;
    inherit Thread.Mutex : w_mutex;
    object r_lock=r_mutex::lock();
    object w_lock;
    mixed storage;
    
    void write(mixed data)
    {
      w_lock=w_mutex::lock();
      storage=data;
      destruct(r_lock);
    }
    
    mixed read()
    {
      mixed tmp;
      r_lock=r_mutex::lock();
      tmp=storage;
      storage=0;
      destruct(w_lock);
      return tmp;
    }
    </example>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Mutex.lock>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Mutex-&gt;lock</tt> - lock the mutex
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object lock();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function attempts to lock the mutex, if the mutex is already
    locked the current thread will sleep until the lock is unlocked by some
    other thread. The value returned is the 'key' to the lock. When the
    key is destructed or has no more references the lock will automatically
    be unlocked. The key will also be destructed if the lock is destructed.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Mutex.trylock>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Mutex-&gt;trylock</tt> - try to lock the mutex
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object trylock();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function performs the same operation as lock(), but if the mutex
    is already locked zero will be returned instead of sleeping until the
    lock is unlocked.
    <p>
    </dl>
    
    <hr newpage noshade size=1>
    <anchor name=Thread.Condition>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Condition</tt> - condition variables
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Thread.Condition is a pre-compiled Pike program that implements
    condition variables. Condition variables are used by threaded programs
    to wait for events happening in other threads.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Condition variables are only available on systems with POSIX or UNIX threads
    support.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <example language=pike>
    // This program implements a fifo that can be used to send
    // data between two threads.
    inherit Thread.Condition : r_cond;
    inherit Thread.Condition: w_cond;
    inherit Thread.Mutex: lock;
    
    mixed *buffer = allocate(128);
    int r_ptr, w_ptr;
    
    int query_messages()    {  return w_ptr - r_ptr;  }
    
    // This function reads one mixed value from the fifo.
    // If no values are available it blocks until a write has been done.
    mixed read()
    {
      mixed tmp;
      // We use this mutex lock to make sure no write() is executed
      // between the query_messages and the wait() call. If it did
      // we would wind up in a deadlock.
      object key=lock::lock();
      while(!query_messages()) r_cond::wait(key);
      tmp=buffer[r_ptr++ % sizeof(buffer)];
      w_cond::signal();
      return tmp;
    }
    
    // This function pushes one mixed value on the fifo.
    // If the fifo is full it blocks until a value has been read.
    void write(mixed v)
    {
      object key=lock::lock();
      while(query_messages() == sizeof(buffer)) w_cond::wait(key);
      buffer[w_ptr++ % sizeof(buffer)]=v;
      r_cond::signal();
    }
    </example>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.Mutex>Thread.Mutex</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Condition.wait>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Condition-&gt;wait</tt> - wait for condition
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void wait();<br>
    or<br>
    void wait(object <I>mutex_key</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function makes the current thread sleep until the condition
    variable is signalled. The optional argument should be the 'key'
    to a mutex lock. If present the mutex lock will be unlocked before
    waiting for the condition in one atomic operation. After waiting
    for the condition the mutex referenced by mutex_key will be re-locked.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.Mutex.lock>Thread.Mutex-&gt;lock</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Condition.signal>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Condition-&gt;signal</tt> - signal a condition variable
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void signal();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Signal wakes up one of the threads currently waiting for the
    condition.
    <p>
    <dt><encaps>BUGS</encaps><dd>
    It sometimes wakes up more than one thread.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Condition.broadcast>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Condition-&gt;broadcast</tt> - signal all waiting threads
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void broadcast();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function wakes up all threads currently waiting for this
    condition.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Fifo>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Fifo</tt> - first in, first out object
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Thread.Fifo implements a fixed length fifo. A fifo is a queue
    of values and is often used as a stream of data between two threads.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.Queue>Thread.Queue</link>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Fifos are only available on systems with POSIX threads support.
    <p>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Fifo.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Fifo-&gt;create</tt> - initialize the fifo
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void create(int <I>size</I>);<br>
    or<br>
    object(Thread.Fifo) Thread.Fifo();<br>
    or<br>
    object(Thread.Fifo) Thread.Fifo(int <i>size</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The function create() is called when the fifo is cloned, if the
    optional size argument is present it sets how many values can be
    written to the fifo without blocking. The default size is 128.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Fifo.write>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Fifo-&gt;write</tt> - queue a value
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void write(mixed <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function puts a value last in the fifo. If there is no more
    room in the fifo the current thread will sleep until space is
    available.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Fifo.read>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Fifo-&gt;read</tt> - read a value from the fifo
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed read();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function retrieves a value from the fifo. Values will be
    returned in the order they were written. If there are no values
    present in the fifo the current thread will sleep until some other
    thread writes a value to the fifo.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Fifo.size>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Fifo-&gt;size</tt> - return number of values in fifo
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int size();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns how many values are currently in the fifo. <!-- L}ter fel /hedda -->
    <p>
    </dl>
    
    </anchor>
    
    
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Queue>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Queue</tt> - a queue of values
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Thread.Queue implements a queue, or a pipeline. The main difference
    between Thread.Queue and Thread.Fifo is that queues
    will never block in write(), only allocate more memory.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Thread.Fifo>Thread.Fifo</link>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Queues are only available on systems with POSIX or UNIX threads support.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Queue.write>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Queue-&gt;write</tt> - queue a value
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void write(mixed <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function puts a value last in the queue. If the queue is
    too small to hold the value the queue will be expanded to make
    room for it.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Queue.read>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Queue-&gt;read</tt> - read a value from the queue
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed read();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function retrieves a value from the queue. Values will be
    returned in the order they were written. If there are no values
    present in the queue the current thread will sleep until some other
    thread writes a value to the queue.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Thread.Queue.size>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Thread.Queue-&gt;size</tt> - return number of values in queue
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int queue-&gt;size();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns how many values are currently in the queue.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    </section>
    
    <section title="Threads example">
    Let's look at an example of how to work with threads. This program is the same
    minimal WWW server as in <ref to=io> but it has been
    re-written to use threads, as you can see it is a lot smaller this
    way. This is because we can use blocking I/O operations instead of
    non-blocking and callbacks. This also makes the program much easier to
    follow:
    <example language=pike>
    #!/usr/local/bin/pike
    
    /* A very small threaded httpd capable of fetching files only.
     * Written by Fredrik Hübinette as a demonstration of Pike
     */
    
    import Thread;
    inherit Stdio.Port;
    
    /* number of bytes to read for each write */
    #define BLOCK 16384
    
    /* Where do we have the html files ? */
    #define BASE "/home/hubbe/pike/src/"
    
    /* File to return when we can't find the file requested */
    #define NOFILE "/home/hubbe/www/html/nofile.html"
    
    /* Port to open */
    #define PORT 1905
    
    /* Number of threads to start */
    #define THREADS 5
    
    // There will be one of these for each thread
    class worker
    {
      inherit Stdio.FILE : socket;  // For communication with the browser
      inherit Stdio.File : file;    // For reading the file from disc
    
      void create(function accept)
      {
        string cmd, input, tmp;
    
        while(1)
        {
          socket::close();    // Close previous connection
          file::close();
    
          object o=accept();  // Accept a connection
          if(!o) continue;
          socket::assign(o);
          destruct(o);
    
          // Read request
          sscanf(socket::gets(),"%s %s%*[\012\015 \t]",cmd, input);
          if(cmd!="GET")
          {
    	werror("Only method GET is supported.\n");
    	continue;
          }
    
          // Open the requested file      
          sscanf(input,"%*[/]%s",input);
          input=combine_path(BASE,input);
          
          if(!file::open(input,"r"))
          {
    	if(!file::open(NOFILE,"r"))
    	{
    	  werror("Couldn't find default file.\n");
    	  continue;
    	}
          }
    
          // Copy data to socket
          while(socket::write(file::read(BLOCK))==BLOCK);
        }
      }
    };
    
    int main(int argc, array(string) argv)
    {
      werror("Starting minimal threaded httpd\n");
    
      // Bind the port, don't set it nonblocking
      if(!bind(PORT))
      {
        werror("Failed to open socket (already bound?)\n");
        return 17;
      }
    
      // Start worker threads
      for(int e=1;e&lt;THREADS;e++) thread_create(worker,accept);
      worker(accept);
    }
    </example>
    <p>
    As stated in the beginning of this chapter; Pike threads are only available
    on some UNIX systems. The above example does not work if your system does
    not have threads.
    </section>
    </chapter>
    </anchor>
    
    <chapter title="Modules for specific data types">
    
    There are a few modules that provide extra functions that operate specifically
    on one data type. These modules have the same name as the data type, but are
    capitalized so you can tell the difference. At the time of writing, the only
    such modules are <tt>String</tt> and <tt>Array</tt>, but more are expected to
    show up in the future.
    
    <section title="String">
    The module <tt>String</tt> contains some extra string functionality which
    is not always used. These functions are mostly implemented in Pike as a
    complement to those written in C.
    
    <hr noshade size=1>
    <anchor name=String.implode_nicely>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>String.implode_nicely</tt> - make an English comma separated list
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string implode_nicely(array(string) words, string|void separator)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function implodes a list of words to a readable string.
    If the separator is omitted, the default is <tt>"and"</tt>.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>&gt; implode_nicely(({"green"}));<br>
    Result: green<br>
    &gt; implode_nicely(({"green","blue"}));<br>
    Result: green and blue<br>
    &gt; implode_nicely(({"green","blue","white"}));<br>
    Result: green, blue and white<br>
    &gt; implode_nicely(({"green","blue","white"}),"or");<br>
    Result: green, blue or white<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=%60*>`*</link>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    
    <anchor name=String.capitalize>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>String.capitalize</tt> - capitalize a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string capitalize(string str)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Convert the first character in str to upper case, and return the
    new string.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=lower_case>lower_case</link> and <link to=upper_case>upper_case</link>
    <p>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    
    <anchor name=String.strmult>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>String.strmult</tt> - multiply strings
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string strmult(string <I>s</I>, int <I>num</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function multiplies 's' by 'num'. The return value is the same
    as appending 's' to an empty string 'num' times.
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    </section>
    
    <section title="Array">
    As with <tt>String</tt> these functions are Pike functions written to
    supplement those written in C.
    
    <hr noshade size=1>
    <anchor name=Array.map>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.map</tt> - map an array or mapping over a function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array map(array <I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br>
    array map(array(object) <I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br>
    array map(array(function) <I>arr</I>,-<I>1</I>,mixed ... <I>arg</I>);<br>
    </tt>
    <p>
    
    
    <dt><encaps>DESCRIPTION</encaps><dd>
    First syntax:
    Map array returns an array holding the items of arr mapped through
    the function fun. ie. arr[x]=fun(arr[x], @args) for all x.
    <p>Second syntax:
    Map array calls function fun in all objects in the array arr.
    ie. arr[x]=arr[x]-&gt;fun(@ args);
    <p>Third syntax:
    Map array calls the functions in the array arr:
    arr[x]=arr[x]-&gt;fun(@ args);
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.sum_arrays>Array.sum_arrays</link> and <link to=Array.filter>Array.filter</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Array.filter>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.filter</tt> - filter an array or mapping through a function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array filter(array <I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br>
    array filter(array(object) <I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    array filter(array(function) <I>arr</I>,-<I>1</I>,mixed ... <I>args</I>);<br>
    </tt>
    <p>
    
    <dt><encaps>DESCRIPTION</encaps><dd>
    First syntax:
    Filter array returns an array holding the items of arr for which
    fun returns true.
    <p>Second syntax:
    Filter array calls fun in all the objects in the array arr, and
    return all objects that returned true.
    <p>Third syntax:
    Filter array calls all function pointers in the array arr, and
    return all that returned true.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.sum_arrays>Array.sum_arrays</link> and <link to=Array.map>Array.map</link>
    </dl>
    </anchor>
    
    
    <hr noshade size=1>
    <anchor name=Array.search_array>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.search_array</tt> - search for something in an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int search_array(mixed *<I>arr</I>,function <I>fun</I>,mixed <I>arg</I>, ...);<br>
    or<br>
    int search_array(object *<I>arr</I>,string <I>fun</I>,mixed <I>arg</I>, ...);<br>
    or<br>
    int search_array(function *<I>arr</I>,-<I>1</I>,mixed <I>arg</I>, ...);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    search_array works like map_array, only it returns the index of the
    first call that returned true instead or returning an array of the
    returned values. If no call returns true, -1 is returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.sum_arrays>Array.sum_arrays</link> and <link to=Array.filter_array>Array.filter_array</link>
    <p>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    <anchor name=Array.sum_arrays>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.sum_arrays</tt> - map any number of arrays over a function.
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *sum_arrays(function <I>fun</I>,mixed *<I>arr1</I>,...);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Works like this:
    <p>mixed *sum_arrays(function fun,mixed *arr1,...)<br>
    {<br>
    <dl><dt><dd>int e;<br>
    mixed *res=allocate(sizeof(arr1));<br>
    for(e=0;e&lt;sizeof(arr1);e++)<br>
    {<br>
    <dl><dt><dd>res[e]=fun(arr1[e],arr2[e],...);<br>
    </dl>}<br>
    return res;<br>
    </dl>}<br>
    
    <p>Simple ehh?
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.map_array>Array.map</link>, <link to=Array.filter>Array.filter</link> and <link to=Array.search_array>Array.search_array</link>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    <anchor name=Array.sort_array>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.sort_array</tt> - sort an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *sort_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function sorts an array after a compare-function <i>fun</i>
    which takes two arguments and should return 1 if the first argument
    is larger then the second. The rest of the arguments <i>args</i> will be
    sent as 3rd, 4th etc. argument to <i>fun</i>. If <i>fun</i> is omitted, `&lt; is used
    instead.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.map>Array.map</link> and <link to=sort>sort</link>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    <anchor name=Array.uniq>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Array.uniq</tt> - return one of each element
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array uniq(array <I>a</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns an copy of the array <i>a</i> with all duplicate
    values removed. The order of the values in the result is undefined.
    <p>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    </section>
    </chapter>
    
    <chapter title="Other modules">
    
    Pike also include a number of smaller modules. These modules implement support
    for various algorithms, data structures and system routines.
    
    <anchor name=System>
    <section title="System">
    The system module contains some system-specific functions that may or may
    not be available on your system. Most of these functions do exactly the same
    thing as their UNIX counterpart. See the UNIX man pages for detailed
    information about what these functions do on your system.
    <p>
    Please note that these functions are available globally, you do not
    need to <tt>import System</tt> to use these functions.
    
    <hr noshade size=1>
    <anchor name=chroot>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>chroot</tt> - change the root directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int chroot(string <I>newroot</I>);<br>
    or<br>
    int chroot(object(File) <I>obj</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Changes the root directory for this process to the indicated
    directory.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Since this function modifies the directory structure as seen from
    Pike, you have to modify the environment variables PIKE_MODULE_PATH
    and PIKE_INCLUDE_PATH to compensate for the new root-directory.
    <p>This function only exists on systems that have the chroot(2)
    system call.
    The second variant only works on systems that also have
    the fchroot(2) system call.
    
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getegid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getegid</tt> - get the effective group ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getegid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Get the effective group ID.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link> and <link to=setegid>setegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=geteuid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>geteuid</tt> - get the effective user ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int geteuid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Get the effective user ID.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getgid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getgid</tt> - get the group ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getgid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Get the real group ID.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=gethostbyaddr>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gethostbyaddr</tt> - gets information about a host given its address
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array gethostbyaddr(string <I>addr</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns an array with information about the specified IP address.
    <p>The returned array contains the same information as that returned
    by gethostbyname().
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function only exists on systems that have the gethostbyaddr(2)
    or similar system call.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=gethostbyname>gethostbyname</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=gethostbyname>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gethostbyname</tt> - gets information about a host given its name
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array gethostbyname(string <I>hostname</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns an array with information about the specified host.
    <p>The array contains three elements:
    <p>The first element is the hostname.
    <p>The second element is an array(string) of IP numbers for the host.
    <p>The third element is an array(string) of aliases for the host.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function only exists on systems that have the gethostbyname(2)
    or similar system call.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=gethostbyaddr>gethostbyaddr</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=gethostname>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gethostname</tt> - get the name of this host
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string gethostname();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a string with the name of the host.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function only exists on systems that have the gethostname(2)
    or uname(2) system calls.
    
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getpgrp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getpgrp</tt> - get the process group ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getpgrp();<br>
    or<br>
    int getpgrp(int <I>pid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    With no arguments or with <i>pid</i> equal to zero, returns the process
    group ID of this process.
    <p>If <i>pid</i> is specified, returns the process group ID of that process.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getpid>getpid</link> and <link to=getppid>getppid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getpid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getpid</tt> - get the process ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getpid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the process ID of this process.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getppid>getppid</link> and <link to=getpgrp>getpgrp</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getppid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getppid</tt> - get the parent process ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getppid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the process ID of the parent process.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getpid>getpid</link> and <link to=getpgrp>getpgrp</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=getuid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getuid</tt> - get the user ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getuid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Get the real user ID.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=hardlink>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>hardlink</tt> - create a hardlink
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void hardlink(string <I>from</I>, string <I>to</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Creates a hardlink named <i>to</i> from the file <i>from</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=symlink>symlink</link>, <link to=mv>mv</link> and <link to=rm>rm</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=initgroups>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>initgroups</tt> - initialize the group access list
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void initgroups(string <I>username</I>, int <I>base_gid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Initializes the group access list according to the system
    group database. <i>base_gid</i> is also added to the group access
    list.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link>, <link to=getegid>getegid</link>, system/getgroups and system/setgroups
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=openlog>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>openlog</tt> - initializes the connection to syslogd
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void openlog(string <I>ident</I>, int <I>options</I>, <I>facility</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Initializes the connection to syslogd.
    <p>The <i>ident</i> argument specifies an identifier to tag all log entries
    with.
    <p><i>options</i> is a bit field specifying the behavior of the message
    logging. Valid options are:
    <p><dl><dt><dd><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> LOG_PID </td><td> Log the process ID with each message. </td></tr>
    <tr valign=top><td> LOG_CONS </td><td> Write messages to the console if they can't be sent to syslogd. </td></tr>
    <tr valign=top><td> LOG_NDELAY </td><td> Open the connection to syslogd now and not later. </td></tr>
    <tr valign=top><td> LOG_NOWAIT </td><td> Do not wait for subprocesses talking to syslogd. </td></tr>
    </table>
    </dl>
    <p><i>facility</i> specifies what subsystem you want to log as. Valid
    facilities are:
    <p><dl><dt><dd><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> LOG_AUTH </td><td> Authorization subsystem </td></tr>
    <tr valign=top><td> LOG_AUTHPRIV </td></tr>
    <tr valign=top><td> LOG_CRON </td><td> Crontab subsystem </td></tr>
    <tr valign=top><td> LOG_DAEMON </td><td> System daemons </td></tr>
    <tr valign=top><td> LOG_KERN </td><td> Kernel subsystem (NOT USABLE) </td></tr>
    <tr valign=top><td> LOG_LOCAL </td><td> For local use </td></tr>
    <tr valign=top><td> LOG_LOCAL[1-7] </td><td> For local use </td></tr>
    <tr valign=top><td> LOG_LPR </td><td> Line printer spooling system </td></tr>
    <tr valign=top><td> LOG_MAIL </td><td> Mail subsystem </td></tr>
    <tr valign=top><td> LOG_NEWS </td><td> Network news subsystem </td></tr>
    <tr valign=top><td> LOG_SYSLOG </td></tr>
    <tr valign=top><td> LOG_USER </td></tr>
    <tr valign=top><td> LOG_UUCP </td><td> UUCP subsystem </td></tr>
    </table>
    </dl>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Only available on systems with syslog(3).
    
    BUGS
    LOG_NOWAIT should probably always be specified.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    syslog, closelog and setlogmask
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=readlink>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>readlink</tt> - read a symbolic link
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string readlink(string <I>linkname</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns what the symbolic link <i>linkname</i> points to.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=symlink>symlink</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=setegid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>setegid</tt> - set the effective group ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setegid(int <I>uid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the effective group ID to <i>gid</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=seteuid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>seteuid</tt> - set the effective user ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void seteuid(int <I>uid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the effective user ID to <i>uid</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=setgid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>setgid</tt> - set the group ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setgid(int <I>gid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the real group ID, effective group ID and saved group ID to <i>gid</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=setuid>setuid</link>, <link to=getuid>getuid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=setuid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>setuid</tt> - set the user ID
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setuid(int <I>uid</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the real user ID, effective user ID and saved user ID to <i>uid</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getuid>getuid</link>, <link to=setgid>setgid</link>, <link to=getgid>getgid</link>, <link to=seteuid>seteuid</link>, <link to=geteuid>geteuid</link>, <link to=setegid>setegid</link> and <link to=getegid>getegid</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=symlink>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>symlink</tt> - create a symbolic link
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void symlink(string <I>from</I>, string <I>to</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Creates a symbolic link named <i>to</i> pointing to <i>from</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=hardlink>hardlink</link>, <link to=readlink>readlink</link>, <link to=mv>mv</link> and <link to=rm>rm</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=uname>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>uname</tt> - get operating system information
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:string) <I>uname</I>();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a mapping describing the operating system.
    <p>The mapping contains the following fields:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td>  </td><td> "sysname": </td><td> Operating system name </td></tr>
    <tr valign=top><td>  </td><td> "nodename": "release": "version": "machine": </td><td> Host name Release of this OS Version number of this OS Machine architecture </td></tr>
    </table>
    
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function only exists on systems that have the uname(2)
    system call.
    <p>
    </dl>
    
    </anchor>
    </section>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Process>
    <section title="Process">
    The Process module contains functions to start and control other programs from Pike.
    <hr noshade size=1>
    <anchor name=Process.popen>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Process.popen</tt> - pipe open
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string popen(string <I>cmd</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function runs the command <i>cmd</i> as in a shell and returns the
    output. See your Unix/C manual for details on popen.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Process.system>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Process.system</tt> - run an external program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void system(string <I>cmd</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function runs the external program <i>cmd</i> and waits until it
    is finished. Standard /bin/sh completions/redirections/etc. can
    be used.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Process.popen>Process.popen</link>, <link to=Process.exec>Process.exec</link> and <link to=Process.spawn>Process.spawn</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Process.spawn>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Process.spawn</tt> - spawn a process
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int spawn(string <I>cmd</I>);<br>
    or<br>
    int spawn(string <I>cmd</I>, object <I>stdin</I>);<br>
    or<br>
    int spawn(string <I>cmd</I>, object <I>stdin</I>, object <I>stdout</I>);<br>
    or<br>
    int spawn(string <I>cmd</I>, object <I>stdin</I>, object <I>stdout</I>, object <I>stderr</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function spawns a process but does not wait for it to finish.
    Optionally, clones of Stdio.File can be sent to it to
    specify where stdin, stdout and stderr of the spawned processes
    should go.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Process.popen>Process.popen</link>, <link to=fork>fork</link>, <link to=Process.exec>Process.exec</link>, <link to=Stdio.File.pipe>Stdio.File-&gt;pipe</link> and <link to=Stdio.File.dup2>Stdio.File-&gt;dup2</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=exece>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>exece</tt> - execute a program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int exece(string <I>file</I>, array(string) <I>args</I>);<br>
    or<br>
    int exece(string <I>file</I>, array(string) <I>args</I>, mapping(string:string) <I>env</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function transforms the Pike process into a process running
    the program specified in the argument <i>file</i> with the argument <i>args</i>.
    If the mapping <i>env</i> is present, it will completely replace all
    environment variables before the new program is executed.
    This function only returns if something went wrong during exece(),
    and in that case it returns zero.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    The Pike driver _dies_ when this function is called. You must use
    fork() if you wish to execute a program and still run the Pike
    driver.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>exece("/bin/ls", ({"-l"}));<br>
    exece("/bin/sh", ({"-c", "echo $HOME"}), (["HOME":"/not/home"]));<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=fork>fork</link> and <link to=Stdio.File.pipe>Stdio.File-&gt;pipe</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Process.exec>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Process.exec</tt> - simple way to use exece()
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int exec(string <I>file</I>, string ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function destroys the Pike parser and runs the program
    <i>file</i> instead with the arguments. If no there are no '/' in
    the filename, the variable PATH will be consulted when looking
    for the program. This function does not return except when
    the exec fails for some reason.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>exec("/bin/echo","hello","world");<br>
    <br>
    </tt>
    </dl>
    </anchor>
    
    </section>
    </anchor>
    
    <anchor name=Regexp>
    <section title="Regexp">
    Regexp is short for <b>Regular Expression</b>. A regular expression is
    a standardized way to make pattern that match certain strings. In Pike
    you can often use the sscanf, range and index operators to match strings,
    but sometimes a regexp is both faster and easier.
    <p>
    A regular expression is actually a string, then compiled into an object.
    The string contains characters that make up a pattern for other strings
    to match. Normal characters, such as A through Z only match themselves,
    but some characters have special meaning. 
    
    <table>
    <tr><th> pattern </th><th>Matches</th></tr>
    <tr><td> . </td><td> any one character </td></tr>
    <tr><td> [abc] </td><td> a, b or c </td></tr>
    <tr><td> [a-z] </td><td> any character a to z inclusive </td></tr>
    <tr><td> [^ac] </td><td> any character except a and c </td></tr>
    <tr><td> (x) </td><td> x (x might be any regexp) If used with split, this also puts the string matching x into the result array. </td></tr>
    <tr><td> x* </td><td> zero or more occurrences of 'x' (x may be any regexp) </td></tr>
    <tr><td> x+ </td><td> one or more occurrences of 'x' (x may be any regexp) </td></tr>
    <tr><td> x|y </td><td> x or y. (x or y may be any regexp) </td></tr>
    <tr><td> xy </td><td> xy (x and y may be any regexp) </td></tr>
    <tr><td> ^ </td><td> beginning of string (but no characters) </td></tr>
    <tr><td> $ </td><td> end of string (but no characters) </td></tr>
    <tr><td> \&lt; </td><td> the beginning of a word (but no characters) </td></tr>
    <tr valign=top><td> \&gt; </td><td> the end of a word (but no characters) </td></tr>
    </table>
    Let's look at a few examples:
    <table>
    <tr><th>Regexp</th><th>Matches</th></tr>
    <tr><td>[0-9]+</td><td>one or more digits</td></tr>
    <tr><td>[^ \t\n]</td><td>exactly one non-whitespace character</td></tr>
    <tr><td>(foo)|(bar)</td><td>either 'foo' or 'bar'</td></tr>
    <tr><td>\.html$</td><td>any string ending in '.html'</td></tr>
    <tr><td>^\.</td><td>any string starting with a period</td></tr>
    </table>
    <p>Note that \ can be used to quote these characters in which case
    they match themselves, nothing else. Also note that when quoting
    these something in Pike you need two \ because Pike also uses
    this character for quoting.
    <p>
    To make make regexps fast, they are compiled in a similar way that Pike is,
    they can then be used over and over again without needing to be recompiled.
    To give the user full control over the compilations and use of regexp an
    object oriented interface is provided.
    <p>
    You might wonder what regexps are good for, hopefully it should be more clear
    when you read about the following functions:
    
    <hr noshade size=1>
    <anchor name=Regexp.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Regexp.create</tt> - compile regexp
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void create();<br>
    or<br>
    void create(string <i>regexp</i>);<br>
    or<br>
    object(Regexp) Regexp();<br>
    or<br>
    object(Regexp) Regexp(string <I>regexp</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    When create is called, the current regexp bound to this object is
    cleared. If a string is sent to create(), this string will be compiled
    to an internal representation of the regexp and bound to this object
    for later calls to match or split. Calling create() without an
    argument can be used to free up a little memory after the regexp has
    been used.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link> and <link to=Yp.regexp.match>Yp.regexp-&gt;match</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Regexp.match>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Regexp.match</tt> - match a regexp
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int match(string <i>s</i>)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return 1 if <i>s</i> matches the regexp bound to the object regexp,
    zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Regexp.create>Regexp-&gt;create</link> and <link to=Yp.regexp.split>regexp-&gt;split</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=split>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Regexp.split</tt> - split a string according to a pattern
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string) split(string <i>s</i>)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Works as regexp-&gt;match, but returns an array of the strings that
    matched the sub-regexps. Sub-regexps are those contained in ( ) in
    the regexp. Sub-regexps that were not matched will contain zero.
    If the total regexp didn't match, zero is returned.
    <p>
    <dt><encaps>BUGS</encaps><dd>
    You can only have 40 sub-regexps.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Regexp.create>Regexp-&gt;create</link> and <link to=Regexp.match>Regexp-&gt;match</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    
    <!-- FIX ME: write and document Regexp-&gt;explode -->
    
    </section>
    </anchor>
    
    <anchor name=Gmp>
    <section title="Gmp">
    Gmp is short for GNU Multi-Precision library. It is a set of routines that
    can manipulate very large numbers. Although much slower than regular integers
    they are very useful when you need to handle extremely large numbers.
    Billions and billions as Mr Attenborough would have said..
    <p>
    The Gmp library can handle large integers, floats and rational numbers, but
    currently Pike only has support for large integers. The others will be added
    later or when demand arises. Large integers are implemented as objects cloned
    from Gmp.Mpz. 
    
    <anchor name=Gmp.mpz>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz</tt> - bignum program
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Gmp.mpz is a builtin program written in C. It implements
    large, very large integers. In fact, the only limitation on these
    integers is the available memory.
    <p>The mpz object implements all the normal integer operations.
    (except xor) There are also some extra operators:
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This module is only available if libgmp.a was available and
    found when Pike was compiled.
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;create</tt> - initialize a bignum
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object Mpz();<br>
    or<br>
    object Mpz(int|object|float <I>i</I>);<br>
    or<br>
    object Mpz(string <I>digits</I>, int <I>base</I>);<br>
    <br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    When cloning an mpz it is by default initialized to zero. However,
    you can give a second argument to clone to initialize the new
    object to that value. The argument can be an int, float another
    mpz object, or a string containing an ascii number. You can also
    give the number in the string in another base by specifying the
    base as a second argument. Valid bases are 2-36 and 256.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link>
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.powm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;powm</tt> - raise and modulo
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object powm(int|string|float|object <I>a</I>,int|string|float|object <I>b</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns ( mpz ** <i>a</i> ) % <i>b</i>.
    For example, <tt> Mpz(2)-&gt;powm(10,42); </tt> would return <tt>16</tt>
    since 2 to the power of 10 is 1024 and 1024 modulo 42 is 16.
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.sqrt>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;sqrt</tt> - square root
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object sqrt();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the truncated integer part of the square
    root of the value of mpz. 
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.probably_prime_p>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;probably_prime_p</tt> - is this number a prime?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int probably_prime_p();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns 1 if mpz is a prime, and 0 most of the time
    if it is not.
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.gcd>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;gcd</tt> - greatest common divisor
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object gcd(object|int|float|string arg)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the greatest common divisor for <i>arg</i> and mpz.
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.cast>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;cast</tt> - cast to other type
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object cast( "string" | "int" | "float" );<br>
    or<br>
    (string) mpz<br>
    or<br>
    (int) mpz<br>
    or<br>
    (float) mpz<br>
    </tt>
    <br>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function converts an mpz to a string, int or float. This is
    necessary when you want to view, store or use the result of an mpz
    calculation.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=cast>cast</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.digits>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;digits</tt> - convert mpz to a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string digits();<br>
    or<br>
    string digits(int|void <I>base</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function converts an mpz to a string. If a base is given the
    number will be represented in that base. Valid bases are 2-36 and
    256. The default base is 10.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gmp.mpz.cast>Gmp.mpz-&gt;cast</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gmp.mpz.size>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gmp.mpz-&gt;size</tt> - how long is a number
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string size();<br>
    or<br>
    string size(int|void <I>base</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns how long the mpz would be represented in the
    specified base. The default base is 2.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gmp.mpz.digits>Gmp.mpz-&gt;digits</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    </section>
    </anchor>
    
    <anchor name=Gdbm>
    <section title="Gdbm">
    Gdbm is short for GNU Data Base Manager. It provides a simple data base
    similar to a file system. The functionality is similar to a mapping,
    but the data is located on disk, not in memory. Each gdbm database
    is one file which contains a key-pair values, both keys and values
    have to be strings. All keys are always unique, just as with a mapping.
    <p>
    <!-- FIX ME, implement `[], `[]=, _sizeof, _indices and _values -->
    
    This is the an interface to the gdbm library. This module might or
    might not be available in your Pike depending on whether the gdbm library
    was available on your system when Pike was compiled.
    
    <hr noshade size=1>
    <anchor name=Gdbm.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.create</tt> - open database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int create();<br>
    or<br>
    int create(string <I>file</I>);<br>
    or<br>
    int create(string <I>file</I>, string <I>mode</I>);<br>
    or<br>
    object(Gdbm) Gdbm();
    or<br>
    object(Gdbm) Gdbm(string <i>file</i>);
    or<br>
    object(Gdbm) Gdbm(string <i>file</i>, string <i>mode</i>);
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Without arguments, this function does nothing. With one argument it
    opens the given file as a gdbm database, if this fails for some
    reason, an error will be generated. If a second argument is present,
    it specifies how to open the database using one or more of the follow
    flags in a string:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> r </td><td> open database for reading </td></tr>
    <tr valign=top><td> w </td><td> open database for writing </td></tr>
    <tr valign=top><td> c </td><td> create database if it does not exist </td></tr>
    <tr valign=top><td> t </td><td> overwrite existing database </td></tr>
    <tr valign=top><td> f </td><td> fast mode </td></tr>
    </table>
    
    <p>The fast mode prevents the database from synchronizing each change
    in the database immediately. This is dangerous because the database
    can be left in an unusable state if Pike is terminated abnormally.
    <p>The default mode is "rwc".
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.close>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.close</tt> - close database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void close();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This closes the database.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.store>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.store</tt> - store a value in the database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int Gdbm.store(string <I>key</I>, string <I>data</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Associate the contents of <i>data</i> with the key <i>key</i>. If the key <i>key</i>
    already exists in the database the data for that key will be replaced.
    If it does not exist it will be added. An error will be generated if
    the database was not open for writing.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.fetch>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.fetch</tt> - fetch a value from the database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string fetch(string <I>key</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the data associated with the key <i>key</i> in the database.
    If there was no such key in the database, zero is returned.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.delete>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.delete</tt> - delete a value from the database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int delete(string <I>key</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Remove a key from the database. Note that no error will be generated
    if the key does not exist.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.firstkey>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.firstkey</tt> - get first key in database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string firstkey();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the first key in the database, this can be any key in the
    database.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.nextkey>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>nextkey</tt> - get next key in database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string nextkey(string <I>key</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This returns the key in database that follows the key <i>key</i>.
    This is of course used to iterate over all keys in the database.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>/* Write the contents of the database */<br>
    for(key=gdbm-&gt;firstkey(); k; k=gdbm-&gt;nextkey(k))<br>
    <dl><dt><dd>write(k+":"+gdbm-&gt;fetch(k)+"\n");<br>
    </dl>
    </tt>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.reorganize>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gdbm.reorganize</tt> - reorganize database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int reorganize();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Deletions and insertions into the database can cause fragmentation
    which will make the database bigger. This routine reorganizes the
    contents to get rid of fragmentation. Note however that this function
    can take a LOT of time to run.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gdbm.sync>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sync</tt> - synchronize database
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void sync();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    When opening the database with the 'f' flag writings to the database
    can be cached in memory for a long time. Calling sync will write
    all such caches to disk and not return until everything is stored
    on the disk.
    <p>
    </dl>
    </anchor>
    </section>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Getopt>
    <section title="Getopt">
    Getopt is a group of function which can be used to find command line options.
    Command line options come in two flavors: long and short. The short ones
    consists of a dash followed by a character (<tt>-t</tt>), the long ones
    consist of two dashes followed by a string of text (<tt>--test</tt>).
    The short options can also be combined, which means that you can write
    <tt>-tda</tt> instead of <tt>-t -d -a</tt>. Options can also require
    arguments, in which case they cannot be combined. To write an option
    with an argument you write <tt>-t <i>argument</i></tt> or <tt>-t<i>argument</i></tt> or <tt>--test=<i>argument</i></tt>.
    
    <hr noshade size=1>
    <anchor name=Getopt.find_option>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Getopt.find_option</tt> - find command line options
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt><p>mixed find_option(array(string) <i>argv</i>,<br>
    <dl><dt><dd>string <i>shortform</i>,<br>
    void|string <i>longform</i>,<br>
    void|string <i>envvar</i>,<br>
    void|mixed <i>def</i>,<br>
    void|int <i>throw_errors</i>);<br>
    </dl></tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This is a generic function to parse command line options of the
    type '-f', '--foo' or '--foo=bar'. The first argument should be
    the array of strings that is sent as second argument to your
    main() function, the second is a string with the short form of
    your option. The short form must be only one character long.
    The 'longform' is an alternative and maybe more readable way to
    give the same option. If you give "foo" as longform your program
    will accept --foo as argument. The envvar argument specifies what
    environment variable can be used to specify the same option. The
    envvar option exists to make it easier to customize program usage.
    The 'def' has two functions: It specifies that the option takes an
    argument and it tells find_option what to return if the option is
    not present. If 'def' is given and the option does not have an
    argument find_option will print an error message and exit the program.
    <p>Also, as an extra bonus: shortform, longform and envvar can all be
    arrays, in which case either of the options in the array will be
    accpted.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    find_option modifies argv.<br>
    This function reads options even if they are written after the first
    non-option on the line.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    This program tests two different options. One is called <tt>-f</tt> or
    <tt>-foo</tt> and the other is called <tt>-b</tt> or <tt>--bar</tt> and
    can also be given by using the <tt>BAR_OPTION</tt> environment variable.
    
    <example language=pike>
    int main(int argc, array(string) argv)<br>
    {
      if(find_option(argv,"f","foo"))
        werror("The FOO option was given.\n");
    
      werror("The BAR option got the "+
        find_option(argv,"b","bar","BAR_OPTION","default")+
        " argument.\n");
    }
    </example>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Getopt.get_args>Getopt.get_args</link>
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Getopt.find_all_options>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Getopt.find_all_options</tt> - find command line options
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt><p>array find_all_options(array(string) <i>argv</i>, array <i>option</i>, int|void <i>posix_me_harder</i>, int|void <i>throw_errors</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function does the job of several calls to <tt>find_option</tt>.
    The main advantage of this is that it allows it to handle the
    POSIX_ME_HARDER environment variable better. When the either
    the argument <i>posix_me_harder</i> or the environment variable
    POSIX_ME_HARDER is true, no arguments will be parsed after the first
    non-option on the command line.
    <p>
    Each element in the array <i>options</i> should be an array on the
    following form:
    <p>
    <dl>
    <dt>({
    <dd>string <i>name</i>,
    <dd>int <i>type</i>,
    <dd>string|array(string) <i>aliases</i>,
    <dd>void|string|array(string) <i>env_var</i>,
    <dd>void|mixed <i>default</i>
    <dt>})
    </dl>
    Only the first three elements has to be included.
    <dl>
    <dt> <i>name</i>
    <dd> Name is a tag used to identify the option in the output.
    <dt> <i>type</i>
    <dd> Type is one of Getopt.HAS_ARG, Getopt.NO_ARG and Getopt.MAY_HAVE_ARG
         and it affects how the error handling and parsing works.
         You should use HAS_ARG for options that require a path, a number or
         similar. NO_ARG should be used for options that do not need an
         argument, such as <tt>--version</tt>. MAY_HAVE_ARG should be used
         for options that may or may not need an argument.
    <dt> <i>aliases</i>
    <dd> This  is a string or an array of string of options that will be looked for.
         Short and long options can be mixed, and short options can be
         combined into one string. Note that you must include the dashes
         in <i>aliases</i> so find_all_options can distinguish between
          long and short options. Example: <tt>({"-tT","--test"})</tt>
          This would make find_all_options look for <tt>-t</tt>,
          <tt>-T</tt> and <tt>--test</tt>.
    <dt> <i>env_var</i>
    <dd> This is a string or an array of strings containing names of
         environment variables that can be used instead of the
         command line option.
    <dt> <i>default</i>
    <dd> This is the default value the option will have in the output
         from this function. Options without defaults will be omitted
         from the output if they are not found in argv.
    </dl>
    The good news is that the output from this function is a lot simpler.
    Find_all_options returns an array where each element is an array on
    this form:
    <dl>
    <dt>({
    <dd>string <i>name</i>,
    <dd>mixed <i>value</i>
    <dt>})
    </dl>
    The <i>name</i> is the identifier from the input and <i>value</i> is the
    value given to it from the argument, environment variable or <i>default</i>.
    If no default is given, <i>value</i> will be 1.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    find_all_options modifies argv.<br>
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    First let's take a look at input and output:
    <pre>
    &gt; Getopt.find_all_options(({"test","-dd"}),
    &gt;&gt;  ({ ({ "debug", Getopt.NO_ARG, ({"-d","--debug"}), "DEBUG", 1}) }));
    Result: ({
      ({ "debug",  1 }),
      ({ "debug",  1 })
    })
    </pre>
    <p>
    This is what it would look like in real code:
    <example language=pike>
    import Getopt;
    
    int debug=0;
    
    int main(int argc, array(string) argv
    {
      foreach(find_all_options(argv, ({
        ({ "debug", MAY_HAVE_ARG, ({"-d","--debug"}), "DEBUG", 1}),
        ({ "version", NO_ARG, ({"-v","--version" }) })  })),
        mixed option)
      {
        switch(option[0])
        {
          case "debug": debug+=option[1]; break;
          case "version":
            write("Test program version 1.0\n");
            exit(1);
        }
      }
    
      argv=Getopt.get_args(argv);
    }
    </example>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Getopt.get_args>Getopt.get_args</link>
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Getopt.get_args>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Getopt.get_args</tt> - get the non-option arguments
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string) get_args(array(string) <I>argv</I>,void|int <i>throw_errors</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the remaining command line arguments after
    you have run find_options to find all the options in the
    argument list. If there are any options left not handled by
    find_options an error message will be written and the program will
    exit. Otherwise a new 'argv' array without the parsed options is
    returned.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>int main(int argc, array(string) argv)<br>
    {<br>
    <dl><dt><dd>if(find_option(argv,"f","foo"))<br>
    <dl><dt><dd>werror("The FOO option was given.\n");<br>
    </dl></dl>
    <p><dl><dt><dd>argv=get_args(argv);<br>
    werror("The arguments are: "+(argv*" ")+".\n");<br>
    </dl>}<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Getopt.find_option>Getopt.find_option</link>
    <p>
    </dl>
    
    </anchor>
    </section>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Gz>
    <section title="Gz">
    The Gz module contains functions to compress and uncompress strings using
    the same algorithm as the program <tt>gzip</tt>. Packing can be done in
    streaming mode or all at once. Note that this module is only available if
    the gzip library was available when Pike was compiled. The Gz module consists
    of two classes; Gz.deflate and Gz.inflate. Gz.deflate is used to pack data
    and Gz.inflate is used to unpack data. (Think "inflatable boat")
    Note that these functions use the same <i>algorithm</i> as gzip, they do
    not use the exact same format however, so you cannot directly unzip gzipped
    files with these routines. Support for this will be added in the future.
    <p>
    <anchor name=Gz.deflate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.deflate</tt> - string packer
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Gz.inflate is a builtin program written in C. It interfaces the
    packing routines in the libz library.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This program is only available if libz was available and found when
    Pike was compiled.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gz.inflate>Gz.inflate</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gz.deflate.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.deflate-&gt;create</tt> - initialize packer
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void create(int X)<br>
    or<br>
    object(Gz.deflate) Gz.deflate(int X)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is called when a new Gz.deflate is created.
    If given, X should be a number from 0 to 9 indicating the packing /
    CPU ratio. Zero means no packing, 2-3 is considered 'fast', 6 is
    default and higher is considered 'slow' but gives better packing.
    <p>This function can also be used to re-initialize a Gz.deflate object
    so it can be re-used.
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gz.deflate.deflate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.deflate-&gt;deflate</tt> - pack data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string deflate(string <I>data</I>, int <I>flush</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function performs gzip style compression on a string and
    returns the packed data. Streaming can be done by calling this
    function several times and concatenating the returned data.
    The optional 'flush' argument should be one f the following:
    <p>
    <table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> Gz.NO_FLUSH       </td><td> Only data that doesn't fit in the internal buffers is returned. </td></tr>
    <tr valign=top><td> Gz.PARTIAL_FLUSH </td><td> All input is packed and returned. </td></tr>
    <tr valign=top><td> Gz.SYNC_FLUSH    </td><td> All input is packed and returned. </td></tr>
    <tr valign=top><td> Gz.FINISH        </td><td> All input is packed and an 'end of data' marker is appended. </td></tr>
    </table>
    
    <p>Using flushing will degrade packing. Normally NO_FLUSH should be
    used until the end of the data when FINISH should be used. For
    interactive data PARTIAL_FLUSH should be used.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gz.inflate.inflate>Gz.inflate-&gt;inflate</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gz.inflate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.inflate</tt> - string unpacker
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Gz.inflate is a builtin program written in C. It interfaces the
    packing routines in the libz library.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This program is only available if libz was available and found when
    Pike was compiled.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gz.deflate>Gz.deflate</link>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gz.inflate.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.inflate-&gt;create</tt> - initialize unpacker
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void create()<br>
    or<br>
    object(Gz.inflate) Gz.inflate()<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is called when a new Gz.inflate is created.
    It can also be called after the object has been used to re-initialize
    it.
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=Gz.inflate.inflate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Gz.inflate-&gt;inflate</tt> - unpack data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string inflate(string <I>data</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function performs gzip style decompression. It can inflate
    a whole file at once or in blocks.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>import Stdio;<br>
    // whole file<br>
    write(Gz.inflate()-&gt;inflate(stdin-&gt;read());<br>
    
    <p>// streaming (blocks)<br>
    function inflate=Gz.inflate()-&gt;inflate;<br>
    while(string s=stdin-&gt;read(8192))<br>
    <dl><dt><dd>write(inflate(s));<br>
    </dl></tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Gz.deflate.deflate>Gz.deflate-&gt;deflate</link>
    <p>
    </dl>
    
    </anchor>
    </section>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Yp>
    <section title="Yp">
    This module is an interface to the Yellow Pages functions. Yp is also
    known as NIS (Network Information System) and is most commonly used to
    distribute passwords and similar information within a network.
    
    <hr noshade size=1>
    <anchor name=Yp.default_yp_domain>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.default_yp_domain</tt> - get the default Yp domain
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string default_yp_domain()<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the default yp-domain.
    <p>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    
    <anchor name=Yp.YpDomain>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain</tt> - class representing an Yp domain
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object(Yp.YpDomain) Yp.YpDomain(string|void <i>domain</i>);
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This creates a new YpDomain object.
    <p>
    If there is no YP server available for the domain, this
    function call will block until there is one. If no server appears
    in about ten minutes or so, an error will be returned. The timeout
    is not configurable from the C interface to Yp either.
    <p>
    If no domain is given, the default domain will be used. (As returned
    by Yp.default_yp_domain)
    </dl>
    </anchor>
    
    <hr noshade size=1>
    <anchor name=Yp.YpDomain.bind>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain-&gt;bind</tt> - bind this object to another domain
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void bind(string|void <i>domain</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Re-bind the object to another (or the same) domain. If no domain is given,
    the default domain will be used.
    <p>
    </dl>
    </anchor>
    
    <hr noshade size=1>
    <anchor name=Yp.YpDomain.match>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.Ypdomain-&gt;match</tt> - match a key in a map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string match(string <i>map</i>, string <i>key</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
       If 'map' does not exist, an error will be generated. 
       Otherwise the string matching the key will be returned.
       If there is no such key in the map, 0 will be returned.
    <p>
       <i>arguments</i> is the map Yp-map to search in. This must be a full map
       name, for example, you should use <tt>passwd.byname</tt> instead of
       just <tt>passwd</tt>. <i>key</i> is the key to search for. The key
       must match exactly, no pattern matching of any kind is done.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <example language=pike>
    object dom = Yp.YpDomain();
    write(dom->match("passwd.byname", "root"));
    </example>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Yp.YpDomain.all>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain-&gt;all</tt> - return the whole map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:string) all(string <i>map</i>)</tt>
    
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
      Returns the whole map as a mapping. <i>map</i> is the YP-map to search in.
      This must be the full map name, you have to use <tt>passwd.byname</tt>
      instead of just <tt>passwd</tt>.
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Yp.YpDomain.map>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain-&gt;map</tt> - call a function for each entry in an Yp map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void map(string <i>map</i>, function(string,string:void) <i>over</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
        For each entry in 'map', call the function(s) specified by 'over'.
        Over will get two arguments, the first being the key, and the
        second the value. <i>map</i> is the YP-map to search in.
        This must be the full map name, as an
        example, passwd.byname instead of just passwd.
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Yp.YpDomain.server>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain-&gt;server</tt> - find an Yp server
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string server(string <i>map</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
      Returns the hostname of the server serving the map <i>map</i>. <i>map</i>
      is the YP-map to search in. This must be the full map name, as an
        example, passwd.byname instead of just passwd.
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Yp.YpDomain.order>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpDomain-&gt;order</tt> - get the 'order' for specified map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int order(string <i>map</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
      Returns the 'order' number for the map <i>map</i>. This is usually a
      time_t (see the global function time()). When the map is changed, this number
      will change as well. <i>map</i> is
        the YP-map to search in. This must be the full map name, as an
        example, passwd.byname instead of just passwd.
    </dl>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Yp.YpMap>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap</tt> - class representing one Yp map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object(Yp.YpMap) Yp.Ypmap(string <i>map</i>, string|void <i>domain</i>)</tt>
    <dt><encaps>DESCRIPTION</encaps><dd>
      This creates a new YpMap object. 
    <p>
      If there is no YP server available for the domain, this
      function call will block until there is one. If no server appears
      in about ten minutes or so, an error will be returned. The timeout
      is not configurable from the C-yp interface either. <i>map</i> is
        the YP-map to bind to. This must be the full map name, as an
        example, passwd.byname instead of just passwd.
      If no domain is specified, the
      default domain will be used. This is usually best.
    <p>
    </dl>
    </anchor>
    <hr noshade size=1>
    <anchor name=Yp.YpMap.match>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap-&gt;match</tt> - find key in map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string match(string <i>key</i>)</tt><br>
    or<br>
    <tt>string <i>Yp.YpMap</i>[string <i>key</i>]</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
      Search for the key <i>key</i>. If there is no <i>key</i> in the map, 0
      will be returned, otherwise the string matching the key will
      be returned.
      <i>key</i> must match exactly, no pattern
       matching of any kind is done.
    </dl>
    </anchor>
    <hr noshade size=1>
    
    
    <anchor name=Yp.YpMap.all>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap-&gt;all</tt> - return the whole map as a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:string) all();</tt><br>
    or<br>
    <tt>(mapping) <i>Yp.YpMap</i></tt><br>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
        Returns the whole map as a mapping.
    </dl>
    </anchor>
    <hr noshade size=1>
    <p>
    <anchor name=Yp.YpMap.map>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap-&gt;map</tt> - call a function for each entry in the map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void map(function(string,string:void) <i>over</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
        For each entry in the map, call the function(s) specified by 'over'.
        The function will be called like 'void over(string key, string value)'
    </dl>
    </anchor>
    <hr noshade size=1>
    
    
    <anchor name=Yp.YpMap.server>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap-&gt;server</tt> - find what server servers this map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string server()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
        Returns the hostname of the server serving this map.
    </dl>
    </anchor>
    <hr noshade size=1>
    <p>
    <anchor name=Yp.YpMap.order>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap-&gt;order()</tt> - find the 'order' of this map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int order()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
        Returns the 'order' number for this map. This is usually a
        time_t (see the global function time())
    </dl>
    </anchor>
    <hr noshade size=1>
    <p>
    <anchor name=Yp.YpMap._sizeof>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap._sizeof</tt> - return the number of entries in the map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int sizeof(<i>Yp.YpMap</i>)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
       Returns the number of entries in the map. This is equivalent to
    <tt>sizeof((mapping)map);</tt>
    </dl>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=Yp.YpMap._indices>
    <anchor name=Yp.YpMap._values>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Yp.YpMap._indices</tt> - return the indices from the map<br>
    <tt>Yp.YpMap._values</tt> - return the values from the map
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    array(string) indices(<i>Yp.YpMap</i>)<br>
    array(string) values(<i>Yp.Ypmap</i>)
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
      Returns the indices of the map. If indices is called first, values must
      be called immediately after. If values is called first, it is the
      other way around.
    </dl>
    </anchor>
    </anchor>
    
    <p>
    <hr noshade size=1>
    Here is an example program using the Yp module, it lists users and
    their GECOS field from the Yp map "passwd.byname" if your system uses
    Yp.
    
    <example language=pike>
    	import Yp;
    
    	void print_entry(string key, string val)
    	{
    	  val = (val/":")[4];
    	  if(strlen(val))
    	  {
    	    string q = ".......... ";
    	    werror(key+q[strlen(key)..]+val+"\n");
    	  }
    	}
      
    	void main(int argc, array(string) argv)
    	{
    	  object (YpMap) o = YpMap("passwd.byname");
    
    	  werror("server.... "+ o-&gt;server() + "\n"
    	  	 "age....... "+ (-o-&gt;order()+time()) + "\n"
    	  	 "per....... "+ o["per"] + "\n"
    	  	 "size...... "+ sizeof(o) + "\n");
      
    	  o-&gt;map(print_entry); // Print username/GECOS pairs
    	}
    </example>
    </section>
    </anchor>
    <hr noshade size=1>
    
    <anchor name=MIME>
    <section title="MIME">
    
    <a href="http://www.roxen.com/rfc/rfc1521.txt">RFC1521</a>, the
    <b>Multipurpose Internet Mail Extensions</b> memo, defines a
    structure is the base for all messages read and written by modern mail
    and news programs.  It is also partly the base for the HTTP protocol.
    Just like <a href="http://www.roxen.com/rfc/rfc822.txt">RFC822</a>,
    MIME declares that a message should consist of two entities,
    the headers and the body.  In addition, the following properties are given
    to these two entities:
    
    <dl>
    <dt>Headers
    <dd><ul>
    <li>A MIME-Version header must be present to signal MIME compatibility
    <li>A Content-Type header should be present to describe the nature of the
    data in the message body.  Seven major types are defined, and an extensive
    number of subtypes are available.  The header can also contain attributes
    specific to the type and subtype.
    <li>A Content-Transfer-Encoding may be present to notify that the data of
    the body is encoded in some particular encoding.
    </ul>
    <dt>Body
    <dd><ul>
    <li>Raw data to be interpreted according to the Content-Type header
    <li>Can be encoded using one of several Content-Transfer-Encodings to
    allow transport over non 8bit clean channels
    </ul>
    </dl>
    
    The MIME module can extract and analyze these two entities from a stream
    of bytes.  It can also recreate such a stream from these entities.
    To encapsulate the headers and body entities, the class MIME.Message is
    used.  An object of this class holds all the headers as a mapping from
    string to string, and it is possible to obtain the body data in either
    raw or encoded form as a string.  Common attributes such as message type and
    text char set are also extracted into separate variables for easy access.
    
    <p>
    The Message class does not make any interpretation of the body data, unless
    the content type is <tt>multipart</tt>.  A multipart message contains several
    individual messages separated by boundary strings.  The <tt>create</tt>
    method of the Message class will divide a multipart body on these boundaries,
    and then create individual Message objects for each part.  These objects
    will be collected in the array <tt>body_parts</tt> within the original
    Message object.  If any of the new Message objects have a body of type
    multipart, the process is of course repeated recursively.  The following
    figure illustrates a multipart message containing three parts, one of
    which contains plain text, one containing a graphical image, and the third
    containing raw uninterpreted data:
    
    <img src=multipart.gif>
    
    <hr newpage>
    
    <section title="Global functions">
    
    <anchor name=MIME.decode>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.decode</tt> - Remove transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string decode(string <i>data</i>, string <i>encoding</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Extract raw data from an encoded string suitable for transport between systems.
    The encoding can be any of
    <tt><ul>
    <li>7bit
    <li>8bit
    <li>base64
    <li>binary
    <li>quoted-printable
    <li>x-uue
    </ul></tt>
    The encoding string is not case sensitive.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.encode>MIME.encode</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.decode_base64>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.decode_base64</tt> - Decode <tt>base64</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string decode_base64(string <i>encoded_data</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function decodes data encoded using the <tt>base64</tt> transfer encoding.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.encode_base64>MIME.encode_base64</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.decode_qp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.decode_qp</tt> - Decode <tt>quoted-printable</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string decode_qp(string <i>encoded_data</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function decodes data encoded using the <tt>quoted-printable</tt>
    (a.k.a. quoted-unreadable) transfer encoding.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.encode_qp>MIME.encode_qp</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.decode_uue>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.decode_uue</tt> - Decode <tt>x-uue</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string decode_uue(string <i>encoded_data</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function decodes data encoded using the <tt>x-uue</tt> transfer encoding.
    It can also be used to decode generic UUEncoded files.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.encode_uue>MIME.encode_uue</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.decode_word>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.decode_word</tt> - De-scramble RFC1522 encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string) decode_word(string <i>word</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Extracts the textual content and character set from an <i>encoded word</i>
    as specified by RFC1522.  The result is an array where the first element
    is the raw text, and the second element the name of the character set.
    If the input string is not an encoded word, the result is still an array,
    but the char set element will be set to 0.  Note that this function can only
    be applied to individual encoded words.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    &gt; Array.map("=?iso-8859-1?b?S2lscm95?= was =?us-ascii?q?h=65re?="/" ",
                MIME.decode_word);
    Result: ({ /* 3 elements */
        ({ /* 2 elements */
            "Kilroy",
            "iso-8859-1"
        }),
        ({ /* 2 elements */
            "was",
            0
        }),
        ({ /* 2 elements */
            "here",
            "us-ascii"
        })
    })
    </pre>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.encode_word>MIME.encode_word</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.encode>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.encode</tt> - Apply transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode(string <i>data</i>, string <i>encoding</i>,
     void|string <i>filename</i>,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void|int <i>no_linebreaks</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Encode raw data into something suitable for transport to other systems.
    The encoding can be any of
    <tt><ul>
    <li>7bit
    <li>8bit
    <li>base64
    <li>binary
    <li>quoted-printable
    <li>x-uue
    </ul></tt>
    The encoding string is not case sensitive.  For the <tt>x-uue</tt> encoding,
    an optional filename string may be supplied.  If a nonzero value is passed
    as <i>no_linebreaks</i>, the result string will not contain any linebreaks
    (base64 and quoted-printable only).
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.decode>MIME.decode</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.encode_base64>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.encode_base64</tt> - Encode string using <tt>base64</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode_base64(string <i>data</i>, void|int <i>no_linebreaks</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function encodes data using the <tt>base64</tt> transfer encoding.
    If a nonzero value is passed as <i>no_linebreaks</i>, the result string
    will not contain any linebreaks.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.decode_base64>MIME.decode_base64</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.encode_qp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.encode_qp</tt> - Encode string using <tt>quoted-printable</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode_qp(string <i>data</i>, void|int <i>no_linebreaks</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function encodes data using the <tt>quoted-printable</tt>
    (a.k.a. quoted-unreadable) transfer encoding.  If a nonzero value is passed as <i>no_linebreaks</i>, the result string will not contain any linebreaks.
    <strong>Please do not use this function.  QP is evil, and there's no
    excuse for using it.</strong>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.decode_qp>MIME.decode_qp</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.encode_uue>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.encode_uue</tt> - Encode string using <tt>x-uue</tt> transfer encoding
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode_uue(string <i>encoded_data</i>,
     void|string <i>filename</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function encodes data using the <tt>x-uue</tt> transfer encoding.
    The optional argument filename specifies an advisory filename to include
    in the encoded data, for extraction purposes.
    This function can also be used to produce generic UUEncoded files.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.decode_uue>MIME.decode_uue</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.encode_word>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.encode_word</tt> - Encode word according to RFC1522
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode_word(array(string) <i>word</i>, string <i>encoding</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Create an <i>encoded word</i> as specified in RFC1522 from an array containing
    a raw text string and a char set name.  The text will be transfer encoded
    according to the encoding argument, which can be either <tt>"base64"</tt> or
    <tt>"quoted-printable"</tt> (or either <tt>"b"</tt> or <tt>"q"</tt> for
    short).  If either the second element of the array (the char set name), or
    the encoding argument is 0, the raw text is returned as is.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    > MIME.encode_word( ({ "Quetzalcoatl", "iso-8859-1" }), "base64" );
    Result: =?iso-8859-1?b?UXVldHphbGNvYXRs?=
    > MIME.encode_word( ({ "Foo", 0 }), "base64" );
    Result: Foo
    </pre>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.decode_word>MIME.decode_word</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.generate_boundary>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.generate_boundary</tt> - Create a suitable boundary string for multiparts
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string generate_boundary();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function will create a string that can be used as a separator string
    for multipart messages.  The generated string is guaranteed not to appear
    in <tt>base64</tt>, <tt>quoted-printable</tt>, or <tt>x-uue</tt> encoded data.
    It is also unlikely to appear in normal text.  This function is used by
    the cast method of the <tt>Message</tt> class if no boundary string is
    specified.
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.guess_subtype>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.guess_subtype</tt> - Provide a reasonable default for the subtype field
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string guess_subtype(string <i>type</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Some pre-RFC1521 mailers provide only a type and no subtype in the
    Content-Type header field.  This function can be used to obtain a
    reasonable default subtype given type type of a message.  Currently,
    the function uses the following guesses:
    <table border=1>
    <tr><th>type</th><th>subtype</th></tr>
    <tr><td>text</td><td>plain</td></tr>
    <tr><td>message</td><td>rfc822</td></tr>
    <tr><td>multipart</td><td>mixed</td></tr>
    </table>
    <p>
    </dl>
    </anchor>
    
    
    <hr newpage>
    <anchor name=MIME.quote>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.quote</tt> - Create an RFC822 header field from lexical elements
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string quote(array(string|int) <i>lexical_elements</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the inverse of the <link to=tokenize>tokenize</link> function.
    A header field value is constructed from a sequence of lexical elements.
    Characters (<tt>int</tt>s) are taken to be special-characters, whereas
    strings are encoded as atoms or quoted-strings, depending on whether
    they contain any special characters.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    > MIME.quote( ({ "attachment", ';', "filename", '=', "/usr/dict/words" }) );
    Result: attachment;filename="/usr/dict/words"
    </pre>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    There is no way to construct a domain-literal using this function.
    Neither can it be used to produce comments.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.tokenize>MIME.tokenize</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.reconstruct_partial>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.reconstruct_partial</tt> - Join a fragmented message to its original form
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int|object reconstruct_partial(array(object) <i>collection</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function will attempt to reassemble a fragmented message from its
    parts.  The array <i>collection</i> should contain <tt>MIME.Message</tt>
    objects forming a complete set of parts for a single fragmented message.
    The order of the messages in this array is not important, but every part
    must exist at least once.
    <p>
    Should the function succeed in reconstructing the original message, a
    new <tt>MIME.Message</tt> object is returned.  Note that this message may
    in turn be a part of another, larger, fragmented message.
    If the function fails to reconstruct an original message, it returns an
    integer indicating the reason for its failure:
    <ul>
    <li>If an empty <i>collection</i> is passed in, or one that contains messages
    which are not of type <tt>message/partial</tt>, or parts of different
    fragmented messages, the function returns 0.
    <li>If more fragments are needed to reconstruct the entire message, the
    number of additional messages needed is returned.
    <li>If more fragments are needed, but the function can't tell exactly how
    many, -1 is returned.
    </ul>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.is_partial>MIME.Message-&gt;is_partial</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.tokenize>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.tokenize</tt> - Separate an RFC822 header field into lexical elements
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string|int) tokenize(string <i>header</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    A structured header field, as specified by RFC822, is constructed from
    a sequence of lexical elements.  These are:
    <ul>
    <li>individual special characters
    <li>quoted-strings
    <li>domain-literals
    <li>comments
    <li>atoms
    </ul>
    This function will analyze a string containing the header value, and produce
    an array containing the lexical elements.  Individual special characters
    will be returned as characters (i.e. <tt>int</tt>s).  Quoted-strings,
    domain-literals and atoms will be decoded and returned as strings.
    Comments are not returned in the array at all.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    > MIME.tokenize("multipart/mixed; boundary=\"foo/bar\" (Kilroy was here)");
    Result: ({ /* 7 elements */
        "multipart",
        47,
        "mixed",
        59,
        "boundary",
        61,
        "foo/bar"
    })
    </pre>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    As domain-literals are returned as strings, there is no way to tell the
    domain-literal <tt>[127.0.0.1]</tt> from the quoted-string
    <tt>"[127.0.0.1]"</tt>.  Hopefully this won't cause any problems.
    Domain-literals are used seldom, if at all, anyway...
    <p>
    The set of special-characters is the one specified in RFC1521 (i.e. <tt>"&lt;",
    "&gt;", "@", ",", ";", ":", "\", "/", "?", "="</tt>), and not the one
    specified in RFC822.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.quote>MIME.quote</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    </section>
    
    <section title="The MIME.Message class">
    This class is used to hold a decoded MIME message.
    
    <section title="Public fields">
    
    <hr newpage>
    <anchor name=MIME.Message.body_parts>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;body_parts</tt> - Multipart sub-messages
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(object) msg-&gt;body_parts;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    If the message is of type <tt>multipart</tt>, this is an array containing one
    Message object for each part of the message.  If the message is not a
    multipart, this field is <tt>0</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.type>MIME.Message-&gt;type</link>,
    <link to=MIME.Message.boundary>MIME.Message-&gt;boundary</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.boundary>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.message-&gt;boundary</tt> - Boundary string for multipart messages
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg->boundary;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    For multipart messages, this <tt>Content-Type</tt> parameter gives a
    delimiter string for separating the individual messages.  As multiparts
    are handled internally by the module, you should not need to access this
    field.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setboundary>MIME.Message-&gt;setboundary</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.charset>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;charset</tt> - Character encoding for text bodies
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg-&gt;charset;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    One of the possible parameters of the <tt>Content-Type</tt> header is the
    charset attribute.  It determines the character encoding used in bodies of
    type text.  If there is no <tt>Content-Type</tt> header, the value of this
    field is <tt>"us-ascii"</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.type>MIME.Message-&gt;type</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.disposition>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;disposition</tt> - Multipart subpart disposition
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg-&gt;disposition;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The first part of the <tt>Content-Disposition</tt> header, hinting on how
    this part of a multipart message should be presented in an interactive
    application.  If there is no <tt>Content-Disposition</tt> header, this
    field is <tt>0</tt>.
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.disp_params>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;disp_params</tt> - Content-Disposition parameters
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:string) msg-&gt;disp_params;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    A mapping containing all the additional parameters to the
    <tt>Content-Disposition</tt> header.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setdisp_param>MIME.Message-&gt;setdisp_param</link>,
    <link to=MIME.Message.get_filename>MIME.Message-&gt;get_filename</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.headers>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;headers</tt> - All header fields of the message
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt> mapping(string:string) msg-&gt;headers;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This mapping contains all the headers of the message.  The key is the
    header name (in lower case) and the value is the header value.
    Although the mapping contains all headers, some particular headers get
    special treatment by the module and should <b>not</b> be accessed through
    this mapping.  These fields are currently:
    <ul>
    <li><tt>content-type</tt>
    <li><tt>content-disposition</tt>
    <li><tt>content-length</tt>
    <li><tt>content-transfer-encoding</tt>
    </ul>
    The contents of these fields can be accessed and/or modified through a set
    of variables and methods available for this purpose.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.type>MIME.Message-&gt;type</link>,
    <link to=MIME.Message.subtype>MIME.Message-&gt;subtype</link>,
    <link to=MIME.Message.charset>MIME.Message-&gt;charset</link>,
    <link to=MIME.Message.boundary>MIME.Message-&gt;boundary</link>,
    <link to=MIME.Message.transfer_encoding>MIME.Message-&gt;transfer_encoding</link>,
    <link to=MIME.Message.params>MIME.Message-&gt;params</link>,
    <link to=MIME.Message.disposition>MIME.Message-&gt;disposition</link>,
    <link to=MIME.Message.disp_params>MIME.Message-&gt;disp_params</link>,
    <link to=MIME.Message.setencoding>MIME.Message-&gt;setencoding</link>,
    <link to=MIME.Message.setparam>MIME.Message-&gt;setparam</link>,
    <link to=MIME.Message.setdisp_param>MIME.Message-&gt;setdisp_param</link>,
    <link to=MIME.Message.setcharset>MIME.Message-&gt;setcharset</link>,
    <link to=MIME.Message.setboundary>MIME.Message-&gt;setboundary</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.params>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;params</tt> - Content-Type parameters
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:string) msg-&gt;params;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    A mapping containing all the additional parameters to the
    <tt>Content-Type</tt> header.  Some of these parameters have fields of their
    own, which should be accessed instead of this mapping wherever applicable.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.charset>MIME.Message-&gt;charset</link>,
    <link to=MIME.Message.boundary>MIME.Message-&gt;boundary</link>,
    <link to=MIME.Message.setparam>MIME.Message-&gt;setparam</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.subtype>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;subtype</tt> - The subtype attribute of the Content-Type header
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg-&gt;subtype;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The <tt>Content-Type</tt> header contains a type, a subtype, and optionally
    some parameters.  This field contains the subtype attribute extracted from the
    header.  If there is no <tt>Content-Type</tt> header, the value of this field
    is <tt>"plain"</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.type>MIME.Message-&gt;type</link>,
    <link to=MIME.Message.params>MIME.Message-&gt;params</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.transfer_encoding>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;transfer_encoding</tt> - Body encoding method
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg-&gt;transfer_encoding;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The contents of the <tt>Content-Transfer-Encoding</tt> header.  If no
    <tt>Content-Transfer-Encoding</tt> header is given, this field is <tt>0</tt>.
    Transfer encoding and decoding is done transparently by the module, so this
    field should be interesting only to applications wishing to do auto conversion
    of certain transfer encodings.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setencoding>MIME.Message-&gt;setencoding</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.type>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;type</tt> - The type attribute of the Content-Type header
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string msg-&gt;type;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The <tt>Content-Type</tt> header contains a type, a subtype, and optionally
    some parameters.  This field contains the type attribute extracted from the
    header.  If there is no <tt>Content-Type</tt> header, the value of this field
    is <tt>"text"</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.subtype>MIME.Message-&gt;subtype</link>,
    <link to=MIME.Message.params>MIME.Message-&gt;params</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    </section>
    
    <section title="Public methods">
    
    <hr newpage>
    <anchor name=MIME.Message.cast>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;cast</tt> - Encode message into byte stream
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string (string )<i>MIME.Message</i>;<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Casting the message object to a string will yield a byte stream suitable
    for transmitting the message over protocols such as ESMTP and NNTP.
    The body will be encoded using the current transfer encoding, and subparts
    of a multipart will be collected recursively.  If the message is a multipart
    and no boundary string has been set, one is generated using
    <link to=generate_boundary>generate_boundary</link>.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    > object msg = MIME.Message( "Hello, world!",
            ([ "MIME-Version" : "1.0",
               "Content-Type":"text/plain",
               "Content-Transfer-Encoding":"base64" ]) );
    Result: object
    > (string )msg;
    Result: Content-Type: text/plain
    Content-Length: 20
    Content-Transfer-Encoding: base64
    MIME-Version: 1.0
     
    SGVsbG8sIHdvcmxkIQ==
    </pre>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.create>MIME.Message-&gt;create</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;create</tt> - Create a Message object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object MIME.Message(void | string <i>message</i>,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    void | mapping(string:string) <i>headers</i>,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    void | array(object) <i>parts</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    There are several ways to call the constructor of the Message class;
    <ul>
    <li>With zero arguments, you will get a dummy message without either headers
    or body.  Not very useful.
    <li>With one argument, the argument is taken to be a byte stream containing
    a message in encoded form.  The constructor will analyze the string and
    extract headers and body.
    <li>With two or three arguments, the first argument is taken to be the raw
    body data, and the second argument a desired set of headers.  The keys of
    this mapping are not case-sensitive.  If the given headers indicate that the
    message should be of type multipart, an array of Message objects constituting
    the subparts should be given as a third argument.
    </ul>
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <pre>
    > object msg = MIME.Message( "Hello, world!",
            ([ "MIME-Version" : "1.0",
               "Content-Type" : "text/plain; charset=iso-8859-1" ]) );
    Result: object
    > msg->charset;
    Result: iso-8859-1
    </pre>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.cast>MIME.Message-&gt;cast</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.getdata>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;getdata</tt> - Obtain raw body data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string getdata();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This method returns the raw data of the message body entity.  The
    <link to=MIME.Message.type>type</link> and <link to=MIME.Message.subtype>subtype</link> attributes
    indicate how this data should be interpreted.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.getencoded>MIME.Message-&gt;getencoded</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.getencoded>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;getencoded</tt> - Obtain encoded body data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string getencoded();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This method returns the data of the message body entity, encoded using the
    current transfer encoding.  You should never have to call this function.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.getdata>MIME.Message-&gt;getdata</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.get_filename>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;get_filename</tt> - Get supplied filename for body data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string get_filename();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This method tries to find a suitable filename should you want to save the
    body data to disk.  It will examine the <tt>filename</tt> attribute of the
    <tt>Content-Disposition</tt> header, and failing that the <tt>name</tt>
    attribute of the <tt>Content-Type</tt> header.  If neither attribute is set,
    the method returns 0.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    An interactive application should always query the user for the actual
    filename to use.  This method may provide a reasonable default though.
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.is_partial>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;is_partial</tt> - Identify <tt>message/partial</tt> message
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string|int) is_partial();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    If this message is a part of a fragmented message (i.e. has a Content-Type
    of <tt>message/partial</tt>), an array with three elements is returned.
    The first element is an identifier string.  This string should be used to
    group this message with the other fragments of the message (which will have
    the same id string).  The second element is the sequence number of this
    fragment.  The first part will have number 1, the next number 2 etc.
    The third element of the array is either the total number of fragments
    that the original message has been split into, or 0 of this information
    was not available.  If this method is called in a message that is not
    a part of a fragmented message, it will return 0.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.reconstruct_partial>MIME.reconstruct_partial</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setboundary>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setboundary</tt> - Set boundary parameter
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setboundary(string <i>boundary</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the <tt>boundary</tt> parameter of the <tt>Content-Type</tt> header.
    This is equivalent of calling
    <tt>msg-&gt;setparam("boundary", <i>boundary</i>)</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setparam>MIME.Message-&gt;setparam</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setcharset>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setcharset</tt> - Set charset parameter
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setcharset(string <i>charset</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Sets the <tt>charset</tt> parameter of the <tt>Content-Type</tt> header.
    This is equivalent of calling
    <tt>msg->setparam("charset", <i>charset</i>)</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setparam>MIME.Message-&gt;setparam</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setdata>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setdata</tt> - Replace body data
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setdata(string <i>data</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Replaces the body entity of the data with a new piece of raw data.
    The new data should comply to the format indicated by the
    <link to=type>type</link> and <link to=subtype>subtype</link> attributes.
    Do not use this method unless you know what you are doing.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.getdata>MIME.Message-&gt;getdata</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setdisp_param>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setdisp_param</tt> - Set Content-Disposition parameters
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setdisp_param(string <i>param</i>, string <i>value</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Set or modify the named parameter of the <tt>Content-Disposition</tt> header.
    A common parameters is e.g. <tt>filename</tt>.  It is not allowed to modify
    the <tt>Content-Disposition</tt> header directly, please use this
    function instead.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setparam>MIME.Message-&gt;setparam</link>,
    <link to=MIME.Message.get_filename>MIME.Message-&gt;get_filename</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setencoding>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setencoding</tt> - Set transfer encoding for message body
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setencoding(string <i>encoding</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Select a new transfer encoding for this message.  The
    <tt>Content-Transfer-Encoding</tt> header will be modified accordingly,
    and subsequent calls to <tt>getencoded</tt> will produce data encoded using
    the new encoding.  See <link to=MIME.Message.encode>encode</link> for a list of valid
    encodings.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.getencoded>MIME.Message-&gt;getencoded</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=MIME.Message.setparam>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>MIME.Message-&gt;setparam</tt> - Set Content-Type parameters
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void setparam(string <i>param</i>, string <i>value</i>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Set or modify the named parameter of the <tt>Content-Type</tt> header.
    Common parameters include <tt>charset</tt> for text messages, and
    <tt>boundary</tt> for multipart messages.  It is not allowed to modify
    the <tt>Content-Type</tt> header directly, please use this function instead.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=MIME.Message.setcharset>MIME.Message-&gt;setcharset</link>,
    <link to=MIME.Message.setboundary>MIME.Message-&gt;setboundary</link>,
    <link to=MIME.Message.setdisp_param>MIME.Message-&gt;setdisp_param</link>
    <p>
    </dl>
    </anchor>
    <hr newpage>
    </section>
    </section>
    </section>
    </anchor>
    
    <anchor name=Simulate>
    <section title="Simulate">
    This module is used to achieve better compatibility with older versions of
    Pike. It can also be used for convenience, but I would advice against it
    since some functions defined here are much slower than using similar
    functions in other modules. The purpose of this section in the manual is
    to make it easier for the reader to understand code that uses the Simulate
    module, not to encourage the use of the Simulate module.
    <p>
    Simulate inherits the Array, Stdio, String and Process modules, so
    importing he Simulate module also imports all identifiers from these
    modules. In addition, these functions are available:
    
    <hr newpage>
    
    <anchor name=Simulate.member_array>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.member_array</tt> - find first occurrence of a value in an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int member_array(mixed <I>item</I>, mixed *<I>arr</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the index of the first occurrence of item in array arr.
    If not found, then -1 is returned. This is the same as
    <tt>search(<i>arr</i>, <i>item</i>)</tt>.
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    <anchor name=Simulate.previous_object>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.previous_object</tt> - return the calling object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object previous_object();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns an object pointer to the object that called current function,
    if any.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=backtrace>backtrace</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    
    <anchor name=Simulate.this_function>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.this_function</tt> - return a function pointer to the current function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>function this_function();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a function pointer to the current function, useful for
    making recursive lambda-functions.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=backtrace>backtrace</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    <anchor name=Simulate.get_function>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.get_function</tt> - fetch a function from an object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>function get_function(object <I>o</I>, string <I>name</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Defined as: return o[name];
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    <anchor name=Simulate.map_regexp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.map_regexp</tt> - filter an array through a regexp
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string) regexp(array(string) <I>arr</I>, string <I>reg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns those strings in arr that matches the regexp in reg.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Regexp>Regexp</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    
    <anchor name=Simulate.PI>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.PI</tt> - pi
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>PI<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This is not a function, it is a constant roughly equal to the mathematical
    constant Pi.
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    <anchor name=Simulate.all_efuns>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>all_efuns</tt> - return all 'efuns'
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping all_efuns();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the same as all_constants.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=all_constants>all_constants</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    
    <anchor name=Simulate.filter_array>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.filter_array</tt> - filter an array through a function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>
    <p>mixed *filter_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    mixed *filter_array(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    mixed *filter_array(function *<I>arr</I>,-<I>1</I>,mixed ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Filter array is the same function as Array.filter.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.filter>Array.filter</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    <anchor name=Simulate.implode>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.implode</tt> - implode an array of strings
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string implode(array(string) <I>a</I>, string <I>delimiter</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the inverse of explode. It concatenates all the
    strings in a with a delimiter in between each.
    <p>This function is the same as multiplication.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>&gt; implode( ({ "foo","bar","gazonk"}), "-" );<br>
    Result: foo-bar-gazonk<br>
    &gt; ({ "a","b","c" })*" and ";<br>
    Result: a and b and c<br>
    &gt; <br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Simulate.explode>Simulate.explode</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    
    <anchor name=Simulate.m_indices>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.m_indices</tt> - return all indices from a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *m_indices(mapping <I>m</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is equal to indices.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=indices>indices</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.m_sizeof>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.m_sizeof</tt> - return the size of a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int m_sizeof(mapping <I>m</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is equal to sizeof.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.m_values>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.m_values</tt> - return all values from a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *m_values(mapping <I>m</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is equal to values.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=values>values</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    <anchor name=Simulate.map_array>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.map_array</tt> - map an array over a function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *map_array(mixed *<I>arr</I>,function <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    mixed *map_array(object *<I>arr</I>,string <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    mixed *map_array(function *<I>arr</I>,-<I>1</I>,mixed ... <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the same as Array.map.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Array.map>Array.map</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    
    
    
    <anchor name=Simulate.strstr>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.strstr</tt> - find a string inside a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int strstr(string <I>str1</I>,string <I>str2</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the position of <i>str2</i> in <i>str1</i>, if <i>str2</i> can't be found in <i>str1</i>
    -1 is returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sscanf>sscanf</link>, <link to=Simulate.explode>Simulate.explode</link>, <link to=search>search</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.sum>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.sum</tt> - add values together
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>
    <p>int sum(int ... <I>i</I>);<br>
    or<br>
    float sum(float ... <I>f</I>);<br>
    or<br>
    string sum(string|float|int ... <I>p</I>);<br>
    or<br>
    array sum(array ... <I>a</I>);<br>
    or<br>
    mapping sum(mapping ... <I>m</I>);<br>
    or<br>
    list sum(multiset ... <I>l</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function does exactly the same thing as adding all the arguments
    together with +. It's just here so you can get a function pointer to
    the summation operator.
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.add_efun>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.add_efun</tt> - add an efun or constant
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void add_efun(string func_name, mixed function)<br>
    or<br>
    void add_efun(string func_name)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the same as add_constant.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=add_constant>Simulate.add_constant</link>
    <p>
    </dl>
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.l_sizeof>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.l_sizeof</tt> - return the size of a multiset
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int l_sizeof(multiset <I>m</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is equal to sizeof.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>
    <p>
    </dl>
    
    </anchor>
    <hr newpage>
    <anchor name=Simulate.listp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.listp</tt> - is the argument a list? (multiset)
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int listp(mixed l)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the same as multisetp.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=multisetp>Simulate.multisetp</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.mklist>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.mklist</tt> - make a multiset
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>multiset mklist(mixed *a)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function creates a multiset from an array.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; mklist( ({1,2,3}) );<br>
    Result: (&lt; /* 3 elements */<br>
    <dl><dt><dd>1,<br>
    2,<br>
    3<br>
    </dl>&gt;)<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=aggregate_multiset>aggregate_multiset</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.aggregate_list>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.aggregate_list</tt> - aggregate a multiset
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>multiset aggregate_list(mixed ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is exactly the same as aggregate_multiset.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=aggregate_multiset>aggregate_multiset</link>
    <p>
    </dl>
    
    </anchor>
    
    <hr newpage>
    <anchor name=Simulate.query_host_name>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>Simulate.query_host_name</tt> - return the name of the host we are running on
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string query_host_name();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the name of the machine the interpreter is
    running on. This is the same thing that the command 'hostname'
    prints.
    <p>
    </dl>
    
    </anchor>
    </section>
    <!-- Simulate.explode saknas -->
    </anchor>
    
    <hr newpage>
    
    <!--  FIX ME priority_queue and heap should be placed inside Structs
    <h2>Structs</h2>
    
    <h2>Msql</h2>
    <h2>Mysql</h2>
    <h2>Sql</h2>
    <h2>LR</h2>
    
     -->
    
    </chapter>
    
    <!-- This chapter should be updated from http://www.mirar.org/ -->
    <!-- Until then we might have to remove it -->
    <anchor name=Image>
    <chapter title="The Image module">
    The Image module is used to manipulate bit-mapped color images. 
    It can read PPM images and do various manipulations, or it can be
    used to create completely new images. The created images can be
    saved as PPM or converted to GIF.
    <p>
    All images handled by this module are stored as 24-bit RGB images.
    This means that a 1024 pixel wide and 1024 pixel high image will
    use 1024*1024*3 bytes = 3 megabytes. It is quite easy to mess up
    and use up all the memory by giving the wrong argument to one
    of the scaling functions.
    <p>
    Most functions in this module work by creating a new Image and then
    returning that instead of changing the Image you are working with.
    This makes it possible to share the same image between many variables
    without having to worry that it will be changed by accident. This
    can reduce the amount of memory used.
    <p>
    Many functions in this module work with the 'current color', this can
    be thought of as the background color if you wish. To change the
    current color you use 'setcolor'.
    <p>
    
    Let's look at an example of how this can be used:
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	int main()
    	{
    	  write("Content-type: image/gif\n\n");
    	  object font=Image.font();
    	  font-&gt;load("testfont");
    	  object image=font-&gt;write(ctime(time));
    	  write(image-&gt;togif());
    	}
    </example>
    This very simple example can be used as a CGI script to produce a gif image
    which says what time it is in white text on a black background.
    <p>
    
    <section title="Image.image">
    
    <dl><dd>
    The main object of the <link to=Image>Image</link> module, this object
         is used as drawing area, mask or result of operations.
    
    <p>     init: <link to=Image.image.clear>Image.image-&gt;clear</link>,
         <link to=Image.image.clone>Image.image-&gt;clone</link>,
         <link to=Image.image.create>Image.image-&gt;create</link>, 
         <link to=Image.image.xsize>Image.image-&gt;xsize</link>,
         <link to=Image.image.ysize>Image.image-&gt;ysize</link>
    
    <p>     plain drawing: <link to=Image.image.box>Image.image-&gt;box</link>,
         <link to=Image.image.circle>Image.image-&gt;circle</link>,
         <link to=Image.image.getpixel>Image.image-&gt;getpixel</link>, 
         <link to=Image.image.line>Image.image-&gt;line</link>,
         <link to=Image.image.setcolor>Image.image-&gt;setcolor</link>,
         <link to=Image.image.setpixel>Image.image-&gt;setpixel</link>, 
         <link to=Image.image.treshold>Image.image-&gt;treshold</link>,
         <link to=Image.image.tuned_box>Image.image-&gt;tuned_box</link>,
         <link to=Image.image.polyfill>Image.image-&gt;polyfill</link>
    
    <p>     operators: <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link>,
         <link to=Image.image.%60*>Image.image-&gt;`*</link>,
         <link to=Image.image.%60+>Image.image-&gt;`+</link>,
         <link to=Image.image.%60->Image.image-&gt;`-</link>,
         <link to=Image.image.%60|>Image.image-&gt;`|</link>
    
    <p>     pasting images, layers: <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>, 
         <link to=Image.image.paste>Image.image-&gt;paste</link>,
         <link to=Image.image.paste_alpha>Image.image-&gt;paste_alpha</link>,
         <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>,
         <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link>
    
    <p>     getting sub-images, scaling, rotating: <link to=Image.image.autocrop>Image.image-&gt;autocrop</link>, 
         <link to=Image.image.ccw>Image.image-&gt;ccw</link>,
         <link to=Image.image.cw>Image.image-&gt;cw</link>,
         <link to=Image.image.clone>Image.image-&gt;clone</link>,
         <link to=Image.image.copy>Image.image-&gt;copy</link>, 
         <link to=Image.image.dct>Image.image-&gt;dct</link>,
         <link to=Image.image.mirrorx>Image.image-&gt;mirrorx</link>, 
         <link to=Image.image.rotate>Image.image-&gt;rotate</link>,
         <link to=Image.image.rotate_expand>Image.image-&gt;rotate_expand</link>, 
         <link to=Image.image.scale>Image.image-&gt;scale</link>, 
         <link to=Image.image.skewx>Image.image-&gt;skewx</link>,
         <link to=Image.image.skewx_expand>Image.image-&gt;skewx_expand</link>,
         <link to=Image.image.skewy>Image.image-&gt;skewy</link>,
         <link to=Image.image.skewy_expand>Image.image-&gt;skewy_expand</link>
    
    <p>     calculation by pixels: <link to=Image.image.apply_matrix>Image.image-&gt;apply_matrix</link>, 
         <link to=Image.image.change_color>Image.image-&gt;change_color</link>,
         <link to=Image.image.color>Image.image-&gt;color</link>,
         <link to=Image.image.distancesq>Image.image-&gt;distancesq</link>, 
         <link to=Image.image.grey>Image.image-&gt;grey</link>,
         <link to=Image.image.invert>Image.image-&gt;invert</link>, 
         <link to=Image.image.map_closest>Image.image-&gt;map_closest</link>,
         <link to=Image.image.map_fast>Image.image-&gt;map_fast</link>, 
         <link to=Image.image.modify_by_intensity>Image.image-&gt;modify_by_intensity</link>,
         <link to=Image.image.select_from>Image.image-&gt;select_from</link> 
    
    <p>     converting to other data types: <link to=Image.image.cast>Image.image-&gt;cast</link>,
         <link to=Image.image.fromgif>Image.image-&gt;fromgif</link>, 
         <link to=Image.image.frompnm>Image.image-&gt;frompnm</link>/<link to=Image.image.fromppm>Image.image-&gt;fromppm</link>, 
         <link to=Image.image.gif_add>Image.image-&gt;gif_add</link>,
         <link to=Image.image.gif_add_fs>Image.image-&gt;gif_add_fs</link>,
         <link to=Image.image.gif_add_fs_nomap>Image.image-&gt;gif_add_fs_nomap</link>,
         <link to=Image.image.gif_add_nomap>Image.image-&gt;gif_add_nomap</link>,
         <link to=Image.image.gif_begin>Image.image-&gt;gif_begin</link>,
         <link to=Image.image.gif_end>Image.image-&gt;gif_end</link>,
         <link to=Image.image.gif_netscape_loop>Image.image-&gt;gif_netscape_loop</link>,
         <link to=Image.image.to8bit>Image.image-&gt;to8bit</link>,
         <link to=Image.image.to8bit_closest>Image.image-&gt;to8bit_closest</link>, 
         <link to=Image.image.to8bit_fs>Image.image-&gt;to8bit_fs</link>,
         <link to=Image.image.to8bit_rgbcube>Image.image-&gt;to8bit_rgbcube</link>, 
         <link to=Image.image.to8bit_rgbcube_rdither>Image.image-&gt;to8bit_rgbcube_rdither</link>,
         <link to=Image.image.tobitmap>Image.image-&gt;tobitmap</link>, 
         <link to=Image.image.togif>Image.image-&gt;togif</link>,
         <link to=Image.image.togif_fs>Image.image-&gt;togif_fs</link>, 
         <link to=Image.image.toppm>Image.image-&gt;toppm</link>,
         <link to=Image.image.tozbgr>Image.image-&gt;tozbgr</link>
    </dl>
    
    
    <encaps>SEE ALSO</encaps>
    <dl><dd>     <link to=Image>Image</link>,
         <link to=Image.font>Image.font</link>
    </dl>
    
    <hr>
    <anchor name=Image.image.%60%26>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>`&amp;</tt> - makes a new image out of the minimum pixels values<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object `&amp;(object&nbsp;operand)<br>
    object `&amp;(array(int)&nbsp;color)<br>
    object `&amp;(int&nbsp;value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    makes a new image out of the minimum pixels values
         
    
    <p> object operand
         the other image to compare with;
         the images must have the same size.
     array(int) color
         an array in format ({r,g,b}), this is equal
         to using a uniform-colored image.
     int value
         equal to ({value,value,value}).
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.%60->Image.image-&gt;`-</link>, <link to=Image.image.%60+>Image.image-&gt;`+</link>, <link to=Image.image.%60|>Image.image-&gt;`|</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.%60*>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>`*</tt> - Multiplies pixel values and creates a new image<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object `*(object&nbsp;operand)<br>
    object `*(array(int)&nbsp;color)<br>
    object `*(int&nbsp;value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Multiplies pixel values and creates a new image.
    
    <p>     This can be useful to lower the values of an image,
         making it grayer, for instance:
    
    <p>     <pre>image=image*128+64;</pre>
    
    <p> object operand
         the other image to multiply with;
         the images must have the same size.
     array(int) color
         an array in format ({r,g,b}), this is equal
         to using a uniform-colored image.
     int value
         equal to ({value,value,value}).
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.%60->Image.image-&gt;`-</link>, <link to=Image.image.%60+>Image.image-&gt;`+</link>, <link to=Image.image.%60|>Image.image-&gt;`|</link>, <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link> and <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.%60+>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>`+</tt> - adds two images
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object `+(object&nbsp;operand)<br>
    object `+(array(int)&nbsp;color)<br>
    object `+(int&nbsp;value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    adds two images; values are truncated at 255.
    
    <p> object operand
         the image which to add.
     array(int) color
         an array in format ({r,g,b}), this is equal
         to using a uniform-colored image.
     int value
         equal to ({value,value,value}).
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.%60->Image.image-&gt;`-</link>, <link to=Image.image.%60|>Image.image-&gt;`|</link>, <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.%60->
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>`-</tt> - makes a new image out of the difference
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object `-(object&nbsp;operand)<br>
    object `-(array(int)&nbsp;color)<br>
    object `-(int&nbsp;value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    makes a new image out of the difference
    
    <p> object operand
         the other image to compare with;
         the images must have the same size.
     array(int) color
         an array in format ({r,g,b}), this is equal
         to using a uniform-colored image.
     int value
         equal to ({value,value,value}).
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.%60+>Image.image-&gt;`+</link>, <link to=Image.image.%60|>Image.image-&gt;`|</link>, <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.%60|>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>`|</tt> - makes a new image out of the maximum pixels values<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object `|(object&nbsp;operand)<br>
    object `|(array(int)&nbsp;color)<br>
    object `|(int&nbsp;value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    makes a new image out of the maximum pixels values
         
    
    <p> object operand
         the other image to compare with;
         the images must have the same size.
     array(int) color
         an array in format ({r,g,b}), this is equal
         to using a uniform-colored image.
     int value
         equal to ({value,value,value}).
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.%60->Image.image-&gt;`-</link>, <link to=Image.image.%60+>Image.image-&gt;`+</link>, <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.add_layers>Image.image-&gt;add_layers</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.add_layers>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>add_layers</tt> - add layers together
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object add_layers(array(int|object))&nbsp;layer0, ...)<br>
    object add_layers(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, array(int|object))&nbsp;layer0, ...)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Using the called object as base, adds layers using masks,
         opaque channel values and special methods.
    
    <p>     The destination image can also be cropped, thus
         speeding up the process.
    
    <p>     Each array in the layers array is one of:
         <pre>
         ({object image,object|int mask})
         ({object image,object|int mask,int opaque_value})
         ({object image,object|int mask,int opaque_value,int method})
         </pre>
         Given 0 as mask means the image is totally opaque.
    
    <p>     Default opaque value is 255, only using the mask.
    
    <p>     Methods for now are:
         <pre>
         0  no operation (just paste with mask, default)
         1  maximum  (`|)
         2  minimum  (`&amp;)
         3  multiply (`*)
         4  add      (`+)
         5  diff     (`-)
         </pre>
         The layer image and the current source are calculated
         through the given method and then pasted using the mask
         and the opaque channel value. 
    
    <p>     All given images must be the same size.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(int|object) layer0</tt>
      <dd>image to paste
    <dt><tt>int x1</tt>
    <dt><tt>int y1</tt>
    <dt><tt>int x2</tt>
    <dt><tt>int y2</tt>
      <dd>rectangle for cropping
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    a new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link>, <link to=Image.image.paste_alpha>Image.image-&gt;paste_alpha</link>, <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>, <link to=Image.image.%60|>Image.image-&gt;`|</link>, <link to=Image.image.%60%26>Image.image-&gt;`&amp;</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link>, <link to=Image.image.%60+>Image.image-&gt;`+</link> and <link to=Image.image.%60->Image.image-&gt;`-</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.apply_matrix>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>apply_matrix</tt> - Applies a pixel-transform matrix, or filter, to the image.<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object apply_matrix(array(array(int|array(int)))&nbsp;matrix)<br>
    object apply_matrix(array(array(int|array(int)))&nbsp;matrix, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object apply_matrix(array(array(int|array(int)))&nbsp;matrix, int&nbsp;r, int&nbsp;g, int&nbsp;b, int|float&nbsp;div)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Applies a pixel-transform matrix, or filter, to the image.
        
         <pre>
                                2   2
         pixel(x,y)= base+ k ( sum sum pixel(x+k-1,y+l-1)*matrix(k,l) ) 
                               k=0 l=0 
         </pre>
         
         1/k is sum of matrix, or sum of matrix multiplied with div.
         base is given by r,g,b and is normally black.
    
    <p>     blur (ie a 2d gauss function):
         <pre>
         ({({1,2,1}),
           ({2,5,2}),
           ({1,2,1})})
         </pre>
         
         sharpen (k>8, preferably 12 or 16):
         <pre>
         ({({-1,-1,-1}),
           ({-1, k,-1}),
           ({-1,-1,-1})})
         </pre>
    
    <p>     edge detect:
         <pre>
         ({({1, 1,1}),
           ({1,-8,1}),
           ({1, 1,1})})
         </pre>
    
    <p>     horizontal edge detect (get the idea):
         <pre>
         ({({0, 0,0})
           ({1,-8,1}),
           ({0, 0,0})})
         </pre>
    
    <p>     emboss (might prefer to begin with a <link to=Image.image.grey>Image.image-&gt;grey</link> image):
         <pre>
         ({({2, 1, 0})
           ({1, 0,-1}),
           ({0,-1, 2})}), 128,128,128, 5
         </pre>
    
    <p>     This function is not very fast, and it's hard to 
         optimize it more, not using assembler.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(array(int|array(int)))</tt>
      <dd>the matrix; innermost is a value or an array with red, green, blue
         values for red, green, blue separation.
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>base level of result, default is zero
    <dt><tt>int|float div</tt>
      <dd>division factor, default is 1.0.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.autocrop>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>autocrop</tt> - Removes "unnecessary" borders around the image<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object autocrop()<br>
    object autocrop(int&nbsp;border)<br>
    object autocrop(int&nbsp;border, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object autocrop(int&nbsp;border, int&nbsp;left, int&nbsp;right, int&nbsp;top, int&nbsp;bottom)<br>
    object autocrop(int&nbsp;border, int&nbsp;left, int&nbsp;right, int&nbsp;top, int&nbsp;bottom, int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Removes "unnecessary" borders around the image, adds one of
         its own if wanted to, in selected directions.
    
    <p>     "Unnecessary" is all pixels that are equal -- ie if all the same pixels
         to the left are the same color, that column of pixels are removed.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int border</tt>
      <dd>added border size in pixels
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color of the new border
    <dt><tt>int left</tt>
    <dt><tt>int right</tt>
    <dt><tt>int top</tt>
    <dt><tt>int bottom</tt>
      <dd>which borders to scan and cut the image; 
         a typical example is removing the top and bottom unnecessary
         pixels:
         <pre>img=img->autocrop(0, 0,0,1,1);</pre>
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.copy>Image.image-&gt;copy</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.box>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>box</tt> - Draws a filled rectangle on the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object box(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2)<br>
    object box(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object box(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Draws a filled rectangle on the image.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x1</tt>
    <dt><tt>int y1</tt>
    <dt><tt>int x2</tt>
    <dt><tt>int y2</tt>
      <dd>box corners
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color of the box
    <dt><tt>int alpha</tt>
      <dd>alpha value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.cast>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>cast</tt> - convert to other types
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string cast(string&nbsp;type)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    known bugs: always casts to string...
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the image data as a string ("rgbrgbrgb...")
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.toppm>Image.image-&gt;toppm</link>, <link to=Image.image.togif>Image.image-&gt;togif</link>, <link to=Image.image.tozbgr>Image.image-&gt;tozbgr</link>, <link to=Image.image.to8bit>Image.image-&gt;to8bit</link> and <link to=Image.image.to8bit_rgbcube>Image.image-&gt;to8bit_rgbcube</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.ccw>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>ccw</tt> - rotates an image 90 degrees counter-clockwise<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object ccw()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    rotates an image counter-clockwise, 90 degrees.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.change_color>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>change_color</tt> - Replaces one color with another
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object change_color(int&nbsp;tor, int&nbsp;tog, int&nbsp;tob)<br>
    object change_color(int&nbsp;fromr, int&nbsp;fromg, int&nbsp;fromb, &nbsp;int&nbsp;tor, int&nbsp;tog, int&nbsp;tob)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Changes one color (exact match) to another.
         If non-exact-match is preferred, check <link to=Image.image.distancesq>Image.image-&gt;distancesq</link>
         and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int tor</tt>
    <dt><tt>int tog</tt>
    <dt><tt>int tob</tt>
      <dd>destination color and next current color
    <dt><tt>int fromr</tt>
    <dt><tt>int fromg</tt>
    <dt><tt>int fromb</tt>
      <dd>source color, default is current color
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    a new (the destination) image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.circle>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>circle</tt> - Draw a line on the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object circle(int&nbsp;x, int&nbsp;y, int&nbsp;rx, int&nbsp;ry)<br>
    object circle(int&nbsp;x, int&nbsp;y, int&nbsp;rx, int&nbsp;ry, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object circle(int&nbsp;x, int&nbsp;y, int&nbsp;rx, int&nbsp;ry, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Draws a line on the image. The line is <i>not</i> anti-aliased.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>circle center
    <dt><tt>int rx</tt>
    <dt><tt>int ry</tt>
      <dd>circle radius in pixels
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color
    <dt><tt>int alpha</tt>
      <dd>alpha value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.clear>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>clear</tt> - create a new empty image of same size
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>void clear()<br>
    void clear(int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    void clear(int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    gives a new, cleared image with the same size of drawing area
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color of the new image
    <dt><tt>int alpha</tt>
      <dd>new default alpha channel value
    
    </dl><p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.copy>Image.image-&gt;copy</link> and <link to=Image.image.clone>Image.image-&gt;clone</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.clone>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>clone</tt> - Copies to or initialize a new image object<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object clone()<br>
    object clone(int&nbsp;xsize, int&nbsp;ysize)<br>
    object clone(int&nbsp;xsize, int&nbsp;ysize, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object clone(int&nbsp;xsize, int&nbsp;ysize, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Copies to or initialize a new image object.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int xsize</tt>
    <dt><tt>int ysize</tt>
      <dd>size of (new) image in pixels, called image
         is cropped to that size
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>current color of the new image, 
         default is black. 
         Will also be the background color if the cloned image
         is empty (no drawing area made).
    <dt><tt>int alpha</tt>
      <dd>new default alpha channel value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.copy>Image.image-&gt;copy</link> and <link to=Image.image.create>Image.image-&gt;create</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.color>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>color</tt> - Colorize an image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object color()<br>
    object color(int&nbsp;value)<br>
    object color(int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Colorize an image. 
    
    <p>    The red, green and blue values of the pixels are multiplied
        with the given value(s). This works best on a grey image...
    
    <p>    The result is divided by 255, giving correct pixel values.
    
    <p>    If no arguments are given, the current color is used as factors.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>red, green, blue factors
    <dt><tt>int value</tt>
      <dd>factor
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.grey>Image.image-&gt;grey</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.modify_by_intensity>Image.image-&gt;modify_by_intensity</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.copy>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>copy</tt> - Copies a part of the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object copy()<br>
    object copy(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2)<br>
    object copy(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object copy(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Copies this part of the image. The requested area can
         be smaller, giving a cropped image, or bigger - 
         the new area will be filled with the given or current color.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x1</tt>
    <dt><tt>int y1</tt>
    <dt><tt>int x2</tt>
    <dt><tt>int y2</tt>
      <dd>The requested new area. Default is the old image size.
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color of the new image
    <dt><tt>int alpha</tt>
      <dd>new default alpha channel value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    a new image object
    <p>
    <dt><encaps>NOTE</encaps>
    <dd>
    <link to=Image.image.clone>Image.image-&gt;clone</link>(void) and <link to=Image.image.copy>Image.image-&gt;copy</link>(void) does the same 
         operation
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.clone>Image.image-&gt;clone</link> and <link to=Image.image.autocrop>Image.image-&gt;autocrop</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.create>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>create</tt> - Initializes a new image object
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>void create()<br>
    void create(int&nbsp;xsize, int&nbsp;ysize)<br>
    void create(int&nbsp;xsize, int&nbsp;ysize, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    void create(int&nbsp;xsize, int&nbsp;ysize, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Initializes a new image object.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int xsize</tt>
    <dt><tt>int ysize</tt>
      <dd>size of (new) image in pixels
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>background color (will also be current color),
         default color is black
    <dt><tt>int alpha</tt>
      <dd>default alpha channel value
    
    </dl><p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.copy>Image.image-&gt;copy</link>, <link to=Image.image.clone>Image.image-&gt;clone</link> and <link to=Image.image>Image.image</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.cw>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>cw</tt> - rotates an image 90 degrees clockwise<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object cw()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    rotates an image clockwise, 90 degrees.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.dct>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>dct</tt> - Scales the image to a new size<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object dct(int&nbsp;newx, int&nbsp;newy)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Scales the image to a new size.
         
         Method for scaling is rather complex;
         the image is transformed via a cosine transform,
         and then resampled back.
    
    <p>     This gives a quality-conserving upscale,
         but the algorithm used is n*n+n*m, where n
         and m is pixels in the original and new image.
    
    <p>     Recommended wrapping algorithm is to scale
         overlapping parts of the image-to-be-scaled.
    
    <p>     This functionality is actually added as an
         true experiment, but works...
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int newx</tt>
    <dt><tt>int newy</tt>
      <dd>new image size in pixels
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>NOTE</encaps>
    <dd>
    Do NOT use this function if you don't know what 
         you're dealing with! Read some signal theory first...
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.distancesq>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>distancesq</tt> - Makes a grey-scale image for alpha-channel use
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object distancesq()<br>
    object distancesq(int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a grey-scale image, for alpha-channel use.
        
        The given value (or current color) are used for coordinates
        in the color cube. Each resulting pixel is the 
        distance from this point to the source pixel color,
        in the color cube, squared, right-shifted 8 steps:
    
    <p>    <pre>
        p = pixel color
        o = given color
        d = destination pixel
        d.red=d.blue=d.green=
            ((o.red-p.red)²+(o.green-p.green)²+(o.blue-p.blue)²)>>8
        </pre>
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>red, green, blue coordinates
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.select_from>Image.image-&gt;select_from</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.fromgif>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>fromgif</tt> - Reads GIF data to the called image object<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object fromgif(string&nbsp;gif)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Reads GIF data to the called image object.
    
    <p>     GIF animation delay or loops are ignored,
         and the resulting image is the written result.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>string pnm</tt>
      <dd>pnm data, as a string
     known bugs: yes, it does -- it may even do segment overrides...
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the called object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.togif>Image.image-&gt;togif</link> and <link to=Image.image.frompnm>Image.image-&gt;frompnm</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.frompnm>
    <anchor name=Image.image.fromppm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>frompnm, fromppm</tt> - Reads PNM data to the called image object
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object|string frompnm(string&nbsp;pnm)<br>
    object|string fromppm(string&nbsp;pnm)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Reads a PNM (PBM, PGM or PPM in ascii or binary)
         to the called image object.
    
    <p>     The method accepts P1 through P6 type of PNM data.
    
    <p>     "fromppm" is an alias for "frompnm".
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>string pnm</tt>
      <dd>pnm data, as a string
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the called object or a hint of what wronged.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.toppm>Image.image-&gt;toppm</link> and <link to=Image.image.fromgif>Image.image-&gt;fromgif</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.getpixel>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getpixel</tt> - get the value of a pixel
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>array(int) getpixel(int&nbsp;x, int&nbsp;y)</tt>
    <p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>position of the pixel
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    color of the requested pixel -- ({int red,int green,int blue})
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.gif_add>
    <anchor name=Image.image.gif_add_fs>
    <anchor name=Image.image.gif_add_fs_nomap>
    <anchor name=Image.image.gif_add_nomap>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gif_add, gif_add_fs, gif_add_fs_nomap, gif_add_nomap</tt> - Makes a GIF (sub)image data chunk
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string gif_add()<br>
    string gif_add(int&nbsp;x, int&nbsp;y)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, int&nbsp;delay_cs)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, float&nbsp;delay_s)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, int&nbsp;delay_cs)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, float&nbsp;delay_s)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, int&nbsp;delay_cs)<br>
    string gif_add(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, float&nbsp;delay_s)<br>
    string gif_add_fs()<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, int&nbsp;delay_cs)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, float&nbsp;delay_s)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, int&nbsp;delay_cs)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, float&nbsp;delay_s)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, int&nbsp;delay_cs)<br>
    string gif_add_fs(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, float&nbsp;delay_s)<br>
    string gif_add_nomap()<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;delay_cs)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, float&nbsp;delay_s)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, int&nbsp;delay_cs)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, float&nbsp;delay_s)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, int&nbsp;delay_cs)<br>
    string gif_add_nomap(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, float&nbsp;delay_s)<br>
    string gif_add_fs_nomap()<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;delay_cs)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, float&nbsp;delay_s)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, int&nbsp;delay_cs)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, int&nbsp;num_colors, float&nbsp;delay_s)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, int&nbsp;delay_cs)<br>
    string gif_add_fs_nomap(int&nbsp;x, int&nbsp;y, array(array(int))&nbsp;colors, float&nbsp;delay_s)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a GIF (sub)image data chunk, to be placed 
         at the given position. 
    
    <p>     The "fs" versions uses Floyd-Steinberg dithering, and the "nomap"
         versions have no local colormap.
    
    <p>     Example: 
         <pre>
         object img1 = Image(200,200); 
         object img2 = Image(200,200); 
         // load img1 and img2 with stuff
         write(img1->gif_begin()+
               img1->gif_netscape_loop()+
               img1->gif_add(0,0,100)+
               img2->gif_add(0,0,100)+
               img1->gif_end());
         // voila, a gif animation...
         </pre>
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>the location of this sub-image
    <dt><tt>int delay_cs</tt>
      <dd>frame delay in centiseconds
    <dt><tt>float delay_s</tt>
      <dd>frame delay in seconds
    <dt><tt>int num_colors</tt>
      <dd>number of colors to quantize to (default is 256)
    <dt><tt>array array(array(int)) colors</tt>
      <dd>colors to map to, format is ({({r,g,b}),({r,g,b}),...}).
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the GIF data chunk as a string
    <p>
    <dt><encaps>NOTE</encaps>
    <dd>
    I (Mirar) recommend reading about the GIF file format before 
         experimenting with these.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.gif_add>Image.image-&gt;gif_add</link>, <link to=Image.image.gif_end>Image.image-&gt;gif_end</link>, <link to=Image.image.gif_netscape_loop>Image.image-&gt;gif_netscape_loop</link> and <link to=Image.image.togif */>Image.image-&gt;togif */</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.gif_begin>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gif_begin</tt> - Makes GIF header<p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string gif_begin()<br>
    string gif_begin(int&nbsp;num_colors)<br>
    string gif_begin(array(array(int))&nbsp;colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes GIF header. With no argument, there is no
         global colortable (palette).
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int num_colors</tt>
      <dd>number of colors to quantize to (default is 256) 
     array array(array(int)) colors
         colors to map to, format is ({({r,g,b}),({r,g,b}),...}).
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the GIF data
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.gif_add>Image.image-&gt;gif_add</link>, <link to=Image.image.gif_end>Image.image-&gt;gif_end</link>, <link to=Image.image.togif>Image.image-&gt;togif</link> and <link to=Image.image.gif_netscape_loop>Image.image-&gt;gif_netscape_loop</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.gif_end>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gif_end</tt> - Ends GIF data
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string gif_end()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Ends GIF data.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the GIF data.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.gif_begin>Image.image-&gt;gif_begin</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.gif_netscape_loop>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gif_netscape_loop</tt> - makes a gif chunk which defines how many times it should loop
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string gif_netscape_loop()<br>
    string gif_netscape_loop(int&nbsp;loops)</tt>
    <p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int loops</tt>
      <dd>number of loops, default is 65535.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    a gif chunk that defines that the GIF animation should loop
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.gif_add>Image.image-&gt;gif_add</link>, <link to=Image.image.gif_begin>Image.image-&gt;gif_begin</link> and <link to=Image.image.gif_end>Image.image-&gt;gif_end</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.grey>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>grey</tt> - Makes a grey-scale image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object grey()<br>
    object grey(int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a grey-scale image (with weighted values).
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>weight of color, default is r=87,g=127,b=41,
         which should be pretty accurate of what the eyes see...
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.color>Image.image-&gt;color</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.modify_by_intensity>Image.image-&gt;modify_by_intensity</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.invert>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>invert</tt> - Invert an image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object invert()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Invert an image. Each pixel value gets to be 255-x, where x 
        is the old value.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.line>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>line</tt> - Draws a line on the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object line(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2)<br>
    object line(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object line(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Draws a line on the image. The line is <i>not</i> anti-aliased.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x1</tt>
    <dt><tt>int y1</tt>
    <dt><tt>int x2</tt>
    <dt><tt>int y2</tt>
      <dd>line endpoints
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color
    <dt><tt>int alpha</tt>
      <dd>alpha value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.map_closest>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>map_closest</tt> - Maps all pixel colors to the colors given
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object map_closest(array(array(int))&nbsp;colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps all pixel colors to the colors given.
    
    <p>    Method to find the correct color is linear search
        over the colors given, selecting the nearest in the
        color cube. Slow...
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(array(int)) color</tt>
      <dd>list of destination (available) colors
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.map_fast>Image.image-&gt;map_fast</link>, <link to=Image.image.select_colors>Image.image-&gt;select_colors</link> and <link to=Image.image.map_fs>Image.image-&gt;map_fs</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.map_closest>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>map_closest</tt> - Selects the best colors to represent the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>array(array(int)) map_closest(int&nbsp;num_colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Selects the best colors to represent the image.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int num_colors</tt>
      <dd>number of colors to return
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    an array of colors
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.map_fast>Image.image-&gt;map_fast</link> and <link to=Image.image.select_colors>Image.image-&gt;select_colors</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.map_fast>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>map_fast</tt> - Maps all pixel colors to the colors given
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object map_fast(array(array(int))&nbsp;colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps all pixel colors to the colors given.
    
    <p>    Method to find the correct color is to branch
        in a binary space partitioning tree in the 
        colorcube. This is fast, but in some cases
        it gives the wrong color (mostly when few colors
        are available).
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(array(int)) color</tt>
      <dd>list of destination (available) colors
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.map_fast>Image.image-&gt;map_fast</link> and <link to=Image.image.select_colors>Image.image-&gt;select_colors</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.map_fs>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>map_fs</tt> - Maps all pixel colors to the colors given
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object map_fs(array(array(int))&nbsp;colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps all pixel colors to the colors given.
    
    <p>    Method to find the correct color is linear search
        over the colors given, selecting the nearest in the
        color cube. Slow...
    
    <p>    Floyd-Steinberg error correction is added to create
        a better-looking image, in many cases, anyway.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(array(int)) color</tt>
      <dd>list of destination (available) colors
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.map_fast>Image.image-&gt;map_fast</link>, <link to=Image.image.select_colors>Image.image-&gt;select_colors</link> and <link to=Image.image.map_closest>Image.image-&gt;map_closest</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.mirrorx>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mirrorx</tt> - mirrors an image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object mirrorx()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    mirrors an image:
    <center>
    <image src=lenna.rs dpi=225 align=center>&nbsp;-&gt;&nbsp;<illustration align=center src=lenna.rs dpi=225>return src->mirrorx();</illustration><br>
    </center>
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.mirrorx>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mirrorx</tt> - mirrors an image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object mirrory()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    mirrors an image:
    <center>
    <image src=lenna.rs dpi=225 align=center>&nbsp;-&gt;&nbsp;;<illustration align=center src=lenna.rs dpi=225>return src->mirrory();</illustration><br>
    </center>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.modify_by_intensity>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>modify_by_intensity</tt> - Re-color an image from intensity values
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object modify_by_intensity(int&nbsp;r, int&nbsp;g, int&nbsp;b, int|array(int)&nbsp;v1, ..., int|array(int)&nbsp;vn)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Re-color an image from intensity values.
    
    <p>    For each color an intensity is calculated, from r, g and b factors
        (see <link to=Image.image.grey>Image.image-&gt;grey</link>), this gives a value between 0 and max.
    
    <p>    The color is then calculated from the values given, v1 representing
        the intensity value of 0, vn representing max, and colors between
        representing intensity values between, linear.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>red, green, blue intensity factors
    <dt><tt>int|array(int) v1</tt>
    <dt><tt>int|array(int) vn</tt>
      <dd>destination color
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.grey>Image.image-&gt;grey</link>, <link to=Image.image.%60*>Image.image-&gt;`*</link> and <link to=Image.image.color>Image.image-&gt;color</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.paste>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>paste</tt> - Pastes a given image over the current image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object paste(object&nbsp;image)<br>
    object paste(object&nbsp;image, int&nbsp;x, int&nbsp;y)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Pastes a given image over the current image.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>object image</tt>
      <dd>image to paste
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>where to paste the image; default is 0,0
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link>, <link to=Image.image.paste_alpha>Image.image-&gt;paste_alpha</link> and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.paste_alpha>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>paste_alpha</tt> - Pastes a given image over the current image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object paste_alpha(object&nbsp;image, int&nbsp;alpha)<br>
    object paste_alpha(object&nbsp;image, int&nbsp;alpha, int&nbsp;x, int&nbsp;y)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Pastes a given image over the current image, with
         the specified alpha channel value.
         
         An alpha channel value of 0 leaves nothing of the original 
         image in the paste area, 255 is meaningless and makes the
         given image invisible.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>object image</tt>
      <dd>image to paste
    <dt><tt>int alpha</tt>
      <dd>alpha channel value
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>where to paste the image; default is 0,0
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link>, <link to=Image.image.paste>Image.image-&gt;paste</link> and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.paste_alpha_color>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>paste_alpha_color</tt> - Pastes a given color over the current image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object paste_alpha_color(object&nbsp;mask)<br>
    object paste_alpha_color(object&nbsp;mask, int&nbsp;x, int&nbsp;y)<br>
    object paste_alpha_color(object&nbsp;mask, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object paste_alpha_color(object&nbsp;mask, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;x, int&nbsp;y)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Pastes a given color over the current image,
        using the given mask as opaque channel.  
        
        A pixel value of 255 makes the result become the color given,
        0 doesn't change anything.
        
        The masks red, green and blue values are used separately.
        If no color are given, the current is used.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>object mask</tt>
      <dd>mask image
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>what color to paint with; default is current
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>where to paste the image; default is 0,0
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link>, <link to=Image.image.paste_alpha>Image.image-&gt;paste_alpha</link> and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.paste_mask>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>paste_mask</tt> - Pastes a given image over the current image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object paste_mask(object&nbsp;image, object&nbsp;mask)<br>
    object paste_mask(object&nbsp;image, object&nbsp;mask, int&nbsp;x, int&nbsp;y)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Pastes a given image over the current image,
        using the given mask as opaque channel.  
        
        A pixel value of 255 makes the result become a pixel
        from the given image, 0 doesn't change anything.
    
    <p>    The masks red, green and blue values are used separately.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>object image</tt>
      <dd>image to paste
    <dt><tt>object mask</tt>
      <dd>mask image
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>where to paste the image; default is 0,0
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.paste>Image.image-&gt;paste</link>, <link to=Image.image.paste_alpha>Image.image-&gt;paste_alpha</link> and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.polygone>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>polygone</tt> - fills an area with the current color
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object polygone(array(int|float)&nbsp;...&nbsp;curve)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    fills an area with the current color
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>array(int|float) curve</tt>
      <dd>curve(s), <tt>({x1,y1,x2,y2,...,xn,yn})</tt>,
         automatically closed.
    
    <p>     If any given curve is inside another, it
         will make a hole.
    </dl><p>
    
    <dt><encaps>NOTE</encaps><dd>
    This function is new (April-97) and rather untested.
    <p>
    
    <dt><encaps>RETURNS</encaps><dd>
    the current object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.box>Image.image-&gt;box</link> and <link to=Image.image.setcolor>Image.image-&gt;setcolor</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.rotate>
    <anchor name=Image.image.rotate_expand>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>rotate, rotate_expand</tt> - Rotates an image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object rotate(int|float&nbsp;angle)<br>
    object rotate(int|float&nbsp;angle, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object rotate_expand(int|float&nbsp;angle)<br>
    object rotate_expand(int|float&nbsp;angle, int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Rotates an image a certain amount of degrees (360° is 
         a complete rotation) counter-clockwise:
    <center>
    <image src=lenna.rs dpi=225 align=center>&nbsp;-&gt;&nbsp;<illustration align=center src=lenna.rs dpi=225>return src->rotate(45)</illustration><br>
    </center>
         The "expand" variant of functions stretches the 
         image border pixels rather then filling with 
         the given or current color.
    
    <p>     This rotate uses the skewx() and skewy() functions.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int|float angle</tt>
      <dd>the number of degrees to rotate
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color to fill with; default is current
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.scale>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>scale</tt> - scales the image by a given factor
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object scale(float&nbsp;factor)<br>
    object scale(0.5)<br>
    object scale(float&nbsp;xfactor, float&nbsp;yfactor)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    scales the image with a factor,
         0.5 is an optimized case.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>float factor</tt>
      <dd>factor to use for both x and y
    <dt><tt>float xfactor</tt>
    <dt><tt>float yfactor</tt>
      <dd>separate factors for x and y
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.scale>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>scale</tt> - scales the image to a specified new size
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object scale(int&nbsp;newxsize, int&nbsp;newysize)<br>
    object scale(0, int&nbsp;newysize)<br>
    object scale(int&nbsp;newxsize, 0)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    scales the image to a specified new size,
         if one of newxsize or newysize is 0,
         the image aspect ratio is preserved.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int newxsize</tt>
    <dt><tt>int newysize</tt>
      <dd>new image size in pixels
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.select_from>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>select_from</tt> - Makes a grey-scale image for alpha-channel use
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object select_from(int&nbsp;x, int&nbsp;y)<br>
    object select_from(int&nbsp;x, int&nbsp;y, int&nbsp;edge_value)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a grey-scale image, for alpha-channel use.
        
        This is very close to a flood fill.
        
        The image is scanned from the given pixel,
        filled with 255 if the color is the same,
        or 255 minus distance in the colorcube, squared, right-shifted
        8 steps (see <link to=Image.image.distancesq>Image.image-&gt;distancesq</link>).
    
    <p>    When the edge distance is reached, the scan is stopped.
        Default edge value is 30.
        This value is squared and compared with the square of the 
        distance above.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>originating pixel in the image
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.distancesq>Image.image-&gt;distancesq</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.setcolor>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>setcolor</tt> - set the current color
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object setcolor(int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object setcolor(int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    set the current color
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>new color
    <dt><tt>int alpha</tt>
      <dd>new alpha value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.setpixel>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>setpixel</tt> - set a pixel in the image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object setpixel(int&nbsp;x, int&nbsp;y)<br>
    object setpixel(int&nbsp;x, int&nbsp;y, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object setpixel(int&nbsp;x, int&nbsp;y, int&nbsp;r, int&nbsp;g, int&nbsp;b, int&nbsp;alpha)</tt>
    <p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
    <dt><tt>int y</tt>
      <dd>position of the pixel
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color
    <dt><tt>int alpha</tt>
      <dd>alpha value
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.skewx>
    <anchor name=Image.image.skewx_expand>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>skewx, skewx_expand</tt> - Skews an image an amount of pixels or a factor
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object skewx(int&nbsp;x)<br>
    object skewx(int&nbsp;yfactor)<br>
    object skewx(int&nbsp;x, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewx(int&nbsp;yfactor, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewx_expand(int&nbsp;x)<br>
    object skewx_expand(int&nbsp;yfactor)<br>
    object skewx_expand(int&nbsp;x, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewx_expand(int&nbsp;yfactor, int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Skews an image an amount of pixels or a factor;
         a skew-x is a transformation:
    <center>
    <image src=lenna.rs dpi=225 align=center>&nbsp;-&gt;&nbsp;<illustration align=center src=lenna.rs dpi=225>return src->skewx(0.3)</illustration><br>
    </center>
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x</tt>
      <dd>the number of pixels
         The "expand" variant of functions stretches the 
         image border pixels rather then filling with 
         the given or current color.
    <dt><tt>float yfactor</tt>
      <dd>best described as: x=yfactor*this->ysize()
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color to fill with; default is current
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.skewy>
    <anchor name=Image.image.skewy_expand>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>skewy, skewy_expand</tt> - Skews an image an amount of pixels or a factor
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object skewy(int&nbsp;y)<br>
    object skewy(int&nbsp;xfactor)<br>
    object skewy(int&nbsp;y, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewy(int&nbsp;xfactor, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewy_expand(int&nbsp;y)<br>
    object skewy_expand(int&nbsp;xfactor)<br>
    object skewy_expand(int&nbsp;y, int&nbsp;r, int&nbsp;g, int&nbsp;b)<br>
    object skewy_expand(int&nbsp;xfactor, int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Skews an image an amount of pixels or a factor;
         a skew-y is a transformation:
    <center>
    <image src=lenna.rs dpi=225 align=center>&nbsp;-&gt;&nbsp;<illustration align=center src=lenna.rs dpi=225>return src->skewy(0.3)</illustration><br>
    </center>
         The "expand" variant of functions stretches the 
         image border pixels rather then filling with 
         the given or current color.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int y</tt>
      <dd>the number of pixels
    <dt><tt>float xfactor</tt>
      <dd>best described as: t=xfactor*this->xsize()
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>color to fill with; default is current
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.to8bit>
    <anchor name=Image.image.to8bit_closest>
    <anchor name=Image.image.to8bit_fs>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>to8bit, to8bit_closest, to8bit_fs</tt> - Map image to 8-bit data
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string to8bit(array(array(int))&nbsp;colors)<br>
    string to8bit_fs(array(array(int))&nbsp;colors)<br>
    string to8bit_closest(array(array(int))&nbsp;colors)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps the image to the given colors and returns 
         the 8 bit data.
    
    <p>     to8bit_fs uses Floyd-Steinberg dithering
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the calculated string
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.to8bit_rgbcube>Image.image-&gt;to8bit_rgbcube</link>, <link to=Image.image.tozbgr>Image.image-&gt;tozbgr</link>, <link to=Image.image.map_fast>Image.image-&gt;map_fast</link>, <link to=Image.image.map_closest>Image.image-&gt;map_closest</link>, <link to=Image.image.select_colors>Image.image-&gt;select_colors</link> and <link to=Image.image.tobitmap>Image.image-&gt;tobitmap</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.to8bit_rgbcube>
    <anchor name=Image.image.to8bit_rgbcube_rdither>
    <anchor name=Image.image.tozbgr>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>to8bit_rgbcube, to8bit_rgbcube_rdither, tozbgr</tt> - Maps the image into a colorcube
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string tozbgr(array(array(int))&nbsp;colors)<br>
    string to8bit_rgbcube(int&nbsp;red, int&nbsp;green, int&nbsp;blue)<br>
    string to8bit_rgbcube(int&nbsp;red, int&nbsp;green, int&nbsp;blue, string&nbsp;map)<br>
    string to8bit_rgbcube_rdither(int&nbsp;red, int&nbsp;green, int&nbsp;blue)<br>
    string to8bit_rgbcube_rdither(int&nbsp;red, int&nbsp;green, int&nbsp;blue, string&nbsp;map)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps the image into a colorcube with the given 
         dimensions. Red is least significant, blue is most.
    
    <p>     The "rdither" type of method uses a random dither algorithm.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int red</tt>
    <dt><tt>int green</tt>
    <dt><tt>int blue</tt>
      <dd>The sides of the colorcube. Not the number of bits!
    <dt><tt>string map</tt>
      <dd>Map this position in the colorcube to another value,
         ie: say we have position red=1,green=2,blue=3 in a colorcube of
         6×6×6, we have the index 1+2*6+3*6*6=121. If the 
         map-string contains 'å' in position 121, the resulting
         byte is 'å' or 229.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the calculated string
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.tozbgr>Image.image-&gt;tozbgr</link>, <link to=Image.image.to8bit>Image.image-&gt;to8bit</link> and <link to=Image.image.tobitmap>Image.image-&gt;tobitmap</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.tobitmap>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>tobitmap</tt> - Maps the image to a bitmap
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string tobitmap();</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Maps the image to a bitmap.
    
    <p>     Bit 0 is the leftmost pixel, and the rows are aligned to 
         bytes.
    
    <p>     Any pixel value other then black results in a set bit.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    the calculated string
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.tozbgr>Image.image-&gt;tozbgr</link>, <link to=Image.image.to8bit>Image.image-&gt;to8bit</link>, <link to=Image.image.to8bit_rgbcube>Image.image-&gt;to8bit_rgbcube</link> and <link to=Image.image.cast>Image.image-&gt;cast</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.togif>
    <anchor name=Image.image.togif_fs>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>togif, togif_fs</tt> - Makes GIF data
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string togif()<br>
    string togif(int&nbsp;num_colors)<br>
    string togif(array(array(int))&nbsp;colors)<br>
    string togif(int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)<br>
    string togif(int&nbsp;num_colors, int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)<br>
    string togif(array(array(int))&nbsp;colors, int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)<br>
    string togif_fs()<br>
    string togif_fs(int&nbsp;num_colors)<br>
    string togif_fs(array(array(int))&nbsp;colors)<br>
    string togif_fs(int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)<br>
    string togif_fs(int&nbsp;num_colors, int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)<br>
    string togif_fs(array(array(int))&nbsp;colors, int&nbsp;trans_r, int&nbsp;trans_g, int&nbsp;trans_b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes GIF data. The togif_fs variant uses Floyd-Steinberg 
         dithering.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int num_colors</tt>
      <dd>number of colors to quantize to (default is 256) 
     array array(array(int)) colors
         colors to map to (default is to quantize to 256), format is ({({r,g,b}),({r,g,b}),...}).
    <dt><tt>int trans_r</tt>
    <dt><tt>int trans_g</tt>
    <dt><tt>int trans_b</tt>
      <dd>one color, that is to be transparent.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the GIF data
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.togif_begin>Image.image-&gt;togif_begin</link>, <link to=Image.image.togif_add>Image.image-&gt;togif_add</link>, <link to=Image.image.togif_end>Image.image-&gt;togif_end</link>, <link to=Image.image.toppm>Image.image-&gt;toppm</link> and <link to=Image.image.fromgif>Image.image-&gt;fromgif</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.image.toppm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>toppm</tt> - Return PPM (P6, binary pixmap) data from the Image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>string toppm()</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns PPM (P6, binary pixmap) data from the
         current image object.
    </p>
    <dt><encaps>RETURNS</encaps><dd>
    PPM data
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.frompnm>Image.image-&gt;frompnm</link> and <link to=Image.image.fromgif>Image.image-&gt;fromgif</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.treshold>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>treshold</tt> - Makes a black-white image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object treshold()<br>
    object treshold(int&nbsp;r, int&nbsp;g, int&nbsp;b)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a black-white image. 
    
    <p>     If all red, green, blue parts of a pixel
         is larger or equal then the given value, the pixel will become
         white, else black.
    
    <p>     This method works fine with the grey method.
    
    <p>     If no arguments are given, the current color is used 
         for treshold values.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int r</tt>
    <dt><tt>int g</tt>
    <dt><tt>int b</tt>
      <dd>red, green, blue threshold values
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the new image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.image.grey>Image.image-&gt;grey</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.tuned_box>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>tuned_box</tt> - Draws a filled rectangle with colors (and alpha values) tuned
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object tuned_box(int&nbsp;x1, int&nbsp;y1, int&nbsp;x2, int&nbsp;y2, array(array(int))&nbsp;corner_color)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Draws a filled rectangle with colors (and alpha values) tuned
         between the corners.
    
    <p>     Tuning function is (1.0-x/xw)*(1.0-y/yw) where x and y is
         the distance to the corner and xw and yw are the sides of the
         rectangle.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>int x1</tt>
    <dt><tt>int y1</tt>
    <dt><tt>int x2</tt>
    <dt><tt>int y2</tt>
      <dd>rectangle corners
    <dt><tt>array(array(int)) corner_color</tt>
      <dd>colors of the corners:
         <pre>
         ({x1y1,x2y1,x1y2,x2y2})
         </pre>
         each of these is an array of integers:
         <pre>
         ({r,g,b}) or ({r,g,b,alpha})
         </pre>
         Default alpha channel value is 0 (opaque).
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    the object called
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.xsize>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>xsize</tt> - return the width of the image in pixels
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>int xsize()</tt>
    <p>
    <dt><encaps>RETURNS</encaps><dd>
    the width of the image in pixels
    <p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.image.ysize>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>ysize</tt> - the height of the image in pixels
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>int ysize()</tt>
    <p>
    <dt><encaps>RETURNS</encaps><dd>
    the height of the image
    <p>
    </dl>
    </anchor>
    <hr newpage>
    </section>
    
    <section title="Image.font">
    
    <dl><dd>
    This object adds the text-drawing and -creation
         capabilities of the <link to=Image>Image</link> module.
    
    <p>     For simple usage, see
         <link to=Image.font.write>Image.font-&gt;write</link> and <link to=Image.font.load>Image.font-&gt;load</link>.
    
    <p>     other methods: <link to=Image.font.baseline>Image.font-&gt;baseline</link>,
         <link to=Image.font.height>Image.font-&gt;height</link>,
         <link to=Image.font.set_xspacing_scale>Image.font-&gt;set_xspacing_scale</link>,
         <link to=Image.font.set_yspacing_scale>Image.font-&gt;set_yspacing_scale</link>,
         <link to=Image.font.text_extents>Image.font-&gt;text_extents</link>
    </dl>
    
    
    <encaps>NOTE</encaps>
    <dl><dd>
    Short technical documentation on a font file:
         <pre>
                struct file_head 
                {
                   unsigned INT32 cookie;   - 0x464f4e54 
                   unsigned INT32 version;  - 1 
                   unsigned INT32 chars;    - number of chars
                   unsigned INT32 height;   - height of font
                   unsigned INT32 baseline; - font baseline
                   unsigned INT32 o[1];     - position of char_head's
                } *fh;
                struct char_head
                {
                   unsigned INT32 width;    - width of this character
                   unsigned INT32 spacing;  - spacing to next character
                   unsigned char data[1];   - pixmap data (1byte/pixel)
                } *ch;
         </pre>
    </dl>
    
    
    <encaps>SEE ALSO</encaps>
    <dl><dd>     <link to=Image>Image</link>,
         <link to=Image.image>Image.image</link>
    </dl>
    
    <hr>
    <anchor name=Image.font.baseline>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>baseline</tt> - Return the font baseline
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>int baseline()</tt>
    <p>
    <dt><encaps>RETURNS</encaps><dd>
    font baseline (pixels from top)
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.font.height>Image.font-&gt;height</link> and <link to=Image.font.text_extents>Image.font-&gt;text_extents</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.font.height>
    <anchor name=Image.font.text_extents>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>height, text_extents</tt> - Calculate extents of a text-image
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>int height()<br>
    array(int) text_extents(string&nbsp;text, ...)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Calculate extents of a text-image,
         that would be created by calling <link to=Image.font.write>Image.font-&gt;write</link>
         with the same arguments.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>string text, ...</tt>
      <dd>One or more lines of text.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    an array of width and height
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.font.write>Image.font-&gt;write</link>, <link to=Image.font.height>Image.font-&gt;height</link> and <link to=Image.font.baseline>Image.font-&gt;baseline</link>
    </p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.font.load>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>load</tt> - Loads a font file to this font object
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object|int load(string&nbsp;filename)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Loads a font file to this font object.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>string filename</tt>
      <dd>Font file
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    zero upon failure, font object upon success
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.font.write>Image.font-&gt;write</link>
    </p>
    </dl>
    </anchor>
    
    <hr>
    <anchor name=Image.font.set_xspacing_scale>
    <anchor name=Image.font.set_yspacing_scale>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>set_xspacing_scale, set_yspacing_scale</tt> - Set character spacing
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>void set_xspacing_scale(float&nbsp;scale)<br>
    void set_yspacing_scale(float&nbsp;scale)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Set spacing scale to write characters closer
         or more far away. This does not change scale
         of character, only the space between them.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>float scale</tt>
      <dd>what scale to use
    
    </dl><p>
    </dl>
    </anchor>
    </anchor>
    
    <hr>
    <anchor name=Image.font.write>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>write</tt> - Writes some text
    <p><dt><encaps>SYNTAX</encaps><dd>
    <tt>object write(string&nbsp;text, ...)</tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Writes some text; thus creating an image object
         that can be used as mask or as a complete picture.
    </p>
    <dt><encaps>ARGUMENTS</encaps><dd><dl>
    <dt><tt>string text, ...</tt>
      <dd>One or more lines of text.
    
    </dl><p>
    <dt><encaps>RETURNS</encaps><dd>
    an Image::image object
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Image.font.text_extents>Image.font-&gt;text_extents</link>, <link to=Image.font.load>Image.font-&gt;load</link>, <link to=Image.image.paste_mask>Image.image-&gt;paste_mask</link> and <link to=Image.image.paste_alpha_color>Image.image-&gt;paste_alpha_color</link>
    </p>
    </dl>
    </anchor>
    <hr newpage>
    </section>
    </chapter>
    </anchor>
    
    <chapter title="The preprocessor">
    <anchor name=preprocessor>
    Pike has a builtin C-style preprocessor. The preprocessor reads the source
    before it is compiled and removes comments and expands macros. The preprocessor
    can also remove code depending on an expression that is evaluated when you
    compile the program. The preprocessor helps to keep your programming abstract
    by using defines instead of writing the same constant everywhere. 
    <p>
    It currently works similar to old C preprocessors but has a few extra features.
    This chapter describes the different preprocessor directives. This is
    what it can do:
    
    <hr noshade size=1>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#!<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This directive is in effect a comment statement, since the
    preprocessor will ignore everything to the end of the line.
    This is used to write Unix type scripts in Pike by starting
    the script with
    <p>#!/usr/local/bin/pike
    
    <p>
    </dl>
    
    <hr noshade size=1>
    <anchor name=define>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#define<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The simplest way to use define is to write
    <p><dl><dt><dd>#define &lt;identifier&gt; &lt;replacement string&gt;<br>
    </dl>
    <p>which will cause all subsequent occurrences of 'identifier' to be
    replaced with the replacement string.
    <p>Define also has the capability to use arguments, thus a line like
    <p><dl><dt><dd>#define &lt;identifier&gt;(arg1, arg2) &lt;replacement string&gt;<br>
    </dl>
    <p>would cause identifier to be a macro. All occurrences of
    'identifier(something1,something2d)' would be replaced with
    the replacement string. And in the replacement string, arg1 and arg2
    will be replaced with something1 and something2.
    <p>
    <dt><encaps>BUGS</encaps><dd>
    Note that it is not a good idea to do something like this:
    <p>#define foo bar // a comment
    <p>The comment will be included in the define, and thus inserted in the
    code. This will have the effect that the rest of the line will be
    ignored when the word foo is used. Not exactly what you might expect.
    <dt><encaps>EXAMPLE</encaps><dd>
    <example language=pike>
    #define A "test"
    #define B 17
    #define C(X) (X)+(B)+"\n"
    #define W write
    #define Z Stdio.stdout
    int main()
    {
      Z->W(C(A));
    }
    </example>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=undef>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#undef<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This removes the effect of a #define, all subsequent occurrences of
    the undefined identifier will not be replaced by anything. Note that
    when undefining a macro, you just give the identifier, not the
    arguments.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>#define foo bar<br>
    #undef foo<br>
    #define foo(bar) gazonk bar<br>
    #undef foo<br>
    <br>
    </tt>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=if>
    <anchor name=elseif>
    <anchor name=else>
    <anchor name=endif>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#if<br>
    #elif<br>
    #elseif<br>
    #else<br>
    #endif<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The #if directive causes conditional compiling of code depending on
    the expression after the #if directive. That is, if the expression
    is true, the code up to the next #else, #elif, #elseif or #endif is
    compiled. If the expression is false, that code will be skipped.
    If the skip leads up to a #else, the code after the else will be
    compiled. #elif and #elseif are equivalent and causes the code that
    follow them to be compiled if the previous #if or #elif evaluated
    false and the expression after the #elif evaluates true.
    <p>Expressions given to #if, #elif or #endif are special, all identifiers
    evaluate to zero unless they are defined to something else. Integers,
    strings and floats are the only types that can be used, but all pike
    operators can be used on these types.
    <p>
    Also, two special functions can be used, <tt>defined()</tt> and <tt>constant()</tt>.
    <tt>defined(<i>identifier</i>)</tt> expands to 1 if <i>identifier</i> is defined and
    0 otherwise. <tt>constant(<i>identifier</i>)</tt> expands to 1 if <i>identifier</i> is
    an predefined constant (with add_constant), 0 otherwise.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>#if 1<br>
    <dl><dt><dd>write("foo");<br>
    </dl>#else<br>
    <dl><dt><dd>write("bar");<br>
    </dl>#endif<br>
    
    <p>#if defined(FOO)<br>
    <dl><dt><dd>write(FOO);<br>
    </dl>#elif defined(BAR)<br>
    <dl><dt><dd>write(BAR);<br>
    </dl>#else<br>
    <dl><dt><dd>write("default");<br>
    </dl>#endif<br>
    
    <p>#if !constant(write_file)<br>
    inherit "simulate.pike"<br>
    #endif<br>
    <br>
    </tt>
    <p>
    </dl>
    
    </anchor>
    </anchor>
    </anchor>
    </anchor>
    <hr noshade size=1>
    <anchor name=error>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#error<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This directive causes a compiler error, it can be used to notify
    the user that certain functions are missing and similar things.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>#if !constant(write_file)<br>
    #error write_file function is missing<br>
    #endif<br>
    <br>
    </tt>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=include>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#include<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This directive should be given a file as argument, it will then be
    compiled as if all those lines were written at the #include line.
    The compiler then continues to compile this file.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>#include "foo.h"<br>
    <br>
    </tt>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=line>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#line<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This directive tells the compiler what line and file we are compiling.
    This is for instance used by the #include directive to tell the
    compiler that we are compiling another file. The directive takes
    the line number first, and optionally, the file afterwards.
    <p>This can also be used when generating Pike from something else, to
    tell the compiler where the code originally originated from.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>#line 4 "foo.cf" /* The next line was generated from 4 in foo.cf */<br>
    <br>
    </tt>
    <p>
    </dl>
    
    </anchor>
    <hr noshade size=1>
    <anchor name=pragma>
    <dl>
    <dt><encaps>DIRECTIVE</encaps><dd>
    <tt>#pragma<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This is a generic directive for flags to the compiler. Currently, the
    only flag available is 'all_inline' which is the same as adding the
    modifier 'inline' to all functions that follows.
    
    <p>
    </dl>
    
    </anchor>
    
    </anchor>
    
    </chapter>
    
    <chapter title="All the builtin functions" name=functions>
    
    This chapter is a reference for all the builtin functions in Pike.
    They are listed in alphabetical order.
    
    <HR NEWPAGE>
    <anchor name=_memory_usage>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>_memory_usage</tt> - check memory usage
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:int) <I>_memory_usage</I>();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is mostly intended for debugging. It delivers a mapping
    with information about how many arrays/mappings/strings etc. there
    are currently allocated and how much memory they use. Try evaluating
    the function in hilfe to see precisely what it returns.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=_verify_internals>_verify_internals</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=_next>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>_next</tt> - find the next object/array/whatever
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed _next(mixed <I>p</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    All objects, arrays, mappings, multisets, programs and strings are stored in linked lists
    inside Pike. This function returns the next object/array/mapping/string/etc
    in the linked list. It is mainly meant for debugging Pike but
    can also be used to control memory usage.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=next_object>next_object</link> and <link to=_prev>_prev</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=_prev>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>_prev</tt> - find the previous object/array/whatever
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed _next(mixed <I>p</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the 'previous' object/array/mapping/etc
    in the linked list. It is mainly meant for debugging Pike but
    can also be used to control memory usage. Note that this function
    does not work on strings.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=_next>_next</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=_refs>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>_refs</tt> - find out how many references a pointer type value has
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int _refs(string|array|mapping|multiset|function|object|program <I>o</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function checks how many references the value <i>o</i> has.
    Note that the number of references will always be at least one since
    the value is located on the stack when this function is executed.
    _refs() is mainly meant for debugging Pike but
    can also be used to control memory usage.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=_next>_next</link> and <link to=_prev>_prev</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=_verify_internals>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>_verify_internals</tt> - check Pike internals
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void _verify_internals();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function goes through most of the internal Pike structures and
    generates a fatal error if one of them is found to be out of order.
    It is only used for debugging.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=acos>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>acos</tt> - Trigonometrical inverse cosine
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float acos(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return the arcus cosine value for <i>f</i>.
    The result will be in radians.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=cos>cos</link> and <link to=asin>asin</link>
    <p>
    </dl>
    </anchor>
    
    
    
    <HR NEWPAGE>
    <anchor name=add_constant>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>add_constant</tt> - add new predefined functions or constants
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void add_constant(string <I>name</I>, mixed <I>value</I>);<br>
    or<br>
    void add_constant(string <I>name</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function adds a new constant to Pike, it is often used to
    add builtin functions. All programs compiled after add_constant
    function is called can access 'value' by the name given by 'name'.
    If there is a constant called 'name' already, it will be replaced by
    by the new definition. This will not affect already compiled programs.
    <p>
    Calling add_constant without a value will remove that name from the list
    of constants. As with replacing, this will not affect already compiled
    programs.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>add_constant("true",1);<br>
    add_constant("false",0);<br>
    add_constant("PI",4.0);<br>
    add_constant("sqr",lambda(mixed x) { return x * x; });<br>
    add_constant("add_constant");<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=all_constants>all_constants</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=add_include_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>add_include_path</tt> - add a directory to search for include files
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void add_include_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function adds another directory to the search for include files.
    This is the same as the command line option <tt>-I</tt>. Note that
    the added directory will only be searched when using &lt;&nbsp;&gt; to
    quote the included file.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=remove_include_path>remove_include_path</link> and <link to=include>#include</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=add_module_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>add_module_path</tt> - add a directory to search for modules
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void add_module_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function adds another directory to the search for modules.
    This is the same as the command line option <tt>-M</tt>. For more
    information about modules, see <ref to=modules>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=remove_module_path>remove_module_path</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=add_program_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>add_program_path</tt> - add a directory to search for modules
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void add_program_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function adds another directory to the search for programs.
    This is the same as the command line option <tt>-P</tt>. For more
    information about programs, see <ref to=programs>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=remove_program_path>remove_program_path</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=aggregate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>aggregate</tt> - construct an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *aggregate(mixed ... <I>elems</I>);<br>
    or<br>
    ({ elem1, elem2, ... })<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Construct an array with the arguments as indices. This function
    could be written in Pike as:
    <p>mixed *aggregate(mixed ... elems) { return elems; }
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Arrays are dynamically allocated there is no need to declare them
    like int a[10]=allocate(10); (and it isn't possible either) like
    in C, just int *a=allocate(10); will do.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>, <link to=arrayp>arrayp</link> and <link to=allocate>allocate</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=aggregate_mapping>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>aggregate_mapping</tt> - construct a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping aggregate_mapping(mixed ... <I>elems</I>);<br>
    or<br>
    ([ key1:val1, key2:val2, ... ])<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Groups the arguments together two and two to key-index pairs and
    creates a mapping of those pairs. The second syntax is always
    preferable.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>, <link to=mappingp>mappingp</link> and <link to=mkmapping>mkmapping</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=aggregate_multiset>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>aggregate_multiset</tt> - construct a multiset
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>multiset aggregate_multiset(mixed ... <I>elems</I>);<br>
    or<br>
    (&lt; elem1, elem2, ... &gt;)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Construct a multiset with the arguments as indexes. This function
    could be written in Pike as:
    <p>multiset aggregate(mixed ... elems) { return mkmultiset(elems); }
    <p>The only problem is that mkmultiset is implemented using
    aggregate_multiset...
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>, <link to=multisetp>multisetp</link> and <link to=Simulate.mkmultiset>Simulate.mkmultiset</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=alarm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>alarm</tt> - set an alarm clock for delivery of a signal
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int alarm(int <I>seconds</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    <tt>alarm</tt> arranges for a SIGALRM signal to be delivered to the
    process <!-- hedda: Menar du process eller thread? Lite mer förklaring, tack.  hubbe: det st}r process, vad tror du jag menar??? -->in <i>seconds</i> seconds.
    <p>
    If <i>seconds</i> is zero, no new alarm is scheduled.
    <p>
    In any event any previously set alarm is canceled.
    <p>
    <dt><encaps>RETURN VALUE</encaps><dd>
    <tt>alarm</tt> returns the number of seconds remaining until any
    previously  scheduled  alarm  was  due to be delivered, or
    zero if there was no previously scheduled alarm.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=all_constants>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>all_constants</tt> - return all predefined constants
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping (string:mixed) <I>all_constant</I>();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a mapping containing all constants, indexed on the names of the
    constant, and with the value of the efun as argument.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=add_constant>add_constant</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=allocate>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>allocate</tt> - allocate an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *allocate(int <I>size</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Allocate an array of size elements and initialize them to zero.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>mixed *a=allocate(17);<br>
    </tt>
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    Arrays are dynamically allocated there is no need to declare them
    like <tt>int a[10]=allocate(10);</tt> (and it is not possible either) like
    in C, just <tt>array(int) a=allocate(10);</tt> will do.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>, <link to=aggregate>aggregate</link> and <link to=arrayp>arrayp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=arrayp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>arrayp</tt> - is the argument an array?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int arrayp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is an array, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=allocate>allocate</link>, <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=floatp>floatp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=multisetp>multisetp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=asin>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>asin</tt> - Trigonometrical inverse sine
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float asin(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the arcus sinus value for <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sin>sin</link> and <link to=acos>acos</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=atan>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>atan</tt> - Trigonometrical inverse tangent
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float atan(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the arcus tangent value for <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=tan>tan</link>, <link to=asin>asin</link> and <link to=acos>acos</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=backtrace>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>backtrace</tt> - get a description of the call stack
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(array) backtrace();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns a description of the call stack at this moment.
    The description is returned in an array with one entry for each call
    in the stack. Each entry has this format:
    <p>({<br>
    <dl><dt><dd><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> file, </td><td> /* a string with the filename if known, else zero */ </td></tr>
    <tr valign=top><td> line, </td><td> /* an integer containing the line if known, else zero */ </td></tr>
    <tr valign=top><td> function, </td><td> /* The function pointer to the called function */ </td></tr>
    <tr valign=top><td> mixed|void ..., </td><td> /* The arguments the function was called with */ </td></tr>
    </table>
    </dl>})<br>
    
    <p>The current call frame will be last in the array, and the one above
    that the last but one and so on.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=catch>catch</link> and <link to=throw>throw</link>
    <p>
    </dl>
    </anchor>
    <HR NEWPAGE>
    <anchor name=call_function>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>call_function</tt> - call a function with arguments
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed call_function(function <I>fun</I>,mixed ... <I>args</I>);<br>
    or<br>
    mixed fun ( mixed ... <I>args</I> );<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function takes a function pointer as first argument and calls
    this function with the rest of the arguments as arguments. Normally,
    you will never have to write call_function(), because you will use the
    second syntax instead.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=backtrace>backtrace</link> and <link to=Simulate.get_function>Simulate.get_function</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=call_out>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>call_out</tt> - make a delayed call to a function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed call_out(function <I>f</I>, int <I>delay</I>, mixed ... <I>args</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Call_out places a call to the function <i>f</i> with the argument <i>args</i>
    in a queue to be called in about delay seconds. The return value
    identifies this call out. The return value can be sent to
    find_call_out or remove_call_out to remove the call out again.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=remove_call_out>remove_call_out</link>, <link to=find_call_out>find_call_out</link> and <link to=call_out_info>call_out_info</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=call_out_info>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>call_out_info</tt> - get info about all call outs
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed **call_out_info();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns an array with one entry for each entry in the
    call out queue. The first in the queue will be in index 0. Each index
    contains an array that looks like this:
    <p>({<br>
    <dl><dt><dd><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> time_left, </td><td> /* an int */ </td></tr>
    <tr valign=top><td> caller, </td><td> /* the object that made the call out */ </td></tr>
    <tr valign=top><td> function, </td><td> /* the function to be called */ </td></tr>
    <tr valign=top><td> arg1, </td><td> /* the first argument, if any */ </td></tr>
    <tr valign=top><td> arg2, </td><td> /* the second argument, if any */ </td></tr>
    <tr valign=top><td> ...   </td><td> /* and so on... */ </td></tr>
    </table>
    </dl>})<br>
    
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=call_out>call_out</link>, <link to=find_call_out>find_call_out</link> and <link to=remove_call_out>remove_call_out</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=_do_call_outs>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    	<tt>_do_call_outs</tt> - do all pending call_outs.
    
    <dt><encaps>SYNTAX</encaps><dd>
    	<tt>void _do_call_out();</tt>
    
    <dt><encaps>DESCRIPTION</encaps><dd>
    <dd>        This function runs all pending call_outs that should have been
            run if Pike returned to the backend.  It should not be used in
            normal operation.
    <p>
    	As a side-effect, this function sets the value returned by
    	<tt>time(1)</tt> to the current time.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=call_out>call_out</link>, <link to=find_call_out>find_call_out</link> and <link to=remove_call_out>remove_call_out</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=catch>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>catch</tt> - catch errors
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>catch { commands }<br>
    or<br>
    catch ( expression )<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    catch traps exceptions such as run time errors or calls to throw() and
    returns the argument given to throw. For a run time error, this value
    is ({ "error message", backtrace }) 
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=throw>throw</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=cd>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>cd</tt> - change directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int cd(string <I>s</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Change the current directory for the whole Pike process, return
    1 for success, 0 otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getcwd>getcwd</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=ceil>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>ceil</tt> - Truncate a number upward
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float ceil(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return the closest integer value higher or equal to <i>f</i>.
    Note that <tt>ceil()</tt> does <strong>not</strong> return an int, merely an integer value stored in a float.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=floor>floor</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=clone>
    <anchor name=new>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>clone</tt> - clone an object from a program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object clone(program <I>p</I>,mixed ... <I>args</I>);</tt><br>
    or<br>
    <tt>object new(program <I>p</I>,mixed ... <I>args</I>);</tt><br>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    <tt>new()</tt> or <tt>clone()</tt> creates an object from the program <i>p</i>. Or in C++ terms:
    It creates an instance of the class <i>p</i>. This clone will first have
    all global variables initialized, and then <tt>create()</tt> will be called
    with <i>args</i> as arguments.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=destruct>destruct</link>, <link to=compile_string>compile_string</link> and <link to=compile_file>compile_file</link>
    <p>
    </dl>
    </anchor>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=column>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>column</tt> - extract a column
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array column(mixed *data,mixed index)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is exactly equivalent to:
    <example language=pike>
    map_array(data, lambda(mixed x,mixed y) { return x[y]; }, index)
    </example>
    Except of course it is a lot shorter and faster.
    That is, it indexes every index in the array data on the value of
    the argument index and returns an array with the results.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <pre>
    	&gt; column( ({ ({1,2}), ({3,4}), ({5,6}) }), 1)
    	Result: ({2, 4, 6})
    </pre>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=rows>rows</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=combine_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>combine_path</tt> - concatenate paths
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string combine_path(string <I>absolute</I>, string <I>relative</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Concatenate a relative path to an absolute path and remove any
    "//", "/.." or "/." to produce a straightforward absolute path
    as a result.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>&gt; combine_path("/foo/bar/","..");<br>
    Result: /foo<br>
    &gt; combine_path("/foo/bar/","../apa.c");<br>
    Result: /foo/apa.c<br>
    &gt; combine_path("/foo/bar","./sune.c");<br>
    Result: /foo/bar/sune.c<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getcwd>getcwd</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=compile_file>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>compile_file</tt> - compile a file to a program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>program compile_file(string <I>filename</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function will compile the file <i>filename</i> to a Pike program that can
    later be used for cloning.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link> and <link to=compile_string>compile_string</link>
    <p>
    </dl>
    </anchor>
    <HR NEWPAGE>
    <anchor name=compile_string>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>compile_string</tt> - compile a string to a program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>program compile_string(string <I>prog</I>, string <I>name</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    <tt>compile_string()</tt> takes a piece of Pike code as a string and
    compiles it into a clonable program. Note that <i>prog</i> must contain
    the complete source for a program. You can not compile a single expression
    or statement.The second argument will be used as the file name of the
    program and will be used for error messages and such.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=compile_string>compile_string</link> and <link to=clone>clone</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=copy_value>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>copy_value</tt> - copy a value recursively
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed copy_value(mixed <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Copy value will copy the value given to it recursively. If the result
    value is changed destructively (only possible for multisets, arrays and
    mappings) the copied value will not be changed. The resulting value
    will always be equal to the copied (tested with the efun equal), but
    they may not the the same value. (tested with ==)
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=equal>equal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=cos>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>cos</tt> - Trigonometrical cosine
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float cos(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the cosine value for <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=acos>acos</link> and <link to=sin>sin</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=crypt>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>crypt</tt> - crypt a password
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string crypt(string <I>password</I>);<br>
    or<br>
    int crypt(string <I>typed_password</I>, string <I>crypted_password</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function crypts and verifies a short string. (normally only
    the first 8 characters are significant) The first syntax crypts
    the string password into something that is hopefully hard to decrypt,
    and the second function crypts the first string and verifies that the
    crypted result matches the second argument and returns 1 if they
    matched, 0 otherwise.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>To crypt a password use:<br>
    <dl><dt><dd>crypted_password = crypt(typed_password);<br>
    </dl>To see if the same password was used again use:<br>
    <dl><dt><dd>matched = crypt(typed_password, crypted_password);<br>
    </dl>
    </tt>
    </dl>
    
    </anchor>
    <HR NEWPAGE>
    <anchor name=ctime>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>ctime</tt> - convert time int to readable date string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string ctime(int <I>current_time</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Convert the output from a previous call to time() into a readable
    string containing the current year, month, day and time.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; ctime(time());<br>
    Result: Wed Jan 14 03:36:08 1970<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=time>time</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=decode_value>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>decode_value</tt> - code a value into a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed decode_value(string <I>coded_value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function takes a string created with encode_value() and converts
    it back to the value that was coded. 
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=encode_value>encode_value</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=describe_backtrace>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>describe_backtrace</tt> - make a backtrace readable
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string describe_backtrace(mixed **<I>backtrace</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Describe backtrace returns a string containing a readable message
    that describes where the backtrace was made. The argument 'backtrace'
    should normally be the return value from a call to backtrace()
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=backtrace>backtrace</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=destruct>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>destruct</tt> - destruct an object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void destruct(object <I>o</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Destruct marks an object as destructed, all pointers and function
    pointers to this object will become zero. The destructed object will
    be freed from memory as soon as possible. This will also call
    o-&gt;destroy.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=encode_value>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>encode_value</tt> - code a value into a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string encode_value(mixed <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function takes a value, and converts it to a string. This string
    can then be saved, sent to another Pike process, packed or used in
    any way you like. When you want your value back you simply send this
    string to decode_value() and it will return the value you encoded.
    <p>
    Almost any value can be coded, mappings, floats, arrays, circular
    structures etc. At present, objects, programs and functions cannot be
    saved in this way. This is being worked on.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=encode_value>decode_value</link> and <link to=sprintf>sprintf</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=equal>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>equal</tt> - check if two values are equal or not
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int equal(mixed <I>a</I>, mixed <I>b</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function checks if the values a and b are equal. For all types but
    arrays, multisets and mappings, this operation is the same as doing a == b.
    For arrays, mappings and multisets however, their contents are checked
    recursively, and if all their contents are the same and in the same
    place, they are considered equal.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>&gt; ({ 1 }) == ({ 1 });<br>
    Result: 0<br>
    &gt; equal( ({ 1 }), ({ 1 }) );<br>
    Result: 1<br>
    &gt; <br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=copy_value>copy_value</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=errno>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>errno</tt> - return system error number
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int errno();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the system error from the last file operation.
    Note that you should normally use the function errno in the file
    object instead.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=errno>errno</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=exece>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>exece</tt> - execute a program
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int exece(string <I>file</I>, array(string) <I>args</I>);<br>
    or<br>
    int exece(string <I>file</I>, array(string) <I>args</I>, mapping(string:string) <I>env</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function transforms the Pike process into a process running
    the program specified in the argument 'file' with the argument 'args'.
    If the mapping 'env' is present, it will completely replace all
    environment variables before the new program is executed.
    This function only returns if something went wrong during exece(),
    and in that case it returns zero.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    The Pike driver _dies_ when this function is called. You must use
    fork() if you wish to execute a program and still run the Pike
    driver.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>exece("/bin/ls", ({"-l"}));<br>
    exece("/bin/sh", ({"-c", "echo $HOME"}), (["HOME":"/not/home"]));<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=fork>fork</link> and <link to=Stdio.File.pipe>file-&gt;pipe</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=exit>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>exit</tt> - exit Pike interpreter
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void exit(int <I>returncode</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function exits the whole Pike program with the return code
    given. Using exit() with any other value than 0 indicates that
    something went wrong during execution. See your system manuals for
    more information about return codes.
    
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=exp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>exp</tt> - Natural exponent
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float exp(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return the natural exponent of <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=pow>pow</link> and <link to=log>log</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=file_stat>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>file_stat</tt> - stat a file
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int *file_stat(string <I>file</I>);<br>
    or<br>
    int *file_stat(string <I>file</I>, <I>1</I>);<br>
    or<br>
    int *file-&gt;stat();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    file_stat returns an array of integers describing some properties<br>
    about the file. Currently file_stat returns 7 entries:<br>
    ({<br>
    <dl><dt><dd><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> mode, </td><td> /* file mode, protection bits etc. etc. */ </td></tr>
    <tr valign=top><td> size, </td><td> /* file size for regular files,            -2 for dirs,            -3 for links,            -4 for otherwise */ </td></tr>
    <tr valign=top><td> atime, </td><td> /* last access time */ </td></tr>
    <tr valign=top><td> mtime, </td><td> /* last modify time */ </td></tr>
    <tr valign=top><td> ctime, </td><td> /* last status time change */ </td></tr>
    <tr valign=top><td> uid,   </td><td> /* The user who owns this file */ </td></tr>
    <tr valign=top><td> gid    </td><td> /* The group this file belongs to */ </td></tr>
    </table>
    </dl>})<br>
    If you give 1 as a second argument, file_stat does not follow links.<br>
    You can never get -3 as size if you don't give a second argument.<br>
    
    <p>If there is no such file or directory, zero is returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=get_dir>get_dir</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=find_call_out>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>find_call_out</tt> - find a call out in the queue
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int find_call_out(function <I>f</I>);<br>
    or<br>
    int find_call_out(mixed <I>id</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function searches the call out queue. If given a function as
    argument, it looks for the first call out scheduled to that function.
    The argument can also be a call out id as returned by call_out, in
    which case that call_out will be found. (Unless it has already been
    called.) find_call_out will then return how many seconds remains
    before that call will be executed. If no call is found,
    zero_type(find_call_out(f)) will return 1.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=call_out>call_out</link>, <link to=remove_call_out>remove_call_out</link> and <link to=call_out_info>call_out_info</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=floatp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>floatp</tt> - is the argument a float?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int floatp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a float, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=arrayp>arrayp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=multisetp>multisetp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=floor>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>floor</tt> - Truncate a number downward
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float floor(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return the closest integer value lower or equal to <i>f</i>.
    Note that floor() does <strong>not</strong> return an int, merely an integer value stored in a float.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=ceil>ceil</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=fork>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>fork</tt> - fork the process in two
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int fork();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Fork splits the process in two, and for the parent it returns the
    pid of the child. Refer to your Unix manual for further details.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function cause endless bugs if used without proper care.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Process.exec>Process.exec</link> and <link to=Stdio.File.pipe>Stdio.File-&gt;pipe</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=function_name>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>function_name</tt> - return the name of a function, if known
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string function_name(function <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the name of the function <i>f</i>. If the function is
    a pre-defined function in the driver, zero will be returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=function_object>function_object</link> and <link to=Simulate.get_function>Simulate.get_function</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=function_object>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>function_object</tt> - return what object a function is in
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object function_object(function <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Function_object will return the object the function <i>f</i> is in. If the
    function is a predefined function from the driver, zero will be
    returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=function_name>function_name</link> and <link to=Simulate.get_function>Simulate.get_function</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=functionp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>functionp</tt> - is the argument a function?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int functionp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a function, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=arrayp>arrayp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=multisetp>multisetp</link> and <link to=floatp>floatp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=gc>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>gc</tt> - do garbage collection
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int gc();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function checks all the memory for cyclic structures such
    as arrays containing themselves and frees them if appropriate.
    It also frees up destructed objects. It then returns how many
    arrays/objects/programs/etc. it managed to free by doing this.
    Normally there is no need to call this function since Pike will
    call it by itself every now and then. (Pike will try to predict
    when 20% of all arrays/object/programs in memory is 'garbage'
    and call this routine then.)
    
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=get_dir>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>get_dir</tt> - read a directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array(string) get_dir(string <I>dirname</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns an array of all filenames in the directory <i>dirname</i>, or zero if
    no such directory exists.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=mkdir>mkdir</link> and <link to=cd>cd</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=getcwd>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getcwd</tt> - return current working directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string getcwd();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    getcwd returns the current working directory.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=cd>cd</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=getenv>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getenv</tt> - get an environment variable
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string getenv(string <I>varname</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the value of the environment variable with the name <i>varname</i>,
    if no such environment variable exists, zero is returned.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function is provided by master.pike
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=getpid>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>getpid</tt> - get the process id of this process
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int getpid();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This returns the pid of this process. Useful for sending
    signals to yourself.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=kill>kill</link>, <link to=fork>fork</link> and <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=glob>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>glob</tt> - match strings against globs
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int glob(string <I>glob</I>, string <I>str</I>);<br>
    or<br>
    array(string) glob(string <I>glob</I>, array(string) <I>arr</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function matches "globs". In a glob string a question sign
    matches any character and an asterisk matches any string. When
    given two strings as argument a true/false value is returned
    which reflects if the <i>str</i> matches <i>glob</i>. When given an array as
    second argument, an array containing all matching strings is returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sscanf>sscanf</link> and <link to=Regexp.regexp>Regexp.regexp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=hash>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>hash</tt> - hash a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int hash(string <I>s</I>);<br>
    or<br>
    int hash(string <I>s</I>, int <I>max</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function will return an int derived from the string s. The same
    string will always hash to the same value. If a second argument
    is given, the result will be &gt;= 0 and lesser than that argument.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=indices>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>indices</tt> - return an array of all index possible for a value
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *indices(string|array|mapping|multiset|object <I>foo</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    <tt>indices</tt> returns an array of all values you can use as index when
    indexing <i>foo</i>. For strings and arrays this is simply an array of the
    ascending numbers. For mappings and multisets, the array may contain any
    kind of value. For objects, the result is an array of strings.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=values>values</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=intp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>intp</tt> - is the argument an int?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array intp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is an int, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=arrayp>arrayp</link>, <link to=programp>programp</link>, <link to=floatp>floatp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=multisetp>multisetp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=kill>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>kill</tt> - send signal to other process
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int kill(int pid, int signal)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Kill sends a signal to another process. If something goes wrong
    -1 is returned, 0 otherwise.
    <p>Some signals and their supposed purpose:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> SIGHUP   </td><td> Hang-up, sent to process when user logs out </td></tr>
    <tr valign=top><td> SIGINT   </td><td> Interrupt, normally sent by ctrl-c </td></tr>
    <tr valign=top><td> SIGQUIT  </td><td> Quit, sent by ctrl-\ </td></tr>
    <tr valign=top><td> SIGILL   </td><td> Illegal instruction </td></tr>
    <tr valign=top><td> SIGTRAP  </td><td> Trap, mostly used by debuggers </td></tr>
    <tr valign=top><td> SIGABRT  </td><td> Aborts process, can be caught, used by Pike whenever something         goes seriously wrong. </td></tr>
    <tr valign=top><td> SIGBUS   </td><td> Bus error </td></tr>
    <tr valign=top><td> SIGFPE   </td><td> Floating point error (such as division by zero) </td></tr>
    <tr valign=top><td> SIGKILL  </td><td> Really kill a process, cannot be caught </td></tr>
    <tr valign=top><td> SIGUSR1  </td><td> Signal reserved for whatever you want to use it for. </td></tr>
    <tr valign=top><td> SIGSEGV  </td><td> Segmentation fault, caused by accessing memory where you         shouldn't. Should never happen to Pike. </td></tr>
    <tr valign=top><td> SIGUSR2  </td><td> Signal reserved for whatever you want to use it for. </td></tr>
    <tr valign=top><td> SIGALRM  </td><td> Signal used for timer interrupts. </td></tr>
    <tr valign=top><td> SIGTERM  </td><td> Termination signal </td></tr>
    <tr valign=top><td> SIGSTKFLT </td><td> Stack fault </td></tr>
    <tr valign=top><td> SIGCHLD  </td><td> Child process died </td></tr>
    <tr valign=top><td> SIGCONT  </td><td> Continue suspended </td></tr>
    <tr valign=top><td> SIGSTOP  </td><td> Stop process </td></tr>
    <tr valign=top><td> SIGSTP   </td><td> Suspend process </td></tr>
    <tr valign=top><td> SIGTTIN  </td><td> tty input for background process </td></tr>
    <tr valign=top><td> SIGTTOU  </td><td> tty output for background process </td></tr>
    <tr valign=top><td> SIGXCPU  </td><td> Out of CPU </td></tr>
    <tr valign=top><td> SIGXFSZ  </td><td> File size limit exceeded </td></tr>
    <tr valign=top><td> SIGPROF  </td><td> Profile trap </td></tr>
    <tr valign=top><td> SIGWINCH </td><td> Window change signal </td></tr>
    </table>
    
    <p>Note that you have to use signame to translate the name of a signal
    to its number.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=signal>signal</link>, <link to=signum>signum</link>, <link to=signame>signame</link> and <link to=fork>fork</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=load_module>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>load_module</tt> - load a binary module
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int load_module(string <I>module_name</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function loads a module written in C or some other language
    into Pike. The module is initialized and any programs or constants
    defined will immediately be available.
    <p>When a module is loaded the functions init_module_efuns and
    init_module_programs are called to initialize it. When Pike exits
    exit_module is called in all dynamically loaded modules. These
    functions _must_ be available in the module.
    <p>Please see the source and any examples available at
    ftp://www.infovav.se/pub/pike for more information on how to
    write modules for Pike in C.
    <p>
    <dt><encaps>BUGS</encaps><dd>
    Please use "./name.so" instead of just "foo.so" for the module
    name. If you use just "foo.se" the module will not be found.
    
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=localtime>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>localtime</tt> - break down time() into intelligible components
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping(string:int) localtime(int <I>time</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Given a time represented as second since 1970, as returned by the
    function time(), this function returns a mapping with the following
    components:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> sec      </td><td> seconds over the minute </td><td> 0 - 59 </td></tr>
    <tr valign=top><td> min      </td><td> minutes over the hour   </td><td> 0 - 59 </td></tr>
    <tr valign=top><td> hour     </td><td> what hour in the day    </td><td> 0 - 23 </td></tr>
    <tr valign=top><td> mday     </td><td> day of the month        </td><td> 1 - 31 </td></tr>
    <tr valign=top><td> mon      </td><td> what month              </td><td> 0 - 11 </td></tr>
    <tr valign=top><td> year     </td><td> years since 1900        </td><td> 0 - </td></tr>
    <tr valign=top><td> wday     </td><td> day of week (0=Sunday)  </td><td> 0 - 6 </td></tr>
    <tr valign=top><td> yday     </td><td> day of year             </td><td> 0 - 365 </td></tr>
    <tr valign=top><td> isdst    </td><td> is daylight saving time </td><td> 0/1 </td></tr>
    <tr valign=top><td> timezone </td><td> difference between local time and UTC </td></tr>
    </table>
    
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    The 'timezone' might not be available on all platforms.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=time>time</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=log>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>log</tt> - Natural logarithm
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float log(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return the natural logarithm of <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=pow>pow</link> and <link to=exp>exp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=lower_case>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>lower_case</tt> - convert a string to lower case
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string lower_case(string <I>s</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a string with all capital letters converted to lower case.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=upper_case>upper_case</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=m_delete>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>m_delete</tt> - remove an index from a mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping m_delete(mapping <I>map</I>, mixed <I>index</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Removes the entry with index <i>index</i> from mapping <i>map</i> destructively.
    Returns the changed mapping. If the mapping does not have an
    entry with index <i>index</i>, nothing is done.
    Note that m_delete changes map destructively and only returns
    the mapping for compatibility reasons.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=mappingp>mappingp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=mappingp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mappingp</tt> - is the argument a mapping?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int mappingp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a mapping, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=arrayp>arrayp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=multisetp>multisetp</link>, <link to=floatp>floatp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=master>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>master</tt> - return the master object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object master();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Master is added by the master object to make it easier to access it.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=mkdir>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mkdir</tt> - make directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int mkdir(string <I>dirname</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Create a directory, return zero if it fails and nonzero if it successful.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=rm>rm</link> and <link to=cd>cd</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=mkmapping>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mkmapping</tt> - make a mapping from two arrays
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mapping mkmapping(mixed *<I>ind</I>, mixed *<I>val</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Makes a mapping ind[x]:val[x], 0&lt;=x&lt;sizeof(ind).
    <i>ind</i> and <i>val</i> must have the same size.
    This is the inverse operation of <tt>indices</tt> and <tt>values</tt>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=indices>indices</link> and <link to=values>values</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=mkmultiset>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mkmultiset</tt> - make a multiset
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>multiset mkmultiset(mixed *a)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function creates a multiset from an array.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; mkmultiset( ({1,2,3}) );<br>
    Result: (&lt; /* 3 elements */<br>
    <dl><dt><dd>1,<br>
    2,<br>
    3<br>
    </dl>&gt;)<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=aggregate_multiset>aggregate_multiset</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=mktime>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mktime</tt> - convert date and time to seconds
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int mktime(mapping tm)</tt><br>
    or<br>
    <tt>int mktime(int sec, int min, int hour, int mday, int mon, int year, int isdst, int tz)</tt><br>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function converts information about date and time into an integer which
    contains the number of seconds since the beginning of 1970. You can either
    call this function with a mapping containing the following elements:
    <p>
    <center>
    <table>
    <tr><td>year</td><td>The number of years since 1900</td></tr>
    <tr><td>mon</td><td>The month</td></tr>
    <tr><td>mday</td><td>The day of the month.</td></tr>
    <tr><td>hour</td><td>The number of hours past midnight</td></tr>
    <tr><td>min</td><td>The number of minutes after the hour</td></tr>
    <tr><td>sec</td><td>The number of seconds after the minute</td></tr>
    <tr><td>isdst</td><td>If this is 1, daylight savings time is assumed</td></tr>
    <tr><td>tm</td><td>The timezone (-12 &lt;= tz &lt;= 12)</td></tr>
    </table>
    </center>
    <p>
    Or you can just send them all on one line as the second syntax suggests.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=time>time</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=multisetp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>multisetp</tt> - is the argument a multiset?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int multisetp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a multiset, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=arrayp>arrayp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=floatp>floatp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=mv>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>mv</tt> - move a file (may handle directories as well)
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int mv(string <I>from</I>,string <I>to</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Rename or move a file between directories. If the destination
    file already exists, it will be overwritten. Returns 1 on success,
    0 otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=rm>rm</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=next_object>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>next_object</tt> - get next object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object next_object(object <I>o</I>);<br>
    or<br>
    object next_object();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    All objects are stored in a linked list, next_object() returns the
    first object in this list, and next_object(o) the next object in the
    list after o.
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>/* This example calls shutting_down() in all cloned objects */<br>
    object o;<br>
    for(o=next_object();o;o=next_object(o))<br>
    <dl><dt><dd>o-&gt;shutting_down();<br>
    </dl></tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link> and <link to=destruct>destruct</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=object_program>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>object_program</tt> - get the program associated with the object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>program object_program(object <I>o</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the program from which <i>o</i> was cloned.
    If <i>o</i> is not an object or has been destructed <i>o</i> zero is returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=clone>clone</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=objectp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>objectp</tt> - is the argument an object?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int objectp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is an object, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=programp>programp</link>, <link to=floatp>floatp</link>, <link to=stringp>stringp</link>, <link to=arrayp>arrayp</link>, <link to=mappingp>mappingp</link>, <link to=multisetp>multisetp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=pow>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>pow</tt> - Raise a number to the power of another.
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float pow(float <I>n</I>, float <I>x</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Return <i>n</i> raised to the power of <i>x</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=exp>exp</link> and <link to=log>log</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=programp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>programp</tt> - is the argument a program?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int programp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a program, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=multisetp>multisetp</link>, <link to=arrayp>arrayp</link>, <link to=stringp>stringp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=floatp>floatp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=putenv>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>putenv</tt> - put environment variable
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void putenv(string <I>varname</I>, string <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function sets the environment variable <i>varname</i> to <i>value</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=getenv>getenv</link> and <link to=exece>exece</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=query_host_name>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>query_host_name</tt> - return the name of the host we are running on
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string query_host_name();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the name of the machine the interpreter is
    running on. This is the same thing that the command <tt>hostname</tt>
    prints.
    
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=query_num_arg>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>query_num_arg</tt> - find out how many arguments were given
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int query_num_arg();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    <tt>query_num_arg</tt> returns the number of arguments given when this
    function was called. This is only useful for varargs functions.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=call_function>call_function</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=random>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>random</tt> - return a random number
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int random(int <I>max</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns a random number in the range 0 - max-1.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=random_seed>random_seed</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=random_seed>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>random_seed</tt> - seed random generator
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void random_seed(int <I>seed</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function sets the initial value for the random generator.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>Pike v1.0E-13 Running Hilfe v1.2 (Hubbe's Incremental Pike Front-End)<br>
    &gt; random_seed(17);<br>
    Result: 0<br>
    &gt; random(1000);<br>
    Result: 732<br>
    &gt; random(1000);<br>
    Result: 178<br>
    &gt; random(1000);<br>
    Result: 94<br>
    &gt; random_seed(17);<br>
    Result: 0<br>
    &gt; random(1000);<br>
    Result: 732<br>
    &gt; random(1000);<br>
    Result: 178<br>
    &gt; random(1000);<br>
    Result: 94<br>
    &gt;<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=random>random</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=remove_call_out>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>remove_call_out</tt> - remove a call out from the call out queue
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int remove_call_out(function <I>f</I>);<br>
    or<br>
    int remove_call_out(function <I>id</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function finds the first call to the function <i>f</i> in the call
    out queue and removes it. The time left to that call out will be
    returned. If no call out was found, zero_type(remove_call_out(f))
    will return 1. You can also give a call out id as argument. (as
    returned by call_out)
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=call_out_info>call_out_info</link>, <link to=call_out>call_out</link> and <link to=find_call_out>find_call_out</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=remove_include_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>remove_include_path</tt> - remove a directory to search for include files
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void remove_include_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function removes a directory from the list of directories to search
    for include files. It is the opposite of add_include_path.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=add_include_path>add_include_path</link> and <link to=include>#include</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=remove_module_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>remove_module_path</tt> - remove a directory to search for modules
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void remove_module_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function removes a directory from the list of directories to search
    for modules. It is the opposite of add_module_path. For more information
    about modules, see <ref to=modules>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=add_module_path>add_module_path</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=remove_program_path>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>remove_program_path</tt> - remove a directory to search for modules
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void remove_program_path(string <I>path</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function removes a directory from the list of directories to search
    for program. It is the opposite of add_program_path. For more information
    about programs, see <ref to=programs>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=add_program_path>add_program_path</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=replace>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>replace</tt> - generic replace function
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string replace(string <I>s</I>, string <I>from</I>, string <I>to</I>);<br>
    or<br>
    string replace(string <I>s</I>, array(string) <I>from</I>, array(string) <I>to</I>);<br>
    or<br>
    array replace(array <I>a</I>, mixed <I>from</I>, mixed <I>to</I>);<br>
    or<br>
    mapping replace(mapping <I>a</I>, mixed <I>from</I>, mixed <I>to</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function can do several kinds replacement operations, the
    different syntaxes do different things as follow:
    <p>string replace(string s, string from, string to);
    <p><dl><dt><dd>When given strings as second and third argument, a copy of<br>
    s with every occurrence of 'from' replaced with 'to' is returned.<br>
    </dl>
    <p>string replace(string s, array(string) from, array(string) to);
    <p><dl><dt><dd>When given arrays of strings as second and third argument,<br>
    every occurrence of from[0] in s is replaced by to[0],<br>
    from[1] is replaced by to[1] and so on...<br>
    </dl>
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> array replace(array a, mixed from, mixed to); </td><td>  </td></tr>
    <tr valign=top><td> mapping replace(mapping a, mixed from, mixed to); </td></tr>
    </table>
    
    <p><dl><dt><dd>When the first argument is an array or mapping, the values in<br>
    a are searched for values equal to from, which are replaced by<br>
    to destructively.<br>
    </dl>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=replace_master>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>replace_master</tt> - replace the master object
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void replace_master(object <I>o</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function replaces the master object with the argument you specify.
    This will let you control many aspects of how Pike works, but beware that
    master.pike may be required to fill certain functions, so it is probably
    a good idea to have your master inherit the original master and only
    re-define certain functions.
    <!-- FIX ME, tell how to inherit the master -->
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=reverse>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>reverse</tt> - reverse a string, array or int
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string reverse(string <I>s</I>);<br>
    or<br>
    array reverse(array <I>a</I>);<br>
    or<br>
    int reverse(int <I>i</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function reverses a string, char by char, an array, value
    by value or an int, bit by bit and returns the result. Reversing
    strings can be particularly useful for parsing difficult syntaxes
    which require scanning backwards.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sscanf>sscanf</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=rm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>rm</tt> - remove file or directory
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int rm(string <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Remove a file or directory, return 0 if it fails. Nonzero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=mkdir>mkdir</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=rows>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>rows</tt> - select a set of rows from an array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>array rows(mixed data, mixed *index)<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is exactly equivalent to:
    <p>map_array(index,lambda(mixed x,mixed y) { return y[x]; },data)
    <p>Except of course it is a lot shorter and faster.
    That is, it indexes data on every index in the array index and
    returns an array with the results.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=column>column</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=rusage>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>rusage</tt> - return resource usage
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int *rusage();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns an array of ints describing how much resources
    the interpreter process has used so far. This array will have at least
    29 elements, of which those values not available on this system will
    be zero. The elements are as follows:
    <p>0: user time
    1: system time
    2: maxrss
    3: idrss
    4: isrss
    5: minflt
    6: minor page faults
    7: major page faults
    8: swaps
    9: block input op.
    10: block output op.
    11: messages sent
    12: messages received
    13: signals received
    14: voluntary context switches
    15: involuntary context switches
    16: sysc
    17: ioch
    18: rtime
    19: ttime
    20: tftime
    21: dftime
    22: kftime
    23: ltime
    24: slptime
    25: wtime
    26: stoptime
    27: brksize
    28: stksize
    <p>Don't ask me to explain these values, read your system manuals for
    more information. (Note that all values may not be present though)
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=time>time</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=search>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>search</tt> - search for a value in a string or array
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int search(string <I>haystack</I>, string <I>needle</I>, [ int <I>start</I> ]);<br>
    or<br>
    int search(mixed *<I>haystack</I>, mixed <I>needle</I>, [ int <I>start</I> ]);<br>
    or<br>
    mixed search(mapping <I>haystack</I>, mixed <I>needle</I>, [ mixed <I>start</I> ]);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Search for <i>needle</i> in <i>haystack</i>. Return the position of <i>needle</i> in
    <i>haystack</i> or -1 if not found. If the optional argument <i>start</i> is present
    search is started at this position. Note that when <i>haystack</i> is a string
    <i>needle</i> must be a string, and the first occurrence of this string is
    returned. However, when <i>haystack</i> is an array, <i>needle</i> is compared only
    to one value at a time in <i>haystack</i>.
    <p>
    When the <i>haystack</i> is a mapping, <tt>search</tt> tries to find the index
    connected to the data <i>needle</i>. That is, it tries to lookup the mapping
    backwards. If <i>needle</i> isn't present in the mapping, zero is returned,
    and zero_type() will return 1 for this zero.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=indices>indices</link>, <link to=values>values</link> and <link to=zero_type>zero_type</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=signal>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>signal</tt> - trap signals
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void signal(int <I>sig</I>, function(int:void) <I>callback</I>);<br>
    or<br>
    void signal(int <I>sig</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function allows you to trap a signal and have a function called
    when the process receives a signal. Although it IS possible to trap
    SIGBUS, SIGSEGV etc. I advice you not to. Pike should not receive any
    such signals and if it does it is because of bugs in the Pike
    interpreter. And all bugs should be reported, no matter how trifle.
    <p>The callback will receive the signal number as the only argument.
    See the document for the function 'kill' for a list of signals.
    <p>If no second argument is given, the signal handler for that signal
    is restored to the default handler.
    <p>If the second argument is zero, the signal will be completely ignored.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=kill>kill</link>, <link to=signame>signame</link> and <link to=signum>signum</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=signame>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>signame</tt> - get the name of a signal
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string signame(int <I>sig</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a string describing the signal.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; signame(9);<br>
    Result: SIGKILL<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=kill>kill</link>, <link to=signum>signum</link> and <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=signum>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>signum</tt> - get a signal number given a descriptive string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int signum(string <I>sig</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is the opposite of signame.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; signum("SIGKILL");<br>
    Result: 9<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=signame>signame</link>, <link to=kill>kill</link> and <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sin>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sin</tt> - Trigonometrical sine
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float sin(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the sinus value for <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=asin>asin</link> and <link to=cos>cos</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sizeof>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sizeof</tt> - return the size of an array, string, multiset or mapping
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int sizeof(string|multiset|mapping|array|object <I>a</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the number of indexes available in the argument
    given to it. It replaces older functions like strlen, m_sizeof and
    size.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sleep>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sleep</tt> - let interpreter doze off for a while
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void sleep(int <I>s</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function makes the program stop for s seconds. Only signal
    handlers can interrupt the sleep. Other callbacks are not called
    during sleep.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sort>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sort</tt> - sort an array destructively
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *sort(array(mixed) <I>index</I>, array(mixed) ... <I>data</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function sorts the array 'index' destructively. That means
    that the array itself is changed and returned, no copy is created.
    If extra arguments are given, they are supposed to be arrays of the
    same size. Each of these arrays will be modified in the same way as
    'index'. Ie. if index 3 is moved to position 0 in 'index' index 3
    will be moved to position 0 in all the other arrays as well.
    <p>Sort can sort strings, integers and floats in ascending order.
    Arrays will be sorted first on the first element of each array.
    <p>Sort returns its first argument.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=reverse>reverse</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sprintf>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sprintf</tt> - print the result from sprintf
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string sprintf(string <I>format</I>,mixed <I>arg</I>,....);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    The format string is a string containing a description of how to
    output the data in the rest of the arguments. This string should
    generally speaking have one %&lt;modifiers&gt;&lt;operator&gt; (examples:
    %s, %0d, %-=20s) for each of the rest arguments.
    <p>Modifiers:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> 0 </td><td> Zero pad numbers (implies right justification) </td></tr>
    <tr valign=top><td> ! </td><td> Toggle truncation </td></tr>
    <tr valign=top><td> ' ' (space) </td><td> pad positive integers with a space </td></tr>
    <tr valign=top><td> + </td><td> pad positive integers with a plus sign </td></tr>
    <tr valign=top><td> - </td><td> left adjusted within field size (default is right) </td></tr>
    <tr valign=top><td> | </td><td> centered within field size </td></tr>
    <tr valign=top><td> = </td><td> column mode if strings are greater than field size </td></tr>
    <tr valign=top><td> / </td><td> Rough line break (break at exactly field size instead of between words) </td></tr>
    <tr valign=top><td> # </td><td> table mode, print a list of '\n' separated word (top-to-bottom order) </td></tr>
    <tr valign=top><td> $ </td><td> Inverse table mode (left-to-right order) </td></tr>
    <tr valign=top><td> n </td><td> (where n is a number or *) a number specifies field size </td></tr>
    <tr valign=top><td> .n </td><td> set precision </td></tr>
    <tr valign=top><td> :n </td><td> set field size &amp; precision </td></tr>
    <tr valign=top><td> ;n </td><td> Set column width </td></tr>
    <tr valign=top><td> * </td><td> if n is a * then next argument is used for precision/field size </td></tr>
    <tr valign=top><td> 'X' </td><td> Set a pad string. ' cannot be a part of the pad_string (yet) </td></tr>
    <tr valign=top><td> ~ </td><td> Get pad string from argument list. </td></tr>
    <tr valign=top><td> &lt; </td><td> Use same arg again </td></tr>
    <tr valign=top><td> ^ </td><td> repeat this on every line produced </td></tr>
    <tr valign=top><td> @ </td><td> do this format for each entry in argument array </td></tr>
    <tr valign=top><td> &gt; </td><td> Put the string at the bottom end of column instead of top </td></tr>
    <tr valign=top><td> _ </td><td> Set width to the length of data </td></tr>
    </table>
    
    <p>Operators:
    <p><table border=0 cellpadding=0 cellspacing=0>
    <tr valign=top><td> %% </td><td> percent </td></tr>
    <tr valign=top><td> %d </td><td> signed decimal int </td></tr>
    <tr valign=top><td> %u </td><td> unsigned decimal int (doesn't really exist in Pike) </td></tr>
    <tr valign=top><td> %o </td><td> unsigned octal int </td></tr>
    <tr valign=top><td> %x </td><td> lowercase unsigned hexadecimal int </td></tr>
    <tr valign=top><td> %X </td><td> uppercase unsigned hexadecimal int </td></tr>
    <tr valign=top><td> %c </td><td> char (or short with %2c, %3c gives 3 bytes etc.) </td></tr>
    <tr valign=top><td> %f </td><td> float </td></tr>
    <tr valign=top><td> %g </td><td> heuristically chosen representation of float </td></tr>
    <tr valign=top><td> %e </td><td> exponential notation float </td></tr>
    <tr valign=top><td> %s </td><td> string </td></tr>
    <tr valign=top><td> %O </td><td> any type (debug style) </td></tr>
    <tr valign=top><td> %n </td><td> nop </td></tr>
    <tr valign=top><td> %t </td><td> type of argument </td></tr>
    <tr valign=top><td> %&lt;modifiers&gt;{format%} </td><td> do a format for every index in an array. </td></tr>
    </table>
    
    <p>
    <dt><encaps>EXAMPLES</encaps><dd>
    <tt>Pike v0.1 Running Hilfe v1.2 (Incremental Pike Front end)<br>
    &gt; int screen_width=70;<br>
    Result: 70<br>
    &gt; mixed sample;<br>
    &gt; write(sprintf("fish: %c\n", 65));<br>
    fish: A<br>
    Result: 0<br>
    &gt; write(sprintf("Hello green friends\n"));<br>
    Hello green friends<br>
    Result: 0<br>
    &gt; write(sprintf("num: %d\n", 10));<br>
    num: 10<br>
    Result: 0<br>
    &gt; write(sprintf("num: %+10d\n", 10));<br>
    num:        +10<br>
    Result: 0<br>
    &gt; write(sprintf("num: %010d\n", 5*2));<br>
    num: 0000000010<br>
    Result: 0<br>
    &gt; write(sprintf("num: %|10d\n", 20/2));<br>
    num:     10    <br>
    Result: 0<br>
    &gt; write(sprintf("%|*s\n",screen_width,"THE NOT END"));<br>
    <dl><dt><dd>THE NOT END                              <br>
    </dl>Result: 0<br>
    &gt; write(sprintf("%|=*s\n",screen_width, "fun with penguins\n"));<br>
    <dl><dt><dd>fun with penguins                           <br>
    </dl>Result: 0<br>
    &gt; write(sprintf("%-=*O\n",screen_width,({ "fish", 9, "gumbies", 2 })));<br>
    ({ /* 4 elements */                                                   <br>
    <dl><dt><dd>"fish",                                                           <br>
    9,                                                                <br>
    "gumbies",                                                        <br>
    2                                                                 <br>
    </dl>})                                                                    <br>
    Result: 0<br>
    &gt; write(sprintf("%-=*s\n", screen_width,<br>
    <dl><dt><dd>"This will wordwrap the specified string within the "+<br>
    "specified field size, this is useful say, if you let "+<br>
    "users specify their screen size, then the room "+<br>
    "descriptions will automagically word-wrap as appropriate.\n"+<br>
    "slosh-n's will of course force a new-line when needed.\n"));<br>
    </dl>This will wordwrap the specified string within the specified field    <br>
    size, this is useful say, if you let users specify their screen size, <br>
    then the room descriptions will automagically word-wrap as            <br>
    appropriate.                                                          <br>
    slosh-n's will of course force a new-line when needed.                <br>
    Result: 0<br>
    &gt; write(sprintf("%-=*s %-=*s\n", screen_width/2,<br>
    <dl><dt><dd>"Two columns next to each other (any number of columns will "+<br>
    "of course work) independently word-wrapped, can be useful.",<br>
    screen_width/2-1,<br>
    "The - is to specify justification, this is in adherence "+<br>
    "to std sprintf which defaults to right-justification, "+<br>
    "this version also supports center and right justification."));<br>
    </dl>Two columns next to each other (any The - is to specify justification,<br>
    number of columns will of course    this is in adherence to std      <br>
    work) independently word-wrapped,   sprintf which defaults to         <br>
    can be useful.                      right-justification, this version <br>
    <dl><dt><dd>also supports center and right    <br>
    justification.                    <br>
    </dl>Result: 0<br>
    &gt;  write(sprintf("%-$*s\n", screen_width,<br>
    <dl><dt><dd>"Given a\nlist of\nslosh-n\nseparated\n'words',\nthis option\n"+<br>
    "creates a\ntable out\nof them\nthe number of\ncolumns\n"+<br>
    "be forced\nby specifying a\nprecision.\nThe most obvious\n"+<br>
    "use is for\nformatted\nls output."));<br>
    </dl>Given a          list of          slosh-n          <br>
    separated        'words',         this option      <br>
    creates a        table out        of them          <br>
    the number of    columns          be forced        <br>
    by specifying a  precision.       The most obvious <br>
    use is for       formatted        ls output.       <br>
    Result: 0<br>
    &gt;  write(sprintf("%-#*s\n", screen_width,<br>
    <dl><dt><dd>"Given a\nlist of\nslosh-n\nseparated\n'words',\nthis option\n"+<br>
    "creates a\ntable out\nof them\nthe number of\ncolumns\n"+<br>
    "be forced\nby specifying a\nprecision.\nThe most obvious\n"+<br>
    "use is for\nformatted\nls output."));<br>
    </dl>Given a          creates a        by specifying a  <br>
    list of          table out        precision.       <br>
    slosh-n          of them          The most obvious <br>
    separated        the number of    use is for       <br>
    'words',         columns          formatted        <br>
    this option      be forced        ls output.       <br>
    Result: 0<br>
    &gt; sample = ({ "first column: bing", "second column: womble" });<br>
    Result: ({ /* 2 elements */<br>
    <dl><dt><dd>"first column: bing",<br>
    "second column: womble"<br>
    </dl>})<br>
    &gt; write(sprintf("%-=*s\n%-=@*s\n", screen_width,<br>
    <dl><dt><dd>"Another bizarre option is the @ operator, it applies the "+<br>
    "format string it is in to each element of the array:",<br>
    screen_width/sizeof(sample),<br>
    sample));<br>
    </dl>Another bizarre option is the @ operator, it applies the format string<br>
    it is in to each element of the array:                                <br>
    first column: bing                 second column: womble              <br>
    Result: 0<br>
    &gt; write(sprintf("Better use these instead: %{gurksallad: %s\n%}\n",<br>
    <dl><dt><dd>sample));<br>
    </dl>Better use these instead: gurksallad: first column: bing<br>
    gurksallad: second column: womble<br>
    <br>
    Result: 0<br>
    &gt; write(sprintf("Of course all the simple printf options "+<br>
    <dl><dt><dd>"are supported:\n %s: %d %x %o %c\n",<br>
    "65 as decimal, hex, octal and a char",<br>
    65, 65, 65, 65));<br>
    </dl>Of course all the simple printf options are supported:<br>
    <dl><dt><dd>65 as decimal, hex, octal and a char: 65 41 101 A<br>
    </dl>Result: 0<br>
    &gt; write(sprintf("%|*s\n",screen_width, "THE END"));<br>
    <dl><dt><dd>THE END                                <br>
    </dl>Result: 0<br>
    &gt; quit<br>
    Exiting.<br>
    </tt>
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sscanf>sscanf</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=sqrt>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>sqrt</tt> - Square root
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float sqrt(float <I>f</I>);<br>
    or<br>
    int sqrt(int <I>i</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the square root of <i>f</i>, or in the second case, the square root
    truncated to the closest lower integer.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=pow>pow</link>, <link to=log>log</link>, <link to=exp>exp</link> and <link to=floor>floor</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=strerror>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>strerror</tt> - return a string describing an error
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string strerror(int <I>errno</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns a description of an error code. The error
    code is usually obtained from the file-&gt;errno() call.
    <p>
    <dt><encaps>NOTA BENE</encaps><dd>
    This function may not be available on all platforms.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=stringp>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>stringp</tt> - is the argument a string?
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int stringp(mixed <I>arg</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns 1 if <i>arg</i> is a string, zero otherwise.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=intp>intp</link>, <link to=multisetp>multisetp</link>, <link to=arrayp>arrayp</link>, <link to=programp>programp</link>, <link to=objectp>objectp</link>, <link to=mappingp>mappingp</link>, <link to=floatp>floatp</link> and <link to=functionp>functionp</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=strlen>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>strlen</tt> - Return the length of a string
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int strlen(string <I>s</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function is equal to sizeof.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=sizeof>sizeof</link>
    <p>
    </dl>
    </anchor>
    
    
    <HR NEWPAGE>
    <anchor name=tan>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>tan</tt> - Trigonometrical tangent
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>float tan(float <I>f</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns the tangent value for <i>f</i>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=atan>atan</link>, <link to=sin>sin</link> and <link to=cos>cos</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=this_object>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>this_object</tt> - return the object we are evaluating in currently
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>object this_object();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the object we are currently evaluating in.
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=throw>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>throw</tt> - throw a value to catch or global error handling
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>void throw(mixed <I>value</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function throws a value to a waiting catch. If no catch is
    waiting global error handling will send the value to handle_error
    in the master object. If you throw an array with where the first
    index contains an error message and the second index is a backtrace,
    (the output from backtrace() that is) then it will be treated exactly
    like a real error by overlying functions.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=catch>catch</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=time>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>time</tt> - return the current time
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int time();<br>
    or<br>
    int time(1);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns the number of seconds since 1 Jan 1970.
    The function ctime() converts this integer to a readable string.
    <p>The second syntax does not call the system call time() as often,
    but is only updated in the backed. (when Pike code isn't running)
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=time>time</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=trace>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>trace</tt> - change debug trace level
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int trace(int <I>t</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function affects the debug trace level. (also set by the -t
    command line option) The old level is returned. Trace level 1 or
    higher means that calls to Pike functions are printed to stderr,
    level 2 or higher means calls to builtin functions are printed, 3
    means every opcode interpreted is printed, 4 means arguments to
    these opcodes are printed as well. See the command lines options
    for more information
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=typeof>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>typeof</tt> - check return type of expression
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>typeof ( expression )<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This is a not really a function even if it looks like it, it returns
    a human readable (almost) representation of the type that the
    expression would return without actually evaluating it.
    The representation is in the form of a string.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; typeof(`sizeof);<br>
    Result: function(object | mapping | array | multiset | string : int)<br>
    &gt; typeof(sizeof(({})));<br>
    Result: int<br>
    &gt; <br>
    </tt>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=ualarm>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>ualarm</tt> - set an alarm clock for delivery of a signal
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int ualarm(int <I>useconds</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    ualarm arranges for a SIGALRM signal to be delivered to the
    process in useconds micro seconds.
    <p>If useconds is zero, no new alarm is scheduled.
    <p>In any event any previously set alarm is canceled.
    <p>
    <dt><encaps>RETURN VALUE</encaps><dd>
    ualarm returns the number of microseconds seconds  remaining<br>
    <dl><dt><dd>until any previously  scheduled  alarm  was  due to be delivered, or<br>
    </dl>zero if there was no previously scheduled alarm.<br>
    
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=signal>signal</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=upper_case>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>upper_case</tt> - convert a string to upper case
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string upper_case(string <I>s</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Returns a copy of the string <i>s</i> with all lower case character converted
    to upper case character.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=lower_case>lower_case</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=values>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>values</tt> - return an array of all possible values from indexing
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>mixed *values(string|multiset|mapping|array|object <I>foo</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Values return an array of all values you can get when indexing the
    value foo. For strings, an array of int with the ascii values of the
    characters in the string is returned. For a multiset, an array filled with
    ones is return. For mappings, objects and arrays, the returned array
    may contain any kind of value.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=indices>indices</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=version>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>version</tt> - return version info
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>string version();<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    This function returns a brief information about the Pike version.
    <p>
    <dt><encaps>EXAMPLE</encaps><dd>
    <tt>&gt; version();<br>
    Result: Pike v0.3<br>
    <br>
    </tt>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=write>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>write</tt> - write text to stdout
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int write(string <I>text</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    Added by the master, it directly calls write in a
    <link to=Stdio.stdout>Stdio.stdout</link>.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=Stdio.werror>Stdio.werror</link>
    <p>
    </dl>
    </anchor>
    
    <HR NEWPAGE>
    <anchor name=zero_type>
    <dl>
    <dt><encaps>NAME</encaps><dd>
    <tt>zero_type</tt> - return the type of zero
    <p>
    <dt><encaps>SYNTAX</encaps><dd>
    <tt>int zero_type(mixed <I>a</I>);<br>
    </tt>
    <p>
    <dt><encaps>DESCRIPTION</encaps><dd>
    There are many types of zeros out there, or at least there are two.
    One is returned by normal functions, and one returned by mapping
    lookups and find_call_out() when what you looked for wasn't there.
    The only way to separate these two kinds of zeros is zero_type.
    When doing a find_call_out or mapping lookup, zero_type on this value
    will return 1 if there was no such thing present in the mapping, or
    no such call_out could be found. If the argument to zero_type is a
    destructed object or a function in a destructed object, 2 will be
    returned. Otherwise zero_type will return zero.
    <p>If the argument is not an int, zero will be returned.
    <p>
    <dt><encaps>SEE ALSO</encaps><dd>
    <link to=find_call_out>find_call_out</link>
    <p>
    </dl>
    </anchor>
    </chapter>
    
    <!--
    
    <H1>XXX. Things to describe somewhere</H1>
    <ul>
      <li>garbage collection
      <li>int ... args
      <li>data storage (local vs. global variables)
      <li>trace
      <li>Pike command line
      <li>hilfe
      <li>socket->query_address()
      <li> scope for class {}
      <li>optimization
    </ul>
    <HR NEWPAGE>
    <HR NEWPAGE>
    <HR NEWPAGE>
    
    <chapter title="Pike internals - how to extend Pike">
    The rest of this book describes how Pike works and how to extend it with
    your own functions written in C or C++. Even if you are not interested in
    extending Pike, the information in this section can make you understand
    Pike better and thus make you a better Pike programmer. From this point on
    I will assume that the reader knows C or C++.
    <p>
    <section title="The master object">
    Pike is a very dynamic language. Sometimes that is not enough, sometimes you
    want to change the way Pike handles errors, loads modules or start scripts.
    All this and much more can be changed by modifying the <b>master object</b>.
    The <b>master object</b> is a Pike object like any other object, but it is
    loaded before anything else and is expected to perform certain things for
    the Pike executable. The Pike executable cannot function without a master
    object to take care of these things. Here is a list of the methods needed
    in the <b>master object</b>:
    <dl>
    <dt> <tt>program cast_to_program(string <i>program_name</i>, string <i>current_file</i>)</tt>
    <dd> This function is called whenever someone performs a cast from a string
         to a program.
    <dt> <tt>program handle_inherit(string <i>program_name</i>, string <i>current_file</i>)</tt>
    <dd> This is called whenever a Pike program which uses inherit with a string
         argument is called. It is expected to return the program to inherit.
    <dt> <tt>void handle_error(mixed *<i>trace</i>)</tt>
    <dd> This function is expected to write the error messages when a
         run time error occurs. The argument is of the form
         <tt>({"<i>error_description</i>", backtrace() })</tt>. If any error
         occurs in this routine Pike will dump core.
    <dt> <tt>program cast_to_program(string <i>program_name</i>, string <i>current_file</i>)</tt>
    <dd> This function is called whenever someone performs a cast from a string
         to an object.
    <dt> <tt>mixed resolv(string <i>identifier</i>, string <i>current_file</i>)</tt>
    <dd> This function is called whenever the compiler finds an unknown identifier
         in a program. It is normally used for loading modules.
         It is supposed to return <tt>([])[0]</tt> if the master doesn't know what
         the value should be, and the value in question otherwise.
    <dt> <tt>void _main(array(string) <i>argv</i>, array(string) <i>env</i>)</tt>
    <dd> This function is supposed to start a Pike script. It receives all
         the command line arguments in the first array and all environment
         variables on the form <tt>"<i>var</i>=<i>value</i>"</tt>.
         _main is called as soon as all modules and setup is done.
    <dt> <tt>void compile_error(string <i>file</i>, int <i>line</i>, string <i>err</i>)</tt>
    <dd> This function is called whenever a compile error is encountered. Normally
         it just writes a message to stderr.
    <dt> <tt>string handle_include(string <i>file</i>, string <i>current_file</i>, int <i>local_include</i>)</tt>
    <dd> This function is used to locate include files. <i>file</i> is the file
         name the user wants to include, and <i>local_include</i> is 1 if
         the user used double quotes rather than lesser-than, greater-than to
         quote the file name. Otherwise it is zero.
    </dl>
    <p>
    Aside from the above functions, which are expected from the Pike binary,
    the master object is also expected to provide functions used by Pike
    scripts. The current master add the following global functions:
    <dl><dd>
    	add_include_path,
    	remove_include_path,
    	add_module_path,
    	remove_module_path,
    	add_program_path,
    	remove_program_path,
    	master,
    	describe_backtrace,
    	mkmultiset,
    	strlen,
    	new,
    	clone,
    	UNDEFINED,
    	write,
    	getenv and putenv.
    </dl>
    <p>
    There are at least two ways to change the behavior of the master object.
    (Except for editing it directly, which would cause other Pike scripts not
     to run in most cases.) You can either copy the master object, modify it
    and use the command line option <tt>-m</tt> to load your file instead of
    the default master object. However, since there might be more functionality
    added to the master object in the future I do not recommend this.
    <p>
    A better way is to write an object that inherits the master and then calls
    replace_master with the new object as argument. This should be far more
    future-safe. Although I can not guarantee that the interface between Pike
    and the master object will not change in the future, so be careful if you
    do this.
    <p>
    Let's look an example:
    <example language=pike>
    	#!/usr/local/bin/pike
    
    	class new_master {
    	  inherit "/master";
    
     	  void create()
     	  {
     	    /* You need to copy the values from the old master to the new */
     	    /* NOTE: At this point we are still using the old master */
     	    object old_master = master();
     	    object new_master = this_object();
     
     	    foreach(indices(old_master), string varname)
     	    {
     	      /* The catch is needed since we can't assign constants */
     	      catch { new_master[varname] = old_master[varname]; };
     	    }
     	  }
    
    	  void handle_error(mixed *trace)
    	  {
    	    Stdio.write_file("error log",describe_backtrace(trace));
    	  }
    	};
    
    	int main(int argc, array(string) argv)
    	{
    	  replace_master(new_master());
    	  /* Run rest of program */
    	  exit(0);
    	}
    </example>
    This example installs a master object which logs run time errors to file
    instead of writing them to stderr.
    <p>
    </section>
    
    
    <h2> Functional overview </h2>
    
    <h2>Overview of the Pike source</h2>
    <dl>
    <dt> library files
    <dd> 
      <dl>
      <dt> callback
      </dl>
    
    <dt> compiler
    <dt> backend
    <dt> callback
    <dt> constants
    <dt> docode
    <dt> 
    </dl>
    
    <ul>
      <li>Overview of the Pike source
      <li>The master object
      <li>The file structure of a module
      <li>Data types from the inside
      <li>Writing portable modules: autoconf
      <li>Other useful functions
    </ul>
    </chapter>
    
    -->
    
    
    <appendix title="Terms and jargon">
    <dl>
      <dt> HTTP <dd> Hyper-Text Transfer Protocol, the protocol used by WWW to transfer HTML from the server to the client. Based on TCP.
      <dt> WWW <dd> World Wide Web, popularly known as 'the Internet' :)
      <dt> TCP <dd> Transmission Control Protocol, the Internet standard for computer communication
      <dt> ASCII <dd> American Standard Code for Information Interchange.  Standard set by the American Standards Authority for encoding English letters, numbers , some symbols and control characters in 7 bits. There are also some "semi-standard" systems which add other characters by using 8 bits, which are also loosely called ASCII.
      <dt> UNIX <dd> A group of operating systems. Some noteworthy Unixes are: Solaris, Linux, HP-UX, Digital Unix, SunOs, BSD and Unixware.
      <dt> clone <dd> To create an object from a program. Or to use C++ jargon: to instantiate a class.
      <dt> command line <dd> The line you write to execute a program
      <dt> command line option <dd> The words after the program name on the <i>command line</i>.
      <dt> constant <dd> 1) A value written directly in the code, such as <tt>1</tt> or <tt>"foo"</tt>. 2) A value defined with add_constant.
      <dt> identifier <dd> The name of a variable, function, class or constant.
      <dt> interpreter <dd> An interpreter <i>interprets </i> byte-code instruction by instruction. In this context 'the interpreter' is usually the Pike binary.
      <dt> iteration <dd> Iteration is when the program is executing a loop. Each time the loop is called is also called one iteration.
      <dt> object <dd> An object is what you get if you call a program. Objects contain variables and a reference to the program from which they were cloned. Same as 'instance' in C++.
      <dt> program <dd> 1) An executable file 2) A builtin Pike data type. Programs are almost the same as classes in C++ and contain the actual compiled code.
      <dt> recursion <dd> Recursion is an alternative to iteration. Recursion occurs when a function calls itself.
      <dt> stderr <dd> Standard error. The error channel. This is where errors are supposed to be written. It is usually the screen, but can be redirected to a file or another program. See the manual page for sh(1) for more details.
      <dt> stdin <dd> Standard input. Usually the keyboard, but can also be from a file or another program. See the manual page for sh(1) for more details.
      <dt> stdout <dd> Standard output. This is usually the screen but can be redirected to a file or another program. See the manual page for sh(1) for more details.
    </dl>
    </appendix>
    
    <appendix title="Register program" name=register_program>
    Here is a complete listing of the example program from
    chapter 2.
    
    <example language=pike>
    #!/usr/local/bin/pike
    
    mapping records(string:array(string)) = ([
      "Star Wars Trilogy" : ({
        "Fox Fanfare",
        "Main Title",
        "Princess Leia's Theme",
        "Here They Come",
        "The Asteroid Field",
        "Yoda's Theme",
        "The Imperial March",
        "Parade of th Ewoks",
        "Luke and Leia",
        "Fight with Tie Fighters",
        "Jabba the Hut",
        "Darth Vader's Death",
        "The Forest Battle",
        "Finale",
      })
    ]);
    
    void list_records()
    {
      int i;
      array(string) record_names=sort(indices(records));
    
      write("Records:\n");
      for(i=0;i&lt;sizeof(record_names);i++)
        write(sprintf("%3d: %s\n", i+1, record_names[i]));
    }
    
    void show_record(int num)
    {
      int i;
      array(string) record_names=sort(indices(records));
      string name=record_names[num-1];
      string songs=records[name];
      
      write(sprintf("Record %d, %s\n",num,name));
      for(i=0;i&lt;sizeof(songs);i++)
        write(sprintf("%3d: %s\n", i+1, songs[i]));
    }
    
    void add_record()
    {
      string record_name=readline("Record name: ");
      records[record_name]=({});
      write("Input song names, one per line. End with '.' on its own line.\n");
      while(1)
      {
        string song;
        song=readline(sprintf("Song %2d: ",sizeof(records[record_name])+1));
        if(song==".") return;
        records[record_name]+=({song});
      }
    }
    
    void save(string file_name)
    {
      string name, song;
      object o;
      o=Stdio.File();
    
      if(!o-&gt;open(file_name,"wct"))
      {
        write("Failed to open file.\n");
        return;
      }
    
      foreach(indices(records),name)
      {
        o-&gt;write("Record: "+name+"\n");
        foreach(records[name],song)
          o-&gt;write("Song: "+song+"\n");
      }
    
      o-&gt;close();
    }
    
    void load(string file_name)
    {
      object o;
      string name="ERROR";
      string file_contents,line;
    
      o=Stdio.File();
      if(!o-&gt;open(file_name,"r"))
      {
        write("Failed to open file.\n");
        return;
      }
    
      file_contents=o-&gt;read();
      o-&gt;close();
    
      records=([]);
    
      foreach(file_contents/"\n",line)
      {
        string cmd, arg;
        if(sscanf(line,"%s: %s",cmd,arg))
        {
          switch(lower_case(cmd))
          {
            case "record":
              name=arg;
              records[name]=({});
              break;
    
            case "song":
              records[name]+=({arg});
              break;
          }
        }
      }
    }
    
    void delete_record(int num)
    {
      array(string) record_names=sort(indices(records));
      string name=record_names[num-1];
    
      m_delete(records,name);
    }
    
    void find_song(string title)
    {
      string name, song;
      int hits;
    
      title=lower_case(title);
    
      foreach(indices(records),name)
      {
        foreach(records[name],song)
        {
          if(search(lower_case(song), title) != -1)
          {
            write(name+"; "+song+"\n");
            hits++;
          }
        }
      }
    
      if(!hits) write("Not found.\n");
    }
    
    int main(int argc, array(string)  argv)
    {
      string cmd;
      while(cmd=readline("Command: "))
      {
        string args;
        sscanf(cmd,"%s %s",cmd,args);
    
        switch(cmd)
        {
          case "list":
            if((int)args)
            {
              show_record((int)args);
            }else{
              list_records();
            }
            break;
    
          case "quit":
           exit(0);
    
          case "add":
            add_record();
    	break;
    
          case "save":
            save(args);
            break;
    
          case "load":
            load(args);
            break;
    
          case "delete":
            delete_record((int)args);
            break;
    
          case "search":
            find_song(args);
            break;
        }
      }
    }
    </example>
    </appendix>
    
    <appendix title="Reserved words">
    
    These are words that have special meaning in Pike and can not be used
    as variable or function names.
    <p>
      array break case catch continue default do else float for foreach
      function gauge if inherit inline int lambda mapping mixed multiset nomask
      object predef private program protected public return sscanf static string
      switch typeof varargs void while
    
    </appendix>
    
    <appendix title="BNF for Pike">
    
    BNF is short for "Backus Naur Form". It is a precise way of describing syntax.
    This is the BNF for Pike:
    
    <table>
    <tr valign=top><td>program</td><td>::=</td><td>{ definition }</td></tr>
    <tr valign=top><td>definition</td><td>::=</td><td>import | inheritance | function_declaration | function_definition | variables | constant | class_def</td></tr>
    <tr valign=top><td>import</td><td>::=</td><td>modifiers <b>import</b> constant_identifier ";"</td></tr>
    <tr valign=top><td>inheritance</td><td>::=</td><td>modifiers <b>inherit</b> program_specifier [ ":" identifier ] ";" </td></tr>
    <tr valign=top><td>function_declaration</td><td>::=</td><td>modifiers type identifier "(" arguments ")" ";"</td></tr>
    <tr valign=top><td>function_definition</td><td>::=</td><td>modifiers type identifier "(" arguments ")" block </td></tr>
    <tr valign=top><td>variables</td><td>::=</td><td>modifiers type variable_names ";"</td></tr>
    <tr valign=top><td>variable_names</td><td>::=</td><td>variable_name { "," variable_name }</td></tr>
    <tr valign=top><td>variable_name</td><td>::=</td><td>{ "*" } identifier [ "=" expression2 ]</td></tr>
    <tr valign=top><td>constant</td><td>::=</td><td>modifiers <b>constant</b> constant_names ";" </td></tr>
    <tr valign=top><td>constant_names</td><td>::=</td><td>constant_name { "," constant_name }</td></tr>
    <tr valign=top><td>constant_name</td><td>::=</td><td>identifier "=" expression2</td></tr>
    <tr valign=top><td>class_def</td><td>::=</td><td>modifiers <b>class</b> [ ";" ] </td></tr>
    <tr valign=top><td>class</td><td>::=</td><td><b>class</b> [ identifier ] "{" program "}"</td></tr>
    <tr valign=top><td>modifiers</td><td>::=</td><td> { <b>static</b> | <b>private</b> | <b>nomask</b> | <b>public</b> | <b>protected</b> | <b>inline</b> }</td></tr>
    <tr valign=top><td>block</td><td>::=</td><td>"{" { statement }  "}" </td></tr>
    <tr valign=top><td>statement</td><td>::=</td><td>expression2 ";" | cond | while | do_while | for | switch | case | default | return | block | foreach | break | continue | ";" </td></tr>
    <tr valign=top><td>cond</td><td>::=</td><td><b>if</b> statement [ <b>else</b> statement ]</td></tr>
    <tr valign=top><td>while</td><td>::=</td><td><b>while</b> "(" expression ")" statement</td></tr>
    <tr valign=top><td>do_while</td><td>::=</td><td><b>do</b> statement <b>while</b> "(" expression ")" ";" </td></tr>
    <tr valign=top><td>for</td><td>::=</td><td><b>for</b> "(" [ expression ] ";" [ expression ] ";" [ expression ] ")" statement</td></tr>
    <tr valign=top><td>switch</td><td>::=</td><td><b>switch</b> "(" expression ")" block</td></tr>
    <tr valign=top><td>case</td><td>::=</td><td><b>case</b> expression [ ".." expression ] ":"</td></tr>
    <tr valign=top><td>default</td><td>::=</td><td><b>default</b> ":"</td></tr>
    <tr valign=top><td>foreach</td><td>::=</td><td><b>foreach</b> "(" expression ":" expression6 ")" statement</td></tr>
    <tr valign=top><td>break</td><td>::=</td><td><b>break</b> ";"</td></tr>
    <tr valign=top><td>continue</td><td>::=</td><td><b>continue</b> ";"</td></tr>
    <tr valign=top><td>expression</td><td>::=</td><td>expression2 { "," expression2 }</td></tr>
    <tr valign=top><td>expression2</td><td>::=</td><td>{ lvalue ( "=" | "+=" | "*=" | "/=" | "&amp;=" | "|=" | "^=" | "&lt;&lt;=" | "&gt;&gt;=" | "%=" ) } expression3</td></tr>
    <tr valign=top><td>expression3</td><td>::=</td><td>expression4 '?' expression3 ":" expression3 </td></tr>
    <tr valign=top><td>expression4</td><td>::=</td><td>{ expression5 ( "||" | "&amp;&amp;" | "|" | "^" | "&amp;" | "==" | "!=" | "&gt;" | "&lt;" | "&gt;=" | "&lt;=" | "&lt;&lt;" | "&gt;&gt;" | "+" | "*" | "/" | "%" ) } expression5</td></tr>
    <tr valign=top><td>expression5</td><td>::=</td><td>expression6 | "(" type ")" expression5 | "--" expression6 | "++" expression6 | expression6 "--" | expression6 "++" | "~" expression5 | "-" expression5 </td></tr>
    <tr valign=top><td>expression6</td><td>::=</td><td>string | number | float | catch | gauge | typeof | sscanf | lambda | class | constant_identifier | call | index | mapping | multiset | array | parenthesis | arrow </td></tr>
    <tr valign=top><td>number</td><td>::=</td><td>digit { digit } | "0x" { digits } | "'" character "'" </td></tr>
    <tr valign=top><td>float</td><td>::=</td><td>digit { digit } "." { digit }</td></tr>
    <tr valign=top><td>catch</td><td>::=</td><td><b>catch</b> ( "(" expression ")" | block )</td></tr>
    <tr valign=top><td>gauge</td><td>::=</td><td><b>gauge</b> ( "(" expression ")" | block )</td></tr>
    <tr valign=top><td>sscanf</td><td>::=</td><td><b>sscanf</b> "(" expression2 "," expression2 { "," lvalue } ")" </td></tr>
    
    <tr valign=top><td>lvalue</td><td>::=</td><td><b>lambda</b> expression6 | type identifier </td></tr>
    <tr valign=top><td>lambda</td><td>::=</td><td><b>lambda</b> "(" arguments ")" block</td></tr>
    <tr valign=top><td>constant_identifier</td><td>::=</td><td>identifier { "." identifier }</td></tr>
    <tr valign=top><td>call</td><td>::=</td><td>expression6 "(" expression_list ")" </td></tr>
    <tr valign=top><td>index</td><td>::=</td><td>expression6 "[" expression [ ".." expression ] "]"</td></tr>
    <tr valign=top><td>array</td><td>::=</td><td>"({" expression_list "})"</td></tr>
    <tr valign=top><td>multiset</td><td>::=</td><td>"(&lt;" expression_list "&gt;)"</td></tr>
    <tr valign=top><td>mapping</td><td>::=</td><td>"([" [ expression : expression { "," expression ":" expression } ] [ "," ] "])"</td></tr>
    <tr valign=top><td>arrow</td><td>::=</td><td>expression6 "-&gt;" identifier</td></tr>
    <tr valign=top><td>parenthesis</td><td>::=</td><td>"(" expression ")"</td></tr>
    <tr valign=top><td>expression_list</td><td>::=</td><td> [ splice_expression { "," splice_expression } ] [ "," ]</td></tr>
    <tr valign=top><td>splice_expression</td><td>::=</td><td>[ "@" ] expression2</td></tr>
    <tr valign=top><td>type</td><td>::=</td><td> ( <b>int</b> | <b>string</b> | <b>float</b> | <b>program</b> | <b>object</b> [ "(" program_specifier ")" ] | <b>mapping</b> [ "(" type ":" type ")" | <b>array</b> [ "(" type ")" ] | <b>multiset</b> [ "(" type ")" ] | <b>function</b> [ function_type ] ) { "*" }</td></tr>
    <tr valign=top><td>function_type</td><td>::=</td><td>"(" [ type { "," type } [ "..." ] ")"</td></tr>
    <tr valign=top><td>arguments</td><td>::=</td><td>[ argument { "," argument } ] [","]</td></tr>
    <tr valign=top><td>argument</td><td>::=</td><td>type [ "..." ] [ identifier ]</td></tr>
    <tr valign=top><td>program_specifier</td><td>::=</td><td>string_constant | constant_identifier</td></tr>
    <tr valign=top><td>string</td><td>::=</td><td>string_literal { string_literal }</td></tr>
    <tr valign=top><td>identifier</td><td>::=</td><td>letter { letter | digit } | "`+" | "`/" | "`%" | "`*" | "`&amp;" | "`|" | "`^" | "`~" | "`&lt;" | "`&lt;&lt;" | "`&lt;=" | "`&gt;" | "`&gt;&gt;" | "`&gt;=" | "`==" | "`!=" | "`!" | "`()" | "`-" | "`-&gt;" | "`-&gt;=" | "`[]" | "`[]="</td></tr>
    <tr valign=top><td>letter</td><td>::=</td><td>"a"-"z" | "A"-"Z" | "_"</td></tr>
    <tr valign=top><td>digit</td><td>::=</td><td>"0"-"9"</td></tr>
    </table>
    
    </appendix>
    
    <appendix title="How to install Pike" name=install>
    To install Pike, you need a C compiler, a couple of Mb of disk space,
    the source for Pike, and a bit of patience. The latest version of Pike is
    always available from <a href=http://pike.infovav.se>the Pike home page</a>.
    Lists of mirror sites and binary releases should also be available there.
    Pike should compile and install nicely on almost any UNIX platform. It has
    been tested on the following:
    <ul>
    <li> Solaris 2.4, 2.5, 2.5.1
    <li> SunOs 4.1.1, 4.1.3
    <li> Linux Red Hat 3, Red Hat 4, Slackware 3.0, Slackware 96
    <li> HP-UX 9, 10
    <li> AIX 4
    <li> IRIX
    <li> SCO UNIX
    <li> Ultrix
    <li> Digital Unix (OSF/1)
    </ul>
    
    After obtaining the Pike source you need to unpack it. To unpack Pike you
    need gzip, which is available from any GNU mirror site. You also need tar,
    which is a part of UNIX. If you got Pike-v0.5.tar.gz, simply unpack it by
    typing:
    <pre>
    	$ gunzip -d Pike-v0.5.tar.gz
    	$ tar xvf Pike-v0.5.tar
    </pre>
    
    Now you have a directory called Pike-v0.5. Please read the README file
    in the new directory since newer versions can contain information not
    available at the time this book was written.
    <p>
    Now, to compile Pike, the following three commands should be enough.
    <pre>
    	$ cd Pike-v0.5/src
    	$ ./configure --prefix=/dir/to/install/pike
    	$ make
    </pre>
    They will (in order) change directory to the source directory. Configure will
    then find out what features are available on your system and construct
    makefiles. You will see a lot of output after you run configure. Do not
    worry, that is normal. It is usually not a good idea to install Pike anywhere
    but in /usr/local (the default) since Pike scripts written by other people
    will usually assume that's where Pike is. However, if you do not have write
    access to /usr/local you will have to install Pike somewhere else on your
    system.
    <p>
    After that <tt>make</tt> will actually compile the program. After compilation
    it is a good idea to do <tt>make verify</tt> to make sure that Pike is
    100% compatible with your system. Make verify will take a while to run
    and use a lot of CPU, but it is worth it to see that your compilation was
    successful. After doing that you should run <tt>make install</tt> to install
    the Pike binaries, libraries and include files in the directory you selected
    earlier.
    <p>
    You are now ready to use Pike.
    </appendix>
    
    <index title=Index>