acpc_dealer 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/Brickfile +6 -0
  3. data/README.md +7 -6
  4. data/Rakefile +30 -14
  5. data/acpc_dealer.gemspec +2 -1
  6. data/bin/acpc_dealer +4 -0
  7. data/ext/hand_evaluator/extconf.rb +10 -0
  8. data/lib/acpc_dealer/version.rb +1 -1
  9. data/lib/hand_evaluator.bundle +0 -0
  10. data/spec/dealer_runner_spec.rb +76 -72
  11. metadata +19 -82
  12. data/vendor/project_acpc_server/LICENCE +0 -23
  13. data/vendor/project_acpc_server/Makefile +0 -35
  14. data/vendor/project_acpc_server/README +0 -113
  15. data/vendor/project_acpc_server/README.submission +0 -42
  16. data/vendor/project_acpc_server/acpc_play_match.pl +0 -101
  17. data/vendor/project_acpc_server/bm_run_matches.c +0 -238
  18. data/vendor/project_acpc_server/bm_server.c +0 -1604
  19. data/vendor/project_acpc_server/bm_server.config +0 -78
  20. data/vendor/project_acpc_server/bm_widget.c +0 -230
  21. data/vendor/project_acpc_server/dealer.c +0 -1293
  22. data/vendor/project_acpc_server/evalHandTables +0 -4269
  23. data/vendor/project_acpc_server/example_player.c +0 -204
  24. data/vendor/project_acpc_server/example_player.limit.2p.sh +0 -3
  25. data/vendor/project_acpc_server/example_player.limit.3p.sh +0 -3
  26. data/vendor/project_acpc_server/example_player.nolimit.2p.sh +0 -3
  27. data/vendor/project_acpc_server/example_player.nolimit.3p.sh +0 -3
  28. data/vendor/project_acpc_server/game.c +0 -1792
  29. data/vendor/project_acpc_server/game.h +0 -253
  30. data/vendor/project_acpc_server/holdem.limit.2p.reverse_blinds.game +0 -13
  31. data/vendor/project_acpc_server/holdem.limit.3p.game +0 -13
  32. data/vendor/project_acpc_server/holdem.nolimit.2p.reverse_blinds.game +0 -12
  33. data/vendor/project_acpc_server/holdem.nolimit.3p.game +0 -12
  34. data/vendor/project_acpc_server/kuhn.limit.3p.game +0 -14
  35. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf1.sh +0 -3
  36. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf2.sh +0 -3
  37. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player.sf3.sh +0 -3
  38. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/LICENCE +0 -23
  39. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/Makefile +0 -127
  40. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/README.md +0 -35
  41. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/CExceptionConfig.h +0 -12
  42. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/dealer_connection.c +0 -49
  43. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/dealer_connection.h +0 -22
  44. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/kuhn_3p_equilibrium_player.c +0 -483
  45. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/kuhn_3p_equilibrium_player.h +0 -108
  46. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/main.c +0 -84
  47. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/player_config.c +0 -253
  48. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/src/player_config.h +0 -21
  49. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/support/test_helper.c +0 -45
  50. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/support/test_helper.h +0 -27
  51. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player.c +0 -698
  52. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_1.c +0 -324
  53. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_2.c +0 -262
  54. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/test/test_kuhn_3p_equilibrium_player_sub_family_3.c +0 -177
  55. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/docs/license.txt +0 -30
  56. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/docs/readme.txt +0 -242
  57. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/lib/CException.c +0 -43
  58. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/lib/CException.h +0 -86
  59. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/release/build.info +0 -2
  60. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/cexception/release/version.info +0 -2
  61. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/History.md +0 -27
  62. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/Makefile +0 -8
  63. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/Readme.md +0 -103
  64. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/package.json +0 -9
  65. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/src/commander.c +0 -250
  66. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/src/commander.h +0 -88
  67. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/commander.c/test.c +0 -34
  68. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/colour_prompt.rb +0 -94
  69. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/colour_reporter.rb +0 -39
  70. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_config.yml +0 -36
  71. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_module.rb +0 -202
  72. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/generate_test_runner.rb +0 -316
  73. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/test_file_filter.rb +0 -23
  74. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/auto/unity_test_summary.rb +0 -139
  75. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/docs/Unity Summary.txt +0 -216
  76. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/docs/license.txt +0 -31
  77. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/release/build.info +0 -2
  78. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/release/version.info +0 -2
  79. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity.c +0 -1146
  80. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity.h +0 -245
  81. data/vendor/project_acpc_server/kuhn_3p_equilibrium_player/vendor/unity/src/unity_internals.h +0 -546
  82. data/vendor/project_acpc_server/net.c +0 -218
  83. data/vendor/project_acpc_server/net.h +0 -62
  84. data/vendor/project_acpc_server/play_match.pl +0 -99
  85. data/vendor/project_acpc_server/protocol.md +0 -239
  86. data/vendor/project_acpc_server/protocol.odt +0 -0
  87. data/vendor/project_acpc_server/protocol.pdf +0 -0
  88. data/vendor/project_acpc_server/rng.c +0 -139
  89. data/vendor/project_acpc_server/rng.h +0 -63
  90. data/vendor/project_acpc_server/validate_submission.pl +0 -546
@@ -1,43 +0,0 @@
1
- #include "CException.h"
2
-
3
- volatile CEXCEPTION_FRAME_T CExceptionFrames[CEXCEPTION_NUM_ID] = { 0 };
4
-
5
- //------------------------------------------------------------------------------------------
6
- // Throw
7
- //------------------------------------------------------------------------------------------
8
- void Throw(CEXCEPTION_T ExceptionID)
9
- {
10
- unsigned int MY_ID = CEXCEPTION_GET_ID;
11
- CExceptionFrames[MY_ID].Exception = ExceptionID;
12
- if (CExceptionFrames[MY_ID].pFrame)
13
- {
14
- longjmp(*CExceptionFrames[MY_ID].pFrame, 1);
15
- }
16
- CEXCEPTION_NO_CATCH_HANDLER(MY_ID);
17
- }
18
-
19
- //------------------------------------------------------------------------------------------
20
- // Explanation of what it's all for:
21
- //------------------------------------------------------------------------------------------
22
- /*
23
- #define Try
24
- { <- give us some local scope. most compilers are happy with this
25
- jmp_buf *PrevFrame, NewFrame; <- prev frame points to the last try block's frame. new frame gets created on stack for this Try block
26
- unsigned int MY_ID = CEXCEPTION_GET_ID; <- look up this task's id for use in frame array. always 0 if single-tasking
27
- PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; <- set pointer to point at old frame (which array is currently pointing at)
28
- CExceptionFrames[MY_ID].pFrame = &NewFrame; <- set array to point at my new frame instead, now
29
- CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- initialize my exception id to be NONE
30
- if (setjmp(NewFrame) == 0) { <- do setjmp. it returns 1 if longjump called, otherwise 0
31
- if (&PrevFrame) <- this is here to force proper scoping. it requires braces or a single line to be but after Try, otherwise won't compile. This is always true at this point.
32
-
33
- #define Catch(e)
34
- else { } <- this also forces proper scoping. Without this they could stick their own 'else' in and it would get ugly
35
- CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; <- no errors happened, so just set the exception id to NONE (in case it was corrupted)
36
- }
37
- else <- an exception occurred
38
- { e = CExceptionFrames[MY_ID].Exception; e=e;} <- assign the caught exception id to the variable passed in.
39
- CExceptionFrames[MY_ID].pFrame = PrevFrame; <- make the pointer in the array point at the previous frame again, as if NewFrame never existed.
40
- } <- finish off that local scope we created to have our own variables
41
- if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE) <- start the actual 'catch' processing if we have an exception id saved away
42
- */
43
-
@@ -1,86 +0,0 @@
1
- #ifndef _CEXCEPTION_H
2
- #define _CEXCEPTION_H
3
-
4
- #include <setjmp.h>
5
-
6
- #ifdef __cplusplus
7
- extern "C"
8
- {
9
- #endif
10
-
11
-
12
- //To Use CException, you have a number of options:
13
- //1. Just include it and run with the defaults
14
- //2. Define any of the following symbols at the command line to override them
15
- //3. Include a header file before CException.h everywhere which defines any of these
16
- //4. Create an Exception.h in your path, and just define EXCEPTION_USE_CONFIG_FILE first
17
-
18
- #ifdef CEXCEPTION_USE_CONFIG_FILE
19
- #include "CExceptionConfig.h"
20
- #endif
21
-
22
- //This is the value to assign when there isn't an exception
23
- #ifndef CEXCEPTION_NONE
24
- #define CEXCEPTION_NONE (0x5A5A5A5A)
25
- #endif
26
-
27
- //This is number of exception stacks to keep track of (one per task)
28
- #ifndef CEXCEPTION_NUM_ID
29
- #define CEXCEPTION_NUM_ID (1) //there is only the one stack by default
30
- #endif
31
-
32
- //This is the method of getting the current exception stack index (0 if only one stack)
33
- #ifndef CEXCEPTION_GET_ID
34
- #define CEXCEPTION_GET_ID (0) //use the first index always because there is only one anyway
35
- #endif
36
-
37
- //The type to use to store the exception values.
38
- #ifndef CEXCEPTION_T
39
- #define CEXCEPTION_T unsigned int
40
- #endif
41
-
42
- //This is an optional special handler for when there is no global Catch
43
- #ifndef CEXCEPTION_NO_CATCH_HANDLER
44
- #define CEXCEPTION_NO_CATCH_HANDLER(id)
45
- #endif
46
-
47
- //exception frame structures
48
- typedef struct {
49
- jmp_buf* pFrame;
50
- CEXCEPTION_T volatile Exception;
51
- } CEXCEPTION_FRAME_T;
52
-
53
- //actual root frame storage (only one if single-tasking)
54
- extern volatile CEXCEPTION_FRAME_T CExceptionFrames[];
55
-
56
- //Try (see C file for explanation)
57
- #define Try \
58
- { \
59
- jmp_buf *PrevFrame, NewFrame; \
60
- unsigned int MY_ID = CEXCEPTION_GET_ID; \
61
- PrevFrame = CExceptionFrames[CEXCEPTION_GET_ID].pFrame; \
62
- CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); \
63
- CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
64
- if (setjmp(NewFrame) == 0) { \
65
- if (1)
66
-
67
- //Catch (see C file for explanation)
68
- #define Catch(e) \
69
- else { } \
70
- CExceptionFrames[MY_ID].Exception = CEXCEPTION_NONE; \
71
- } \
72
- else \
73
- { e = CExceptionFrames[MY_ID].Exception; e=e; } \
74
- CExceptionFrames[MY_ID].pFrame = PrevFrame; \
75
- } \
76
- if (CExceptionFrames[CEXCEPTION_GET_ID].Exception != CEXCEPTION_NONE)
77
-
78
- //Throw an Error
79
- void Throw(CEXCEPTION_T ExceptionID);
80
-
81
- #ifdef __cplusplus
82
- } // extern "C"
83
- #endif
84
-
85
-
86
- #endif // _CEXCEPTION_H
@@ -1,27 +0,0 @@
1
-
2
- 1.2.1 / 2013-01-08
3
- ==================
4
-
5
- * add freeing of normalized argv
6
- * dont worry about zeroing in command_free()
7
- * fix docs
8
-
9
- 1.2.0 / 2013-01-08
10
- ==================
11
-
12
- * add command_free()
13
-
14
- 1.1.0 / 2012-12-18
15
- ==================
16
-
17
- * add short flag expansion
18
-
19
- 1.0.0 / 2012-12-13
20
- ==================
21
-
22
- * fix malloc(), add a byte for nul
23
-
24
- 0.0.1 / 2012-06-16
25
- ==================
26
-
27
- * Initial release
@@ -1,8 +0,0 @@
1
-
2
- test: test.c src/commander.c
3
- $(CC) $^ -std=c99 -o $@
4
-
5
- clean:
6
- rm -f test
7
-
8
- .PHONY: clean
@@ -1,103 +0,0 @@
1
-
2
- # commander.c
3
-
4
- Commander option parser ported to C.
5
-
6
- ## Automated --help
7
-
8
- The previous example would produce the following `--help`:
9
-
10
- ```
11
-
12
- Usage: example [options]
13
-
14
- Options:
15
-
16
- -V, --version output program version
17
- -h, --help output help information
18
- -v, --verbose enable verbose stuff
19
- -r, --required <arg> required arg
20
- -o, --optional [arg] optional arg
21
-
22
- ```
23
-
24
- ## Example
25
-
26
- ```c
27
- #include <stdio.h>
28
- #include "commander.h"
29
-
30
- static void
31
- verbose(command_t *self) {
32
- printf("verbose: enabled\n");
33
- }
34
-
35
- static void
36
- required(command_t *self) {
37
- printf("required: %s\n", self->arg);
38
- }
39
-
40
- static void
41
- optional(command_t *self) {
42
- printf("optional: %s\n", self->arg);
43
- }
44
-
45
- int
46
- main(int argc, const char **argv){
47
- command_t cmd;
48
- command_init(&cmd, argv[0], "0.0.1");
49
- command_option(&cmd, "-v", "--verbose", "enable verbose stuff", verbose);
50
- command_option(&cmd, "-r", "--required <arg>", "required arg", required);
51
- command_option(&cmd, "-o", "--optional [arg]", "optional arg", optional);
52
- command_parse(&cmd, argc, argv);
53
- printf("additional args:\n");
54
- for (int i = 0; i < cmd.argc; ++i) {
55
- printf(" - '%s'\n", cmd.argv[i]);
56
- }
57
- command_free(&cmd);
58
- return 0;
59
- }
60
- ```
61
-
62
- ## Closure
63
-
64
- `cmd.data` is a `void *` so pass along a struct to the callbacks if you want.
65
-
66
- ## Usage
67
-
68
- `cmd.usage` defaults to "[options]".
69
-
70
- ## Links
71
-
72
- - Used by the [mon(1)](https://github.com/visionmedia/mon/blob/master/src/mon.c) process monitor
73
-
74
- ## Short flags
75
-
76
- Compound short flags are automatically expanded to their canonical form. For example `-vLO` would
77
- become `-v -L -O`.
78
-
79
- ## License
80
-
81
- (The MIT License)
82
-
83
- Copyright (c) 2012 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
84
-
85
- Permission is hereby granted, free of charge, to any person obtaining
86
- a copy of this software and associated documentation files (the
87
- 'Software'), to deal in the Software without restriction, including
88
- without limitation the rights to use, copy, modify, merge, publish,
89
- distribute, sublicense, and/or sell copies of the Software, and to
90
- permit persons to whom the Software is furnished to do so, subject to
91
- the following conditions:
92
-
93
- The above copyright notice and this permission notice shall be
94
- included in all copies or substantial portions of the Software.
95
-
96
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
97
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
98
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
99
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
100
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
101
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
102
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
103
-
@@ -1,9 +0,0 @@
1
- {
2
- "name": "commander",
3
- "version": "1.2.1",
4
- "repo": "visionmedia/commander.c",
5
- "description": "Command-line argument parser",
6
- "keywords": ["cli", "command", "parser", "argv", "args", "options"],
7
- "license": "MIT",
8
- "src": ["src/commander.h", "src/commander.c"]
9
- }
@@ -1,250 +0,0 @@
1
-
2
- //
3
- // commander.c
4
- //
5
- // Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
6
- //
7
-
8
- #include <stdio.h>
9
- #include <stdlib.h>
10
- #include <string.h>
11
- #include <assert.h>
12
- #include "commander.h"
13
-
14
- /*
15
- * Output error and exit.
16
- */
17
-
18
- static void
19
- error(char *msg) {
20
- fprintf(stderr, "%s\n", msg);
21
- exit(1);
22
- }
23
-
24
- /*
25
- * Output command version.
26
- */
27
-
28
- static void
29
- command_version(command_t *self) {
30
- printf("%s\n", self->version);
31
- exit(0);
32
- }
33
-
34
- /*
35
- * Output command help.
36
- */
37
-
38
- void
39
- command_help(command_t *self) {
40
- printf("\n");
41
- printf(" Usage: %s %s\n", self->name, self->usage);
42
- printf("\n");
43
- printf(" Options:\n");
44
- printf("\n");
45
- for (int i = 0; i < self->option_count; ++i) {
46
- command_option_t *option = &self->options[i];
47
- printf(" %s, %-25s %s\n"
48
- , option->small
49
- , option->large_with_arg
50
- , option->description);
51
- }
52
- printf("\n");
53
- exit(0);
54
- }
55
-
56
- /*
57
- * Initialize with program `name` and `version`.
58
- */
59
-
60
- void
61
- command_init(command_t *self, const char *name, const char *version) {
62
- self->arg = NULL;
63
- self->name = name;
64
- self->version = version;
65
- self->option_count = self->argc = 0;
66
- self->usage = "[options]";
67
- self->nargv = NULL;
68
- command_option(self, "-V", "--version", "output program version", command_version);
69
- command_option(self, "-h", "--help", "output help information", command_help);
70
- }
71
-
72
- /*
73
- * Free up commander after use.
74
- */
75
-
76
- void
77
- command_free(command_t *self) {
78
- for (int i = 0; i < self->option_count; ++i) {
79
- command_option_t *option = &self->options[i];
80
- free(option->argname);
81
- free(option->large);
82
- }
83
-
84
- if (self->nargv) {
85
- for (int i = 0; self->nargv[i]; ++i) {
86
- free(self->nargv[i]);
87
- }
88
- free(self->nargv);
89
- }
90
- }
91
-
92
- /*
93
- * Parse argname from `str`. For example
94
- * Take "--required <arg>" and populate `flag`
95
- * with "--required" and `arg` with "<arg>".
96
- */
97
-
98
- static void
99
- parse_argname(const char *str, char *flag, char *arg) {
100
- int buffer = 0;
101
- size_t flagpos = 0;
102
- size_t argpos = 0;
103
- size_t len = strlen(str);
104
-
105
- for (int i = 0; i < len; ++i) {
106
- if (buffer || '[' == str[i] || '<' == str[i]) {
107
- buffer = 1;
108
- arg[argpos++] = str[i];
109
- } else {
110
- if (' ' == str[i]) continue;
111
- flag[flagpos++] = str[i];
112
- }
113
- }
114
-
115
- arg[argpos] = '\0';
116
- flag[flagpos] = '\0';
117
- }
118
-
119
- /*
120
- * Normalize the argument vector by exploding
121
- * multiple options (if any). For example
122
- * "foo -abc --scm git" -> "foo -a -b -c --scm git"
123
- */
124
-
125
- static char **
126
- normalize_args(int *argc, char **argv) {
127
- int size = 0;
128
- int alloc = *argc + 1;
129
- char **nargv = malloc(alloc * sizeof(char *));
130
-
131
- for (int i = 0; argv[i]; ++i) {
132
- const char *arg = argv[i];
133
- int len = strlen(arg);
134
-
135
- // short flag
136
- if (len > 2 && '-' == arg[0] && !strchr(arg + 1, '-')) {
137
- alloc += len - 2;
138
- nargv = realloc(nargv, alloc * sizeof(char *));
139
- for (int j = 1; j < len; ++j) {
140
- nargv[size] = malloc(3);
141
- sprintf(nargv[size], "-%c", arg[j]);
142
- size++;
143
- }
144
- continue;
145
- }
146
-
147
- // regular arg
148
- nargv[size] = malloc(len + 1);
149
- strcpy(nargv[size], arg);
150
- size++;
151
- }
152
-
153
- nargv[size] = NULL;
154
- *argc = size;
155
- return nargv;
156
- }
157
-
158
- /*
159
- * Define an option.
160
- */
161
-
162
- void
163
- command_option(command_t *self, const char *small, const char *large, const char *desc, command_callback_t cb) {
164
- int n = self->option_count++;
165
- if (n == COMMANDER_MAX_OPTIONS) error("Maximum option definitions exceeded");
166
- command_option_t *option = &self->options[n];
167
- option->cb = cb;
168
- option->small = small;
169
- option->description = desc;
170
- option->required_arg = option->optional_arg = 0;
171
- option->large_with_arg = large;
172
- option->argname = malloc(strlen(large) + 1);
173
- assert(option->argname);
174
- option->large = malloc(strlen(large) + 1);
175
- assert(option->large);
176
- parse_argname(large, option->large, option->argname);
177
- if ('[' == option->argname[0]) option->optional_arg = 1;
178
- if ('<' == option->argname[0]) option->required_arg = 1;
179
- }
180
-
181
- /*
182
- * Parse `argv` (internal).
183
- * Input arguments should be normalized first
184
- * see `normalize_args`.
185
- */
186
-
187
- static void
188
- command_parse_args(command_t *self, int argc, char **argv) {
189
- int literal = 0;
190
-
191
- for (int i = 1; i < argc; ++i) {
192
- const char *arg = argv[i];
193
- for (int j = 0; j < self->option_count; ++j) {
194
- command_option_t *option = &self->options[j];
195
-
196
- // match flag
197
- if (!strcmp(arg, option->small) || !strcmp(arg, option->large)) {
198
- self->arg = NULL;
199
-
200
- // required
201
- if (option->required_arg) {
202
- arg = argv[++i];
203
- if (!arg || '-' == arg[0]) {
204
- fprintf(stderr, "%s %s argument required\n", option->large, option->argname);
205
- exit(1);
206
- }
207
- self->arg = arg;
208
- }
209
-
210
- // optional
211
- if (option->optional_arg) {
212
- if (argv[i + 1] && '-' != argv[i + 1][0]) {
213
- self->arg = argv[++i];
214
- }
215
- }
216
-
217
- // invoke callback
218
- option->cb(self);
219
- goto match;
220
- }
221
- }
222
-
223
- // --
224
- if ('-' == arg[0] && '-' == arg[1] && 0 == arg[2]) {
225
- literal = 1;
226
- goto match;
227
- }
228
-
229
- // unrecognized
230
- if ('-' == arg[0] && !literal) {
231
- fprintf(stderr, "unrecognized flag %s\n", arg);
232
- exit(1);
233
- }
234
-
235
- int n = self->argc++;
236
- if (n == COMMANDER_MAX_ARGS) error("Maximum number of arguments exceeded");
237
- self->argv[n] = (char *) arg;
238
- match:;
239
- }
240
- }
241
-
242
- /*
243
- * Parse `argv` (public).
244
- */
245
-
246
- void
247
- command_parse(command_t *self, int argc, char **argv) {
248
- self->nargv = normalize_args(&argc, argv);
249
- command_parse_args(self, argc, self->nargv);
250
- }