code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>

.. _it_codingstyle:

Stile del codice per il kernel Linux
====================================

Questo è un breve documento che descrive lo stile di codice preferito per
il kernel Linux.  Lo stile di codifica è molto personale e non voglio
**forzare** nessuno ad accettare il mio, ma questo stile è quello che
dev'essere usato per qualsiasi cosa che io sia in grado di mantenere, e l'ho
preferito anche per molte altre cose.  Per favore, almeno tenete in
considerazione le osservazioni espresse qui.

La prima cosa che suggerisco è quella di stamparsi una copia degli standard
di codifica GNU e di NON leggerla.  Bruciatela, è un grande gesto simbolico.

Comunque, ecco i punti:

1) Indentazione
---------------

La tabulazione (tab) è di 8 caratteri e così anche le indentazioni. Ci sono
alcuni movimenti di eretici che vorrebbero l'indentazione a 4 (o perfino 2!)
caratteri di profondità, che è simile al tentativo di definire il valore del
pi-greco a 3.

Motivazione: l'idea dell'indentazione è di definire chiaramente dove un blocco
di controllo inizia e finisce.  Specialmente quando siete rimasti a guardare lo
schermo per 20 ore a file, troverete molto più facile capire i livelli di
indentazione se questi sono larghi.

Ora, alcuni rivendicano che un'indentazione da 8 caratteri sposta il codice
troppo a destra e che quindi rende difficile la lettura su schermi a 80
caratteri.  La risposta a questa affermazione è che se vi servono più di 3
livelli di indentazione, siete comunque fregati e dovreste correggere il vostro
programma.

In breve, l'indentazione ad 8 caratteri rende più facile la lettura, e in
aggiunta vi avvisa quando state annidando troppo le vostre funzioni.
Tenete ben a mente questo avviso.

Al fine di facilitare l'indentazione del costrutto switch, si preferisce
allineare sulla stessa colonna la parola chiave ``switch`` e i suoi
subordinati ``case``. In questo modo si evita una doppia indentazione per
i ``case``.  Un esempio.:

.. code-block:: c

	switch (suffix) {
	case 'G':
	case 'g':
		mem <<= 30;
		break;
	case 'M':
	case 'm':
		mem <<= 20;
		break;
	case 'K':
	case 'k':
		mem <<= 10;
		fallthrough;
	default:
		break;
	}

A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla
stessa riga:

.. code-block:: c

	if (condition) do_this;
	  do_something_everytime;

Non usate le virgole per evitare le parentesi:

.. code-block:: c

	if (condition)
               do_this(), do_that();

Invece, usate sempre le parentesi per racchiudere più istruzioni.

.. code-block:: c

	if (condition) {
               do_this();
               do_that();
       }

Non mettete nemmeno più assegnamenti sulla stessa riga.  Lo stile del kernel
è ultrasemplice.  Evitate espressioni intricate.

Al di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli
spazi non vengono mai usati per l'indentazione, e l'esempio qui sopra è
volutamente errato.

Procuratevi un buon editor di testo e non lasciate spazi bianchi alla fine
delle righe.

2) Spezzare righe lunghe e stringhe
-----------------------------------

Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando
strumenti comuni.

Come limite di riga si preferiscono le 80 colonne.

Espressioni più lunghe di 80 colonne dovrebbero essere spezzettate in
pezzi più piccoli, a meno che eccedere le 80 colonne non aiuti ad
aumentare la leggibilità senza nascondere informazioni.

I nuovi pezzi derivati sono sostanzialmente più corti degli originali
e vengono posizionati più a destra. Uno stile molto comune è quello di
allineare i nuovi pezzi alla parentesi aperta di una funzione.

Lo stesso si applica, nei file d'intestazione, alle funzioni con una
lista di argomenti molto lunga.

Tuttavia, non spezzettate mai le stringhe visibili agli utenti come i
messaggi di printk, questo perché inibireste la possibilità
d'utilizzare grep per cercarle.

3) Posizionamento di parentesi graffe e spazi
---------------------------------------------

Un altro problema che s'affronta sempre quando si parla di stile in C è
il posizionamento delle parentesi graffe.  Al contrario della dimensione
dell'indentazione, non ci sono motivi tecnici sulla base dei quali scegliere
una strategia di posizionamento o un'altra; ma il modo qui preferito,
come mostratoci dai profeti Kernighan e Ritchie, è quello di
posizionare la parentesi graffa di apertura per ultima sulla riga, e quella
di chiusura per prima su una nuova riga, così:

.. code-block:: c

	if (x is true) {
		we do y
	}

Questo è valido per tutte le espressioni che non siano funzioni (if, switch,
for, while, do).  Per esempio:

.. code-block:: c

	switch (action) {
	case KOBJ_ADD:
		return "add";
	case KOBJ_REMOVE:
		return "remove";
	case KOBJ_CHANGE:
		return "change";
	default:
		return NULL;
	}

Tuttavia, c'è il caso speciale, le funzioni: queste hanno la parentesi graffa
di apertura all'inizio della riga successiva, quindi:

.. code-block:: c

	int function(int x)
	{
		body of function
	}

Eretici da tutto il mondo affermano che questa incoerenza è ...
insomma ... incoerente, ma tutte le persone ragionevoli sanno che (a)
K&R hanno **ragione** e (b) K&R hanno ragione.  A parte questo, le funzioni
sono comunque speciali (non potete annidarle in C).

Notate che la graffa di chiusura è da sola su una riga propria, ad
**eccezione** di quei casi dove è seguita dalla continuazione della stessa
espressione, in pratica ``while`` nell'espressione do-while, oppure ``else``
nell'espressione if-else, come questo:

.. code-block:: c

	do {
		body of do-loop
	} while (condition);

e

.. code-block:: c

	if (x == y) {
		..
	} else if (x > y) {
		...
	} else {
		....
	}

Motivazione: K&R.

Inoltre, notate che questo posizionamento delle graffe minimizza il numero
di righe vuote senza perdere di leggibilità.  In questo modo, dato che le
righe sul vostro schermo non sono una risorsa illimitata (pensate ad uno
terminale con 25 righe), avrete delle righe vuote da riempire con dei
commenti.

Non usate inutilmente le graffe dove una singola espressione è sufficiente.

.. code-block:: c

	if (condition)
		action();

e

.. code-block:: none

	if (condition)
		do_this();
	else
		do_that();

Questo non vale nel caso in cui solo un ramo dell'espressione if-else
contiene una sola espressione; in quest'ultimo caso usate le graffe per
entrambe i rami:

.. code-block:: c

	if (condition) {
		do_this();
		do_that();
	} else {
		otherwise();
	}

Inoltre, usate le graffe se un ciclo contiene più di una semplice istruzione:

.. code-block:: c

	while (condition) {
		if (test)
			do_something();
	}

3.1) Spazi
**********

Lo stile del kernel Linux per quanto riguarda gli spazi, dipende
(principalmente) dalle funzioni e dalle parole chiave.  Usate una spazio dopo
(quasi tutte) le parole chiave.  L'eccezioni più evidenti sono sizeof, typeof,
alignof, e __attribute__, il cui aspetto è molto simile a quello delle
funzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il
linguaggio non lo richiede; come ``sizeof info`` dopo aver dichiarato
``struct fileinfo info``).

Quindi utilizzate uno spazio dopo le seguenti parole chiave::

	if, switch, case, for, do, while

ma non con sizeof, typeof, alignof, o __attribute__.  Ad esempio,

.. code-block:: c

	s = sizeof(struct file);

Non aggiungete spazi attorno (dentro) ad un'espressione fra parentesi. Questo
esempio è **brutto**:

.. code-block:: c

	s = sizeof( struct file );

Quando dichiarate un puntatore ad una variabile o una funzione che ritorna un
puntatore, il posto suggerito per l'asterisco ``*`` è adiacente al nome della
variabile o della funzione, e non adiacente al nome del tipo. Esempi:

.. code-block:: c

	char *linux_banner;
	unsigned long long memparse(char *ptr, char **retptr);
	char *match_strdup(substring_t *s);

Usate uno spazio attorno (da ogni parte) alla maggior parte degli operatori
binari o ternari, come i seguenti::

	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :

ma non mettete spazi dopo gli operatori unari::

	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined

nessuno spazio dopo l'operatore unario suffisso di incremento o decremento::

	++  --

nessuno spazio dopo l'operatore unario prefisso di incremento o decremento::

	++  --

e nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e
``->``.

Non lasciate spazi bianchi alla fine delle righe.  Alcuni editor con
l'indentazione ``furba`` inseriranno gli spazi bianchi all'inizio di una nuova
riga in modo appropriato, quindi potrete scrivere la riga di codice successiva
immediatamente.  Tuttavia, alcuni di questi stessi editor non rimuovono
questi spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio
perché volete lasciare una riga vuota.  Il risultato è che finirete per avere
delle righe che contengono spazi bianchi in coda.

Git vi avviserà delle modifiche che aggiungono questi spazi vuoti di fine riga,
e può opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando
una serie di modifiche, questo potrebbe far fallire delle modifiche successive
perché il contesto delle righe verrà cambiato.

4) Assegnare nomi
-----------------

C è un linguaggio spartano, e così dovrebbero esserlo i vostri nomi.  Al
contrario dei programmatori Modula-2 o Pascal, i programmatori C non usano
nomi graziosi come ThisVariableIsATemporaryCounter.  Un programmatore C
chiamerebbe questa variabile ``tmp``, che è molto più facile da scrivere e
non è una delle più difficili da capire.

TUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi
descrittivi per variabili globali sono un dovere.  Chiamare una funzione
globale ``pippo`` è un insulto.

Le variabili GLOBALI (da usare solo se vi servono **davvero**) devono avere
dei nomi descrittivi, così come le funzioni globali.  Se avete una funzione
che conta gli utenti attivi, dovreste chiamarla ``count_active_users()`` o
qualcosa di simile, **non** dovreste chiamarla ``cntusr()``.

Codificare il tipo di funzione nel suo nome (quella cosa chiamata notazione
ungherese) è stupido - il compilatore conosce comunque il tipo e
può verificarli, e inoltre confonde i programmatori.

Le variabili LOCALI dovrebbero avere nomi corti, e significativi.  Se avete
un qualsiasi contatore di ciclo, probabilmente sarà chiamato ``i``.
Chiamarlo ``loop_counter`` non è produttivo, non ci sono possibilità che
``i`` possa non essere capito.  Analogamente, ``tmp`` può essere una qualsiasi
variabile che viene usata per salvare temporaneamente un valore.

Se avete paura di fare casino coi nomi delle vostre variabili locali, allora
avete un altro problema che è chiamato sindrome dello squilibrio dell'ormone
della crescita delle funzioni. Vedere il capitolo 6 (funzioni).

5) Definizione di tipi (typedef)
--------------------------------

Per favore non usate cose come ``vps_t``.
Usare il typedef per strutture e puntatori è uno **sbaglio**. Quando vedete:

.. code-block:: c

	vps_t a;

nei sorgenti, cosa significa?
Se, invece, dicesse:

.. code-block:: c

	struct virtual_container *a;

potreste dire cos'è effettivamente ``a``.

Molte persone pensano che la definizione dei tipi ``migliori la leggibilità``.
Non molto. Sono utili per:

 (a) gli oggetti completamente opachi (dove typedef viene proprio usato allo
     scopo di **nascondere** cosa sia davvero l'oggetto).

     Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente
     con le loro funzioni accessorie.

     .. note::
       Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se,
       una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è
       che davvero non c'è alcuna informazione portabile.

 (b) i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare
     confusione sul fatto che siano ``int`` oppure ``long``.

     u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono
     nella categoria (d) piuttosto che in questa.

     .. note::

       Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è
       ``unsigned long``, non c'è alcun bisogno di avere:

        typedef unsigned long myfalgs_t;

      ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int``
      e in altre configurazioni ``unsigned long``, allora certamente typedef
      è una buona scelta.

 (c) quando di rado create letteralmente dei **nuovi** tipi su cui effettuare
     verifiche.

 (d) circostanze eccezionali, in cui si definiscono nuovi tipi identici a
     quelli definiti dallo standard C99.

     Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei
     tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso.

     Perciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti
     con segno, identici ai tipi standard, sono permessi- tuttavia, non sono
     obbligatori per il nuovo codice.

 (e) i tipi sicuri nella spazio utente.

     In alcune strutture dati visibili dallo spazio utente non possiamo
     richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima.
     Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati
     condivise con lo spazio utente.

Magari ci sono altri casi validi, ma la regola di base dovrebbe essere di
non usare MAI MAI un typedef a meno che non rientri in una delle regole
descritte qui.

In generale, un puntatore, o una struttura a cui si ha accesso diretto in
modo ragionevole, non dovrebbero **mai** essere definite con un typedef.

6) Funzioni
-----------

Le funzioni dovrebbero essere brevi e carine, e fare una cosa sola.  Dovrebbero
occupare uno o due schermi di testo (come tutti sappiamo, la dimensione
di uno schermo secondo ISO/ANSI è di 80x24), e fare una cosa sola e bene.

La massima lunghezza di una funziona è inversamente proporzionale alla sua
complessità e al livello di indentazione di quella funzione.  Quindi, se avete
una funzione che è concettualmente semplice ma che è implementata come un
lunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose
per molti casi differenti, allora va bene avere funzioni più lunghe.

Comunque, se avete una funzione complessa e sospettate che uno studente
non particolarmente dotato del primo anno delle scuole superiori potrebbe
non capire cosa faccia la funzione, allora dovreste attenervi strettamente ai
limiti.  Usate funzioni di supporto con nomi descrittivi (potete chiedere al
compilatore di renderle inline se credete che sia necessario per le
prestazioni, e probabilmente farà un lavoro migliore di quanto avreste potuto
fare voi).

Un'altra misura delle funzioni sono il numero di variabili locali.  Non
dovrebbero eccedere le 5-10, oppure state sbagliando qualcosa.  Ripensate la
funzione, e dividetela in pezzettini.  Generalmente, un cervello umano può
seguire facilmente circa 7 cose diverse, di più lo confonderebbe.  Lo sai
d'essere brillante, ma magari vorresti riuscire a capire cos'avevi fatto due
settimane prima.

Nei file sorgenti, separate le funzioni con una riga vuota.  Se la funzione è
esportata, la macro **EXPORT** per questa funzione deve seguire immediatamente
la riga della parentesi graffa di chiusura. Ad esempio:

.. code-block:: c

	int system_is_up(void)
	{
		return system_state == SYSTEM_RUNNING;
	}
	EXPORT_SYMBOL(system_is_up);

6.1) Prototipi di funzione
**************************

Nei prototipi di funzione, includete i nomi dei parametri e i loro tipi.
Nonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito
perché è un modo semplice per aggiungere informazioni importanti per il
lettore.

Non usate la parola chiave ``extern`` con le dichiarazioni di funzione perché
rende le righe più lunghe e non è strettamente necessario.

Quando scrivete i prototipi di funzione mantenete `l'ordine degli elementi <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_.

Prendiamo questa dichiarazione di funzione come esempio::

 __init void * __must_check action(enum magic value, size_t size, u8 count,
                                  char *fmt, ...) __printf(4, 5) __malloc;

L'ordine suggerito per gli elementi di un prototipo di funzione è il seguente:

- classe d'archiviazione (in questo caso ``static __always_inline``. Da notare
  che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come
  ``inline``)
- attributi della classe di archiviazione (in questo caso ``__init``, in altre
  parole la sezione, ma anche cose tipo ``__cold``)
- il tipo di ritorno (in questo caso, ``void *``)
- attributi per il valore di ritorno (in questo caso, ``__must_check``)
- il nome della funzione (in questo caso, ``action``)
- i parametri della funzione(in questo caso,
  ``(enum magic value, size_t size, u8 count, char *fmt, ...)``,
  da notare che va messo anche il nome del parametro)
- attributi dei parametri (in questo caso, ``__printf(4, 5)``)
- attributi per il comportamento della funzione (in questo caso, ``__malloc_``)

Notate che per la **definizione** di una funzione (il altre parole il corpo
della funzione), il compilatore non permette di usare gli attributi per i
parametri dopo i parametri. In questi casi, devono essere messi dopo gli
attributi della classe d'archiviazione (notate che la posizione di
``__printf(4,5)`` cambia rispetto alla **dichiarazione**)::

 static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
              size_t size, u8 count, char *fmt, ...) __malloc
 {
         ...
 }*)**``)**``)``)``*)``)``)``)``*``)``)``)*)

7) Centralizzare il ritorno delle funzioni
------------------------------------------

Sebbene sia deprecata da molte persone, l'istruzione goto è impiegata di
frequente dai compilatori sotto forma di salto incondizionato.

L'istruzione goto diventa utile quando una funzione ha punti d'uscita multipli
e vanno eseguite alcune procedure di pulizia in comune.  Se non è necessario
pulire alcunché, allora ritornate direttamente.

Assegnate un nome all'etichetta di modo che suggerisca cosa fa la goto o
perché esiste.  Un esempio di un buon nome potrebbe essere ``out_free_buffer:``
se la goto libera (free) un ``buffer``.  Evitate l'uso di nomi GW-BASIC come
``err1:`` ed ``err2:``, potreste doverli riordinare se aggiungete o rimuovete
punti d'uscita, e inoltre rende difficile verificarne la correttezza.

I motivo per usare le goto sono:

- i salti incondizionati sono più facili da capire e seguire
- l'annidamento si riduce
- si evita di dimenticare, per errore, di aggiornare un singolo punto d'uscita
- aiuta il compilatore ad ottimizzare il codice ridondante ;)

.. code-block:: c

	int fun(int a)
	{
		int result = 0;
		char *buffer;

		buffer = kmalloc(SIZE, GFP_KERNEL);
		if (!buffer)
			return -ENOMEM;

		if (condition1) {
			while (loop1) {
				...
			}
			result = 1;
			goto out_free_buffer;
		}
		...
	out_free_buffer:
		kfree(buffer);
		return result;
	}

Un baco abbastanza comune di cui bisogna prendere nota è il ``one err bugs``
che assomiglia a questo:

.. code-block:: c

	err:
		kfree(foo->bar);
		kfree(foo);
		return ret;

Il baco in questo codice è che in alcuni punti d'uscita la variabile ``foo`` è
NULL.  Normalmente si corregge questo baco dividendo la gestione dell'errore in
due parti ``err_free_bar:`` e ``err_free_foo:``:

.. code-block:: c

	 err_free_bar:
		kfree(foo->bar);
	 err_free_foo:
		kfree(foo);
		return ret;

Idealmente, dovreste simulare condizioni d'errore per verificare i vostri
percorsi d'uscita.

8) Commenti
-----------

I commenti sono una buona cosa, ma c'è anche il rischio di esagerare.  MAI
spiegare COME funziona il vostro codice in un commento: è molto meglio
scrivere il codice di modo che il suo funzionamento sia ovvio, inoltre
spiegare codice scritto male è una perdita di tempo.

Solitamente, i commenti devono dire COSA fa il codice, e non COME lo fa.
Inoltre, cercate di evitare i commenti nel corpo della funzione: se la
funzione è così complessa che dovete commentarla a pezzi, allora dovreste
tornare al punto 6 per un momento.  Potete mettere dei piccoli commenti per
annotare o avvisare il lettore circa un qualcosa di particolarmente arguto
(o brutto), ma cercate di non esagerare.  Invece, mettete i commenti in
testa alla funzione spiegando alle persone cosa fa, e possibilmente anche
il PERCHÉ.

Per favore, quando commentate una funzione dell'API del kernel usate il
formato kernel-doc.  Per maggiori dettagli, leggete i file in
:ref::ref:`Documentation/translations/it_IT/doc-guide/ <it_doc_guide>` e in
``script/kernel-doc``.

Lo stile preferito per i commenti più lunghi (multi-riga) è:

.. code-block:: c

	/*
	 * This is the preferred style for multi-line
	 * comments in the Linux kernel source code.
	 * Please use it consistently.
	 *
	 * Description:  A column of asterisks on the left side,
	 * with beginning and ending almost-blank lines.
	 */

Per i file in net/ e in drivers/net/ lo stile preferito per i commenti
più lunghi (multi-riga) è leggermente diverso.

.. code-block:: c

	/* The preferred comment style for files in net/ and drivers/net
	 * looks like this.
	 *
	 * It is nearly the same as the generally preferred comment style,
	 * but there is no initial almost-blank line.
	 */

È anche importante commentare i dati, sia per i tipi base che per tipi
derivati.  A questo scopo, dichiarate un dato per riga (niente virgole
per una dichiarazione multipla).  Questo vi lascerà spazio per un piccolo
commento per spiegarne l'uso.

9) Avete fatto un pasticcio
---------------------------

Va bene, li facciamo tutti.  Probabilmente vi è stato detto dal vostro
aiutante Unix di fiducia che ``GNU emacs`` formatta automaticamente il
codice C per conto vostro, e avete notato che sì, in effetti lo fa, ma che
i modi predefiniti non sono proprio allettanti (infatti, sono peggio che
premere tasti a caso - un numero infinito di scimmie che scrivono in
GNU emacs non faranno mai un buon programma).

Quindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più
sensati.  Per fare quest'ultima cosa, potete appiccicare il codice che
segue nel vostro file .emacs:

.. code-block:: none

  (defun c-lineup-arglist-tabs-only (ignored)
    "Line up argument lists by tabs, not spaces"
    (let* ((anchor (c-langelem-pos c-syntactic-element))
           (column (c-langelem-2nd-pos c-syntactic-element))
           (offset (- (1+ column) anchor))
           (steps (floor offset c-basic-offset)))
      (* (max steps 1)
         c-basic-offset)))

  (dir-locals-set-class-variables
   'linux-kernel
   '((c-mode . (
          (c-basic-offset . 8)
          (c-label-minimum-indentation . 0)
          (c-offsets-alist . (
                  (arglist-close         . c-lineup-arglist-tabs-only)
                  (arglist-cont-nonempty .
		      (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
                  (arglist-intro         . +)
                  (brace-list-intro      . +)
                  (c                     . c-lineup-C-comments)
                  (case-label            . 0)
                  (comment-intro         . c-lineup-comment)
                  (cpp-define-intro      . +)
                  (cpp-macro             . -1000)
                  (cpp-macro-cont        . +)
                  (defun-block-intro     . +)
                  (else-clause           . 0)
                  (func-decl-cont        . +)
                  (inclass               . +)
                  (inher-cont            . c-lineup-multi-inher)
                  (knr-argdecl-intro     . 0)
                  (label                 . -1000)
                  (statement             . 0)
                  (statement-block-intro . +)
                  (statement-case-intro  . +)
                  (statement-cont        . +)
                  (substatement          . +)
                  ))
          (indent-tabs-mode . t)
          (show-trailing-whitespace . t)
          ))))

  (dir-locals-set-directory-class
   (expand-file-name "~/src/linux-trees")
   'linux-kernel)

Questo farà funzionare meglio emacs con lo stile del kernel per i file che
si trovano nella cartella ``~/src/linux-trees``.

Ma anche se doveste fallire nell'ottenere una formattazione sensata in emacs
non tutto è perduto: usate ``indent``.

Ora, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs,
ed è per questo che dovete passargli alcune opzioni da riga di comando.
Tuttavia, non è così terribile, perché perfino i creatori di GNU indent
riconoscono l'autorità di K&R (le persone del progetto GNU non sono cattive,
sono solo mal indirizzate sull'argomento), quindi date ad indent le opzioni
``-kr -i8`` (che significa ``K&R, 8 caratteri di indentazione``), o utilizzate
``scripts/Lindent`` che indenterà usando l'ultimo stile.

``indent`` ha un sacco di opzioni, e specialmente quando si tratta di
riformattare i commenti dovreste dare un'occhiata alle pagine man.
Ma ricordatevi: ``indent`` non è un correttore per una cattiva programmazione.

Da notare che potete utilizzare anche ``clang-format`` per aiutarvi con queste
regole, per riformattare rapidamente ad automaticamente alcune parti del
vostro codice, e per revisionare interi file al fine di identificare errori
di stile, refusi e possibilmente anche delle migliorie. È anche utile per
ordinare gli ``#include``, per allineare variabili/macro, per ridistribuire
il testo e altre cose simili.
Per maggiori dettagli, consultate il file
:ref:`Documentation/translations/it_IT/process/clang-format.rst <it_clangformat>`.

10) File di configurazione Kconfig
----------------------------------

Per tutti i file di configurazione Kconfig* che si possono trovare nei
sorgenti, l'indentazione è un po' differente.  Le linee dopo un ``config``
sono indentate con un tab, mentre il testo descrittivo è indentato di
ulteriori due spazi.  Esempio::

  config AUDIT
	bool "Auditing support"
	depends on NET
	help
	  Enable auditing infrastructure that can be used with another
	  kernel subsystem, such as SELinux (which requires this for
	  logging of avc messages output).  Does not do system-call
	  auditing without CONFIG_AUDITSYSCALL.

Le funzionalità davvero pericolose (per esempio il supporto alla scrittura
per certi filesystem) dovrebbero essere dichiarate chiaramente come tali
nella stringa di titolo::

  config ADFS_FS_RW
	bool "ADFS write support (DANGEROUS)"
	depends on ADFS_FS
	...

Per la documentazione completa sui file di configurazione, consultate
il documento Documentation/kbuild/kconfig-language.rst

11) Strutture dati
------------------

Le strutture dati che hanno una visibilità superiore al contesto del
singolo thread in cui vengono create e distrutte, dovrebbero sempre
avere un contatore di riferimenti.  Nel kernel non esiste un
*garbage collector* (e fuori dal kernel i *garbage collector* sono lenti
e inefficienti), questo significa che **dovete** assolutamente avere un
contatore di riferimenti per ogni cosa che usate.

Avere un contatore di riferimenti significa che potete evitare la
sincronizzazione e permette a più utenti di accedere alla struttura dati
in parallelo - e non doversi preoccupare di una struttura dati che
improvvisamente sparisce dalla loro vista perché il loro processo dormiva
o stava facendo altro per un attimo.

Da notare che la sincronizzazione **non** si sostituisce al conteggio dei
riferimenti.  La sincronizzazione ha lo scopo di mantenere le strutture
dati coerenti, mentre il conteggio dei riferimenti è una tecnica di gestione
della memoria.  Solitamente servono entrambe le cose, e non vanno confuse fra
di loro.

Quando si hanno diverse classi di utenti, le strutture dati possono avere
due livelli di contatori di riferimenti.  Il contatore di classe conta
il numero dei suoi utenti, e il contatore globale viene decrementato una
sola volta quando il contatore di classe va a zero.

Un esempio di questo tipo di conteggio dei riferimenti multi-livello può
essere trovato nella gestore della memoria (``struct mm_sturct``: mm_user e
mm_count), e nel codice dei filesystem (``struct super_block``: s_count e
s_active).

Ricordatevi: se un altro thread può trovare la vostra struttura dati, e non
avete un contatore di riferimenti per essa, quasi certamente avete un baco.

12) Macro, enumerati e RTL
---------------------------

I nomi delle macro che definiscono delle costanti e le etichette degli
enumerati sono scritte in maiuscolo.

.. code-block:: c

	#define CONSTANT 0x12345

Gli enumerati sono da preferire quando si definiscono molte costanti correlate.

I nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano
a delle funzioni possono essere scritte in minuscolo.

Generalmente, le funzioni inline sono preferibili rispetto alle macro che
sembrano funzioni.

Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un
blocco do - while:

.. code-block:: c

	#define macrofun(a, b, c)			\
		do {					\
			if (a == 5)			\
				do_this(b, c);		\
		} while (0)

Cose da evitare quando si usano le macro:

1) le macro che hanno effetti sul flusso del codice:

.. code-block:: c

	#define FOO(x)					\
		do {					\
			if (blah(x) < 0)		\
				return -EBUGGERED;	\
		} while (0)

sono **proprio** una pessima idea.  Sembra una chiamata a funzione ma termina
la funzione chiamante; non cercate di rompere il decodificatore interno di
chi legge il codice.

2) le macro che dipendono dall'uso di una variabile locale con un nome magico:

.. code-block:: c

	#define FOO(val) bar(index, val)

potrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno
legge il codice e potrebbe romperlo con una cambiamento che sembra innocente.

3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe
ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione
inline.

4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono
essere racchiuse fra parentesi. State attenti a problemi simili con le macro
parametrizzate.

.. code-block:: c

	#define CONSTANT 0x4000
	#define CONSTEXP (CONSTANT | 3)

5) collisione nello spazio dei nomi quando si definisce una variabile locale in
una macro che sembra una funzione:

.. code-block:: c

	#define FOO(x)				\
	({					\
		typeof(x) ret;			\
		ret = calc_ret(x);		\
		(ret);				\
	})

ret è un nome comune per una variabile locale - __foo_ret difficilmente
andrà in conflitto con una variabile già esistente.

Il manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo
di gcc copre anche l'RTL che viene usato frequentemente nel kernel per il
linguaggio assembler.

13) Visualizzare i messaggi del kernel
--------------------------------------

Agli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio
di riguardo per l'ortografia e farete una belle figura. In inglese, evitate
l'uso incorretto di abbreviazioni come ``dont``: usate ``do not`` oppure
``don't``.  Scrivete messaggi concisi, chiari, e inequivocabili.

I messaggi del kernel non devono terminare con un punto fermo.

Scrivere i numeri fra parentesi (%d) non migliora alcunché e per questo
dovrebbero essere evitati.

Ci sono alcune macro per la diagnostica in <linux/dev_printk.h> che dovreste
usare per assicurarvi che i messaggi vengano associati correttamente ai
dispositivi e ai driver, e che siano etichettati correttamente:  dev_err(),
dev_warn(), dev_info(), e così via.  Per messaggi che non sono associati ad
alcun dispositivo, <linux/printk.h> definisce pr_info(), pr_warn(), pr_err(),
eccetera.

Tirar fuori un buon messaggio di debug può essere una vera sfida; e quando
l'avete può essere d'enorme aiuto per risolvere problemi da remoto.
Tuttavia, i messaggi di debug sono gestiti differentemente rispetto agli
altri.  Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no;
essa non viene compilata nella configurazione predefinita, a meno che
DEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati.  Questo vale anche per
dev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg().

Molti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono
-DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG
in specifici file.  Infine, quando un messaggio di debug dev'essere stampato
incondizionatamente, per esempio perché siete già in una sezione di debug
racchiusa in #ifdef, potete usare printk(KERN_DEBUG ...).

14) Assegnare memoria
---------------------

Il kernel fornisce i seguenti assegnatori ad uso generico:
kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc().
Per maggiori informazioni, consultate la documentazione dell'API:
:ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst <it_memory_allocation>`

Il modo preferito per passare la dimensione di una struttura è il seguente:

.. code-block:: c

	p = kmalloc(sizeof(*p), ...);

La forma alternativa, dove il nome della struttura viene scritto interamente,
peggiora la leggibilità e introduce possibili bachi quando il tipo di
puntatore cambia tipo ma il corrispondente sizeof non viene aggiornato.

Il valore di ritorno è un puntatore void, effettuare un cast su di esso è
ridondante. La conversione fra un puntatore void e un qualsiasi altro tipo
di puntatore è garantito dal linguaggio di programmazione C.

Il modo preferito per assegnare un vettore è il seguente:

.. code-block:: c

	p = kmalloc_array(n, sizeof(...), ...);

Il modo preferito per assegnare un vettore a zero è il seguente:

.. code-block:: c

	p = kcalloc(n, sizeof(...), ...);

Entrambe verificano la condizione di overflow per la dimensione
d'assegnamento n * sizeof(...), se accade ritorneranno NULL.

Questi allocatori generici producono uno *stack dump* in caso di fallimento
a meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella
maggior parte dei casi, è inutile stampare messaggi aggiuntivi quando uno di
questi allocatori ritornano un puntatore NULL.

15) Il morbo inline
-------------------

Sembra che ci sia la percezione errata che gcc abbia una qualche magica
opzione "rendimi più veloce" chiamata ``inline``. In alcuni casi l'uso di
inline è appropriato (per esempio in sostituzione delle macro, vedi
capitolo 12), ma molto spesso non lo è. L'uso abbondante della parola chiave
inline porta ad avere un kernel più grande, che si traduce in un sistema nel
suo complesso più lento per via di una cache per le istruzioni della CPU più
grande e poi semplicemente perché ci sarà meno spazio disponibile per una
pagina di cache. Pensateci un attimo; una fallimento nella cache causa una
ricerca su disco che può tranquillamente richiedere 5 millisecondi. Ci sono
TANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi.

Spesso le persone dicono che aggiungere inline a delle funzioni dichiarate
static e utilizzare una sola volta è sempre una scelta vincente perché non
ci sono altri compromessi. Questo è tecnicamente vero ma gcc è in grado di
trasformare automaticamente queste funzioni in inline; i problemi di
manutenzione del codice per rimuovere gli inline quando compare un secondo
utente surclassano il potenziale vantaggio nel suggerire a gcc di fare una
cosa che avrebbe fatto comunque.

16) Nomi e valori di ritorno delle funzioni
-------------------------------------------

Le funzioni possono ritornare diversi tipi di valori, e uno dei più comuni
è quel valore che indica se una funzione ha completato con successo o meno.
Questo valore può essere rappresentato come un codice di errore intero
(-Exxx = fallimento, 0 = successo) oppure un booleano di successo
(0 = fallimento, non-zero = successo).

Mischiare questi due tipi di rappresentazioni è un terreno fertile per
i bachi più insidiosi.  Se il linguaggio C includesse una forte distinzione
fra gli interi e i booleani, allora il compilatore potrebbe trovare questi
errori per conto nostro ... ma questo non c'è.  Per evitare di imbattersi
in questo tipo di baco, seguite sempre la seguente convenzione::

	Se il nome di una funzione è un'azione o un comando imperativo,
	essa dovrebbe ritornare un codice di errore intero.  Se il nome
	è un predicato, la funzione dovrebbe ritornare un booleano di
	"successo"

Per esempio, ``add work`` è un comando, e la funzione add_work() ritorna 0
in caso di successo o -EBUSY in caso di fallimento.  Allo stesso modo,
``PCI device present`` è un predicato, e la funzione pci_dev_present() ritorna
1 se trova il dispositivo corrispondente con successo, altrimenti 0.

Tutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e
così dovrebbero anche tutte le funzioni pubbliche.  Le funzioni private
(static) possono non seguire questa convenzione, ma è comunque raccomandato
che lo facciano.

Le funzioni il cui valore di ritorno è il risultato di una computazione,
piuttosto che l'indicazione sul successo di tale computazione, non sono
soggette a questa regola.  Solitamente si indicano gli errori ritornando un
qualche valore fuori dai limiti.  Un tipico esempio è quello delle funzioni
che ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo
di notifica degli errori.

17) L'uso di bool
-----------------

Nel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99.
Un valore bool può assumere solo i valori 0 o 1, e implicitamente o
esplicitamente la conversione a bool converte i valori in vero (*true*) o
falso (*false*).  Quando si usa un tipo bool il costrutto !! non sarà più
necessario, e questo va ad eliminare una certa serie di bachi.

Quando si usano i valori booleani, dovreste utilizzare le definizioni di true
e false al posto dei valori 1 e 0.

Per il valore di ritorno delle funzioni e per le variabili sullo stack, l'uso
del tipo bool è sempre appropriato.  L'uso di bool viene incoraggiato per
migliorare la leggibilità e spesso è molto meglio di 'int' nella gestione di
valori booleani.

Non usate bool se per voi sono importanti l'ordine delle righe di cache o
la loro dimensione; la dimensione e l'allineamento cambia a seconda
dell'architettura per la quale è stato compilato.  Le strutture che sono state
ottimizzate per l'allineamento o la dimensione non dovrebbero usare bool.

Se una struttura ha molti valori true/false, considerate l'idea di raggrupparli
in un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa,
come u8.

Come per gli argomenti delle funzioni, molti valori true/false possono essere
raggruppati in un singolo argomento a bit denominato 'flags'; spesso 'flags' è
un'alternativa molto più leggibile se si hanno valori costanti per true/false.

Detto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti
può migliorare la leggibilità.

18) Non reinventate le macro del kernel
---------------------------------------

Il file di intestazione include/linux/kernel.h contiene un certo numero
di macro che dovreste usare piuttosto che implementarne una qualche variante.
Per esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la
macro:

.. code-block:: c

	#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

Analogamente, se dovete calcolare la dimensione di un qualche campo di una
struttura, usate

.. code-block:: c

	#define sizeof_field(t, f) (sizeof(((t*)0)->f))

Ci sono anche le macro min() e max() che, se vi serve, effettuano un controllo
rigido sui tipi.  Sentitevi liberi di leggere attentamente questo file
d'intestazione per scoprire cos'altro è stato definito che non dovreste
reinventare nel vostro codice.

19) Linee di configurazione degli editor e altre schifezze
-----------------------------------------------------------

Alcuni editor possono interpretare dei parametri di configurazione integrati
nei file sorgenti e indicati con dai marcatori speciali.  Per esempio, emacs
interpreta le linee marcate nel seguente modo:

.. code-block:: c

	-*- mode: c -*-

O come queste:

.. code-block:: c

	/*
	Local Variables:
	compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
	End:
	*/

Vim interpreta i marcatori come questi:

.. code-block:: c

	/* vim:set sw=8 noet */

Non includete nessuna di queste cose nei file sorgenti.  Le persone hanno le
proprie configurazioni personali per l'editor, e i vostri sorgenti non
dovrebbero sovrascrivergliele.  Questo vale anche per i marcatori
d'indentazione e di modalità d'uso.  Le persone potrebbero aver configurato una
modalità su misura, oppure potrebbero avere qualche altra magia per far
funzionare bene l'indentazione.

20) Inline assembly
-------------------

Nel codice specifico per un'architettura, potreste aver bisogno di codice
*inline assembly* per interfacciarvi col processore o con una funzionalità
specifica della piattaforma.  Non esitate a farlo quando è necessario.
Comunque, non usatele gratuitamente quando il C può fare la stessa cosa.
Potete e dovreste punzecchiare l'hardware in C quando è possibile.

Considerate la scrittura di una semplice funzione che racchiude pezzi comuni
di codice assembler piuttosto che continuare a riscrivere delle piccole
varianti.  Ricordatevi che l' *inline assembly* può utilizzare i parametri C.

Il codice assembler più corposo e non banale dovrebbe andare nei file .S,
coi rispettivi prototipi C definiti nei file d'intestazione.  I prototipi C
per le funzioni assembler dovrebbero usare ``asmlinkage``.

Potreste aver bisogno di marcare il vostro codice asm come volatile al fine
d'evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali.
Non c'è sempre bisogno di farlo, e farlo quando non serve limita le
ottimizzazioni.

Quando scrivete una singola espressione *inline assembly* contenente più
istruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa;
ad eccezione dell'ultima stringa/istruzione, ognuna deve terminare con ``\n\t``
al fine di allineare correttamente l'assembler che verrà generato:

.. code-block:: c

	asm ("magic %reg1, #42\n\t"
	     "more_magic %reg2, %reg3"
	     : /* outputs */ : /* inputs */ : /* clobbers */);

21) Compilazione sotto condizione
---------------------------------

Ovunque sia possibile, non usate le direttive condizionali del preprocessore
(#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da
seguire.  Invece, usate queste direttive nei file d'intestazione per definire
le funzioni usate nei file .c, fornendo i relativi stub nel caso #else,
e quindi chiamate queste funzioni senza condizioni di preprocessore.  Il
compilatore non produrrà alcun codice per le funzioni stub, produrrà gli
stessi risultati, e la logica rimarrà semplice da seguire.

È preferibile non compilare intere funzioni piuttosto che porzioni d'esse o
porzioni d'espressioni.  Piuttosto che mettere una ifdef in un'espressione,
fattorizzate parte dell'espressione, o interamente, in funzioni e applicate
la direttiva condizionale su di esse.

Se avete una variabile o funzione che potrebbe non essere usata in alcune
configurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione
inutilizzata, marcate questa definizione come __maybe_unused piuttosto che
racchiuderla in una direttiva condizionale del preprocessore.  (Comunque,
se una variabile o funzione è *sempre* inutilizzata, rimuovetela).

Nel codice, dov'è possibile, usate la macro IS_ENABLED per convertire i
simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche
condizioni C:

.. code-block:: c

	if (IS_ENABLED(CONFIG_SOMETHING)) {
		...
	}

Il compilatore valuterà la condizione come costante (constant-fold), e quindi
includerà o escluderà il blocco di codice come se fosse in un #ifdef, quindi
non ne aumenterà il tempo di esecuzione.  Tuttavia, questo permette al
compilatore C di vedere il codice nel blocco condizionale e verificarne la
correttezza (sintassi, tipi, riferimenti ai simboli, eccetera).  Quindi
dovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste
solo quando la condizione è soddisfatta.

Alla fine di un blocco corposo di #if o #ifdef (più di alcune linee),
mettete un commento sulla stessa riga di #endif, annotando la condizione
che termina.  Per esempio:

.. code-block:: c

	#ifdef CONFIG_SOMETHING
	...
	#endif /* CONFIG_SOMETHING */

Appendice I) riferimenti
------------------------

The C Programming Language, Second Edition
by Brian W. Kernighan and Dennis M. Ritchie.
Prentice Hall, Inc., 1988.
ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).

The Practice of Programming
by Brian W. Kernighan and Rob Pike.
Addison-Wesley, Inc., 1999.
ISBN 0-201-61586-X.

Manuali GNU - nei casi in cui sono compatibili con K&R e questo documento -
per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui
http://www.gnu.org/manual/

WG14 è il gruppo internazionale di standardizzazione per il linguaggio C,
URL: http://www.open-std.org/JTC1/SC22/WG14/

Kernel process/coding-style.rst, by greg@kroah.com at OLS 2002:
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/


code:
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>

.. _it_deprecated:

==============================================================================
Interfacce deprecate, caratteristiche del linguaggio, attributi, e convenzioni
==============================================================================

In un mondo perfetto, sarebbe possibile prendere tutti gli usi di
un'interfaccia deprecata e convertirli in quella nuova, e così sarebbe
possibile rimuovere la vecchia interfaccia in un singolo ciclo di sviluppo.
Tuttavia, per via delle dimensioni del kernel, la gerarchia dei manutentori e
le tempistiche, non è sempre possibile fare questo tipo di conversione tutta
in una volta. Questo significa che nuove istanze di una vecchia interfaccia
potrebbero aggiungersi al kernel proprio quando si sta cercando di rimuoverle,
aumentando così il carico di lavoro. Al fine di istruire gli sviluppatori su
cosa è considerato deprecato (e perché), è stata create la seguente lista a cui
fare riferimento quando qualcuno propone modifiche che usano cose deprecate.

__deprecated
------------
Nonostante questo attributo marchi visibilmente un interfaccia come deprecata,
`non produce più alcun avviso durante la compilazione
<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
perché uno degli obiettivi del kernel è quello di compilare senza avvisi;
inoltre, nessuno stava agendo per rimuovere queste interfacce. Nonostante l'uso
di `__deprecated` in un file d'intestazione sia opportuno per segnare una
interfaccia come 'vecchia', questa non è una soluzione completa. L'interfaccia
deve essere rimossa dal kernel, o aggiunta a questo documento per scoraggiarne
l'uso.

BUG() e BUG_ON()
----------------
Al loro posto usate WARN() e WARN_ON() per gestire le
condizioni "impossibili" e gestitele come se fosse possibile farlo.
Nonostante le funzioni della famiglia BUG() siano state progettate
per asserire "situazioni impossibili" e interrompere in sicurezza un
thread del kernel, queste si sono rivelate essere troppo rischiose
(per esempio, in quale ordine rilasciare i *lock*? Ci sono stati che
sono stati ripristinati?). Molto spesso l'uso di BUG()
destabilizza il sistema o lo corrompe del tutto, il che rende
impossibile un'attività di debug o anche solo leggere un rapporto
circa l'errore.  Linus ha un'opinione molto critica al riguardo:
`email 1
<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_,
`email 2
<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_

Tenete presente che la famiglia di funzioni WARN() dovrebbe essere
usato solo per situazioni che si suppone siano "impossibili".  Se
volete avvisare gli utenti riguardo a qualcosa di possibile anche se
indesiderato, usare le funzioni della famiglia pr_warn().  Chi
amministra il sistema potrebbe aver attivato l'opzione sysctl
*panic_on_warn* per essere sicuri che il sistema smetta di funzionare
in caso si verifichino delle condizioni "inaspettate". (per esempio,
date un'occhiata al questo `commit
<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_)

Calcoli codificati negli argomenti di un allocatore
----------------------------------------------------
Il calcolo dinamico delle dimensioni (specialmente le moltiplicazioni) non
dovrebbero essere fatto negli argomenti di funzioni di allocazione di memoria
(o simili) per via del rischio di overflow. Questo può portare a valori più
piccoli di quelli che il chiamante si aspettava. L'uso di questo modo di
allocare può portare ad un overflow della memoria di heap e altri
malfunzionamenti. (Si fa eccezione per valori numerici per i quali il
compilatore può generare avvisi circa un potenziale overflow. Tuttavia, anche in
questi casi è preferibile riscrivere il codice come suggerito di seguito).

Per esempio, non usate ``count * size`` come argomento::

	foo = kmalloc(count * size, GFP_KERNEL);

Al suo posto, si dovrebbe usare l'allocatore a due argomenti::

	foo = kmalloc_array(count, size, GFP_KERNEL);

Nello specifico, kmalloc() può essere sostituta da kmalloc_array(), e kzalloc()
da kcalloc().

Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
le funzioni del tipo *saturate-on-overflow*::

	bar = vmalloc(array_size(count, size));

Un altro tipico caso da evitare è quello di calcolare la dimensione di una
struttura seguita da un vettore di altre strutture, come nel seguente caso::

	header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
			 GFP_KERNEL);

Invece, usate la seguente funzione::

	header = kzalloc(struct_size(header, item, count), GFP_KERNEL);

.. note:: Se per caso state usando struct_size() su una struttura dati che
	  in coda contiene un array di lunghezza zero o uno, allora siete
	  invitati a riorganizzare il vostro codice usando il
	  `flexible array member <#zero-length-and-one-element-arrays>`_.

Per altri calcoli, usate le funzioni size_mul(), size_add(), e size_sub(). Per
esempio, al posto di::

       foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);

dovreste scrivere:

       foo = krealloc(size_add(current_size,
                               size_mul(chunk_size,
                                        size_sub(count, 3))), GFP_KERNEL);

Per maggiori dettagli fate riferimento a array3_size() e flex_array_size(), ma
anche le funzioni della famiglia check_mul_overflow(), check_add_overflow(),
check_sub_overflow(), e check_shl_overflow().

simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
Le funzioni simple_strtol(), simple_strtoll(),
simple_strtoul(), e simple_strtoull() ignorano volutamente
i possibili overflow, e questo può portare il chiamante a generare risultati
inaspettati. Le rispettive funzioni kstrtol(), kstrtoll(),
kstrtoul(), e kstrtoull() sono da considerarsi le corrette
sostitute; tuttavia va notato che queste richiedono che la stringa sia
terminata con il carattere NUL o quello di nuova riga.

strcpy()
--------
La funzione strcpy() non fa controlli agli estremi del buffer
di destinazione. Questo può portare ad un overflow oltre i limiti del
buffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione
`CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano
a ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare
questa funzione. La versione sicura da usare è strscpy(), tuttavia va
prestata attenzione a tutti quei casi dove viene usato il valore di
ritorno di strcpy().  La funzione strscpy() non ritorna un puntatore
alla destinazione, ma un contatore dei byte non NUL copiati (oppure
un errno negativo se la stringa è stata troncata).

strncpy() su stringe terminate con NUL
--------------------------------------
L'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che
il buffer di destinazione verrà terminato con il carattere NUL. Questo
potrebbe portare a diversi overflow di lettura o altri malfunzionamenti
causati, appunto, dalla mancanza del terminatore. Questa estende la
terminazione nel buffer di destinazione quando la stringa d'origine è più
corta; questo potrebbe portare ad una penalizzazione delle prestazioni per
chi usa solo stringe terminate. La versione sicura da usare è
strscpy(), tuttavia va prestata attenzione a tutti quei casi dove
viene usato il valore di ritorno di strncpy().  La funzione strscpy()
non ritorna un puntatore alla destinazione, ma un contatore dei byte
non NUL copiati (oppure un errno negativo se la stringa è stata
troncata). Tutti i casi che necessitano di estendere la
terminazione con NUL dovrebbero usare strscpy_pad().

Se il chiamate no usa stringhe terminate con NUL, allore strncpy()
può continuare ad essere usata, ma i buffer di destinazione devono essere
marchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
per evitare avvisi durante la compilazione.

strlcpy()
---------
La funzione strlcpy(), per prima cosa, legge interamente il buffer di
origine, magari leggendo più di quanto verrà effettivamente copiato. Questo
è inefficiente e può portare a overflow di lettura quando la stringa non è
terminata con NUL. La versione sicura da usare è strscpy(), tuttavia
va prestata attenzione a tutti quei casi dove viene usato il valore di
ritorno di strlcpy(), dato che strscpy() ritorna un valore di errno
negativo quanto la stringa viene troncata.

Segnaposto %p nella stringa di formato
--------------------------------------

Tradizionalmente, l'uso del segnaposto "%p" nella stringa di formato
esponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera.  Per
evitare che questi indirizzi vengano sfruttati da malintenzionati,
tutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo,
rendendolo di fatto inutilizzabile.  Nuovi usi di "%p" non dovrebbero
essere aggiunti al kernel.  Per una rappresentazione testuale di un
indirizzo usate "%pS", l'output è migliore perché mostrerà il nome del
simbolo.  Per tutto il resto, semplicemente non usate "%p".

Parafrasando la `guida
<https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_
di Linus:

- Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso
  è importante. Forse dovrebbe essere rimosso del tutto?
- Se credi davvero che il vero valore del puntatore sia importante,
  perché alcuni stati del sistema o i livelli di privilegi di un
  utente sono considerati "special"? Se pensi di poterlo giustificare
  (in un commento e nel messaggio del commit) abbastanza bene da
  affrontare il giudizio di Linus, allora forse potrai usare "%px",
  assicurandosi anche di averne il permesso.

Potete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa
funzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo
aggiungete l'opzione di debug "`no_hash_pointers
<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_" alla
riga di comando del kernel.

Vettori a dimensione variabile (VLA)
------------------------------------

Usare VLA sullo stack produce codice molto peggiore rispetto a quando si usano
vettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_,
tutt'altro che banali, sono già un motivo valido per eliminare i VLA; in
aggiunta sono anche un problema per la sicurezza. La crescita dinamica di un
vettore nello stack potrebbe eccedere la memoria rimanente in tale segmento.
Questo può portare a dei malfunzionamenti, potrebbe sovrascrivere
dati importanti alla fine dello stack (quando il kernel è compilato senza
`CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente
allo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`).

Salto implicito nell'istruzione switch-case
-------------------------------------------

Il linguaggio C permette ai casi di un'istruzione `switch` di saltare al
prossimo caso quando l'istruzione "break" viene omessa alla fine del caso
corrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se
l'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio,
osservando il seguente pezzo di codice non è chiaro se lo stato
`STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`::

  switch (value) {
  case STATE_ONE:
          do_something();
  case STATE_TWO:
          do_other();
          break;
  default:
          WARN("unknown state");
  }

Dato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione
"break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non
permettiamo più che vi sia un "salto implicito" (*fall-through*). Per
identificare un salto implicito intenzionale abbiamo adottato la pseudo
parola chiave 'fallthrough' che viene espansa nell'estensione di gcc
`__attribute__((fallthrough))` `Statement Attributes
<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
(Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente
supportata dai compilatori C, analizzatori statici, e dagli IDE,
allora potremo usare quella sintassi per la pseudo parola chiave)

Quando la sintassi [[fallthrough]] sarà più comunemente supportata dai
compilatori, analizzatori statici, e ambienti di sviluppo IDE,
allora potremo usarla anche noi.

Ne consegue che tutti i blocchi switch/case devono finire in uno dei seguenti
modi:

* ``break;``
* `fallthrough;``
* ``continue;``
* ``goto <label>;``
* ``return [expression];``

Array di lunghezza zero o con un solo elemento
----------------------------------------------
All'interno del kernel ricorre spesso la necessita di avere membri
di dimensione variabile all'interno di una struttura dati. In questi
casi il codice del kernel dovrebbe usare sempre i `"flexible array
member" <https://en.wikipedia.org/wiki/Flexible_array_member>`_. La
tecnica degli array a lunghezza nulla o di un solo elemento non
dovrebbe essere più usata.

Nel codice C più vecchio, la dichiarazione di un membro di dimensione
variabile in coda ad una struttura dati veniva fatto dichiarando un
array di un solo elemento posizionato alla fine della struttura dati::

        struct something {
                size_t count;
                struct foo items[1];
        };

Questo ha portato ad un calcolo di sizeof() traballante (dovrebbe
rimuovere la dimensione del singolo elemento in coda per calcolare la
dimensione esatta dell' "intestazione"). Per evitare questi problemi è
stata introdotta un' `estensione a GNU C
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ che
permettesse la dichiarazione di array a lungezza zero::

        struct something {
                size_t count;
                struct foo items[0];
        };

Ma questo ha portato nuovi problemi, e non ha risolto alcuni dei
problemi che affliggono entrambe le tecniche: per esempio
l'impossibilità di riconoscere se un array di quel tipo viene usato
nel mezzo di una struttura dati e _non_ alla fine (potrebbe accadere
sia direttamente, sia indirettamente quando si usano le unioni o le
strutture di strutture).

Lo standard C99 introduce i "flexible array members". Questi array non
hanno una dimensione nella loro dichiarazione::

        struct something {
                size_t count;
                struct foo items[];
        };

Questo è il modo con cui ci si aspetta che vengano dichiarati gli
elementi di lunghezza variabile in coda alle strutture dati.  Permette
al compilatore di produrre errori quando gli array flessibili non si
trovano alla fine della struttura dati, il che permette di prevenire
alcuni tipi di bachi dovuti a `comportamenti inaspettati
<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
Inoltre, permette al compilatore di analizzare correttamente le
dimensioni degli array (attraverso sizeof(), `CONFIG_FORTIFY_SOURCE`,
e `CONFIG_UBSAN_BOUNDS`). Per esempio, non esiste alcun meccanismo in
grado di avvisarci che il seguente uso di sizeof() dia sempre come
zero come risultato::

        struct something {
                size_t count;
                struct foo items[0];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
        instance->count = count;

        size = sizeof(instance->items) * instance->count;
        memcpy(instance->items, source, size);

Il valore di ``size`` nell'ultima riga sarà ``zero``, quando uno
invece si aspetterebbe che il suo valore sia la dimensione totale in
byte dell'allocazione dynamica che abbiamo appena fatto per l'array
``items``. Qui un paio di esempi reali del problema: `collegamento 1
<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
`collegamento 2
<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
Invece, `i flexible array members hanno un tipo incompleto, e quindi
sizeof() non può essere applicato
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_; dunque ogni
uso scorretto di questo operatore verrà identificato immediatamente
durante la compilazione.

Per quanto riguarda gli array di un solo elemento, bisogna essere
consapevoli che `questi array occupano almeno quanto lo spazio di un
singolo oggetti dello stesso tipo
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, e quindi
contribuiscono al calcolo della dimensione della struttura che li
contiene. In questo caso è facile commettere errori quando si vuole
calcolare la dimensione totale della memoria totale da allocare per
una struttura dati::

        struct something {
                size_t count;
                struct foo items[1];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
        instance->count = count;

        size = sizeof(instance->items) * instance->count;
        memcpy(instance->items, source, size);

In questo esempio ci siamo dovuti ricordare di usare ``count - 1`` in
struct_size(), altrimenti avremmo --inavvertitamente-- allocato
memoria per un oggetti ``items`` in più. Il modo più pulito e meno
propenso agli errori è quello di usare i `flexible array member`, in
combinazione con struct_size() e flex_array_size()::

        struct something {
                size_t count;
                struct foo items[];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
        instance->count = count;

	memcpy(instance->items, source, flex_array_size(instance, items, instance->count));

repo_name: angery/linux


code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/process/development-process.rst <development_process_main>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>

.. _it_development_process_main:

Una guida al processo di sviluppo del Kernel
============================================

Contenuti:

.. toctree::
   :numbered:
   :maxdepth: 2

   1.Intro
   2.Process
   3.Early-stage
   4.Coding
   5.Posting
   6.Followthrough
   7.AdvancedTopics
   8.Conclusion

Lo scopo di questo documento è quello di aiutare gli sviluppatori (ed i loro
supervisori) a lavorare con la communità di sviluppo con il minimo sforzo. È
un tentativo di documentare il funzionamento di questa communità in modo che
sia accessibile anche a coloro che non hanno famigliarità con lo sviluppo del
Kernel Linux (o, anzi, con lo sviluppo di software libero in generale).  Benchè
qui sia presente del materiale tecnico, questa è una discussione rivolta in
particolare al procedimento, e quindi per essere compreso non richiede una
conoscenza approfondità sullo sviluppo del kernel.


code:
.. include:: ../disclaimer-ita.rst

:Original: :doc:`../../../process/email-clients`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>

.. _it_email_clients:

Informazioni sui programmi di posta elettronica per Linux
=========================================================

Git
---

Oggigiorno, la maggior parte degli sviluppatori utilizza ``git send-email``
al posto dei classici programmi di posta elettronica.  Le pagine man sono
abbastanza buone. Dal lato del ricevente, i manutentori utilizzano ``git am``
per applicare le patch.

Se siete dei novelli utilizzatori di ``git`` allora inviate la patch a voi
stessi. Salvatela come testo includendo tutte le intestazioni. Poi eseguite
il comando ``git am messaggio-formato-testo.txt`` e revisionatene il risultato
con ``git log``. Quando tutto funziona correttamente, allora potete inviare
la patch alla lista di discussione più appropriata.

Panoramica delle opzioni
------------------------

Le patch per il kernel vengono inviate per posta elettronica, preferibilmente
come testo integrante del messaggio.  Alcuni manutentori accettano gli
allegati, ma in questo caso gli allegati devono avere il *content-type*
impostato come ``text/plain``.  Tuttavia, generalmente gli allegati non sono
ben apprezzati perché rende più difficile citare porzioni di patch durante il
processo di revisione.

Inoltre, è vivamente raccomandato l'uso di puro testo nel corpo del
messaggio, sia per la patch che per qualsiasi altro messaggio. Il sito
https://useplaintext.email/ può esservi d'aiuto per configurare il
vostro programma di posta elettronica.

I programmi di posta elettronica che vengono usati per inviare le patch per il
kernel Linux dovrebbero inviarle senza alterazioni.  Per esempio, non
dovrebbero modificare o rimuovere tabulazioni o spazi, nemmeno all'inizio o
alla fine delle righe.

Non inviate patch con ``format=flowed``.  Questo potrebbe introdurre
interruzioni di riga inaspettate e indesiderate.

Non lasciate che il vostro programma di posta vada a capo automaticamente.
Questo può corrompere le patch.

I programmi di posta non dovrebbero modificare la codifica dei caratteri nel
testo.  Le patch inviate per posta elettronica dovrebbero essere codificate in
ASCII o UTF-8.
Se configurate il vostro programma per inviare messaggi codificati con UTF-8
eviterete possibili problemi di codifica.

I programmi di posta dovrebbero generare e mantenere le intestazioni
"References" o "In-Reply-To:" cosicché la discussione non venga interrotta.

Di solito, il copia-e-incolla (o taglia-e-incolla) non funziona con le patch
perché le tabulazioni vengono convertite in spazi.  Usando xclipboard, xclip
e/o xcutsel potrebbe funzionare, ma è meglio che lo verifichiate o meglio
ancora: non usate il copia-e-incolla.

Non usate firme PGP/GPG nei messaggi che contengono delle patch.  Questo
impedisce il corretto funzionamento di alcuni script per leggere o applicare
patch (questo si dovrebbe poter correggere).

Prima di inviare le patch sulle liste di discussione Linux, può essere una
buona idea quella di inviare la patch a voi stessi, salvare il messaggio
ricevuto, e applicarlo ai sorgenti con successo.

Alcuni suggerimenti per i programmi di posta elettronica (MUA)
--------------------------------------------------------------

Qui troverete alcuni suggerimenti per configurare i vostri MUA allo scopo
di modificare ed inviare patch per il kernel Linux.  Tuttavia, questi
suggerimenti non sono da considerarsi come un riassunto di una configurazione
completa.

Legenda:

- TUI = interfaccia utente testuale (*text-based user interface*)
- GUI = interfaccia utente grafica (*graphical user interface*)

Alpine (TUI)
************

Opzioni per la configurazione:

Nella sezione :menuselection:`Sending Preferences`:

- :menuselection:`Do Not Send Flowed Text` deve essere ``enabled``
- :menuselection:`Strip Whitespace Before Sending` deve essere ``disabled``

Quando state scrivendo un messaggio, il cursore dev'essere posizionato
dove volete che la patch inizi, poi premendo :kbd:`CTRL-R` vi verrà chiesto
di selezionare il file patch da inserire nel messaggio.

Claws Mail (GUI)
****************

Funziona. Alcune persone riescono ad usarlo con successo per inviare le patch.

Per inserire una patch usate :menuselection:`Messaggio-->Inserisci file`
(:kbd:`CTRL-I`) oppure un editor esterno.

Se la patch che avete inserito dev'essere modificata usato la finestra di
scrittura di Claws, allora assicuratevi che l'"auto-interruzione" sia
disabilitata :menuselection:`Configurazione-->Preferenze-->Composizione-->Interruzione riga`.

Evolution (GUI)
***************

Alcune persone riescono ad usarlo con successo per inviare le patch.

Quando state scrivendo una lettera selezionate: Preformattato
  da :menuselection:`Formato-->Stile del paragrafo-->Preformattato`
  (:kbd:`CTRL-7`) o dalla barra degli strumenti

Poi per inserire la patch usate:
:menuselection:`Inserisci--> File di testo...` (:kbd:`ALT-N x`)

Potete anche eseguire ``diff -Nru old.c new.c | xclip``, selezionare
:menuselection:`Preformattato`, e poi usare il tasto centrale del mouse.

Kmail (GUI)
***********

Alcune persone riescono ad usarlo con successo per inviare le patch.

La configurazione base che disabilita la composizione di messaggi HTML è
corretta; non abilitatela.

Quando state scrivendo un messaggio, nel menu opzioni, togliete la selezione a
"A capo automatico". L'unico svantaggio sarà che qualsiasi altra cosa scriviate
nel messaggio non verrà mandata a capo in automatico ma dovrete farlo voi.
Il modo più semplice per ovviare a questo problema è quello di scrivere il
messaggio con l'opzione abilitata e poi di salvarlo nelle bozze. Riaprendo ora
il messaggio dalle bozze le andate a capo saranno parte integrante del
messaggio, per cui togliendo l'opzione "A capo automatico" non perderete nulla.

Alla fine del vostro messaggio, appena prima di inserire la vostra patch,
aggiungete il delimitatore di patch: tre trattini (``---``).

Ora, dal menu :menuselection:`Messaggio`, selezionate :menuselection:`Inserisci file di testo...`
quindi scegliete la vostra patch.
Come soluzione aggiuntiva potreste personalizzare la vostra barra degli
strumenti aggiungendo un'icona per :menuselection:`Inserisci file di testo...`.

Allargate la finestra di scrittura abbastanza da evitare andate a capo.
Questo perché in Kmail 1.13.5 (KDE 4.5.4), Kmail aggiunge andate a capo
automaticamente al momento dell'invio per tutte quelle righe che graficamente,
nella vostra finestra di composizione, si sono estete su una riga successiva.
Disabilitare l'andata a capo automatica non è sufficiente. Dunque, se la vostra
patch contiene delle righe molto lunghe, allora dovrete allargare la finestra
di composizione per evitare che quelle righe vadano a capo. Vedere:
https://bugs.kde.org/show_bug.cgi?id=174034

Potete firmare gli allegati con GPG, ma per le patch si preferisce aggiungerle
al testo del messaggio per cui non usate la firma GPG.  Firmare le patch
inserite come testo del messaggio le rende più difficili da estrarre dalla loro
codifica a 7-bit.

Se dovete assolutamente inviare delle patch come allegati invece di integrarle
nel testo del messaggio, allora premete il tasto destro sull'allegato e
selezionate :menuselection:`Proprietà`, e poi attivate
:menuselection:`Suggerisci visualizzazione automatica` per far si che
l'allegato sia più leggibile venendo visualizzato come parte del messaggio.

Per salvare le patch inviate come parte di un messaggio, selezionate il
messaggio che la contiene, premete il tasto destro e selezionate
:menuselection:`Salva come`. Se il messaggio fu ben preparato, allora potrete
usarlo interamente senza alcuna modifica.
I messaggi vengono salvati con permessi di lettura-scrittura solo per l'utente,
nel caso in cui vogliate copiarli altrove per renderli disponibili ad altri
gruppi o al mondo, ricordatevi di usare ``chmod`` per cambiare i permessi.

Lotus Notes (GUI)
*****************

Scappate finché potete.

IBM Verse (Web GUI)
*******************

Vedi il commento per Lotus Notes.

Mutt (TUI)
**********

Un sacco di sviluppatori Linux usano ``mutt``, per cui deve funzionare
abbastanza bene.

Mutt non ha un proprio editor, quindi qualunque sia il vostro editor dovrete
configurarlo per non aggiungere automaticamente le andate a capo.  Molti
editor hanno un'opzione :menuselection:`Inserisci file` che inserisce il
contenuto di un file senza alterarlo.

Per usare ``vim`` come editor per mutt::

  set editor="vi"

Se per inserire la patch nel messaggio usate xclip, scrivete il comando::

  :set paste

prima di premere il tasto centrale o shift-insert. Oppure usate il
comando::

  :r filename

(a)llega funziona bene senza ``set paste``

Potete generare le patch con ``git format-patch`` e usare Mutt per inviarle::

    $ mutt -H 0001-some-bug-fix.patch

Opzioni per la configurazione:

Tutto dovrebbe funzionare già nella configurazione base.
Tuttavia, è una buona idea quella di impostare ``send_charset``::

   set send_charset="us-ascii:utf-8"

Mutt è molto personalizzabile. Qui di seguito trovate la configurazione minima
per iniziare ad usare Mutt per inviare patch usando Gmail::

  # .muttrc
  # ================  IMAP ====================
  set imap_user = 'yourusername@gmail.com'
  set imap_pass = 'yourpassword'
  set spoolfile = imaps://imap.gmail.com/INBOX
  set folder = imaps://imap.gmail.com/
  set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
  set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
  set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"

  # ================  SMTP  ====================
  set smtp_url = "smtp://username@smtp.gmail.com:587/"
  set smtp_pass = $imap_pass
  set ssl_force_tls = yes # Require encrypted connection

  # ================  Composition  ====================
  set editor = `echo \$EDITOR`
  set edit_headers = yes  # See the headers when editing
  set charset = UTF-8     # value of $LANG; also fallback for send_charset
  # Sender, email address, and sign-off line must match
  unset use_domain        # because joe@localhost is just embarrassing
  set realname = "YOUR NAME"
  set from = "username@gmail.com"
  set use_from = yes

La documentazione di Mutt contiene molte più informazioni:

    https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail

    http://www.mutt.org/doc/manual/

Pine (TUI)
**********

Pine aveva alcuni problemi con gli spazi vuoti, ma questi dovrebbero essere
stati risolti.

Se potete usate alpine (il successore di pine).

Opzioni di configurazione:

- Nelle versioni più recenti è necessario avere ``quell-flowed-text``
- l'opzione ``no-strip-whitespace-before-send`` è necessaria

Sylpheed (GUI)
**************

- funziona bene per aggiungere testo in linea (o usando allegati)
- permette di utilizzare editor esterni
- è lento su cartelle grandi
- non farà l'autenticazione TSL SMTP su una connessione non SSL
- ha un utile righello nella finestra di scrittura
- la rubrica non comprende correttamente il nome da visualizzare e
  l'indirizzo associato

Thunderbird (GUI)
*****************

Thunderbird è un clone di Outlook a cui piace maciullare il testo, ma esistono
modi per impedirglielo.

- permettere l'uso di editor esterni:
  La cosa più semplice da fare con Thunderbird e le patch è quello di usare
  l'estensione "external editor" e di usare il vostro ``$EDITOR`` preferito per
  leggere/includere patch nel vostro messaggio.  Per farlo, scaricate ed
  installate l'estensione e aggiungete un bottone per chiamarla rapidamente
  usando :menuselection:`Visualizza-->Barra degli strumenti-->Personalizza...`;
  una volta fatto potrete richiamarlo premendo sul bottone mentre siete nella
  finestra :menuselection:`Scrivi`

  Tenete presente che "external editor" richiede che il vostro editor non
  faccia alcun fork, in altre parole, l'editor non deve ritornare prima di
  essere stato chiuso.  Potreste dover passare dei parametri aggiuntivi al
  vostro editor oppure cambiargli la configurazione.  Per esempio, usando
  gvim dovrete aggiungere l'opzione -f ``/usr/bin/gvim -f`` (Se il binario
  si trova in ``/usr/bin``) nell'apposito campo nell'interfaccia di
  configurazione di  :menuselection:`external editor`.  Se usate altri editor
  consultate il loro  manuale per sapere come configurarli.

Per rendere l'editor interno un po' più sensato, fate così:

- Modificate le impostazioni di Thunderbird per far si che non usi
  ``format=flowed``. Andate in :menuselection:`Modifica-->Preferenze-->Avanzate-->Editor di configurazione`
  per invocare il registro delle impostazioni.

- impostate ``mailnews.send_plaintext_flowed`` a ``false``

- impostate ``mailnews.wraplength`` da ``72`` a ``0``

- :menuselection:`Visualizza-->Corpo del messaggio come-->Testo semplice`

- :menuselection:`Visualizza-->Codifica del testo-->Unicode`

TkRat (GUI)
***********

Funziona. Usare "Inserisci file..." o un editor esterno.

Gmail (Web GUI)
***************

Non funziona per inviare le patch.

Il programma web Gmail converte automaticamente i tab in spazi.

Allo stesso tempo aggiunge andata a capo ogni 78 caratteri. Comunque
il problema della conversione fra spazi e tab può essere risolto usando
un editor esterno.

Un altro problema è che Gmail usa la codifica base64 per tutti quei messaggi
che contengono caratteri non ASCII. Questo include cose tipo i nomi europei.