|
/* 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); }
~/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. 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); }
~/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. 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. 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); }
|