2012-12-19 14 views
9

Dire che ho un file eseguibile (in esecuzione su Mac, Win e Linux)parsing "condizionale" di argomenti della riga di comando

a.out [-a] [-b] [-r -i <file> -o <file> -t <double> -n <int> ] 

dove un argomento in [ ] significa che è facoltativa. Tuttavia, se è stato impostato l'ultimo argomento -r, è necessario fornire anche -i, -o, -t e -n.

Esistono molte buone librerie C++ per analizzare gli argomenti della riga di comando, ad es. gflags(), simpleopt (http://code.jellycan.com/simpleopt/), boost.program_options (http://www.boost.org/doc/libs/1_52_0/doc/html/program_options.html), ecc. Ma mi chiedevo se ce n'è uno che consente di codificare queste relazioni condizionali tra argomenti direttamente, senza codificare manualmente la gestione degli errori

if (argR.isSet() && (! argI.isSet() || ! argO.isSet() || ...)) ... 

e impostazione manuale di --help.

La libreria tclap consente di argomenti XOR, ad es. o -a o -b è consentito ma non entrambi. Quindi, in quella terminologia, un AND per argomenti sarebbe bello.

Qualcuno conosce una libreria versatile, leggera e multipiattaforma che può farlo?

+0

[Qui] (http://www.boost.org/libs/program_options/example/real.cpp) è l'esempio di Boost.Program_options che gestisce opzioni in conflitto e dipendenti. –

risposta

2

È possibile passare due volte gli argomenti; Se -r è nelle opzioni, reimpostare il parser e ricominciare con le nuove opzioni obbligatorie aggiunte.


Si potrebbe anche prendere in considerazione come le TCLAP XorHandler opere, e creare il proprio AndHandler.

+0

Sì, l'ho provato, ma poi devi ancora codificare la schermata di aiuto (che non è un problema, ma sarebbe bello avere). Aggiungere AndHandler sarebbe una buona opzione, immagino. – nils

+0

@Nick La schermata della guida richiede comunque una gestione speciale. Una cosa che mi piace delle opzioni del programma Boost è che non mostra la schermata di aiuto, ma devi fornire la tua opzione '--help', controllarla e stampare da solo la guida. In questo modo puoi semplicemente aggiungere le opzioni speciali e stampare tutto in una volta. –

0

È possibile modificare la sintassi dell'argomento in modo che -r utilizzi quattro valori in una riga.

+2

Questo sarebbe piuttosto confuso, tuttavia, poiché non è così che gli argomenti generalmente funzionano –

+0

Vero, tuttavia, potrebbero essere diversi tipi di dati. Per quanto ne so, le librerie citate nella domanda gestiscono i multi-argomenti (solo) come un unico tipo. – nils

0

ho parte della TCLAP frammento di codice in giro che sembra adattarsi alla porzione gestione degli errori che stai cercando, ma non corrisponde esattamente quello che stai cercando:

# include "tclap/CmdLine.h" 

namespace TCLAP { 

class RequiredDependentArgException : public ArgException { 
public: 
    /** 
    * Constructor. 
    * \param text - The text of the exception. 
    * \param parentArg - The text identifying the parent argument source 
    * \param dependentArg - The text identifying the required dependent argument 
    * of the exception. 
    */ 
    RequiredDependentArgException(
    const TCLAP::Arg& parentArg, 
    const TCLAP::Arg& requiredArg) 
    : ArgException(
    std::string("Required argument ") + 
    requiredArg.toString() + 
    std::string(" missing when the ") + 
    parentArg.toString() + 
    std::string(" flag is specified."), 
    requiredArg.toString()) 
    { } 
}; 

} // namespace TCLAP 

e poi usufruire della nuova eccezione dopo TCLAP::CmdLine::parse è stato chiamato:

if (someArg.isSet() && !conditionallyRequiredArg.isSet()) { 
    throw(TCLAP::RequiredDependentArgException(someArg, conditionallyRequiredArg)); 
} 

ricordo di aver guardato a estendere e l'aggiunta di una classe supplementare che avrebbe gestito questa logica, ma poi ho capito l'unica cosa che mi è stato effettivamente lookin g era un bel errore di segnalazione perché la logica non era del tutto semplice e non poteva essere facilmente condensata (almeno, non in un modo che era utile al prossimo povero ragazzo che arrivava). Uno scenario artificioso mi ha dissuaso dal perseguire ulteriormente, qualcosa con l'effetto di "se A è vero, B deve essere impostato ma C non può essere impostato se D è di valore N." Esprimere queste cose nel C++ nativo è la strada da percorrere, specialmente quando arriva il momento di fare controlli molto severi sugli argomenti in CLI arg.

Per casi e requisiti veramente patologici, creare una macchina a stati utilizzando qualcosa come Boost.MSM (Macchina a più stati). HTH.

Problemi correlati