mirror of
https://github.com/tailix/libclayer.git
synced 2024-11-20 11:06:24 -05:00
Remove command line parser
This commit is contained in:
parent
e6181321b1
commit
e780eb67b7
14 changed files with 0 additions and 566 deletions
|
@ -77,9 +77,6 @@ endif
|
||||||
# Default packages #
|
# Default packages #
|
||||||
####################
|
####################
|
||||||
|
|
||||||
if WITH_CMDLINE
|
|
||||||
libkernaux_la_SOURCES += src/cmdline.c
|
|
||||||
endif
|
|
||||||
if WITH_ELF
|
if WITH_ELF
|
||||||
libkernaux_la_SOURCES += src/elf.c
|
libkernaux_la_SOURCES += src/elf.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -49,7 +49,6 @@ zero). Work-in-progress APIs can change at any time.
|
||||||
* [Mutex](/include/kernaux/generic/mutex.h) (*non-breaking since* **0.5.0**)
|
* [Mutex](/include/kernaux/generic/mutex.h) (*non-breaking since* **0.5.0**)
|
||||||
* Algorithms
|
* Algorithms
|
||||||
* [Free list memory allocator](/include/kernaux/free_list.h) (*non-breaking since* **0.5.0**)
|
* [Free list memory allocator](/include/kernaux/free_list.h) (*non-breaking since* **0.5.0**)
|
||||||
* [Simple command line parser](/include/kernaux/cmdline.h) (*non-breaking since* **0.2.0**)
|
|
||||||
* [Page Frame Allocator](/include/kernaux/pfa.h) (*work in progress*)
|
* [Page Frame Allocator](/include/kernaux/pfa.h) (*work in progress*)
|
||||||
* Data formats
|
* Data formats
|
||||||
* [ELF](/include/kernaux/elf.h) (*work in progress*)
|
* [ELF](/include/kernaux/elf.h) (*work in progress*)
|
||||||
|
@ -143,7 +142,6 @@ explicitly included, use `--without-all`.
|
||||||
* `--with[out]-arch-riscv64` - architecture riscv64
|
* `--with[out]-arch-riscv64` - architecture riscv64
|
||||||
* `--with[out]-arch-x86-64` - architecture x86-64
|
* `--with[out]-arch-x86-64` - architecture x86-64
|
||||||
* `--with[out]-asm` - kernel assembler helpers
|
* `--with[out]-asm` - kernel assembler helpers
|
||||||
* `--with[out]-cmdline` - command line parser
|
|
||||||
* `--with[out]-free-list` - free list memory allocator
|
* `--with[out]-free-list` - free list memory allocator
|
||||||
* `--with[out]-memmap` - memory map
|
* `--with[out]-memmap` - memory map
|
||||||
* `--with[out]-ntoa` - itoa/ftoa
|
* `--with[out]-ntoa` - itoa/ftoa
|
||||||
|
|
|
@ -66,7 +66,6 @@ AC_ARG_WITH( [arch-i386], AS_HELP_STRING([--without-arch-i386], [wit
|
||||||
AC_ARG_WITH( [arch-riscv64], AS_HELP_STRING([--without-arch-riscv64], [without architecture riscv64]))
|
AC_ARG_WITH( [arch-riscv64], AS_HELP_STRING([--without-arch-riscv64], [without architecture riscv64]))
|
||||||
AC_ARG_WITH( [arch-x86-64], AS_HELP_STRING([--without-arch-x86-64], [without architecture x86-64]))
|
AC_ARG_WITH( [arch-x86-64], AS_HELP_STRING([--without-arch-x86-64], [without architecture x86-64]))
|
||||||
AC_ARG_WITH( [asm], AS_HELP_STRING([--without-asm], [without kernel assembler helpers]))
|
AC_ARG_WITH( [asm], AS_HELP_STRING([--without-asm], [without kernel assembler helpers]))
|
||||||
AC_ARG_WITH( [cmdline], AS_HELP_STRING([--without-cmdline], [without command line parser]))
|
|
||||||
AC_ARG_WITH( [elf], AS_HELP_STRING([--without-elf], [without ELF utils]))
|
AC_ARG_WITH( [elf], AS_HELP_STRING([--without-elf], [without ELF utils]))
|
||||||
AC_ARG_WITH( [free-list], AS_HELP_STRING([--without-free-list], [without free list memory allocator]))
|
AC_ARG_WITH( [free-list], AS_HELP_STRING([--without-free-list], [without free list memory allocator]))
|
||||||
AC_ARG_WITH( [mbr], AS_HELP_STRING([--without-mbr], [without MBR utils]))
|
AC_ARG_WITH( [mbr], AS_HELP_STRING([--without-mbr], [without MBR utils]))
|
||||||
|
@ -107,7 +106,6 @@ if test -z "$with_arch_i386"; then with_arch_i386=no; fi
|
||||||
if test -z "$with_arch_riscv64"; then with_arch_riscv64=no; fi
|
if test -z "$with_arch_riscv64"; then with_arch_riscv64=no; fi
|
||||||
if test -z "$with_arch_x86_64"; then with_arch_x86_64=no; fi
|
if test -z "$with_arch_x86_64"; then with_arch_x86_64=no; fi
|
||||||
if test -z "$with_asm"; then with_asm=no; fi
|
if test -z "$with_asm"; then with_asm=no; fi
|
||||||
if test -z "$with_cmdline"; then with_cmdline=no; fi
|
|
||||||
if test -z "$with_elf"; then with_elf=no; fi
|
if test -z "$with_elf"; then with_elf=no; fi
|
||||||
if test -z "$with_free_list"; then with_free_list=no; fi
|
if test -z "$with_free_list"; then with_free_list=no; fi
|
||||||
if test -z "$with_mbr"; then with_mbr=no; fi
|
if test -z "$with_mbr"; then with_mbr=no; fi
|
||||||
|
@ -149,7 +147,6 @@ AS_IF([test "$with_arch_i386" = no ], [with_arch_i386=no], [wit
|
||||||
AS_IF([test "$with_arch_riscv64" = no ], [with_arch_riscv64=no], [with_arch_riscv64=yes])
|
AS_IF([test "$with_arch_riscv64" = no ], [with_arch_riscv64=no], [with_arch_riscv64=yes])
|
||||||
AS_IF([test "$with_arch_x86_64" = no ], [with_arch_x86_64=no], [with_arch_x86_64=yes])
|
AS_IF([test "$with_arch_x86_64" = no ], [with_arch_x86_64=no], [with_arch_x86_64=yes])
|
||||||
AS_IF([test "$with_asm" = no ], [with_asm=no], [with_asm=yes])
|
AS_IF([test "$with_asm" = no ], [with_asm=no], [with_asm=yes])
|
||||||
AS_IF([test "$with_cmdline" = no ], [with_cmdline=no], [with_cmdline=yes])
|
|
||||||
AS_IF([test "$with_elf" = no ], [with_elf=no], [with_elf=yes])
|
AS_IF([test "$with_elf" = no ], [with_elf=no], [with_elf=yes])
|
||||||
AS_IF([test "$with_free_list" = no ], [with_free_list=no], [with_free_list=yes])
|
AS_IF([test "$with_free_list" = no ], [with_free_list=no], [with_free_list=yes])
|
||||||
AS_IF([test "$with_mbr" = no ], [with_mbr=no], [with_mbr=yes])
|
AS_IF([test "$with_mbr" = no ], [with_mbr=no], [with_mbr=yes])
|
||||||
|
@ -209,7 +206,6 @@ AM_CONDITIONAL([WITH_ARCH_I386], [test "$with_arch_i386" = yes])
|
||||||
AM_CONDITIONAL([WITH_ARCH_RISCV64], [test "$with_arch_riscv64" = yes])
|
AM_CONDITIONAL([WITH_ARCH_RISCV64], [test "$with_arch_riscv64" = yes])
|
||||||
AM_CONDITIONAL([WITH_ARCH_X86_64], [test "$with_arch_x86_64" = yes])
|
AM_CONDITIONAL([WITH_ARCH_X86_64], [test "$with_arch_x86_64" = yes])
|
||||||
AM_CONDITIONAL([WITH_ASM], [test "$with_asm" = yes])
|
AM_CONDITIONAL([WITH_ASM], [test "$with_asm" = yes])
|
||||||
AM_CONDITIONAL([WITH_CMDLINE], [test "$with_cmdline" = yes])
|
|
||||||
AM_CONDITIONAL([WITH_ELF], [test "$with_elf" = yes])
|
AM_CONDITIONAL([WITH_ELF], [test "$with_elf" = yes])
|
||||||
AM_CONDITIONAL([WITH_FREE_LIST], [test "$with_free_list" = yes])
|
AM_CONDITIONAL([WITH_FREE_LIST], [test "$with_free_list" = yes])
|
||||||
AM_CONDITIONAL([WITH_MBR], [test "$with_mbr" = yes])
|
AM_CONDITIONAL([WITH_MBR], [test "$with_mbr" = yes])
|
||||||
|
@ -257,7 +253,6 @@ AS_IF([test "$with_arch_i386" = yes], [AC_DEFINE([WITH_ARCH_I386],
|
||||||
AS_IF([test "$with_arch_riscv64" = yes], [AC_DEFINE([WITH_ARCH_RISCV64], [1], [with architecture riscv64])])
|
AS_IF([test "$with_arch_riscv64" = yes], [AC_DEFINE([WITH_ARCH_RISCV64], [1], [with architecture riscv64])])
|
||||||
AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86_64], [1], [with architecture x86_64])])
|
AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86_64], [1], [with architecture x86_64])])
|
||||||
AS_IF([test "$with_asm" = yes], [AC_DEFINE([WITH_ASM], [1], [with kernel assembler helpers])])
|
AS_IF([test "$with_asm" = yes], [AC_DEFINE([WITH_ASM], [1], [with kernel assembler helpers])])
|
||||||
AS_IF([test "$with_cmdline" = yes], [AC_DEFINE([WITH_CMDLINE], [1], [with command line parser])])
|
|
||||||
AS_IF([test "$with_elf" = yes], [AC_DEFINE([WITH_ELF], [1], [with ELF utils])])
|
AS_IF([test "$with_elf" = yes], [AC_DEFINE([WITH_ELF], [1], [with ELF utils])])
|
||||||
AS_IF([test "$with_free_list" = yes], [AC_DEFINE([WITH_FREE_LIST], [1], [with free list memory allocator])])
|
AS_IF([test "$with_free_list" = yes], [AC_DEFINE([WITH_FREE_LIST], [1], [with free list memory allocator])])
|
||||||
AS_IF([test "$with_mbr" = yes], [AC_DEFINE([WITH_MBR], [1], [with MBR utils])])
|
AS_IF([test "$with_mbr" = yes], [AC_DEFINE([WITH_MBR], [1], [with MBR utils])])
|
||||||
|
@ -288,7 +283,6 @@ dnl Packages (enabled by default)
|
||||||
AS_IF([test "$with_arch_i386" = no], [AC_SUBST([comment_line_arch_i386], [//])])
|
AS_IF([test "$with_arch_i386" = no], [AC_SUBST([comment_line_arch_i386], [//])])
|
||||||
AS_IF([test "$with_arch_riscv64" = no], [AC_SUBST([comment_line_arch_riscv64], [//])])
|
AS_IF([test "$with_arch_riscv64" = no], [AC_SUBST([comment_line_arch_riscv64], [//])])
|
||||||
AS_IF([test "$with_arch_x86_64" = no], [AC_SUBST([comment_line_arch_x86_64], [//])])
|
AS_IF([test "$with_arch_x86_64" = no], [AC_SUBST([comment_line_arch_x86_64], [//])])
|
||||||
AS_IF([test "$with_cmdline" = no], [AC_SUBST([comment_line_cmdline], [//])])
|
|
||||||
AS_IF([test "$with_elf" = no], [AC_SUBST([comment_line_elf], [//])])
|
AS_IF([test "$with_elf" = no], [AC_SUBST([comment_line_elf], [//])])
|
||||||
AS_IF([test "$with_free_list" = no], [AC_SUBST([comment_line_free_list], [//])])
|
AS_IF([test "$with_free_list" = no], [AC_SUBST([comment_line_free_list], [//])])
|
||||||
AS_IF([test "$with_mbr" = no], [AC_SUBST([comment_line_mbr], [//])])
|
AS_IF([test "$with_mbr" = no], [AC_SUBST([comment_line_mbr], [//])])
|
||||||
|
|
|
@ -9,7 +9,6 @@ nobase_include_HEADERS = \
|
||||||
kernaux/asm/riscv64.h \
|
kernaux/asm/riscv64.h \
|
||||||
kernaux/asm/x86_64.h \
|
kernaux/asm/x86_64.h \
|
||||||
kernaux/asm/x86.h \
|
kernaux/asm/x86.h \
|
||||||
kernaux/cmdline.h \
|
|
||||||
kernaux/elf.h \
|
kernaux/elf.h \
|
||||||
kernaux/free_list.h \
|
kernaux/free_list.h \
|
||||||
kernaux/generic/display.h \
|
kernaux/generic/display.h \
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <kernaux/arch/i386.h>
|
#include <kernaux/arch/i386.h>
|
||||||
#include <kernaux/arch/riscv64.h>
|
#include <kernaux/arch/riscv64.h>
|
||||||
#include <kernaux/arch/x86_64.h>
|
#include <kernaux/arch/x86_64.h>
|
||||||
#include <kernaux/cmdline.h>
|
|
||||||
#include <kernaux/elf.h>
|
#include <kernaux/elf.h>
|
||||||
#include <kernaux/free_list.h>
|
#include <kernaux/free_list.h>
|
||||||
#include <kernaux/generic/display.h>
|
#include <kernaux/generic/display.h>
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef KERNAUX_INCLUDED_CMDLINE
|
|
||||||
#define KERNAUX_INCLUDED_CMDLINE
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#define KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX 256
|
|
||||||
#define KERNAUX_CMDLINE_ERROR_MSG_SLEN_MAX \
|
|
||||||
(KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX - 1)
|
|
||||||
|
|
||||||
bool kernaux_cmdline(
|
|
||||||
const char *cmdline,
|
|
||||||
char *error_msg,
|
|
||||||
size_t *argc,
|
|
||||||
char **argv,
|
|
||||||
char *buffer,
|
|
||||||
size_t arg_count_max,
|
|
||||||
size_t buffer_size
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef KERNAUX_INCLUDED_VERSION
|
#ifndef KERNAUX_INCLUDED_VERSION
|
||||||
#define KERNAUX_INCLUDED_VERSION
|
#define KERNAUX_INCLUDED_VERSION
|
||||||
|
|
||||||
@comment_line_cmdline@#define KERNAUX_VERSION_WITH_CMDLINE
|
|
||||||
@comment_line_elf@#define KERNAUX_VERSION_WITH_ELF
|
@comment_line_elf@#define KERNAUX_VERSION_WITH_ELF
|
||||||
@comment_line_free_list@#define KERNAUX_VERSION_WITH_FREE_LIST
|
@comment_line_free_list@#define KERNAUX_VERSION_WITH_FREE_LIST
|
||||||
@comment_line_mbr@#define KERNAUX_VERSION_WITH_MBR
|
@comment_line_mbr@#define KERNAUX_VERSION_WITH_MBR
|
||||||
|
|
|
@ -8,7 +8,6 @@ include/kernaux/asm/i386.h
|
||||||
include/kernaux/asm/riscv64.h
|
include/kernaux/asm/riscv64.h
|
||||||
include/kernaux/asm/x86.h
|
include/kernaux/asm/x86.h
|
||||||
include/kernaux/asm/x86_64.h
|
include/kernaux/asm/x86_64.h
|
||||||
include/kernaux/cmdline.h
|
|
||||||
include/kernaux/elf.h
|
include/kernaux/elf.h
|
||||||
include/kernaux/free_list.h
|
include/kernaux/free_list.h
|
||||||
include/kernaux/generic/display.h
|
include/kernaux/generic/display.h
|
||||||
|
|
291
src/cmdline.c
291
src/cmdline.c
|
@ -1,291 +0,0 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
|
|
||||||
#include <kernaux/cmdline.h>
|
|
||||||
#include <kernaux/macro.h>
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
INITIAL,
|
|
||||||
FINAL,
|
|
||||||
WHITESPACE,
|
|
||||||
TOKEN,
|
|
||||||
BACKSLASH,
|
|
||||||
QUOTE,
|
|
||||||
QUOTE_BACKSLASH,
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool kernaux_cmdline_common(
|
|
||||||
const char *cmdline,
|
|
||||||
char *error_msg,
|
|
||||||
size_t *argc,
|
|
||||||
char arg_terminator,
|
|
||||||
char **argv,
|
|
||||||
char *buffer,
|
|
||||||
size_t *arg_idxs,
|
|
||||||
size_t arg_count_max,
|
|
||||||
size_t buffer_size
|
|
||||||
);
|
|
||||||
|
|
||||||
static bool kernaux_cmdline_iter(
|
|
||||||
char cur,
|
|
||||||
enum State *state,
|
|
||||||
size_t *buffer_or_file_pos,
|
|
||||||
char *error_msg,
|
|
||||||
size_t *argc,
|
|
||||||
char arg_terminator,
|
|
||||||
char **argv,
|
|
||||||
char *buffer,
|
|
||||||
size_t *arg_idxs,
|
|
||||||
size_t arg_count_max,
|
|
||||||
size_t buffer_size
|
|
||||||
);
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* Implementations: public API *
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
bool kernaux_cmdline(
|
|
||||||
const char *const cmdline,
|
|
||||||
char *const error_msg,
|
|
||||||
size_t *const argc,
|
|
||||||
char **const argv,
|
|
||||||
char *const buffer,
|
|
||||||
const size_t arg_count_max,
|
|
||||||
const size_t buffer_size
|
|
||||||
) {
|
|
||||||
KERNAUX_NOTNULL(cmdline);
|
|
||||||
KERNAUX_NOTNULL(error_msg);
|
|
||||||
KERNAUX_ASSERT(argc);
|
|
||||||
KERNAUX_NOTNULL(argv);
|
|
||||||
KERNAUX_ASSERT(arg_count_max > 0);
|
|
||||||
KERNAUX_ASSERT(buffer_size > 0);
|
|
||||||
|
|
||||||
return kernaux_cmdline_common(
|
|
||||||
cmdline,
|
|
||||||
error_msg,
|
|
||||||
argc,
|
|
||||||
'\0', // arg_terminator
|
|
||||||
argv,
|
|
||||||
buffer,
|
|
||||||
NULL,
|
|
||||||
arg_count_max,
|
|
||||||
buffer_size
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* Implementation: main function *
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
#define CLEAR do { \
|
|
||||||
*argc = 0; \
|
|
||||||
if (argv) memset(argv, 0, sizeof(char*) * arg_count_max); \
|
|
||||||
if (buffer) memset(buffer, '\0', buffer_size); \
|
|
||||||
if (arg_idxs) memset(arg_idxs, 0, sizeof(size_t) * arg_count_max); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
bool kernaux_cmdline_common(
|
|
||||||
const char *const cmdline,
|
|
||||||
char *const error_msg,
|
|
||||||
size_t *const argc,
|
|
||||||
char arg_terminator,
|
|
||||||
char **const argv,
|
|
||||||
char *const buffer,
|
|
||||||
size_t *const arg_idxs,
|
|
||||||
const size_t arg_count_max,
|
|
||||||
const size_t buffer_size
|
|
||||||
) {
|
|
||||||
KERNAUX_NOTNULL(cmdline);
|
|
||||||
KERNAUX_NOTNULL(error_msg);
|
|
||||||
KERNAUX_ASSERT(argc);
|
|
||||||
(void)arg_idxs;
|
|
||||||
|
|
||||||
memset(error_msg, '\0', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
|
||||||
CLEAR;
|
|
||||||
|
|
||||||
if (cmdline[0] == '\0') return true;
|
|
||||||
|
|
||||||
enum State state = INITIAL;
|
|
||||||
size_t buffer_or_file_pos = 0;
|
|
||||||
|
|
||||||
for (size_t index = 0; state != FINAL; ++index) {
|
|
||||||
const bool result = kernaux_cmdline_iter(
|
|
||||||
cmdline[index],
|
|
||||||
&state,
|
|
||||||
&buffer_or_file_pos,
|
|
||||||
error_msg,
|
|
||||||
argc,
|
|
||||||
arg_terminator,
|
|
||||||
argv,
|
|
||||||
buffer,
|
|
||||||
arg_idxs,
|
|
||||||
arg_count_max,
|
|
||||||
buffer_size
|
|
||||||
);
|
|
||||||
if (!result) goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
CLEAR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* Implementation: iteration function *
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
#define FAIL(msg) do { \
|
|
||||||
strcpy(error_msg, msg); \
|
|
||||||
return false; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define PUT_CHAR(char) do { \
|
|
||||||
if (buffer_size && *buffer_or_file_pos >= buffer_size) { \
|
|
||||||
FAIL("EOF or buffer overflow"); \
|
|
||||||
} \
|
|
||||||
if (buffer) { \
|
|
||||||
buffer[*buffer_or_file_pos] = char; \
|
|
||||||
} \
|
|
||||||
++(*buffer_or_file_pos); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define PUT_ARG do { \
|
|
||||||
if (arg_count_max && *argc >= arg_count_max) { \
|
|
||||||
FAIL("too many args"); \
|
|
||||||
} \
|
|
||||||
if (argv && buffer) { \
|
|
||||||
argv[*argc] = &buffer[*buffer_or_file_pos]; \
|
|
||||||
} \
|
|
||||||
if (arg_idxs) { \
|
|
||||||
arg_idxs[*argc] = *buffer_or_file_pos; \
|
|
||||||
} \
|
|
||||||
++(*argc); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define PUT_ARG_AND_CHAR(char) do { \
|
|
||||||
if (arg_count_max && *argc >= arg_count_max) { \
|
|
||||||
FAIL("too many args"); \
|
|
||||||
} \
|
|
||||||
if (buffer_size && *buffer_or_file_pos >= buffer_size) { \
|
|
||||||
FAIL("EOF or buffer overflow"); \
|
|
||||||
} \
|
|
||||||
if (argv && buffer) { \
|
|
||||||
argv[*argc] = &buffer[*buffer_or_file_pos]; \
|
|
||||||
buffer[*buffer_or_file_pos] = char; \
|
|
||||||
} \
|
|
||||||
if (arg_idxs) { \
|
|
||||||
arg_idxs[*argc] = *buffer_or_file_pos; \
|
|
||||||
} \
|
|
||||||
++(*argc); \
|
|
||||||
++(*buffer_or_file_pos); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
bool kernaux_cmdline_iter(
|
|
||||||
const char cur,
|
|
||||||
enum State *const state,
|
|
||||||
size_t *const buffer_or_file_pos,
|
|
||||||
char *const error_msg,
|
|
||||||
size_t *const argc,
|
|
||||||
char arg_terminator,
|
|
||||||
char **const argv,
|
|
||||||
char *const buffer,
|
|
||||||
size_t *const arg_idxs,
|
|
||||||
const size_t arg_count_max,
|
|
||||||
const size_t buffer_size
|
|
||||||
) {
|
|
||||||
switch (*state) {
|
|
||||||
case FINAL:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INITIAL:
|
|
||||||
if (cur == '\0') {
|
|
||||||
*state = FINAL;
|
|
||||||
} else if (cur == ' ') {
|
|
||||||
*state = WHITESPACE;
|
|
||||||
} else if (cur == '\\') {
|
|
||||||
*state = BACKSLASH;
|
|
||||||
PUT_ARG;
|
|
||||||
} else if (cur == '"') {
|
|
||||||
*state = QUOTE;
|
|
||||||
PUT_ARG;
|
|
||||||
} else {
|
|
||||||
*state = TOKEN;
|
|
||||||
PUT_ARG_AND_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WHITESPACE:
|
|
||||||
if (cur == '\0') {
|
|
||||||
*state = FINAL;
|
|
||||||
} else if (cur == ' ') {
|
|
||||||
// do nothing
|
|
||||||
} else if (cur == '\\') {
|
|
||||||
*state = BACKSLASH;
|
|
||||||
PUT_ARG;
|
|
||||||
} else if (cur == '"') {
|
|
||||||
*state = QUOTE;
|
|
||||||
PUT_ARG;
|
|
||||||
} else {
|
|
||||||
*state = TOKEN;
|
|
||||||
PUT_ARG_AND_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOKEN:
|
|
||||||
if (cur == '\0') {
|
|
||||||
*state = FINAL;
|
|
||||||
PUT_CHAR(arg_terminator);
|
|
||||||
} else if (cur == ' ') {
|
|
||||||
*state = WHITESPACE;
|
|
||||||
PUT_CHAR(arg_terminator);
|
|
||||||
} else if (cur == '\\') {
|
|
||||||
*state = BACKSLASH;
|
|
||||||
} else if (cur == '"') {
|
|
||||||
FAIL("unescaped quotation mark");
|
|
||||||
} else {
|
|
||||||
PUT_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BACKSLASH:
|
|
||||||
if (cur == '\0') {
|
|
||||||
FAIL("EOL after backslash");
|
|
||||||
} else {
|
|
||||||
*state = TOKEN;
|
|
||||||
PUT_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QUOTE:
|
|
||||||
if (cur == '\0') {
|
|
||||||
FAIL("EOL inside quote");
|
|
||||||
} else if (cur == '\\') {
|
|
||||||
*state = QUOTE_BACKSLASH;
|
|
||||||
} else if (cur == '"') {
|
|
||||||
*state = WHITESPACE;
|
|
||||||
PUT_CHAR(arg_terminator);
|
|
||||||
} else {
|
|
||||||
PUT_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QUOTE_BACKSLASH:
|
|
||||||
if (cur == '\0') {
|
|
||||||
FAIL("EOL after backslash inside quote");
|
|
||||||
} else {
|
|
||||||
*state = QUOTE;
|
|
||||||
PUT_CHAR(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
/test_arch_i386
|
/test_arch_i386
|
||||||
/test_cmdline
|
|
||||||
/test_elf
|
/test_elf
|
||||||
/test_free_list
|
/test_free_list
|
||||||
/test_mbr
|
/test_mbr
|
||||||
|
|
|
@ -16,20 +16,6 @@ test_arch_i386_SOURCES = \
|
||||||
test_arch_i386.c
|
test_arch_i386.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
################
|
|
||||||
# test_cmdline #
|
|
||||||
################
|
|
||||||
|
|
||||||
if WITH_CMDLINE
|
|
||||||
TESTS += test_cmdline
|
|
||||||
test_cmdline_LDADD = $(top_builddir)/libkernaux.la
|
|
||||||
test_cmdline_SOURCES = \
|
|
||||||
main.c \
|
|
||||||
test_cmdline.c \
|
|
||||||
cmdline_test.h \
|
|
||||||
cmdline_test.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
############
|
############
|
||||||
# test_elf #
|
# test_elf #
|
||||||
############
|
############
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
#include "cmdline_test.h"
|
|
||||||
|
|
||||||
#include <kernaux/cmdline.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define ARG_COUNT_MAX 100
|
|
||||||
#define BUFFER_SIZE 4096
|
|
||||||
|
|
||||||
void test(
|
|
||||||
const char *const cmdline,
|
|
||||||
size_t arg_count_max,
|
|
||||||
size_t buffer_size,
|
|
||||||
|
|
||||||
const bool expected_result,
|
|
||||||
const char *const expected_error_msg,
|
|
||||||
size_t expected_argc,
|
|
||||||
const char *const *const expected_argv
|
|
||||||
) {
|
|
||||||
if (arg_count_max == 0) arg_count_max = ARG_COUNT_MAX;
|
|
||||||
if (buffer_size == 0) buffer_size = BUFFER_SIZE;
|
|
||||||
|
|
||||||
char *error_msg = malloc(KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
|
||||||
size_t argc = 1234;
|
|
||||||
char **const argv = malloc(sizeof(char*) * arg_count_max);
|
|
||||||
size_t *arg_idxs = malloc(sizeof(size_t) * arg_count_max);
|
|
||||||
char *const buffer = malloc(buffer_size);
|
|
||||||
|
|
||||||
assert(error_msg);
|
|
||||||
assert(argv);
|
|
||||||
assert(buffer);
|
|
||||||
|
|
||||||
{
|
|
||||||
memset(error_msg, 'x', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
|
||||||
memset(argv, 0, sizeof(char*) * arg_count_max);
|
|
||||||
memset(arg_idxs, 0, sizeof(size_t) * arg_count_max);
|
|
||||||
memset(buffer, 'x', buffer_size);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
kernaux_cmdline(
|
|
||||||
cmdline,
|
|
||||||
error_msg,
|
|
||||||
&argc,
|
|
||||||
argv,
|
|
||||||
buffer,
|
|
||||||
arg_count_max,
|
|
||||||
buffer_size
|
|
||||||
) == !!expected_result
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(strcmp(error_msg, expected_error_msg) == 0);
|
|
||||||
assert(argc == expected_argc);
|
|
||||||
|
|
||||||
if (expected_argv) {
|
|
||||||
for (size_t index = 0; index < argc; ++index) {
|
|
||||||
assert(strcmp(argv[index], expected_argv[index]) == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t index = argc; index < arg_count_max; ++index) {
|
|
||||||
assert(argv[index] == NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(error_msg);
|
|
||||||
free(argv);
|
|
||||||
free(arg_idxs);
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef KERNAUX_INCLUDED_TESTS_CMDLINE_TEST
|
|
||||||
#define KERNAUX_INCLUDED_TESTS_CMDLINE_TEST
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
void test(
|
|
||||||
const char *cmdline,
|
|
||||||
size_t arg_count_max,
|
|
||||||
size_t buffer_size,
|
|
||||||
|
|
||||||
bool expected_result,
|
|
||||||
const char *expected_error_msg,
|
|
||||||
size_t expected_argc,
|
|
||||||
const char *const *const expected_argv
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,119 +0,0 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cmdline_test.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static const char *const argv_spaceX3_X3[] = {" ", " ", " "};
|
|
||||||
static const char *const argv_backslashX3_X3[] = {"\\\\\\", "\\\\\\", "\\\\\\"};
|
|
||||||
static const char *const argv_quotmarkX3_X3[] = {"\"\"\"", "\"\"\"", "\"\"\""};
|
|
||||||
|
|
||||||
static const char *const argv_aX50[] = {
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *const argv_a_X1[] = { "a" };
|
|
||||||
static const char *const argv_a_X2[] = { "a", "a" };
|
|
||||||
static const char *const argv_a_X3[] = { "a", "a", "a" };
|
|
||||||
static const char *const argv_a_X4[] = { "a", "a", "a", "a" };
|
|
||||||
static const char *const argv_a_X5[] = { "a", "a", "a", "a", "a" };
|
|
||||||
static const char *const argv_a_X6[] = { "a", "a", "a", "a", "a", "a" };
|
|
||||||
|
|
||||||
void test_main()
|
|
||||||
{
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 3, 0, true, "", 3, argv_spaceX3_X3);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 3, 0, true, "", 3, argv_backslashX3_X3);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 3, 0, true, "", 3, argv_quotmarkX3_X3);
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 0, 12, true, "", 3, argv_spaceX3_X3);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 0, 12, true, "", 3, argv_backslashX3_X3);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 0, 12, true, "", 3, argv_quotmarkX3_X3);
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 3, 12, true, "", 3, argv_spaceX3_X3);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 3, 12, true, "", 3, argv_backslashX3_X3);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 3, 12, true, "", 3, argv_quotmarkX3_X3);
|
|
||||||
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 2, 0, false, "too many args", 0, NULL);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 2, 0, false, "too many args", 0, NULL);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 2, 0, false, "too many args", 0, NULL);
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 0, 11, false, "EOF or buffer overflow", 0, NULL);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 0, 11, false, "EOF or buffer overflow", 0, NULL);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 0, 11, false, "EOF or buffer overflow", 0, NULL);
|
|
||||||
test("\\ \\ \\ \\ \\ \\ \\ \\ \\ ", 2, 11, false, "too many args", 0, NULL);
|
|
||||||
test("\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\", 2, 11, false, "too many args", 0, NULL);
|
|
||||||
test("\\\"\\\"\\\" \\\"\\\"\\\" \\\"\\\"\\\"", 2, 11, false, "too many args", 0, NULL);
|
|
||||||
|
|
||||||
test("\\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
test(" \\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
test("\\ \\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
test("\\\\\\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
test("\\\"\\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
test("foo\\", 0, 0, false, "EOL after backslash", 0, NULL);
|
|
||||||
|
|
||||||
test("\"\\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
test("\" \\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
test("\"\\ \\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
test("\"\\\\\\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
test("\"\\\"\\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
test("\"foo\\", 0, 0, false, "EOL after backslash inside quote", 0, NULL);
|
|
||||||
|
|
||||||
test("foo\"", 0, 0, false, "unescaped quotation mark", 0, NULL);
|
|
||||||
test("foo\"bar", 0, 0, false, "unescaped quotation mark", 0, NULL);
|
|
||||||
|
|
||||||
test("\"", 0, 0, false, "EOL inside quote", 0, NULL);
|
|
||||||
test("\"foo", 0, 0, false, "EOL inside quote", 0, NULL);
|
|
||||||
|
|
||||||
test(
|
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
"",
|
|
||||||
1,
|
|
||||||
argv_aX50
|
|
||||||
);
|
|
||||||
|
|
||||||
test("a", 1, 0, true, "", 1, argv_a_X1);
|
|
||||||
test("a ", 1, 0, true, "", 1, argv_a_X1);
|
|
||||||
test("a a", 1, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a ", 1, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a", 2, 0, true, "", 2, argv_a_X2);
|
|
||||||
test("a a ", 2, 0, true, "", 2, argv_a_X2);
|
|
||||||
test("a a a", 2, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a ", 2, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a", 3, 0, true, "", 3, argv_a_X3);
|
|
||||||
test("a a a ", 3, 0, true, "", 3, argv_a_X3);
|
|
||||||
test("a a a a", 3, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a ", 3, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a", 4, 0, true, "", 4, argv_a_X4);
|
|
||||||
test("a a a a ", 4, 0, true, "", 4, argv_a_X4);
|
|
||||||
test("a a a a a", 4, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a a ", 4, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a a", 5, 0, true, "", 5, argv_a_X5);
|
|
||||||
test("a a a a a ", 5, 0, true, "", 5, argv_a_X5);
|
|
||||||
test("a a a a a a", 5, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a a a ", 5, 0, false, "too many args", 0, NULL);
|
|
||||||
test("a a a a a a", 6, 0, true, "", 6, argv_a_X6);
|
|
||||||
test("a a a a a a ", 6, 0, true, "", 6, argv_a_X6);
|
|
||||||
|
|
||||||
{
|
|
||||||
char *const buffer = malloc(4096);
|
|
||||||
memset(buffer, 'a', 4096 - 1);
|
|
||||||
buffer[4096 - 1] = '\0';
|
|
||||||
// 4095 of "a"
|
|
||||||
test(buffer, 256, 4096, true, "", 1, NULL);
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
char *const buffer = malloc(4096 + 1);
|
|
||||||
memset(buffer, 'a', 4096);
|
|
||||||
buffer[4096] = '\0';
|
|
||||||
// 4096 of "a"
|
|
||||||
test(buffer, 256, 4096, false, "EOF or buffer overflow", 0, NULL);
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue