Un file ha bisogno di un header, e le funzioni (almeno quelle importanti, che di solito sono quelle globali) hanno bisogno di una intestazione fatta come si deve (comunque anche le funzioni statiche si meritano un minimo di presentazione). Spero che il messaggio sia chiaro.
Va bene, e allora come lo facciamo un header ? Premettendo che le varianti possibili sono infinite, direi che, per cominciare, anche qualcosa semplice semplice, come questa, potrebbe andare:
/*! * FILE * getComments.c - estrazione commenti da un sorgente C * PROJECT * myDoc - generazione automatica documentazione * FUNCTIONS * globali: * getComments() * statiche: * formatLine() * AUTHOR * A.Abate * OPERATING SYSTEM * Linux (all versions) * COMPILER * GNU gcc * RELEASE * 1.0 (Settembre 2012) */Evidentemente si può abbondare più o meno con le descrizioni. Per esempio, se il file contiene il codice di un protocollo di comunicazione, si potrebbe aggiungere una descrizione a blocchi (un disegno in modo text) con le entità implicate e i flussi di comunicazione dei messaggi.
Per quanto riguarda le funzioni importanti, si può usare la classica sintassi delle Man Pages di Unix (e Linux), e quindi fare qualcosa del genere:
/*! * NAME * getComments - esamina un sorgente C per estrarre i commenti * SYNOPSIS * int getComments( * char *inpath, * char *oupath) * DESCRIPTION * Estrae i commenti da un sorgente C con pathname <inpath> e li * scrive in un file di documentazione con pathname <outpath>. * RETURN VALUE * 0 a operazione effettuata. Un valore negativo in caso di * errore. */E, anche qui, si può abbondare più o meno con le descrizioni, aggiungendo, per esempio, dettagli su tutti i codici di ritorno, e, se necessario, inserendo un ulteriore appartato EXAMPLES, con brevi esempi d'uso.
Come i più osservatori avranno notato, la prima riga dei due esempi qui sopra comincia con "/*!", ossia contiene un simbolo di riconoscimento per un eventuale tool di auto-generazione della documentazione (tipo Doxygen). E, sempre i più osservatori, avranno notato che anche il contenuto dei due esempi parla di auto-documentazione. Il fatto è che ho pensato di proporre un caso reale, e cosa c'è di meglio che scrivere, ad-hoc, un semplicissimo tool di documentazione che ho scritto e testato in pochissimo tempo (è veramente molto semplice, ma si può perfezionare).
Beh, il mini-tool sarebbe (quasi) tutto qua:
int getComments( char *inpath, char *oupath) { char *line = NULL; size_t len = 0; int retcode; bool start_comment = false; // apro il file di input FILE *fpin; if (fpin = fopen(inpath, "r")) { // apro il file di output FILE *fpout; if (fpout = fopen(oupath, "w")) { // leggo il file di input while (getline(&line, &len, fpin) != -1) { // test fine commenti per reset flag start_comment if (strstr(line, "*/") && start_comment) { start_comment = false; fprintf (fpout, "\n\n\n"); } // test flag start_comment if (start_comment) { // formatto e scrivo linea su file output fprintf(fpout, "%s", formatLine(line)); } // test inizio commenti per set flag start_comment if (strstr(line, "/*!")) start_comment = true; } // libera risorse e set retcode=OK fclose(fpout); free(line); retcode = 0; } else retcode = -2; // fopen err: set retcode=err fclose(fpin); // libera risorse } else retcode = -1; // fopen err: set retcode=err // esce con il retcode settato return retcode; }Direi che il codice è così intuitivo (e commentato) che non c'è molto da aggiungere: si cerca il codice di riferimento (/*!) e si copia in un file di documentazione tutto quello che lo segue fino a fine commento. La funzione formatLine() (che ho omesso) può non fare nulla (ossia restituire direttamente la linea passata), o fare qualche elaborazione più o meno sofisticata (come minimo raccomando di togliere gli inizi linea del tipo " *"). Io, per testare l'applicazione, ho scritto un main() che ricorre tutti i sorgenti di una directory e scrive i risultati in un altra directory (e, direi, funziona bene).
Quella presentata è una alternativa rapida ai vari tool tipo Doxigen, che sono, ovviamente, raccomandabili per grossi progetti (ma anche l'alternativa artigianale descritta non è male).
Chiudo con un messaggio per quelli che pensano (come già fatto notare qui) che scrivere i commenti (e, a maggior ragione, headers e descrizioni di funzioni) sia tempo perso che allunga i tempi di sviluppo. Bisogna avere larghezza di vedute, ragionare a lunga scadenza: anche se aumento del 10% i tempi di sviluppo (e documentare non richiede molto tempo, specie se lo fai mentre scrivi il codice), verrà il giorno in cui si recupererà con gli interessi il tempo perso in partenza, per esempio alla prima occasione di manutenzione o modifica (provate a farlo su un codice No Comment, poi mi raccontate...). E il tempo è denaro.
Ciao e al prossimo post.
Nessun commento:
Posta un commento