Started rudimentary argument struct + parsing function prototypes

Fortune for sink's current commit: Half blessing − 半吉
args
Avril 3 years ago
parent 5d1daa98e4
commit c64f3f7499
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,26 @@
#include "args.h"
const pargs_t* parsed_args = NULL;
static const pargs_t default_args[1] = { A_DEFAULT_ARGS }; //A_DEFAULT_ARGS_P;
const pargs_t* a_get_program_args() {
return parsed_args ?: default_args;
}
bool a_is_parsed() { return parsed_args != NULL; }
enum arg_parse_result a_parse_into(pargs_t *restrict parsed, int *restrict argc, char** *restrict p_argv, char** *restrict p_envp)
{
//TODO
return A_PF_UNKNOWN;
}
enum arg_parse_result a_parse(int *restrict argc, char** *restrict p_argv, char** *restrict p_envp)
{
_Thread_local static pargs_t glob_parsed_args;
enum arg_parse_result r = a_parse_into(&glob_parsed_args, argc, p_argv, p_envp);
if(!r) parsed_args = &glob_parsed_args; // A_P_OK
return r;
}

@ -0,0 +1,68 @@
#ifndef _ARGS_H
#define _ARGS_H
#define _a_inline_proto __attribute__((__gnu_inline__, __always_inline__)) extern inline
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
enum arg_parse_result {
A_PF_UNKNOWN = -1,
A_P_OK = 0,
// TODO: specific errors...
};
typedef struct {
struct {
bool in,out,err;
} replace; // { 1, 1, 0 }
const char* target; // NULL -> default "/dev/null"
struct {
/*struct _Alignas(uint64_t) {
int64_t n : 63;
bool all : 1;
} __attribute__((packed, aligned(uint64_t)));*/
size_t n;
int fds[];
}* restrict fd_pass; // A_FD_PASS_NONE
} pargs_t;
#define A_FD_PASS_ALL ((void*)(~((uintptr_t)0ul)))
#define A_FD_PASS_NONE NULL
#define A_DEFAULT_ARGS ((pargs_t){ { true, true, false}, NULL, A_FD_PASS_NONE })
#define A_DEFAULT_ARGS_P ((pargs_t[1]) { A_DEFAULT_ARGS } )
extern const pargs_t* parsed_args;
/// Return parsed args or default args if no parsed args have been set.
_a_inline_proto const pargs_t* a_get_program_args()
{
__attribute__((section(".text#"))) // Does this give any actual benefit?
static const pargs_t default_args = A_DEFAULT_ARGS;
return parsed_args ?: &default_args;//A_DEFAULT_ARGS_P;
}
/// Have the program's arguments been parsed?
_a_inline_proto bool a_is_parsed()
{ return parsed_args != NULL; }
enum arg_parse_result a_parse_into(pargs_t *restrict parsed, int *restrict argc, char** *restrict p_argv, char** *restrict p_envp);
_a_inline_proto // TODO: XXX: Is this worth it?
enum arg_parse_result a_parse(int *restrict argc, char** *restrict p_argv, char** *restrict p_envp)
{
static pargs_t glob_parsed_args; //XXX: Wth is this an error?
enum arg_parse_result r = a_parse_into(&glob_parsed_args, argc, p_argv, p_envp);
if(!r) parsed_args = &glob_parsed_args; // A_P_OK
return r;
}
#undef _a_inline_proto
#endif /* _ARGS_H */

@ -8,6 +8,8 @@
#include "comp_features.h" #include "comp_features.h"
#include "args.h"
__attribute__((used)) // For loading debug binary symbol __attribute__((used)) // For loading debug binary symbol
const enum compiled_features sink_compiled_features = FEATURE_FLAGS; const enum compiled_features sink_compiled_features = FEATURE_FLAGS;
@ -206,8 +208,15 @@ static void print_debug_info(int argc, char* const* argv, char* const* envp)
#define print_debug_info(a,b,c) ((void)((void)(a), (void)(b), (void)(c))) #define print_debug_info(a,b,c) ((void)((void)(a), (void)(b), (void)(c)))
#endif #endif
static bool parse_args(int *restrict argc, char** *restrict argv, char** *restrict envp)
{
return a_parse(argc, argv, envp) == A_P_OK || true; //TODO: Print proper error messages on failures.
}
int main(int argc, char** argv, char** envp) int main(int argc, char** argv, char** envp)
{ {
if(!parse_args(&argc, &argv, &envp)) return 1;
#if FEATURE_HAS_FLAG(NO_ENV) #if FEATURE_HAS_FLAG(NO_ENV)
(void)envp; (void)envp;
#define GET_ENV ((char*[]){NULL}) #define GET_ENV ((char*[]){NULL})

Loading…
Cancel
Save