#include "pqexpbuffer.h"
Go to the source code of this file.
Functions | |
char * | gets_interactive (const char *prompt) |
char * | gets_fromFile (FILE *source) |
void | initializeInput (int flags) |
bool | saveHistory (char *fname, int max_lines, bool appendFlag, bool encodeFlag) |
void | pg_append_history (const char *s, PQExpBuffer history_buf) |
void | pg_send_history (PQExpBuffer history_buf) |
char* gets_fromFile | ( | FILE * | source | ) |
Definition at line 164 of file input.c.
References appendPQExpBufferStr(), createPQExpBuffer(), PQExpBufferData::data, PQExpBufferData::len, NULL, pg_strdup(), PQExpBufferBroken, psql_error(), resetPQExpBuffer(), sigint_interrupt_enabled, and strerror().
Referenced by exec_command(), gets_interactive(), and MainLoop().
{ static PQExpBuffer buffer = NULL; char line[1024]; if (buffer == NULL) /* first time through? */ buffer = createPQExpBuffer(); else resetPQExpBuffer(buffer); for (;;) { char *result; /* Enable SIGINT to longjmp to sigint_interrupt_jmp */ sigint_interrupt_enabled = true; /* Get some data */ result = fgets(line, sizeof(line), source); /* Disable SIGINT again */ sigint_interrupt_enabled = false; /* EOF or error? */ if (result == NULL) { if (ferror(source)) { psql_error("could not read from input file: %s\n", strerror(errno)); return NULL; } break; } appendPQExpBufferStr(buffer, line); if (PQExpBufferBroken(buffer)) { psql_error("out of memory\n"); return NULL; } /* EOL? */ if (buffer->data[buffer->len - 1] == '\n') { buffer->data[buffer->len - 1] = '\0'; return pg_strdup(buffer->data); } } if (buffer->len > 0) /* EOF after reading some bufferload(s) */ return pg_strdup(buffer->data); /* EOF, so return null */ return NULL; }
char* gets_interactive | ( | const char * | prompt | ) |
Definition at line 60 of file input.c.
References gets_fromFile(), and sigint_interrupt_enabled.
Referenced by MainLoop().
{ #ifdef USE_READLINE if (useReadline) { char *result; /* Enable SIGINT to longjmp to sigint_interrupt_jmp */ sigint_interrupt_enabled = true; /* On some platforms, readline is declared as readline(char *) */ result = readline((char *) prompt); /* Disable SIGINT again */ sigint_interrupt_enabled = false; return result; } #endif fputs(prompt, stdout); fflush(stdout); return gets_fromFile(stdin); }
void initializeInput | ( | int | flags | ) |
Definition at line 272 of file input.c.
References expand_tilde(), finishInput(), get_home_path(), GetVariable(), initialize_readline(), MAXPGPATH, NULL, pg_malloc(), pg_strdup(), pset, PSQLHISTORY, snprintf(), and _psqlSettings::vars.
Referenced by main().
{ #ifdef USE_READLINE if (flags & 1) { const char *histfile; char home[MAXPGPATH]; useReadline = true; initialize_readline(); useHistory = true; using_history(); history_lines_added = 0; histfile = GetVariable(pset.vars, "HISTFILE"); if (histfile == NULL) { char *envhist; envhist = getenv("PSQL_HISTORY"); if (envhist != NULL && strlen(envhist) > 0) histfile = envhist; } if (histfile == NULL) { if (get_home_path(home)) { psql_history = pg_malloc(strlen(home) + 1 + strlen(PSQLHISTORY) + 1); snprintf(psql_history, MAXPGPATH, "%s/%s", home, PSQLHISTORY); } } else { psql_history = pg_strdup(histfile); expand_tilde(&psql_history); } if (psql_history) { read_history(psql_history); decode_history(); } } #endif atexit(finishInput); }
void pg_append_history | ( | const char * | s, | |
PQExpBuffer | history_buf | |||
) |
Definition at line 90 of file input.c.
References appendPQExpBufferChar(), and appendPQExpBufferStr().
Referenced by MainLoop().
{ #ifdef USE_READLINE if (useHistory && s) { appendPQExpBufferStr(history_buf, s); if (!s[0] || s[strlen(s) - 1] != '\n') appendPQExpBufferChar(history_buf, '\n'); } #endif }
void pg_send_history | ( | PQExpBuffer | history_buf | ) |
Definition at line 112 of file input.c.
References PQExpBufferData::data, free, hctl_ignoredups, hctl_ignorespace, _psqlSettings::histcontrol, i, pg_strdup(), pset, and resetPQExpBuffer().
Referenced by MainLoop().
{ #ifdef USE_READLINE static char *prev_hist = NULL; char *s = history_buf->data; int i; /* Trim any trailing \n's (OK to scribble on history_buf) */ for (i = strlen(s) - 1; i >= 0 && s[i] == '\n'; i--) ; s[i + 1] = '\0'; if (useHistory && s[0]) { if (((pset.histcontrol & hctl_ignorespace) && s[0] == ' ') || ((pset.histcontrol & hctl_ignoredups) && prev_hist && strcmp(s, prev_hist) == 0)) { /* Ignore this line as far as history is concerned */ } else { /* Save each previous line for ignoredups processing */ if (prev_hist) free(prev_hist); prev_hist = pg_strdup(s); /* And send it to readline */ add_history(s); /* Count lines added to history for use later */ history_lines_added++; } } resetPQExpBuffer(history_buf); #endif }
Definition at line 341 of file input.c.
References close, DEVNULL, Max, Min, PG_BINARY, psql_error(), and strerror().
Referenced by exec_command(), and finishInput().
{ #ifdef USE_READLINE /* * Suppressing the write attempt when HISTFILE is set to /dev/null may * look like a negligible optimization, but it's necessary on e.g. Darwin, * where write_history will fail because it tries to chmod the target * file. */ if (useHistory && fname && strcmp(fname, DEVNULL) != 0) { if (encodeFlag) encode_history(); /* * On newer versions of libreadline, truncate the history file as * needed and then append what we've added. This avoids overwriting * history from other concurrent sessions (although there are still * race conditions when two sessions exit at about the same time). If * we don't have those functions, fall back to write_history(). * * Note: return value of write_history is not standardized across GNU * readline and libedit. Therefore, check for errno becoming set to * see if the write failed. Similarly for append_history. */ #if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY) if (appendFlag) { int nlines; int fd; /* truncate previous entries if needed */ if (max_lines >= 0) { nlines = Max(max_lines - history_lines_added, 0); (void) history_truncate_file(fname, nlines); } /* append_history fails if file doesn't already exist :-( */ fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600); if (fd >= 0) close(fd); /* append the appropriate number of lines */ if (max_lines >= 0) nlines = Min(max_lines, history_lines_added); else nlines = history_lines_added; errno = 0; (void) append_history(nlines, fname); if (errno == 0) return true; } else #endif { /* truncate what we have ... */ if (max_lines >= 0) stifle_history(max_lines); /* ... and overwrite file. Tough luck for concurrent sessions. */ errno = 0; (void) write_history(fname); if (errno == 0) return true; } psql_error("could not save history to file \"%s\": %s\n", fname, strerror(errno)); } #else /* only get here in \s case, so complain */ psql_error("history is not supported by this installation\n"); #endif return false; }