[RELEASE] u22-v03

This version is submitted to U22 breau.
This commit is contained in:
2020-09-14 00:00:00 +00:00
parent 360595de37
commit 84c3a02b9a
357 changed files with 29223 additions and 0 deletions

View 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
View 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
View 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
View 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);
}