瀏覽代碼

move hmain from cpputil to base

ithewei 4 年之前
父節點
當前提交
8c87a9415c
共有 11 個文件被更改,包括 118 次插入95 次删除
  1. 1 1
      Makefile.vars
  2. 1 0
      base/README.md
  3. 68 34
      base/hmain.c
  4. 19 13
      base/hmain.h
  5. 1 1
      cmake/vars.cmake
  6. 0 1
      cpputil/README.md
  7. 14 15
      docs/API.md
  8. 6 2
      examples/CMakeLists.txt
  9. 6 6
      examples/hmain_test.cpp
  10. 0 20
      examples/httpd/httpd.cpp
  11. 2 2
      examples/wrk.cpp

+ 1 - 1
Makefile.vars

@@ -23,6 +23,7 @@ BASE_HEADERS =  base/hplatform.h\
 				base/hssl.h\
 				base/hlog.h\
 				base/hbuf.h\
+				base/hmain.h\
 				base/hendian.h\
 
 SSL_HEADERS =   ssl/hssl.h
@@ -40,7 +41,6 @@ CPPUTIL_HEADERS = cpputil/hmap.h\
 				cpputil/hpath.h\
 				cpputil/hdir.h\
 				cpputil/hurl.h\
-				cpputil/hmain.h\
 				cpputil/hscope.h\
 				cpputil/hthreadpool.h\
 				cpputil/hobjectpool.h\

+ 1 - 0
base/README.md

@@ -11,6 +11,7 @@
 ├── hendian.h       大小端
 ├── herr.h          错误码表
 ├── hlog.h          日志
+├── hmain.h         命令行解析
 ├── hmath.h         数学函数
 ├── hmutex.h        线程同步锁
 ├── hplatform.h     平台相关宏

+ 68 - 34
cpputil/hmain.cpp → base/hmain.c

@@ -13,6 +13,58 @@
 
 main_ctx_t  g_main_ctx;
 
+static void init_arg_kv(int maxsize) {
+    g_main_ctx.arg_kv_size = 0;
+    SAFE_ALLOC(g_main_ctx.arg_kv, sizeof(char*) * maxsize);
+}
+
+static void save_arg_kv(const char* key, int key_len, const char* val, int val_len) {
+    if (key_len <= 0) key_len = strlen(key);
+    if (val_len <= 0) val_len = strlen(val);
+    char* arg = NULL;
+    SAFE_ALLOC(arg, key_len + val_len + 2);
+    memcpy(arg, key, key_len);
+    arg[key_len] = '=';
+    memcpy(arg + key_len + 1, val, val_len);
+    // printf("save_arg_kv: %s\n", arg);
+    g_main_ctx.arg_kv[g_main_ctx.arg_kv_size++] = arg;
+}
+
+static void init_arg_list(int maxsize) {
+    g_main_ctx.arg_list_size = 0;
+    SAFE_ALLOC(g_main_ctx.arg_list, sizeof(char*) * maxsize);
+}
+
+static void save_arg_list(const char* arg) {
+    // printf("save_arg_list: %s\n", arg);
+    g_main_ctx.arg_list[g_main_ctx.arg_list_size++] = strdup(arg);
+}
+
+static const char* get_val(char** kvs, const char* key) {
+    if (kvs == NULL) return NULL;
+    int key_len = strlen(key);
+    char* kv = NULL;
+    int kv_len = 0;
+    for (int i = 0; kvs[i]; ++i) {
+        kv = kvs[i];
+        kv_len = strlen(kv);
+        if (kv_len <= key_len) continue;
+        // key=val
+        if (memcmp(kv, key, key_len) == 0 && kv[key_len] == '=') {
+            return kv + key_len + 1;
+        }
+    }
+    return NULL;
+}
+
+const char* get_arg(const char* key) {
+    return get_val(g_main_ctx.arg_kv, key);
+}
+
+const char* get_env(const char* key) {
+    return get_val(g_main_ctx.save_envp, key);
+}
+
 int main_ctx_init(int argc, char** argv) {
     if (argc == 0 || argv == NULL) {
         argc = 1;
@@ -70,8 +122,8 @@ int main_ctx_init(int argc, char** argv) {
     SAFE_ALLOC(cmdline, g_main_ctx.arg_len);
     g_main_ctx.cmdline = cmdline;
     for (i = 0; argv[i]; ++i) {
+        strcpy(argp, argv[i]);
         g_main_ctx.save_argv[i] = argp;
-        strcpy(g_main_ctx.save_argv[i], argv[i]);
         argp += strlen(argv[i]) + 1;
 
         strcpy(cmdline, argv[i]);
@@ -100,16 +152,6 @@ int main_ctx_init(int argc, char** argv) {
         envp += strlen(environ[i]) + 1;
     }
     g_main_ctx.save_envp[g_main_ctx.envc] = NULL;
-
-    // parse env
-    for (i = 0; environ[i]; ++i) {
-        char* b = environ[i];
-        char* delim = strchr(b, '=');
-        if (delim == NULL) {
-            continue;
-        }
-        g_main_ctx.env_kv[std::string(b, delim-b)] = std::string(delim+1);
-    }
 #endif
 
     // signals
@@ -137,10 +179,14 @@ static int get_arg_type(int short_opt, const char* options) {
 }
 
 int parse_opt(int argc, char** argv, const char* options) {
+    if (argc < 1) return 0;
+    init_arg_kv(strlen(options) + 1);
+    init_arg_list(argc);
+
     for (int i = 1; argv[i]; ++i) {
         char* p = argv[i];
         if (*p != '-') {
-            g_main_ctx.arg_list.push_back(argv[i]);
+            save_arg_list(argv[i]);
             continue;
         }
         while (*++p) {
@@ -149,14 +195,14 @@ int parse_opt(int argc, char** argv, const char* options) {
                 printf("Invalid option '%c'\n", *p);
                 return -20;
             } else if (arg_type == NO_ARGUMENT) {
-                g_main_ctx.arg_kv[std::string(p, 1)] = OPTION_ENABLE;
+                save_arg_kv(p, 1, OPTION_ENABLE, 0);
                 continue;
             } else if (arg_type == REQUIRED_ARGUMENT) {
                 if (*(p+1) != '\0') {
-                    g_main_ctx.arg_kv[std::string(p, 1)] = p+1;
+                    save_arg_kv(p, 1, p+1, 0);
                     break;
                 } else if (argv[i+1] != NULL) {
-                    g_main_ctx.arg_kv[std::string(p, 1)] = argv[++i];
+                    save_arg_kv(p, 1, argv[++i], 0);
                     break;
                 } else {
                     printf("Option '%c' requires param\n", *p);
@@ -195,6 +241,10 @@ static const option_t* get_option(const char* opt, const option_t* long_options,
 #define SHORT_OPTION    -1
 #define LONG_OPTION     -2
 int parse_opt_long(int argc, char** argv, const option_t* long_options, int size) {
+    if (argc < 1) return 0;
+    init_arg_kv(size + 1);
+    init_arg_list(argc);
+
     char opt[MAX_OPTION+1] = {0};
     for (int i = 1; argv[i]; ++i) {
         char* arg = argv[i];
@@ -230,7 +280,7 @@ int parse_opt_long(int argc, char** argv, const option_t* long_options, int size
         const option_t* pOption = get_option(opt, long_options, size);
         if (pOption == NULL) {
             if (delim == NULL && opt_type == NOPREFIX_OPTION) {
-                g_main_ctx.arg_list.push_back(arg);
+                save_arg_list(arg);
                 continue;
             } else {
                 printf("Invalid option: '%s'\n", argv[i]);
@@ -260,30 +310,14 @@ int parse_opt_long(int argc, char** argv, const option_t* long_options, int size
         }
         // preferred to use short_opt as key
         if (pOption->short_opt > 0) {
-            g_main_ctx.arg_kv[std::string(1, pOption->short_opt)] = value;
+            save_arg_kv(&pOption->short_opt, 1, value, 0);
         } else if (pOption->long_opt) {
-            g_main_ctx.arg_kv[pOption->long_opt] = value;
+            save_arg_kv(pOption->long_opt, 0, value, 0);
         }
     }
     return 0;
 }
 
-const char* get_arg(const char* key) {
-    auto iter = g_main_ctx.arg_kv.find(key);
-    if (iter == g_main_ctx.arg_kv.end()) {
-        return NULL;
-    }
-    return iter->second.c_str();
-}
-
-const char* get_env(const char* key) {
-    auto iter = g_main_ctx.env_kv.find(key);
-    if (iter == g_main_ctx.env_kv.end()) {
-        return NULL;
-    }
-    return iter->second.c_str();
-}
-
 #ifdef OS_UNIX
 /*
  * memory layout

+ 19 - 13
cpputil/hmain.h → base/hmain.h

@@ -1,15 +1,17 @@
 #ifndef HV_MAIN_H_
 #define HV_MAIN_H_
 
+#include "hexport.h"
 #include "hplatform.h"
 #include "hdef.h"
-#include "hstring.h"
 #include "hproc.h"
 
 #ifdef _MSC_VER
 #pragma comment(lib, "winmm.lib") // for timeSetEvent
 #endif
 
+BEGIN_EXTERN_C
+
 typedef struct main_ctx_s {
     char    run_dir[MAX_PATH];
     char    program_name[MAX_PATH];
@@ -27,19 +29,21 @@ typedef struct main_ctx_s {
     char**  os_argv;
     char**  save_argv;
     char*   cmdline;
-    keyval_t        arg_kv;
-    hv::StringList  arg_list;
+    // parsed arg
+    int     arg_kv_size;
+    char**  arg_kv;
+    int     arg_list_size;
+    char**  arg_list;
 
     // env
     int     envc;
     int     env_len;
     char**  os_envp;
     char**  save_envp;
-    keyval_t    env_kv;
 
     // signals
-    procedure_t reload_fn;
-    void*       reload_userdata;
+    procedure_t     reload_fn;
+    void*           reload_userdata;
     // master workers model
     int             worker_processes;
     int             worker_threads;
@@ -55,8 +59,8 @@ typedef struct main_ctx_s {
 // option define
 #define OPTION_PREFIX   '-'
 #define OPTION_DELIM    '='
-#define OPTION_ENABLE   "on"
-#define OPTION_DISABLE  "off"
+#define OPTION_ENABLE   "1"
+#define OPTION_DISABLE  "0"
 typedef struct option_s {
     char        short_opt;
     const char* long_opt;
@@ -84,7 +88,7 @@ HV_EXPORT void  delete_pidfile();
 HV_EXPORT pid_t getpid_from_pidfile();
 
 // signal=[start,stop,restart,status,reload]
-HV_EXPORT int  signal_init(procedure_t reload_fn = NULL, void* reload_userdata = NULL);
+HV_EXPORT int  signal_init(procedure_t reload_fn DEFAULT(NULL), void* reload_userdata DEFAULT(NULL));
 HV_EXPORT void signal_handle(const char* signal);
 #ifdef OS_UNIX
 // we use SIGTERM to quit process, SIGUSR1 to reload confile
@@ -101,9 +105,11 @@ HV_EXPORT extern main_ctx_t   g_main_ctx;
 // master-workers processes
 HV_EXPORT int master_workers_run(
         procedure_t worker_fn,
-        void* worker_userdata = NULL,
-        int worker_processes = DEFAULT_WORKER_PROCESSES,
-        int worker_threads = 0,
-        bool wait = true);
+        void* worker_userdata DEFAULT(NULL),
+        int worker_processes DEFAULT(DEFAULT_WORKER_PROCESSES),
+        int worker_threads DEFAULT(0),
+        bool wait DEFAULT(true));
+
+END_EXTERN_C
 
 #endif // HV_MAIN_H_

+ 1 - 1
cmake/vars.cmake

@@ -16,6 +16,7 @@ set(BASE_HEADERS
     base/hsocket.h
     base/hlog.h
     base/hbuf.h
+    base/hmain.h
     base/hendian.h
 )
 
@@ -41,7 +42,6 @@ set(CPPUTIL_HEADERS
     cpputil/hpath.h
     cpputil/hdir.h
     cpputil/hurl.h
-    cpputil/hmain.h
     cpputil/hscope.h
     cpputil/hthreadpool.h
     cpputil/hobjectpool.h

+ 0 - 1
cpputil/README.md

@@ -4,7 +4,6 @@
 .
 ├── hdir.h          目录(ls实现)
 ├── hfile.h         文件类
-├── hmain.h         命令行解析
 ├── hobjectpool.h   对象池
 ├── hscope.h        作用域模板类
 ├── hstring.h       字符串操作

+ 14 - 15
docs/API.md

@@ -252,6 +252,20 @@
 - class HVLBuf
 - class HRingBuf
 
+### hmain.h
+- main_ctx_init
+- parse_opt
+- parse_opt_long
+- get_arg
+- get_env
+- setproctitle
+- signal_init
+- signal_handle
+- create_pidfile
+- delete_pidfile
+- getpid_form_pidfile
+- master_workers_run
+
 ### hstring.h
 - to_string
 - from_string
@@ -328,21 +342,6 @@
 - json::parse
 - json::dump
 
-### hmain.h
-- main_ctx_init
-- parse_opt
-- parse_opt_long
-- get_arg
-- get_env
-- setproctitle
-- signal_init
-- signal_handle
-- signal_handler
-- create_pidfile
-- delete_pidfile
-- getpid_form_pidfile
-- master_workers_run
-
 ### singleton.h
 - DISABLE_COPY
 - SINGLETON_DECL

+ 6 - 2
examples/CMakeLists.txt

@@ -7,7 +7,8 @@ list(APPEND EXAMPLES
     tcp_proxy_server
     udp_echo_server
     udp_proxy_server
-    jsonrpc
+    jsonrpc_client
+    jsonrpc_server
 )
 
 include_directories(.. ../base ../ssl ../event ../util)
@@ -44,9 +45,12 @@ target_link_libraries(jsonrpc_server ${HV_LIBRARIES})
 
 if(WITH_EVPP)
     include_directories(../cpputil ../evpp)
+
+    # hmain_test
     add_executable(hmain_test hmain_test.cpp)
     target_link_libraries(hmain_test ${HV_LIBRARIES})
 
+    # nmap
     glob_headers_and_sources(NMAP_FILES nmap)
     add_executable(nmap ${NMAP_FILES})
     target_compile_definitions(nmap PRIVATE PRINT_DEBUG)
@@ -60,6 +64,7 @@ if(WITH_HTTP)
     add_executable(wrk wrk.cpp)
     target_link_libraries(wrk ${HV_LIBRARIES})
 
+    list(APPEND EXAMPLES wrk)
 if(WITH_HTTP_SERVER)
     include_directories(../http/server)
 
@@ -120,5 +125,4 @@ endif()
 endif()
 endif()
 
-add_custom_target(jsonrpc DEPENDS jsonrpc_client jsonrpc_server)
 add_custom_target(examples DEPENDS ${EXAMPLES})

+ 6 - 6
examples/hmain_test.cpp

@@ -180,17 +180,17 @@ int main(int argc, char** argv) {
     /*
     printf("---------------arg------------------------------\n");
     printf("%s\n", g_main_ctx.cmdline);
-    for (auto& pair : g_main_ctx.arg_kv) {
-        printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
+    for (int i = 0; i < g_main_ctx.arg_kv_size; ++i) {
+        printf("%s\n", g_main_ctx.arg_kv[i]);
     }
-    for (auto& item : g_main_ctx.arg_list) {
-        printf("%s\n", item.c_str());
+    for (int i = 0; i < g_main_ctx.arg_list_size; ++i) {
+        printf("%s\n", g_main_ctx.arg_list[i]);
     }
     printf("================================================\n");
 
     printf("---------------env------------------------------\n");
-    for (auto& pair : g_main_ctx.env_kv) {
-        printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
+    for (int i = 0; i < g_main_ctx.envc; ++i) {
+        printf("%s\n", g_main_ctx.save_envp[i]);
     }
     printf("================================================\n");
     */

+ 0 - 20
examples/httpd/httpd.cpp

@@ -203,26 +203,6 @@ int main(int argc, char** argv) {
         exit(ret);
     }
 
-    /*
-    printf("---------------arg------------------------------\n");
-    printf("%s\n", g_main_ctx.cmdline);
-    for (auto& pair : g_main_ctx.arg_kv) {
-        printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
-    }
-    for (auto& item : g_main_ctx.arg_list) {
-        printf("%s\n", item.c_str());
-    }
-    printf("================================================\n");
-    */
-
-    /*
-    printf("---------------env------------------------------\n");
-    for (auto& pair : g_main_ctx.env_kv) {
-        printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
-    }
-    printf("================================================\n");
-    */
-
     // help
     if (get_arg("h")) {
         print_help();

+ 2 - 2
examples/wrk.cpp

@@ -190,11 +190,11 @@ int main(int argc, char** argv) {
         exit(ret);
     }
 
-    if (get_arg("h") || g_main_ctx.arg_list.size() != 1) {
+    if (get_arg("h") || g_main_ctx.arg_list_size != 1) {
         print_help();
         exit(0);
     }
-    url = g_main_ctx.arg_list[0].c_str();
+    url = g_main_ctx.arg_list[0];
 
     if (get_arg("v")) {
         verbose = true;