Argp Örnekleri
Önceki Argp Sonraki
Argp Örnekleri
Bu örnek yazılımlarla argp arayüzünün temel kullanımı örneklenmeye çalışılmıştır.
1. Örnek
Bu örnekte, argp arayüzünü kullanan olası en küçük yazılımın nasıl olacağı gösterilmiştir. Komut satırında mevcut olmayan bir seçenek belirtildiğinde bir hata iletisi basıp çıkmak dışında birşey yapmaz. --help seçeneği ile ise argp arayüzünde gerçeklenmiş seçeneklerin yardım iletisini basar.
/* 1. Argp örneği -- argp kullanılan en küçük yazılım */

/* Bu, argp kullanılan (olası) en küçük yazılımdır.
   --help ve --usage ile yardım ve kısa kullanım iletisi
   basmak dışında, sadece tanımsız bir komut satırı seçeneği
   ya da argümanı için bir hata iletisi basar. */

#include <argp.h>

int main (int argc, char **argv)
{
  argp_parse (0, argc, argv, 0, 0, 0);
  exit (0);
}
Çıktısı şöyle birşey oluyor:
~/deneme$ gcc deneme.c
~/deneme$ ./a.out
~/deneme$ ./a.out --help
Usage: a.out [OPTION...]

  -?, --help                 Give this help list
      --usage                Give a short usage message
~/deneme$ ./a.out --usage
Usage: a.out [-?] [--help] [--usage]
~/deneme$ ./a.out --version
./a.out: unrecognized option `--version'
Try `a.out --help' or `a.out --usage' for more information.
~/deneme$ ./a.out alooo
a.out: Too many arguments
Try `a.out --help' or `a.out --usage' for more information.
2. Örnek
Bu yazılımda GNU standart komut satırı biçimi ile uyumlu argp kullanımı dışında herhangi bir seçenek ya da argüman tanımlanmamıştır.
--help ve --usage seçeneklerine ek olarak GNU standartlarına uygun olarak bir de --version seçeneğine sahiptir. GNU standardındaki gibi --help çıktısında açıklayıcı bir dizge ile hata bildirme adresi basar.
argp değişkeni argüman çözümleyici belirtimini içerir. argp_parse işlevine parametreler bu yapının alanları üzerinden aktarılır. Normalde ilk üç alan kullanılır ama bu küçük yazılımda kullanılmamıştır. Argp arayüzünün kullandığı iki genel değişken bu yazılımda kullanılmıştır: argp_program_version ve argp_program_bug_address. Bunlar, hemen hemen her yazılımda çeşitli görevler için farklı argüman çözümleyiciler kullanılıyor olsa bile, daima birer sabit olarak verildiğinden genel değişkenler olacağı varsayılmıştır.
/* 2. Argp Örneği - Argp kullanılan az küçük bir yazılım */

/*  Bu yazılımda GNU standart komut satırı biçimi ile uyumlu argp
    kullanımı dışında herhangi bir seçenek ya da argüman
    tanımlanmamıştır.

    --help ve --usage seçeneklerine ek olarak GNU standartlarına uygun
    olarak bir de --version seçeneğine sahiptir. GNU standardındaki gibi
    --help çıktısında açıklayıcı bir dizge ile hata bildirme adresi basar.

    argp değişkeni argüman çözümleyici belirtimini içerir. argp_parse
    işlevine parametreler bu yapının alanları üzerinden aktarılır. Normalde
    ilk üç alan kullanılır ama bu küçük yazılımda kullanılmamıştır. Argp
    arayüzünün kullandığı iki genel değişken bu yazılımda kullanılmıştır:
    argp_program_version ve  argp_program_bug_address.
    Bunlar, hemen hemen her yazılımda çeşitli görevler için farklı
    argüman çözümleyiciler kullanılıyor olsa bile, daima birer sabit
    olarak verildiğinden genel değişkenler olacağı varsayılmıştır. */

#include <argp.h>

const char *argp_program_version =
  "argp-ex2 1.0";
const char *argp_program_bug_address =
  "<bug-gnu-utils@gnu.org>";

/* Yazılım açıklaması. */
static char doc[] =
  "Argp example #2 -- a pretty minimal program using argp";

/*  Argüman çözümleyicimiz. options, parser, ve
    args_doc alanları sıfırdır, çünkü bizim seçenek ve
    argümanımız yok. --help seçeneğinin çıktısında doc ve
    argp_program_bug_address, --version seçeneğinin çıktısında ise
    argp_program_version kullanılacak.  */
static struct argp argp = { 0, 0, 0, doc };

int main (int argc, char **argv)
{
  argp_parse (&argp, argc, argv, 0, 0, 0);
  exit (0);
}
Çıktısı şöyle birşey oluyor:
~/deneme$ gcc -o argp-ex2 deneme.c
~/deneme$ ./argp-ex2 --version
argp-ex2 1.0
~/deneme$ ./argp-ex2 --help
Usage: argp-ex2 [OPTION...]
Argp example #2 -- a pretty minimal program using argp

  -?, --help                 Give this help list
      --usage                Give a short usage message
  -V, --version              Print program version

Report bugs to <bug-gnu-utils@gnu.org>.
~/deneme$ ./argp-ex2 --usage
Usage: argp-ex2 [-?V] [--help] [--usage] [--version]
3. örnek
Bu yazılımda 2. örneğe ek olarak bazı kullanıcı seçenekleri ve argümanları kullanılmıştır.
Bu örnekte argp'nin ilk dört alanını kullandık (Argp Çözümleyicisinin Belirtilmesi) ve çözümleyici işlev olarak parse_opt işlevini belirttik. Bkz. Argp Çözümleyici İşlevleri.
Bu örnekte, main işlevinde parse_opt ile iletişim için bir yapı kullanıldığına dikkat edin. Bu yapı, bir gösterici olarak argp_parse tarafından input argümanında aktarılır. Bkz. Argp. parse_opt işlevi tarafından state argümanının input alanı ile alınır. Bkz. Argp Çözümleme Durumu. Şüphesiz bunun yerine genel değişkenler kullanmak mümkündür ama böyle bir yapı kullanmak biraz daha esnek ve temizdir.
/* 3. Argp Örneği -- Argp arayüzünü ek seçenek ve argümanlarla
   kullanan bir yazılım örneği
*/

/*  Bu yazılımda 2. örneğe ek olarak bazı kullanıcı seçenekleri ve
    argümanları kullanılmıştır.

    Bu örnekte argp'nin ilk dört alanını kullandık:
      options  - argp_option vektörüne bir gösterici (aşağıya bakın)
      parser   - argp tarafından çağrılan ve tek bir seçeneği çözümleyen işlev
      args_doc - seçenek olmayan argümanların kullanımını açıklayan bir dizge
      doc      - bu yazılımın açıklamasını içeren dizge; bir düşey sekme (\v)
                 içeriyorsa, bundan sonraki parça seçeneklerden sonra basılır

    parser işlevi şu argümanları alır:
      key  - Seçeneğin türünü (argp_option yapısının KEY alanından alınarak)
             ya da bunun dışında birşeyi belirten özel bir anahtar; burada
             kullandığımız tek özel anahtar bir seçenek olmayan argüman
             belirten ARGP_KEY_ARG anahtarıdır. ARGP_KEY_END anahtarı ise
             tüm argümanların çözümlendiğini belirtir.
      arg  - bir dizge olarak seçenek argümanı; argümansızsa NULL
      state - argp_state yapısına bir gösterici; çözümleme durumu ile ilgili
             faydalı bilgiler içerir. Burada kullanılan, argp_parse işlevinin
             girdi argümanı olan input alanı ile çözümlenen
             seçenek olmayan argümanın numarasını içeren arg_num alanıdır.
    İşlev başarılı ise 0 ile belirtilen anahtar bilinmiyorsa ARGP_ERR_UNKNOWN
    ile ya da başka bir hatayı belirten bir hata kodu ile dönmelidir.

    Bu örnekte, main işlevinde parse_opt ile iletişim için bir yapı
    kullanıldığına dikkat edin. Bu yapı, bir gösterici olarak argp_parse
    tarafından input argümanında aktarılır. parse_opt işlevi tarafından
    state argümanının input alanı ile alınır. Şüphesiz bunun yerine genel
    değişkenler kullanmak mümkündür ama böyle bir yapı kullanmak biraz daha
    esnek ve temizdir.

    options alanı bir argp_option vektörüne bir gösterici içerir; bu yapı
    aşağıdaki alanlara sahiptir (bu örnekteki gibi dizi ilklendirmesiyle
    seçenek yapılarınıza atama yapıyorsanız, belirtilmeyen alanlar öntanımlı
    olarak 0 olacak ve belirtilmeleri gerekmeyecektir):
      name   - seçeneğin uzun seçenek ismi (sıfır olabilir)
      key    - bu seçenek ve seçeneğin kısa seçenek ismi (basılabilen bir ascii
               karakterse) çözümlenirken çözümleyici işleve aktarılacak anahtar.
      arg    - varsa, bu seçeneğinin argümanının ismi
      flags  - bu seçeneği açıklayan bayraklar; bazıları:
               OPTION_ARG_OPTIONAL - bu seçeneğin argümanı isteğe bağlıdır
               OPTION_ALIAS        - bu seçenek önceki seçeneğe bir takma addır.
               OPTION_HIDDEN       - --help çıktısında bu seçenek gösterilmez.
      doc    - --help çıktısında bu seçeneğin açıklamasını içeren dizge

    Bir seçenek vektörü tüm alanları sıfır değeri içeren bir yapı ile
    sonlanmalıdır.
*/

#include <argp.h>

const char *argp_yazılım_version =
  "argp-ex3 1.0";
const char *argp_yazılım_bug_address =
  "<bug-gnu-utils@gnu.org>";

/* Yazılım açıklaması. */
static char doc[] =
  "Argp example #3 -- a program with options and arguments using argp";

/* Kabul ettiğimiz argümanlar için bir açıklama. */
static char args_doc[] = "ARG1 ARG2";

/* Kabul ettiğimiz seçenekler. */
static struct argp_option options[] = {
  {"verbose",  'v', 0,      0,  "Produce verbose output" },
  {"quiet",    'q', 0,      0,  "Don't produce any output" },
  {"silent",   's', 0,      OPTION_ALIAS },
  {"output",   'o', "FILE", 0,
    "Output to FILE instead of standard output" },
  { 0 }
};

/* parse_opt ile main iletişiminde kullanılır. */
struct arguments
{
  char *args[2];                /* arg1 ve arg2 */
  int silent, verbose;
  char *output_file;
};

/* Tek bir seçeneği çözümlemek için. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  /* argp_parse'daki girdi argümanında bizim arguments
     yapısına bir gösterci olduğunu biliyoruz. */
  struct arguments *arguments = state->input;

  switch (key)
    {
    case 'q': case 's':
      arguments->silent = 1;
      break;
    case 'v':
      arguments->verbose = 1;
      break;
    case 'o':
      arguments->output_file = arg;
      break;

    case ARGP_KEY_ARG:
      if (state->arg_num >= 2)
        /* Argümanlar fazla geldi. */
        argp_usage (state);

      arguments->args[state->arg_num] = arg;

      break;

    case ARGP_KEY_END:
      if (state->arg_num & 2)
        /* Argümanlar yetersiz. */
        argp_usage (state);
      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

/* Argp çözümleyicimiz. */
static struct argp argp = { options, parse_opt, args_doc, doc };

int main (int argc, char **argv)
{
  struct arguments arguments;

  /* Öntanımlı değerler. */
  arguments.silent = 0;
  arguments.verbose = 0;
  arguments.output_file = "-";

  /* Argümanlarımız çözümlensin;  parse_opt tarafından
     görülen her seçenek arguments içine yansıyacak. */
  argp_parse (&argp, argc, argv, 0, 0, &arguments);

  printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
          "VERBOSE = %s\nSILENT = %s\n",
          arguments.args[0], arguments.args[1],
          arguments.output_file,
          arguments.verbose ? "yes" : "no",
          arguments.silent ? "yes" : "no");

  exit (0);
}
4. Örnek
Bu yazılım, 3. örnekteki özelliklerden fazla olarak daha fazla seçenek içerir ve --help çıktısı için daha fazla yapı kullanılmıştır. Ayrıca, bir öğe listesi kabul eden yazılımlar için belli bir noktadan sonraki girdi argümanlarının nasıl `çalınabileceği' gösterilmiştir. Bundan başka, yazılıma seçenek olmayan argümanların belirtilmediği durumda key argümanında ARGP_KEY_NO_ARGS anahtarının kullanımı gösterilmiştir. Bkz. Argp Çözümleyici İşlevleri için Özel Anahtarlar.
Yardım çıktısının yapılanması için iki özellik kullanılmıştır: başlıklar ve iki parçalı seçenek dizgesi. başlıklar seçenekler vektöründeki ilk dört alanı 0 olan girdilerdir. Bkz. Seçenekler. İki parçalı açıklama dizgesi doc değişkeninde belirtilmiştir. Açıklama dizgesinin düşey sekme karakterine ('\v' veya '\013') kadar olan kısmı seçeneklerden önce, kalan kısmı da seçeneklerden sonra basılır. Teamülen, seçeneklerden önce basılan kısım yazılımın ne iş yaptığını kısaca açıklamak içindir. Seçeneklerden sonra basılan kısım ise, yazılımın davranışını daha ayrıntılı açıklayan daha uzun bir dizgedir. Açıklama dizgesinin her iki parçası da çıktıya özdevinimli olarak sığdırılır, belli noktalarda satırları sonlandırmak için satırsonu karakterleri kullanılabilir. Ek olarak, açıklama dizgeleri o anki yerele uygun olarak çevrilmesi için gettext işlevine aktarılır.
/* 4. Argp Örneği - Biraz daha karmaşık seçenekli bir yazılım */

/*  Bu yazılım, 3. örnekteki özelliklerden fazla olarak daha fazla seçenek
    içerir ve --help çıktısı için daha fazla yapı kullanılmıştır.
    Ayrıca, bir öğe listesi kabul eden yazılımlar için belli bir noktadan
    sonraki girdi argümanlarının nasıl `çalınabileceği' gösterilmiştir.
    Bundan başka, yazılıma seçenek olmayan argümanların belirtilmediği durumda
    key argümanında ARGP_KEY_NO_ARGS anahtarının kullanımı gösterilmiştir.

    Yardım çıktısının yapılanması için iki özellik kullanılmıştır:
    başlıklar ve iki parçalı seçenek dizgesi.
    başlıklar, seçenekler vektöründeki ilk dört alanı 0 olan girdilerdir.
    İki parçalı açıklama dizgesi doc değişkeninde belirtilmiştir. Açıklama
    dizgesinin düşey sekme karakterine ('\v' veya '\013') kadar olan kısmı
    seçeneklerden önce, kalan kısmı da seçeneklerden sonra basılır. Teamülen,
    seçeneklerden önce basılan kısım yazılımın ne iş yaptığını kısaca
    açıklamak içindir. Seçeneklerden sonra basılan kısım ise, yazılımın
    davranışını daha ayrıntılı açıklayan daha uzun bir dizgedir. Açıklama
    dizgesinin her iki parçası da çıktıya özdevinimli olarak sığdırılır,
    belli noktalarda satırları sonlandırmak için satırsonu karakterleri
    kullanılabilir. Ek olarak, açıklama dizgeleri o anki yerele uygun olarak
    çevrilmesi için gettext işlevine aktarılır.
*/

#include <stdlib.h>
#include <error.h>
#include <argp.h>

const char *argp_program_version =
  "argp-ex4 1.0";
const char *argp_program_bug_address =
  "<bug-gnu-utils@prep.ai.mit.edu>";

/* Yazılım açıklaması. */
static char doc[] =
  "Argp example #4 -- a yazılım with somewhat more complicated\
options\
\vThis part of the documentation comes *after* the options;\
  note that the text is automatically filled, but it's possible\
  to force a line-break, e.g.\n<-- here.";

/* Kabul ettiğimiz argümanlar için açıklama. */
static char args_doc[] = "ARG1 [STRING...]";

/* Kısa seçeneksiz seçenekler için anahtarlar. */
#define OPT_ABORT  1            /* -abort */

/* Kabul ettiğimiz seçenekler. */
static struct argp_option options[] = {
  {"verbose",  'v', 0,       0, "Produce verbose output" },
  {"quiet",    'q', 0,       0, "Don't produce any output" },
  {"silent",   's', 0,       OPTION_ALIAS },
  {"output",   'o', "FILE",  0,
    "Output to FILE instead of standard output" },

  {0,0,0,0, "The following options should be grouped together:" },
  {"repeat",   'r', "COUNT", OPTION_ARG_OPTIONAL,
    "Repeat the output COUNT (default 10) times"},
  {"abort",    OPT_ABORT, 0, 0, "Abort before showing any output"},

  { 0 }
};

/* main ile parse_opt'un iletişimi için kullanılır. */
struct arguments
{
  char *arg1;                   /* arg1 */
  char **strings;               /* [string...] */
  int silent, verbose, abort;   /* -s, -v, --abort */
  char *output_file;            /* --output için dosya ismi*/
  int repeat_count;             /* --repeat için argüman sayısı*/
};

/* Tek bir seçeneği çözümlemek için. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  /* argp_parse'daki girdi argümanında bizim arguments
     yapısına bir gösterci olduğunu biliyoruz. */
  struct arguments *arguments = state->input;

  switch (key)
    {
    case 'q': case 's':
      arguments->silent = 1;
      break;
    case 'v':
      arguments->verbose = 1;
      break;
    case 'o':
      arguments->output_file = arg;
      break;
    case 'r':
      arguments->repeat_count = arg ? atoi (arg) : 10;
      break;
    case OPT_ABORT:
      arguments->abort = 1;
      break;

    case ARGP_KEY_NO_ARGS:
      argp_usage (state);

    case ARGP_KEY_ARG:
      /*  Burada daha fazla argüman alabilecekken çözümlemeyi
          sonlandırdığımız için state->arg_num == 0 olduğunu biliyoruz. */
      arguments->arg1 = arg;

      /*  Artık kalan tüm argümanları tüketebiliriz.
          state->next ilgilendiğimiz ilk dizge olarak çözümlenecek sonraki
          argümanın state->argv içindeki indisidir.
          Yani, arguments->strings için değer olarak
          &state->argv[state->next] kullanabiliriz.

          Buna ek olarak, state->next'e argümanların sonunu atayarak,
          argp'nin çözümlemeyi burada sonlandırıp dönmesini sağlayabiliriz. */
      arguments->strings = &state->argv[state->next];
      state->next = state->argc;

      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

/* Argp çözümleyicimiz. */
static struct argp argp = { options, parse_opt, args_doc, doc };

int main (int argc, char **argv)
{
  int i, j;
  struct arguments arguments;

  /* Öntanımlı değerler. */
  arguments.silent = 0;
  arguments.verbose = 0;
  arguments.output_file = "-";
  arguments.repeat_count = 1;
  arguments.abort = 0;

  /* Argümanlarımız çözümlensin;  parse_opt tarafından
     görülen her seçenek arguments içine yansıyacak. */
  argp_parse (&argp, argc, argv, 0, 0, &arguments);

  if (arguments.abort)
    error (10, 0, "ABORTED");

  for (i = 0; i < arguments.repeat_count; i++)
    {
      printf ("ARG1 = %s\n", arguments.arg1);
      printf ("STRINGS = ");
      for (j = 0; arguments.strings[j]; j++)
        printf (j == 0 ? "%s" : ", %s", arguments.strings[j]);
      printf ("\n");
      printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n",
              arguments.output_file,
              arguments.verbose ? "yes" : "no",
              arguments.silent ? "yes" : "no");
    }

  exit (0);
}
Önceki Üst Ana Başlık Sonraki
argp_help Bayrakları Başlangıç Alt Seçeneklerin Çözümlenmesi
Bir Linux Kitaplığı Sayfası