NAME
ersetzt. Der Bezeichner NAME
darf dabei nur
aus Buchstaben, Ziffern und Unterstrichen bestehen.
Ist die Environmentvariable name
nicht gesetzt, wird ein
Leerstring eingesetzt.
NAME
auch Sonderzeichen mit Ausnahme der geschlossenen Klammer
enthalten darf.
\0101
wird durch das Zeichen A
ersetzt.
0
, einem x
und hexadezimalen
Zahlen, wird durch das ASCII-Zeichen ersetzt, dessen Wertigkeit der Zahl
entspricht.
0\x42
wird durch das Zeichen B
ersetzt.
1
und
9
einschliesslich, sowie optional weiteren Ziffern von 0
bis 9
, wird durch das ASCII-Zeichen ersetzt, dessen Wertigkeit der Zahl
entspricht.
\67
wird durch das Zeichen C
ersetzt.
\
) ersetzt
CR
, einen Wagenruecklauf ersetzt.
$
) ersetzt.
~
) ersetzt.
Wenn das Heimatverzeichnis/home/uwe
ist, dann wird~
durch/home/uwe
ersetzt.
name
ersetzt.
~uwe
wird durch/home/uwe
ersetzt.
name
ersetzt. Diese Version ist
vorzuziehen, wenn name
Sonderzeichen enthaelt oder
sich direkt daran weitere Zeichen oder Buchstaben
anschliessen.
~(uwe)/tmp
wird durch/home/uwe/tmp
ersetzt.
~
) ersetzt.
Das $[
-Konstrukt ermoeglicht eine Textersetzung in Abhaengigkeit
vom Ergebnis einer Bedingung. Die Syntax ist:
$[bedingung?was-wenn-wahr:was-wenn-falsch]
Der else
-Teil der Bedingung darf weggelassen werden:
$[bedingung?was-wenn-wahr]
bedingung
kann sein:
something
und something-else
gleich sind.
something
und something-else
ungleich sind.
something
nicht leer ist.
Der Term in den eckigen Klammern wird erst in seine Einzelteile
zerlegt, dann erst werden die notwendigen Interpretationen ausgefuehrt.
Nicht notwendige Interpretationen (zum Beispiel der else
-Teil
einer wahren Bedinungen) werden nicht durchgefuehrt.
Der Einsatz der Library erfordert nur geringe Aenderungen am Programm:
Die Textersetzung wird durch die Routine tip_interpret durchgefuehrt:
Die Funktion fuehrt die Ersetzung durch. Sie durchsucht den String
format zeichenweise. Falls das Zeichen einem magic der Tabelle
entspricht oder die nächsten Zeichen einem der magicstrings
in
der Tabelle entsprechen, wird die assozierte Routine tab->interp
aufgerufen. Falls tab->interp nicht zustaendig ist
(TIP_NOTDONE
zurueckliefert), wird die Tabelle weiter durchsucht.
tip_interpret
liefert die
die Anzahl der geschriebenen Zeichen ohne das abschliessende
'\0'
, also strlen(to)
, oder TIP_ERROR
,
falls ein Fehler auftrat, zurueck.
Die tip_interpret zu uebergebende Tabelle tab wird durch ein
Element beendet, dessen magic
'\0'
und dessen
magicstring
NULL
ist. Der Datentyp ist
definiert als:
typedef struct { char magicchar; const char *magicstring; size_t magiclen; tip_fn_t interp; } tip_t;
Die Routine interp
wird aufgerufen, falls:
magicchar
ungleich '\0' und das nächste Zeichen im zu
interpretierenden Text gleich magicchar
ist, oder
magicstring
ungleich NULL
ist und die nächsten
magiclen
Zeichen im zu interpretierenden Text gleich magicstring
sind.
interp
wird unter section Ersetzungsunterroutinen: tip_fn_t beschrieben.
tip_t
wird niemals einzeln verwendet, sondern immer nur als
Array, dessen letztes Element als magic ein '\0'
hat
und dessen magicstring
NULL
ist.
Die Funktion arbeitet wie tip_interpret, alloziert aber den Speicherbereich für das Ergebnis selbst. Das verwendete Verfahren führt unter Umständen dazu, daß einzelne Interpretationen mehrfach durchgeführt werden.
Die Funktion wird aufgerufen, wenn tip_interpret (siehe section Durchfuehrung der Ersetzung)
im format-String ein oder mehrere Zeichen fand, die
der tip_function
in der Tabelle tab zugeordnet wurden. Sie erhaelt folgende
Parameter:
tip_function
eine Ersetzung durchfuehren konnte.
Returncodes:
Wird eine Ersetzung durchgefuehrt, ist der String mit einer 0 abzuschliessen.
Folgende Ersatzroutinen enthaelt die Library:
magic
das
Zeichen $
. Siehe section Ersetzung durch Environmentvariablen.
magic
das Zeichen ~
.
Bei Einsatz von tip_tilde ist Vorsicht geboten. Die Zugriffe auf die
Passwortdatei, die notwendig sind, um das Heimatverzeichnis feststellen
zu können, geschehen mit Hilfe der Funktionen getpwuid
und getpwnam
, und verstellen daher den Dateizeiger
saemtlicher `/etc/passwd' mit Hilfe der Routinen
aus <pwd.h> lesender oder schreibender Funktionen. Bei Aufruf von
tip_deinit
wird endpwent
aufgerufen, falls tip_tilde vorher
aufgerufen worden ist.
magic
das Zeichen
\\
.
magicstring
wird $[
erwartet. Die Bedinungen muß
außerdem mit einem ]
abgeschlossen werden.
magicstring
wird ${strip
erwartet. Der
Ausdruck muß außerdem mit einem }
abgeschlossen werden.
Die Funktion kann als Beispiel für eigene Funktionen dienen.
undefined
eingesetzt. Der Ausdruck
muß mit einem }
abgeschlossen werden.
Das Beispiel setzt den Inhalt des Makros test
ein.
${macro test}
}
abgeschlossen werden. Fehlt value,
wird ein leerer String als Wert eingesetzt.
Das Beispiel setzt das Makro test
auf hallo
:
${defmacro test hallo}
tip_defmacro
ist über die Funktion tip_defmacro_intern
realisiert, siehe section Definition und Nutzung von Makros.
}
abgeschlossen werden. Der Scanner,
der nach der abschliessenden Klammer sucht, ist recht empfindlich, und
verlangt, daß der Parameterstring der Syntax der Interpretationsroutinen
genügt.
Das Beispiel setzt einen einzelnen $ ein, ist also eine aufwendigere
Schreibweise für \$
:
${literal %}
}
abgeschlossen werden.
Das Beispiel zeigt, wie man aus vier Backslashs einen machen kann:
Das Beispiel setzt den Inhalt des Makros test
ein.
${force \\\\}
Makros dienen als Schreiberleichterung. Sie behalten ihren Inhalt bis sie gelöscht werden oder das Programm endet.
Es gibt zwei Arten, Makros einen Wert zuzuweisen:
defmacro
aufgerufen, kann also benutzt
werden, um aus einer interpretierten Datei heraus einen Makrowert
zu setzen.
intern
bezieht sich darauf, daß ihr Aufruf in das Programm eincodiert
werden muß.
Es gibt zwei Arten, ein Makros zu löschen:
undefmacro
aufgerufen, kann also benutzt werden, um aus einer interpretierten
Datei heraus ein Makro zu löschen.
Ein Makro kann auch einen leeren Wert haben.
Beide Arten, eine Makro zu definieren oder zu löschen sind identisch und arbeiten auf derselben Datenbasis.
Mit dieser Funktion kann man aus einem C-Programm heraus ein Makro auf einen Wert setzen (value != NULL) oder ein Makro löschen (value == NULL).
endpwent
auf,
und auch nur, falls tip_tilde eine der Routinen aus <pwd.h> benutzt hat.
Liefert 0 bei Erfolg, sonst einen Wert ungleich 0.
static size_t my_tip_prozent(const char *this, const char **next, char *to, size_t maxlen); tip_t tab[]= { {'$',tip_dollar}, {'\\',tip_backslash}, {'%',my_tip_prozent}, {0,NULL}, }; static void mylog(const char *format); static size_t my_tip_prozent(const char *this, const char **next, char *to, size_t maxlen) { char buf[128]; time_t t; size_t l; switch(this[1]) { case 't': /* %t -> Ausgabe von ctime() ohne \n */ if (maxlen<25) /* strlen(ctime) */ return TIP_ERROR; time(&t); strcpy(to,ctime(&t)); *strchr(to,'\n')=0; return 24; case 'p': /* %p -> pid */ sprintf(buf,"%ld",(long) getpid()); l=strlen(buf); if (l+1>maxlen) return TIP_ERROR; strcpy(to,buf); return l; } return TIP_NOTDONE; }; extern FILE *logfile; static void mylog(const char *format) { char buf[4096]; if (tip_interpret(tab,format,buf,sizeof(buf))!=TIP_ERROR) fprintf(logfile,"%s\n",buf); }
Go to the first, previous, next, last section, table of contents.