readarg/readopt.h

100 lines
2.6 KiB
C
Raw Normal View History

2021-02-08 16:07:25 +00:00
#pragma once
#include <stdio.h>
#define READOPT_ALLOC_STRINGS(...) ((char *[]){__VA_ARGS__, NULL})
2022-09-25 10:08:56 +00:00
enum readopt_error
{
READOPT_ERROR_SUCCESS,
READOPT_ERROR_NOVAL,
READOPT_ERROR_NOTREQ,
READOPT_ERROR_NOTOPT,
READOPT_ERROR_RANGEOPT,
READOPT_ERROR_RANGEOPER
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
enum readopt_form
{
READOPT_FORM_SHORT,
READOPT_FORM_LONG
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
enum readopt_format
{
READOPT_FORMAT_PLAIN,
READOPT_FORMAT_MDOC,
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
struct readopt_view_strings
{
const char **strings;
size_t len;
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
struct readopt_bounds
{
/* The upper value will be ignored if inf is non-zero. */
size_t val[2];
int inf;
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
struct readopt_oper
{
char *name;
struct readopt_bounds bounds;
struct readopt_view_strings val;
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
struct readopt_opt
{
/* Two null-terminated arrays of either long or short option names. */
char **names[2];
2021-02-08 16:07:25 +00:00
2022-09-25 10:08:56 +00:00
struct
{
int req;
2021-02-08 16:07:25 +00:00
2022-09-25 10:08:56 +00:00
/* oper.name is the name of the value itself (not the option). */
struct readopt_oper oper;
} cont;
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
struct readopt_parser
{
struct readopt_opt *opts;
struct readopt_oper *opers;
struct readopt_view_strings args;
struct
{
int pending;
const char *grppos;
struct
{
struct readopt_opt *opt;
/* Reference to the current argument being parsed. */
const char **arg;
/* Reference to the last element of the option/operand value view. */
const char **eoval;
/* Intermediate operands which have not yet been assigned. */
struct readopt_view_strings ioper;
} curr;
} state;
enum readopt_error error;
2021-02-08 16:07:25 +00:00
};
2022-09-25 10:08:56 +00:00
/* Iteratively parse the arguments. */
2021-03-02 17:25:50 +00:00
int readopt_parse(struct readopt_parser *rp);
2022-09-25 10:08:56 +00:00
/* args should always exclude the first element. */
2021-02-08 16:07:25 +00:00
void readopt_parser_init(struct readopt_parser *rp, struct readopt_opt *opts, struct readopt_oper *opers, struct readopt_view_strings args);
2022-09-25 10:08:56 +00:00
/* Check whether the argument is a valid option (can be used to check for the end of an array of options). */
2021-02-08 16:07:25 +00:00
int readopt_validate_opt(struct readopt_opt *opt);
2022-09-25 10:08:56 +00:00
/* Check whether the argument is a valid operand (can be used to check for the end of an array of operands). */
2021-02-08 16:07:25 +00:00
int readopt_validate_oper(struct readopt_oper *oper);
2022-09-25 10:08:56 +00:00
/* Check whether the operand's values are within the defined limits. */
2021-02-08 16:07:25 +00:00
int readopt_validate_within(struct readopt_oper *oper);
2022-09-25 10:08:56 +00:00
/* Get the upper limit. */
2021-02-08 16:07:25 +00:00
size_t readopt_select_upper(struct readopt_bounds bounds);
2022-09-25 10:08:56 +00:00
/* Get the lower limit. This does not always return the minimum. */
2021-02-08 16:07:25 +00:00
size_t readopt_select_lower(struct readopt_bounds bounds);