feat: cli skel

This commit is contained in:
lohhiiccc 2026-04-29 16:43:47 +02:00 committed by lohhiiccc
parent 52c007a247
commit df1f050d68
19 changed files with 334 additions and 16 deletions

View file

@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
SUBDIRS =
if BUILD_BUNDLED_LIBCLI
SUBDIRS += libcli
@ -9,3 +9,5 @@ endif
if BUILD_BUNDLED_LIBFT_SSL
SUBDIRS += libft_ssl
endif
SUBDIRS += src

View file

@ -69,9 +69,6 @@ AS_IF([test "x$have_system_libcli" != "xyes"], [
AC_CONFIG_SUBDIRS([libcli])
])
///
AC_ARG_WITH([bundled-libft_ssl],
AS_HELP_STRING(
[--with-bundled-libft_ssl],
@ -98,10 +95,6 @@ AS_IF([test "x$have_system_libft_ssl" != "xyes"], [
])
////
AC_CONFIG_FILES([
Makefile
src/Makefile

View file

16
includes/compiler.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef COMPILER_H
#define COMPILER_H
#define __unused __attribute__((unused))
#define COUNT_OF(arr) (sizeof(arr) / sizeof((arr)[0]))
#define STATIC_ARRAY_FOREACH(arr, ptr) \
for ((ptr) = (arr); (ptr) < (arr) + COUNT_OF(arr); (ptr)++)
#define HAS_FLAG(flags, flag) ((flags) & (flag))
#define SET_FLAG(flags, flag) ((flags) |= (flag))
#define CLEAR_FLAG(flags, flag) ((flags) &= ~(flag))
#define TOGGLE_FLAG(flags, flag) ((flags) ^= (flag))
#endif

19
includes/ft_ssl.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef FT_SSL_H
#define FT_SSL_H
#include <cli.h>
#include <libft_ssl.h>
#include <stdint.h>
struct ssl_config
{
const struct digest_algo *algo;
uint8_t flags;
const char *string;
char **files;
int nb_files;
};
enum cli_code cli_parse_arguments(int argc, char **argv, struct ssl_config *config);
#endif

8
includes/ft_ssl_flags.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef FT_SSL_FLAGS_H
#define FT_SSL_FLAGS_H
#define FLAG_P (1 << 0)
#define FLAG_Q (1 << 1)
#define FLAG_R (1 << 2)
#endif

View file

@ -0,0 +1,15 @@
#ifndef FT_SSL_CLI_HANDLER_H
#define FT_SSL_CLI_HANDLER_H
#include <cli.h>
extern const struct option_descriptor g_options[];
int cli_handle_help(const char *arg, void *config);
int cli_handle_version(const char *arg, void *config);
int cli_handle_p(const char *arg, void *config);
int cli_handle_q(const char *arg, void *config);
int cli_handle_r(const char *arg, void *config);
int cli_handle_s(const char *arg, void *config);
#endif

View file

@ -0,0 +1,68 @@
#ifndef FT_SSL_OPT_H
#define FT_SSL_OPT_H
#include <cli.h>
#define FT_SSL_OPTION_LIST \
X( \
'h', \
"help", \
no_argument, \
cli_handle_help, \
OPT_ARG_NONE, \
"Display this help and exit" \
) \
X( \
'V', \
"version", \
no_argument, \
cli_handle_version, \
OPT_ARG_NONE, \
"Display version information and exit" \
) \
X( \
'p', \
"stdin", \
no_argument, \
cli_handle_p, \
OPT_ARG_NONE, \
"Echo stdin to stdout and append checksum to output" \
) \
X( \
'q', \
"quiet", \
no_argument, \
cli_handle_q, \
OPT_ARG_NONE, \
"Quiet mode: only print the digest" \
) \
X( \
'r', \
"reverse", \
no_argument, \
cli_handle_r, \
OPT_ARG_NONE, \
"Reverse the output format (digest then filename)" \
) \
X( \
's', \
"string", \
required_argument, \
cli_handle_s, \
OPT_ARG_STRING, \
"Hash a string" \
)
#undef X
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) + 1
enum { FT_SSL_OPT_LEN = (0 FT_SSL_OPTION_LIST ) };
#undef X
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
+ (1 * (has_arg == no_argument) \
+ (2 * (has_arg == required_argument) \
+ (3 * (has_arg == optional_argument))))
enum { FT_SSL_OPTSTR_LEN = (2 FT_SSL_OPTION_LIST) };
/* +2 for ':' to disable getopt error messages and \0 */
#endif

@ -1 +1 @@
Subproject commit bf43c7a124130db8fbbce1e496af4f3aacd07316
Subproject commit f21811b66f4f5d29ada3a53bd91763cac3f6d87f

View file

@ -1,9 +1,11 @@
bin_PROGRAMS = ft_ssl
FT_SSL_VERSION = 0.0.1
BUILT_SOURCES = $(VERSION_HEADER)
VERSION_HEADER = $(top_srcdir)/includes/version_gen.h
BUILT_SOURCES = $(VERSION_HEADER)
CLEANFILES = $(VERSION_HEADER)
$(VERSION_HEADER): FORCE
@NEW_HEADER=$$(mktemp); \
FT_SSL_BUILD_DATE=$$(git -C $(top_srcdir) log -1 --format=%cd \
@ -38,13 +40,21 @@ FORCE:
.PHONY: FORCE
ft_ssl_SOURCES = \
main.c
main.c \
cli/parse.c \
cli/handlers/option_map.c \
cli/handlers/handle_help.c \
cli/handlers/handle_version.c \
cli/handlers/handle_p.c \
cli/handlers/handle_q.c \
cli/handlers/handle_r.c \
cli/handlers/handle_s.c
ft_ssl_CPPFLAGS = \
-I $(top_srcdir)/includes \
-D_GNU_SOURCE
BASE_CFLAGS = -std=c99 $(STRICT_CFLAGS)
ft_ssl_CFLAGS = -std=c99 $(STRICT_CFLAGS)
ft_ssl_LDADD = -lm
@ -53,13 +63,13 @@ ft_ssl_CPPFLAGS += $(LIBCLI_CFLAGS)
ft_ssl_LDADD += $(LIBCLI_LIBS)
else
ft_ssl_CPPFLAGS += -I $(top_srcdir)/libcli/include
ft_ssl_LDADD += $(top_builddir)/libcli/src/libcli.la
endif
if USE_SYSTEM_LIBFT_SSL
ft_ssl_CPPFLAGS += $(LIBFT_SSL_CFLAGS)
ft_ssl_LDADD += $(LIBFT_SSL_LIBS)
else
ft_ssl_CPPFLAGS += -I $(top_srcdir)/libft_ssl/include
ft_ssl_LDADD += $(top_builddir)/libft_ssl/src/libft_ssl.la
endif

View file

@ -0,0 +1,11 @@
#include <cli.h>
#include "compiler.h"
#include "internal/cli/option.h"
#include "internal/cli/cli_handlers.h"
int
cli_handle_help(__unused const char *arg, __unused void *config_void)
{
cli_print_options(g_options, FT_SSL_OPT_LEN, cli_arg_type_to_str);
return CLI_EXIT_SUCCESS;
}

View file

@ -0,0 +1,13 @@
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/cli/cli_handlers.h"
int
cli_handle_p(__unused const char *arg, void *config_void)
{
struct ssl_config *config = (struct ssl_config *)config_void;
SET_FLAG(config->flags, FLAG_P);
return CLI_SUCCESS;
}

View file

@ -0,0 +1,13 @@
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/cli/cli_handlers.h"
int
cli_handle_q(__unused const char *arg, void *config_void)
{
struct ssl_config *config = (struct ssl_config *)config_void;
SET_FLAG(config->flags, FLAG_Q);
return CLI_SUCCESS;
}

View file

@ -0,0 +1,13 @@
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/cli/cli_handlers.h"
int
cli_handle_r(__unused const char *arg, void *config_void)
{
struct ssl_config *config = (struct ssl_config *)config_void;
SET_FLAG(config->flags, FLAG_R);
return CLI_SUCCESS;
}

View file

@ -0,0 +1,11 @@
#include "ft_ssl.h"
#include "internal/cli/cli_handlers.h"
int
cli_handle_s(const char *arg, void *config_void)
{
struct ssl_config *config = (struct ssl_config *)config_void;
config->string = arg;
return CLI_SUCCESS;
}

View file

@ -0,0 +1,12 @@
#include <stdio.h>
#include <cli.h>
#include "compiler.h"
int
cli_handle_version(__unused const char *arg, __unused void *config_void)
{
printf("version x\n");
return CLI_EXIT_SUCCESS;
}

View file

@ -0,0 +1,13 @@
#include "internal/cli/cli_handlers.h"
#include "internal/cli/option.h"
#undef X
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc) \
{ short_opt, long_opt, has_arg, handler, arg_type, desc },
const struct option_descriptor g_options[] = {
FT_SSL_OPTION_LIST
{0, NULL, 0, NULL, OPT_ARG_NONE, NULL }
};
#undef X

80
src/cli/parse.c Normal file
View file

@ -0,0 +1,80 @@
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <cli.h>
#include <libft_ssl.h>
#include "ft_ssl.h"
#include "internal/cli/cli_handlers.h"
#include "internal/cli/option.h"
/* Forward declarations */
static void init_config(struct ssl_config *config);
static const struct digest_algo *find_algo(const char *name);
static enum cli_code parse_subcommand(int argc, char **argv, int first_arg,
struct ssl_config *config);
/* ------------------- */
static const struct digest_algo * const s_algos[] = {
&g_md5,
&g_sha256,
NULL
};
enum cli_code
cli_parse_arguments(int argc, char **argv, struct ssl_config *config)
{
char opt_str[FT_SSL_OPTSTR_LEN];
struct option long_opts[FT_SSL_OPT_LEN + 1];
enum cli_code ret;
init_config(config);
ret = cli_parse(argc, argv, config, g_options, FT_SSL_OPT_LEN, opt_str, long_opts);
if (CLI_SUCCESS != ret)
return ret;
return parse_subcommand(argc, argv, optind, config);
}
static enum cli_code
parse_subcommand(int argc, char **argv, int first_arg,
struct ssl_config *config)
{
if (first_arg >= argc)
{
fprintf(stderr, "%s: missing command\n", argv[0]);
fprintf(stderr, "usage: %s {md5|sha256} [-pqr] [-s string] [file...]\n",
argv[0]);
return CLI_ERROR;
}
config->algo = find_algo(argv[first_arg]);
if (NULL == config->algo)
{
fprintf(stderr, "%s: unknown command -- '%s'\n", argv[0], argv[first_arg]);
fprintf(stderr, "usage: %s {md5|sha256} [-pqr] [-s string] [file...]\n",
argv[0]);
return CLI_ERROR;
}
config->files = argv + first_arg + 1;
config->nb_files = argc - first_arg - 1;
return CLI_SUCCESS;
}
static const struct digest_algo *
find_algo(const char *name)
{
size_t i;
for (i = 0; NULL != s_algos[i]; i++)
{
if (0 == strcmp(s_algos[i]->name, name))
return s_algos[i];
}
return NULL;
}
static void
init_config(struct ssl_config *config)
{
memset(config, 0, sizeof(struct ssl_config));
}

View file

@ -1,6 +1,27 @@
#include <stdlib.h>
#include <cli.h>
#include "ft_ssl.h"
char *g_prog_name = NULL;
int
main()
main(int argc, char **argv)
{
return 0;
struct ssl_config config = {0};
int ret = CLI_ERROR;
g_prog_name = argv[0];
cli_set_prog_name(g_prog_name);
ret = cli_parse_arguments(argc, argv, &config);
if (CLI_SUCCESS != ret)
goto cleanup;
/* TODO:
* ret = ssl_run(&config);
*/
cleanup:
return (CLI_ERROR == ret) ? 2 : EXIT_SUCCESS;
}