@@ -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