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 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,?> = 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 '}'