Difference between revisions of "M4 - very short intro (Deutsch)"
(→"Kontrol-Strukturen") |
m (→Beispiel:) |
||
Line 51: | Line 51: | ||
divert(3)dnl | divert(3)dnl | ||
Das ist Abschnitt 3 | Das ist Abschnitt 3 | ||
− | divert(2) | + | divert(2)dnl |
Das ist Abschnitt 2a | Das ist Abschnitt 2a | ||
divert(1)dnl | divert(1)dnl | ||
Das ist Abschnitt 1 | Das ist Abschnitt 1 | ||
− | divert(2) | + | divert(2)dnl |
Das ist Abschnitt 2b | Das ist Abschnitt 2b | ||
− | divert(-1) | + | divert(-1)dnl |
Die Ausgabe sind dann wie folgt aus: | Die Ausgabe sind dann wie folgt aus: | ||
Line 65: | Line 65: | ||
Das ist Abschnitt 2b | Das ist Abschnitt 2b | ||
Das ist Abschnitt 3 | Das ist Abschnitt 3 | ||
− | + | ||
Bemerkung: die Sprache ist sehr mächtig und man kann "Wildes" konstruieren, dass man nach 2 Tagen selber nicht mehr versteht ;-) | Bemerkung: die Sprache ist sehr mächtig und man kann "Wildes" konstruieren, dass man nach 2 Tagen selber nicht mehr versteht ;-) |
Revision as of 19:05, 1 May 2012
Einleitung
Die offizielle Doku gibt es hier: http://www.gnu.org/software/m4/manual/index.html Hier noch ein ganze kurze Einführung:
Von der Idee her, ist es mit dem C-Präprocessor vergleichbar, der ebenfalls Macro-Ersetzungen durchführt und das Ergebnis an den C-Compiler weiterleitet. Bei m4 ist das Ergebnisse lediglich der Text, den die Macro-Ersetzungen ergeben.
Wie es genau funktioniert, aber unbedingt nachlesen, da es manchmal auch auf die Feinheiten ankommt.
Kommentare werden mit # wie in C gekennzeichnet.
Es gibt keinen "Befehlsterminator" wie z.B. ein Semikolon.
Ersetzungen werden aber ähnlich wie ein Funktionen in einer Programmiersprache aufgerufen.
Wichtig ist auch die Quotierung mit ` und ' , die das Verhalten bei der Macro-Expandierung entscheidend beeinflusst. siehe hier und folgende http://www.gnu.org/software/m4/manual/m4.html#Quoting-Arguments
Macro definieren
Im Gegensatz zum C-Präprocessor wird hier ein sogenanntes "builtin" benutzt:
define(name, [expansion])
Zu beachten: werden die Argumente nicht quotiert, kann hier schon die Macro-Erweiterung zuschlagen, was dann zu unerwünschten Ergebnissen führen kann.
Mit den "Pseudo-Variablen" $1, $2, etc. kann man die Argumente des Macros in der Expansion referenzieren. Im Gegensatz zum C-Präprozessor, der überwiegend mit benannten Parametern arbeitet.
- $* - alle Argumente
- $@ - alle Argumente quotiert - Im Gegensatz zur vorhergehenden Variante werden die Argumente nicht weiter expandiert.
- $# - Anzahl der Argumente
Kontrol-Strukturen
Hiermit sind bedingte Ausführung und Schleifen gemeint.
- ifdef(name, string1, [string2])
- - wenn name definiert ist, dann ist das Ergebnis string1, sonst string2
- ifelse(string1, string2, equal1, string3, string4, equal2, ..., [not_equal])
- - wenn string1 = string2, dann equal1, sonst if string3 = string4, dann equal2, sonst ..., sonst not_equal
- join oder joinall([separator], [args....])
- - args zusammenfügen, Separator dazwischen setzen. Bei joinall wird immer der Separator gesetzt - auch wenn ein Argument leer ist.
- Rekursive Macro-Definitionen sind auch möglich - hilfreich dabei die shift Funktion, die jeweils das erste Argument abschneidet.
- forloop (iterator, start, end, text)
- - iterator muss ein gültiger Macroname sein, Start und Ende ganze Zahlen, der Text wird gemäß der Schleifendurchläufe ersetzt.
- foreach (iterator, paren-list, text) / foreachq (iterator, paren-list, text)
- - jedes Argument der parent-list wird an den Iterator gebunden und dann eine Ersetzung für Text ausgeführt.
divert
Da dieses Konstrukt häufig in Ethersex eingesetzt wird, hier noch ein paar Extra-Bemerkungen: Mit divert(<ausgabeidx>) wird ein Text-Abschnitt begonnen, der an der durch <ausgabeindex> definierten Stelle in die Ausgabe-Text eingefügt wird. <ausgabeidx> ist eine ganze, positive Zahl. Abschnitt 1 wird vor 2, 2 wird vor 3, usw. ausgegeben. Dabei spielt es keine Rolle, in welcher Reiehnfolge die Abschnitt in der m4-Quelldatei definiert werden.
Der Textabschnitt wird durch ein weiteres "divert" beendet, wobei "divert(-1)" dafür sorgt, dass kein neuer Abschnitt beginnt.
Sind mehrer Abschnitte mit dem gleichen <ausgabeidx> definiert, so werden sie mit der Reihenfolge ihrer Defnition ausgegeben.
Beispiel:
divert(3)dnl Das ist Abschnitt 3 divert(2)dnl Das ist Abschnitt 2a divert(1)dnl Das ist Abschnitt 1 divert(2)dnl Das ist Abschnitt 2b divert(-1)dnl
Die Ausgabe sind dann wie folgt aus:
Das ist Abschnitt 1 Das ist Abschnitt 2a Das ist Abschnitt 2b Das ist Abschnitt 3
Bemerkung: die Sprache ist sehr mächtig und man kann "Wildes" konstruieren, dass man nach 2 Tagen selber nicht mehr versteht ;-)
Wichtiges
- dnl - "Discard to next line" - Schließt die Zeile ab - alles nachfolgende wird ignoriert.
- divert - der nachfolgende Text wird ausgegeben. Der Text endet beim erneuten auftauchen des Wortes "divert". Das Wort selber kann man deshalb nur mit im Handbuch beschriebenen Tricks im Text verwenden werden ....