1

About the situation:

Greetings, I am working on a project "osfi" in C (with cmake but targeted to be run only on Linux-based OSes), i required a function that parses arguments passed from command line, so i wrote one using the GNU C argp.h. I ended up creating a library osfi_arg_parser.c that contains that function.

Here's what my program and library snippets looks like:

osfi.c

#include <stdbool.h>
#include "project_config.h"
#include "arg_parser.h"
// other includes...

int main(int argc, char **argv)
{
  struct arg_parser_arguments *arguments_p = arg_parser_parse(argc, argv);
  // other code...
  return(0);
}

arg_parser.c

#include <stdbool.h>
#include <argp.h>
#include "project_config.h"
#include "arg_parser.h"

// version string is passed by cmake through project_config.h.in and project_config.h
// need to add if a define passed by cmake is NULL, then disable program_version program_bug_address
const char *argp_program_version = "osfi " PROJECT_VERSION;
const char *argp_program_bug_address = PROJECT_BUG_ADDRESS;
#define argp_program_version_hook
#define argp_err_exit_status  0
static char doc[] = "Tool that aims automating and speeding up installation "\
                    "and configuration process of Linux-based OSes.";
static char args_doc[] = "[OPTION]...";
static struct argp_option option[] =
{
  {
    "output-dir",      'o',                    "[FILE_TYPE:]OUTPUT_DIR",
    0,
    "Path to directory where to output files of type FILE_TYPE: FILE_TYPE can be \"none\" (default if omitted), \"i\", \"p\", \"l\", \"install\", \"progress\", or \"log\"",
    0
  },
  { 0, 0, 0, 0, 0, 0 }
};
/*
//add another parser for plugin options
static error_t parse_plug_in_opt()
{
}
*/
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
  struct arg_parser_arguments *arguments_p = state->input;
  switch (key)
  {
    case 'o':
      arguments_p->option_output_dir = true;
      arguments_p->argument_output_dir = arg;
      break;
    case ARGP_KEY_NO_ARGS:
      break;

    default:
      return ARGP_ERR_UNKNOWN;
  }
  return 0;
}

void argp_initialize_arg_parser_arguments(struct arg_parser_arguments
                                          *arguments_p)
{
  arguments_p->option_output_dir = false;
  arguments_p->argument_output_dir = "-";
}

//static struct argp_child *argp_child = {  };
static struct argp argp = { option, parse_opt, args_doc, doc, 0, 0, 0};

struct arg_parser_arguments *arg_parser_parse(int argc, char **argv)
{
  struct arg_parser_arguments arguments, *arguments_p = &arguments;
  argp_initialize_arg_parser_arguments(arguments_p);
  argp_parse(&argp, argc, argv, 0, 0, arguments_p);
  return(arguments_p);
}

arg_parser.h

#ifndef ARG_PARSER_H_INCLUDED
#define ARG_PARSER_H_INCLUDED

struct arg_parser_arguments
{
  bool option_output_dir;
  char *argument_output_dir;
};

struct arg_parser_arguments *arg_parser_parse(int argc, char **argv);

#endif

NOTE: I know that code isn't refactored, to 79 characters lenght and possibly uses concepts that may be old, unpractical or unoptimized for speed or different architecture use cases (I'm only learning and hope with further reading & OTHER questions on stack I will turn my code better in many aspects)

The behaviour of my code:

[someincognitomachine@someanonyomususer osfi]$ ./build/bin/osfi  --help
Usage: osfi [OPTION...] [OPTION]...
Tool that aims automating and speeding up installation and configuration
process of Linux-based OSes.

  -o,                              --output-dir=[FILE_TYPE:]OUTPUT_DIR
Path to directory where to output files of type
                             FILE_TYPE: FILE_TYPE can be "none" (default if
                             omitted), "i", "p", "l", "install", 

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

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

Report bugs to .

The Questions:

  1. How to make argp aware of where i want my --output-dir=[FILE_TYPE:]OUTPUT_DIR and <documertation-of-the-option> generated strings placed?
  2. Is there a permanent solution for solving this text behaviour problem? (I have tried to use OPTION_DOC and adding an option under the 'o' option just with documentation string part on the option, all kinds of escape sequences in the string.)
-o,                              --output-dir=[FILE_TYPE:]OUTPUT_DIR
Path to directory where to output files of type
                             FILE_TYPE: FILE_TYPE can be "none" (default if
                             omitted), "i", "p", "l", "install", "progress", or
                             "log"

Edit 1: replaced actual code with snippets

user398271
  • 41
  • 3

0 Answers0