10.12.2010

Размышления об идеальном формате конфигов

Когда у меня возникла необходимость написать парсер конфиг-файла, то я сначала решил нарисовать парсер ini-файлов, а потом задумался. Ведь на самом деле то ini несколько туповатый формат. Да и измерения всего два. Нехорошо както.


XML я изначально не люблю. Ну не нравится он мне. Огромный оверхед, тегов как правило больше, чем полезной информации. Нет, можно конечно писать короткие теги, но проку от такого конфига будет? Неинформативен ибо.


И вотсобственно я задумался, и поставил несколько постулатов:

  • Конфиг должен быть читабельный

  • Необходимо неограниченное количество измерений

  • Необходимо поддерживать типы данных

  • Помимо парсера нужен также и генератор


В итоге у меня родилось нечто похожее на перловые хеши.

Вид у конфига такой:


name.name.name.value=11; # int
name
{
my.other_value="String"; # string
word=12,3; # float
inner
{
new_block
{
a.b.c=12;
c.d="my string value";
}
}
}
my.other=on; # bool

Попробую пояснить.
Точки и фигурные скобки разделяют имена, после = пишется значение. a.b.c=1; равнозначно a{b{c=1;}}, пока что поддерживаются 4 типа данных: строки, целые, числа с плавающей точкой и bool. Комментарии начинаются с '#' (если он не в строке) и продолжаются до конца строки. Имя должно начинаться с буквы и может содержать в себе букву, цифру и '_'. Пробелы, табы игнорируются, но не внутри имени или значения. В float '.' и ',' - равнозначны.

Подумываю над поддержкой списков - надо ли? Ведь список можно "эмулировать" както типа 'a {b0=0;b1=1;b2=2;b3=3;}'.

Вобщем это все уже в принципе реализовано, но пока что не отдельной библиотекой, а в рамках одного моего проекта (хотя таки да, там это библиотека).

Доступ к данным изнутри кода реализован както вот так:


CConfig config;
config.load("/path/file.conf");
int a = config.root().folder("a").folder("b").file("c").get(123 /*default value*/);
std::string s = config.root().folder("a").folder("b").file("c").toString(); // result: "123"
config.root().folder("a").folder("b").file("c1").set(12,34);
config.save("/tmp/file");

Да, генератор тоже реализован, причем рисует оптимальный конфиг, тоесть пользуется разделителями ( . { } ) с умом.

Как вы считаете, я ничего не забыл?


Оригинал записи - в личном блоге. Комментировать можно тут, но желательно там.

Комментариев нет: