La domanda principale è: vuoi che il tuo file di configurazione sia in un linguaggio completo di Turing (come lo è Python)? Se lo desideri, potresti anche prendere in considerazione l'idea di incorporare un altro linguaggio di scripting (Turing completo) come Guile o Lua (perché potrebbe essere percepito come "più semplice" da usare o da incorporare rispetto a Python; leggi il capitolo su Estensione e & Incorporamento di Python ). Non ne discuterò ulteriormente (perché altre risposte - di Amon - ne hanno discusso in profondità), ma noto che incorporare un linguaggio di scripting nella tua applicazione è una scelta architettonica importante , che dovresti considerare molto presto; Non raccomando davvero di fare questa scelta in seguito!
Un esempio ben noto di un programma configurabile tramite "script" è l' editor di emacs GNU (o probabilmente AutoCAD nel regno proprietario); quindi tieni presente che se accetti lo scripting, qualche utente alla fine userebbe, e forse abuserà, dal tuo punto di vista, tale funzionalità ampiamente e creerebbe uno script con più di mille righe; quindi la scelta di un linguaggio di scripting abbastanza buono è importante.
Tuttavia (almeno su sistemi POSIX), si potrebbe considerare conveniente per consentire il "file" di configurazione per essere dinamicamente calcolato in fase di inizializzazione (naturalmente, lasciando l'onere di una configurazione sano al vostro amministratore di sistema o l'utente; in realtà si tratta di una configurazione testo che proviene da un file o da un comando). Per questo, potresti semplicemente adottare la convenzione (e documentarla ) che un percorso del file di configurazione che inizia con es. A !
o a |
è in realtà un comando di shell che dovresti leggere come pipeline . Ciò lascia all'utente la scelta di utilizzare qualsiasi "preprocessore" o "linguaggio di scripting" con cui ha più familiarità.
(devi fidarti del tuo utente riguardo ai problemi di sicurezza se accetti una configurazione calcolata dinamicamente)
Quindi, nel tuo codice di inizializzazione, main
accetteresti (ad esempio) un --config
argomento confarg
e ne ricaveresti un po FILE*configf;
'. Se quell'argomento inizia con !
(cioè se (confarg[0]=='!')
....), useresti configf = popen(confarg+1, "r");
e chiuderesti quella pipe con pclose(configf);
. Altrimenti dovresti usare configf=fopen(confarg, "r");
e chiudere quel file con fclose(configf);
(non dimenticare il controllo degli errori). Vedi pipe (7) , popen (3) , fopen (3) . Per un'applicazione codificata in Python leggi di os.popen , ecc ...
(documento anche per l'utente strano che desidera passare un file di configurazione chiamato !foo.config
per passare ./!foo.config
per aggirare il popen
trucco sopra)
A proposito, un simile trucco è solo una comodità (per evitare che l'utente avanzato debba, ad esempio, codificare alcuni script di shell per generare un file di configurazione ). Se l'utente desidera segnalare un bug, deve inviarti il file di configurazione generato ...
Nota che potresti anche progettare la tua applicazione con la possibilità di usare e caricare plugin al momento dell'inizializzazione, ad esempio con dlopen (3) (e devi fidarti del tuo utente su quel plugin). Ancora una volta, questa è una decisione architetturale molto importante (e devi definire e fornire alcune API e convenzioni piuttosto stabili su questi plugin e la tua applicazione).
Per un'applicazione codificata in un linguaggio di scripting come Python potresti anche accettare alcuni argomenti del programma per eval o exec o primitive simili. Ancora una volta, i problemi di sicurezza sono quindi la preoccupazione dell'utente (avanzato) .
Per quanto riguarda il formato testuale per il tuo file di configurazione (sia esso generato o meno), credo che devi principalmente documentarlo bene (e la scelta di un determinato formato non è così importante; tuttavia ti consiglio di lasciare che il tuo utente sia in grado di mettere alcuni commenti -skipping- al suo interno). Puoi usare JSON (preferibilmente con un parser JSON che accetta e salta i commenti con la solita //
fino a eol o /*
... */
...), o YAML, o XML, o INI o le tue cose. L'analisi di un file di configurazione è ragionevolmente semplice (e troverai molte librerie relative a quell'attività).