shell-test.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdint.h>
  4. #ifdef _MSC_VER
  5. #include <Windows.h>
  6. #define usleep(usecs) Sleep(usecs/1000)
  7. #else
  8. #include <unistd.h>
  9. #endif
  10. static void flush_wait(void)
  11. {
  12. fflush(NULL);
  13. usleep(10*1000); // Wait 10 ms.
  14. }
  15. static void help(void)
  16. {
  17. puts("Fake shell");
  18. puts("");
  19. puts("Usage:");
  20. puts(" shell-test --help");
  21. puts(" Prints this help to stdout.");
  22. puts(" shell-test");
  23. puts(" shell-test EXE");
  24. puts(" Prints \"ready $ \" to stderr.");
  25. puts(" shell-test -t {prompt text}");
  26. puts(" Prints \"{prompt text} $ \" to stderr.");
  27. puts(" shell-test EXE \"prog args...\"");
  28. puts(" Prints \"ready $ prog args...\\n\" to stderr.");
  29. puts(" shell-test -t {prompt text} EXE \"prog args...\"");
  30. puts(" Prints \"{prompt text} $ progs args...\" to stderr.");
  31. puts(" shell-test REP N {text}");
  32. puts(" Prints \"{lnr}: {text}\\n\" to stdout N times, taking N milliseconds.");
  33. puts(" Example:");
  34. puts(" shell-test REP 97 \"foo bar\"");
  35. puts(" 0: foo bar");
  36. puts(" ...");
  37. puts(" 96: foo bar");
  38. puts(" shell-test INTERACT");
  39. puts(" Prints \"interact $ \" to stderr, and waits for \"exit\" input.");
  40. puts(" shell-test EXIT {code}");
  41. puts(" Exits immediately with exit code \"{code}\".");
  42. }
  43. int main(int argc, char **argv)
  44. {
  45. if (argc == 2 && strcmp(argv[1], "--help") == 0) {
  46. help();
  47. }
  48. #ifdef _MSC_VER
  49. SetConsoleOutputCP(CP_UTF8);
  50. #endif
  51. if (argc >= 2) {
  52. if (strcmp(argv[1], "-t") == 0) {
  53. if (argc < 3) {
  54. fprintf(stderr,"Missing prompt text for -t option\n");
  55. return 5;
  56. } else {
  57. fprintf(stderr, "%s $ ", argv[2]);
  58. if (argc >= 5 && (strcmp(argv[3], "EXE") == 0)) {
  59. fprintf(stderr, "%s\n", argv[4]);
  60. }
  61. }
  62. } else if (strcmp(argv[1], "EXE") == 0) {
  63. fprintf(stderr, "ready $ ");
  64. if (argc >= 3) {
  65. fprintf(stderr, "%s\n", argv[2]);
  66. }
  67. } else if (strcmp(argv[1], "REP") == 0) {
  68. if (argc != 4) {
  69. fprintf(stderr, "REP expects exactly 3 arguments\n");
  70. return 4;
  71. }
  72. int count = 0;
  73. if (sscanf(argv[2], "%d", &count) != 1) {
  74. fprintf(stderr, "Invalid count: %s\n", argv[2]);
  75. return 4;
  76. }
  77. for (int i = 0; i < count; i++) {
  78. printf("%d: %s\n", i, argv[3]);
  79. if (i % 100 == 0) {
  80. usleep(1000); // Wait 1 ms (simulate typical output).
  81. }
  82. fflush(NULL);
  83. }
  84. } else if (strcmp(argv[1], "UTF-8") == 0) {
  85. // test split-up UTF-8 sequence
  86. printf("\xc3"); flush_wait();
  87. printf("\xa5\n"); flush_wait();
  88. // split up a 2+2 grapheme clusters all possible ways
  89. printf("ref: \xc3\xa5\xcc\xb2\n"); flush_wait();
  90. printf("1: \xc3"); flush_wait();
  91. printf("\xa5\xcc\xb2\n"); flush_wait();
  92. printf("2: \xc3\xa5"); flush_wait();
  93. printf("\xcc\xb2\n"); flush_wait();
  94. printf("3: \xc3\xa5\xcc"); flush_wait();
  95. printf("\xb2\n"); flush_wait();
  96. } else if (strcmp(argv[1], "INTERACT") == 0) {
  97. char input[256];
  98. char cmd[100];
  99. int arg;
  100. while (1) {
  101. fprintf(stderr, "interact $ ");
  102. if (fgets(input, sizeof(input), stdin) == NULL) {
  103. break; // EOF
  104. }
  105. if(1 == sscanf(input, "%99s %d", cmd, &arg)) {
  106. arg = 0;
  107. }
  108. if (strcmp(cmd, "exit") == 0) {
  109. return arg;
  110. } else {
  111. fprintf(stderr, "command not found: %s\n", cmd);
  112. }
  113. }
  114. } else if (strcmp(argv[1], "EXIT") == 0) {
  115. int code = 1;
  116. if (argc >= 3) {
  117. if (sscanf(argv[2], "%d", &code) != 1) {
  118. fprintf(stderr, "Invalid exit code: %s\n", argv[2]);
  119. return 2;
  120. }
  121. }
  122. return code;
  123. } else {
  124. fprintf(stderr, "Unknown first argument: %s\n", argv[1]);
  125. return 3;
  126. }
  127. fflush(NULL);
  128. return 0;
  129. } else if (argc == 1) {
  130. fprintf(stderr, "ready $ ");
  131. return 0;
  132. } else {
  133. fprintf(stderr, "Missing first argument\n");
  134. return 2;
  135. }
  136. }