La question principale est la suivante: voulez-vous que votre fichier de configuration soit dans un langage complet de Turing (comme Python)? Si vous le souhaitez, vous pouvez également envisager d'intégrer un autre langage de script (complet de Turing) tel que Guile ou Lua (car il pourrait être perçu comme "plus simple" à utiliser, ou à intégrer, que Python; lisez le chapitre sur Extension & Incorporation de Python ). Je ne discuterai pas de cela plus avant (car d'autres réponses, comme Amon par exemple , en ont discuté en profondeur), mais remarquez que l' intégration d'un langage de script dans votre application est un choix architectural majeur , à prendre très tôt en compte.; Je ne recommande vraiment pas de faire ce choix plus tard!
Un exemple bien connu de programme configurable via des "scripts" est l' éditeur GNU emacs (ou probablement AutoCAD dans le domaine propriétaire); Sachez donc que si vous acceptez les scripts, un utilisateur utilisera éventuellement - et peut-être même abusera, de votre point de vue - cette installation de manière intensive et créera un script de plusieurs milliers de lignes. par conséquent, le choix d'un langage de script suffisant est important.
Cependant (du moins sur les systèmes POSIX), il peut être utile d’activer le calcul dynamique du "fichier" de configuration au moment de l’initialisation (bien sûr, le fardeau d’une configuration rationnelle incombant à votre administrateur système ou à votre utilisateur; c’est en fait une configuration. texte qui provient d’un fichier ou d’une commande). Pour cela, vous pouvez simplement adopter la convention (et la documenter ) selon laquelle un chemin de fichier de configuration commençant par, par exemple, a !
ou |
est en fait une commande shell que vous liriez comme un pipeline . Cela laisse à l'utilisateur le choix d'utiliser le "préprocesseur" ou le "langage de script" avec lequel il est le plus familier.
(vous devez faire confiance à votre utilisateur pour les problèmes de sécurité si vous acceptez une configuration calculée dynamiquement)
Ainsi, dans votre code d’initialisation, vous main
accepteriez (par exemple) des --config
arguments confarg
et en retirerions des argumentsFILE*configf;
. Si cet argument commence par !
(c'est-à-dire si (confarg[0]=='!')
....), vous utiliseriez configf = popen(confarg+1, "r");
et fermez ce tuyau avec pclose(configf);
. Sinon, vous utiliseriez configf=fopen(confarg, "r");
et fermeriez ce fichier avec fclose(configf);
(n'oubliez pas la vérification des erreurs). Voir pipe (7) , popen (3) , fopen (3) . Pour une application codée en Python, lisez à propos de os.popen , etc ...
(document également pour l'utilisateur étrange qui souhaite passer un fichier de configuration nommé !foo.config
à passer ./!foo.config
pour contourner l' popen
astuce ci-dessus)
En passant, une telle astuce n’est qu’une commodité (pour éviter d’obliger l’utilisateur avancé à coder par exemple un script shell pour générer un fichier de configuration ). Si l'utilisateur souhaite signaler un bogue, il doit vous envoyer le fichier de configuration généré ...
Notez que vous pouvez également concevoir votre application avec la possibilité d’utiliser et de charger des plugins au moment de l’initialisation, par exemple avec dlopen (3) (et vous devez faire confiance à votre utilisateur pour ce plugin). Là encore, il s’agit d’une décision très importante en matière d’architecture (et vous devez définir et fournir des API et des conventions relativement stables concernant ces plug-ins et votre application).
Pour une application codée dans un langage de script tel que Python, vous pouvez également accepter certains arguments de programme pour les primitives eval ou exec ou similaires. Encore une fois, les problèmes de sécurité sont alors la préoccupation de l'utilisateur (avancé) .
En ce qui concerne le format textuel pour votre fichier de configuration (que ce soit généré ou non), je crois que vous avez besoin surtout pour documenter bien (et le choix d' un certain format particulier est pas si important que cela, mais je vous recommande de laisser votre utilisateur soit en mesure de mettre quelques-uns commentaires commentés à l'intérieur). Vous pouvez utiliser JSON (de préférence avec un analyseur JSON acceptant et ignorant les commentaires avec les //
lettres habituelles jusqu’à eol ou /*
... */
...), ou YAML, ou XML, ou INI ou votre propre chose. L'analyse d'un fichier de configuration est relativement facile (et vous trouverez de nombreuses bibliothèques liées à cette tâche).