~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.c

  • Committer: Jim Winstead
  • Date: 2008-07-19 02:56:45 UTC
  • mto: (202.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 207.
  • Revision ID: jimw@mysql.com-20080719025645-w2pwytebgzusjzjb
Various fixes to enable compilation on Mac OS X, and remove the glib dependency.
Temporarily disables tab-completion in the drizzle client until an appropriate
autoconf check can be added/enabled.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 **/
35
35
 
36
36
#include "client_priv.h"
 
37
#include <my_sys.h>
37
38
#include <m_ctype.h>
38
39
#include <stdarg.h>
39
40
#include <my_dir.h>
49
50
#include <locale.h>
50
51
#endif
51
52
 
52
 
#include <glib.h>
53
 
 
54
53
const char *VER= "14.14";
55
54
 
56
55
/* Don't try to make a nice table if the data is too big */
153
152
  *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
154
153
static char *histfile;
155
154
static char *histfile_tmp;
156
 
static GString *glob_buffer;
157
 
static GString *processed_prompt= NULL;
158
 
static GString *default_prompt= NULL;
 
155
static DYNAMIC_STRING *glob_buffer;
 
156
static DYNAMIC_STRING *processed_prompt= NULL;
 
157
static char *default_prompt= NULL;
159
158
static char *full_username=0,*part_username=0;
160
159
static int wait_time = 5;
161
160
static STATUS status;
199
198
static int get_options(int argc,char **argv);
200
199
bool get_one_option(int optid, const struct my_option *opt,
201
200
                    char *argument);
202
 
static int com_quit(GString *str,char*),
203
 
  com_go(GString *str,char*), com_ego(GString *str,char*),
204
 
  com_print(GString *str,char*),
205
 
  com_help(GString *str,char*), com_clear(GString *str,char*),
206
 
  com_connect(GString *str,char*), com_status(GString *str,char*),
207
 
  com_use(GString *str,char*), com_source(GString *str, char*),
208
 
  com_rehash(GString *str, char*), com_tee(GString *str, char*),
209
 
  com_notee(GString *str, char*), com_charset(GString *str,char*),
210
 
  com_prompt(GString *str, char*), com_delimiter(GString *str, char*),
211
 
  com_warnings(GString *str, char*), com_nowarnings(GString *str, char*),
212
 
  com_nopager(GString *str, char*), com_pager(GString *str, char*);
 
201
static int com_quit(DYNAMIC_STRING *str,char*),
 
202
  com_go(DYNAMIC_STRING *str,char*), com_ego(DYNAMIC_STRING *str,char*),
 
203
  com_print(DYNAMIC_STRING *str,char*),
 
204
  com_help(DYNAMIC_STRING *str,char*), com_clear(DYNAMIC_STRING *str,char*),
 
205
  com_connect(DYNAMIC_STRING *str,char*), com_status(DYNAMIC_STRING *str,char*),
 
206
  com_use(DYNAMIC_STRING *str,char*), com_source(DYNAMIC_STRING *str, char*),
 
207
  com_rehash(DYNAMIC_STRING *str, char*), com_tee(DYNAMIC_STRING *str, char*),
 
208
  com_notee(DYNAMIC_STRING *str, char*), com_charset(DYNAMIC_STRING *str,char*),
 
209
  com_prompt(DYNAMIC_STRING *str, char*), com_delimiter(DYNAMIC_STRING *str, char*),
 
210
  com_warnings(DYNAMIC_STRING *str, char*), com_nowarnings(DYNAMIC_STRING *str, char*),
 
211
  com_nopager(DYNAMIC_STRING *str, char*), com_pager(DYNAMIC_STRING *str, char*);
213
212
 
214
213
static int read_and_execute(bool interactive);
215
214
static int sql_connect(char *host,char *database,char *user,char *password,
236
235
typedef struct {
237
236
  const char *name;             /* User printable name of the function. */
238
237
  char cmd_char;                /* msql command character */
239
 
  int (*func)(GString *str,char *); /* Function to call to do the job. */
 
238
  int (*func)(DYNAMIC_STRING *str,char *); /* Function to call to do the job. */
240
239
  bool takes_params;            /* Max parameters for command */
241
240
  const char *doc;              /* Documentation for this function.  */
242
241
} COMMANDS;
995
994
int history_length;
996
995
static int not_in_history(const char *line);
997
996
static void initialize_readline (const char *name);
998
 
static void fix_history(GString *final_command);
 
997
static void fix_history(DYNAMIC_STRING *final_command);
999
998
 
1000
999
static COMMANDS *find_command(char *name,char cmd_name);
1001
 
static bool add_line(GString *buffer,char *line,char *in_string,
 
1000
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1002
1001
                     bool *ml_comment);
1003
 
static void remove_cntrl(GString *buffer);
 
1002
static void remove_cntrl(DYNAMIC_STRING *buffer);
1004
1003
static void print_table_data(MYSQL_RES *result);
1005
1004
static void print_table_data_html(MYSQL_RES *result);
1006
1005
static void print_table_data_xml(MYSQL_RES *result);
1023
1022
 
1024
1023
  MY_INIT(argv[0]);
1025
1024
  delimiter_str= delimiter;
1026
 
  default_prompt = g_string_new(g_strdup(getenv("DRIZZLE_PS1") ?
1027
 
                                         getenv("DRIZZLE_PS1") :
1028
 
                                         "drizzle>> "));
1029
 
  current_prompt = g_strdup(default_prompt->str);
1030
 
  processed_prompt = g_string_sized_new(16);
 
1025
  default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
 
1026
                            getenv("DRIZZLE_PS1") :
 
1027
                            "drizzle>> ", MYF(0));
 
1028
  current_prompt= my_strdup(default_prompt, MYF(0));
 
1029
 
 
1030
  processed_prompt= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
1031
  init_dynamic_string(processed_prompt, "", 32, 32);
 
1032
 
1031
1033
  prompt_counter=0;
1032
1034
 
1033
1035
  outfile[0]=0;                 // no (default) outfile
1114
1116
 
1115
1117
  put_info("Welcome to the Drizzle client..  Commands end with ; or \\g.",
1116
1118
           INFO_INFO,0,0);
1117
 
  glob_buffer = g_string_sized_new(512);
1118
 
  g_string_printf(glob_buffer,
1119
 
                  "Your Drizzle connection id is %u\nServer version: %s\n",
1120
 
                  mysql_thread_id(&mysql), server_version_string(&mysql));
1121
 
  put_info(glob_buffer->str,INFO_INFO,0,0);
1122
 
  g_string_truncate(glob_buffer,0);
 
1119
 
 
1120
  glob_buffer= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
1121
  init_dynamic_string(glob_buffer, "", 512, 512);
 
1122
 
 
1123
  /* this is a slight abuse of the DYNAMIC_STRING interface. deal. */
 
1124
  sprintf(glob_buffer->str,
 
1125
          "Your Drizzle connection id is %u\nServer version: %s\n",
 
1126
          mysql_thread_id(&mysql), server_version_string(&mysql));
 
1127
  put_info(glob_buffer->str, INFO_INFO, 0, 0);
 
1128
  dynstr_set(glob_buffer, NULL);
1123
1129
 
1124
1130
  initialize_readline(my_progname);
1125
1131
  if (!status.batch && !quick && !opt_html && !opt_xml)
1126
1132
  {
1127
1133
    /* read-history from file, default ~/.mysql_history*/
1128
1134
    if (getenv("MYSQL_HISTFILE"))
1129
 
      histfile=g_strdup(getenv("MYSQL_HISTFILE"));
 
1135
      histfile= strdup(getenv("MYSQL_HISTFILE"));
1130
1136
    else if (getenv("HOME"))
1131
1137
    {
1132
1138
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1187
1193
 
1188
1194
  if (sig >= 0)
1189
1195
    put_info(sig ? "Aborted" : "Bye", INFO_RESULT,0,0);
1190
 
  assert(glob_buffer != NULL);
1191
 
  g_string_free(glob_buffer,true);
1192
 
  assert(processed_prompt != NULL);
1193
 
  g_string_free(processed_prompt,true);
1194
 
  assert(default_prompt != NULL);
1195
 
  g_string_free(default_prompt,true);
 
1196
  if (glob_buffer)
 
1197
    dynstr_free(glob_buffer);
 
1198
  my_free(glob_buffer, MYF(MY_ALLOW_ZERO_PTR));
 
1199
  if (processed_prompt)
 
1200
    dynstr_free(processed_prompt);
 
1201
  my_free(processed_prompt,MYF(MY_ALLOW_ZERO_PTR));
1196
1202
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
1197
1203
  my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
1198
1204
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
1546
1552
                                    opt->name);
1547
1553
    break;
1548
1554
  case OPT_SERVER_ARG:
1549
 
#ifdef EMBEDDED_LIBRARY
1550
 
    /*
1551
 
      When the embedded server is being tested, the client needs to be
1552
 
      able to pass command-line arguments to the embedded server so it can
1553
 
      locate the language files and data directory.
1554
 
    */
1555
 
    if (!embedded_server_arg_count)
1556
 
    {
1557
 
      embedded_server_arg_count= 1;
1558
 
      embedded_server_args[0]= (char*) "";
1559
 
    }
1560
 
    if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
1561
 
        !(embedded_server_args[embedded_server_arg_count++]=
1562
 
          g_strdup(argument)))
1563
 
    {
1564
 
      put_info("Can't use server argument", INFO_ERROR);
1565
 
      return 0;
1566
 
    }
1567
 
#else /*EMBEDDED_LIBRARY */
1568
1555
    printf("WARNING: --server-arg option not supported in this configuration.\n");
1569
 
#endif
1570
1556
    break;
1571
1557
  case 'A':
1572
1558
    opt_rehash= 0;
1595
1581
    {
1596
1582
      char *start= argument;
1597
1583
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1598
 
      opt_password= g_strdup(argument);
 
1584
      opt_password= strdup(argument);
1599
1585
      while (*argument) *argument++= 'x';               // Destroy argument
1600
1586
      if (*start)
1601
1587
        start[1]=0 ;
1687
1673
  {
1688
1674
    skip_updates= 0;
1689
1675
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
1690
 
    current_db= g_strdup(*argv);
 
1676
    current_db= strdup(*argv);
1691
1677
  }
1692
1678
  if (tty_password)
1693
1679
    opt_password= get_tty_password(NullS);
1724
1710
          (uchar) line[2] == 0xBF)
1725
1711
        line+= 3;
1726
1712
      line_number++;
1727
 
      if (glob_buffer->len!=0)
 
1713
      if (glob_buffer->length!=0)
1728
1714
        status.query_start_line=line_number;
1729
1715
    }
1730
1716
    else
1731
1717
    {
1732
1718
      char *prompt= (char*) (ml_comment ? "   /*> " :
1733
 
                             (glob_buffer->len == 0) ?  construct_prompt() :
 
1719
                             (glob_buffer->length == 0) ?  construct_prompt() :
1734
1720
                             !in_string ? "    -> " :
1735
1721
                             in_string == '\'' ?
1736
1722
                             "    '> " : (in_string == '`' ?
1737
1723
                                          "    `> " :
1738
1724
                                          "    \"> "));
1739
 
      if (opt_outfile && (glob_buffer->len==0))
 
1725
      if (opt_outfile && (glob_buffer->length==0))
1740
1726
        fflush(OUTFILE);
1741
1727
 
1742
1728
      if (opt_outfile)
1760
1746
      Check if line is a mysql command line
1761
1747
      (We want to allow help, print and clear anywhere at line start
1762
1748
    */
1763
 
    if ((named_cmds || (glob_buffer->len==0))
 
1749
    if ((named_cmds || (glob_buffer->length==0))
1764
1750
        && !ml_comment && !in_string && (com=find_command(line,0)))
1765
1751
    {
1766
1752
      if ((*com->func)(glob_buffer,line) > 0)
1767
1753
        break;
1768
1754
      // If buffer was emptied
1769
 
      if (glob_buffer->len==0)
 
1755
      if (glob_buffer->length==0)
1770
1756
        in_string=0;
1771
1757
      if (interactive && status.add_to_history && not_in_history(line))
1772
1758
        add_history(line);
1780
1766
  if (!interactive && !status.exit_status)
1781
1767
  {
1782
1768
    remove_cntrl(glob_buffer);
1783
 
    if (glob_buffer->len != 0)
 
1769
    if (glob_buffer->length != 0)
1784
1770
    {
1785
1771
      status.exit_status=1;
1786
1772
      if (com_go(glob_buffer,line) <= 0)
1842
1828
}
1843
1829
 
1844
1830
 
1845
 
static bool add_line(GString *buffer,char *line,char *in_string,
 
1831
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1846
1832
                        bool *ml_comment)
1847
1833
{
1848
1834
  uchar inchar;
1852
1838
  bool ss_comment= 0;
1853
1839
 
1854
1840
 
1855
 
  if (!line[0] && (buffer->len==0))
 
1841
  if (!line[0] && (buffer->length==0))
1856
1842
    return(0);
1857
1843
  if (status.add_to_history && line[0] && not_in_history(line))
1858
1844
    add_history(line);
1864
1850
    {
1865
1851
      // Skip spaces at the beggining of a statement
1866
1852
      if (my_isspace(charset_info,inchar) && (out == line) &&
1867
 
          (buffer->len==0))
 
1853
          (buffer->length==0))
1868
1854
        continue;
1869
1855
    }
1870
1856
 
1903
1889
        // Flush previously accepted characters
1904
1890
        if (out != line)
1905
1891
        {
1906
 
          g_string_append_len(buffer, line, (gssize) (out-line));
 
1892
          dynstr_append_mem(buffer, line, (out-line));
1907
1893
          out= line;
1908
1894
        }
1909
1895
 
1953
1939
      // Flush previously accepted characters
1954
1940
      if (out != line)
1955
1941
      {
1956
 
        g_string_append_len(buffer, line, (gssize) (out - line));
 
1942
        dynstr_append_mem(buffer, line, (out - line));
1957
1943
        out= line;
1958
1944
      }
1959
1945
 
1960
1946
      // Flush possible comments in the buffer
1961
 
      if (buffer->len != 0)
 
1947
      if (buffer->length != 0)
1962
1948
      {
1963
1949
        if (com_go(buffer, 0) > 0) // < 0 is not fatal
1964
1950
          return(1);
1965
1951
        assert(buffer!=NULL);
1966
 
        g_string_truncate(buffer,0);
 
1952
        dynstr_set(buffer, NULL);
1967
1953
      }
1968
1954
 
1969
1955
      /*
1970
1956
        Delimiter wants the get rest of the given line as argument to
1971
1957
        allow one to change ';' to ';;' and back
1972
1958
      */
1973
 
      g_string_append(buffer,pos);
 
1959
      dynstr_append(buffer,pos);
1974
1960
      if (com_delimiter(buffer, pos) > 0)
1975
1961
        return(1);
1976
1962
 
1977
 
      g_string_truncate(buffer,0);
 
1963
      dynstr_set(buffer, NULL);
1978
1964
      break;
1979
1965
    }
1980
1966
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
1990
1976
      // Flush previously accepted characters
1991
1977
      if (out != line)
1992
1978
      {
1993
 
        g_string_append_len(buffer, line, (gssize) (out-line));
 
1979
        dynstr_append_mem(buffer, line, (out-line));
1994
1980
        out= line;
1995
1981
      }
1996
1982
 
2000
1986
                                 my_isspace(charset_info, pos[2]))))
2001
1987
      {
2002
1988
        // Add trailing single line comments to this statement
2003
 
        g_string_append(buffer, pos);
 
1989
        dynstr_append(buffer, pos);
2004
1990
        pos+= strlen(pos);
2005
1991
      }
2006
1992
 
2017
2003
        if (com_go(buffer, 0) > 0)             // < 0 is not fatal
2018
2004
          return(1);
2019
2005
      }
2020
 
      g_string_truncate(buffer,0);
 
2006
      dynstr_set(buffer, NULL);
2021
2007
    }
2022
2008
    else if (!*ml_comment
2023
2009
             && (!*in_string
2029
2015
      // Flush previously accepted characters
2030
2016
      if (out != line)
2031
2017
      {
2032
 
        g_string_append_len(buffer, line, (gssize) (out - line));
 
2018
        dynstr_append_mem(buffer, line, (out - line));
2033
2019
        out= line;
2034
2020
      }
2035
2021
 
2036
2022
      // comment to end of line
2037
2023
      if (preserve_comments)
2038
 
        g_string_append(buffer,pos);
 
2024
        dynstr_append(buffer,pos);
2039
2025
 
2040
2026
      break;
2041
2027
    }
2052
2038
      *ml_comment= 1;
2053
2039
      if (out != line)
2054
2040
      {
2055
 
        g_string_append_len(buffer, line, (gssize) (out-line));
 
2041
        dynstr_append_mem(buffer, line, (out-line));
2056
2042
        out=line;
2057
2043
      }
2058
2044
    }
2068
2054
      *ml_comment= 0;
2069
2055
      if (out != line)
2070
2056
      {
2071
 
        g_string_append_len(buffer, line, (gssize) (out - line));
 
2057
        dynstr_append_mem(buffer, line, (out - line));
2072
2058
        out= line;
2073
2059
      }
2074
2060
      // Consumed a 2 chars or more, and will add 1 at most,
2097
2083
      }
2098
2084
    }
2099
2085
  }
2100
 
  if (out != line || (buffer->len > 0))
 
2086
  if (out != line || (buffer->length > 0))
2101
2087
  {
2102
2088
    *out++='\n';
2103
2089
    uint length=(uint) (out-line);
2104
2090
    if ((!*ml_comment || preserve_comments)
2105
 
        && (g_string_append_len(buffer, line, length) == NULL))
 
2091
        && dynstr_append_mem(buffer, line, length))
2106
2092
      return(1);
2107
2093
  }
2108
2094
  return(0);
2113
2099
******************************************************************/
2114
2100
 
2115
2101
 
 
2102
#ifdef HAVE_READLINE_COMPLETION
2116
2103
static char *new_command_generator(const char *text, int);
2117
2104
extern char **new_mysql_completion (const char *text, int start, int end);
 
2105
#endif
2118
2106
 
2119
2107
/*
2120
2108
  Tell the GNU Readline library how to complete.  We want to try to complete
2134
2122
#endif
2135
2123
 
2136
2124
/* glues pieces of history back together if in pieces   */
2137
 
static void fix_history(GString *final_command)
 
2125
static void fix_history(DYNAMIC_STRING *final_command)
2138
2126
{
2139
2127
  int total_lines = 1;
2140
2128
  const char *ptr = final_command->str;
 
2129
  char str_char = '\0';  /* Character if we are in a string or not */
 
2130
 
2141
2131
  /* Converted buffer */
2142
 
  GString * fixed_buffer;
2143
 
  fixed_buffer = g_string_sized_new(16);
2144
 
  char str_char = '\0';  /* Character if we are in a string or not */
 
2132
  DYNAMIC_STRING *fixed_buffer=
 
2133
    (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
2134
 
 
2135
  init_dynamic_string(fixed_buffer, "", 512, 512);
2145
2136
 
2146
2137
  /* find out how many lines we have and remove newlines */
2147
2138
  while (*ptr != '\0')
2156
2147
        str_char = *ptr;
2157
2148
      else if (str_char == *ptr)   /* close string */
2158
2149
        str_char = '\0';
2159
 
      g_string_append_len(fixed_buffer, ptr, 1);
 
2150
      dynstr_append_mem(fixed_buffer, ptr, 1);
2160
2151
      break;
2161
2152
    case '\n':
2162
2153
      /*
2163
2154
        not in string, change to space
2164
2155
        if in string, leave it alone
2165
2156
      */
2166
 
      g_string_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
 
2157
      dynstr_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2167
2158
      total_lines++;
2168
2159
      break;
2169
2160
    case '\\':
2170
 
      g_string_append_c(fixed_buffer, '\\');
 
2161
      dynstr_append(fixed_buffer, "\\");
2171
2162
      /* need to see if the backslash is escaping anything */
2172
2163
      if (str_char)
2173
2164
      {
2174
2165
        ptr++;
2175
2166
        /* special characters that need escaping */
2176
2167
        if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2177
 
          g_string_append_len(fixed_buffer, ptr, 1);
 
2168
          dynstr_append_mem(fixed_buffer, ptr, 1);
2178
2169
        else
2179
2170
          ptr--;
2180
2171
      }
2181
2172
      break;
2182
2173
    default:
2183
 
      g_string_append_len(fixed_buffer, ptr, 1);
 
2174
      dynstr_append_mem(fixed_buffer, ptr, 1);
2184
2175
    }
2185
2176
    ptr++;
2186
2177
  }
2206
2197
static void initialize_readline (const char *name)
2207
2198
{
2208
2199
  /* Allow conditional parsing of the ~/.inputrc file. */
2209
 
  rl_readline_name= name;
 
2200
  rl_readline_name= (char *)name;
2210
2201
 
 
2202
#ifdef HAVE_READLINE_COMPLETION
2211
2203
  /* Tell the completer that we want a crack first. */
2212
2204
  rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
2213
2205
  rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
 
2206
#endif
2214
2207
}
2215
2208
 
 
2209
#ifdef HAVE_READLINE_COMPLETION
2216
2210
/*
2217
2211
  Attempt to complete on the contents of TEXT.  START and END show the
2218
2212
  region of TEXT that contains the word to complete.  We can use the
2255
2249
 
2256
2250
    if (e)
2257
2251
    {
2258
 
      ptr= g_strdup(e->str);
 
2252
      ptr= strdup(e->str);
2259
2253
      e = e->pNext;
2260
2254
      return ptr;
2261
2255
    }
2280
2274
    while (e && !ptr)
2281
2275
    {                                   /* find valid entry in bucket */
2282
2276
      if ((uint) strlen(e->str) == b->nKeyLength)
2283
 
        ptr = g_strdup(e->str);
 
2277
        ptr = strdup(e->str);
2284
2278
      /* find the next used entry */
2285
2279
      e = e->pNext;
2286
2280
      if (!e)
2307
2301
  }
2308
2302
  return NullS;
2309
2303
}
 
2304
#endif
2310
2305
 
2311
2306
 
2312
2307
/* Build up the completion hash */
2465
2460
  if (opt_reconnect)
2466
2461
  {
2467
2462
    put_info("No connection. Trying to reconnect...",INFO_INFO,0,0);
2468
 
    (void) com_connect((GString *) 0, 0);
 
2463
    (void) com_connect((DYNAMIC_STRING *) 0, 0);
2469
2464
    if (opt_rehash)
2470
2465
      com_rehash(NULL, NULL);
2471
2466
  }
2487
2482
  {
2488
2483
    MYSQL_ROW row= mysql_fetch_row(res);
2489
2484
    if (row[0])
2490
 
      current_db= g_strdup(row[0]);
 
2485
      current_db= strdup(row[0]);
2491
2486
    mysql_free_result(res);
2492
2487
  }
2493
2488
}
2534
2529
}
2535
2530
 
2536
2531
 
2537
 
static int com_server_help(GString *buffer,
 
2532
static int com_server_help(DYNAMIC_STRING *buffer,
2538
2533
                           char *line __attribute__((unused)),
2539
2534
                           char *help_arg)
2540
2535
{
2626
2621
}
2627
2622
 
2628
2623
static int
2629
 
com_help(GString *buffer __attribute__((unused)),
 
2624
com_help(DYNAMIC_STRING *buffer __attribute__((unused)),
2630
2625
         char *line __attribute__((unused)))
2631
2626
{
2632
2627
  register int i, j;
2658
2653
 
2659
2654
 
2660
2655
static int
2661
 
com_clear(GString *buffer,char *line __attribute__((unused)))
 
2656
com_clear(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
2662
2657
{
2663
2658
  if (status.add_to_history)
2664
2659
    fix_history(buffer);
2665
 
  g_string_truncate(buffer, 0);
 
2660
  dynstr_set(buffer, NULL);
2666
2661
  return 0;
2667
2662
}
2668
2663
 
2669
2664
static int
2670
 
com_charset(GString *buffer __attribute__((unused)), char *line)
 
2665
com_charset(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
2671
2666
{
2672
2667
  char buff[256], *param;
2673
2668
  CHARSET_INFO * new_cs;
2698
2693
  1  if fatal error
2699
2694
*/
2700
2695
static int
2701
 
com_go(GString *buffer,
 
2696
com_go(DYNAMIC_STRING *buffer,
2702
2697
       char *line __attribute__((unused)))
2703
2698
{
2704
2699
  char          buff[200]; /* about 110 chars used so far */
2713
2708
  /* Remove garbage for nicer messages */
2714
2709
  remove_cntrl(buffer);
2715
2710
 
2716
 
  if (buffer->len == 0)
 
2711
  if (buffer->length == 0)
2717
2712
  {
2718
2713
    // Ignore empty quries
2719
2714
    if (status.batch)
2724
2719
  if (!connected && reconnect())
2725
2720
  {
2726
2721
    // Remove query on error
2727
 
    g_string_truncate(buffer, 0);
 
2722
    dynstr_set(buffer, NULL);
2728
2723
    return opt_reconnect ? -1 : 1;          // Fatal error
2729
2724
  }
2730
2725
  if (verbose)
2731
2726
    (void) com_print(buffer, 0);
2732
2727
 
2733
2728
  if (skip_updates &&
2734
 
      ((buffer->len < 4)
2735
 
      || g_string_equal(g_string_new_len(buffer->str,4),
2736
 
                        g_string_new("SET "))))
 
2729
      ((buffer->length < 4) || !strncmp(buffer->str, "SET ", 4)))
2737
2730
  {
2738
2731
    (void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2739
2732
    return 0;
2741
2734
 
2742
2735
  timer=start_timer();
2743
2736
  executing_query= 1;
2744
 
  error= mysql_real_query_for_lazy(buffer->str,buffer->len);
 
2737
  error= mysql_real_query_for_lazy(buffer->str,buffer->length);
2745
2738
 
2746
2739
  if (status.add_to_history)
2747
2740
  {
2748
 
    g_string_append(buffer, vertical ? "\\G" : delimiter);
 
2741
    dynstr_append(buffer, vertical ? "\\G" : delimiter);
2749
2742
    /* Append final command onto history */
2750
2743
    fix_history(buffer);
2751
2744
  }
2752
2745
 
2753
 
  g_string_truncate(buffer, 0);
 
2746
  dynstr_set(buffer, NULL);
2754
2747
 
2755
2748
  if (error)
2756
2749
    goto end;
2914
2907
 
2915
2908
 
2916
2909
static int
2917
 
com_ego(GString *buffer,char *line)
 
2910
com_ego(DYNAMIC_STRING *buffer,char *line)
2918
2911
{
2919
2912
  int result;
2920
2913
  bool oldvertical=vertical;
3013
3006
static void
3014
3007
print_table_data(MYSQL_RES *result)
3015
3008
{
3016
 
  GString       *separator = g_string_sized_new(256);
3017
3009
  MYSQL_ROW     cur;
3018
3010
  MYSQL_FIELD   *field;
3019
3011
  bool          *num_flag;
 
3012
  DYNAMIC_STRING *separator=
 
3013
    (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
3014
  init_dynamic_string(separator, "", 256, 256);
3020
3015
 
3021
3016
  num_flag=(bool*) my_malloc(sizeof(bool)*mysql_num_fields(result),
3022
3017
                             MYF(MY_WME));
3027
3022
      return;
3028
3023
    mysql_field_seek(result,0);
3029
3024
  }
3030
 
  separator = g_string_append_c(separator, '+');
 
3025
  dynstr_append(separator, "+");
3031
3026
  while ((field = mysql_fetch_field(result)))
3032
3027
  {
3033
3028
    uint length= column_names ? field->name_length : 0;
3041
3036
    field->max_length=length;
3042
3037
    uint x;
3043
3038
    for (x=0; x< (length+2); x++)
3044
 
      g_string_append_c(separator, '-');
3045
 
    g_string_append_c(separator, '+');
 
3039
      dynstr_append(separator, "-");
 
3040
    dynstr_append(separator, "+");
3046
3041
  }
3047
 
  // End marker for \0
3048
 
  // TODO: Huh? Do we need this with GString?
3049
 
  g_string_append_c(separator, '\0');
3050
3042
 
3051
3043
  tee_puts((char*) separator->str, PAGER);
3052
3044
  if (column_names)
3258
3250
  mysql_field_seek(result,0);
3259
3251
 
3260
3252
  tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
3261
 
  xmlencode_print(glob_buffer->str, glob_buffer->len);
 
3253
  xmlencode_print(glob_buffer->str, glob_buffer->length);
3262
3254
  tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
3263
3255
            PAGER);
3264
3256
 
3463
3455
}
3464
3456
 
3465
3457
static int
3466
 
com_tee(GString *buffer __attribute__((__unused__)), char *line )
 
3458
com_tee(DYNAMIC_STRING *buffer __attribute__((__unused__)), char *line )
3467
3459
{
3468
3460
  char file_name[FN_REFLEN], *end, *param;
3469
3461
 
3507
3499
 
3508
3500
 
3509
3501
static int
3510
 
com_notee(GString *buffer __attribute__((unused)),
 
3502
com_notee(DYNAMIC_STRING *buffer __attribute__((unused)),
3511
3503
          char *line __attribute__((unused)))
3512
3504
{
3513
3505
  if (opt_outfile)
3521
3513
*/
3522
3514
 
3523
3515
static int
3524
 
com_pager(GString *buffer __attribute__((__unused__)),
 
3516
com_pager(DYNAMIC_STRING *buffer __attribute__((__unused__)),
3525
3517
          char *line __attribute__((unused)))
3526
3518
{
3527
3519
  char pager_name[FN_REFLEN], *end, *param;
3565
3557
 
3566
3558
 
3567
3559
static int
3568
 
com_nopager(GString *buffer __attribute__((unused)),
 
3560
com_nopager(DYNAMIC_STRING *buffer __attribute__((unused)),
3569
3561
            char *line __attribute__((unused)))
3570
3562
{
3571
3563
  strmov(pager, "stdout");
3578
3570
/* If arg is given, exit without errors. This happens on command 'quit' */
3579
3571
 
3580
3572
static int
3581
 
com_quit(GString *buffer __attribute__((unused)),
 
3573
com_quit(DYNAMIC_STRING *buffer __attribute__((unused)),
3582
3574
         char *line __attribute__((unused)))
3583
3575
{
3584
3576
  /* let the screen auto close on a normal shutdown */
3587
3579
}
3588
3580
 
3589
3581
static int
3590
 
com_rehash(GString *buffer __attribute__((unused)),
 
3582
com_rehash(DYNAMIC_STRING *buffer __attribute__((unused)),
3591
3583
           char *line __attribute__((unused)))
3592
3584
{
3593
3585
  build_completion_hash(1, 0);
3597
3589
 
3598
3590
 
3599
3591
static int
3600
 
com_print(GString *buffer,char *line __attribute__((unused)))
 
3592
com_print(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
3601
3593
{
3602
3594
  tee_puts("--------------", stdout);
3603
3595
  (void) tee_fputs(buffer->str, stdout);
3604
 
  if ( (buffer->len == 0)
3605
 
       || (buffer->str)[(buffer->len)-1] != '\n')
 
3596
  if ( (buffer->length == 0)
 
3597
       || (buffer->str)[(buffer->length)-1] != '\n')
3606
3598
    tee_putc('\n', stdout);
3607
3599
  tee_puts("--------------\n", stdout);
3608
3600
  /* If empty buffer */
3611
3603
 
3612
3604
/* ARGSUSED */
3613
3605
static int
3614
 
com_connect(GString *buffer, char *line)
 
3606
com_connect(DYNAMIC_STRING *buffer, char *line)
3615
3607
{
3616
3608
  char *tmp, buff[256];
3617
3609
  bool save_rehash= opt_rehash;
3632
3624
    if (tmp && *tmp)
3633
3625
    {
3634
3626
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
3635
 
      current_db= g_strdup(tmp);
 
3627
      current_db= strdup(tmp);
3636
3628
      tmp= get_arg(buff, 1);
3637
3629
      if (tmp)
3638
3630
      {
3639
3631
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
3640
 
        current_host=g_strdup(tmp);
 
3632
        current_host=strdup(tmp);
3641
3633
      }
3642
3634
    }
3643
3635
    else
3647
3639
    }
3648
3640
    // command used
3649
3641
    assert(buffer!=NULL);
3650
 
    g_string_truncate(buffer, 0);
 
3642
    dynstr_set(buffer, NULL);
3651
3643
  }
3652
3644
  else
3653
3645
    opt_rehash= 0;
3666
3658
}
3667
3659
 
3668
3660
 
3669
 
static int com_source(GString *buffer __attribute__((__unused__)), char *line)
 
3661
static int com_source(DYNAMIC_STRING *buffer __attribute__((__unused__)), char *line)
3670
3662
{
3671
3663
  char source_name[FN_REFLEN], *end, *param;
3672
3664
  LINE_BUFFER *line_buff;
3712
3704
  status.file_name=source_name;
3713
3705
  // Empty command buffer
3714
3706
  assert(glob_buffer!=NULL);
3715
 
  g_string_truncate(glob_buffer, 0);
 
3707
  dynstr_set(glob_buffer, NULL);
3716
3708
  error= read_and_execute(false);
3717
3709
  // Continue as before
3718
3710
  status=old_status;
3724
3716
 
3725
3717
/* ARGSUSED */
3726
3718
static int
3727
 
com_delimiter(GString *buffer __attribute__((unused)), char *line)
 
3719
com_delimiter(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
3728
3720
{
3729
3721
  char buff[256], *tmp;
3730
3722
 
3754
3746
 
3755
3747
/* ARGSUSED */
3756
3748
static int
3757
 
com_use(GString *buffer __attribute__((unused)), char *line)
 
3749
com_use(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
3758
3750
{
3759
3751
  char *tmp, buff[FN_REFLEN + 1];
3760
3752
  int select_db;
3816
3808
        return put_error(&mysql);
3817
3809
    }
3818
3810
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
3819
 
    current_db=g_strdup(tmp);
 
3811
    current_db= strdup(tmp);
3820
3812
    if (select_db > 1)
3821
3813
      build_completion_hash(opt_rehash, 1);
3822
3814
  }
3826
3818
}
3827
3819
 
3828
3820
static int
3829
 
com_warnings(GString *buffer __attribute__((unused)),
 
3821
com_warnings(DYNAMIC_STRING *buffer __attribute__((unused)),
3830
3822
             char *line __attribute__((unused)))
3831
3823
{
3832
3824
  show_warnings = 1;
3835
3827
}
3836
3828
 
3837
3829
static int
3838
 
com_nowarnings(GString *buffer __attribute__((unused)),
 
3830
com_nowarnings(DYNAMIC_STRING *buffer __attribute__((unused)),
3839
3831
               char *line __attribute__((unused)))
3840
3832
{
3841
3833
  show_warnings = 0;
3997
3989
 
3998
3990
 
3999
3991
static int
4000
 
com_status(GString *buffer __attribute__((unused)),
 
3992
com_status(DYNAMIC_STRING *buffer __attribute__((unused)),
4001
3993
           char *line __attribute__((unused)))
4002
3994
{
4003
3995
  const char *status_str;
4070
4062
    tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname);
4071
4063
  }
4072
4064
 
4073
 
#ifndef EMBEDDED_LIBRARY
4074
4065
  if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket)
4075
4066
    tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port);
4076
4067
  else
4077
4068
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", mysql.unix_socket);
4078
4069
  if (mysql.net.compress)
4079
4070
    tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
4080
 
#endif
4081
4071
 
4082
4072
  if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
4083
4073
  {
4224
4214
}
4225
4215
 
4226
4216
 
4227
 
static void remove_cntrl(GString *buffer)
 
4217
static void remove_cntrl(DYNAMIC_STRING *buffer)
4228
4218
{
4229
4219
  char *start=  buffer->str;
4230
 
  char *end= start + (buffer->len);
 
4220
  char *end= start + (buffer->length);
4231
4221
  while (start < end && !my_isgraph(charset_info,end[-1]))
4232
4222
    end--;
4233
4223
  uint chars_to_truncate = end-start;
4234
 
  if (buffer->len > chars_to_truncate)
4235
 
    g_string_truncate(buffer, chars_to_truncate);
 
4224
  if (buffer->length > chars_to_truncate)
 
4225
    dynstr_trunc(buffer, chars_to_truncate);
4236
4226
}
4237
4227
 
4238
4228
 
4347
4337
{
4348
4338
  // Erase the old prompt
4349
4339
  assert(processed_prompt!=NULL);
4350
 
  g_string_truncate(processed_prompt, 0);
 
4340
  dynstr_set(processed_prompt, NULL);
4351
4341
 
4352
4342
  // Get the date struct
4353
4343
  time_t  lclock = time(NULL);
4358
4348
  {
4359
4349
    if (*c != PROMPT_CHAR)
4360
4350
    {
4361
 
      g_string_append_c(processed_prompt, c[0]);
 
4351
      dynstr_append_mem(processed_prompt, c, 1);
4362
4352
    }
4363
4353
    else
4364
4354
    {
4375
4365
        break;
4376
4366
      case 'v':
4377
4367
        if (connected)
4378
 
          g_string_append(processed_prompt, mysql_get_server_info(&mysql));
 
4368
          dynstr_append(processed_prompt, mysql_get_server_info(&mysql));
4379
4369
        else
4380
 
          g_string_append(processed_prompt, "not_connected");
 
4370
          dynstr_append(processed_prompt, "not_connected");
4381
4371
        break;
4382
4372
      case 'd':
4383
 
        g_string_append(processed_prompt, current_db ? current_db : "(none)");
 
4373
        dynstr_append(processed_prompt, current_db ? current_db : "(none)");
4384
4374
        break;
4385
4375
      case 'h':
4386
4376
      {
4387
4377
        const char *prompt;
4388
4378
        prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
4389
4379
        if (strstr(prompt, "Localhost"))
4390
 
          g_string_append(processed_prompt, "localhost");
 
4380
          dynstr_append(processed_prompt, "localhost");
4391
4381
        else
4392
4382
        {
4393
4383
          const char *end=strcend(prompt,' ');
4394
 
          g_string_append_len(processed_prompt, prompt, (gssize) (end-prompt));
 
4384
          dynstr_append_mem(processed_prompt, prompt, (end-prompt));
4395
4385
        }
4396
4386
        break;
4397
4387
      }
4399
4389
      {
4400
4390
        if (!connected)
4401
4391
        {
4402
 
          g_string_append(processed_prompt, "not_connected");
 
4392
          dynstr_append(processed_prompt, "not_connected");
4403
4393
          break;
4404
4394
        }
4405
4395
 
4406
4396
        const char *host_info = mysql_get_host_info(&mysql);
4407
4397
        if (strstr(host_info, "memory"))
4408
4398
        {
4409
 
          g_string_append(processed_prompt, mysql.host );
 
4399
          dynstr_append(processed_prompt, mysql.host);
4410
4400
        }
4411
4401
        else if (strstr(host_info,"TCP/IP") ||
4412
4402
                 !mysql.unix_socket)
4414
4404
        else
4415
4405
        {
4416
4406
          char *pos=strrchr(mysql.unix_socket,'/');
4417
 
          g_string_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
 
4407
          dynstr_append(processed_prompt, pos ? pos+1 : mysql.unix_socket);
4418
4408
        }
4419
4409
      }
4420
4410
      break;
4421
4411
      case 'U':
4422
4412
        if (!full_username)
4423
4413
          init_username();
4424
 
        g_string_append(processed_prompt, full_username ? full_username :
 
4414
        dynstr_append(processed_prompt, full_username ? full_username :
4425
4415
                        (current_user ?  current_user : "(unknown)"));
4426
4416
        break;
4427
4417
      case 'u':
4428
4418
        if (!full_username)
4429
4419
          init_username();
4430
 
        g_string_append(processed_prompt, part_username ? part_username :
 
4420
        dynstr_append(processed_prompt, part_username ? part_username :
4431
4421
                        (current_user ?  current_user : "(unknown)"));
4432
4422
        break;
4433
4423
      case PROMPT_CHAR:
4434
 
        g_string_append_c(processed_prompt, PROMPT_CHAR);
 
4424
        {
 
4425
          char c= PROMPT_CHAR;
 
4426
          dynstr_append_mem(processed_prompt, &c, 1);
 
4427
        }
4435
4428
        break;
4436
4429
      case 'n':
4437
 
        g_string_append_c(processed_prompt, '\n');
 
4430
        {
 
4431
          char c= '\n';
 
4432
          dynstr_append_mem(processed_prompt, &c, 1);
 
4433
        }
4438
4434
        break;
4439
4435
      case ' ':
4440
4436
      case '_':
4441
 
        g_string_append_c(processed_prompt, ' ');
 
4437
        {
 
4438
          char c= ' ';
 
4439
          dynstr_append_mem(processed_prompt, &c, 1);
 
4440
        }
4442
4441
        break;
4443
4442
      case 'R':
4444
4443
        if (t->tm_hour < 10)
4445
 
          g_string_append_c(processed_prompt, '0');
 
4444
          add_int_to_prompt(0);
4446
4445
        add_int_to_prompt(t->tm_hour);
4447
4446
        break;
4448
4447
      case 'r':
4450
4449
        if (getHour == 0)
4451
4450
          getHour=12;
4452
4451
        if (getHour < 10)
4453
 
          g_string_append_c(processed_prompt, '0');
 
4452
          add_int_to_prompt(0);
4454
4453
        add_int_to_prompt(getHour);
4455
4454
        break;
4456
4455
      case 'm':
4457
4456
        if (t->tm_min < 10)
4458
 
          g_string_append_c(processed_prompt, '0');
 
4457
          add_int_to_prompt(0);
4459
4458
        add_int_to_prompt(t->tm_min);
4460
4459
        break;
4461
4460
      case 'y':
4462
4461
        getYear = t->tm_year % 100;
4463
4462
        if (getYear < 10)
4464
 
          g_string_append_c(processed_prompt, '0');
 
4463
          add_int_to_prompt(0);
4465
4464
        add_int_to_prompt(getYear);
4466
4465
        break;
4467
4466
      case 'Y':
4469
4468
        break;
4470
4469
      case 'D':
4471
4470
        dateTime = ctime(&lclock);
4472
 
        g_string_append(processed_prompt, strtok(dateTime,"\n"));
 
4471
        dynstr_append(processed_prompt, strtok(dateTime,"\n"));
4473
4472
        break;
4474
4473
      case 's':
4475
4474
        if (t->tm_sec < 10)
4476
 
          g_string_append_c(processed_prompt, '0');
 
4475
          add_int_to_prompt(0);
4477
4476
        add_int_to_prompt(t->tm_sec);
4478
4477
        break;
4479
4478
      case 'w':
4480
 
        g_string_append(processed_prompt, (day_names[t->tm_wday]));
 
4479
        dynstr_append(processed_prompt, (day_names[t->tm_wday]));
4481
4480
        break;
4482
4481
      case 'P':
4483
 
        g_string_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
 
4482
        dynstr_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4484
4483
        break;
4485
4484
      case 'o':
4486
4485
        add_int_to_prompt(t->tm_mon+1);
4487
4486
        break;
4488
4487
      case 'O':
4489
 
        g_string_append(processed_prompt, month_names[t->tm_mon]);
 
4488
        dynstr_append(processed_prompt, month_names[t->tm_mon]);
4490
4489
        break;
4491
4490
      case '\'':
4492
 
        g_string_append(processed_prompt, "'");
 
4491
        dynstr_append(processed_prompt, "'");
4493
4492
        break;
4494
4493
      case '"':
4495
 
        g_string_append_c(processed_prompt, '"');
 
4494
        dynstr_append(processed_prompt, "\"");
4496
4495
        break;
4497
4496
      case 'S':
4498
 
        g_string_append_c(processed_prompt, ';');
 
4497
        dynstr_append(processed_prompt, ";");
4499
4498
        break;
4500
4499
      case 't':
4501
 
        g_string_append_c(processed_prompt, '\t');
 
4500
        dynstr_append(processed_prompt, "\t");
4502
4501
        break;
4503
4502
      case 'l':
4504
 
        g_string_append(processed_prompt, delimiter_str);
 
4503
        dynstr_append(processed_prompt, delimiter_str);
4505
4504
        break;
4506
4505
      default:
4507
 
        g_string_append(processed_prompt, c);
 
4506
        dynstr_append_mem(processed_prompt, c, 1);
4508
4507
      }
4509
4508
    }
4510
4509
  }
4511
 
  // TODO: Is this needed with GString?
4512
 
  g_string_append_c(processed_prompt, '\0');
4513
4510
  return processed_prompt->str;
4514
4511
}
4515
4512
 
4517
4514
static void add_int_to_prompt(int toadd)
4518
4515
{
4519
4516
  char buffer[16];
4520
 
  int10_to_str(toadd,buffer,10);
4521
 
  g_string_append(processed_prompt, buffer);
 
4517
  int10_to_str(toadd, buffer, 10);
 
4518
  dynstr_append(processed_prompt, buffer);
4522
4519
}
4523
4520
 
4524
4521
static void init_username()
4531
4528
      (result=mysql_use_result(&mysql)))
4532
4529
  {
4533
4530
    MYSQL_ROW cur=mysql_fetch_row(result);
4534
 
    full_username=g_strdup(cur[0]);
4535
 
    part_username=g_strdup(strtok(cur[0],"@"));
 
4531
    full_username= strdup(cur[0]);
 
4532
    part_username= strdup(strtok(cur[0],"@"));
4536
4533
    (void) mysql_fetch_row(result);             // Read eof
4537
4534
  }
4538
4535
}
4539
4536
 
4540
 
static int com_prompt(GString *buffer __attribute__((__unused__)), char *line)
 
4537
static int com_prompt(DYNAMIC_STRING *buffer __attribute__((__unused__)), char *line)
4541
4538
{
4542
4539
  char *ptr=strchr(line, ' ');
4543
4540
  prompt_counter = 0;
4544
4541
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4545
 
  current_prompt=g_strdup(ptr ? ptr+1 : default_prompt->str);
 
4542
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4546
4543
  if (!ptr)
4547
4544
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4548
 
                default_prompt->str);
 
4545
                default_prompt);
4549
4546
  else
4550
4547
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4551
4548
  return 0;