getopt, getopt_long, getopt_long_only - Analyser les options en ligne de commande.
La fonction
getopt()
analyse les arguments de la ligne de commande. Ses éléments
argc
et
argv
correspondent aux nombres et à la table d'arguments qui sont transmis à
la fonction
main()
lors du lancement du programme.
Un élément de
argv qui commence par `-' (et qui ne soit pas uniquement "-" ou "--")
est considéré comme une option. Les caractères à la suite du '-' initial sont les
caractères de l'option. Si
getopt() est appelée à plusieurs reprises, elle
renverra successivement chaque caractère de chaque option.
Si
getopt() trouve un caractère d'option, elle le renvoie, mettant à jour
la variable externe
optind et la variable statique
nextchar pour
préparer l'appel suivant a
getopt().
S'il n'y a plus de caractères d'option,
getopt() renvoie
EOF.
Alors,
optind devient l'index du premier élément de
argv qui ne
soit pas une option.
optstring
est une chaîne contenant l'ensemble des caractères d'option autorisés. Si un de
ces caractères est suivi par un double-point, l'option nécessite un argument
supplémentaire, et
getopt placera un pointeur sur le texte correspondant
de
argv dans
optarg.
Deux doubles-points signifient qu'une option prend un argument optionnel. S'il existe
un texte dans le même élément de
argv, il est renvoyé dans
optarg, sinon
optarg contient zéro.
Il s'agit d'une extension GNU. Si
optstring
contient
W
suivi d'un point-virgule, alors
-W foo
est traité comme l'option longue
--foo.
(L'option
-W
est réservée par POSIX.2 pour des extensions spécifique à l'implémentation).
Ce comportement, spécifique à la version GNU, n'est pas disponible avant
la bibliothèque GNU libc 2.
Par défaut,
getopt() permute les éléments de
argv au fur et à
mesure de son analyse, ainsi tous les arguments éventuels ne constituant pas
des options se trouvent à la fin. Deux autres modes sont également implémentés :
Si le premier caractère de
optstring vaut `+', ou si la variable
d'environnement POSIXLY_CORRECT est validée, alors l'analyse
s'arrête aussitot qu'un argument ne constituant pas une option est rencontré.
Si le premier caractère de
optstring vaut `-', alors les arguments
ne correspondant pas à une option sont manipulés comme s'ils étaient des
arguments d'une option dont le caractère soit le caractère de code 1.
Ceci est utilisé par les programmes qui sont conçus pour recevoir des
options et d'autres éléments de
argv et qui prennent en compte
l'ordre des arguments.
L'argument spécial `--' arrête l'analyse des options, quelque soit le
mode en cours.
Si
getopt() ne reconnaît pas un caractère d'option, il affiche un
message d'erreur sur la sortie standard stderr, stocke le caractère dans
optopt, et renvoie `?'. Le programme appelant peut empêcher l'affichage
du message d'erreur en positionnant
opterr à 0.
Si
getopt() trouve dans
argv un caractère d'option non inclus dans
optstring, ou s'il manque un argument d'option, l'appel renvoie
`?' et remplit la variable externe
optopt avec le vrai caractère trouvé.
Si le premier caractère de
optstring est un deux-points (`:'), alors
getopt() renvoie `:' plutôt que `?' pour indiquer un argument d'option
manquant. Si une erreur est détectée, si le premier caractère de
optstring
n'est PAS un deux-points, et si la variable externe
opterr est non-nulle,
(nulle par défaut), alors
getopt() affiche un message d'erreur.
La fonction
getopt_long()
fonctionne comme
getopt()
sauf qu'elle accepte également des noms longs d'option, commencant par deux
tirets.
Les noms longs d'option peuvent être abrégés, si l'abréviation est unique,
ou si elle correspond exactement à une option définie.
Une option longue peut prendre un argument, de la forme
--arg=param
ou
--arg param.
longopts
est un pointeur sur le premier élément d'un tableau de structures
struct option
déclarées dans
<getopt.h>
ainsi :
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
La signification des différents champs est la suivante :
- name
-
est le nom de l'option longue.
- has_arg
-
vaut :
no_argument (ou 0), si l'option ne prend pas d'argument,
required_argument (ou 1) si l'option prend un argument, ou
optional_argument (ou 2) si l'option prend un argument optionnel.
- flag
-
spécifie la manière de renvoyer les résultats pour une option longue. Si
flag vaut NULL, alors getopt_long() renvoie val.
(Par exemple le programme appelant peut remplir val avec le caractère
de l'option courte correspondante). Sinon, getopt_long() renvoie 0, et
flag pointe sur une variable correspondant à val si l'option est
trouvée, mais reste inchangé si l'option est absente.
- val
-
est la valeur à renvoyer, ou à charger dans la variable pointée par flag.
Le dernier élément de la table doit être rempli avec des zéros.
Si
longindex n'est pas
NULL, il pointe sur une variable qui est
remplie avec l'index de l'option longue correspondant à
longopts.
getopt_long_only() fonctionne comme
getopt_long(), mais `-' tout
comme `--' indiquent une option longue. Si une option commençant par `-'
(et non `--') ne correspond pas à une option longue, mais correspond à une
option courte, elle est analysee en tant qu'option courte.
Le programme suivant illustre l'utilisation de
getopt_long()
avec la plupart de ses fonctionnaliteé.
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 1, 0, 'c'},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" avec argument %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("chiffre dans deux arguments.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c de valeur `%s'\n", optarg);
break;
case 'd':
printf ("option d de valeur `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? caractère de code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("Arguments ne constituant pas des options: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
Christophe Blaess, 1996-2003.