M4 - very short intro (Deutsch)

From Ethersex_Wiki
Revision as of 11:10, 1 May 2012 by Tkaltenbrunner (talk | contribs) (Macro definieren)
Jump to: navigation, search

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.

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 ....