浏览代码

feat: 添加tty的检查

SongZihuan 3 年之前
父节点
当前提交
5f3825ef36
共有 6 个文件被更改,包括 60 次插入17 次删除
  1. 1 0
      include/core/env.h
  2. 7 0
      include/main.h
  3. 4 0
      src/core/env.c
  4. 13 12
      src/main.c
  5. 8 1
      src/runtime/aFunlang.c
  6. 27 4
      src/tool/stdio_.c

+ 1 - 0
include/core/env.h

@@ -112,6 +112,7 @@ AFUN_CORE_EXPORT FileLine getActivityLine(af_Environment *env);
 AFUN_CORE_EXPORT af_VarSpaceListNode *getRunVarSpaceList(af_Environment *env);
 AFUN_CORE_EXPORT int isCoreExit(af_Environment *env);
 AFUN_CORE_EXPORT bool getErrorStd(af_Environment *env);
+AFUN_CORE_EXPORT int32_t getCoreExitCode(af_Environment *env);
 
 /* 消息 属性访问 */
 AFUN_CORE_EXPORT af_Object *getMsgNormalData(af_Message *msg);

+ 7 - 0
include/main.h

@@ -1,6 +1,13 @@
 #ifndef AFUN_MAIN_H
 #define AFUN_MAIN_H
 
+#ifdef aFunWIN32_NO_CYGWIN
+#include <io.h>
+#define isatty _isatty
+#else
+#include "unistd.h"
+#endif
+
 extern char *base_path;
 extern Logger *aFunlangLogger;
 

+ 4 - 0
src/core/env.c

@@ -1916,4 +1916,8 @@ int isCoreExit(af_Environment *env) {
 
 bool getErrorStd(af_Environment *env) {
     return env->core->error_std->num;  // true-stderr, false-stdout
+}
+
+int32_t getCoreExitCode(af_Environment *env) {
+    return env->core->exit_code_->num;
 }

+ 13 - 12
src/main.c

@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "aFun.h"
+#include "main.h"
 #include "main_run.h"
 #include "main_build.h"
 
@@ -44,6 +45,7 @@ static int mainBuild(ff_FFlags *ff);
 char *base_path = NULL;
 static Logger aFunlangLogger_;
 Logger *aFunlangLogger = &aFunlangLogger_;
+static bool tty_stdin = false;
 
 void freeBaseName(void) {
     free(base_path);
@@ -51,6 +53,7 @@ void freeBaseName(void) {
 
 int main(int argc, char **argv) {
     jmp_buf main_buf;
+    tty_stdin = isatty(fileno(stdin));
     base_path = getExedir(1);
     if (base_path == NULL)
         goto INIT_ERROR;
@@ -76,7 +79,7 @@ INIT_ERROR:
 
     initLogger(aFunlangLogger, "aFunlang-exe", info.level);
     aFunlangLogger->buf = &main_buf;
-    writeDebugLog(aFunlangLogger, "aFunlang-exe init success");
+    writeDebugLog(aFunlangLogger, "aFunlang-exe init success: %s", (tty_stdin ? "tty" : "no-tty"));
 
     int exit_code = EXIT_SUCCESS;
     ff_FFlags *ff = ff_initFFlags(argc, argv, true, false, stderr, aFunlang_exe);
@@ -171,6 +174,8 @@ static int mainRun(ff_FFlags *ff) {
 
     if (argc == 0) {
         /* 进入命令行模式 */
+        if (!tty_stdin)
+            return 0;
         env = creatAFunEnvironment(0, NULL);
         printWelcomeInfo();
         do {
@@ -180,7 +185,8 @@ static int mainRun(ff_FFlags *ff) {
                 break;
             }
             exit_code = runCodeFromStdin("stdin", env);
-        } while (isCoreExit(env) != 1);  // exit_code == -1 表示stdin出现错误
+        } while (exit_code == 0 && isCoreExit(env) != 1);  // exit_code == -1 表示stdin出现错误
+        exit_code = getCoreExitCode(env);
         destructAFunEnvironment(env);
     } else {
         env = creatAFunEnvironment(argc - 1, argv + 1);
@@ -189,10 +195,7 @@ static int mainRun(ff_FFlags *ff) {
     }
 
     undefRunEnv(&ri);
-    if (exit_code != 0)
-        writeErrorLog(aFunlangLogger, "aFun exit code: %d", exit_code);
-    else
-        writeInfoLog(aFunlangLogger, "aFun exit code: %d", exit_code);
+    writeInfoLog(aFunlangLogger, "aFun exit code: %d", exit_code);
     printf_stdout(0, "aFun %s: %d\n", HT_aFunGetText(exit_code_n, "exit code"), exit_code);
 
     return exit_code;
@@ -279,7 +282,7 @@ static int mainCL(ff_FFlags *ff) {
     if (rl != NULL)
         exit_code = runCodeFromRunList(rl, NULL, save_aub, env);
 
-    if (command_line && isCoreExit(env) != 1) {
+    if (tty_stdin && command_line && isCoreExit(env) != 1) {
         printWelcomeInfo();
         do {
             if (ferror(stdin) || feof(stdin)) {  // 错误应在实际程序中处理, 若在此仍处于错误状态则直接返回
@@ -288,13 +291,11 @@ static int mainCL(ff_FFlags *ff) {
                 break;
             }
             exit_code = runCodeFromStdin("stdin", env);
-        } while (isCoreExit(env) != 1);
+        } while (exit_code == 0 && isCoreExit(env) != 1);
     }
 
-    if (exit_code != 0)
-        writeErrorLog(aFunlangLogger, "aFun exit code: %d", exit_code);
-    else
-        writeInfoLog(aFunlangLogger, "aFun exit code: %d", exit_code);
+    exit_code = getCoreExitCode(env);
+    writeInfoLog(aFunlangLogger, "aFun exit code: %d", exit_code);
     printf_stdout(0, "aFun %s: %d\n", HT_aFunGetText(exit_code_n, "exit code"), exit_code);
 
     undefRunEnv(&ri);

+ 8 - 1
src/runtime/aFunlang.c

@@ -2,6 +2,13 @@
 #include "__aFunlang.h"
 #include "__env.h"
 
+#ifdef aFunWIN32_NO_CYGWIN
+#include <io.h>
+#define isatty _isatty
+#else
+#include "unistd.h"
+#endif
+
 static int runCode_(FilePath name, af_Parser *parser, int mode, FilePath save_path, af_Environment *env);
 static bool aFunInit_mark = false;
 
@@ -162,7 +169,7 @@ int runCodeFromFileSource(FilePath file, bool save_afb, FilePath save_path, int
  * 目标: 运行stdin的程序 (源码形式)
  */
 int runCodeFromStdin(char *name, af_Environment *env){
-    if (env == NULL || CLEAR_STDIN() || !aFunInit_mark)  // ferror在feof前执行
+    if (env == NULL || CLEAR_STDIN() || !aFunInit_mark || !isatty(fileno(stdin)))  // ferror在feof前执行
         return -1;
 
     if (name == NULL)

+ 27 - 4
src/tool/stdio_.c

@@ -21,6 +21,7 @@
 #pragma warning(disable : 5105)  // 关闭 5105 的警告输出 (Windows.h中使用)
 #endif
 #include <conio.h>
+#include <io.h>
 #include <Windows.h>
 // 获取CodePage, 并将内存中utf-8字符串转换为对应编码输出
 // cygwin环境下, 终端默认为uft-8
@@ -54,6 +55,14 @@ int fgets_stdin(char **dest, int len) {
     char *wstr = calloc(len, sizeof(char));
     int re = 0;
 
+    if (!_isatty(fileno(stdin))) {
+        *dest = NEW_STR(len);
+        re = fgets(*dest, len, stdin) != NULL;
+        if (!re)
+            free(*dest);
+        return re;
+    }
+
     UINT code_page = GetConsoleCP();
     if (fgets(wstr, len, stdin) != NULL)
         re = convertMultiByte(dest, wstr, code_page, CP_UTF8);
@@ -86,6 +95,8 @@ int fungetc_stdin(int ch) {
  * 无内容则返回false
  */
 bool checkStdin(void) {
+    if (!_isatty(fileno(stdin)))
+        return true;
     if (!stdin_empty)
         return true;
     return _kbhit();
@@ -104,11 +115,17 @@ static int fputs_std_(char *str, FILE *std) {
 }
 
 int fputs_stdout(char *str) {
-    return fputs_std_(str, stdout);
+    if (_isatty(fileno(stdout)))
+        return fputs_std_(str, stdout);
+    fputs(str, stdout);
+    return 1;
 }
 
 int fputs_stderr(char *str) {
-    return fputs_std_(str, stderr);
+    if (_isatty(fileno(stderr)))
+        return fputs_std_(str, stderr);
+    fputs(str, stderr);
+    return 1;
 }
 
 static size_t vprintf_std_(FILE *std, size_t buf_len, char *format, va_list ap) {
@@ -124,11 +141,15 @@ static size_t vprintf_std_(FILE *std, size_t buf_len, char *format, va_list ap)
 }
 
 size_t vprintf_stdout(size_t buf_len, char *format, va_list ap) {
-    return vprintf_std_(stdout, buf_len, format, ap);
+    if (_isatty(fileno(stdout)))
+        return vprintf_std_(stdout, buf_len, format, ap);
+    return vfprintf(stdout, format, ap);
 }
 
 size_t vprintf_stderr(size_t buf_len, char *format, va_list ap) {
-    return vprintf_std_(stderr, buf_len, format, ap);
+    if (_isatty(fileno(stderr)))
+        return vprintf_std_(stderr, buf_len, format, ap);
+    return vfprintf(stderr, format, ap);
 }
 
 size_t printf_stdout(size_t buf_len, char *format, ...) {
@@ -170,6 +191,8 @@ int fgets_stdin(char **dest, int len) {
  * 参考自: https://gist.github.com/SuperH-0630/a4190b89d21c349a8d6882ca71453ae6
  */
 bool checkStdin(void) {
+    if (!isatty(fileno(stdin)))
+        return true;
     bool re = false;
 
     int oldf = fcntl(STDIN_FILENO, F_GETFL, 0);