2 * psql - the PostgreSQL interactive terminal
4 * Copyright 2000 by PostgreSQL Global Development Group
6 * $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.26 2003/07/27 03:32:26 momjian Exp $
8 #include "postgres_fe.h"
17 #include "pqexpbuffer.h"
19 #include "tab-complete.h"
22 /* Runtime options for turning off readline and history */
23 /* (of course there is no runtime command for doing that :) */
25 static bool useReadline;
26 static bool useHistory;
33 hctl_ignoreboth = hctl_ignorespace | hctl_ignoredups
39 static void finishInput(void);
42 /* designed for use with on_exit() */
43 static void finishInput(int, void *);
46 #define PSQLHISTORY ".psql_history"
51 * translate DOS console character set into ANSI, needed e.g. for
54 if (GetVariableBool(pset.vars, "WIN32_CONSOLE"))
59 static enum histcontrol
60 GetHistControlConfig(void)
65 var = GetVariable(pset.vars, "HISTCONTROL");
67 if (!var) HC = hctl_none;
68 else if (strcmp(var, "ignorespace") == 0) HC = hctl_ignorespace;
69 else if (strcmp(var, "ignoredups") == 0) HC = hctl_ignoredups;
70 else if (strcmp(var, "ignoreboth") == 0) HC = hctl_ignoreboth;
79 gets_basic(const char prompt[])
81 fputs(prompt, stdout);
83 return gets_fromFile(stdin);
90 * Gets a line of interactive input, using readline of desired.
91 * The result is malloced.
94 gets_interactive(const char *prompt)
99 static char *prev_hist = NULL;
102 /* On some platforms, readline is declared as readline(char *) */
103 s = readline((char *) prompt);
105 s = gets_basic(prompt);
107 if (useHistory && s && s[0])
111 HC = GetHistControlConfig();
113 if (((HC & hctl_ignorespace) && s[0] == ' ') ||
114 ((HC & hctl_ignoredups) && prev_hist && strcmp(s, prev_hist) == 0))
116 /* Ignore this line as far as history is concerned */
121 prev_hist = strdup(s);
128 return gets_basic(prompt);
137 * Gets a line of noninteractive input from a file (which could be stdin).
140 gets_fromFile(FILE *source)
142 PQExpBufferData buffer;
145 initPQExpBuffer(&buffer);
147 while (fgets(line, sizeof(line), source) != NULL)
149 appendPQExpBufferStr(&buffer, line);
150 if (buffer.data[buffer.len - 1] == '\n')
152 buffer.data[buffer.len - 1] = '\0';
158 return buffer.data; /* EOF after reading some bufferload(s) */
160 /* EOF, so return null */
161 termPQExpBuffer(&buffer);
168 * Put any startup stuff related to input in here. It's good to maintain
169 * abstraction this way.
171 * The only "flag" right now is 1 for use readline & history.
174 initializeInput(int flags)
182 initialize_readline();
185 SetVariable(pset.vars, "HISTSIZE", "500");
187 home = getenv("HOME");
190 char *psql_history = (char *) malloc(strlen(home) + 1 +
191 strlen(PSQLHISTORY) + 1);
195 sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
196 read_history(psql_history);
206 on_exit(finishInput, NULL);
213 saveHistory(char *fname)
216 if (useHistory && fname)
218 if (write_history(fname) == 0)
221 psql_error("could not save history to file \"%s\": %s\n", fname, strerror(errno));
234 finishInput(int exitstatus, void *arg)
243 home = getenv("HOME");
246 psql_history = (char *) malloc(strlen(home) + 1 +
247 strlen(PSQLHISTORY) + 1);
251 hist_size = GetVariableNum(pset.vars,"HISTSIZE",-1,-1,true);
254 stifle_history(hist_size);
256 sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
257 write_history(psql_history);