diff -r -c -B -b pgsql.orig/src/bin/psql/command.c pgsql.patch2/src/bin/psql/command.c *** pgsql.orig/src/bin/psql/command.c 2003-02-22 16:30:41.000000000 +0100 --- pgsql.patch2/src/bin/psql/command.c 2003-02-27 17:04:31.000000000 +0100 *************** *** 668,682 **** if (!opt0) { /* list all variables */ ! ! /* ! * XXX This is in utter violation of the GetVariable ! * abstraction, but I have not bothered to do it better. ! */ ! struct _variable *ptr; ! ! for (ptr = pset.vars; ptr->next; ptr = ptr->next) ! fprintf(stdout, "%s = '%s'\n", ptr->next->name, ptr->next->value); success = true; } else --- 668,674 ---- if (!opt0) { /* list all variables */ ! PrintVariables(pset.vars); success = true; } else *************** *** 1070,1078 **** save_char = options_string[pos + token_end + 1]; options_string[pos + token_end + 1] = '\0'; value = GetVariable(pset.vars, options_string + pos + 1); ! if (!value) ! value = ""; ! return_val = xstrdup(value); options_string[pos + token_end + 1] = save_char; *string = &options_string[pos + token_end + 1]; /* XXX should we set *quote to ':' here? */ --- 1062,1068 ---- save_char = options_string[pos + token_end + 1]; options_string[pos + token_end + 1] = '\0'; value = GetVariable(pset.vars, options_string + pos + 1); ! return_val = xstrdup(value ? value : ""); options_string[pos + token_end + 1] = save_char; *string = &options_string[pos + token_end + 1]; /* XXX should we set *quote to ':' here? */ *************** *** 1284,1298 **** case '7': case '8': case '9': ! { ! long int l; ! char *end; ! ! l = strtol(p, &end, 0); ! c = (char) l; ! p = end - 1; break; ! } default: c = *p; } --- 1274,1282 ---- case '7': case '8': case '9': ! c = parse_char((char **)&p); break; ! default: c = *p; } diff -r -c -B -b pgsql.orig/src/bin/psql/common.c pgsql.patch2/src/bin/psql/common.c *** pgsql.orig/src/bin/psql/common.c 2003-02-22 16:30:41.000000000 +0100 --- pgsql.patch2/src/bin/psql/common.c 2003-02-27 17:12:40.000000000 +0100 *************** *** 176,181 **** --- 176,194 ---- PGconn *cancelConn; volatile bool cancel_pressed; + + bool CheckCancelConn(void) + { + return cancelConn != NULL; + } + + + void ResetCancelConn(void) + { + cancelConn = NULL; + } + + #ifndef WIN32 #define write_stderr(String) write(fileno(stderr), String, strlen(String)) *************** *** 222,228 **** { PGresult *res = NULL; PGresult *newres; ! const char *var; ExecStatusType rstatus; if (!pset.db) --- 235,241 ---- { PGresult *res = NULL; PGresult *newres; ! int echo_hidden; ExecStatusType rstatus; if (!pset.db) *************** *** 231,247 **** return NULL; } ! var = GetVariable(pset.vars, "ECHO_HIDDEN"); ! if (var) { printf("********* QUERY **********\n" "%s\n" "**************************\n\n", query); fflush(stdout); - } ! if (var && strcmp(var, "noexec") == 0) return NULL; /* discard any uneaten results of past queries */ while ((newres = PQgetResult(pset.db)) != NULL) --- 244,260 ---- return NULL; } ! echo_hidden = SwitchVariable(pset.vars, "ECHO_HIDDEN", "noexec", NULL); ! if (echo_hidden != var_notset) { printf("********* QUERY **********\n" "%s\n" "**************************\n\n", query); fflush(stdout); ! if (echo_hidden == 1) return NULL; + } /* discard any uneaten results of past queries */ while ((newres = PQgetResult(pset.db)) != NULL) *************** *** 357,369 **** if (buf[0] == 'x') return false; } ! else ! { ! const char *var = GetVariable(pset.vars, "ECHO"); ! ! if (var && strncmp(var, "queries", strlen(var)) == 0) puts(query); - } cancelConn = pset.db; --- 370,377 ---- if (buf[0] == 'x') return false; } ! else if (VariableEquals(pset.vars, "ECHO", "queries")) puts(query); cancelConn = pset.db; *************** *** 565,567 **** --- 573,587 ---- return stdout; } + + + char parse_char(char **buf) + { + long l; + + l = strtol(*buf, buf, 0); + *buf--; + return (char)l; + } + + diff -r -c -B -b pgsql.orig/src/bin/psql/common.h pgsql.patch2/src/bin/psql/common.h *** pgsql.orig/src/bin/psql/common.h 2003-02-24 01:55:25.000000000 +0100 --- pgsql.patch2/src/bin/psql/common.h 2003-02-27 15:08:11.000000000 +0100 *************** *** 43,48 **** --- 43,54 ---- /* sprompt.h */ extern char *simple_prompt(const char *prompt, int maxlen, bool echo); + /* Parse a numeric character code from the string pointed at by *buf, e.g. + * one written as 0x0c (hexadecimal) or 015 (octal); advance *buf to the last + * character of the numeric character code. + */ + extern char parse_char(char **buf); + /* Used for all Win32 popen/pclose calls */ #ifdef WIN32 #define popen(x,y) _popen(x,y) diff -r -c -B -b pgsql.orig/src/bin/psql/input.c pgsql.patch2/src/bin/psql/input.c *** pgsql.orig/src/bin/psql/input.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/input.c 2003-02-27 18:17:46.000000000 +0100 *************** *** 208,217 **** strlen(PSQLHISTORY) + 1); if (psql_history) { ! const char *var = GetVariable(pset.vars, "HISTSIZE"); - if (var) - stifle_history(atoi(var)); sprintf(psql_history, "%s/%s", home, PSQLHISTORY); write_history(psql_history); free(psql_history); --- 208,219 ---- strlen(PSQLHISTORY) + 1); if (psql_history) { ! int hist_size; ! hist_size = GetVariableNum(pset.vars,"HISTSIZE",-1,-1,true); ! ! if (hist_size >= 0) ! stifle_history(hist_size); sprintf(psql_history, "%s/%s", home, PSQLHISTORY); write_history(psql_history); free(psql_history); diff -r -c -B -b pgsql.orig/src/bin/psql/large_obj.c pgsql.patch2/src/bin/psql/large_obj.c *** pgsql.orig/src/bin/psql/large_obj.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/large_obj.c 2003-02-27 16:51:43.000000000 +0100 *************** *** 40,54 **** static bool handle_transaction(void) { - const char *var = GetVariable(pset.vars, "LO_TRANSACTION"); PGresult *res; ! bool commit; PQnoticeProcessor old_notice_hook; ! if (var && strcmp(var, "nothing") == 0) return true; ! ! commit = (var && strcmp(var, "commit") == 0); notice[0] = '\0'; old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL); --- 40,59 ---- static bool handle_transaction(void) { PGresult *res; ! bool commit = false; PQnoticeProcessor old_notice_hook; ! switch (SwitchVariable(pset.vars, "LO_TRANSACTION", ! "nothing", ! "commit", ! NULL)) ! { ! case 1: return true; ! case 2: ! commit = true; ! } notice[0] = '\0'; old_notice_hook = PQsetNoticeProcessor(pset.db, _my_notice_handler, NULL); *************** *** 87,97 **** { PGresult *res; int status; ! bool own_transaction = true; ! const char *var = GetVariable(pset.vars, "LO_TRANSACTION"); ! if (var && strcmp(var, "nothing") == 0) ! own_transaction = false; if (!pset.db) { --- 92,100 ---- { PGresult *res; int status; ! bool own_transaction; ! own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing"); if (!pset.db) { *************** *** 154,164 **** Oid loid; char oidbuf[32]; unsigned int i; ! bool own_transaction = true; ! const char *var = GetVariable(pset.vars, "LO_TRANSACTION"); ! if (var && strcmp(var, "nothing") == 0) ! own_transaction = false; if (!pset.db) { --- 157,165 ---- Oid loid; char oidbuf[32]; unsigned int i; ! bool own_transaction; ! own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing"); if (!pset.db) { *************** *** 271,281 **** int status; Oid loid = atooid(loid_arg); char buf[256]; - bool own_transaction = true; - const char *var = GetVariable(pset.vars, "LO_TRANSACTION"); ! if (var && strcmp(var, "nothing") == 0) ! own_transaction = false; if (!pset.db) { --- 272,281 ---- int status; Oid loid = atooid(loid_arg); char buf[256]; ! bool own_transaction; ! ! own_transaction = VariableEquals(pset.vars, "LO_TRANSACTION", "nothing"); if (!pset.db) { diff -r -c -B -b pgsql.orig/src/bin/psql/mainloop.c pgsql.patch2/src/bin/psql/mainloop.c *** pgsql.orig/src/bin/psql/mainloop.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/mainloop.c 2003-02-27 18:05:07.000000000 +0100 *************** *** 40,55 **** char *line; /* current line of input */ int len; /* length of the line */ volatile int successResult = EXIT_SUCCESS; ! volatile backslashResult slashCmdStatus; bool success; ! volatile char in_quote; /* == 0 for no in_quote */ ! volatile bool in_xcomment; /* in extended comment */ ! volatile int xcdepth; ! volatile int paren_level; unsigned int query_start; volatile int count_eof = 0; - const char *var; volatile unsigned int bslash_count = 0; int i, --- 40,53 ---- char *line; /* current line of input */ int len; /* length of the line */ volatile int successResult = EXIT_SUCCESS; ! volatile backslashResult slashCmdStatus = CMD_UNKNOWN; bool success; ! volatile char in_quote = 0; /* == 0 for no in_quote */ ! volatile int in_xcomment = 0; /* in extended comment */ ! volatile int paren_level = 0; unsigned int query_start; volatile int count_eof = 0; volatile unsigned int bslash_count = 0; int i, *************** *** 81,96 **** exit(EXIT_FAILURE); } - in_xcomment = false; - in_quote = 0; - paren_level = 0; - slashCmdStatus = CMD_UNKNOWN; /* set default */ prev_lineno = pset.lineno; pset.lineno = 0; /* main loop to get queries and execute them */ ! while (1) { #ifndef WIN32 --- 79,90 ---- exit(EXIT_FAILURE); } prev_lineno = pset.lineno; pset.lineno = 0; /* main loop to get queries and execute them */ ! while (successResult == EXIT_SUCCESS) { #ifndef WIN32 *************** *** 111,116 **** --- 105,111 ---- } cancel_pressed = false; + fflush(stdout); } if (sigsetjmp(main_loop_jmp, 1) != 0) *************** *** 119,133 **** if (pset.cur_cmd_interactive) { ! fputc('\n', stdout); resetPQExpBuffer(query_buf); /* reset parsing state */ ! in_xcomment = false; in_quote = 0; paren_level = 0; count_eof = 0; slashCmdStatus = CMD_UNKNOWN; } else { --- 114,129 ---- if (pset.cur_cmd_interactive) { ! putc('\n', stdout); resetPQExpBuffer(query_buf); /* reset parsing state */ ! in_xcomment = 0; in_quote = 0; paren_level = 0; count_eof = 0; slashCmdStatus = CMD_UNKNOWN; + fflush(stdout); } else { *************** *** 152,174 **** line = xstrdup(query_buf->data); resetPQExpBuffer(query_buf); /* reset parsing state since we are rescanning whole line */ ! in_xcomment = false; in_quote = 0; paren_level = 0; slashCmdStatus = CMD_UNKNOWN; } - else - { - fflush(stdout); - /* * otherwise, set interactive prompt if necessary and get * another line */ ! if (pset.cur_cmd_interactive) { int prompt_status; if (in_quote && in_quote == '\'') prompt_status = PROMPT_SINGLEQUOTE; else if (in_quote && in_quote == '"') --- 148,168 ---- line = xstrdup(query_buf->data); resetPQExpBuffer(query_buf); /* reset parsing state since we are rescanning whole line */ ! in_xcomment = 0; in_quote = 0; paren_level = 0; slashCmdStatus = CMD_UNKNOWN; } /* * otherwise, set interactive prompt if necessary and get * another line */ ! else if (pset.cur_cmd_interactive) { int prompt_status; + fflush(stdout); + if (in_quote && in_quote == '\'') prompt_status = PROMPT_SINGLEQUOTE; else if (in_quote && in_quote == '"') *************** *** 186,192 **** } else line = gets_fromFile(source); - } /* Setting this will not have effect until next line. */ --- 180,185 ---- *************** *** 204,253 **** { if (pset.cur_cmd_interactive) { - bool getout = true; - /* This tries to mimic bash's IGNOREEOF feature. */ ! const char *val = GetVariable(pset.vars, "IGNOREEOF"); ! if (val) ! { ! long int maxeof; ! char *endptr; ! ! if (*val == '\0') ! maxeof = 10; ! else ! { ! maxeof = strtol(val, &endptr, 0); ! if (*endptr != '\0') /* string not valid as a ! * number */ ! maxeof = 10; ! } ! ! if (count_eof++ != maxeof) ! getout = false; /* not quite there yet */ ! } ! ! if (getout) ! { ! if (QUIET()) ! putc('\n', stdout); ! else ! puts("\\q"); ! break; ! } ! else { if (!QUIET()) printf(gettext("Use \"\\q\" to leave %s.\n"), pset.progname); continue; } } - else - /* not interactive */ break; } ! else count_eof = 0; pset.lineno++; --- 197,217 ---- { if (pset.cur_cmd_interactive) { /* This tries to mimic bash's IGNOREEOF feature. */ ! count_eof++; ! if (count_eof < GetVariableNum(pset.vars,"IGNOREEOF",0,10,false)) { if (!QUIET()) printf(gettext("Use \"\\q\" to leave %s.\n"), pset.progname); continue; } + + puts(QUIET() ? "" : "\\q"); } break; } ! count_eof = 0; pset.lineno++; *************** *** 260,267 **** } /* echo back if flag is set */ ! var = GetVariable(pset.vars, "ECHO"); ! if (!pset.cur_cmd_interactive && var && strcmp(var, "all") == 0) puts(line); fflush(stdout); --- 224,230 ---- } /* echo back if flag is set */ ! if (!pset.cur_cmd_interactive && VariableEquals(pset.vars, "ECHO", "all")) puts(line); fflush(stdout); *************** *** 277,290 **** #define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding)) success = true; ! for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, pset.encoding) : 0; ! i < len; ! ADVANCE_1) { /* was the previous character a backslash? */ ! bool was_bslash = (i > 0 && line[i - prevlen] == '\\'); ! ! if (was_bslash) bslash_count++; else bslash_count = 0; --- 240,252 ---- #define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, pset.encoding)) success = true; ! prevlen = 0; ! thislen = ((len > 0) ? PQmblen(line, pset.encoding) : 0); ! ! for (i = 0; (i < len) && (success || !die_on_error); ADVANCE_1) { /* was the previous character a backslash? */ ! if (i > 0 && line[i - prevlen] == '\\') bslash_count++; else bslash_count = 0; *************** *** 309,338 **** in_quote = 0; } ! /* in extended comment? */ ! else if (in_xcomment) ! { ! if (line[i] == '*' && line[i + thislen] == '/') ! { ! if (xcdepth > 0) ! xcdepth--; ! else { ! in_xcomment = false; ADVANCE_1; } - } - else if (line[i] == '/' && line[i + thislen] == '*') - xcdepth++; - } ! /* start of extended comment? */ ! else if (line[i] == '/' && line[i + thislen] == '*') { ! xcdepth = 0; ! in_xcomment = true; ADVANCE_1; } /* start of quote? */ else if (line[i] == '\'' || line[i] == '"') --- 271,294 ---- in_quote = 0; } ! /* start of extended comment? */ ! else if (line[i] == '/' && line[i + thislen] == '*') { ! in_xcomment++; ! if (in_xcomment == 1) ADVANCE_1; } ! /* end of extended comment? */ ! else if (line[i] == '*' && line[i + thislen] == '/') { ! in_xcomment--; ! if (in_xcomment <= 0) ! { ! in_xcomment = 0; ADVANCE_1; } + } /* start of quote? */ else if (line[i] == '\'' || line[i] == '"') *************** *** 354,360 **** /* colon -> substitute variable */ /* we need to be on the watch for the '::' operator */ ! else if (line[i] == ':' && !was_bslash && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0 && !(prevlen > 0 && line[i - prevlen] == ':') ) --- 310,316 ---- /* colon -> substitute variable */ /* we need to be on the watch for the '::' operator */ ! else if (line[i] == ':' && !bslash_count && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0 && !(prevlen > 0 && line[i - prevlen] == ':') ) *************** *** 412,418 **** } /* semicolon? then send query */ ! else if (line[i] == ';' && !was_bslash && !paren_level) { line[i] = '\0'; /* is there anything else on the line? */ --- 368,374 ---- } /* semicolon? then send query */ ! else if (line[i] == ';' && !bslash_count && !paren_level) { line[i] = '\0'; /* is there anything else on the line? */ *************** *** 443,449 **** * if you have a burning need to send a semicolon or colon to * the backend ... */ ! else if (was_bslash && (line[i] == ';' || line[i] == ':')) { /* remove the backslash */ memmove(line + i - prevlen, line + i, len - i + 1); --- 399,405 ---- * if you have a burning need to send a semicolon or colon to * the backend ... */ ! else if (bslash_count && (line[i] == ';' || line[i] == ':')) { /* remove the backslash */ memmove(line + i - prevlen, line + i, len - i + 1); *************** *** 452,458 **** } /* backslash command */ ! else if (was_bslash) { const char *end_of_cmd = NULL; --- 408,414 ---- } /* backslash command */ ! else if (bslash_count) { const char *end_of_cmd = NULL; *************** *** 500,514 **** paren_level = 0; /* process anything left after the backslash command */ ! i += end_of_cmd - &line[i]; query_start = i; } - - - /* stop the script after error */ - if (!success && die_on_error) - break; - } /* for (line) */ --- 456,464 ---- paren_level = 0; /* process anything left after the backslash command */ ! i = end_of_cmd - line; query_start = i; } } /* for (line) */ *************** *** 534,558 **** if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE")) { success = SendQuery(query_buf->data); ! slashCmdStatus = success ? CMD_SEND : CMD_ERROR; resetPQExpBuffer(previous_buf); appendPQExpBufferStr(previous_buf, query_buf->data); resetPQExpBuffer(query_buf); } ! ! if (!success && die_on_error && !pset.cur_cmd_interactive) { successResult = EXIT_USER; - break; - } - - /* Have we lost the db connection? */ ! if (pset.db == NULL && !pset.cur_cmd_interactive) ! { successResult = EXIT_BADCONN; - break; } } /* while !endoffile/session */ --- 484,502 ---- if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE")) { success = SendQuery(query_buf->data); ! slashCmdStatus = (success ? CMD_SEND : CMD_ERROR); resetPQExpBuffer(previous_buf); appendPQExpBufferStr(previous_buf, query_buf->data); resetPQExpBuffer(query_buf); } ! if (!pset.cur_cmd_interactive) { + if (!success && die_on_error) successResult = EXIT_USER; /* Have we lost the db connection? */ ! else if (!pset.db) successResult = EXIT_BADCONN; } } /* while !endoffile/session */ diff -r -c -B -b pgsql.orig/src/bin/psql/prompt.c pgsql.patch2/src/bin/psql/prompt.c *** pgsql.orig/src/bin/psql/prompt.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/prompt.c 2003-02-27 16:52:47.000000000 +0100 *************** *** 69,85 **** char buf[MAX_PROMPT_SIZE + 1]; bool esc = false; const char *p; ! const char *prompt_string; ! if (status == PROMPT_READY) ! prompt_string = GetVariable(pset.vars, "PROMPT1"); ! else if (status == PROMPT_CONTINUE || status == PROMPT_SINGLEQUOTE || status == PROMPT_DOUBLEQUOTE || status == PROMPT_COMMENT || status == PROMPT_PAREN) ! prompt_string = GetVariable(pset.vars, "PROMPT2"); ! else if (status == PROMPT_COPY) ! prompt_string = GetVariable(pset.vars, "PROMPT3"); ! else ! prompt_string = "? "; destination[0] = '\0'; --- 69,98 ---- char buf[MAX_PROMPT_SIZE + 1]; bool esc = false; const char *p; ! const char *prompt_string = "? "; ! const char *prompt_name = NULL; ! switch (status) ! { ! case PROMPT_READY: ! prompt_name = "PROMPT1"; ! break; ! ! case PROMPT_CONTINUE: ! case PROMPT_SINGLEQUOTE: ! case PROMPT_DOUBLEQUOTE: ! case PROMPT_COMMENT: ! case PROMPT_PAREN: ! prompt_name = "PROMPT2"; ! break; ! ! case PROMPT_COPY: ! prompt_name = "PROMPT3"; ! break; ! } + if (prompt_name) + prompt_string = GetVariable(pset.vars, prompt_name); destination[0] = '\0'; *************** *** 92,112 **** { switch (*p) { - case '%': - strcpy(buf, "%"); - break; - /* Current database */ case '/': if (pset.db) strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE); break; case '~': - { - const char *var; - if (pset.db) { if (strcmp(PQdb(pset.db), PQuser(pset.db)) == 0 || ((var = getenv("PGDATABASE")) && strcmp(var, PQdb(pset.db)) == 0)) strcpy(buf, "~"); --- 105,119 ---- { switch (*p) { /* Current database */ case '/': if (pset.db) strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE); 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)) strcpy(buf, "~"); *************** *** 114,120 **** strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE); } break; ! } /* DB server hostname (long/short) */ case 'M': case 'm': --- 121,127 ---- strncpy(buf, PQdb(pset.db), MAX_PROMPT_SIZE); } break; ! /* DB server hostname (long/short) */ case 'M': case 'm': *************** *** 164,178 **** case '7': case '8': case '9': ! { ! long int l; ! char *end; ! ! l = strtol(p, &end, 0); ! sprintf(buf, "%c", (unsigned char) l); ! p = end - 1; break; - } case 'R': switch (status) --- 171,178 ---- case '7': case '8': case '9': ! *buf = parse_char(&p); break; case 'R': switch (status) diff -r -c -B -b pgsql.orig/src/bin/psql/startup.c pgsql.patch2/src/bin/psql/startup.c *** pgsql.orig/src/bin/psql/startup.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/startup.c 2003-02-27 16:08:26.000000000 +0100 *************** *** 251,260 **** */ else if (options.action == ACT_SINGLE_SLASH) { ! const char *value; ! ! if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0) puts(options.action_string); successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; } --- 251,259 ---- */ else if (options.action == ACT_SINGLE_SLASH) { ! if (VariableEquals(pset.vars, "ECHO", "all")) puts(options.action_string); + successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; } *************** *** 264,273 **** */ else if (options.action == ACT_SINGLE_QUERY) { ! const char *value; ! ! if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0) puts(options.action_string); successResult = SendQuery(options.action_string) ? EXIT_SUCCESS : EXIT_FAILURE; } --- 263,271 ---- */ else if (options.action == ACT_SINGLE_QUERY) { ! if (VariableEquals(pset.vars, "ECHO", "all")) puts(options.action_string); + successResult = SendQuery(options.action_string) ? EXIT_SUCCESS : EXIT_FAILURE; } diff -r -c -B -b pgsql.orig/src/bin/psql/variables.c pgsql.patch2/src/bin/psql/variables.c *** pgsql.orig/src/bin/psql/variables.c 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/variables.c 2003-02-27 18:09:27.000000000 +0100 *************** *** 68,73 **** --- 68,141 ---- } + bool + VariableEquals(VariableSpace space, const char name[], const char value[]) + { + const char *var; + var = GetVariable(space, name); + return var && (strcmp(var, value) == 0); + } + + + int + GetVariableNum(VariableSpace space, + const char name[], + int defaultval, + int faultval, + bool allowtrail) + { + const char *var; + int result; + + var = GetVariable(space, name); + if (!var) + result = defaultval; + else if (!var[0]) + result = faultval; + else + { + char *end; + result = strtol(var, &end, 0); + if (!allowtrail && *end) + result = faultval; + } + + return result; + } + + + int + SwitchVariable(VariableSpace space, const char name[], const char *opt, ...) + { + int result; + const char *var; + + var = GetVariable(space, name); + if (var) + { + va_list args; + va_start(args, opt); + for (result=1; opt && (strcmp(var, opt) != 0); result++) + opt = va_arg(args,const char *); + + if (!opt) result = var_notfound; + va_end(args); + } + else + result = var_notset; + + return result; + } + + + void + PrintVariables(VariableSpace space) + { + struct _variable *ptr; + for (ptr = space->next; ptr; ptr = ptr->next) + printf("%s = '%s'\n", ptr->name, ptr->value); + } + bool SetVariable(VariableSpace space, const char *name, const char *value) diff -r -c -B -b pgsql.orig/src/bin/psql/variables.h pgsql.patch2/src/bin/psql/variables.h *** pgsql.orig/src/bin/psql/variables.h 2003-02-22 16:24:27.000000000 +0100 --- pgsql.patch2/src/bin/psql/variables.h 2003-02-27 18:04:08.000000000 +0100 *************** *** 31,36 **** --- 31,59 ---- VariableSpace CreateVariableSpace(void); const char *GetVariable(VariableSpace space, const char *name); bool GetVariableBool(VariableSpace space, const char *name); + bool VariableEquals(VariableSpace space, const char name[], const char *opt); + + /* Read numeric variable, or defaultval if it is not set, or faultval if its + * value is not a valid numeric string. If allowtrail is false, this will + * include the case where there are trailing characters after the number. + */ + int GetVariableNum(VariableSpace space, + const char name[], + int defaultval, + int faultval, + bool allowtrail); + + + /* Find value of variable among NULL-terminated list of alternative + * options. Returns var_notset if the variable was not set, var_notfound if its + * value did not occur in the list of options, or the number of the matching + * option. The first option is 1, the second is 2 and so on. + */ + enum { var_notset = 0, var_notfound = -1 }; + int SwitchVariable(VariableSpace space, const char name[], const char *opt,...); + + void PrintVariables(VariableSpace space); + bool SetVariable(VariableSpace space, const char *name, const char *value); bool SetVariableBool(VariableSpace space, const char *name); bool DeleteVariable(VariableSpace space, const char *name);