Skip to content

Commit 80428a2

Browse files
committed
Initial commit.
0 parents  commit 80428a2

File tree

7 files changed

+387
-0
lines changed

7 files changed

+387
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.swp
2+
build

.vimrc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Plugin 'altercation/vim-colors-solarized'
2+
3+
let g:solarized_termcolors=256
4+
syntax enable
5+
set background=dark
6+
colorscheme solarized
7+
8+
" syntastic settings
9+
10+
set statusline+=%#warningmsg#
11+
set statusline+=%{SyntasticStatuslineFlag()}
12+
set statusline+=%*
13+
14+
15+
let g:sytastic_c_checkers = ['cmake']
16+
let g:syntastic_always_populate_loc_list = 1
17+
let g:syntastic_auto_loc_list = 1
18+
let g:syntastic_check_on_open = 1
19+
let g:syntastic_check_on_wq = 0
20+
21+
let g:syntastic_c_include_dirs = [ '/home/stefan/workspace/jansson-2.9/build/include', '/home/stefan/workspace/SOEM/install/include' ]
22+
let g:syntastic_c_check_header = 0
23+
24+
" let g:syntastic_c_checkers = ['clang_check']

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cmake_minimum_required (VERSION 3.1.0)
2+
project (SimpleArgumentParser C CXX)
3+
4+
set (SimpleArgumentParser_VERSION_MAJOR 0)
5+
set (SimpleArgumentParser_VERSION_MINOR 1)
6+
7+
8+
add_library(sap SHARED "${CMAKE_SOURCE_DIR}/src/sap.c" "${CMAKE_SOURCE_DIR}/src/sap.h")

src/.sap.c.swp

20 KB
Binary file not shown.

src/.sap.h.swp

12 KB
Binary file not shown.

src/sap.c

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
#include "sap.h"
2+
3+
sap_t* sap_create() {
4+
5+
sap_t* parser = calloc(1, sizeof(sap_t));
6+
7+
return parser;
8+
9+
};
10+
11+
int sap_add_command(sap_t* parser, char* command, command_handler handler) {
12+
13+
if (parser == NULL || command == NULL) {
14+
return -1;
15+
}
16+
17+
/* go through the command list and look for existing
18+
* commands, return -1 if so. */
19+
20+
int i = 0;
21+
22+
for (i = 0; parser->commands[i] != NULL; i += 1) {
23+
24+
sap_command_t* current_command = parser->commands[i];
25+
26+
if (strcmp(current_command->label, command) == 0) {
27+
return -1;
28+
}
29+
30+
}
31+
32+
if (i >= SAP_MAX_COMMANDS) {
33+
return -1;
34+
}
35+
36+
/* Create new command */
37+
38+
sap_command_t* new_command = calloc(1, sizeof(sap_command_t));
39+
40+
*new_command = (sap_command_t) {
41+
.label = command,
42+
.handler = handler
43+
};
44+
45+
parser->commands[i+0] = new_command;
46+
parser->commands[i+1] = NULL;
47+
48+
return 0;
49+
50+
}
51+
52+
int sap_set_default(sap_t* parser, command_handler handler) {
53+
54+
if (parser == NULL || handler == NULL) {
55+
56+
return -1;
57+
58+
}
59+
60+
sap_command_t* command = calloc(1, sizeof(sap_t));
61+
command->label = "";
62+
command->handler = handler;
63+
64+
parser->default_command = command;
65+
66+
return 0;
67+
68+
}
69+
70+
#define option_regex "^--\\(\\w\\+\\)\\(=\\([^\\s]\\+\\)\\)\\?$"
71+
72+
static int sap_is_option(char* arg) {
73+
74+
regex_t regex;
75+
int reti = regcomp(&regex, option_regex, 0);
76+
77+
if (reti) {
78+
fprintf(stderr, "Could not compile regex.\n");
79+
exit(-1);
80+
}
81+
82+
/* execute regular expession */
83+
84+
reti = regexec(&regex, arg, 0, NULL, 0);
85+
86+
regfree(&regex);
87+
88+
if (!reti) {
89+
return 1;
90+
} else if (reti == REG_NOMATCH) {
91+
return 0;
92+
}
93+
94+
95+
return 0;
96+
97+
}
98+
99+
static sap_option_t* sap_parse_option(char* arg) {
100+
101+
int status;
102+
regmatch_t match[4];
103+
104+
/* set the first and third match to -1 so we can identify those late
105+
* if they match than there will be some plausable values */
106+
107+
match[1].rm_so = -1;
108+
match[1].rm_eo = -1;
109+
110+
match[3].rm_so = -1;
111+
match[3].rm_eo = -1;
112+
113+
/* execute the regular expression, we assume that
114+
* the string has been checked before */
115+
116+
regex_t regex;
117+
regcomp(&regex, option_regex, 0);
118+
regexec(&regex, arg, 4, match, 0);
119+
120+
regfree(&regex);
121+
122+
/* if there is no match on the first argument then
123+
* there is somehow an error and we return NULL */
124+
125+
if (match[1].rm_so == -1) {
126+
return NULL;
127+
}
128+
129+
/* if we found something then we create a new option
130+
* and store this string as the options label */
131+
132+
int len = match[1].rm_eo - match[1].rm_so;
133+
char* label = calloc(1, len);
134+
memcpy(label, arg + match[1].rm_so, len);
135+
136+
sap_option_t* option = calloc(1, sizeof(sap_option_t));
137+
option->label = label;
138+
option->value = NULL;
139+
option->is_flag = 1;
140+
141+
/* if there is no value assigned to the option then we mark
142+
* this option as flag. Meaning this option is enabled.
143+
* if there is a value, we mark this no flag and store the
144+
* value in the options value attribute */
145+
146+
if (match[3].rm_so == -1) {
147+
return option;
148+
}
149+
150+
len = match[3].rm_eo - match[3].rm_so;
151+
char* value = calloc(1, len);
152+
memcpy(value, arg + match[3].rm_so, len);
153+
154+
option->value = value;
155+
option->is_flag = 0;
156+
157+
return option;
158+
159+
}
160+
161+
162+
#define command_regex "^[^--]\\(\\w\\|\\/\\|.\\|-\\)\\+$"
163+
164+
static int sap_is_command(char* arg) {
165+
166+
regex_t regex;
167+
int reti = regcomp(&regex, command_regex, 0);
168+
169+
if (reti) {
170+
fprintf(stderr, "Could not compile regex.\n");
171+
exit(-1);
172+
}
173+
174+
/* execute regular expession */
175+
176+
reti = regexec(&regex, arg, 0, NULL, 0);
177+
178+
regfree(&regex);
179+
180+
if (!reti) {
181+
return 1;
182+
} else if (reti == REG_NOMATCH) {
183+
return 0;
184+
}
185+
186+
return 0;
187+
188+
}
189+
190+
int sap_execute(sap_t* parser, int argc, char* argv[]) {
191+
192+
return sap_execute_ex(parser, argc, argv, NULL);
193+
194+
}
195+
196+
int sap_execute_ex(sap_t* parser, int argc, char* argv[], sap_options_t* extra_options) {
197+
198+
/* get first argument */
199+
200+
sap_option_t* current_option;
201+
202+
203+
/* determine command label */
204+
205+
char* command_str = argv[0];
206+
int new_argc = argc;
207+
int new_argc_offset = 0;
208+
int option_counter = 0;
209+
210+
211+
if (!sap_is_command(command_str)) {
212+
return -1;
213+
}
214+
215+
new_argc -= 1;
216+
new_argc_offset += 1;
217+
218+
sap_options_t* options = calloc(1, sizeof(sap_options_t));
219+
220+
for (int i = 1; i < argc; i += 1) {
221+
222+
char* current_string = argv[i];
223+
224+
if (sap_is_command(current_string)) {
225+
break;
226+
}
227+
228+
/* check if current_string is option */
229+
230+
if (sap_is_option(current_string)) {
231+
232+
sap_option_t* option = sap_parse_option(current_string);
233+
234+
options->list[i-1] = option;
235+
options->list[i-0] = NULL;
236+
237+
option_counter += 1;
238+
239+
new_argc -= 1;
240+
new_argc_offset += 1;
241+
242+
}
243+
244+
}
245+
246+
/* get command from the parsers commands list */
247+
248+
sap_command_t* command = parser->default_command;
249+
250+
for (int i = 0; parser->commands[i] != NULL; i += 1) {
251+
252+
if (strcmp(parser->commands[i]->label, command_str) != 0) {
253+
254+
continue;
255+
256+
}
257+
258+
command = parser->commands[i];
259+
260+
break;
261+
262+
}
263+
264+
265+
if (command == NULL) {
266+
return -1;
267+
}
268+
269+
/* collect remaining arguments */
270+
char* new_argv[new_argc];
271+
272+
int j = 0;
273+
for (int i = new_argc_offset; i < argc; i += 1) {
274+
275+
new_argv[j++] = argv[i];
276+
277+
}
278+
279+
/* collect privous options and copy */
280+
281+
if (extra_options != NULL) {
282+
283+
for (int i = 0; extra_options->list[i]; i += 1) {
284+
285+
options->list[option_counter + 0] = extra_options->list[i];
286+
options->list[option_counter + 1] = NULL;
287+
288+
option_counter += 1;
289+
290+
}
291+
292+
}
293+
294+
return command->handler(new_argc, new_argv, options);
295+
296+
}
297+
298+
void sap_destroy(sap_t* parser) {
299+
300+
301+
}

src/sap.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#ifndef __SAP_H__
2+
#define __SAP_H__
3+
4+
#include <stdlib.h>
5+
#include <stdio.h>
6+
#include <string.h>
7+
#include <regex.h>
8+
9+
#define SAP_MAX 10
10+
#define SAP_MAX_OPTIONS 50
11+
#define SAP_MAX_COMMANDS 50
12+
13+
typedef struct sap_option_st {
14+
15+
char* label;
16+
char* value;
17+
int is_flag;
18+
19+
} sap_option_t;
20+
21+
typedef struct sap_options_st {
22+
23+
sap_option_t* list[SAP_MAX_OPTIONS];
24+
25+
} sap_options_t;
26+
27+
typedef int (*command_handler)(int argc, char* argv[], sap_options_t* options);
28+
29+
typedef struct sap_command_st {
30+
31+
char* label;
32+
command_handler handler;
33+
34+
} sap_command_t;
35+
36+
typedef struct sap_st {
37+
38+
sap_command_t* commands[SAP_MAX_COMMANDS];
39+
sap_command_t* default_command;
40+
41+
} sap_t;
42+
43+
44+
45+
sap_t* sap_create();
46+
int sap_add_command(sap_t* parser, char* command, command_handler handler);
47+
int sap_set_default(sap_t* parser, command_handler handler);
48+
int sap_execute(sap_t* parser, int argc, char* argv[]);
49+
int sap_execute_ex(sap_t* parser, int argc, char* argv[], sap_options_t* options);
50+
void sap_destroy(sap_t* parser);
51+
52+
#endif

0 commit comments

Comments
 (0)