mirror of
https://github.com/tailix/libkernaux.git
synced 2026-08-15 11:00:07 -04:00
Change kernaux_cmdline
This commit is contained in:
parent
12fd0be859
commit
7ac36e8fc4
4 changed files with 39 additions and 55 deletions
|
|
@ -3,8 +3,8 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const size_t ARGV_COUNT_MAX = 100;
|
#define ARGV_COUNT_MAX 100
|
||||||
static const size_t ARG_SIZE_MAX = 4096;
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
static const char *const cmdline = "foo bar\\ baz \"car cdr\"";
|
static const char *const cmdline = "foo bar\\ baz \"car cdr\"";
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ int main()
|
||||||
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
||||||
size_t argc;
|
size_t argc;
|
||||||
char *argv[ARGV_COUNT_MAX];
|
char *argv[ARGV_COUNT_MAX];
|
||||||
char buffer[ARGV_COUNT_MAX * ARG_SIZE_MAX];
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
assert(kernaux_cmdline(
|
assert(kernaux_cmdline(
|
||||||
cmdline,
|
cmdline,
|
||||||
|
|
@ -22,7 +22,7 @@ int main()
|
||||||
argv,
|
argv,
|
||||||
buffer,
|
buffer,
|
||||||
ARGV_COUNT_MAX,
|
ARGV_COUNT_MAX,
|
||||||
ARG_SIZE_MAX
|
BUFFER_SIZE
|
||||||
));
|
));
|
||||||
|
|
||||||
assert(strcmp(error_msg, "") == 0);
|
assert(strcmp(error_msg, "") == 0);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ bool kernaux_cmdline(
|
||||||
char **argv,
|
char **argv,
|
||||||
char *buffer,
|
char *buffer,
|
||||||
size_t argv_count_max,
|
size_t argv_count_max,
|
||||||
size_t arg_size_max
|
size_t buffer_size
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ bool kernaux_cmdline(
|
||||||
char **argv,
|
char **argv,
|
||||||
char *buffer,
|
char *buffer,
|
||||||
const size_t argv_count_max,
|
const size_t argv_count_max,
|
||||||
const size_t arg_size_max
|
const size_t buffer_size
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
cmdline == NULL ||
|
cmdline == NULL ||
|
||||||
|
|
@ -30,27 +30,21 @@ bool kernaux_cmdline(
|
||||||
argc == NULL ||
|
argc == NULL ||
|
||||||
argv == NULL ||
|
argv == NULL ||
|
||||||
argv_count_max == 0 ||
|
argv_count_max == 0 ||
|
||||||
arg_size_max == 0
|
buffer_size == 0
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(error_msg, '\0', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
memset(error_msg, '\0', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
||||||
*argc = 0;
|
*argc = 0;
|
||||||
|
memset(argv, 0, sizeof(char*) * argv_count_max);
|
||||||
|
memset(buffer, '\0', buffer_size);
|
||||||
|
|
||||||
for (size_t index = 0; index < argv_count_max; ++index) {
|
if (cmdline[0] == '\0') return true;
|
||||||
argv[index] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer, '\0', argv_count_max * arg_size_max);
|
|
||||||
|
|
||||||
if (cmdline[0] == '\0') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum State state = INITIAL;
|
enum State state = INITIAL;
|
||||||
|
|
||||||
size_t buffer_size = 0;
|
size_t buffer_pos = 0;
|
||||||
|
|
||||||
for (size_t index = 0; ; ++index) {
|
for (size_t index = 0; ; ++index) {
|
||||||
const char cur = cmdline[index];
|
const char cur = cmdline[index];
|
||||||
|
|
@ -90,7 +84,7 @@ bool kernaux_cmdline(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +92,7 @@ bool kernaux_cmdline(
|
||||||
state = TOKEN;
|
state = TOKEN;
|
||||||
argv[(*argc)++] = buffer;
|
argv[(*argc)++] = buffer;
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -132,7 +126,7 @@ bool kernaux_cmdline(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
@ -140,30 +134,30 @@ bool kernaux_cmdline(
|
||||||
state = TOKEN;
|
state = TOKEN;
|
||||||
argv[(*argc)++] = buffer;
|
argv[(*argc)++] = buffer;
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKEN:
|
case TOKEN:
|
||||||
if (cur == '\0') {
|
if (cur == '\0') {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = FINAL;
|
state = FINAL;
|
||||||
*(buffer++) = '\0';
|
*(buffer++) = '\0';
|
||||||
buffer_size = 0;
|
buffer_pos = 0;
|
||||||
}
|
}
|
||||||
else if (cur == ' ') {
|
else if (cur == ' ') {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = WHITESPACE;
|
state = WHITESPACE;
|
||||||
*(buffer++) = '\0';
|
*(buffer++) = '\0';
|
||||||
buffer_size = 0;
|
buffer_pos = 0;
|
||||||
}
|
}
|
||||||
else if (cur == '\\') {
|
else if (cur == '\\') {
|
||||||
state = BACKSLASH;
|
state = BACKSLASH;
|
||||||
|
|
@ -173,13 +167,13 @@ bool kernaux_cmdline(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -189,14 +183,14 @@ bool kernaux_cmdline(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = TOKEN;
|
state = TOKEN;
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -209,23 +203,23 @@ bool kernaux_cmdline(
|
||||||
state = QUOTE_BACKSLASH;
|
state = QUOTE_BACKSLASH;
|
||||||
}
|
}
|
||||||
else if (cur == '"') {
|
else if (cur == '"') {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = WHITESPACE;
|
state = WHITESPACE;
|
||||||
*(buffer++) = '\0';
|
*(buffer++) = '\0';
|
||||||
buffer_size = 0;
|
buffer_pos = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -235,14 +229,14 @@ bool kernaux_cmdline(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (buffer_size >= arg_size_max) {
|
if (buffer_pos >= buffer_size) {
|
||||||
strcpy(error_msg, "arg too long");
|
strcpy(error_msg, "arg too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = QUOTE;
|
state = QUOTE;
|
||||||
*(buffer++) = cur;
|
*(buffer++) = cur;
|
||||||
++buffer_size;
|
++buffer_pos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -256,12 +250,7 @@ bool kernaux_cmdline(
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
*argc = 0;
|
*argc = 0;
|
||||||
|
memset(argv, 0, sizeof(char*) * argv_count_max);
|
||||||
for (size_t index = 0; index < argv_count_max; ++index) {
|
memset(buffer, '\0', buffer_size);
|
||||||
argv[index] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer, '\0', argv_count_max * arg_size_max);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const size_t ARGV_COUNT_MAX = 100;
|
#define ARGV_COUNT_MAX 100
|
||||||
static const size_t ARG_SIZE_MAX = 4096;
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
static void test(
|
static void test(
|
||||||
const char *cmdline,
|
const char *cmdline,
|
||||||
size_t argv_count_max,
|
size_t argv_count_max,
|
||||||
size_t arg_size_max,
|
size_t buffer_size,
|
||||||
|
|
||||||
bool expected_result,
|
bool expected_result,
|
||||||
const char *expected_error_msg,
|
const char *expected_error_msg,
|
||||||
|
|
@ -237,25 +237,20 @@ int main()
|
||||||
void test(
|
void test(
|
||||||
const char *const cmdline,
|
const char *const cmdline,
|
||||||
size_t argv_count_max,
|
size_t argv_count_max,
|
||||||
size_t arg_size_max,
|
size_t buffer_size,
|
||||||
|
|
||||||
const bool expected_result,
|
const bool expected_result,
|
||||||
const char *const expected_error_msg,
|
const char *const expected_error_msg,
|
||||||
size_t expected_argc,
|
size_t expected_argc,
|
||||||
const char *const *const expected_argv
|
const char *const *const expected_argv
|
||||||
) {
|
) {
|
||||||
if (argv_count_max == 0) {
|
if (argv_count_max == 0) argv_count_max = ARGV_COUNT_MAX;
|
||||||
argv_count_max = ARGV_COUNT_MAX;
|
if (buffer_size == 0) buffer_size = BUFFER_SIZE;
|
||||||
}
|
|
||||||
|
|
||||||
if (arg_size_max == 0) {
|
|
||||||
arg_size_max = ARG_SIZE_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
||||||
size_t argc = 1234;
|
size_t argc = 1234;
|
||||||
char *argv[argv_count_max];
|
char *argv[argv_count_max];
|
||||||
char buffer[argv_count_max * arg_size_max];
|
char buffer[buffer_size];
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
kernaux_cmdline(
|
kernaux_cmdline(
|
||||||
|
|
@ -265,7 +260,7 @@ void test(
|
||||||
argv,
|
argv,
|
||||||
buffer,
|
buffer,
|
||||||
argv_count_max,
|
argv_count_max,
|
||||||
arg_size_max
|
buffer_size
|
||||||
) == !!expected_result
|
) == !!expected_result
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue