The main question is: do you want your configuration file to be in some Turing complete language (like Python is)? If you do want that, you might also consider embedding some other (Turing complete) scripting language like Guile or Lua (because there could be perceived as "simpler" to use, or to embed, than Python is; read the chapter on Extending & Embedding Python). I won't discuss that further (because other answers -e.g. by Amon- discussed that in depth) but notice that embedding a scripting language in your application is a major architectural choice, that you should consider very early; I really don't recommend making that choice later!
Відомим прикладом програми, що можна налаштувати через "скрипти", є редактор GNU emacs AutoCAD у власному регіоні); так що знайте, що якщо ви приймаєте сценарії, деякі користувачі зрештою використають - і, можливо, зловживають, у вашій точці зору - цю об'єкт широко і роблять скрипт з декількох тисяч рядків; отже, важливим є вибір досить гарної мови сценаріїв.
Проте (принаймні, у системах POSIX) можна вважати зручним, якщо файл конфігурації “динамічно обчислюється під час ініціалізації (звичайно, залишається тягар нормальної конфігурації для системного адміністратора або користувача, насправді це конфігурація text , яка надходить з деяких файлів або з деяких команд). Для цього можна просто прийняти конвенцію (і документ ), що шлях конфігураційного файлу починається з напр. !
або |
насправді є командою , яку ви читаєте як . Це залишає ваш користувач з можливістю вибору будь-якого "препроцесора" або "мови сценаріїв", з яким він найбільш знайомий.
(потрібно довіряти користувачеві щодо проблем безпеки, якщо ви приймаєте динамічно обчислену конфігурацію)
Таким чином, у коді ініціалізації ваш main
(наприклад) прийме --config
аргумент confarg
і отримати з нього FILE * configf;
. Якщо цей аргумент починається з !
(тобто якщо (confarg [0] == '!')
....), ви повинні використовувати configf = popen ( confarg + 1, "r");
і закрийте цю трубку за допомогою pclose (configf);
. В іншому випадку ви використовуєте configf = fopen (confarg, "r");
і закрийте цей файл за допомогою fclose (configf);
(не забудьте перевірити помилки). Див. трубу (7) , popen (3) , fopen (3) . Про програму, закодовану в Python, читайте про os.popen , і т.д.
(документ також для дивного користувача, який бажає передати файл налаштування з ім'ям ! foo.config
, щоб передати ./!foo.config
, щоб обійти
підказка вище)
Нарешті, такий прийом - це лише зручність (щоб не вимагати від просунутих користувачів, наприклад, кодувати сценарій оболонки, щоб генерувати файл налаштування ). Якщо користувач бажає повідомити про будь-яку помилку, він повинен надіслати вам згенерований файл конфігурації ...
Зверніть увагу, що ви також можете розробити свою програму з можливістю використання та завантаження плагінів під час ініціалізації, напр dlopen (3) (і ви повинні довіряти своєму користувачеві) про цей плагін). Знову ж таки, це дуже важливе архітектурне рішення (і вам потрібно визначити і надати досить стійкий API і правила щодо цих плагінів і вашої програми).
For an application coded in a scripting language like Python you could also accept some program argument for eval or exec or similar primitives. Again, the security issues are then the concern of the (advanced) user.
Regarding the textual format for your configuration file (be it generated or not), I believe that you mostly need to document it well (and the choice of some particular format is not that important; however I recommend to let your user be able to put some -skipped- comments inside it). You could use JSON (preferably with some JSON parser accepting and skipping comments with usual //
till eol or /*
...*/
...), or YAML, or XML, or INI or your own thing. Parsing a configuration file is reasonably easy (and you'll find many libraries related to that task).