Modified patch attached and applied. Thanks.
I adjusted based on Tom's comments to use a zero byte, and to clean up
the formatting. I didn't see any extra non-readline overhead, just
calls to functions that are no-ops in non-readline cases.
---------------------------------------------------------------------------
Tom Lane wrote:
> "Sergey E. Koposov" <[EMAIL PROTECTED]> writes:
> > On Wed, 7 Dec 2005, Andrew Dunstan wrote:
> >> A zero byte is probably a pretty bad choice. Some other low valued byte
> >> (e.g. \x01 ) would probably work better.
>
> > Currently I replace '\n' with the '\x01' as Andrew suggested.
>
> Won't this get confused by some of the Far Eastern encodings we support?
> The zero-byte approach is at least proof against that. But what we need
> to ask is whether we can expect readline to cope with either.
>
> The patch *looks* pretty ugly: random insertions of blank space,
> general failure to conform to the project's code layout conventions,
> etc. (Some of this would get cleaned up by pgindent, but I'm not sure
> how much.) Also I get the impression that the patch enforces a lot of
> history maintenance overhead even in the non-USE_READLINE case, which is
> surely useless.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings
>
--
Bruce Momjian | http://candle.pha.pa.us
[email protected] | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/bin/psql/help.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.106
diff -c -c -r1.106 help.c
*** src/bin/psql/help.c 15 Oct 2005 02:49:40 -0000 1.106
--- src/bin/psql/help.c 11 Feb 2006 21:52:55 -0000
***************
*** 7,12 ****
--- 7,13 ----
*/
#include "postgres_fe.h"
#include "common.h"
+ #include "pqexpbuffer.h"
#include "input.h"
#include "print.h"
#include "help.h"
Index: src/bin/psql/input.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/input.c,v
retrieving revision 1.46
diff -c -c -r1.46 input.c
*** src/bin/psql/input.c 15 Oct 2005 02:49:40 -0000 1.46
--- src/bin/psql/input.c 11 Feb 2006 21:52:56 -0000
***************
*** 7,14 ****
*/
#include "postgres_fe.h"
- #include "input.h"
#include "pqexpbuffer.h"
#include "settings.h"
#include "tab-complete.h"
#include "common.h"
--- 7,14 ----
*/
#include "postgres_fe.h"
#include "pqexpbuffer.h"
+ #include "input.h"
#include "settings.h"
#include "tab-complete.h"
#include "common.h"
***************
*** 90,107 ****
#ifdef USE_READLINE
char *s;
- static char *prev_hist = NULL;
-
if (useReadline)
/* On some platforms, readline is declared as readline(char *)
*/
s = readline((char *) prompt);
else
s = gets_basic(prompt);
! if (useHistory && s && s[0])
{
! enum histcontrol HC;
HC = GetHistControlConfig();
if (((HC & hctl_ignorespace) && s[0] == ' ') ||
--- 90,144 ----
#ifdef USE_READLINE
char *s;
if (useReadline)
/* On some platforms, readline is declared as readline(char *)
*/
s = readline((char *) prompt);
else
s = gets_basic(prompt);
! return s;
! #else
! return gets_basic(prompt);
! #endif
! }
!
!
! /* Put the line in the history buffer and also add the trailing \n */
! void pgadd_history(char *s, PQExpBuffer history_buf)
! {
! #ifdef USE_READLINE
!
! int slen;
! if (useReadline && useHistory && s && s[0])
{
! slen = strlen(s);
! if (s[slen-1] == '\n')
! appendPQExpBufferStr(history_buf, s);
! else
! {
! appendPQExpBufferStr(history_buf, s);
! appendPQExpBufferChar(history_buf, '\n');
! }
! }
! #endif
! }
!
+ /* Feed the contents of the history buffer to readline */
+ void pgflush_history(PQExpBuffer history_buf)
+ {
+ #ifdef USE_READLINE
+ char *s;
+ static char *prev_hist;
+ int slen, i;
+
+ if (useReadline && useHistory )
+ {
+ enum histcontrol HC;
+
+ s = history_buf->data;
+ prev_hist = NULL;
+
HC = GetHistControlConfig();
if (((HC & hctl_ignorespace) && s[0] == ' ') ||
***************
*** 112,128 ****
else
{
free(prev_hist);
prev_hist = pg_strdup(s);
add_history(s);
}
}
-
- return s;
- #else
- return gets_basic(prompt);
#endif
}
/*
--- 149,175 ----
else
{
free(prev_hist);
+ slen = strlen(s);
+ /* Trim the trailing \n's */
+ for (i = slen-1; i >= 0 && s[i] == '\n'; i--)
+ ;
+ s[i + 1] = '\0';
prev_hist = pg_strdup(s);
add_history(s);
}
+
+ resetPQExpBuffer(history_buf);
}
#endif
}
+ void pgclear_history(PQExpBuffer history_buf)
+ {
+ #ifdef USE_READLINE
+ if (useReadline && useHistory)
+ resetPQExpBuffer(history_buf);
+ #endif
+ }
/*
***************
*** 157,162 ****
--- 204,233 ----
}
+ static void encode_history()
+ {
+ HIST_ENTRY *cur_hist;
+ char *cur_ptr;
+
+ for (history_set_pos(0), cur_hist = current_history();
+ cur_hist; cur_hist = next_history())
+ for (cur_ptr = cur_hist->line; *cur_ptr; cur_ptr++)
+ if (*cur_ptr == '\n')
+ *cur_ptr = '\0';
+ }
+
+ static void decode_history()
+ {
+ HIST_ENTRY *cur_hist;
+ char *cur_ptr;
+
+ for (history_set_pos(0), cur_hist = current_history();
+ cur_hist; cur_hist = next_history())
+ for (cur_ptr = cur_hist->line; *cur_ptr; cur_ptr++)
+ if (*cur_ptr == '\0')
+ *cur_ptr = '\n';
+ }
+
/*
* Put any startup stuff related to input in here. It's good to maintain
***************
*** 197,202 ****
--- 268,275 ----
if (psql_history)
read_history(psql_history);
+
+ decode_history();
}
#endif
***************
*** 215,220 ****
--- 288,294 ----
#ifdef USE_READLINE
if (useHistory && fname)
{
+ encode_history();
if (write_history(fname) == 0)
return true;
Index: src/bin/psql/input.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/input.h,v
retrieving revision 1.23
diff -c -c -r1.23 input.h
*** src/bin/psql/input.h 1 Jan 2005 05:43:08 -0000 1.23
--- src/bin/psql/input.h 11 Feb 2006 21:52:56 -0000
***************
*** 39,42 ****
--- 39,47 ----
void initializeInput(int flags);
bool saveHistory(char *fname);
+ void pgadd_history(char *s, PQExpBuffer history_buf);
+ void pgclear_history(PQExpBuffer history_buf);
+ void pgflush_history(PQExpBuffer history_buf);
+
+
#endif /* INPUT_H */
Index: src/bin/psql/mainloop.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/mainloop.c,v
retrieving revision 1.69
diff -c -c -r1.69 mainloop.c
*** src/bin/psql/mainloop.c 18 Dec 2005 02:17:16 -0000 1.69
--- src/bin/psql/mainloop.c 11 Feb 2006 21:52:56 -0000
***************
*** 37,42 ****
--- 37,43 ----
PQExpBuffer query_buf; /* buffer for query being accumulated */
PQExpBuffer previous_buf; /* if there isn't anything in the new
buffer
* yet, use
this one for \e, etc. */
+ PQExpBuffer history_buf;
char *line; /* current line of input */
int added_nl_pos;
bool success;
***************
*** 66,72 ****
query_buf = createPQExpBuffer();
previous_buf = createPQExpBuffer();
! if (!query_buf || !previous_buf)
{
psql_error("out of memory\n");
exit(EXIT_FAILURE);
--- 67,75 ----
query_buf = createPQExpBuffer();
previous_buf = createPQExpBuffer();
! history_buf = createPQExpBuffer();
!
! if (!query_buf || !previous_buf || !history_buf)
{
psql_error("out of memory\n");
exit(EXIT_FAILURE);
***************
*** 90,96 ****
successResult = EXIT_USER;
break;
}
!
cancel_pressed = false;
}
--- 93,99 ----
successResult = EXIT_USER;
break;
}
! pgclear_history(history_buf);
cancel_pressed = false;
}
***************
*** 106,111 ****
--- 109,116 ----
count_eof = 0;
slashCmdStatus = PSQL_CMD_UNKNOWN;
prompt_status = PROMPT_READY;
+ if (pset.cur_cmd_interactive)
+ pgclear_history(history_buf);
if (pset.cur_cmd_interactive)
putc('\n', stdout);
***************
*** 138,148 ****
psql_scan_reset(scan_state);
slashCmdStatus = PSQL_CMD_UNKNOWN;
prompt_status = PROMPT_READY;
}
!
! /*
! * otherwise, get another line
! */
else if (pset.cur_cmd_interactive)
{
/* May need to reset prompt, eg after \r command */
--- 143,157 ----
psql_scan_reset(scan_state);
slashCmdStatus = PSQL_CMD_UNKNOWN;
prompt_status = PROMPT_READY;
+
+ if (pset.cur_cmd_interactive)
+ /*
+ * Pass all the contents of history_buf to
readline
+ * and free the history buffer.
+ */
+ pgflush_history(history_buf);
}
! /* otherwise, get another line */
else if (pset.cur_cmd_interactive)
{
/* May need to reset prompt, eg after \r command */
***************
*** 212,218 ****
*/
psql_scan_setup(scan_state, line, strlen(line));
success = true;
!
while (success || !die_on_error)
{
PsqlScanResult scan_result;
--- 221,231 ----
*/
psql_scan_setup(scan_state, line, strlen(line));
success = true;
!
! if (pset.cur_cmd_interactive)
! /* Put current line in the history buffer */
! pgadd_history(line, history_buf);
!
while (success || !die_on_error)
{
PsqlScanResult scan_result;
***************
*** 287,292 ****
--- 300,312 ----
scan_result == PSCAN_EOL)
break;
}
+
+ if (pset.cur_cmd_interactive && prompt_status !=
PROMPT_CONTINUE)
+ /*
+ * Pass all the contents of history_buf to readline
+ * and free the history buffer.
+ */
+ pgflush_history(history_buf);
psql_scan_finish(scan_state);
free(line);
***************
*** 333,338 ****
--- 353,359 ----
destroyPQExpBuffer(query_buf);
destroyPQExpBuffer(previous_buf);
+ destroyPQExpBuffer(history_buf);
psql_scan_destroy(scan_state);
Index: src/bin/psql/prompt.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/prompt.c,v
retrieving revision 1.41
diff -c -c -r1.41 prompt.c
*** src/bin/psql/prompt.c 3 Jan 2006 23:32:30 -0000 1.41
--- src/bin/psql/prompt.c 11 Feb 2006 21:52:56 -0000
***************
*** 12,17 ****
--- 12,18 ----
#include "settings.h"
#include "common.h"
+ #include "pqexpbuffer.h"
#include "input.h"
#include "variables.h"
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.144
diff -c -c -r1.144 tab-complete.c
*** src/bin/psql/tab-complete.c 11 Jan 2006 08:43:12 -0000 1.144
--- src/bin/psql/tab-complete.c 11 Feb 2006 21:52:59 -0000
***************
*** 43,48 ****
--- 43,49 ----
#include "postgres_fe.h"
#include "tab-complete.h"
+ #include "pqexpbuffer.h"
#include "input.h"
/* If we don't have this, we might as well forget about the whole thing: */
***************
*** 50,56 ****
#include <ctype.h>
#include "libpq-fe.h"
- #include "pqexpbuffer.h"
#include "common.h"
#include "settings.h"
--- 51,56 ----
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster