dice.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #define _GNU_SOURCE 1 // Needed to avoid various "implicit function declaration" warnings/errors.
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <readline/readline.h>
  6. #include "args.h"
  7. #include "parse.h"
  8. #include "io.h"
  9. int main(int argc, char** argv) {
  10. struct arguments args;
  11. args.prompt = "\001\e[0;32m\002dice> \001\e[0m\002";
  12. if(isatty(fileno(stdin))) {
  13. args.mode = INTERACTIVE;
  14. } else {
  15. args.mode = PIPE;
  16. }
  17. args.ist = stdin;
  18. FILE *rnd_src;
  19. char rnd_src_path[] = "/dev/urandom";
  20. rnd_src = fopen(rnd_src_path, "r");
  21. args.seed_set = false;
  22. if(rnd_src) {
  23. int fread_num_items = fread(&args.seed, sizeof(args.seed), 1, rnd_src);
  24. if(fread_num_items > 0) {
  25. args.seed_set = true;
  26. }
  27. fclose(rnd_src);
  28. }
  29. argp_parse(&argp, argc, argv, 0, 0, &args);
  30. if(!args.seed_set) {
  31. fprintf(stderr, "Problem opening %s for reading and/or seed not given, falling back to a time-based random seed.\n", rnd_src_path);
  32. struct timespec t;
  33. clock_gettime(CLOCK_REALTIME, &t);
  34. args.seed = t.tv_nsec * t.tv_sec;
  35. }
  36. srandom(args.seed);
  37. struct parse_tree *t = malloc(sizeof(struct parse_tree));
  38. if(!t) {
  39. fprintf(stderr, "malloc error\n");
  40. exit(1);
  41. }
  42. parse_tree_initialise(t);
  43. char *histfile="~/.dice_history";
  44. void (*process_next_line)(struct parse_tree*, struct arguments*);
  45. switch(args.mode) {
  46. case INTERACTIVE:
  47. {
  48. read_history_wrapper(histfile);
  49. rl_bind_key('\t', rl_insert); // File completion is not relevant for this program
  50. process_next_line = &readline_wrapper;
  51. }
  52. break;
  53. case PIPE: case SCRIPTED:
  54. {
  55. process_next_line = &getline_wrapper;
  56. }
  57. break;
  58. default:
  59. process_next_line = &no_read;
  60. }
  61. do {
  62. process_next_line(t, &args);
  63. } while(!(t->quit || feof(args.ist)));
  64. if(args.mode == INTERACTIVE) {
  65. write_history_wrapper(histfile);
  66. }
  67. if(t) {
  68. parse_tree_reset(t);
  69. free(t);
  70. t = NULL;
  71. }
  72. return 0;
  73. }