Quali sono le migliori pratiche considerate per l'utilizzo / la guida della stampa (--help)?


13

Durante la scrittura di strumenti per l'interfaccia della riga di comando di UNIX, come devo fare in modo che il programma stampi aiuto e / o utilizzo?

Di solito lo uso fprintf(stderr, "help text here");, ma ci sono diversi problemi.

  • Innanzitutto, non sono sicuro se dovrei usare stderr. Va bene o dovrei usare stdout?
  • Come puoi immaginare, il testo della guida è piuttosto lungo, a seconda di quante opzioni ha lo strumento. Ora, di solito, ne inserisco diversi "strings like that\n"nel secondo parametro. Questo, tuttavia, riempie il mio codice sorgente con cinquanta o più righe di testo di aiuto. Non è affatto facile da gestire. Cosa dovrei fare invece?
  • Quando uno strumento non è scritto in C o in un linguaggio simile a C, tendo ad usare qui-documenti ove possibile (soprattutto con Perl). Non posso usarlo in C, ma c'è qualcosa del genere che potrei usare?
  • Stavo pensando di metterlo in un headerfile.hinterno a #define HELP "help text here", non l'ho mai visto in natura, non so se dovrei davvero usarlo.

Idealmente, potrei mettere il testo in un file esterno e includerlo. L'uso #includeper quello sembra sbagliato, però. Cosa dovrei fare allora?

L'idea è di avere un testo di aiuto facilmente gestibile. Avere all'interno del codice sorgente non è davvero conveniente.


1
Cosa c'è di così brutto in 50 righe nel tuo codice sorgente? Mettilo alla fine. Non è che dovrai rovinarlo regolarmente.
whatsisname

2
Utilizzo di @whatsisname, aiuto per normali e longopts. Alla fine ho circa 200 righe di stringhe nel codice sorgente. A parte questo, non penso che questa sia la migliore pratica, ecc. Ci deve essere un modo più efficiente di inserire testi di aiuto, ecc.
polemon,

Risposte:


8

Ispirati dagli interni della tua piattaforma target

Dai un'occhiata al codice sorgente del BSD. Ad esempio, ecco i seguenti:

  • usage(void)per lo /usr/bin/unamestrumento di NetBSD [ fonte ]:

    usage(void)
    {
        fprintf(stderr, "usage: uname [-amnprsv]\n");
        exit(EXIT_FAILURE);
    }
    
  • usage(void)per /usr/bin/telnet[ fonte ] di NetBSD

  • usage(void)per /bin/ls[ fonte ] di OpenBSD

Dai un'occhiata alle alternative

E decidi tu stesso se stanno meglio o peggio. Puoi utilizzare Google CodeSearch per trovare altri, come:

  • Utilizzo di SkyLoad [ fonte ]

Come puoi vedere, uno stile diverso tra questi e gli strumenti integrati dei sistemi BSD elencati sopra. Esso non significa che devi seguire uno o l'altro. Ma di solito è bello guardarsi intorno e accontentarsi della soluzione coerente.

Una soluzione non standard per le 50 linee di aiuto ...

Se non ti piace evitare 50 righe di testo, puoi semplicemente leggere la guida da un file di testo (in testo normale, o forse analizzare direttamente la manfonte se ne hai creata una). Trovo che sia un modo piuttosto elegante (come puoi anche consultare il documento di testo), tuttavia per i programmi di sistemi di base che li renderebbero intrinsecamente insicuri e introdurrebbero un punto di errore. Altre persone sosterranno che è pesante per un usageo un helpmessaggio, ma non è che questi siano chiamati in loop stretti veloci ...

In caso di dubbi, segui i giganti.


9

Uso stdoutperché un aiuto non è un errore.

Se questo è un lungo aiuto in C, provo a imitare qui-docs:

printf("This is the help for MyWonderfulApp\n"
       "Options are:\n"
       "    --help: display what you are reading now\n"
       "    --quiet: output nothing\n");

Ma il più delle volte scrivo una manpagina usando nroff -mantag dedicati. La guida in-app consiste semplicemente nel fare riferimento a quella manpagina.


Ma l'aiuto non è necessariamente un output standard desiderabile, vero? Che ne dici stdlog?
Greyfade,

@greyfade: è lo stdlogstandard C?
mouviciel,

@mouviciel: ... Ho pensato che lo fosse. Non credo. C ++ ha un flusso standard correlati ( cin, cout, cerre clog), quindi credo che ho pensato che stdlogera in C standard. Colpa mia.
Greyfade,

2

Se sarei io ti avevo appena aperto fonti di grep, tail, cat, your_other_favorite_unix_shell_commandper vedere come è fatto lì. Sono abbastanza sicuro che i loro modi siano abbastanza ben studiati e possano essere mantenuti da molte persone.

Informazioni su stderro stdout. È davvero semplice, se c'è un errore - scrivi a stderr, se sono solo informazioni - stdout. Ad esempio, se eseguo il tuo strumento con opzioni errate, potresti voler visualizzare un errore, ad esempio Use --help for usage, questo appartiene stderr. Se eseguo il tuo strumento con un'opzione valida --help, ti preghiamo di utilizzare stdout.

Se preferisci non avere stringhe di aiuto lunghe vicino al tuo codice, non farlo. #define in un file di intestazione va benissimo, ma è davvero una preferenza personale. Se dovessi leggere il codice di uno strumento da riga di comando preferirei che la sua stringa di aiuto si trovasse all'interno di un file che gestisce le opzioni fornite dall'utente.


2
Questo non risponde alla sua domanda.
Mavrik,

Hm, che succede con il meno? Per che cosa?
devmiles.com

@Mavrik: lo fa il primo paragrafo.
haylem,

1

Uso la libreria gnu getopts . Per un esempio con l'aiuto, vedere questo progetto di esempio , in particolare il metodo principale nella parte inferiore di parser.y .

Dato che è racchiuso tra parentesi graffe, l'editor vim che uso può piegare le linee insieme e non le noto nemmeno quando non ne ho bisogno.


1

Se uso C o preferisco non dipendere dalle librerie Boost, allora mi attengo a GNU getopt. Altrimenti preferisco le opzioni del programma Boost che stampano automaticamente la guida.

Considero anche di indovinare l'opzione giusta una delle migliori pratiche in termini di gestione delle opzioni. L'ho imparato da Git e ora uso lo stesso nei miei progetti. In pratica utilizza la distanza Damerau-Levenshtein per stampare le migliori corrispondenze se l'utente inserisce un'opzione della riga di comando sconosciuta.

Ho scritto un piccolo articolo su questo che puoi usare come esempio.

Spero che sia d'aiuto :)


1

Ovviamente, scrivere una pagina di apertura nel codice cout << o printf () è scomodo, in particolare se è necessario modificare e riempire nuovamente i paragrafi. Quindi, è ovviamente una buona idea modificare quel testo in un file separato, usando ad esempio emacs dove puoi formattare più facilmente il tuo testo.

Quindi è possibile utilizzare il seguente script sed per convertire quel file di testo in un file di intestazione C legale:

s/\"/\\\"/g
s/$/\\n"/
s/^/"/
1i\
const char *helpStr = 
$a\
;

Quindi, dopo #include -ing del file di intestazione nel codice sorgente, puoi semplicemente scrivere il tuo testo usando

cout << helpStr;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.