GETOPT(3)

NOME
getopt - analisa sintaticamente das opções da linha de comando (parsing)

SINÓPSE
#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);

DESCRIÇÃO
A função getopt() analisa os argumentos da linha de comando. Seus argumentos argc e argv são, respectivamente, a contagem de argumentos e o array como passados para a função main() na invocação do programa. Um elemento de argv que inicia com '-' (e não é exatamente '-' ou '--') é um elemento de opção. Os caracteres deste elemento (fora o '-' inicial) são caracteres de opção. Se getopt() é chamado repetidamente, ele retorna sucessivamente cada um dos caracteres de opção de cada um dos elementos de opção.

Se getopt() encontra um outro caractere de opção, ela retorna este caractere, atualizando a variável externa optind e uma variável estática nextchar de forma que a próxima chamada a getopt() pode continuar a busca com o caractere de opção seguinte ou um elemento de argv.

Se não há mais caracteres de opção, getopt() retorna -1. Então optind é o índice em argv do primeiro elemento de argv que não é uma opção.

optstring é uma string contendo os caracteres de opção legítimos. Se tal caractere é seguido por dois-pontos, a opção requer um argumento, então getopt atribui um ponteiro para o texto que segue no mesmo elemento de argv, ou para o texto do elemento seguinte de argv, em optarg. Dois dois-pontos significam que uma opção recebe um argumento opcional; se há texto no elemento de argv atual, ele é retornado em optarg, caso contrário optarg é zerado. Esta é uma extensão GNU. Se optstring contém W seguido de um ponto-e-vírgula, então -W foo é tratado como a opção longa --foo. (A opção -W é reservada pelo POSIX.2 para extensões de implementação.) Este comportamento é uma extensão GNU, não disponível em bibliotecas anteriores à GNU libc 2.

Por padrão, getopt() permuta o conteúdo de argv enquanto realiza a busca, de forma que finalmente todas as não-opções estão no fim. Dois outros modos são também implementados. Se o primeiro caractere de optstring é '+' ou a variável de ambiente POSIXLY_CORRECT está ligada, então o processamento de opções para tão logo um argumento que não é uma opção é encontrado. Se o primeiro caractere de optstring é '-', então cada elemento de argv que não é uma opção é tratado como se fosse um argumento de uma opção com código de caractere 1. (Isto é usado por programas que foram escritos para esperar opções e outros elementos de argv em qualquer ordem e que se importam com a ordem dos dois.) O argumento especial '--' força um fim de busca de opções independentemente do modo de busca.

Se getopt() não reconhece um caractere de opção, ele imprime uma mensagem de erro para stderr, guarda o caractere em optopt, e retorna '?'. O programa chamador pode evitar a mensagem de erro ajustando opterr para 0.

A função getopt_long() funciona como getopt() exceto que ele também aceita opções longas, iniciadas por dois traços. Nomes de opções longas podem ser abreviados se a abreviação for única ou se iguala exatamente àlguma opção definida. Uma opção longa pode recer um parâmetro da forma --arg=param ou --arg param.

longopts é um ponteiro para o primeiro elemento de um array de struct option declarado em <getopt.h> como

struct option {
const char *name;
int has_arg;
int *flag;
int val;
};

Os significados dos diferentes campos são:

nome
    é o nome da opção longa.

has_arg
    é: no_argument (ou 0) se a opção não recebe um argumento, required_argument (ou 1) se a opção requer um argumento, ou optional_argument (ou 2) se a opção recebe um argumento opcional.

flag
    especifica como os resultados são retornados para uma opção longa. Se flag é NULO, então getopt_long() retorna val. (Por exemplo, o programa chamador pode ajustar val para o caractere de opção curta equivalente.) Caso contrário, getopt_long() retorna 0, e flag aponta para uma variável a qual é ajustada para val se a opção é encontrada, mas deixada intocada se a opção não é encontrada.

val é o valor a retornar, ou a carregar para a variável apontada por flag.

O último elemento do array tem que ser preenchido com zeros.

Se longindex não é NULO, aponta para uma variável a qual é ajustada para o índice da opção longa relativa a longopts.

getopt_long_only() é como getopt_long(), mas tanto '-' como '--' podem indicar uma opção longa. Se uma opção que começa com '-' (não '--') não for igual a uma opção longa, mas é igual a uma opção curta, ela é interpretada como uma opção curta.

VALORES RETORNADOS
A função getopt() retorna o caractere de opção se a opção foi encontrada com sucesso, ':' se houve um parâmetro faltando para uma das opções, '?' para um caractere de opção desconhecido, ou -1 para o fim da lista de opções.

getopt_long() e getopt_long_only() também retornam o caractere de opção quando uma opção curta é reconhecida. Para uma opção longa, elas retornam val se flag é NULO, e 0 caso contrário. Retornos de erro e de -1 significam o mesmo que para getopt(), mais '?' para opção ambígua ou um parâmetro estranho.

VARIÁVEIS DE AMBIENTE

POSIXLY_CORRECT
    Se ligada, então o processamento de opção para tão logo um argumento que não é uma opção seja encontrado.

_<PID>_GNU_nonoption_argv_flags_
    Esta variável foi usada pelo programa bash 2.0 para comunicar à GNU libc quais argumentos são os resultados da expansão de coringas e portanto não deveriam ser considerados como opções. Este comportamente foi removido no bash versão 2.01, mas o suporte foi mantido na GNU libc.

EXEMPLO
O seguinte programa exemplo do código fonte, ilustra o uso de getopt_long() com a maioria de seus recursos.

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for 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);
}

PROBLEMAS
A especificação POSIX.2 de getopt() tem um erro técnico descrito na Interpretação 150 do POSIX.2. A implementação GNU (e provavelmente todas as outras) implementam o comportamento correto em vez do que está especificado.

DE ACORDO COM

getopt():
    POSIX.2, desde que a variável de ambiente POSIXLY_CORRECT está ligada. Caso contrário, os elementos de argv não são realmente const, porque nós os permutamos. Nós fingimos que eles são const no protótipo para ficar compatível com outros sistemas.

TRADUZIDO POR LDP-BR em 28/05/2001.

  Tradução:
Felipe M Pereira <Felipe.Pereira@ic.unicamp.br>

  Revisão.:
André Luiz Fassone <lonely_wolf@ig.com.br>