mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
300 lines
10 KiB
C++
300 lines
10 KiB
C++
/*
|
|
MIT License
|
|
|
|
Copyright (c) 2022 Leonard Iklé
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
/**
|
|
* This is a simple alternative cross-platform implementation of getopt, which
|
|
* is used to parse argument strings submitted to the executable (argc and argv
|
|
* which are received in the main function).
|
|
*/
|
|
|
|
#ifndef CAG_LIBRARY_H
|
|
#define CAG_LIBRARY_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
/**
|
|
* The following defines CAG_EXPORT and CAG_IMPORT which are required to export
|
|
* shared library functions.
|
|
*/
|
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
#define CAG_EXPORT __declspec(dllexport)
|
|
#define CAG_IMPORT __declspec(dllimport)
|
|
#elif __GNUC__ >= 4
|
|
#define CAG_EXPORT __attribute__((visibility("default")))
|
|
#define CAG_IMPORT __attribute__((visibility("default")))
|
|
#else
|
|
#define CAG_EXPORT
|
|
#define CAG_IMPORT
|
|
#endif
|
|
|
|
/**
|
|
* This block defines CAG_PUBLIC, which only uses CAG_EXPORT and CAG_IMPORT if
|
|
* the cargs is compiled as a shared library.
|
|
*/
|
|
#if defined(CAG_SHARED)
|
|
#if defined(CAG_EXPORTS)
|
|
#define CAG_PUBLIC CAG_EXPORT
|
|
#else
|
|
#define CAG_PUBLIC CAG_IMPORT
|
|
#endif
|
|
#else
|
|
#define CAG_PUBLIC
|
|
#endif
|
|
|
|
/**
|
|
* This block defines CAG_DEPRECATED which can be used to deprecate library
|
|
* functions including a comment on the deprecation.
|
|
*/
|
|
#if (!__cplusplus && __STDC_VERSION__ >= 202311L) || (__cplusplus >= 201402L)
|
|
#define CAG_DEPRECATED(comment) [[deprecated(comment)]]
|
|
#else
|
|
#define CAG_DEPRECATED(comment)
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
/**
|
|
* An option is used to describe a flag/argument option submitted when the
|
|
* program is run.
|
|
*/
|
|
typedef struct cag_option
|
|
{
|
|
const char identifier;
|
|
const char *access_letters;
|
|
const char *access_name;
|
|
const char *value_name;
|
|
const char *description;
|
|
} cag_option;
|
|
|
|
/**
|
|
* A context is used to iterate over all options provided. It stores the parsing
|
|
* state.
|
|
*/
|
|
typedef struct cag_option_context
|
|
{
|
|
const struct cag_option *options;
|
|
size_t option_count;
|
|
int argc;
|
|
char **argv;
|
|
int index;
|
|
int inner_index;
|
|
int error_index;
|
|
char error_letter;
|
|
bool forced_end;
|
|
char identifier;
|
|
char *value;
|
|
} cag_option_context;
|
|
|
|
/**
|
|
* Prototype for printer used in cag_option_printer. For example fprintf have
|
|
* same prototype
|
|
*/
|
|
typedef int (*cag_printer)(void *ctx, const char *fmt, ...);
|
|
|
|
/**
|
|
* This is just a small macro which calculates the size of an array.
|
|
*/
|
|
#define CAG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
|
|
/**
|
|
* @brief Prepare argument options context for parsing.
|
|
*
|
|
* This function prepares the context for iteration and initializes the context
|
|
* with the supplied options and arguments. After the context has been prepared,
|
|
* it can be used to fetch arguments from it.
|
|
*
|
|
* @param context The context which will be initialized.
|
|
* @param options The registered options which are available for the program.
|
|
* @param option_count The amount of options which are available for the
|
|
* program.
|
|
* @param argc The amount of arguments the user supplied in the main function.
|
|
* @param argv A pointer to the arguments of the main function.
|
|
*/
|
|
CAG_PUBLIC void cag_option_init(cag_option_context *context,
|
|
const cag_option *options, size_t option_count, int argc, char **argv);
|
|
|
|
/**
|
|
* @brief Fetches an option from the argument list.
|
|
*
|
|
* This function fetches a single option from the argument list. The context
|
|
* will be moved to that item. Information can be extracted from the context
|
|
* after the item has been fetched.
|
|
* The arguments will be re-ordered, which means that non-option arguments will
|
|
* be moved to the end of the argument list. After all options have been
|
|
* fetched, all non-option arguments will be positioned after the index of
|
|
* the context.
|
|
*
|
|
* @param context The context from which we will fetch the option.
|
|
* @return Returns true if there was another option or false if the end is
|
|
* reached.
|
|
*/
|
|
CAG_PUBLIC bool cag_option_fetch(cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Gets the identifier of the option.
|
|
*
|
|
* This function gets the identifier of the option, which should be unique to
|
|
* this option and can be used to determine what kind of option this is.
|
|
*
|
|
* @param context The context from which the option was fetched.
|
|
* @return Returns the identifier of the option.
|
|
*/
|
|
CAG_PUBLIC char cag_option_get_identifier(const cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Gets the value from the option.
|
|
*
|
|
* This function gets the value from the option, if any. If the option does not
|
|
* contain a value, this function will return NULL.
|
|
*
|
|
* @param context The context from which the option was fetched.
|
|
* @return Returns a pointer to the value or NULL if there is no value.
|
|
*/
|
|
CAG_PUBLIC const char *cag_option_get_value(const cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Gets the current index of the context.
|
|
*
|
|
* This function gets the index within the argv arguments of the context. The
|
|
* context always points to the next item which it will inspect. This is
|
|
* particularly useful to inspect the original argument array, or to get
|
|
* non-option arguments after option fetching has finished.
|
|
*
|
|
* @param context The context from which the option was fetched.
|
|
* @return Returns the current index of the context.
|
|
*/
|
|
CAG_PUBLIC int cag_option_get_index(const cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Retrieves the index of an invalid option.
|
|
*
|
|
* This function retrieves the index of an invalid option if the provided option
|
|
* does not match any of the options specified in the `cag_option` list. This is
|
|
* particularly useful when detailed information about an invalid option is
|
|
* required.
|
|
*
|
|
* @param context Pointer to the context from which the option was fetched.
|
|
* @return Returns the index of the invalid option, or -1 if it is not invalid.
|
|
*/
|
|
CAG_PUBLIC int cag_option_get_error_index(const cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Retrieves the letter character of the invalid option.
|
|
*
|
|
* This function retrieves the character of the invalid option character
|
|
* if the provided option does not match any of the options specified in the
|
|
* `cag_option` list.
|
|
*
|
|
* @param context Pointer to the context from which the option was fetched.
|
|
* @return Returns the letter that was unknown, or 0 otherwise.
|
|
*/
|
|
CAG_PUBLIC char cag_option_get_error_letter(const cag_option_context *context);
|
|
|
|
/**
|
|
* @brief Prints the error associated with the invalid option to the specified
|
|
* destination.
|
|
*
|
|
* This function prints information about the error associated with the invalid
|
|
* option to the specified destination (such as a file stream). It helps in
|
|
* displaying the error of the current context.
|
|
*
|
|
* @param context Pointer to the context from which the option was fetched.
|
|
* @param destination Pointer to the file stream where the error information
|
|
* will be printed.
|
|
*/
|
|
#ifndef CAG_NO_FILE
|
|
CAG_PUBLIC void cag_option_print_error(const cag_option_context *context,
|
|
FILE *destination);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Prints the error associated with the invalid option using user
|
|
* callback.
|
|
*
|
|
* This function prints information about the error associated with the invalid
|
|
* option using user callback. Callback prototype is same with fprintf. It helps
|
|
* in displaying the error of the current context.
|
|
*
|
|
* @param context Pointer to the context from which the option was fetched.
|
|
* @param printer The printer callback function. For example fprintf.
|
|
* @param printer_ctx The parameter for printer callback. For example fprintf
|
|
* could use parameter stderr.
|
|
*/
|
|
CAG_PUBLIC void cag_option_printer_error(const cag_option_context *context,
|
|
cag_printer printer, void *printer_ctx);
|
|
|
|
/**
|
|
* @brief Prints all options to the terminal.
|
|
*
|
|
* This function prints all options to the terminal. This can be used to
|
|
* generate the output for a "--help" option.
|
|
*
|
|
* @param options The options which will be printed.
|
|
* @param option_count The option count which will be printed.
|
|
* @param destination The destination where the output will be printed.
|
|
*/
|
|
#ifndef CAG_NO_FILE
|
|
CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
|
|
FILE *destination);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Prints all options using user callback.
|
|
*
|
|
* This function prints all options using user callback. This can be used to
|
|
* generate the output for a "--help" option.
|
|
* Using user callback is useful in tiny system without FILE support
|
|
*
|
|
* @param options The options which will be printed.
|
|
* @param option_count The option count which will be printed.
|
|
* @param destination The destination where the output will be printed.
|
|
* @param printer The printer callback function. For example fprintf.
|
|
* @param printer_ctx The parameter for printer callback. For example fprintf
|
|
* could use parameter stderr.
|
|
*/
|
|
CAG_PUBLIC void cag_option_printer(const cag_option *options,
|
|
size_t option_count, cag_printer printer, void *printer_ctx);
|
|
|
|
CAG_DEPRECATED(
|
|
"cag_option_prepare has been deprecated. Use cag_option_init instead.")
|
|
CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
|
|
const cag_option *options, size_t option_count, int argc, char **argv);
|
|
|
|
CAG_DEPRECATED(
|
|
"cag_option_get has been deprecated. Use cag_option_get_identifier instead.")
|
|
CAG_PUBLIC char cag_option_get(const cag_option_context *context);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#endif
|