result_t console_base::readLine(const char *msg, std::string &retVal, exlib::AsyncEvent *ac) { #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); if (!_init) { _init = true; #ifdef MacOS void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else const char *readline_dylib_names[] = { "libreadline.so.6", "libreadline.so.5", "libreadline.so" }; const size_t readline_dylib_names_size = ARRAYSIZE(readline_dylib_names); void *handle = 0; for (size_t i = 0; i < readline_dylib_names_size; i++) { handle = dlopen(readline_dylib_names[i], RTLD_LAZY); if (handle) break; } #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } } #endif if (!ac) { flushLog(); return CHECK_ERROR(CALL_E_NOSYNC); } #ifndef _WIN32 if (_readline && _add_history) { char *line = _readline(msg); if (!line) return CHECK_ERROR(LastError()); if (*line) { _add_history(line); retVal = line; } free(line); } else #endif { s_std.out(msg); char *line = read_line(); if (!line) return CHECK_ERROR(LastError()); retVal = line; free(line); } return 0; }
result_t console_base::readLine(const char *msg, std::string &retVal, exlib::AsyncEvent *ac) { #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); if (!_init) { _init = true; #ifdef MacOS void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else void *handle = dlopen("libreadline.so", RTLD_LAZY); #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } } #endif if (!ac) { flushLog(); return CALL_E_NOSYNC; } #ifndef _WIN32 if (_readline && _add_history) { char *line; if ((line = _readline(msg)) != NULL) { if (*line) { _add_history(line); retVal = line; } free(line); } } else #endif { char *line; logger::std_out(msg); if ((line = read_line()) != NULL) { retVal = line; free(line); } } return 0; }
result_t console_base::readLine(exlib::string msg, exlib::string &retVal, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_LONGSYNC); flushLog(); #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); #ifdef DEBUG #ifdef __clang__ static void (*_free)(void*); if (_free == 0) _free = (void (*)(void*))dlsym(RTLD_NEXT, "free"); #else #define _free __real_free #endif #else #define _free free #endif if (!_init) { _init = true; #ifdef __clang__ void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else const char *readline_dylib_names[] = { "libreadline.so.6", "libreadline.so.5", "libreadline.so" }; const size_t readline_dylib_names_size = ARRAYSIZE(readline_dylib_names); void *handle = 0; for (size_t i = 0; i < readline_dylib_names_size; i++) { handle = dlopen(readline_dylib_names[i], RTLD_LAZY); if (handle) break; } #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } else { _readline = readline; _add_history = add_history; } } if (isatty(fileno(stdin))) { char *line; const char* lfptr = qstrrchr(msg.c_str(), '\n'); if (lfptr != NULL) { puts(msg.substr(0, lfptr - msg.c_str()).c_str()); line = _readline(lfptr + 1); } else line = _readline(msg.c_str()); if (!line) return CHECK_ERROR(LastError()); if (*line) { _add_history(line); retVal = line; } _free(line); } else #endif { std_logger::out(msg); char *line = read_line(); if (!line) return CHECK_ERROR(LastError()); retVal = line; free(line); } return 0; }