aboutsummaryrefslogtreecommitdiff
path: root/shell.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--shell.c212
1 files changed, 177 insertions, 35 deletions
diff --git a/shell.c b/shell.c
index 11c53c2..9c5ac08 100644
--- a/shell.c
+++ b/shell.c
@@ -13,10 +13,36 @@
13#define SOLUTIONS_BUFFER_SIZE 500000 /* Should be enough */ 13#define SOLUTIONS_BUFFER_SIZE 500000 /* Should be enough */
14#define MAX_PATH_LENGTH 10000 /* Should be enough */ 14#define MAX_PATH_LENGTH 10000 /* Should be enough */
15 15
16#define _flag_cube "-cube"
17#define _flag_perm "-perm"
18#define _flag_command "-command"
19#define _flag_str_cube "-cubestr"
20#define _flag_format "-format"
21#define _flag_format_in "-fin"
22#define _flag_format_out "-fout"
23#define _flag_moves "-moves"
24#define _flag_trans "-trans"
25#define _flag_solver "-solver"
26#define _flag_options "-options"
27#define _flag_nisstype "-nisstype"
28#define _flag_minmoves "-m"
29#define _flag_maxmoves "-M"
30#define _flag_optimal "-O"
31#define _flag_maxsolutions "-n"
32
33#define _info_cubeformat(cube) cube " must be given in B32 format."
34#define _info_movesformat "The accepted moves are U, D, R, L, F and B, " \
35 "optionally followed by a 2, a ' or a 3."
36#define _info_transformat "The transformation must be given in the format " \
37 "(rotation|mirrored) (2 letters), for exmple " \
38 "'rotation UF' or 'mirrored BL'."
39#define _info_formats "The available formats are H48, B32 and SRC."
40
16typedef struct { 41typedef struct {
17 int command_index; 42 int command_index;
18 char cube[22]; 43 char cube[22];
19 char cube_perm[22]; 44 char cube_perm[22];
45 char *str_command;
20 char *str_cube; 46 char *str_cube;
21 char *str_format; 47 char *str_format;
22 char *str_format_in; 48 char *str_format_in;
@@ -45,6 +71,7 @@ static int64_t randomcube_exec(args_t *);
45static int64_t datasize_exec(args_t *); 71static int64_t datasize_exec(args_t *);
46static int64_t gendata_exec(args_t *); 72static int64_t gendata_exec(args_t *);
47static int64_t solve_exec(args_t *); 73static int64_t solve_exec(args_t *);
74static int64_t help_exec(args_t *);
48 75
49static int parse_args(int, char **, args_t *); 76static int parse_args(int, char **, args_t *);
50static bool parse_int8(char *, int8_t *); 77static bool parse_int8(char *, int8_t *);
@@ -52,6 +79,7 @@ static bool parse_int64(char *, int64_t *);
52 79
53static bool set_cube(int, char **, args_t *); 80static bool set_cube(int, char **, args_t *);
54static bool set_cube_perm(int, char **, args_t *); 81static bool set_cube_perm(int, char **, args_t *);
82static bool set_str_command(int, char **, args_t *);
55static bool set_str_cube(int, char **, args_t *); 83static bool set_str_cube(int, char **, args_t *);
56static bool set_str_format(int, char **, args_t *); 84static bool set_str_format(int, char **, args_t *);
57static bool set_str_format_in(int, char **, args_t *); 85static bool set_str_format_in(int, char **, args_t *);
@@ -68,24 +96,6 @@ static bool set_maxsolutions(int, char **, args_t *);
68static bool set_id(int, char **, args_t *); 96static bool set_id(int, char **, args_t *);
69 97
70static uint64_t rand64(void); 98static uint64_t rand64(void);
71
72#define COMMAND(N, E) { .name = N, .exec = E }
73struct {
74 char *name;
75 int64_t (*exec)(args_t *);
76} commands[] = {
77 COMMAND("compose", compose_exec),
78 COMMAND("inverse", inverse_exec),
79 COMMAND("applymoves", applymoves_exec),
80 COMMAND("applytrans", applytrans_exec),
81 COMMAND("frommoves", frommoves_exec),
82 COMMAND("convert", convert_exec),
83 COMMAND("randomcube", randomcube_exec),
84 COMMAND("datasize", datasize_exec),
85 COMMAND("gendata", gendata_exec),
86 COMMAND("solve", solve_exec),
87 COMMAND(NULL, NULL)
88};
89 99
90#define OPTION(N, A, S) { .name = N, .nargs = A, .set = S } 100#define OPTION(N, A, S) { .name = N, .nargs = A, .set = S }
91struct { 101struct {
@@ -93,23 +103,118 @@ struct {
93 int nargs; 103 int nargs;
94 bool (*set)(int, char **, args_t *); 104 bool (*set)(int, char **, args_t *);
95} options[] = { 105} options[] = {
96 OPTION("-cube", 1, set_cube), 106 OPTION(_flag_cube, 1, set_cube),
97 OPTION("-perm", 1, set_cube_perm), 107 OPTION(_flag_perm, 1, set_cube_perm),
98 OPTION("-cubestr", 1, set_str_cube), 108 OPTION(_flag_command, 1, set_str_command),
99 OPTION("-format", 1, set_str_format), 109 OPTION(_flag_str_cube, 1, set_str_cube),
100 OPTION("-fin", 1, set_str_format_in), 110 OPTION(_flag_format, 1, set_str_format),
101 OPTION("-fout", 1, set_str_format_out), 111 OPTION(_flag_format_in, 1, set_str_format_in),
102 OPTION("-moves", 1, set_str_moves), 112 OPTION(_flag_format_out, 1, set_str_format_out),
103 OPTION("-trans", 1, set_str_trans), 113 OPTION(_flag_moves, 1, set_str_moves),
104 OPTION("-solver", 1, set_str_solver), 114 OPTION(_flag_trans, 1, set_str_trans),
105 OPTION("-options", 1, set_str_options), /* TODO: remove, use only solver */ 115 OPTION(_flag_solver, 1, set_str_solver),
106 OPTION("-nisstype", 1, set_str_nisstype), /* TODO: remove, use flags */ 116 OPTION(_flag_options, 1, set_str_options), /* TODO: remove, use only solver */
107 OPTION("-m", 1, set_minmoves), 117 OPTION(_flag_nisstype, 1, set_str_nisstype), /* TODO: remove, use flags */
108 OPTION("-M", 1, set_maxmoves), 118 OPTION(_flag_minmoves, 1, set_minmoves),
109 OPTION("-O", 1, set_optimal), 119 OPTION(_flag_maxmoves, 1, set_maxmoves),
110 OPTION("-n", 1, set_maxsolutions), 120 OPTION(_flag_optimal, 1, set_optimal),
121 OPTION(_flag_maxsolutions, 1, set_maxsolutions),
111 OPTION(NULL, 0, NULL) 122 OPTION(NULL, 0, NULL)
112}; 123};
124
125#define COMMAND(N, S, D, E) { .name = N, .syn = S, .desc = D, .exec = E }
126struct {
127 char *name;
128 char *syn;
129 char *desc;
130 int64_t (*exec)(args_t *);
131} commands[] = {
132/* TODO: add synopsis and description here */
133 COMMAND(
134 "compose",
135 "compose " _flag_cube " CUBE " _flag_perm " PERM",
136 "Apply on CUBE the permutation defined by PERM. "
137 _info_cubeformat("CUBE and PERM"),
138 compose_exec
139 ),
140 COMMAND(
141 "inverse",
142 "inverse " _flag_cube " CUBE ",
143 "Compute the inverse of the given CUBE. "
144 _info_cubeformat("CUBE"),
145 inverse_exec
146 ),
147 COMMAND(
148 "applymoves",
149 "applymoves " _flag_cube " CUBE " _flag_moves " MOVES",
150 "Apply the given MOVES to the given CUBE. "
151 _info_cubeformat("CUBE") " " _info_movesformat,
152 applymoves_exec
153 ),
154 COMMAND(
155 "applytrans",
156 "applytrans " _flag_cube " CUBE " _flag_trans " TRANS",
157 "Apply the single transformation TRANS to the given CUBE. "
158 _info_cubeformat("CUBE") " " _info_transformat,
159 applytrans_exec
160 ),
161 COMMAND(
162 "frommoves",
163 "frommoves " _flag_moves " MOVES",
164 "Return the cube obtained by applying the given MOVES "
165 "to a solved cube. " _info_movesformat,
166 frommoves_exec
167 ),
168 COMMAND(
169 "convert",
170 "convert " _flag_str_cube " CUBESTR "
171 _flag_format_in " FORMAT_IN " _flag_format_out " FORMAT_OUT",
172 "Convert the cube described by CUBESTR from FORMAT_IN to "
173 "FORMAT_OUT."
174 _info_formats " "
175 "CUBESTR must be a valid cube in the FORMAT_IN format.",
176 convert_exec
177 ),
178 COMMAND(
179 "randomcube",
180 "randomcube",
181 "Returns a random cube in B32 format.",
182 randomcube_exec
183 ),
184 COMMAND(
185 "datasize",
186 "datasize" _flag_solver " SOLVER " _flag_options " OPTIONS",
187 "Return the size in bytes of the data table used by "
188 "SOLVER when called with the given OPTIONS.",
189 datasize_exec
190 ),
191 COMMAND(
192 "gendata",
193 "gendata" _flag_solver " SOLVER " _flag_options " OPTIONS",
194 "Generate the data table used by "
195 "SOLVER when called with the given OPTIONS.",
196 gendata_exec
197 ),
198 COMMAND(
199 "solve",
200 "solve" _flag_solver " SOLVER " _flag_options " OPTIONS "
201 "[" _flag_minmoves " n] [" _flag_maxmoves " N] "
202 _flag_cube " CUBE",
203 "Solve the given CUBE using SOLVER with the given OPTIONS, "
204 "using at least n and at most N moves. "
205 _info_cubeformat("CUBE"),
206 solve_exec
207 ),
208 COMMAND(
209 "help",
210 "help [" _flag_command " COMMAND]",
211 "If no COMMAND is specified, prints some generic information "
212 "and the list of commands. Otherwise it prints detailed "
213 "information about the specified COMMAND.",
214 help_exec
215 ),
216 COMMAND(NULL, NULL, NULL, NULL)
217};
113 218
114char *tablepaths[] = { 219char *tablepaths[] = {
115 "tables/", 220 "tables/",
@@ -397,6 +502,33 @@ solve_exec(args_t *args)
397 return 0; 502 return 0;
398} 503}
399 504
505static int64_t
506help_exec(args_t *args)
507{
508 int i;
509
510 if (args->str_command == NULL || args->str_command[0] == '\0') {
511 printf("This is a rudimentary shell for the H48 library.\n");
512 printf("Available commands and usage:\n\n");
513 for (i = 0; commands[i].name != NULL; i++)
514 printf("%-15s%s\n", commands[i].name, commands[i].syn);
515 printf("\nUse 'help COMMAND' for more information.\n");
516 } else {
517 for (i = 0; commands[i].name != NULL; i++)
518 if (!strcmp(args->str_command, commands[i].name))
519 break;
520 if (commands[i].name == NULL) {
521 printf("Unknown command %s\n", args->str_command);
522 return 1;
523 }
524 printf("Command %s\n\n", commands[i].name);
525 printf("Synopsis: %s\n\n", commands[i].syn);
526 printf("Description: %s\n", commands[i].desc);
527 }
528
529 return 0;
530}
531
400static int 532static int
401parse_args(int argc, char **argv, args_t *args) 533parse_args(int argc, char **argv, args_t *args)
402{ 534{
@@ -507,6 +639,14 @@ set_cube_perm(int argc, char **argv, args_t *args)
507} 639}
508 640
509static bool 641static bool
642set_str_command(int argc, char **argv, args_t *args)
643{
644 args->str_command = argv[0];
645
646 return true;
647}
648
649static bool
510set_str_cube(int argc, char **argv, args_t *args) 650set_str_cube(int argc, char **argv, args_t *args)
511{ 651{
512 args->str_cube = argv[0]; 652 args->str_cube = argv[0];
@@ -602,7 +742,8 @@ set_maxsolutions(int argc, char **argv, args_t *args)
602 return parse_int64(argv[0], &args->maxsolutions); 742 return parse_int64(argv[0], &args->maxsolutions);
603} 743}
604 744
605void log_stderr(const char *str, ...) 745void
746log_stderr(const char *str, ...)
606{ 747{
607 va_list args; 748 va_list args;
608 749
@@ -611,7 +752,8 @@ void log_stderr(const char *str, ...)
611 va_end(args); 752 va_end(args);
612} 753}
613 754
614int main(int argc, char **argv) 755int
756main(int argc, char **argv)
615{ 757{
616 int parse_error; 758 int parse_error;
617 args_t args; 759 args_t args;

Generated with cgit - Back to sebastiano.tronto.net