917 lines
38 KiB
Plaintext
917 lines
38 KiB
Plaintext
MACROS(IQL) DABA16 MACROS(IQL)
|
|
|
|
NAME
|
|
macros - Makro-Unterstuetzung des Terminal-Monitors
|
|
|
|
BESCHREIBUNG
|
|
|
|
Die Makro-Unterstuetzung zusammen mit der Terminal-Monitor-
|
|
Kommando-Unterstuetzung und dem DBBS (QL-Sprache) bieten
|
|
die Moeglichkeit, neue Eingabe-Nutzungs-Interfaces
|
|
(Benutzungsoberflaechen) zu erstellen.
|
|
|
|
Die Makro-Unterstuetzung ist integrierter Bestandteil des
|
|
Terminal-Monitors und besteht aus dem Makro-Prozessor und
|
|
den bereitgestellten System-Makros.
|
|
|
|
Durch die Verwendung von Makros, die vom Nutzer definiert
|
|
(in der Makro-Tabelle gespeichert) wurden, entfernt der
|
|
Makro-Prozessor Zeichenketten aus dem Eingabetext und er-
|
|
setzt diese durch anderen oder keinen Text (Makro-
|
|
Transformation) wobei durch Funktions-Makros ausgeloeste
|
|
Funktionen ausgefuehrt werden koennen. Es ist letztlich das
|
|
Ziel, den Ausgabetext des Makro-Prozessors in Form von QL-
|
|
Anweisungen dem DBBS zur Ausfuehrung zu uebergeben.
|
|
|
|
Das Ersetzen von Eingabetext wird als Substitution bezeich-
|
|
net. Makros, die dies ausfuehren werden Substitutions-
|
|
Makros genannt.
|
|
|
|
Makros, die neben einer Substitution eine bestimmte Funktio-
|
|
nen ausfuehren, werden als Funktions-Makros bezeichnet und
|
|
ausschlisslich durch das System zur Nutzung durch den Anwen-
|
|
der bereitgestellt (System-Funktions-Makros oder kurz
|
|
Funktions-Makros). Sie sind nach dem Start des Terminal-
|
|
Monitors in der Makro-Tabelle versteckt definiert (vordefi-
|
|
niert). Mit ihnen koennen Nutzer-Makros definiert (in der
|
|
Makro-Tabelle gespeichert) und Substitutions-Makros aus der
|
|
Makro-Tabelle entfernt werden. Ausserdem sind u.a. Ein- und
|
|
Ausgaben von Text, Vergleichsoprationen, die Bildung von
|
|
Teil-Zeichenketten und das Anzeigen der Werte der Makros der
|
|
Makro-Tabelle moeglich.
|
|
|
|
Darueber hinaus gibt es vom System bereitgestellte System-
|
|
Substitutions-Makros. Ein Teil der System-Substitutions-
|
|
Makros wird immer ausschliesslich durch den Monitor defi-
|
|
niert. Ein anderer Teil kann in Quellfom durch einen Nutzer
|
|
in Files bereitgestellt und beim Start des Monitors durch
|
|
diesen definiert oder vom Nutzer direkt definiert werden.
|
|
Ein weiterer Teil wird erst nach bestimmten Funktionen durch
|
|
den Monitor definiert und somit nutzbar.
|
|
|
|
Dem Anwender ist es nur gestattet, Substitutions-Makros
|
|
(keine Funktions-Makros) zu definieren!
|
|
|
|
Arbeitsweise des Makro-Prozessors
|
|
|
|
Vor einer Aktion zergliedert der Makro-Prozessor den Ein-
|
|
gabetext in Woerter. Er unterscheidet als Worte Bezeichner,
|
|
Zahlen und Operatoren. Ausserdem gibt es fuer den Makro-
|
|
Prozessor Standardbegrenzer (Blank, Tabulator- und Newline-
|
|
Zeichen) sowie Sonderzeichen.
|
|
|
|
Bezeichner sind eine unmittelbare Folge von Gross- oder
|
|
Kleinbuchstaben sowie dem Unterstreichungszeichen und Zif-
|
|
fern, beginnend mit einem Buchstaben oder Unterstrich.
|
|
|
|
Zahlen sind eine unmittbare Folge von Ziffern, einschliess-
|
|
lich eines Dezimalpunktes inmitten oder am Ende.
|
|
|
|
Operatoren sind alle Zeichen, die nicht in Bezeichnern oder
|
|
Zahlen verwendet werden duerfen und nicht Standardbegrenzer
|
|
oder Sonderzeichen sind.
|
|
|
|
|
|
|
|
Als Wortwechsel wird die Position bezeichnet, an der das
|
|
vorangehende Wort endet. Es ist i.allg. beendet, wenn dem
|
|
Wort ein Standardbegrenzer (Blank, Tab- oder Newline-
|
|
Zeichen) oder ein Zeichen eines anderen Worttypes folgt.
|
|
|
|
Basiskonzepte
|
|
|
|
Alle in der Makro-Tabelle gespeicherten Makros bestehen aus
|
|
zwei Teilen, dem Template und dem Replacement. Der
|
|
Template-Teil definiert, wann der Makro aufgerufen und damit
|
|
abgearbeitet wird.
|
|
|
|
Er besteht aus einem Schluesselwort, dem Schluesselwoerter,
|
|
Parameterdefinitionen und Symbole fuer Gruppen von Begren-
|
|
zern folgen koennen.
|
|
|
|
Das erste und weitere folgende Schluesselwoerter (ohne Para-
|
|
meter dazwischen) bilden den Namen des Makros.
|
|
|
|
Die Parameterdefinitionen werden den Woertern des Eingabe-
|
|
textes zugeordnet, die die entsprechende Stellung zu den
|
|
Schluesselwoertern besitzen. Diese Woerter stellen die ak-
|
|
tuellen Werte der Parameter dar.
|
|
|
|
|
|
Die Begrenzersymbole im Template-Teil bezeichnen Gruppen von
|
|
Begrenzern (i.allg. Wortwechsel oder Standarbegrenzer), die
|
|
zwischen Schluesselwoertern und Parameterwerten im Eingabe-
|
|
text auftreten duerfen, wenn das Makro abzuarbeiten ist.
|
|
|
|
Der Replacement-Teil besteht aus Woertern, Parameterreferen-
|
|
zen und Standardbegrenzern. Bei der Ausfuehrung eines Ma-
|
|
kros werden im Replacement-Teil eventuell vorhandene Parame-
|
|
terreferenzen durch die konkreten Parameterwerte ersetzt,
|
|
wobei die Komponenten und ihre Reihenfolge erhalten bleiben.
|
|
Der so entstandene Text wird als Wert des Makros bezeichnet,
|
|
der auch den Wert einer leeren Zeichenkette annehmen kann.
|
|
|
|
Die Analyse des Eingabetextes durch den Makro-Prozessor er-
|
|
folgt von links nach rechts. Die Position im Text, an der
|
|
das jeweils aktuelle Schluesselwort beginnt, heisst Analyse-
|
|
position. Ab der Analyseposition wird die folgende Konstruk-
|
|
tion mit allen Template-Teilen der Makro-Tabelle (ein-
|
|
schliesslich der spezifizierten Begrenzer) verglichen.
|
|
|
|
War der Vergleich erfolgreich, ersetzt der Wert des entspre-
|
|
chenden Makros den Eingabetext, wobei durch Funktions-Makros
|
|
neben einer Substitution auch eine Funktion ausgefuehrt wer-
|
|
den kann.
|
|
|
|
Sind bei einer Substitution mehrere Makros der Makro-Tabelle
|
|
zutreffend, wird das zuletzt definierte Makro verarbeitet.
|
|
|
|
Die Analyseposition rueckt erst weiter, wenn kein weiterer
|
|
positiver Vergleich des nun an der Analyseposition modifi-
|
|
zierten Textes mehr eintritt.
|
|
|
|
Da durch diese Arbeitsweise endlose Zyklen auftreten koennen
|
|
erfolgt nach 100 Durchlaeufen ein Abbruch.
|
|
|
|
Beispielsweise veranlasst der Template-Teil "ret" den Makro
|
|
gleichen Namens aufzurufen, wenn das Wort "ret" (i.allg. be-
|
|
grenzt durch einen Wortwechsel oder beliebig viele Standard-
|
|
begrenzer) im Eingabestrom auftritt. Bei einem solchen Zu-
|
|
treffen eines Makros wird der Template-Teil im Text entfernt
|
|
und durch den Replacement-Teil ersetzt. Bei einem
|
|
Replacement-Teil von z.B. "retrieve" fuer den "ret"-Makro
|
|
wuerde jedes Auftreten des Wortes "ret" im Text durch das
|
|
Wort "retrieve" ersetzt werden. Die Anweisung
|
|
|
|
ret (t.all)
|
|
|
|
wuerde dann durch retrieve (t.all) ersetzt werden.
|
|
|
|
|
|
Makros koennen Parameter besitzen, die durch das Dollar-
|
|
Zeichen angezeigt werden und dem ein einziges graphisches
|
|
Zeichen (besser Buchstabe oder Ziffer) sowie ein Begrenzer
|
|
folgen muessen. Heisst beispielsweise der Template-Teil
|
|
"get $1", so wird der Makro ausgeloest, wenn das Wort "get",
|
|
gefolgt von irgendeinem anderen Wort, im Anfragen-
|
|
Eingabestrom auftritt. Das dem Wort "get" folgende Wort
|
|
wird fuer die spaetere Verwendung gemerkt. Wuerde der
|
|
Replacement-Teil des "get"-Makros
|
|
|
|
retrieve (t.all) where t.tnum = $1
|
|
|
|
heissen und man wuerde "get 35" eingeben, so wuerden alle
|
|
Informationen ueber die Teilenummer 35 wiedergefunden.
|
|
|
|
Definieren von Makros
|
|
|
|
Makros koennen unter Verwendung des Funktions-Makros, define
|
|
genannt, definiert werden. Der Template-Teil des define Ma-
|
|
kros selbst kann vereinfacht durch :
|
|
|
|
{define;$t;$r}
|
|
|
|
beschrieben werden, wobei $t und $r der Template- bzw.
|
|
Replacement-Teil des zu definierenden Makros sind.
|
|
|
|
Nun einige Beispiele.
|
|
|
|
Um den obigen "ret"-Makro zu definieren, ist :
|
|
|
|
{define;ret;retrieve}
|
|
|
|
einzugeben. Wenn das gelesen wird, entfernt der Makro-
|
|
Prozessor alles zwischen den geschweiften Klammern und
|
|
aendert die Makro-Tabelle so, dass ein Auftreten des Wortes
|
|
"ret" durch "retrieve" ersetzt wird. Der define Makro
|
|
selbst hat die leere Zeichenkette als Replacement-Teil.
|
|
Deshalb scheint dieser Makro nach der Eingabe verlorengegan-
|
|
gen zu sein.
|
|
|
|
Ein nuetzlicher Makro fuer das Verkuerzen der range Anwei-
|
|
sung kann wie folgt definiert werden.
|
|
|
|
{define;rg $v $r;range of $v is $r}
|
|
|
|
Dieser Makro veranlasst das Wort "rg", im Text gefolgt von
|
|
zwei weiteren Woertern als Parameter, zu entfernen und durch
|
|
die Woerter "range of" zu ersetzen, gefolgt vom ersten Para-
|
|
meter von "rg", gefolgt vom Wort "is", gefolgt vom zweiten
|
|
"rg"-Parameter.
|
|
|
|
Die Eingabe
|
|
|
|
rg t teile
|
|
|
|
wird zu
|
|
|
|
range of t is teile
|
|
|
|
|
|
Auswertungszeitpunkt
|
|
|
|
Bei der Eingabe des define-Makros wird er nicht unmittelbar
|
|
danach verarbeitet. Das ist aequivalent der Arbeitsweise
|
|
mit Anfragen, bei der auch das Speichern von Anfragen im
|
|
Monitor-Puffer und ihre Ausfuehrung unterschieden werden.
|
|
Die Verarbeitung eines Makros erfolgt erst, wenn der Anfra-
|
|
genpuffer ausgewertet wird.
|
|
|
|
Die Terminal-Monitor-Kommandos \go, \list, und \eval werten
|
|
den Anfragenpuffer aus. Das Kommando \go sendet das Ergeb-
|
|
nis der Auswertung an das DBBS, \list zeigt das Ergebnis der
|
|
Auswertung am Terminal an und \eval stellt das Ergebnis in
|
|
den Anfragenpuffer zurueck.
|
|
|
|
Es ist wichtig, define Makros (wie alle anderen Makros auch)
|
|
auszuwerten. Ansonsten wird so getan, als waeren sie nicht
|
|
eingegeben.
|
|
|
|
Gewoehnlich werden Makros wie folgt definiert :
|
|
|
|
{define . . . }
|
|
\eval
|
|
\reset
|
|
|
|
Bei der Ausfuehrung von \eval erfolgt keine sichtbare Reak-
|
|
tion.
|
|
|
|
Kaschieren
|
|
|
|
Einige Zeichenketten durchlaufen den Makro-Prozessor, ohne
|
|
verarbeitet zu werden. In solch einem Fall koennen die
|
|
Anfuehrungs-Zeichen (` und ') benutzt werden, um den litera-
|
|
len Text einzuschliessen und zu kaschieren (vor dem Makro-
|
|
Prozessor zu verstecken). Um z.B. das Wort "ret" ohne Kon-
|
|
vertierung durch obigen Makro den Makro-Prozessor durchlau-
|
|
fen zu lassen, muss
|
|
|
|
`ret'
|
|
|
|
eingegeben werden.
|
|
|
|
Eine andere Verwendung des Einschlusses in Anfuehrungszei-
|
|
chen zum Kaschieren besteht bei der Parameterzusammenfas-
|
|
sung. Wenn gewuenscht wird, statt eines Wortes mehrere Wo-
|
|
erter wie einen Parameter zu behandeln, muessen diese in An-
|
|
fuehrungszeichen eingeschlossen werden.
|
|
|
|
Das Backslash-Zeichen kaschiert nur das unmittelbar folgende
|
|
Zeichen als waere dieses Zeichen in Anfuehrungszeichen ein-
|
|
geschlossen. So kann das Anfuehrungszeichen "`" als Literal
|
|
benutzt werden, indem ein Backslash-Zeichen vorangeht.
|
|
|
|
Mit dem Backslash-Zeichen kann man ein einzelnes ihm folgen-
|
|
des Zeichen kaschieren, wenn es ausserhalb einer kaschierten
|
|
Zeichenfolge steht und der aktuelle Parameterbegrenzer, ein
|
|
Standardbegrenzer (Blank, Tab- oder Newline-Zeichen) oder
|
|
ein Sonderzeichen (`, {, @ ) ist.
|
|
|
|
Weil Makros normalerweise auf nur einer Zeile spezifiziert
|
|
werden koennen, ist es haeufig bedeutungsvoll, mit einem
|
|
Backslash-Zeichen am Zeilenende das Newline-Zeichen zu ka-
|
|
schieren (verstecken).
|
|
|
|
|
|
Um ein langes "get"-Makro aus einem Input-File zu definie-
|
|
ren, kann aus diesem folgendes eingegeben werden:
|
|
|
|
{define; get $n; retrieve (t.all) \
|
|
where t.name = "$n"}
|
|
|
|
Das Backslash-Zeichen kaschiert stets das naechste Zeichen,
|
|
auch ein Backslash-Zeichen selbst. Um also einen Backslash
|
|
bereitzustellen, sind zwei Backslash einzugeben.
|
|
|
|
Erweiterte Parameter
|
|
|
|
Parameter sind nicht nur auf das folgende Wort einge-
|
|
schraenkt, sondern beinhalten auch eine Begrenzungsspezifi-
|
|
kation.
|
|
|
|
Beispielsweise sei im Template-Teil fuer "define" definiert
|
|
:
|
|
|
|
{define; $t; $r}
|
|
|
|
Der Parameter $t endet am zweiten Semikolon und der Parame-
|
|
ter $r an der rechten geschweiften Klammer. Die Regel be-
|
|
sagt, dass das Zeichen, das der Parameterspezifikation
|
|
folgt, den Parameter beendet. Wenn dieses Zeichen ein
|
|
Blank, Tab- oder Newline-Zeichen bzw. das Ende des
|
|
Template-Teil ist, repraesentiert das Template ein Wort.
|
|
|
|
Wie bei allen guten Regeln gibt es eine Ausnahme. Weil
|
|
System-Makros stets in geschweifte Klammern eingeschlossen
|
|
werden, weiss der Makro-Prozessor, dass sie eigentlich in-
|
|
einander geschachtelt sind.
|
|
|
|
Im Makro
|
|
|
|
{define; x; {pathname}}
|
|
|
|
beendet die erste rechte geschweifte Klammer "pathname" aber
|
|
nicht das define Makro. Wuerde man aber
|
|
|
|
{define; x; `{pathname}'}
|
|
|
|
eingeben, waeren die Worte, wie ueblich, als Ketten von Zei-
|
|
chen und Ziffern (einschliesslich Unterstreichungszeichen)
|
|
definiert.
|
|
|
|
Zusammenstellung der Funktions-Makros
|
|
|
|
Die Funktions-Makros koennen zu Funktionsgruppen zusammen-
|
|
gefasst werden.
|
|
|
|
Es gibt eine Gruppe, die fuer alle Arbeiten mit der Makro-
|
|
Tabelle zustaendig ist und ausschliesslich Substitutions-
|
|
Makros verarbeitet. Dazu gehoert das Definieren (Aktivie-
|
|
ren) eines Makros (Aufnahme in die Makro-Tabelle) einmal mit
|
|
einer Spezialverarbeitung bezueglich der Begrenzer (define)
|
|
und zum anderen mit exakt zu spezifizierenden Begrenzern
|
|
(rawdefine). Weiterhin koennen eine spezifizierte Gruppe
|
|
von Makros (remove mit Parameter) bzw. alle Substitutions-
|
|
Makros der Makro-Tabelle gestrichen (entaktiviert, remove
|
|
ohne Parameter) werden. Ausserdem gibt es Funktions-Makros,
|
|
die eine spezifizierte Gruppe von Makros (dump mit Parame-
|
|
ter) bzw. alle Makros der Makro-Tabelle am Terminal
|
|
(Standard-Output) anzeigen (dump ohne Parameter).
|
|
|
|
Eine andere Gruppe von Funktions-Makros dient der Eingabe
|
|
von Nutzerdaten von der Tastatur (exakt: Standard-Input)
|
|
bzw. Ausgabe am Terminal (exakt: Standard-Output) auch, wenn
|
|
sie aus einem Include-File aufgerufen werden. Es gibt ein
|
|
Makro nur zur Ausgabe (type), eines zur Ausgabe und Eingabe
|
|
(ersetzt den Makro-Wert) (read) und ein anderes zur Ausgabe
|
|
und anschliessenden Definition eines Makros mit dem Wert der
|
|
Eingabe (readdefine). Mit letzterem ist eine elegante Mo-
|
|
eglichkeit gegeben, Nutzereingaben Makros als Variablen zu-
|
|
zuweisen. Bei den read- und readdefine-Makros wird vom
|
|
Terminal-Monitor der readcount-Makro definiert, der die La-
|
|
enge des eingegebenen Textes enthaelt.
|
|
|
|
Eine weitere Gruppe von Makros dient der Berechnung des Wer-
|
|
tes eines Ausdruckes, der entweder den Wert des Makros er-
|
|
setzt (expr) bzw. einem Makro zugewiesen wird, der definiert
|
|
wird (exprdefine).
|
|
|
|
Weiterhin sind weitere Makros zum Vergleichen verfuegbar.
|
|
Zum Zeichenkettenvergleich und anschliessender Zuweisung ei-
|
|
nes Wertes zum Wert dient ein Makro (same). Ein anderer Ma-
|
|
kro (ifsame) dient ebenfalls dem Zeichenkettenvergleich, wo-
|
|
bei bei exakter Uebereinstimmung ein spezifizierter Wert und
|
|
bei Nichtuebereinstimmung ein anderer spezifizierter Wert
|
|
zugewiesen werden. Ein weiterer Makro ist fuer die Berech-
|
|
nung eines Ausdruckes und der anschliessender Zuweisung (je
|
|
nach Ergebnis des Vergleiches) entweder eines im Makro spe-
|
|
zifizierten "wahren" oder eines "falschen" Wertes verfuegbar
|
|
(if). Ebenso gibt es zwei Makros zum numerischen Vergleich,
|
|
einmal fuer einen Vergleich auf "gleich" (ifeq) und zum an-
|
|
deren auf "groesser oder gleich". In beiden Faellen wird
|
|
bei "wahr" ein spezifizierter Wert zum Wert des Makros und
|
|
bei "falsch" ein anderer.
|
|
|
|
|
|
Mit einem weiteren Makro ist die Bildung einer Teil-
|
|
Zeichenkette (Substring), die dem Wert des Makros zugewiesen
|
|
wird, aus einem Makro mit einer Zeichenkette mittels Posi-
|
|
tionsspezifikation (substr) moeglich.
|
|
|
|
Letztlich kann mit einem Makro bis zum Newline-Zeichen der
|
|
Eingabetext uebergangen werden (dnl).
|
|
|
|
Begrenzersymbole
|
|
|
|
Bestimmte Zeichenfolgen werden intern verwendet und stellen
|
|
im Template-Teil eines Makros Symbole fuer Gruppen von Be-
|
|
grenzern dar. Normalerweise sollen sie nicht sichtbar wer-
|
|
den, aber sie koennen als Ausgabe von dump auftreten und
|
|
werden manchmal benutzt, um sehr phantasievolle Makros zu
|
|
erstellen.
|
|
|
|
\| entspricht einem Wortwechsel oder beliebig vielen Stan-
|
|
dardbegrenzern. Bei einem Wortwechsel entspricht es genau
|
|
Null Blanks, Tab- oder Newline-Zeichen (nur zwischen unmit-
|
|
telbar angrenzenden Woertern) und kann z.B. mit Satzzeichen
|
|
auftreten.
|
|
|
|
|
|
|
|
So wird \| beispielsweise dem Zwischenraum zwischen dem
|
|
letzte Zeichen eines Wortes und einem folgenden Komma ent-
|
|
sprechen.
|
|
|
|
\^ entspricht exakt einem Blank-, Tab- oder Newline-Zeichen.
|
|
|
|
\& entspricht exakt einem Wortwechsel.
|
|
|
|
Bei der Definition eines Makros mit dem rawdefine-
|
|
Funktions-Makro sind als zusaetzliche Symbole fuer Begren-
|
|
zergruppen
|
|
|
|
\<blank> genau ein Blank
|
|
\<tab> genau ein Tabulator-Zeichen
|
|
\<nl> genau Newline-Zeichen
|
|
\^ am Beginn des Template-Teiles:
|
|
Anwendung am Zeilenanfang
|
|
|
|
nutzbar.
|
|
|
|
Der Definitionsprozess
|
|
|
|
Wenn z.B. ein Makro {define;get where...;retrieve (t.tname)
|
|
where...} definiert wird, wird bei der Definition fuer den
|
|
Template-Teil dieses Makros folgendes in die Makro-Tabelle
|
|
eingetragen:
|
|
|
|
get\|where\&
|
|
|
|
Dabei sucht der Makro-Prozessor streng genommen sogar nach
|
|
"\&get", was aber ueberfluessig ist, da die Textanalyse
|
|
stets mit einem Wortwechsel beginnt.
|
|
|
|
Beim define werden alle Sequenzen von Blanks, Tab- und
|
|
Newline-Zeichen im Template-Teil zwischen den Woertern in
|
|
das Begrenzersymbol \| ueberfuehrt. Damit ist es fuer einen
|
|
Vergleich gleichgueltig, wieviele Begrenzerzeichen im Ein-
|
|
gabetext auftreten.
|
|
|
|
Wenn ein Tab- oder Newline-Zeichen eingegeben werden soll,
|
|
koennen das Tab- (\t) oder das Newline-Zeichen (\n) ka-
|
|
schiert benutzt werden. Wenn das folgende Makro definiert
|
|
und aus einem Include-File eingezogen werden wuerde:
|
|
|
|
{define; get $n \n; \
|
|
ret (p.all) where p.name = "$n"}
|
|
|
|
wird daraus beim Definieren als Parameterbegrenzer am Para-
|
|
meterende "\^" eingesetzt. Bei einer Spezifikation von der
|
|
Tastatur (Standard-Input) wuerde bei einem Blank, Tab- oder
|
|
Newline-Zeichen die Eingabe des Parameters beendet werden.
|
|
Dieser Makro koennte benutzt werden, um durch Eingabe von :
|
|
|
|
get *Pe*
|
|
|
|
alle Informationen ueber alle Personen zu erhalten, die im
|
|
Namen die Zeichenkette "Pe" (z.B. die mit "Pe" beginnenden
|
|
Familiennamen oder die Vornamen "Peter" oder "Petra") be-
|
|
inhalten.
|
|
|
|
Es ist zu bemerken, dass dies eine gute Methode ist, den
|
|
"ret" Makro innerhalb des "get" Makros aufzurufen.
|
|
|
|
Aus dem obigen Beispiel ist ersichtlich, dass der Makropro-
|
|
zessor das durch einen Backslash kaschierte Zeichen "n" in
|
|
ein Newline-Zeichen transformiert, ebenso wie aus "\t" ein
|
|
Tabulator-Zeichen wird.
|
|
|
|
Parameter-Vorverarbeitung
|
|
|
|
Der Makro-Prozessor entnimmt nach der Vorschrift des
|
|
Template-Teiles dem Eingabetext die Parameter. In manchen
|
|
Faellen ist es notwendig, dass diese Parameter einer vor-
|
|
herigen Bearbeitung durch den Makro-Prozessor unterzogen,
|
|
also vorverarbeitet werden, bevor die Werte der Parameter
|
|
eingesetzt werden. Zur Spezifikation einer Vorverarbeitung
|
|
muss die Parameterdefinition im Template-Teil des define-
|
|
Makros mit "$$" gekennzeichnet werden. Das bedeutet, dass
|
|
in einem define-Makro alle vorzuverarbeitenden Parameter mit
|
|
"$$" zu kennzeichnen sind. Im Eingabetext muss der Parame-
|
|
terwert durch "@" eingeleitet werden.
|
|
|
|
Da Funktions-Makros stets vorverarbeitet werden, ist keine
|
|
Kennzeichnung erforderlich.
|
|
|
|
Ein Beispiel der Benutzung der Parameter-Vorverarbeitung ist
|
|
im Abschnitt "System-Substitutions-Makros" enthalten.
|
|
|
|
Funktions-Makros
|
|
|
|
Es gibt verschiedene in den Makro-Prozessor integrierte
|
|
Funktions-Makros. In der nachfolgenden Beschreibung sind
|
|
einige der Parameterspezifikationen, nicht wie ueblich mit
|
|
einem, sondern mit zwei Dollar-Zeichen (Kennzeichen der Mo-
|
|
eglichkeit der Spezifikation einer Vorverarbeitung) mar-
|
|
kiert.
|
|
|
|
{define; $$t; $$r}
|
|
|
|
|
|
definiert einen Makro, wie er oben beschrieben wurde. Eine
|
|
Spezialverarbeitung des Template-Teiles bezueglich der Be-
|
|
grenzer, die hierbei erfolgt, wurde bereits beschrieben.
|
|
|
|
{rawdefine; $$t; $$r}
|
|
|
|
ist eine andere Form von define. Dabei wird keine Spezial-
|
|
verarbeitung ausgefuehrt.
|
|
|
|
{remove; $$n}
|
|
|
|
entfernt die mit dem Makro-Namen $n benannten
|
|
Substitutions-Makros aus der Makro-Tabelle.
|
|
|
|
{remove}
|
|
|
|
entfernt alle Substitutions-Makros aus der Makro-Tabelle.
|
|
|
|
{dump; $$n}
|
|
|
|
zeigt den Wert der Substitutions-Makros mit dem Namen $n.
|
|
Die Anzeige erfolgt in Form eines rawdefine Makros.
|
|
|
|
{dump}
|
|
|
|
zeigt die Werte aller Substitutions-Makros an.
|
|
|
|
{type;$$s}
|
|
|
|
gibt $s auf Standard-Output aus.
|
|
|
|
{read;$$s}
|
|
|
|
gibt $s auf Standard-Output aus und liest eine eingegebene
|
|
Zeile (begrenzt durch das Newline-Zeichen, nicht kaschier-
|
|
bar) von Standard-Input. Die eingegebene Zeile wird zum
|
|
Wert des Makros. Der dabei definierte Makro
|
|
|
|
{readcount}
|
|
|
|
liefert die Anzahl der gelesenen Zeichen und ist vom Nutzer
|
|
auswertbar. Ein File-Ende (EOF) ergibt den Wert -1, ein
|
|
einzelnes Newline-Zeichen ergibt 0.
|
|
|
|
{readdefine; $$n; $$s}
|
|
|
|
gibt auch $s auf Standard-Output aus und liest eine Zeile
|
|
von Standard-Input. Der Makro stellt aber die eingelesene
|
|
Zeile in den mit $n benannten Makro. Der Replacement-Teil
|
|
ist ein Zaehler mit der Anzahl der Zeichen der Zeile. Der
|
|
Makro {readcount} ist auch hier definiert.
|
|
|
|
{expr; $$e}
|
|
|
|
berechnet den Ausdruck $e, der zum Wert des Makros wird.
|
|
|
|
{exprdefine; $$n; $$e}
|
|
|
|
berechnet den Ausdruck $e fuer den Makro $n. Der Wert des
|
|
Makros ist eine leere Kette und deshalb im Gegensatz zum
|
|
expr-Makro nicht fuer eine Schachtelung nutzbar. Er ent-
|
|
spricht dem Makro {define;n;@{expr;e}}.
|
|
|
|
{same; $$a; $$b}
|
|
|
|
vergleicht die Zeichenketten $a und $b und liefert als Wert
|
|
0 fuer $a = $b, +1 fuer $a > $b und -1 fuer $a < $b.
|
|
|
|
{ifsame; $$a; $$b; $t; $f}
|
|
|
|
vergleicht die Zeichenketten $a und $b. Bei exakter Uebe-
|
|
reinstimmung wird als Wert der Replacement-Text $t zugeord-
|
|
net, ansonsten $f.
|
|
|
|
{if; $$e; $t; $f}
|
|
|
|
berechnet den Ausdruck $e und liefert $t (true, wahr), wenn
|
|
$e > 0, sonst $f (false, falsch).
|
|
|
|
{ifeq; $$a; $$b; $t; $f}
|
|
|
|
aehnelt ifsame, aber der Vergleich erfolgt numerisch.
|
|
|
|
{ifgt; $$a; $$b; $t; $f}
|
|
|
|
aehnelt ifeq, aber der Test erfolgt auf $a groesser $b.
|
|
|
|
{substr; $$f; $$t; $$s}
|
|
|
|
stellt den Teil einer Zeichenkette (Substring) von $s zwi-
|
|
schen den Zeichenpositionen $f und $t bereit, wobei $f und
|
|
$t ab Null gezaehlt werden. Liegen $f oder $t ausserhalb
|
|
des Bereiches, werden aus dem Bereich soviele Zeichen, wie
|
|
moeglich, uebernommen.
|
|
|
|
{dnl}
|
|
|
|
|
|
|
|
|
|
uebergeht alle Zeichen bis zum Newline-Zeichen.
|
|
|
|
Berechnung eines arithmetischen Ausdruckes
|
|
|
|
Die e-Parameter der if-, expr- und exprdefine-Makros und die
|
|
f- und t-Parameter des substr-Makros koennen arithmetische
|
|
Ausdruecke sein.
|
|
|
|
Ein Ausdruck darf Operatoren und Operanden enthalten.
|
|
Gueltige Operatoren sind:
|
|
|
|
** Potenzieren
|
|
- ! Vorzeichen, logische Negation
|
|
* / % Muliplikation, Division, Divisionsrest
|
|
+ - Addition, Subtraktion (zweistellig)
|
|
> >= < <= Vergleiche
|
|
= != gleich, ungleich
|
|
& logisches Und
|
|
| logisches Oder
|
|
|
|
|
|
Operationen der gleichen Zeile sind von gleicher Bindungs-
|
|
staerke, ansonsten nimmt die Bindungsstaerke von oben nach
|
|
unten ab.
|
|
|
|
Der Ausdruck darf als Operanden nur ganzzahlige numerische
|
|
Werte im Bereich von -32768 bis 32767 enthalten. Ansonsten
|
|
erfolgt eine Fehlermeldung und ein Abbruch. Es Ausdruck
|
|
darf keine Blanks, Tabulator-, Newline- oder EOF-Zeichen
|
|
enthalten (Ausdruckende).
|
|
|
|
Die Berechnung erfolgt in der Festkommaarithmetik. Eine Di-
|
|
vision durch 0 ergibt nach Warnung den Wert 0. Die logi-
|
|
schen Operationen (! & |) deuten <=0 als FALSE und >0 als
|
|
TRUE. Die logischen Operationen und die Vergleichsoperatio-
|
|
nen liefern den Wert 0 fuer FALSE und 1 fuer TRUE. Die Be-
|
|
rechnung eines Ausdruckes erfolgt von links nach rechts ent-
|
|
sprechen den Bindungsregeln. Klammerung zur Realisierung
|
|
einer anderen Vorrangfolge ist moeglich.
|
|
|
|
System-Substitutions-Makros
|
|
|
|
Durch die Monitor-Kommandos \eval, \list und \go erfolgt ei-
|
|
ne Verarbeitung (Substitution) von im Monitor-Puffer enthal-
|
|
tenen Makros.
|
|
|
|
Durch das \go-Kommando wird der durch die Makrosubstitution
|
|
erzeugte Text dem Parser des DBBS uebergeben. Dabei werden
|
|
einige DABA-System-Substitutions-Makros verarbeitet, was
|
|
nachfolgend etwas naeher betrachtet werden soll.
|
|
|
|
Vor den an den Parser des DBBS uebergebenen Text (Anfragen-
|
|
stapel) wird der Makro {begintrap} und danach {endtrap} ab-
|
|
gearbeitet.
|
|
|
|
Nachdem der Anfragenstapel durch das DBBS bearbeitet wurde
|
|
und bevor das Prompt-Zeichen erscheint, wird von DABA der
|
|
Makro {tuplecount} definiert, der bei den Tupeloperationen
|
|
(nicht bei Funktionen (Datenbankdienste) wie z.B. "print")
|
|
die Anzahl der bearbeiteten Tupel enthaelt (Bei einem Anfra-
|
|
genstapel hat {tuplecount} den Wert der letzten QL-
|
|
Anweisung). Danach erfolgt bei vom Nutzer definierten
|
|
{querytrap}-Makro das Schreiben des dem DBBS uebergebenen
|
|
Anfragenstapels in das in {querytrap} definierte Protokoll-
|
|
File.
|
|
|
|
Wenn durch den Nutzer dynamisch ein neues Protokollfile zu
|
|
definieren ist, hat das in zwei Schritten zu erfolgen. Im
|
|
ersten Schritt ist {querytrap} zu entfernen (remove) (Ab-
|
|
schliessen des alten Protokollfiles nach dem letzmaligen
|
|
Protokollieren in das alte Protokoll). Danach erfolgt mit
|
|
einem neuen \go das Definieren eines neuen Protokolles mit
|
|
{querytrap}.
|
|
|
|
|
|
Nach der moeglichen Protokollierung wird der Makro {conti-
|
|
nuetrap} ausgefuehrt. Erst dann erscheint das Prompt-
|
|
Zeichen.
|
|
|
|
Wenn die an das DBBS uebergebene Anfrage eine Fehlerbedin-
|
|
gung ergeben hat, wird der Makro {errorcount} durch das Sy-
|
|
stem definiert, der die Fehlernummer enthaelt. Anschlies-
|
|
send wird der Makro {catcherror} ausgefuehrt, wenn er vom
|
|
Nutzer definiert wurde. Ist der catcherror-Makro nicht de-
|
|
finiert oder 0, so wird die Standardfehlerbehandlung aus-
|
|
gefuehrt und eine entsprechende Fehlermeldung ausgegeben.
|
|
Wurde vom Nutzer der catcherror-Makro mit 0 definiert, ist
|
|
zwar der errorcount-Makro definiert (Fehlerfall), eine Stan-
|
|
dardfehlerbehandlung unterbleibt. So kann der Nutzer seine
|
|
eigene Fehlerbehandlung ausfuehren.
|
|
|
|
Unabhaengig vom Wert des catcherror-Makros steht dem Nutzer
|
|
in jedem Falle bei einem Fehler der errorcount-Makro zur
|
|
Verfuegung, um das Vorhandensein eines Fehlers abzutesten.
|
|
|
|
Einige speziellen Makros werden durch den Terminal-Monitor
|
|
benutzt, um die Ausfuehrungsumgebung zu steuern und Ergeb-
|
|
nisse dem Nutzer bereitzustellen.
|
|
|
|
|
|
Nachfolgend aufgefuehrte Makros sind durch den Monitor be-
|
|
reitgestellt und dem Nutzer immer verfuegbar.
|
|
|
|
{pathname}
|
|
|
|
Pfadname des File-Systems von DABA.
|
|
|
|
{usercode}
|
|
|
|
2-Byte Nutzercode (Usercode) des gerade arbeitenden Nutzers
|
|
|
|
{dbname}
|
|
|
|
Name der bearbeiteten Datenbank.
|
|
|
|
Die folgenden Makros koennen in ihrer Quellform vom Nutzer
|
|
in Files bereitgestellt werden. Sie werden zum Zeitpunkt des
|
|
Monitor-Startes von diesem definiert. Sie koennen aber auch
|
|
vom Nutzer nachtraeglich definiert werden. Unter bestimmten
|
|
Bedingungen werden sie ausgefuehrt.
|
|
|
|
{begintrap}
|
|
|
|
|
|
|
|
wird am Beginn einer Anfrage ausgefuehrt.
|
|
|
|
{endtrap}
|
|
|
|
wird ausgefuehrt, nachdem die Anfragespezifikation DABA ue-
|
|
bergeben wurde.
|
|
|
|
{continuetrap}
|
|
|
|
wird ausgefuehrt, nachdem die Anfrage beendet wurde. Der
|
|
Unterschied zwischen continuetrap und endtrap besteht darin,
|
|
dass der endtrap-Makro ausgefuehrt wird, nachdem die Anfrage
|
|
uebergeben aber bevor sie ausgefuehrt wird, waehrend der
|
|
Aufruf des continuetrap-Makros nach Ausfuehrung der Anfrage
|
|
erfolgt.
|
|
|
|
{querytrap}
|
|
|
|
definiert den Namen eines Protokollfiles. Ist querytrap de-
|
|
finiert, werden auf dem File alle Nutzeraktionen protokol-
|
|
liert. Wird das Makro geloescht, wird das Protokollfile ge-
|
|
schlossen.
|
|
|
|
{exectrap}
|
|
|
|
wird nach Ausfuehrung eines \edit- oder \shell- Kommandos
|
|
gerufen, wenn das bearbeitete Programm einen Rueckkehrcode
|
|
ungleich Null lieferte.
|
|
|
|
{editor}
|
|
|
|
kann verwendet werden, um den Pfadnamen eines Editors fuer
|
|
die Benutzung durch das \edit Kommando zu definieren.
|
|
|
|
{shell}
|
|
|
|
kann verwendet werden, um den Pfadnamen der durch das \shell
|
|
Kommando zu nutzenden Shell zu definieren.
|
|
|
|
{catcherror}
|
|
|
|
wird benutzt, um bei einem Template von Null, die Systemfeh-
|
|
lerbehandlung auszuschalten.
|
|
|
|
Das vom Nutzer zu definierende
|
|
|
|
{default}
|
|
|
|
|
|
|
|
Makro wird fueer ein \branch-Kommando verwendet, dessen
|
|
Zielmarke nicht gefunden wird.
|
|
|
|
Die folgenden Makros werden unter bestimmten Bedingungen vom
|
|
Monitor definiert.
|
|
|
|
{tuplecount}
|
|
|
|
wird nach jeder Anfrage gesetzt (aber bevor continuetrap er-
|
|
reicht ist) und stellt einen Zaehler der Anzahl der Tupel
|
|
dar, die bei retrieve die Qualifikation der Anfrage erfuel-
|
|
len (Anzahl relevanter Tupel), bei append zugefuegt, bei re-
|
|
place geaendert bzw. bei delete geloescht wurden. Der Za-
|
|
ehler wird von Funktionen der Datenbankdienste (z.B.
|
|
"print") nicht gesetzt.
|
|
|
|
Wenn mehrere Anfragen als Stapel bearbeitet werden, wird der
|
|
Zaehler auf die Anzahl der Tupel gesetzt, die der letzten
|
|
Anfrage entsprechen.
|
|
|
|
Um beispielsweise die Anzahl bearbeiteter Tupel automatisch
|
|
nach jeder Anfrage anzuzeigen, kann spezifiziert werden :
|
|
|
|
{define; {begintrap}; {remove; {tuplecount}}}
|
|
{define; {continuetrap}; \
|
|
{ifsame; @{tuplecount}; {tuplecount};; \
|
|
{type;@{tuplecount} tuples touched}}}
|
|
|
|
Dabei wird vor der Ausfuehrung des Anfragenstapels der
|
|
tuplecount-Makro durch den begintrap-Makro aus der Makro-
|
|
Tabelle entfernt. Nach Ausfuehrung der Anfragen durch das
|
|
DBBS (definiert bei einer Beantwortbarkeit der QL-Anweisung
|
|
den tuplecount-Makro) wird durch den continuetrap-Makro der
|
|
aktuelle Wert des tuplecount-Makros (mit spezifizierter Vor-
|
|
verarbeitung) mit der Zeichenkette "{tuplecount}" vergli-
|
|
chen. Wenn beide Werte nicht uebereinstimmen, wird die
|
|
Nachricht "n tupples touched" vor dem Erscheinen des
|
|
Prompt-Zeichens ausgegeben.
|
|
|
|
War die Anfrage fehlerhaft, wird vom Monitor kein
|
|
tuplecount-Makro definiert. Folglich kann durch die Vorver-
|
|
arbeitung "@{tuplecount}" nicht durch seinen Wert ersetzt
|
|
werden und bleibt die Zeichenkette "{tuplecount}". Der Ver-
|
|
gleich ergibt deshalb Gleichheit und es erfolgt keine Reak-
|
|
tion (Template dafuer leer).
|
|
|
|
{errorcount}
|
|
|
|
|
|
|
|
wird vom System definiert, wenn eine spezifizierte QL-
|
|
Anweisung einen Fehler ergeben hat und enthaelt die Fehler-
|
|
nummer.
|
|
|
|
{readcount}
|
|
|
|
enthaelt nach einem read- oder readdefine-Makro die Anzahl
|
|
der gelesenen Zeichen (oder -1 bei Control-D bzw. 0 bei ei-
|
|
nem einzelne Newline-Zeichen).
|
|
|
|
|
|
SIEHE AUCH
|
|
|
|
monitor(iql)
|
|
|
|
|
|
DIAGNOSE
|
|
|
|
infinite loop in makro -
|
|
Ein Abschnitt des Input-Text wurde 100 mal einer
|
|
Makro-Substitution unterzogen z.B nach
|
|
{define;alpha;alpha}. Anschliessend geht der
|
|
Makro-Prozessor weiter.
|
|
every parameter needs a delimiter -
|
|
Die Parameterdefinition hat keinen Begrenzer.
|
|
|
|
null parameter name -
|
|
Die Parameterdefinition hat keine Namensangabe.
|
|
|
|
parameter <p_name> redeclared -
|
|
Der gleiche Parametername <p_name> wird in einem
|
|
template mehrfach als solcher verwendet.
|
|
|
|
parameter <p_name> referenced but not defined -
|
|
Der im replacement referenzierte <p_name> wurde im
|
|
Template-Teil nicht definiert.
|
|
|
|
|
|
Beispiele
|
|
|
|
/* Erzeugen des QL-Schluesselwortes "retrieve"
|
|
aus dem Wort "get"*/
|
|
|
|
{define;get;retrieve}\eval
|
|
|
|
/* Erzeugen einer kompletten retrieve-QL-
|
|
Anweisung fuer eine spezielle Anwendung*/
|
|
|
|
{define; get $1; retrieve (p.all)
|
|
where p.name="$1"}\eval
|
|
|
|
/* In einem Menue werden dem Nutzer die
|
|
Antworten a, b oder ? gestattet.
|
|
Er erhaelt die Eingabeaufforderung a, b, ?.
|
|
Abhaengig von der Antwort werden bestimmte
|
|
Marken angesprungen.
|
|
|
|
{define; {default}; ab}\eval
|
|
\branch {read; a, b, ?}
|
|
\mark a
|
|
:
|
|
\mark b
|
|
:
|
|
\mark ab
|
|
|
|
Die durch das default-Makro definierte Sprungmarke bewirkt,
|
|
dass irgendeine Eingabe (ausser a oder b) stets einen Sprung
|
|
nach der Marke "ab" ergibt. Dort koennte z.B. eine Hilfe
|
|
ausgegeben werden.
|
|
|
|
/* Der Nutzer wird durch die Ausgabe des Textes
|
|
"Name:" aufgefordert, einen Namen einzugeben.
|
|
Gibt er nur ein Newline-Zeichen ein,
|
|
erfolgt ein Srung zur Marke "Ende"*/
|
|
|
|
{readdefine; name; Name:}\eval
|
|
\branch ?{readcount}=0 Ende
|
|
retrieve (p.all) where p.`name'="name"\go
|
|
|
|
Der eingegebene Text wird in die QL-Anweisung zwischen die "
|
|
"-Zeichen eingesetzt. Vorher wird die Zeichenkette "name"
|
|
durch die Zeichen (`') kaschiert.
|
|
|
|
/* Es soll immer ein Sprung nach "normal"
|
|
erfolgen, es sei denn, der im vorhergehenden
|
|
Beispiel eingegebene Name ist "XXX" */
|
|
|
|
\branch {ifsame;@name;XXX;Ausnahme;normal}
|
|
|
|
Wenn durch "@" keine Vorverarbeitung angezeigt worden waere,
|
|
wuerde immer nach "normal" gesprungen werden.
|