Конфиги
Итак, что у нас по конфигам?
Мне нужны конфиги со следующими критериями:
- простые, читаемые человеком и обрабатываемые sed'ом
- с высокой скоростью разбора (поскольку, tool может вызываться чем-то вроде xargs)
- поддержка структур, hex-значений, списков, массивов - не нужна, у меня 3 типа данных - int, string и bool
Выбор главным образом:
- формата (нескучный/ini/xml/...)
- парсера (самописный/внешняя библиотека)
Что я смотрел из форматов:
В итоге, посмотрев всё вышеперечисленное, пришёл к выводу, что больше всех мне подошёл бы ini. Но, посмотрев в репу в поисках библиотек нашёл только libini-config2, которая к тому же This package is part of the ding-libs, libraries that are required for the proper functioning of SSSD, the System Security Services Daemon.
Посмотрим, кто её использует:
[alex@caspar ~]$ apt-cache rdepends libini-config2
sssd-tools
sssd
python-sss
libini-config-dev
Мде, одна единственная утилита, питоний биндинг к ней и её же хидер. Выходит все крутые парни пишут собственный парсер. Чтож, придётся и мне писать велосипед, поскольку всё остальное дико избыточно для моего случая.
Остановился на следующем варианте (синтаксис идентичен sysctl.conf):
## Пример конфига для версии выше 0.5
## опции демона
daemon.socket = /var/run/xa-tags/socket
daemon.address = 127.0.0.1
daemon.port = 7982
; используются только если запускаем от root'а
daemon.uid = nobody
daemon.gid = nogroup
; уходить в фон при запуске?
daemon.fork = false
daemon.loglevel = info
daemon.pid = /var/run/xa-tags/pid
## опции базы, используются tool'ом и daemon'ом
db.driver = sqlite3
; используется только для sqlite
db.path = /var/lib/xa-tags/db.sqlite3
; используется во всех остальных случаях
db.user = username
db.pass = password
; различные опции для базы
; использовать транзакции?
db.async = true
; запретить все модификации базы?
db.readonly = true
; время между коммитами в секундах
db.commit = 5
## неймспейсы, используются так же как и 'db.'
; - второй компонент имени - шорткат неймспейса
; - значение - путь, все файлы ниже которого
; попадают в неймспейс
namespace.films = /mnt/data/films
namespace.test = /mnt/data/upload
## различные опции
tool.loglevel = info
client.loglevel = info
Это полный конфиг для всех компонентов. Разбор конфига в теории прост до безобразия - построчно пропускаем через regexp, всё что не совпало - в отвал, это комментарии, всё что совпало - первое совпадение - имя ключа, второе - значение. Далее у имени ключа проверяется префикс и отправляется в нужный обработчик для дальнейшей валидации.