1
0
Fork 0
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:
Alex Kotov 2022-01-22 02:42:54 +05:00
parent 12fd0be859
commit 7ac36e8fc4
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
4 changed files with 39 additions and 55 deletions

View file

@ -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);

View file

@ -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

View file

@ -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;
} }

View file

@ -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
); );