1 /*
2 * This file part of sdcv - console version of Stardict program
3 * http://sdcv.sourceforge.net
4 * Copyright (C) 2005 Evgeniy <dushistov@mail.ru>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <cstdio>
26 #include <cstdlib>
27 #ifdef WITH_READLINE
28 #include <readline/history.h>
29 #include <readline/readline.h>
30 #endif
31 #include <glib.h>
32
33 #include "utils.hpp"
34
35 #include "readline.hpp"
36
stdio_getline(FILE * in,std::string & str)37 bool stdio_getline(FILE *in, std::string &str)
38 {
39 assert(in != nullptr);
40 str.clear();
41 int ch;
42 while ((ch = fgetc(in)) != EOF && ch != '\n')
43 str += ch;
44
45 return EOF != ch;
46 }
47
48 #ifndef WITH_READLINE
49 namespace
50 {
51 class dummy_readline : public IReadLine
52 {
53 public:
read(const std::string & banner,std::string & line)54 bool read(const std::string &banner, std::string &line) override
55 {
56 printf("%s", banner.c_str());
57 return stdio_getline(stdin, line);
58 }
59 };
60 }
61 #else
62
63 namespace
64 {
65 class real_readline : public IReadLine
66 {
67
68 public:
real_readline()69 real_readline()
70 {
71 rl_readline_name = "sdcv";
72 using_history();
73 const std::string histname = std::string(g_get_home_dir()) + G_DIR_SEPARATOR + ".sdcv_history";
74 read_history(histname.c_str());
75 }
76
~real_readline()77 ~real_readline()
78 {
79 const std::string histname = std::string(g_get_home_dir()) + G_DIR_SEPARATOR + ".sdcv_history";
80 write_history(histname.c_str());
81 const gchar *hist_size_str = g_getenv("SDCV_HISTSIZE");
82 int hist_size;
83 if (!hist_size_str || sscanf(hist_size_str, "%d", &hist_size) < 1)
84 hist_size = 2000;
85 history_truncate_file(histname.c_str(), hist_size);
86 }
87
read(const std::string & banner,std::string & line)88 bool read(const std::string &banner, std::string &line) override
89 {
90 char *phrase = nullptr;
91 phrase = readline(banner.c_str());
92 if (phrase) {
93 line = phrase;
94 free(phrase);
95 return true;
96 }
97 return false;
98 }
99
add_to_history(const std::string & phrase)100 void add_to_history(const std::string &phrase) override
101 {
102 add_history(phrase.c_str());
103 }
104 };
105 }
106 #endif //WITH_READLINE
107
create_readline_object()108 IReadLine *create_readline_object()
109 {
110 #ifdef WITH_READLINE
111 return new real_readline;
112 #else
113 return new dummy_readline;
114 #endif
115 }
116