Wertarbeit

Soll eine Anwendung eine Konfigurationsdatei nutzen, erfinden Entwickler gern das Rad neu. Für die meisten Zwecke genügt jedoch ein Standardformat, für das es bereits einen fertigen Parser gibt.

In Pocket speichern vorlesen Druckansicht 11 Kommentare lesen
Lesezeit: 4 Min.
Von
  • Michael Riepe

Soll ein Programm universell nutzbar sein, kommt der Entwickler nicht darum herum, einen Mechanismus zum Einstellen der Arbeitsparameter zu integrieren. Werkzeuge für die Kommandozeile besitzen üblicherweise Optionen, mit denen sich einzelne Parameter ändern lassen. Lässt man sie beim Aufruf weg, verwendet das Programm einen voreingestellten Wert. Der ist oft konstant und lässt sich nur durch Neuübersetzen des Programms ändern.

Wer den Nutzern seiner Software entgegenkommen möchte, kann Default-Parameter variabel machen. Das Kompressions-Tool gzip etwa liest beim Start die Environment-Variable GZIP und interpretiert ihren Wert als zusätzliche Optionen, bevor es die Kommandozeile auswertet. So kann der Anwender etwa mit dem Shell-Kommando export GZIP=-9 standardmäßig die höchste Kompressionsstufe wählen, ohne die Option –9 bei jedem Aufruf zu übergeben. Das funktioniert auch, wenn ein anderes Programm – etwa targzip aufruft und man keinen Einfluss auf die Kommandozeile hat.

Allerdings stößt die Methode an ihre Grenzen, wenn viele Parameter zu setzen oder komplexere Werte wie Listen zu übergeben sind. In solchen Fällen empfiehlt sich der Einsatz einer Konfigurationsdatei – vorzugsweise in einem einfachen (Text-)Format, damit der Anwender sie leicht ändern kann. Zwar kann man auch XML-Dateien mit einem gewöhnlichen Texteditor bearbeiten, doch wer das einmal gemacht hat, möchte es wahrscheinlich nicht wieder tun.

Ein einfaches Format hat darüber hinaus den Vorteil, dass es sich leichter und schneller parsen lässt. Da das Programm die Konfiguration bei jedem Start liest, sollte der Vorgang nicht zu viel Zeit in Anspruch nehmen. Verbreitet sind Varianten des von Windows bekannten INI-Formats, die im Wesentlichen Zuweisungen der Form variable = wert oder variable: wert enthält. Bei Bedarf lassen die sich in mehrere Abschnitte gliedern, die jeweils mit [abschnitt] eingeleitet werden. Kommentare beginnen meist mit einem Semikolon oder # und enden am Ende der Zeile.

Parsen lassen sich solche Dateien zum Beispiel mit MiniINI (siehe Onlinequellen [a]). Die Bibliothek kann aus einer Datei oder aus dem Speicher lesen. Letzteres gestattet es unter anderem, komprimierte Konfigurationsdateien zu verwenden. Der in C++ geschriebene Parser ist auf Geschwindigkeit getrimmt und daher eher minimalistisch: Parameter können nur einen der Datentypen std::string, int, float oder bool haben, außerdem sind Arrays erlaubt. MiniINI ignoriert alle Leerzeichen, sodass es nicht möglich ist, Strings mit eingebetteten Leerzeichen ans Programm zu übergeben. Viele Anwendungen benötigen das jedoch ohnehin nicht.

Die in C geschriebene Bibliothek libiniparser [b] unterstützt die Datentypen String (char*), int, double und Boolean, wobei Letzterer ebenfalls int als Speicherelement nutzt. Der Parser erstellt aus der Konfigurationsdatei ein internes Verzeichnis (Typ dictionary), dessen Einträge sich vom Programm mit iniparser_set modifizieren lassen. Die Funktion iniparser_dump_ini schreibt die geänderte Konfiguration wieder in eine INI-Datei. Mit iniparser_dumpsection_ini lässt sich ein einzelner Abschnitt in einer Datei sichern.

parse_conf [c] versteht ein erweitertes Dateiformat, das es gestattet, einen Konfigurationsparameter in einem anderen zu referenzieren. Das ermöglicht Konstruktionen wie

libdir = /my/lib/dir
libfile = $(libdir)/file

Auf diese Art referenzierte Variablen müssen im selben oder im globalen Abschnitt definiert sein. Auf Variablen aus anderen Abschnitten kann man mit $[abschnitt](variable) zugreifen. Wie libiniparser gestattet es die parse_conf-Bibliothek, Parameter zu ändern und die modifizierte Konfiguration in eine Datei zu schreiben.

Verlangt die Anwendung eine hierarchische Konfiguration, kann der Entwickler zum Beispiel auf libconfig zurückgreifen [d]. Die Bibliothek versteht eine C-ähnliche Syntax, die neben skalaren Parametern auch Arrays und Listen unterstützt. Letztere schließen mehrere Werte – mit Kommas getrennt – in eckige beziehungsweise runde Klammern ein. Geschweifte Klammern dienen zum einen zum Aufbau der Variablenhierarchie, zum anderen zur Konstruktion von beliebigen Werte-Tupeln:

point = { x = 1; y = 2; z = 3; }; 

etwa definiert einen Punkt im dreidimensionalen Raum durch seine Koordinaten. Die lassen sich im Programm individuell abrufen: point.x etwa liefert nur die x-Koordinate. Außer den skalaren Grunddatentypen Boolean, String, int und double unterstützt die Bibliothek long long für Ganzzahlen mit 64 Bit. In der Konfigurationsdatei sind 64-Bit-Werte durch ein angehängtes „L“ erkennbar. libconfig bietet sowohl eine C- als auch eine C++-API.

Alle Links: www.ix.de/ix1306155 (mr)