diff --git a/pkmn.c b/pkmn.c index 372421f..767bc7c 100644 --- a/pkmn.c +++ b/pkmn.c @@ -1,5 +1,11 @@ +#define SHINEY_PROB 8192 + #include #include +#include +#include +#include +#include const char *argp_program_version = "pkmn 1.0"; @@ -16,10 +22,8 @@ static char args_doc[] = "pokemon_name"; /* The options we understand. */ static struct argp_option options[] = { {"random", 'r', 0, 0, "Use a random pokemon"}, - {"shiney", 'S', 0, 0, "Use a shiney pokemon"}, + {"shiney", 's', 0, 0, "Use a shiney pokemon"}, {"verbose", 'v', 0, 0, "Produce verbose output" }, - {"quiet", 'q', 0, 0, "Don't produce any output" }, - {"silent", 's', 0, OPTION_ALIAS }, { 0 } }; @@ -41,18 +45,13 @@ parse_opt (int key, char *arg, struct argp_state *state) switch (key) { - case 'q': case 's': - arguments->silent = 1; - break; case 'v': arguments->verbose = 1; break; case 'r': - printf("Random pokemon\n"); arguments->random = 1; break; - case 'S': - printf("Shiney pokemon\n"); + case 's': arguments->shiney = 1; break; @@ -80,16 +79,67 @@ parse_opt (int key, char *arg, struct argp_state *state) /* Our argp parser. */ static struct argp argp = { options, parse_opt, args_doc, doc }; + +int pkmn_name_from_file(char *pokemon_file, char *pokemon_name) { + + int BUFFER_SIZE = 512; + + // A file is of the form "[S_][0-9][0-9][0-9]_pokemon.cow" + // We want to write the pokemon name in pokemon_name + // Using regex: s/^[S_]*[0-9]*_//g + // char *pokemon_file = "843_silicobra.cow"; + char regex_pattern[] = "^[0-9]+_(([a-zA-Z]|-)+)\\.cow$"; // Regex pattern to match the Pokémon name + regex_t regex; + regmatch_t matches[100]; + char match_buffer[BUFFER_SIZE]; + int ret; + + // Compile the regular expression + ret = regcomp(®ex, regex_pattern, REG_EXTENDED); + if (ret != 0) { + fprintf(stderr, "Failed to compile regex\n"); + return 1; + } + + // Execute the regular expression + ret = regexec(®ex, pokemon_file, 100, matches, 0); + if (ret == 0) { + // Extract the matched substring + int start = matches[1].rm_so; + int end = matches[1].rm_eo; + int match_length = end - start; + if (match_length < BUFFER_SIZE - 1) { + strncpy(match_buffer, pokemon_file + start, match_length); + match_buffer[match_length] = '\0'; + strcpy(pokemon_name, match_buffer); + } else { + fprintf(stderr, "Match too long for buffer\n"); + } +} else if (ret == REG_NOMATCH) { + fprintf(stderr, "No match found\n"); +} else { + fprintf(stderr, "Regex match failed\n"); + } + + // Free the regex memory + regfree(®ex); + + return 0; +} + int main (int argc, char **argv) { struct arguments arguments; char pkmn_path[] = "~/pokemons/"; /* Default values. */ - arguments.silent = 0; arguments.verbose = 0; arguments.random = 0; arguments.shiney = 0; + // A pokemon has a 1/SHINEY_PROB chance of being shiney + srand(time(NULL)); + arguments.shiney = (rand() % SHINEY_PROB) == 0; + /* Parse our arguments; every option seen by parse_opt will be reflected in arguments. */ argp_parse (&argp, argc, argv, 0, 0, &arguments); @@ -97,36 +147,52 @@ int main (int argc, char **argv) { if (arguments.verbose) { printf("ARG1 = %s\n", arguments.args[0]); printf("VERBOSE = %s\n", arguments.verbose ? "yes" : "no"); - printf("SILENT = %s\n", arguments.silent ? "yes" : "no"); printf("RANDOM = %s\n", arguments.random ? "yes" : "no"); printf("SHINEY = %s\n", arguments.shiney ? "yes" : "no"); } - // If random flag is set, roll a random pokemon - // Pokemons are located in ~/pokemons/ - char pokemon[512]; + char pokemon_file[512]; if (arguments.random) { system("ls ~/pokemons/yes | shuf -n 1 > /tmp/pkmn"); FILE *f = fopen("/tmp/pkmn", "r"); - fscanf(f, "%s", pokemon); + fscanf(f, "%s", pokemon_file); fclose(f); - printf("Random pokemon: %s\n", pokemon); - } - - // Then we can use the pokemon name to display it - // echo "$pokemon_name!" | cowsay -f "$cow_file" -W 70 - char command[512]; - if (arguments.random) { - sprintf(command, "echo \"%s!\" | cowsay -f ~/pokemons/yes/%s -W 70", pokemon, pokemon); + if (arguments.verbose) { + printf("Random pokemon: %s\n", pokemon_file); + } } else { - sprintf(command, "echo \"%s!\" | cowsay -f %s -W 70", arguments.args[0], "pikachu"); + // TODO + exit(EXIT_FAILURE); + sprintf(pokemon_file, "%s%s", pkmn_path, arguments.args[0]); } - printf("Command: %s\n", command); - - if (!arguments.silent) { - system(command); + if (arguments.shiney) { + // Append "S_" at the beginning of the file + char tmp[512]; + sprintf(tmp, "S_%s", pokemon_file); + sprintf(pokemon_file, "%s", tmp); + if (arguments.verbose) { + printf("Shiney pokemon: %s\n", pokemon_file); + } } - exit(0); + // Extract the pokemon name from the file + char pokemon_name[512]; + pkmn_name_from_file(pokemon_file, pokemon_name); + if (arguments.verbose) { + printf("Pokemon file: %s\n", pokemon_file); + printf("Pokemon name: %s\n", pokemon_name); + } + + // Execute the command echo "$pokemon_name!" | cowsay -f "$cow_file" -W 70 + char command[1024]; + if (arguments.shiney) { + sprintf(command, "echo \"Shiny %s!\" | cowsay -f %s%s -W 70", pokemon_name, pkmn_path, pokemon_file); + } else { + sprintf(command, "echo \"%s!\" | cowsay -f %syes/%s -W 70", pokemon_name, pkmn_path, pokemon_file); + } + system(command); + + + exit(EXIT_SUCCESS); } \ No newline at end of file