Go to the source code of this file.
Typedefs | |
typedef enum _promptStatus | promptStatus_t |
Enumerations | |
enum | _promptStatus { PROMPT_READY, PROMPT_CONTINUE, PROMPT_COMMENT, PROMPT_SINGLEQUOTE, PROMPT_DOUBLEQUOTE, PROMPT_DOLLARQUOTE, PROMPT_PAREN, PROMPT_COPY } |
Functions | |
char * | get_prompt (promptStatus_t status) |
typedef enum _promptStatus promptStatus_t |
enum _promptStatus |
PROMPT_READY | |
PROMPT_CONTINUE | |
PROMPT_COMMENT | |
PROMPT_SINGLEQUOTE | |
PROMPT_DOUBLEQUOTE | |
PROMPT_DOLLARQUOTE | |
PROMPT_PAREN | |
PROMPT_COPY |
Definition at line 11 of file prompt.h.
{ PROMPT_READY, PROMPT_CONTINUE, PROMPT_COMMENT, PROMPT_SINGLEQUOTE, PROMPT_DOUBLEQUOTE, PROMPT_DOLLARQUOTE, PROMPT_PAREN, PROMPT_COPY } promptStatus_t;
char* get_prompt | ( | promptStatus_t | status | ) |
Definition at line 67 of file prompt.c.
References buf, _psqlSettings::db, DEFAULT_PGSOCKET_DIR, free, GetVariable(), is_absolute_path, is_superuser(), MAX_PROMPT_SIZE, name, NULL, pg_strdup(), 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(), strlcat(), strlcpy(), val, and _psqlSettings::vars.
Referenced by handleCopyIn(), and MainLoop().
{ #define MAX_PROMPT_SIZE 256 static char destination[MAX_PROMPT_SIZE + 1]; char buf[MAX_PROMPT_SIZE + 1]; bool esc = false; const char *p; const char *prompt_string = "? "; switch (status) { case PROMPT_READY: prompt_string = pset.prompt1; break; case PROMPT_CONTINUE: case PROMPT_SINGLEQUOTE: case PROMPT_DOUBLEQUOTE: case PROMPT_DOLLARQUOTE: case PROMPT_COMMENT: case PROMPT_PAREN: prompt_string = pset.prompt2; break; case PROMPT_COPY: prompt_string = pset.prompt3; break; } destination[0] = '\0'; for (p = prompt_string; *p && strlen(destination) < sizeof(destination) - 1; p++) { memset(buf, 0, sizeof(buf)); if (esc) { switch (*p) { /* Current database */ case '/': if (pset.db) strlcpy(buf, PQdb(pset.db), sizeof(buf)); break; case '~': if (pset.db) { const char *var; if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 || ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0)) strlcpy(buf, "~", sizeof(buf)); else strlcpy(buf, PQdb(pset.db), sizeof(buf)); } break; /* DB server hostname (long/short) */ case 'M': case 'm': if (pset.db) { const char *host = PQhost(pset.db); /* INET socket */ if (host && host[0] && !is_absolute_path(host)) { strlcpy(buf, host, sizeof(buf)); if (*p == 'm') buf[strcspn(buf, ".")] = '\0'; } #ifdef HAVE_UNIX_SOCKETS /* UNIX socket */ else { if (!host || strcmp(host, DEFAULT_PGSOCKET_DIR) == 0 || *p == 'm') strlcpy(buf, "[local]", sizeof(buf)); else snprintf(buf, sizeof(buf), "[local:%s]", host); } #endif } break; /* DB server port number */ case '>': if (pset.db && PQport(pset.db)) strlcpy(buf, PQport(pset.db), sizeof(buf)); break; /* DB server user name */ case 'n': if (pset.db) strlcpy(buf, session_username(), sizeof(buf)); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': *buf = (char) strtol(p, (char **) &p, 8); --p; break; case 'R': switch (status) { case PROMPT_READY: if (!pset.db) buf[0] = '!'; else if (!pset.singleline) buf[0] = '='; else buf[0] = '^'; break; case PROMPT_CONTINUE: buf[0] = '-'; break; case PROMPT_SINGLEQUOTE: buf[0] = '\''; break; case PROMPT_DOUBLEQUOTE: buf[0] = '"'; break; case PROMPT_DOLLARQUOTE: buf[0] = '$'; break; case PROMPT_COMMENT: buf[0] = '*'; break; case PROMPT_PAREN: buf[0] = '('; break; default: buf[0] = '\0'; break; } break; case 'x': if (!pset.db) buf[0] = '?'; else switch (PQtransactionStatus(pset.db)) { case PQTRANS_IDLE: buf[0] = '\0'; break; case PQTRANS_ACTIVE: case PQTRANS_INTRANS: buf[0] = '*'; break; case PQTRANS_INERROR: buf[0] = '!'; break; default: buf[0] = '?'; break; } break; case '?': /* not here yet */ break; case '#': if (is_superuser()) buf[0] = '#'; else buf[0] = '>'; break; /* execute command */ case '`': { FILE *fd; char *file = pg_strdup(p + 1); int cmdend; cmdend = strcspn(file, "`"); file[cmdend] = '\0'; fd = popen(file, "r"); if (fd) { if (fgets(buf, sizeof(buf), fd) == NULL) buf[0] = '\0'; pclose(fd); } if (strlen(buf) > 0 && buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; free(file); p += cmdend + 1; break; } /* interpolate variable */ case ':': { char *name; const char *val; int nameend; name = pg_strdup(p + 1); nameend = strcspn(name, ":"); name[nameend] = '\0'; val = GetVariable(pset.vars, name); if (val) strlcpy(buf, val, sizeof(buf)); free(name); p += nameend + 1; break; } case '[': case ']': #if defined(USE_READLINE) && defined(RL_PROMPT_START_IGNORE) /* * readline >=4.0 undocumented feature: non-printing * characters in prompt strings must be marked as such, in * order to properly display the line during editing. */ buf[0] = (*p == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; buf[1] = '\0'; #endif /* USE_READLINE */ break; default: buf[0] = *p; buf[1] = '\0'; break; } esc = false; } else if (*p == '%') esc = true; else { buf[0] = *p; buf[1] = '\0'; esc = false; } if (!esc) strlcat(destination, buf, sizeof(destination)); } return destination; }