NOMBRE¶
getopt - Analiza las opciones de la línea de órdenes
SINOPSIS¶
#include <unistd.h>
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#define _GNU_SOURCE
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
DESCRIPCIÓN¶
La función
getopt() analiza los argumentos de la línea de
órdenes. Sus argumentos
argc y
argv son el número
y el vector de argumentos como los pasados a la función
main()
cuando se ejecuta el programa. Un elemento de
argv que comience con '-'
(y que no sea exactamente "-" ni "--") es un elemento de
opción. Los caracteres de este elemento (aparte del '-' inicial) son
caracteres de opción. Si
getopt() se llama repetidamente,
devuelve sucesivamente cada uno de los caracteres de opción de cada uno
de los elementos de opción.
Si
getopt() encuentra otro carácter de opción, lo devuelve,
actualizando la variable externa
optind y una variable estática
nextchar de forma que la siguiente llamada a
getopt() pueda
seguir la búsqueda en el siguiente carácter de opción o
elemento de
argv.
Si no hay más caracteres de opción,
getopt() devuelve -1.
Entonces
optind es el índice en
argv del primer elemento
de
argv que no es una opción.
optstring es una cadena que contiene los caracteres de opción
legítimos. Si un carácter de éstos es seguido por el
carácter de dos puntos, la opción necesita un argumento, de
forma que
getopt coloca un puntero al texto siguiente en el mismo
elemento de
argv, o el texto del siguiente elemento de
argv, en
optarg. Dos caracteres de dos puntos significan que una opción
toma un arg. opcional; si hay texto en el elemento de
argv actual, se
devuelve en
optarg; si no,
optarg se pone a cero. Lo siguiente
es una extensión de GNU. Si
optstring contiene
W seguido
por un punto y coma, entonces
-W foo se trata como la opción
larga
--foo. (La opción
-W está reservada en
POSIX.2 para extensiones de implementación). Este comportamiento es una
extensión de GNU, no disponible en bibliotecas anteriores a la
versión 2 de GNU libc.
Por omisión,
getopt() permuta los contenidos de
argv cuando
lo escudriña, de modo que todo lo que no sea una opción vaya al
final. Están implementados otros dos modos de operación. Si el
primer carácter de
optstring es '+' o está definida la
variable de ambiente POSIXLY_CORRECT, entonces el procesamiento de la
opción se para tan pronto se encuentra un argumento que no es una
opción. Si el primer carácter de
optstring es '-',
entonces cada elemento de
argv que no sea una opción se maneja
como si fuera el argumento de una opción con código de
carácter 1. (Esto se usa en programas que fueron escritos para esperar
opciones y otros elementos de
argv en cualquier orden y donde importa
el ordenamiento de ambos). El argumento especial '--' fuerza que se acabe el
rastreo de las opciones sin tenerse en cuenta el modo.
Si
getopt() no reconoce un carácter de opción, muestra un
mensaje de error en stderr, guarda el carácter en
optopt, y
devuelve '?'. El programa que llama a la función puede evitar el
mensaje de error poniendo
opterr a 0.
Si
getopt() encuentra un carácter de opción en
argv
que no estaba incluido en
optstring, o si detecta que falta un
argumento de opción, devuelve `?' y pone en la variable externa
optopt el carácter de opción real. Si el primer
carácter de
optstring es un carácter de dos puntos (`:'),
getopt() devuelve `:' en lugar de `?' para indicar que falta un
argumento de opción. Si se detecta un error, y el primer
carácter de
optstring no es un carácter de dos puntos, y
la variable externa
opterr es distinta de cero (que es el valor por
defecto),
getopt() muestra un mensaje de error.
La función
getopt_long() trabaja como
getopt() salvo en que
también acepta opciones largas, que empiezan por dos guiones. Los
nombres de opción largos pueden abreviarse si la abreviatura es
única o si es una concordancia exacta para alguna opción
definida. Una opción larga puede tomar un parámetro, de la forma
--arg=param o
--arg param.
longopts es un puntero al primer elemento de un vector de
struct
option declarado en
<getopt.h> como
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
Los significados de los diferentes campos son:
- name
- es el nombre de la opción larga.
- has_arg
- es: no_argument (ó 0) si la opción no toma un
argumento, required_argument (ó 1) si la opción
requiere un argumento, u optional_argument (ó 2) si la
opción toma un argumento opcional.
- flag
- especifica cómo se devuelven los resultados para una opción
larga. Si flag es NULL, entonces getopt_long()
devuelve val. (Por ejemplo, el programa puede poner val como
el carácter de opción corta equivalente.) De otro modo,
getopt_long() devuelve 0, y flag apunta a una variable que
se pone a val si la opción se encuentra, pero que se deja
intacta si la opción no se encuentra.
- val
- es el valor a devolver, o a cargar en la variable apuntada por
flag.
El último elemento del vector tiene que ser llenado con ceros.
Si
longindex no es
NULL, apunta a una variable que toma el valor
del índice de la opción larga relativa a
longopts.
getopt_long_only() es como
getopt_long(), pero tanto `-' como `--'
pueden indicar una opción larga. Si una opción que empiece por
`-' (no `--') no concordara con una opción larga, pero sí con
una corta, se consideraría como tal.
VALOR DEVUELTO¶
La función
getopt() devuelve el carácter de la
opción si ésta se ha encontrado, ':' si faltaba un
parámetro de alguna de las opciones, '?' para un carácter de
opción desconocida, o -1 si se ha llegado al final de la lista de
opciones.
getopt_long() y
getopt_long_only() también devuelven el
carácter de la opción cuendo se reconoce una corta. Para una
opción larga, devuelven
val si
flag es
NULL, y 0
en otra circunstancia. Las devoluciones de error y -1 son las mismas que para
getopt(), más '?' indicando una concordancia ambigua o un
parámetro extraño.
VARIABLES DE AMBIENTE¶
- POSIXLY_CORRECT
- Si está definida, entonces el procesamiento de las opciones se para
tan pronto como se encuentre un argumento que no sea una
opción.
- _<PID>_GNU_nonoption_argv_flags_
- Esta variable era utilizada por bash 2.0 para comunicar a GNU libc
qué argumentos eran el resultado de la expansión de
comodines y, por tanto, no debían considerarse como opciones. Este
comportamiento se eliminó en la versión 2.01 de bash
pero el soporte permanece en GNU libc.
EJEMPLO¶
El siguiente programa de ejemplo ilustra el empleo de
getopt_long() con
la mayoría de sus características.
#include <stdio.h> /* para printf */
#include <stdlib.h> /* para exit */
#include <getopt.h>
int
main (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 (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\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 with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
FALLOS¶
La especificación POSIX.2 de
getopt() tiene un error
técnico descrito en la Interpretación 150 de POSIX.2. La
implementación GNU (y probablemente el resto de implementaciones)
implementa el comportamiento correcto en lugar del indicado.
- getopt():
- POSIX.2, supuesto que tengamos definida la variable de entorno
POSIXLY_CORRECT. Si no, los elementos de argv no son realmente
const, puesto que los permutamos. Los ponemos como const en el prototipo
para compatibilidad con otros sistemas.