Go to the first, previous, next, last section, table of contents.


MUIbase programmieren

Dieses Kapitel(22) beschreibt die Programmiersprache von MUIbase, einschließlich aller verfügbaren Funktionen. Das Kapitel dient jedoch nicht als allgemeine Anleitung für Programmieren. Man sollte mit den Grundzügen der Programmierung vertraut sein und schon kleinere(23) Programme geschrieben haben(24).

Programmeditor

Um ein Programm für ein Projekt einzugeben, öffnet man den Programmeditor über den Menüpunkt `Programm - Ändern...'. Dies öffnet das Fenster `Ändere Programm' mit:

Der Programmeditor ist ein asynchrones Fenster. Das Fenster kann offen gelassen und weiterhin mit dem Rest der Anwendung gearbeitet werden. Man kann den Editor zu jeder Zeit schließen, indem dessen Fensterschließ-Knopf gedrückt wird. Wurden Änderungen seit der letzten erfolgreichen Kompiliation vorgenommen, dann erscheint ein Sicherheitsfenster, das um Bestätigung fragt, ob das Fenster geschlossen werden darf.

Man kann das Projektprogramm auch ohne das Öffnen des Programmeditors kompilieren, indem der Menüpunkt `Programm - Kompilieren' ausgewählt wird. Dies ist nützlich, wenn Änderungen an einer Einfügedatei gemacht wurden und diese Änderungen in das Projektprogramm einfließen sollen.

Vorverarbeitung

MUIbase-Programme werden vorverarbeitet, wie ein C-Compiler einen C-Quellcode vorverarbeitet. Dieser Abschnitt beschreibt, wie die Vorverarbeitungs-Anweisungen verwendet werden.

Alle Anweisungen beginnen mit dem Rauten-Symbol #, welcher das erste Zeichen in einer Zeile sein muß. Leerzeichen und Tabulatoren können nach dem begonnenen # folgen.

#define

#define name string

Definiert ein neues Symbol mit dem gegebenen Namen und Inhalt. Das Symbol string kann jeder Text einschließlich Leerzeichen sein und endet am Zeilenende. Paßt string nicht in eine Zeile, dann können weitere Zeilen durch ein Backslash-Zeichen \ am Ende jeder Zeile (außer der letzten) verwendet werden. Taucht das Symbol name im verbleibenden Quellcode auf, dann wird es durch den Inhalt von string ersetzt.

Beispiel: `(PRINTF "X ist %i" X)' gibt `X ist 1' aus (name's in Zeichenketten werden nicht verändert.)

Das Ersetzen von definierten Symbolen geschieht syntaktisch, das bedeutet, daß Symbole durch jeden Text ersetzt werden können, z.B. man kann sich seine eigene Syntax wie im folgenden Beispiel definieren:

#define BEGIN (
#define END )

BEGIN defun test ()
        ...
END

Die zu ersetzende Zeichenkette einer Definition kann ein anderes Symbol enthalten, das mit der #define-Anweisung definiert wurde, um verschachtelte Definitionen zu ermöglichen. Es gibt jedoch eine Obergrenze von 16 verschachtelten Definitionen.

Siehe auch #undef, #ifdef, #ifndef.

#undef

#undef name

Entfernt die Definition des Symbols name. Wurde name nicht definiert, dann passiert nichts.

Siehe auch #define, #ifdef, #ifndef.

#include

#include filename

Liest den Inhalt von filename (eine Zeichenkette in Anführungszeichen) an diese Stelle. MUIbase sucht im aktuellen Verzeichnis und im in den Einstellungen festgelegten Verzeichnis (siehe Einfügedateienverzeichnis(25)) nach der zu ladenden Datei.

Der Dateiinhalt wird durch den Compiler verarbeitet, als ob er Teil des momentanen Quellcodes wäre.

Eine externe Datei kann eine oder mehrere externe Dateien enthalten. Es gibt jedoch eine Obergrenze von 16 verschachtelten #include-Anweisungen. Um zu vermeiden, daß Dateien mehr als einmal eingefügt werden, kann die bedingte Kompilation verwendet werden.

Man sollte vorsichtig sein, wenn man Quellcode in externe Dateien auslagert! Die Fehlersuche und das Auffinden von Fehlern in externen Dateien wesentlich schwerer. Man verschiebe daher nur getesteten und Projekt-unabhängigen Code in externe Dateien.

#if

#if const-expr

Ist der gegebene konstante Ausdruck const-expr nicht NIL, dann wird der Text bis zum zugehörigen #else, #elif oder #endif zur Kompilation verwendet, anderenfalls (der Ausdruck lieferte NIL) wird der Text bis zum zugehörigen #else, #elif oder #endif nicht zur Kompilation herangezogen.

Momentan können nur TRUE und NIL als konstante Ausdrücke verwendet werden.

Siehe auch #ifdef, #ifndef, #elif, #else, #endif.

#ifdef

#ifdef name

Ist das gegebene Symbol name mit einer #define-Anweisung definiert worden, dann wird der Text bis zum zugehörigen #else, #elif oder #endif zur Kompilation verwendet, anderenfalls nicht betrachtet.

Siehe auch #if, #ifndef, #elif, #else, #endif.

#ifndef

#ifndef name

Ist das gegebene Symbol name nicht mit einer #define-Anweisung definiert worden, dann wird der Text bis zum zugehörigen #else, #elif oder #endif zur Kompilation verwendet, anderenfalls nicht betrachtet.

Siehe auch #if, #ifdef, #elif, #else, #endif.

#elif

#elif const-expr

Beliebig viele #elif-Anweisungen können zwischen einem #if, #ifdef oder #ifndef und dem zugehörigen #else oder #endif auftreten. Die Zeilen, die der elif-Anweisung folgen, werden für eine Kompilation verwendet, aber nur dann, wenn jede der folgenden Bedingungen erfüllt ist:

Wenn die oben genannten Bedingungen stimmen, dann werden die nachfolgenden Anweisungen #elif und #else bis zum zugehörigen #endif ignoriert.

Siehe auch #if, #ifdef, #ifndef, #else, #endif.

#else

#else

Dies kehrt den Sinn einer bedingten Anweisung um, der sonst gestimmt hätte. Wenn die vorhergehende Bedingung anzeigen würde, daß Zeilen eingefügt werden, dann werden die Zeilen zwischen #else und dem zugehörigen #endif ignoriert. Zeigt die vorhergehende Bedingung an, daß Zeilen ignoriert werden, dann werden nachfolgende Zeilen für die Kompilation eingefügt.

Bedingte Anweisungen und dazugehörige #else-Anweisungen können verschachtelt werden. Es gibt jedoch eine maximale Verschachteltiefe von 16 verschachtelten bedingten Anweisungen.

Siehe auch #if, #ifdef, #ifndef, #elif, #endif.

#endif

#endif

Beendet einen Bereich von Zeilen, der mit einer der bedingten Anweisungen #if, #ifdef oder #ifndef beginnt. Jeder dieser Anweisungen muß eine zugehörige #endif-Anweisung besitzen.

Siehe auch #if, #ifdef, #ifndef, #elif, #else.

Programmiersprache

MUIbase verwendet eine Programmiersprache mit einen lisp-ähnlichen Aufbau. Tatsächlich sind einige Konstrukte und Funktionen vom Standard-lisp entnommen worden. MUIbase ist jedoch nicht vollständig kompatibel zu Standard-lisp. Viele Funktionen fehlen (z.B. destruktive Befehle) und die Bedeutung einiger Befehle unterscheiden sich (z.B. der Befehl return).

Warum lisp?

Der Vorteil einer lisp-ähnlichen Sprache ist, daß man sowohl funktionell als auch mit Befehlen programmieren kann. Funktionelle Sprachen sind in mathematischen Anwendungen weit verbreitet. Das Grundelement von funktionellen Sprachen ist die Verwendung von Ausdrücken. Funktionen werden in mathematischer Schreibweise definiert und häufig wird Rekursion benutzt.

Befehlssprachen (wie C, Pascal, Modula) benutzen eine Befehlsvorschrift, wie etwas berechnet werden soll(26). Hier ist das Grundelement der Zustand (z.B. Variablen) und ein Programm berechnet dessen Ausgabe durch den Sprung von einem Zustand in einen anderen (z.B. durch Zuweisen von Werten an Variablen).

Lisp kombiniert beide Techniken und deshalb kann man auswählen, auf welche Art etwas implementiert werden soll. Man verwendet diejenige, die besser zum vorgegebenen Problem paßt oder die man lieber mag.

Lisp-Aufbau

Ein lisp-Ausdruck ist entweder eine Konstante, eine Variable oder ein Funktionsausdruck. Beim Funktionsaufruf verwendet lisp eine Prefix-Notation(27). Die Funktion und seine Parameter werden von runden Klammern eingeschlossen. Um zum Beispiel zwei Werte a und b zu addieren, schreibt man

(+ a b)

Alle Ausdrücke liefern einen Wert, z.B. im obigen Beispiel die Summe von a und b. Ausdrücke können verschachtelt werden, d.h. man kann Ausdrücke als Unterausdruck in eine andere einsetzen.

Funktionen werden nach dem call-by-value-Schema(28) aufgerufen, das bedeutet, daß zuerst die Parameter berechnet werden, bevor die Funktion aufgerufen wird.

Wenn nicht anders angegeben, sind alle Funktionen strikt, d.h. alle Parameter einer Funktion müssen zuerst ermittelt werden, bevor sie an die Funktion übergeben und diese ausgeführt wird. Einige Funktionen sind jedoch nicht strikt, z.B. IF, AND und OR. Diese Funktionen brauchen nicht alle Parameter ermitteln.

Programmarten

MUIbase kennt drei Programmarten. Die erste ist das Projektprogramm. Im Programm dieser Art können Funktionen und globale Variablen definiert werden. Die Funktionen können als Auslösefunktionen für Felder verwendet werden. Ein Projektprogramm wird im Programmeditor (siehe Programmeditor) festgelegt.

Die zweite Art ist das Abfrageprogramm. FÜr dieses können nur Ausdrücke eingegeben werden. Ein solcher Ausdruck darf globale Variablen enthalten und Funktionen aufrufen, die im Projektprogramm definiert wurden. Man kann jedoch in einem Abfrageprogramm keine neuen globalen Variablen und Funktionen festlegen. Abfrageprogramme werden im Abfrageeditor (siehe Abfrageeditor) eingegeben.

Die dritte Programmart sind Filterausdrücke. Hier lassen sich nur Ausdrücke eingeben, die vordefinierte MUIbase-Funktionen aufrufen. Es sind nicht alle vordefinierten Funktionen verfügbar und zwar nur solche die keine Seiteneffekte aufweisen, z.B. kann man keine Funktion verwenden, die Daten in eine Datei schreibt. Filterausdrücke werden im Filterfenster (siehe Filter ändern(29)) verändert.

Namenskonventionen

In einem MUIbase-Programm können Symbole, wie Funktionen, lokale und globale Variablen, definiert werden. Die Namen dieser Symbole müssen folgenden Punkten genügen:

Datensatzinhalte ansprechen

Um auf Tabellen und Felder in einem MUIbase-Programm zugreifen zu können, muß ein Pfad zu diesen angegeben werden. Ein Pfad ist eine durch Punkte getrennte Liste von Komponenten, wobei jede Komponente der Name einer Tabelle oder eines Feldes ist.

Pfade können entweder relativ oder absolut sein. Absolute Pfade beginnen mit dem Tabellennamen als erste Komponente, gefolgt von einer Liste von Feldern, die zum gewünschten Feld hinführen, auf das man zugreifen möchte. Zum Beispiel greift der absolute Pfad `Person.Name' auf das Feld `Name' im aktuellen Datensatz der Tabelle `Person' zu oder der absolute Pfad `Person.Vater.Name' auf das Feld `Name' in dem Datensatz, der durch das Feld `Vater' referenziert wird (der ein Beziehungsfeld zur Tabelle `Person' ist).

Relative Pfade haben schon eine aktuelle Tabelle, auf die sie sich beziehen. Zum Beispiel ist in einem Filterausdruck die aktuelle Tabelle diejenige, für die der Filterausdruck geschrieben wird. Der relative Pfad(31) für ein Feld in der aktuellen Tabelle ist dann nur der Feldname selbst. Auf Felder, auf die nicht direkt von der aktuellen Tabelle aus zugegriffen werden kann, sondern indirekt über eine Beziehung, dann gelten die gleichen Regeln wie für absolute Pfade.

Es ist nicht immer eindeutig, ob ein angegebener Pfad ein relativer oder ein absoluter ist, z.B. bei einem Filterausdruck für eine Tabelle `Foo'(32), das ein Feld `Bar' besitzt, wenn es auch eine Tabelle `Bar' gibt. Wird nun `Bar' eingegeben, dann ist unklar, was gemeint ist: die Tabelle oder das Feld? Daher werden alle Pfade zuerst als relative Pfade betrachtet. Wird kein Feld für den angegebenen Pfad gefunden, dann wird der Pfad global betrachtet. In unserem Beispiel würde das Feld bevorzugt.

Was aber, wenn im Beispiel oben auf die Tabelle zugegriffen werden soll? In dem Fall muß der Pfad absolut angegeben werden. Um einen Pfad als global zu kennzeichnen, müssen vor dem Pfad zwei Doppelpunkte angefügt werden. In unserem Beispiel müßte man `::Bar' eingeben, um auf die Tabelle zuzugreifen.

Um Pfade und ihre Anordnungen besser zu verstehen, betrachten wir hier als Beispiel, daß das Feld `Bar' in der Tabelle `Foo' eine Beziehung zur Tabelle `Bar' ist und die Tabelle `Bar' enthält ein Feld `Name'. Nun kann man auf das Feld `Name' zugreifen, indem man `Bar.Name' oder `::Bar.Name' eingibt. Beide Ausdrücke haben unterschiedliche Bedeutungen. `::Bar.Name' bedeutet, daß der aktuelle Datensatz der Tabelle `Bar' hergenommen wird und der Wert des Feldes `Name' in diesem Datensatz zurückgeliefert wird, wohingegen `Bar.Name' den aktuellen Datensatz von `Foo' hernimmt, die Beziehung des Feldes `Bar' ermittelt und diesen Datensatz zum Ermitteln des Wertes vom Feld `Name' verwendet.

Um ein komplexeres Beispiel anzubringen, stellen wir uns vor, daß die Tabelle `Bar' zwei Datensätze hat. Der eine enthält im Feld `Name' den Eintrag `Mats'(33) und der andere `Steffen'. Der erste Datensatz ist der momentan aktive. Des weiteren hat die Tabelle `Foo' einen Datensatz (den aktuellen), dessen Feld `Bar' auf den zweiten Datensatz der Tabelle `Bar' verweist. `::Bar.Name' liefert jetzt `Mats' und `Bar.Name' liefert `Steffen'.

Datentypen zum Programmieren

Die Programmiersprache von MUIbase kennt die folgenden Datentypen:

Typ         Beschreibung

Bool        alle Ausdrücke. Nicht-NIL-Ausdrücke werden als TRUE betrachtet.

Integer     lange Ganzzahl, 32 bit, Auswahlwerte werden automatisch in
            Integer umgewandelt

Real        double, 64 bit

String      Zeichenketten von unterschiedlicher Länge

Memo        wie Zeichenketten, aber zeilenorientiertes Format

Date        Datumswerte

Time        Zeitwerte

Record      Zeiger auf einen Datensatz

File        Dateideskriptor zum Lesen/Schreiben

List        Liste von Elementen, NIL ist eine leere Liste.

Alle Programmiertypen unterstützen den Wert NIL.

Konstanten

Die Programmiersprache von MUIbase kann konstante Ausdrücke handhaben, die abhängig von ihrem Typ eingegeben werden kann:

Typ         Beschreibung

Integer     Ganzzahlkonstanten im Bereich von -2147483648 bis
            2147483647 können wie üblich angegeben werden.

Real        Fließkommazahlen im Bereich von -3.59e308 bis
            3.59e308 können wie üblich angegeben werden, sowohl
            im wissenschaftlichen als auch nicht-wissenschaft-
            lichen Format. Wird der Dezimalpunkt vergelassen,
            so wird die Zahl nicht als Real betrachtet, sondern
            als Integer.

String      Zeichenkettenkonstanten sind jedes Zeichen in einer
            Kette, umschlossen mit doppelten Anführungsstrichen,
            z.B."Beispielzeichenkette". Innerhalb der doppelten
            Anführungszeichen kann jedes Zeichen angegeben werden,
            mit Ausnahme von Steuerzeichen und neuen Zeilen. Es
            gibt jedoch besondere Escapezeichen zum Eingeben
            solcher Zeichen:

                \n              neue Zeile (nl)
                \t              horizontaler Tabulator (ht)
                \v              vertikaler Tabulator (vt)
                \b              Rückschritt (bs)
                \r              Wagenrücklauf (cr)
                \f              Seitenumbruch (ff)
                \\              der Backslash selbst
                \"              doppeltes Anführungszeichen
                \e              Escapezeichen 033
                \nnn            Zeichen mit dem Oktalcode nnn
                \xnn            Zeichen mit dem Hexcode nn

Memo        Es gibt keine konstanten Werte, sondern stattdessen
            nur eine konstante Zeichenkette.

Date        Konstante Datumswerte können in einem der Formate
            `TT.MM.JJJJ', `MM/TT/JJJJ' oder `JJJJ-MM-TT'
            angegeben werden, wobei `TT', `MM' und `JJJJ'
            die zwei- und vierstelligen Werte für Tag, Monat
            bzw. Jahr darstellen.

Time        Konstante Zeitwerte werden im Format `HH:MM:SS' angegeben,
            wobei `HH' ein zweistelliger Wert im Bereich 0 bis 23
            ist, der Stunden darstellt, `MM' ein zweistelliger
            Wert im Bereich 0 bis 59 ist, der Minuten repräsentiert
            und `SS' ein zweistelliger Wert im Bereich 0 bis 59 ist,
            der Sekunden anzeigt.

Für andere vordefinierte Konstanten, siehe Vordefinierte Konstanten.

Befehlsaufbau

Im Rest dieses Kapitels findet man die Beschreibung aller Befehle und Funktionen, die für die Programmierung von MUIbase zur Verfügung stehen. Der folgende Aufbau wird verwendet, um die Befehle zu beschreiben:

Anm.d.Übersetzers: Bei der Beschreibung der Befehle wird die englische Namensgebung der Parameter etc. beibehalten. Dies vermeidet Fehler bei der Übersetzung und bleibt dennoch verständlich.

Befehle definieren

Dieser Abschnitt listet Befehle zum Definieren von Funktionen und globalen Variablen auf. Die Befehle sind nur für Projektprogramme verfügbar.

DEFUN

DEFUN definiert eine Funktion mit einem festgelegten Namen, einer Liste von Parametern, die an die Funktion weitergereicht und eine Liste von Ausdrücken, die abgearbeitet werden.

(DEFUN name (varlist) expr ...)

Der Name der Funktion muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).

Der Parameter varlist legt die Parameter der Funktion fest:

varlist: var1 ...

wobei var1 ... die Namen der Parameter sind. Die Namen müssen den gleichen Regeln wie die des Funktionsnamens genügen.

Es ist auch möglich, Typdeklarierer an die Parameter zu hängen (siehe Typdeklarierer).

Die Funktion führt die Ausdrücke expr, ... der Reihe nach aus und liefert den Wert des letzten Ausdrucks. Die Funktion kann auch weitere Funktionen einschließlich sich selbst aufrufen. Eine selbstdefinierte Funktion wird wie eine vordefinierte Funktion aufgerufen.

Um zum Beispiel die Anzahl der Elemente einer Liste zu zählen, kann folgende Funktion definiert werden:

(DEFUN len (l)
    (IF (= l NIL)
        0
        (+ 1 (len (REST l)))
    )
)

Mit DEFUN definierte Funktionen werden in Popuplisten von Tabellen- und Feldfenstern aufgelistet (siehe Tabellen erstellen und Felder erstellen).

Dieser Befehl ist nur für Projektprogramme verfügbar.

Siehe auch DEFUN*, DEFVAR.

DEFUN*

DEFUN* ist die Stern-Variante von DEFUN und hat den selben Effekt wie DEFUN (siehe DEFUN). Der einzige Unterschied ist, daß Funktionen, die mit DEFUN* definiert wurden, beim Erzeugen oder Ändern von Tabellen und Feldern nicht in den Popuplisten aufgelistet werden. Es ist jedoch möglich, den Funktionsnamen in den entsprechenden Zeichenkettenfeldern einzugeben.

Dieser Befehl ist nur für Projektprogramme verfügbar.

Siehe auch DEFUN, DEFVAR.

DEFVAR

(DEFVAR var [expr])

Definiert eine globale Variable mit dem Vorgabewert aus expr oder NIL, wenn expr fehlt. Der Name der Variablen muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).

Man kann Typdeklarierer an den Variablennamen anhängen (siehe Typdeklarierer).

DEFVAR ist nur verfügbar für Projektprogramme. Alle DEFVAR-Befehle sollten am Anfang vor allen Funktionsdefinitionen plaziert werden.

Beispiel: `(DEFVAR x 42)' definiert eine globale Variable `x' mit dem Wert 42.

Es gibt einige vordefinierte Variablen in MUIbase (siehe Vordefinierte Variablen).

Siehe auch DEFUN, DEFUN*, LET.

Programmsteuerungsfunktionen

Dieser Abschnitt listet Funktionen zur Programmflußkontrolle auf, z.B. Funktionen zum Definieren von lokalen Variablen, Schleifenfunktionen, bedingte Programmausführung, Schleifenkontrollfunktionen und mehr.

PROGN

Um mehrere Ausdrücke der Reihe nach auszuführen, wird der PROGN-Aufruf(34) verwendet.

([expr ...])

führt expr ... der Reihe nach aus. Liefert das Ergebnis des letzten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde). In Lisp ist dieser Aufruf als (PROGN [expr ...]) bekannt.

Beispiel: `(1 2 3 4)' liefert 4.

Siehe auch PROG1.

PROG1

Neben PROGN gibt es mit PROG1 eine andere Möglichkeit, mehrere Ausdrücke zu errechnen.

(PROG1 [expr ...])

führt expr ... aus und liefert den Wert des ersten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde).

Beispiel: `(PROG1 1 2 3 4)' liefert 1.

Siehe auch PROGN.

LET

LET definiert einen neuen Block von lokalen Variablen. Dies ist nützlich, um z.B. lokale Variablen einer Funktion zu definieren. Der Aufbau ist:

(LET (varlist) expr ...)

wobei varlist eine Liste von lokalen Variablen ist.

varlist: varspec ...
varspec: (var expr) | var

Hier ist var der Name der Variable, der mit einem Kleinbuchstaben beginnt, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).

Im Falle von (var expr) wird die neue Variable mit dem gegebenen Ausdruck initalisiert(35). Im anderen Fall ist die neue Variable auf NIL gesetzt.

Es ist auch möglich, Typdeklarierer an die Variablen zu hängen (siehe Typdeklarierer).

Nach dem Initialisieren aller Variablen wird die Liste der Ausdrücke expr ... ausgewertet und der Wert der letzten zurückgegeben.

Der folgende LET-Ausdruck

(LET ((x 0) y (z (+ x 1)))
    (+ x z)
)

liefert zum Beispiel 1.

Siehe auch DOTIMES, DOLIST, DO, DEFVAR.

SETQ

Die Funktion SETQ setzt Werte in Variablen, Feldern und Tabellen.

(SETQ lvalue1 expr ...)

Setzt lvalue1 auf den Wert von expr. Die Punkte zeigen weitere Zuweisungen für lvalues an. Ein lvalue ist eine Variable, ein Feld einer Tabelle oder eine Tabelle. Im Falle einer Variable muß diese voher definiert worden sein (z.B. mit dem LET-Ausdruck).

Setzen des Wertes einer Tabelle bedeutet das Setzen seines Programm- oder Oberflächenzeigers: `(SETQ Table expr)' setzt den Programm-Datensatzzeiger von Table auf den Wert von expr und `(SETQ Table* expr)' setzt dessen Oberflächen-Datensatzzeiger und aktualisiert die Anzeige. Mehr Informationen über Programm- und Oberflächen-Datensatzzeigern, siehe Tabellen.

SETQ liefert den Wert des letzten Ausdrucks.

Beispiel: `(SETQ a 1 b 2)' weist 1 der Variable `a' zu, 2 der Variable `b' und liefert 2.

Siehe auch SETQ*, LET, DEFVAR, Tabellen, Aufbau von Ausdrücken.

SETQ*

SETQ* ist die Stern-Variante von SETQ (siehe SETQ) und hat ähnliche Auswirkungen. Der Unterschied ist, daß SETQ* beim Zuweisen eines Wertes zu einer Variable die Auslösefunktion dieses Feldes aufruft (siehe Auslösefunktion Feld(36)) , statt den Wert direkt zuzuweisen. Ist zum Feld keine Auslösefunktion zugewiesen, dann verhält sich SETQ* genauso wie SETQ und weist einfach den Wert der Variable zu.

Beispiel: `(SETQ* Table.Attr 0)' ruft die Auslösefunktion von `Table.Attr' mit dem Parameter 0 auf.

Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben, z.B. wenn eine Auslösefunktion für ein Feld definiert wurde und diese Funktion SETQ* aufruft, das sich selbst einen Wert setzt.

Siehe auch SETQ*, LET, DEFVAR.

FUNCALL

FUNCALL wird verwendet, um eine Funktion aufzurufen.

(FUNCALL fun-expr [expr ...])

Ruft die Funktion fun-expr mit den gegebenen Parametern auf. Der Ausdruck fun-expr kann jeder Ausdruck sein, dessen Wert eine vor- oder benutzerdefinierte Funktion ist, z.B. eine Variable, die die Funktion enthält, die aufgerufen werden soll. Stimmt die Anzahl der Parameter nicht, dann wird eine Fehlermeldung erzeugt.

FUNCALL liefert den Rückgabewert des Funktionsaufrufes oder NIL, wenn fun-expr NIL ist.

Mehr Informationen über funktionelle Ausdrücke, siehe Funktionale Parameter.

IF

IF ist ein Bedingungsoperator.

(IF expr1 expr2 [expr3])

Der Ausdruck expr1 wird getestet. Wenn er nicht NIL liefert, dann wird der Wert von expr2 geliefert, anderenfalls der von expr3 (oder NIL, wenn nicht vorhanden).

Diese Funktion ist nicht strikt, das bedeutet, daß entweder der eine oder der andere Ausdruck ausgewertet wird.

Siehe auch CASE, COND.

CASE

CASE ähnelt der switch-Anweisung in der Sprache C.

(CASE expr [case ...])

Hier ist expr der Auswahlausdruck und case ... sind Paare bestehend aus:

case: (value [expr ...])

wobei value ein einzelner Ausdruck oder eine Liste von Ausdrücken(37) ist und expr ... die Ausdrücke sind, die ausgeführt werden, wenn der Fallausdruck paßt.

Der Ausdruck CASE wertet erst expr aus. Dann wird jedes Fallpaar geprüft, ob es (oder einer der Ausdrücke in der Liste) zum ausgewerten Ausdruck paßt. Wird ein passender Fallausdruck gefunden, dann werden die dazugehörigen Ausdrücke ausgeführt und der Wert des letzten Ausdrucks zurückgeliefert. Paßt kein Fall, dann wird NIL zurückgeliefert.

Beispiel: `(CASE 1 ((2 3 4) 1) (1 2))' liefert 2.

Siehe auch IF, COND.

COND

COND ist wie IF ein Bedingungsoperator.

(COND [(test-expr [expr ...]) ...])

COND prüft der Reihe nach den ersten Ausdruck jeder Liste. Für den ersten, der nicht NIL liefert, wird der dazugehörige Ausdruck expr ... ausgeführt und der Wert des letzten Ausdrucks zurückgeliefert.

Liefern alle geprüften Ausdrücke NIL, dann wird NIL zurückgegeben.

Beispiel

(COND ((> 1 2) "1 > 2")
      ((= 1 2) "1 = 2")
      ((< 1 2) "1 < 2")
)

liefert "1 < 2".

Siehe auch IF, CASE.

DOTIMES

Für einfache Schleifen kann der Befehl DOTIMES verwendet werden.

(DOTIMES (name int-expr [result-expr ...]) [loop-expr ...])

Hier ist name der name einer neuen Variable, die innerhalb der Schleife verwendet wird(38). Der Name muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).

Die Anzahl der Schleifendurchläufe wird über int-expr angegeben. In result-expr ... können Ausdrücke angegeben werden, die nach dem Beenden der Schleife ausgeführt werden sollen. loop-expr enthält den Körper der Schleife, darin sind die Ausdrücke, die bei jedem Schleifendurchlauf ausgewertet werden.

Bevor die Schleife ausgeführt wird, errechnet DOTIMES den Wert von int-expr, um die Anzahl festzustellen, wie oft die Schleife ausgeführt werden soll. Hier wird int-expr nur einmal zu Beginn der Schleife ausgewertet und muß einen Ganzzahlwert liefern. Danach setzt DOTIMES die Schleifenvariable schrittweise in jedem Durchlauf auf 0 bis int-expr-1. Zuerst wird die Variable auf Null gesetzt und geprüft, ob diese schon größer oder gleich dem Wert von expr ist. Ist int-expr ist negativ oder NIL, oder ist die Variable größer oder gleich dem Wert von expr, dann wird die Schleife abgebrochen und die Rückgabewerte ermittelt. Anderenfalls werden die Ausdrücke in der Schleife abgearbeitet und die Variable um eins erhöht. Danach kehrt die Schleife wieder zum Abbruchtest zurück und führt -wenn möglich- weitere Schleifendurchläufe aus.

Der Ausdruck DOTIMES liefert den Wert des letzten Rückgabewert-Ausdrucks oder NIL, wenn kein solcher angegeben wurde.

Beispiel

(DOTIMES (i 50 i) (PRINT i))

Gibt die Nummern von 0 bis 49 aus und liefert den Wert 50.

Siehe auch DOLIST, DO, FOR ALL, LET.

DOLIST

Für Schleifen über Listen kann der Ausdruck DOLIST verwendet werden.

(DOLIST (name list-expr [result-expr ...]) [loop-expr ...])

Hier ist name der Name einer neuen Variable, der in der Schleife verwendet wird. Der Name muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).

In list-expr wird die Liste festgelegt, über diese die Schleife ausgeführt werden soll, result-expr ... sind Ausdrücke, die nach dem Beenden der Schleife ausgeführt werden und loop-expr ... bilden den Körper der Schleife.

Bevor die Schleife ausgeführt wird, berechnet DOLIST den Wert von list-expr. Dieser Ausdruck wird nur einmal beim Start der Schleife ausgewertet und muß einen Listenwert liefern. Dann setzt DOTIMES bei jedem Schleifendurchlauf die Schleifenvariable der Reihe nach auf jedes Element der Liste. Zuerst wird die Schleifenvariable mit dem ersten Element der Liste initialisiert. Ist die Liste schon leer (NIL), dann wird die Schleife beendet und die Rückgabewerte berechnet. Anderenfalls werden die Schleifenausdrücke ausgeführt und die Variable auf das nächste Element in der Liste gesetzt. Danach kehrt die Schleife wieder zum Abbruchtest zurück und führt -wenn möglich- weitere Schleifendurchläufe aus.

Der Ausdruck DOLIST liefert den Wert des letzten Rückgabewert-Ausdrucks oder NIL, wenn kein solcher angegeben wurde.

Beispiel

(DOLIST (i (SELECT * FROM Accounts)) (PRINT i))

Gibt alle Datensätze der Tabelle `Accounts' aus und liefert NIL.

Siehe auch DOTIMES, DO, FOR ALL, LET.

DO

Mit dem Ausdruck DO können beliebige Schleifen programmiert werden.

(DO ([binding ...]) (term-expr [result-expr ...]) [loop-expr ...])

wobei binding ... die Variablenzuweisungen sind, die jeweils wie folgt aussehen können:

Des weiteren ist term-expr der Abbruchbedingungsausdruck, result-expr ... sind die Rückgabewertausdrücke (voreingestellt ist NIL) und loop-expr ... bilden den Körper der Schleife.

Die DO-Schleife initialisiert zuerst alle lokalen Variablen mit den Startwerten und testet dann die Abbruchbedingung. Liefert sie TRUE, dann wird die Schleife unterbrochen und die Rückgabewertausdrücke ausgeführt. Der Wert des letzten Rückgabewerts wird zurückgeliefert. Anderenfalls werden die Schleifenausdrücke (loopexpr ...) ausgeführt und jede Variable wird mit dem Wert der Schrittweite aktualisiert. Danach kehrt die Ausführung zum Test der Abbruchbedingung zurück und so weiter.

Beispiel

(DO ((i 0 (+ i 1))) ((>= i 5) i) (PRINT i))

Gibt die Werte 0, 1, 2, 4 und 4 aus und liefert den Wert 5. Natürlich ist das ein ziemlich komplizierter Weg, eine einfache FOR-Schleife zu bauen. Dafür gibt es mit dem Ausdruck DOTIMES eine einfachere Version.

Siehe auch DOTIMES, DOLIST, FOR ALL, LET.

FOR ALL

Der Ausdruck FOR ALL wird verwendet, um eine Liste von Datensätzen abzuarbeiten.

(FOR ALL table-list [WHERE where-expr] [ORDER BY order-list] DO expr ...)

Hier ist table-list eine durch Kommas getrennte Liste von Tabellen, where-expr ein Ausdruck zum Testen einer jeden Menge von Datensätzen, order-list eine durch Kommas getrennte Liste von Ausdrücken, nach denen sortiert werden soll und expr ... sind die Ausdrücke, die für jeden Datensatz ausgeführt werden sollen.

FOR ALL erzeugt zuerst eine Liste aller Datensätze, für die der Schleifenkörper ausgeführt werden soll. Dies wird wie bei einem SELECT-Ausdruck durchgeführt. Siehe SELECT für mehr Informationen, wie diese Liste erzeugt wird. Für jedes Element dieser Liste wird der Schleifenkörper expr ... ausgeführt.

Zum Beispiel kann ein Aufsummieren eines Tabellenfeldes folgendermaßen durchgeführt werden:

(SETQ sum 0)
(FOR ALL Accounts DO
    (SETQ sum (+ sum Accounts.Amount))
)

Der Ausdruck FOR ALL liefert NIL.

Siehe auch SELECT, DOTIMES, DOLIST, DO.

NEXT

NEXT kann verwendet werden, um DOTIMES-, DOLIST-, DO- und FOR ALL-Schleifen zu steuern.

Ein Aufruf von NEXT im Schleifenkörper springt zum nächsten Schleifendurchlauf. Dies kann benutzt werden, wenn uninteressante Schleifendurchläufe übersprungen werden sollen, wie z.B. in folgendem Beispiel:

(FOR ALL Table DO
    (IF nicht-interessant-im-aktuellen-Datensatz (NEXT))
    ...
)

Siehe auch EXIT, DOTIMES, DOLIST, DO, FOR ALL.

EXIT

EXIT kann verwendet werden, um eine Schleife zu beenden.

(EXIT [expr ...])

EXIT innerhalb eines Schleifenkörpers beendet die Schleife und führen die optionalen Ausdrücke expr ... aus und liefern den Wert des letzten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde) als Rückgabewert der Schleife. Mögliche Rückgabewerte der Schleife im Beispiel

(DOTIMES (x 10 ret-expr ...) ...)

werden nicht ausgeführt.

Man kann die Funktion EXIT z.B. verwenden, um eine FOR ALL-Schleife zu beenden, wenn ein Datensatz gefunden wurde, der uns interessiert:

(FOR ALL Table DO
    (IF interessanter-aktueller-Datensatz (EXIT Table))
    ...
)

Siehe auch NEXT, RETURN, HALT, DOTIMES, DOLIST, DO, FOR ALL.

RETURN

Innerhalb einer Funktionsdefinition kann mit dem Befehl RETURN zur aufrufenden Funktion zurückgesprungen werden.

(RETURN [expr ...])

beendet die Funktion, führt die optionalen Ausdrücke expr ... aus und liefert den Wert des letzten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde).

Beispiel

(DEFUN find-record (name)
    (FOR ALL Table DO
        (IF (= Name name) (RETURN Table))
    )
)

Das Beispiel sucht nach einem Datensatz, dessen Feld Name zum gegebenen Namen paßt. Die Funktion liefert den ersten Datensatz, der gefunden wurde oder NIL, wenn kein Datensatz gefunden wurde.

Siehe auch HALT, EXIT.

HALT

HALT kann verwendet werden, um die Programmausführung abzubrechen.

(HALT)

stoppt stillschweigend die Programmausführung.

Siehe auch ERROR, EXIT, RETURN.

ERROR

Zum Abbrechen der Programmausführung mit einer Fehlermeldung kann die Funktion ERROR verwendet werden.

(ERROR fmt [arg ...])

stoppt die Programmausführung und öffnet ein Fenster mit einer Fehlermeldung. Die Fehlermeldung wird wie in der Funktion SPRINTF (siehe SPRINTF) aus fmt und den optionalen Parametern arg ... erzeugt.

Siehe auch HALT, SPRINTF.

Typaussagen

Für jeden Datentyp ist eine Aussage definiert, die TRUE liefert, wenn der übergebene Ausdruck vom gegebenen Typ ist, anderenfalls NIL. Die Aussagen sind:

Aussage            Beschreibung

(STRP expr)        TRUE wenn expr vom Typ Zeichenkette ist, sonst NIL.

(MEMOP expr)       TRUE wenn expr vom Typ mehrzeiliger Text ist, sonst NIL.

(INTP expr)        TRUE wenn expr vom Typ Ganzzahl ist, sonst NIL.

(REALP expr)       TRUE wenn expr vom Typ Fließkommazahl ist, sonst NIL.

(DATEP expr)       TRUE wenn expr vom Typ Datum ist, sonst NIL.

(TIMEP expr)       TRUE wenn expr vom Typ Zeit ist, sonst NIL.

(NULLP expr)       TRUE wenn expr vom Typ NIL (leere Liste) ist, sonst NIL.

(CONSP expr)       TRUE wenn expr keine leere Liste ist, sonst NIL.

(LISTP expr)       TRUE wenn expr eine Liste (die NIL sein kann) ist, sonst NIL.

(RECP table expr)   TRUE wenn expr ein Datensatzzeiger der gegebenen Tabelle ist.
                   Wenn expr NIL ist, dann wird TRUE geliefert (Anfangsdatensatz).
                   Wenn table NIL ist, dann wird geprüft, ob expr
                   ein Datensatzzeiger irgendeiner Tabelle ist.

Typumwandlungsfunktionen

Dieser Abschnitt listet Funktionen auf, die zum Umwandeln von einem Datentyp in einen anderen verwendet werden.

STR

STR kann verwendet werden, um einen Ausdruck in eine Zeichenkettendarstellung umzuwandeln.

(STR expr)

wandelt expr in eine Zeichenkettendarstellung um. Der Typ von expr bestimmt die Umwandlung:

Typ                 Ergebniszeichenkette

Zeichenkette        Die Zeichenkette selbst.

mehrzeiliger Text   Der gesamte mehrzeilige Text in einer Zeichenkette.

Ganzzahl            Zeichenkettendarstellung einer Ganzzahl.

Fließkommazahl      Zeichenkettendarstellung einer Fließkommazahl.
                    Wenn expr ein Feld ist, dann wird die Anzahl
                    der Nachkommastellen dieses Feldes, anderenfalls
                    zwei Ziffern verwendet.

Auswahl             Auswahltext des Auswahlfeldes.

Datum               Zeichenkettendarstellung des Datumswertes.

Zeit                Zeichenkettendarstellung des Zeitwertes.

Bool                Die Zeichenkette "TRUE"

NIL                 Benutzerdefinierte Zeichenkette für NIL, wenn
                    expr ein Feld ist, anderenfalls die
                    Zeichenkette "NIL"

Datensatz           Zeichenkettendarstellung der Datensatznummer.

Andere              Zeichenkettendarstellung des internen Adreßzeigers(39)

Siehe auch MEMO, SPRINTF.

MEMO

MEMO kann verwendet werden, um einen Ausdruck in einen mehrzeiligen Text umzuwandeln.

(MEMO expr)

wandelt expr in eine mehrzeilige Textdarstellung. Es faßt den Ausdruck wie bei der Funktion STR (siehe STR) auf, liefert aber einen mehrzeiligen Text statt einer Zeichenkette.

Siehe auch STR.

INT

INT wird verwendet, um einen Ausdruck in eine Ganzzahl umzuwandeln.

(INT expr)

wandelt expr in eine Ganzzahl. Mögliche Umwandlungen sind:

Typ             Ergebniswert

Zeichenkette        Wenn die gesamte Zeichenkette eine Ganzzahl darstellt, dann
                    wird die Zeichenkette in eine Ganzzahl umgewandelt. Führende
                    und folgende Leerzeichen werden ignoriert.
                    Stellt es keine Ganzzahl dar, wird NIL geliefert.

mehrzeiliger Text   Analog Zeichenkette.

Ganzzahl            Der Wert selbst.

Fließkommazahl      Wenn der Wert im Ganzzahlbereich liegt, wird der
                    Fließkommazahlenwert gerundet und geliefert, anderenfalls NIL.

Auswahltext         Die interne Nummer (beginnend bei 0) des aktuellen Auswahltextes.

Datum               Anzahl Tage seit dem 01.01.0000.

Zeit                Anzahl Sekunden seit 00:00:00.

Datensatz           Datensatznummer.

NIL                 NIL

Andere              Eine Fehlermeldung wird erzeugt und die Programmausführung
                    abgebrochen.

Siehe auch REAL, ASC.

REAL

REAL wird verwendet, um einen Ausdruck in einen Wert vom Typ Fließkommazahl umzuwandeln.

(REAL expr)

wandelt expr in eine Fließkommazahl. Es faßt den Ausdruck wie bei der Funktion INT (siehe INT) auf, liefert aber einen Wert vom Typ Fließkommazahl anstatt einer Ganzzahl.

Siehe auch INT.

DATE

DATE wird verwendet, um einen Ausdruck in ein Datum umzuwandeln (40).

(DATE expr)

wandelt den gegebenen Ausdruck in ein Datum(41). Mögliche Umwandlungen sind:

Typ             Rückgabewert

Zeichenkette        Wenn die gesamte Zeichenkette einen Datumswert darstellt,
                    dann wird die Zeichenkette in ein Datum umgewandelt.
                    Führende und folgende Leerzeichen werden ignoriert.
                    Stellt es kein Datum dar, wird NIL geliefert.

mehrzeiliger Text   Analog Zeichenkette.

Ganzzahl            Ein Datumswert wird erzeugt, wenn die gegebene Ganzzahl die
                    Anzahl der Tage seit dem 01.01.0000 darstellt. Ist die
                    Ganzzahl zu groß (Datum würde größer als der 31.12.9999) oder
                    negativ, dann wird NIL zurückgegeben.

Fließkommazahl      Analog Ganzzahl.

Datum               Der Wert selbst.

NIL                 NIL

Andere              Eine Fehlermeldung wird erzeugt und die Programmausführung
                    abgebrochen.

TIME

TIME wird verwendet, um einen Ausdruck in einen Zeitwert umzuwandeln.

(TIME expr)

wandelt den gegebenen Ausdruck in einen Zeitwert. Mögliche Umwandlungen sind:

Type            Return value

Zeichenkette        Wenn die gesamte Zeichenkette einen Zeitwert darstellt, dann
                    wird die Zeichenkette in eine Zeit umgewandelt. Führende
                    und folgende Leerzeichen werden ignoriert.
                    Stellt es keine Zeit dar, wird NIL geliefert.

mehrzeiliger Text   Analog Zeichenkette.

Ganzzahl            Ein Zeitwert wird erzeugt, wenn die gegebene Ganzzahl die
                    Anzahl der Sekunden seit 00:00:00 darstellt. Die Ganzzahl
                    modulo der Anzahl der Sekunden pro Tag wird hergenommen,
                    d.h. z.B. `(TIME 86400)' liefert 00:00:00.

Fließkommazahl      Analog Ganzzahl.

Zeit                Der Wert selbst.

NIL                 NIL

Andere              Eine Fehlermeldung wird erzeugt und die Programmausführung
                    abgebrochen.

Boolesche Funktionen

Dieser Abschnitt listet die booleschen Operatoren auf.

AND

AND prüft, ob alle seine Parameter TRUE sind.

(AND [expr ...])

prüft der Reihe nach expr ..., bis ein Ausdruck zu NIL wird. Sind alle Ausdrücke zu Nicht-NIL aufgelöst worden, dann wird der Wert des letzten Ausdrucks zurückgeliefert, anderenfalls NIL.

Diese Funktion ist nicht strikt, dies bedeutet, daß nicht alle Parameter von AND ausgewertet werden müssen, z.B. wird in `(AND NIL (+ 1 2))' der Ausdruck `(+ 1 2)' nicht ausgewertet, da ein NIL-Wert schon ermittelt wurde. In `(AND (+ 1 2) NIL)' jedoch wird der Ausdruck `(+ 1 2)' ausgewertet.

Siehe auch OR, NOT.

OR

OR prüft, ob alle seiner Parameter NIL sind.

(OR [expr ...])

prüft der Reihe nach expr ..., bis ein Ausdruck zu Nicht-NIL wird. Liefert den Wert des ersten Ausdrucks, der zu Nicht-NIL wurde, oder NIL, wenn alle Ausdrücke zu NIL wurden.

Diese Funktion ist nicht strikt, dies bedeutet, daß nicht alle Parameter von AND ausgewertet werden müssen, z.B. wird in `(OR TRUE (+ 1 2))' der Ausdruck `(+ 1 2)' nicht ausgewertet, da ein Nicht-NIL-Wert (hier TRUE) schon ermittelt wurde. In `(OR (+ 1 2) TRUE)' jedoch wird der Ausdruck `(+ 1 2)' ausgewertet.

Siehe auch AND, NOT.

NOT

NOT wird verwendet, um den Wert eines booleschen Ausdrucks zu invertieren.

(NOT expr)

liefert TRUE, wenn expr NIL ist, sonst NIL.

Siehe auch AND, OR.

Vergleichsfunktionen

In diesem Abschnitt findet man Funktionen zum Vergleich von Werten vor (42).

Relationsoperatoren

Zum Vergleichen zweier Werte in einem MUIbase-Programm verwendet man

(op expr1 expr2)

wobei op einer aus {=, <>, <, >, >=, <=, =*, <>*, <*, >*, >=*, <=*} ist. Der Stern wird für besondere Vergleiche (Zeichenkettenvergleiche ohne Groß-/Kleinschreibung, Datensatzvergleich mit der benutzerdefinierten Reihenfolge) verwendet.

Die folgende Tabelle zeigt alle Regeln beim Vergleich von zwei Werten in einem MUIbase-Programm.

Typ                Vergleichsreihenfolge

Ganzzahl            NIL < MIN_INT < ... < -1 < 0 < 1 < ... < MAX_INT

Fließkommazahl      NIL < -HUGE_VAL < ... < -1.0 < 0.0 < 1.0 < ... < HUGE_VAL

Zeichenkette        NIL <  "" <  "Z" <  "a"  <  "aa" <  "b" < ... (mit groß/klein)
                    NIL <* "" <* "a" <* "AA" <* "b" < ...        (groß/klein egal)

mehrzeiliger Text   wie bei Zeichenketten

Datum               NIL < 1.1.0000 < ... < 31.12.9999

Zeit                NIL < 00:00:00 < ... < 23:59:59

Bool                NIL < TRUE

Datensatz           NIL < jeder_Datensatz    (Datensätze selbst können nicht
                                              mit < verglichen werden)
                    NIL <* rec1 <* rec2    (Reihenfolge festgelegt durch Benutzer)

Anm.d.Übersetzers: HUGE_VAL steht für den größtmöglichen Fließkommazahlenwert, den ein Prozessor handhaben kann. MIN_INT ist die kleinste Ganzzahl und MAX_INT ist die größte Ganzzahl (nein, man kehrt nicht nur das Vorzeichen um, um die 'andere' größte Zahl zu erhalten).

Siehe auch CMP, CMP*, LIKE.

CMP

CMP liefert eine Ganzzahl, die eine Sortierung ihrer Argumente repräsentiert.

(CMP expr1 expr2)

liefert einen Wert kleiner als 0, wenn expr1 kleiner ist als expr2; 0, wenn expr1 gleich expr2 ist und einen Wert größer 0, wenn expr1 größer ist als expr2. Zum Erkennen der Sortierung wird die einfache (ohne Stern) Sortierrelation wie bei den Relationaloperatoren (siehe Relationsoperatoren) verwendet.

Es darf nicht angenommen werden, daß der Rückgabewert immer -1, 0 oder 1 ist!

Beispiel: `(CMP "Bike" "bIKE")' liefert -32.

Siehe auch CMP*, Relationsoperatoren.

CMP*

CMP* ist die Stern-Version von CMP. Der Unterschied ist, daß CMP* eine erweiterte Sortierung wie bei den Relationsoperatoren (siehe Relationsoperatoren) verwendet, bei denen Zeichenketten zeichengrößenunabhängig und Datensätze gemäß ihrer benutzerdefinierten Datensatzreihenfolge verglichen werden.

Beispiel: `(CMP* "Bike" "bIKE")' liefert 0.

Siehe auch CMP, Relationsoperatoren.

Mathematik-Funktionen

Einige mathematische Funktionen werden hier aufgelistet.

Werte addieren

Zum Zusammenzählen von Zahlen verwendet man

(+ expr ...)

Liefert die Summe der Parameter expr .... Wenn irgendein Parameter NIL ist, dann ist das Ergebnis NIL. Wenn die Werte vom Typ Fließkomma- oder Ganzzahl sind, dann ist das Ergebnis auch eine Fließkommazahl (oder Ganzzahl).

Es lassen sich auch Zeichenketten und mehrzeilige Texte 'addieren'. In diesem Fall ist das Ergebnis die zusammengehängten Zeichenketten bzw mehrzeiligen Texte.

Ist expr vom Typ Datum und der Rest der Parameter sind Ganz-/Fließkommazahlen, dann wird die Summe der Ganz-/Fließkommazahlen als Anzahl Tage aufgefaßt und zu expr addiert. Ist das zurückgelieferte Ergebnis außerhalb des gültigen Bereichs (vor dem 1.1.0000 oder nach dem 31.12.9999), dann ist das Ergenis NIL.

Ist expr vom Typ Zeit und der Rest der Parameter sind Ganz-/Fließkommazahlen, dann wird die Summe der Ganz-/Fließkommazahlen als Anzahl Sekunden aufgefaßt und zu expr addiert. Es können jedoch in den restlichen Parametern Ausdrücke vom Typ Zeit vorhanden sein. Das zurückgelieferte Ergebnis wird modulo 24:00:00 genommen.

Beispiele

Ausdruck                        Wert

(+ 1 2 3)                        6
(+ 5 1.0)                        6.0
(+ "Hallo" " " "Welt!")          "Hallo Welt!"
(+ 28.11.1968 +365 -28 -9)       22.10.1969
(+ 07:30:00 3600)                08:30:00
(+ 03:00:00 23:59:59)            02:59:59

Siehe auch Werte subtrahieren, 1+, Werte multiplizieren (*), CONCAT, CONCAT2.

Werte subtrahieren

Zum Subtrahieren von Werten verwendet man

(- expr1 expr2 ...)

Zieht die Summe expr2 ... von expr1 ab. Hier gelten die gleichen Regeln wie beim Addieren von Werten (siehe Werte addieren), außer daß Zeichenketten und mehrzeilige Texte nicht subtrahiert werden können.

(- expr) hat eine spezielle Bedeutung: Es liefert den negativen Wert von expr (Ganz- oder Fließkommazahl), z.B. `(- (+ 1 2))' liefert -3.

Siehe auch Werte addieren, 1-.

1+

1+ erhöht den Wert einer Ganz- bzw Fließkommazahl (-ausdrucks) um Eins.

(1+ expr)

Liefert den Wert von expr (Ganz- oder Fließkommazahl) plus Eins. Wenn expr NIL ist, dann wird NIL geliefert.

Siehe auch Werte addieren, 1-.

1-

1- verringert den Wert einer Ganz- bzw Fließkommazahl (-ausdrucks) um Eins.

(1- expr)

Liefert den Wert von expr (Ganz- oder Fließkommazahl) minus Eins. Wenn expr NIL ist, dann wird NIL geliefert.

Siehe auch Werte subtrahieren, 1+.

Werte multiplizieren (*)

Zum Multiplizieren von Ganz-/Fließkommazahlen verwendet man

(* expr ...)

Liefert die Multiplikation der Ganz-/Fließkommazahlen expr .... Wenn alle Parameter Ganzzahlen sind, dann wird eine Ganzzahl geliefert, anderenfalls ist der Wert vom Typ Fließkommazahl.

Siehe auch Werte addieren, Werte dividieren.

Werte dividieren

Zum Dividieren von Ganz-/Fließkommazahlen verwendet man

(/ expr1 [expr2 ...])

Teilt expr1 durch die Multiplikation der restlichen Parameter. Liefert eine Fließkommazahl. Bei einer Division durch 0 wird NIL geliefert.

Siehe auch Werte multiplizieren (*), DIV, MOD.

DIV

DIV verwendet man zur Ganzzahldivision.

(DIV int1 int2)

Liefert die Ganzzahldivision von int1 mit int2. Zum Beispiel liefert `(DIV 5 3)' den Wert 1.

Siehe auch Werte dividieren, MOD.

MOD

MOD wird zur Modulo-Berechnung verwendet.

(MOD int1 int2)

Liefert int1 modulo int2. Zum Beispiel liefert `(MOD 5 3)' den Wert 2.

Siehe auch DIV.

MAX

MAX liefert den Parameter mit dem größten Wert.

(MAX expr ...)

Liefert den größten Wert der Argumente expr ... (alles Ganz- oder Fließkommazahlen). Ist eine der Ausdrücke NIL, dann wird NIL geliefert.

Siehe auch MIN.

MIN

MIN liefert den Parameter mit dem kleinsten Wert.

(MIN expr ...)

Liefert den kleinsten Wert der Argumente expr ... (alles Ganz- oder Fließkommazahlen). Ist eine der Ausdrücke NIL, dann wird NIL geliefert.

Siehe auch MAX.

ABS

ABS berechnet den absoluten Wert eines Ausdrucks.

(ABS expr)

Liefert den absoluten Wert(43) von expr (Ganz- oder Fließkommazahl). Ist expr NIL, dann wird NIL geliefert.

TRUNC

TRUNC schneidet die Nachkommastellen einer Zahl ab.

(TRUNC real)

Liefert die größte Ganzzahl (als Fließkommazahl), die nicht größer ist als die angegebene Fließkommazahl. Ist real NIL, dann wird NIL geliefert.

Beispiele: `(TRUNC 26.1)' liefert 26, `(TRUNC -1.2)' liefert -2.

Siehe auch ROUND.

ROUND

ROUND rundet einen Fließkommawert.

(ROUND real digits)

Liefert den angegebenen Fließkommawert aufgerundet auf digits Stellen. Ist real oder digits gleich NIL, dann wird NIL geliefert.

Beispiele: `(ROUND 70.70859 2)' liefert 70.71, `(ROUND 392.36 -1)' liefert 392.0.

Siehe auch TRUNC.

RANDOM

RANDOM kann zum Generieren von Zufallszahlen verwendet werden.

(RANDOM expr)

Liefert eine Zufallszahl. Beim ersten Aufruf wird der Zufallszahlengenerator mit dem Wert aus der aktuellen Uhrzeit initialisiert. RANDOM erzeugt eine Zufallszahl im Bereich von 0 ... expr, ausgenommen expr selbst. Der Typ von expr (Ganz- oder Fließkommazahl) ist auch der Rückgabewert-Typ. Ist expr NIL, dann wird NIL geliefert.

Beispiele:

Beispiel                Bedeutung

(RANDOM 10)             liefert einen Wert von 0 bis 9,
(RANDOM 10.0)           liefert einen Wert von 0.0 bis 9.99999...

Zeichenkettenfunktionen

Dieser Abschnitt behandelt Funktionen für Zeichenketten.

LEN

LEN berechnet die Länge der Zeichenkette.

(LEN str)

Liefert die Länge der gegebenen Zeichenkette oder NIL wenn str NIL ist.

Siehe auch WORDS, LINES, MAXLEN.

LEFTSTR

LEFTSTR extrahiert eine Teilzeichenkette aus einer Zeichenkette.

(LEFTSTR str len)

Liefert den linken Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist str oder len gleich NIL oder ist len negativ, dann wird NIL geliefert.

Beispiel: `(LEFTSTR "Hallo Welt!" 5)' liefert "Hallo".

Siehe auch RIGHTSTR, MIDSTR, WORD, LINE.

RIGHTSTR

RIGHTSTR extrahiert eine Teilzeichenkette aus einer Zeichenkette.

(RIGHTSTR str len)

Liefert den rechten Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist str oder len gleich NIL oder ist len negativ, dann wird NIL geliefert.

Beispiel: `(RIGHTSTR "Hallo Welt!" 5)' liefert "Welt!".

Siehe auch LEFTSTR, MIDSTR, WORD, LINE.

MIDSTR

MIDSTR extrahiert eine Teilzeichenkette aus einer Zeichenkette.

(MIDSTR str pos len)

Liefert einen Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist len NIL, dann ist die Anzahl der zurückgegebenen Zeichen nicht eingeschränkt(44). Die Teilzeichenkette beginnt an der Stelle pos (beginnend bei Null). Wenn str oder len NIL sind oder wenn len negativ ist, dann wird NIL zurückgeliefert. Ist pos außerhalb des gültigen Bereichs (negativ oder größer als Zeichenkettenlänge), dann wird NIL geliefert.

Beispiel: `(MIDSTR "Hallo Welt!" 3 5)' liefert "lo We".

Siehe auch LEFTSTR, RIGHTSTR, WORD, LINE, SETMIDSTR, INSMIDSTR.

SETMIDSTR

SETMIDSTR setzt eine Teilzeichenkette in einer Zeichenkette.

(SETMIDSTR str index set)

Liefert eine Kopie der Zeichenkette str, in dem die Zeichenkette beginnend bei index mit der Zeichenkette set überschrieben wird. Die Länge der zurückgelieferten Zeichenkette ist größer oder gleich der von str. Ist einer der Parameter NIL oder ist index außerhalb des gültigen Bereichs, dann wird NIL geliefert.

Beispiel: `(SETMIDSTR "Hallo Welt!" 6 "Melanie!")' liefert "Hallo Melanie!".

Siehe auch INSMIDSTR, REPLACESTR.

INSMIDSTR

INSMIDSTR wird verwendet, um eine Teilzeichenkette in eine Zeichenkette einzufügen.

(INSMIDSTR str index insert)

Liefert eine Kopie der Zeichenkette str, in der die Zeichenkette insert an der gegebenen Stelle eingefügt wurde. Ist eines der Parameter NIL oder ist index außerhalb des gültigen Bereichs, dann wird NIL zurückgeliefert.

Beispiel: `(INSMIDSTR "Hallo Welt!" 6 "MUIbase-")' liefert "Hallo MUIbase-Welt!".

Siehe auch SETMIDSTR, REPLACESTR.

INDEXSTR

INDEXSTR sucht in einer Zeichenkette nach dem ersten Vorkommen der Teilzeichenkette.

(INDEXSTR str substr)

Sucht nach dem ersten Vorkommen von substr in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) von der Teilzeichenkette in str oder NIL, wenn die Teilzeichenkette nicht vorhanden ist. Ist eines der Argumente NIL, dann wird NIL zurückgegeben.

Beispiel: `(INDEXSTR "Hallo Welt!" "Welt")' liefert 6.

Siehe auch INDEXSTR*, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.

INDEXSTR*

INDEXSTR* hat den selben Effekt als INDEXSTR (siehe INDEXSTR), außer daß der Zeichenkettenvergleich nicht auf Groß-/Kleinschreibung achtet.

Siehe auch INDEXSTR, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.

INDEXBRK

INDEXBRK sucht nach dem ersten Vorkommen eines Zeichens in einer Zeichenkette.

(INDEXBRK str brkstr)

Sucht nach dem ersten Vorkommen eines Zeichens von brkstr(45) in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) des ersten Zeichens, das in str gefunden wurde, anderenfalls NIL. Ist eines der Parameter NIL, dann wird NIL geliefert.

Beispiel: `(INDEXBRK "Hallo Welt!" "aeiou")' liefert 1.

Siehe auch INDEXBRK*, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.

INDEXBRK*

INDEXBRK* hat den selben Effekt wie INDEXBRK (siehe INDEXBRK), außer daß der Zeichenvergleich nicht auf Groß-/Kleinschreibung achtet.

Siehe auch INDEXBRK, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.

RINDEXSTR

RINDEXSTR sucht in einer Zeichenkette nach dem letzten Vorkommen der Teilzeichenkette.

(RINDEXSTR str substr)

Sucht nach dem letzten Vorkommen von substr in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) von der Teilzeichenkette in str oder NIL, wenn die Teilzeichenkette nicht vorhanden ist. Ist eines der Argumente NIL, dann wird NIL zurückgegeben.

Beispiel: `(RINDEXSTR "Do itashimashite." "shi")' liefert 11 (46).

Siehe auch RINDEXSTR*, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.

RINDEXSTR*

RINDEXSTR* hat den selben Effekt als RINDEXSTR (siehe RINDEXSTR), außer daß der Zeichenkettenvergleich nicht auf Groß-/Kleinschreibung achtet.

Siehe auch RINDEXSTR, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.

RINDEXBRK

RINDEXBRK sucht nach dem letzten Vorkommen eines Zeichens in einer Zeichenkette.

(RINDEXBRK str brkstr)

Sucht nach dem letzten Vorkommen eines Zeichens von brkstr(47) in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) des letzten Zeichens, das in str gefunden wurde, anderenfalls NIL. Ist eines der Parameter NIL, dann wird NIL geliefert.

Beispiel: `(RINDEXBRK "Konnichiwa" "chk")' liefert 6.

Siehe auch RINDEXBRK*, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.

RINDEXBRK*

RINDEXBRK* hat den selben Effekt wie RINDEXBRK (siehe RINDEXBRK), außer daß der Zeichenvergleich nicht auf Groß-/Kleinschreibung achtet.

Siehe auch RINDEXBRK, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.

REPLACESTR

REPLACESTR ersetzt Teilzeichenketten durch andere.

(REPLACESTR str substr replacestr)

Ersetzt alle Vorkommen von substr in str durch replacestr. Wenn eine der Zeichenketten NIL ist oder substr leer ist, dann wird NIL zurückgeliefert.

Beispiel: `(REPLACESTR "From Freiburg to San Francisco" "Fr" "X")' liefert "Xom Xeiburg to San Xancisco".

Siehe auch SETMIDSTR, INSMIDSTR, REMCHARS.

REMCHARS

REMCHARS entfernt Zeichen aus einer Zeichenkette.

(REMCHARS str chars-to-remove)

Liefert eine Kopie von str, in der alle Zeichen von chars-to-remove entfernt wurden. Ist str oder chars-to-remove NIL, dann wird NIL geliefert.

Beispiel: `(REMCHARS deine-zeichenkette " \t\n")' entfernt alle Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen aus deine-zeichenkette.

Siehe auch REPLACESTR, TRIMSTR.

TRIMSTR

TRIMSTR entfernt führende und abschließende Leerzeichen von einer Zeichenkette.

(TRIMSTR str)

Liefert eine Kopie von str, in der alle führenden und abschließenden Leerzeichen entfernt wurden.

Beispiel: (TRIMSTR " Ich fuhr Selmas Fahrrad zu Schrott. ") liefert "Ich fuhr Selmas Fahrrad zu Schrott.".

Siehe auch REMCHARS.

WORD

WORD liefert ein Wort einer Zeichenkette.

(WORD str num)

Liefert das num-te Wort (beginnend bei Null) aus der gegebenen Zeichenkette. Wörter in einer Zeichenkette sind nicht-leere Teilzeichenketten, die durch Leerzeichen-ähnliche Zeichen (z.B. Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen) getrennt werden.

Ist str oder num gleich NIL oder ist num außerhalb des gültigen Bereichs (negativ oder größer als Anzahl Wörter in der Zeichenkette), dann wird NIL zurückgeliefert.

Beispiel: `(WORD "Deshalb lieh ich Selma mein Fahrrad." 3)' liefert "Selma".

Siehe auch WORDS, LINE, LEFTSTR, RIGHTSTR, MIDSTR.

WORDS

WORDS zählt die Anzahl der Wörter in einer Zeichenkette.

(WORDS str)

Liefert die Anzahl der Wörter in der gegebenen Zeichenkette oder NIL, wenn str NIL ist. Wörter sind Teilzeichenketten, die durch Leerzeichen-ähnliche Zeichen (z.B. Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen) getrennt werden.

Beispiel: `(WORDS "In Wirklichkeit ist es aber nicht mein Fahrrad.")' liefert 8.

Siehe auch WORD, LINES, LEN.

CONCAT

CONCAT verbindet Zeichenketten.

(CONCAT [str ...])

Liefert die Verknüpfung der gegebenen Liste von Zeichenketten, wobei einzelne Leerzeichenzwischen den Zeichenketten eingefügt werden. Ist eine der Zeichenketten NIL oder die Liste leer, dann wird NIL zurückgeliefert.

Beispiele: `(CONCAT "Ich" "dachte," "es" "war" "ein "verlassenes" "Fahrrad.")' liefert "Ich dachte, es war ein verlassenes Fahrrad.".

Siehe auch CONCAT2, Werte addieren, COPYSTR, SPRINTF.

CONCAT2

CONCAT2 verbindet Zeichenketten.

(CONCAT2 insert [str ...])

Liefert die Verknüpfung der gegebenen Liste von Zeichenketten. Zwischen den Zeichenketten wird jeweils die gegebene Zeichenkette insert eingefügt. Ist eine der Zeichenketten NIL oder die Liste leer, dann wird NIL zurückgeliefert.

Beispiel: `(CONCAT2 "! " "Aber" "es" "war es nicht!")' liefert "Aber! es! war es nicht!".

Siehe auch CONCAT, Werte addieren, COPYSTR, SPRINTF.

COPYSTR

COPYSTR erzeugt Kopien einer Zeichenkette.

(COPYSTR str num)

Liefert eine Zeichenkette, die num mal die Zeichenkette str enthält. Ist str NIL, num gleich NIL oder kleiner als NUll, dann wird NIL zurückgegeben.

Beispiel: `(COPYSTR "+-" 5)' liefert "+-+-+-+-+-"

Siehe auch CONCAT CONCAT2, Werte addieren, SPRINTF.

UPPER

UPPER wandelt eine Zeichenkette in Großbuchstaben.

(UPPER str)

Liefert eine Kopie der gegebenen Zeichenkette, in der alle Zeichen zu Großbuchstaben umgewandelt wurden(48). Ist str NIL, dann wird NIL geliefert.

Beispiel: `(UPPER "Selma fand einen Brief, der an mein Fahrrad geheftet war.")' liefert "SELMA FAND EINEN BRIEF, DER AN MEIN FAHRRAD GEHEFTET WAR.".

Siehe auch LOWER.

LOWER

LOWER wandelt eine Zeichenkette in Kleinbuchstaben.

(LOWER str)

Liefert eine Kopie der gegebenen Zeichenkette, in der alle Zeichen zu Kleinbuchstaben umgewandelt wurden. Ist str NIL, dann wird NIL geliefert.

Beispiel: `(LOWER "Der Brief war von Silke.")' liefert "der brief war von silke.".

Siehe auch UPPER.

ASC

ASC wandelt ein Zeichen in ihren ASCII-Code.

(ASC str)

Liefert den ASCII-Code des ersten Zeichens von str. Ist str leer, wird 0 geliefert. Ist str NIL, dann wird NIL geliefert.

Beispiel: (ASC "A") liefert 65.

Siehe auch CHR, INT.

CHR

CHR wandelt einen ASCII-Code in ein Zeichen um.

(CHR int)

Liefert eine Zeichenkette, die das Zeichen mit dem ASCII-Code int enthält. Ist int gleich 0, dann wird eine leere Zeichenkette geliefert. Ist int NIL oder nicht inner halb des ASCII-Zeichensatzes (0..255), dann wird NIL geliefert.

Beispiel: `(CHR 99)' liefert to "c".

Siehe auch ASC, STR.

LIKE

LIKE vergleicht Zeichenketten.

(LIKE str1 str2)

Liefert TRUE, wenn str1 mit str2 übereinstimmt, anderenfalls NIL. Die Zeichenkette str2 kann die Jokerzeichen '?' und '*' enthalten, wobei '?' genau irgendein einzelnes Zeichen und '*' eine Zeichenkette jeder Länge irgendeines Inhalts(49) darstellt. Der Zeichenkettenvergleich wird ohne Beachtung der Groß-/Kleinschreibung durchgeführt.

Beispiel: `(LIKE "Silke war für ein Jahr in Frankreich." "*Jahr*")' liefert TRUE.

Siehe auch Vergleichsfunktionen.

SPRINTF

SPRINTF formatiert eine Zeichenkette mit verschiedenen Daten.

(SPRINTF fmt [expr ...])

SPRINTF erhält eine Reihe von Parametern, die in Zeichenketten umgewandelt werden und in aufbereiteter Form als einzelne Zeichenkette zurückgegeben wird. Die Zeichenkette fmt entscheidet genau, was in die zurückgegebene Zeichenkette geschrieben werden soll und kann zwei Arten von Elemente enthalten: ordinäre Zeichen, die unverändert kopiert werden und Umwandlungsbefehle, die SPRINTF anweisen, die Parameter aus seiner Parameterliste zu nehmen und zu formatieren. Umwandlungsbefehle beginnen immer mit dem Zeichen `%'.

Umwandlungsbefehle benötigen immer diese Form:

%[flags][width][.precision]type

where

Zu beachten ist, daß alle Felder außer type optional sind. Die folgenden Tabellen listen die gültigen Optionen für diese Felder auf.

Flaggenfeld flags

-:
Das Ergebnis ist linksbündig, das rechts mit Leerzeichen aufgefüllt wird. Normalerweise wird das Feld rechtsbündig ausgerichtet und links mit Leerzeichen oder `0'en aufgefüllt, wenn kein `-' angegeben wird.
+:
Das Ergebnis erhält immer ein Zeichen `-' oder `+' vorangestellt, wenn es eine numerische Umwandlung ist.
Leerzeichen:
Positive Zahlen erhalten ein Leerzeichen anstatt dem Zeichen `+', aber negative Zahlen bekommen nach wie vor das Zeichen `-' vorangestellt.

Breitenfeld width

n:
Mindestens n Zeichen werden ausgegeben. Hat die Umwandlung weniger als n Zeichen ergeben, dann wird mit Leerzeichen aufgefüllt.
*:
Der Breite-Parameter wird in der Parameterliste als Ganz- oder Fließkommazahl vor dem eigentlichen Umwandlungsparameter mitgeliefert. Der Wert ist beschränkt auf 0 bis 999.

Genaugkeitsfeld precision

.n:
Für Ganzzahl-, Zeichenketten-, Bool-, Datums- und Zeit-Werte ist n die Anzahl der auszugebenden Zeichen vom umgewandelten Element. Für Umwandlungen von Fließkommazahlen legt n die Anzahl der Nachkommastellen fest.
.*:
Die Genauigkeit wird in der Parameterliste als Ganz- oder Fließkommazahl vor dem eigentlichen Umwandlungsparameter mitgeliefert. Der Wert ist beschränkt auf 0 bis 999.

(Anm.d.Übersetzers: Bitte nicht den davorstehenden Punkt übersehen!)

Typenfeld type

b:
Wandelt einen booleschen Parameter nach "TRUE" (wahr) oder "NIL" (falsch).
i:
Wandelt eine Ganzzahl um.
e:
Wandelt eine Fließkommazahl in das Format `[-]d.ddde+dd' um. Genau eine Ziffer erscheint vor dem Dezimalpunkt, gefolgt von Nachkommastellen, einem `e' und dem Exponenten. Die Anzahl der Nachkommastellen wird im Genauigkeitsfeld festgelegt oder wenn nicht, dann ist sie 2. Der Dezimalpunkt erscheint nicht, wenn sie 0 ist.
f:
Wandelt eine Fließkommazahl in das Format `[-]ddd.ddd' um. Die Anzahl der Nachkommastellen wird im Genauigkeitsfeld festgelegt oder wenn nicht, dann ist sie 2. Der Dezimalpunkt erscheint nicht, wenn sie 0 ist.
s:
Schreibt eine Zeichenkette bis zum Ende der Zeichenkette oder soviele Zeichen, wie im Präzisionsfeld angegeben.
d:
Wandelt einen Datumswert um.
t:
Wandelt einen Zeitwert um.
%:
Nur das Zeichen `%' wird geschrieben und kein Parameter umgewandelt.

SPRINTF liefert die formatierte Zeichenkette oder NIL, wenn fmt NIL ist.

Beispiele

Aufruf                          Ergebnis

(SPRINTF "Hallo")                "Hallo"
(SPRINTF "%s" "Hallo")           "Hallo"
(SPRINTF "%10s" "Hallo")         "     Hallo"
(SPRINTF "%-10.10s" "Hallo")     "Hallo     "
(SPRINTF "%010.3s" "Hallo")      "       Hal"
(SPRINTF "%-5.3b" TRUE)          "TRU  "
(SPRINTF "%i" 3)                 "3"
(SPRINTF "%03i" 3)               "003"
(SPRINTF "% 0+- 5.3i" 3)         " 003 "
(SPRINTF "%f" 12)                "12.00"
(SPRINTF "%10e 12.0)             "   1.20e+1"
(SPRINTF "%+-10.4f" 12.0)        "+12.0000  "
(SPRINTF "%10.5t" 12:30:00)      "     12:30"
(SPRINTF "%d" 28.11.1968)        "28.11.1968"
(SPRINTF "Ha%s %4.4s!"
   "llo"
   "Weltmeisterschaft")          "Hallo Welt!"

Siehe auch PRINTF, FPRINTF, STR, Werte addieren, CONCAT, CONCAT2, COPYSTR.

Funktionen für mehrzeilige Texte

Dieser Abschnitt behandelt Funktionen für mehrzeilige Texte.

LINE

LINE holt eine Zeile aus einem mehrzeiligen Text.

(LINE memo num)

Liefert die num-te Zeile (beginnend bei Null) aus dem gegebenen mehrzeiligen Text. Die Zeile hat dann kein abschließendes Neue-Zeile-Zeichen.

Ist str oder num gleich NIL oder ist num außerhalb des gültigen Bereichs (negativ oder größer als Anzahl Zeilen), dann wird NIL zurückgeliefert.

Siehe auch LINES, WORD.

LINES

LINES liefert die Anzahl der Zeilen in einem mehrzeiligen Text.

(LINES memo)

Liefert die Anzahl der Zeilen des gegebenen mehrzeiligen Textes oder NIL, wenn memo NIL ist.

Siehe auch LINE, WORDS, LEN.

MEMOTOLIST

MEMOTOLIST wandelt einen mehrzeiligen Text in eine Liste von Zeichenketten um.

(MEMOTOLIST memo)

Wandelt den gegebenen mehrzeiligen Text in eine Liste. Ist memo gleich NIL, dann wird NIL geliefert, anderenfalls wird eine Liste erzeugt, in der jedes Element eine Zeile des mehrzeiligen Textes enthält.

Beispiel: `(MEMOTOLIST "Meine Versicherung\nzahlt für\ndas kaputte Fahrrad.")' liefert ( "Meine Versicherung" "zahlt für" "das kaputte Fahrrad." ).

Siehe auch LISTTOMEMO.

LISTTOMEMO

LISTTOMEMO wandelt eine Liste in einen mehrzeiligen Text um.

(LISTTOMEMO list)

Wandelt eine gegebene Liste in einen mehrzeiligen Text. Ist list gleich NIL, dann wird NIL zurückgegeben, anderenfalls wird ein mehrzeiliget Text erzeugt, dessen einzelne Zeilen die Zeichenkettendarstellung des entsprechenden Listenelements enthalten(50).

Beispiel: `(LISTTOMEMO (LIST "Silke" "leiht mir" "'mein' Fahrrad" "bis zum" 01.09.1998)' liefert: "Silke\nleiht mir\n'mein' Fahrrad\nbis zum\n01.09.1998".

Siehe auch MEMOTOLIST.

FILLMEMO

FILLMEMO füllt einen mehrzeiligen Text mit den Ergebnissen von Ausdrücken.

(FILLMEMO memo)

Erzeugt eine Kopie des gegebenen mehrzeiligen Textes, in dem alle Teilzeichenketten der Form `$(expr)' durch ihre Ergebnisse nach der Auswertung ersetzt werden.

Beispiel: `(FILLMEMO "(+ 1 1) ist $(+ 1 1).")' liefert "(+ 1 1) ist 2."

Man sollte nur kleine Ausdrücke in einem mehrzeiligen Text verwenden, da die Fehlersuche nicht einfach ist(51).

Siehe auch FORMATMEMO, INDENTMEMO.

FORMATMEMO

FORMATMEMO formatiert einen mehrzeiligen Text.

(FORMATMEMO memo width fill)

Formatiert memo in einen mehrzeiligen Text mit Zeilen, die nicht länger sind als width Zeichen. Ist fill nicht NIL, dann werden Leerzeichen zum Auffüllen der Zeilen verwendet, damit die Zeilen genau die Länge width erhalten. Der mehrzeilige Test wird abschnittweise abgearbeitet. Ein Abschnitt beginnt beim ersten Zeichen, das kein Leerzeichen ist. Die Zeile mit diesem Zeichen mit den nachfolgenden Zeilen bis zur Zeile, in der das erste Zeichen win Leerzeichen ist, wird als Abschnitt aufgefaßt. Der gesamte Abschnitt wird wortweise formatiert, dies bedeutet, es werden soviele Wörter in eine Zeile gesetzt, wie dafür Platz ist(52).

Siehe auch FILLMEMO, INDENTMEMO.

INDENTMEMO

INDENTMEMO rückt einen mehrzeiligen Text ein, in dem links Leerzeichen eingefügt werden.

(INDENTMEMO memo indent)

Liefert eine Kopie des gegebenen mehrzeiligen Textes, in dem jede Zeile mit indent Leerzeichen eingerückt wird. Ist memo oder indent NIL, dann wird NIL zurückgeliefert. Ist indent negativ, dann wird 0 angenommen.

Siehe auch FILLMEMO, FORMATMEMO.

Listenfunktionen

Dieser Abschnitt listet Funktionen zum Verarbeiten von Listen auf.

CONS

CONS erzeugt ein Paar von Ausdrücken.

(CONS elem list)

Erzeugt eine neue Liste. Das erste Element der neuen Liste ist elem, der Rest sind die Elemente von list (die eine Liste sein muß oder NIL). Die Liste list wird nicht kopiert, sondern nur ein Zeiger auf diese wird verwendet(53)!

Beispiel: `(CONS 1 (CONS 2 NIL))' liefert ( 1 2 ).

Die Elemente der Liste können von jedem Typ sein, z.B. ist es auch möglich, eine Liste von Listen zu haben (z.B. siehe SELECT). Der Konstruktor CONS kann auch verwendet werden, um Element-Paare zu erzeugen, z.B. `(CONS 1 2)' ist ein Paar mit den Ganzzahlen 1 und 2.

Siehe auch LIST, FIRST, REST.

LIST

LIST erzeugt eine Liste anhand ihrer Parameter.

(LIST [elem ...])

nimmt die Parameter elem ... und generiert daraus eine Liste. Dies ist gleichbedeutend dem Aufruf von (CONS elem (CONS ... NIL)). Man beachte, daß NIL alleine für eine leere Liste steht.

Siehe auch CONS, LENGTH.

LENGTH

LENGTH ermittelt die Länge einer Liste.

(LENGTH list)

liefert die Länge der gegebenen Liste.

Beispiel: `(LENGTH (LIST "a" 2 42 3))' liefert 4.

Siehe auch LIST.

FIRST

FIRST holt das erste Element aus einer Liste.

(FIRST list)

liefert das erste Element der gegebenen Liste. Ist list leer (NIL), dann wird NIL geliefert.

Siehe auch REST, LAST, NTH, CONS.

REST

REST liefert die Teilliste nach dem ersten Element einer Liste.

(REST list)

liefert den Rest der gegebenen Liste (die Liste ohne dem ersten Element). Ist list leer (NIL), dann wird NIL zurückgeliefert.

Beispiel: `(REST (LIST 1 2 3))' liefert ( 2 3 ).

Siehe auch FIRST, CONS.

LAST

LAST holt das letzte Element aus einer Liste.

(LAST list)

Liefert das letzte Element der gegebenen Liste oder NIL, wenn list NIL ist.

Siehe auch FIRST, NTH.

NTH

NTH holt das n-te Element aus einer Liste.

(NTH n list)

Liefert das n-te Element der gegebenen Liste (beginnend bei 0) oder NIL, wenn das Element nicht existiert.

Siehe auch FIRST, LAST.

APPEND

APPEND verbindet Listen.

(APPEND [list ...])

liefert die Verknüpfung von list ....

Beispiel: `(APPEND (list 1 2) (list 3 4) (list 5))' liefert ( 1 2 3 4 5 ).

Siehe auch LIST.

REVERSE

REVERSE kehrt eine Liste um.

(REVERSE list)

liefert die umgekehrte Liste(54).

Beispiel: `(REVERSE (list 1 2 3))' liefert ( 3 2 1 ).

MAPFIRST

MAPFIRST wendet eine Funktion auf alle Listenelemente an.

(MAPFIRST func list [...])

Erzeugt eine Liste, deren Elemente das Ergebnis einer angegebenen Funktion sind, die als Parameter die einzelnen Listenelemente der Reihe nach bekommen hat. Die Länge der zurückgelieferten Liste ist genau so lang, wie die längste angegebene Liste. Ist eine der gegebenen Listen zu kurz, dann wird die Liste mit NIL aufgefüllt.

Beispiele

Ausdruck                              Wert

(MAPFIRST 1+ (LIST 1 2 3))             ( 2 3 4 )
(MAPFIRST + (LIST 1 2 3) (LIST 2 3))   ( 3 5 NIL )

SORTLIST

SORTLIST sortiert die Elemente einer Liste.

(SORTLIST func list)

Liefert eine Kopie der gegebenen Liste, die mit der Funktion func sortiert wurde. Die Sortierfunktion muß zwei Parameter für jedes Element verarbeiten und einen Ganzzahlwert liefern, der kleiner als Null ist, wenn das erste Element 'kleiner' ist als das zweite, einen Wert größer Null, wenn das zweite 'größer' ist als das erste und einen Wert gleich Null, wenn beide Elemente 'gleich' sind.(55)

Beispiel für eine Zeichenkettenvergleichsfunktion für die Sortierung:

(DEFUN cmp_str (x y)
    (COND
        ((< x y) -1)
        ((> x y) 1)
        (TRUE 0)
    )
)

Nun läßt sich eine Liste durch den Aufruf

(SORTLIST cmp_str (LIST "hi" "gut" "großartig" "ok"))

sortieren, die ( "großartig" "gut" "hi" "ok" ) liefert.

Siehe auch SORTLISTGT, MAPFIRST.

SORTLISTGT

SORTLIST sortiert die Elemente einer Liste.

(SORTLISTGT gtfunc list)

Arbeitet wie SORTLIST, aber hier wird eine Sortierfunktion angegeben, die einen Wert ungleich NIL liefert, wenn das erste Element 'größer' ist als das zweite, anderenfalls NIL.

Beispiel: `(SORTLISTGT > (LIST "hi" "gut" "großartig" "ok"))' liefert ( "großartig" "gut" "hi" "ok" ).

Siehe auch SORTLIST, MAPFIRST.

Benutzereingabefunktionen

Zum Abfragen von Benutzereingaben können folgende Funktionen verwendet werden:

ASKFILE

ASKFILE fragt den Benutzer nach einem Dateinamen.

(ASKFILE title oktext default savemode)

Öffnet ein Dateiauswahlfenster zur Eingabe eines Dateinamens. Der Fenstertitel kann in title, der Text des `Ok'-Knopfes in oktext und der vorgegebene Dateiname in default gesetzt werden. Für jeden dieser Argumente kann NIL gesetzt werden, um Vorgabewerte zu verwenden. Der letzte Parameter savemode (bool) setzt das Dateiauswahlfenster in den Speichermodus. Dieser Modus sollte verwendet werden, wenn nach einem Dateinamen gefragt wird, im etwas in eine Datei zu schreiben.

ASKFILE liefert den eingegebenen Dateinamen als Zeichenkette oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Siehe auch ASKDIR, ASKSTR.

ASKDIR

ASKDIR fragt den Benutzer nach einem Verzeichnisnamen.

(ASKDIR title oktext default savemode)

Öffnet ein Dateiauswahlfenster zur Eingabe eines Verzeichnisnamens. Die Parameter werden auf die gleiche Weise verwendet als wie(56) in ASKFILE (siehe ASKFILE).

ASKDIR liefert den eingegebenen Verzeichnisnamen als Zeichenkette oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Siehe auch ASKFILE, ASKSTR.

ASKSTR

ASKSTR fragt den Benutzer nach einer Zeichenkette.

(ASKSTR title oktext default maxlen)

Öffnet ein Fenster, das nach einer Zeichenketteneingabe fragt. Der Fenstertitel, der Text des `Ok'-Knopfes und der Vorgabewert können mit title, oktext beziehungsweise default (mit Zeichenketten oder NIL für die Vorgabewerte) gesetzt werden. maxlen bestimmt die maximale Anzahl Zeichen, die der Benutzer eingeben kann.

ASKSTR liefert die eingegebene Zeichenkette oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Siehe auch ASKFILE, ASKDIR, ASKCHOICESTR, ASKINT.

ASKINT

ASKINT fragt den Benutzer nach einer Ganzzahl.

(ASKINT title oktext default min max)

Öffnet ein Eingabefenster, das nach einer Ganzzahleingabe fragt. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In default wird der Vorgabewert übergeben oder NIL, wenn mit einem leeren Feld begonnen werden soll. In min und max wird der erlaubte Zahlenbereich festgelegt. Eingegebene Werte außerhalb dieses Bereichs werden vom Eingabefenster nicht akzeptiert. Man verwende NIL für den Vorgabebereich(57).

ASKINT liefert die eingegebene Ganzzahl oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Siehe auch ASKSTR.

ASKCHOICE

ASKCHOICE fragt den Benutzer nach einer Auswahl aus mehreren Elementen.

(ASKCHOICE title oktext choices default)

Öffnet ein Eingabefenster, das den Benutzer nach einem Element aus mehreren fragt. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In choices wird eine Liste angegeben, aus dieser sich der Benutzer einen Eintrag auswählen kann. Diese Listeneinträge können alle Arten von Ausdrücken haben, die in Zeichenketten umgewandelt werden können. Die vorgegebene Auswahl wird in default angegeben, die ein Ganzzahlindex auf die Auswahlliste (beginnend bei Index 0 für das erste Element) ist und NIL markiert keine vorgegebene Auswahl.

ASKCHOICE liefert den Index des gewählten Elements oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Beispiel

(LET ((items (LIST "Erster Eintrag" 2 3.14 "Letzter Eintrag")) index)
    (SETQ index (ASKCHOICE "Wähle ein Element" "Ok" items NIL))
    (IF index
        (PRINTF "Benutzer wählte Element Nummer %i mit dem Inhalt <%s>\n"
            index (STR (NTH index items))
        )
    )
)

Siehe auch ASKCHOICESTR, ASKOPTIONS.

ASKCHOICESTR

ASKCHOICESTR fragt den Benutzer nach einer Zeichenkette und bietet vorgegebene an.

(ASKCHOICESTR title oktext strings default)

Öffnet ein Eingabefenster, das dem Benutzer erlaubt, eine Zeichenkette aus mehreren auszuwählen oder jede beliebige Zeichenkette im separaten Zeichenkettenfeld einzugeben. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In strings wird eine Liste von Zeichenketten übergeben, aus der der Benutzer eine auswählen kann. Der Vorgabewert des Zeichenkettenfeldes kann mit default (als Zeichenkette oder NIL für ein leeres Zeichenkettenfeld) gesetzt werden.

ASKCHOICESTR liefert die ausgewählte Zeichenkette oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.

Beispiel

(LET ((strings (LIST "Claudia" "Mats" "Ralphie")) likebest)
    (SETQ likebest
        (ASKCHOICESTR "Wen mögen Sie am liebsten?" "Ok" strings "Meine Collie-Hunde!")
    )
    (IF likebest (PRINTF "Benutzer wählte <%s>\n" likebest))
)

Siehe auch ASKCHOICE, ASKOPTIONS.

ASKOPTIONS

ASKOPTIONS fragt den Benutzer nach mehreren aus einer Liste von Elementen.

(ASKOPTIONS title oktext options selected)

Öffnet ein Eingabefenster, das dem Benutzer erlaubt, mehrere Optionen aus vielen auszuwählen. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In options wird eine Liste von Optionen angegeben, aus der der Benutzer mehrere auswählen kann. Die Listenelemente können jeder Art von Ausdrücken sein, die sich in Zeichenketten umwandeln lassen. Die Vorgabeauswahl läßt sich in selected festlegen, die eine Liste von Ganzzahlen ist und jeweils den Index des entsprechenden Elements in der Liste options angibt, der vorab ausgewählt wird. Wird NIL statt der Liste angegeben, dann werden keine Elemente vorab ausgewählt.

ASKOPTIONS liefert eine Liste von Ganzzahlen, die den Index der ausgewählten Elemente enthält oder NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen oder kein Element ausgewählt hat.

Beispiel

(LET ((options (LIST "Salva Mea" "Insomnia" "Don't leave" "7 days & 1 week"))
        (selected (LIST 0 1 3))
    )
    (SETQ selected (ASKOPTIONS "Wähle Musiktitel" "Ok" options selected))
    (IF selected
        (
            (PRINTF "Benutzer wählte folgende Einträge:\n")
            (DOLIST (i selected)
                (PRINTF "\tNummer %i enthält: <%s>\n" i (STR (NTH i options)))
            )
        )
    )
)

(Anm.d.Übersetzers: Hier hören Programmierer und Übersetzer die gleiche Musik von Faithless :-)

ASKBUTTON

ASKBUTTON fragt den Benutzer nach einen Knopfdruck.

(ASKBUTTON title text buttons canceltext)

Öffnet ein Eingabefenster mit dem gegebenen Fenstertitel title (als Zeichenkette oder NIL für einen Vorgabetitel) und dem gegebenen Beschreibungstext text (als Zeichenkette oder NIL für keinen Text). Die Funktion wartet auf einen Druck der in buttons (als Liste von Zeichenketten) festgelegten Knöpfe oder des `Abbrechen'-Knopfes. Der Text des Abbruchknopfes läßt sich mit canceltext ändern. Wird hier NIL angegeben, dann wird ein Vorgabetext verwendet, der sich nach der Anzahl der festgelegten Knöpfe richtet.

ASKBUTTON liefert die Nummer des gedrückten Knopfes (beginnend bei 0 mit dem am weitesten links angeordneten Knopf) oder NIL, wenn der Benutzer den `Abbruch'-Knopf gedrückt hat.

Beispiele

(LET ((buttons (LIST "Zuhause" "Im Bett" "Vor meinem Amiga")) index)
    (SETQ index (ASKBUTTON "Bitte beantworten:"
        "Wo werden sie morgen sein?" buttons "Weiß nicht")
    )
    (IF index
        (PRINTF "Benutzer entschied sich für: <%s>\n" (NTH index buttons))
    )
)

(ASKBUTTON "Info"
    "Du hast nun schon für fünf\nStunden mit deinem Amiga gespielt.\nGeh ins Bett!"
    NIL NIL
)

Siehe auch ASKCHOICE.

ASKMULTI

ASKMULTI fragt den Benutzer nach verschiedenartigen Informationen.

(ASKMULTI title oktext itemlist)

ASKMULTI ist ein Mehrzweck-Eingabefenster. Es öffnet ein Fenster mit dem angegebenen Titel title, einem Satz von grafischen Objekten für die Dateneingabe und zwei Knöpfen (`Ok' und `Abbrechen') zum Beenden des Eingabefensters. Der Text für den `Ok'-Knopf kann mit oktext verändert werden (als Zeichenkette oder NIL für einen Vorgabetext). Der Satz der grafischen Objekte werden in itemlist festgelegt, das eine Liste ein Elementen ist, in der jedes eine der folgenden Formate hat:

    (LIST title "String" initial [help])      zum Bearbeiten einer Textzeile,
    (LIST title "Memo" initial [help])        zum Bearbeiten von mehrzeiligen Texten,
    (LIST title "Integer" initial [help])     zum Bearbeiten einer Ganzzahl,
    (LIST title "Real" initial [help])        zum Bearbeiten einer Fließkommazahl,
    (LIST title "Date" initial [help])        zum Bearbeiten eines Datums,
    (LIST title "Time" initial [help])        zum Bearbeiten einer Zeit,
    (LIST title "Bool" initial [help])        zum Bearbeiten eines booleschen Wertes,
    (LIST title "Choice" initial
        (LIST choice ...) [help]
    )                                     für ein Auswahlfeld.
    (LIST title "ChoiceList" initial
        (LIST choice ...) [help]
    )                                     zum Auswählen eines Elements
                                          aus einer Liste.
    (LIST title "Options" initial
        (LIST choice ...) [help]
    )                                     zum Auswählen mehrerer Elemente
                                          aus einer Liste.
    non-list-expr                           für statischen Text

Der Titel title (als Zeichenkette oder NIL für keinen Titel) wird links neben dem grafischen Objekt angeordnet. Ist der Vorgabewert initial NIL, dann wird ein Vorgabewert verwendet (z.B. ein leeres Textfeld). Für Auswahlfelder muß der Vorgabewert der Index (beginnend bei 0) sein, für Auswahllistenfelder darf der Vorgabewert NIL (kein Eintrag ausgewählt) sein und für Optionsfelder muß der Vorgabewert eine Liste von Ganzzahlen sein, die die Indexe (beginnend bei 0) der Elemente sein, die vorbelegt sein sollen. Das optionale Hilfsfeld (eine Zeichenkette) kann verwendet werden, um dem Benutzer mehr Informationen über die Verwendung des Feldes mitzugeben.

ASKMULTI liefert eine Liste von Werten, die der Benutzer bearbeitet und über den `Ok'-Knopf bestätigt hat. Jeder Ergebniswert eines Feldes hat das gleiche Format wie der für den Vorgabewert, z.B. für ein Auswahllistenfeld ist der Rückgabewert der Index des ausgewählten Elements (oder NIL, wenn keines ausgewählt wurde) oder für Optionsfelder ist er die Liste von Ganzzahlen, die die Indexe der ausgewählten Elemente darstellen. Für statischen Text wird NIL zurückgegeben.

Wurde z.B. ein Datumsfeld, ein statischer Text, ein Auswahlfeld, ein Optionsfeld und ein Zeichenkettenfeld mit dem Vorgabewert "Welt" festgelegt und der Benutzer gab 11.11.1999 ein, wählte den Auswahleintrag mit dem Index 2, wählte das dritte und vierte Element des Optionsfeldes und ließ das Zeichenkettenfeld unberührt, dann liefert die Funktion die Liste ( 11.11.1999 NIL 2 ( 3 4 ) "world" ).

Brach der Benutzer das Eingabefenster ab, wird NIL geliefert.

Beispiel

(ASKMULTI "Bitte bearbeiten:" NIL (LIST
    (LIST "_Name" "String" "")
    (LIST "_Geburtstag" "Date" NIL)
    (LIST "Ge_schlecht" "Choice" 0 (LIST "männlich" "weiblich"))
    (LIST "_Hat ein Auto?" "Bool" NIL)
    (LIST "_Mag", "Options" (LIST 0 2)
        (LIST "Bier" "Wein" "Whisky" "Wodka" "Schnaps")
    ))
)

Man sehe sich auch das Projekt `AskDemo.mb' für weitere Beispiele an.

E/A-Funktionen

Dieser Abschnitt listet die Funktionen und Variablen zur Dateiein- und ausgabe (z.B. drucken) auf.

FOPEN

FOPEN öffnet eine Datei zum Lesen/Schreiben.

(FOPEN filename mode)

Öffnet eine Datei mit dem Dateinamen filename (als Zeichenkette). Das Argument mode (als Zeichenkette) steuert den Zugriff auf die Datei. Mit `"w"' wird die Datei zum Schreiben geöffnet, mit `"a"' zum Anfügen an die bestehende Datei und mit `"r"' zum Lesen aus einer Datei. Es sind auch andere Zeichen (oder Kombinationen von ihnen) möglich, wie z.B. `"r+"' zum Lesen und Schreiben. Es gibt keine Überprüfung, ob die angegebenen Modi gültig sind. Es wird jedoch NIL zurückgeliefert, wenn die Datei nicht geöffnet werden konnte.

FOPEN liefert bei Erfolg einen Dateihandler. Schlug er fehl, wird NIL geliefert. Sind filename oder mode NIL, dann wird NIL zurückgeliefert.

Beispiel: `(FOPEN "PRT:" "w")' öffnet und liefert einen Dateihandle zum Drucker.

Siehe auch FCLOSE, stdout, FFLUSH.

FCLOSE

FCLOSE schließt eine Datei.

(FCLOSE file)

Schließt gegebene Datei. Es liefert 0 bei Erfolg oder NIL, wenn ein Fehler auftrat. Ist file NIL, dann wird 0 geliefert (keine Fehler)! Der Zugriff auf eine Datei nach dem Schließen einer Datei ist eine illegale Operation und führt zum Abbruch der Programmausführung mit einer Fehlermeldung.

Siehe auch FOPEN, FFLUSH.

stdout

Die globale Variable stdout trägt den Dateihandle zur Standardausgabe von MUIbase. Der Ausgabedateinamen kann im Menüpunkt `Programm - Ausgabedatei...' gesetzt werden. Man kann `PRT:' verwenden, um die Ausgabe zum Drucken zu schicken oder `CON:////Output/CLOSE/WAIT' für die Ausgabe in ein (neues) Shellfenster.

Beim ersten Zugriff auf diese Variable (entweder direkt, z.B. durch den Aufruf von `(FPRINTF stdout ...)' oder indirekt, z.B. durch den Aufruf von `(PRINTF ...)') wird die Datei geöffnet. Die Datei wird nicht vor der Programmausführung geöffnet. Dies verhindert das Öffnen der Datei, wenn keine Ausgabe erzeugt wird, z.b. wenn einfach nur Berechnungen und Änderungen an einigen Datensätzen durchgeführt werden.

Wenn MUIbase die Programmausgabedatei nicht öffnen kann, dann wird die Ausführung unterbruchen und eine Fehlermeldung ausgegeben.

Siehe auch FOPEN, PRINTF.

PRINT

PRINT wandelt einen Ausdruck in eine Zeichenkette und gibt ihn aus.

(PRINT elem)

Wandelt den Wert von elem in eine lesbare Zeichenkette und gibt ihn über stdout aus. Diese Funktion ist hauptsächlich zu Prüfzwecken vorhanden.

Siehe auch PRINTF, stdout.

PRINTF

PRINTF gibt eine formatierte Zeichenkette aus.

(PRINTF format [expr ...])

Formatiert eine Zeichenkette aus der gegebenen Formatzeichenkette und seinen Parameter und gibt sie an stdout aus. Die Formatierung entspricht der von SPRINTF (siehe SPRINTF).

PRINTF liefert die Anzahl der ausgegebenen Zeichen oder NIL bei einem Fehler. Ist format NIL, dann wird NIL geliefert.

Beispiel: `(PRINTF "%i Tage und %i Woche" 7 1)' gibt die Zeichenkette "7 Tage und 1 Woche" nach stdout aus und liefert 18.

Siehe auch PRINT, FPRINTF, stdout.

FPRINTF

FPRINTF gibt eine formatierte Zeichenkette in eine Datei aus.

(FPRINTF file format [expr ...])

Formatiert eine Zeichenkette aus der gegebenen Formatzeichenkette und seinen Parameter und gibt sie in die angegebene Datei aus. Die Formatierung entspricht der von SPRINTF (siehe SPRINTF).

PRINTF liefert die Anzahl der ausgegebenen Zeichen oder NIL bei einem Fehler. Ist file NIL, dann liefert FPRINTF dennoch die Anzahl der potentiell geschriebenen Zeichen zurück, macht aber keine Ausgabe. Ist format NIL, dann wird NIL geliefert.

Siehe auch PRINTF, FOPEN.

FERROR

FERROR prüft, on ein Ein-/Ausgabefehler einer Datei aufgetreten ist.

(FERROR file)

liefert TRUE, wenn ein Fehler bei der gegebenen Datei auftrat, anderenfalls NIL. Ist `file' NIL, wird NIL geliefert.

Siehe auch FEOF, FOPEN, FCLOSE.

FEOF

FEOF prüft auf den Endestatus einer Datei.

(FEOF file)

Überprüft den Dateende-Indikator der gegebenen Datei und liefert TRUE, wenn er gesetzt ist, anderenfalls NIL. Ist `file' NIL, wird NIL geliefert.

Siehe auch FERROR, FTELL, FOPEN, FCLOSE.

FSEEK

FSEEK setzt die Schreib-/Leseposition in einer Datei.

(FSEEK file offset whence)

Setzt die Schreib-/Leseposition für die gegebene Datei. Die neue Position -gemessen in Bytes- wird erreicht durch das Hinzufügen von offset bytes bezogen auf die Position, die durch whence festgelegt wird. Ist whence auf SEEK_SET, SEEK_CUR oder SEEK_END gesetzt, dann ist offset relativ zum Beginn der Datei, der aktuellen Position beziehungsweise zum Ende der Datei.

Bei Erfolg liefert FSEEK 0, anderenfalls NIL und die Dateiposition bleibt unverändert. Ist file, offset oder whence NIL, oder ist whence nicht eine der Konstanten SEEK_SET, SEEK_CUR oder SEEK_END, dann wird NIL geliefert.

Siehe auch FTELL, Vordefinierte Konstanten.

FTELL

FTELL liefert die Schreib-/Leseposition der Datei.

(FTELL file)

Ermittelt die aktuelle Schreib-/Leseposition relativ zum Anfang der gegebenen Datei und liefert sie als Ganzzahl. Tritt ein Fehler auf oder ist `file' NIL, dann wird NIL geliefert. Siehe auch FSEEK, FEOF.

FGETCHAR

FGETCHAR liest ein Zeichen aus einer Datei.

(FGETCHAR file)

Liefert das nächste Zeichen von der gegebenen Datei als Zeichenkette oder NIL, wenn file NIL ist, das Ende der Datei erreicht wurde oder ein Fehler auftrat. Ist das nächste Zeichen ein Nullbyte, dann wird eine leere Zeichenkette geliefert.

Siehe auch FGETCHARS, FGETSTR, FPUTCHAR.

FGETCHARS

FGETCHARS liest Zeichen aus einer Datei.

(FGETCHARS num file)

liefert eine Zeichenkette, die die nächsten num Zeichen aus der gegebenen Datei enthält. Ist das Ende der Datei erreicht worden, bevor num Zeichen gelesen werden konnten, oder wenn ein Nullbyte gelesen wurde, dann werden nur die bisher gelesenen Zeichen zurückgegeben. Ist num oder file NIL, num negativ, das Ende der Datei erreicht worden, bevor das erste Zeichen gelesen wurde, oder ein Lesefehler aufgetreten, dann wird NIL zurückgeliefert.

Siehe auch FGETCHAR, FGETSTR.

FGETSTR

FGETSTR liest eine Zeichenkette aus einer Datei.

(FGETSTR file)

liefert die nächste Zeile aus der gegebenen Datei oder NIL, falls file NIL ist, das Ende der Datei erreicht wurde oder ein Fehler auftrat. Das Ende einer Zeile wird entweder durch ein Neue-Zeile-Zeichen oder durch ein Nullbyte gekennzeichnet oder falls das Ende der Datei erkannt wurde. In jedem Fall enthält die Zeichenkette keine Neue-Zeile-Zeichen.

Siehe auch FGETCHAR, FGETCHARS, FGETMEMO, FPUTSTR.

FGETMEMO

FGETMEMO liest einen mehrzeiligen Text aus einer Datei.

(FGETMEMO file)

liefert einen mehrzeiligen Text, der den Inhalt der gegebenen Datei bis zum nächsten Nullbyte oder zum Ende der Datei enthält. Ist file NIL, das Ende der Datei erreicht worden, bevor ein Zeichen gelesen wurde oder trat ein Fehler auf, dann wird NIL zurückgeliefert.

Siehe auch FGETSTR, FPUTMEMO.

FPUTCHAR

FPUTCHAR schreibt ein Zeichen in eine Datei.

(FPUTCHAR str file)

Schreibt das erste Zeichen von str in die gegebene Datei. Ist str leer, dann wird ein Nullbyte geschrieben. Sind str oder file NIL, dann passiert nichts. Liefert str oder NIL, wenn ein Ausgabefehler auftrat.

Siehe auch FPUTSTR, FGETCHAR.

FPUTSTR

FPUTSTR schreibt eine Zeichenkette in eine Datei.

(FPUTSTR str file)

Gibt str zusammen mit einem Neue-Zeile-Zeichen in die gegebene Datei aus. Sind str oder file NIL, dann passiert nichts. Liefert str oder NIL, wenn ein Ausgabefehler auftrat.

Siehe auch FPUTCHAR, FPUTMEMO, FGETSTR.

FPUTMEMO

FPUTMEMO schreibt einen mehrzeiligen Text in eine Datei.

(FPUTMEMO memo file)

Gibt memo in die gegebene Datei aus. Sind memo oder file NIL, dann passiert nichts. Liefert memo oder NIL, wenn ein Ausgabefehler auftrat.

Siehe auch FPUTSTR, FGETMEMO.

FFLUSH

FFLUSH leert den Schreibpuffer in eine Datei.

(FFLUSH file)

Schreibt den Schreibpuffer(58) der gegebenen Datei. Liefert 0 bei Erfolg, NIL bei einem Fehler. Ist file NIL, dann wird 0 zurückgegeben (kein Fehler).

Siehe auch FOPEN, FCLOSE.

Datensatzfunktionen

Dieser Abschnitt behandelt Funktionen für Datensätze.

NEW

NEW legt einen neuen Datensatz für eine Tabelle an.

(NEW table init)

Legt einen neuen Datensatz für die gegebene Tabelle an. Das Argument init legt den Datensatz fest, der zum Einrichten des neuen Datensatzes verwendet werden soll. Ein Wert von NIL steht für den Vorgabedatensatz.

NEW liefert den Datensatzzeiger für den neuen Datensatz.

Die Funktion NEW hat zudem den Nebeneffekt, daß der Programm-Datensatzzeiger der gegebenen Tabelle (siehe Tabellen) auf den neuen Datensatz gesetzt wird.

Beispiel: `(NEW table NIL)' legt einen neuen Datensatz in der gegebenen Tabelle an und richtet ihn mit dem Vorgabedatensatz ein.

Siehe auch NEW*, DELETE, Tabellen.

NEW*

NEW* ist die Version von NEW (siehe NEW) mit dem Stern.

(NEW* table init)

NEW* prüft, ob eine Auslösefunktion für die gegebene Tabelle (siehe Auslösefunktion Neu(59)) definiert wurde. Ist eine vorhanden, dann wird diese zum Anlegen des Datensatzes ausgeführt und dessen Ergebnis zurückgeliefert. Das Argument init gibt den Datensatz an, anhand dessen der neue Datensatz initialisiert werden soll (NIL für den Vorgabedatensatz).

Wurde keine Auslösefunktion eingerichtet, dann verhält sich die Funktion wie NEW.

Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben, wenn z.B. für eine Tabelle eine Auslösefunktion für `New' definiert wurde und diese Funktion NEW* aufruft, um den Datensatz anzulegen.

Siehe auch NEW, DELETE*.

DELETE

DELETE löscht einen Datensatz einer Tabelle.

(DELETE table requester)

Löscht den aktuellen Programm-Datensatz der gegebenen Tabelle, nachdem ein optionales Löschfenster bestätigt wurde. Das erste Argument definiert die Tabelle, für die der aktuelle Programm-Datensatz gelöscht werden soll und das zweite ist ein boolescher Ausdruck. Ist dieser NIL, dann wird der Datensatz stillschweigend gelöscht, anderenfalls wird der Status des Menüpunkts `Datensätze löschen bestätigen?' geprüft. Ist dieser nicht gesetzt, dann wird der Datensatz auch stillschweigend gelöscht, anderenfalls erscheint das Löschbestätigungsfenster, das bestätigt werden muß. Bricht der Benutzer die Löschfunktion ab, dann wird der Datensatz nicht gelöscht.

Der Rückgabewert der Funkion DELETE wiederspiegelt die ausgewählte Aktion. Liefert sie TRUE, dann ist der Datensatz gelöscht worden, anderenfalls NIL (wenn der Benutzer die Funktion unterbrochen hat).

Beim Löschen setzt DELETE den Programm-Datensatzzeiger (siehe Tabellen) der gegebenen Tabelle auf NIL.

Beispiel: `(DELETE table NIL)' löscht stillschweigend den aktuellen Datensatz der gegebenen Tabelle.

Siehe auch DELETE*, DELETEALL, NEW, Tabellen.

DELETE*

DELETE* ist die Version von DELETE (siehe DELETE) mit dem Stern.

(DELETE* table requester)

DELETE* prüft, ob eine Auslösefunktion für die gegebene Tabelle (siehe Auslösefunktion Löschen(60)) definiert wurde. Ist eine vorhanden, dann wird diese zum Löschen des Datensatzes ausgeführt und dessen Ergebnis zurückgeliefert. Das Argument requester gibt an, ob die Auslösefunktion ein Bestätigungsfenster öffnen soll, bevor der Datensatz gelöscht wird.

Wurde keine Auslösefunktion eingerichtet, dann verhält sich die Funktion wie DELETE.

Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben, wenn z.B. für eine Tabelle eine Auslösefunktion für `Delete' definiert wurde und diese Funktion DELETE* aufruft, um den Datensatz zu löschen.

Siehe auch DELETE, DELETEALL, NEW*.

DELETEALL

DELETEALL löscht alle Datensätze einer Tabelle.

(DELETEALL table[*])

Löscht alle Datensätze der gegebenen Tabelle. Wird ein Stern hinter dem Tabellennamen angehängt, dann werden nur die Datensätze gelöscht, die dem aktuellen Filter der Tabelle genügen. Es erscheint kein Sicherheitsfenster, bevor dir Datensätze gelöscht werden!

DELETEALL liefert TRUE, wenn alle Datensätze erfolgreich gelöscht werden konnten, anderenfalls NIL. Ist table NIL, dann wird NIL geliefert.

Beispiel: `(DELETEALL table*)' löscht alle Datensätze in der gegebenen Tabelle, die dem Filter der Tabelle genügen.

Siehe auch DELETE, Tabellen.

GETMATCHFILTER

GETMATCHFILTER liefert den Status der Filterübereinstimmung eines Datensatzes.

(GETMATCHFILTER rec)

Liefert TRUE, wenn der gegebene Datensatz dem Filter seiner Tabelle entspricht, anderenfalls NIL. Ist der Filter der Tabelle momentan nicht aktiviert, dann wird TRUE geliefert. Ist rec NIL (der Vorgabedatensatz), dann wird NIL geliefert.

Siehe auch SETMATCHFILTER, GETISSORTED, GETFILTERSTR, SETFILTERSTR.

SETMATCHFILTER

SETMATCHFILTER setzt den Status der Filterübereinstimmung eines Datensatzes.

(SETMATCHFILTER rec on)

Ändert den Status der Filterübereinstimmung beim gegebenen Datensatz auf den Wert von on. SETMATCHFILTER liefert den neuen Status der Filterübereinstimmung des gegebenen Datensatzes. Der neue Status kann vom erwarteten abweichen, weil das Setzen auf NIL nur dann wirksam ist, wenn der Filter der dazugehörigen Tabelle aktiviert ist, anderenfalls wird TRUE geliefert. Der Aufruf von SETMATCHFILTER mit dem Wert NIL für rec (der Vorgabedatensatz) liefert immer NIL.

Siehe auch GETMATCHFILTER, SETISSORTED, GETFILTERSTR, SETFILTERSTR.

GETISSORTED

GETISSORTED liefert den Sortierstatus eines Datensatzes.

(GETISSORTED rec)

Liefert TRUE, wenn der gegebene Datensatz nach der für die Tabelle definierten Reihenfolge sortiert ist, ansonsten NIL. Ist rec NIL, dann wird NIL geliefert.

Siehe auch SETISSORTED, GETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.

SETISSORTED

SETISSORTED setzt den Sortierstatus eines Datensatzes.

(SETISSORTED rec on)

Ändert den Sortierstatus des angegebenen Datensaztes auf on. Die Funktion wird verwendet, wenn man der Meinung ist, daß der Datensatz in der richtigen Reihenfolge steht (on = TRUE) oder er neu sortiert werden sollte (on = NIL). Neusortieren aller unsortierten Datensätze kann mit der Funktion REORDER (siehe REORDER) durchgeführt werden.

SETISSORTED liefert den neuen Sortierstatus des gegebenen Datensatzes. Der Aufruf von SETISSORTED mit dem Wert NIL für rec (der Anfangsdatensatz) wird NIL liefern.

Für ein Beispiel, wie diese Funktion angewendet wird, siehe Comparison function.

Siehe auch GETISSORTED, SETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.

RECNUM

RECNUM liefert die Datensatznummer des Datensatzes.

(RECNUM record)

Liefert die Datensatznummer des gegebenen Datensatzes. Man beachte, daß die Nummerierung der Datensätze von z.B. der der Listen abweicht. Bei Listen, Zeicheketten und anderem beginnt die Zählung bei Null, bei den Datensätzen beginnt sie jedoch bei 1. Die Nummer 0 ist für den Vorgabedatensatz reserviert. Dies scheint mit den restlichen MUIbase-Funktionen unvereinbar zu sein, aber hier macht es wirklich Sinn, da die Datensatznummern auch in der Fensteranzeige verwendet werden.

Siehe auch RECORDS, INT.

COPYREC

COPYREC kopiert Datensätze.

(COPYREC rec source)

Kopiert den Inhalt des Datensatzes source in den Datensatz rec. Ist source NIL, dann wird rec auf die Werte des Vorgabedatensatzes gesetzt. Ist rec NIL, dann wird eine Fehlermeldung erzeugt.

COPYREC liefert rec.

Siehe auch NEW.

Feldfunktionen

Dieser Abschnitt behandelt Funktionen für Felder einer Tabelle.

ATTRNAME

ATTRNAME liefert den Namen des Feldes.

(ATTRNAME attr)

Liefert eine Zeichenkette mit dem Namen des angegebenen Feldes.

Siehe auch TABLENAME

MAXLEN

MAXLEN liefert die maximale Anzahl von Zeichen eines Zeichenkettenfeldes.

(MAXLEN string-attr)

Liefert die maximale Anzahl von Zeichen, die das gegebene Zeichenkettenfeld aufnehmen kann.

Siehe auch LEN.

GETLABELS

GETLABELS liefert alle Auswahltexte eines Auswahl- oder Zeichenkettenfeldes.

(GETLABELS attr)

Liefert die Auswahltexte des gegebenenen Auswahl- oder Zeichenkettenfeldes. Im Falle eines Auswahlfeldes werden die im Auswahltexteditor (siehe Typabhängige Einstellungen(61)) eingegebenen Texte zurückgegeben, Bei Zeichenkettenfeldern werden die Auswahltexte zurückgegebene, die für das Listenansicht-Popup (siehe Feldobjekteditor) eingegeben wurden.

Die Auswahltexte werden in einer einzelnen Zeichenkette zurückgegeben und werden jeweils durch ein Neue-Zeile-Zeichen getrennt.

Beispiel: Man nehme an, man hat ein Auswahlfeld mit den Auswahltexten `Auto', `Haus' und `Öl'. Der Aufruf von GETLABELS mit diesem Feld liefert dann die Zeichenkette "Auto\nHaus\nÖl".

Hinweis: Diese Rückgabezeichenkette läßt sich einfach mit MEMOTOLIST (siehe MEMOTOLIST) in eine Liste umwandeln.

Siehe auch SETLABELS.

SETLABELS

SETLABELS wird verwendet, um die Auswahltexte eines Zeichenkettenfeldes zu setzen.

(SETLABELS attr str)

Setzt die Auswahltexte des Zeichenkettenfeldes attr auf die Auswahlfelder, die im Parameter str aufgelistet sind. Der Parameter str enthält für jeden Auswahltext eine Zeile. Die Auswahltexte ersetzen diejenigen, die in dem Listenansicht-Popup des Feldobjekteditors (siehe Feldobjekteditor) eingegeben wurden.

SETLABELS liefert den Wert des Parameters str.

Beispiel: `(SETLABELS Table.String "Mein Haus\nist\ndein Haus")' setzt die Listenansicht-Auswahltexte des gegebenen Zeichenkettenfeldes auf sets the list-view labels of the specifies string attribute to `Mein Haus', `ist' und `dein Haus'.

Hinweis: Man kann eine Liste von Auswahltexte durch den Aufruf von LISTTOMEMO in das benötigte Zeichenkettenformat umwandeln.

Siehe auch GETLABELS.

Tabellenfunktionen

TABLENAME

TABLENAME liefert den Namen einer Tabelle.

(TABLENAME table)

Liefert eine Zeichenkette, die den Namen der angegebenen Tabelle enthält.

Siehe auch ATTRNAME

GETORDERSTR

GETORDERSTR liefert die Datensatzreihenfolge einer Tabelle.

(GETORDERSTR table)

Verwendet die Tabelle eine Felderliste zum Sortieren, dann enthält die gelieferte Zeichenkette die Feldnamen, getrennt durch Leerzeichen. Jedes Feld hat ein `+' oder ein `-' vorangestellt, um eine auf- bzw. absteigende Sortierung anzuzeigen.

Wird die Tabelle anhand einer Vergleichsfunktion sortiert, dann wird der Name dieser Funktion geliefert.

Eine leere Zeichenkette zeigt an, daß keine Sortierung vorliegt.

Beispiel

Angenommen, es gibt eine Tabelle `Person', die nach ihren Feldern `Name' (aufsteigend), `Stadt' (aufsteigend) und `Geburtstag' (absteigend) sortiert ist. Dann liefert `(ORDERSTR Person)' die Zeichenkette "+Name +Stadt -Geburtstag".

Siehe auch SETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Sortieren, Comparison function.

SETORDERSTR

SETORDERSTR setzt die Sortierreihenfolge einer Tabelle.

(SETORDERSTR table order)

Setzt die Sortierreihenfolge der gegebenen Tabelle auf die Felder in der Zeichenkette order. Die Zeichenkette order kann entweder eine Liste von Feldnamen enthalten oder den Namen der Vergleichsfunktion.

Zum Sortieren einer Feldliste muß die Zeichenkette order die Feldnamen für die Sortierung enthalten, die durch eine beliebige Anzahl von Leerzeichen, Tabulatoren oder Neue-Zeile-Zeichen getrennt sind. Jedem Feldnamen kann ein `+' oder ein `-' für auf- bzw. absteigende Sortierung vorangestellt werden. Wird dieses Zeichen weggelassen, dann wird aufsteigende Sortierung angenommen.

Zum Sortieren anhand einer Vergleichsfunktion muß die Zeichenkette order den Namen der Funktion tragen.

SETORDERSTR liefert TRUE, wenn es möglich war, die neue Sortierung zu setzen, anderenfalls NIL, wenn z.B. ein unbekanntes Feld angegeben wurde oder das Typ des Feldes für die Sortierung nicht erlaubt ist. Wird NIL für order angegeben, dann passiert nichts und es wird NIL zurückgeliefert.

Hinweis: Zum Erzeugen der Sortierzeichenkette sollten man nicht direkt den Feldnamen in die Zeichenkette einfügen, weil bei einer Änderung des Feldnamens der Name in der Zeichenkette nicht mit verändert wird. Besser ist es, die Funktion ATTRNAME (siehe ATTRNAME) zu verwenden und dessen Ergebnis in die Sortierzeichenkette zu kopieren.

Beispiel

Man betrachte eine Tabelle `Person' mit den Feldern `Name', `Stadt' und `Geburtstag'. `(SETORDERSTR Person (SPRINTF "+%s" (ATTRNAME Person.Name)))' setzt dann die Sortierreihenfolge der Tabelle `Person' auf `Name' als (aufsteigendes) Sortierfeld.

Siehe auch GETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Sortieren, Comparison function.

REORDER

REORDER bringt alle unsortierten Datensätze zurück in die richtige Reihenfolge.

(REORDER table)

Untersucht alle Datensätze der gegebenen Tabelle nach unsortierten Datensätzen und fügt diese in ihrer korrekten Position ein. Nach dem Einfügen eines unsortierten Datensatzes wird der Sortierstatus des Datensatzes auf TRUE gesetzt, so daß bei nach Beendigung der Funktion REORDER der Sortierstatus aller Datensätze auf TRUE steht.

REORDER liefert NIL.

Normalerweise wird diese Funktion nur dann aufgerufen, wenn eine Vergleichsfunktion für die Sortierung der Tabelle definiert wurde. Sortierungen anhand einer Felderliste sind automatisch, das bedeutet, daß ein Datensatz automatisch sortiert wird, wenn er benötigt wird.

Für einen Anwendungsfall zur Anwendung dieser Funktion siehe Comparison function.

Siehe auch REORDERALL, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Sortieren, Comparison function.

REORDERALL

REORDERALL sortiert alle Datensätze einer Tabelle neu.

(REORDERALL table)

Sortiert alle Datensätze der gegebenen Tabelle neu, indem der Sortierstatus aller Datensätze auf NIL gesetzt und dann REORDER zum kompletten Neusortieren aufgerufen wird.

REORDERALL liefert NIL.

Siehe auch REORDER, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Sortieren, Comparison function.

GETFILTERACTIVE

GETFILTERACTIVE liefert den Filterstatus einer Tabelle.

(GETFILTERACTIVE table)

Liefert TRUE, wenn der Filter gegebenen Tabelle momentan aktiviert ist, anderenfalls NIL.

Siehe auch SETFILTERACTIVE, GETFILTERSTR, GETMATCHFILTER.

SETFILTERACTIVE

SETFILTERACTIVE setzt den Filterstatus einer Tabelle.

(SETFILTERACTIVE table bool)

Setzt den Filterstatus der gegebenen Tabelle. Ist bool nicht NIL, dann wird er Filter aktiviert, anderenfalls deaktiviert.

SETFILTERACTIVE liefert den neuen Status des Filters. Der neue Status muß nicht dem erwarteten entsprechen, falls beim Aktivieren des Filters ein Fehler auftrat und der Filter deshalb nicht aktiviert werden konnte. Deaktivieren des Filters gelingt jedoch immer..

Siehe auch GETFILTERACTIVE, SETFILTERSTR, SETMATCHFILTER.

GETFILTERSTR

GETFILTERSTR liefert den Datensatzfilterausdruck einer Tabelle.

(GETFILTERSTR table)

Liefert den Datensatzfilterausdruck der gegebenen Tabelle als Zeichenkette. Eine leere Zeichenkette bedeutet, daß kein Filterausdruck für diese Tabelle gesetzt wurde.

Siehe auch SETFILTERSTR, GETFILTERACTIVE, GETMATCHFILTER.

SETFILTERSTR

SETFILTERSTR setzt den Datensatzfilterausdruck einer Tabelle.

(SETFILTERSTR table filter-str)

Setzt den Datensatzfilterausdruck der gegebenen Tabelle auf den Ausdruck im Parameter filter-str(62). Ist der Filter der gegebenen Tabelle momentan aktiviert, dann wird der neue Filterausdruck sofort auf alle Datensätze angewendet und der Status der Filterübereinstimmung aller Datensätze neu berechnet.

SETFILTERSTR liefert TRUE, wenn es möglich war, den gegebenen Filterzeichenkettenausdruck zu kompilieren, anderenfalls wird NIL geliefert. Man beachte, daß man nur das Ergebnis der Kompilierung erhält. Ist der Filter der gegebenen Tabelle momentan aktiviert und das Neuberechnen aller Stati der Filterübereinstimmungen fehlschlägt, dann wird man nicht über das Ergebnis dieser Funktion informiert. Daher ist der empfohlene Weg, einen neuen Filterausdruck zu setzen, folgender:

(SETFILTERACTIVE Table NIL)               ; gelingt immer.
(IF (NOT (SETFILTERSTR Table filter-string))
    (ERROR "Kann den Filter für %s nicht setzen!" (TABLENAME Table))
)
(IF (NOT (SETFILTERACTIVE Table TRUE))
    (ERROR "Kann den Filter für %s nicht aktivieren!" (TABLENAME Table))
)

Wird SETFILTERSTR mit dem Wert NIL für den Parameter filter-str aufgerufen, dann passiert nichts und NIL wird zurückgeliefert.

Beispiel: `(SETFILTERSTR Table "(> Wert 0.0)")'.

Siehe auch GETFILTERSTR, SETFILTERACTIVE, SETMATCHFILTER.

RECORDS

RECORDS liefert die Anzahl der Datensätze in einer Tabelle.

(RECORDS table)

Liefert die Anzahl der Datensätze in der gegebenen Tabelle. Man kann einen Stern zum Tabellennamen hinzufügen, um die Anzahl der Datensätze zu ermitteln, die dem Filter der Tabelle genügen.

Siehe auch RECORD, RECNUM.

RECORD

RECORD liefert einen Datensatzzeiger für eine gegebene Datensatznummer.

(RECORD table num)

Liefert den Datensatzzeiger des num-ten Datensatzes in der gegebenen Tabelle oder NIL, wenn ein Datensatz mit dieser Nummer nicht existiert. Man kann einen Stern zum Tabellennamen hinzufügen, um den num-ten Datensatz zu erhalten, der dem Datensatzfilter genügt(63)'(64).

Es ist darauf zu achten, daß Datensatznummern bei 1 beginnen und die Datensatznummer 0 für den Vorgabedatensatz verwendet wird.

Siehe auch RECORDS, RECNUM.

SELECT

SELECT ermittelt und liefert diverse Daten von Datensätzen.

(SELECT [DISTINCT] exprlist FROM tablelist
        [WHERE where-expr] [ORDER BY orderlist])

wobei exprlist entweder ein einfacher Stern `*' oder eine Liste von durch Komma getrennten Ausdrücken mit optionalen Titeln ist:

exprlist:     * | expr "Titel", ...

und tablelist eine Liste von Tabellennamen:

tablelist:      table[*] [ident], ...

Für jede Tabelle in der Tabellenliste kann ein Identifier(65) Dies kann nützlich sein, wenn eine Tabelle mehr als einmal in der Tabellenliste vorkommt (siehe unten das Beispiel zum Vergleichen von Altersangaben). Wird ein Stern zum Tabellennamen hinzugefügt, dann werden nur die Datensätze der Tabelle betrachtet, die dem momentanen Filter der Tabelle genügen.

Die Sortierliste hat den folgenden Aufbau:

orderlist:    expr [ASC | DESC], ...

wobei expr, ... beliebige Ausdrücke oder Feldnummern sein können. Zum Beispiel sortiert `(SELECT Name FROM ... ORDER BY 1)' das Ergebnis nach dem Feld `Name'. Man kann zudem ASC oder DESC für eine auf- bzw. absteigende Sortierung angeben. Ist keiner der beiden vorhanden, dann wird aufsteigende Sortierung angenommen.

Wie es arbeitet

Die SELECT-FROM-WHERE-Abfrage bildet das (mathematische) Kreuzprodukt aller Tabellen in der Tabellenliste (es wertet alle Datensatzmengen in table, ... aus) und prüft den WHERE-Ausdruck (wenn vorhanden). Liefert der WHERE-Ausdruck TRUE (oder es gibt keinen WHERE-Ausdruck), dann wird eine Liste erzeugt, dessen Elemente anhand der Ausdrucksliste im SELECT-Teil berechnet wurden. Wurde ein einzelner Stern in der Ausdrucksliste angegeben, dann enthält die Liste die Werte aller Felder, die zu den Tabellen in der Tabellenliste gehören (hiervon ausgenommen sind die virtuellen Felder und Knöpfe).

Das Ergebnis der Abfrage ist eine Liste von Listen. Der erste Listeneintrag enthält die Titelzeichenketten, die restlichen die Werte der FROM-Liste für die passenden Datensätze.

Beispiele

Siehe Abfragebeispiele für einige Beispiele mit der Funktion SELECT.

Siehe auch FOR ALL.

Oberflächenfunktionen

Dieser Abschnitt beschreibt die Funktionen zum Verändern von Benutzeroberflächenelementen.

SETCURSOR

SETCURSOR setzt den Cursor auf ein Benutzeroberflächenelement.

(SETCURSOR attr-or-table)

Setzt den Cursor auf das gegebene Feld oder Benutzeroberflächenelement der Tabelle. Die Funktion öffnet auch das Fenster, in dem das Feld/die Tabelle eingebettet ist, wenn das Fenster noch geschlossen ist.

SETCURSOR liefert TRUE, wenn kein Fehler auftrat (Fenster konnte geöffnet werden) oder NIL bei einem Fehler.

GETDISABLED

GETDISABLED liefert den Inaktiv-Status eines Feldes.

(GETDISABLED attr)

Liefert den Inaktiv-Status des angegebenen Feldes im aktuellen Datensatz.

Siehe auch SETDISABLED, GETWINDOWDISABLED.

SETDISABLED

SETDISABLED setzt den Inaktiv-Status eines Feldes.

(SETDISABLED attr bool)

Setzt den Inaktiv-Status des angegebenen Feldes im aktuellen Datensatz auf den Wert von bool. Liefert den neuen Wert des Inaktiv-Status.

Siehe auch GETDISABLED, SETWINDOWDISABLED.

GETWINDOWDISABLED

GETWINDOWDISABLED liefert den Inaktiv-Status eines Fensters.

(GETWINDOWDISABLED attr-or-table)

Liefert den Status des Inaktiv-Flags für das Fenster, in dem das angegebene Feld oder die Tabelle eingebettet ist. Ist das Feld oder die Tabelle im Hauptfenster eingebettet, dann wird NIL geliefert(66).

Siehe auch SETWINDOWDISABLED, GETWINDOWOPEN, GETDISABLED.

SETWINDOWDISABLED

SETWINDOWDISABLED setzt den Inaktiv-Status eines Fensters.

(SETWINDOWDISABLED attr-or-table disabled)

Setzt den Status des Inaktiv-Flags des Fensters, in dem das angegebene Feld bzw. die Tabelle eingebettet ist, auf den Wert von disabled. Wenn man ein Fenster deaktiviert, dann wird das Fenster geschlossen und der dazugehörige Fensterknopf wird deaktiviert. Das Hauptfenster eines Projekts kann nicht deaktiviert werden.

SETWINDOWDISABLED liefert den neuen Inaktiv-Status des Fensters.

Siehe auch GETWINDOWDISABLED, SETWINDOWOPEN, SETDISABLED.

GETWINDOWOPEN

GETWINDOWOPEN liefert den Geöffnet-Status eines Fensters.

(GETWINDOWOPEN attr-or-table)

Liefert den Geöffnet-Status des Fensters, in dem das Feld bzw. die Tabelle eingebettet ist.

Siehe auch SETWINDOWOPEN, GETWINDOWDISABLED.

SETWINDOWOPEN

SETWINDOWOPEN öffnet und schließt ein Fenster.

(SETWINDOWOPEN attr-or-table open)

Öffnet oder schließt das Fenster, in dem das gegebenen Feld bzw. die gegebenen Tabelle eingebettet ist. ist open nicht NIL, dann wird das Fenster geöffnet, anderenfalls wird es geschlossen. Das Hauptfenster eines Projekts kann nicht geschlossen werden.

SETWINDOWOPEN liefert den neuen Geöffnet-Status des Fensters.

Siehe auch GETWINDOWOPEN, SETWINDOWDISABLED.

Projektfunktionen

Dieser Abschnitt listet Funktionen auf, die mit Projekten zu tun haben.

PROJECTNAME

PROJECTNAME liefert den Projektnamen.

(PROJECTNAME)

PROJECTNAME liefert den Namen des aktuellen Projekts als Zeichenkette oder NIL, wenn noch kein Name definiert wurde.

Siehe auch CHANGES.

CHANGES

CHANGES liefert die Anzahl der bisher gemachten Änderungen am aktuellen Projekt.

(CHANGES)

Liefert eine Ganzzahl mit der Anzahl der Änderungen seit der letzten Speicherung des aktuellen Projekts.

Siehe auch PROJECTNAME.

Systemfunktionen

Dieser Abschnitt listet Funktionen auf, die auf das Betriebssystem zugreifen.

EDIT

EDIT startet den externen Editor.

(EDIT filename)

Startet den externen Editor zum Bearbeiten der gegebenen Datei. Der externen Editor kann unter dem Menüpunkt `Einstellungen - Externen Editor setzen' (siehe Externer Editor) eingestellt werden. EDIT starten den externen Editor asynchron, das bedeutet, die Funktion kehrt sofort wieder zurück (und wartet nicht auf das Ende des Editors).

EDIT liefert TRUE, wenn der Editor erfolgreich gestartet werden konnte, anderenfalls NIL.

Siehe auch EDIT*, VIEW, SYSTEM.

EDIT*

EDIT* ist die Version von EDIT mit dem Stern und hat den selben Effekt wie EDIT (siehe EDIT). Der einzige Unterschied ist, daß EDIT* den externen Editor synchron startet und wartet, bis der Benutzer den Editor verlassen hat.

Siehe auch EDIT, VIEW*, SYSTEM.

VIEW

VIEW startet den externen Anzeiger.

(VIEW filename)

Startet den externen Anzeiger zum Anzeigen der gegebenen Datei. Der externen Anzeiger kann unter dem Menüpunkt `Einstellungen - Externen Anzeiger setzen' (siehe Externer Anzeiger) eingestellt werden. VIEW starten den externen Anzeiger asynchron, das bedeutet, die Funktion kehrt sofort wieder zurück (und wartet nicht auf das Ende des Anzeigers).

VIEW liefert TRUE, wenn der Anzeiger erfolgreich gestartet werden konnte, anderenfalls NIL.

Siehe auch VIEW*, EDIT, SYSTEM.

VIEW*

VIEW* ist die Version von VIEW mit dem Stern und hat den selben Effekt wie VIEW (siehe VIEW). Der einzige Unterschied ist, daß VIEW* den externen Anzeiger synchron startet und wartet, bis der Benutzer den Anzeiger verlassen hat.

Siehe auch VIEW, EDIT*, SYSTEM.

SYSTEM

SYSTEM ruft ein externes Programm auf.

(SYSTEM fmt [arg ...])

Ruft ein externes Programm auf. Die Befehlszeile zum Programmaufruf wird aus fmt und den optionalen Parametern wie in der Funktion SPRINTF (siehe SPRINTF) erzeugt. SYSTEM wartet, bis das aufgerufene Programm beendet wurde. Wenn nicht gewünscht ist, daß SYSTEM warten soll, dann benutzt man eine Befehlszeile, die das Programm im Hintergrund startet.

SYSTEM liefert bei Erfolg TRUE, anderenfalls NIL, wenn z.B. die Befehlszeile nicht ausgeführt werden konnte oder der aufgerufene Befehl einen Fehlercode lieferte.

Beispiel: `(SYSTEM "run %s %s" "clock" "digital")' startet die Systemuhr mit Digitalmodus als Hintergrundprozeß.

Siehe auch EDIT, EDIT*, VIEW, VIEW*.

STAT

STAT untersucht eine Datei.

(STAT filename)

Untersucht, ob der angegebene Dateiname im Dateisystem existiert. STAT liefert NIL, wenn der Dateiname nicht gefunden werden konnte; 0, wenn der Dateiname existiert und ein Verzeichnis ist, und eine Ganzzahl größer 0, wenn der Dateiname existiert und eine gültige Datei ist(67)

TACKON

TACKON erzeugt einen Pfadnamen.

(TACKON dirname filename)

Verknüpft dirname und filename zu einem Pfadnamen. TACKON weiß, wie es mit Doppelpunkten und Schrägstrichen (Slashes) in dirname umzugehen hat. Es liefert den Pfadnamen als Zeichekette oder NIL, wenn dirname oder filename NIL ist.

Beispiel: `(TACKON "Sys:System" "CLI")' liefert "Sys:System/CLI".

Siehe auch FILENAME, DIRNAME.

FILENAME

FILENAME extrahiert den Dateinamen aus einem Pfadnamen.

(FILENAME path)

Extrahiert die letzte Komponente eines gegebenen Pfadnamens. Es wird nicht geprüft, ob die letzte Komponente momentan auf eine Datei verweist, so daß es auch möglich ist, FILENAME zu verwenden, um den Namen eines Unterverzeichnisses zu erhalten. FILENAME liefert sein Ergebnis als Zeichenkette oder NIL, wenn path NIL ist.

Beispiel: `(FILENAME "Sys:System/CLI")' liefert "CLI".

Siehe auch DIRNAME, TACKON.

DIRNAME

DIRNAME extrahiert den Verzeichnis-Teil eines Pfadnamens.

(DIRNAME path)

Extrahiert den Verzeichnis-Teil des gegebenen Pfadnamens. Es wird nicht geprüft, ob path momentan auf eine Datei verweist, so daß es auch möglich ist, DIRNAME zu verwenden, um den Namen eines übergeordneten Verzeichnisses zu erhalten. DIRNAME liefert sein Ergebnis als Zeichenkette oder NIL, wenn path NIL ist.

Beispiel: `(DIRNAME "Sys:System/CLI")' liefert "Sys:System".

Siehe auch FILENAME, TACKON.

TODAY

TODAY liefert das heutige Datum.

(TODAY)

Liefert das heutige Datum als Datumswert.

Siehe auch NOW.

NOW

NOW liefert die aktuelle Uhrzeit.

(NOW)

Liefert die aktuelle Uhrzeit als Zeitwert.

Siehe auch TODAY.

MESSAGE

MESSAGE gibt eine Meldung für den Benutzer aus.

(MESSAGE fmt [arg ...])

Setzt den Fenstertitel des Pause/Abbrechen-Fensters (wenn es geöffnet ist). Die Titelzeichenkette wird aus fmt und den optionalen Parametern wie in der Funktion SPRINTF (siehe SPRINTF) erzeugt.

MESSAGE liefert die formatierte Titelzeichenkette.

Beispiel: `(MESSAGE "6 * 7 = %i" (* 6 7))'.

Siehe auch PRINT, PRINTF.

GC

GC erzwingt das Aufräumen des Speichers(68).

(GC)

Erzwingt das Aufräumen des Speichers und liefert NIL. Im Normalfall wird das Aufräumen automatisch von Zeit zu Zeit durchgeführt.

Vordefinierte Variablen

MUIbase kennt einige vordefinierte globale Variablen.

Momentan existiert nur eine einzige globale Variable: stdout (siehe stdout).

Vordefinierte Konstanten

Die folgenden vordefinierten Konstanten können in jedem Ausdruck bei der Programmierung verwendet werden:

Name            Typ             Wert            Bemerkung
-------------------------------------------------------------------------
NIL             jeder           NIL
TRUE            bool            TRUE
RESET           Zeichenkette    "\33c"
NORMAL          Zeichenkette    "\33[0m"
ITON            Zeichenkette    "\33[3m"
ITOFF           Zeichenkette    "\33[23m"
ULON            Zeichenkette    "\33[4m"
ULOFF           Zeichenkette    "\33[24m"
BFON            Zeichenkette    "\33[1m"
BFOFF           Zeichenkette    "\33[22m"
ELITEON         Zeichenkette    "\33[2w"
ELITEOFF        Zeichenkette    "\33[1w"
CONDON          Zeichenkette    "\33[4w"
CONDOFF         Zeichenkette    "\33[3w"
WIDEON          Zeichenkette    "\33[6w"
WIDEOFF         Zeichenkette    "\33[5w"
NLQON           Zeichenkette    "\33[2\"z"
NLQOFF          Zeichenkette    "\33[1\"z"
INT_MAX         Ganzzahl        2147483647      Größter Ganzzahlwert 
INT_MIN         Ganzzahl        -2147483648     Kleinster Ganzzahlwert
HUGE_VAL        Fließkommazahl  1.797693e+308   Größte absolute Fließkommazahl
PI              Fließkommazahl  3.14159265359
OSVER           Ganzzahl        <OS-Version>
OSREV           Ganzzahl        <OS-Revision>
MBVER           Ganzzahl        <MUIbase-Version>
MBREV           Ganzzahl        <MUIbase-Revision>
LANGUAGE        Zeichenkette    hängt von der lokalen Sprache ab
SEEK_SET        Ganzzahl        siehe stdio.h     Suche vom Beginn der Datei.
SEEK_CUR        Ganzzahl        siehe stdio.h     Suche von aktueller Position.
SEEK_END        Ganzzahl        siehe stdio.h     Suche vom Ende der Datei.

Siehe Konstanten für weitere Informationen über Konstanten. Zum Definieren eigener Konstanten benutzt man die Preprozessor-Anweisung #define (siehe #define).

Funktionale Parameter

Es ist möglich, eine Funktion als einen Parameter an eine andere Funktion zu übergeben. Dies ist nützlich für die Definition von übergeordneten Funktionen, wie z.B. zum Sortieren oder Abbilden einer Liste.

Um eine Funktion auzurufen, die als Parameter übergeben wurde, muß die Funktion FUNCALL (siehe FUNCALL) verwendet werden.

Beispiel:

(DEFUN map (l fun)              # Parameter: Liste und Funktion
    (LET (res)                  # lokale Variable res, vorbelegt mit NIL
        (DOLIST (i l)           # jedes Element der Reihe nach
            (SETQ res
                (CONS (FUNCALL fun i) res)       # Funktion anwenden und
            )                                    # neue Liste erzeugen
        )
        (REVERSE res)           # die Liste muß nun umgekehrt werden
    )
)

Jetzt kann diese Abbildefunktion zum Beispiel verwendet werden, um alle Elemente einer Liste mit Ganzzahlen um 1 zu erhöhen:

`(map (LIST 1 2 3 4) 1+)' liefert ( 2 3 4 5 ).

Siehe auch FUNCALL, MAPFIRST.

Typdeklarierer

Es ist möglich, den Typ einer lokalen Variable durch Anfügen eines Typdeklarierers hinter dem Namen festzulegen. Die folgenden Typdeklarierer existieren:

Deklarierer Beschreibung

:INT        für Ganzzahlen
:REAL       für Fließkommazahlen
:STR        für Zeichenketten
:MEMO       für mehrzeilige Zeichenketten
:DATE       für Datumswerte
:TIME       für Zeitwerte
:LIST       für Listen
:FILE       für Dateihandler
:FUNC       für Funktionen jedes Typs
:table      für Datensatzzeiger auf table

Der Typdeklarierer wird an den Variablennamen wie im folgenden Beispiel angehängt:

(LET (x:INT (y:REAL 0.0) z) ...)

Das Beispiel definiert drei neue Variablen `x', `y' und `z', wobei `x' vom Typ Ganzzahl ist und mit NIL vorbelegt wird, `y' vom Typ Fließkommazahl ist und mit 0.0 vorbelegt wird, und `z' eine Variable ohne Typ ist, die mit NIL vorbelegt wird.

Der Vorteil von Typspezifizierern ist, daß der Compiler mehr Typfehler entdecken kann, z.B. wenn eine Funktion

(DEFUN foo (x:INT) ...)

definiert ist und sie mit `(foo "bar")' aufgerufen wird, dann erzeugt der Compiler eine Fehlermeldung. Wird `foo' jedoch mit einem Wert ohne Typ aufgerufen, z.B. `(foo (FIRST list))', dann kann keine Fehlerprüfung durchgeführt werden, da zum Zeitpunkt des Kompilierens der Typ von `(FIRST list)' nicht bekannt ist.

Aus Geschwindigkeitsgründen wird beim Programmlauf keine Typüberprüfung durchgeführt. Es könnte eingebaut werden, aber dies würde eine kleine Verlangsamung bewirken, die nicht wirklich notwendig ist, da ein falscher Typ früher oder später in einem Typfehler endet.

Typdeklarierer für Datensatzzeiger haben eine andere nützliche Eigenschaft. Wird eine Variable als Datensatzzeiger auf eine Tabelle belegt, dann kann auf alle Felder dieser Tabelle mit dem Variablennamen statt des Tabellennamens im Feldpfad zugegriffen werden. Hat man z.B. eine Tabelle `Foo' mit einem Feld `Bar' und man definiert eine Variable `foo' als

(LET (foo:Foo)

dann kann man das Feld `Bar' des dritten Datensatzes mit

(SETQ foo (RECORD Foo 3)) (PRINT foo.Bar)

ausgeben.

Zu beachten ist in Select-from-where Ausdrücken, daß die Variablen in der FROM-Liste automatisch vom Typ des Datensatzzeigers des zugeordneten Tabelle sind.

Aufbau von Ausdrücken

Der Aufbau von Ausdrücken ist von sehr großer Bedeutung, um zu verstehen, was ein Programm tut.

Dieser Abschnitt bescheibt die Semantik, abhängig vom Aufbau der Ausdrücke:

(func [expr ...])
Errechnet expr ... und ruft dann die Funktion func (Aufruf mit Wert) auf. Liefert den Rückgabewert der aufgerufenen Funktion. In MUIbase gibt es einige nicht-strikte Funktionen, z.B. AND, OR und IF. Diese Funktionen müssen nicht zwingend alle Ausdrücke errechnen. Mehr zu nicht-strikten Funktionen, siehe Lisp-Aufbau, AND, OR, and IF.
([expr ...])
Errechnet expr ... und liefert den Wert des letzten Ausdrucks (siehe PROGN). Ein leerer Ausdruck () wird zu NIL.
Table
Liefert den Programmdatensatzzeiter der gegebenen Tabelle.
Table*
Liefert den Datensatzzeiger der Benutzeroberfläche von der gegebenen Tabelle.
AttrPath
Liefert den Inhalt des gegebenen Feldes. Der Feldpfad legt fest, welcher Datensatz verwendet wird, aus dem der Feldinhalt geholt wird. Zum Beispiel benutzt `Table.Attribute' den Programmdatensatzzeiger von `Table', um den Wert des Feldes zu ermitteln; `Table.ReferenceAttribute.Attribute' verwendet den Programmdatensatzzeiger von `Table', um den Wert des Beziehungsfeldes zu ermitteln (der ein Datensatzzeiger ist) und verwendet diesen Datensatz, um den Wert von `Attribute' zu erhalten.
localvar
Liefert den Inhalt der lokalen Variable. Lokale Variablen können mit z.B. LET (siehe LET) definiert werden.
localvar.AttrPath
Verwendet den Datensatzzeiger von localvar, um den Wert des gegebenen Feldes zu ermitteln.

Auslösefunktionen

Zum automatischen Ausführen von MUIbase-Programmen können Auslösefunktionen für Projekte, Tabellen und Felder festgelegt werden, wie in bestimmten Fällen aufgerufen werden. Dieser Abschnitt bescheibt alle vorhandenen Auslösemöglichkeiten.

onOpen

Nach dem Öffnen eines Projekts durchsucht MUIbase das Programm des Projekts nach einer Funktion mit dem Namen onOpen. Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen.

Beispiel

(DEFUN onOpen ()
    (ASKBUTTON NIL "Danke für das Öffnen!" NIL NIL)
)

Siehe auch onClose, onChange, Beispielprojekt `Trigger.mb'.

onClose

Bevor ein Projekt geschlossen wird, durchsucht MUIbase das Programm des Projekts nach einer Funktion mit dem Namen onClose. Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen. In der jetzigen Version wird der Rückgabewert der Funktion ignoriert und das Projekt unabhängig vom Rückgabewert geschlossen.

Wurden in der Funktion onClose Änderungen am Projekt durchgeführt, dann fragt MUIbase nach, ob das Projekt zuerst gespeichert werden soll, bevor das Projekt geschlossen wird. Wird der Menüpunkt `Projekt - Speichern & Schließen' zum Schließen des Projekts aufgerufen, dann wird die Auslösefunktion aufgerufen, bevor das Projekt gespeichert wird, so daß die Änderungen automatisch gespeichert werden.

Beispiel

(DEFUN onClose ()
    (ASKBUTTON NIL "Auf Wiedersehen!" NIL NIL)
)

Siehe auch onOpen, onChange, Beispielprojekt `Trigger.mb'.

onChange

Wann immer der Benutzer eine Änderung am Projekt durchführt oder nach dem Speichern eines Projekts, durchsucht MUIbase das Programm des Projekts nach einer Funktion mit dem Namen onChange. Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen. Dies kann verwendet werden, um die Anzahl der Änderungen zu erfassen, die ein Benutzer an diesem Projekt durchgeführt hat.

Beispiel

(DEFUN onChange ()
    (SETQ Control.NumChanges (CHANGES))
)

Im obigen Beispiel könnte `Control.NumChanges' ein virtuelles Feld sein, das in einer `Nur-ein-Datensatz'-Tabelle zum Anzeigen der Anzahl von Projektänderungen verwendet wird.

Siehe auch onOpen, onClose, Beispielprojekt `Trigger.mb'.

Auslösefunktion Neu

Sobald der Benutzer einen neuen Datensatz durch Auswählen der Menüpunkte `Neuer Datensatz' oder `Datensatz kopieren' anlegen möchte und die Auslösefunktion `Neu' für diese Tabelle auf eine MUIbase-Funktion gesetzt wurde, dann wird diese Auslösefunktion ausgeführt. Die Auslösefunktion für `Neu' kann im Tabellenfenster (siehe Tabellen erstellen) gesetzt werden.

Die Auslösefunktion erhält NIL oder einen Datensatzzeiger als ersten und einzigen Parameter. NIL bedeutet, daß der Benutzer einen neuen Datensatz anlegen möchte und ein Datensatzzeiger zeigt an, daß der Benutzer einen Datensatz eine Kopie dieses Datensatzes anlegen will. Hat die Auslösefunktion mehr als einen Parameter, dann werden diese mit NIL vorbelegt. Die Auslösefunktion sollte nun einen neuen Datensatz mit NEW (siehe NEW) anlegen. Der Rückgabewert der Auslösefunktion wird ausgewertet. Ist er ein Datensatzzeiger, dann wird dieser Datensatz angezeigt.

Die Auslösefunktion `Neu' wird auch aufgerufen, wenn ein MUIbase-Programm die Funktion NEW* (siehe NEW*) aufruft.

Beispiel einer Auslösefunktion Neu

(DEFUN newRecord (init)
    (PROG1                      ; zum Rückgeben des Ergebnisses von NEW
        (NEW Table init)
        ...
    )
)

Siehe auch NEW*, Auslösefunktion Löschen.

Auslösefunktion Löschen

Sobald der Benutzer einen Datensatz durch Auswählen des Menüpunkts `Datensatz löschen' löschen möchte und die Auslösefunktion `Löschen' für diese Tabelle auf eine MUIbase-Funktion gesetzt wurde, dann wird diese Auslösefunktion ausgeführt. Die Auslösefunktion für `Löschen' kann im Tabellenfenster (siehe Tabellen erstellen) gesetzt werden.

Die Auslösefunktion erhält einen booleschen Parameter als einzigen Parameter. Ist er nicht NIL, dann sollte die Funktion nachfragen, ob der Benutzer wirklich diesen Datensatz löschen möchte. Wenn er es möchte, dann sollte die Funktion DELETE (siehe DELETE) zum Löschen des Datensatzes aufrufen.

Die Auslösefunktion `Delete' wird auch aufgerufen, wenn ein MUIbase-Programm die Funktion DELETE* (siehe DELETE*) aufruft..

Beispiel einer Auslösefunktion Löschen

(DEFUN deleteRecord (requester)
    (DELETE Table requester)
)

Siehe auch DELETE*, Auslösefunktion Neu.

Comparison function

Um eine Sortierung von Datensätzen einer Tabelle zu definieren, kann eine Vergleichsfunktion verwendet werden, die zwei Datensatzzeiger als Argumente erhält und eine Ganzzahl zurückliefert, die das Sortierverhältnis der beiden Datensätze anzeigt. Die Vergleichsfunktion sollte einen Wert kleiner 0 liefern, wenn ihr erstes Argument kleiner ist als das zweite; 0, wenn sie gleich sind und einen Wert größer 0, wenn das erste Argument größer ist als das zweite.

Angenommen, man hat eine Tabelle `Persons' mit dem Zeichenkettenfeld `Name', dann könnte man folgende Funktion zum Vergleich zweier Datensätze verwenden:

(DEFUN cmpPersons (rec1:Persons rec2:Persons)
    (CMP rec1.Name rec2.Name)
)

Dies wird alle Datensätze bezüglich dem Feld `Name' sortieren, wobei Zeichengrößen unterschieden werden. Anzumerken ist, daß Sortieren anhand einer Felderliste nicht das gleiche Ergebnis liefert, da der Zeichenkettenvergleich zeichengrößenunabhängig durchgeführt wird.

Mit einer Vergleichsfunktion lassen sich sehr komplexe Sortierungen definieren. Man achte jedoch darauf, keine rekursiven Funktionsaufrufe zu erzeugen, die sich selbst aufrufen. MUIbase wird seine Programmausführung anhalten und dies mit einer Fehlermeldung quittieren, sollte so etwas versucht werden. Auch sollten keine Befehle verwendet werden, die Seiteneffekte erzeugen könnten, wie z.B. einen Wert einem Feld zuweisen.

Wird eine Vergleichsfunktion verwendet, dann weiß MUIbase nicht immer, wann es die Datensätze neu zu sortieren hat. Nehmen wir im obigen Beispiel zusätzlich an, daß es die Tabelle `Toys' mit dem Zeichenkettenfeld `Name' und das Beziehungsfeld `Owner' gibt, das auf `Persons' verweist. Zudem nehmen wir folgende Vergleichsfunktion an:

(DEFUN cmpToys (rec1:Toys rec2:Toys)
    (CMP* rec1.Owner rec2.Owner)
)

Diese Funktion verwendet die Sortierung von `Persons', um die Sortierung der Datensätze festzustellen, so daß die Datensätze von `Toys' analog der Sortierung von `Persons' sortiert sind.

Ändert nun der Benutzer einen Datensatz in der Tabelle `Persons' und dieser Datensatz erhält eine neue Position, dann müßten auch Datensätze in `Toys' neu sortiert werden, die auf diesen Datensatz verweisen. MUIbase kennt jedoch diese Abhängigkeit nicht.

Neben der Verwendung des Menüpunktes `Tabelle - Alle Datensätze neu sortieren' auf die Tabelle `Toys' zum Neusortieren kann auch ein automatisches Neusortieren implementiert werden, indem folgende Auslösefunktion für das Feld `Name' der Tabelle `Persons' festgelegt wird:

(DEFUN setName (newValue)
    (SETQ Persons.Name newValue)
    (FOR ALL Toys WHERE (= Toys.Owner Persons) DO
        (SETISSORTED Toys NIL) 
    )
    (REORDER Toys)
)

Diese Funktion löscht die Sortierzustände aller Datensätze, die auf den aktuellen Datensatz der Tabelle `Persons' verweisen und sortiert anschließend alle unsortierten Datensätze der Tabelle `Toys'.

Siehe auch Sortieren, GETISSORTED, SETISSORTED, REORDER, REORDERALL, GETORDERSTR, SETORDERSTR, Demo `Order.mb'.

Auslösefunktion Feld

Im Feldfenster (siehe Felder erstellen) kann eine Auslösefunktion definiert werden, die immer dann aufgerufen wird, denn der Benutzer den Inhalt des Feldes ändern möchte.

Wurde eine solche Auslösefunktion definiert und der Benutzer ändert den Wert dieses Feldes, dann wird der Datensatzinhalt nicht automatisch auf den neuen Wert gesetzt. Stattdessen wird der Wert als erster Parameter an die Auslösefunktion übergeben. Die Auslösefunktion kann nun den Wert überprüfen und ihn ablehnen. Um den Wert im Datensatz zu speichern, muß die Funktion SETQ verwendet werden.

Die Auslösefunktion sollte das Ergebnis des SETQ-Aufrufs (siehe SETQ) oder den alten Wert des Feldes, wenn sie den neuen Wert abzulehnt, zurückgeben.

Die Auslösefunktion wird auch ausgeführt, wenn ein MUIbase-Programm die Funktion SETQ* (siehe SETQ*) zum Setzen eines Feldwertes aufruft.

Beispiel einer Auslösefunktion Feld

(DEFUN setAmount (amount)
    (IF some-expression
        (SETQ Table.Amount amount)
        (ASKBUTTON NIL "Ungültiger Wert!" NIL NIL)
    )
    Table.Amount                        ; liefert momentanen Wert zurück
)

Siehe auch SETQ*

Virtuelle Felder programmieren

In MUIbase sind virtuelle Felder besondere Felder, die ihren Inhalt nebenbei berechnen, wenn er benötigt wird. Wird z.B. zu einem anderen Datensatz gewechselt, indem man auf einen der Pfeile in der Panelleiste einer Tabelle klickt und ein virtuelles Feld in dieser Tabelle das Flag `Sofort' (siehe Feldobjekteditor) gesetzt hat, dann wird der Wert dieses Feldes berechnet und dargestellt. Zum Berechnen des Wertes wird die Auslösefunktion `Berechne' des Feldes aufgerufen. Diese Auslösefunktion kann im Feldfenster (siehe Typabhängige Einstellungen (69)). festgelegt werden. Der Rückgabewert dieser Funktion definiert den Wert des virtuellen Feldes. Wurde keine `Berechne'-Auslösefunktion für ein virtuelles Feld festgelegt, dann ist der Wert des Feldes NIL.

Man kann auch die Berechnung eines virtuellen Feldes auslösen, indem man einfach in einem MUIbase-Programm darauf zugreift, so daß man z.B. auf Knopfdruck zum Berechnen des Wertes eines virtuellen Feldes wie im folgenden nur eine Funktion für den Knopf festlegen muß:

(DEFUN buttonHook ()
    virtual-attr
)

Man kann auch den virtuellen Wert auf jeden Wert setzen, indem man die Funktion SETQ verwendet:

(SETQ virtual-attr expr)

Wird jedoch nach dem SETQ-Aufruf auf das virtuelle Feld zugegriffen, dann wird der Wert des virtuellen Feldes neu berechnet.

Der Wert eines virtuellen Feldes wird nicht zwischengespeichert, da nicht einfach festzustellen ist, wann der Wert neu berechnet werden muß und wann nicht. Daher sollte man auf virtuelle Felder möglichst sparsam zugreifen und den Wert in lokalen Variablen für die weitere Verwendung selbst zwischenspeichern.

Für ein Beispiel, wie virtuelle Felder benutzt werden, sehe man sich das Beispielprojekt `Movie.mb' an.

Siehe auch virtuelles Feld, Beispielprojekt `Movie.db'.


Go to the first, previous, next, last section, table of contents.