main.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <getopt.h>
  4. #include <string.h>
  5. #include "brainfuck.h"
  6. #define COMMAND_LINE_STR_SIZE (20)
  7. static struct option long_options[] = {
  8. {"version", no_argument, 0, 'v'},
  9. {"help", no_argument, 0, 'h'},
  10. {"eval", required_argument, 0, 'e'},
  11. {0, 0, 0, 0}
  12. };
  13. void printUsage(char *name) {
  14. printf("Usage: %s[options] file..\n", name);
  15. printf("Options: \n");
  16. printf(" -e --eval\t\tRun code in a string\n");
  17. printf(" -v --version\t\tshow version\n");
  18. printf(" -h --help\t\tshow help\n\n");
  19. printf("\nFor more information, please see: \n");
  20. printf("github.com/SuperH-0630/BranchFuckPro\n");
  21. }
  22. void printVersion() {
  23. printf("%s", bf_getVersionInfo());
  24. }
  25. int runFile(int argc, char **argv, bf_env *env) {
  26. while (optind < argc) {
  27. FILE *file = fopen(argv[optind], "r");
  28. if (file == NULL) {
  29. perror("read file error");
  30. return 1;
  31. }
  32. bf_code code;
  33. code = bf_parserBrainFuck_File(file);
  34. bf_runBrainFuck(code, env);
  35. bf_printError("run error", env);
  36. bf_initEnv(env);
  37. bf_freeBrainFuck(code);
  38. fclose(file);
  39. optind++;
  40. }
  41. return 0;
  42. }
  43. int runCommandLine_(bf_env *env) {
  44. int size = COMMAND_LINE_STR_SIZE;
  45. int status;
  46. char *str = calloc(size + 1, sizeof(char ));
  47. fgets(str, COMMAND_LINE_STR_SIZE + 1, stdin);
  48. while (!strchr(str, '\n') && !feof(stdin) && !ferror(stdin)) {
  49. char *new = calloc(size + COMMAND_LINE_STR_SIZE + 1, sizeof(char ));
  50. strcpy(new, str);
  51. fgets(new + size, COMMAND_LINE_STR_SIZE + 1, stdin);
  52. free(str);
  53. str = new;
  54. size += COMMAND_LINE_STR_SIZE;
  55. }
  56. bf_code code;
  57. code = bf_parserBrainFuck_Str(str);
  58. status = bf_runBrainFuck(code, env);
  59. bf_printError("command line error", env);
  60. bf_freeBrainFuck(code);
  61. free(str);
  62. return status;
  63. }
  64. int runCommandLine(bf_env *env) {
  65. int ch;
  66. unsigned int count = 0;
  67. printf("BranchFuck %s (" __DATE__ ", " __TIME__ ")\n", bf_getVersion());
  68. printf("Welcome to ues BranchFuck CommandLine (Type 'q' to quit)\n");
  69. while (1) {
  70. if (feof(stdin) || ferror(stdin))
  71. return 1;
  72. printf("[%d] >", count);
  73. ch = getc(stdin);
  74. if (ch == 'q')
  75. return 0;
  76. else
  77. ungetc(ch, stdin);
  78. runCommandLine_(env);
  79. count++;
  80. }
  81. }
  82. int main(int argc, char **argv){
  83. int option_index = 0;
  84. int status;
  85. bf_env *env = bf_setEnv();
  86. while (1) {
  87. option_index = 0;
  88. int c = getopt_long (argc, argv, "vhe:", long_options, &option_index);
  89. if (c == -1)
  90. break;
  91. switch (c) {
  92. case 0:
  93. break;
  94. case 'h':
  95. printUsage(argv[0]);
  96. return 0;
  97. case 'v':
  98. printVersion();
  99. return 0;
  100. case 'e': {
  101. bf_code code;
  102. code = bf_parserBrainFuck_Str((char *) optarg);
  103. bf_runBrainFuck(code, env);
  104. bf_printError("eval error", env);
  105. bf_freeBrainFuck(code);
  106. break;
  107. }
  108. default:
  109. case '?':
  110. printUsage(argv[0]);
  111. return 1;
  112. }
  113. }
  114. status = runFile(argc, argv, env);
  115. if (status != 0)
  116. return status;
  117. status = runCommandLine(env);
  118. if (status == 1) {
  119. printf("stdin error\n");
  120. return status;
  121. }
  122. printf("BranchFuckPro: bye~\n");
  123. return 0;
  124. }