]> granicus.if.org Git - postgresql/blob - src/bin/psql/input.c
This should fix the \e (\p, \g, ...) behaviour on an empty query buffer.
[postgresql] / src / bin / psql / input.c
1 #include <config.h>
2 #include <c.h>
3 #include "input.h"
4
5 #include <pqexpbuffer.h>
6
7 #include "settings.h"
8 #include "tab-complete.h"
9
10 /* Runtime options for turning off readline and history */
11 /* (of course there is no runtime command for doing that :) */
12 #ifdef USE_READLINE
13 static bool useReadline;
14
15 #endif
16 #ifdef USE_HISTORY
17 static bool useHistory;
18
19 #endif
20
21
22 /*
23  * gets_interactive()
24  *
25  * Gets a line of interactive input, using readline of desired.
26  * The result is malloced.
27  */
28 char *
29 gets_interactive(const char *prompt)
30 {
31         char       *s;
32
33 #ifdef USE_READLINE
34         if (useReadline)
35                 s = readline(prompt);
36         else
37         {
38 #endif
39                 fputs(prompt, stdout);
40                 fflush(stdout);
41                 s = gets_fromFile(stdin);
42 #ifdef USE_READLINE
43         }
44 #endif
45
46 #ifdef USE_HISTORY
47         if (useHistory && s && s[0] != '\0')
48                 add_history(s);
49 #endif
50
51         return s;
52 }
53
54
55
56 /*
57  * gets_fromFile
58  *
59  * Gets a line of noninteractive input from a file (which could be stdin).
60  */
61 char *
62 gets_fromFile(FILE *source)
63 {
64         PQExpBufferData buffer;
65         char            line[1024];
66
67         initPQExpBuffer(&buffer);
68
69         while (fgets(line, 1024, source) != NULL)
70         {
71                 appendPQExpBufferStr(&buffer, line);
72                 if (buffer.data[buffer.len - 1] == '\n')
73                 {
74                         buffer.data[buffer.len - 1] = '\0';
75                         return buffer.data;
76                 }
77         }
78
79         if (buffer.len > 0)
80                 return buffer.data;             /* EOF after reading some bufferload(s) */
81
82         /* EOF, so return null */
83         termPQExpBuffer(&buffer);
84         return NULL;
85 }
86
87
88
89 /*
90  * Put any startup stuff related to input in here. It's good to maintain
91  * abstraction this way.
92  *
93  * The only "flag" right now is 1 for use readline & history.
94  */
95 void
96 initializeInput(int flags, PsqlSettings *pset)
97 {
98 #ifdef USE_READLINE
99         if (flags == 1)
100         {
101                 useReadline = true;
102                 rl_readline_name = "psql";
103         initialize_readline(&(pset->db));
104         }
105 #endif
106
107 #ifdef USE_HISTORY
108         if (flags == 1)
109         {
110                 const char *home;
111
112                 useHistory = true;
113                 using_history();
114                 home = getenv("HOME");
115                 if (home)
116                 {
117                         char       *psql_history = (char *) malloc(strlen(home) + 20);
118
119                         if (psql_history)
120                         {
121                                 sprintf(psql_history, "%s/.psql_history", home);
122                                 read_history(psql_history);
123                                 free(psql_history);
124                         }
125                 }
126         }
127 #endif
128 }
129
130
131
132 bool
133 saveHistory(const char *fname)
134 {
135 #ifdef USE_HISTORY
136         if (useHistory)
137         {
138                 if (write_history(fname) != 0)
139                 {
140                         perror(fname);
141                         return false;
142                 }
143                 return true;
144         }
145         else
146                 return false;
147 #else
148         return false;
149 #endif
150 }
151
152
153
154 void
155 finishInput(void)
156 {
157 #ifdef USE_HISTORY
158         if (useHistory)
159         {
160                 char       *home;
161                 char       *psql_history;
162
163                 home = getenv("HOME");
164                 if (home)
165                 {
166                         psql_history = (char *) malloc(strlen(home) + 20);
167                         if (psql_history)
168                         {
169                                 sprintf(psql_history, "%s/.psql_history", home);
170                                 write_history(psql_history);
171                                 free(psql_history);
172                         }
173                 }
174         }
175 #endif
176 }