Argument Parsing with argp()
swget.c
—
C source code,
3 KB (3134 bytes)
File contents
// argp() demo program for swget project
// To compile: gcc -std=c99 -Werror -Wall -Wextra swget.c -o swget
#include <stdio.h> // Provides for printf, etc...
#include <stdlib.h> // Provides for exit, ...
#include <string.h> // Provides for memset, ...
#include <argp.h> // Provides GNU argp() argument parser
// Set up the argument parser
const char *argp_program_version = "swget 1.0";
const char *argp_program_bug_address = "<jshafer@pacific.edu>";
static char doc[] = "swget -- a simple web download utility";
static char args_doc[] = ""; // No standard arguments
// (i.e. arguments without "names")
// Options. Field 1 in ARGP.
// Order of fields: {NAME, KEY, ARG, FLAGS, DOC, GROUP}.
static struct argp_option options[] = {
{"url", 'u', "URL", 0, "URL of object to download", 0 },
{"destdir", 'd', "DESTDIR", 0, "Directory to save downloaded object to", 0 },
{"verbose", 'v', 0, 0, "Provide verbose output, including server headers", 0 },
{ 0, 0, 0, 0, 0, 0} // Last entry should be all zeros in all fields
};
/* Used by main to communicate with parse_opt. */
struct arguments
{
// char *args[0]; // No standard arguments (without flags)
int verbose; // For --verbose /-v
char *url; // Argument for --url / -d
char *destdir; // Argument for --destdir / -d
};
// Parser. Field 2 in ARGP.
// Order of parameters: KEY, ARG, STATE.
// Parse a single option.
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
// Figure out which option we are parsing, and decide
// how to store it
switch (key)
{
case 'v':
arguments->verbose = 1;
break;
case 'u':
arguments->url = arg;
break;
case 'd':
arguments->destdir = arg;
break;
case ARGP_KEY_END:
// Reached the last key.
// Check if our url and destdir REQUIRED "options" have been set to non-default values
if (strcmp(arguments->url, "") ==0 || strcmp(arguments->destdir, "") == 0)
{
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
// Our argp parser.
static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };
int main (int argc, char **argv)
{
struct arguments arguments;
// Parse our arguments; every option seen by parse_opt will be reflected in arguments.
// Default values.
arguments.verbose = 0;
arguments.url = ""; // Empty string - only contains null character
arguments.destdir = "";
argp_parse (&argp, argc, argv, 0, 0, &arguments);
printf ("User arguments:\n"
" url=%s\n"
" destdir=%s\n"
" verbose=%s\n",
arguments.url, // This is a pointer to the start of the URL char array
arguments.destdir, // This is a pointer to the start of the destir char array
arguments.verbose ? "yes" : "no"); // This is an integer we are testing
return (0);
}
