-
Notifications
You must be signed in to change notification settings - Fork 0
/
elk_args.h
140 lines (125 loc) · 3.42 KB
/
elk_args.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// elk_args.h - v0.1 - a dead simple parser in plain c.
//
// Copyright (c) 2016 Emil Andersen Lauridsen
// Distributed under the MIT License, see LICENSE
//
// Currently only support parsing plain flags (boolean style) and flags with
// arguments (currently only stored as a string).
//
// TODO:
// - Handle non flag arguments
//
// Example usage:
// #include <stdio.h>
// #define ELKA_IMPLEMENTATION
// #include "elk_args.h"
// int
// main(int argc, char** argv)
// {
// elka_state args = {0};
//
// elka_flag verbose = {0};
// elka_add_flag(&args, &verbose, "verbose", 'v', elka_bool);
//
// elka_flag message = {0};
// elka_add_flag(&args, &message, 0, 'm', elka_string);
//
// elka_parse(&args, argc, argv);
//
// printf("Verbose: %d\n", verbose.Value.AsBool);
// printf("Message: %s\n", message.Value.AsString);
// }
//
// Example output:
// $ elka_test --verbose -m "Hello, World!"
// Verbose: 1
// Message: Hello, World!
//
// Changelog:
// v0.1:
// - Released to public under MIT license
#ifndef ELK_ARGS_H
#define ELK_ARGS_H
typedef enum elka_type
{
elka_bool,
elka_string,
} elka_type;
typedef struct elka_flag
{
struct elka_flag* Next;
char* LongName;
char ShortName;
elka_type Type;
union {
int AsBool;
char* AsString;
} Value;
} elka_flag;
typedef struct elka_state
{
elka_flag* First;
} elka_state;
extern void elka_add_flag(elka_state* State, elka_flag* Flag, char* LongName,
char ShortName, elka_type Type);
// Add's a flag to be parsed.
extern int elka_parse(elka_state* State, int Count, char** Data);
#endif // ELKA_ARGS_H
#ifdef ELKA_IMPLEMENTATION
// Define ELKA_STRCMP if you already have your own strcmp.
// As long as equality returns 0 we'll be happy.
#ifndef ELKA_STRCMP
#include <string.h>
#define ELKA_STRCMP strcmp
#endif
void elka_add_flag(elka_state* State, elka_flag* Flag,
char* LongName, char ShortName, elka_type Type)
{
Flag->LongName = LongName;
Flag->ShortName = ShortName;
Flag->Type = Type;
Flag->Next = State->First;
State->First = Flag;
}
int elka_parse(elka_state* State, int Count, char** Data)
{
for (int Index = 1; Index < Count; Index++)
{
char* Arg = Data[Index];
if (Arg[0] == '-')
{
int IsLong = (Arg[1] == '-');
for (elka_flag* Flag = State->First; Flag; Flag = Flag->Next)
{
int Match = 0;
if (IsLong)
{
Match = Flag->LongName && ELKA_STRCMP(Arg + 2, Flag->LongName) == 0;
}
else
{
Match = Flag->ShortName && Flag->ShortName == Arg[1];
}
if (Match)
{
switch (Flag->Type)
{
case elka_bool: {
Flag->Value.AsBool = 1;
} break;
case elka_string: {
Flag->Value.AsString = Data[++Index];
} break;
}
break;
}
}
}
else
{
// TODO(kiljacken): Handle plain arguments
}
}
return(0);
}
#endif // ELKA_IMPLEMENTATION