Головне питання: чи хочете, щоб ваш конфігураційний файл був на якійсь мові Тьюрінга (як Python)? Якщо ви цього хочете, ви можете також розглянути можливість вбудовування будь-якої іншої мови (сценарій Тюрінга), такої як Guile або Lua (оскільки там можна сприймати як "простіший" для використання або вбудовування, ніж Python; читайте розділ Розширення & Вбудовування Python ). Я не буду це обговорювати далі (тому що інші відповіді - наприклад , Амон - обговорювали це глибоко), але зауважу, що вбудованість мови сценаріїв у ваш додаток є головним архітектурним вибором , про який слід розглянути дуже рано; Я дійсно не рекомендую робити цей вибір пізніше!
Добре відомий приклад налаштування програми через "скрипти" - це редактор GNU emacs (або, можливо, AutoCAD у власній царині); тож майте на увазі, що якщо ви приймете сценарій, якийсь користувач врешті-решт використовуватиме - і, можливо, зловживає, з точки зору вашої точки зору - цей інструмент і зробить сценарій з багатотисячним рядком; тому вибір важливої мови сценаріїв є важливим.
Однак (принаймні, в системах POSIX), ви можете вважати зручним включити "файл" конфігурації динамічно обчислюватися під час ініціалізації (звичайно, залишаючи тягар розумної конфігурації вашому системному адміністратору або користувачеві; насправді це конфігурація текст, який надходить з якогось файлу або з якоїсь команди). Для цього ви можете просто прийняти умову (і документувати її), що шлях конфігураційного файлу, що починається, наприклад, з a !
або a, |
є насправді командою оболонки, яку ви читали б як конвеєр . Це залишає користувачеві можливість вибору будь-якого «препроцесора» або «мови сценаріїв», з якої він найбільш знайомий.
(вам потрібно довіритися своєму користувачеві щодо проблем безпеки, якщо ви приймаєте динамічно обчислені конфігурації)
Тож у коді ініціалізації ви main
(наприклад) приймете якийсь --config
аргумент confarg
і отримаєте FILE*configf;
його з нього. Якщо цей аргумент починається з !
(тобто, якщо (confarg[0]=='!')
....), ви б використовували configf = popen(confarg+1, "r");
та закривали цю трубку pclose(configf);
. Інакше ви б використали configf=fopen(confarg, "r");
та закрили цей файл за допомогою fclose(configf);
(не забудьте перевірку помилок). Дивіться труба (7) , попен (3) , фопен (3) . Для програми, закодованої в Python, прочитайте про os.popen тощо.
(документ також для дивного користувача, який хоче передати файл конфігурації, іменований !foo.config
для передачі, ./!foo.config
щоб обійти popen
фокус вище)
До речі, такий трюк є лише зручністю (щоб не вимагати від досвідченого користувача, наприклад, кодувати якийсь скрипт оболонки для створення файлу конфігурації ). Якщо користувач хоче повідомити про будь-яку помилку, він повинен надіслати вам створений файл конфігурації ...
Зауважте, що ви також можете розробити свою програму з можливістю використання та завантаження плагінів під час ініціалізації, наприклад, з dlopen (3) (і вам потрібно довіряти своєму користувачеві про цей плагін). Знову ж таки, це дуже важливе архітектурне рішення (і вам потрібно визначити та надати деякі досить стабільні API та умови щодо цих плагінів та вашої програми).
Для додатки , закодоване в мові сценаріїв , як Python ви можете також прийняти деякі програми аргумент для Eval або Exec або подібних примітивів. Знову ж таки, питання безпеки викликають занепокоєння (просунутого) користувача.
Що стосується текстового формату вашого файлу конфігурації (генерується він чи ні), я вважаю, що в основному вам потрібно добре його документувати (а вибір якогось конкретного формату не так важливий; проте я рекомендую дозволити вашому користувачеві мати можливість розмістити дещо -сказано- коментарі всередині нього). Ви можете використовувати JSON (бажано, щоб якийсь аналізатор JSON приймав і пропускав коментарі звичайними //
до eol або /*
... */
...), або YAML, або XML, або INI або власною справою. Розбирати файл конфігурації досить просто (і ви знайдете багато бібліотек, пов’язаних із цим завданням).