[RELEASE] u22-v03
This version is submitted to U22 breau.
This commit is contained in:
12
util/parsarg/CMakeLists.txt
Normal file
12
util/parsarg/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_library(parsarg
|
||||
parsarg.c
|
||||
)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_executable(parsarg-test test.c)
|
||||
target_link_libraries(parsarg-test
|
||||
parsarg
|
||||
|
||||
conv
|
||||
)
|
||||
endif()
|
79
util/parsarg/parsarg.c
Normal file
79
util/parsarg/parsarg.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "./parsarg.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void parsarg_initialize(parsarg_t* pa, int argc, char** argv) {
|
||||
assert(pa != NULL);
|
||||
|
||||
*pa = (typeof(*pa)) {
|
||||
.argc = argc,
|
||||
.argv = argv,
|
||||
};
|
||||
}
|
||||
|
||||
void parsarg_deinitialize(parsarg_t* pa) {
|
||||
assert(pa != NULL);
|
||||
|
||||
}
|
||||
|
||||
char* parsarg_pop_name(parsarg_t* pa, size_t* len) {
|
||||
assert(pa != NULL);
|
||||
assert(len != NULL);
|
||||
|
||||
*len = 0;
|
||||
if (pa->argc <= 0 || pa->value != NULL || pa->after_option) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* v = *pa->argv;
|
||||
|
||||
size_t offset = 0;
|
||||
while (v[offset] == '-') ++offset;
|
||||
|
||||
if (offset == 0) return NULL;
|
||||
v += offset;
|
||||
|
||||
--pa->argc;
|
||||
++pa->argv;
|
||||
|
||||
if (v[0] == 0) {
|
||||
pa->after_option = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (v[*len] != '=' && v[*len] != 0) ++*len;
|
||||
pa->value = (v[*len] == '='? &v[*len+1]: NULL);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool parsarg_pop_value(parsarg_t* pa, char** str) {
|
||||
assert(pa != NULL);
|
||||
assert(str != NULL);
|
||||
|
||||
*str = NULL;
|
||||
if (pa->value != NULL) {
|
||||
*str = pa->value;
|
||||
pa->value = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pa->argc <= 0) return false;
|
||||
|
||||
char* v = *pa->argv;
|
||||
if (!pa->after_option) {
|
||||
if (v[0] == '-') return false;
|
||||
}
|
||||
--pa->argc;
|
||||
++pa->argv;
|
||||
|
||||
*str = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parsarg_finished(const parsarg_t* pa) {
|
||||
assert(pa != NULL);
|
||||
|
||||
return pa->argc <= 0;
|
||||
}
|
42
util/parsarg/parsarg.h
Normal file
42
util/parsarg/parsarg.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
char* value;
|
||||
|
||||
bool after_option;
|
||||
} parsarg_t;
|
||||
|
||||
void
|
||||
parsarg_initialize(
|
||||
parsarg_t* pa,
|
||||
int argc,
|
||||
char** argv
|
||||
);
|
||||
|
||||
void
|
||||
parsarg_deinitialize(
|
||||
parsarg_t* pa
|
||||
);
|
||||
|
||||
char* /* NULLABLE */
|
||||
parsarg_pop_name(
|
||||
parsarg_t* pa,
|
||||
size_t* len
|
||||
);
|
||||
|
||||
bool
|
||||
parsarg_pop_value(
|
||||
parsarg_t* pa,
|
||||
char** str
|
||||
);
|
||||
|
||||
bool
|
||||
parsarg_finished(
|
||||
const parsarg_t* pa
|
||||
);
|
45
util/parsarg/test.c
Normal file
45
util/parsarg/test.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "./parsarg.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
parsarg_t pa;
|
||||
parsarg_initialize(&pa, argc-1, argv+1);
|
||||
|
||||
while (!parsarg_finished(&pa)) {
|
||||
size_t nlen;
|
||||
const char* n = parsarg_pop_name(&pa, &nlen);
|
||||
|
||||
char* v;
|
||||
parsarg_pop_value(&pa, &v);
|
||||
|
||||
if (n == NULL && v == NULL) continue;
|
||||
/* when the args ends with '--' */
|
||||
|
||||
if (n == NULL) {
|
||||
printf("param: %s\n", v);
|
||||
continue;
|
||||
}
|
||||
if (nlen == 3 && strncmp(n, "num", nlen) == 0) {
|
||||
char* end;
|
||||
const intmax_t i = strtoimax(v, &end, 0);
|
||||
if (*end == 0 && 0 <= i && i <= 100) {
|
||||
printf("num = %"PRIdMAX"\n", i);
|
||||
} else {
|
||||
printf("error: '%s' is not an valid integer for num (0~100)\n", v);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (nlen == 3 && strncmp(n, "str", nlen) == 0) {
|
||||
printf("str = '%s'\n", v);
|
||||
continue;
|
||||
}
|
||||
printf("error: unknown option '%.*s'\n", (int) nlen, n);
|
||||
}
|
||||
|
||||
parsarg_deinitialize(&pa);
|
||||
}
|
Reference in New Issue
Block a user