| ||||||
/* 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 =
"<[email protected]>";
/* 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 <[email protected]>.
~/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 =
"<[email protected]>";
/* 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 =
"<[email protected]>";
/* 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);
}
| |||||||||