Skip to content

Commit df9f599

Browse files
committed
psql: Add quit/help behavior/hint, for other tool portability
Issuing 'quit'/'exit' in an empty psql buffer exits psql. Issuing 'quit'/'exit' in a non-empty psql buffer alone on a line with no prefix whitespace issues a hint on how to exit. Also add similar 'help' hints for 'help' in a non-empty psql buffer. Reported-by: Everaldo Canuto Discussion: https://postgr.es/m/flat/CALVFHFb-C_5_94hueWg6Dd0zu7TfbpT7hzsh9Zf0DEDOSaAnfA%40mail.gmail.com Author: original author Robert Haas, modified by me
1 parent eab30cc commit df9f599

File tree

1 file changed

+100
-13
lines changed

1 file changed

+100
-13
lines changed

src/bin/psql/mainloop.c

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,108 @@ MainLoop(FILE *source)
216216
continue;
217217
}
218218

219-
/* A request for help? Be friendly and give them some guidance */
220-
if (pset.cur_cmd_interactive && query_buf->len == 0 &&
221-
pg_strncasecmp(line, "help", 4) == 0 &&
222-
(line[4] == '\0' || line[4] == ';' || isspace((unsigned char) line[4])))
219+
/* Recognize "help", "quit", "exit" only in interactive mode */
220+
if (pset.cur_cmd_interactive)
223221
{
224-
free(line);
225-
puts(_("You are using psql, the command-line interface to PostgreSQL."));
226-
printf(_("Type: \\copyright for distribution terms\n"
227-
" \\h for help with SQL commands\n"
228-
" \\? for help with psql commands\n"
229-
" \\g or terminate with semicolon to execute query\n"
230-
" \\q to quit\n"));
222+
char *first_word = line;
223+
char *rest_of_line = NULL;
224+
bool found_help = false;
225+
bool found_exit_or_quit = false;
231226

232-
fflush(stdout);
233-
continue;
227+
/* Search for the words we recognize; must be first word */
228+
if (pg_strncasecmp(first_word, "help", 4) == 0)
229+
{
230+
rest_of_line = first_word + 4;
231+
found_help = true;
232+
}
233+
else if (pg_strncasecmp(first_word, "exit", 4) == 0 ||
234+
pg_strncasecmp(first_word, "quit", 4) == 0)
235+
{
236+
rest_of_line = first_word + 4;
237+
found_exit_or_quit = true;
238+
}
239+
240+
/*
241+
* If we found a command word, check whether the rest of the line
242+
* contains only whitespace plus maybe one semicolon. If not,
243+
* ignore the command word after all.
244+
*/
245+
if (rest_of_line != NULL)
246+
{
247+
/*
248+
* Ignore unless rest of line is whitespace, plus maybe one
249+
* semicolon
250+
*/
251+
while (isspace((unsigned char) *rest_of_line))
252+
++rest_of_line;
253+
if (*rest_of_line == ';')
254+
++rest_of_line;
255+
while (isspace((unsigned char) *rest_of_line))
256+
++rest_of_line;
257+
if (*rest_of_line != '\0')
258+
{
259+
found_help = false;
260+
found_exit_or_quit = false;
261+
}
262+
}
263+
264+
/*
265+
* "help" is only a command when the query buffer is empty, but we
266+
* emit a one-line message even when it isn't to help confused
267+
* users. The text is still added to the query buffer in that
268+
* case.
269+
*/
270+
if (found_help)
271+
{
272+
if (query_buf->len != 0)
273+
#ifndef WIN32
274+
puts(_("Use \\? for help or press control-C to clear the input buffer."));
275+
#else
276+
puts(_("Use \\? for help."));
277+
#endif
278+
else
279+
{
280+
puts(_("You are using psql, the command-line interface to PostgreSQL."));
281+
printf(_("Type: \\copyright for distribution terms\n"
282+
" \\h for help with SQL commands\n"
283+
" \\? for help with psql commands\n"
284+
" \\g or terminate with semicolon to execute query\n"
285+
" \\q to quit\n"));
286+
free(line);
287+
fflush(stdout);
288+
continue;
289+
}
290+
}
291+
/*
292+
* "quit" and "exit" are only commands when the query buffer is
293+
* empty, but we emit a one-line message even when it isn't to
294+
* help confused users. The text is still added to the query
295+
* buffer in that case.
296+
*/
297+
if (found_exit_or_quit)
298+
{
299+
if (query_buf->len != 0)
300+
{
301+
if (prompt_status == PROMPT_READY ||
302+
prompt_status == PROMPT_CONTINUE ||
303+
prompt_status == PROMPT_PAREN)
304+
puts(_("Use \\q to quit."));
305+
else
306+
#ifndef WIN32
307+
puts(_("Use control-D to quit."));
308+
#else
309+
puts(_("Use control-C to quit."));
310+
#endif
311+
}
312+
else
313+
{
314+
/* exit app */
315+
free(line);
316+
fflush(stdout);
317+
successResult = EXIT_SUCCESS;
318+
break;
319+
}
320+
}
234321
}
235322

236323
/* echo back if flag is set, unless interactive */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy