Dokumentation der Sprache BOIL
------------------------------
(C) netEstate GmbH, www.netestate.de
Bitte rufen Sie den Interpreter 'boiler' ohne Optionen auf, um sich
einen Ueberblick der Optionen zu verschaffen.
BOIL (Brunnis Own Interpreter Language) ist stark an C angelehnt.
Unterschiede gegenueber C:
1. Datentypen
---------------------------------------------------------------------------
Nur die Datentypen long,unsigned long,double,string und void sind erlaubt
(insb. keine Zeiger oder andere abgeleitete Datentypen). long, unsigned long
und double sind nach der Deklaration immer 0 und string undefiniert (analog
zu (char*) 0 in C). Zuweisungen, Funktionsargumente und Rueckgabewerte von
Funktionen mit undefinierten Strings sind moeglich, aber keine Ausdruecke.
Ob ein String undefiniert ist, kann nur mit der Library-Funktion defined()
abgefragt werden.
2. Konversionen und Casten
---------------------------------------------------------------------------
Automatische Konversionen zwischen den Datentypen finden nur in folgenden
Faellen statt:
-Zwischen long und unsigned long
-Von long oder unsigned long nach double
Bei operatoren und Funktionen ist darauf zu achten, welche Typen erlaubt sind,
ob eine implizite Konversion erfolgt, ob eine explizite Konversion (cast) mit
Datenverlust noetig ist und welche Typen zurueckgegeben werden. Casten ist
zwischen allen Typen moeglich. Beispiel: printf((string) 2.1);
3. Fehlende Operatoren
---------------------------------------------------------------------------
-Alle Zuweisungsoperatoren ausser '=' und '+='
Achtung: += liefert aus Performancegruenden den Typ void zurueck
-Kommaoperator ','
-Konditionaloperator '?:'
-sizeof
-Einstelliger Operator '+'
Bei strings sollte aus Performancegruenden unbedingt a+=b anstatt a=a+b
verwendet werden.
4. Kompilerdirektiven
---------------------------------------------------------------------------
Es existiert nur '#include datei', wobei der Dateiname nicht durch '<', '>'
oder '"' eingeschlossen sein darf. Bei Verwendung von #include muss der
Interpreter mit der option '-r Zahl' aufgerufen werden, die die maximale
"Rekursionstiefe" des Parsers hinsichtlich #include angibt (default 0).
5. Programmstruktur
---------------------------------------------------------------------------
Eine Funktion main() muss nicht definiert werden. Feder Anweisungsblock ist
ein gueltiges Programm. beispiel:
{ printf("Hello World\n"); }
Wird der Code in ASCII/HTML eingebettet (Option -h) sieht das ganze z.B.
so aus:
Content-Type: text/html
Test
printf("Hello"); ?> printf("World"); ?>
oder alternativ:
Content-Type: text/html
Test
<% printf("Hello"); %> <% printf("World"); %>
Damit das ganze als CGI-Skript funktioniert, muss die erste Zeile
#!/pfad/zu/boiler -hi
lauten. die Option i steht fuer das Ignorieren der ersten Zeile, die der
Parser nicht schlucken wuerde.
6. Bezeichner fuer Variablen und Funktionen
---------------------------------------------------------------------------
Variablen und Funktionen koennen ueberall definiert werden. Der
Gueltigkeitsbereich ist der jeweilige Anweisungsblock der Definition.
Jeder Bezeichner einer Variable oder Funktion kann auch ein Ausdruck der Form
[ String-Ausdruck ] sein, wodurch ein Bezeichner entsprechenden Namens
referenziert wird. Beispiel:
{
string s="printf";
[s]("Hello World\n");
s="Hello World\n";
string [s]=s;
printf([s]);
void [s](string a) { printf(a); return; };
[s](s);
s="exit";
[s]();
}
Bei einer Definition wird die entsprechende Variable oder Funktion im
gleichen Anweisungsblock angelegt und ist somit nur in diesem gueltig. Dies
ist nicht immer wuenschenswert, weswegen bei einer Referenzierung ueber
einen String-Ausdruck ein zweiter Long-Ausdruck angegeben werden kann, der
fuer den Gueltigkeitsbereich des Bezeichners relativ zum aktuellen
Anweisungsblock steht. '0' bedeutet aktueller Block, '1' ergibt den
uebergeordneten Block, '2' den Block darueber u.s.w. eine negative Zahl
steht fuer den Startblock - dient also zur Referenzierung "globaler"
Bezeichner, die Zahl -2 steht fuer den Systemblock, der von allen (auch
abgekapselten) Programmteilen verwendet werden kann. Im Systemblock finden sich
u.A. die Systemfunktionen und die Systemvariablen wie error und perror.
Der Aufruf von:
{
string s="startblock\n";
{
string s="subblock 1\n";
{
string s="subblock 2\n";
printf(s+["s",1]+["s",2]+["s",-1]);
}
}
}
ergibt die Ausgabe:
subblock 2
subblock 1
startblock
startblock
7. Accounting
---------------------------------------------------------------------------
Es gibt vier Accounting-Typen:
0 Interne Rekursionen
1 Variablen
2 Funktionen
3 Aufrufe von Library-Funktionen
Die internen Rekursionen sind nicht Rekursionen des BOIL-Programms, es sind die
vielen kleinen Subfunktionsaufrufe die der Interpreter macht um eine Anweisung
auszufuehren. Wenn der Interpreter einen Subfunktionsaufruf mach, eine Variable
oder Funktion erzeugt oder eine Library-Funktion aufruft, erhoeht er die
entsprechenden Accouting-Zaehler. Wenn eine Subfunktion beeendet, eine Variable
oder Funktion geloescht oder eine Library-Funktion beendet wird, werden die
entsprechenden Accounting-Zaehler dekrementiert. Das Accounting wird am besten
anhand eines kleinen Beispiels deutlich (examples/accounting):
{
for (unsigned long i=0;i!=10;i++) { printf("."); }
printf("\n");
}
Wird dies aufgerufen mit
boiler -z on -s -a 0:0:0:0 -a 1:0:0:0 -a 2:0:0:0 -a 3:0:0:0 accounting
erhalten wir die Ausgabe:
..........
accounting-stats:
-----------------
type 0: sum: 169 (0 max) actual: 0 (0 max) time: 0.017135 (0 max)
type 1: sum: 1 (0 max) actual: 0 (0 max) time: 0.016029 (0 max)
type 2: sum: 0 (0 max) actual: 0 (0 max) time: 0.000000 (0 max)
type 3: sum: 11 (0 max) actual: 0 (0 max) time: 0.001578 (0 max)
Das bedeutet:
-Der Interpreter brauchte 169 Subfunktionsaufrufe in 0.017 Sekunden um das
Programm auszufuehren.
-Eine Variable wurde definiert
-Keine Funktion wurde definiert
-Elf Aufrufe von printf wurden in 0.001 Sekunden gehandhabt
Es hat keinen Sinn Zeitlimits fuer Variablen und Funktionen zu setzen, bei
Library-Funktionsaufrufen und internen Rekursionen dagegen ist es sinnvoll.
Limits fuer die aktuellen Zaehler von Library-Funktionsaufrufen haben keinen
Sinn da der Interpreter maximal eine Library-Funktion zu jedem Zeitpunkt
ausfuehrt. Der Unterschied zwischen akkumulierten und aktuellen Instanzen ist
einfach: Werden zum Beispiel die akkumulierten Instanzen der internen
Rekursionen begrenzt, ist damit die "Laufzeit" des Programms begrenzt. Werden
dagegen die aktuellen Instanzen begrenzt, ist die Rekursionstiefe begrenzt.
8. Neue Optionen fuer Funktionsbloecke
---------------------------------------------------------------------------
Bei jeder Funktionsdeklaration kann vor die Liste der Argumente ein String-
Ausdruck gesetzt werden, der eine Optionsliste wie beim Aufruf des
Interpreters enthalten muss:
void print("-z off",string s) { printf(s); return; }
In diesem Beispiel werden Aufrufe der Funktion print vom Zeit-Accounting
ausgenommen.
Sobald sich der Interpreter beim Ausfuehren der Funktion befindet, gelten die
veraenderten Optionen. Hierbei gelten Folgende Regeln:
-Sobald die Option -a verwendet wurde, erhaelt die Funktion ein separates
Accounting, das bei jedem Aufruf zurueckgesetzt wird (Ausnahme: Rekursion)
-Sobald die Option -x verwendet wurde, sind die bisherigen Verbote fuer
Funktionsaufrufe ungueltig
Folgende Optionen koennen bei einer Funktionsdeklaration nicht angegeben
werden: -m -d -s
Folgende sind zusaetzlich moeglich:
-p Gibt ein Passwort fuer den externen Aufruf der Funktion an (Siehe weiter
unten).
-l Loescht die Liste aller Handles fuer Dateien, Datenbankverbindungen, etc.
so dass die Funktion nicht auf diese zugreifen kann, ohne sie vorher zu
oeffnen.
-c typ:handle Uebergibt ein Handle (nur nach -l moeglich). Typen:
1 Streams
2 Postgres-Verbindungen
3 Postgres-Abfragen
4 RPC-Server
5 RPC-Client
6 Sockets
7 Verzeichnisse
8 msql-Verbindungen
9 msql-Abfragen
10 mysql-Verbindungen
11 mysql-Abfragen
-f Flags. Die angegebene Zahl regelt die Berechtigungen des Funktionsrumpfes
beim Zugriff auf uebergeordnete Objekte:
1 Funktionsaufrufe sind gestattet
2 Zugriff auf Variablen ist gestattet (lesend und schreibend)
4 Variablen koennen deklariert werden
ist die Zahl 0, so ist der Funktionsrumpf bis auf die Argumente und den
Rueckgabewert vom restlichen Programm abgekapselt. Sofern nicht -l
angegeben wurde koennen aber weiterhin die Handles des rufenden Programms
benutzt werden.
Eine Zugriffsbeschraenkung kann somit durch die Deklaration von Funktionen
mit Optionsstrings umgangen werden, wenn diese nicht mit "-o off" ausgeschaltet
wurden.
9. Zur Laufzeit geparste Programmteile
---------------------------------------------------------------------------
Bei einer Funktionsdeklaration kann anstatt des Rumpfes auch ein Ausdruck der
Form eval(code) angegeben werden. Der String-Ausdruck code muss ein korrektes
BOIL-Programm sein und wird zum Funktionsrumpf. Parser-Optionen koennen mit
Hilfe eines Optionsstrings angegeben werden. Beispiel:
void print(string a) eval("{ printf(a); return; }")
10. Laufzeitfehler innerhalb von Funktionsaufrufen
---------------------------------------------------------------------------
Laufzeitfehler oder Aufrufe von exit() innerhalb von Funktionsaufrufen
fuehren normalerweise zum Abbruch des Programms, was nicht immer
wuenschenswert ist (z.b. bei Funktionen, die waehrend der Laufzeit geparst
wurden). Durch Klammerung des Funktionsnamens beim Aufruf kann dies verhindert
werden. Zudem werden auf diese Art Accountinginformationen eines
Funktionsrumpfes mit separatem Accounting dem aufrufenden Programm
zugaenglich. Ein Funktionsaufruf der Form
(funktion)(argumente)
Setzt folgende Variablen im aktuellen Anweisungsblock:
unsigned long func_status Status
1=OK
2=continue-Anweisung
3=break-Anweisung
4=return-Anweisung
5=exit-Anweisung oder Laufzeitfehler
string func_error Fehlermeldung
unsigned long func_error_line Zeile des Fehlers
string func_error_file Datei des Fehlers
Fuer jeden Accounting-Typ wird gesetzt:
string func_acc_ X1:X2:X3
X1=Akkumulierte Instanzen
X2=Aktuelle Instanzen
X3=Instanzlaufzeit Sekunden
X4=Instanzlaufzeit Mikrosekunden
11 Externe Funktionen
---------------------------------------------------------------------------
Die verteilte Programmierung wird von BOIL mit Hilfe der Remote Procedure Calls
(RPC) unterstuetzt. Der Aufruf einer Funktion kann zur Ausfuehrung eines
im gleichen Programm angegebenen Funktionsrumpfes fuehren oder - voellig
transparent - ueber einen RPC von einem entfernten BOIL-Server verarbeitet
werden.
Auf der Client-Seite werden hierfuer externe Funktionen deklariert. Der
Funktionsrumpf ist ein Ausdruck der Form
external(Client-Handle,Funktionsname,Passwort)
z.B.:
void print external(clnt,"print","geheim")
Die Client-Handles werden mit Hilfe der Library-Funktionen
clnt_create(host,rpc-programmnummer,version,protokoll) und clnt_destroy(handle)
verwaltet.
Auf der Server-Seite muss mit der Library-Funktion
svc_register(rpc-programmnummer,version,protokoll,fork,socket) ein oder mehrere
RPC-Server angemeldet werden. Mit der Funktion
svc_run(timeout_sek,timeout_usek) koennen dann Aufrufe entgegengenommen
werden. Ist fork=1, so wird vor dem Ausfuehren der aufgerufenen Funktion ein
Kindprozess erzeugt, so dass der Server fuer weitere Aufrufe zur Verfuegung
steht. Nachteil: Veraenderungen in den Datenstrukturen des Serverprogramms
gehen verloren. ACHTUNG: wenn svc_run zurueckkehrt koennen auch mehrere
Prozesse gestartet worden sein. Sofern eine globale Funktion
void fork_handler(long pid) definiert ist, wird sie nach der Erzeugung des
Kinprozesses mit dessen PID aufgerufen. Es koennen nur solche Funktionen des
Servers Aufgerufen werden, bei denen mit "-p" ein Passwort angegeben wurde.
Mit der Funktion svc_unregister(handle) werden die angemeldeten RPC-Server
wieder abgemeldet.
Das Ende eines Kindprozesses wird vom Interpreter defaultmaessig ignoriert.
Dies kann mit dem Aufruf sigcld(1) veraendert werden, so dass das Ende jedes
Kindprozesses mit der Funktion long waidpid() abgefangen werden muss (ansonsten
entstehen Zombieprozesse).
Ein Beispiel fuer den Aufbau von Server und Clients findet sich im Verzeichnis
examples/rpc.
12. Library-Funktionen
---------------------------------------------------------------------------
Tritt ein Fehler, EOF, etc. innerhalb einer Library-Funktion auf, wird die
Systemvariable 'error' auf 1 gesetzt (und behaelt diesen Wert, falls
nicht zurueckgesetzt wird). In perror steht dann ein entsprechender
Fehlertext. error und perror koennen auch von einem Cast von string zu long
oder double gesetzt werden. Bei Funktionen mit zweideutigem Rueckgabewert
empfiehlt sich die Abfrage von error (z.b. ist der Rueckgabewert von strlen()
bei einem undefinierten String 0).
Folgende Library-Funktionen wurden bis jetzt implementiert (R steht fuer
Rueckgabewert):
12.1 Standardfunktionen
---------------------------------------------------------------------------
unsigned long printf(string a)
R 0 a ist Leer oder Fehler
R Anzahl der ausgegebenen Zeichen
void sleep(unsigned long time)
time Sekunden warten.
string getenv(string)
Eine Umgebungsvariable einlesen.
R undefiniert Fehler
R Inhalt der Umgebungsvariable
unsigned long setenv(string name,string value,unsigned long overwrite)
Eine Umgebungsvariable setzen.
R 0 Fehler
R 1 OK
void srandom(unsigned long seed)
Siehe 'man srandom'. Die Anzahl der Mikrosekunden beim Start des Interpreters
modulo 65536 bestimmt den Defaultseed.
long random()
Siehe 'man random'.
string crypt(string key)
Ein Passwort verschluesseln. Das im Gegensatz zur libc-Funktion fehlende
Argument 'salt' wird mit Hilfe von random() erzeugt.
R undefiniert Fehler
R Verschluesseltes Passwort
long waitpid()
Auf das Ende eines Kindprozesses warten.
R -1 Fehler
R 0 Kein Kindprozess wurde beendet
R PID des beendeten Kindes
void sigcld(unsigned long flag)
Signal-Handling fuer SIGCLD umstellen:
flag==0 Ignorieren,defaulteinstellung
flag==1 Eigener Handler. Auf die Kinder muss mit waidpid() gewartet
werden
long getpid()
Eigene PID bestimmen.
R -1 Fehler
R PID
long system(string cmd)
Ein Shell-Kommando aufrufen.
R -1 Fehler
R Exit-Code
double sqrt(double arg)
Quadratwurzel bestimmen.
R Ergebnis
12.2 Zeit
---------------------------------------------------------------------------
unsigned long time()
R Aktuelle Zeit
Sofern eine Variable time_usec des Typs unsigned long existiert, wird dort
der Mikrosekundenanteil der Zeit abgelegt.
unsigned long mktime(unsigned long year,
unsigned long month,
unsigned long day,
unsigned long hour,
unsigned long minute,
unsigned long second)
Konkrete Uhrzeit in Sekunden seit dem 1. Januar 1970 umrechnen.
R 0 Fehler oder 1. Jan 1970 00:00:00
R Anzahl der Sekunden
string strftime(string format,unsigned long seconds)
Anzahl der Sekunden in einen formatierten Datumsstring umwandeln. Es koennen
die gleichen Metazeichen wie bei 'man strftime' angegeben werden.
R undefiniert Fehler
R Datumsstring
12.3 Dateien und Verzeichnisse
---------------------------------------------------------------------------
long filesize(string path)
R -1 Datei nicht gefunden oder > 2GB
R Dateigroesse
unsigned long fileatime(string path)
atime eines Dateisystemobjektes ausgeben.
R 0 Fehler
R atime
unsigned long filemtime(string path)
mtime eines Dateisystemobjektes ausgeben.
R 0 Fehler
R mtime
unsigned long unlink(string path)
Datei entfernen.
R 0 Fehler
R 1 OK
string tmpnam()
Eindeutigen Dateinamen fuer eine temporaere Datei erzeugen.
R undefiniert Fehler
R Dateiname
long opendir(string path)
Ein Verzeichnis oeffnen.
R -1 Fehler
R Handle
string readdir(long handle)
Naechsten Dateinamen holen ("." und ".." werden ebenfalls ausgegeben).
R undefiniert Fehler
R Dateiname
unsigned long closedir(long handle)
Ein Verzeichnis schliessen.
R 0 Fehler
R 1 OK
unsigned long mkdir(string path)
Ein Verzeichnis erzeugen.
R 0 Fehler
R 1 OK
unsigned long rmdir(string path)
Ein Verzeichnis loeschen. Vorher muessen alle enthaltenen Dateien und
Verzeichnissse geloescht werden.
R 0 Fehler
R 1 OK
unsigned long rename(string oldpath,string newpath)
Eine Datei umbenennen.
R 0 Fehler
R 1 OK
12.4 Funktionen fuer CGI-Skripten
---------------------------------------------------------------------------
unsigned long cgiwrap(string path,string postdata,unsigned long head)
Spezialfunktion fuer eigene Zwecke.
Gibt ein Dokument zzgl. Content-Typ aus bzw. startet ein CGI-Skript, falls
file die Endung .cgi hat:
gif image/gif
jpg image/jpeg
jpeg image/jpeg
jpe image/jpeg
html text/html
htm text/html
cgi Content-type wird vom aufgerufenen CGI-Skript bestimmt
sonst application/octet-stream
Ist head==1, so wird der Content-type nicht ausgegeben.
Hat die Datei keine Endung und ist ein Verzeichnis, so wird versucht
index.html bzw. index.htm in diesem auszugeben. Ansonsten Ergibt die Funktion
einen Fehler.
R 0 Fehler
R 1 OK
unsigned long getpost()
Liest via POST (CGI) uebermittelte Daten in Variablen des aktuellen Blocks ein.
R 0 Fehler
R 1 OK
unsigned long postdata(string postdata)
unsigned long postdata_utf8(string postdata)
Liest via POST/GET (CGI) uebermittelte Daten in Variablen des aktuellen Blocks
ein. Die Daten werden als Argument uebergeben und mussen vorher aus der
Umgebungsvariable QUERY_STRING oder von stdin gelesen worden sein.
R 0 Fehler
R 1 OK
string postdata_utf8tolatin1(string postdata)
Rekodiert Formulardaten aus QUERY_STRING oder von stdin von UTF8 nach latin1.
Bei invalidem UTF8 wird der Originalstring zurückgegeben und error gesetzt.
R undefiniert Fehler
R Ergebnis
string file_upload(long maxsize)
Liest via POST (CGI) uebermittelte Daten mit Encoding-Type
'multipart/form-data' ein. Derartige Formulare werden vor allem fuer
File-Uploads verwendet (). Es kann nur eine einzige Datei
uebertragen werden, deren temporaerer Filename der Rueckgabewert ist. Sonstige
POST-Daten werden als Variablen des aktuellen Blocks angelegt. Außerdem
wird ein entsprechender query-string mit wwwurl-Encoding in der Variablen
upload_postdata des aktuellen Blocks angelegt. Der urspruengliche Dateiname
wird als Variable 'file' abgelegt.
R undefiniert Fehler
R Dateiname
string htmlenc(string data)
Diverse HTML-Metazeichen in data werden im Format %Zahl; geschuetzt, so dass
sie nicht als HTML interpretiert werden ('<','>','"','\','&').
R undefiniert Fehler
R Neue Zeichenkette
unsigned long phtmlenc(string data)
Wie htmlenc, nur wird das Ergebnis gleich mit printf() ausgegeben.
R 0 Fehler
R 1 OK
string fullhtmlenc(string data)
Jedes nicht alphanumerische Zeichen in data wird im Format %Zahl geschuetzt,
was beim Zusammenbau von POST- bzw. GET-Daten in der Default-Kodierung
'application/x-www-form-urlencoded' nuetzlich ist.
R undefiniert Fehler
R Neue Zeichenkette
12.5 Funktionen fuer BOIL-Interna
---------------------------------------------------------------------------
void exit()
Sofortiger Programmabbruch.
unsigned long setproctitle(string)
Setzt Titel des Programms im Prozessquerschnitt.
R 0 Fehler
R 1 OK
unsigned long isset(string)
Prueft auf Vorhandensein einer Variable.
R 0 Variable nicht vorhanden oder Fehler
R 1 Variable vorhanden
unsigned long isfunc(string)
Prueft auf Vorhandensein einer Funktion.
R 0 Funktion nicht vorhanden oder Fehler
R 1 Funktion vorhanden
unsigned long deletefunc(string name,long block)
Eine Funktion loeschen. Systemfunktionen koennen nicht geloescht werden.
R 0 Fehler
R 1 OK
unsigned long deletevar(string name,long block)
Eine Variable loeschen. Systemvariablen koennen nicht geloescht werden.
R 0 Fehler
R 1 OK
unsigned long parse(string code,string options)
Parsen des BOIL-Programms in code.
R 0 Fehler
R 1 OK
12.6 Locking
---------------------------------------------------------------------------
long do_lock(string file)
Ein Lockfile fuer die Datei file (.lck) anlegen.
R -1 Fehler
R 0 Bereits gelockt
R 1 OK
long do_unlock(string file)
Einen Lock wieder freigeben.
R -1 Fehler
R 1 OK
12.7 Strings
---------------------------------------------------------------------------
string base64encode(long stream)
R undefiniert Fehler
R Inhalt von stream in base64-Kodierung
string base64stringencode(string a)
R undefiniert Fehler
R Inhalt von a in base64-Kodierung
long base64decode(string b64,long stream)
Dekodiert den base64-String in b64 und schreibt das Ergebnis in stream.
R 0 Fehler
R 1 OK
string md5(string a)
R undefiniert Fehler
R MD5-Hashwert von a
unsigned long defined(string a)
R 0 String a undefiniert
R 1 String a definiert
string strstr(string a,string needle)
Needle in a suchen und diesen String mit dem rest von a zurueckgeben.
R undefiniert Fehler (z.B. needle nicht gefunden)
R needle mit Rest von a
string strtok(string a,string delim)
a entsprechend der angegebenen Trennzeichen aufteilen. Das 2. bis n. Token
erhaelt man ueber die Funktion token(). Als Token wird eine nichtleere
Zeichenkette aus Zeichen, die nicht in delim vorkommen, verstanden. Sie muss
mit 0 enden oder von einem Zeichen aus tokens gefolgt werden.
R undefiniert Fehler (z.B. Token nicht gefunden)
R 1. Token
string token(string delim)
Weitere Tokens extrahieren.
R undefiniert Fehler (z.B. Token nicht gefunden)
R Token
string strtok1(string a,string delim)
Wie strtok(), betrifft aber den Inhalt der Variable mit dem Namen a (Reentrante
version). Anstatt token(delim) ab dem zweiten Aufruf ruft man hier immer wieder
strtok1(a,delim) auf. Der Inhalt der Variable a geht im Verlauf der Zerlegung
verloren.
string strtok_esc(string a,string delim)
Wie strtok, nur werden durch '\' geschuetzte Zeichen nicht fuer die Trennung
herangezogen.
R undefiniert Fehler (z.B. Token nicht gefunden)
R 1. Token
string token_esc(string delim)
R undefiniert Fehler (z.B. Token nicht gefunden)
R Token
string strtolower(string a)
Grossbuchstaben in Kleinbuchstaben.
R undefiniert Fehler
R Ergebnis
string strtoupper(string a)
Kleinbuchstaben in Grossbuchstaben.
R undefiniert Fehler
R Ergebnis
string substr(string a,unsigned long start,unsigned long length)
Eine Zeichenkette aus a extrahieren. Start beginnt bei 0, Length bei 1.
R undefiniert Fehler (z.B. Startposition zu hoch)
R Ergebnis
unsigned long strlen(string a)
Laenge der Zeichenkette a.
R 0 Fehler oder Zeichenkette leer
R Laenge
string escape(string a,string escapes)
Die in escapes angegebenen Metazeichen durch \ schuetzen.
R undefiniert Fehler
R Geschuetzter String
string unescape(string a)
Schutz von Metazeichen entfernen.
R undefiniert Fehler
R Ungeschuetzter String
string escape1(string a)
Zeilenumbruch, Wagenruecklauf, vertikalen Tabulator und Seitenvorschub
durch "\n","\r","\v" und "\f" ersetzen.
R undefiniert Fehler
R Geschuetzter String
string unescape1(string a)
escape1() rueckgaengig machen.
R undefiniert Fehler
R Ungeschuetzter String
string textfile(string path)
Eine Textdatei einlesen.
R undefiniert Fehler
R Textdatei als Zeichenkette
unsigned long getchar(string a,unsigned long pos)
Ein Zeichen aus einer Zeichenkette extrahieren. pos beginnt bei 0.
R 0 Fehler
R Zeichen
string chr(unsigned long ch)
Liefert das Zeichen zum 8-Bit-Codepunkt ch.
R undefiniert Fehler
R Zeichen
string sql_escape(string data)
Metazeichen von SQL (''','"','\') durch '\' schuetzen.
R undefiniert Fehler
R Geschuetzter String
string str_repl(string source,string search,string replace)
in source search durch replace ersetzen (1x).
R undefiniert Fehler
R Ergebnis
string str_repla(string source,string search,string replace)
in source search durch replace ersetzen (sooft es vorkommt).
R undefiniert Fehler
R Ergebnis
string latin1toutf8(string source)
source von Latin1 nach UTF8 konvertieren.
R undefiniert Fehler
R Ergebnis
string utf8tolatin1(string source,unsigned long mode)
source von UTF8 nach Latin1 konvertieren.
mode = 0 -> Bei nicht kodierbaren Zeichen Fehler erzeugen
mode = 1 -> Nicht kodierbare Zeichen durch ? ersetzen
mode = 2 -> Nicht kodierbare Zeichen durch HTML-Charrefs (z.B. α) ersetzen
R undefiniert Fehler
R Ergebnis
12.8 Streams
---------------------------------------------------------------------------
long fopen(string filename,string mode)
Filename oeffnen und Handle zurueckgeben. Filename "STDIN" bzw. "STDOUT" kann
fuer die entsprechenden Streams angegeben werden.
R -1 Fehler
R Handle
long popen(string command,string mode)
Kommando ausfuehren und Handle zum Lesen/Schreiben der Ausgabe/Eingabe
zurueckgeben.
R -1 Fehler
R Handle
unsigned long exec(string path,string argname,
string inname,string outname)
Das Kommando 'path' mit der Funktion exec() aufrufen. Kommandozeilenargumente
werden mit Variablen der Form argname_Zaehler uebergeben. argname ist der
Basisname, der Zaehler faengt bei 0 an und hoert auf wenn die entsprechende
Stringvariable undefiniert ist. inname und outname sind die Namen der
long-Variablen in denen die Stream-Handles zum Schreiben der Eingabe und Lesen
der Ausgabe gespeichert werden. Anwendungsbeispiel:
string arg_0="sendmail",arg_1="-bm",arg_2=bm,arg_3;
long in,out;
exec("/usr/sbin/sendmail","arg_","in","out");
R 0 Fehler
R 1 OK
long feof(long handle)
R -1 Fehler
R 0 Kein EOF
R 1 EOF
string fgets(long handle)
R undefiniert Fehler oder EOF
R Eingelesene Zeile
unsigned long fputs(long handle,string data)
R 0 Fehler
R 1 OK
unsigned long fclose(long handle)
R 0 Fehler
R 1 OK
long pclose(long handle)
R -1 Fehler
R Exit-Code des Programms
unsigned long fflush(long handle)
R 0 Fehler
R 1 OK
unsigned long setoutstream(long handle)
Der Ausgabestream (printf,?> ,etc.) wird gesetzt. Voreingestellt ist stdout.
R 0 Fehler
R 1 OK
12.9 Postgres
---------------------------------------------------------------------------
unsigned long pg_close(long connection)
Verbindung zu einer Postgres-Datenbank schliessen.
R 0 Fehler
R 1 OK
long pg_connect(string host,string port,string options,string tty,
string dbname)
Verbindung zu einer Postgres-Datenbank oeffnen. Es wird ein Handle fuer
die Verbindung zurueckgegeben.
R -1 Fehler
R Handle
long pg_exec(long connection,string query)
Postgres-Befehl ausfuehren. Es wird ein Handle fuer das Ergebnis
zurueckgegeben.
R -1 Fehler
R Handle
unsigned long pg_freeresult(long result)
Ergebnis eines Postgres-Befehls loeschen.
R 0 Fehler
R 1 OK
unsigned long pg_numfields(long result)
Anzahl der Felder eines Ergebnisses.
R 0 Fehler oder 0 Felder
R Anzahl
unsigned long pg_numrows(long result)
Anzahl der Datensaetze eines Ergebnisses.
R 0 Fehler oder 0 Datensaetze
R Anzahl
string pg_fieldname(long result,unsigned long field)
Den Namen eines Feldes bestimmen.
R undefiniert Fehler
R Name
string pg_fieldtype(long result,unsigned long field)
Den Typ eines Feldes bestimmen.
R undefiniert Fehler
R Typ
string pg_result(long result,unsigned long row,unsigned long field)
Den Wert eines Feldes auslesen.
R undefiniert Fehler
R Wert
12.10 msql
---------------------------------------------------------------------------
unsigned long msql_close(long connection)
Verbindung zu einer Datenbank schliessen.
R 0 Fehler
R 1 OK
long msql_connect(string host)
Verbindung zu einer Datenbank oeffnen. Es wird ein Handle fuer
die Verbindung zurueckgegeben.
R -1 Fehler
R Handle
unsigned long msql_selectdb(long connection,string database)
Datenbank auswaehlen.
R 0 Fehler
R 1 OK
long msql_exec(long connection,string query)
SQL-Befehl ausfuehren. Es wird ein Handle fuer das Ergebnis
zurueckgegeben.
R -1 Fehler
R Handle
unsigned long msql_freeresult(long result)
Ergebnis eines Befehls loeschen.
R 0 Fehler
R 1 OK
unsigned long msql_numfields(long result)
Anzahl der Felder eines Ergebnisses.
R 0 Fehler oder 0 Felder
R Anzahl
unsigned long msql_numrows(long result)
Anzahl der Datensaetze eines Ergebnisses.
R 0 Fehler oder 0 Datensaetze
R Anzahl
string msql_fieldname(long result,unsigned long field)
Den Namen eines Feldes bestimmen.
R undefiniert Fehler
R Name
long msql_fieldtype(long result,unsigned long field)
Den Typ eines Feldes bestimmen.
R -1 Fehler
R Typ
string msql_result(long result,unsigned long row,unsigned long field)
Den Wert eines Feldes auslesen.
R undefiniert Fehler
R Wert
12.11 mysql
---------------------------------------------------------------------------
Entsprechend den msql-Funktionen mit Prefix "mysql_". mysql_connect() hat
allerdings drei Argumente:
long mysql_connect(string host,string user,string password)
12.12 Sockets
---------------------------------------------------------------------------
unsigned long inet_aton(string ip)
IP-Adresse konvertieren.
R 0 Fehler oder 0.0.0.0
R Adresse
string inet_ntoa(unsigned long ip)
IP-Adresse konvertieren.
R undefiniert Fehler
R Adresse
long makesock(string host,unsigned long port,long type,long protocol)
socket() und bind() aufrufen. Ist host=="" so wird an jede IP-Adresse des
Systems gebind()ed. Ist port=0 wird bind() nicht aufgerufen.
R -1 Fehler
R Socket-Handle
unsigned long closesock(long handle)
Einen Socket wieder schliessen.
R 0 Fehler
R 1 OK
unsigned long connectsock(long sock,string dest,unsigned long destport)
Eine Verbindung aufbauen. dest kann sowohl IP-Adresse als auch Hostname sein.
R 0 Fehler
R 1 OK
unsigned long send(long sock,string msg)
Daten ueber einen verbundenen Socket senden.
R 0 Fehler
R 1 OK
string recv(long sock)
Daten zeilenweise ueber einen verbundenen Socket empfangen.
R undefiniert Fehler oder EOF
R 1 OK
12.13 RPC
---------------------------------------------------------------------------
long clnt_create(string host,
unsigned long program,
unsigned long version,
string protocol)
Ein Handle fuer externe Funktionsaufrufe gewinnen. Achtung: das Protokoll wird
als String ("udp","tcp") angegeben.
R -1 Fehler
R Handle
unsigned long clnt_destroy(long handle)
Ein Handle fuer externe Funktionsaufrufe freigeben.
R 0 Fehler
R 1 OK
long svc_register(unsigned long program,
unsigned long version,
unsigned long protocol,
unsigned long fork,
long socket)
Einen RPC-Server anmelden. Ist fork==1, so wird bei jedem Request ein
Kindprozess erzeugt.
R -1 Fehler
R Handle
long svc_run(unsigned long timeout_sec,
unsigned long timeout_usec)
Einen oder mehrere RPC-Requests entgegennehmen. Findet bis zum Timeout kein
Request statt, kehrt die Funktion zurueck.
R -1 Fehler
R 0 Timeout
R 1 OK
unsigned long svc_unregister(long handle)
Einen RPC-Server abmelden.
R 0 Fehler
R 1 OK
unsigned long clnt_timeout(long handle,unsigned long seconds)
Setzt den Timeout fuer RPC-Requests (UDP und TCP).
R 0 Fehler
R 1 OK
unsigned long clnt_udp_retry(long handle,unsigned long seconds)
Setzt den Retry-Timeout fuer RPC-Requests (nur UDP).
R 0 Fehler
R 1 OK
13. BNF-Grammatik (fuer die, denen das weiterhilft)
---------------------------------------------------------------------------
Zuerst die mehrbuchstabigen Tokens:
Token Syntaktischer Wert
----------------------------------
LONG long
UNSIGNED unsigned
DOUBLE double
STRING string
VOID void
IF if
ELSE else
FOR for
WHILE while
DO do
BREAK break
CONTINUE continue
RETURN return
EVAL eval
EXTERNAL external
OR ||
AND &&
EQUAL ==
NOTEQUAL !=
LE <=
GE >=
SHIFTLEFT <<
SHIFTRIGHT >>
PLUSPLUS ++
MINUSMINUS --
PLUSEQUAL +=
Die terminalen Tokens sind CONST (Konstante), NAME (Bezeichner), und
PRINT (Textausgabe bei Einbettung in ASCII/HTML).
Die nichtterminalen Tokens sind wie folgt definiert:
type: LONG
| UNSIGNED LONG
| DOUBLE
| STRING
| VOID
reference: NAME
| '[' expr ']'
| '[' expr ',' expr ']'
expr_list: expr
| expr_list ',' expr
function_call: reference '(' expr_list ')'
| reference '(' ')'
| '(' reference ')' '(' expr_list ')'
| '(' reference ')' '(' ')'
expr: CONST
| reference
| function_call
| reference '=' expr
| reference PLUSEQUAL expr
| reference PLUSPLUS
| reference MINUSMINUS
| PLUSPLUS reference
| MINUSMINUS reference
| '(' type ')' expr
| '(' expr ')'
| '-' expr
| '~' expr
| '!' expr
| expr '?' expr ':' expr
| expr '*' expr
| expr '/' expr
| expr '%' expr
| expr '+' expr
| expr '-' expr
| expr SHIFTLEFT expr
| expr SHIFTRIGHT expr
| expr '<' expr
| expr '>' expr
| expr LE expr
| expr GE expr
| expr EQUAL expr
| expr NOTEQUAL expr
| expr '&' expr
| expr '^' expr
| expr '|' expr
| expr AND expr
| expr OR expr
arg_list_entry: type NAME
arg_list: arg_list_entry
| arg_list ',' arg_list_entry
function_dekl: type reference external_stmt
| type reference '(' arg_list ')' block
| type reference '(' ')' block
| type reference '(' arg_list ')' eval_stmt
| type reference '(' ')' eval_stmt
| type reference '(' expr ',' arg_list ')' block
| type reference '(' expr ')' block
| type reference '(' expr ',' arg_list ')'
eval_stmt
| type reference '(' expr ')' eval_stmt
dekl_list_entry: reference
| reference '=' expr
dekl_list: dekl_list_entry
| dekl_list ',' dekl_list_entry
variable_dekl: type dekl_list ';'
expr_stmt: ';'
| expr ';'
choice_stmt: IF '(' expr ')' stmt
| IF '(' expr ')' stmt ELSE stmt
loop_stmt: WHILE '(' expr ')' stmt
| DO stmt WHILE '(' expr ')' ';'
| FOR '(' stmt expr ';' expr ')' stmt
| FOR '(' stmt ';' expr ')' stmt
| FOR '(' stmt expr ';' ')' stmt
| FOR '(' stmt ';' ')' stmt
jump_stmt: BREAK ';'
| CONTINUE ';'
| RETURN ';'
| RETURN expr ';'
eval_stmt: | EVAL '(' expr ')'
external_stmt: EXTERNAL '(' expr ',' expr ',' expr ')'
stmt: variable_dekl
| function_dekl
| expr_stmt
| block
| choice_stmt
| loop_stmt
| jump_stmt
| PRINT
stmt_list: stmt
| stmt_list stmt
block: '{' '}'
| '{' stmt_list '}'