2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2005, PostgreSQL Global Development Group
6 * $PostgreSQL: pgsql/src/bin/psql/prompt.c,v 1.40 2005/10/15 02:49:40 momjian Exp $
8 #include "postgres_fe.h"
16 #include "variables.h"
23 #ifdef HAVE_UNIX_SOCKETS
28 /*--------------------------
31 * Returns a statically allocated prompt made by interpolating certain
32 * tcsh style escape sequences into pset.vars "PROMPT1|2|3".
33 * (might not be completely multibyte safe)
35 * Defined interpolations are:
36 * %M - database server "hostname.domainname", "[local]" for AF_UNIX
37 * sockets, "[local:/dir/name]" if not default
38 * %m - like %M, but hostname only (before first dot), or always "[local]"
39 * %> - database server port number
40 * %n - database user name
41 * %/ - current database
42 * %~ - like %/ but "~" when database name equals user name
43 * %# - "#" if superuser, ">" otherwise
44 * %R - in prompt1 normally =, or ^ if single line mode,
45 * or a ! if session is not connected to a database;
46 * in prompt2 -, *, ', or ";
48 * %x - transaction status: empty, *, !, ? (unknown or no connection)
49 * %? - the error code of the last query (not yet implemented)
52 * %[0-9] - the character with the given decimal code
53 * %0[0-7] - the character with the given octal code
54 * %0x[0-9A-Fa-f] - the character with the given hexadecimal code
56 * %`command` - The result of executing command in /bin/sh with trailing
58 * %:name: - The value of the psql variable 'name'
59 * (those will not be rescanned for more escape sequences!)
61 * %[ ... %] - tell readline that the contained text is invisible
63 * If the application-wide prompts become NULL somehow, the returned string
64 * will be empty (not NULL!).
65 *--------------------------
69 get_prompt(promptStatus_t status)
71 #define MAX_PROMPT_SIZE 256
72 static char destination[MAX_PROMPT_SIZE + 1];
73 char buf[MAX_PROMPT_SIZE + 1];
76 const char *prompt_string = "? ";
77 const char *prompt_name = NULL;
82 prompt_name = "PROMPT1";
86 case PROMPT_SINGLEQUOTE:
87 case PROMPT_DOUBLEQUOTE:
88 case PROMPT_DOLLARQUOTE:
91 prompt_name = "PROMPT2";
95 prompt_name = "PROMPT3";
100 prompt_string = GetVariable(pset.vars, prompt_name);
102 destination[0] = '\0';
104 for (p = prompt_string;
105 p && *p && strlen(destination) < MAX_PROMPT_SIZE;
108 memset(buf, 0, MAX_PROMPT_SIZE + 1);
113 /* Current database */
116 strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
123 if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 ||
124 ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0))
127 strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE);
131 /* DB server hostname (long/short) */
136 const char *host = PQhost(pset.db);
139 if (host && host[0] && !is_absolute_path(host))
141 strncpy(buf, host, MAX_PROMPT_SIZE);
143 buf[strcspn(buf, ".")] = '\0';
145 #ifdef HAVE_UNIX_SOCKETS
150 || strcmp(host, DEFAULT_PGSOCKET_DIR) == 0
152 strncpy(buf, "[local]", MAX_PROMPT_SIZE);
154 snprintf(buf, MAX_PROMPT_SIZE, "[local:%s]", host);
159 /* DB server port number */
161 if (pset.db && PQport(pset.db))
162 strncpy(buf, PQport(pset.db), MAX_PROMPT_SIZE);
164 /* DB server user name */
167 strncpy(buf, session_username(), MAX_PROMPT_SIZE);
178 *buf = (char) strtol(p, (char **) &p, 8);
187 else if (!GetVariableBool(pset.vars, "SINGLELINE"))
192 case PROMPT_CONTINUE:
195 case PROMPT_SINGLEQUOTE:
198 case PROMPT_DOUBLEQUOTE:
201 case PROMPT_DOLLARQUOTE:
220 switch (PQtransactionStatus(pset.db))
226 case PQTRANS_INTRANS:
229 case PQTRANS_INERROR:
249 /* execute command */
253 char *file = pg_strdup(p + 1);
256 cmdend = strcspn(file, "`");
259 fd = popen(file, "r");
262 fgets(buf, MAX_PROMPT_SIZE - 1, fd);
265 if (strlen(buf) > 0 && buf[strlen(buf) - 1] == '\n')
266 buf[strlen(buf) - 1] = '\0';
272 /* interpolate variable */
279 name = pg_strdup(p + 1);
280 nameend = strcspn(name, ":");
281 name[nameend] = '\0';
282 val = GetVariable(pset.vars, name);
284 strncpy(buf, val, MAX_PROMPT_SIZE);
292 #if defined(USE_READLINE) && defined(RL_PROMPT_START_IGNORE)
295 * readline >=4.0 undocumented feature: non-printing
296 * characters in prompt strings must be marked as such, in
297 * order to properly display the line during editing.
300 buf[1] = (*p == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
301 #endif /* USE_READLINE */
322 strncat(destination, buf, MAX_PROMPT_SIZE - strlen(destination));
325 destination[MAX_PROMPT_SIZE] = '\0';