Programming, using and understanding

Pike

by Fredrik Hübinette

Preface

This book was written with the intention of making 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 it 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
Ian Carr-de Avelon and Henrik Wallin 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.

Table of contents

Preface
Table of contents
Introduction
Overview
The history of Pike
A comparison with other languages
What is Pike
How to read this manual
1 Getting started
1.1 Your first Pike program
1.2 Improving hello_world.pike
1.3 Further improvements
1.4 Control structures
1.5 Functions
1.6 True and false
1.7 Data Types
2 A more elaborate example
2.1 Taking care of input
2.1.1 add_record()
2.1.2 main()
2.2 Communicating with files
2.2.1 save()
2.2.2 load()
2.2.3 main() revisited
2.3 Completing the program
2.3.1 delete()
2.3.2 search()
2.3.3 main() again
2.4 Then what?
2.5 Simple exercises
3 Control Structures
3.1 Conditions
3.1.1 if
3.1.2 switch
3.2 Loops
3.2.1 while
3.2.2 for
3.2.3 do-while
3.2.4 foreach
3.3 Breaking out of loops
3.3.1 break
3.3.2 continue
3.3.3 return
3.4 Exercises
4 Data types
4.1 Basic types
4.1.1 int
4.1.2 float
4.1.3 string
4.2 Pointer types
4.2.1 array
4.2.2 mapping
4.2.3 multiset
4.2.4 program
4.2.5 object
4.2.6 function
4.3 Sharing data
4.4 Writing data types
5 Operators
5.1 Arithmetic operators
5.2 Comparison operators
5.3 Logical operators
5.4 Bitwise/set operators
5.5 Indexing
5.6 The assignment operators
5.7 The rest of the operators
5.8 Operator precedence
5.9 Operator functions
6 Object orientation
6.1 Terminology
6.2 The approach
6.3 How does this help?
6.4 Pike and object orientation
6.5 Inherit
6.6 Multiple inherit
6.7 Pike inherit compared to other languages
6.8 Modifiers
6.9 Operator overloading
6.10 Simple exercises
7 Miscellaneous functions
7.1 sscanf
7.2 catch & throw
7.3 gauge
7.4 typeof
8 Modules
8.1 How to use modules
8.2 Where do modules come from?
8.3 The . operator
8.4 How to write a module
8.5 Simple exercises
9 File I/O
9.1 File management - Stdio.File
9.2 Buffered file management - Stdio.FILE
9.3 Standard streams - Stdio.stdin, stdout and stderr
9.4 Listening to sockets - Stdio.Port
9.5 UDP socket and message management - Stdio.UDP
9.6 Terminal management - Stdio.Terminfo
9.6.1 Stdio.Terminfo.Termcap
9.6.2 Stdio.Terminfo.Terminfo
9.7 Simple input-by-prompt - Stdio.Readline
9.8 Other Stdio functions
9.9 A simple example
9.10 A more complex example - a simple WWW server
10 Threads
10.1 Starting a thread
10.2 Threads reference section
10.3 Threads example
11 Modules for specific data types
11.1 String
11.2 Array
12 Image
12.1 Image.Image
12.2 Image.Colortable
12.3 Image.Layer
12.4 Image.Font
12.5 Image.colortable
12.6 Image.Poly
12.7 Image.Color
12.7.1 Image.Color.Color
12.8 Image.X
12.9 Image.ANY
12.10 Image.AVS
12.11 Image.BMP
12.12 Image.GD
12.13 Image.GIF
12.14 Image.HRZ
12.15 Image.ILBM
12.16 Image.PCX
12.17 Image.PNG
12.18 Image.PNM
12.19 Image.PSD
12.20 Image.TGA
12.21 Image.XBM
12.22 Image.XCF
12.23 Image.XWD
12.24 Image.JPEG
12.25 Image.TIFF
12.26 Image.TTF
12.26.1 Image.TTF.Face
12.26.2 Image.TTF.FaceInstance
12.27 Image.XFace
13 Protocols
13.1 Protocols.HTTP
13.1.1 Protocols.HTTP.Query
13.2 Protocols.LysKOM
13.2.1 Protocols.LysKOM.Session
13.2.2 Protocols.LysKOM.Connection
13.2.3 Protocols.LysKOM.Request
13.2.3.1 Protocols.LysKOM.Request._Request
13.3 Protocols.DNS
13.3.1 Protocols.DNS.client
14 Other modules
14.1 System
14.2 Process
14.3 Regexp
14.4 Gmp
14.5 Gdbm
14.6 Getopt
14.7 Gz
14.8 Yp
14.9 ADT.Table
14.10 Yabu transaction database
14.10.1 The database
14.10.2 Tables
14.10.3 Transactions
14.11 MIME
14.11.1 Global functions
14.11.2 The MIME.Message class
14.11.2.1 Public fields
14.11.2.2 Public methods
14.12 Simulate
14.13 Mysql.mysql
14.14 The Pike Crypto Toolkit
14.14.1 Introduction
14.14.2 Block ciphers
14.14.3 Stream Ciphers
14.14.4 Hash Functions
14.14.5 Public key algorithms
14.14.6 Combining block cryptos
14.15 Locale.Gettext
14.16 Calendar
14.16.1 Calendar.time_unit
14.16.2 Calendar.Gregorian
14.16.2.1 Calendar.Gregorian.
14.16.2.2 Calendar.Gregorian.Year
14.16.2.3 Calendar.Gregorian.Stardate
14.16.2.3.1 Calendar.Gregorian.Stardate.TNGDate
14.17 Parser
14.18 Math
14.18.1 Math.Matrix
14.19 Calendar.time_unit
14.20 Calendar.Gregorian
14.20.1 Calendar.Gregorian.
14.20.2 Calendar.Gregorian.Year
14.20.3 Calendar.Gregorian.Stardate
14.20.3.1 Calendar.Gregorian.Stardate.TNGDate
14.21 Crypto.randomness
14.21.1 Crypto.randomness.pike_random
14.21.2 Crypto.randomness.arcfour_random
14.22 Geographical.Position
14.23 Geographical.Countries
14.24 Parser.SGML
14.25 Protocols.HTTP
14.25.1 Protocols.HTTP.Query
14.26 Protocols.LysKOM
14.26.1 Protocols.LysKOM.Session
14.26.2 Protocols.LysKOM.Connection
14.26.3 Protocols.LysKOM.Request
14.26.3.1 Protocols.LysKOM.Request._Request
14.27 Protocols.DNS
14.27.1 Protocols.DNS.client
15 The preprocessor
16 Builtin functions
17 Pike internals - how to extend Pike
17.1 The master object
17.2 Data types from the inside
17.2.1 Basic data types
17.2.2 struct svalue
17.2.3 struct pike_string
17.2.4 struct array
17.2.5 struct mapping
17.2.6 struct object
17.2.7 struct program
17.3 The interpreter
Appendix A Terms and jargon
Appendix B Register program
Appendix C Reserved words
Appendix D BNF for Pike
Appendix E How to install Pike
Appendix F How to convert from old versions of Pike
Appendix G Image.Layer modes
Appendix H Image.Color colors
Index

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.

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.

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 the 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 of 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.

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.

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.

A comparison with other languages

Python
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.
C++
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++.
Lisp and Scheme
Internally Pike has a lot in common with simple interpreted Lisp and Scheme implementations. They are all stack based, byte-compiled, interpreted languages. Pike is also a 'one-cell' language, just like Scheme.
Pascal
Pike has nothing in common with Pascal.
Tcl/Tk
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.

What is Pike

Pike is: Pike has:

How to read this manual

This manual uses a couple of different typefaces to describe different things:
italics
Italics is used as a placeholder for other things. If it says a word in the text it means that you should put your own word there.
bold
Bold is just used to emphasize that this word is not merely what it sounds like. It is actually a term.
fixed size
Fixed size is used to for examples and text directly from the computer.
Also, please beware that the word program is also a builtin Pike data type.

Chapter 1, Getting started

First you need to have Pike installed on your computer. See appendix E "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.

1.1 Your first Pike program

int main()
{
    write("hello world\n");
    return 0;
}
Let's call this file hello_world.pike, and then we try to run it:

	$ pike hello_world.pike
	hello world
	$ 
Pretty simple, Let's see what everything means:
int main()
This begins the function main. Before the function name the type of value it returns is declared, in this case int 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 main 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 name of the function, the parameters, 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 main;

{
    write("hello world\n");
    return 0;
}
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.

write("hello world\n");
The first statement is a call to the builtin function write. This will execute the code in the function write with the arguments as input data. In this case, the constant string hello world\n is sent. Well, not quite. The \n combination corresponds to the newline character. write then writes this string to stdout when executed. Stdout is the standard Unix output channel, usually the screen.

return 0;
This statement exits the function and returns the value zero. Any statements following the return statements will not be executed.

1.2 Improving hello_world.pike

Typing pike hello_world.pike 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:

#!/usr/local/bin/pike

int main()
{
    write("hello world\n");
    return 0;
}
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:

	$ chmod +x hello_world.pike
	$ ./hello_world.pike
	hello world
	$ 
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.

1.3 Further improvements

Now, wouldn't it be nice if it said Hello world! instead of hello world ? 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 command line option that will make it type the old hello world. 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:

#!/usr/local/bin/pike

int main(int argc, array(string) argv)
{
    if(argc > 1 && argv[1]=="--traditional")
    {
        write("hello world\n"); // old style
    }else{
        write("Hello world!\n"); // new style
    }
    return 0;
}
Let's run it:

	$ chmod +x hello_world.pike
	$ ./hello_world.pike
	Hello world!
	$ ./hello_world.pike --traditional
	hello world
	$ 
What is new in this version, then?
int main(int argc, array(string) argv)
In this version the space between the parenthesis has been filled. What it means is that main now takes two arguments. One is called argc, and is of the type int. The other is called argv and is a an array of strings.

The arguments to main are taken from the command line when the Pike program is executed. The first argument, argc, is how many words were written on the command line (including the command itself) and argv is an array formed by these words.

if(argc > 1 && argv[1] == "--traditional")
{
    write("hello world\n"); // old style
}else{
    write("Hello world!\n"); // new style
}
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:

argc > 1 && argv[1] == "--traditional"
Loosely translated, this means: argc is greater than one, and the second element in the array argv is equal to the string --traditional. 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.

Also note the comments:

write("hello world\n"); // old style
The // begins a comment which continues to the end of the line. Comments will be ignored 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, i.e. /* ... */, which can extend over several lines. The // comment only extends to the end of the line.

1.4 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 control structures to make Pike execute pieces of code in more interesting orders than from top to bottom.

We have already seen an example of the if statement:

if( expression )
    statement1;
else
    statement2;
if simply evaluates the expression and if the result is true it executes statement1, otherwise it executes statement2. If you have no need for statement2 you can leave out the whole else part like this:
if( expression )
    statement1;
In this case statement1 is evaluated if expression is true, otherwise nothing is evaluated.

Note for beginners: go back to our first example and make sure you understand what if does.

Another very simple control structure is the while statement:

while( expression )
    statement;
This statement evaluates expression and if it is found to be true it evaluates statement. After that it starts over and evaluates expression again. This continues until expression is no longer true. This type of control structure is called a loop and is fundamental to all interesting programming.

1.5 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:
modifiers type name(type varname1, type varname2, ...)
{
    statements
}
The modifiers are optional. See
section 6.8 "Modifiers" for more details about modifiers. The type specifies what kind of data the function returns. For example, the word int would signify that the function returns an integer number. The name 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 statements between the brackets are the function body. Those statements will be executed whenever the function is called.

Example:

int sqr(int x) { return x*x; }
This line defines a function called sqr to take one argument of the type int and also returns an int. The code itself returns the argument multiplied by itself. To call this function from somewhere in the code you could simply put: sqr(17) and that would return the integer value 289.

As the example above shows, return is used to specify the return value of a function. The value after return must be of the type specified before the function name. If the function is specified to return void, nothing at all should be written after return. Note that when a return statement is executed, the function will finish immediately. Any statements following the return will be ignored.

There are many more control structures, they will all be described in a later chapter devoted only to control structures.

1.6 True and false

Throughout this chapter the words true and false 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 explain in a later chapter.)

1.7 Data Types

As you saw in our first examples we have to indicate the type of value returned by a function or contained in a variable. We used integers (int), strings (string), and arrays (with the * notation). The others are mapping, mixed, void, float, multiset, function, object and program. Neither mixed nor void are really types, void signifies that no value should be returned and mixed that the return value can be of any type, or that the variable can contain any type of value. Function, object and program are all types related to object orientation. We will not discuss the last three in any great detail here,
Int
The integer type stores a signed integer. It is 32 bit or 64 depending on architecture.
Float
This variable type stores a floating point number.
Array
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:
arr=({1,2,3});
Or, if you have already created an array, you can change the values in the array like this:
arr [ ind ] = data;
This sets entry number ind in the array arr to data. ind 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 array in front of the variable name we want:
array i;
We can also declare several array variables on the same line:
array i, j;
If we want to specify that the variable should hold an array of strings, we would write:
array (string) i;
String
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:
\nnewline
\rcarriage return
\ttab
\bbackspace
\"" (quotation character)
\\\ (literal backslash)
Mapping
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:
mapping(string:string) map=(["five":"good", "ten":"excellent"]);
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.
Multiset
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.

Chapter 2, A more elaborate example

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.
#!/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"
    })
]);
We want to be able to get a simple list of the records in our database. The function list_records just goes through the mapping records and puts the indices, i.e. the record names, in an array of strings, record_names. By using the builtin function sort 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 sizeof gives the number of items in an array. The printout is formatted through the use of sprintf which works more or less like the C function of the same name.
void list_records()
{
    int i;
    array (string) record_names=sort(indices(records));

    write("Records:\n");
    for(i=0;i<sizeof(record_names);i++)
        write(sprintf("%3d: %s\n", i+1, record_names[i]));
}
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 songs and print the record name followed by the songs, each song on a separate line.
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<sizeof(songs);i++)
        write(sprintf("%3d: %s\n", i+1, songs[i]));
}
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.
int main(int argc, array (string) argv)
{
    if(argc <= 1)
    {
        list_records();
    } else {
        show_record((int) argv[1]);
    }
}

2.1 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 main() function to accept "commands".

2.1.1 add_record()

Using the method Stdio.Readline()->read() we wait for input which will be put into the variable record_name. The argument to ->read() 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 while to check whether we should continue inputting songs. The while(1) means "loop forever", because 1 is always true. This program does not in fact loop forever, because it uses return 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 += operator. It is the same as saying records[record_name]=records[record_name]+({song}).
void add_record()
{
    string record_name=Stdio.Readline()->read("Record name: ");
    records[record_name]=({});
    write("Input song names, one per line. End with '.' on its own line.\n");
    while(1)
    {
        string song;
        song=Stdio.Readline()->read(sprintf("Song %2d: ",
                                                                sizeof(records[record_name])+1));
        if(song==".")
             return;
        if (strlen(song))
            records[record_name]+=({song});
    }
}

2.1.2 main()

The main function now does not care about any command line arguments. Instead we use Stdio.Readline()->read() 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 switch() 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 switch() the argument (in this case cmd) is checked in the case statements. The first case where the expression equals cmd 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 as in 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 switch() block. "add" of course turns control over to the function described above. If the command given is "quit" the exit(0) statement stops the execution of the program and returns 0 (zero) to the operating system, telling it that everything was ok.
int main(int argc, array(string) argv)
{
    string cmd;
    while(cmd=Stdio.Readline()->read("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;
        }
    }
}

2.2 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 Stdio.File. To Pike, a program is a data type which contains code, functions and variables. A program can be cloned which means that Pike creates a data area in memory for the program, places a reference to the program in the data area, and initializes it to act on the data in question. The methods (i.e. functions in the object) and variables in the object Stdio.File enable us to perform actions on the associated data file. The methods we need to use are open, read, write and close. See
chapter 9 "File I/O" for more details.

2.2.1 save()

First we clone a Stdio.File program to the object o. Then we use it to open the file 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 (->) is what you use to access methods and variables in an object. If there is no error we use yet another control structure, foreach, to go through the mapping records 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.
Finally, remember to close the file.
void save(string file_name)
{
    string name, song;
    Stdio.File o=Stdio.File();

    if(!o->open(file_name,"wct"))
    {
        write("Failed to open file.\n");
        return;
    }

    foreach(indices(records),name)
    {
        o->write("Record: "+name+"\n");
        foreach(records[name],song)
            o->write("Song: "+song+"\n");
    }

    o->close();
}

2.2.2 load()

The load function begins much the same, except we open the file named file for reading instead. When receiving data from the file we put it in the string file_contents. The absence of arguments to the method o->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 file_contents 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 foreach statement we can take the string file_contents apart piece by piece, putting each piece back in its proper place in the mapping records.
void load(string file_name)
{
    string name="ERROR";
    string file_contents,line;

    Stdio.File o=Stdio.File();
    if(!o->open(file_name,"r"))
    {
        write("Failed to open file.\n");
        return;
    }

    file_contents=o->read();
    o->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;
            }
        }
    }
}

2.2.3 main() revisited

main() 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.
case "save":
    save(args);
    break;

case "load":
    load(args);
    break;

2.3 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.

2.3.1 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 list_records function). Then we find the name of the record of the number num and use the builtin function m_delete() to remove that entry from records.
void delete_record(int num)
{
    array(string) record_names=sort(indices(records));
    string name=record_names[num-1];

    m_delete(records,name);
}

2.3.2 search()

Searching for songs is quite easy too. To count the number of hits 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 search(), 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 search() 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.
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");
}

2.3.3 main() again

Once again main() is left unchanged, except for yet another two case statements used to call the search() and delete functions, respectively. Note that you must provide an argument to delete or it will not work properly.
case "delete":
    delete_record((int)args);
    break;

case "search":
    find_song(args);
    break;

2.4 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
appendix B "Register program". Read it, study it and enjoy!

2.5 Simple exercises

  • Make a program which writes hello world 10 times.
  • Modify hello_world.pike to write the first argument to the program.
  • Make a program that writes a hello_world program to stdout when executed.
  • Modify the register program to store data about programs and diskettes instead of songs and records.
  • 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.
  • Add code to the register program to check that the arguments to show_record and delete_records are numbers. Also make sure that the number isn't less than one or bigger than the available number of records.
  • Rewrite the register program and put all the code in main().
  • Chapter 3, 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.

    3.1 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.

    3.1.1 if

    The simplest one is called the if statement. It can be written anywhere where a statement is expected and it looks like this:
    if( expression ) statement1; else statement2;
    Please note that there is no semicolon after the parenthesis or after the else. Step by step, if does the following:
    1. First it evaluates expression.
    2. If the result was false go to point 5.
    3. Execute statement1.
    4. Jump to point 6.
    5. Execute statement2.
    6. Done.
    This is actually more or less how the interpreter executes the if statement. In short, statement1 is executed if expression is true otherwise statement2 is executed. If you are interested in having something executed if the expression is false you can drop the whole else part like this:
    if( expression )
        statement1;
    If on the other hand you are not interested in evaluating something if the expression is false you should use the not operator to negate the true/false value of the expression. See chapter 5 for more information about the not operator. It would look like this:
    if( ! expression )
        statement2 ;
    Any of the statements here and in the rest of this chapter can also be a block 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;
    if ( ! expression )
    {
        statement;
        statement;
        statement;
    }

    3.1.2 switch

    A more sophisticated condition control structure is the switch statement. A switch lets you select one of many choices depending on the value of an expression and it can look something like this:
    switch ( expression )
    {
        case constant1:
            statement1;
            break;

        case constant2:
            statement2;
            break;

        case constant3 .. constant4:
            statement3;
            break;

        default:
            statement5;
    }
    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 case 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 case statement. When a break 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.

    One of the case statements in the above example differs in that it is a range. In this case, any value between constant3 and constant4 will cause Pike to jump to statement3. Note that the ranges are inclusive, so the values constant3 and constant4 are also valid.

    3.2 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.

    3.2.1 while

    While is the simplest of the loop control structures. It looks just like an if statement without the else part:
    while ( expression )
        statement;
    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:
    int e=1;
    while(e<5)
    {
        show_record(e);
        e=e+1;
    }
    This would call show_record with the values 1, 2, 3 and 4.

    3.2.2 for

    For is simply an extension of while. It provides an even shorter and more compact way of writing loops. The syntax looks like this:
    for ( initializer_statement ; expression ; incrementor_expression )
        statement ;
    For does the following steps:
    1. Executes the the initializer_statement. The initializer statement is executed only once and is most commonly used to initialize the loop variable.
    2. Evaluates expression
    3. If the result was false it exits the loop and continues with the program after the loop.
    4. Executes statement.
    5. Executes the increment_expression.
    6. Starts over from 2.
    This means that the example in the while section can be written like this:
    for(int e=1; e<5; e=e+1)
        show_record(e);

    3.2.3 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.
    do
        statement;
    while ( expression );
    As usual, the statement can also be a block of statements, and then you do not need a semicolon after it. To clarify, this statement executes statement first, and then evaluates the expression. If the expression is true 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:
    do {
        modem->write("ATDT441-9109\n"); // Dial 441-9109
    } while(modem->gets()[..6]] != "CONNECT");
    This example assumes you have written something that can communicate with the modem by using the functions write and gets.

    3.2.4 foreach

    Foreach is unique in that it does not have an explicit test expression evaluated for each iteration in the loop. Instead, foreach executes the statement once for each element in an array. Foreach looks like this:
    foreach ( array_expression, variable )
        statement ;
    We have already seen an example of foreach in the find_song function in chapter 2. What foreach does is:
    1. It evaluates the array_expression which must return an array.
    2. If the array is empty, exit the loop.
    3. It then assigns the first element from the array to the variable.
    4. Then it executes the statement.
    5. If there are more elements in the array, the next one is assigned to the variable, otherwise exit the loop.
    6. Go to point 4.
    Foreach is not really necessary, but it is faster and clearer than doing the same thing with a for loop, as shown here:
    array tmp1= array_expression;
    for ( tmp2 = 0; tmp2 < sizeof(tmp1); tmp2++ )
    {
        variable = tmp1 [ tmp2 ];
        statement;
    }

    3.3 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:

    3.3.1 break

    break exits a loop or switch statement immediately and continues executing after the loop. Break can not be used outside of a loop or switch. It is quite useful in conjunction with while(1) to construct command parsing loops for instance:
    while(1)
    {
        string command=Stdio.Readline()->read("> ");
        if(command=="quit") break;
        do_command(command);
    }

    3.3.2 continue

    Continue does almost the same thing as break, 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 while loop, this means it jumps up to the top again. For a for loop, it jumps to the incrementor expression. For a do-while loop it jumps down to the expression at the end. To continue our example above, continue can be used like this:
    while(1)
    {
        string command=Stdio.Readline()->read("> ");
        if(strlen(command) == 0) continue;
        if(command=="quit") break;
        do_command(command);
    }
    This way, do_command will never be called with an empty string as argument.

    3.3.3 return

    Return 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 return. Of course the type of the return value must match the type in the function declaration. If your function declaration is int main() the value after return must be an int. For instance, if we wanted to make a program that always returns an error code to the system, just like the UNIX command false this is how it would be done:
    #!/usr/local/bin/pike

    int main()
    {
        return 1;
    }
    This would return the error code 1 to the system when the program is run.

    3.4 Exercises

  • End all functions in the examples in chapter two with a return statement.
  • Change all foreach loops to for or while loops.
  • Make the find_song function in chapter 2 return when the first matching song is found.
  • Make the find_song function write the number of the record the song is on.
  • If you failed to get the program to work properly in the last exercise of chapter 2, try it again now.
  • Make a program that writes all the numbers from 1 to 1000.
  • Modify the program in the previous exercise to NOT write numbers divisible by 3, 7 or 17.
  • Make a program that writes all the prime numbers between 1 and 1000.
  • Chapter 4, 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: basic types, and pointer types. The difference is that basic types are copied when assigned to a variable. With pointer types, merely the pointer is copied, that way you get two variables pointing to the same thing.

    4.1 Basic types

    The basic types are int, float and string. 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.

    4.1.1 int

    Int 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 int might be larger than 32 bits. Since they are integers, no decimals are allowed. An integer constant can be written in several ways:
    78 // decimal number
    0116 // octal number
    0x4e // hexadecimal number
    'N' // Ascii character
    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 N which just happens to be 78 in ASCII.

    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++.

    All the arithmetic, bitwise and comparison operators can be used on integers. Also note these functions:

    int intp(mixed x)
    This function returns 1 if x is an int, 0 otherwise.
    int random(int x)
    This function returns a random number greater or equal to zero and smaller than x.
    int reverse(int x)
    This function reverses the order of the bits in x and returns the new number. It is not very useful.
    int sqrt(int x)
    This computes the square root of x. The value is always rounded down.

    4.1.2 float

    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 float. 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:
    3.14159265358979323846264338327950288419716939937510 // Pi
    1.0e9 // A billion
    1.0e-9 // A billionth
    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 float might have higher accuracy than that. In the exponential form, e means "times 10 to the power of", so 1.0e9 is equal to "1.0 times 10 to the power of 9".

    All the arithmetic and comparison operators can be used on floats. Also, these functions operates on floats:

    trigonometric functions
    The trigonometric functions are: sin, asin, cos, acos, tan and atan. 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.
    float log(float x)
    This function computes the natural logarithm of x,
    float exp(float x)
    This function computes e raised to the power of x.
    float pow(float|int x, float|int y)
    This function computes x raised to the power of y.
    float sqrt(float x)
    This computes the square root of x.
    float floor(float x)
    This function computes the largest integer value less than or equal to x. Note that the value is returned as a float, not an int.
    float ceil(float x),
    This function computes the smallest integer value greater than or equal to x and returns it as a float.
    float round(float x),
    This function computes the closest integer value to x and returns it as a float.

    4.1.3 string

    A string can be seen as an array of values from 0 to 2³²-1. 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 shared, 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:
    "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
    "\x4e" // N (4e is the hexadecimal ASCII value for N)
    "\d78" // N (78 is the decimal ACII value for N)
    "hello world\116\t\n\r\b\0\"\\" // All of the above
    "\xff" // the character 255
    "\xffff" // the character 65536
    "\xffffff" // the character 16777215
    "\116""3" // 'N' followed by a '3'
    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, \t is the sequence to produce a tab character, \\ is used when you want one backslash and \" is used when you want a double quote (") to be a part of the string instead of ending it. Also, \XXX where XXX is an octal number from 0 to 37777777777 or \xXX where XX is 0 to ffffffff lets you write any character you want in the string, even null characters. From version 0.6.105, you may also use \dXXX where XXX is 0 to 2³²-1. If you write two constant strings after each other, they will be concatenated into one string.

    You might be surprised to see that individual characters can have values up to 2³²-1 and wonder how much memory that use. Do not worry, Pike automatically decides the proper amount of memory for a string, so all strings with character values in the range 0-255 will be stored with one byte per character. You should also beware that not all functions can handle strings which are not stored as one byte per character, so there are some limits to when this feature can be used.

    Although strings are a form of arrays, they are immutable. This means that there is no way to change an individual character within a string without creating a new string. This may seem strange, but keep in mind that strings are shared, so if you would change a character in the string "foo", you would change *all* "foo" everywhere in the program.

    However, the Pike compiler will allow you to to write code like you could change characters within strings, the following code is valid and works:

    string s="hello torld";
    s[6]='w';
    However, you should be aware that this does in fact create a new string and it may need to copy the string s to do so. This means that the above operation can be quite slow for large strings. You have been warned. Most of the time, you can use replace, sscanf, `/ or some other high-level string operation to avoid having to use the above construction too much.

    All the comparison operators plus the operators listed here can be used on strings:

    Summation
    Adding strings together will simply concatenate them. "foo"+"bar" becomes "foobar".
    Subtraction
    Subtracting one string from another will remove all occurrences of the second string from the first one. So "foobarfoogazonk" - "foo" results in "bargazonk".
    Indexing
    Indexing will let you get the ASCII value of any character in a string. The first index is zero.
    Range
    The range operator will let you copy any part of the string into a new string. Example: "foobar"[2..4] will return "oba".
    Division
    Division will let you divide a string at every occurrence of a word or character. For instance if you do "foobargazonk" / "o" the result would be ({"f","","bargaz","nk"}). It is also possible to divide the string into strings of length N by dividing the string by N. If N is converted to a float before dividing, the reminder of the division will be included in the result.
    Multiplication
    The inverse of the division operator can be accomplished by multiplying an array with a string. So if you evaluate ({"f","","bargaz","nk"}) * "o" the result would be "foobargazonk".
    Modulo
    To complement the division operator, you can do string % int. This operator will simply return the part of the string that was not included in the array returned by string / int

    Also, these functions operates on strings:

    string String.capitalize(string s)
    Returns s with the first character converted to upper case.
    int String.count(string haystack, string needle)
    Returns the number of occurances of needle in haystack. Equvivalent to sizeof(haystack/needle)-1.
    int String.width(string s)
    Returns the width s in bits (8, 16 or 32).
    string lower_case(string s)
    Returns s with all the upper case characters converted to lower case.
    string replace(string s, string from, string to)
    This function replaces all occurrences of the string from in s with to and returns the new string.
    string reverse(string s)
    This function returns a copy of s with the last byte from s first, the second last in second place and so on.
    int search(string haystack, string needle)
    This function finds the first occurrence of needle in haystack and returns where it found it.
    string sizeof(string s)
    Same as strlen(s), returns the length of the string.
    int stringp(mixed s)
    This function returns 1 if s is a string, 0 otherwise.
    int strlen(string s)
    Returns the length of the string s.
    string upper_case(string s)
    This function returns s with all lower case characters converted to upper case.

    4.2 Pointer types

    The basic types are, as the name implies, very basic. They are the foundation, most of the pointer types are merely interesting ways to store the basic types. The pointer types are array, mapping, multiset, program, object and function. They are all pointers 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.

    4.2.1 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 elements and are accessible through the index operator. To write a constant array you enclose the values you want in the array with ({ }) like this:
    ({ }) // 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
    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.


    fig 4.1

    Operators and functions usable with arrays:

    indexing ( arr [ c ] )
    Indexing an array retrieves or sets a given element in the array. The index c has to be an integer. To set an index, simply put the whole thing on the left side of an assignment, like this: arr [ c ] = new_value
    range ( arr [ from .. to ] )
    The range copies the elements from, from+1, , from+2 ... to into a new array. The new array will have the size to-from+1.
    comparing (a == b and a != b)
    The equal operator returns 1 if a and b are the same arrays. It is not enough that they have the same size and same data. They must be the same array. For example: ({1}) == ({1}) would return 0, while array(int) a=({1}); return a==a; would return 1. Note that you cannot use the operators >, >=, < or <= on arrays.
    Summation (a + b)
    As with strings, summation concatenates arrays. ({1})+({2}) returns ({1,2}).
    Subtractions (a - b)
    Subtracting one array from another returns a copy of a with all the elements that are also present in b removed. So ({1,3,8,3,2}) - ({3,1}) returns ({8,2}).
    Intersection (a & b)
    Intersection returns an array with all values that are present in both a and b. The order of the elements will be the same as the the order of the elements in a. Example: ({1,3,7,9,11,12}) & ({4,11,8,9,1}) will return: ({1,9,11}).
    Union (a | b)
    Union works almost as summation, but it only adds elements not already present in a. So, ({1,2,3}) | ({1,3,5}) will return ({1,2,3,5}). Note: the order of the elements in a can be changed!
    Xor (a ^ b)
    This is also called symmetric difference. It returns an array with all elements present in a or b but the element must NOT be present in both. Example: ({1,3,5,6}) ^ ({4,5,6,7}) will return ({1,3,4,7}).
    Division (a / b)
    This will split the array a into an array of arrays. If b is another array, a will be split at each occurance of that array. If b is an integer or float, a will be split between every bth element. Examples: ({1,2,3,4,5})/({2,3}) will return ({ ({1}), ({4,5}) }) and ({1,2,3,4})/2 will return ({ ({1,2}), ({3,4}) }).
    Modulo (a % b)
    This operation is valid only if b is an integer. It will return the part of the array that was not included by dividing a by b.
    array aggregate(mixed ... elems)
    This function does the same as the ({ }) operator; it creates an array from all arguments given to it. In fact, writing ({1,2,3}) is the same as writing aggregate(1,2,3).
    array allocate(int size)
    This function allocates a new array of size size. All the elements in the new array will be zeroes.
    int arrayp(mixed a)
    This function returns 1 if a is an array, 0 otherwise.
    array column(array(mixed) a, mixed ind)
    This function goes through the array a and indexes every element in it on ind and builds an array of the results. So if you have an array a in which each element is a also an array. This function will take a cross section, by picking out element ind from each of the arrays in a. Example: column( ({ ({1,2,3}), ({4,5,6}), ({7,8,9}) }), 2) will return ({3,6,9}).
    int equal(mixed a, mixed b)
    This function returns 1 if if a and b 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.
    array Array.filter(array a, mixed func, mixed ... args)
    filter returns every element in a for which func returns true when called with that element as first argument, and args for the second, third, etc. arguments.
    array Array.map(array a, mixed func, mixed ... args)
    This function works similar to Array.filter but returns the results of the function func instead of returning the elements from a for which func returns true.
    array replace(array a, mixed from, mixed to)
    This function will create a copy of a with all elements equal to from replaced by to.
    array reverse(array a)
    Reverse will create a copy of a with the last element first, the last but one second, and so on.
    array rows(array a, array indexes)
    This function is similar to column. It indexes a with each element from indexes and returns the results in an array. For example: rows( ({"a","b","c"}), ({ 2,1,2,0}) ) will return ({"c","b","c","a"}).
    int search(array haystack, mixed needle)
    This function returns the index of the first occurrence of an element equal (tested with ==) to needle in the array haystack.
    int sizeof(mixed arr)
    This function returns the number of elements in the array arr.
    array sort(array arr, array ... rest)
    This function sorts arr 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 arr. See chapter 16 "Builtin functions" for more details.
    array uniq(array a)
    This function returns a copy of the array a with all duplicate elements removed. Note that this function can return the elements in any order.

    4.2.2 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:


    fig 4.2

    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 m and we index it like this: m [ i ] the lookup function will quickly find the index 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:

    ([ ]) // 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

    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.

    The following operators and functions are important:

    indexing ( m [ ind ] )
    As discussed above, indexing is used to retrieve, store and add values to the mapping.
    addition, subtraction, union, intersection and xor
    All these operators works exactly as on arrays, with the difference that they operate on the indices. In those cases when the value can come from either mapping, it will be taken from the right side of the operator. This makes it easier to add new values to a mapping with +=. Some examples:
    ([1:3, 3:1]) + ([2:5, 3:7]) returns ([1:3, 2:5, 3:7 ])
    ([1:3, 3:1]) - ([2:5, 3:7]) returns ([1:3])
    ([1:3, 3:1]) | ([2:5, 3:7]) returns ([1:3, 2:5, 3:7 ])
    ([1:3, 3:1]) & ([2:5, 3:7]) returns ([3:7])
    ([1:3, 3:1]) ^ ([2:5, 3:7]) returns ([1:3, 2:5])
    same ( a == b )
    Returns 1 if a is the same mapping as b, 0 otherwise.
    not same ( a != b )
    Returns 0 if a is the same mapping as b, 1 otherwise.
    array indices(mapping m)
    Indices returns an array containing all the indices in the mapping m.
    mixed m_delete(mapping m, mixed ind)
    This function removes the index-value pair with the index ind from the mapping m. It will return the value that was removed.
    int mappingp(mixed m)
    This function returns 1 if m is a mapping, 0 otherwise.
    mapping mkmapping(array ind, array val)
    This function constructs a mapping from the two arrays ind and val. Element 0 in ind and element 0 in val becomes one index-value pair. Element 1 in ind and element 1 in val becomes another index-value pair, and so on..
    mapping replace(mapping m, mixed from, mixed to)
    This function creates a copy of the mapping m with all values equal to from replaced by to.
    mixed search(mapping m, mixed val)
    This function returns the index of the 'first' index-value pair which has the value val.
    int sizeof(mapping m)
    Sizeof returns how many index-value pairs there are in the mapping.
    array values(mapping m)
    This function does the same as indices, but returns an array with all the values instead. If indices and values 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 mkmapping to rebuild the mapping m again.
    int zero_type(mixed t)
    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 zero_type(m [ ind ]) returns 1, it means that the value was not present in the mapping. If the value was present in the mapping, zero_type will return something else than 1.

    4.2.3 multiset

    A multiset is almost the same thing as a mapping. The difference is that there are no values:


    fig 4.3

    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: mset[ ind ] = val the index ind will be added to the multiset mset if val is true. Otherwise ind will be removed from the multiset instead.

    Writing a constant multiset is similar to writing an array:

    (< >) // Empty multiset
    (< 17 >) // Multiset with one index: 17
    (< "", 1, 3.0, 1 >) // Multiset with 3 indices
    Note that you can actually have more than one of the same index in a multiset. This is normally not used, but can be practical at times.

    4.2.4 program

    Normally, when we say program we mean something we can execute from a shell prompt. However, Pike has another meaning for the same word. In Pike a program is the same as a class in C++. A program 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 program does not hold space to store any data however. All the information in a program 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 object which is the next data type we will discuss.


    fig 4.4
    Writing a program is easy, in fact, every example we have tried so far has been a program. To load such a program into memory, we can use compile_file which takes a file name, compiles the file and returns the compiled program. It could look something like this:
    program p = compile_file("hello_world.pike");
    You can also use the cast operator like this:
    program p = (program) "hello_world";
    This will also load the program hello_world.pike, the only difference is that it will cache the result so that next time you do (program)"hello_world" you will receive the _same_ program. If you call compile_file("hello_world.pike") repeatedly you will get a new program each time.

    There is also a way to write programs inside programs with the help of the class keyword:

    class class_name {
        inherits, variables and functions
    }
    The class keyword can be written as a separate entity outside of all functions, but it is also an expression which returns the program written between the brackets. The class_name is optional. If used you can later refer to that program by the name class_name. 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 structs (or records if you program Pascal). Let's look at an example:
    class record {
        string title;
        string artist;
        array(string) songs;
    }

    array(record) records = ({});

    void add_empty_record()
    {
        records+=({ record() });
    }

    void show_record(record rec)
    {
        write("Record name: "+rec->title+"\n");
        write("Artist: "+rec->artist+"\n");
        write("Songs:\n");
        foreach(rec->songs, string song)
            write(" "+song+"\n");
    }
    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 program called record which has three identifiers. In add_empty_record a new object is created by calling record. This is called cloning and it allocates space to store the variables defined in the class record. Show_record takes one of the records created in add_empty_record and shows the contents of it. As you can see, the arrow operator is used to access the data allocated in add_empty_record. If you do not understand this section I suggest you go on and read the next section about objects and then come back and read this section again.

    cloning
    To create a data area for a program you need to instantiate or clone the program. This is accomplished by using a pointer to the program as if it was a function and call it. That creates a new object and calls the function create in the new object with the arguments. It is also possible to use the functions new() and clone() which do exactly the same thing except you can use a string to specify what program you want to clone.
    compiling
    All programs are generated by compiling a string. The string may of course be read from a file. For this purpose there are three functions:
    program compile(string p);
    program compile_file(string filename);
    program compile_string(string p, string filename);
    compile_file simply reads the file given as argument, compiles it and returns the resulting program. compile_string instead compiles whatever is in the string p. The second argument, filename, is only used in debug printouts when an error occurs in the newly made program. Both compile_file and compile_string calls compile to actually compile the string after calling cpp on it.
    casting
    Another way of compiling files to program is to use the cast operator. Casting a string to the type program 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.
    int programp(mixed p)
    This function returns 1 if p is a program, 0 otherwise.
    comparisons
    As with all data types == and != can be used to see if two programs are the same or not.

    The following operators and functions are important:

    cloning ( p ( args ) )
    Creates an object from a program. Discussed in the next section.
    indexing ( p [ string ], or p -> identifier )
    Retreives the value of the named constant from a program.
    array(string) indices(program p)
    Returns an array with the names of all non-static constants in the program.
    array(mixed) values(program p)
    Returns an array with the values of all non-static constants in the program.

    4.2.5 object

    Although programs are absolutely necessary for any application you might want to write, they are not enough. A program doesn't have anywhere to store data, it just merely outlines how to store data. To actually store the data you need an object. 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 program outlines where in the object different variables are stored.

    fig 4.5
    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:
    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(record) records = ({});

    void add_empty_record()
    {
        records+=({ record() });
    }

    void show_record(object rec)
    {
        rec->show();
    }
    Here we can clearly see how the function show prints the contents of the variables in that object. In essence, instead of accessing the data in the object with the -> 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 record stores its data, but we do not have to change anything outside of the record program.

    Functions and operators relevant to objects:

    indexing
    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 -> operator is actually the same as indexing. This means that o->foo is the same as o["foo"]
    cloning
    As discussed in the section about programs, cloning a program can be done in two different ways:
    Whenever you clone an object, all the global variables will be initialized. After that the function create will be called with any arguments you call the program with.
    void destruct(object o)
    This function invalidates all references to the object o and frees all variables in that object. This function is also called when o runs out of references. If there is a function named destroy in the object, it will be called before the actual destruction of the object.
    array(string) indices(object o)
    This function returns a list of all identifiers in the object o.
    program object_program(object o)
    This function returns the program from which o was cloned.
    int objectp(mixed o)
    This function returns 1 if o is an object, 0 otherwise. Note that if o has been destructed, this function will return 0.
    object this_object()
    This function returns the object in which the interpreter is currently executing.
    array values(object o)
    This function returns the same as rows(o,indices(o)). That means it returns all the values of the identifiers in the object o.
    comparing
    As with all data types == and != can be used to check if two objects are the same or not.

    4.2.6 function

    When indexing an object on a string, and that string is the name of a function in the object a function is returned. Despite its name, a function is really a function pointer.

    fig 4.6
    When the function pointer is called, the interpreter sets this_object() 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:
    int foo() { return 1; }
    function bar() { return foo; }
    int gazonk() { return foo(); }
    int teleledningsanka() { return bar()(); }
    In this example, the function bar returns a pointer to the function foo. No indexing is necessary since the function foo is located in the same object. The function gazonk simply calls foo. However, note that the word foo in that function is an expression returning a function pointer that is then called. To further illustrate this, foo has been replaced by bar() in the function teleledningsanka.

    For convenience, there is also a simple way to write a function inside another function. To do this you use the lambda keyword. The syntax is the same as for a normal function, except you write lambda instead of the function name:

    lambda ( types ) { statements }
    The major difference is that this is an expression that can be used inside an other function. Example:
    function bar() { return lambda() { return 1; }; )
    This is the same as the first two lines in the previous example, the keyword lambda allows you to write the function inside bar.

    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.

    This is what you can do with a function pointer.

    calling ( f ( mixed ... args ) )
    As mentioned earlier, all function pointers can be called. In this example the function f is called with the arguments args.
    string function_name(function f)
    This function returns the name of the function f is pointing at.
    object function_object(function f)
    This function returns the object the function f is located in.
    int functionp(mixed f)
    This function returns 1 if f is a function, 0 otherwise. If f is located in a destructed object, 0 is returned.
    function this_function()
    This function returns a pointer to the function it is called from. This is normally only used with lambda functions because they do not have a name.

    4.3 Sharing data

    As mentioned in the beginning of this chapter, the assignment operator (=) 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:
    int main(int argc, array(string) argv)
    {
        array(string) tmp;
        tmp=argv;
        argv[0]="Hello world.\n";
        write(tmp[0]);
    }
    This program will of course write Hello world.

    Sometimes you want to create a copy of a mapping, array or object. To do so you simply call copy_value 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.

    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: copy_of_arr = arr + ({}); If you need to copy a mapping you use an empty mapping, and for a multiset you use an empty multiset.

    4.4 Writing data types

    When declaring a variable, you also have to specify what type of variable it is. For most types, such as int and string this is very easy. But there are much more interesting ways to declare variables than that, let's look at a few examples:
    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

    // x is a mapping from int to string
    mapping(string:int) x;

    // x implements Stdio.File
    Stdio.File x;

    // x implements Stdio.File
    object(Stdio.File) x;

    // 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:array(string)))) x;
    As you can see there are some interesting ways to specify types. Here is a list of what is possible:
    mixed
    This means that the variable can contain any type, or the function return any value
    array( type )
    This means an array of elements with the type type.
    type *
    This also means an array of elements with the type type.
    mapping( key type : value type )
    This is a mapping where the keys are of type key type and the values of value type.
    multiset ( type )
    This means a multiset containing values of the type type.
    object ( program )
    This means an object which 'implements' the specified program. The program 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 inherit for more information about this casting. The compiler will assume that any function or variable accessed in this object has the same type information as that function or variable has in program.
    program
    This too means 'an object which implements program'. program can be a class or a constant.
    function( argument types : return type )
    This is a function taking the specified arguments and returning return type. The argument types is a comma separated list of types that specify the arguments. The argument list can also end with ... to signify that there can be any amount of the last type.
    type1 | type2
    This means either type1 or type2
    void
    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: function(int|void:void) this means a function that may or may not take an integer argument and does not return a value.

    Chapter 5, 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 operators 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.

    5.1 Arithmetic operators

    The arithmetic operators are the simplest ones, since they work just like you remember from math in school. The arithmetic operators are:

    Function Syntax Identifier Returns
    Addition a + b `+ the sum of a and b
    Subtraction a - b `- b subtracted from a
    Negation - a `- minus a
    Multiplication a * b `* a multiplied by b
    Division a / b `/ a divided by b
    Modulo a % b `% the remainder of a division between a and b

    The third column, "Identifier" is the name of the function that actually evaluates the operation. For instance, a + b can also be written as `+(a, b). I will show you how useful this can be at the end of this chapter.

    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 modulo operator. The modulo operator returns the remainder from an integer division. It is the same as calculating a - floor(a / b) * b. floor rounds the value down to closest lower integer value. Note that the call to floor 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, 8 / 3 would return 2.

    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.

    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:

    Operation Returned type Returned value
    int + int int the sum of the two values
    float + int
    int + float
    float + float
     float the sum of the two values
    string + string
    int + string
    float + string
    string + int
    string + float
     string 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.
    array + array array The two arrays are concatenated into a new array and that new array is returned.
    mapping + mapping mapping 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.
    multiset + multiset multiset A multiset with all the indices from both multisets is returned.
    int - int int The right value subtracted from the left.
    float - int
    int - float
    float - float
     float The right value subtracted from the left.
    string - string string A copy of the left string with all occurrences of the right string removed.
    array - array array A copy of the left array with all elements present in the right array removed. Example: ({2,1,4,5,3,6,7}) - ({3,5,1}) will return ({2,4,6,7}).
    mapping - mapping mapping A new mapping with all index-value pairs from the left mapping, except those indices that are also present in the right mapping.
    multiset - multiset multiset A copy of the left multiset without any index present in the left multiset.
    int int Same as 0 - int.
    float float Same as 0 - float.
    int * int int the product of the two values
    float * int
    int * float
    float * float
     float the product of the two values
    array(string) * string string All the strings in the array are concatenated with the string on the right in between each string. Example: ({"foo","bar"})*"-" will return "foo-bar".
    array(array) * array array All the arrays in the left array are concatenated with the array on the right in between each array. Example: ({ ({"foo"}) ,({"bar"})})*({"-"}) will return ({ "foo","-","bar" }).
    string * int string This operation will concatenate the string N times. Example: "foo"*3 will return "foofoofoo".
    array * int string This operation will concatenate the array N times. Example: ({"foo"})*3 will return ({"foo","foo","foo"}).
    int / int int The right integer divided by the left integer rounded towards minus infinity.
    float / int
    int / float
    float / float
     float The right value divided by the left value.
    string / string array(string) 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: "foo-bar"/"-" will return ({"foo","bar"})
    string / int array(string) This will split the string into pieces. The size of the pieces is given by the integer. Only complete pieces will be included in the result, the 'reminder' is discarded. Example: "foo-bar"/2 will return ({"fo","o-","ba"})
    string / float array(string) This is similar to dividing a string with an integer, but it allows fraction-sized segments and the reminder will always be included. Example: "foo-bar"/2.5 will return ({"fo","o-b","ar"})
    array / int array(array) This is similar to dividing a string with an integer, but splits an array. Example: ({1,2,3,4,5,6,7})/2 will return ({({1,2}),({3,4}),({5,6})})
    array / float array(array) You should be able to predict what this does by now. :) Example: ({1,2,3,4,5,6,7,8})/2.5 will return ({({1,2}),({3,4,5}),({6,7}),({8})})
    int % int int The remainder of a division. If a and b are integers, a%b is the same as a-(a/b)*b
    float % float
    int % float
    float % int
     float The remainder of a division. If a and b are floats, a%b is the same as a-floor(a/b)*b
    string % int string The remainder of a string division. Example: "foo-bar"%2 will return "r"
    array % int string The remainder of an array division. Example: ({1,2,3,4,5,6,7})%2 will return ({7})

    5.2 Comparison operators

    The arithmetic operators would be hard to use for anything interesting without the ability to compare the results to each other. For this purpose there are six comparison operators:

    Function Syntax Identifier Returns
    Same a == b `== 1 if a is the same value as b, 0 otherwise
    Not same a != b `!= 0 if a is the same value as b, 1 otherwise
    Greater than a > b `>  1 if a is greater than b, 0 otherwise
    Greater than or equal to a >= b `>= 1 if a is greater to or equal to b, 0 otherwise
    Lesser than a < b `<  1 if a is lesser than b, 0 otherwise
    Lesser than or equal to a <= b `<= 1 if a is lesser than or equal to b, 0 otherwise

    The == and != operators can be used on any type. For two values to be same they must be the same type. Therefore 1 and 1.0 are not same. Also, for two values of pointer types 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.

    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 values of the environment variables LC_CTYPE and LC_LANG are respected.

    5.3 Logical operators

    Logical operators are operators that operate with truth values. In Pike any value except zero is considered true. 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:

    Function Syntax Returns
    And a && b If a is false, a is returned and b is not evaluated. Otherwise, b is returned.
    Or a || b If a is true, a is returned and b is not evaluated. Otherwise, b is returned.
    Not ! a Returns 0 if a is true, 1 otherwise.
    If-else a ? b : c If a is true, b is returned and c is not evaluated. Otherwise c is returned and b is not evaluated.

    5.4 Bitwise/set operators

    These operators are used to manipulate bits as members in sets. They can also manipulate arrays, multisets and mappings as sets.

    Function Syntax Identifier Returns
    Shift left a << b `<< Multiplies a by 2 b times.
    Shift right a >> b `>> Divides a by 2 b times.
    Inverse (not) ~ a `~ Returns -1-a.
    Intersection (and) a & b `& All elements present in both a and b.
    Union (or) a | b `| All elements present in a or b.
    Symmetric difference (xor) a ^ b `^ All elements present in a or b, but not present in both.

    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 work I suggest you go look it up in some other programming book or just don't use these operators on integers.

    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: ({7,6,4,3,2,1}) & ({1, 23, 5, 4, 7}) will return ({7,4,1}). 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 operation on a mapping however, only the indices are considered. The values are just copied with the indices. 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: ([1:2]) | ([1:3]) will return ([1:3]).

    5.5 Indexing

    The index and range operators are used to retrieve information from a complex data type.

    Function Syntax Identifier Returns
    Index a [ b ] `[] Returns the index b from a.
    Lookup a ->identifier `-> Looks up the identifier. Same as a["identifier"].
    Assign index a [ b ] = c `[]=; Sets the index b in a to c.
    Assign index a ->identifier = c `->= Sets the index "identifier" in a to c.
    Range a [ b .. c ] `[..] Returns a slice of a starting at the index b and ending at c.
    Range a [ .. c ] `[..] Returns a slice of a starting at the beginning of a and ending at c.
    Range a [ b .. ] `[..] Returns a slice of a from the index b to the end of a.

    The index operator can be written in two different ways. It can be written as ob [ index ] or ob->identifier. However, the latter syntax is equal to ob [ "identifier" ]. 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:

    Operation Returns
    string[int] Returns the ascii value of the Nth character in the string.
    array[int] Return the element in the array corresponding to the integer.
    array[int]=mixed Sets the element in the array to the mixed value.
    mapping[mixed]
    mapping->identifier
     Returns the value associated with the index, 0 if it is not found.
    mapping[mixed]=mixed
    mapping->identifier=mixed
     Associate the second mixed value with the first mixed value.
    multiset[mixed]
    multiset->identifier
     Returns 1 if the index (the value between the brackets) is present in the multiset, 0 otherwise.
    multiset[mixed]=mixed
    multiset->identifier=mixed
     If the mixed value is true the index is added to the multiset. Otherwise the index is removed from the multiset.
    object[string]
    object->identifier
     Returns the value of the named identifier in the object.
    object[string]=mixed
    object->identifier=mixed
     Set the given identifier in the object to the mixed value. Only works if the identifier references a variable in the object.
    program[string]
    program->identifier
     Returns the value of the named constant identifier in the program.
    string[int..int] Returns a piece of the string.
    array[int..int] Returns a slice of the array.

    When indexing an array or string 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 arr[-i] is the same as arr[sizeof(arr)-i]. 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 a[b..c] will be treated as follows:

    5.6 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:
    variable = expression;
    The variable 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 variable to expression. Note that the above is also an expression which returns the value of the expression. This can be used in some interesting ways:
    variable1 = variable2 = 1; // Assign 1 to both variables
    variable1 =(variable2 = 1); // Same as above

    // Write the value of the expression, if any
    if(variable = expression)
        write(variable);
    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 if(variable == expression) 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:

    Syntax Same as Function
    variable += expression  variable = variable + expression Add expression to variable
    variable -= expression  variable = variable - expression Subtract expression from variable
    variable *= expression  variable = variable * expression Multiply variable with expression
    variable /= expression  variable = variable / expression Divide variable by expression
    variable %= expression  variable = variable % expression Modulo variable by expression
    variable <<= expression  variable = variable << expression Shift variable expression bits left
    variable >>= expression  variable = variable >> expression Shift variable expression bits right
    variable |= expression  variable = variable | expression Or variable with expression
    variable &= expression  variable = variable & expression And variable with expression
    variable ^= expression  variable = variable ^ expression Xor variable with expression

    In all of the above expressions variable can actually be any of type of assignable values. Assignable values are also known as lvalues and here is a list of lvalues:

    Lvalue type Syntax Valid assignment type
    a local or global variable   identifier  same as variable
    an element in an array   array [ int ] any type
    elements in elements in an array   array [ string ] any type
    This is like map(arr, `[]=,string_indexing_element, assignment_element)
    an element in an string   string [ int ] integer
    an element in a mapping   mapping[mixed] or mapping->identifier  any type
    an element in a multiset   multiset[mixed] or multiset->identifier  true / false
    a variable in an object   object[string] or object->identifier  same type as named variable
    a list of lvalues   [ lvalue, lvalue ]   an array, first value in the array will be assigned to the first lvalue in the list, second value in the array to the second value in the list etc.

    5.7 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.

    Function Syntax Identifier Returns
           
    splice @ a none Sends each element in the array a as an individual argument to a function call.
    Increment ++ a none Increments a and returns the new value of a.
    Decrement -- a none Decrements a and returns the new value of a.
    Post increment a ++ none Increments a and returns the old value of a.
    Post decrement a -- none Decrements a and returns the old value of a.
    casting (type) a none Tries to convert a into a value of the specified type.
    Null a, b none Evaluates a and b, then returns b.

    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. 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 clone is implemented like this:

    object clone(mixed p, mixed ... args) { ( (program)p )(@args); }

    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.

    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 (++a) 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 (a++) it will instead return the value of the variable before it was incremented/decremented.

    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:

    casting from to operation
    int string Convert the int to ASCII representation
    float string Convert the float to ASCII representation
    string int Convert decimal, octal or hexadecimal number to an int. Note that this will only work with decimal numbers in future versions.
    string float Convert ASCII number to a float.
    string program String is a filename, compile the file and return the program. Results are cached.
    string object This first casts the string to a program, (see above) and then clones the result. Results are cached.
    object type This calls the function 'cast' with a string containing the type as an argument.
    string array Same as doing values(string)
    array(int) string This does the inverse of the operation above. Ie. it constructs a string from an array of integers.
    array array(type) This recursively casts all values in the array to type.
    mapping array Same as Array.transpose(({indices(mapping),values(mapping)). Example: (array)([1:2,3:4]) will return ({ ({1,2}), ({3,4}) })
    multiset array Same as doing indices(multiset).
    int float Returns a float with the same value as the integer.
    float int Returns the integer closest to the float.
    function object Same as function_object(function).

    You can also use the cast operator to tell the compiler things. If a is a variable of type mixed containing an int, then the expression (int)a can be used instead of a and that will tell the compiler that the type of that expression is int.

    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.

    5.8 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 with lower. The following table shows the relative priority of all the operators in descending order:

    (a) a() a[b] a->b a[b..c] ({}) ([]) (<>)
    !a ~a (type)a ++a --a
    a++ a--
    a*b a/b a%b
    a+b a-b
    a>>b a<<b
    a>b a>=b a<b a<=b
    a==b a!=b
    a&b
    a^b
    a|b
    &&
    ||
    a?b:c
    =
    @a
    ,

    Examples:

    The expression is evaluated in this order:
    1+2*2   1+(2*2)
    1+2*2*4   1+((2*2)*4)
    (1+2)*2*4   ((1+2)*2)*4
    1+4,c=2|3+5   (1+4),(c=((2|3)+5))
    1+5 & 4 == 3   (1+(5 & 4)) == 3
    c=1,99   (c=1),99
    !a++ + ~--a()  (!(a++)) + (~((--a)()))

    5.9 Operator functions

    As mentioned earlier a + b can just as well be written as `+(a, b). Together with the function map 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:
    map(arr, `-)
    This will return an array with each element negated.
    map(text/"\n",`/," ")
    This will divide a text into lines, each line will then be mapped through `/ and divided into an array of words.
    `+(0, @arr)
    This will add all the integers in the array arr together.
    int abs(int a) { return ( a>0 ? `+ : `-)(a); }
    This is a rather absurd but working function which will return the absolute value of a.

    Chapter 6, Object orientation

    As mentioned 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 oriented programming.

    6.1 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 Pike-ish terms to C++-ish terms:
    a class
    a class
    a clone
    an instance of a class
    to clone
    to create an instance
    an object
    an instance of a class
    a program
    a class

    6.2 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. Now we have a running system with many running programs, each performing only the task it was designed for.

    This analogy has one major flaw, when running programs in UNIX they actually run simultaneously. UNIX is multitasking, 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 threads as will be discussed in a later chapter.

    6.3 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.

    In my experience, the advantages of object oriented programming are:

    Modular programming made easy
    Using The approach makes it easy to divide a project into smaller pieces, these pieces are usually easier to write than the whole.
    Local data scope
    This is a very nifty thing with object oriented programs. If your program uses several files, windows, stacks, TCP connections or whatever, you simply write a program that handles one such file, window, stack or TCP connection. If correctly written, you can then just create many clones of that program.
    Using the same interface to different objects
    I can write a function that take 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 write method) and send that to the function that outputs the data.
    Most of these things can be done without object orientation, but it is object orientation that makes them easy.

    6.4 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 program then cloned and then main() is called in that clone. All this is done by the master object, which is compiled and cloned before before all other objects. What the master object actually does is:
    program scriptclass=compile_file(argv[0]); // Load script
    object script=scriptclass(); // clone script
    int ret=script->main(sizeof(argv), argv); // call main()
    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.

    If you don't want to put each program in a separate file, you can use the class keyword to write all your classes in one file. We have already seen an example how this in chapter 4 "Data types", but let's go over it in more detail. The syntax looks like this:

    class class_name {
        class_definition
    }
    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 class_name and leave the class unnamed. The class definition is simply the functions and programs you want to add to the class.

    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:

    class foo {};
    constant foo = class {};
    Because classes are defined as constants, it is possible to use a class defined inside classes you define later, like this:
    class foo
    {
        int test() { return 17; }
    };

    class bar
    {
        program test2() { return foo; }
    };

    6.5 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 inherit is all about. Let's say I want to change the hello_world program to write a version number before it writes hello world, using inherit I could do this like this:
    inherit "hello_world";
    int main(int argc, array(string) argv)
    {
        write("Hello world version 1.0\n");
        return ::main(argc,argv);
    }
    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 :: in front of the function name. The argument to inherit can be one of the following:
    A string
    This will have the same effect as casting the string to a program and then doing inherit on this program.
    A constant containing a program.
    Any constant from this program, module or inherited program that contains a program can be inherited.
    A class name
    A class defined with the class keyword is in fact added as a constant, so the same rule as above applies.

    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:


    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 inherits with the :: 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.

    6.6 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 get 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:
    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 the third inherit
        test1::read(); // Read data from the fourth inherit
        test2::main(0,({})); // Call main in the fifth inherit
        ::read(); // Read data from all inherits
    }
    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 read without any :: 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.

    If you leave the inherit name blank and just call ::read Pike will call all inherited read() functions. If there is more than one inherited read function the results will be returned in an array.

    Let's look at another example:

    #!/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<sizeof(argv);e++)
        {
            input::open(argv[e],"r");
            while(output::write(input::read(4096)) == 4096);
        }
    }
    This short piece of code works a lot like the UNIX command cat. 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.

    6.7 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.

    6.8 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 modifiers. 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:
    static
    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.
    final
    This prevents other objects from re-defining this identifier in programs that inherit this program.
    local
    This makes the identifier 'local' meaning that even if it is overloaded in an inheriting program, this program will still use this identifer.
    private
    This prevents inheriting programs from accessing this identifier. Note that inheriting program can still re-define the identifier. Also note that private does not imply static.
    public
    This is the opposite of private. This is the default for all identifiers. public can be used to override the effects of a private inherit.
    protected
    Reserved for future use.
    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, private inherit means that the identifiers from this inherit will not be available to program inheriting this program. static private inherit will also hide those identifiers from the index and arrow operators, making the inherit available only to the code in this program.

    6.9 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.

    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 == and ! 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 chapter 5 "Operators" for information on which operators can operate on objects without operator overloading.

    Operation Will call Or
    a+b a->`+(b) b->``+(a)
    a+b+c+d a->`+(b,c,d) (b->(a))+c+d
    a-b a->`-(b) b->``-(a)
    a&b a->`&(b) b->``&(a)
    a|b a->`|(b) b->``|(a)
    a^b a->`^(b) b->``^(a)
    a>>b a->`>>(b) b->``>>(a)
    a<<b a->`<<(b) b->``<<(a)
    a*b a->`*(b) b->``*(a)
    a*b*c*d a->`*(b,c,d) b->`*(a)*c*d
    a/b a->`/(b) b->``/(a)
    a%b a->`%(b) b->``%(a)
    ~a a->`~()  
    a==b a->`==(b) b->`==(a)
    a!=b !( a->`==(b) ) !( b->`==(a) )
    a<b a->`<(b) b->`>(a)
    a>b a->`>(b) b->`<(a)
    a<=b !( b->`>(a) ) !( a->`<(b) )
    a>=b !( b->`<(a) ) !( a->`>(b) )
    (int)a a->cast("int")  
    !a a->`!()  
    if(a) { ... }  !( a->`!() )  
    a[b] a->`[](b)  
    a[b]=c a->`[]=(b,c)  
    a->foo a->`->("foo")  
    a->foo=b a->`->=("foo",b)  
    sizeof(a) a->_sizeof()  
    indices(a) a->_indices()  
    values(a) a->_values()  
    a(b) a->`()(b)  

    Here is a really silly example of a program that will write 10 to stdout when executed.

    #!/usr/local/bin/pike
    class three {
        int `+(int foo) { return 3+foo; }
    };

    int main()
    {
        write(sprintf("%d\n",three()+7));
    }
    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.

    6.10 Simple exercises

  • Make a program that clones 10 hello world and then runs main() in each one of them.
  • Modify the register program to use an object for each record.
  • Modify the register program to use the following search function:
    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");
    }
  • Chapter 7, Miscellaneous functions

    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.

    7.1 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:
    int sscanf(string str, string fmt, lvalue ...)
    The string str will be matched against the format string fmt. fmt can contain strings separated by %d,%s,%c and %f. Every % corresponds to one lvalue. 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.

    Whenever a percent is found in the format string, a match is according to the following table:
    %b reads a binary integer
    %d reads a decimal integer
    %o reads an octal integer
    %x reads a hexadecimal integer
    %D reads an integer that is either octal (leading zero), hexadecimal (leading 0x) or decimal.
    %f reads a float
    %c matches one char and returns it as an integer
    %2c matches two chars and returns them as an integer (short)
    %4F matches four chars and returns them as a float (IEEE single precision)
    %8F matches eigth chars and returns them as a float (IEEE double precision)
    %s 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.
    %5s gives a string of 5 characters (5 can be any number)
    %[set] 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'.
    %{format%} Repeatedly matches 'format' as many times as possible and assigns an array of arrays with the results to the lvalue.

    If a * is put between the percent and the operator, the operator will only match its argument, not assign any variables.

    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.

    Let's look at a couple of examples:

    // 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);

    SEE ALSO : sprintf

    7.2 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:
    catch { statements }
    If an error occurs, catch will return a description of the error. The description of the error has the following format:
    ({
         "error description",
         backtrace()
    })
    If no error occurs, catch will return zero. You may emulate your own errors using the function throw, described in
    chapter 16 "Builtin functions".

    Example:

    int x,y;
    // This might generate "division by zero"
    mixed error=catch { x/=y; };

    7.3 gauge

    The syntax for gauge is the same as the syntax for catch:
    gauge { statements }
    However, gauge simply returns how many seconds 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 1.0.

    7.4 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:
    typeof( exit(1) )
    This will return the string "void" since exit is a function that returns void. It will not execute the function exit and exit the process as you might expect.

    If you want to know the type after evaluation, use sprintf("%t", expr).

    Chapter 8, 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.

    here is a list of the basic Pike modules:

    Stdio
    This module contains file I/O routines.
    Array
    This module contains functions that operate on arrays.
    Calendar
    Support for different calendar and date formats.
    Crypto *
    Cryptography routines.
    Gdbm *
    This module contains support for Gdbm databases.
    Getopt
    Routines to parse command line options
    Gmp *
    Support for large numbers.
    Gz *
    Deflate packing algorithms.
    Image
    Image manipulation routines.
    LR
    LALR(1) parser generator.
    Msql *
    Sql database support for the mini-SQL database server.
    MIME
    Support for coding and decoding MIME.
    Mysql *
    Sql database support for the mySQL database server.
    Process
    Functions to start and control other processes.
    Protocols
    Support for HTTP, NNTP, SMNT, DNS, TELNET and other protocols.
    Regexp
    Regexp matching routines.
    Simulate
    Routines to emulate old Pike routines.
    String
    Routines that operate on strings.
    Sql *
    Support for ASN1, PKCS and other standards.
    Standards
    Generic SQL database support.
    System
    Support for system specific functions.
    Thread *
    Thread support functions.
    Tools
    Complete programs available to use from within scripts.
    Yp *
    Network Information System support.

    * These modules might not be available depending on how Pike was compiled and whether support for these functions exist on your system.

    8.1 How to use modules

    A module is a bunch of functions, programs or other modules collected in one symbol. For instance, the module Stdio contains the objects stdin, stdout and stderr. To access these objects you can write Stdio.stdin, Stdio.stdout or Stdio.stderr anywhere in your program where an object of that type is acceptable. If you use Stdio a lot you can put import Stdio; 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 stdin instead of Stdio.stdin. It is also possible to import all modules in a directory with import by putting the directory name in doublequtes. So, to import all modules in the current directory, you would use import ".";.

    8.2 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.

    When you use Stdio Pike will look for that module:

    1. In imported directories.
    2. In directories added with add_module_path()
    3. In directories specified with -M on the command line.
    4. In directories in the environment variable PIKE_MODULE_PATH
    5. In the directory with builtin modules, usually /usr/local/lib/pike/modules/
    For each of these directories, Pike will do the following:
    1. If there is a file called Stdio.pmod.pike, Pike will load this Pike program, clone it and use that as a module.
    2. If there is a file called Stdio.pmod.so, Pike will load this with load_module(), clone it and use that as a module.
    3. 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 module in that directory, all identifiers from that module will overload any modules actually present in the directory.
    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.

    8.3 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.

    You can also use the . operator without an identifier preceeding it to access modules in the same directory as the program itself. For instance, .my_module.foo would mean 'the identifier foo in the module my_module in this directory.

    8.4 How to write a module

    Here is an example of a simple module:
    constant PI = 3.14159265358979323846264338327950;
    float cos2(float f) { return pow(cos(f),2.0); }
    if we save this short file as Trig.pmod we can now use this module like this:
    int main()
    {
        write(sprintf("%f\n",.Trig.cos2(.Trig.PI));
    }
    or like this:
    import .Trig;

    int main()
    {
        write(sprintf("%f\n",cos2(PI));
    }

    8.5 Simple exercises

  • Save the hello_world.pike program as hello_world.pike.pmod, then make a program that loads this module and calls its main().
  • Make a directory called Programs.pmod 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.
  • 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 hello_world.
  • Try putting Programs.pmod in another directory and then try to run the programs from the last two examples.
  • Chapter 9, File I/O

    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 Stdio.

    9.1 File management - Stdio.File

    CLASS
    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. Stdio.File is completely written in C. What follows is a description of all the functions in Stdio.File.

    METHOD
    Stdio.File.create - init file struct

    SYNTAX
    object(Stdio.File) Stdio.File();
    object(Stdio.File) Stdio.File(string filename);
    object(Stdio.File) Stdio.File(string filename, string mode);
    object(Stdio.File) Stdio.File(string filename, string mode, int mask);
    object(Stdio.File) Stdio.File(string fd);
    object(Stdio.File) Stdio.File(int fd);
    object(Stdio.File) Stdio.File(int fd, string mode);

    DESCRIPTION
    There are four 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.

    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. Default open mode is "r" and default mask is 0666.

    Alternatively, you can clone a File with "stdin", "stdout" or "stderr" as argument. This will open the specified standard stream.

    For the advanced users, you can use the file descriptors of the systems (note: emulated by pike on some systems - like NT). This is only useful for streaming purposes on unix systems. This is not recommended at all if you don't know what you're into. Default mode for this is "rw".

    NOTE
    Open mode will be filtered through the system UMASK. You might need to use chmod later.

    SEE ALSO
    clone and Stdio.File->open

    METHOD
    Stdio.File.open - open a file

    SYNTAX
    int open(string filename, string how);
    int open(string filename, string how, int mode);

    DESCRIPTION
    Open a file for read, write or append. The variable how should contain one or more of the following letters:

    'r' open file for reading
    'w' open file for writing
    'a' open file for append (use with 'w')
    't' truncate file at open (use with 'w')
    'c' create file if it doesn't exist (use with 'w')
    'x' fail if file already exist (use with 'c')

    How should _always_ contain at least one of 'r' or 'w'.

    The third argument is protection bits if the file is created. Default is 0666 (all read+write, in octal notation).

    RETURNS
    1 on success, 0 otherwise

    SEE ALSO
    Stdio.File->close

    METHOD
    Stdio.File.close - close a file

    SYNTAX
    int close(string how);
    int close();

    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.

    SEE ALSO
    Stdio.File->open

    METHOD
    Stdio.File.read - read data from a file or stream

    SYNTAX
    string read(int nbytes);
    string read(int nbytes, int notall);
    string read();

    DESCRIPTION
    Read tries to read nbytes bytes from the file, and return it as a string. If something goes wrong, zero is returned.

    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.

    If no arguments are given, read will read to the end of the file/stream.

    SEE ALSO
    Stdio.File->read_oob and Stdio.File->write

    METHOD
    Stdio.File.read_oob - read out-of-band data from a stream

    SYNTAX
    string read_oob(int nbytes);
    string read_oob(int nbytes, int notall);
    string read_oob();

    DESCRIPTION
    Tries to read nbytes bytes of out-of-band data from the stream, and returns it as a string. If something goes wrong, zero is returned.

    If a one is given as a second argument to read_oob(), only as many bytes of out-of-band data as are currently available will be returned.

    If no arguments are given, read_oob will read to the end of the stream.

    NOTE
    This function is only available if the option '--with-oob' was specified when Pike was compiled.

    It is not guaranteed that all out-of-band data sent from the other end will be received. Most streams only allow for a single byte of out-of-band data at a time.

    SEE ALSO
    Stdio.File->read and Stdio.File->write_oob

    METHOD
    Stdio.File.write - write data to a file or stream

    SYNTAX
    int write(string data);

    DESCRIPTION
    Write data to file or stream and return how many bytes that were actually written. 0 is returned in nonblocking mode if it was not possible to write anything without blocking. -1 is returned if something went wrong and no bytes were written.

    SEE ALSO
    Stdio.File->read and Stdio.File->write_oob

    METHOD
    Stdio.File.write_oob - write out-of-band data to a stream

    SYNTAX
    int write_oob(string data);

    DESCRIPTION
    Writes out-of-band data to a stream and returns how many bytes that were actually written. -1 is returned if something went wrong and no bytes were written.

    NOTE
    This function is only available if the option '--with-oob' was specified when Pike was compiled.

    It is not guaranteed that all out-of-band data will be received at the other end. Most streams only allow for a single byte of out-of-band data at a time. Some streams will send the rest of the data as ordinary data.

    SEE ALSO
    Stdio.File->read_oob and Stdio.File->write

    METHOD
    Stdio.File.seek - seek to a position in a file

    SYNTAX
    int seek(int pos);

    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 new position in the file when successful.

    SEE ALSO
    Stdio.File->tell

    METHOD
    Stdio.File.tell - tell where we are in a file

    SYNTAX
    int tell();

    DESCRIPTION
    Returns the current position in the file.

    SEE ALSO
    Stdio.File->seek

    METHOD
    Stdio.File.truncate - truncate a file

    SYNTAX
    int truncate(int length);

    DESCRIPTION
    Truncates a file to that length. Returns 1 if ok, 0 if failed.

    SEE ALSO
    Stdio.File->open

    METHOD
    Stdio.File.stat - do file_stat on an open file

    SYNTAX
    array(int) stat();

    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.

    SEE ALSO
    file_stat

    METHOD
    Stdio.File.errno - what was last error?

    SYNTAX
    int errno();

    DESCRIPTION
    Returns the error code for the last command on this file. Error code is normally cleared when a command is successful.

    METHOD
    Stdio.File.set_buffer - set internal socket buffer

    SYNTAX
    void set_buffer(int bufsize, string mode);
    void set_buffer(int bufsize);

    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.

    SEE ALSO
    Stdio.File->open_socket and Stdio.Port->accept

    METHOD
    Stdio.File.set_nonblocking - make stream nonblocking

    SYNTAX
    void set_nonblocking(function(mixed, string:void) read_callback,
    function(mixed:void) write_callback,
    function(mixed:void) close_callback);
    or
    void set_nonblocking(function(mixed, string:void) read_callback,
    function(mixed:void) write_callback,
    function(mixed:void) close_callback,
    function(mixed, string:void) read_oob_callback,
    function(mixed:void) write_oob_callback);
    or
    void set_nonblocking();

    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.

    When out-of-band data arrives on the stream, read_oob_callback will be called with some or all of this data. When the stream allows out-of-band data to be sent, write_oob_callback is called so that you can write out-of-band data to it.

    All callbacks will have the id of file as first argument when called.

    If no arguments are given, the callbacks are not changed. The stream is just set to nonblocking mode.

    NOTE
    Out-of-band data is only supported if Pike was compiled with the option '--with-oob'.

    SEE ALSO
    Stdio.File->set_blocking and Stdio.File->set_id

    METHOD
    Stdio.File.set_read_callback - set the read callback

    SYNTAX
    void set_read_callback(function read_callback)

    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.

    SEE ALSO
    Stdio.File->set_nonblocking

    METHOD
    Stdio.File.set_write_callback - set the write callback

    SYNTAX
    void set_write_callback(function write_callback)

    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.

    SEE ALSO
    Stdio.File->set_nonblocking

    METHOD
    Stdio.File.set_close_callback - set the close callback

    SYNTAX
    void set_close_callback(function close_callback)

    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.

    SEE ALSO
    Stdio.File->set_nonblocking

    METHOD
    Stdio.File.set_blocking - make stream blocking

    SYNTAX
    void set_blocking();

    DESCRIPTION
    This function sets a stream to blocking mode. i.e. all reads and writes will wait until data has been written before returning.

    SEE ALSO
    Stdio.File->set_nonblocking

    METHOD
    Stdio.File.set_id - set id of this file

    SYNTAX
    void set_id(mixed id);

    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.

    SEE ALSO
    Stdio.File->query_id

    METHOD
    Stdio.File.query_id - get id of this file

    SYNTAX
    mixed query_id();

    DESCRIPTION
    This function returns the id of this file.

    SEE ALSO
    Stdio.File->set_id

    METHOD
    Stdio.File.query_read_callback - return the read callback function

    SYNTAX
    function query_read_callback();

    DESCRIPTION
    This function returns the read_callback, which is set with set_nonblocking or set_read_callback.

    SEE ALSO
    Stdio.File->set_nonblocking and Stdio.File->set_read_callback

    METHOD
    Stdio.File.query_write_callback - return the write callback function

    SYNTAX
    function query_write_callback();

    DESCRIPTION
    This function returns the write_callback, which is set with set_nonblocking or set_write_callback.

    SEE ALSO
    Stdio.File->set_nonblocking and Stdio.File->set_write_callback

    METHOD
    Stdio.File.query_close_callback - return the close callback function

    SYNTAX
    function query_close_callback();

    DESCRIPTION
    This function returns the close_callback, which is set with set_nonblocking or set_close_callback.

    SEE ALSO
    Stdio.File->set_nonblocking and Stdio.File->set_close_callback

    METHOD
    Stdio.File.dup - duplicate a file

    SYNTAX
    object(Stdio.File) dup();

    DESCRIPTION
    This function returns a clone of Stdio.File with all variables copied from this file. Note that all variables, even id, is copied.

    SEE ALSO
    Stdio.File->assign

    METHOD
    Stdio.File.dup2 - duplicate a file over another

    SYNTAX
    int dup2(object(Stdio.File) to);

    DESCRIPTION
    This function works similarly to Stdio.File->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.

    EXAMPLE
    /* Redirect stdin to come from the file 'foo' */
    object o=Stdio.File();
    o->open("foo","r");
    o->dup2(Stdio.File("stdin"));

    SEE ALSO
    Stdio.File->assign and Stdio.File->dup

    METHOD
    Stdio.File.assign - assign a file

    SYNTAX
    void assign(object f);

    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->dup to move files around.

    SEE ALSO
    Stdio.File->dup

    METHOD
    Stdio.File.open_socket - open a socket

    SYNTAX
    int open_socket(int|void port, string|void address);

    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->connect() This function returns 1 for success, 0 otherwise.

    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.

    SEE ALSO
    Stdio.File->connect and Stdio.File->set_nonblocking

    METHOD
    Stdio.File.connect - connect a socket to something

    SYNTAX
    int connect(string IP,int port);

    DESCRIPTION
    This function connects a socket previously created with Stdio.File->open_socket to a remote socket. The argument is the IP name or number for he remote machine.

    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.

    SEE ALSO
    Stdio.File->query_address

    METHOD
    Stdio.File.query_address - get addresses

    SYNTAX
    string query_address();
    string query_address(1);

    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.

    SEE ALSO
    Stdio.File->connect

    METHOD
    Stdio.File.pipe - create a two-way pipe

    SYNTAX
    object pipe();

    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.

    SEE ALSO
    fork

    METHOD
    Stdio.File.set_close_on_exec - set / clear the close on exec flag

    SYNTAX
    void set_close_on_exec(int onoff);

    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.

    SEE ALSO
    exece

    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 File:: even if that is not strictly necessary.

    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());
    }

    9.2 Buffered file management - Stdio.FILE

    CLASS
    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:

    METHOD
    Stdio.FILE.gets - get one line

    SYNTAX
    string gets();

    DESCRIPTION
    This function returns one line from the FILE, it returns zero if no more lines are available.

    METHOD
    Stdio.FILE.printf - formatted print

    SYNTAX
    string printf(string format, mixed ... data);

    DESCRIPTION
    This function does approximately the same as: write(sprintf(format,@data))

    SEE ALSO
    sprintf

    METHOD
    Stdio.FILE.ungets - put a string back in the buffer

    SYNTAX
    string ungets(string s);

    DESCRIPTION
    This function puts a string back in the input buffer. The string can then be read with read, gets or getchar.

    METHOD
    Stdio.FILE.getchar - get one character from the input stream

    SYNTAX
    int getchar();

    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.

    9.3 Standard streams - Stdio.stdin, stdout and stderr

    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 Stdio.stdin, Stdio.stdout and Stdio.stderr respectively. Standard input is a clone of Stdio.FILE, which means you can use the line oriented functions. Stdio.stdout and Stdio.stderr are simply clones of Stdio.File.

    Example:

    int main()
    {
        int line;
        while(string s=Stdio.stdin.gets())
            write(sprintf("%5d: %s\n",line++,s));
    }
    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 Stdio.stdout.write instead of just write because they are the same function.

    9.4 Listening to sockets - Stdio.Port

    CLASS
    Stdio.Port 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 Stdio.Port. Stdio.Port 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 Stdio.Port:

    METHOD
    Stdio.Port.bind - open socket and bind it to a port

    SYNTAX
    int bind(int port);
    int bind(int port,function accept_callback);
    int bind(int port,function accept_callback, string IP);

    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.

    If the optional argument IP is given, bind will try to bind to this IP name (or number).

    SEE ALSO
    Stdio.Port->accept

    METHOD
    Stdio.Port.listen_fd - listen to an already open port

    SYNTAX
    int listen_fd(int fd);
    int listen_fd(int fd,function accept_callback);

    DESCRIPTION
    This function does the same as Stdio.Port->bind, except that instead of creating a new socket and bind it to a port, it expects that the file descriptor fd is an already open port.

    NOTE
    This function is only for the advanced user, and is generally used when sockets are passed to Pike at exec time.

    SEE ALSO
    Stdio.Port->bind and Stdio.Port->accept

    METHOD
    Stdio.Port.create - create and/or setup a port

    SYNTAX
    object(Stdio.Port) Stdio.Port("stdin")
    object(Stdio.Port) Stdio.Port("stdin",function accept_callback)
    object(Stdio.Port) Stdio.Port("stdin",function accept_callback)
    object(Stdio.Port) Stdio.Port(int port)
    object(Stdio.Port) Stdio.Port(int port,function accept_callback)
    object(Stdio.Port) Stdio.Port(int port,function accept_callback, string ip)

    DESCRIPTION
    When create is called with "stdin" 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.

    SEE ALSO
    clone and Stdio.Port->bind

    METHOD
    Stdio.Port.set_id - set the id of a port

    SYNTAX
    void set_id(mixed id);

    DESCRIPTION
    This function sets the id used for accept_callback by this port. The default id is this_object().

    SEE ALSO
    Stdio.Port->query_id

    METHOD
    Stdio.Port.query_id - Return the id for this port.

    SYNTAX
    mixed query_id();

    DESCRIPTION
    This function returns the id for this port. The id is normally the first argument to accept_callback.

    SEE ALSO
    Stdio.Port->set_id

    METHOD
    Stdio.Port.errno - return the last error

    SYNTAX
    int errno();

    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.

    SEE ALSO
    Stdio.Port->errno

    METHOD
    Stdio.Port.accept - accept a connection

    SYNTAX
    object accept();

    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.

    SEE ALSO
    Stdio.File

    9.5 UDP socket and message management - Stdio.UDP

    CLASS
    Stdio.UDP

    SYNTAX
    Stdio.UDP();

    DESCRIPTION
    Stdio.UDP is the way of transceiving UDP from Pike.

    SEE ALSO
    Stdio.File

    METHOD
    Stdio.UDP.bind

    SYNTAX
    bind(int port); bind(int port,string address);

    DESCRIPTION
    binds a port for recieving or transmitting UDP

    RETURNS
    the called object

    METHOD
    Stdio.UDP.enable_broadcast

    SYNTAX
    enable_broadcast()

    DESCRIPTION
    enable transmission of broadcasts. This is normally only avalable to root users.

    RETURNS
    1 upon success, 0 otherwise

    METHOD
    Stdio.UDP.read

    SYNTAX
    read()
    read(int flags)

    DESCRIPTION
    read from the UDP socket. Flags is a bitfield, 1 for out of band data and 2 for peek.

    RETURNS
    mapping(string:int|string) in the form
    ([
       "data" : string recieved data
       "ip" : string   recieved from this ip
       "port" : int    ...and this port
    ])
    

    SEE ALSO
    Stdio.UDP.set_nonblocking and Stdio.UDP.set_read_callback

    METHOD
    Stdio.UDP.send

    SYNTAX
    send(string to_addr,int to_port,string data)
    send(string to_addr,int to_port,string data,int flags)

    DESCRIPTION

    RETURNS
    number of bytes sent

    METHOD
    Stdio.UDP.set_nonblocking

    SYNTAX
    set_nonblocking();
    set_blocking();
    set_nonblocking(function, mixed ...);

    DESCRIPTION
    sets this object to be nonblocking or blocking. If set_nonblocking is given with argument, these are passed to set_read_callback().

    RETURNS
    the called object

    METHOD
    Stdio.UDP.set_read_callback

    SYNTAX
    set_read_callback(function(mapping(string:int|string), mixed...), mixed ... extra);

    DESCRIPTION
    The called function is recieving mapping similar to the return value of read:
    ([
       "data" : string recieved data
       "ip" : string   recieved from this ip
       "port" : int    ...and this port
    ])
    

    RETURNS
    the called object

    METHOD
    Stdio.UDP.query_address

    SYNTAX
    query_address()

    DESCRIPTION

    RETURNS
    the current address in format "<ip> <port>".

    SEE ALSO
    Stdio.File.query_address

    9.6 Terminal management - Stdio.Terminfo

    FUNCTION
    Stdio.Terminfo.getFallbackTerm - get fallback terminal

    SYNTAX
    object(Stdio.Terminfo.Terminfo)|object(Stdio.Terminfo.Termcap) getFallbackTerm(string term);

    DESCRIPTION
    Returns an object describing the fallback terminal for the terminal term. This is usually equvivalent to Stdio.Terminfo.getTerm("dumb").

    SEE ALSO
    Stdio.Terminfo.getTerm

    FUNCTION
    Stdio.Terminfo.getTerm - get terminal description

    SYNTAX
    object(Stdio.Terminfo.Terminfo)|object(Stdio.Terminfo.Termcap) getTerm();
    or
    object(Stdio.Terminfo.Terminfo)|object(Stdio.Terminfo.Termcap) getTerm(string term);

    DESCRIPTION
    Returns an object describing the terminal term. If term is not specified, it will default to getenv("TERM") or if that fails to "dumb".

    Lookup of terminal information will first be done in the systems terminfo database, and if that fails in the termcap database. If neither database exists, a hardcoded entry for "dumb" will be used.

    SEE ALSO
    Stdio.Terminfo.getTerminfo, Stdio.Terminfo.getTermcap and Stdio.getFallbackTerm

    FUNCTION
    Stdio.Terminfo.getTermcap - get termcap description

    SYNTAX
    object(Stdio.Terminfo.Termcap) getTermcap(string term);

    DESCRIPTION
    Return the terminal description of term from the systems termcap database. Returns 0 if not found.

    SEE ALSO
    Stdio.Terminfo.getTerm and Stdio.Terminfo.getTerminfo

    FUNCTION
    Stdio.Terminfo.getTerminfo - get terminfo description

    SYNTAX
    object(Stdio.Terminfo.Terminfo) getTerminfo(string term);

    DESCRIPTION
    Return the terminal description of term from the systems terminfo database. Returns 0 if not found.

    SEE ALSO
    Stdio.Terminfo.getTerm and Stdio.Terminfo.getTermcap

    9.6.1 Stdio.Terminfo.Termcap

    CLASS
    Stdio.Terminfo.Termcap Termcap terminal decription object.

    METHOD
    Stdio.Terminfo.Termcap.create - initialize termcap object

    SYNTAX
    object(Stdio.Terminfo.Termcap) Termcap(string cap);
    or
    object(Stdio.Terminfo.Termcap) Termcap(string cap, object tcdb);
    or
    object(Stdio.Terminfo.Termcap) Termcap(string cap, object tcdb, int maxrecurse);

    METHOD
    Stdio.Terminfo.Termcap.tputs - put termcap string

    9.6.2 Stdio.Terminfo.Terminfo

    CLASS
    Stdio.Terminfo.Terminfo Terminfo terminal description object.

    9.7 Simple input-by-prompt - Stdio.Readline

    CLASS
    Stdio.Readline

    METHOD
    Stdio.Readline.create - init readline

    SYNTAX
    object(Stdio.Readline) Stdio.Readline();
    or
    object(Stdio.Readline) Stdio.Readline(object infd);
    or
    object(Stdio.Readline) Stdio.Readline(object infd,
    object|string interm);

    or
    object(Stdio.Readline) Stdio.Readline(object infd,
    object|string interm,
    object outfd);

    or
    object(Stdio.Readline) Stdio.Readline(object infd,
    object|string interm,
    object outfd,
    object|string outterm);

    DESCRIPTION
    Creates a Readline object, that takes input from infd, and has output on outfd.

    infd defaults to Stdio.stdout.

    interm defaults to Stdio.Terminfo.getTerm().

    outfd defaults to infd, unless infd is 0, in which case outfd defaults to Stdio.stdout.

    outterm defaults to interm.

    9.8 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.

    FUNCTION
    Stdio.append_path - append paths in a secure way

    SYNTAX
    string append_path(string absolute, string ... relative);

    DESCRIPTION
    Append relative paths to an absolute path and remove any "//", "../" or "/." to produce a straightforward absolute path as a result. "../" is ignorded in the relative paths if it makes the created path begin with something else than the absolute path (or so far created path).

    EXAMPLE
    > Stdio.append_path("/foo/bar/","..");
    Result: /foo/bar/
    > Stdio.append_path("/foo/bar/","../apa.c");
    Result: /foo/bar/apa.c
    > Stdio.append_path("/foo/bar","./sune.c");
    Result: /foo/bar/sune.c
    > Stdio.append_path("/foo/bar","bertil/../../sune.c");
    Result: /foo/bar/sune.c
    > Stdio.append_path("/foo/bar","klas","bertil/../../sune.c");
    Result: /foo/bar/klas/sune.c

    SEE ALSO
    combine_path

    FUNCTION
    Stdio.file_size - return the size of a file in bytes

    SYNTAX
    int file_size(string file);

    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.

    SEE ALSO
    Stdio.write_file and Stdio.read_bytes

    FUNCTION
    Stdio.exist - check if a path exists

    SYNTAX
    int exist(string path);

    DESCRIPTION
    Returns true if the given path exists (is a directory or file), otherwise false.

    SEE ALSO
    Stdio.is_dir, Stdio.is_file and Stdio.is_link

    FUNCTION
    Stdio.is_dir - check if a path is a directory

    SYNTAX
    int is_dir(string path);

    DESCRIPTION
    Returns true if the given path is a directory, otherwise false.

    SEE ALSO
    Stdio.exist, Stdio.is_file and Stdio.is_link

    FUNCTION
    Stdio.is_file - check if a path is a file

    SYNTAX
    int is_file(string path);

    DESCRIPTION
    Returns true if the given path is a file, otherwise false.

    SEE ALSO
    Stdio.exist, Stdio.is_dir and Stdio.is_link

    FUNCTION
    Stdio.is_link - check if a path is a symbolic link

    SYNTAX
    int is_link(string path);

    DESCRIPTION
    Returns true if the given path is a symbolic link, otherwise false.

    SEE ALSO
    Stdio.exist, Stdio.is_dir and Stdio.is_file

    FUNCTION
    Stdio.mkdirhier - make a directory hierarchy

    SYNTAX
    int mkdirhier(string pathname, void|int mode);

    DESCRIPTION
    Creates zero or more directories to ensure that the given pathname is a directory. Returns zero if it fails and nonzero if it is successful. If a mode is given, it's used for the new directories after being &'ed with the current umask (on OS'es that supports this).

    SEE ALSO
    mkdir

    FUNCTION
    Stdio.perror - print error

    SYNTAX
    void perror(string s);

    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.

    SEE ALSO
    Stdio.werror

    FUNCTION
    Stdio.read_bytes - read a number of bytes into a string from a file

    SYNTAX
    string read_bytes(string file,int start,int len);
    string read_bytes(string file,int start);
    string read_bytes(string file);

    DESCRIPTION
    Read len number of bytes from file file staring at byte start and return it as a string. If len is omitted, the rest of the file will be returned. If start is also omitted, the entire file will be returned.

    SEE ALSO
    Stdio.write_file

    FUNCTION
    Stdio.read_file - read a number of lines into a string from file

    SYNTAX
    string read_file(string file, int start, int len);
    string read_file(string file);

    DESCRIPTION
    Read len lines from the file file after skipping start lines and return those lines as a string. If start and len are omitted the whole file is read.

    SEE ALSO
    Stdio.read_bytes and Stdio.write_file

    FUNCTION
    Stdio.readline - read a line from stdin

    SYNTAX
    string readline(string prompt);

    DESCRIPTION
    This function is gone. Use Stdio.Readline()->read instead.

    SEE ALSO
    Stdio.File

    FUNCTION
    Stdio.recursive_rm - remove a file or a directory tree recursively

    SYNTAX
    int recursive_rm(string path);

    DESCRIPTION
    Remove a file or directory a directory tree, return 0 if it fails. Nonzero otherwise.

    SEE ALSO
    rm

    FUNCTION
    Stdio.sendfile - send contents from one file to another

    SYNTAX
    object sendfile(array(string) headers,
    object from, int offset, int len,
    array(string) trailers,
    object to);

    or
    object sendfile(array(string) headers,
    object from, int offset, int len,
    array(string) trailers,
    object to,
    function(int, mixed ...:void) callback,
    mixed ... args);

    DESCRIPTION
    Sends headers followed by len bytes starting at offset from the file from followed by trailers to the file to. When completed callback is called with the total number of bytes sent as the first argument, followed by args.

    Any of headers, from and trailers may be left out by setting them to 0.

    Setting offset to -1 means send from the current position in from.

    Setting len to -1 means send until from's end of file is reached.

    NOTE
    The sending is performed asynchronously, and may complete before the function returns.

    For callback to be called, the backend must be active (ie main() must have returned -1).

    In some cases, the backend must also be active for any sending to be performed at all.

    SEE ALSO
    Stdio.File->set_nonblocking

    FUNCTION
    Stdio.werror - write to stderr

    SYNTAX
    void werror(string s);

    DESCRIPTION
    Writes a message to stderr. Stderr is normally the console, even if the process output has been redirected to a file or pipe.

    FUNCTION
    Stdio.write_file - append a string to a file

    SYNTAX
    int write_file(string file, string str)

    DESCRIPTION
    Append the string str onto the file file. Returns number of bytes written.

    SEE ALSO
    Stdio.read_bytes

    9.9 A simple example

    Here is a simple example of how to use the Stdio-functions.

    string grep(string indata, string needle)
    {
        object out=Stdio.File(),in=Stdio.File();
        object process=
         Process.create_process(({"/bin/grep",needle}),
            (["stdin":out->pipe(),
            "stdout":in->pipe()]) );
        out->write(indata);
        out->close();
        process->wait();
        return in->read();
    }
    This function filters the indata through the UNIX-command /bin/grep and return the result.

    9.10 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)

    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.

    #!/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;
    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.

    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.

    /* 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
    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/

    Next we declare a class called output_class. Later we will clone one instance of this class for each incoming HTTP connection.

    class output_class
    {
        inherit Stdio.File : socket;
        inherit Stdio.File : file;
    Our new class inherits Stdio.File twice. To be able to separate them they are then named 'socket' and 'file'.

        int offset=0;
    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).

    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.

        void write_callback()
        {
            int written;
            string data;
    The following line means: call seek in the inherited program 'file'.
            file::seek(offset);
    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.

            data=file::read(BLOCK);
    Read BLOCK (16060) bytes from the file. If there are less that that left to read only that many bytes will be returned.

            if(strlen(data))
            {
    If we managed to read something...

                written=socket::write(data);
    ... we try to write it to the socket.

                if(written >= 0)
                {
                    offset+=written;
                    return;
                }
    Update offset if we managed to write to the socket without errors.

                werror("Error: "+socket::errno()+".\n");
            }
    If something went wrong during writing, or there was nothing left to read we destruct this instance of this class.

            destruct(this_object());
        }
    That was the end of write_callback()

    Next we need a variable to buffer the input received in. We initialize it to an empty string.

        string input="";
    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.

        void read_callback(mixed id,string data)
        {
            string cmd;
                    
            input+=data;
    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.

            if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input)>2)
            {
    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.

                if(cmd!="GET")
                {
                    werror("Only method GET is supported.\n");
                    destruct(this_object());
                    return;
                }
    If the first word isn't GET print an error message and terminate this instance of the program. (and thus the connection)
                sscanf(input,"%*[/]%s",input);
    Remove the leading slash.

                input=BASE+combine_path("/",input);
    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.
                if(!file::open(input,"r"))
                {
    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.

    if(!file::open(NOFILE,"r"))
    {
    If this fails too. Write an error message and destruct this object.

        werror("Couldn't find default file.\n");
        destruct(this_object());
        return;
    }
                }
    Ok, now we set up the socket so we can write the data back.
                socket::set_buffer(65536,"w");
    Set the buffer size to 64 kilobytes.

                socket::set_nonblocking(0,write_callback,0);
    Make it so that write_callback is called when it is time to write more data to the socket.

                write_callback();
    Jump-start the writing.
            }
        }
    That was the end of read_callback().

    This function is called if the connection is closed while we are reading from the socket.

        void selfdestruct() { destruct(this_object()); }

    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.

        void create(object f)
        {
            socket::assign(f);
    We insert the data from the file f into 'socket'.

            socket::set_nonblocking(read_callback,0,selfdestruct);
    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.

        }
    End of create()

    };
    End of the new class.

    Next we define the function called when someone connects.

    void accept_callback()
    {
        object tmp_output;
    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.

        tmp_output=accept();
    The function accept clones a Stdio.File and makes this equal to the newly connected socket.

        if(!tmp_output) return;
    If it failed we just return.

        output_class(tmp_output);
    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.

        destruct(tmp_output);
    Destruct the object returned by accept(), output_class has already copied the contents of this object.

    }

    Then there is main, the function that gets it all started.
    int main(int argc, array(string) argv)
    {
        werror("Starting minimal httpd\n");
    Write an encouraging message to stderr.
        if(!bind(PORT, accept_callback))
        {
            werror("Failed to open socket (already bound?)\n");
            return 17;
        }

    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.
        return - 17; /* Keep going */
    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)
    }
    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.

    Chapter 10, 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 #if constant(thread_create). Pike needs POSIX or UNIX thread support when compiled to support threads.

    10.1 Starting a thread

    Starting a thread is very easy. You simply call thread_create with a function pointer and any arguments it needs and that function will be executed in a separate thread. The function thread_create will return immediately and both the calling function and the called function will execute at the same time. Example:
    void foo(int x)
    {
        for(int e=0;e<5;e++)
        {
            sleep(1);
            write("Hello from thread "+x+".\n");
        }
    }

    int main()
    {
        thread_create(foo, 2);
        thread_create(foo, 3);
        foo(1);
    }
    This may all seem very simple, but there are a few complications to watch out for:
    Accessing unlocked data
    Look at this code:
    void mapadd(mapping m, int i, int j)
    {
        if(map[i])
            map[i]+=({j});
        else
            map[i]=({j});
    }
    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 map[i] is zero and both threads will then do map[i]=({j}); and one value of j 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 condition variables, 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:
    #!/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->gets())
            {
                if(search(line, lookfor) >=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<4;e++) // Start workers
            thread_create(worker,argv[e]);
        for(int e=2;e<argc;e++) // Feed workers
            Fifo::write(argv[1]);
        for(int e=0;e<4;e++) // Tell workers to die
            Fifo::write(0);
        for(int e=0;e<4;e++) // Wait for workers to die
            ended::read();
        exit(0);
    }
    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.
    Deadlocks
    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.

    10.2 Threads reference section

    This section describes all thread-related functions and classes.

    FUNCTION
    Thread.thread_create - create a thread

    SYNTAX
    object thread_create(function f, mixed ... args);

    DESCRIPTION
    This function creates a new thread which will run simultaneously to the rest of the program. The new thread will call the function f with the arguments args. 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.

    NOTE
    This function is only available on systems with POSIX or UNIX threads support.

    SEE ALSO
    Thread.Mutex, Thread.Condition and Thread.this_thread

    FUNCTION
    Thread.this_thread - return thread id

    SYNTAX
    object this_thread();

    DESCRIPTION
    This function returns the object that identifies this thread.

    SEE ALSO
    Thread.thread_create

    FUNCTION
    Thread.all_threads - return all thread ids

    SYNTAX
    array(object) all_threads();

    DESCRIPTION
    This function returns an array with the thread ids of all threads.

    SEE ALSO
    Thread.thread_create

    CLASS
    Thread.Mutex - mutex locks

    DESCRIPTION
    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.

    NOTE
    Mutex locks are only available on systems with POSIX or UNIX threads support.

    In POSIX threads, mutex locks can only be unlocked by the same thread that locked them. In Pike any thread can unlock a locked mutex.

    EXAMPLE
    /* 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.
     */
    
    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;
    }

    METHOD
    Thread.Mutex.lock - lock the mutex

    SYNTAX
    object lock();

    DESCRIPTION
    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.

    METHOD
    Thread.Mutex.trylock - try to lock the mutex

    SYNTAX
    object trylock();

    DESCRIPTION
    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.

    CLASS
    Thread.Condition - condition variables

    DESCRIPTION
    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.

    NOTE
    Condition variables are only available on systems with POSIX or UNIX threads support.

    EXAMPLE
    // 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;

    array 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();
    }

    SEE ALSO
    Thread.Mutex

    METHOD
    Thread.Condition.wait - wait for condition

    SYNTAX
    void wait();
    void wait(object mutex_key);

    DESCRIPTION
    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.

    SEE ALSO
    Thread.Mutex->lock

    METHOD
    Thread.Condition.signal - signal a condition variable

    SYNTAX
    void signal();

    DESCRIPTION
    Signal wakes up one of the threads currently waiting for the condition.

    BUGS
    It sometimes wakes up more than one thread.

    METHOD
    Thread.Condition.broadcast - signal all waiting threads

    SYNTAX
    void broadcast();

    DESCRIPTION
    This function wakes up all threads currently waiting for this condition.

    CLASS
    Thread.Fifo - first in, first out object

    DESCRIPTION
    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.

    NOTE
    Fifos are only available on systems with POSIX threads support.

    SEE ALSO
    Thread.Queue

    METHOD
    Thread.Fifo.create - initialize the fifo

    SYNTAX
    void create(int size);
    object(Thread.Fifo) Thread.Fifo();
    object(Thread.Fifo) Thread.Fifo(int size);

    DESCRIPTION
    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.

    METHOD
    Thread.Fifo.write - queue a value

    SYNTAX
    void write(mixed value);

    DESCRIPTION
    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.

    METHOD
    Thread.Fifo.read - read a value from the fifo

    SYNTAX
    mixed read();

    DESCRIPTION
    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.

    METHOD
    Thread.Fifo.size - return number of values in fifo

    SYNTAX
    int size();

    DESCRIPTION
    This function returns how many values are currently in the fifo.

    CLASS
    Thread.Queue - a queue of values

    DESCRIPTION
    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.

    NOTE
    Queues are only available on systems with POSIX or UNIX threads support.

    SEE ALSO
    Thread.Fifo

    METHOD
    Thread.Queue.write - queue a value

    SYNTAX
    void write(mixed value);

    DESCRIPTION
    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.

    METHOD
    Thread.Queue.read - read a value from the queue

    SYNTAX
    mixed read();

    DESCRIPTION
    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.

    METHOD
    Thread.Queue.size - return number of values in queue

    SYNTAX
    int queue->size();

    DESCRIPTION
    This function returns how many values are currently in the queue.

    CLASS
    Thread.thread_local - Thread local variable class

    DESCRIPTION
    This class allows you to have variables which are separate for each thread that uses it. It has two methods: get and set. A value stored in an instance of thread_local can only be retreived by that same thread.

    METHOD
    Thread.thread_local.thread_local.set - Set the thread_local value

    SYNTAX
    mixed set(mixed value);

    DESCRIPTION
    This sets the value returned by the get method. Note that this value can only be retreived by the same thread. Calling this method does not affect the value returned by get when called by another thread.

    METHOD
    Thread.thread_local.thread_local.get - Get the thread_local value

    SYNTAX
    mixed set(mixed value);

    DESCRIPTION
    This returns the value prevoiusly stored in the thread_local by the set method by this thread.

    10.3 Threads example

    Let's look at an example of how to work with threads. This program is the same minimal WWW server as in
    chapter 9 "File I/O" 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:
    #!/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=BASE+combine_path("/",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<THREADS;e++) thread_create(worker,accept);
        worker(accept);
    }

    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.

    Chapter 11, 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 String and Array, but more are expected to show up in the future.

    11.1 String

    The module String 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.

    FUNCTION
    String.fuzzymatch - make a fuzzy compare of two strings

    SYNTAX
    int fuzzymatch(string word1, string word2);

    DESCRIPTION
    This function compares two strings using a fuzzy matching routine. The higher the resulting value, the better the strings match.

    EXAMPLE
    > fuzzymatch("cat", "hat");
    Result: 66
    > fuzzymatch("cat", "dog");
    Result: 0
    > fuzzymatch("United States", "United Nations");
    Result: 70

    SEE ALSO
    Array.diff, Array.diff_compare_table and Array.diff_longest_sequence

    FUNCTION
    String.implode_nicely - make an English comma separated list

    SYNTAX
    string implode_nicely(array(string|float|int) words, string|void separator);

    DESCRIPTION
    This function implodes a list of words to a readable string. If the separator is omitted, the default is "and". If the words are numbers they are converet to strings first.

    EXAMPLE
    > implode_nicely(({"green"}));
    Result: green
    > implode_nicely(({"green","blue"}));
    Result: green and blue
    > implode_nicely(({"green","blue","white"}));
    Result: green, blue and white
    > implode_nicely(({"green","blue","white"}),"or");
    Result: green, blue or white
    > implode_nicely(({1,2,3}),"or even");
    Result: 1, 2 or even 3

    SEE ALSO
    `*

    FUNCTION
    String.capitalize - capitalize a string

    SYNTAX
    string capitalize(string str);

    DESCRIPTION
    Convert the first character in str to upper case, and return the new string.

    SEE ALSO
    lower_case and upper_case

    FUNCTION
    String.common_prefix - find the longest common beginning

    SYNTAX
    string common_prefix(array(string) strs);

    DESCRIPTION
    Find the longest common beginning from an array of strings.

    EXAMPLE
    > String.common_prefix(({ "muzzle", "muzzy" }));
    Result: "muzz"
    > String.common_prefix(({ "labyrinth", "diatom" }));
    Result: ""
    > String.common_prefix(({}));
    Result: ""

    FUNCTION
    String.sillycaps - Sillycaps A String

    SYNTAX
    string sillycaps(string str);

    DESCRIPTION
    Convert the first character in each word (separated by spaces) in str to upper case, and return the new string.

    FUNCTION
    String.strmult - multiply strings

    SYNTAX
    string strmult(string s, int num);

    DESCRIPTION
    This function multiplies 's' by 'num'. The return value is the same as appending 's' to an empty string 'num' times.

    FUNCTION
    String.count - count needles in a haystack string

    SYNTAX
    string count(string haystack, string needle);

    DESCRIPTION
    This function counts the number of times the needle can be found in haystack. Intersections between needles are not counted, ie count("....","..") is 2.

    FUNCTION
    String.width - return width of string

    SYNTAX
    int width(string s);

    DESCRIPTION
    Returns the width in bits (8, 16 or 32) of the widest character in s.

    FUNCTION
    String.trim_whites - trim spaces and tabs from a string

    SYNTAX
    string trim_whites(string s);

    DESCRIPTION
    Trim leading and trailing spaces and tabs from the string s.

    FUNCTION
    String.trim_all_whites - trim all white spaces from a string

    SYNTAX
    string trim_all_whites(string s);

    DESCRIPTION
    Trim leading and trailing white space characters (" \t\r\n") from the string s.

    11.2 Array

    As with String these functions are mostly Pike functions written to supplement those written in C.

    FUNCTION
    Array.diff - gives the difference of two arrays

    SYNTAX
    array(array(array)) diff(array a, array b);

    DESCRIPTION
    Calculates which parts of the arrays that are common to both, and which parts that are not. Returns an array with two elements, the first is an array of parts in array a, and the second is an array of parts in array b.

    EXAMPLE
    > Array.diff("Hello world!"/"","Help!"/"");
    Result: ({ /* 2 elements */
        ({ /* 3 elements */
            ({ /* 3 elements */
                "H",
                "e",
                "l"
            }),
            ({ /* 8 elements */
                "l",
                "o",
                " ",
                "w",
                "o",
                "r",
                "l",
                "d"
            }),
            ({ /* 1 elements */
                "!"
            })
        }),
        ({ /* 3 elements */
            ({ /* 3 elements */
                "H",
                "e",
                "l"
            }),
            ({ /* 1 elements */
                "p"
            }),
            ({ /* 1 elements */
                "!"
            })
        })
    })
    

    SEE ALSO
    Array.diff_compare_table, Array.diff_longest_sequence and String.fuzzymatch

    FUNCTION
    Array.diff_compare_table - gives the comparison-table used by Array.diff()

    SYNTAX
    array(array(int)) diff_compare_table(array a, array b);

    DESCRIPTION
    Returns an array which maps from index in a to corresponding indices in b.

    EXAMPLE
    > Array.diff_compare_table("Hello world!"/"","Help!"/"");
    Result: ({ /* 12 elements */
        ({ /* 1 elements */
            0
        }),
        ({ /* 1 elements */
            1
        }),
        ({ /* 1 elements */
            2
        }),
        ({ /* 1 elements */
            2
        }),
        ({ }),
        ({ }),
        ({ }),
        ({ }),
        ({ }),
        ({ /* 1 elements */
            2
        }),
        ({ }),
        ({ /* 1 elements */
            4
        })
    })
    

    SEE ALSO
    Array.diff, Array.diff_longest_sequence and String.fuzzymatch

    FUNCTION
    Array.diff_longest_sequence - gives the longest common sequence of two arrays

    SYNTAX
    array(int) diff_longest_sequence(array a, array b);

    DESCRIPTION
    Gives the longest sequence of indices in b that have corresponding values in the same order in a.

    EXAMPLE
    > Array.diff_longest_sequence("Hello world!"/"","Help!"/"");
    Result: ({ /* 4 elements */
        0,
        1,
        2,
        4
    })

    SEE ALSO
    Array.diff, Array.diff_compare_table and String.fuzzymatch

    FUNCTION
    Array.everynth - return every n:th element of an array

    SYNTAX
    array(mixed) Array.everynth(array(mixed) arr1, void|int nth, void|int start);

    DESCRIPTION
    This function returns an array with every n:th element of an other array. If nth is zero, every second element is returned.

    EXAMPLE
    > Array.everynth(({"1","2","3","4","5","6"}),2,1);
    Result: ({ /* 3 elements */
        "2",
        "4",
        "6"
    })
    

    SEE ALSO
    Array.splice and `/

    FUNCTION
    Array.filter - filter an array or mapping through a function

    SYNTAX
    array filter(array arr,function fun,mixed ... args);
    array filter(array(object) arr,string fun,mixed ... args);
    array filter(array(function) arr,-1,mixed ... args);

    DESCRIPTION
    First syntax:
    Filter array returns an array holding the items of arr for which fun returns true.

    Second syntax:
    Filter array calls fun in all the objects in the array arr, and return all objects that returned true.

    Third syntax:
    Filter array calls all function pointers in the array arr, and return all that returned true.

    SEE ALSO
    Array.sum_arrays and Array.map

    FUNCTION
    Array.longest_ordered_sequence - find the longest ordered sequence of elements

    SYNTAX
    array(int) longest_ordered_sequence(array a);

    DESCRIPTION
    This function returns an array of the indices in the longest ordered sequence of elements in the array.

    EXAMPLE
    > array a = ({ 1,2,3,4,2,3,5,6 });
    Result: ({ /* 8 elements */
        1,
        2,
        3,
        4,
        2,
        3,
        5,
        6
    })
    > array seq = Array.longest_ordered_sequence(a);
    Result: ({ /* 6 elements */
        0,
        1,
        4,
        5,
        6,
        7
    })
    > rows(a,seq);
    Result: ({ /* 6 elements */
        1,
        2,
        2,
        3,
        5,
        6
    })
    

    SEE ALSO
    Array.diff

    FUNCTION
    Array.map - map an array or mapping over a function

    SYNTAX
    array map(array arr,function fun,mixed ... args);
    array map(array(object) arr,string fun,mixed ... args);
    array map(array(function) arr,-1,mixed ... arg);

    DESCRIPTION
    First syntax:
    Map array returns an array holding the items of arr mapped through the function fun. i.e. arr[x]=fun(arr[x], @args) for all x.

    Second syntax:
    Map array calls function fun in all objects in the array arr. i.e. arr[x]=arr[x]->fun(@ args);

    Third syntax:
    Map array calls the functions in the array arr: arr[x]=arr[x]->fun(@ args);

    SEE ALSO
    Array.sum_arrays and Array.filter

    FUNCTION
    Array.permute - Give a specified permutation of an array

    SYNTAX
    array permute(array in,int number);

    DESCRIPTION
    permute gives you a selected permutation of an array. The numbers of permutations equal sizeof(in)! (the factorial of the size of the given array).

    EXAMPLE
    Array.permute( ({ 1,2,3 }), 0) -> ({1,2,3})
    Array.permute( ({ 1,2,3 }), 3) -> ({1,3,2})

    SEE ALSO
    Array.shuffle

    FUNCTION
    Array.reduce - Iterativily apply a function on an array

    SYNTAX
    mixed reduce(function f, array arr, void|mixed zero);

    DESCRIPTION
    reduce sends the first two elements in arr to f, then the result and the next element in arr to f and so on. Then it returns the result. The function will return zero if arr is the empty array. If arr has size 1 it will return the element in arr.

    EXAMPLE
    Array.reduce(aggregate, indices(allocate(4)))  ->
       ({ ({ ({ 0, 1 }), 2 }), 3 })
    Array.reduce(`+, ({}), "FOO?")  ->  
       "FOO?"
    Array.reduce(lambda(int a, int b) {
                 while(b) { int t=b; b=a%b; a=t; }
                 return a;
                 }, ({7191,21573,64719,33694}))
      -> 17
    

    SEE ALSO
    Array.rreduce

    FUNCTION
    Array.rreduce - Iterativily apply a function on an array backwards

    SYNTAX
    mixed rreduce(function f, array arr, void|mixed zero);

    DESCRIPTION
    reduce sends the last two elements in arr to f, then the third last element in arr and the result to f and so on. Then it returns the result. The function will return zero if arr is the empty array. If arr has size 1 it will return the element in arr.

    EXAMPLE
    Array.rreduce(aggregate, indices(allocate(4)))  ->
       ({ 0, ({ 1, ({ 2, 3 }) }) })
    

    SEE ALSO
    Array.reduce

    FUNCTION
    Array.search_array - search for something in an array

    SYNTAX
    int search_array(array arr,function fun,mixed arg, ...);
    int search_array(array(object) arr,string fun,mixed arg, ...);
    int search_array(array(function) arr,-1,mixed arg, ...);

    DESCRIPTION
    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.

    SEE ALSO
    Array.sum_arrays and Array.filter

    FUNCTION
    Array.shuffle - Random-shuffle an array

    SYNTAX
    array shuffle(array in);

    DESCRIPTION
    shuffle gives back the same elements, but by random order.

    EXAMPLE
    Array.shuffle( ({"this","is","an","ordered","array"}) ) -> ({"is","ordered","array","this","an"})

    SEE ALSO
    Array.permute

    FUNCTION
    Array.sort_array - sort an array

    SYNTAX
    array sort_array(array arr,function fun,mixed ... args);

    DESCRIPTION
    This function sorts an array after a compare-function fun which takes two arguments and should return 1 if the first argument is larger then the second. The rest of the arguments args will be sent as 3rd, 4th etc. argument to fun. If fun is omitted, `> is used instead.

    SEE ALSO
    Array.map and sort

    FUNCTION
    Array.splice - splice two or more arrays

    SYNTAX
    array(mixed) Array.splice(array(mixed) arr1, array(mixed) arr2, array(mixed) ...);

    DESCRIPTION
    This function splice two or more arrays together. This means that the the array becomes an array of the first element in the first given array, the first argument in next array and so on for all arrays. Then the second elements are added.

    EXAMPLE
    > Array.splice(({1,2,3}),({"1","2","3"}),({"a","b","c"}));
    Result: ({ /* 9 elements */
        1,
        "1",
        "a",
        2,
        "2",
        "b",
        3,
        "3",
        "c"
    })
    > Array.splice(({1,2,3}),({"1","2","3"}),({"a","b"}));
    Result: ({ /* 9 elements */
        1,
        "1",
        "a",
        2,
        "2",
        "b",
    })
    

    SEE ALSO
    `/, `*, `+, `- and Array.everynth

    FUNCTION
    Array.sum_arrays - map any number of arrays over a function

    SYNTAX
    array sum_arrays(function fun,array arr1,...);

    DESCRIPTION
    Works like this:
    array sum_arrays(function fun,array arr1,...)
    {
        int e;
        array res=allocate(sizeof(arr1));
        for(e=0;e<sizeof(arr1);e++)
        {
            res[e]=fun(arr1[e],arr2[e],...);
        }
        return res;
    }

    Simple ehh?

    SEE ALSO
    Array.map, Array.filter and Array.search_array

    FUNCTION
    Array.uniq - remove elements that are duplicates

    SYNTAX
    array uniq(array a);

    DESCRIPTION
    This function returns an copy of the array a with all duplicate values removed. The order of the values in the result is undefined.

    Chapter 12, Image

    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.

    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.

    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.

    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'.

    Let's look at an example of how this can be used:

    #!/usr/local/bin/pike

    int main()
    {
        write("Content-type: image/gif\n\n");
        object font=Image.font();
        font->load("testfont");
        object image=font->write(ctime(time));
        write(Image.GIF.encode(image));
    }
    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.

    DESCRIPTION
    This module adds image-drawing and -manipulating capabilities to pike.

    Image.Image Basic image manipulation
    Image.Font Creating images from text
    Image.Colortable Color reduction, quantisation and dither
    Image.Color Color names, objects and conversion
    encoding/decoding image files
    Image.GIF GIF encoding/decoding capabilities
    Image.JPEG JPEG encoding/decoding capabilities (needs libjpeg)
    Image.PNG PNG encoding/decoding capabilities (needs libz)
    Image.PNM PNM (PBM/PGM/PPM) encoding/decoding capabilities
    Image.XFace XFace encoding/decoding capabilities (needs libgmp)
    Image.XWD XWD (X-windows dump) decoding capabilities
    advanced
    Image.X module for supporting X-windows low-level formats, keeping a lot of bit-mending stuff.
    $Id: module.pmod,v 1.8 2000/03/22 18:12:19 peter Exp $

    NOTE
    Image module documentation is based on these file versions:
    
    

    $Id: blit.c,v 1.37 1999/06/18 19:19:14 mirar Exp $ $Id: blit_layer_include.h,v 1.6 1999/04/13 12:32:11 mirar Exp $ $Id: colors.c,v 1.30 2000/02/03 19:02:22 grubba Exp $ $Id: colortable.c,v 1.77 1999/10/30 11:51:41 mirar Exp $ $Id: colortable.h,v 1.17 1999/04/11 12:55:43 mirar Exp $ $Id: colortable_lookup.h,v 1.9 1999/04/10 02:02:07 mirar Exp $ $Id: dct.c,v 1.14 1999/06/18 19:19:20 mirar Exp $ $Id: any.c,v 1.16 2000/03/22 18:12:19 peter Exp $ $Id: bmp.c,v 1.20 2000/02/03 12:25:18 grubba Exp $ $Id: gif.c,v 1.50 1999/11/14 22:16:08 mast Exp $ $Id: gif_lzw.c,v 1.6 1999/05/30 20:11:14 mirar Exp $ $Id: gif_lzw.h,v 1.7 1999/05/30 20:11:15 mirar Exp $ $Id: ilbm.c,v 1.13 2000/02/03 19:01:29 grubba Exp $ $Id: pnm.c,v 1.20 1999/06/19 11:08:00 mirar Exp $ $Id: x.c,v 1.26 2000/03/27 07:42:35 hubbe Exp $ $Id: xwd.c,v 1.13 2000/01/11 01:42:36 mast Exp $ $Id: font.c,v 1.58 2000/03/25 23:34:32 hubbe Exp $ $Id: image.c,v 1.160 2000/04/09 06:15:17 per Exp $ $Id: image.h,v 1.35 1999/09/25 19:58:48 grubba Exp $ $Id: layers.c,v 1.43 2000/02/22 03:41:27 per Exp $ $Id: matrix.c,v 1.22 2000/04/09 06:15:17 per Exp $ $Id: operator.c,v 1.25 1999/09/14 23:17:15 marcus Exp $ $Id: orient.c,v 1.13 1999/06/19 20:24:48 hubbe Exp $ $Id: pattern.c,v 1.18 1999/07/16 11:44:20 mirar Exp $ $Id: poly.c,v 1.3 1999/07/28 09:26:20 mirar Exp $ $Id: polyfill.c,v 1.30 1999/06/19 20:24:49 hubbe Exp $ Experimental functions.

    METHOD
    Image.lay

    SYNTAX
    Image.Layer lay(array(Image.Layer|mapping))
    Image.Layer lay(array(Image.Layer|mapping), int xoffset, int yoffset, int xsize, int ysize)

    DESCRIPTION
    Combine layers.

    RETURNS
    a new layer object.

    SEE ALSO
    Image.Layer

    METHOD
    Image.load,
    Image.load_layer,
    Image._load

    SYNTAX
    object(Image.Image) load()
    object(Image.Image) load(object file)
    object(Image.Image) load(string filename)
    object(Image.Layer) load_layer()
    object(Image.Layer) load_layer(object file)
    object(Image.Layer) load_layer(string filename)
    mapping _load()
    mapping _load(object file)
    mapping _load(string filename)

    DESCRIPTION
    Helper function to load an image from a file. If no filename is given, Stdio.stdin is used. The result is the same as from the decode functions in Image.ANY.

    NOTE
    All data is read, ie nothing happens until the file is closed. Throws upon error.

    12.1 Image.Image

    CLASS
    Image.Image

    DESCRIPTION
    The main object of the Image module, this object is used as drawing area, mask or result of operations.

    basic:
    clear, clone, create, xsize, ysize

    plain drawing:
    box, circle, getpixel, line, setcolor, setpixel, threshold, polyfill

    operators:
    `&, `*, `+, `-, `==, `>, `<, `|

    pasting images:
    paste, paste_alpha, paste_alpha_color, paste_mask

    getting subimages, scaling, rotating:
    autocrop, clone, copy, dct, mirrorx, rotate, rotate_ccw, rotate_cw, rotate_expand, scale, skewx, skewx_expand, skewy, skewy_expand

    calculation by pixels:
    apply_matrix, change_color, color, distancesq, grey, invert, modify_by_intensity, outline select_from, rgb_to_hsv, hsv_to_rgb,

    average, max, min, sum, sumf, find_min, find_max

    special pattern drawing:
    noise, turbulence, test, tuned_box, gradients, random

    SEE ALSO
    Image, Image.Font, Image.Colortable and Image.X

    METHOD
    Image.Image.apply_matrix

    SYNTAX
    object apply_matrix(array(array(int|array(int))) matrix)
    object apply_matrix(array(array(int|array(int))) matrix, int r, int g, int b)
    object apply_matrix(array(array(int|array(int))) matrix, int r, int g, int b, int|float div)

    DESCRIPTION
    Applies a pixel-transform matrix, or filter, to the image.

    2   2
    pixel(x,y)= base+ k ( sum sum pixel(x+k-1,y+l-1)*matrix(k,l) )
    k=0 l=0
    

    1/k is sum of matrix, or sum of matrix multiplied with div. base is given by r,g,b and is normally black.

    blur (ie a 2d gauss function):
    ({({1,2,1}),
    ({2,5,2}),
    ({1,2,1})})
    
    original
    sharpen (k>8, preferably 12 or 16):
    ({({-1,-1,-1}),
    ({-1, k,-1}),
    ({-1,-1,-1})})
    
    edge detect:
    ({({1, 1,1}),
    ({1,-8,1}),
    ({1, 1,1})})
    
    horisontal edge detect (get the idea):
    ({({0, 0,0}),
    ({1,-2,1}),
    ({0, 0,0})})
    
    emboss (might prefer to begin with a grey image):
    ({({2, 1, 0}),
    ({1, 0,-1}),
    ({0,-1,-2})}), 128,128,128, 3
    
    greyed

    This function is not very fast.

    ARGUMENTS
    argument(s)description
    array(array(int|array(int)))
    the matrix; innermost is a value or an array with red, green, blue values for red, green, blue separation.
    int r
    int g
    int b
    base level of result, default is zero
    int|float div
    division factor, default is 1.0.

    RETURNS
    the new image object

    METHOD
    Image.Image.apply_max

    SYNTAX
    object apply_max(array(array(int|array(int))) matrix)
    object apply_max(array(array(int|array(int))) matrix, int r, int g, int b)
    object apply_max(array(array(int|array(int))) matrix, int r, int g, int b, int|float div)

    DESCRIPTION
    This is the same as apply_matrix, but it uses the maximum instead.

    This function is not very fast.

    ARGUMENTS
    argument(s)description
    array(array(int|array(int)))
    the matrix; innermost is a value or an array with red, green, blue values for red, green, blue separation.
    int r
    int g
    int b
    base level of result, default is zero
    int|float div
    division factor, default is 1.0.

    RETURNS
    the new image object

    NOTE
    experimental status; may not be exact the same output in later versions

    METHOD
    Image.Image.autocrop,
    Image.Image.find_autocrop

    SYNTAX
    object autocrop()
    object autocrop(int border)
    object autocrop(int border, Color color)
    object autocrop(int border, int left, int right, int top, int bottom)
    object autocrop(int border, int left, int right, int top, int bottom, Color color)
    array(int) find_autocrop()
    array(int) find_autocrop(int border)
    array(int) find_autocrop(int border, int left, int right, int top, int bottom)

    DESCRIPTION
    Removes "unneccesary" borders around the image, adds one of its own if wanted to, in selected directions.

    "Unneccesary" 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.

    The find_autocrop() function simply returns x1,y1,x2,y2 for the kept area. (This can be used with copy later.)

    ARGUMENTS
    argument(s)description
    int border
    int left
    int right
    int top
    int bottom
    which borders to scan and cut the image; a typical example is removing the top and bottom unneccesary pixels:
    img=img->autocrop(0, 0,0,1,1);

    RETURNS
    the new image object

    SEE ALSO
    copy

    METHOD
    Image.Image.max,
    Image.Image.min,
    Image.Image.sumf,
    Image.Image.sum,
    Image.Image.average

    SYNTAX
    array(float) average()
    array(int) min()
    array(int) max()
    array(int) sum()
    array(float) sumf()

    DESCRIPTION
    Gives back the average, minimum, maximum color value, and the sum of all pixel's color value.

    NOTE
    sum() values can wrap! Most systems only have 31 bits available for positive integers. (Meaning, be careful with images that have more than 8425104 pixels.)

    average() and sumf() may also wrap, but on a line basis. (Meaning, be careful with images that are wider than 8425104 pixels.) These functions may have a precision problem instead, during to limits in the 'double' C type and/or 'float' Pike type.

    METHOD
    Image.Image.bitscale

    SYNTAX
    object bitscale(float factor)
    object bitscale(float xfactor, float yfactor)

    DESCRIPTION
    scales the image with a factor, without smoothing. This routine is faster than scale, but gives less correct results

    ARGUMENTS
    argument(s)description
    float factor
    factor to use for both x and y
    float xfactor
    float yfactor
    separate factors for x and y

    RETURNS
    the new image object

    METHOD
    Image.Image.bitscale

    SYNTAX
    object bitscale(int newxsize, int newysize)
    object bitscale(0, int newysize)
    object bitscale(int newxsize, 0)

    DESCRIPTION
    scales the image to a specified new size, if one of newxsize or newysize is 0, the image aspect ratio is preserved.

    ARGUMENTS
    argument(s)description
    int newxsize
    int newysize
    new image size in pixels

    RETURNS
    the new image object

    NOTE
    resulting image will be 1x1 pixels, at least

    METHOD
    Image.Image.box

    SYNTAX
    object box(int x1, int y1, int x2, int y2)
    object box(int x1, int y1, int x2, int y2, int r, int g, int b)
    object box(int x1, int y1, int x2, int y2, int r, int g, int b, int alpha)

    DESCRIPTION
    Draws a filled rectangle on the image.

    original ->box(40,10,10,80,0,255,0)

    ARGUMENTS
    argument(s)description
    int x1
    int y1
    int x2
    int y2
    box corners
    int r
    int g
    int b
    color of the box
    int alpha
    alpha value

    RETURNS
    the object called

    METHOD
    Image.Image.cast

    SYNTAX
    string cast(string type)

    DESCRIPTION
    Cast the image to another datatype. Currently supported are string ("rgbrgbrgb...") and array (double array of Image.Color objects).

    SEE ALSO
    Image.Color and Image.X

    METHOD
    Image.Image.change_color

    SYNTAX
    object change_color(int tor, int tog, int tob)
    object change_color(int fromr, int fromg, int fromb,  int tor, int tog, int tob)

    DESCRIPTION
    Changes one color (exakt match) to another. If non-exakt-match is preferred, check distancesq and paste_alpha_color.

    ARGUMENTS
    argument(s)description
    int tor
    int tog
    int tob
    destination color and next current color
    int fromr
    int fromg
    int fromb
    source color, default is current color

    RETURNS
    a new (the destination) image object

    METHOD
    Image.Image.circle

    SYNTAX
    object circle(int x, int y, int rx, int ry)
    object circle(int x, int y, int rx, int ry, int r, int g, int b)
    object circle(int x, int y, int rx, int ry, int r, int g, int b, int alpha)

    DESCRIPTION
    Draws a circle on the image. The circle is not antialiased.

    original ->circle(50,50,30,50,0,255,255)

    ARGUMENTS
    argument(s)description
    int x
    int y
    circle center
    int rx
    int ry
    circle radius in pixels
    int r
    int g
    int b
    color
    int alpha
    alpha value

    RETURNS
    the object called

    METHOD
    Image.Image.clear

    SYNTAX
    void clear()
    void clear(int r, int g, int b)
    void clear(int r, int g, int b, int alpha)

    DESCRIPTION
    gives a new, cleared image with the same size of drawing area

    original ->clear(0,128,255)

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    color of the new image
    int alpha
    new default alpha channel value

    SEE ALSO
    copy and clone

    METHOD
    Image.Image.clone

    SYNTAX
    object clone()
    object clone(int xsize, int ysize)
    object clone(int xsize, int ysize, int r, int g, int b)
    object clone(int xsize, int ysize, int r, int g, int b, int alpha)

    DESCRIPTION
    Copies to or initialize a new image object.

    original clone clone(50,50)

    ARGUMENTS
    argument(s)description
    int xsize
    int ysize
    size of (new) image in pixels, called image is cropped to that size
    int r
    int g
    int b
    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).
    int alpha
    new default alpha channel value

    RETURNS
    the new object

    SEE ALSO
    copy and create

    METHOD
    Image.Image.color

    SYNTAX
    object color()
    object color(int value)
    object color(int r, int g, int b)

    DESCRIPTION
    Colorize an image.

    The red, green and blue values of the pixels are multiplied with the given value(s). This works best on a grey image...

    The result is divided by 255, giving correct pixel values.

    If no arguments are given, the current color is used as factors.

    original ->color(128,128,255);

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    red, green, blue factors
    int value
    factor

    RETURNS
    the new image object

    SEE ALSO
    grey, `* and modify_by_intensity

    METHOD
    Image.Image.copy

    SYNTAX
    object copy()
    object copy(int x1, int y1, int x2, int y2)
    object copy(int x1, int y1, int x2, int y2, int r, int g, int b)
    object copy(int x1, int y1, int x2, int y2, int r, int g, int b, int alpha)

    DESCRIPTION
    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.

    original ->copy(5,5,XSIZE-6,YSIZE-6) ->copy(-5,-5,XSIZE+4,YSIZE+4,10,75,10)

    ARGUMENTS
    argument(s)description
    int x1
    int y1
    int x2
    int y2
    The requested new area. Default is the old image size.
    int r
    int g
    int b
    color of the new image
    int alpha
    new default alpha channel value

    RETURNS
    a new image object

    NOTE
    clone(void) and copy(void) does the same operation

    SEE ALSO
    clone and autocrop

    METHOD
    Image.Image.create

    SYNTAX
    void create()
    void create(int xsize, int ysize)
    void create(int xsize, int ysize, Color color)
    void create(int xsize, int ysize, int r, int g, int b)
    void create(int xsize, int ysize, int r, int g, int b, int alpha)
    void create(int xsize, int ysize, string method, method ...)

    DESCRIPTION
    Initializes a new image object.

    Image.Image(XSIZE,YSIZE) Image.Image(XSIZE,YSIZE,255,128,0)

    The image can also be calculated from some special methods, for convinience:

    channel modes; followed by a number of 1-char-per-pixel strings
    or image objects (where red channel will be used),
    or an integer value:
    "grey" : make a grey image (needs 1 source: grey)
    "rgb"  : make an rgb image (needs 3 sources: red, green and blue)
    "cmyk" : make a rgb image from cmyk (cyan, magenta, yellow, black)
    
    

    generate modes; all extra arguments is given to the generation function. These has the same name as the method: "test," "gradients" "noise" "turbulence" "random" "randomgrey" specials cases: "tuned_box" (coordinates is automatic)

    ARGUMENTS
    argument(s)description
    int xsize
    int ysize
    size of (new) image in pixels
    Color color
    int r
    int g
    int b
    background color (will also be current color), default color is black
    int alpha
    default alpha channel value

    BUGS
    SIGSEGVS can be caused if the size is too big, due to unchecked overflow - (xsize*ysize)&MAXINT is small enough to allocate.

    SEE ALSO
    copy, clone and Image.Image

    METHOD
    Image.Image.dct

    SYNTAX
    object dct(int newx, int newy)

    DESCRIPTION
    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.

    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.

    Recommended wrapping algorithm is to scale overlapping parts of the image-to-be-scaled.

    This functionality is actually added as an true experiment, but works...

    ARGUMENTS
    argument(s)description
    int newx
    int newy
    new image size in pixels

    RETURNS
    the new image object

    NOTE
    Do NOT use this function if you don't know what you're dealing with! Read some signal theory first...

    It write's dots on stderr, to indicate some sort of progress. It doesn't use any fct (compare: fft) algorithms.

    METHOD
    Image.Image.distancesq

    SYNTAX
    object distancesq()
    object distancesq(int r, int g, int b)

    DESCRIPTION
    Makes an 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, rightshifted 8 steps:

    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
    

    original distance² to cyan ...to purple ...to yellow

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    red, green, blue coordinates

    RETURNS
    the new image object

    SEE ALSO
    select_from

    METHOD
    Image.Image.find_min,
    Image.Image.find_max

    SYNTAX
    array(int) find_min()
    array(int) find_max()
    array(int) find_min(int r, int g, int b)
    array(int) find_max(int r, int g, int b)

    DESCRIPTION
    Gives back the position of the minimum or maximum pixel value, weighted to grey.

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    weight of color, default is r=87,g=127,b=41, same as the grey() method.

    METHOD
    Image.Image.gamma

    SYNTAX
    object gamma(float g)
    object gamma(float gred, ggreen, gblue)

    DESCRIPTION
    Calculate pixels in image by gamma curve.

    Intensity of new pixels are calculated by:
    i' = i^g

    For example, you are viewing your image on a screen with gamma 2.2. To correct your image to the correct gamma value, do something like:

    my_display_image(my_image()->gamma(1/2.2);

    ARGUMENTS
    argument(s)description
    int g
    int gred
    int ggreen
    int gblue
    gamma value

    RETURNS
    a new image object

    SEE ALSO
    grey, `* and color

    METHOD
    Image.Image.getpixel

    SYNTAX
    array(int) getpixel(int x, int y)

    DESCRIPTION

    ARGUMENTS
    argument(s)description
    int x
    int y
    position of the pixel

    RETURNS
    color of the requested pixel -- ({int red,int green,int blue})

    METHOD
    Image.Image.gradients

    SYNTAX
    int gradients(array(int) point,  ...)
    int gradients(array(int) point,  ...,  float grad)

    DESCRIPTION
    original 2 color
    gradient
    10 color
    gradient
    3 colors,
    grad=4.0
    3 colors,
    grad=1.0
    3 colors,
    grad=0.25

    RETURNS
    the new image

    METHOD
    Image.Image.grey

    SYNTAX
    object grey()
    object grey(int r, int g, int b)

    DESCRIPTION
    Makes a grey-scale image (with weighted values).

    original ->grey(); ->grey(0,0,255);

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    weight of color, default is r=87,g=127,b=41, which should be pretty accurate of what the eyes see...

    RETURNS
    the new image object

    SEE ALSO
    color, `* and modify_by_intensity

    METHOD
    Image.Image.rgb_to_hsv,
    Image.Image.hsv_to_rgb

    SYNTAX
    object rgb_to_hsv()
    object hsv_to_rgb()

    DESCRIPTION
    Converts RGB data to HSV data, or the other way around. When converting to HSV, the resulting data is stored like this: pixel.r = h; pixel.g = s; pixel.b = v;

    When converting to RGB, the input data is asumed to be placed in the pixels as above.

    original ->hsv_to_rgb(); ->rgb_to_hsv();
    tuned box (below) the rainbow (below) same, but rgb_to_hsv()

    HSV to RGB calculation:

    in = input pixel
    out = destination pixel
    h=-pos*c_angle*3.1415/(float)NUM_SQUARES;
    out.r=(in.b+in.g*cos(in.r));
    out.g=(in.b+in.g*cos(in.r + pi*2/3));
    out.b=(in.b+in.g*cos(in.r + pi*4/3));
    

    RGB to HSV calculation: Hmm.

    
    
    

    Example: Nice rainbow.

    object i = Image.Image(200,200);
    i = i->tuned_box(0,0, 200,200,
    ({ ({ 255,255,128 }), ({ 0,255,128 }),
    ({ 255,255,255 }), ({ 0,255,255 })}))
    ->hsv_to_rgb();
    

    RETURNS
    the new image object

    METHOD
    Image.Image.invert

    SYNTAX
    object invert()

    DESCRIPTION
    Invert an image. Each pixel value gets to be 255-x, where x is the old value.

    original ->invert(); ->rgb_to_hsv()->invert()->hsv_to_rgb();

    RETURNS
    the new image object

    METHOD
    Image.Image.line

    SYNTAX
    object line(int x1, int y1, int x2, int y2)
    object line(int x1, int y1, int x2, int y2, int r, int g, int b)
    object line(int x1, int y1, int x2, int y2, int r, int g, int b, int alpha)

    DESCRIPTION
    Draws a line on the image. The line is not antialiased.

    original ->line(50,10,10,50,255,0,0)

    ARGUMENTS
    argument(s)description
    int x1
    int y1
    int x2
    int y2
    line endpoints
    int r
    int g
    int b
    color
    int alpha
    alpha value

    RETURNS
    the object called

    METHOD
    Image.Image.make_ascii

    SYNTAX
    string make_ascii(object orient1,  object orient2,  object orient3,  object orient4,  int|void xsize,  int|void ysize)

    DESCRIPTION
    This method creates a string that looks like the image. Example:
    //Stina is an image with a cat.
    array(object) Stina4=Stina->orient4();
    Stina4[1]*=215;
    Stina4[3]*=215;
    string foo=Stina->make_ascii(@Stina4,40,4,8);
    

    RETURNS
    some nice acsii-art.

    NOTE
    experimental status; may not be exact the same output in later versions
          |      /    -    \
    hue=  0     64   128  192  (=red in an hsv image)
    

    SEE ALSO
    orient and orient4

    METHOD
    Image.Image.map_closest,
    Image.Image.select_colors,
    Image.Image.map_fast,
    Image.Image.map_fs

    SYNTAX
    object map_closest(array(array(int)) colors)
    object map_fast(array(array(int)) colors)
    object map_fs(array(array(int)) colors)
    array select_colors(int num)

    DESCRIPTION
    Compatibility functions. Do not use!

    Replacement examples:

    Old code:

    img=map_fs(img->select_colors(200));
    New code:
    img=Image.Colortable(img,200)->floyd_steinberg()->map(img);

    Old code:

    img=map_closest(img->select_colors(17)+({({255,255,255}),({0,0,0})}));
    New code:
    img=Image.Colortable(img,19,({({255,255,255}),({0,0,0})}))->map(img);

    METHOD
    Image.Image.match

    SYNTAX
    object match(int|float scale,  object needle)
    object match(int|float scale,  object needle,  object haystack_cert,  object needle_cert)
    object match(int|float scale,  object needle,  object haystack_avoid,  int foo)
    object match(int|float scale,  object needle,  object haystack_cert,  object needle_cert,  object haystack_avoid,  int foo)

    DESCRIPTION
    This method creates an image that describes the match in every pixel in the image and the needle-Image.

    new pixel value =
    sum( my_abs(needle_pixel-haystack_pixel))
    

    The new image only have the red rgb-part set.

    ARGUMENTS
    argument(s)description
    int|float scale
    Every pixel is divided with this value. Note that a proper value here depends on the size of the neadle.
    object needle
    The image to use for the matching.
    object haystack_cert
    This image should be the same size as the image itselves. A non-white-part of the haystack_cert-image modifies the output by lowering it.
    object needle_cert
    The same, but for the needle-image.
    int foo
    object haystack_avoid
    This image should be the same size as the image itselves. If foo is less than the red value in haystack_avoid the corresponding matching-calculating is not calculated. The avoided parts are drawn in the color 0,100,0.

    RETURNS
    the new image object

    NOTE
    experimental status; may not be exact the same output in later versions

    SEE ALSO
    phasev and phaseh

    METHOD
    Image.Image.mirrorx

    SYNTAX
    object mirrorx()

    DESCRIPTION
    mirrors an image:
    original ->mirrorx();

    RETURNS
    the new image object

    METHOD
    Image.Image.mirrory

    SYNTAX
    object mirrory()

    DESCRIPTION
    mirrors an image:
    original ->mirrory();

    METHOD
    Image.Image.modify_by_intensity

    SYNTAX
    object modify_by_intensity(int r, int g, int b, int|array(int) v1, ..., int|array(int) vn)

    DESCRIPTION
    Recolor an image from intensity values.

    For each color an intensity is calculated, from r, g and b factors (see grey), this gives a value between 0 and max.

    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.

    original ->grey()->modify_by_intensity(1,0,0, 0,({255,0,0}),({0,255,0}));

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    red, green, blue intensity factors
    int|array(int) v1
    int|array(int) vn
    destination color

    RETURNS
    the new image object

    SEE ALSO
    grey, `* and color

    METHOD
    Image.Image.noise

    SYNTAX
    void noise(array(float|int|array(int)) colorrange)
    void noise(array(float|int|array(int)) colorrange, float scale, float xdiff, float ydiff, float cscale)

    DESCRIPTION
    Gives a new image with the old image's size, filled width a 'noise' pattern.

    The random seed may be different with each instance of pike.

    Example: ->noise( ({0,({255,0,0}), 0.3,({0,255,0}), 0.6,({0,0,255}), 0.8,({255,255,0})}), 0.2,0.0,0.0,1.0 );

    ARGUMENTS
    argument(s)description
    array(float|int|array(int)) colorrange
    colorrange table
    float scale
    default value is 0.1
    float xdiff
    float ydiff
    default value is 0,0
    float cscale
    default value is 1

    SEE ALSO
    turbulence

    METHOD
    Image.Image.orient,
    Image.Image.orient4

    SYNTAX
    object orient(void|array(object))
    array(object) orient4()

    DESCRIPTION
    Draws images describing the orientation of the current image.

    orient gives an HSV image (run a hsv_to_rgb pass on it to get a viewable image). corresponding to the angle of the orientation:

          |      /    -    \
    hue=  0     64   128  192  (=red in an hsv image)
    purple cyan green red
    
    Red, green and blue channels are added and not compared separately.

    If you first use orient4 you can give its output as input to this function.

    The orient4 function gives back 4 image objects, corresponding to the amount of different directions, see above.

    RETURNS
    an image or an array of the four new image objects

    NOTE
    experimental status; may not be exact the same output in later versions

    METHOD
    Image.Image.outline,
    Image.Image.outline_mask

    SYNTAX
    object outline()
    object outline(int olr, int olg, int olb)
    object outline(int olr, int olg, int olb, int bkgr, int bkgg, int bkgb)
    object outline(array(array(int)) mask)
    object outline(array(array(int)) mask, int olr, int olg, int olb)
    object outline(array(array(int)) mask, int olr, int olg, int olb, int bkgr, int bkgg, int bkgb)
    object outline_mask()
    object outline_mask(int bkgr, int bkgg, int bkgb)
    object outline_mask(array(array(int)) mask)
    object outline_mask(array(array(int)) mask, int bkgr, int bkgg, int bkgb)

    DESCRIPTION
    Makes an outline of this image, ie paints with the given color around the non-background pixels.

    Default is to paint above, below, to the left and the right of these pixels.

    You can also run your own outline mask.

    The outline_mask function gives the calculated outline as an alpha channel image of white and black instead.

    original masked
    through
    threshold
    ...and
    outlined
    with red

    ARGUMENTS
    argument(s)description
    array(array(int)) mask
    mask matrix. Default is ({({0,1,0}),({1,1,1}),({0,1,0})}).
    int olr
    int olg
    int olb
    outline color. Default is current.
    int bkgr
    int bkgg
    int bkgb
    background color (what color to outline to); default is color of pixel 0,0.
    int|float div
    division factor, default is 1.0.

    RETURNS
    the new image object

    NOTE
    no antialias!

    METHOD
    Image.Image.paste

    SYNTAX
    object paste(object image)
    object paste(object image, int x, int y)

    DESCRIPTION
    Pastes a given image over the current image.

    ARGUMENTS
    argument(s)description
    object image
    image to paste (may be empty, needs to be an image object)
    int x
    int y
    where to paste the image; default is 0,0

    RETURNS
    the object called

    SEE ALSO
    paste_mask, paste_alpha and paste_alpha_color

    METHOD
    Image.Image.paste_alpha

    SYNTAX
    object paste_alpha(object image, int alpha)
    object paste_alpha(object image, int alpha, int x, int y)

    DESCRIPTION
    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.

    ARGUMENTS
    argument(s)description
    object image
    image to paste
    int alpha
    alpha channel value
    int x
    int y
    where to paste the image; default is 0,0

    RETURNS
    the object called

    SEE ALSO
    paste_mask, paste and paste_alpha_color

    METHOD
    Image.Image.paste_alpha_color

    SYNTAX
    object paste_alpha_color(object mask)
    object paste_alpha_color(object mask, int x, int y)
    object paste_alpha_color(object mask, int r, int g, int b)
    object paste_alpha_color(object mask, int r, int g, int b, int x, int y)
    object paste_alpha_color(object mask, Color color)
    object paste_alpha_color(object mask, Color color, int x, int y)

    DESCRIPTION
    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.

    ARGUMENTS
    argument(s)description
    object mask
    mask image
    int r
    int g
    int b
    what color to paint with; default is current
    int x
    int y
    where to paste the image; default is 0,0

    RETURNS
    the object called

    SEE ALSO
    paste_mask, paste_alpha and paste_alpha_color

    METHOD
    Image.Image.paste_mask

    SYNTAX
    object paste_mask(object image, object mask)
    object paste_mask(object image, object mask, int x, int y)

    DESCRIPTION
    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.

    The masks red, green and blue values are used separately.

    ARGUMENTS
    argument(s)description
    object image
    image to paste
    object mask
    mask image
    int x
    int y
    where to paste the image; default is 0,0

    RETURNS
    the object called

    SEE ALSO
    paste, paste_alpha and paste_alpha_color

    METHOD
    Image.Image.phasev,
    Image.Image.phaseh,
    Image.Image.phasehv,
    Image.Image.phasevh

    SYNTAX
    object phaseh()
    object phasev()
    object phasevh()
    object phasehv()

    DESCRIPTION
    Draws images describing the phase of the current image. phaseh gives the horizontal phase and phasev the vertical phase.

    phaseh gives an image where

    max  falling   min  rising
    value=  0     64      128   192
    

    0 is set if there is no way to determine if it is rising or falling. This is done for the every red, green and blue part of the image.

    Phase images can be used to create ugly effects or to find meta-information in the orginal image.

    original phaseh() phasev() phasevh() phasehv()

    RETURNS
    the new image object

    NOTE
    experimental status; may not be exact the same output in later versions

    BUGS
    0 should not be set as explained above.

    METHOD
    Image.Image.polyfill

    SYNTAX
    object polyfill(array(int|float) ... curve)

    DESCRIPTION
    fills an area with the current color

    ARGUMENTS
    argument(s)description
    array(int|float) curve
    curve(s), ({x1,y1,x2,y2,...,xn,yn}), automatically closed.

    If any given curve is inside another, it will make a hole.

    RETURNS
    the current object

    NOTE
    Lines in the polygon may not be crossed without the crossing coordinate specified in both lines.

    BUGS
    Inverted lines reported on Intel and Alpha processors.

    SEE ALSO
    setcolor

    METHOD
    Image.Image.random,
    Image.Image.randomgrey

    SYNTAX
    object random()
    object random(int seed)
    object randomgrey()
    object random(greyint seed)

    DESCRIPTION
    Gives a randomized image;
    original ->random() ->random(17) greyed
    (same again)
    color(red)
    (same again)
    ...red channel

    Use with ->grey() or ->color() for one-color-results.

    RETURNS
    a new image

    SEE ALSO
    test and noise

    METHOD
    Image.Image.write_lsb_rgb,
    Image.Image.read_lsb_grey,
    Image.Image.write_lsb_grey,
    Image.Image.read_lsb_rgb

    SYNTAX
    object write_lsb_rgb(string what)
    object write_lsb_grey(string what)
    string read_lsb_rgb()
    string read_lsb_grey()

    DESCRIPTION
    These functions read/write in the least significant bit of the image pixel values. The _rgb() functions read/write on each of the red, green and blue values, and the grey keeps the same lsb on all three.

    The string is nullpadded or cut to fit.

    ARGUMENTS
    argument(s)description
    string what
    the hidden message

    RETURNS
    the current object or the read string

    METHOD
    Image.Image.rotate,
    Image.Image.rotate_expand

    SYNTAX
    object rotate(int|float angle)
    object rotate(int|float angle, int r, int g, int b)
    object rotate_expand(int|float angle)
    object rotate_expand(int|float angle, int r, int g, int b)

    DESCRIPTION
    Rotates an image a certain amount of degrees (360° is a complete rotation) counter-clockwise:

    original ->rotate(15,255,0,0); ->rotate_expand(15);

    The "expand" variant of functions stretches the image border pixels rather then filling with the given or current color.

    This rotate uses the skewx() and skewy() functions.

    ARGUMENTS
    argument(s)description
    int|float angle
    the number of degrees to rotate
    int r
    int g
    int b
    color to fill with; default is current

    RETURNS
    the new image object

    METHOD
    Image.Image.rotate_ccw

    SYNTAX
    object rotate_ccw()

    DESCRIPTION
    rotates an image counter-clockwise, 90 degrees.

    original ->rotate_ccw();

    RETURNS
    the new image object

    METHOD
    Image.Image.rotate_cw

    SYNTAX
    object rotate_cw()

    DESCRIPTION
    rotates an image clockwise, 90 degrees.

    original ->rotate_cw();

    RETURNS
    the new image object

    METHOD
    Image.Image.scale

    SYNTAX
    object scale(float factor)
    object scale(0.5)
    object scale(float xfactor, float yfactor)

    DESCRIPTION
    scales the image with a factor, 0.5 is an optimized case.

    ARGUMENTS
    argument(s)description
    float factor
    factor to use for both x and y
    float xfactor
    float yfactor
    separate factors for x and y

    RETURNS
    the new image object

    METHOD
    Image.Image.scale

    SYNTAX
    object scale(int newxsize, int newysize)
    object scale(0, int newysize)
    object scale(int newxsize, 0)

    DESCRIPTION
    scales the image to a specified new size, if one of newxsize or newysize is 0, the image aspect ratio is preserved.

    ARGUMENTS
    argument(s)description
    int newxsize
    int newysize
    new image size in pixels

    RETURNS
    the new image object

    NOTE
    resulting image will be 1x1 pixels, at least

    METHOD
    Image.Image.select_from

    SYNTAX
    object select_from(int x, int y)
    object select_from(int x, int y, int edge_value)

    DESCRIPTION
    Makes an grey-scale image, for alpha-channel use.

    This is very close to a floodfill.

    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, rightshifted 8 steps (see distancesq).

    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.

    ARGUMENTS
    argument(s)description
    int x
    int y
    originating pixel in the image

    RETURNS
    the new image object

    SEE ALSO
    distancesq

    METHOD
    Image.Image.setcolor

    SYNTAX
    object setcolor(int r, int g, int b)
    object setcolor(int r, int g, int b, int alpha)

    DESCRIPTION
    set the current color

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    new color
    int alpha
    new alpha value

    RETURNS
    the object called

    METHOD
    Image.Image.setpixel

    SYNTAX
    object setpixel(int x, int y)
    object setpixel(int x, int y, int r, int g, int b)
    object setpixel(int x, int y, int r, int g, int b, int alpha)

    DESCRIPTION
    original ->setpixel(10,10,255,0,0)

    ARGUMENTS
    argument(s)description
    int x
    int y
    position of the pixel
    int r
    int g
    int b
    color
    int alpha
    alpha value

    RETURNS
    the object called

    METHOD
    Image.Image.skewx,
    Image.Image.skewx_expand

    SYNTAX
    object skewx(int x)
    object skewx(int yfactor)
    object skewx(int x, int r, int g, int b)
    object skewx(int yfactor, int r, int g, int b)
    object skewx_expand(int x)
    object skewx_expand(int yfactor)
    object skewx_expand(int x, int r, int g, int b)
    object skewx_expand(int yfactor, int r, int g, int b)

    DESCRIPTION
    Skews an image an amount of pixels or a factor; a skew-x is a transformation:

    original ->skewx(15,255,0,0); ->skewx_expand(15);

    ARGUMENTS
    argument(s)description
    int x
    the number of pixels The "expand" variant of functions stretches the image border pixels rather then filling with the given or current color.
    float yfactor
    best described as: x=yfactor*this->ysize()
    int r
    int g
    int b
    color to fill with; default is current

    RETURNS
    the new image object

    METHOD
    Image.Image.skewy,
    Image.Image.skewy_expand

    SYNTAX
    object skewy(int y)
    object skewy(int xfactor)
    object skewy(int y, int r, int g, int b)
    object skewy(int xfactor, int r, int g, int b)
    object skewy_expand(int y)
    object skewy_expand(int xfactor)
    object skewy_expand(int y, int r, int g, int b)
    object skewy_expand(int xfactor, int r, int g, int b)

    DESCRIPTION
    Skews an image an amount of pixels or a factor; a skew-y is a transformation:

    original ->skewy(15,255,0,0); ->skewy_expand(15);

    The "expand" variant of functions stretches the image border pixels rather then filling with the given or current color.

    ARGUMENTS
    argument(s)description
    int y
    the number of pixels
    float xfactor
    best described as: t=xfactor*this->xsize()
    int r
    int g
    int b
    color to fill with; default is current

    RETURNS
    the new image object

    METHOD
    Image.Image.test

    SYNTAX
    object test()
    object test(int seed)

    DESCRIPTION
    Generates a test image, currently random gradients.

    original ->test() ...and again

    RETURNS
    the new image

    NOTE
    May be subject to change or cease without prior warning.

    SEE ALSO
    gradients and tuned_box

    METHOD
    Image.Image.threshold

    SYNTAX
    object threshold()
    object threshold(int level)
    object threshold(int r, int g, int b)
    object threshold(Color color)

    DESCRIPTION
    Makes a black-white image.

    If any of red, green, blue parts of a pixel is larger then the given value, the pixel will become white, else black.

    This method works fine with the grey method.

    If no arguments are given, it will paint all non-black pixels white. (Ie, default is 0,0,0.)

    original ->threshold(100); ->threshold(0,100,0);

    RETURNS
    the new image object

    NOTE
    The above statement "any ..." was changed from "all ..." in Pike 0.7 (9906). It also uses 0,0,0 as default input, instead of current color. This is more useful.

    SEE ALSO
    grey

    METHOD
    Image.Image.tuned_box

    SYNTAX
    object tuned_box(int x1, int y1, int x2, int y2, array(array(int)) corner_color)

    DESCRIPTION
    Draws a filled rectangle with colors (and alpha values) tuned between the corners.

    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.

    original tuned box solid tuning
    (blue,red,green,yellow)
    tuning transparency
    (as left + 255,128,128,0)

    ARGUMENTS
    argument(s)description
    int x1
    int y1
    int x2
    int y2
    rectangle corners
    array(array(int)) corner_color
    colors of the corners:
    ({x1y1,x2y1,x1y2,x2y2})
    
    each of these is an array of integeres:
    ({r,g,b}) or ({r,g,b,alpha})
    
    Default alpha channel value is 0 (opaque).

    RETURNS
    the object called

    METHOD
    Image.Image.turbulence

    SYNTAX
    void turbulence(array(float|int|array(int)) colorrange)
    void turbulence(array(float|int|array(int)) colorrange, int octaves, float scale, float xdiff, float ydiff, float cscale)

    DESCRIPTION
    gives a new image with the old image's size, filled width a 'turbulence' pattern

    The random seed may be different with each instance of pike.

    Example:
    ->turbulence( ({0,({229,204,204}), 0.9,({229,20,20}), 0.9,Color.black}) );

    ARGUMENTS
    argument(s)description
    array(float|int|array(int)) colorrange
    colorrange table
    int octaves
    default value is 3
    float scale
    default value is 0.1
    float xdiff
    float ydiff
    default value is 0,0
    float cscale
    default value is 1

    SEE ALSO
    noise and Image.Color

    METHOD
    Image.Image.xsize

    SYNTAX
    int xsize()

    RETURNS
    the width of the image

    METHOD
    Image.Image.ysize

    SYNTAX
    int ysize()

    RETURNS
    the height of the image

    METHOD
    Image.Image.`/,
    Image.Image.`%

    SYNTAX
    object `/(object operand)
    object `/(Color color)
    object `/(int value)
    object `%(object operand)
    object `%(Color color)
    object `%(int value)

    DESCRIPTION
    Divides pixel values and creates a new image from the result or the rest.

    ARGUMENTS
    argument(s)description
    object operand
    the other image to divide with; the images must have the same size.
    Color color
    int value
    if specified as color or value, it will act as a whole image of that color (or value).

    RETURNS
    the new image object

    NOTE
    It isn't possible to do a modulo 256 either. (why?)

    SEE ALSO
    `-, `+, `|, `&, `* and Image.Layer

    METHOD
    Image.Image.`&

    SYNTAX
    object `&(object operand)
    object `&(array(int) color)
    object `&(int value)

    DESCRIPTION
    makes a new image out of the minimum pixels values

    ARGUMENTS
    argument(s)description
    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 an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    the new image object

    SEE ALSO
    `-, `+, `|, `* and Image.Layer

    METHOD
    Image.Image.`==,
    Image.Image.`<,
    Image.Image.`<

    SYNTAX
    int `==(object operand)
    int `==(array(int) color)
    int `==(int value)
    int `<(object operand)
    int `<(array(int) color)
    int `<(int value)
    int `>(object operand)
    int `>(array(int) color)
    int `>(int value)

    DESCRIPTION
    Compares an image with another image or a color.

    Comparision is strict and on pixel-by-pixel basis. (Means if not all pixel r,g,b values are correct compared with the corresponding pixel values, 0 is returned.)

    ARGUMENTS
    argument(s)description
    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 an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    true (1) or false (0).

    NOTE
    `< or `> on empty ("no image") image objects or images with different size will result in an error. `== is always true on two empty image objects and always false if one and only one of the image objects is empty or the images differs in size.

    a>=b and a<=b between objects is equal to !(a<b) and !(a>b), which may not be what you want (since both < and > can return false, comparing the same images).

    SEE ALSO
    `-, `+, `|, `* and `&

    METHOD
    Image.Image.`*

    SYNTAX
    object `*(object operand)
    object `*(array(int) color)
    object `*(int value)

    DESCRIPTION
    Multiplies pixel values and creates a new image.

    This can be useful to lower the values of an image, making it greyer, for instance:

    image=image*128+64;

    ARGUMENTS
    argument(s)description
    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 an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    the new image object

    SEE ALSO
    `-, `+, `|, `& and Image.Layer

    METHOD
    Image.Image.`+

    SYNTAX
    object `+(object operand)
    object `+(array(int) color)
    object `+(int value)

    DESCRIPTION
    adds two images; values are truncated at 255.

    ARGUMENTS
    argument(s)description
    object operand
    the image which to add.
    array(int) color
    an array in format ({r,g,b}), this is equal to using an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    the new image object

    SEE ALSO
    `-, `|, `&, `* and Image.Layer

    METHOD
    Image.Image.`-

    SYNTAX
    object `-(object operand)
    object `-(array(int) color)
    object `-(int value)

    DESCRIPTION
    makes a new image out of the difference

    ARGUMENTS
    argument(s)description
    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 an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    the new image object

    SEE ALSO
    `+, `|, `&, `*, Image.Layer, min, max and `==

    METHOD
    Image.Image.`|

    SYNTAX
    object `|(object operand)
    object `|(array(int) color)
    object `|(int value)

    DESCRIPTION
    makes a new image out of the maximum pixels values

    ARGUMENTS
    argument(s)description
    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 an uniform-colored image.
    int value
    equal to ({value,value,value}).

    RETURNS
    the new image object

    SEE ALSO
    `-, `+, `&, `* and Image.Layer

    12.2 Image.Colortable

    CLASS
    Image.Colortable

    DESCRIPTION
    This object keeps colortable information, mostly for image re-coloring (quantization).

    The object has color reduction, quantisation, mapping and dithering capabilities.

    SEE ALSO
    Image, Image.Image, Image.Font and Image.GIF

    METHOD
    Image.Colortable.create,
    Image.Colortable.add

    SYNTAX
    void create()
    void create(array(array(int)) colors)
    void create(object(Image.Image) image, int number)
    void create(object(Image.Image) image, int number, array(array(int)) needed)
    void create(int r, int g, int b)
    void create(int r, int g, int b,  array(int) from1, array(int) to1, int steps1,  ...,  array(int) fromn, array(int) ton, int stepsn)
    object add(array(array(int)) colors)
    object add(object(Image.Image) image, int number)
    object add(object(Image.Image) image, int number, array(array(int)) needed)
    object add(int r, int g, int b)
    object add(int r, int g, int b,  array(int) from1, array(int) to1, int steps1,  ...,  array(int) fromn, array(int) ton, int stepsn)

    DESCRIPTION
    create initiates a colortable object. Default is that no colors are in the colortable.

    add takes the same argument(s) as create, thus adding colors to the colortable.

    The colortable is mostly a list of colors, or more advanced, colors and weight.

    The colortable could also be a colorcube, with or without additional scales. A colorcube is the by-far fastest way to find colors.

    Example:

    ct=colortable(my_image,256); // the best 256 colors
    ct=colortable(my_image,256,({0,0,0})); // black and the best other 255
    
    

    ct=colortable(({({0,0,0}),({255,255,255})})); // black and white

    ct=colortable(6,7,6); // a colortable of 252 colors ct=colortable(7,7,5, ({0,0,0}),({255,255,255}),11); // a colorcube of 245 colors, and a greyscale of the rest -> 256

    ARGUMENTS
    argument(s)description
    array(array(int)) colors
    list of colors
    object(Image.Image) image
    source image
    int number
    number of colors to get from the image

    0 (zero) gives all colors in the image.

    Default value is 256.

    array(array(int)) needed
    needed colors (to optimize selection of others to these given)

    this will add to the total number of colors (see argument 'number')

    int r
    int g
    int b
    size of sides in the colorcube, must (of course) be equal or larger than 2 - if smaller, the cube is ignored (no colors). This could be used to have only scales (like a greyscale) in the output.
    array(int) fromi
    array(int) toi
    int stepi
    This is to add the possibility of adding a scale of colors to the colorcube; for instance a grayscale using the arguments ({0,0,0}),({255,255,255}),17, adding a scale from black to white in 17 or more steps.

    Colors already in the cube is used again to add the number of steps, if possible.

    The total number of colors in the table is therefore r*b*g+step1+...+stepn.

    NOTE
    max hash size is (probably, set by a #define) 32768 entries, giving maybe half that number of colors as maximum.

    METHOD
    Image.Colortable.cast

    SYNTAX
    object cast(string to)

    DESCRIPTION
    cast the colortable to an array or mapping, the array consists of Image.Color objects and are not in index order. The mapping consists of index:Image.Color pairs, where index is the index (int) of that color.

    example: (mapping)Image.Colortable(img)

    ARGUMENTS
    argument(s)description
    string to
    must be "string", "array" or "mapping".

    METHOD
    Image.Colortable.corners

    SYNTAX
    array(object) corners()

    DESCRIPTION
    Gives the eight corners in rgb colorspace as an array. The "black" and "white" corners are the first two.

    METHOD
    Image.Colortable.cubicles

    SYNTAX
    object cubicles()
    object cubicles(int r, int g, int b)
    object cubicles(int r, int g, int b, int accuracy)

    DESCRIPTION
    Set the colortable to use the cubicles algorithm to lookup the closest color. This is a mostly very fast and very accurate way to find the correct color, and the default algorithm.

    The colorspace is divided in small cubes, each cube containing the colors in that cube. Each cube then gets a list of the colors in the cube, and the closest from the corners and midpoints between corners.

    When a color is needed, the algorithm first finds the correct cube and then compares with all the colors in the list for that cube.

    example: colors=Image.Colortable(img)->cubicles();

    algorithm time: between O[m] and O[m * n], where n is numbers of colors and m is number of pixels

    The arguments can be heavy trimmed for the usage of your colortable; a large number (10×10×10 or bigger) of cubicles is recommended when you use the colortable repeatedly, since the calculation takes much more time than usage.

    recommended values:

    image size  setup
    100×100     cubicles(4,5,4) (default)
    1000×1000   cubicles(12,12,12) (factor 2 faster than default)
    

    In some cases, the full method is faster.

    original default cubicles,
    16 colors
    accuracy=200

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    Size, ie how much the colorspace is divided. Note that the size of each cubicle is at least about 8b, and that it takes time to calculate them. The number of cubicles are r*g*b, and default is 4,5,4, ie 80 cubicles. This works good for 200±100 colors.
    int accuracy
    Accuracy when checking sides of cubicles. Default is 16. A value of 1 gives complete accuracy, ie cubicle() method gives exactly the same result as full(), but takes (in worst case) 16× the time to calculate.

    RETURNS
    the called object

    NOTE
    this method doesn't figure out the cubicles, this is done on the first use of the colortable.

    Not applicable to colorcube types of colortable.

    METHOD
    Image.Colortable.floyd_steinberg

    SYNTAX
    object floyd_steinberg()
    object floyd_steinberg(int bidir, int|float forward, int|float downforward, int|float down, int|float downback, int|float factor)

    DESCRIPTION
    Set dithering method to floyd_steinberg.

    The arguments to this method is for fine-tuning of the algorithm (for computer graphics wizards).

    original floyd_steinberg to a 4×4×4 colorcube floyd_steinberg to 16 chosen colors

    ARGUMENTS
    argument(s)description
    int bidir
    Set algorithm direction of forward. -1 is backward, 1 is forward, 0 for toggle of direction each line (default).
    int|float forward
    int|float downforward
    int|float down
    int|float downback
    Set error correction directions. Default is forward=7, downforward=1, down=5, downback=3.
    int|float factor
    Error keeping factor. Error will increase if more than 1.0 and decrease if less than 1.0. A value of 0.0 will cancel any dither effects. Default is 0.95.

    RETURNS
    the called object

    METHOD
    Image.Colortable.full

    SYNTAX
    object full()

    DESCRIPTION
    Set the colortable to use full scan to lookup the closest color.

    example: colors=Image.Colortable(img)->full();

    algorithm time: O[n*m], where n is numbers of colors and m is number of pixels

    RETURNS
    the called object

    NOTE
    Not applicable to colorcube types of colortable.

    SEE ALSO
    cubicles and map

    METHOD
    Image.Colortable.image

    SYNTAX
    object image()

    DESCRIPTION
    cast the colortable to an image object

    each pixel in the image object is an entry in the colortable

    RETURNS
    the resulting image object

    METHOD
    Image.Colortable.`*,
    Image.Colortable.``*,
    Image.Colortable.map

    SYNTAX
    object map(object image)
    object `*(object image)
    object ``*(object image)
    object map(string data, int xsize, int ysize)
    object `*(string data, int xsize, int ysize)
    object ``*(string data, int xsize, int ysize)

    DESCRIPTION
    Map colors in an image object to the colors in the colortable, and creates a new image with the closest colors.

    no dither
    floyd_steinberg dither
    ordered dither
    randomcube dither
    original 2 4 8 16 32 colors

    RETURNS
    a new image object

    NOTE
    Flat (not cube) colortable and not 'full' method: this method does figure out the data needed for the lookup method, which may take time the first use of the colortable - the second use is quicker.

    SEE ALSO
    cubicles and full

    METHOD
    Image.Colortable.nodither

    SYNTAX
    object nodither()

    DESCRIPTION
    Set no dithering (default).

    RETURNS
    the called object

    METHOD
    Image.Colortable.ordered

    SYNTAX
    object ordered()
    object ordered(int r, int g, int b)
    object ordered(int r, int g, int b, int xsize, int ysize)
    object ordered(int r, int g, int b, int xsize, int ysize, int x, int y)
    object ordered(int r, int g, int b, int xsize, int ysize, int rx, int ry, int gx, int gy, int bx, int by)

    DESCRIPTION
    Set ordered dithering, which gives a position-dependent error added to the pixel values.

    original mapped to
    Image.Colortable(6,6,6)->
    ordered
    (42,42,42,2,2)
    ordered() ordered
    (42,42,42, 8,8,
    0,0, 0,1, 1,0)

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    The maximum error. Default is 32, or colorcube steps (256/size).
    int xsize
    int ysize
    Size of error matrix. Default is 8×8. Only values which factors to multiples of 2 and 3 are possible to choose (2,3,4,6,8,12,...).
    int x
    int y
    int rx
    int ry
    int gx
    int gy
    int bx
    int by
    Offset for the error matrix. x and y is for both red, green and blue values, the other is individual.

    RETURNS
    the called object

    SEE ALSO
    randomcube, nodither, floyd_steinberg and create

    METHOD
    Image.Colortable.randomcube,
    Image.Colortable.randomgrey

    SYNTAX
    object randomcube()
    object randomcube(int r, int g, int b)
    object randomgrey()
    object randomgrey(int err)

    DESCRIPTION
    Set random cube dithering. Color choosen is the closest one to color in picture plus (flat) random error; color±random(error).

    The randomgrey method uses the same random error on red, green and blue and the randomcube method has three random errors.

    original mapped to
    Image.Colortable(4,4,4)->
    randomcube() randomgrey()

    ARGUMENTS
    argument(s)description
    int r
    int g
    int b
    int err
    The maximum error. Default is 32, or colorcube step.

    RETURNS
    the called object

    NOTE
    randomgrey method needs colorcube size to be the same on red, green and blue sides to work properly. It uses the red colorcube value as default.

    SEE ALSO
    ordered, nodither, floyd_steinberg and create

    METHOD
    Image.Colortable.reduce,
    Image.Colortable.reduce_fs

    SYNTAX
    object reduce(int colors)
    object reduce_fs(int colors)

    DESCRIPTION
    reduces the number of colors

    All needed (see create) colors are kept.

    reduce_fs creates and keeps the outmost corners of the color space, to improve floyd-steinberg dithering result. (It doesn't work very well, though.)

    ARGUMENTS
    argument(s)description
    int colors
    target number of colors

    RETURNS
    the new Colortable object

    NOTE
    this algorithm assumes all colors are different to begin with (!)

    reduce_fs keeps the "corners" as "needed colors".

    SEE ALSO
    corners

    METHOD
    Image.Colortable.rigid

    SYNTAX
    object rigid()
    object rigid(int r, int g, int b)

    DESCRIPTION
    Set the colortable to use the "rigid" method of looking up colors.

    This is a very simple way of finding the correct color. The algorithm initializes a cube with r x g x b colors, where every color is chosen by closest match to the corresponding coordinate.

    This format is not recommended for exact match, but may be usable when it comes to quickly view pictures on-screen.

    It has a high init-cost and low use-cost. The structure is initiated at first usage.

    RETURNS
    the called object

    NOTE
    Not applicable to colorcube types of colortable.

    SEE ALSO
    cubicles, map and full

    METHOD
    Image.Colortable.spacefactors

    SYNTAX
    object spacefactors(int r, int g, int b)

    DESCRIPTION
    Colortable tuning option, this sets the color space distance factors. This is used when comparing distances in the colorspace and comparing grey levels.

    Default factors are 3, 4 and 1; blue is much darker than green. Compare with Image.Image->grey().

    RETURNS
    the called object

    NOTE
    This has no sanity check. Some functions may bug if the factors are to high - color reduction functions sums grey levels in the image, this could exceed maxint in the case of high factors. Negative values may also cause strange effects. *grin*

    METHOD
    Image.Colortable.`+

    SYNTAX
    object `+(object with, ...)

    DESCRIPTION
    sums colortables

    ARGUMENTS
    argument(s)description
    object(Colortable) with
    Colortable object with colors to add

    RETURNS
    the resulting new Colortable object

    METHOD
    Image.Colortable.`-

    SYNTAX
    object `-(object with, ...)

    DESCRIPTION
    subtracts colortables

    ARGUMENTS
    argument(s)description
    object(Colortable) with
    Colortable object with colors to subtract

    RETURNS
    the resulting new Colortable object

    12.3 Image.Layer

    CLASS
    Image.Layer

    DESCRIPTION

    SEE ALSO
    layers

    METHOD
    Image.Layer.alpha,
    Image.Layer.image,
    Image.Layer.set_image

    SYNTAX
    object set_image(object(Image.Image) image)
    object set_image(object(Image.Image) image, object(Image.Image) alpha_channel)
    object|int(0) image()
    object|int(0) alpha()

    DESCRIPTION
    Set/change/get image and alpha channel for the layer. You could also cancel the channels giving 0 instead of an image object.

    NOTE
    image and alpha channel must be of the same size, or canceled.

    METHOD
    Image.Layer.alpha_value,
    Image.Layer.set_alpha_value

    SYNTAX
    object set_alpha_value(float value)
    double alpha_value()

    DESCRIPTION
    Set/get the general alpha value of this layer. This is a float value between 0 and 1, and is multiplied with the alpha channel.

    METHOD
    Image.Layer.autocrop,
    Image.Layer.find_autocrop

    SYNTAX
    object autocrop()
    object autocrop(int(0..1) left, int(0..1) right, int(0..1) top, int(0..1) bottom)
    array(int) find_autocrop()
    array(int) find_autocrop(int(0..1) left, int(0..1) right, int(0..1) top, int(0..1) bottom)

    DESCRIPTION
    This crops (of finds) a suitable crop, non-destructive crop. The layer alpha channel is checked, and edges that is transparent is removed.

    (What really happens is that the image and alpha channel is checked, and edges equal the fill setup is cropped away.)

    find_autocrop() returns an array of xoff,yoff,xsize,ysize, which can be fed to crop().

    NOTE
    A tiled image will not be cropped at all.

    left...bottom arguments can be used to tell what sides cropping are ok on.

    SEE ALSO
    crop and Image.Image->autocrop

    METHOD
    Image.Layer.mode,
    Image.Layer.set_mode,
    Image.Layer.available_modes

    SYNTAX
    object set_mode(string mode)
    string mode()
    array(string) available_modes()

    DESCRIPTION
    Set/get layer mode. Mode is one of these:

    "normal", "add", "subtract", "multiply", "divide", "modulo", "invsubtract", "invdivide", "invmodulo", "difference", "max", "min", "bitwise_and", "bitwise_or", "bitwise_xor",

    "replace", "red", "green", "blue",

    "replace_hsv", "hue", "saturation", "value", "color",

    "darken", "lighten",

    "dissolve", "behind", "erase",

    available_modes() simply gives an array containing the names of these modes.

    NOTE
    image and alpha channel must be of the same size, or canceled.

    METHOD
    Image.Layer.clone

    SYNTAX
    object clone()

    DESCRIPTION
    Creates a copy of the called object.

    RETURNS
    the copy

    METHOD
    Image.Layer.create

    SYNTAX
    void create(object image, object alpha, string mode)
    void create(mapping info)
    void create()
    void create(int xsize, int ysize, object color)
    void create(object color)

    DESCRIPTION
    The Layer construct either three arguments, the image object, alpha channel and mode, or a mapping with optional elements:
    "image":image,
    // default: black
    
    

    "alpha":alpha, // alpha channel object // default: full opaque

    "mode":string mode, // layer mode, see mode. // default: "normal"

    "alpha_value":float(0.0-1.0), // layer general alpha value // default is 1.0; this is multiplied // with the alpha channel.

    "xoffset":int, "yoffset":int, // offset of this layer

    "fill":Color, "fill_alpha":Color, // fill color, ie what color is used // "outside" the image. default: black // and black (full transparency).

    "tiled":int(0|1), // select tiling; if 1, the image // will be tiled. deafult: 0, off

    The layer can also be created "empty", either giving a size and color - this will give a filled opaque square, or a color, which will set the "fill" values and fill the whole layer with an opaque color.

    All values can be modified after object creation.

    NOTE
    image and alpha channel must be of the same size.

    METHOD
    Image.Layer.crop

    SYNTAX
    object crop(int xoff, int yoff, int xsize, int ysize)

    DESCRIPTION
    Crops this layer at this offset and size. Offset is not relative the layer offset, so this can be used to crop a number of layers simuntaneously.

    The fill values are used if the layer is enlarged.

    RETURNS
    a new layer object

    NOTE
    The new layer object may have the same image object, if there was no cropping to be done.

    METHOD
    Image.Layer.fill,
    Image.Layer.fill_alpha,
    Image.Layer.set_fill

    SYNTAX
    object set_fill(Color color)
    object set_fill(Color color, Color alpha)
    object fill()
    object fill_alpha()

    DESCRIPTION
    Set/query fill color and alpha, ie the color used "outside" the image. This is mostly useful if you want to "frame" a layer.

    METHOD
    Image.Layer.set_misc_value,
    Image.Layer.get_misc_value

    SYNTAX
    mixed set_misc_value( mixed what,  mixed to )
    mixed get_misc_value( mixed what )

    DESCRIPTION
    Set or query misc. attributes for the layer.

    As an example, the XCF and PSD image decoders set the 'name' attribute to the name the layer had in the source file.

    METHOD
    Image.Layer.xoffset,
    Image.Layer.yoffset,
    Image.Layer.set_offset

    SYNTAX
    object set_offset(int x, int y)
    int xoffset()
    int yoffset()

    DESCRIPTION
    Set/query layer offset.

    METHOD
    Image.Layer.tiled,
    Image.Layer.set_tiled

    SYNTAX
    object set_tiled(int yes)
    int tiled()

    DESCRIPTION
    Set/query tiled flag. If set, the image and alpha channel will be tiled rather then framed by the fill values.

    METHOD
    Image.Layer.ysize,
    Image.Layer.xsize

    SYNTAX
    int xsize()
    int ysize()

    DESCRIPTION
    Query layer offset. This is the same as layer image/alpha image size.

    12.4 Image.Font

    CLASS
    Image.Font

    DESCRIPTION

    NOTE
    Short technical documentation on a font file: This object adds the text-drawing and -creation capabilities of the Image module.

    For simple usage, see write and load.

    other methods: baseline, height, set_xspacing_scale, set_yspacing_scale, text_extents

    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;
    
    

    version 2:

    On-disk syntax (everything in N.B.O), int is 4 bytes, a byte is 8 bits:

    pos 0 int cookie = 'FONT'; or 0x464f4e54 4 int version = 2; 1 was the old version without the last four chars 8 int numchars; Always 256 in this version of the dump program 12 int height; in (whole) pixels 16 int baseline; in (whole) pixels 20 char direction; 1==right to left, 0 is left to right 21 char format; Font format 22 char colortablep; Colortable format 23 char kerningtablep; Kerning table format

    24 int offsets[numchars]; pointers into the data, realative to &cookie. [colortable] [kerningtable]

    At each offset:

    0 int width; in pixels 4 int spacing; in 1/1000:th of a pixels 8 char data[]; Enough data to plot width * font->height pixels Please note that if width is 0, there is no data.

    Font formats: id type 0 Raw 8bit data 1 RLE encoded data, char length, char data, 70% more compact than raw data 2 ZLib compressed data 60% more compact than RLE

    Colortable types: 0 No colortable (the data is an alpha channel) 1 24bit RGB with alpha (index->color, 256*4 bytes, rgba) 2 8bit Greyscale with alpha (index->color, 256*2 bytes)

    Kerningtable types: 0 No kerning table 1 numchars*numchars entries, each a signed char with the kerning value 2 numchar entries, each with a list of kerning pairs, like this: int len len * (short char, short value) **!

    SEE ALSO
    Image and Image.Image

    METHOD
    Image.Font.baseline

    SYNTAX
    int baseline()

    RETURNS
    font baseline (pixels from top)

    SEE ALSO
    height and text_extents

    METHOD
    Image.Font.create

    SYNTAX
    void create(string filename)

    DESCRIPTION
    Loads a font file to this font object. Similar to load().

    METHOD
    Image.Font.height,
    Image.Font.text_extents

    SYNTAX
    int height()
    array(int) text_extents(string text, ...)

    DESCRIPTION
    Calculate extents of a text-image, that would be created by calling write with the same arguments.

    ARGUMENTS
    argument(s)description
    string text, ...
    One or more lines of text.

    RETURNS
    an array of width and height

    SEE ALSO
    write, height and baseline

    METHOD
    Image.Font.load

    SYNTAX
    object|int load(string filename)

    DESCRIPTION
    Loads a font file to this font object.

    ARGUMENTS
    argument(s)description
    string filename
    Font file

    RETURNS
    zero upon failure, font object upon success

    SEE ALSO
    write

    METHOD
    Image.Font.set_xspacing_scale,
    Image.Font.set_yspacing_scale

    SYNTAX
    void set_xspacing_scale(float scale)
    void set_yspacing_scale(float scale)

    DESCRIPTION
    Set spacing scale to write characters closer or more far away. This does not change scale of character, only the space between them.

    ARGUMENTS
    argument(s)description
    float scale
    what scale to use

    METHOD
    Image.Font.write

    SYNTAX
    object write(string text, ...)

    DESCRIPTION
    Writes some text; thus creating an image object that can be used as mask or as a complete picture.

    ARGUMENTS
    argument(s)description
    string text, ...
    One or more lines of text.

    RETURNS
    an Image.Image object

    SEE ALSO
    text_extents, load, Image.Image->paste_mask and Image.Image->paste_alpha_color

    12.5 Image.colortable

    CLASS
    Image.colortable

    12.6 Image.Poly

    CLASS
    Image.Poly

    DESCRIPTION

    12.7 Image.Color

    DESCRIPTION
    This module keeps names and easy handling for easy color support. It gives you an easy way to get colors from names.

    A color is here an object, containing color information and methods for conversion, see below.

    Image.Color can be called to make a color object. Image.Color() takes the following arguments:

    Image.Color(string name)          // "red"
    Image.Color(string prefix_string) // "lightblue"
    Image.Color(string hex_name)      // "#ff00ff"
    Image.Color(string cmyk_string)   // "%17,42,0,19.4"
    Image.Color(string hsv_string)    // "%@327,90,32"
    Image.Color(int red, int green, int blue)
    

    The color names available can be listed by using indices on Image.Color. The colors are available by name directly as Image.Color.name, too:

    ...Image.Color.red...
    ...Image.Color.green...
    or, maybe
    import Image.Color;
    ...red...
    ...green...
    ...lightgreen...
    

    Giving red, green and blue values is equal to calling Image.Color.rgb().

    The prefix_string method is a form for getting modified colors, it understands all modifiers (light, dark, bright, dull and neon). Simply use "method"+"color"; (as in lightgreen, dullmagenta, lightdullorange).

    The hex_name form is a simple #rrggbb form, as in HTML or X-program argument. A shorter form (#rgb) is also accepted. This is the inverse to the Image.Color.Color->hex() method.

    The cmyk_string is a string form of giving cmyk (cyan, magenta, yellow, black) color. These values are floats representing percent.

    The hsv_string is another hue, saturation, value representation, but in floats; hue is in degree range (0..360), and saturation and value is given in percent. This is not the same as returned or given to the hsv() methods!

    NOTE
    Image.Color["something"] will never(!) generate an error, but a zero_type 0, if the color is unknown. This is enough to give the error "not present in module", if used as Image.Color.something, though.

    If you are using colors from for instance a webpage, you might want to create the color from Image.Color.guess(), since that method is more tolerant for mistakes and errors.

    Image.Color() is case- and space-sensitive. Use Image.Color.guess() to catch all variants.

    and subtract with a space (lower_case(x)-" ") to make sure you get all variants.

    SEE ALSO
    Image.Color.Color, Image.Color.guess, Image and Image.Colortable

    METHOD
    Image.Color.greylevel,
    Image.Color.hsv,
    Image.Color.rgb,
    Image.Color.html,
    Image.Color.cmyk

    SYNTAX
    object rgb(int red,  int green,  int blue)
    object hsv(int hue,  int saturation,  int value)
    object cmyk(float c, float m, float y, float k)
    object greylevel(int level)
    object html(string html_color)

    DESCRIPTION
    Creates a new color object from given red, green and blue, hue, saturation and value, or greylevel, in color value range. It could also be created from cmyk values in percent.

    The html() method only understands the HTML color names, or the #rrggbb form. It is case insensitive.

    RETURNS
    the created object.

    METHOD
    Image.Color.guess

    SYNTAX
    object guess(string)

    DESCRIPTION
    This is equivalent to Image.Color(lower_case(str)-" "), and tries the color with a prepending '#' if no corresponding color is found.

    RETURNS
    a color object or zero_type

    METHOD
    Image.Color._indices,
    Image.Color._values

    SYNTAX
    array(string) _indices()
    array(object) _values()

    DESCRIPTION
    (ie as indices(Image.Color) or values(Image.Color)) indices gives a list of all the known color names, values gives there corresponding objects.

    SEE ALSO
    Image.Color

    12.7.1 Image.Color.Color

    CLASS
    Image.Color.Color

    DESCRIPTION
    This is the color object. It has six readable variables, r, g, b, for the red, green and blue values, and h, s, v, for the hue, saturation anv value values.

    METHOD
    Image.Color.Color.neon,
    Image.Color.Color.dull,
    Image.Color.Color.dark,
    Image.Color.Color.light,
    Image.Color.Color.bright

    SYNTAX
    object light()
    object dark()
    object neon()
    object bright()
    object dull()

    DESCRIPTION
    Color modification methods. These returns a new color.

    methodeffect hsvas
    light raise light level±0 ±0+50
    dark lower light level±0 ±0-50
    brightbrighter color ±0+50+50
    dull greyer color ±0-50-50
    neon set to extreme ±0maxmax

    light and dark lower/highers saturation when value is min-/maximised respective.

    RETURNS
    the new color object

    NOTE
    The opposites may not always take each other out. The color is maximised at white and black levels, so, for instance Image.Color.white->light()->dark() doesn't give the white color back, but the equal to Image.Color.white->dark(), since white can't get any lighter.

    METHOD
    Image.Color.Color.cast

    SYNTAX
    array|string cast()

    DESCRIPTION
    cast the object to an array, representing red, green and blue (equal to ->rgb()), or to a string, giving the name (equal to ->name()).

    RETURNS
    the name as string or rgb as array

    SEE ALSO
    rgb and name

    METHOD
    Image.Color.Color.greylevel,
    Image.Color.Color.hsv,
    Image.Color.Color.rgb,
    Image.Color.Color.cmyk

    SYNTAX
    array(int) rgb()
    array(int) hsv()
    array(int) cmyk()
    int greylevel()
    int greylevel(int r,  int g,  int b)

    DESCRIPTION
    This is methods of getting information from an Image.Color.Color object.

    They give an array of red, green and blue (rgb) values (color value),
    hue, saturation and value (hsv) values (range as color value),
    cyan, magenta, yellow, black (cmyk) values (in percent)
    or the greylevel value (range as color value).

    The greylevel is calculated by weighting red, green and blue. Default weights are 87, 127 and 41, respective, and could be given by argument.

    RETURNS
    array(int) respective int

    SEE ALSO
    Image.Color.Color and grey

    METHOD
    Image.Color.Color.create

    SYNTAX
    void create(int r, int g, int b)

    DESCRIPTION
    This is the main Image.Color.Color creation method, mostly for internal use.

    METHOD
    Image.Color.Color.grey

    SYNTAX
    object grey()
    object grey(int red, int green, int blue)

    DESCRIPTION
    Gives a new color, containing a grey color, which is calculated by the greylevel method.

    RETURNS
    a new Image.Color.Color object

    SEE ALSO
    greylevel

    METHOD
    Image.Color.Color.name,
    Image.Color.Color.hex,
    Image.Color.Color.html

    SYNTAX
    string hex()
    string hex(int n)
    string name()
    string html()

    DESCRIPTION
    Information methods.

    hex() simply gives a string on the #rrggbb format. If n is given, the number of significant digits is set to this number. (Ie, n=3 gives #rrrgggbbb.)

    name() is a simplified method; if the color exists in the database, the name is returned, per default is the hex() method use.

    html() gives the HTML name of the color, or the hex(2) if it isn't one of the 16 HTML colors.

    RETURNS
    a new Image.Color.Color object

    SEE ALSO
    rgb, hsv and Image.Color

    METHOD
    Image.Color.Color.s,
    Image.Color.Color.

    SYNTAX
    _sprintf(string s,  mapping flags)

    DESCRIPTION

    METHOD
    Image.Color.Color.`==

    SYNTAX
    int `==(object other_color)
    int `==(array(int) rgb)
    int `==(int greylevel)
    int `==(string name)

    DESCRIPTION
    Compares this object to another color, or color name. Example:
    object red=Image.Color.red;
    object other=Image.Color. ...;
    object black=Image.Color.black;
    
    

    if (red==other) ... if (red==({255,0,0})) ... if (black==0) ... if (red=="red") ...

    RETURNS
    1 or 0

    NOTE
    The other datatype (not color object) must be to the right!

    SEE ALSO
    rgb, grey and name

    12.8 Image.X

    DESCRIPTION
    This submodule handles encoding and decoding of the binary formats of X11.

    SEE ALSO
    Image, Image.Image and Image.Colortable

    METHOD
    Image.X.decode_pseudocolor

    SYNTAX
    object decode_pseudocolor(string data, int width, int height, int bpp, int alignbits, int swapbytes, object colortable)

    DESCRIPTION
    lazy support for pseudocolor ZPixmaps

    NOTE
    currently, only byte-aligned pixmaps are supported

    METHOD
    Image.X.decode_truecolor_masks,
    Image.X.decode_truecolor

    SYNTAX
    object decode_truecolor(string data, int width, int height, int bpp, int alignbits, int swapbytes, int rbits, int rshift, int gbits, int gshift, int bbits, int bshift)
    object decode_truecolor_masks(string data, int width, int height, int bpp, int alignbits, int swapbytes, int rmask, int gmask, int bmask)

    DESCRIPTION
    lazy support for truecolor ZPixmaps

    NOTE
    currently, only byte-aligned masks are supported

    METHOD
    Image.X.encode_pseudocolor

    SYNTAX
    string encode_pseudocolor(object image, int bpp, int alignbits, int vbpp, object colortable)
    string encode_pseudocolor(object image, int bpp, int alignbits, int vbpp, object colortable, string translate)

    DESCRIPTION

    ARGUMENTS
    argument(s)description
    object image
    the image object to encode
    int bpp
    bits per pixel, how many bits each pixel should take
    int vbpp
    value bits per pixel; how many bits per pixel that really contains information
    int alignbits
    the number of even bits each line should be padded to
    object colortable
    colortable to get indices for pseudocolor
    string translate
    translate table for colors. Length of this string should be 1<<vbpp (or 2<<vbpp if vbpp are greater than 8).

    NOTE
    currently, only upto 16 bits pseudocolor are supported.

    METHOD
    Image.X.encode_truecolor,
    Image.X.encode_truecolor_masks

    SYNTAX
    string encode_truecolor(object image, int bpp, int alignbits, int swapbytes, int rbits, int rshift, int gbits, int gshift, int bbits, int bshift)
    string encode_truecolor_masks(object image, int bpp, int alignbits, int swapbytes, int rmask, int gmask, int bmask)
    string encode_truecolor(object image, int bpp, int alignbits, int swapbytes, int rbits, int rshift, int gbits, int gshift, int bbits, int bshift, object ct)
    string encode_truecolor_masks(object image, int bpp, int alignbits, int swapbytes, int rmask, int gmask, int bmask, object ct)

    DESCRIPTION
    Pack an image into a truecolor string. You will get a string of packed red, green and blue bits; ie:

    encode_truecolor(img, 12,32, 0, 3,5, 4,0, 3,8) will give (aligned to even 32 bits for each row):
    0bbbrrr0 gggg0bbb rrr0gggg 0bbb...
    <--pixel 1--><--pixel 2--> <--3-->
    10987654 32101098 76543210 1098... <- bit position <-><-> <--> | | +--- 4,0: 4 bits green shifted 0 bits | +-------- 3,5: 3 bits red shifted 5 bits +----------- 3,8: 3 bits blue shifted 8 bits

    The above call is equal to
    encode_truecolor_masks(img, 12,32, 0, 224, 15, 768) and
    encode_truecolor(img, 12,32, 0, 3,5,4,0,3,8, colortable(1<<3,1<<4,1<<3)).
    The latter gives possibility to use dither algorithms, but is slightly slower.

    ARGUMENTS
    argument(s)description
    object image
    the image object to encode
    int bpp
    bits per pixel, how many bits each pixel should take
    int alignbits
    the number of even bits each line should be padded to
    int rbits
    int gbits
    int bbits
    bits for each basecolor
    int rshift
    int gshift
    int bshift
    leftshifts for each basecolor
    int rmask
    int gmask
    int bmask
    masks for each basecolor (xbits and gbits are calculated from this), needs to be massive (no zeroes among the ones in the mask).
    object ct
    colortable object (for dithering, or whatever)
    int swapbytes
    swap bytes for bpp==16,24,32, swaps bits in the bytes if bpp==1, for change of byte/bitorder between client and server.

    12.9 Image.ANY

    DESCRIPTION
    This method calls the other decoding methods and has some heuristics for what type of image this is.

    Methods: decode, decode_alpha, _decode

    SEE ALSO
    Image

    METHOD
    Image.ANY._decode,
    Image.ANY.decode,
    Image.ANY.decode_alpha

    SYNTAX
    mapping _decode(string data)
    object decode(string data)
    object decode_alpha(string data)

    DESCRIPTION
    Tries heuristics to find the correct method of decoding the data, then calls that method.

    The result of _decode() is a mapping that contains

    "type":image data type (ie, "image/jpeg" or similar)
    "image":the image object,
    "alpha":the alpha channel or 0 if N/A
    

    NOTE
    Throws upon failure.

    12.10 Image.AVS

    DESCRIPTION

    METHOD
    Image.AVS._decode,
    Image.AVS.encode,
    Image.AVS.decode

    SYNTAX
    object decode(string data)
    mapping _decode(string data)
    string encode(object image)

    DESCRIPTION
    Handle encoding and decoding of AVS-X images. AVS is rather trivial, and not really useful, but:

    An AVS file is a raw (uncompressed) 24 bit image file with alpha. The alpha channel is 8 bit, and there is no separate alpha for r, g and b.

    12.11 Image.BMP

    DESCRIPTION
    This submodule keeps the BMP (Windows Bitmap) encode/decode capabilities of the Image module.

    BMP is common in the Windows environment.

    Simple encoding:
    encode

    SEE ALSO
    Image, Image.Image and Image.Colortable

    METHOD
    Image.BMP._decode,
    Image.BMP.decode,
    Image.BMP.decode_header

    SYNTAX
    object decode(string data)
    mapping _decode(string data)
    mapping decode_header(string data)
    object decode(string data, mapping options)
    mapping _decode(string data, mapping options)
    mapping decode_header(string data, mapping options)

    DESCRIPTION
    Decode a BMP.

    decode gives an image object, _decode gives a mapping in the format

    "type":"image/bmp",
    "image":image object,
    "colortable":colortable object (if applicable)
    
    

    "xsize":int, "ysize":int, "compression":int, "bpp":int, "windows":int,

    RETURNS
    the encoded image as a string

    BUGS
    Doesn't support all BMP modes. At all.

    SEE ALSO
    encode

    METHOD
    Image.BMP.encode

    SYNTAX
    string encode(object image)
    string encode(object image, mapping options)
    string encode(object image, object colortable)
    string encode(object image, int bpp)

    DESCRIPTION
    Make a BMP. It default to a 24 bpp BMP file, but if a colortable is given, it will be 8bpp with a palette entry.

    option is a mapping that may contain:

    "colortable": Image.Colortable   - palette
    "bpp":        1|4|8|24           - force this many bits per pixel
    "rle":        0|1                - run-length encode (default is 0)
    
    

    ARGUMENTS
    argument(s)description
    object image
    Source image.
    object colortable
    Colortable object, shortcut for "colortable" in options.

    RETURNS
    the encoded image as a string

    BUGS
    Doesn't support old BMP mode, only "windows" mode.

    SEE ALSO
    decode

    12.12 Image.GD

    DESCRIPTION
    Handle encoding and decoding of GD images.

    GD is the internal format of libgd by Thomas Boutell, http://www.boutell.com/gd/ It is a rather simple, uncompressed, palette format.

    METHOD
    Image.GD._decode,
    Image.GD.decode,
    Image.GD.decode_alpha,
    Image.GD.decode_header

    SYNTAX
    object decode(string data)
    object decode_alpha(string data)
    mapping decode_header(string data)
    mapping _decode(string data)

    DESCRIPTION
    decodes a GD image

    The decode_header and _decode has these elements:

    "image":object            - image object    \
    "alpha":object            - decoded alpha   |- not decode_header
    "colortable":object       - decoded palette /
    
    

    "type":"image/x-gd" - image type "xsize":int - horisontal size in pixels "ysize":int - vertical size in pixels "alpha_index":int - index to transparancy in palette -1 means no transparency "colors":int - numbers of colors

    METHOD
    Image.GD.encode

    SYNTAX
    string encode(object image)
    string encode(object image, mapping options)

    DESCRIPTION
    encode a GD image

    options is a mapping with optional values:

    "colortable":object       - palette to use (max 256 colors)
    "alpha":object            - alpha channel (truncated to 1 bit)
    "alpha_index":int         - index to transparancy in palette
    

    12.13 Image.GIF

    DESCRIPTION
    This submodule keep the GIF encode/decode capabilities of the Image module.

    GIF is a common image storage format, usable for a limited color palette - a GIF image can only contain as most 256 colors - and animations.

    Simple encoding: encode, encode_trans

    Advanced stuff: render_block, header_block, end_block, netscape_loop_block

    Very advanced stuff: _render_block, _gce_block

    SEE ALSO
    Image, Image.Image and Image.Colortable

    METHOD
    Image.GIF.decode

    SYNTAX
    object decode(string data)
    object decode(array _decoded)
    object decode(array __decoded)

    DESCRIPTION
    Decodes GIF data and creates an image object.

    RETURNS
    the decoded image as an image object

    NOTE
    This function may throw errors upon illegal GIF data. This function uses __decode, _decode, Image.Image->paste and Image.Image->paste_alpha internally.

    SEE ALSO
    encode

    METHOD
    Image.GIF.decode_layers,
    Image.GIF.decode_layer

    SYNTAX
    object decode_layers(string data)
    object decode_layers(array _decoded)
    object decode_layer(string data)
    object decode_layer(array _decoded)

    DESCRIPTION
    Decodes GIF data and creates an array of layers or the resulting layer.

    NOTE
    The resulting layer may not have the same size as the gif image, but the resulting bounding box of all render chunks in the gif file. The offset should be correct, though.

    SEE ALSO
    encode and decode_map

    METHOD
    Image.GIF.decode_map

    SYNTAX
    mapping decode_map(INT32 args)

    DESCRIPTION
    Returns a mapping similar to other decoders _decode function.

    "image":the image
    "alpha":the alpha channel
    
    

    "xsize":int "ysize":int size of image "type":"image/gif" file type information as MIME type

    NOTE
    The wierd name of this function (not _decode as the other decoders) is because gif was the first decoder and was written before the API was finally defined. Sorry about that. /Mirar

    METHOD
    Image.GIF.encode,
    Image.GIF.encode_trans

    SYNTAX
    string encode(object img);
    string encode(object img, int colors);
    string encode(object img, object colortable);
    string encode_trans(object img, object alpha);
    string encode_trans(object img, int tr_r, int tr_g, int tr_b);
    string encode_trans(object img, int colors, object alpha);
    string encode_trans(object img, int colors, int tr_r, int tr_g, int tr_b);
    string encode_trans(object img, int colors, object alpha, int tr_r, int tr_g, int tr_b);
    string encode_trans(object img, object colortable, object alpha);
    string encode_trans(object img, object colortable, int tr_r, int tr_g, int tr_b);
    string encode_trans(object img, object colortable, object alpha, int a_r, int a_g, int a_b);
    string encode_trans(object img, object colortable, int transp_index);

    DESCRIPTION
    Create a complete GIF file.

    The latter (encode_trans) functions add transparency capabilities.

    Example:

    img=Image.Image([...]);
    [...] // make your very-nice image
    write(Image.GIF.encode(img)); // write it as GIF on stdout
    

    ARGUMENTS
    argument(s)description
    object img
    The image which to encode.
    int colors
    object colortable
    These arguments decides what colors the image should be encoded with. If a number is given, a colortable with be created with (at most) that amount of colors. Default is '256' (GIF maximum amount of colors).
    object alpha
    Alpha channel image (defining what is transparent); black color indicates transparency. GIF has only transparent or nontransparent (no real alpha channel). You can always dither a transparency channel: Image.Colortable(my_alpha, ({({0,0,0}),({255,255,255})})) ->full()->floyd_steinberg()->map(my_alpha)
    int tr_r
    int tr_g
    int tr_b
    Use this (or the color closest to this) color as transparent pixels.
    int a_r
    int a_g
    int a_b
    Encode transparent pixels (given by alpha channel image) to have this color. This option is for making GIFs for the decoders that doesn't support transparency.
    int transp_index
    Use this color no in the colortable as transparent color.

    NOTE
    For advanced users:
    Image.GIF.encode_trans(img,colortable,alpha);
    is equivalent of using
    Image.GIF.header_block(img->xsize(),img->ysize(),colortable)+
    Image.GIF.render_block(img,colortable,0,0,0,alpha)+
    Image.GIF.end_block();
    and is actually implemented that way.

    METHOD
    Image.GIF.end_block

    SYNTAX
    string end_block();

    DESCRIPTION
    This function gives back a GIF end (trailer) block.

    RETURNS
    the end block as a string.

    NOTE
    This is in the advanced sector of the GIF support; please read some about how GIFs are packed.

    The result of this function is always ";" or "\x3b", but I recommend using this function anyway for code clearity.

    SEE ALSO
    header_block and end_block

    METHOD
    Image.GIF.header_block

    SYNTAX
    string header_block(int xsize, int ysize, int numcolors);
    string header_block(int xsize, int ysize, object colortable);
    string header_block(int xsize, int ysize, object colortable, int background_color_index, int gif87a, int aspectx, int aspecty);
    string header_block(int xsize, int ysize, object colortable, int background_color_index, int gif87a, int aspectx, int aspecty, int r, int g, int b);

    DESCRIPTION
    This function gives back a GIF header block.

    Giving a colortable to this function includes a global palette in the header block.

    ARGUMENTS
    argument(s)description
    int xsize
    int ysize
    Size of drawing area. Usually same size as in the first (or only) render block(s).
    int background_color_index
    This color in the palette is the background color. Background is visible if the following render block(s) doesn't fill the drawing area or are transparent. Most decoders doesn't use this value, though.
    int gif87a
    If set, write 'GIF87a' instead of 'GIF89a' (default 0 == 89a).
    int aspectx
    int aspecty
    Aspect ratio of pixels, ranging from 4:1 to 1:4 in increments of 1/16th. Ignored by most decoders. If any of aspectx or aspecty is zero, aspectratio information is skipped.
    int r
    int g
    int b
    Add this color as the transparent color. This is the color used as transparency color in case of alpha-channel given as image object. This increases (!) the number of colors by one.

    RETURNS
    the created header block as a string

    NOTE
    This is in the advanced sector of the GIF support; please read some about how GIFs are packed.

    This GIF encoder doesn't support different size of colors in global palette and color resolution.

    SEE ALSO
    header_block and end_block

    METHOD
    Image.GIF.netscape_loop_block

    SYNTAX
    string netscape_loop_block();
    string netscape_loop_block(int number_of_loops);

    DESCRIPTION
    Creates a application-specific extention block; this block makes netscape and compatible browsers loop the animation a certain amount of times.

    ARGUMENTS
    argument(s)description
    int number_of_loops
    Number of loops. Max and default is 65535.

    METHOD
    Image.GIF.render_block

    SYNTAX
    string render_block(object img, object colortable, int x, int y, int localpalette);
    string render_block(object img, object colortable, int x, int y, int localpalette, object alpha);
    string render_block(object img, object colortable, int x, int y, int localpalette, object alpha, int r, int g, int b);
    string render_block(object img, object colortable, int x, int y, int localpalette, int delay, int transp_index, int interlace, int user_input, int disposal);
    string render_block(object img, object colortable, int x, int y, int localpalette, object alpha, int r, int g, int b, int delay, int interlace, int user_input, int disposal);

    DESCRIPTION
    This function gives a image block for placement in a GIF file, with or without transparency. The some options actually gives two blocks, the first with graphic control extensions for such things as delay or transparency.

    Example:

    img1=Image.Image([...]);
    img2=Image.Image([...]);
    [...] // make your very-nice images
    nct=Image.Colortable([...]); // make a nice colortable
    write(Image.GIF.header_block(xsize,ysize,nct)); // write a GIF header
    write(Image.GIF.render_block(img1,nct,0,0,0,10)); // write a render block
    write(Image.GIF.render_block(img2,nct,0,0,0,10)); // write a render block
    [...]
    write(Image.GIF.end_block()); // write end block
    // voila! A GIF animation on stdout.
    

    The above animation is thus created:

    object nct=colortable(lena,32,({({0,0,0})}));
    string s=GIF.header_block(lena->xsize(),lena->ysize(),nct);
    foreach ( ({lena->xsize(),
    (int)(lena->xsize()*0.75),
    (int)(lena->xsize()*0.5),
    (int)(lena->xsize()*0.25),
    (int)(1),
    (int)(lena->xsize()*0.25),
    (int)(lena->xsize()*0.5),
    (int)(lena->xsize()*0.75)}),int xsize)
    {
    object o=lena->scale(xsize,lena->ysize());
    object p=lena->clear(0,0,0);
    p->paste(o,(lena->xsize()-o->xsize())/2,0);
    s+=GIF.render_block(p,nct,0,0,0,25);
    }
    s+=GIF.netscape_loop_block(200);
    s+=GIF.end_block();
    write(s);
    

    ARGUMENTS
    argument(s)description
    object img
    The image.
    object colortable
    Colortable with colors to use and to write as palette.
    int x
    int y
    Position of this image.
    int localpalette
    If set, writes a local palette.
    object alpha
    Alpha channel image; black is transparent.
    int r
    int g
    int b
    Color of transparent pixels. Not all decoders understands transparency. This is ignored if localpalette isn't set.
    int delay
    View this image for this many centiseconds. Default is zero.
    int transp_index
    Index of the transparent color in the colortable. -1 indicates no transparency.
    int user_input
    If set: wait the delay or until user input. If delay is zero, wait indefinitely for user input. May sound the bell upon decoding. Default is non-set.
    int disposal
    Disposal method number;
    0
    No disposal specified. The decoder is not required to take any action. (default)
    1
    Do not dispose. The graphic is to be left in place.
    2
    Restore to background color. The area used by the graphic must be restored to the background color.
    3
    Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic.
    4-7
    To be defined.

    NOTE
    This is in the advanced sector of the GIF support; please read some about how GIFs are packed.

    The user_input and disposal method are unsupported in most decoders.

    SEE ALSO
    encode, header_block and end_block

    METHOD
    Image.GIF._decode

    SYNTAX
    array _decode(string gifdata);
    array _decode(array __decoded);

    DESCRIPTION
    Decodes a GIF image structure down to chunks, and also decode the images in the render chunks.

    ({int xsize,int ysize,    // 0: size of image drawing area
    void|object colortable, // 2: opt. global colortable
    ({ int aspx, int aspy,  // 3 0: aspect ratio or 0, 0 if not set
    int background }),   //   2: index of background color
    
    followed by any number these blocks in any order (gce chunks are decoded and incorporated in the render chunks):
    ({ GIF.RENDER,          //   0: block identifier
    int x, int y,         //   1: position of render
    object image,         //   3: render image
    void|object alpha,    //   4: 0 or render alpha channel
    object colortable,    //   5: colortable (may be same as global)
    
    

    int interlace, // 6: interlace flag int trans_index, // 7: 0 or transparent color index int delay, // 8: 0 or delay in centiseconds int user_input, // 9: user input flag int disposal}) // 10: disposal method number (0..7)

    ({ GIF.EXTENSION, // 0: block identifier int extension, // 1: extension number string data }) // 2: extension data

    and possibly ended with one of these:
    ({ GIF.ERROR_PREMATURE_EOD })   // premature end-of-data
    
    

    ({ GIF.ERROR_TOO_MUCH_DATA, // data following end marker string data }) // (rest of file)

    ({ GIF.ERROR_UNKNOWN_DATA, // unknown data string data }) // (rest of file)

    The decode method uses this data in a way similar to this program:

    import Image;
    
    

    object my_decode_gif(string data) { array a=GIF._decode(data); object img=image(a[0],a[1]); foreach (a[4..],array b) if (b[0]==GIF.RENDER) if (b[4]) img->paste_alpha(b[3],b[4],b[1],b[2]); else img->paste(b[3],b[1],b[2]); return img; }

    ARGUMENTS
    argument(s)description
    string gifdata
    GIF data (with header and all)
    array __decoded
    GIF data as from __decode

    RETURNS
    the above array

    NOTE
    May throw errors if the GIF header is incomplete or illegal.

    This is in the very advanced sector of the GIF support; please read about how GIF files works.

    METHOD
    Image.GIF._encode

    SYNTAX
    string _encode(array data)

    DESCRIPTION
    Encodes GIF data; reverses _decode.

    ARGUMENTS
    argument(s)description
    array data
    data as returned from _encode

    NOTE
    Some given values in the array are ignored. This function does not give the _exact_ data back!

    METHOD
    Image.GIF._gce_block

    SYNTAX
    string _gce_block(int transparency, int transparency_index, int delay, int user_input, int disposal);

    DESCRIPTION
    This function gives back a Graphic Control Extension block. A GCE block has the scope of the following render block.

    ARGUMENTS
    argument(s)description
    int transparency
    int transparency_index
    The following image has transparency, marked with this index.
    int delay
    View the following rendering for this many centiseconds (0..65535).
    int user_input
    Wait the delay or until user input. If delay is zero, wait indefinitely for user input. May sound the bell upon decoding.
    int disposal
    Disposal method number;
    0
    No disposal specified. The decoder is not required to take any action.
    1
    Do not dispose. The graphic is to be left in place.
    2
    Restore to background color. The area used by the graphic must be restored to the background color.
    3
    Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic.
    4-7
    To be defined.

    NOTE
    This is in the very advanced sector of the GIF support; please read about how GIF files works.

    Most decoders just ignore some or all of these parameters.

    SEE ALSO
    _render_block and render_block

    METHOD
    Image.GIF._render_block

    SYNTAX
    string _render_block(int x, int y, int xsize, int ysize, int bpp, string indices, 0|string colortable, int interlace);

    DESCRIPTION
    Advanced (!) method for writing renderblocks for placement in a GIF file. This method only applies LZW encoding on the indices and makes the correct headers.

    ARGUMENTS
    argument(s)description
    int x
    int y
    Position of this image.
    int xsize
    int ysize
    Size of the image. Length if the indices string must be xsize*ysize.
    int bpp
    Bits per pixels in the indices. Valid range 1..8.
    string indices
    The image indices as an 8bit indices.
    string colortable
    Colortable with colors to write as palette. If this argument is zero, no local colortable is written. Colortable string len must be 1<<bpp.
    int interlace
    Interlace index data and set interlace bit. The given string should _not_ be pre-interlaced.

    NOTE
    This is in the very advanced sector of the GIF support; please read about how GIF files works.

    SEE ALSO
    encode, _encode, header_block and end_block

    METHOD
    Image.GIF.__decode

    SYNTAX
    array __decode();

    DESCRIPTION
    Decodes a GIF image structure down to chunks and

    ({int xsize,int ysize,      // 0: size of image drawing area
    int numcol,               // 2: suggested number of colors
    void|string colortable,   // 3: opt. global colortable
    ({ int aspx, int aspy,    // 4,0: aspect ratio or 0, 0 if not set
    int background }),     //   1: index of background color
    
    followed by any number these blocks in any order:
    ({ GIF.EXTENSION,         //   0: block identifier
    int extension,         //   1: extension number
    string data })         //   2: extension data
    
    

    ({ GIF.RENDER, // 0: block identifier int x, int y, // 1: position of render int xsize, int ysize, // 3: size of render int interlace, // 5: interlace flag void|string colortbl, // 6: opt. local colortable int lzwsize, // 7: lzw code size string lzwdata }) // 8: packed lzw data

    and possibly ended with one of these:
    ({ GIF.ERROR_PREMATURE_EOD })   // premature end-of-data
    
    

    ({ GIF.ERROR_TOO_MUCH_DATA, // data following end marker string data }) // (rest of file)

    ({ GIF.ERROR_UNKNOWN_DATA, // unknown data string data }) // (rest of file)

    RETURNS
    the above array

    NOTE
    May throw errors if the GIF header is incomplete or illegal.

    This is in the very advanced sector of the GIF support; please read about how GIF files works.

    12.14 Image.HRZ

    DESCRIPTION

    METHOD
    Image.HRZ._decode,
    Image.HRZ.encode,
    Image.HRZ.decode

    SYNTAX
    object decode(string data)
    mapping _decode(string data)
    string encode(object image)

    DESCRIPTION
    Handle encoding and decoding of HRZ images. HRZ is rather trivial, and not really useful, but:

    The HRZ file is always 256x240 with RGB values from 0 to 63. No compression, no header, just the raw RGB data. HRZ is (was?) used for amatuer radio slow-scan TV.

    12.15 Image.ILBM

    DESCRIPTION
    This submodule keep the ILBM encode/decode capabilities of the Image module.

    SEE ALSO
    Image, Image.Image and Image.Colortable

    METHOD
    Image.ILBM.decode

    SYNTAX
    object decode(string data)
    object decode(array _decoded)
    object decode(array __decoded)

    DESCRIPTION
    Decodes ILBM data and creates an image object.

    RETURNS
    the decoded image as an image object

    NOTE
    This function may throw errors upon illegal ILBM data. This function uses __decode and _decode internally.

    SEE ALSO
    encode

    METHOD
    Image.ILBM.encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)

    DESCRIPTION
    Encodes an ILBM image.

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "alpha":image object
    Use this image as mask
    (Note: ILBM mask is boolean.
    The values are calculated by (r+2g+b)/4>=128.)
    
    

    "palette":colortable object Use this as palette for pseudocolor encoding

    METHOD
    Image.ILBM._decode

    SYNTAX
    array _decode(string|array data)

    DESCRIPTION
    Decode an ILBM image file.

    Result is a mapping,

    ([
    "image": object image,
    
    

    ... more ... ])

    image is the stored image.

    METHOD
    Image.ILBM.__decode

    SYNTAX
    array __decode();

    DESCRIPTION
    Decodes an ILBM image structure down to chunks and

    ({int xsize,int ysize,      // 0: size of image drawing area
    string bitmapheader,      // 2: BMHD chunk
    void|string colortable,   // 3: opt. colortable chunk (CMAP)
    void|string colortable,   // 4: opt. colormode chunk (CAMG)
    string body,              // 5: BODY chunk
    mapping more_chunks})     // 6: mapping with other chunks
    

    RETURNS
    the above array

    NOTE
    May throw errors if the ILBM header is incomplete or illegal.

    12.16 Image.PCX

    DESCRIPTION

    METHOD
    Image.PCX.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes a PCX image.

    NOTE
    Throws upon error in data.

    METHOD
    Image.PCX.encode,
    Image.PCX._encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)
    string _encode(object image)
    string _encode(object image,  mapping options)

    DESCRIPTION
    Encodes a PCX image. The _encode and the encode functions are identical

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "raw":1
    Do not RLE encode the image
    "dpy":int
    "xdpy":int
    "ydpy":int
    Image resolution (in pixels/inch, integer numbers)
    "xoffset":int
    "yoffset":int
    Image offset (not used by most programs, but gimp uses it)
    

    METHOD
    Image.PCX._decode

    SYNTAX
    mapping _decode(string data)

    DESCRIPTION
    Decodes a PCX image to a mapping.

    NOTE
    Throws upon error in data.

    12.17 Image.PNG

    DESCRIPTION

    NOTE
    This module uses zlib.

    METHOD
    Image.PNG.decode

    SYNTAX
    object decode(string data)
    object decode(string data,  mapping options)

    DESCRIPTION
    Decodes a PNG image.

    The options argument may be a mapping containing zero or more encoding options:

    
    

    NOTE
    Throws upon error in data.

    METHOD
    Image.PNG.encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)

    DESCRIPTION
    Encodes a PNG image.

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "alpha":image object
    Use this image as alpha channel
    (Note: PNG alpha channel is grey.
    The values are calculated by (r+2g+b)/4.)
    
    

    "palette":colortable object Use this as palette for pseudocolor encoding (Note: encoding with alpha channel and pseudocolor at the same time are not supported)

    NOTE
    Please read some about PNG files.

    METHOD
    Image.PNG._chunk

    SYNTAX
    string _chunk(string type, string data)

    DESCRIPTION
    Encodes a PNG chunk.

    NOTE
    Please read about the PNG file format.

    METHOD
    Image.PNG._decode

    SYNTAX
    array _decode(string|array data)
    array _decode(string|array data, mapping options)

    DESCRIPTION
    Decode a PNG image file.

    Result is a mapping,

    ([
    "image": object image,
    
    

    ... options ... ])

    image is the stored image.

    Valid entries in options is a superset of the one given to encode:

    basic options:
    
    

    "alpha": object alpha, - alpha channel

    "palette": object colortable, - image palette (if non-truecolor)

    advanced options:

    "background": array(int) color, - suggested background color "background_index": int index, - what index in colortable

    "chroma": ({ float white_point_x, float white_point_y, float red_x, float red_y, - CIE x,y chromaticities float green_x, float green_y, float blue_x, float blue_y })

    "gamma": float gamma, - gamma

    "spalette": object colortable, - suggested palette, for truecolor images "histogram": array(int) hist, - histogram for the image, corresponds to palette index

    "physical": ({ int unit, - physical pixel dimension int x,y }) unit 0 means pixels/meter

    "sbit": array(int) sbits - significant bits

    "text": array(array(string)) text - text information, ({ ({ keyword, data }), ... })

    Standard keywords:

    Title Short (one line) title or caption for image Author Name of image's creator Description Description of image (possibly long) Copyright Copyright notice Creation Time Time of original image creation Software Software used to create the image Disclaimer Legal disclaimer Warning Warning of nature of content Source Device used to create the image Comment Miscellaneous comment

    "time": ({ int year, month, day, - time of last modification hour, minute, second })

    wizard options: "compression": int method - compression method (0)

    This method can also take options, as a mapping:

    advanced options:
    "palette": colortable object
    - replace the decoded palette with this when
    unpacking the image data, if applicable
    

    NOTE
    Please read about the PNG file format. This function ignores any checksum errors in the file. A PNG of higher color resolution than the Image module supports (8 bit) will lose that information in the conversion. It throws an error if the image data is erroneous.

    METHOD
    Image.PNG.__decode

    SYNTAX
    array __decode(string data)
    array __decode(string data,  int dontcheckcrc)

    DESCRIPTION
    Splits a PNG file into chunks.

    Result is an array of arrays, ({ ({ string chunk_type, string data, int crc_ok }), ({ string chunk_type, string data, int crc_ok }) ... })

    chunk_type is the type of the chunk, like "IHDR" or "IDAT".

    data is the actual chunk data.

    crcok is set to 1 if the checksum is ok and dontcheckcrc parameter isn't set.

    Returns 0 if it isn't a PNG file.

    NOTE
    Please read about the PNG file format.

    12.18 Image.PNM

    DESCRIPTION
    This submodule keeps the PNM encode/decode capabilities of the Image module.

    PNM is a common image storage format on unix systems, and is a very simple format.

    This format doesn't use any color palette.

    The format is divided into seven subformats;

    P1(PBM) - ascii bitmap (only two colors)
    P2(PGM) - ascii greymap (only grey levels)
    P3(PPM) - ascii truecolor
    P4(PBM) - binary bitmap
    P5(PGM) - binary greymap
    P6(PPM) - binary truecolor
    

    Simple encoding:
    encode,
    encode_binary,
    encode_ascii

    Simple decoding:
    decode

    Advanced encoding:
    encode_P1,
    encode_P2,
    encode_P3,
    encode_P4,
    encode_P5,
    encode_P6

    SEE ALSO
    Image, Image.Image and Image.GIF

    METHOD
    Image.PNM.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes PNM (PBM/PGM/PPM) data and creates an image object.

    RETURNS
    the decoded image as an image object

    NOTE
    This function may throw errors upon illegal PNM data.

    SEE ALSO
    encode

    METHOD
    Image.PNM.encode,
    Image.PNM.encode_P1,
    Image.PNM.encode_P5,
    Image.PNM.encode_ascii,
    Image.PNM.encode_P6,
    Image.PNM.encode_P2,
    Image.PNM.encode_binary,
    Image.PNM.encode_P3,
    Image.PNM.encode_P4

    SYNTAX
    string encode(object image)
    string encode_binary(object image)
    string encode_ascii(object image)
    string encode_P1(object image)
    string encode_P2(object image)
    string encode_P3(object image)
    string encode_P4(object image)
    string encode_P5(object image)
    string encode_P6(object image)

    DESCRIPTION
    Make a complete PNM file from an image.

    encode_binary() and encode_ascii() uses the most optimized encoding for this image (bitmap, grey or truecolor) - P4, P5 or P6 respective P1, P2 or P3.

    encode_P1/encode_P4 assumes the image is black and white. Use Image.Image->threshold() or something like Image.Colortable( ({({0,0,0}),({255,255,255})}) )->floyd_steinberg()->map(my_image) to get a black and white image.

    encode_P2/encode_P5 assumes the image is greyscale. Use Image.Image->grey() to get a greyscale image.

    RETURNS
    the encoded image as a string

    NOTE
    encode() is equal to encode_binary(), but may change in a future release.

    SEE ALSO
    decode

    12.19 Image.PSD

    DESCRIPTION

    12.20 Image.TGA

    DESCRIPTION

    METHOD
    Image.TGA.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes a Targa image.

    NOTE
    Throws upon error in data.

    METHOD
    Image.TGA.encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)

    DESCRIPTION
    Encodes a Targa image.

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "alpha":image object
    Use this image as alpha channel
    (Note: Targa alpha channel is grey.
    The values are calculated by (r+2g+b)/4.)
    
    

    "raw":1 Do not RLE encode the image

    METHOD
    Image.TGA._decode

    SYNTAX
    object _decode(string data)

    DESCRIPTION
    Decodes a Targa image to a mapping. The mapping follows this format: ([ "image":img_object, "alpha":alpha_channel ])

    NOTE
    Throws upon error in data.

    12.21 Image.XBM

    DESCRIPTION

    METHOD
    Image.XBM.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes a XBM image.

    NOTE
    Throws upon error in data.

    METHOD
    Image.XBM.encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)

    DESCRIPTION
    Encodes a XBM image.

    The options argument may be a mapping containing zero or more encoding options.

    normal options:
    "name":"xbm_image_name"
    The name of the XBM. Defaults to 'image'
    

    METHOD
    Image.XBM._decode

    SYNTAX
    object _decode(string data)
    object _decode(string data,  mapping options)

    DESCRIPTION
    Decodes a XBM image to a mapping.

    Supported options:
    ([
    "fg":({fgcolor}),    // Foreground color. Default black
    "bg":({bgcolor}),    // Background color. Default white
    "invert":1,          // Invert the mask
    ])
    

    NOTE
    Throws upon error in data.

    12.22 Image.XCF

    DESCRIPTION

    METHOD
    Image.XCF.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes a XCF image to a single image object.

    NOTE
    Throws upon error in data, you will loose quite a lot of information by doing this. See Image.XCF._decode and Image.XCF.__decode

    METHOD
    Image.XCF.decode_layers

    SYNTAX
    array(object) decode_layers( string data )

    DESCRIPTION
    Decodes a XCF image to an array of Image.Layer objects

    The layer object have the following extra variables (to be queried using get_misc_value):

    image_xres, image_yres, image_colormap, image_guides, image_parasites, name, parasites, visible, active

    METHOD
    Image.XCF._decode

    SYNTAX
    mapping _decode(string|object data, mapping|void options)

    DESCRIPTION
    Decodes a XCF image to a mapping, with at least an 'image' and possibly an 'alpha' object. Data is either a XCF image, or a XCF.GimpImage object structure (as received from __decode)

     Supported options
    ([
    "background":({r,g,b})||Image.Color object
    "draw_all_layers":1,
    Draw invisible layers as well
    
    

    "draw_guides":1, Draw the guides

    "draw_selection":1, Mark the selection using an overlay

    "ignore_unknown_layer_modes":1 Do not asume 'Normal' for unknown layer modes.

    "mark_layers":1, Draw an outline around all (drawn) layers

    "mark_layer_names":Image.Font object, Write the name of all layers using the font object,

    "mark_active_layer":1, Draw an outline around the active layer ])

    NOTE
    Throws upon error in data. For more information, see Image.XCF.__decode

    METHOD
    Image.XCF.__decode

    SYNTAX
    object __decode(string|mapping data,  mapping|void options)

    DESCRIPTION
    Decodes a XCF image to a Image.XCF.GimpImage object.

    Returned structure reference
    
    

    class GimpImage { int width; int height; int compression; int type; int tattoo_state; float xres = 72.0; float yres = 72.0; int res_unit; Image.Colortable colormap; Image.Colortable meta_colormap; array(Layer) layers = ({}); array(Channel) channels = ({}); array(Guide) guides = ({}); array(Parasite) parasites = ({}); array(Path) paths = ({});

    Layer active_layer; Channel active_channel; Channel selection; }

    class Layer { string name; int opacity; int type; int mode; int tattoo; mapping flags = ([]); int width, height; int xoffset, yoffset; array (Parasite) parasites; LayerMask mask; Hierarchy image; }

    class Channel { string name; int width; int height; int opacity; int r, g, b; int tattoo; Hierarchy image_data; object parent; mapping flags = ([]); array (Parasite) parasites; }

    class Hierarchy { Image.Image img; Image.Image alpha; int width; int height; int bpp; }

    class Parasite { string name; int flags; string data; }

    class Guide { int pos; int vertical; }

    class Path { string name; int ptype; int tattoo; int closed; int state; int locked; array (PathPoint) points = ({}); }

    class PathPoint { int type; float x; float y; }

    METHOD
    Image.XCF.___decode

    SYNTAX
    object ___decode(string|mapping data)

    DESCRIPTION
    Decodes a XCF image to a mapping.

    Structure reference
    
    

    ([ "width":int, "height":int, "type":int, "properties":({ ([ "type":int, "data":string, ]), ... }), "layers":({ ([ "name":string, "width":int, "height":int, "type":type, "properties":({ ([ "type":int, "data":string, ]), ... }), "mask":0 || ([ "name":string, "width":int, "height":int, "properties":({ ([ "type":int, "data":string, ]), ... }), "image_data":([ "bpp":int, "width":int, "height":int, "tiles":({ string, ... }), ]), ]), "image_data":([ "bpp":int, "width":int, "height":int, "tiles":({ string, ... }), ]), ]), ... }), "channels":({ "name":string, "width":int, "height":int, "properties":({ ([ "type":int, "data":string, ]), ... }), "image_data":([ "bpp":int, "width":int, "height":int, "tiles":({ string, ... }), ]), }), ])

    12.23 Image.XWD

    DESCRIPTION
    This submodule keeps the XWD (X Windows Dump) decode capabilities of the Image module.

    XWD is the output format for the xwd program.

    Simple decoding:
    decode

    Advanced decoding:
    _decode

    SEE ALSO
    Image, Image.Image, Image.PNM and Image.X

    METHOD
    Image.XWD.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Simple decodes a XWD image file.

    METHOD
    Image.XWD._decode,
    Image.XWD.decode_header

    SYNTAX
    mapping _decode(string data)
    mapping decode_header(string data)

    DESCRIPTION
    Decodes XWD data and returns the result.

    Supported XWD visual classes and encoding formats are TrueColor / ZPixmap DirectColor / ZPixmap PseudoColor / ZPixmap

    If someone sends me files of other formats, these formats may be implemented. :) /mirar@idonex.se

    RETURNS
    the decoded image as an image object

    NOTE
    This function may throw errors upon illegal or unknown XWD data.

    SEE ALSO
    decode

    12.24 Image.JPEG

    DESCRIPTION

    NOTE
    This module uses libjpeg, a software from Independent JPEG Group.

    METHOD
    Image.JPEG._decode,
    Image.JPEG.decode,
    Image.JPEG.decode_header

    SYNTAX
    object decode(string data)
    object decode(string data,  mapping options)
    mapping _decode(string data)
    mapping _decode(string data,  mapping options)
    mapping decode_header(string data)

    DESCRIPTION
    Decodes a JPEG image. The simple decode function simply gives the image object, the other functions gives a mapping of information (see below)

    The options argument may be a mapping containing zero or more encoding options:

    advanced options:
    "block_smoothing":0|1
    Do interblock smoothing. Default is on (1).
    "fancy_upsampling":0|1
    Do fancy upsampling of chroma components.
    Default is on (1).
    "method":JPEG.IFAST|JPEG.ISLOW|JPEG.FLOAT|JPEG.DEFAULT|JPEG.FASTEST
    DCT method to use.
    DEFAULT and FASTEST is from the jpeg library,
    probably ISLOW and IFAST respective.
    
    

    wizard options: "scale_num":1.. "scale_denom":1.. Rescale the image when read from JPEG data. My (Mirar) version (6a) of jpeglib can only handle 1/1, 1/2, 1/4 and 1/8.

    _decode and decode_header gives a mapping as result, with this content:

    "xsize":int
    "ysize":int
    size of image
    "xdpi":float
    "ydpi":float
    image dpi, if known
    "type":"image/jpeg"
    file type information as MIME type
    
    

    JPEG specific: "num_compontents":int number of channels in JPEG image "color_space":"GRAYSCALE"|"RGB"|"YUV"|"CMYK"|"YCCK"|"UNKNOWN" color space of JPEG image "density_unit":int "x_density":int "y_density":int density of image; unit is 1:dpi 2:dpcm 0:no units "adobe_marker":0|1 if the file has an adobe marker

    NOTE
    Please read some about JPEG files.

    METHOD
    Image.JPEG.encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)

    DESCRIPTION
    Encodes a JPEG image.

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "quality":0..100
    Set quality of result. Default is 75.
    "optimize":0|1
    Optimize Huffman table. Default is on (1) for
    images smaller than 50kpixels.
    "progressive":0|1
    Make a progressive JPEG. Default is off.
    
    

    advanced options: "smooth":1..100 Smooth input. Value is strength. "method":JPEG.IFAST|JPEG.ISLOW|JPEG.FLOAT|JPEG.DEFAULT|JPEG.FASTEST DCT method to use. DEFAULT and FASTEST is from the jpeg library, probably ISLOW and IFAST respective.

    "density_unit":int "x_density":int "y_density":int density of image; unit is 1:dpi 2:dpcm 0:no units

    wizard options: "baseline":0|1 Force baseline output. Useful for quality<25. Default is on for quality<25. "quant_tables":mapping(int,array(array(int))) Tune quantisation tables manually.

    NOTE
    Please read some about JPEG files. A quality setting of 100 does not mean the result is lossless.

    12.25 Image.TIFF

    DESCRIPTION

    METHOD
    Image.TIFF.decode

    SYNTAX
    object decode(string data)

    DESCRIPTION
    Decodes a TIFF image.

    NOTE
    Throws upon error in data.

    METHOD
    Image.TIFF.encode,
    Image.TIFF._encode

    SYNTAX
    string encode(object image)
    string encode(object image,  mapping options)
    string _encode(object image)
    string _encode(object image,  mapping options)

    DESCRIPTION
    encode and _encode are identical.

    The options argument may be a mapping containing zero or more encoding options:

    normal options:
    "compression":Image.TIFF.COMPRESSION_*,
    "name":"an image name",
    "comment":"an image comment",
    "alpha":An alpha channel,
    "dpy":Dots per inch (as a float),
    "xdpy":Horizontal dots per inch (as a float),
    "ydpy":Vertical dots per inch (as a float),
    

    METHOD
    Image.TIFF._decode

    SYNTAX
    mapping _decode(string data)

    DESCRIPTION
    Decodes a TIFF image to a mapping with at least the members image and alpha.

    NOTE
    Throws upon error in data.

    12.26 Image.TTF

    DESCRIPTION
    This module adds TTF (Truetype font) capability to the Image module.

    NOTE
    This module needs the libttf "Freetype" library

    METHOD
    Image.TTF.`

    SYNTAX
    object `()(string filename)
    object `()(string filename, mapping options)

    DESCRIPTION
    Makes a new TTF Face object.

    ARGUMENTS
    argument(s)description
    string filename
    The filename of the TTF font or the TTC font collection.
    mapping options
    advanced options:
    "face":int
    If opening a font collection,  '.TTC',
    this is used to get other fonts than the first.
    

    RETURNS
    0 if failed.

    12.26.1 Image.TTF.Face

    CLASS
    Image.TTF.Face

    DESCRIPTION
    This represents instances of TTF Faces.

    METHOD
    Image.TTF.Face.flush

    SYNTAX
    object flush()

    DESCRIPTION
    This flushes all cached information. Might be used to save memory - the face information is read back from disk upon need.

    RETURNS
    the called object

    METHOD
    Image.TTF.Face.names,
    Image.TTF.Face._names

    SYNTAX
    mapping names()
    array(array) _names()

    DESCRIPTION
    Gives back the names or the complete name-list of this face.

    The result from names() is a mapping, which has any or all of these indices:

    "copyright":   ("Copyright the Foo Corporation...bla bla")
    "family":      ("My Little Font")
    "style":       ("Bold")
    "full":        ("Foo: My Little Font: 1998")
    "expose":      ("My Little Font Bold")
    "version":     ("June 1, 1998; 1.00, ...")
    "postscript":  ("MyLittleFont-Bold")
    "trademark":   ("MyLittleFont is a registered...bla bla")
    

    This is extracted from the information from _names(), and fit into pike-strings using unicode or iso-8859-1, if possible.

    The result from _names() is a matrix, on this form:

    ({ ({ int platform, encoding, language, id, string name }),
    ({ int platform, encoding, language, id, string name }),
    ...
    })
    

    RETURNS
    the name as a mapping to string or the names as a matrix

    NOTE
    To use the values from _names(), check the TrueType standard documentation.

    METHOD
    Image.TTF.Face.properties

    SYNTAX
    mapping properties()

    DESCRIPTION
    This gives back a structure of the face's properties. Most of this stuff is information you can skip.

    The most interesting item to look at may be ->num_Faces, which describes the number of faces in a .TTC font collection.

    RETURNS
    a mapping of a lot of properties

    METHOD
    Image.TTF.Face.`

    SYNTAX
    object `()()

    DESCRIPTION
    This instantiates the face for normal usage - to convert font data to images.

    RETURNS
    a Image.TTF.FaceInstance object.

    12.26.2 Image.TTF.FaceInstance

    CLASS
    Image.TTF.FaceInstance

    DESCRIPTION
    This is the instance of a face, with geometrics, encodings and stuff.

    METHOD
    Image.TTF.FaceInstance.create

    SYNTAX
    void create(object face)

    DESCRIPTION
    creates a new Instance from a face.

    12.27 Image.XFace

    DESCRIPTION

    NOTE
    This module uses libgmp.

    METHOD
    Image.XFace.decode

    SYNTAX
    object decode(string data)
    object decode(string data,  mapping options)

    DESCRIPTION
    Decodes an X-Face image.

    The options argument may be a mapping containing zero options.

    METHOD
    Image.XFace.decode_header

    SYNTAX
    object decode_header(string data)
    object decode_header(string data,  mapping options)

    DESCRIPTION
    Decodes an X-Face image header.

    "xsize":int
    "ysize":int
    size of image
    "type":"image/x-xface"
    file type information
    

    The options argument may be a mapping containing zero options.

    NOTE
    There aint no such thing as a X-Face image header. This stuff tells the characteristics of an X-Face image.

    METHOD
    Image.XFace.encode

    SYNTAX
    string encode(object img)
    string encode(object img,  mapping options)

    DESCRIPTION
    Encodes an X-Face image.

    The img argument must be an image of the dimensions 48 by 48 pixels. All non-black pixels will be considered white.

    The options argument may be a mapping containing zero options.

    Chapter 13, Protocols

    The Protocol modules is some helper modules that makes it easier for the pike programmer to use some of the protocols used on the internet.

    13.1 Protocols.HTTP

    METHOD
    Protocols.HTTP.delete_url

    SYNTAX
    object(Protocols.HTTP.Query) delete_url(string url)
    object(Protocols.HTTP.Query) delete_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) delete_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP DELETE request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.get_url

    SYNTAX
    object(Protocols.HTTP.Query) get_url(string url)
    object(Protocols.HTTP.Query) get_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) get_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP GET request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.get_url_nice,
    Protocols.HTTP.get_url_data

    SYNTAX
    array(string) get_url_nice(string url)
    array(string) get_url_nice(string url, mapping query_variables)
    array(string) get_url_nice(string url, mapping query_variables,  mapping request_headers)
    string get_url_data(string url)
    string get_url_data(string url, mapping query_variables)
    string get_url_data(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Returns an array of ({content_type,data}) and just the data string respective, after calling the requested server for the information. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.post_url_nice,
    Protocols.HTTP.post_url_data,
    Protocols.HTTP.post_url

    SYNTAX
    array(string) post_url_nice(string url, mapping query_variables)
    array(string) post_url_nice(string url, mapping query_variables,  mapping request_headers)
    string post_url_data(string url, mapping query_variables)
    string post_url_data(string url, mapping query_variables,  mapping request_headers)
    object(Protocols.HTTP.Query) post_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) post_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Similar to the get_url class of functions, except that the query variables is sent as a post request instead of a get.

    METHOD
    Protocols.HTTP.put_url

    SYNTAX
    object(Protocols.HTTP.Query) put_url(string url)
    object(Protocols.HTTP.Query) put_url(string url, string file)
    object(Protocols.HTTP.Query) put_url(string url, string file, mapping query_variables)
    object(Protocols.HTTP.Query) put_url(string url, string file, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP PUT request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.unentity

    SYNTAX
    string unentity(string s)

    DESCRIPTION
    Helper function for replacing HTML entities with the corresponding iso-8859-1 characters.

    NOTE
    All characters isn't replaced, only those with corresponding iso-8859-1 characters.

    13.1.1 Protocols.HTTP.Query

    CLASS
    Protocols.HTTP.Query

    DESCRIPTION
    Open and execute a HTTP query.

    METHOD
    Protocols.HTTP.Query.set_callbacks,
    Protocols.HTTP.Query.async_request

    SYNTAX
    object set_callbacks(function request_ok, function request_fail, mixed ...extra)
    object async_request(string server, int port, string query);
    object async_request(string server, int port, string query, mapping headers, void|string data);

    DESCRIPTION
    Setup and run an asynchronous request, otherwise similar to thread_request.

    request_ok(object httpquery,...extra args) will be called when connection is complete, and headers are parsed.

    request_fail(object httpquery,...extra args) is called if the connection fails.

    variable int ok Tells if the connection is successfull. variable int errno Errno copied from the connection.

    variable mapping headers Headers as a mapping. All header names are in lower case, for convinience.

    variable string protocol Protocol string, ie "HTTP/1.0".

    variable int status variable string status_desc Status number and description (ie, 200 and "ok").

    variable mapping hostname_cache Set this to a global mapping if you want to use a cache, prior of calling *request().

    variable mapping async_dns Set this to an array of Protocols.DNS.async_clients, if you wish to limit the number of outstanding DNS requests. Example: async_dns=allocate(20,Protocols.DNS.async_client)();

    RETURNS
    the called object

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    array cast("array")

    DESCRIPTION
    Gives back ({mapping headers,string data, string protocol,int status,string status_desc});

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    mapping cast("mapping")

    DESCRIPTION
    Gives back headers | (["protocol":protocol, "status":status number, "status_desc":status description, "data":data]);

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    string cast("string")

    DESCRIPTION
    Gives back the answer as a string.

    METHOD
    Protocols.HTTP.Query.data

    SYNTAX
    string data()

    DESCRIPTION
    Gives back the data as a string.

    METHOD
    Protocols.HTTP.Query.downloaded_bytes

    SYNTAX
    int downloaded_bytes()

    DESCRIPTION
    Gives back the number of downloaded bytes.

    METHOD
    Protocols.HTTP.Query.thread_request

    SYNTAX
    object thread_request(string server, int port, string query);
    object thread_request(string server, int port, string query, mapping headers, void|string data);

    DESCRIPTION
    Create a new query object and begin the query.

    The query is executed in a background thread; call '() in this object to wait for the request to complete.

    'query' is the first line sent to the HTTP server; for instance "GET /index.html HTTP/1.1".

    headers will be encoded and sent after the first line, and data will be sent after the headers.

    RETURNS
    the called object

    METHOD
    Protocols.HTTP.Query.total_bytes

    SYNTAX
    int total_bytes()

    DESCRIPTION
    Gives back the size of a file if a content-length header is present and parsed at the time of evaluation. Otherwise returns -1.

    object(pseudofile) file() object(pseudofile) file(mapping newheaders,void|mapping removeheaders) object(pseudofile) datafile(); Gives back a pseudo-file object, with the method read() and close(). This could be used to copy the file to disc at a proper tempo.

    datafile() doesn't give the complete request, just the data.

    newheaders, removeheaders is applied as: (oldheaders|newheaders))-removeheaders Make sure all new and remove-header indices are lower case.

    void async_fetch(function done_callback); Fetch all data in background.

    METHOD
    Protocols.HTTP.Query.`

    SYNTAX
    int `()()

    DESCRIPTION
    Wait for connection to complete.

    RETURNS
    1 on successfull connection, 0 if failed

    13.2 Protocols.LysKOM

    13.2.1 Protocols.LysKOM.Session

    CLASS
    Protocols.LysKOM.Session

    DESCRIPTION
    variable user This variable contains the person that are logged in.

    METHOD
    Protocols.LysKOM.Session.create

    SYNTAX
    void create(string server)
    void create(string server, mapping options)

    DESCRIPTION
    Initializes the session object, and opens a connection to that server.

    options is a mapping of options,

    ([
       "login" : int|string    login as this person number
                             (get number from name)
       "create" : string       
                             create a new person and login with it
       "password" : string     send this login password
       "invisible" : int(0..1) if set, login invisible
       advanced
       "port" : int(0..65535)  server port (default is 4894)
       "whoami" : string       present as this user
                             (default is from uid/getpwent and hostname)
    ])
    

    SEE ALSO
    Connection

    METHOD
    Protocols.LysKOM.Session.create_person

    SYNTAX
    object create_person(string name, string password)

    DESCRIPTION
    Create a person, which will be logged in.

    RETURNS
    the new person object

    METHOD
    Protocols.LysKOM.Session.create_text

    SYNTAX
    object create_text(string subject, string body, mapping options)
    object create_text(string subject, string body, mapping options, function callback, mixed ...extra)

    DESCRIPTION
    Creates a new text.

    if "callback" are given, this function will be called when the text is created, with the text as first argument. Otherwise, the new text is returned.

    options is a mapping that may contain:

    ([
       "recpt" : Conference|array(Conference) 
            recipient conferences
       "cc" : Conference|array(Conference)    
            cc-recipient conferences
       "bcc" : Conference|array(Conference)   
            bcc-recipient conferences *
       
       "comm_to" : Text|array(Text)           
            what text(s) is commented
       "foot_to" : Text|array(Text)           
            what text(s) is footnoted
       
       "anonymous" : int(0..1)                
            send text anonymously
    ])
    

    NOTE
    The above marked with a '*' is only available on a protocol 10 server. A LysKOM error will be thrown if the call fails.

    SEE ALSO
    Conference.create_text, Text.comment and Text.footnote

    METHOD
    Protocols.LysKOM.Session.login

    SYNTAX
    object login(int user_no, string password)
    object login(int user_no, string password, int invisible)

    DESCRIPTION
    Performs a login. Returns 1 on success or throws a lyskom error.

    RETURNS
    the called object

    METHOD
    Protocols.LysKOM.Session.logout

    SYNTAX
    object logout()

    DESCRIPTION
    Logouts from the server.

    RETURNS
    the called object

    METHOD
    Protocols.LysKOM.Session.send_message

    SYNTAX
    object send_message(string message,  mapping options)

    DESCRIPTION
    Sends a message.

    options is a mapping that may contain:

    ([
       "recpt" : Conference recipient conference
    ])
    

    METHOD
    Protocols.LysKOM.Session.try_complete_person

    SYNTAX
    array(object) try_complete_person(string orig)

    DESCRIPTION
    Runs a LysKOM completion on the given string, returning an array of confzinfos of the match.

    13.2.2 Protocols.LysKOM.Connection

    CLASS
    Protocols.LysKOM.Connection

    DESCRIPTION
    This class contains nice abstraction for calls into the server. They are named "call", "async_call" or "async_cb_call", depending on how you want the call to be done.

    METHOD
    Protocols.LysKOM.Connection./call/,
    Protocols.LysKOM.Connection.async_/call/,
    Protocols.LysKOM.Connection.async_cb_/call/

    SYNTAX
    mixed /call/(mixed ...args)
    object async_/call/(mixed ...args)
    object async_cb_/call/(function callback, mixed ...args)

    DESCRIPTION
    Do a call to the server. This really clones a request object, and initialises it. /call/ is to be read as one of the calls in the lyskom protocol. ('-' is replaced with '_'.) (ie, logout, async_login or async_cb_get_conf_stat.)

    The first method is a synchronous call. This will send the command, wait for the server to execute it, and then return the result.

    The last two is asynchronous calls, returning the initialised request object.

    variable int protocol_level variable string session_software variable string software_version Description of the connected server.

    METHOD
    Protocols.LysKOM.Connection.create

    SYNTAX
    void create(string server)
    void create(string server, mapping options)

    DESCRIPTION
    ([
       "login" : int|string    login as this person number
                             (get number from name)
       "password" : string     send this login password
       "invisible" : int(0..1) if set, login invisible
       advanced
       "port" : int(0..65535)  server port (default is 4894)
       "whoami" : string       present as this user
                             (default is from uid/getpwent and hostname)
    ])
    

    13.2.3 Protocols.LysKOM.Request

    DESCRIPTION
    This class contains nice abstraction for calls into the server. They are named "call", "async_call" or "async_cb_call", depending on how you want the call to be done.

    13.2.3.1 Protocols.LysKOM.Request._Request

    CLASS
    Protocols.LysKOM.Request._Request

    DESCRIPTION
    This is the main request class. All lyskom request classes inherits this class.

    METHOD
    Protocols.LysKOM.Request._Request.async,
    Protocols.LysKOM.Request._Request.sync

    SYNTAX
    void async(mixed ...args)
    mixed sync(mixed ...args)

    DESCRIPTION
    initialise an asynchronous or a synchronous call, the latter is also evaluating the result. This calls 'indata' in itself, to get the correct arguments to the lyskom protocol call.

    METHOD
    Protocols.LysKOM.Request._Request._reply,
    Protocols.LysKOM.Request._Request.reply

    SYNTAX
    mixed _reply(object|array what)
    mixed reply(object|array what)

    DESCRIPTION
    _reply is called as callback to evaluate the result, and calls reply in itself to do the real work.

    METHOD
    Protocols.LysKOM.Request._Request.`

    SYNTAX
    mixed `()()

    DESCRIPTION
    wait for the call to finish.

    variable int ok tells if the call is executed ok variable object error how the call failed The call is completed if (ok||error).

    METHOD
    Protocols.LysKOM.Request._Request._async,
    Protocols.LysKOM.Request._Request._sync

    SYNTAX
    void _async(int call,  mixed_data)
    mixed _sync(int call,  mixed_data)

    DESCRIPTION
    initialise an asynchronous or a synchronous call, the latter is also evaluating the result. These are called by async and sync respectively.

    13.3 Protocols.DNS

    DESCRIPTION

    13.3.1 Protocols.DNS.client

    CLASS
    Protocols.DNS.client

    DESCRIPTION
    Synchronous DNS client.

    METHOD
    Protocols.DNS.client.create

    SYNTAX
    void create()
    void create(void|string|array server,  void|int|array domain)

    DESCRIPTION

    METHOD
    Protocols.DNS.client.gethostbyname,
    Protocols.DNS.client.gethostbyaddr

    SYNTAX
    array gethostbyname(string hostname)
    array gethostbyaddr(string hostip)

    DESCRIPTION
    Querys the host name or ip from the default or given DNS server. The result is a mapping with three elements,
    ({
       string hostname  [0] hostname
       array(string) ip [1] ip number(s)
       array(string) ip [2] dns name(s)
    })
    

    METHOD
    Protocols.DNS.client.get_primary_mx

    SYNTAX
    string get_primary_mx(string hostname)

    DESCRIPTION
    Querys the primary mx for the host.

    RETURNS
    the hostname of the primary mail exchanger

    Chapter 14, Other modules

    Pike also include a number of smaller modules. These modules implement support for various algorithms, data structures and system routines.

    14.1 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.

    Please note that these functions are available globally, you do not need to import System to use these functions.

    FUNCTION
    chroot - change the root directory

    SYNTAX
    int chroot(string newroot);
    int chroot(object(File) obj);

    DESCRIPTION
    Changes the root directory for this process to the indicated directory.

    NOTE
    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.

    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.

    FUNCTION
    getegid - get the effective group ID

    SYNTAX
    int getegid();

    DESCRIPTION
    Get the effective group ID.

    SEE ALSO
    setuid, getuid, setgid, getgid, seteuid, geteuid and setegid

    FUNCTION
    geteuid - get the effective user ID

    SYNTAX
    int geteuid();

    DESCRIPTION
    Get the effective user ID.

    SEE ALSO
    setuid, getuid, setgid, getgid, seteuid, setegid and getegid

    FUNCTION
    getgid - get the group ID

    SYNTAX
    int getgid();

    DESCRIPTION
    Get the real group ID.

    SEE ALSO
    setuid, getuid, setgid, seteuid, geteuid, setegid and getegid

    FUNCTION
    getgroups - get the supplemental group access list

    SYNTAX
    array(int) getgroups();

    DESCRIPTION
    Get the current supplemental group access list for this process.

    SEE ALSO
    initgroups, setgroups, getgid, setgid, getegid and setegid

    FUNCTION
    gethostbyaddr - gets information about a host given its address

    SYNTAX
    array gethostbyaddr(string addr);

    DESCRIPTION
    Returns an array with information about the specified IP address.

    The returned array contains the same information as that returned by gethostbyname().

    NOTE
    This function only exists on systems that have the gethostbyaddr(2) or similar system call.

    SEE ALSO
    gethostbyname

    FUNCTION
    gethostbyname - gets information about a host given its name

    SYNTAX
    array gethostbyname(string hostname);

    DESCRIPTION
    Returns an array with information about the specified host.

    The array contains three elements:

    The first element is the hostname.

    The second element is an array(string) of IP numbers for the host.

    The third element is an array(string) of aliases for the host.

    NOTE
    This function only exists on systems that have the gethostbyname(2) or similar system call.

    SEE ALSO
    gethostbyaddr

    FUNCTION
    gethostname - get the name of this host

    SYNTAX
    string gethostname();

    DESCRIPTION
    Returns a string with the name of the host.

    NOTE
    This function only exists on systems that have the gethostname(2) or uname(2) system calls.

    FUNCTION
    getpgrp - get the process group ID

    SYNTAX
    int getpgrp();
    int getpgrp(int pid);

    DESCRIPTION
    With no arguments or with pid equal to zero, returns the process group ID of this process.

    If pid is specified, returns the process group ID of that process.

    SEE ALSO
    getpid and getppid

    FUNCTION
    getpid - get the process ID

    SYNTAX
    int getpid();

    DESCRIPTION
    Returns the process ID of this process.

    SEE ALSO
    getppid and getpgrp

    FUNCTION
    getppid - get the parent process ID

    SYNTAX
    int getppid();

    DESCRIPTION
    Returns the process ID of the parent process.

    SEE ALSO
    getpid and getpgrp

    FUNCTION
    getuid - get the user ID

    SYNTAX
    int getuid();

    DESCRIPTION
    Get the real user ID.

    SEE ALSO
    setuid, setgid, getgid, seteuid, geteuid, setegid and getegid

    FUNCTION
    hardlink - create a hardlink

    SYNTAX
    void hardlink(string from, string to);

    DESCRIPTION
    Creates a hardlink named to from the file from.

    SEE ALSO
    symlink, mv and rm

    FUNCTION
    initgroups - initialize the group access list

    SYNTAX
    void initgroups(string username, int base_gid);

    DESCRIPTION
    Initializes the group access list according to the system group database. base_gid is also added to the group access list.

    SEE ALSO
    setuid, getuid, setgid, getgid, seteuid, geteuid, setegid, getegid, getgroups and setgroups

    FUNCTION
    openlog - initializes the connection to syslogd

    SYNTAX
    void openlog(string ident, int options, facility);

    DESCRIPTION
    Initializes the connection to syslogd.

    The ident argument specifies an identifier to tag all log entries with.

    options is a bit field specifying the behavior of the message logging. Valid options are:

    LOG_PID Log the process ID with each message.
    LOG_CONS Write messages to the console if they can't be sent to syslogd.
    LOG_NDELAY Open the connection to syslogd now and not later.
    LOG_NOWAIT Do not wait for subprocesses talking to syslogd.

    facility specifies what subsystem you want to log as. Valid facilities are:

    LOG_AUTH Authorization subsystem
    LOG_AUTHPRIV
    LOG_CRON Crontab subsystem
    LOG_DAEMON System daemons
    LOG_KERN Kernel subsystem (NOT USABLE)
    LOG_LOCAL For local use
    LOG_LOCAL[1-7] For local use
    LOG_LPR Line printer spooling system
    LOG_MAIL Mail subsystem
    LOG_NEWS Network news subsystem
    LOG_SYSLOG
    LOG_USER
    LOG_UUCP UUCP subsystem

    NOTE
    Only available on systems with syslog(3).

    BUGS
    LOG_NOWAIT should probably always be specified.

    SEE ALSO
    syslog, closelog and setlogmask

    FUNCTION
    readlink - read a symbolic link

    SYNTAX
    string readlink(string linkname);

    DESCRIPTION
    Returns what the symbolic link linkname points to.

    SEE ALSO
    symlink

    FUNCTION
    setegid - set the effective group ID

    SYNTAX
    void setegid(int uid);

    DESCRIPTION
    Sets the effective group ID to gid.

    SEE ALSO
    setuid, getuid, setgid, getgid, seteuid, geteuid and getegid

    FUNCTION
    seteuid - set the effective user ID

    SYNTAX
    void seteuid(int uid);

    DESCRIPTION
    Sets the effective user ID to uid.

    SEE ALSO
    setuid, getuid, setgid, getgid, geteuid, setegid and getegid

    FUNCTION
    setgid - set the group ID

    SYNTAX
    void setgid(int gid);

    DESCRIPTION
    Sets the real group ID, effective group ID and saved group ID to gid.

    SEE ALSO
    setuid, getuid, getgid, seteuid, geteuid, setegid and getegid

    FUNCTION
    setgroups - set the supplemental group access list

    SYNTAX
    void getgroups(array(int) gids);

    DESCRIPTION
    Set the supplemental group access list for this process.

    SEE ALSO
    initgroups, getgroups, getgid, setgid, getegid and setegid

    FUNCTION
    setuid - set the user ID

    SYNTAX
    void setuid(int uid);

    DESCRIPTION
    Sets the real user ID, effective user ID and saved user ID to uid.

    SEE ALSO
    getuid, setgid, getgid, seteuid, geteuid, setegid and getegid

    FUNCTION
    symlink - create a symbolic link

    SYNTAX
    void symlink(string from, string to);

    DESCRIPTION
    Creates a symbolic link for an original file from with the new name to.

    SEE ALSO
    hardlink, readlink, mv and rm

    FUNCTION
    uname - get operating system information

    SYNTAX
    mapping(string:string) uname();

    DESCRIPTION
    Returns a mapping describing the operating system.

    The mapping contains the following fields:

    "sysname": Operating system name
    "nodename": "release": "version": "machine": Host name Release of this OS Version number of this OS Machine architecture

    NOTE
    This function only exists on systems that have the uname(2) system call.

    14.2 Process

    The Process module contains functions to start and control other programs from Pike.

    CLASS
    Process.create_process - Create a new process

    SYNTAX
    Process.create_process Process.create_process(array(string) command, void | mapping(string:mixed) modifiers);

    DESCRIPTION
    This is the recommended and most portable way to start processes in Pike. The command name and arguments are sent as an array of strings so that you do not have to worry about qouting them. The optional mapping modifiers can can contain zero or more of the following parameters:
    "cwd" : string dir
    This parameter executes the command in another directory than the current directory of this process. Please note that if the command is given is a relative path, it will be relative to this directory rather than the current directory of this process.
    "stdin" : Stdio.File stdin
    "stdout" : Stdio.File stdout
    "stderr" : Stdio.File stderr
    These parameters allows you to change the standard input, output and error streams of the newly created process. This is particularly useful in combination with Stdio.File->pipe.
    "env" : mapping(string:string) env
    This mapping will become the environment variables for the created process. Normally you will want to only add or change variables which can be achived by getting the environment mapping for this process with getenv. Example:
    (["env" : getenv() + (["TERM":"vt100"])
    .
    The following options are only available on some systems.
    "uid" : int|string uid
    This parameter changes which user the new process will execute as. Note that the current process must be running as root to use this option. The uid can be given either as an integer as a string containing the login name of that user. Please note that using a string here can be noticably slower than using an integer. The "gid" and "groups" for the new process will be set to the right values for that user unless overriden by opions blow. If maximum performance is an issue, you should use the "gid" and "group" options to set those values explicitly. (See setuid and getpwuid for more info)
    "gid" : int|string gid
    This parameter changes the primary group for the new process. When the new process creates files, they will will be created with this group. The group can either be given as an int or a string containing the name of the group. As with the "uid" parameters, integers are faster than numbers. (See setgid and getgrgid for more info)
    "setgroups" : array(int|string) groups
    This parameter allows you to the set the list of groups that the new process belongs to. It is recommended that if you use this parameter you supply at least one at no more than 16 groups. (Some system only supports 8 groups even...) The groups can be given as gids or as strings with the group names. If maximum performance is an issue, please use integers.
    "noinitgroups" : int(0..1) yesno
    This parameter overrides a behaviour of the "uid" parameter. If this parameter is used, the gid and groups of the new process will be inherited from the current process rather than changed to the approperiate values for that uid.
    "priority" : string pri
    This sets the priority of the new process, see set_priority for more info.
    "nice" : int nice
    This sets the nice level of the new process. Note that a negative number means higher priority positive numbers means higher priority. Only root may use negative numbers.
    "keep_signals" : int(0..1) yesno
    This prevents Pike to restore all signal handlers to their default value for the new process. Useful to ignore certain signals in the new process.
    "fds" : array(Stdio.File|zero) fds
    This parameter allows you to map files to filedescriptors 3 and up. The file fds[0] will be remapped to fd #3 in the new process, etc.
    These parameter limits the new process in certain ways, they are not available on all systems. Each of these can either be given as a mapping (["soft":soft_limit,"hard":hard_limit]) or as an integer. If an integer is given both the hard limit and the soft limit will be changed. The new process may change the soft limit, but may not change it any higher than the hard limit.
    "cpu" : int|mapping(string:int) seconds
    Limit the CPU time of the new process.
    "core" : int|mapping(string:int) bytes
    Limit the core file size.
    "data" : int|mapping(string:int) bytes
    Limit the data size of the new process.
    "fsize" : int|mapping(string:int) bytes
    Limits the maximum file size of the new process.
    "nofile" : int|mapping(string:int) num_files
    Maximum open files for the new process.
    "stack" : int|mapping(string:int) bytes
    Limit the stack size of the nwe process.
    "map_mem" : int|mapping(string:int) bytes
    "vmem" : int|mapping(string:int) vmem
    Maximum amount of mmapped memory.
    "as" : int|mapping(string:int) memory
    "mem" : int|mapping(string:int) memory
    Maximum amount of total memory.

    SEE ALSO
    Process.popen and Process.system

    METHOD
    Process.create_process.set_priority - Set the priority of this process

    SYNTAX
    int set_priority(string pri);

    DESCRIPTION
    This function sets the priority of this process, the string pri should be one of:
    "realtime" or "highest" This gives the process realtime priority, this basically gives the process access to the cpu whenever it wants.
    "higher" This gives the process higher priority than most other processes on your system.
    "high" This gives your proces a little bit higher priority than what is 'normal'.
    "normal" This sets the process' priority to whatever is 'normal' for new processes on your system.
    "low" This will give the process a lower priority than what is normal on your system.
    "lowest" This will give the process a lower priority than most processes on your system.

    METHOD
    Process.create_process.wait - Wait for this process to finish

    SYNTAX
    int wait();

    DESCRIPTION
    This function makes the calling thread wait for the process to finish. It returns the exit code of that process.

    METHOD
    Process.create_process.status - Check if process is still running

    SYNTAX
    int status();

    DESCRIPTION
    This function returns zero if the process is still running. If the process has exited, it will return one.

    METHOD
    Process.create_process.pid - Get the process id of this process

    SYNTAX
    int pid();

    DESCRIPTION
    This function returns the process identifier for the process.

    METHOD
    Process.create_process.kill - Kill this process

    SYNTAX
    int kill(int signal);

    DESCRIPTION
    This function sends the given signal to the process, it returns one if the operation succeded, zero otherwise.

    SEE ALSO
    signum

    FUNCTION
    Process.popen - pipe open

    SYNTAX
    string popen(string cmd);

    DESCRIPTION
    This function runs the command cmd as in a shell and returns the output. See your Unix/C manual for details on popen.

    FUNCTION
    Process.system - run an external program

    SYNTAX
    void system(string cmd);

    DESCRIPTION
    This function runs the external program cmd and waits until it is finished. Standard /bin/sh completions/redirections/etc. can be used.

    SEE ALSO
    Process.create_process, Process.popen, Process.exec and Process.spawn

    FUNCTION
    Process.spawn - spawn a process

    SYNTAX
    int spawn(string cmd);
    int spawn(string cmd, object stdin);
    int spawn(string cmd, object stdin, object stdout);
    int spawn(string cmd, object stdin, object stdout, object stderr);

    DESCRIPTION
    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.

    SEE ALSO
    Process.popen, fork, Process.exec, Stdio.File->pipe and Stdio.File->dup2

    FUNCTION
    Process.exece - execute a program

    SYNTAX
    int exece(string file, array(string) args);
    int exece(string file, array(string) args, mapping(string:string) env);

    DESCRIPTION
    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.

    NOTE
    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.

    EXAMPLE
    exece("/bin/ls", ({"-l"}));
    exece("/bin/sh", ({"-c", "echo $HOME"}), (["HOME":"/not/home"]));

    SEE ALSO
    fork and Stdio.File->pipe

    FUNCTION
    Process.exec - simple way to use exece()

    SYNTAX
    int exec(string file, string ... args);

    DESCRIPTION
    This function destroys the Pike parser and runs the program file 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.

    EXAMPLE
    exec("/bin/echo","hello","world");

    CLASS
    Process.Spawn - spawn off another program with control structure

    SYNTAX
    object Process.Spawn(string program, void|array(string) args, void|mapping(string:string) env, void|string cwd);
    or object Process.Spawn(string program, void|array(string) args, void|mapping(string:string) env, void|string cwd, array(void|object(Stdio.file)) fds, void|array(void|object(Stdio.file)) fds_to_close);

    DESCRIPTION
    Spawn off another program (program) and creates the control structure. This does not spawn off a shell to find the program, therefore must program be the full path the the program.

    args is per default no argument(s),

    env is reset to the given mapping, or kept if the argument is 0. fds is your stdin, stdout and stderr. Default is local pipes (see stdin et al). fds_to_close is file descriptors that are closed in the forked branch when the program is executed (ie, the other end of the pipes).

    VARIABLE
    Process.Spawn.stdin,
    Process.Spawn.stdout,
    Process.Spawn.stderr,
    Process.Spawn.fd - pipes to the program

    SYNTAX
    object(Stdio.File) stdin;
    object(Stdio.File) stdout;
    object(Stdio.File) stderr;
    array(void|object(Stdio.File)) fd;

    DESCRIPTION
    Pipes to the spawned program (if set). fd[0]==stdin, etc.

    VARIABLE
    Process.Spawn.pid - spawned program pid

    SYNTAX
    int pid;

    DESCRIPTION
    pid of the spawned program.

    METHOD
    Process.Spawn.wait - wait for the spawned program to finish

    SYNTAX
    void wait();

    DESCRIPTION
    Returns when the program has exited.

    METHOD
    Process.Spawn.kill - send a signal to the program

    SYNTAX
    int kill(int signal);

    DESCRIPTION
    Sends a signal to the program.

    14.3 Regexp

    Regexp is short for Regular Expression. 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.

    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.
    pattern  Matches
    .   any one character
    [abc]   a, b or c
    [a-z]   any character a to z inclusive
    [^ac]   any character except a and c
    (x)   x (x might be any regexp) If used with split, this also puts the string matching x into the result array.
    x*   zero or more occurrences of 'x' (x may be any regexp)
    x+   one or more occurrences of 'x' (x may be any regexp)
    x|y   x or y. (x or y may be any regexp)
    xy   xy (x and y may be any regexp)
    ^   beginning of string (but no characters)
    $   end of string (but no characters)
    \<   the beginning of a word (but no characters)
    \>   the end of a word (but no characters)
    Let's look at a few examples:
    Regexp Matches
    [0-9]+ one or more digits
    [^ \t\n] exactly one non-whitespace character
    (foo)|(bar) either 'foo' or 'bar'
    \.html$ any string ending in '.html'
    ^\. any string starting with a period

    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.

    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.

    You might wonder what regexps are good for, hopefully it should be more clear when you read about the following functions:

    METHOD
    Regexp.create - compile regexp

    SYNTAX
    void create();
    void create(string regexp);
    object(Regexp) Regexp();
    object(Regexp) Regexp(string regexp);

    DESCRIPTION
    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.

    SEE ALSO
    clone and Regexp->match

    METHOD
    Regexp.match - match a regexp

    SYNTAX
    int match(string s)

    DESCRIPTION
    Return 1 if s matches the regexp bound to the object regexp, zero otherwise.

    SEE ALSO
    Regexp->create and Regexp->split

    METHOD
    Regexp.split - split a string according to a pattern

    SYNTAX
    array(string) split(string s)

    DESCRIPTION
    Works as regexp->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.

    BUGS
    You can only have 40 sub-regexps.

    SEE ALSO
    Regexp->create and Regexp->match

    14.4 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..

    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.

    CLASS
    Gmp.mpz - bignum program

    DESCRIPTION
    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.

    The mpz object implements all the normal integer operations. (except xor) There are also some extra operators:

    NOTE
    This module is only available if libgmp.a was available and found when Pike was compiled.

    METHOD
    Gmp.mpz.create - initialize a bignum

    SYNTAX
    object Mpz();
    object Mpz(int|object|float i);
    object Mpz(string digits, int base);

    DESCRIPTION
    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.

    SEE ALSO
    clone

    METHOD
    Gmp.mpz.powm - raise and modulo

    SYNTAX
    object powm(int|string|float|object a,int|string|float|object b);

    DESCRIPTION
    This function returns ( mpz ** a ) % b. For example, Mpz(2)->powm(10,42); would return 16 since 2 to the power of 10 is 1024 and 1024 modulo 42 is 16.

    METHOD
    Gmp.mpz.sqrt - square root

    SYNTAX
    object sqrt();

    DESCRIPTION
    This function returns the truncated integer part of the square root of the value of mpz.

    METHOD
    Gmp.mpz.probably_prime_p - is this number a prime?

    SYNTAX
    int probably_prime_p();

    DESCRIPTION
    This function returns 1 if mpz is a prime, and 0 most of the time if it is not.

    METHOD
    Gmp.mpz.gcd - greatest common divisor

    SYNTAX
    object gcd(object|int|float|string arg)

    DESCRIPTION
    This function returns the greatest common divisor for arg and mpz.

    METHOD
    Gmp.mpz.cast - cast to other type

    SYNTAX
    object cast( "string" | "int" | "float" );
    (string) mpz
    (int) mpz
    (float) mpz

    DESCRIPTION
    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.

    SEE ALSO
    cast

    METHOD
    Gmp.mpz.digits - convert mpz to a string

    SYNTAX
    string digits();
    string digits(int|void base);

    DESCRIPTION
    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.

    SEE ALSO
    Gmp.mpz->cast

    METHOD
    Gmp.mpz.size - how long is a number

    SYNTAX
    string size();
    string size(int|void base);

    DESCRIPTION
    This function returns how long the mpz would be represented in the specified base. The default base is 2.

    SEE ALSO
    Gmp.mpz->digits

    14.5 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.

    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.

    METHOD
    Gdbm.gdbm.create - open database

    SYNTAX
    int create();
    int create(string file);
    int create(string file, string mode);
    object(Gdbm) Gdbm(); object(Gdbm) Gdbm(string file); object(Gdbm) Gdbm(string file, string mode);

    DESCRIPTION
    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:

    r open database for reading
    w open database for writing
    c create database if it does not exist
    t overwrite existing database
    f fast mode

    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.

    The default mode is "rwc".

    METHOD
    Gdbm.gdbm.close - close database

    SYNTAX
    void close();

    DESCRIPTION
    This closes the database.

    METHOD
    Gdbm.gdbm.store - store a value in the database

    SYNTAX
    int store(string key, string data);

    DESCRIPTION
    Associate the contents of data with the key key. If the key key 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.

    METHOD
    Gdbm.gdbm.fetch - fetch a value from the database

    SYNTAX
    string fetch(string key);

    DESCRIPTION
    Returns the data associated with the key key in the database. If there was no such key in the database, zero is returned.

    METHOD
    Gdbm.gdbm.delete - delete a value from the database

    SYNTAX
    int delete(string key);

    DESCRIPTION
    Remove a key from the database. Note that no error will be generated if the key does not exist.

    METHOD
    Gdbm.gdbm.firstkey - get first key in database

    SYNTAX
    string firstkey();

    DESCRIPTION
    Returns the first key in the database, this can be any key in the database.

    METHOD
    Gdbm.gdbm.nextkey - get next key in database

    SYNTAX
    string nextkey(string key);

    DESCRIPTION
    This returns the key in database that follows the key key. This is of course used to iterate over all keys in the database.

    EXAMPLE
    /* Write the contents of the database */
    for(key=gdbm->firstkey(); k; k=gdbm->nextkey(k))
    write(k+":"+gdbm->fetch(k)+"\n");

    METHOD
    Gdbm.gdbm.reorganize - reorganize database

    SYNTAX
    int reorganize();

    DESCRIPTION
    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.

    METHOD
    Gdbm.gdbm.sync - synchronize database

    SYNTAX
    void sync();

    DESCRIPTION
    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.

    14.6 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 (-t), the long ones consist of two dashes followed by a string of text (--test). The short options can also be combined, which means that you can write -tda instead of -t -d -a. Options can also require arguments, in which case they cannot be combined. To write an option with an argument you write -t argument or -targument or --test=argument.

    FUNCTION
    Getopt.find_option - find command line options

    SYNTAX

    mixed find_option(array(string) argv,

    string shortform,
    void|string longform,
    void|string envvar,
    void|mixed def,
    void|int throw_errors);

    DESCRIPTION
    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.

    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.

    NOTE
    find_option modifies argv.
    This function reads options even if they are written after the first non-option on the line.

    EXAMPLE
    /* This program tests two different options. One is called -f or * --foo and the other is called -b or --bar and can also be given * by using the BAR_OPTION environment variable. */

    int main(int argc, array(string) argv)
    {
        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");
    }

    SEE ALSO
    Getopt.get_args

    FUNCTION
    Getopt.find_all_options - find command line options

    SYNTAX
    array find_all_options(array(string) argv, array option, int|void posix_me_harder, int|void throw_errors);

    DESCRIPTION
    This function does the job of several calls to find_option. The main advantage of this is that it allows it to handle the POSIX_ME_HARDER environment variable better. When the either the argument posix_me_harder or the environment variable POSIX_ME_HARDER is true, no arguments will be parsed after the first non-option on the command line.

    Each element in the array options should be an array on the following form:

    ({
    string name,
    int type,
    string|array(string) aliases,
    void|string|array(string) env_var,
    void|mixed default
    })
    Only the first three elements has to be included.
    name
    Name is a tag used to identify the option in the output.
    type
    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 --version. MAY_HAVE_ARG should be used for options that may or may not need an argument.
    aliases
    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 aliases so find_all_options can distinguish between long and short options. Example: ({"-tT","--test"}) This would make find_all_options look for -t, -T and --test.
    env_var
    This is a string or an array of strings containing names of environment variables that can be used instead of the command line option.
    default
    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.
    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:
    ({
    string name,
    mixed value
    })
    The name is the identifier from the input and value is the value given to it from the argument, environment variable or default. If no default is given, value will be 1.

    NOTE
    find_all_options modifies argv.

    EXAMPLE
    First let's take a look at input and output:
    > Getopt.find_all_options(({"test","-dd"}),
    >>  ({ ({ "debug", Getopt.NO_ARG, ({"-d","--debug"}), "DEBUG", 1}) }));
    Result: ({
      ({ "debug",  1 }),
      ({ "debug",  1 })
    })
    

    This is what it would look like in real code:

    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);
    }

    SEE ALSO
    Getopt.get_args

    FUNCTION
    Getopt.get_args - get the non-option arguments

    SYNTAX
    array(string) get_args(array(string) argv,void|int throw_errors);

    DESCRIPTION
    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.

    EXAMPLE
    int main(int argc, array(string) argv)
    {
        if(find_option(argv,"f","foo"))
            werror("The FOO option was given.\n");

        argv=get_args(argv);
        werror("The arguments are: "+(argv*" ")+".\n");
    }

    SEE ALSO
    Getopt.find_option

    14.7 Gz

    The Gz module contains functions to compress and uncompress strings using the same algorithm as the program gzip. 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 algorithm 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.

    CLASS
    Gz.deflate - string packer

    DESCRIPTION
    Gz.inflate is a builtin program written in C. It interfaces the packing routines in the libz library.

    NOTE
    This program is only available if libz was available and found when Pike was compiled.

    SEE ALSO
    Gz.inflate

    METHOD
    Gz.deflate.create - initialize packer

    SYNTAX
    void create(int X)
    object(Gz.deflate) Gz.deflate(int X)

    DESCRIPTION
    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.

    This function can also be used to re-initialize a Gz.deflate object so it can be re-used.

    METHOD
    Gz.deflate.deflate - pack data

    SYNTAX
    string deflate(string data, int flush);

    DESCRIPTION
    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:

    Gz.NO_FLUSH Only data that doesn't fit in the internal buffers is returned.
    Gz.PARTIAL_FLUSH All input is packed and returned.
    Gz.SYNC_FLUSH All input is packed and returned.
    Gz.FINISH All input is packed and an 'end of data' marker is appended.

    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.

    SEE ALSO
    Gz.inflate->inflate

    CLASS
    Gz.inflate - string unpacker

    DESCRIPTION
    Gz.inflate is a builtin program written in C. It interfaces the packing routines in the libz library.

    NOTE
    This program is only available if libz was available and found when Pike was compiled.

    SEE ALSO
    Gz.deflate

    METHOD
    Gz.inflate.create - initialize unpacker

    SYNTAX
    void create()
    object(Gz.inflate) Gz.inflate()

    DESCRIPTION
    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.

    METHOD
    Gz.inflate.inflate - unpack data

    SYNTAX
    string inflate(string data);

    DESCRIPTION
    This function performs gzip style decompression. It can inflate a whole file at once or in blocks.

    EXAMPLE
    import Stdio;
    // whole file
    write(Gz.inflate()->inflate(stdin->read());

    // streaming (blocks)
    function inflate=Gz.inflate()->inflate;
    while(string s=stdin->read(8192))

    write(inflate(s));

    SEE ALSO
    Gz.deflate->deflate

    METHOD
    Gz.crc32 - calculate checksum

    SYNTAX
    string crc32(string data,void|int start_value);

    DESCRIPTION
    This method is usable for calculating checksums, and presents the standard ISO3309 Cyclic Redundancy Check.

    SEE ALSO
    Gz

    14.8 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.

    FUNCTION
    Yp.default_yp_domain - get the default Yp domain

    SYNTAX
    string default_yp_domain();

    DESCRIPTION
    Returns the default yp-domain.

    CLASS
    Yp.YpDomain - class representing an Yp domain

    SYNTAX
    object(Yp.YpDomain) Yp.YpDomain(string|void domain);

    DESCRIPTION
    This creates a new YpDomain object.

    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.

    If no domain is given, the default domain will be used. (As returned by Yp.default_yp_domain)

    METHOD
    Yp.YpDomain.bind - bind this object to another domain

    SYNTAX
    void bind(string|void domain);

    DESCRIPTION
    Re-bind the object to another (or the same) domain. If no domain is given, the default domain will be used.

    METHOD
    Yp.YpDomain.match - match a key in a map

    SYNTAX
    string match(string map, string key);

    DESCRIPTION
    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.

    arguments is the map Yp-map to search in. This must be a full map name, for example, you should use passwd.byname instead of just passwd. key is the key to search for. The key must match exactly, no pattern matching of any kind is done.

    EXAMPLE
    object dom = Yp.YpDomain();
    write(dom->match("passwd.byname", "root"));

    METHOD
    Yp.YpDomain.all - return the whole map

    SYNTAX
    mapping(string:string) all(string map);

    DESCRIPTION
    Returns the whole map as a mapping. map is the YP-map to search in. This must be the full map name, you have to use passwd.byname instead of just passwd.

    METHOD
    Yp.YpDomain.map - call a function for each entry in an Yp map

    SYNTAX
    void map(string map, function(string,string:void) over);

    DESCRIPTION
    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. map is the YP-map to search in. This must be the full map name, as an example, passwd.byname instead of just passwd.

    METHOD
    Yp.YpDomain.server - find an Yp server

    SYNTAX
    string server(string map);

    DESCRIPTION
    Returns the hostname of the server serving the map map. map is the YP-map to search in. This must be the full map name, as an example, passwd.byname instead of just passwd.

    METHOD
    Yp.YpDomain.order - get the 'order' for specified map

    SYNTAX
    int order(string map);

    DESCRIPTION
    Returns the 'order' number for the map map. This is usually a time_t (see the global function time()). When the map is changed, this number will change as well. map is the YP-map to search in. This must be the full map name, as an example, passwd.byname instead of just passwd.

    CLASS
    Yp.YpMap - class representing one Yp map

    SYNTAX
    object(Yp.YpMap) Yp.Ypmap(string map, string|void domain);

    DESCRIPTION
    This creates a new YpMap object.

    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. map 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.

    METHOD
    Yp.YpMap.match - find key in map

    SYNTAX
    string match(string key)
    ; string Yp.YpMap[string key];

    DESCRIPTION
    Search for the key key. If there is no key in the map, 0 will be returned, otherwise the string matching the key will be returned. key must match exactly, no pattern matching of any kind is done.

    METHOD
    Yp.YpMap.all - return the whole map as a mapping

    SYNTAX
    mapping(string:string) all();
    (mapping) Yp.YpMap;

    DESCRIPTION
    Returns the whole map as a mapping.

    METHOD
    Yp.YpMap.map - call a function for each entry in the map

    SYNTAX
    void map(function(string,string:void) over);

    DESCRIPTION
    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)'.

    METHOD
    Yp.YpMap.server - find what server servers this map

    SYNTAX
    string server();

    DESCRIPTION
    Returns the hostname of the server serving this map.

    METHOD
    Yp.YpMap.order - find the 'order' of this map

    SYNTAX
    int order();

    DESCRIPTION
    Returns the 'order' number for this map. This is usually a time_t (see the global function time())

    METHOD
    Yp.YpMap._sizeof - return the number of entries in the map

    SYNTAX
    int sizeof(Yp.YpMap);

    DESCRIPTION
    Returns the number of entries in the map. This is equivalent to sizeof((mapping)map);

    METHOD
    Yp.YpMap._indices - return the indices from the map

    SYNTAX
    array(string) indices(Yp.YpMap)

    DESCRIPTION
    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.

    SEE ALSO
    Yp.YpMap->_values

    METHOD
    Yp.YpMap._values - return the values from the map

    SYNTAX
    array(string) values(Yp.Ypmap)

    DESCRIPTION
    Returns the values of the map. If values is called first, indices must be called immediately after. If indices is called first, it is the other way around.

    SEE ALSO
    Yp.YpMap->_indices
    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.
    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->server() + "\n"
         "age....... "+ (-o->order()+time()) + "\n"
         "per....... "+ o["per"] + "\n"
         "size...... "+ sizeof(o) + "\n");
        
        o->map(print_entry); // Print username/GECOS pairs
    }

    14.9 ADT.Table

    ADT.Table is a generic module for manipulating tables. Each table contains one or several columns. Each column is associated with a name, the column name. Optionally, one can provide a column type. The Table module can do a number of operations on a given table, like computing the sum of a column, grouping, sorting etc.

    All column references are case insensitive. A column can be referred to by its position (starting from zero). All operations are non-destructive. That means that a new table object will be returned after, for example, a sort.

    An example is available at the end of this section.

    METHOD
    ADT.Table.table.create - create a table object

    SYNTAX
    void create(array(array) table, array(string) column_names, array(mapping)|void column_types);

    DESCRIPTION
    The table class takes two or three arguments:

    1. table is a two-dimensional array consisting of one array of columns per row. All rows must have the same number of columns as specified in column_names.

    2. column_names is an array of column names associated with each column in the table. References by column name are case insensitive. The case used in column_names will be used when the table is displayed. A column can also be referred to by its position, starting from zero.

    3. column_types is an optional array of mappings. The column type information is only used when displaying the table. Currently, only the keyword "type" is recognized. The type can be specified as "text" or "num" (numerical). Text columns are left adjusted, whereas numerical columns are right adjusted. If a mapping in the array is 0 (zero), it will be assumed to be a text column. If column_types is omitted, all columns will displayed as text. See ADT.Table.ASCII.encode on how to display a table.

    EXAMPLE
    object t = ADT.Table.table( ({ ({ "Blixt", "Gordon" }),
    ({ "Buck", "Rogers" }) }),
    ({ "First name", "Last name" }) );

    SEE ALSO
    ADT.Table.ASCII.encode

    METHOD
    ADT.Table.table._indices - gives the column names

    SYNTAX
    array(string) _indices();

    DESCRIPTION
    This method returns the column names for the table. The case used when the table was created will be returned.

    METHOD
    ADT.Table.table._values - gives the table contents

    SYNTAX
    array(array) _values();

    DESCRIPTION
    This method returns the contents of a table as a two dimensional array. The format is an array of rows. Each row is an array of columns.

    METHOD
    ADT.Table.table._sizeof - gives the number of table rows

    SYNTAX
    int _sizeof();

    DESCRIPTION
    This method returns the number of rows in the table.

    METHOD
    ADT.Table.table.reverse - reverses the table rows

    SYNTAX
    object reverse();

    DESCRIPTION
    This method reverses the rows of the table and returns a new table object.

    METHOD
    ADT.Table.table.rename - rename a column

    SYNTAX
    object rename(string|int from, string to);

    DESCRIPTION
    This method renames the column named from to to and returns a new table object. Note that from can be the column position.

    METHOD
    ADT.Table.table.type - fetch or set the type for a column

    SYNTAX
    mapping type(string|int column, mapping|void type);

    DESCRIPTION
    This method gives the type for the given column. If a second argument is given, the old type will be replaced with type. The column type is only used when the table is displayed. The format is as specified in create.

    METHOD
    ADT.Table.table.limit - truncate the table

    SYNTAX
    object limit(int n);

    DESCRIPTION
    This method truncates the table to the first n rows and returns a new object.

    METHOD
    ADT.Table.table.sort - sort the table on one or several columns

    SYNTAX
    object sort(string|int column1, string|int column2, ...);

    DESCRIPTION
    This method sorts the table in ascendent order on one or several columns and returns a new table object. The left most column is sorted last. Note that the sort is stable.

    METHOD
    ADT.Table.table.rsort - sort the table in reversed order on one or several columns

    SYNTAX
    object rsort(string|int column1, string|int column2, ...);

    DESCRIPTION
    Like sort, but the order is descendent.

    METHOD
    ADT.Table.table.distinct - keep unique rows only

    SYNTAX
    object distinct(string|int column1, string|int column2, ...);

    DESCRIPTION
    This method groups by the given columns and returns a table with only unique rows. When no columns are given, all rows will be unique. A new table object will be returned.

    METHOD
    ADT.Table.Table.table.sum - computes the sum of equal rows

    SYNTAX
    object sum(string|int column1, string|int column2, ...);

    DESCRIPTION
    This method sums all equal rows. The table will be grouped by the columns not listed. The result will be returned as a new table object.

    METHOD
    ADT.Table.table.group - group the table using functions

    SYNTAX
    object group(mapping(string|int:funcion) fus, mixed ... arg);
    object group(funcion f, array(string|int)|string|int columns, mixed ... arg);

    DESCRIPTION
    This method calls the function for each column each time a non uniqe row will be joined. The table will be grouped by the columns not listed. The result will be returned as a new table object.

    METHOD
    ADT.Table.table.map - map columns over a function

    SYNTAX
    object map(funcion fu, string|int|array(int|string) columns, mixed ... arg);

    DESCRIPTION
    This method calls the function for all rows in the table. The value returned will replace the values in the columns given as argument to map. If the function returns an array, several columns will be replaced. Otherwise the first column will be replaced. The result will be returned as a new table object.

    METHOD
    ADT.Table.table.where - filter the table through a function

    SYNTAX
    object where(array(string|int)|string|int column1, funcion fu, mixed ... arg);

    DESCRIPTION
    This method calls the function for each row. If the function returns zero, the row will be thrown away. If the function returns something non-zero, the row will be kept. The result will be returned as a new table object.

    METHOD
    ADT.Table.table.select - keep only the given columns

    SYNTAX
    object select(string|int column1, string|int column2, ...);

    DESCRIPTION
    This method returns a new table object with the selected columns only.

    METHOD
    ADT.Table.table.remove - remove columns

    SYNTAX
    object remove(string|int column1, string|int column2, ...);

    DESCRIPTION
    Like select, but the given columns will not be in the resulting table.

    METHOD
    ADT.Table.table.encode - represent the table as a binary string

    SYNTAX
    string encode();

    DESCRIPTION
    This method returns a binary string representation of the table. It is useful when one wants to store a table, for example in a file.

    METHOD
    ADT.Table.table.decode - decode an encoded table

    SYNTAX
    string decode(string table_string);

    DESCRIPTION
    This method returns a table object from a binary string representation of a table.

    METHOD
    ADT.Table.table.col - fetch a column

    SYNTAX
    array col(string|int column);

    DESCRIPTION
    This method returns the contents of a given column as an array.

    METHOD
    ADT.Table.table.`[] - fetch a column

    SYNTAX
    array `[](string|int column);

    DESCRIPTION
    Same as col.

    METHOD
    ADT.Table.table.row - fetch a row

    SYNTAX
    array row(int row_number);

    DESCRIPTION
    This method returns the contents of a given row as an array.

    METHOD
    ADT.Table.table.`== - compare two tables

    SYNTAX
    int `==(object table);

    DESCRIPTION
    This method compares two tables. They are equal if the contents of the tables and the column names are equal. The column name comparison is case insensitive.

    METHOD
    ADT.Table.table.append_bottom - concatenate two tables

    SYNTAX
    object append_bottom(object table);

    DESCRIPTION
    This method appends two tables. The table given as an argument will be added at the bottom of the current table. Note, the column names must be equal. The column name comparison is case insensitive.

    METHOD
    ADT.Table.table.append_right - concatenate two tables

    SYNTAX
    object append_right(object table);

    DESCRIPTION
    This method appends two tables. The table given as an argument will be added on the right side of the current table. Note that the number of rows in both tables must be equal.

    METHOD
    ADT.Table.ASCII.encode - produces an ASCII formated table

    SYNTAX
    string encode(object table, mapping|void options);

    DESCRIPTION
    This method returns a table represented in ASCII suitable for human eyes. options is an optional mapping. If the keyword "indent" is used with a number, the table will be indented with that number of space characters.

    EXAMPLE
    array(string) cols = ({ "Fruit", "Provider", "Quantity" });
    array(mapping) types = ({ 0, 0, ([ "type":"num" ]) });
    array(array) table = ({ ({ "Avocado", "Frukt AB", 314 }),
                                                        ({ "Banana", "Banankompaniet", 4276 }),
         ({ "Orange", "Frukt AB", 81 }),
         ({ "Banana", "Frukt AB", 1174 }),
         ({ "Orange", "General Food", 523 }) });

    object t = ADT.Table.table(table, cols, types);

    write("FRUITS\n\n");
    write(ADT.Table.ASCII.encode(t, ([ "indent":4 ])));

    write("\nPROVIDERS\n\n");
    write(ADT.Table.ASCII.encode(t->select("provider", "quantity")->
             sum("quantity")->rsort("quantity")));

    write("\nBIG PROVIDERS\n\n"+
                ADT.Table.ASCII.encode(t->select("provider", "quantity")->
         sum("quantity")->
         where("quantity", `>, 1000)->
         rsort("quantity")));

    write("\nASSORTMENT\n\n");

    write(ADT.Table.ASCII.encode(t->select("fruit")->distinct("fruit")->
         sort("fruit"), ([ "indent":4 ])));

    14.10 Yabu transaction database

    Yabu is a all purpose database, used to store data records associated with a unique key. Yabu is very similar to mappings, however, records are stored in files and not in memory. Also, Yabu features tables, which is a way to handle several mapping-like structures in the same database. A characteristic feature of Yabu is that it allows for transactions. A transaction is a sequence of database commands that will be accepted in whole, or not at all.

    Some effort has been made to make sure that Yabu is crash safe. This means that the database should survive process kills, core dumps and such -- although this is not something that can be absolutely guaranteed. Also, all non-commited and pending transactions will be cancelled in case of a crash.

    Yabu uses three types of objects, listed below:

    A simple example is illustrated below.

    EXAMPLE
    // Create a database called "my.database" in write/create mode.
    object db = Yabu.db("my.database", "wc");

    // Create a table called "fruit".
    object table = db["fruit"];

    // Store a record called "orange" with the value "yummy".
    table["orange"] = "yummy";

    // Store a record called "apple" with the value 42.
    table["apple"] = 42;

    Transactions are slightly more complex, but not much so. See example below.

    EXAMPLE
    // Create a database called "my.database"
    // in write/create/transaction mode.
    object db = Yabu.db("my.database", "wct");

    // Create a table called "fruit".
    object table = db["fruit"];

    // Create a transaction object for table "fruit".
    object transaction = table->transaction();

    // Store a record called "orange" with
    // the value "yummy". Note that this record
    // is only visible through the transaction object.
    transaction["orange"] = "yummy";

    // Store a record called "apple" with the value 42.
    // As with "orange", this record is invisible
    // for all objects except this transaction object.
    transaction["apple"] = 42;

    // Commit the records "orange" and "apple".
    // These records are now a part of the database.
    transaction->commit();

    14.10.1 The database

    The db object is the main Yabu database object. It is used to open the database and it can create table objects.

    A Yabu database can operate in two basic modes:

    • Read mode. In read mode, nothing in the database can be altered, added nor deleted. All Yabu files will be opended in read mode, which means that the database will be in the same state on the disk as it was prior to the opening.
    • Write mode. In write mode, records can be altered, added or deleted. In combination with create mode, new tables can also be added. Transactions can optionally be used with write mode. When compressed mode is enabled, all records will be compressed before stored on to disk.
    Compressed databases opened without compress mode enabled will be handled correctly in both modes, provided that the Gz module is available. However, new records will no longer be compressed in write mode.

    METHOD
    Yabu.db.create - Open a Yabu database

    SYNTAX
    void create(string directory, string mode);

    DESCRIPTION
    Create takes two arguments:

    1. directory is a string specifying the directory where Yabu will store its files. Yabu will create the directory if it does not exist, provided Yabu is opened in write and create mode (see below).

    2. mode is a string specifying the mode in which Yabu will operate. There are five switches available:

    NOTE
    It is very important not to open the same a database more than once at a time. Otherwise there will be conflicts and most likely strange failures and unpredictable behaviours. Yabu does not check weather a database is already open or not.

    EXAMPLE
    // Open a database in create/write/transaction mode.
    object db = Yabu.db("my.database", "cwt");

    // Open a database in read mode.
    object db = Yabu.db("my.database", "r");

    // Open a database in create/write/compress mode.
    object db = Yabu.db("my.database", "cwC");

    SEE ALSO
    Yabu.db->table, Yabu.db->list_tables, Yabu.db->sync and Yabu.db->purge

    METHOD
    Yabu.db.table - Open a table

    SYNTAX
    object(table) table(string table_name);
    object(table) `[](string table_name);

    DESCRIPTION
    This method opens a table with table_name. If the table does not exist, it will be created. A table object will be returned.

    SEE ALSO
    Yabu.db->list_tables, Yabu.db->sync and Yabu.db->purge

    METHOD
    Yabu.db.list_tables - List all tables

    SYNTAX
    array(string) list_tables();
    array(string) _indices();

    DESCRIPTION
    This method lists all available tables.

    SEE ALSO
    Yabu.db->table, Yabu.db->sync, Yabu.db->purge and Yabu.db->_values

    METHOD
    Yabu.db._values - Get all tables

    SYNTAX
    array(Yabu.table) _values();

    DESCRIPTION
    This method returns all available tables.

    SEE ALSO
    Yabu.db->table, Yabu.db->sync, Yabu.db->purge and Yabu.db->_indices

    METHOD
    Yabu.db.sync - Synchronize database

    SYNTAX
    void sync();

    DESCRIPTION
    This method synchronizes the database on disk. Yabu stores some information about the database in memory for performance reasons. Syncing is recommended when one wants the information on disk to be updated with the current information in memory.

    SEE ALSO
    Yabu.db->table, Yabu.db->list_tables and Yabu.db->purge

    METHOD
    Yabu.db.purge - Delete database

    SYNTAX
    void purge();

    DESCRIPTION
    This method deletes the whole database and all database files stored on disk.

    SEE ALSO
    Yabu.db->table, Yabu.db->list_tables and Yabu.db->sync

    14.10.2 Tables

    The table object is used to store and retrieve information from a table. Table objects are created by the db class. A table object can create a transaction object.

    METHOD
    Yabu.table.set - Store a record in a table

    SYNTAX
    mixed set(string key, mixed data);
    mixed `[]=(string key, mixed data);

    DESCRIPTION
    This method stores the contents of data as a record with the name key. If a record with that name already exists, it will be replaced. Records can only be added to the database in write mode.

    SEE ALSO
    Yabu.table->get, Yabu.table->delete, Yabu.table->list_keys and Yabu.table->purge

    METHOD
    Yabu.table.get - Fetch a record from a table

    SYNTAX
    mixed get(string key);
    mixed `[](string key);

    DESCRIPTION
    This method fetches the data associated with the record name key. If a record does not exist, zero is returned.

    SEE ALSO
    Yabu.table->set, Yabu.table->delete, Yabu.table->list_keys and Yabu.table->purge

    METHOD
    Yabu.table.list_keys - List the records in a table

    SYNTAX
    array(string) list_keys();
    array(string) _indices();

    DESCRIPTION
    This method lists all record names in the table.

    SEE ALSO
    Yabu.table->set, Yabu.table->get, Yabu.table->delete, Yabu.table->purge and Yabu.table->_values

    METHOD
    Yabu.table._values - Get all the records in a table

    SYNTAX
    array(mixed) _values();

    DESCRIPTION
    This method returns all record names in the table.

    SEE ALSO
    Yabu.table->set, Yabu.table->get, Yabu.table->delete, Yabu.table->purge and Yabu.table->_indices

    METHOD
    Yabu.table.delete - Delete a record in a table

    SYNTAX
    void delete(string key);

    DESCRIPTION
    This method deletes the record with the name key.

    SEE ALSO
    Yabu.table->set, Yabu.table->get, Yabu.table->list_keys and Yabu.table->purge

    METHOD
    Yabu.table.purge - Delete a table

    SYNTAX
    void purge();

    DESCRIPTION
    This method deletes the whole table and the table files on disk.

    SEE ALSO
    Yabu.table->set, Yabu.table->get, Yabu.table->list_keys and Yabu.table->delete

    METHOD
    Yabu.table.transaction - Begin a transaction

    SYNTAX
    object(transaction) transaction();

    DESCRIPTION
    A transaction is a sequence of table commands that will be accepted in whole, or not at all. If the program for some reason crashes or makes an abrupt exit during a transaction, the transaction is cancelled.

    This method returns a transaction object.

    SEE ALSO
    Yabu.transaction->commit and Yabu.transaction->rollback

    14.10.3 Transactions

    Transactions make it possible to alter, add or delete several database records and guarantee that all changes, or no changes, will be accepted by the database. A transaction object is basically a table object with a few restrictions and additions, listed below:

    • Purge is not available in a transaction object.
    • Commit. In order to make all changes take affect, commit must be issued at the end of a transaction sequence. Changes done by a transaction object will never take affect before commit, even if the database is shut down, the program crashes etc.
    • Rollback. A rollback cancels all changes made by the transaction object.

    Rollbacks always succeeds. However, with commit that is not always the case. A commit will fail if:

    • A record that is altered by the transaction object is altered again by something else, before commit. This is called a conflict, and will result in an error upon commit.

    METHOD
    Yabu.transaction.commit - Commit a transaction

    SYNTAX
    void commit();

    DESCRIPTION
    This method commits the changes made in a transaction. If a record affected by the transaction is altered during the transaction, a conflict will arise and an error is thrown.

    SEE ALSO
    Yabu.table->transaction and Yabu.transaction->rollback

    METHOD
    Yabu.transaction.rollback - Rollback a transaction

    SYNTAX
    void rollback();

    DESCRIPTION
    This method cancels a transaction. All changes made in the transaction are lost.

    SEE ALSO
    Yabu.table->transaction and Yabu.transaction->commit

    14.11 MIME

    RFC1521, the Multipurpose Internet Mail Extensions memo, defines a structure which 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 RFC822, 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:
    Headers
    Body
    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.

    The Message class does not make any interpretation of the body data, unless the content type is multipart. A multipart message contains several individual messages separated by boundary strings. The create 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 body_parts 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:

    14.11.1 Global functions

    FUNCTION
    MIME.decode - Remove transfer encoding

    SYNTAX
    string decode(string data, string encoding);

    DESCRIPTION
    Extract raw data from an encoded string suitable for transport between systems. The encoding can be any of
    • 7bit
    • 8bit
    • base64
    • binary
    • quoted-printable
    • x-uue
    • x-uuencode
    The encoding string is not case sensitive.

    SEE ALSO
    MIME.encode

    FUNCTION
    MIME.decode_base64 - Decode <tt>base64</tt> transfer encoding

    SYNTAX
    string decode_base64(string encoded_data);

    DESCRIPTION
    This function decodes data encoded using the base64 transfer encoding.

    SEE ALSO
    MIME.encode_base64

    FUNCTION
    MIME.decode_qp - Decode <tt>quoted-printable</tt> transfer encoding

    SYNTAX
    string decode_qp(string encoded_data);

    DESCRIPTION
    This function decodes data encoded using the quoted-printable (a.k.a. quoted-unreadable) transfer encoding.

    SEE ALSO
    MIME.encode_qp

    FUNCTION
    MIME.decode_uue - Decode <tt>x-uue</tt> transfer encoding

    SYNTAX
    string decode_uue(string encoded_data);

    DESCRIPTION
    This function decodes data encoded using the x-uue transfer encoding. It can also be used to decode generic UUEncoded files.

    SEE ALSO
    MIME.encode_uue

    FUNCTION
    MIME.decode_word - De-scramble RFC1522 encoding

    SYNTAX
    array(string) decode_word(string word);

    DESCRIPTION
    Extracts the textual content and character set from an encoded word 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.

    EXAMPLE
    > 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"
            })
    })

    SEE ALSO
    MIME.encode_word

    FUNCTION
    MIME.encode - Apply transfer encoding

    SYNTAX
    string encode(string data, string encoding,
    void|string filename,
    void|int no_linebreaks);

    DESCRIPTION
    Encode raw data into something suitable for transport to other systems. The encoding can be any of
    • 7bit
    • 8bit
    • base64
    • binary
    • quoted-printable
    • x-uue
    • x-uuencode
    The encoding string is not case sensitive. For the x-uue encoding, an optional filename string may be supplied. If a nonzero value is passed as no_linebreaks, the result string will not contain any linebreaks (base64 and quoted-printable only).

    SEE ALSO
    MIME.decode

    FUNCTION
    MIME.encode_base64 - Encode string using <tt>base64</tt> transfer encoding

    SYNTAX
    string encode_base64(string data, void|int no_linebreaks);

    DESCRIPTION
    This function encodes data using the base64 transfer encoding. If a nonzero value is passed as no_linebreaks, the result string will not contain any linebreaks.

    SEE ALSO
    MIME.decode_base64

    FUNCTION
    MIME.encode_qp - Encode string using <tt>quoted-printable</tt> transfer encoding

    SYNTAX
    string encode_qp(string data, void|int no_linebreaks);

    DESCRIPTION
    This function encodes data using the quoted-printable (a.k.a. quoted-unreadable) transfer encoding. If a nonzero value is passed as no_linebreaks, the result string will not contain any linebreaks.

    NOTE
    Please do not use this function. QP is evil, and there's no excuse for using it.

    SEE ALSO
    MIME.decode_qp

    FUNCTION
    MIME.encode_uue - Encode string using <tt>x-uue</tt> transfer encoding

    SYNTAX
    string encode_uue(string encoded_data, void|string filename);

    DESCRIPTION
    This function encodes data using the x-uue 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.

    SEE ALSO
    MIME.decode_uue

    FUNCTION
    MIME.encode_word - Encode word according to RFC1522

    SYNTAX
    string encode_word(array(string) word, string encoding);

    DESCRIPTION
    Create an encoded word 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 "base64" or "quoted-printable" (or either "b" or "q" 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.

    EXAMPLE
    > MIME.encode_word( ({ "Quetzalcoatl", "iso-8859-1" }), "base64" );
    Result: =?iso-8859-1?b?UXVldHphbGNvYXRs?=
    > MIME.encode_word( ({ "Foo", 0 }), "base64" );
    Result: Foo
    

    SEE ALSO
    MIME.decode_word

    FUNCTION
    MIME.generate_boundary - Create a suitable boundary string for multiparts

    SYNTAX
    string generate_boundary();

    DESCRIPTION
    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 base64, quoted-printable, or x-uue encoded data. It is also unlikely to appear in normal text. This function is used by the cast method of the Message class if no boundary string is specified.

    FUNCTION
    MIME.guess_subtype - Provide a reasonable default for the subtype field

    SYNTAX
    string guess_subtype(string type);

    DESCRIPTION
    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 the type of a message. (This is done automatically by the MIME.Message class.) Currently, the function uses the following guesses:
    typesubtype
    textplain
    messagerfc822
    multipartmixed

    FUNCTION
    MIME.parse_headers - Separate a bytestream into headers and body

    SYNTAX
    array(mapping(string:string)|string) parse_headers(string message);

    DESCRIPTION
    This is a low level function that will separate the headers from the body of an encoded message. It will also translate the headers into a mapping. It will however not try to analyze the meaning of any particular header, This also means that the body is returned as is, with any transfer-encoding intact. It is possible to call this function with just the header part of a message, in which case an empty body will be returned.

    The result is returned in the form of an array containing two elements. The first element is a mapping containing the headers found. The second element is a string containing the body.

    FUNCTION
    MIME.quote - Create an RFC822 header field from lexical elements

    SYNTAX
    string quote(array(string|int) lexical_elements);

    DESCRIPTION
    This function is the inverse of the tokenize function. A header field value is constructed from a sequence of lexical elements. Characters (ints) are taken to be special-characters, whereas strings are encoded as atoms or quoted-strings, depending on whether they contain any special characters.

    EXAMPLE
    > MIME.quote( ({ "attachment", ';', "filename", '=', "/usr/dict/words" }) );
    Result: attachment;filename="/usr/dict/words"
    

    NOTE
    There is no way to construct a domain-literal using this function. Neither can it be used to produce comments.

    SEE ALSO
    MIME.tokenize

    FUNCTION
    MIME.reconstruct_partial - Join a fragmented message to its original form

    SYNTAX
    int|object reconstruct_partial(array(object) collection);

    DESCRIPTION
    This function will attempt to reassemble a fragmented message from its parts. The array collection should contain MIME.Message 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.

    Should the function succeed in reconstructing the original message, a new MIME.Message 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:

    • If an empty collection is passed in, or one that contains messages which are not of type message/partial, or parts of different fragmented messages, the function returns 0.
    • If more fragments are needed to reconstruct the entire message, the number of additional messages needed is returned.
    • If more fragments are needed, but the function can't tell exactly how many, -1 is returned.

    SEE ALSO
    MIME.Message->is_partial

    FUNCTION
    MIME.tokenize - Separate an RFC822 header field into lexical elements

    SYNTAX
    array(string|int) tokenize(string header);

    DESCRIPTION
    A structured header field, as specified by RFC822, is constructed from a sequence of lexical elements. These are:
    • individual special characters
    • quoted-strings
    • domain-literals
    • comments
    • atoms
    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. ints). Quoted-strings, domain-literals and atoms will be decoded and returned as strings. Comments are not returned in the array at all.

    EXAMPLE
    > MIME.tokenize("multipart/mixed; boundary=\"foo/bar\" (Kilroy was here)");
    Result: ({ /* 7 elements */
        "multipart",
        47,
        "mixed",
        59,
        "boundary",
        61,
        "foo/bar"
    })
    

    NOTE
    As domain-literals are returned as strings, there is no way to tell the domain-literal [127.0.0.1] from the quoted-string "[127.0.0.1]". Hopefully this won't cause any problems. Domain-literals are used seldom, if at all, anyway...

    The set of special-characters is the one specified in RFC1521 (i.e. "<", ">", "@", ",", ";", ":", "\", "/", "?", "="), and not the one specified in RFC822.

    SEE ALSO
    MIME.quote

    14.11.2 The MIME.Message class

    CLASS
    MIME.Message - The MIME.Message class This class is used to hold a decoded MIME message.

    14.11.2.1 Public fields

    VARIABLE
    MIME.Message.body_parts - Multipart sub-messages

    SYNTAX
    array(object) msg->body_parts;

    DESCRIPTION
    If the message is of type multipart, this is an array containing one Message object for each part of the message. If the message is not a multipart, this field is 0.

    SEE ALSO
    MIME.Message->type and MIME.Message->boundary

    VARIABLE
    MIME.Message.boundary - Boundary string for multipart messages

    SYNTAX
    string msg->boundary;

    DESCRIPTION
    For multipart messages, this Content-Type 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.

    SEE ALSO
    MIME.Message->setboundary

    VARIABLE
    MIME.Message.charset - Character encoding for text bodies

    SYNTAX
    string msg->charset;

    DESCRIPTION
    One of the possible parameters of the Content-Type header is the charset attribute. It determines the character encoding used in bodies of type text. If there is no Content-Type header, the value of this field is "us-ascii".

    SEE ALSO
    MIME.Message->type

    VARIABLE
    MIME.Message.disposition - Multipart subpart disposition

    SYNTAX
    string msg->disposition;

    DESCRIPTION
    The first part of the Content-Disposition header, hinting on how this part of a multipart message should be presented in an interactive application. If there is no Content-Disposition header, this field is 0.

    VARIABLE
    MIME.Message.disp_params - Content-Disposition parameters

    SYNTAX
    mapping(string:string) msg->disp_params;

    DESCRIPTION
    A mapping containing all the additional parameters to the Content-Disposition header.

    SEE ALSO
    MIME.Message->setdisp_param and MIME.Message->get_filename

    VARIABLE
    MIME.Message.headers - All header fields of the message

    SYNTAX
    mapping(string:string) msg->headers;

    DESCRIPTION
    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 not be accessed through this mapping. These fields are currently:
    • content-type
    • content-disposition
    • content-length
    • content-transfer-encoding
    The contents of these fields can be accessed and/or modified through a set of variables and methods available for this purpose.

    SEE ALSO
    MIME.Message->type, MIME.Message->subtype, MIME.Message->charset, MIME.Message->boundary, MIME.Message->transfer_encoding, MIME.Message->params, MIME.Message->disposition, MIME.Message->disp_params, MIME.Message->setencoding, MIME.Message->setparam, MIME.Message->setdisp_param, MIME.Message->setcharset and MIME.Message->setboundary

    VARIABLE
    MIME.Message.params - Content-Type parameters

    SYNTAX
    mapping(string:string) msg->params;

    DESCRIPTION
    A mapping containing all the additional parameters to the Content-Type header. Some of these parameters have fields of their own, which should be accessed instead of this mapping wherever applicable.

    SEE ALSO
    MIME.Message->charset, MIME.Message->boundary and MIME.Message->setparam

    VARIABLE
    MIME.Message.subtype - The subtype attribute of the Content-Type header

    SYNTAX
    string msg->subtype;

    DESCRIPTION
    The Content-Type header contains a type, a subtype, and optionally some parameters. This field contains the subtype attribute extracted from the header. If there is no Content-Type header, the value of this field is "plain".

    SEE ALSO
    MIME.Message->type and MIME.Message->params

    VARIABLE
    MIME.Message.transfer_encoding - Body encoding method

    SYNTAX
    string msg->transfer_encoding;

    DESCRIPTION
    The contents of the Content-Transfer-Encoding header. If no Content-Transfer-Encoding header is given, this field is 0. 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.

    SEE ALSO
    MIME.Message->setencoding

    VARIABLE
    MIME.Message.type - The type attribute of the Content-Type header

    SYNTAX
    string msg->type;

    DESCRIPTION
    The Content-Type header contains a type, a subtype, and optionally some parameters. This field contains the type attribute extracted from the header. If there is no Content-Type header, the value of this field is "text".

    SEE ALSO
    MIME.Message->subtype and MIME.Message->params

    14.11.2.2 Public methods

    METHOD
    MIME.Message.cast - Encode message into byte stream

    SYNTAX
    string (string )MIME.Message;

    DESCRIPTION
    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 generate_boundary.

    EXAMPLE
    > 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==

    SEE ALSO
    MIME.Message->create

    METHOD
    MIME.Message.create - Create a Message object

    SYNTAX
    object MIME.Message(void | string message,
    void | mapping(string:string) headers,
    void | array(object) parts);

    DESCRIPTION
    There are several ways to call the constructor of the Message class;
    • With zero arguments, you will get a dummy message without either headers or body. Not very useful.
    • 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.
    • 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.

    EXAMPLE
    > 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

    SEE ALSO
    MIME.Message->cast

    METHOD
    MIME.Message.getdata - Obtain raw body data

    SYNTAX
    string getdata();

    DESCRIPTION
    This method returns the raw data of the message body entity. The type and subtype attributes indicate how this data should be interpreted.

    SEE ALSO
    MIME.Message->getencoded

    METHOD
    MIME.Message.getencoded - Obtain encoded body data

    SYNTAX
    string getencoded();

    DESCRIPTION
    This method returns the data of the message body entity, encoded using the current transfer encoding. You should never have to call this function.

    SEE ALSO
    MIME.Message->getdata

    METHOD
    MIME.Message.get_filename - Get supplied filename for body data

    SYNTAX
    string get_filename();

    DESCRIPTION
    This method tries to find a suitable filename should you want to save the body data to disk. It will examine the filename attribute of the Content-Disposition header, and failing that the name attribute of the Content-Type header. If neither attribute is set, the method returns 0.

    NOTE
    An interactive application should always query the user for the actual filename to use. This method may provide a reasonable default though.

    METHOD
    MIME.Message.is_partial - Identify <tt>message/partial</tt> message

    SYNTAX
    array(string|int) is_partial();

    DESCRIPTION
    If this message is a part of a fragmented message (i.e. has a Content-Type of message/partial), 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.

    SEE ALSO
    MIME.reconstruct_partial

    METHOD
    MIME.Message.setboundary - Set boundary parameter

    SYNTAX
    void setboundary(string boundary);

    DESCRIPTION
    Sets the boundary parameter of the Content-Type header. This is equivalent of calling msg->setparam("boundary", boundary).

    SEE ALSO
    MIME.Message->setparam

    METHOD
    MIME.Message.setcharset - Set charset parameter

    SYNTAX
    void setcharset(string charset);

    DESCRIPTION
    Sets the charset parameter of the Content-Type header. This is equivalent of calling msg->setparam("charset", charset).

    SEE ALSO
    MIME.Message->setparam

    METHOD
    MIME.Message.setdata - Replace body data

    SYNTAX
    void setdata(string data);

    DESCRIPTION
    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 type and subtype attributes. Do not use this method unless you know what you are doing.

    SEE ALSO
    MIME.Message->getdata

    METHOD
    MIME.Message.setdisp_param - Set Content-Disposition parameters

    SYNTAX
    void setdisp_param(string param, string value);

    DESCRIPTION
    Set or modify the named parameter of the Content-Disposition header. A common parameters is e.g. filename. It is not allowed to modify the Content-Disposition header directly, please use this function instead.

    SEE ALSO
    MIME.Message->setparam and MIME.Message->get_filename

    METHOD
    MIME.Message.setencoding - Set transfer encoding for message body

    SYNTAX
    void setencoding(string encoding);

    DESCRIPTION
    Select a new transfer encoding for this message. The Content-Transfer-Encoding header will be modified accordingly, and subsequent calls to getencoded will produce data encoded using the new encoding. See encode for a list of valid encodings.

    SEE ALSO
    MIME.Message->getencoded

    METHOD
    MIME.Message.setparam - Set Content-Type parameters

    SYNTAX
    void setparam(string param, string value);

    DESCRIPTION
    Set or modify the named parameter of the Content-Type header. Common parameters include charset for text messages, and boundary for multipart messages. It is not allowed to modify the Content-Type header directly, please use this function instead.

    SEE ALSO
    MIME.Message->setcharset, MIME.Message->setboundary and MIME.Message->setdisp_param

    14.12 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.

    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:

    FUNCTION
    Simulate.member_array - find first occurrence of a value in an array

    SYNTAX
    int member_array(mixed item, array arr);

    DESCRIPTION
    Returns the index of the first occurrence of item in array arr. If not found, then -1 is returned. This is the same as search(arr, item).

    FUNCTION
    Simulate.previous_object - return the calling object

    SYNTAX
    object previous_object();

    DESCRIPTION
    Returns an object pointer to the object that called current function, if any.

    SEE ALSO
    backtrace

    FUNCTION
    Simulate.this_function - return a function pointer to the current function

    SYNTAX
    function this_function();

    DESCRIPTION
    Returns a function pointer to the current function, useful for making recursive lambda-functions.

    SEE ALSO
    backtrace

    FUNCTION
    Simulate.get_function - fetch a function from an object

    SYNTAX
    function get_function(object o, string name);

    DESCRIPTION
    Defined as: return o[name];

    FUNCTION
    Simulate.map_regexp - filter an array through a regexp

    SYNTAX
    array(string) map_regexp(array(string) arr, string reg);

    DESCRIPTION
    Returns those strings in arr that matches the regexp in reg.

    SEE ALSO
    Regexp

    CONSTANT
    Simulate.PI - pi

    SYNTAX
    PI;

    DESCRIPTION
    This is not a function, it is a constant roughly equal to the mathematical constant Pi.

    FUNCTION
    Simulate.all_efuns - return all 'efuns'

    SYNTAX
    mapping all_efuns();

    DESCRIPTION
    This function is the same as all_constants.

    SEE ALSO
    all_constants

    FUNCTION
    Simulate.explode - explode a string on a delimeter

    SYNTAX
    string explode(string s, string delimiter);

    DESCRIPTION
    This function is really the same as the division operator. It simly divides the string s into an array by splitting s at every occurance of delimeter.

    SEE ALSO
    Simulate.implode

    FUNCTION
    Simulate.filter_array - filter an array through a function

    SYNTAX
    array filter_array(array arr,function fun,mixed ... args);
    array filter_array(array(object) arr,string fun,mixed ... args);
    array filter_array(array(function) arr,-1,mixed ... args);

    DESCRIPTION
    Filter array is the same function as Array.filter.

    SEE ALSO
    Array.filter

    FUNCTION
    Simulate.implode - implode an array of strings

    SYNTAX
    string implode(array(string) a, string delimiter);

    DESCRIPTION
    This function is the inverse of explode. It concatenates all the strings in a with a delimiter in between each.

    This function is the same as multiplication.

    EXAMPLE
    > implode( ({ "foo","bar","gazonk"}), "-" );
    Result: foo-bar-gazonk
    > ({ "a","b","c" })*" and ";
    Result: a and b and c
    >

    SEE ALSO
    Simulate.explode

    FUNCTION
    Simulate.m_indices - return all indices from a mapping

    SYNTAX
    array m_indices(mapping m);

    DESCRIPTION
    This function is equal to indices.

    SEE ALSO
    indices

    FUNCTION
    Simulate.m_sizeof - return the size of a mapping

    SYNTAX
    int m_sizeof(mapping m);

    DESCRIPTION
    This function is equal to sizeof.

    SEE ALSO
    sizeof

    FUNCTION
    Simulate.m_values - return all values from a mapping

    SYNTAX
    array m_values(mapping m);

    DESCRIPTION
    This function is equal to values.

    SEE ALSO
    values

    FUNCTION
    Simulate.map_array - map an array over a function

    SYNTAX
    array map_array(array arr,function fun,mixed ... args);
    array map_array(array(object) arr,string fun,mixed ... args);
    array map_array(array(function) arr,-1,mixed ... arg);

    DESCRIPTION
    This function is the same as Array.map.

    SEE ALSO
    Array.map

    FUNCTION
    Simulate.strstr - find a string inside a string

    SYNTAX
    int strstr(string str1,string str2);

    DESCRIPTION
    Returns the position of str2 in str1, if str2 can't be found in str1 -1 is returned.

    SEE ALSO
    sscanf, Simulate.explode and search

    FUNCTION
    Simulate.sum - add values together

    SYNTAX
    int sum(int ... i);
    float sum(float ... f);
    string sum(string|float|int ... p);
    array sum(array ... a);
    mapping sum(mapping ... m);
    list sum(multiset ... l);

    DESCRIPTION
    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.

    FUNCTION
    Simulate.add_efun - add an efun or constant

    SYNTAX
    void add_efun(string func_name, mixed function)
    void add_efun(string func_name)

    DESCRIPTION
    This function is the same as add_constant.

    SEE ALSO
    Simulate.add_constant

    FUNCTION
    Simulate.l_sizeof - return the size of a multiset

    SYNTAX
    int l_sizeof(multiset m);

    DESCRIPTION
    This function is equal to sizeof.

    SEE ALSO
    sizeof

    FUNCTION
    Simulate.listp - is the argument a list? (multiset)

    SYNTAX
    int listp(mixed l);

    DESCRIPTION
    This function is the same as multisetp.

    SEE ALSO
    Simulate.multisetp

    FUNCTION
    Simulate.mklist - make a multiset

    SYNTAX
    multiset mklist(array a);

    DESCRIPTION
    This function creates a multiset from an array.

    EXAMPLE
    > mklist( ({1,2,3}) ); Result: (< /* 3 elements */ 1, 2, 3 >)

    SEE ALSO
    aggregate_multiset

    FUNCTION
    Simulate.aggregate_list - aggregate a multiset

    SYNTAX
    multiset aggregate_list(mixed ... args);

    DESCRIPTION
    This function is exactly the same as aggregate_multiset.

    SEE ALSO
    aggregate_multiset

    FUNCTION
    Simulate.query_host_name - return the name of the host we are running on

    SYNTAX
    string query_host_name();

    DESCRIPTION
    This function returns the name of the machine the interpreter is running on. This is the same thing that the command 'hostname' prints.

    DESCRIPTION
    This module enables access to the Mysql database from within Pike. Mysql is available from www.tcx.se.

    NOTE
    $Id: mysql.c,v 1.37 2000/08/13 14:55:14 grubba Exp $

    SEE ALSO
    Mysql.mysql, Mysql.result and Sql.sql

    14.13 Mysql.mysql

    CLASS
    Mysql.mysql

    DESCRIPTION
    Mysql.mysql is a pre-compiled Pike program. It enables access to the Mysql database from within Pike. Mysql.mysql is a part of the Mysql module. Mysql is available from www.tcx.se.

    SEE ALSO
    Mysql.result and Sql.sql

    METHOD
    Mysql.mysql.affected_rows

    SYNTAX
    int affected_rows()

    DESCRIPTION
    Returns the number of rows affected by the last query.

    METHOD
    Mysql.mysql.big_query

    SYNTAX
    object(Mysql.mysql_result) big_query(string q)

    DESCRIPTION
    Make an SQL query

    ARGUMENTS
    argument(s)description
    string q
    The SQL query This function sends an SQL query to the Mysql-server. The result of the query is returned as a Mysql.mysql_result object. Returns 0 if the query didn't return any result (e.g. INSERT or similar).

    SEE ALSO
    mysql_result

    METHOD
    Mysql.mysql.binary_data

    SYNTAX
    int binary_data()

    DESCRIPTION
    Inform if this version of mysql supports binary data This function returns non-zero if binary data can be reliably stored and retreived with this version of the mysql-module. Usually, there is no problem storing binary data in mysql-tables, but data containing '\0' (NUL) couldn't be fetched with old versions (prior to 3.20.5) of the mysql-library.

    METHOD
    Mysql.mysql.create

    SYNTAX
    void create()
    void create(string host)
    void create(string host,  string database)
    void create(string host,  string database,  string user)
    void create(string host,  string database,  string user,  string password)

    DESCRIPTION
    Connects to a Mysql database. To access the Mysql database, you must first connect to it. This is done with the function mysql(). If you give no argument, or give "" as hostname it will connect with a UNIX-domain socket, which is a big performance gain.

    METHOD
    Mysql.mysql.create_db

    SYNTAX
    void create_db(string database)

    DESCRIPTION
    Create a new database

    ARGUMENTS
    argument(s)description
    string database
    Name of the database to be created This function creates a new database in the Mysql-server.

    SEE ALSO
    select_db and drop_db

    METHOD
    Mysql.mysql.drop_db

    SYNTAX
    void drop_db(string database)

    DESCRIPTION
    Drop a database

    ARGUMENTS
    argument(s)description
    string database
    Name of database to be dropped This function drops a database from a Mysql-server.

    SEE ALSO
    create_db and select_db

    METHOD
    Mysql.mysql.error

    SYNTAX
    string error()

    DESCRIPTION
    Returns a string describing the last error from the Mysql-server.

    METHOD
    Mysql.mysql.host_info

    SYNTAX
    string host_info()

    DESCRIPTION
    Give information about the Mysql-server connection This function returns a string describing the connection to the Mysql-server.

    SEE ALSO
    statistics, server_info and protocol_info

    METHOD
    Mysql.mysql.insert_id

    SYNTAX
    int insert_id()

    DESCRIPTION
    Returns the id of the last INSERT query into a table with an AUTO INCREMENT field.

    METHOD
    Mysql.mysql.list_dbs

    SYNTAX
    object(Mysql.mysql_result) list_dbs()
    object(Mysql.mysql_result) list_dbs(string wild)

    DESCRIPTION
    List databases Returns a table containing the names of all databases in the Mysql-server. If an argument is specified, only those matching wild are returned.

    SEE ALSO
    list_tables, list_fields, list_processes and Mysql.mysql_result

    METHOD
    Mysql.mysql.list_fields

    SYNTAX
    array(int|mapping(string:mixed)) list_fields(string table)
    array(int|mapping(string:mixed)) list_fields(string table,  string wild)

    DESCRIPTION
    List all fields. Returns an array of mappings with information about the fields in the specified table. The mappings contain the following entries:
    
     "name":        string  The name of the field.
     "table":       string  The name of the table.
     "default":     string  The default value for the field.
     "type":        string  The type of the field.
     "length":      int     The length of the field.
     "max_length":  int     The length of the longest element in this field.
     "flags":       multiset(string)        Some flags.
     "decimals":    int     The number of decimalplaces.
    
    The type of the field can be any of: "decimal", "char", "short", "long", "float", "double", "null", "time", "longlong", "int24", "tiny blob", "medium blob", "long blob", "var string", "string" or "unknown". The flags multiset can contain any of "primary_key": This field is part of the primary key for this table. "not_null": This field may not be NULL. "blob": This field is a blob field.

    ARGUMENTS
    argument(s)description
    string table
    Name of table to list the fields of
    string wild
    Wildcard to filter the result with

    NOTE
    Michael Widenius recomends usage of the following query instead:
    
     show fields in 'table' like "wild"
    

    SEE ALSO
    list_dbs, list_tables, list_processes and fetch_fields

    METHOD
    Mysql.mysql.list_processes

    SYNTAX
    object(Mysql.mysql_result) list_processes()

    DESCRIPTION
    List all processes in the Mysql-server Returns a table containing the names of all processes in the Mysql-server.

    SEE ALSO
    list_dbs, list_tables, list_fields and Mysql.mysql_result

    METHOD
    Mysql.mysql.list_tables

    SYNTAX
    object(Mysql.mysql_result) list_tables()
    object(Mysql.mysql_result) list_tables(string wild)

    DESCRIPTION
    List tables in the current database

    ARGUMENTS
    argument(s)description
    string wild
    Wildcard to filter with. Returns a table containing the names of all tables in the current database. If an argument is given, only those matching wild are returned.

    SEE ALSO
    list_dbs, list_fields, list_processes and Mysql.mysql_result

    METHOD
    Mysql.mysql.protocol_info

    SYNTAX
    int protocol_info()

    DESCRIPTION
    Give the Mysql protocol version This function returns the version number of the protocol the Mysql-server uses.

    SEE ALSO
    statistics, server_info and host_info

    METHOD
    Mysql.mysql.reload

    SYNTAX
    void reload()

    DESCRIPTION
    Reload security tables This function causes the Mysql-server to reload its access tables.

    SEE ALSO
    shutdown

    METHOD
    Mysql.mysql.select_db

    SYNTAX
    void select_db(string database)

    DESCRIPTION
    The Mysql-server can hold several databases. You select which one you want to access with this function.

    SEE ALSO
    create, create_db and drop_db

    METHOD
    Mysql.mysql.server_info

    SYNTAX
    string server_info()

    DESCRIPTION
    Give the version number of the Mysql-server This function returns the version number of the Mysql-server.

    SEE ALSO
    statistics, host_info and protocol_info

    METHOD
    Mysql.mysql.shutdown

    SYNTAX
    void shutdown()

    DESCRIPTION
    Shutdown the Mysql-server This function shuts down a running Mysql-server. reload

    METHOD
    Mysql.mysql.statistics

    SYNTAX
    string statistics()

    DESCRIPTION
    Some Mysql-server statistics This function returns some server statistics. Example:
    
    int main()
    {
      write(mysql()->statistics());
      return(0);
    }
    

    SEE ALSO
    server_info, host_info and protocol_info

    14.14 The Pike Crypto Toolkit

    14.14.1 Introduction

    The Crypto module provides an object-oriented framwork for encryption and related functionality. More specifically, its objects han be classified as follows:
    Block ciphers
    encrypt data in chunks of typically 8 bytes, using a secret key.
    Stream ciphers
    operate on the data to be encrypted one byte at a time, for exemple by xoring it with a sequence of pseudorandom bytes.
    Cryptographic hash functions
    transform a bytesequence of arbitrary length into a short string of a fixed length of typically 16 or 20 bytes, in such a way that it is practically impossible to find two distinct strings with the same hash value.
    Public key algorithms
    can support both encryption and digital signatures.
    Abstract building blocks
    for combining ciphers (mainly for block ciphers). These objects behave like block ciphers, but delegate encryption to one or several underlying objects, in some way. For example, block ciphers are often used in a feedback mode. The ciphers by themselves know nothing about these different "modes of operation", instead this knowledge is abstracted into separate objects. If you want IDEA in Cipher Block Chaining mode, you combine an IDEA object and a CBC object.

    Randomness
    is essential for many cryptographic application. The toolkit includes a few different random number generators, with varying degrees of true randomness.
    Frontend objects
    that handle things like padding messages, or make it more convenient to use popular combinations of ciphers, feedback modes, etc.

    14.14.2 Block ciphers

    The block ciphers included in the current version are DES, IDEA and CAST128 (note that IDEA is patented, see
    Ascom Tech for details). All block ciphers have a common set of methods.

    METHOD
    crypt_block

    SYNTAX
    string o->crypt_block(string blocks);

    DESCRIPTION
    Encrypts or decrypts an even number of block, using the current key. If more than one block is given, they are encrypted/decrypted independently, i.e. in Electronic Code Book (ECB) mode.

    METHOD
    query_block_size

    SYNTAX
    int o->query_block_size();

    DESCRIPTION
    Returns the block size of the cipher, in octets. A typical block size is 8 octets. A string passed to crypt_block() must have a length that is a multiple of the block size.

    METHOD
    query_key_length

    SYNTAX
    int o->query_key_length();

    DESCRIPTION
    Returns the key size of the cipher, in octets. Note that some block ciphers, e.g. CAST128, have a variable key size. In this case, query_key_length returns the recommended key size, although keys of other lengths are accepted by the set_encrypt_key and set_decrypt_key methods. For DES, the real key length is seven octets (56 bits), but the DES standard mandates the use of parity bits. The query_key_length method lies about DES, and says that the key_size is eight octets (64 bits). See also des_parity.

    METHOD
    set_encrypt_key

    SYNTAX
    object o->set_encrypt_key(string key);

    DESCRIPTION
    Installs a key, and configures the object for doing encryption. For convenience, this method returns the object itself.

    METHOD
    set_decrypt_key

    SYNTAX
    object o->set_decrypt_key(string key);

    DESCRIPTION
    Installs a key, and configures the object for doing decryption. For convenience, this method returns the object itself.
    The classes are

    CLASS
    Crypto.des Crypto.des

    CLASS
    Crypto.idea Crypto.idea
    and

    CLASS
    Crypto.cast Crypto.cast
    . To encrypt the block "Pike des" using the DES-key '0123456789abcdef' (in hex), use
    Crypto.des()->set_encrypt_key(Crypto.hex_to_string("0123456789abcdef"))
                            ->crypt_block("Pike DES")
    although most applications will not use the Crypto.des class directly.

    14.14.3 Stream Ciphers

    Currently the only stream cipher in the toolkit is the RC4 cipher (also known as "arcfour").

    CLASS
    Crypto.rc4

    METHOD
    Crypto.rc4.crypt

    SYNTAX
    string Crypto.rc4->crypt(string data);

    DESCRIPTION
    Encrypts or decrypts a string of data.

    METHOD
    Crypto.rc4.set_encrypt_key

    SYNTAX
    object Crypto.rc4->set_encrypt_key(string key);

    DESCRIPTION
    Installs a key, and configures the object for doing encryption. For convenience, this method returns the object itself.

    METHOD
    Crypto.rc4.set_decrypt_key

    SYNTAX
    object Crypto.rc4->set_decrypt_key(string key);

    DESCRIPTION
    Installs a key, and configures the object for doing decryption. For convenience, this method returns the object itself.
    Because of the way RC4 works, set_encrypt_key and set_decrypt_key are actually equivalent.

    14.14.4 Hash Functions

    Cryptographic hash functions are essential for many cryptographic applications, and are also useful in other contexts. The Toolkit includes the two most common, MD5 and SHA1. They have the same methods.

    METHOD
    update

    SYNTAX
    object o->update(string data);

    DESCRIPTION
    Processes some more data. For convenience, this method returns the object itself.

    METHOD
    digest

    SYNTAX
    string o->digest();

    DESCRIPTION
    Returns the hash value, or message digest, corresponding to all the data that was previously passed to the update method. Also resets the hash object, so that it can be used to process a new message.

    METHOD
    query_digest_size

    SYNTAX
    int o->query_digest_size();

    DESCRIPTION
    Returns the size, in octets, of the digests produced by this hash function.
    To get the md5 hash of a string s, you would use
    Crypto.md5()->update(s)->digest()

    14.14.5 Public key algorithms

    The only public key algorithm currently in the toolkit is RSA. As the algorithm uses arithmetic on huge numbers, you must also have the GMP library and the corresponding Pike module installed in order to use RSA.

    CLASS
    Crypto.rsa

    METHOD
    Crypto.rsa.set_public_key

    SYNTAX
    object rsa->set_public_key(object(Gmp.mpz) modulo, object(Gmp.mpz) e)

    DESCRIPTION
    Sets the modulo and the public exponent. For convenience, returns the object itself.

    METHOD
    Crypto.rsa.set_private_key

    SYNTAX
    object rsa->set_public_key(object(Gmp.mpz) d)

    DESCRIPTION
    Sets the private exponent. For convenience, returns the object itself.

    METHOD
    Crypto.rsa.generate_key

    SYNTAX
    object rsa->generate_key(int bits, function|void random)

    DESCRIPTION
    Generates a new rsa key pair, with a modulo of the given bitsize. random should be a function that takes one integer argument n and returns a string of n random octets. The default function is Crypto.randomness.really_random()->read. For convenience, this method returns the object itself.

    METHOD
    Crypto.rsa.query_blocksize

    SYNTAX
    int rsa->query_block_size()

    DESCRIPTION
    Returns the length of the largest string that can be encrypted in one RSA-operation using the current key.

    METHOD
    Crypto.rsa.encrypt

    SYNTAX
    string rsa->encrypt(string message, function|void random)

    DESCRIPTION
    Encrypts message using PKCS#1-style RSA encryption. The function random is used to generate random message padding. Padding does not require a strong random number generator. The default random function is derived from Pike's builting pseudorandom generator predef::random.

    METHOD
    Crypto.rsa.decrypt

    SYNTAX
    string rsa->decrypt(string gibberish)

    DESCRIPTION
    Decrypts a PKCS#1-style RSA-encrypted message. This operation requires knowledge of the private key. Decryption may fail if the input is not a properly encrypted message for this key. In this case, the method returns zero. The PKCS#1 padding method used is vulnerable to a chosen-ciphertext attack discovered by Daniel Bleichenbacher.
    There are several methods for signature creation and verification. I don't quite like the interface, so it may very well change in some future version of the Toolkit.

    METHOD
    Crypto.rsa.sign

    SYNTAX
    object(Gmp.mpz) rsa->sign(string message, program hash)

    DESCRIPTION
    Creates a PKCS#1-style signature. This operation requires knowledge of the private key. hash should be a hash algorithm with an ->identifier method which returns a DER-encoded ASN.1 Object Identifier for the hash algorithm. Currently, this is supported only by Crypto.md5. The function returns the signature as a bignum; applications can use
    Standards.ASN1.Types.asn1_bit_string(rsa->sign(...))->get_der()
    to convert it a DER-encoded ASN.1 bitstring.

    METHOD
    Crypto.rsa.verify

    SYNTAX
    int verify(string message, program hash, object(Gmp.mpz) signature)

    DESCRIPTION
    Verifies a PKCS#1-style RSA signature. Returns 1 if the signature is valid, 0 if not.

    METHOD
    Crypto.rsa.sha_sign

    SYNTAX
    string rsa->sha_sign(string message)

    DESCRIPTION
    Creates an RSA signature using a simpler but non-standard convention.

    METHOD
    Crypto.rsa.sha_verify

    SYNTAX
    int sha_verify(string message, string signature)

    DESCRIPTION
    Verifies signatures created by sha_sign. Returns 1 if the signature is valid, 0 if not.

    14.14.6 Combining block cryptos

    14.15 Locale.Gettext

    DESCRIPTION
    This module enables access to localization functions from within Pike.

    NOTE
    $Id: gettext.c,v 1.5 2000/08/10 09:51:52 per Exp $

    METHOD
    Locale.Gettext.bindtextdomain

    SYNTAX
    string bindtextdomain(string|void domainname,  string|void dirname)

    DESCRIPTION
    The bindtextdomain() function binds the path predicate for a message domain domainname to the value contained in dirname. If domainname is a non-empty string and has not been bound previously, bindtextdomain() binds domainname with dirname.

    If domainname is a non-empty string and has been bound previously, bindtextdomain() replaces the old binding with dirname. The dirname argument can be an absolute or relative pathname being resolved when gettext(), dgettext(), or dcgettext() are called. If domainname is null pointer or an empty string, bindtextdomain() returns 0. User defined domain names cannot begin with the string SYS_. Domain names beginning with this string are reserved for system use. The return value from bindtextdomain() is a string containing dirname or the directory binding associated with domainname if dirname is void. If no binding is found, the default locale path is returned. If domainname is void or an empty string, bindtextdomain() takes no action and returns a 0.

    ARGUMENTS
    argument(s)description
    string domainname
    The domain to query or bind a path to.
    string dirname
    The directory name to bind to the choosen domain.

    SEE ALSO
    textdomain, gettext, dgettext, dcgettext, setlocale and localeconv

    METHOD
    Locale.Gettext.dcgettext

    SYNTAX
    string dcgettext(string domain,  string msg,  int category)

    DESCRIPTION
    Return a translated version of msg within the context of the specified domain and current locale for the specified category. Calling dcgettext with category Locale.Gettext.LC_MESSAGES gives the same result as dgettext. If there is not translation available, msg is returned.

    ARGUMENTS
    argument(s)description
    string domain
    The domain to lookup the message in.
    string msg
    The message to translate.
    int category
    The category which locale should be used.

    SEE ALSO
    bindtextdomain, textdomain, gettext, dgettext, setlocale and localeconv

    METHOD
    Locale.Gettext.dgettext

    SYNTAX
    string dgettext(string domain,  string msg)

    DESCRIPTION
    Return a translated version of msg within the context of the specified domain and current locale. If there is not translation available, msg is returned.

    ARGUMENTS
    argument(s)description
    string domain
    The domain to lookup the message in.
    string msg
    The message to translate.

    SEE ALSO
    bindtextdomain, textdomain, gettext, dcgettext, setlocale and localeconv

    METHOD
    Locale.Gettext.gettext

    SYNTAX
    string gettext(string msg)

    DESCRIPTION
    Return a translated version of msg within the context of the current domain and locale. If there is not translation available, msg is returned.

    ARGUMENTS
    argument(s)description
    string msg
    The message to translate.

    SEE ALSO
    bindtextdomain, textdomain, dgettext, dcgettext, setlocale and localeconv

    METHOD
    Locale.Gettext.localeconv

    SYNTAX
    mapping localeconv()

    DESCRIPTION
    The localeconv() function returns a mapping with settings for the current locale. This mapping contains all values associated with the locale categories LC_NUMERIC and LC_MONETARY.

    string decimal_point: The decimal-point character used to format non-monetary quantities.

    string thousands_sep: The character used to separate groups of digits to the left of the decimal-point character in formatted non-monetary quantities.

    string int_curr_symbol: The international currency symbol applicable to the current locale, left-justified within a four-character space-padded field. The character sequences should match with those specified in ISO 4217 Codes for the Representation of Currency and Funds.

    string currency_symbol: The local currency symbol applicable to the current locale.

    string mon_decimal_point: The decimal point used to format monetary quantities.

    string mon_thousands_sep: The separator for groups of digits to the left of the decimal point in formatted monetary quantities.

    string positive_sign: The string used to indicate a non-negative-valued formatted monetary quantity.

    string negative_sign: The string used to indicate a negative-valued formatted monetary quantity.

    int int_frac_digits: The number of fractional digits (those to the right of the decimal point) to be displayed in an internationally formatted monetary quantity.

    int frac_digits: The number of fractional digits (those to the right of the decimal point) to be displayed in a formatted monetary quantity.

    int p_cs_precedes: Set to 1 or 0 if the currency_symbol respectively precedes or succeeds the value for a non-negative formatted monetary quantity.

    int p_sep_by_space: Set to 1 or 0 if the currency_symbol respectively is or is not separated by a space from the value for a non-negative formatted monetary quantity.

    int n_cs_precedes: Set to 1 or 0 if the currency_symbol respectively precedes or succeeds the value for a negative formatted monetary quantity.

    int n_sep_by_space: Set to 1 or 0 if the currency_symbol respectively is or is not separated by a space from the value for a negative formatted monetary quantity.

    int p_sign_posn: Set to a value indicating the positioning of the positive_sign for a non-negative formatted monetary quantity. The value of p_sign_posn is interpreted according to the following:

    0 - Parentheses surround the quantity and currency_symbol.

    1 - The sign string precedes the quantity and currency_symbol.

    2 - The sign string succeeds the quantity and currency_symbol.

    3 - The sign string immediately precedes the currency_symbol.

    4 - The sign string immediately succeeds the currency_symbol.

    int n_sign_posn: Set to a value indicating the positioning of the negative_sign for a negative formatted monetary quantity. The value of n_sign_posn is interpreted according to the rules described under p_sign_posn.

    SEE ALSO
    bindtextdomain, textdomain, gettext, dgettext, dcgettext and setlocale

    METHOD
    Locale.Gettext.setlocale

    SYNTAX
    int setlocale(int category,  string locale)

    DESCRIPTION
    The setlocale() function is used to set the program's current locale. If locale is "C" or "POSIX", the current locale is set to the portable locale.

    If locale is "", the locale is set to the default locale which is selected from the environment variable LANG.

    The argument category determines which functions are influenced by the new locale: Locale.Gettext.LC_ALL for all of the locale.

    Locale.Gettext.LC_COLLATE for the functions strcoll() and strxfrm() (used by pike, but not directly accessible).

    Locale.Gettext.LC_CTYPE for the character classification and conversion routines.

    Locale.Gettext.LC_MONETARY for localeconv(). Locale.Gettext.LC_NUMERIC for the decimal character. Locale.Gettext.LC_TIME for strftime() (currently not accessible from Pike).

    ARGUMENTS
    argument(s)description
    int category
    The category in which to set the locale.
    string locale
    The locale to change to

    RETURNS
    1 if the locale setting successed, 0 for failure

    SEE ALSO
    bindtextdomain, textdomain, gettext, dgettext, dcgettext and localeconv

    METHOD
    Locale.Gettext.textdomain

    SYNTAX
    string textdomain(string domain|void)
    string textdomain(void)

    DESCRIPTION
    The textdomain() function sets or queries the name of the current domain of the active LC_MESSAGES locale category. The domainname argument is a string that can contain only the characters allowed in legal filenames.

    The domainname argument is the unique name of a domain on the system. If there are multiple versions of the same domain on one system, namespace collisions can be avoided by using bindtextdomain(). If textdomain() is not called, a default domain is selected. The setting of domain made by the last valid call to textdomain() remains valid across subsequent calls to setlocale, and gettext(). The normal return value from textdomain() is a string containing the current setting of the domain. If domainname is void, textdomain() returns a string containing the current domain. If textdomain() was not previously called and domainname is void, the name of the default domain is returned.

    ARGUMENTS
    argument(s)description
    string domainname
    The name of the domain to be made the current domain.

    SEE ALSO
    bindtextdomain, gettext, dgettext, dcgettext, setlocale and localeconv

    14.16 Calendar

    DESCRIPTION
    This module implements calendar calculations, and base classes for time units.

    14.16.1 Calendar.time_unit

    CLASS
    Calendar.time_unit

    DESCRIPTION

    METHOD
    Calendar.time_unit.greater

    SYNTAX
    array(string) greater()

    DESCRIPTION
    Gives a list of methods to get greater (longer) time units from this object. For a month, this gives back ({"year"}), thus the method month->year() gives the year object.

    METHOD
    Calendar.time_unit.lesser

    SYNTAX
    array(string) lesser()

    DESCRIPTION
    Gives a list of methods to get lesser (shorter) time units. ie, for a month, this gives back ({"day"}) and the method day(mixed n) gives back that day object. The method days() gives back a list of possible argument values to the method day. Concurrently, Array.map(o->days(),o->day) gives a list of day objects in the object o.

    Ie:

    array(string) lesser()    - gives back a list of possible xxx's.
    object xxxs()             - gives back a list of possible n's.
    object xxx(mixed n)       - gives back xxx n
    object xxx(object(Xxx) o) - gives back the corresponing xxx
    

    The list of n's (as returned from xxxs) are always in order.

    There are two n's with special meaning, 0 and -1. 0 always gives the first xxx, equal to my_obj->xxx(my_obj->xxxs()[0]), and -1 gives the last, equal to my_obj->xxx(my_obj->xxxs()[-1]).

    To get all xxxs in the object, do something like Array.map(my_obj->xxxs(),my_obj->xxx).

    xxx(object) may return zero, if there was no correspondning xxx.

    METHOD
    Calendar.time_unit.`+,
    Calendar.time_unit.`-,
    Calendar.time_unit.next,
    Calendar.time_unit.prev

    SYNTAX
    object next()
    object prev()
    object `+(int n)
    object `-(int n)
    object `-(object x)

    DESCRIPTION
    next and prev gives the logical next and previous object. The + operator gives that logical relative object, ie my_day+14 gives 14 days ahead. - works the same way, but can also take an object of the same type and give the difference as an integer.

    14.16.2 Calendar.Gregorian

    DESCRIPTION
    time units: Year, Month, Week, Day

    14.16.2.1 Calendar.Gregorian.

    CLASS
    Calendar.Gregorian.

    14.16.2.2 Calendar.Gregorian.Year

    CLASS
    Calendar.Gregorian.Year

    DESCRIPTION
    A Calendar.time_unit.

    Lesser units: Month, Week, Day Greater units: none

    METHOD
    Calendar.Gregorian.Year.parse

    SYNTAX
    object parse(string fmt, string arg)

    DESCRIPTION
    parse a date, create relevant object fmt is in the format "abc%xdef..." where abc and def is matched, and %x is one of those time units: %Y absolute year %y year (70-99 is 1970-1999, 0-69 is 2000-2069) %M month (number, name or short name) (needs %y) %W week (needs %y) %D date (needs %y, %m) %a day (needs %y) %e weekday (needs %y, %w) %h hour (needs %d, %D or %W) %m minute (needs %h) %s second (needs %s)

    function datetime(int|void unix_time) Replacement for localtime.

    function datetime_name(int|void unix_time) Replacement for ctime.

    function datetime_short_name(int|void unix_time) Replacement for ctime.

    14.16.2.3 Calendar.Gregorian.Stardate

    DESCRIPTION
    time unit: TNGDate
    14.16.2.3.1 Calendar.Gregorian.Stardate.TNGDate

    CLASS
    Calendar.Gregorian.Stardate.TNGDate

    DESCRIPTION
    implements ST:TNG stardates can be used as create argument to Day

    14.17 Parser

    14.18 Math

    14.18.1 Math.Matrix

    CLASS
    Math.Matrix

    DESCRIPTION
    This class hold Matrix capabilites, and support a range of matrix operations.

    It can only - for speed and simplicity - hold floating point numbers and are only in 2 dimensions.

    METHOD
    Math.Matrix.`+,
    Math.Matrix.``+,
    Math.Matrix.add

    SYNTAX
    object `+(object with)
    object ``+(object with)
    object add(object with)

    DESCRIPTION
    Add this matrix to another matrix. A new matrix is returned. The matrices must have the same size.

    METHOD
    Math.Matrix.cast

    SYNTAX
    array(array(float)) cast(string to_what)
    array(array(float)) cast(string to_what)

    DESCRIPTION
    This is to be able to get the matrix values. (array) gives back a double array of floats. m->vect() gives back an array of floats.

    METHOD
    Math.Matrix.cast

    SYNTAX
    array(array(float)) cast(string to_what)

    DESCRIPTION
    This is to be able to get the matrix values. This gives back a double array of floats.

    METHOD
    Math.Matrix.create

    SYNTAX
    void create(array(array(int|float)))
    void create(array(int|float))
    void create(int n, int m)
    void create(int n, int m, string type)
    void create(int n, int m, float|int init)
    void create("identity", int size)
    void create("rotate", int size, float rads, Matrix axis)
    void create("rotate", int size, float rads, float x, float y, float z)

    DESCRIPTION
    This method initializes the matrix. It is illegal to create and hold an empty matrix.

    The normal operation is to create the matrix object with a double array, like Math.Matrix( ({({1,2}),({3,4})}) ).

    Another use is to create a special type of matrix, and this is told as third argument.

    Currently there are only the "identity" type, which gives a matrix of zeroes except in the diagonal, where the number one (1.0) is. This is the default, too.

    The third use is to give all indices in the matrix the same value, for instance zero or 42.

    The forth use is some special matrixes. First the square identity matrix again, then the rotation matrix.

    METHOD
    Math.Matrix.cross,
    Math.Matrix.``×,
    Math.Matrix.`×

    SYNTAX
    object (object with)
    object ``×(object with)
    object cross(object with)

    DESCRIPTION
    Matrix cross-multiplication.

    METHOD
    Math.Matrix.`*,
    Math.Matrix.``*,
    Math.Matrix.mult

    SYNTAX
    object `*(object with)
    object ``*(object with)
    object mult(object with)

    DESCRIPTION
    Matrix multiplication.

    METHOD
    Math.Matrix.norm2,
    Math.Matrix.norm,
    Math.Matrix.normv

    SYNTAX
    float norm()
    float norm2()
    object normv()

    DESCRIPTION
    Norm of the matrix, and the square of the norm of the matrix. (The later method is because you may skip a square root sometimes.)

    This equals |A| or sqrt( A02 + A12 + ... + An2 ).

    It is only usable with 1xn or nx1 matrices.

    m->normv() is equal to m*(1.0/m->norm()), with the exception that the zero vector will still be the zero vector (no error).

    METHOD
    Math.Matrix.`-,
    Math.Matrix.``-,
    Math.Matrix.sub

    SYNTAX
    object `-()
    object `-(object with)
    object ``-(object with)
    object sub(object with)

    DESCRIPTION
    Subtracts this matrix from another. A new matrix is returned. -m is equal to -1*m.

    METHOD
    Math.Matrix.transpose

    SYNTAX
    object transpose()

    DESCRIPTION
    Transpose of the matrix as a new object.

    DESCRIPTION
    This module implements calendar calculations, and base classes for time units.

    14.19 Calendar.time_unit

    CLASS
    Calendar.time_unit

    DESCRIPTION

    METHOD
    Calendar.time_unit.greater

    SYNTAX
    array(string) greater()

    DESCRIPTION
    Gives a list of methods to get greater (longer) time units from this object. For a month, this gives back ({"year"}), thus the method month->year() gives the year object.

    METHOD
    Calendar.time_unit.lesser

    SYNTAX
    array(string) lesser()

    DESCRIPTION
    Gives a list of methods to get lesser (shorter) time units. ie, for a month, this gives back ({"day"}) and the method day(mixed n) gives back that day object. The method days() gives back a list of possible argument values to the method day. Concurrently, Array.map(o->days(),o->day) gives a list of day objects in the object o.

    Ie:

    array(string) lesser()    - gives back a list of possible xxx's.
    object xxxs()             - gives back a list of possible n's.
    object xxx(mixed n)       - gives back xxx n
    object xxx(object(Xxx) o) - gives back the corresponing xxx
    

    The list of n's (as returned from xxxs) are always in order.

    There are two n's with special meaning, 0 and -1. 0 always gives the first xxx, equal to my_obj->xxx(my_obj->xxxs()[0]), and -1 gives the last, equal to my_obj->xxx(my_obj->xxxs()[-1]).

    To get all xxxs in the object, do something like Array.map(my_obj->xxxs(),my_obj->xxx).

    xxx(object) may return zero, if there was no correspondning xxx.

    METHOD
    Calendar.time_unit.`+,
    Calendar.time_unit.`-,
    Calendar.time_unit.next,
    Calendar.time_unit.prev

    SYNTAX
    object next()
    object prev()
    object `+(int n)
    object `-(int n)
    object `-(object x)

    DESCRIPTION
    next and prev gives the logical next and previous object. The + operator gives that logical relative object, ie my_day+14 gives 14 days ahead. - works the same way, but can also take an object of the same type and give the difference as an integer.

    14.20 Calendar.Gregorian

    DESCRIPTION
    time units: Year, Month, Week, Day

    14.20.1 Calendar.Gregorian.

    CLASS
    Calendar.Gregorian.

    14.20.2 Calendar.Gregorian.Year

    CLASS
    Calendar.Gregorian.Year

    DESCRIPTION
    A Calendar.time_unit.

    Lesser units: Month, Week, Day Greater units: none

    METHOD
    Calendar.Gregorian.Year.parse

    SYNTAX
    object parse(string fmt, string arg)

    DESCRIPTION
    parse a date, create relevant object fmt is in the format "abc%xdef..." where abc and def is matched, and %x is one of those time units: %Y absolute year %y year (70-99 is 1970-1999, 0-69 is 2000-2069) %M month (number, name or short name) (needs %y) %W week (needs %y) %D date (needs %y, %m) %a day (needs %y) %e weekday (needs %y, %w) %h hour (needs %d, %D or %W) %m minute (needs %h) %s second (needs %s)

    function datetime(int|void unix_time) Replacement for localtime.

    function datetime_name(int|void unix_time) Replacement for ctime.

    function datetime_short_name(int|void unix_time) Replacement for ctime.

    14.20.3 Calendar.Gregorian.Stardate

    DESCRIPTION
    time unit: TNGDate

    14.20.3.1 Calendar.Gregorian.Stardate.TNGDate

    CLASS
    Calendar.Gregorian.Stardate.TNGDate

    DESCRIPTION
    implements ST:TNG stardates can be used as create argument to Day

    14.21 Crypto.randomness

    DESCRIPTION
    Assorted stronger or weaker randomnumber generators.

    14.21.1 Crypto.randomness.pike_random

    CLASS
    Crypto.randomness.pike_random

    DESCRIPTION
    A pseudo random generator based on the ordinary random() function.

    METHOD
    Crypto.randomness.pike_random.read

    SYNTAX
    string read(int len)

    DESCRIPTION
    Returns a string of length len with pseudo random values.

    14.21.2 Crypto.randomness.arcfour_random

    CLASS
    Crypto.randomness.arcfour_random

    DESCRIPTION
    A pseudo random generator based on the arcfour crypto.

    METHOD
    Crypto.randomness.arcfour_random.create

    SYNTAX
    void create(string secret)

    DESCRIPTION
    Initialize and seed the arcfour random generator.

    METHOD
    Crypto.randomness.arcfour_random.read

    SYNTAX
    string read(int len)

    DESCRIPTION
    Return a string of the next len random characters from the arcfour random generator.

    14.22 Geographical.Position

    CLASS
    Geographical.Position

    DESCRIPTION
    This class contains a geographical position, ie a point on the earths surface.

    variable float lat variable float long Longitude (W--E) and latitude (N--S) of the position, float value in degrees. Positive number is north and east, respectively. Negative number is south and west, respectively.

    METHOD
    Geographical.Position.cast

    SYNTAX
    array cast("array")

    DESCRIPTION
    It is possible to cast the position to an array, ({float lat,float long}).

    METHOD
    Geographical.Position.create

    SYNTAX
    void create(float lat, float long)
    void create(string lat, string long)
    void create(string both)

    DESCRIPTION
    Constructor for this class. If feeded with strings, it will perform a dwim scan on the strings. If they fails to be understood, there will be an exception.

    METHOD
    Geographical.Position.latitude,
    Geographical.Position.longitude

    SYNTAX
    string latitude(void|int n)
    string longitude(void|int n)

    DESCRIPTION
    Returns the nicely formatted latitude or longitude.
    n    format
    -    17°42.19'N       42°22.2'W
    1    17.703°N         42.37°W
    2    17°42.18'N       42°22.2'W
    3    17°42'10.4"N     42°22'12"W
    -1   17.703           -42.37
    

    METHOD
    Geographical.Position.`==,
    Geographical.Position.`>,
    Geographical.Position.`>`<,
    Geographical.Position.`>__hash

    SYNTAX
    int __hash()
    int `==(Position pos)
    int `<>(Position pos)
    int `>(Position pos)

    DESCRIPTION
    These exist solely for purpose of detecting equal positions, for instance when used as keys in mappings.

    14.23 Geographical.Countries

    DESCRIPTION
    subclass Country variable string iso2 ISO 2-character code aka domain name variable string name variable array(string) aka Country name and as-known-as, if any variable int former Flag that is set if this isn't a country anymore (Like USSR.) constant array(Country) countries All known countries.

    METHOD
    Geographical.Countries.cast

    SYNTAX
    string cast("string")

    DESCRIPTION
    It is possible to cast a country to a string, which will be the same as performing country->name;.

    METHOD
    Geographical.Countries.from_domain

    SYNTAX
    Country from_domain(string domain)

    DESCRIPTION
    Look up a country from a domain name. Returns zero if the domain doesn't map to a country. Note that there are some valid domains that doesn't:
    INT
    International
    MIL
    US Military
    NET
    Network
    ORG
    Non-Profit Organization
    ARPA
    Old style Arpanet
    NATO
    Nato field

    And that USA has three domains, Great Britain two:

    COM
    US Commercial
    EDU
    US Educational
    GOV
    US Government
    GB
    Great Britain (UK)
    UK
    United Kingdom

    METHOD
    Geographical.Countries.from_domain

    SYNTAX
    Country from_domain(string name)

    DESCRIPTION
    Look up a country from its name or aka. The search is case-insensitive but regards whitespace and interpunctation.

    METHOD
    Geographical.Countries.`[],
    Geographical.Countries.`.

    SYNTAX
    mixed `[](string what)
    mixed `->(string what)

    DESCRIPTION
    Convenience function for getting a country the name-space way; it looks up whatever it is in the name- and domain-space and

    > Geographical.Countries.se;
    Result: Country(Sweden)
    > Geographical.Countries.djibouti;
    Result: Country(Djibouti)
    > Geographical.Countries.com;
    Result: Country(United States)
    > Geographical.Countries.wallis_and_futuna_islands->iso2;
    Result: "WF"
    

    RETURNS
    that country if possible:

    DESCRIPTION
    $Id: module.pmod,v 1.8 2000/03/22 18:12:19 peter Exp $

    METHOD
    Image.load_layer,
    Image._load,
    Image.load

    SYNTAX
    object(Image.Image) load()
    object(Image.Image) load(object file)
    object(Image.Image) load(string filename)
    object(Image.Layer) load_layer()
    object(Image.Layer) load_layer(object file)
    object(Image.Layer) load_layer(string filename)
    mapping _load()
    mapping _load(object file)
    mapping _load(string filename)

    DESCRIPTION
    Helper function to load an image from a file. If no filename is given, Stdio.stdin is used. The result is the same as from the decode functions in Image.ANY.

    NOTE
    All data is read, ie nothing happens until the file is closed. Throws upon error.

    14.24 Parser.SGML

    CLASS
    Parser.SGML

    DESCRIPTION
    This is a handy simple parser of SGML-like syntax like HTML. It doesn't do anything advanced, but finding the corresponding end-tags.

    It's used like this:

    array res=Parser.SGML()->feed(string)->finish()->result();

    The resulting structure is an array of atoms, where the atom can be a string or a tag. A tag contains a similar array, as data.

    Example: A string "<gat>&nbsp;<gurka>&nbsp;</gurka>&nbsp;<banan>&nbsp;<kiwi>&nbsp;</gat>" results in

    ({
    tag "gat" object with data:
    ({
    tag "gurka" object with data:
    ({
    " "
    })
    tag "banan" object with data:
    ({
    " "
    tag "kiwi" object with data:
    ({
    " "
    })
    })
    })
    })
    

    ie, simple "tags" (not containers) are not detected, but containers are ended implicitely by a surrounding container _with_ an end tag.

    The 'tag' is an object with the following variables:

    string name;           - name of tag
    mapping args;          - argument to tag
    int line,char,column;  - position of tag
    string file;           - filename (see create)
    array(SGMLatom) data;  - contained data
    

    METHOD
    Parser.SGML.create

    SYNTAX
    void create()
    void create(string filename)

    DESCRIPTION
    This object is created with this filename. It's passed to all created tags, for debug and trace purposes.

    NOTE
    No, it doesn't read the file itself. See feed.

    METHOD
    Parser.SGML.result,
    Parser.SGML.finish,
    Parser.SGML.feed

    SYNTAX
    object feed(string s)
    array finish()
    array result(string s)

    DESCRIPTION
    Feed new data to the object, or finish the stream. No result can be used until finish() is called.

    Both finish() and result() returns the computed data.

    feed() returns the called object.

    14.25 Protocols.HTTP

    METHOD
    Protocols.HTTP.delete_url

    SYNTAX
    object(Protocols.HTTP.Query) delete_url(string url)
    object(Protocols.HTTP.Query) delete_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) delete_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP DELETE request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.get_url

    SYNTAX
    object(Protocols.HTTP.Query) get_url(string url)
    object(Protocols.HTTP.Query) get_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) get_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP GET request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.get_url_nice,
    Protocols.HTTP.get_url_data

    SYNTAX
    array(string) get_url_nice(string url)
    array(string) get_url_nice(string url, mapping query_variables)
    array(string) get_url_nice(string url, mapping query_variables,  mapping request_headers)
    string get_url_data(string url)
    string get_url_data(string url, mapping query_variables)
    string get_url_data(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Returns an array of ({content_type,data}) and just the data string respective, after calling the requested server for the information. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.http_encode_query

    SYNTAX
    string http_encode_query(mapping variables)

    DESCRIPTION
    Encodes a query mapping to a string; this protects odd - in http perspective - characters like '&' and '#' and control characters, and packs the result together in a HTTP query string.

    Example:

    > Protocols.HTTP.http_encode_query( (["anna":"eva","lilith":"blue"]) );
    Result: "lilith=blue&anna=eva"
    > Protocols.HTTP.http_encode_query( (["&amp;":"&","'=\"":"\0\0\0"]) );
    Result: "%26amp%3b=%26&%27%3d%22=%00%00%00"
    

    METHOD
    Protocols.HTTP.http_encode_string

    SYNTAX
    string http_encode_string(string in)

    DESCRIPTION
    This protects all odd - see http_encode_query - characters for transfer in HTTP.

    Do not use this function to protect URLs, since it will protect URL characters like '/' and '?'.

    METHOD
    Protocols.HTTP.post_url_data,
    Protocols.HTTP.post_url,
    Protocols.HTTP.post_url_nice

    SYNTAX
    array(string) post_url_nice(string url, mapping query_variables)
    array(string) post_url_nice(string url, mapping query_variables,  mapping request_headers)
    string post_url_data(string url, mapping query_variables)
    string post_url_data(string url, mapping query_variables,  mapping request_headers)
    object(Protocols.HTTP.Query) post_url(string url, mapping query_variables)
    object(Protocols.HTTP.Query) post_url(string url, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Similar to the get_url class of functions, except that the query variables is sent as a post request instead of a get.

    METHOD
    Protocols.HTTP.put_url

    SYNTAX
    object(Protocols.HTTP.Query) put_url(string url)
    object(Protocols.HTTP.Query) put_url(string url, string file)
    object(Protocols.HTTP.Query) put_url(string url, string file, mapping query_variables)
    object(Protocols.HTTP.Query) put_url(string url, string file, mapping query_variables,  mapping request_headers)

    DESCRIPTION
    Sends a HTTP PUT request to the server in the URL and returns the created and initialized Query object. 0 is returned upon failure.

    METHOD
    Protocols.HTTP.unentity

    SYNTAX
    string unentity(string s)

    DESCRIPTION
    Helper function for replacing HTML entities with the corresponding iso-8859-1 characters.

    NOTE
    All characters isn't replaced, only those with corresponding iso-8859-1 characters.

    14.25.1 Protocols.HTTP.Query

    CLASS
    Protocols.HTTP.Query

    DESCRIPTION
    Open and execute a HTTP query.

    METHOD
    Protocols.HTTP.Query.set_callbacks,
    Protocols.HTTP.Query.async_request

    SYNTAX
    object set_callbacks(function request_ok, function request_fail, mixed ...extra)
    object async_request(string server, int port, string query);
    object async_request(string server, int port, string query, mapping headers, void|string data);

    DESCRIPTION
    Setup and run an asynchronous request, otherwise similar to thread_request.

    request_ok(object httpquery,...extra args) will be called when connection is complete, and headers are parsed.

    request_fail(object httpquery,...extra args) is called if the connection fails.

    variable int ok Tells if the connection is successfull. variable int errno Errno copied from the connection.

    variable mapping headers Headers as a mapping. All header names are in lower case, for convinience.

    variable string protocol Protocol string, ie "HTTP/1.0".

    variable int status variable string status_desc Status number and description (ie, 200 and "ok").

    variable mapping hostname_cache Set this to a global mapping if you want to use a cache, prior of calling *request().

    variable mapping async_dns Set this to an array of Protocols.DNS.async_clients, if you wish to limit the number of outstanding DNS requests. Example: async_dns=allocate(20,Protocols.DNS.async_client)();

    RETURNS
    the called object

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    array cast("array")

    DESCRIPTION
    Gives back ({mapping headers,string data, string protocol,int status,string status_desc});

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    mapping cast("mapping")

    DESCRIPTION
    Gives back headers | (["protocol":protocol, "status":status number, "status_desc":status description, "data":data]);

    METHOD
    Protocols.HTTP.Query.cast

    SYNTAX
    string cast("string")

    DESCRIPTION
    Gives back the answer as a string.

    METHOD
    Protocols.HTTP.Query.data

    SYNTAX
    string data()

    DESCRIPTION
    Gives back the data as a string.

    METHOD
    Protocols.HTTP.Query.downloaded_bytes

    SYNTAX
    int downloaded_bytes()

    DESCRIPTION
    Gives back the number of downloaded bytes.

    METHOD
    Protocols.HTTP.Query.thread_request

    SYNTAX
    object thread_request(string server, int port, string query);
    object thread_request(string server, int port, string query, mapping headers, void|string data);

    DESCRIPTION
    Create a new query object and begin the query.

    The query is executed in a background thread; call '() in this object to wait for the request to complete.

    'query' is the first line sent to the HTTP server; for instance "GET /index.html HTTP/1.1".

    headers will be encoded and sent after the first line, and data will be sent after the headers.

    RETURNS
    the called object

    METHOD
    Protocols.HTTP.Query.total_bytes

    SYNTAX
    int total_bytes()

    DESCRIPTION
    Gives back the size of a file if a content-length header is present and parsed at the time of evaluation. Otherwise returns -1.

    object(pseudofile) file() object(pseudofile) file(mapping newheaders,void|mapping removeheaders) object(pseudofile) datafile(); Gives back a pseudo-file object, with the method read() and close(). This could be used to copy the file to disc at a proper tempo.

    datafile() doesn't give the complete request, just the data.

    newheaders, removeheaders is applied as: (oldheaders|newheaders))-removeheaders Make sure all new and remove-header indices are lower case.

    void async_fetch(function done_callback); Fetch all data in background.

    METHOD
    Protocols.HTTP.Query.`

    SYNTAX
    int `()()

    DESCRIPTION
    Wait for connection to complete.

    RETURNS
    1 on successfull connection, 0 if failed

    14.26 Protocols.LysKOM

    14.26.1 Protocols.LysKOM.Session

    CLASS
    Protocols.LysKOM.Session

    DESCRIPTION
    variable user This variable contains the person that are logged in.

    METHOD
    Protocols.LysKOM.Session.create

    SYNTAX
    void create(string server)
    void create(string server, mapping options)

    DESCRIPTION
    Initializes the session object, and opens a connection to that server.

    options is a mapping of options,

    ([
       "login" : int|string    login as this person number
                             (get number from name)
       "create" : string       
                             create a new person and login with it
       "password" : string     send this login password
       "invisible" : int(0..1) if set, login invisible
       advanced
       "port" : int(0..65535)  server port (default is 4894)
       "whoami" : string       present as this user
                             (default is from uid/getpwent and hostname)
    ])
    

    SEE ALSO
    Connection

    METHOD
    Protocols.LysKOM.Session.create_person

    SYNTAX
    object create_person(string name, string password)

    DESCRIPTION
    Create a person, which will be logged in.

    RETURNS
    the new person object

    METHOD
    Protocols.LysKOM.Session.create_text

    SYNTAX
    object create_text(string subject, string body, mapping options)
    object create_text(string subject, string body, mapping options, function callback, mixed ...extra)

    DESCRIPTION
    Creates a new text.

    if "callback" are given, this function will be called when the text is created, with the text as first argument. Otherwise, the new text is returned.

    options is a mapping that may contain:

    ([
       "recpt" : Conference|array(Conference) 
            recipient conferences
       "cc" : Conference|array(Conference)    
            cc-recipient conferences
       "bcc" : Conference|array(Conference)   
            bcc-recipient conferences *
       
       "comm_to" : Text|array(Text)           
            what text(s) is commented
       "foot_to" : Text|array(Text)           
            what text(s) is footnoted
       
       "anonymous" : int(0..1)                
            send text anonymously
    ])
    

    NOTE
    The above marked with a '*' is only available on a protocol 10 server. A LysKOM error will be thrown if the call fails.

    SEE ALSO
    Conference.create_text, Text.comment and Text.footnote

    METHOD
    Protocols.LysKOM.Session.login

    SYNTAX
    object login(int user_no, string password)
    object login(int user_no, string password, int invisible)

    DESCRIPTION
    Performs a login. Returns 1 on success or throws a lyskom error.

    RETURNS
    the called object

    METHOD
    Protocols.LysKOM.Session.logout

    SYNTAX
    object logout()

    DESCRIPTION
    Logouts from the server.

    RETURNS
    the called object

    METHOD
    Protocols.LysKOM.Session.send_message

    SYNTAX
    object send_message(string message,  mapping options)

    DESCRIPTION
    Sends a message.

    options is a mapping that may contain:

    ([
       "recpt" : Conference recipient conference
    ])
    

    METHOD
    Protocols.LysKOM.Session.try_complete_person

    SYNTAX
    array(object) try_complete_person(string orig)

    DESCRIPTION
    Runs a LysKOM completion on the given string, returning an array of confzinfos of the match.

    14.26.2 Protocols.LysKOM.Connection

    CLASS
    Protocols.LysKOM.Connection

    DESCRIPTION
    This class contains nice abstraction for calls into the server. They are named "call", "async_call" or "async_cb_call", depending on how you want the call to be done.

    METHOD
    Protocols.LysKOM.Connection./call/,
    Protocols.LysKOM.Connection.async_/call/,
    Protocols.LysKOM.Connection.async_cb_/call/

    SYNTAX
    mixed /call/(mixed ...args)
    object async_/call/(mixed ...args)
    object async_cb_/call/(function callback, mixed ...args)

    DESCRIPTION
    Do a call to the server. This really clones a request object, and initialises it. /call/ is to be read as one of the calls in the lyskom protocol. ('-' is replaced with '_'.) (ie, logout, async_login or async_cb_get_conf_stat.)

    The first method is a synchronous call. This will send the command, wait for the server to execute it, and then return the result.

    The last two is asynchronous calls, returning the initialised request object.

    variable int protocol_level variable string session_software variable string software_version Description of the connected server.

    METHOD
    Protocols.LysKOM.Connection.create

    SYNTAX
    void create(string server)
    void create(string server, mapping options)

    DESCRIPTION
    ([
       "login" : int|string    login as this person number
                             (get number from name)
       "password" : string     send this login password
       "invisible" : int(0..1) if set, login invisible
       advanced
       "port" : int(0..65535)  server port (default is 4894)
       "whoami" : string       present as this user
                             (default is from uid/getpwent and hostname)
    ])
    

    14.26.3 Protocols.LysKOM.Request

    DESCRIPTION
    This class contains nice abstraction for calls into the server. They are named "call", "async_call" or "async_cb_call", depending on how you want the call to be done.

    14.26.3.1 Protocols.LysKOM.Request._Request

    CLASS
    Protocols.LysKOM.Request._Request

    DESCRIPTION
    This is the main request class. All lyskom request classes inherits this class.

    METHOD
    Protocols.LysKOM.Request._Request.sync,
    Protocols.LysKOM.Request._Request.async

    SYNTAX
    void async(mixed ...args)
    mixed sync(mixed ...args)

    DESCRIPTION
    initialise an asynchronous or a synchronous call, the latter is also evaluating the result. This calls 'indata' in itself, to get the correct arguments to the lyskom protocol call.

    METHOD
    Protocols.LysKOM.Request._Request._reply,
    Protocols.LysKOM.Request._Request.reply

    SYNTAX
    mixed _reply(object|array what)
    mixed reply(object|array what)

    DESCRIPTION
    _reply is called as callback to evaluate the result, and calls reply in itself to do the real work.

    METHOD
    Protocols.LysKOM.Request._Request.`

    SYNTAX
    mixed `()()

    DESCRIPTION
    wait for the call to finish.

    variable int ok tells if the call is executed ok variable object error how the call failed The call is completed if (ok||error).

    METHOD
    Protocols.LysKOM.Request._Request._async,
    Protocols.LysKOM.Request._Request._sync

    SYNTAX
    void _async(int call,  mixed_data)
    mixed _sync(int call,  mixed_data)

    DESCRIPTION
    initialise an asynchronous or a synchronous call, the latter is also evaluating the result. These are called by async and sync respectively.

    14.27 Protocols.DNS

    DESCRIPTION

    14.27.1 Protocols.DNS.client

    CLASS
    Protocols.DNS.client

    DESCRIPTION
    Synchronous DNS client.

    METHOD
    Protocols.DNS.client.create

    SYNTAX
    void create()
    void create(void|string|array server,  void|int|array domain)

    DESCRIPTION

    METHOD
    Protocols.DNS.client.gethostbyname,
    Protocols.DNS.client.gethostbyaddr

    SYNTAX
    array gethostbyname(string hostname)
    array gethostbyaddr(string hostip)

    DESCRIPTION
    Querys the host name or ip from the default or given DNS server. The result is a mapping with three elements,
    ({
       string hostname  [0] hostname
       array(string) ip [1] ip number(s)
       array(string) ip [2] dns name(s)
    })
    

    METHOD
    Protocols.DNS.client.get_primary_mx

    SYNTAX
    string get_primary_mx(string hostname)

    DESCRIPTION
    Querys the primary mx for the host.

    RETURNS
    the hostname of the primary mail exchanger

    Chapter 15, The 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.

    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:

    DIRECTIVE
    #!

    DESCRIPTION
    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

    DIRECTIVE
    #""

    DESCRIPTION
    Makes it possible to write strings with newline in them.
    #"Foo
    bar"
    
    is the same as
    "Foo\nbar"
    

    DIRECTIVE
    #define

    DESCRIPTION
    The simplest way to use define is to write

    BUGS
    Note that it is not a good idea to do something like this:

    EXAMPLE
    #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));
    }

    DIRECTIVE
    #undef

    DESCRIPTION
    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.

    EXAMPLES
    #define foo bar
    #undef foo
    #define foo(bar) gazonk bar
    #undef foo

    DIRECTIVE
    #if
    #elif
    #elseif
    #else
    #endif

    DESCRIPTION
    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.

    EXAMPLES
    #if 1
    #else
    #endif

    #elif defined(BAR)
    #else
    #endif

    DIRECTIVE
    #error

    DESCRIPTION
    This directive causes a compiler error, it can be used to notify the user that certain functions are missing and similar things.

    EXAMPLES
    #if !constant(write_file)
    #error write_file function is missing
    #endif

    DIRECTIVE
    #include

    DESCRIPTION
    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.

    EXAMPLES
    #include "foo.h"

    DIRECTIVE
    #line

    DESCRIPTION
    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.

    EXAMPLES
    #line 4 "foo.cf" /* The next line was generated from 4 in foo.cf */

    DIRECTIVE
    #pragma

    DESCRIPTION
    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.

    DIRECTIVE
    #string

    DESCRIPTION
    This directive works as #include but makes the included file a string.
    string html_doc=#string "index.html";
    This puts the file index.html into the string html_doc.

    Chapter 16, Builtin functions

    This chapter is a reference for all the builtin functions in Pike. They are listed in alphabetical order.

    FUNCTION
    _disable_threads - temporarily disable threads

    SYNTAX
    object _disable_threads();

    DESCRIPTION
    This function first posts a notice to all threads that it is time to stop. It then waits until all threads actually *have* stopped, and then then returns an object. All other threads will be blocked from running until that object has been freed/destroyed. This function can completely block Pike if used incorrectly. Use with extreme caution.

    FUNCTION
    _do_call_outs - do all pending call_outs

    SYNTAX
    void _do_call_out();

    DESCRIPTION
    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.

    As a side-effect, this function sets the value returned by time(1) to the current time.

    SEE ALSO
    call_out, find_call_out and remove_call_out

    FUNCTION
    _exit - Really exit

    SYNTAX
    void _exit(int returncode);

    DESCRIPTION
    This function does the same as exit, but doesn't bother to clean up the Pike interpreter before exiting. This means that no destructors will be called, caches will not be flushed, file locks might not be released, and databases might not be closed properly. Use with extreme caution.

    SEE ALSO
    exit

    FUNCTION
    _locate_references - locate where an object is referenced from

    SYNTAX
    mapping(string:int) _locate_references(string|array|mapping|multiset|function|object|program o);

    DESCRIPTION
    This function is mostly intended for debugging. It will search through all data structures in Pike looking for o and print the locations on stderr. o can be anything but int or float.

    FUNCTION
    _memory_usage - check memory usage

    SYNTAX
    mapping(string:int) _memory_usage();

    DESCRIPTION
    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.

    SEE ALSO
    _verify_internals

    FUNCTION
    _next - find the next object/array/whatever

    SYNTAX
    mixed _next(mixed p);

    DESCRIPTION
    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.

    SEE ALSO
    next_object and _prev

    FUNCTION
    _prev - find the previous object/array/whatever

    SYNTAX
    mixed _next(mixed p);

    DESCRIPTION
    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.

    SEE ALSO
    _next

    FUNCTION
    _refs - find out how many references a pointer type value has

    SYNTAX
    int _refs(string|array|mapping|multiset|function|object|program o);

    DESCRIPTION
    This function checks how many references the value o 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.

    SEE ALSO
    _next and _prev

    FUNCTION
    _verify_internals - check Pike internals

    SYNTAX
    void _verify_internals();

    DESCRIPTION
    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.

    FUNCTION
    abs - absolute value

    SYNTAX
    float abs(float f); int abs(int f); object abs(object f);

    DESCRIPTION
    Return the absolute value for f. f can be a Gmp-object.

    FUNCTION
    acos - trigonometrical inverse cosine

    SYNTAX
    float acos(float f);

    DESCRIPTION
    Return the arcus cosine value for f. The result will be in radians.

    SEE ALSO
    cos and asin

    FUNCTION
    add_constant - add new predefined functions or constants

    SYNTAX
    void add_constant(string name, mixed value);
    void add_constant(string name);

    DESCRIPTION
    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.

    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.

    EXAMPLE
    add_constant("true",1);
    add_constant("false",0);
    add_constant("PI",4.0);
    add_constant("sqr",lambda(mixed x) { return x * x; });
    add_constant("add_constant");

    SEE ALSO
    all_constants

    FUNCTION
    add_include_path - add a directory to search for include files

    SYNTAX
    void add_include_path(string path);

    DESCRIPTION
    This function adds another directory to the search for include files. This is the same as the command line option -I. Note that the added directory will only be searched when using < > to quote the included file.

    SEE ALSO
    remove_include_path and #include

    FUNCTION
    add_module_path - add a directory to search for modules

    SYNTAX
    void add_module_path(string path);

    DESCRIPTION
    This function adds another directory to the search for modules. This is the same as the command line option -M. For more information about modules, see chapter 8 "Modules".

    SEE ALSO
    remove_module_path

    FUNCTION
    add_program_path - add a directory to search for modules

    SYNTAX
    void add_program_path(string path);

    DESCRIPTION
    This function adds another directory to the search for programs. This is the same as the command line option -P. For more information about programs, see section 4.2.4 "program".

    SEE ALSO
    remove_program_path

    FUNCTION
    aggregate - construct an array

    SYNTAX
    array aggregate(mixed ... elems);
    ({ elem1, elem2, ... });

    DESCRIPTION
    Construct an array with the arguments as indices. This function could be written in Pike as:

    array aggregate(mixed ... elems) { return elems; }

    NOTE
    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 array(int) a=allocate(10); will do.

    SEE ALSO
    sizeof, arrayp and allocate

    FUNCTION
    aggregate_mapping - construct a mapping

    SYNTAX
    mapping aggregate_mapping(mixed ... elems);
    ([ key1:val1, key2:val2, ... ]);

    DESCRIPTION
    Groups the arguments together two and two to key-index pairs and creates a mapping of those pairs. The second syntax is always preferable.

    SEE ALSO
    sizeof, mappingp and mkmapping

    FUNCTION
    aggregate_multiset - construct a multiset

    SYNTAX
    multiset aggregate_multiset(mixed ... elems);
    (< elem1, elem2, ... >);

    DESCRIPTION
    Construct a multiset with the arguments as indices. This function could be written in Pike as:

    multiset aggregate(mixed ... elems) { return mkmultiset(elems); }

    The only problem is that mkmultiset is implemented using aggregate_multiset...

    SEE ALSO
    sizeof, multisetp and mkmultiset

    FUNCTION
    alarm - set an alarm clock for delivery of a signal

    SYNTAX
    int alarm(int seconds);

    DESCRIPTION
    alarm arranges for a SIGALRM signal to be delivered to the process in seconds seconds.

    If seconds is zero, no new alarm is scheduled.

    In any event any previously set alarm is canceled.

    RETURNS
    alarm 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.

    SEE ALSO
    signal

    FUNCTION
    all_constants - return all predefined constants

    SYNTAX
    mapping (string:mixed) all_constant();

    DESCRIPTION
    Returns a mapping containing all constants, indexed on the names of the constant, and with the value of the efun as argument.

    SEE ALSO
    add_constant

    FUNCTION
    allocate - allocate an array

    SYNTAX
    array allocate(int size);

    DESCRIPTION
    Allocate an array of size elements and initialize them to zero.

    EXAMPLE
    array a=allocate(17);

    NOTE
    Arrays are dynamically allocated there is no need to declare them like int a[10]=allocate(10); (and it is not possible either) like in C, just array(int) a=allocate(10); will do.

    SEE ALSO
    sizeof, aggregate and arrayp

    FUNCTION
    arrayp - is the argument an array?

    SYNTAX
    int arrayp(mixed arg);

    DESCRIPTION
    Returns 1 if arg is an array, zero otherwise.

    SEE ALSO
    allocate, intp, programp, floatp, stringp, objectp, mappingp, multisetp and functionp

    FUNCTION
    array_sscanf - sscanf to an array

    SYNTAX
    array array_sscanf(string data, string format);

    DESCRIPTION
    This function works just like sscanf, but returns the matched results in an array instead of assigning them to lvalues. This is often useful for user-defined sscanf strings.

    SEE ALSO
    sscanf and `/

    FUNCTION
    asin - trigonometrical inverse sine

    SYNTAX
    float asin(float f);

    DESCRIPTION
    Returns the arcus sinus value for f.

    SEE ALSO
    sin and acos

    FUNCTION
    atan - trigonometrical inverse tangent

    SYNTAX
    float atan(float f);

    DESCRIPTION
    Returns the arcus tangent value for f.

    SEE ALSO
    atan2, tan, asin and acos

    FUNCTION
    atan2 - trigonometrical inverse tangent

    SYNTAX
    float atan2(float f1, float f2);

    DESCRIPTION
    Returns the arcus tangent value for f1/f2.

    SEE ALSO
    atan, tan, asin and acos

    FUNCTION
    atexit - schedule a callback for when pike exits

    SYNTAX
    void atexit(function callback);

    DESCRIPTION
    This function puts the callback in a queue of callbacks to call when pike exits. Please note that atexit callbacks are not called if pike exits abnormally.

    SEE ALSO
    exit

    FUNCTION
    backtrace - get a description of the call stack

    SYNTAX
    array(array) backtrace();

    DESCRIPTION
    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:

    ({
         file, /* a string with the filename if known, else zero */
         line, /* an integer containing the line if known, else zero */
         function, /* The function pointer to the called function */
         mixed|void ..., /* The arguments the function was called with */
    })

    The current call frame will be last in the array, and the one above that the last but one and so on.

    SEE ALSO
    catch and throw

    FUNCTION
    basename - get the base of a filename

    SYNTAX
    string basename(string filename);

    DESCRIPTION
    This function returns the base of a filename, for instance the base of "/home/hubbe/bin/pike" would be "pike".

    SEE ALSO
    dirname and explode_path

    FUNCTION
    call_function - call a function with arguments

    SYNTAX
    mixed call_function(function fun,mixed ... args);
    mixed fun ( mixed ... args );

    DESCRIPTION
    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.

    SEE ALSO
    backtrace and Simulate.get_function

    FUNCTION
    call_out - make a delayed call to a function

    SYNTAX
    mixed call_out(function f, float|int delay, mixed ... args);

    DESCRIPTION
    Call_out places a call to the function f with the argument args 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.

    SEE ALSO
    remove_call_out, find_call_out and call_out_info

    FUNCTION
    call_out_info - get info about all call outs

    SYNTAX
    array(array) call_out_info();

    DESCRIPTION
    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:

    ({

    time_left, /* an int */
    caller, /* the object that made the call out */
    function, /* the function to be called */
    arg1, /* the first argument, if any */
    arg2, /* the second argument, if any */
    ... /* and so on... */
    })

    SEE ALSO
    call_out, find_call_out and remove_call_out

    FUNCTION
    catch

    SYNTAX
    catch { commands };
    catch ( expression );

    DESCRIPTION
    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 })

    SEE ALSO
    throw

    FUNCTION
    cd - change directory

    SYNTAX
    int cd(string s);

    DESCRIPTION
    Change the current directory for the whole Pike process, return 1 for success, 0 otherwise.

    SEE ALSO
    getcwd

    FUNCTION
    ceil - truncate a number upward

    SYNTAX
    float ceil(float f);

    DESCRIPTION
    Return the closest integer value higher or equal to f.

    NOTE
    ceil() does not return an int, merely an integer value stored in a float.

    SEE ALSO
    floor and round

    FUNCTION
    chmod - change mode of a file in the filesystem

    SYNTAX
    void chmod(string filename,int mode);

    DESCRIPTION
    Sets the protection mode of the given file. It will throw if it fails.

    SEE ALSO
    Stdio.File->open and errno

    FUNCTION
    clone - clone an object from a program

    SYNTAX
    object clone(program p,mixed ... args);

    DESCRIPTION
    clone() creates an object from the program p. Or in C++ terms: It creates an instance of the class p. This clone will first have all global variables initialized, and then create() will be called with args as arguments.

    SEE ALSO
    new, destruct, compile_string and compile_file

    FUNCTION
    column - extract a column

    SYNTAX
    array column(array data,mixed index)

    DESCRIPTION
    This function is exactly equivalent to:
    map_array(data, lambda(mixed x,mixed y) { return x[y]; }, index)
    Except of course it is a lot shorter and faster. That is, it indices every index in the array data on the value of the argument index and returns an array with the results.

    EXAMPLE
    	> column( ({ ({1,2}), ({3,4}), ({5,6}) }), 1)
    	Result: ({2, 4, 6})
    

    SEE ALSO
    rows

    FUNCTION
    combine_path - concatenate paths

    SYNTAX
    string combine_path(string absolute, string relative);

    DESCRIPTION
    Concatenate a relative path to an absolute path and remove any "//", "/.." or "/." to produce a straightforward absolute path as a result.

    EXAMPLE
    > combine_path("/foo/bar/","..");
    Result: /foo
    > combine_path("/foo/bar/","../apa.c");
    Result: /foo/apa.c
    > combine_path("/foo/bar","./sune.c");
    Result: /foo/bar/sune.c

    SEE ALSO
    getcwd and Stdio.append_path

    FUNCTION
    compile - compile a string to a program

    SYNTAX
    program compile(string program);

    DESCRIPTION
    compile takes a piece of Pike code as a string and compiles it into a clonable program. Note that prog must contain the complete source for a program. You can not compile a single expression or statement. Also note that compile does not preprocess the program. To preprocess the program you can use compile_string or call the preprocessor manually by calling cpp.

    SEE ALSO
    clone, compile_string, compile_file and cpp

    FUNCTION
    compile_file - compile a file to a program

    SYNTAX
    program compile_file(string filename);

    DESCRIPTION
    This function will compile the file filename to a Pike program that can later be used for cloning. It is the same as doing compile_string(Stdio.read_file(filename),filename).

    SEE ALSO
    clone and compile_string

    FUNCTION
    compile_string - compile a string to a program

    SYNTAX
    program compile_string(string prog, string name);

    DESCRIPTION
    Equal to compile(cpp(prog, name));

    SEE ALSO
    compile_string and clone

    FUNCTION
    copy_value - copy a value recursively

    SYNTAX
    mixed copy_value(mixed value);

    DESCRIPTION
    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 ==)

    SEE ALSO
    equal

    FUNCTION
    cos - trigonometrical cosine

    SYNTAX
    float cos(float f);

    DESCRIPTION
    Returns the cosine value for f.

    SEE ALSO
    acos and sin

    FUNCTION
    cpp - run the preprocessor on a string

    SYNTAX
    string cpp ( string source, string filename);

    DESCRIPTION
    This function runs the Pike preprocessor on a string. The second argument filename will be used for inserting #line statements into the result.

    SEE ALSO
    compile, compile_string and compile_file

    FUNCTION
    crypt - crypt a password

    SYNTAX
    string crypt(string password);
    int crypt(string typed_password, string crypted_password);

    DESCRIPTION
    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.

    EXAMPLE
    To crypt a password use:
    crypted_password = crypt(typed_password);
    To see if the same password was used again use:
    matched = crypt(typed_password, crypted_password);

    FUNCTION
    ctime - convert time int to readable date string

    SYNTAX
    string ctime(int current_time);

    DESCRIPTION
    Convert the output from a previous call to time() into a readable string containing the current year, month, day and time.

    EXAMPLE
    > ctime(time());
    Result: Wed Jan 14 03:36:08 1970

    SEE ALSO
    time, localtime, mktime and gmtime

    FUNCTION
    decode_value - decode a value from a string

    SYNTAX
    mixed decode_value(string coded_value);

    DESCRIPTION
    This function takes a string created with encode_value() or encode_value_canonic() and converts it back to the value that was coded.

    SEE ALSO
    encode_value and encode_value_canonic

    FUNCTION
    describe_backtrace - make a backtrace readable

    SYNTAX
    string describe_backtrace(array(array) backtrace);

    DESCRIPTION
    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()

    SEE ALSO
    backtrace and describe_error

    FUNCTION
    describe_error - get the error message from a backtrace

    SYNTAX
    string describe_error(array(array) backtrace);

    DESCRIPTION
    Returns only the error message in a backtrace. If there is no message in it, a fallback message is returned.

    SEE ALSO
    backtrace and describe_backtrace

    FUNCTION
    destruct - destruct an object

    SYNTAX
    void destruct(object o);

    DESCRIPTION
    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->destroy.

    SEE ALSO
    clone

    FUNCTION
    dirname - find the directory part of a path

    SYNTAX
    string dirname(string path);

    DESCRIPTION
    This function returns the directory part of a path. For example, the directory part of "/home/hubbe/bin/pike" would be "/home/hubbe/bin".

    SEE ALSO
    basename and explode_path

    FUNCTION
    encode_value - code a value into a string

    SYNTAX
    string encode_value(mixed value);

    DESCRIPTION
    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.

    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.

    SEE ALSO
    decode_value, sprintf and encode_value_canonic

    FUNCTION
    encode_value_canonic - code a value into a string on canonical form

    SYNTAX
    string encode_value_canonic(mixed value)

    DESCRIPTION
    Takes a value and converts it to a string on canonical form, much like encode_value(). The canonical form means that if an identical value is encoded, it will produce exactly the same string again, even if it's done at a later time and/or in another Pike process. The produced string is compatible with decode_value().

    Note that this function is more restrictive than encode_value() with respect to the types of values it can encode. It will throw an error if it can't encode to a canonical form.

    SEE ALSO
    encode_value and decode_value

    FUNCTION
    enumerate - create an array with an enumeration

    SYNTAX
    array(int) enumerate(int n);
    array enumerate(int n,void|mixed step,void|mixed start,void|function operator);

    DESCRIPTION
    Create an enumeration, useful for initializing arrays or as first argument to map or foreach.

    For instance, enumerate(4) gives ({0,1,2,3}).

    Advanced use: the resulting array is caluculated like this:

    array enumerate(int n,mixed step,mixed start,function operator)
    {
       array res=({});
       for (int i=0; i<n; i++)
       {
          res+=({start});
          start=operator(start,step);
       }
       return res;
    }
    

    The default values is step=1, start=0, operator=add.

    SEE ALSO
    map and foreach

    FUNCTION
    equal - check if two values are equal or not

    SYNTAX
    int equal(mixed a, mixed b);

    DESCRIPTION
    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.

    EXAMPLE
    > ({ 1 }) == ({ 1 });
    Result: 0
    > equal( ({ 1 }), ({ 1 }) );
    Result: 1
    >

    SEE ALSO
    copy_value

    FUNCTION
    errno - return system error number

    SYNTAX
    int errno();

    DESCRIPTION
    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.

    SEE ALSO
    Stdio.File->errno and strerror

    FUNCTION
    exece

    SYNTAX
    int exece(string file, array(string) args);
    int exece(string file, array(string) args, mapping(string:string) env);

    DESCRIPTION
    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.

    NOTE
    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.

    EXAMPLE
    exece("/bin/ls", ({"-l"}));
    exece("/bin/sh", ({"-c", "echo $HOME"}), (["HOME":"/not/home"]));

    SEE ALSO
    fork and Stdio.File->pipe

    FUNCTION
    explode_path - Split a path into components

    SYNTAX
    array(string) explode_path(string path);

    DESCRIPTION
    This function divides a path into its components. This might seem like it could be done by dividing the string on "/", but that would not work on other operating systems.

    EXAMPLE
    > explode_path("/home/hubbe/bin/pike"); Result: ({ "home", "hubbe", "bin", "pike" })

    FUNCTION
    exit - exit Pike interpreter

    SYNTAX
    void exit(int returncode);

    DESCRIPTION
    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.

    FUNCTION
    exp - natural exponent

    SYNTAX
    float exp(float f);

    DESCRIPTION
    Return the natural exponent of f.

    SEE ALSO
    pow and log

    FUNCTION
    file_stat - stat a file

    SYNTAX
    array(int) file_stat(string file);
    array(int) file_stat(string file, 1);
    array(int) file->stat();

    DESCRIPTION
    file_stat returns an array of integers describing some properties
    about the file. Currently file_stat returns 7 entries:
    ({
       int mode  [0] file mode, protection bits etc. etc. 
       int size  [1] file size for regular files, 
                       -2 for dirs,
                       -3 for links,
                       -4 for otherwise 
       int atime [2] last access time 
       int mtime [3] last modify time 
       int ctime [4] last status time change 
       int uid   [5] The user who owns this file
       int gid   [6] The group this file belongs to
    })
    
    If you give 1 as a second argument, file_stat does not follow links.
    You can never get -3 as size if you don't give a second argument.

    If there is no such file or directory, zero is returned.

    SEE ALSO
    get_dir

    FUNCTION
    file_truncate - truncate a file

    SYNTAX
    int file_truncate(string file,int length);

    DESCRIPTION
    Truncates a file to that length. Returns 1 if ok, 0 if failed.

    FUNCTION
    filter - map a function over elements and filter

    SYNTAX
    array filter(array arr,function fun,mixed ...extra);
    mixed filter(mixed arr,void|mixed fun,void|mixed ...extra);

    DESCRIPTION
    Calls the given function for all elements in arr, and keeps the elements in arr that resulted in a non-zero value from the function.
    arr result
    array keep=map(arr,fun,@extra); for (i=0; i<sizeof(arr); i++)    if (keep[i]) res+=({arr[i]});
    multiset (multiset)filter((array)arr,fun,@extra);
    mapping |
    program |
    function
     ind=indices(arr),val=values(arr);
    keep=map(val,fun,@extra);
    for (i=0; i<sizeof(keep); i++)
       if (keep[i]) res[ind[i]]=val[i];
    string (string)filter( (array)arr,fun,@extra );
    object if arr->cast :
       try filter((array)arr,fun,@extra);
       try filter((mapping)arr,fun,@extra);
       try filter((multiset)arr,fun,@extra);

    RETURNS
    the same datatype as given, the exception are program and function that gives a mapping back

    SEE ALSO
    map and foreach

    FUNCTION
    find_call_out - find a call out in the queue

    SYNTAX
    int find_call_out(function f);
    int find_call_out(mixed id);

    DESCRIPTION
    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.

    SEE ALSO
    call_out, remove_call_out and call_out_info

    FUNCTION
    floatp - is the argument a float?

    SYNTAX
    int floatp(mixed arg);

    DESCRIPTION
    Returns 1 if arg is a float, zero otherwise.

    SEE ALSO
    intp, programp, arrayp, stringp, objectp, mappingp, multisetp and functionp

    FUNCTION
    floor - truncate a number downward

    SYNTAX
    float floor(float f);

    DESCRIPTION
    Return the closest integer value lower or equal to f.

    NOTE
    floor() does not return an int, merely an integer value stored in a float.

    SEE ALSO
    ceil and round

    FUNCTION
    fork - fork the process in two

    SYNTAX
    int fork();

    DESCRIPTION
    Fork splits the process in two, and for the parent it returns the pid of the child. Refer to your Unix manual f