feat: add basic parsing and readme

This commit is contained in:
Tilo-K
2025-06-20 15:34:49 +02:00
parent 55e42817be
commit 126fc422c5
4 changed files with 303 additions and 2 deletions

59
README.md Normal file
View File

@@ -0,0 +1,59 @@
<pre style="font-size: 8pt;">
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::.
::.::::::.::::.::.::::.::.:::::.:::::.::::::::.:::.::.::::::.::::
:::::.::::::.:::::::.:::::::.::::::::::::.::.:::::::::::.::::::.:
:::::::::::::::::::::::::::::::::::.:::.:::::::::::::::::::::::::
:.::::::.::::::.:::::::.::::::::::::::::::::::::.::::.::::.::.::.
::::.::::::.::::::.:::::::.::::::::::.::::::.::::::.::::.::::::::
::::::::::::::.::::::::::::::.::.::.:::::.:::::::::::::::::::::::
:.::::.:::::::::::::.::.:::::::::::::::::::::::.::::::.::::.:.::.
::::.::::.:::::::.:::::::::.::::::::::.:::::::::::.::::::::::::::
::::::::::::.::.::::::::::::::.::::::::::::::.:::::::::::.:::::.:
::.::::::::::::::::::::::::::::::.::::::::::::::.:::.::.:::::::::
:::::.::::::::::::::.::-@:::::::::::.::.::.:::::::::::::::::.::::
.:::::::.::.::::::.::::-@+**********=:::::::::::+::::::::::::::.:
:::.::::::::::.::::::::-@************************::::.:::.:::::::
::::::.::::::::::::::::-@************************:::::::::::.:::.
:::::::::.:::::::::::::-@***********************=::::::.:::::::::
::.::::::::::::::::::.:-@***********************::::.::::::::::::
:::::.:::::.::.::.:::::-@***********************=:::::::::.::.::.
:::::::::.:::::::::::::-@************************::::::.:::::::::
::.::::::::::::::::::::-@****====****************::::::::::::::::
:::::.::::::::.::::::::-@:::::::::::::=*******+-:::::.:::::.::.::
.:::::::.::::::::::.:::-@::::::::::::::::::::::::::::::::.:::::::
:::::::::::.:::::::::::-@:::::::::::::::::::::::::::::::::::::::.
:::.::::::::::.::::::::-@::::::.:::::::::::::::.::.::::::::::::::
:::::::::::::::::.:::::-@:::::::::::::::::::::::::::::::.:::::::.
:::::::::::::::::::::::-@:::::::::::::::.::::::::::::.::::::.::::
:::.::.::.:::::::::::::-@::::::::.:::::::::::.::.::.:::::::::::::
::::::::::::::.::::::::-@:::::::::::::::::::::::::::::::::.::::.:
:.:::::::::::::::::::::-@::::::::::::.:::::::::::::::::::::::::::
:::::::::::::::::::::::-@::::::::::::::::::::::::.:::::::::::.:::
:::::::::::::.::.::::::-@::::::::.:::::::::::::.:::::::::.::::::.
:::.:::::.::::::::::.::-@::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::-@:::::::::::::::::::.::::::::.::::::::.::
:::::::::::::::::::::::-@::::::::::::::::::::::::::::::::::::::::
::+***********=::::::::-@-=***********+:::::::::::+***********=::
***********************#@****************************************
***********************#@****************************************
************************@****************************************
*************#%%%##%%%##@#%%%%#%%%##*****************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
*****************************************************************
</pre>
# SeaFlags
### SeaFlags is a simple library for parsing command line arguments.

29
includes/seaflags.h Normal file
View File

@@ -0,0 +1,29 @@
#include <stdlib.h>
struct SeaFlag {
char* name;
char* short_name;
bool is_required;
char** value;
struct SeaFlag* next;
};
struct SeaFlagSet {
struct SeaFlag* firstFlag;
char* programName;
char* programVersion;
char* programAuthor;
char* programDescription;
};
#define SEAFLAGS_UNKNOWN_FLAG 0b00000001
#define SEAFLAGS_UNKNOWN_POSITIONAL_ARG 0b00000010
#define SEAFLAGS_MISSING_REQUIRED_FLAG 0b00000100
void seaflags_init(struct SeaFlagSet* flags, char* programName, char* programVersion, char* programAuthor, char* programDescription);
void seaflags_add_flag(struct SeaFlagSet* flags, char* name, char* short_name, bool is_required, char** value);
int seaflags_parse(struct SeaFlagSet* flags, int argc, char** argv);
void seaflags_free(struct SeaFlagSet* flags);

View File

@@ -0,0 +1,109 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "../includes/seaflags.h"
#define SEAFLAGS_DEBUG
void seaflags_init(struct SeaFlagSet *flags, char *programName, char *programVersion, char *programAuthor, char *programDescription) {
flags->firstFlag = NULL;
flags->programName = programName;
flags->programVersion = programVersion;
flags->programAuthor = programAuthor;
flags->programDescription = programDescription;
}
void seaflags_add_flag(struct SeaFlagSet *flags, char *name, char *short_name, bool is_required, char** value) {
struct SeaFlag* flag = malloc(sizeof(struct SeaFlag));
flag->name = name;
flag->short_name = short_name;
flag->is_required = is_required;
flag->value = value;
flag->next = NULL;
if (flags->firstFlag == NULL) {
flags->firstFlag = flag;
return;
}
struct SeaFlag* current = flags->firstFlag;
if(current == NULL) {
flags->firstFlag = flag;
return;
}
while (current->next != NULL) {
current = current->next;
}
current->next = flag;
}
void seaflags_free(struct SeaFlagSet *flags){
struct SeaFlag* current = flags->firstFlag;
while (current != NULL) {
struct SeaFlag* next = current->next;
free(current->name);
free(current->short_name);
free(current->value);
free(current);
current = next;
}
free(flags);
}
struct SeaFlag* _seaflags_find_flag(struct SeaFlagSet *flags, char *name) {
struct SeaFlag* current = flags->firstFlag;
while (current != NULL) {
if (strcmp(current->name, name) == 0 || strcmp(current->short_name, name) == 0) {
return current;
}
current = current->next;
}
return NULL;
}
int seaflags_parse(struct SeaFlagSet *flags, int argc, char **argv) {
int i = 1;
int result = 0;
#ifdef SEAFLAGS_DEBUG
printf("Parsing %d arguments\n", argc);
#endif
while (i < argc) {
char* current = argv[i];
struct SeaFlag* flag = _seaflags_find_flag(flags, current);
if (flag == NULL) {
fprintf(stderr, "Unknown flag: %s\n", current);
result |= SEAFLAGS_UNKNOWN_FLAG;
}
if(flag != NULL && i+1 < argc) {
#ifdef SEAFLAGS_DEBUG
printf("Setting value for %s to %s\n", current, argv[i+1]);
#endif
*(flag->value) = argv[i+1];
i++;
}
i++;
}
struct SeaFlag* current = flags->firstFlag;
while (current != NULL) {
if (*(current->value) == NULL) {
if (current->is_required == true) {
fprintf(stderr, "Missing required flag: %s\n", current->name);
result |= SEAFLAGS_MISSING_REQUIRED_FLAG;
}
}
current = current->next;
}
return result;
}

View File

@@ -1,4 +1,108 @@
int main(void) {
return 0;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SEAFLAGS_DEBUG
#include "../includes/seaflags.h"
int test_basic_create() {
printf("Running test_basic_create\n");
struct SeaFlagSet flags;
seaflags_init(&flags, "Sea Flag Test", "0.0.0", "Tilo-K" , "A test for the seaflags library");
char* name = NULL;
seaflags_add_flag(&flags, "name", "n", true, &name);
if (flags.firstFlag == NULL) {
printf("Flags not created\n");
return 1;
}
if (flags.firstFlag->name == NULL) {
printf("Flag name not set\n");
return 1;
}
if (flags.firstFlag->short_name == NULL) {
printf("Flag short name not set\n");
return 1;
}
if (flags.firstFlag->is_required != true) {
printf("Flag is_required not set\n");
return 1;
}
if (flags.firstFlag->value == NULL) {
printf("Flag value not set\n");
return 1;
}
return 0;
}
int test_get_flag_value() {
printf("Running test_get_flag_value\n");
struct SeaFlagSet flags;
seaflags_init(&flags, "Sea Flag Test", "0.0.0", "Tilo-K" , "A test for the seaflags library");
char* name = NULL;
printf("Adding flag\n");
seaflags_add_flag(&flags, "--name", "-n", true, &name);
printf("Parsing\n");
seaflags_parse(&flags, 3, (char*[]){"./test", "--name", "test"});
printf("Parsed\n");
if (name == NULL || strcmp(name, "test") != 0) {
printf("Flag value name not set, found %s\n", name);
return 1;
}
return 0;
}
int test_missing_required_flag() {
printf("Running test_missing_required_flag\n");
struct SeaFlagSet flags;
seaflags_init(&flags, "Sea Flag Test", "0.0.0", "Tilo-K" , "A test for the seaflags library");
char* name = NULL;
printf("Adding flag\n");
seaflags_add_flag(&flags, "--name", "-n", true, &name);
printf("Parsing\n");
int result = seaflags_parse(&flags, 1, (char*[]){"./test"});
printf("Parsed\n");
if ((result & SEAFLAGS_MISSING_REQUIRED_FLAG) > 0) {
return 0;
}
printf("Missing required flag not detected %d\n", result);
return 1;
}
int main(void) {
printf("Running main\n");
int result = test_basic_create();
if (result != 0) {
printf("Basic Test failed with result %d\n", result);
return 1;
}
result = test_get_flag_value();
if (result != 0) {
printf("Get Flag Value Test failed with result %d\n", result);
return 1;
}
result = test_missing_required_flag();
if (result != 0) {
printf("Missing Required Flag Test failed with result %d\n", result);
return 1;
}
return 0;
}