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