PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
prompt.h File Reference
Include dependency graph for prompt.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

char * get_prompt (promptStatus_t status)
 

Function Documentation

char* get_prompt ( promptStatus_t  status)

Definition at line 69 of file prompt.c.

References buf, _psqlSettings::db, DEFAULT_PGSOCKET_DIR, fd(), free, GetVariable(), is_absolute_path, is_superuser(), MAX_PROMPT_SIZE, name, NULL, pg_strdup(), PQbackendPID(), PQdb(), PQhost(), PQport(), PQTRANS_ACTIVE, PQTRANS_IDLE, PQTRANS_INERROR, PQTRANS_INTRANS, PQtransactionStatus(), PQuser(), _psqlSettings::prompt1, _psqlSettings::prompt2, _psqlSettings::prompt3, PROMPT_COMMENT, PROMPT_CONTINUE, PROMPT_COPY, PROMPT_DOLLARQUOTE, PROMPT_DOUBLEQUOTE, PROMPT_PAREN, PROMPT_READY, PROMPT_SINGLEQUOTE, pset, session_username(), _psqlSettings::singleline, snprintf(), _psqlSettings::stmt_lineno, strlcat(), strlcpy(), UINT64_FORMAT, val, and _psqlSettings::vars.

Referenced by handleCopyIn(), and MainLoop().

70 {
71 #define MAX_PROMPT_SIZE 256
72  static char destination[MAX_PROMPT_SIZE + 1];
73  char buf[MAX_PROMPT_SIZE + 1];
74  bool esc = false;
75  const char *p;
76  const char *prompt_string = "? ";
77 
78  switch (status)
79  {
80  case PROMPT_READY:
81  prompt_string = pset.prompt1;
82  break;
83 
84  case PROMPT_CONTINUE:
85  case PROMPT_SINGLEQUOTE:
86  case PROMPT_DOUBLEQUOTE:
87  case PROMPT_DOLLARQUOTE:
88  case PROMPT_COMMENT:
89  case PROMPT_PAREN:
90  prompt_string = pset.prompt2;
91  break;
92 
93  case PROMPT_COPY:
94  prompt_string = pset.prompt3;
95  break;
96  }
97 
98  destination[0] = '\0';
99 
100  for (p = prompt_string;
101  *p && strlen(destination) < sizeof(destination) - 1;
102  p++)
103  {
104  memset(buf, 0, sizeof(buf));
105  if (esc)
106  {
107  switch (*p)
108  {
109  /* Current database */
110  case '/':
111  if (pset.db)
112  strlcpy(buf, PQdb(pset.db), sizeof(buf));
113  break;
114  case '~':
115  if (pset.db)
116  {
117  const char *var;
118 
119  if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 ||
120  ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0))
121  strlcpy(buf, "~", sizeof(buf));
122  else
123  strlcpy(buf, PQdb(pset.db), sizeof(buf));
124  }
125  break;
126 
127  /* DB server hostname (long/short) */
128  case 'M':
129  case 'm':
130  if (pset.db)
131  {
132  const char *host = PQhost(pset.db);
133 
134  /* INET socket */
135  if (host && host[0] && !is_absolute_path(host))
136  {
137  strlcpy(buf, host, sizeof(buf));
138  if (*p == 'm')
139  buf[strcspn(buf, ".")] = '\0';
140  }
141 #ifdef HAVE_UNIX_SOCKETS
142  /* UNIX socket */
143  else
144  {
145  if (!host
146  || strcmp(host, DEFAULT_PGSOCKET_DIR) == 0
147  || *p == 'm')
148  strlcpy(buf, "[local]", sizeof(buf));
149  else
150  snprintf(buf, sizeof(buf), "[local:%s]", host);
151  }
152 #endif
153  }
154  break;
155  /* DB server port number */
156  case '>':
157  if (pset.db && PQport(pset.db))
158  strlcpy(buf, PQport(pset.db), sizeof(buf));
159  break;
160  /* DB server user name */
161  case 'n':
162  if (pset.db)
163  strlcpy(buf, session_username(), sizeof(buf));
164  break;
165  /* backend pid */
166  case 'p':
167  if (pset.db)
168  {
169  int pid = PQbackendPID(pset.db);
170 
171  if (pid)
172  snprintf(buf, sizeof(buf), "%d", pid);
173  }
174  break;
175 
176  case '0':
177  case '1':
178  case '2':
179  case '3':
180  case '4':
181  case '5':
182  case '6':
183  case '7':
184  *buf = (char) strtol(p, (char **) &p, 8);
185  --p;
186  break;
187  case 'R':
188  switch (status)
189  {
190  case PROMPT_READY:
191  if (!pset.db)
192  buf[0] = '!';
193  else if (!pset.singleline)
194  buf[0] = '=';
195  else
196  buf[0] = '^';
197  break;
198  case PROMPT_CONTINUE:
199  buf[0] = '-';
200  break;
201  case PROMPT_SINGLEQUOTE:
202  buf[0] = '\'';
203  break;
204  case PROMPT_DOUBLEQUOTE:
205  buf[0] = '"';
206  break;
207  case PROMPT_DOLLARQUOTE:
208  buf[0] = '$';
209  break;
210  case PROMPT_COMMENT:
211  buf[0] = '*';
212  break;
213  case PROMPT_PAREN:
214  buf[0] = '(';
215  break;
216  default:
217  buf[0] = '\0';
218  break;
219  }
220  break;
221 
222  case 'x':
223  if (!pset.db)
224  buf[0] = '?';
225  else
226  switch (PQtransactionStatus(pset.db))
227  {
228  case PQTRANS_IDLE:
229  buf[0] = '\0';
230  break;
231  case PQTRANS_ACTIVE:
232  case PQTRANS_INTRANS:
233  buf[0] = '*';
234  break;
235  case PQTRANS_INERROR:
236  buf[0] = '!';
237  break;
238  default:
239  buf[0] = '?';
240  break;
241  }
242  break;
243 
244  case 'l':
245  snprintf(buf, sizeof(buf), UINT64_FORMAT, pset.stmt_lineno);
246  break;
247 
248  case '?':
249  /* not here yet */
250  break;
251 
252  case '#':
253  if (is_superuser())
254  buf[0] = '#';
255  else
256  buf[0] = '>';
257  break;
258 
259  /* execute command */
260  case '`':
261  {
262  FILE *fd;
263  char *file = pg_strdup(p + 1);
264  int cmdend;
265 
266  cmdend = strcspn(file, "`");
267  file[cmdend] = '\0';
268  fd = popen(file, "r");
269  if (fd)
270  {
271  if (fgets(buf, sizeof(buf), fd) == NULL)
272  buf[0] = '\0';
273  pclose(fd);
274  }
275  if (strlen(buf) > 0 && buf[strlen(buf) - 1] == '\n')
276  buf[strlen(buf) - 1] = '\0';
277  free(file);
278  p += cmdend + 1;
279  break;
280  }
281 
282  /* interpolate variable */
283  case ':':
284  {
285  char *name;
286  const char *val;
287  int nameend;
288 
289  name = pg_strdup(p + 1);
290  nameend = strcspn(name, ":");
291  name[nameend] = '\0';
292  val = GetVariable(pset.vars, name);
293  if (val)
294  strlcpy(buf, val, sizeof(buf));
295  free(name);
296  p += nameend + 1;
297  break;
298  }
299 
300  case '[':
301  case ']':
302 #if defined(USE_READLINE) && defined(RL_PROMPT_START_IGNORE)
303 
304  /*
305  * readline >=4.0 undocumented feature: non-printing
306  * characters in prompt strings must be marked as such, in
307  * order to properly display the line during editing.
308  */
309  buf[0] = (*p == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
310  buf[1] = '\0';
311 #endif /* USE_READLINE */
312  break;
313 
314  default:
315  buf[0] = *p;
316  buf[1] = '\0';
317  break;
318 
319  }
320  esc = false;
321  }
322  else if (*p == '%')
323  esc = true;
324  else
325  {
326  buf[0] = *p;
327  buf[1] = '\0';
328  esc = false;
329  }
330 
331  if (!esc)
332  strlcat(destination, buf, sizeof(destination));
333  }
334 
335  return destination;
336 }
PGconn * db
Definition: settings.h:82
PsqlSettings pset
Definition: startup.c:37
const char * prompt3
Definition: settings.h:137
char * PQport(const PGconn *conn)
Definition: fe-connect.c:5881
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static int fd(const char *x, int i)
Definition: preproc-init.c:105
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5836
static char * buf
Definition: pg_test_fsync.c:65
const char * session_username(void)
Definition: common.c:2032
#define is_absolute_path(filename)
Definition: port.h:77
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
bool singleline
Definition: settings.h:125
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5915
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71
int PQbackendPID(const PGconn *conn)
Definition: fe-connect.c:5986
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:5861
bool is_superuser(void)
Definition: common.c:1985
#define free(a)
Definition: header.h:60
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5828
#define NULL
Definition: c.h:226
#define MAX_PROMPT_SIZE
const char * prompt2
Definition: settings.h:136
const char * prompt1
Definition: settings.h:135
const char * name
Definition: encode.c:521
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
#define UINT64_FORMAT
Definition: c.h:313
long val
Definition: informix.c:689
uint64 stmt_lineno
Definition: settings.h:109
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
#define DEFAULT_PGSOCKET_DIR
VariableSpace vars
Definition: settings.h:115