diff options
Diffstat (limited to 'src/bin/psql/mainloop.c')
-rw-r--r-- | src/bin/psql/mainloop.c | 146 |
1 files changed, 45 insertions, 101 deletions
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index e9ed1a621e5..27b5a560d5f 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.52 2003/03/20 06:00:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.53 2003/03/20 06:43:35 momjian Exp $ */ #include "postgres_fe.h" #include "mainloop.h" @@ -40,16 +40,14 @@ MainLoop(FILE *source) char *line; /* current line of input */ int len; /* length of the line */ volatile int successResult = EXIT_SUCCESS; - volatile backslashResult slashCmdStatus; + volatile backslashResult slashCmdStatus = CMD_UNKNOWN; 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; + 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; - const char *var; volatile unsigned int bslash_count = 0; int i, @@ -81,16 +79,12 @@ MainLoop(FILE *source) 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) + while (successResult == EXIT_SUCCESS) { /* * Welcome code for Control-C @@ -109,6 +103,7 @@ MainLoop(FILE *source) } cancel_pressed = false; + fflush(stdout); } #ifndef WIN32 @@ -118,15 +113,16 @@ MainLoop(FILE *source) if (pset.cur_cmd_interactive) { - fputc('\n', stdout); + putc('\n', stdout); resetPQExpBuffer(query_buf); /* reset parsing state */ - in_xcomment = false; + in_xcomment = 0; in_quote = 0; paren_level = 0; count_eof = 0; slashCmdStatus = CMD_UNKNOWN; + fflush(stdout); } else { @@ -151,23 +147,21 @@ MainLoop(FILE *source) line = xstrdup(query_buf->data); resetPQExpBuffer(query_buf); /* reset parsing state since we are rescanning whole line */ - in_xcomment = false; + in_xcomment = 0; 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) + 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 == '"') @@ -185,7 +179,6 @@ MainLoop(FILE *source) } else line = gets_fromFile(source); - } /* Setting this will not have effect until next line. */ @@ -203,50 +196,21 @@ MainLoop(FILE *source) { 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 */ - } + count_eof++; - if (getout) - { - if (QUIET()) - putc('\n', stdout); - else - puts("\\q"); - break; - } - else + 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"); } - else -/* not interactive */ break; } - else + count_eof = 0; pset.lineno++; @@ -259,8 +223,7 @@ MainLoop(FILE *source) } /* echo back if flag is set */ - var = GetVariable(pset.vars, "ECHO"); - if (!pset.cur_cmd_interactive && var && strcmp(var, "all") == 0) + if (!pset.cur_cmd_interactive && VariableEquals(pset.vars, "ECHO", "all")) puts(line); fflush(stdout); @@ -276,14 +239,13 @@ MainLoop(FILE *source) #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) + 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? */ - bool was_bslash = (i > 0 && line[i - prevlen] == '\\'); - - if (was_bslash) + if (i > 0 && line[i - prevlen] == '\\') bslash_count++; else bslash_count = 0; @@ -308,30 +270,24 @@ MainLoop(FILE *source) in_quote = 0; } - /* in extended comment? */ - else if (in_xcomment) - { - if (line[i] == '*' && line[i + thislen] == '/') - { - if (xcdepth > 0) - xcdepth--; - else + /* start of extended comment? */ + else if (line[i] == '/' && line[i + thislen] == '*') { - in_xcomment = false; + in_xcomment++; + if (in_xcomment == 1) ADVANCE_1; } - } - else if (line[i] == '/' && line[i + thislen] == '*') - xcdepth++; - } - /* start of extended comment? */ - else if (line[i] == '/' && line[i + thislen] == '*') + /* end of extended comment? */ + else if (line[i] == '*' && line[i + thislen] == '/') { - xcdepth = 0; - in_xcomment = true; + in_xcomment--; + if (in_xcomment <= 0) + { + in_xcomment = 0; ADVANCE_1; } + } /* start of quote? */ else if (line[i] == '\'' || line[i] == '"') @@ -353,7 +309,7 @@ MainLoop(FILE *source) /* colon -> substitute variable */ /* we need to be on the watch for the '::' operator */ - else if (line[i] == ':' && !was_bslash + else if (line[i] == ':' && !bslash_count && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0 && !(prevlen > 0 && line[i - prevlen] == ':') ) @@ -411,7 +367,7 @@ MainLoop(FILE *source) } /* semicolon? then send query */ - else if (line[i] == ';' && !was_bslash && !paren_level) + else if (line[i] == ';' && !bslash_count && !paren_level) { line[i] = '\0'; /* is there anything else on the line? */ @@ -442,7 +398,7 @@ MainLoop(FILE *source) * if you have a burning need to send a semicolon or colon to * the backend ... */ - else if (was_bslash && (line[i] == ';' || line[i] == ':')) + else if (bslash_count && (line[i] == ';' || line[i] == ':')) { /* remove the backslash */ memmove(line + i - prevlen, line + i, len - i + 1); @@ -451,7 +407,7 @@ MainLoop(FILE *source) } /* backslash command */ - else if (was_bslash) + else if (bslash_count) { const char *end_of_cmd = NULL; @@ -499,15 +455,9 @@ MainLoop(FILE *source) paren_level = 0; /* process anything left after the backslash command */ - i += end_of_cmd - &line[i]; + i = end_of_cmd - line; query_start = i; } - - - /* stop the script after error */ - if (!success && die_on_error) - break; - } /* for (line) */ @@ -533,25 +483,19 @@ MainLoop(FILE *source) if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE")) { success = SendQuery(query_buf->data); - slashCmdStatus = success ? CMD_SEND : CMD_ERROR; + 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) + if (!pset.cur_cmd_interactive) { + if (!success && die_on_error) successResult = EXIT_USER; - break; - } - - /* Have we lost the db connection? */ - if (pset.db == NULL && !pset.cur_cmd_interactive) - { + else if (!pset.db) successResult = EXIT_BADCONN; - break; } } /* while !endoffile/session */ |