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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <values.h>
#include "config.h"
#define DEFAULT_COUNT 10000
#define MINIMUM_COUNT 1
#define MAXIMUM_COUNT 100000000
#define DEFAULT_THRESH 0.000001
#ifdef MINFLOAT
#define MINIMUM_THRESH MINFLOAT
#else
#define MINIMUM_THRESH 0.0000001
#endif
#define MAXIMUM_THRESH 0.01
extern int yyparse();
extern FILE *yyin;
int cmd_parse_tree = 0;
int cmd_roll = 0;
int cmd_rolleval = 0;
int cmd_calc = 0;
int cmd_count = DEFAULT_COUNT;
float cmd_threshold = DEFAULT_THRESH;
extern char *filename;
static struct option long_options[] =
{
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"print-tree", no_argument, 0, 'p'},
{"roll", no_argument, 0, 'r'},
{"eval", no_argument, 0, 'e'},
{"calc", no_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{"count", required_argument, 0, 'n'},
{"threshold", required_argument, 0, 't'},
{0, 0, 0, 0}
};
void usage() {
fprintf(stderr, "Usage: dicelab [options] [-f <file>]\n"
"Options:\n"
" --help -h -? print this text\n"
" --version -v print the program version\n"
" --print-tree -p print the parse tree (for debugging)\n"
" --eval -e evaluate the statistical distribution by\n"
" re-rolling\n"
" --calc -c calculate the distribution\n"
" --count -n specify the number of rolls used with --eval\n"
" default is %i\n"
" --roll -r roll the dice as specified, will also be used\n"
" if no other action is requested\n"
" --threshold -t cutoff threshold, results with a probability less\n"
" than this value will be discarded by some operations\n"
" when using --calc\n"
"File:\n"
" --file -f read the dice rolling specs from the file\n"
" specified, use stdin if not supplied\n\n",
DEFAULT_COUNT);
};
void splitargv(int argc, char *argv[], int *margc, char ***margv) {
*margc = 0;
*margv = NULL;
int i;
for (i = 0; i < argc; i++) {
char *tok;
int first = 1;
while ((tok = strtok(first ? argv[i] : NULL, " ")) != NULL) {
first = 0;
(*margc)++;
*margv = (char**)realloc(*margv, sizeof(char*) * (*margc));
(*margv)[(*margc)-1] = tok;
}
}
}
int main(int argc, char *argv[]) {
srand(time(NULL));
char *fname = NULL;
int option_index = 0;
int c;
int margc;
char **margv;
splitargv(argc, argv, &margc, &margv);
while (1) {
c = getopt_long(margc, margv, "?hvprecn:f:t:",
long_options, &option_index);
if (c == -1) {
break;
}
switch(c) {
case 'v':
printf("%s v%s by %s\n", PACKAGE_NAME, PACKAGE_VERSION,
PACKAGE_BUGREPORT);
return 0;
break;
case 'p':
cmd_parse_tree = 1;
break;
case 'r':
cmd_roll = 1;
break;
case 'e':
cmd_rolleval = 1;
break;
case 'c':
cmd_calc = 1;
break;
case 'n':
// XXX checl atoi and atof for errors (e.g. param not a number)
cmd_count = atoi(optarg);
if (cmd_count < MINIMUM_COUNT) {
fprintf(stderr, "Value for --count too low, adjusted to %i\n", MINIMUM_COUNT);
cmd_count = MINIMUM_COUNT;
}
if (cmd_count > MAXIMUM_COUNT) {
fprintf(stderr, "Value for --count too high, adjusted to %i\n", MAXIMUM_COUNT);
cmd_count = MAXIMUM_COUNT;
}
break;
case 't':
cmd_threshold = atof(optarg);
if (cmd_threshold < MINIMUM_THRESH) {
fprintf(stderr, "Value for --threshold too low, adjusted\n");
cmd_threshold = MINIMUM_THRESH;
}
if (cmd_threshold > MAXIMUM_THRESH) {
fprintf(stderr, "Value for --threshold too high, adjusted to %f\n", MAXIMUM_THRESH);
cmd_threshold = MAXIMUM_THRESH;
}
break;
case 'f':
fname = (char*)malloc((strlen(optarg)+1)*sizeof(char));
filename = fname;
strcpy(fname, optarg);
break;
default:
usage();
return 1;
}
}
if (optind < margc) {
fprintf(stderr, "useless argument \"%s\"\n", margv[optind]);
usage();
return 1;
}
if ((cmd_parse_tree == 0) && (cmd_roll == 0) && (cmd_rolleval == 0)
&& (cmd_calc == 0)) {
cmd_roll = 1;
}
// clean up the cmdline parsing
free(margv);
margv = NULL;
yyin = stdin;
if (fname) {
yyin = fopen(fname, "r");
if (yyin == NULL) {
fprintf(stderr, "Could not open file \"%s\": %s\n", fname,
strerror(errno));
free(fname);
return 1;
}
}
yyparse();
if(fname) {
free(fname);
}
return 0;
}
|