3333#endif
3434
3535
36- /* functions for use in this file only */
36+ /* functions for use in this file */
3737
3838static backslashResult exec_command (const char * cmd ,
3939 char * const * options ,
4040 const char * options_string ,
4141 PQExpBuffer query_buf ,
4242 PsqlSettings * pset );
4343
44- static bool
45- do_edit (const char * filename_arg , PQExpBuffer query_buf );
44+ static bool do_edit (const char * filename_arg , PQExpBuffer query_buf );
4645
47- static char *
48- unescape (const char * source , PsqlSettings * pset );
46+ static char * unescape (const char * source , PsqlSettings * pset );
47+
48+ static bool do_connect (const char * new_dbname ,
49+ const char * new_user ,
50+ PsqlSettings * pset );
4951
50- static bool
51- do_shell (const char * command );
5252
53+ static bool do_shell (const char * command );
54+
55+ /*
56+ * Perhaps this should be changed to "infinity",
57+ * but there is no convincing reason to bother
58+ * at this point.
59+ */
60+ #define NR_OPTIONS 16
5361
5462
5563/*----------
@@ -78,7 +86,7 @@ HandleSlashCmds(PsqlSettings *pset,
7886{
7987 backslashResult status = CMD_SKIP_LINE ;
8088 char * my_line ;
81- char * options [17 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
89+ char * options [NR_OPTIONS + 1 ] ;
8290 char * token ;
8391 const char * options_string = NULL ;
8492 const char * cmd ;
@@ -120,7 +128,7 @@ HandleSlashCmds(PsqlSettings *pset,
120128 i = 0 ;
121129 token = strtokx (options_string , " \t" , "\"'`" , '\\' , & quote , & pos );
122130
123- for (i = 0 ; token && i < 16 ; i ++ )
131+ for (i = 0 ; token && i < NR_OPTIONS ; i ++ )
124132 {
125133 switch (quote )
126134 {
@@ -194,14 +202,15 @@ HandleSlashCmds(PsqlSettings *pset,
194202 options [i ] = xstrdup (interpolate_var (token + 1 , pset ));
195203 else
196204 options [i ] = xstrdup (token );
197- break ;
198205 }
199206
200207 if (continue_parse )
201208 break ;
202209
203210 token = strtokx (NULL , " \t" , "\"'`" , '\\' , & quote , & pos );
204- }
211+ } /* for */
212+
213+ options [i ] = NULL ;
205214 }
206215
207216 cmd = my_line ;
@@ -216,11 +225,11 @@ HandleSlashCmds(PsqlSettings *pset,
216225 * arguments to start immediately after the command, but that is
217226 * no longer encouraged.
218227 */
219- const char * new_options [17 ];
228+ const char * new_options [NR_OPTIONS + 1 ];
220229 char new_cmd [2 ];
221230 int i ;
222231
223- for (i = 1 ; i < 17 ; i ++ )
232+ for (i = 1 ; i < NR_OPTIONS + 1 ; i ++ )
224233 new_options [i ] = options [i - 1 ];
225234 new_options [0 ] = cmd + 1 ;
226235
@@ -249,7 +258,7 @@ HandleSlashCmds(PsqlSettings *pset,
249258 }
250259
251260 /* clean up */
252- for (i = 0 ; i < 16 && options [i ]; i ++ )
261+ for (i = 0 ; i < NR_OPTIONS && options [i ]; i ++ )
253262 free (options [i ]);
254263
255264 free (my_line );
@@ -274,10 +283,7 @@ exec_command(const char *cmd,
274283 backslashResult status = CMD_SKIP_LINE ;
275284
276285
277- /*
278- * \a -- toggle field alignment This is deprecated and makes no sense,
279- * but we keep it around.
280- */
286+ /* \a -- toggle field alignment This makes little sense but we keep it around. */
281287 if (strcmp (cmd , "a" ) == 0 )
282288 {
283289 if (pset -> popt .topt .format != PRINT_ALIGNED )
@@ -287,22 +293,19 @@ exec_command(const char *cmd,
287293 }
288294
289295
290- /*
291- * \C -- override table title (formerly change HTML caption) This is
292- * deprecated.
293- */
296+ /* \C -- override table title (formerly change HTML caption) */
294297 else if (strcmp (cmd , "C" ) == 0 )
295298 success = do_pset ("title" , options [0 ], & pset -> popt , quiet );
296299
297300
298-
299- /*
301+ /*----------
300302 * \c or \connect -- connect to new database or as different user
301303 *
302- * \c foo bar : connect to db "foo" as user "bar" \c foo [-] :
303- * connect to db "foo" as current user \c - bar : connect to
304- * current db as user "bar" \c : connect to default db as
305- * default user
304+ * \c foo bar: connect to db "foo" as user "bar"
305+ * \c foo [-]: connect to db "foo" as current user
306+ * \c - bar: connect to current db as user "bar"
307+ * \c: connect to default db as default user
308+ *----------
306309 */
307310 else if (strcmp (cmd , "c" ) == 0 || strcmp (cmd , "connect" ) == 0 )
308311 {
@@ -335,45 +338,49 @@ exec_command(const char *cmd,
335338 /* \d* commands */
336339 else if (cmd [0 ] == 'd' )
337340 {
341+ bool show_verbose = strchr (cmd , '+' ) ? true : false;
342+ bool show_desc = strchr (cmd , '?' ) ? true : false;
343+
338344 switch (cmd [1 ])
339345 {
340346 case '\0' :
347+ case '?' :
341348 if (options [0 ])
342- success = describeTableDetails (options [0 ], pset );
349+ success = describeTableDetails (options [0 ], pset , show_desc );
343350 else
344- success = listTables ( "tvs" , NULL , pset ); /* standard listing of
345- * interesting things */
351+ /* standard listing of interesting things */
352+ success = listTables ( "tvs" , NULL , pset , show_desc );
346353 break ;
347354 case 'a' :
348- success = describeAggregates (options [0 ], pset );
355+ success = describeAggregates (options [0 ], pset , show_verbose , show_desc );
349356 break ;
350357 case 'd' :
351358 success = objectDescription (options [0 ], pset );
352359 break ;
353360 case 'f' :
354- success = describeFunctions (options [0 ], pset );
361+ success = describeFunctions (options [0 ], pset , show_verbose , show_desc );
355362 break ;
356363 case 'l' :
357- success = do_lo_list (pset );
364+ success = do_lo_list (pset , show_desc );
358365 break ;
359366 case 'o' :
360- success = describeOperators (options [0 ], pset );
367+ success = describeOperators (options [0 ], pset , show_verbose , show_desc );
361368 break ;
362369 case 'p' :
363370 success = permissionsList (options [0 ], pset );
364371 break ;
365372 case 'T' :
366- success = describeTypes (options [0 ], pset );
373+ success = describeTypes (options [0 ], pset , show_verbose , show_desc );
367374 break ;
368375 case 't' :
369376 case 'v' :
370377 case 'i' :
371378 case 's' :
372379 case 'S' :
373380 if (cmd [1 ] == 'S' && cmd [2 ] == '\0' )
374- success = listTables ("Stvs" , NULL , pset );
381+ success = listTables ("Stvs" , NULL , pset , show_desc );
375382 else
376- success = listTables (& cmd [1 ], options [0 ], pset );
383+ success = listTables (& cmd [1 ], options [0 ], pset , show_desc );
377384 break ;
378385 default :
379386 status = CMD_UNKNOWN ;
@@ -399,14 +406,10 @@ exec_command(const char *cmd,
399406 fputs ("\n" , stdout );
400407 }
401408
402- /*
403- * \f -- change field separator (This is deprecated in favour of
404- * \pset.)
405- */
409+ /* \f -- change field separator */
406410 else if (strcmp (cmd , "f" ) == 0 )
407411 success = do_pset ("fieldsep" , options [0 ], & pset -> popt , quiet );
408412
409-
410413 /* \g means send query */
411414 else if (strcmp (cmd , "g" ) == 0 )
412415 {
@@ -419,12 +422,27 @@ exec_command(const char *cmd,
419422
420423 /* help */
421424 else if (strcmp (cmd , "h" ) == 0 || strcmp (cmd , "help" ) == 0 )
422- helpSQL (options_string );
423-
425+ {
426+ char buf [256 ] = "" ;
427+ int i ;
428+ for (i = 0 ; options && options [i ] && strlen (buf )< 255 ; i ++ )
429+ {
430+ strncat (buf , options [i ], 255 - strlen (buf ));
431+ if (strlen (buf )< 255 && options [i + 1 ])
432+ strcat (buf , " " );
433+ }
434+ buf [255 ] = '\0' ;
435+ helpSQL (buf );
436+ }
424437
425438 /* HTML mode */
426439 else if (strcmp (cmd , "H" ) == 0 || strcmp (cmd , "html" ) == 0 )
427- success = do_pset ("format" , "html" , & pset -> popt , quiet );
440+ {
441+ if (pset -> popt .topt .format != PRINT_HTML )
442+ success = do_pset ("format" , "html" , & pset -> popt , quiet );
443+ else
444+ success = do_pset ("format" , "aligned" , & pset -> popt , quiet );
445+ }
428446
429447
430448 /* \i is include file */
@@ -439,9 +457,12 @@ exec_command(const char *cmd,
439457 success = process_file (options [0 ], pset );
440458 }
441459
460+
442461 /* \l is list databases */
443462 else if (strcmp (cmd , "l" ) == 0 || strcmp (cmd , "list" ) == 0 )
444- success = listAllDbs (pset );
463+ success = listAllDbs (pset , false);
464+ else if (strcmp (cmd , "l?" ) == 0 || strcmp (cmd , "list?" ) == 0 )
465+ success = listAllDbs (pset , true);
445466
446467
447468 /* large object things */
@@ -470,7 +491,9 @@ exec_command(const char *cmd,
470491 }
471492
472493 else if (strcmp (cmd + 3 , "list" ) == 0 )
473- success = do_lo_list (pset );
494+ success = do_lo_list (pset , false);
495+ else if (strcmp (cmd + 3 , "list?" ) == 0 )
496+ success = do_lo_list (pset , true);
474497
475498 else if (strcmp (cmd + 3 , "unlink" ) == 0 )
476499 {
@@ -828,7 +851,7 @@ unescape(const char *source, PsqlSettings *pset)
828851 * Returns true if all ok, false if the new connection couldn't be established
829852 * but the old one was set back. Otherwise it terminates the program.
830853 */
831- bool
854+ static bool
832855do_connect (const char * new_dbname , const char * new_user , PsqlSettings * pset )
833856{
834857 PGconn * oldconn = pset -> db ;
0 commit comments