瀏覽代碼

refactor & feat: 基本可执行程序

SongZihuan 3 年之前
父節點
當前提交
10b5d871e9
共有 8 個文件被更改,包括 240 次插入30 次删除
  1. 25 30
      src/CMakeLists.txt
  2. 31 0
      src/__fflags.h
  3. 22 0
      src/__main.h
  4. 5 0
      src/main-build.cpp
  5. 5 0
      src/main-cl.cpp
  6. 63 0
      src/main-help.cpp
  7. 5 0
      src/main-run.cpp
  8. 84 0
      src/main.cpp

+ 25 - 30
src/CMakeLists.txt

@@ -28,33 +28,28 @@ add_subdirectory(core)  # core 依赖 tool
 add_subdirectory(runtime)  # runtime 依赖 core
 
 # source在子目录中被使用, 为了避免子目录访问到source, 子目录将在此前面被执行
-#file(GLOB source
-#     LIST_DIRECTORIES FALSE
-#     ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
-#
-#file(GLOB private_h
-#     LIST_DIRECTORIES FALSE
-#     ${CMAKE_CURRENT_LIST_DIR}/*.h)
-#
-#file(GLOB include_h
-#     LIST_DIRECTORIES FALSE
-#     "${PROJECT_SOURCE_DIR}/include/*.h")
-#
-#add_executable(aFun-xx "")  # xx表示均为动态链接
-#add_executable(aFun-ct "")  # ct表示均静态链接
-#set(aFunList aFun-xx aFun-ct)
-#
-#foreach(tgt IN LISTS aFunList)
-#    target_sources(${tgt} PRIVATE ${source} ${private_h} ${include_h})
-#    target_include_directories(${tgt} PRIVATE ${PROJECT_SOURCE_DIR}/include)
-#    set_target_properties(${tgt} PROPERTIES PUBLIC_HEADER "${include_h}")
-#    define_FILENAME(${tgt})
-#endforeach()
-#
-#target_link_libraries(aFun-xx PUBLIC rt-shared)
-#target_link_libraries(aFun-ct PUBLIC rt-static)
-#
-#install(TARGETS aFun-xx aFun-ct
-#        RUNTIME DESTINATION ${INSTALL_BINDIR} COMPONENT advanced-runtime
-#        PUBLIC_HEADER DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT dev
-#        PRIVATE_HEADER DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT advanced-dev)
+file(GLOB source
+     LIST_DIRECTORIES FALSE
+     ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
+
+file(GLOB private_h
+     LIST_DIRECTORIES FALSE
+     ${CMAKE_CURRENT_LIST_DIR}/*.h)
+
+add_executable(aFun-xx "")  # xx表示均为动态链接
+add_executable(aFun-ct "")  # ct表示均静态链接
+set(aFunList aFun-xx aFun-ct)
+
+foreach(tgt IN LISTS aFunList)
+    target_sources(${tgt} PRIVATE ${source} ${private_h} ${include_h})
+    target_include_directories(${tgt} PRIVATE ${PROJECT_SOURCE_DIR}/include)
+    define_FILENAME(${tgt})
+endforeach()
+
+target_link_libraries(aFun-xx PUBLIC rt-shared FFlags::fflags)
+target_link_libraries(aFun-ct PUBLIC rt-static FFlags::fflags)
+
+install(TARGETS aFun-xx aFun-ct
+        RUNTIME DESTINATION ${INSTALL_BINDIR} COMPONENT advanced-runtime
+        PUBLIC_HEADER DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT dev
+        PRIVATE_HEADER DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT advanced-dev)

+ 31 - 0
src/__fflags.h

@@ -0,0 +1,31 @@
+#ifndef AFUN_FFLAGS_H
+#define AFUN_FFLAGS_H
+#include "fflags.h"
+
+ff_defArg(help, false)
+        ff_argRule('h', help, not, 'h')
+        ff_argRule('v', version, not, 'v')
+ff_endArg(help, false);
+
+ff_selfProcessChild(run, true);
+
+ff_defArg(cl, false)
+        ff_argRule('e', eval, must, 'e')
+        ff_argRule('f', file, must, 'f')
+        ff_argRule('s', source, must, 's')
+        ff_argRule('b', byte, must, 'b')
+        ff_argRule(aFuntool::NUL, no-aub, not, 'a')
+        ff_argRule(aFuntool::NUL, no-cl, not, 'n')
+        ff_argRule(aFuntool::NUL, no-import, not, 'o')
+        ff_argRule(aFuntool::NUL, import, not, 'i')
+ff_endArg(cl, false);
+
+ff_defArg(build, false)
+        ff_argRule('o', out, must, 'o')
+        ff_argRule('p', path, must, 'p')
+        ff_argRule('f', fource, not, 'f')
+ff_endArg(build, false);
+
+ff_childList(aFunlang_exe, ff_child(run), ff_child(help), ff_child(cl), ff_child(build));
+
+#endif //AFUN_FFLAGS_H

+ 22 - 0
src/__main.h

@@ -0,0 +1,22 @@
+#ifndef AFUN_MAIN_H
+#define AFUN_MAIN_H
+#include "aFunrt.h"
+#include "fflags.h"
+
+void printError(ff_FFlags *ff);
+
+extern std::string program_name;
+extern std::string home_path;
+extern bool tty_stdin;
+
+int mainHelp(ff_FFlags *ff);
+
+void printVersion();
+void printWelcomeInfo();
+void printHelp();
+
+int mainRun(ff_FFlags *ff);
+int mainCL(ff_FFlags *ff);
+int mainBuild(ff_FFlags *ff);
+
+#endif //AFUN_MAIN_H

+ 5 - 0
src/main-build.cpp

@@ -0,0 +1,5 @@
+#include "__main.h"
+
+int mainBuild(ff_FFlags *ff) {
+    return 0;
+}

+ 5 - 0
src/main-cl.cpp

@@ -0,0 +1,5 @@
+#include "__main.h"
+
+int mainCL(ff_FFlags *ff) {
+    return 0;
+}

+ 63 - 0
src/main-help.cpp

@@ -0,0 +1,63 @@
+#include "__main.h"
+
+/*
+ * 函数名: printError
+ * 目标: 打印参数错误信息
+ */
+void printError(ff_FFlags *ff) {
+    errorLog(aFunrt::aFunLogger, "%s argument error", ff_getChild(ff));
+    aFuntool::cout << "Command line argument error (" << ff_getChild(ff) << ")\n";
+    printHelp();
+}
+
+void printVersion() {
+    /* Version的显示不被翻译, 因为它通常还需要被其他程序读取而进行处理, 必须保证一致性 */
+    aFuntool::cout << "aFunlang at      " << program_name << "\n";
+    aFuntool::cout << "aFunlang home at " << home_path << "\n";
+    aFuntool::cout << "version: " aFunVersion "\n";
+    aFuntool::cout << aFunDescription "\n";
+}
+
+void printWelcomeInfo() {
+    aFuntool::cout << "aFunlang " aFunVersion " CommandLine (" __DATE__ ", " __TIME__ ")\n";
+    aFuntool::cout << "[" compilerID "] on " systemName "\n";
+    aFuntool::cout << "(Enter the aFun code to run in the top activity)\n";
+}
+
+void printHelp() {
+    aFuntool::cout << "aFunlang Usage:\n";
+}
+
+int mainHelp(ff_FFlags *ff) {
+    char *text = nullptr;
+    int mark;
+    bool have_opt = false;
+    /* 无信号处理 */
+
+    while (true) {
+        mark = ff_getopt(&text, ff);
+
+        switch (mark) {
+            case 'h':
+                printHelp();
+                break;
+            case 'v':
+                printVersion();
+                break;
+            case -1:
+                goto out;
+            default:
+                printError(ff);
+                return EXIT_FAILURE;
+        }
+
+        have_opt = true;  // 表示有实际参数
+    }
+    out:
+    if (!have_opt) {
+        printHelp();
+        return EXIT_SUCCESS;
+    }
+
+    return EXIT_SUCCESS;
+}

+ 5 - 0
src/main-run.cpp

@@ -0,0 +1,5 @@
+#include "__main.h"
+
+int mainRun(ff_FFlags *ff) {
+    return 0;
+}

+ 84 - 0
src/main.cpp

@@ -0,0 +1,84 @@
+#include <cstdio>
+#include <cstdlib>
+#include "__main.h"
+#include "__fflags.h"
+
+std::string program_name;
+std::string home_path;
+bool tty_stdin = false;
+
+#ifdef aFunWIN32_NO_CYGWIN
+
+int argc_s = 0;
+char **argv_s = nullptr;
+
+static void convertArgs(int argc, char *argv_ansi[]) {
+    argc_s = argc;
+    argv_s = aFuntool::safeCalloc<char *>((size_t)argc);
+    for(int i = 0; i < argc; i++) {
+        if (aFuntool::convertMultiByte(argv_s + i, argv_ansi[i], CP_ACP, CP_UTF8) == 0) {
+            aFuntool::cerr << "Argument conversion error";
+            exit(EXIT_FAILURE);
+        }
+    }
+}
+
+static void convertArgsFree(void *) {
+    for(int i = 0; i < argc_s; i++)
+        free(argv_s[i]);
+    free(argv_s);
+}
+
+int main(int argc, char **argv_ansi) {
+    convertArgs(argc, argv_ansi);
+    aFuntool::aFunAtExit(convertArgsFree, nullptr);
+
+    char **argv = argv_s;
+#else
+    int main(int argc, char **argv) {
+#endif
+    tty_stdin = isatty(fileno(stdin));
+    home_path = aFuntool::getExedir(1);
+    if (home_path.empty()) {
+        aFuntool::cerr << "aFunlang init error.";
+        exit(EXIT_FAILURE);
+    }
+
+    try {
+        aFuntool::LogFactory factor{};
+        factor.initLogSystem(home_path + aFuntool::SEP + "aFunlog");
+
+#ifdef aFunDEBUG
+        aFunrt::aFunInitInfo info{home_path, factor, true, aFuntool::log_debug, aFuntool::log_debug};
+#else
+        aFunrt::aFunInitInfo info{base_path, factor, true, aFuntool::log_info, aFuntool::log_info};
+#endif
+
+        ff_FFlags *ff = ff_initFFlags(argc, argv, true, false, stderr, aFunlang_exe);
+        if (ff == nullptr)
+            aFuntool::aFunExit(EXIT_FAILURE);
+
+        if (!aFunInit(&info)) {
+            aFuntool::cerr << "aFunlang init error.";
+            aFuntool::aFunExit(EXIT_FAILURE);
+        }
+
+        int exit_code = EXIT_SUCCESS;
+        const char *child = ff_getChild(ff);
+        program_name = *argv;  // 获取第一个参数为name
+
+        if (!std::strcmp(child, "cl"))
+            exit_code = mainCL(ff);
+        else if (!std::strcmp(child, "build"))
+            exit_code = mainBuild(ff);
+        else if (!std::strcmp(child, "run"))
+            exit_code = mainRun(ff);
+        else
+            exit_code = mainHelp(ff);
+
+        ff_freeFFlags(ff);
+        aFuntool::aFunExit(exit_code);
+    } catch (aFuntool::Exit &e) {
+        return e.getExitCode();
+    }
+}