~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.c

Moved base64.h to mysys.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 *
34
34
 **/
35
35
 
36
 
#include "config.h"
37
 
 
38
 
#include <string>
39
 
 
40
36
#include "client_priv.h"
41
 
#include <mystrings/m_ctype.h>
 
37
#include <my_sys.h>
 
38
#include <m_ctype.h>
42
39
#include <stdarg.h>
 
40
#include <my_dir.h>
43
41
#ifndef __GNU_LIBRARY__
44
42
#define __GNU_LIBRARY__          // Skip warnings in getopt.h
45
43
#endif
46
44
#include <readline/history.h>
47
45
#include "my_readline.h"
48
46
#include <signal.h>
49
 
#include <sys/ioctl.h>
50
 
 
51
 
 
52
 
#if defined(HAVE_LOCALE_H)
 
47
#include <violite.h>
 
48
 
 
49
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
53
50
#include <locale.h>
54
51
#endif
55
52
 
56
 
#include <libdrizzle/gettext.h>
57
 
 
58
53
const char *VER= "14.14";
59
54
 
60
55
/* Don't try to make a nice table if the data is too big */
61
 
#define MAX_COLUMN_LENGTH       (uint32_t)1024
 
56
#define MAX_COLUMN_LENGTH       1024
62
57
 
63
58
/* Buffer to hold 'version' and 'version_comment' */
64
59
#define MAX_SERVER_VERSION_LENGTH     128
69
64
void* sql_alloc(unsigned size);       // Don't use drizzled alloc for these
70
65
void sql_element_free(void *ptr);
71
66
 
72
 
 
73
67
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
74
68
#include <curses.h>
75
 
#ifdef __sun
76
 
#undef clear
77
 
#undef erase
78
 
#endif
79
69
#include <term.h>
80
70
#else
81
71
#if defined(HAVE_TERMIOS_H)
86
76
#elif defined(HAVE_ASM_TERMBITS_H) && (!defined __GLIBC__ || !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ > 0))
87
77
#include <asm/termbits.h>    // Standard linux
88
78
#endif
 
79
#undef VOID
89
80
#if defined(HAVE_TERMCAP_H)
90
81
#include <termcap.h>
91
82
#else
99
90
#endif
100
91
#endif
101
92
 
102
 
#undef bcmp                             // Fix problem with new readline
 
93
#undef bcmp        // Fix problem with new readline
103
94
 
104
 
#ifdef HAVE_READLINE_HISTORY_H
105
 
#include <readline/history.h>
106
 
#endif
107
95
#include <readline/readline.h>
108
96
 
109
97
/**
130
118
 
131
119
#include "completion_hash.h"
132
120
 
133
 
using namespace std;
134
 
 
135
121
#define PROMPT_CHAR '\\'
136
122
#define DEFAULT_DELIMITER ";"
137
123
 
156
142
  connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
157
143
  opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0,
158
144
  opt_compress=0, using_opt_local_infile=0,
159
 
  vertical=0, line_numbers=1, column_names=1,
160
 
  opt_nopager=1, opt_outfile=0, named_cmds= 0,
 
145
  vertical=0, line_numbers=1, column_names=1,opt_html=0,
 
146
  opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
161
147
  tty_password= 0, opt_nobeep=0, opt_reconnect=1,
162
148
  default_charset_used= 0, opt_secure_auth= 0,
163
149
  default_pager_set= 0, opt_sigint_ignore= 0,
166
152
static bool debug_info_flag, debug_check_flag;
167
153
static bool column_types_flag;
168
154
static bool preserve_comments= 0;
169
 
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
 
155
static ulong opt_max_allowed_packet, opt_net_buffer_length;
170
156
static int verbose=0,opt_silent=0,opt_drizzle_port=0, opt_local_infile=0;
171
157
static uint my_end_arg;
172
158
static char * opt_drizzle_unix_port=0;
173
159
static int connect_flag=CLIENT_INTERACTIVE;
174
160
static char *current_host,*current_db,*current_user=0,*opt_password=0,
175
 
  *delimiter_str= 0,* current_prompt= 0;
 
161
  *delimiter_str= 0,*current_prompt=0,
 
162
  *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
176
163
static char *histfile;
177
164
static char *histfile_tmp;
178
 
static string *glob_buffer;
179
 
static string *processed_prompt= NULL;
 
165
static DYNAMIC_STRING *glob_buffer;
 
166
static DYNAMIC_STRING *processed_prompt= NULL;
180
167
static char *default_prompt= NULL;
181
168
static char *full_username=0,*part_username=0;
182
169
static STATUS status;
183
170
static uint32_t select_limit;
184
171
static uint32_t max_join_size;
185
 
static uint32_t opt_connect_timeout= 0;
 
172
static ulong opt_connect_timeout= 0;
186
173
static char drizzle_charsets_dir[FN_REFLEN+1];
187
 
// TODO: Need to i18n these
 
174
static const char *xmlmeta[] = {
 
175
  "&", "&amp;",
 
176
  "<", "&lt;",
 
177
  ">", "&gt;",
 
178
  "\"", "&quot;",
 
179
  0, 0
 
180
};
188
181
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
189
182
static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
190
183
                                  "Aug","Sep","Oct","Nov","Dec"};
197
190
static uint delimiter_length= 1;
198
191
unsigned short terminal_width= 80;
199
192
 
200
 
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
 
193
static uint opt_protocol= DRIZZLE_PROTOCOL_TCP;
 
194
static CHARSET_INFO *charset_info= &my_charset_latin1;
201
195
 
 
196
const char *default_dbug_option="d:t:o,/tmp/drizzle.trace";
202
197
int drizzle_real_query_for_lazy(const char *buf, int length);
203
198
int drizzle_store_result_for_lazy(DRIZZLE_RES **result);
204
199
 
212
207
static int get_options(int argc,char **argv);
213
208
bool get_one_option(int optid, const struct my_option *opt,
214
209
                    char *argument);
215
 
static int com_quit(string *str,const char*),
216
 
  com_go(string *str,const char*), com_ego(string *str,const char*),
217
 
  com_print(string *str,const char*),
218
 
  com_help(string *str,const char*), com_clear(string *str,const char*),
219
 
  com_connect(string *str,const char*), com_status(string *str,const char*),
220
 
  com_use(string *str,const char*), com_source(string *str, const char*),
221
 
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
222
 
  com_notee(string *str, const char*),
223
 
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
224
 
  com_warnings(string *str, const char*), com_nowarnings(string *str, const char*),
225
 
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
 
210
static int com_quit(DYNAMIC_STRING *str,char*),
 
211
  com_go(DYNAMIC_STRING *str,char*), com_ego(DYNAMIC_STRING *str,char*),
 
212
  com_print(DYNAMIC_STRING *str,char*),
 
213
  com_help(DYNAMIC_STRING *str,char*), com_clear(DYNAMIC_STRING *str,char*),
 
214
  com_connect(DYNAMIC_STRING *str,char*), com_status(DYNAMIC_STRING *str,char*),
 
215
  com_use(DYNAMIC_STRING *str,char*), com_source(DYNAMIC_STRING *str, char*),
 
216
  com_rehash(DYNAMIC_STRING *str, char*), com_tee(DYNAMIC_STRING *str, char*),
 
217
  com_notee(DYNAMIC_STRING *str, char*), com_charset(DYNAMIC_STRING *str,char*),
 
218
  com_prompt(DYNAMIC_STRING *str, char*), com_delimiter(DYNAMIC_STRING *str, char*),
 
219
  com_warnings(DYNAMIC_STRING *str, char*), com_nowarnings(DYNAMIC_STRING *str, char*),
 
220
  com_nopager(DYNAMIC_STRING *str, char*), com_pager(DYNAMIC_STRING *str, char*);
226
221
 
227
222
static int read_and_execute(bool interactive);
228
223
static int sql_connect(char *host,char *database,char *user,char *password,
231
226
static int put_info(const char *str,INFO_TYPE info,uint error,
232
227
                    const char *sql_state);
233
228
static int put_error(DRIZZLE *drizzle);
234
 
static void safe_put_field(const char *pos,uint32_t length);
 
229
static void safe_put_field(const char *pos,ulong length);
 
230
static void xmlencode_print(const char *src, uint length);
235
231
static void init_pager(void);
236
232
static void end_pager(void);
237
233
static void init_tee(const char *);
242
238
static void add_int_to_prompt(int toadd);
243
239
static int get_result_width(DRIZZLE_RES *res);
244
240
static int get_field_disp_length(DRIZZLE_FIELD * field);
245
 
static const char * strcont(register const char *str, register const char *set);
246
241
 
247
242
/* A structure which contains information on the commands this program
248
243
   can understand. */
249
244
typedef struct {
250
245
  const char *name;        /* User printable name of the function. */
251
246
  char cmd_char;        /* msql command character */
252
 
  int (*func)(string *str,const char *); /* Function to call to do the job. */
 
247
  int (*func)(DYNAMIC_STRING *str,char *); /* Function to call to do the job. */
253
248
  bool takes_params;        /* Max parameters for command */
254
249
  const char *doc;        /* Documentation for this function.  */
255
250
} COMMANDS;
256
251
 
257
252
 
258
253
static COMMANDS commands[] = {
259
 
  { "?",      '?', com_help,   1, N_("Synonym for `help'.") },
260
 
  { "clear",  'c', com_clear,  0, N_("Clear command.")},
 
254
  { "?",      '?', com_help,   1, "Synonym for `help'." },
 
255
  { "clear",  'c', com_clear,  0, "Clear command."},
261
256
  { "connect",'r', com_connect,1,
262
 
    N_("Reconnect to the server. Optional arguments are db and host." }),
 
257
    "Reconnect to the server. Optional arguments are db and host." },
263
258
  { "delimiter", 'd', com_delimiter,    1,
264
 
    N_("Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.") },
 
259
    "Set statement delimiter. NOTE: Takes the rest of the line as new delimiter." },
265
260
  { "ego",    'G', com_ego,    0,
266
 
    N_("Send command to drizzle server, display result vertically.")},
267
 
  { "exit",   'q', com_quit,   0, N_("Exit drizzle. Same as quit.")},
268
 
  { "go",     'g', com_go,     0, N_("Send command to drizzle server.") },
269
 
  { "help",   'h', com_help,   1, N_("Display this help.") },
270
 
  { "nopager",'n', com_nopager,0, N_("Disable pager, print to stdout.") },
271
 
  { "notee",  't', com_notee,  0, N_("Don't write into outfile.") },
 
261
    "Send command to drizzle server, display result vertically."},
 
262
  { "exit",   'q', com_quit,   0, "Exit drizzle. Same as quit."},
 
263
  { "go",     'g', com_go,     0, "Send command to drizzle server." },
 
264
  { "help",   'h', com_help,   1, "Display this help." },
 
265
  { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
 
266
  { "notee",  't', com_notee,  0, "Don't write into outfile." },
272
267
  { "pager",  'P', com_pager,  1,
273
 
    N_("Set PAGER [to_pager]. Print the query results via PAGER.") },
274
 
  { "print",  'p', com_print,  0, N_("Print current command.") },
275
 
  { "prompt", 'R', com_prompt, 1, N_("Change your drizzle prompt.")},
276
 
  { "quit",   'q', com_quit,   0, N_("Quit drizzle.") },
277
 
  { "rehash", '#', com_rehash, 0, N_("Rebuild completion hash.") },
 
268
    "Set PAGER [to_pager]. Print the query results via PAGER." },
 
269
  { "print",  'p', com_print,  0, "Print current command." },
 
270
  { "prompt", 'R', com_prompt, 1, "Change your drizzle prompt."},
 
271
  { "quit",   'q', com_quit,   0, "Quit drizzle." },
 
272
  { "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
278
273
  { "source", '.', com_source, 1,
279
 
    N_("Execute an SQL script file. Takes a file name as an argument.")},
280
 
  { "status", 's', com_status, 0, N_("Get status information from the server.")},
 
274
    "Execute an SQL script file. Takes a file name as an argument."},
 
275
  { "status", 's', com_status, 0, "Get status information from the server."},
281
276
  { "tee",    'T', com_tee,    1,
282
 
    N_("Set outfile [to_outfile]. Append everything into given outfile.") },
 
277
    "Set outfile [to_outfile]. Append everything into given outfile." },
283
278
  { "use",    'u', com_use,    1,
284
 
    N_("Use another database. Takes database name as argument.") },
 
279
    "Use another database. Takes database name as argument." },
 
280
  { "charset",    'C', com_charset,    1,
 
281
    "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." },
285
282
  { "warnings", 'W', com_warnings,  0,
286
 
    N_("Show warnings after every statement.") },
 
283
    "Show warnings after every statement." },
287
284
  { "nowarning", 'w', com_nowarnings, 0,
288
 
    N_("Don't show warnings after every statement.") },
 
285
    "Don't show warnings after every statement." },
289
286
  /* Get bash-like expansion for some commands */
290
287
  { "create table",     0, 0, 0, ""},
291
288
  { "create database",  0, 0, 0, ""},
998
995
 
999
996
static const char *load_default_groups[]= { "drizzle","client",0 };
1000
997
 
 
998
static int         embedded_server_arg_count= 0;
 
999
static char       *embedded_server_args[MAX_SERVER_ARGS];
 
1000
 
1001
1001
int history_length;
1002
1002
static int not_in_history(const char *line);
1003
 
static void initialize_readline (char *name);
1004
 
static void fix_history(string *final_command);
 
1003
static void initialize_readline (const char *name);
 
1004
static void fix_history(DYNAMIC_STRING *final_command);
1005
1005
 
1006
 
static COMMANDS *find_command(const char *name,char cmd_name);
1007
 
static bool add_line(string *buffer,char *line,char *in_string,
 
1006
static COMMANDS *find_command(char *name,char cmd_name);
 
1007
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1008
1008
                     bool *ml_comment);
1009
 
static void remove_cntrl(string *buffer);
 
1009
static void remove_cntrl(DYNAMIC_STRING *buffer);
1010
1010
static void print_table_data(DRIZZLE_RES *result);
 
1011
static void print_table_data_html(DRIZZLE_RES *result);
 
1012
static void print_table_data_xml(DRIZZLE_RES *result);
1011
1013
static void print_tab_data(DRIZZLE_RES *result);
1012
1014
static void print_table_data_vertically(DRIZZLE_RES *result);
1013
1015
static void print_warnings(void);
1014
 
static uint32_t start_timer(void);
1015
 
static void end_timer(uint32_t start_time,char *buff);
1016
 
static void drizzle_end_timer(uint32_t start_time,char *buff);
 
1016
static ulong start_timer(void);
 
1017
static void end_timer(ulong start_time,char *buff);
 
1018
static void drizzle_end_timer(ulong start_time,char *buff);
1017
1019
static void nice_time(double sec,char *buff,bool part_second);
1018
 
extern RETSIGTYPE drizzle_end(int sig);
1019
 
extern RETSIGTYPE handle_sigint(int sig);
 
1020
extern sig_handler drizzle_end(int sig);
 
1021
extern sig_handler handle_sigint(int sig);
1020
1022
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1021
 
static RETSIGTYPE window_resize(int sig);
 
1023
static sig_handler window_resize(int sig);
1022
1024
#endif
1023
1025
 
1024
1026
int main(int argc,char *argv[])
1025
1027
{
1026
1028
  char buff[80];
1027
1029
 
1028
 
#if defined(ENABLE_NLS)
1029
 
# if defined(HAVE_LOCALE_H)
1030
 
  setlocale(LC_ALL, "");
1031
 
# endif
1032
 
  bindtextdomain("drizzle", LOCALEDIR);
1033
 
  textdomain("drizzle");
1034
 
#endif
1035
 
 
1036
1030
  MY_INIT(argv[0]);
1037
1031
  delimiter_str= delimiter;
1038
1032
  default_prompt= my_strdup(getenv("DRIZZLE_PS1") ?
1039
1033
                            getenv("DRIZZLE_PS1") :
1040
1034
                            "drizzle>> ", MYF(0));
1041
1035
  current_prompt= my_strdup(default_prompt, MYF(0));
1042
 
  processed_prompt= new string();
1043
 
  processed_prompt->reserve(32);
 
1036
 
 
1037
  processed_prompt= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
1038
  init_dynamic_string(processed_prompt, "", 32, 32);
1044
1039
 
1045
1040
  prompt_counter=0;
1046
1041
 
1047
1042
  outfile[0]=0;      // no (default) outfile
1048
 
  my_stpcpy(pager, "stdout");  // the default, if --pager wasn't given
 
1043
  strmov(pager, "stdout");  // the default, if --pager wasn't given
1049
1044
  {
1050
1045
    char *tmp=getenv("PAGER");
1051
1046
    if (tmp && strlen(tmp))
1052
1047
    {
1053
1048
      default_pager_set= 1;
1054
 
      my_stpcpy(default_pager, tmp);
 
1049
      strmov(default_pager, tmp);
1055
1050
    }
1056
1051
  }
1057
1052
  if (!isatty(0) || !isatty(1))
1094
1089
  }
1095
1090
  completion_hash_init(&ht, 128);
1096
1091
  init_alloc_root(&hash_mem_root, 16384, 0);
1097
 
  memset(&drizzle, 0, sizeof(drizzle));
 
1092
  bzero((char*) &drizzle, sizeof(drizzle));
1098
1093
  if (sql_connect(current_host,current_db,current_user,opt_password,
1099
1094
                  opt_silent))
1100
1095
  {
1118
1113
  window_resize(0);
1119
1114
#endif
1120
1115
 
1121
 
  put_info(_("Welcome to the Drizzle client..  Commands end with ; or \\g."),
 
1116
  put_info("Welcome to the Drizzle client..  Commands end with ; or \\g.",
1122
1117
           INFO_INFO,0,0);
1123
1118
 
1124
 
  glob_buffer= new string();
1125
 
  glob_buffer->reserve(512);
1126
 
  
1127
 
  char * output_buff= (char *)malloc(512);
1128
 
  memset(output_buff, '\0', 512);
1129
 
 
1130
 
  sprintf(output_buff,
1131
 
          _("Your Drizzle connection id is %u\nServer version: %s\n"),
1132
 
          drizzle_thread_id(&drizzle),
1133
 
          server_version_string(&drizzle));
1134
 
  put_info(output_buff, INFO_INFO, 0, 0);
1135
 
 
1136
 
  initialize_readline(current_prompt);
1137
 
  if (!status.batch && !quick)
 
1119
  glob_buffer= (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
1120
  init_dynamic_string(glob_buffer, "", 512, 512);
 
1121
 
 
1122
  /* this is a slight abuse of the DYNAMIC_STRING interface. deal. */
 
1123
  sprintf(glob_buffer->str,
 
1124
          "Your Drizzle connection id is %u\nServer version: %s\n",
 
1125
          drizzle_thread_id(&drizzle), server_version_string(&drizzle));
 
1126
  put_info(glob_buffer->str, INFO_INFO, 0, 0);
 
1127
  dynstr_set(glob_buffer, NULL);
 
1128
 
 
1129
  initialize_readline(my_progname);
 
1130
  if (!status.batch && !quick && !opt_html && !opt_xml)
1138
1131
  {
1139
1132
    /* read-history from file, default ~/.drizzle_history*/
1140
 
    if (getenv("DRIZZLE_HISTFILE"))
1141
 
      histfile= strdup(getenv("DRIZZLE_HISTFILE"));
 
1133
    if (getenv("MYSQL_HISTFILE"))
 
1134
      histfile= strdup(getenv("MYSQL_HISTFILE"));
1142
1135
    else if (getenv("HOME"))
1143
1136
    {
1144
1137
      histfile=(char*) my_malloc((uint) strlen(getenv("HOME"))
1151
1144
          strncmp(link_name, "/dev/null", 10) == 0)
1152
1145
      {
1153
1146
        /* The .drizzle_history file is a symlink to /dev/null, don't use it */
1154
 
        free(histfile);
 
1147
        my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
1155
1148
        histfile= 0;
1156
1149
      }
1157
1150
    }
1158
1151
    if (histfile)
1159
1152
    {
1160
1153
      if (verbose)
1161
 
        tee_fprintf(stdout, _("Reading history-file %s\n"),histfile);
 
1154
        tee_fprintf(stdout, "Reading history-file %s\n",histfile);
1162
1155
      read_history(histfile);
1163
1156
      if (!(histfile_tmp= (char*) my_malloc((uint) strlen(histfile) + 5,
1164
1157
                                            MYF(MY_WME))))
1165
1158
      {
1166
 
        fprintf(stderr, _("Couldn't allocate memory for temp histfile!\n"));
 
1159
        fprintf(stderr, "Couldn't allocate memory for temp histfile!\n");
1167
1160
        exit(1);
1168
1161
      }
1169
1162
      sprintf(histfile_tmp, "%s.TMP", histfile);
1170
1163
    }
1171
1164
  }
1172
1165
  sprintf(buff, "%s",
1173
 
          _("Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n"));
 
1166
          "Type 'help;' or '\\h' for help. Type '\\c' to clear the buffer.\n");
1174
1167
 
1175
1168
  put_info(buff,INFO_INFO,0,0);
1176
1169
  status.exit_status= read_and_execute(!status.batch);
1177
1170
  if (opt_outfile)
1178
1171
    end_tee();
1179
1172
  drizzle_end(0);
1180
 
 
 
1173
#ifndef _lint
1181
1174
  return(0);        // Keep compiler happy
 
1175
#endif
1182
1176
}
1183
1177
 
1184
 
RETSIGTYPE drizzle_end(int sig)
 
1178
sig_handler drizzle_end(int sig)
1185
1179
{
1186
1180
  drizzle_close(&drizzle);
1187
 
  if (!status.batch && !quick && histfile)
 
1181
  if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
1188
1182
  {
1189
1183
    /* write-history */
1190
1184
    if (verbose)
1191
 
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
 
1185
      tee_fprintf(stdout, "Writing history-file %s\n",histfile);
1192
1186
    if (!write_history(histfile_tmp))
1193
1187
      my_rename(histfile_tmp, histfile, MYF(MY_WME));
1194
1188
  }
1197
1191
  free_root(&hash_mem_root,MYF(0));
1198
1192
 
1199
1193
  if (sig >= 0)
1200
 
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
 
1194
    put_info(sig ? "Aborted" : "Bye", INFO_RESULT,0,0);
1201
1195
  if (glob_buffer)
1202
 
    delete glob_buffer;
 
1196
    dynstr_free(glob_buffer);
 
1197
  my_free(glob_buffer, MYF(MY_ALLOW_ZERO_PTR));
1203
1198
  if (processed_prompt)
1204
 
    delete processed_prompt;
1205
 
  free(opt_password);
1206
 
  free(opt_drizzle_unix_port);
1207
 
  free(histfile);
1208
 
  free(histfile_tmp);
1209
 
  free(current_db);
1210
 
  free(current_host);
1211
 
  free(current_user);
1212
 
  free(full_username);
1213
 
  free(part_username);
1214
 
  free(default_prompt);
1215
 
  free(current_prompt);
 
1199
    dynstr_free(processed_prompt);
 
1200
  my_free(processed_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1201
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
1202
  my_free(opt_drizzle_unix_port,MYF(MY_ALLOW_ZERO_PTR));
 
1203
  my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
 
1204
  my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
 
1205
  my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
 
1206
  my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
 
1207
  my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
 
1208
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
1209
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
 
1210
  my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1211
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
 
1212
  while (embedded_server_arg_count > 1)
 
1213
    my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
 
1214
  drizzle_server_end();
1216
1215
  free_defaults(defaults_argv);
1217
1216
  my_end(my_end_arg);
1218
1217
  exit(status.exit_status);
1224
1223
  If query is in process, kill query
1225
1224
  no query in process, terminate like previous behavior
1226
1225
*/
1227
 
RETSIGTYPE handle_sigint(int sig)
 
1226
sig_handler handle_sigint(int sig)
1228
1227
{
1229
1228
  char kill_buffer[40];
1230
1229
  DRIZZLE *kill_drizzle= NULL;
1245
1244
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u", drizzle_thread_id(&drizzle));
1246
1245
  drizzle_real_query(kill_drizzle, kill_buffer, strlen(kill_buffer));
1247
1246
  drizzle_close(kill_drizzle);
1248
 
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
 
1247
  tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
1249
1248
 
1250
1249
  interrupted_query= 1;
1251
1250
 
1257
1256
 
1258
1257
 
1259
1258
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1260
 
RETSIGTYPE window_resize(int sig __attribute__((unused)))
 
1259
sig_handler window_resize(int sig __attribute__((unused)))
1261
1260
{
1262
1261
  struct winsize window_size;
1263
1262
 
1268
1267
 
1269
1268
static struct my_option my_long_options[] =
1270
1269
{
1271
 
  {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1270
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1272
1271
   0, 0, 0, 0, 0},
1273
 
  {"help", 'I', N_("Synonym for -?"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1272
  {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1274
1273
   0, 0, 0, 0, 0},
1275
1274
  {"auto-rehash", OPT_AUTO_REHASH,
1276
 
   N_("Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash."),
 
1275
   "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.",
1277
1276
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
1278
1277
   0, 0},
1279
1278
  {"no-auto-rehash", 'A',
1280
 
   N_("No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of DRIZZLE and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead."),
 
1279
   "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of DRIZZLE and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
1281
1280
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1282
1281
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
1283
 
   N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
 
1282
   "Automatically switch to vertical output mode if the result is wider than the terminal width.",
1284
1283
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1285
1284
  {"batch", 'B',
1286
 
   N_("Don't use history file. Disable interactive behavior. (Enables --silent)"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1285
   "Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1287
1286
  {"character-sets-dir", OPT_CHARSETS_DIR,
1288
 
   N_("Directory where character sets are."), (char**) &charsets_dir,
 
1287
   "Directory where character sets are.", (char**) &charsets_dir,
1289
1288
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1290
 
  {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
 
1289
  {"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
1291
1290
   (char**) &column_types_flag, (char**) &column_types_flag,
1292
1291
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1293
 
  {"comments", 'c', N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"),
 
1292
  {"comments", 'c', "Preserve comments. Send comments to the server."
 
1293
   " The default is --skip-comments (discard comments), enable with --comments",
1294
1294
   (char**) &preserve_comments, (char**) &preserve_comments,
1295
1295
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1296
 
  {"compress", 'C', N_("Use compression in server/client protocol."),
 
1296
  {"compress", 'C', "Use compression in server/client protocol.",
1297
1297
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1298
1298
   0, 0, 0},
1299
 
  {"debug-check", OPT_DEBUG_CHECK, N_("Check memory and open file usage at exit ."),
 
1299
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
1300
1300
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
1301
1301
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1302
 
  {"debug-info", 'T', N_("Print some debug info at exit."), (char**) &debug_info_flag,
 
1302
  {"debug-info", 'T', "Print some debug info at exit.", (char**) &debug_info_flag,
1303
1303
   (char**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1304
 
  {"database", 'D', N_("Database to use."), (char**) &current_db,
 
1304
  {"database", 'D', "Database to use.", (char**) &current_db,
1305
1305
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1306
1306
  {"default-character-set", OPT_DEFAULT_CHARSET,
1307
 
   N_("(not used)"), 0,
1308
 
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1309
 
  {"delimiter", OPT_DELIMITER, N_("Delimiter to be used."), (char**) &delimiter_str,
 
1307
   "Set the default character set.", (char**) &default_charset,
 
1308
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1309
  {"delimiter", OPT_DELIMITER, "Delimiter to be used.", (char**) &delimiter_str,
1310
1310
   (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1311
 
  {"execute", 'e', N_("Execute command and quit. (Disables --force and history file)"), 0,
 
1311
  {"execute", 'e', "Execute command and quit. (Disables --force and history file)", 0,
1312
1312
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1313
 
  {"vertical", 'E', N_("Print the output of a query (rows) vertically."),
 
1313
  {"vertical", 'E', "Print the output of a query (rows) vertically.",
1314
1314
   (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1315
1315
   0},
1316
 
  {"force", 'f', N_("Continue even if we get an sql error."),
 
1316
  {"force", 'f', "Continue even if we get an sql error.",
1317
1317
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1318
1318
   0, 0, 0, 0},
1319
1319
  {"named-commands", 'G',
1320
 
   N_("Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default."),
 
1320
   "Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.",
1321
1321
   (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1322
1322
   0, 0},
1323
1323
  {"no-named-commands", 'g',
1324
 
   N_("Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead."),
 
1324
   "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
1325
1325
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1326
 
  {"ignore-spaces", 'i', N_("Ignore space after function names."), 0, 0, 0,
 
1326
  {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
1327
1327
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1328
 
  {"local-infile", OPT_LOCAL_INFILE, N_("Enable/disable LOAD DATA LOCAL INFILE."),
 
1328
  {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
1329
1329
   (char**) &opt_local_infile,
1330
1330
   (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
1331
 
  {"no-beep", 'b', N_("Turn off beep on error."), (char**) &opt_nobeep,
 
1331
  {"no-beep", 'b', "Turn off beep on error.", (char**) &opt_nobeep,
1332
1332
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1333
 
  {"host", 'h', N_("Connect to host."), (char**) &current_host,
 
1333
  {"host", 'h', "Connect to host.", (char**) &current_host,
1334
1334
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1335
 
  {"line-numbers", OPT_LINE_NUMBERS, N_("Write line numbers for errors."),
 
1335
  {"html", 'H', "Produce HTML output.", (char**) &opt_html, (char**) &opt_html,
 
1336
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1337
  {"xml", 'X', "Produce XML output", (char**) &opt_xml, (char**) &opt_xml, 0,
 
1338
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1339
  {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
1336
1340
   (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
1337
1341
   NO_ARG, 1, 0, 0, 0, 0, 0},
1338
 
  {"skip-line-numbers", 'L', N_("Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead."), 0, 0, 0, GET_NO_ARG,
 
1342
  {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
1339
1343
   NO_ARG, 0, 0, 0, 0, 0, 0},
1340
 
  {"unbuffered", 'n', N_("Flush buffer after each query."), (char**) &unbuffered,
 
1344
  {"unbuffered", 'n', "Flush buffer after each query.", (char**) &unbuffered,
1341
1345
   (char**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1342
 
  {"column-names", OPT_COLUMN_NAMES, N_("Write column names in results."),
 
1346
  {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
1343
1347
   (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
1344
1348
   NO_ARG, 1, 0, 0, 0, 0, 0},
1345
1349
  {"skip-column-names", 'N',
1346
 
   N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."),
 
1350
   "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
1347
1351
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1348
1352
  {"set-variable", 'O',
1349
 
   N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."),
 
1353
   "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
1350
1354
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1351
 
  {"sigint-ignore", OPT_SIGINT_IGNORE, N_("Ignore SIGINT (CTRL-C)"),
 
1355
  {"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C)",
1352
1356
   (char**) &opt_sigint_ignore,  (char**) &opt_sigint_ignore, 0, GET_BOOL,
1353
1357
   NO_ARG, 0, 0, 0, 0, 0, 0},
1354
1358
  {"one-database", 'o',
1355
 
   N_("Only update the default database. This is useful for skipping updates to other database in the update log."),
 
1359
   "Only update the default database. This is useful for skipping updates to other database in the update log.",
1356
1360
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1357
1361
  {"pager", OPT_PAGER,
1358
 
   N_("Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default."),
 
1362
   "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.",
1359
1363
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1360
1364
  {"no-pager", OPT_NOPAGER,
1361
 
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
 
1365
   "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
1362
1366
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1363
1367
  {"password", 'p',
1364
 
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
 
1368
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
1365
1369
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1366
 
  {"port", 'P', N_("Port number to use for connection or 0 for default to, in order of preference, my.cnf, $DRIZZLE_TCP_PORT, ")
1367
 
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
1370
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
1371
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
1372
#if MYSQL_PORT_DEFAULT == 0
 
1373
   "/etc/services, "
 
1374
#endif
 
1375
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
1368
1376
   (char**) &opt_drizzle_port,
1369
1377
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,  0},
1370
 
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
 
1378
  {"prompt", OPT_PROMPT, "Set the drizzle prompt to this value.",
1371
1379
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
1372
1380
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1373
 
  {"protocol", OPT_DRIZZLE_PROTOCOL, N_("The protocol of connection (tcp,socket,pipe,memory)."),
 
1381
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1374
1382
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1375
1383
  {"quick", 'q',
1376
 
   N_("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."),
 
1384
   "Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file.",
1377
1385
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1378
 
  {"raw", 'r', N_("Write fields without conversion. Used with --batch."),
 
1386
  {"raw", 'r', "Write fields without conversion. Used with --batch.",
1379
1387
   (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1380
1388
   0, 0, 0},
1381
 
  {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
 
1389
  {"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default.",
1382
1390
   (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
1383
 
  {"silent", 's', N_("Be more silent. Print results with a tab as separator, each row on new line."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
 
1391
  {"silent", 's', "Be more silent. Print results with a tab as separator, each row on new line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
1384
1392
   0, 0},
1385
 
  {"socket", 'S', N_("Socket file to use for connection."),
 
1393
  {"socket", 'S', "Socket file to use for connection.",
1386
1394
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR_ALLOC,
1387
1395
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1388
 
  {"table", 't', N_("Output in table format."), (char**) &output_tables,
 
1396
  {"table", 't', "Output in table format.", (char**) &output_tables,
1389
1397
   (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1390
1398
  {"tee", OPT_TEE,
1391
 
   N_("Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default."),
 
1399
   "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default.",
1392
1400
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1393
 
  {"no-tee", OPT_NOTEE, N_("Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead"), 0, 0, 0, GET_NO_ARG,
 
1401
  {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
1394
1402
   NO_ARG, 0, 0, 0, 0, 0, 0},
1395
1403
#ifndef DONT_ALLOW_USER_CHANGE
1396
 
  {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
 
1404
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
1397
1405
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1398
1406
#endif
1399
 
  {"safe-updates", 'U', N_("Only allow UPDATE and DELETE that uses keys."),
1400
 
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
1401
 
   0, 0, 0, 0},
1402
 
  {"i-am-a-dummy", 'U', N_("Synonym for option --safe-updates, -U."),
1403
 
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
1404
 
   0, 0, 0, 0},
1405
 
  {"verbose", 'v', N_("Write more. (-v -v -v gives the table output format)."), 0,
 
1407
  {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
 
1408
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1409
   0, 0, 0, 0},
 
1410
  {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
 
1411
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1412
   0, 0, 0, 0},
 
1413
  {"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0,
1406
1414
   0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1407
 
  {"version", 'V', N_("Output version information and exit."), 0, 0, 0,
 
1415
  {"version", 'V', "Output version information and exit.", 0, 0, 0,
1408
1416
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1409
 
  {"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_NO_ARG,
 
1417
  {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
1410
1418
   NO_ARG, 0, 0, 0, 0, 0, 0},
1411
1419
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
1412
 
   N_("Number of seconds before connection timeout."),
 
1420
   "Number of seconds before connection timeout.",
1413
1421
   (char**) &opt_connect_timeout,
1414
1422
   (char**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
1415
1423
   0, 0},
1416
1424
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1417
 
   N_("Max packet length to send to, or receive from server"),
 
1425
   "Max packet length to send to, or receive from server",
1418
1426
   (char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
1419
1427
   GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
1420
1428
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1421
1429
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
1422
 
   N_("Buffer for TCP/IP and socket communication"),
 
1430
   "Buffer for TCP/IP and socket communication",
1423
1431
   (char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0, GET_ULONG,
1424
1432
   REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
1425
1433
  {"select_limit", OPT_SELECT_LIMIT,
1426
 
   N_("Automatic limit for SELECT when using --safe-updates"),
 
1434
   "Automatic limit for SELECT when using --safe-updates",
1427
1435
   (char**) &select_limit,
1428
1436
   (char**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
1429
1437
   0, 1, 0},
1430
1438
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1431
 
   N_("Automatic limit for rows in a join when using --safe-updates"),
 
1439
   "Automatic limit for rows in a join when using --safe-updates",
1432
1440
   (char**) &max_join_size,
1433
1441
   (char**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
1434
1442
   0, 1, 0},
1435
 
  {"secure-auth", OPT_SECURE_AUTH, N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"), (char**) &opt_secure_auth,
 
1443
  {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
 
1444
   " uses old (pre-4.1.1) protocol", (char**) &opt_secure_auth,
1436
1445
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1437
 
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
 
1446
  {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.",
 
1447
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1448
  {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
1438
1449
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
1439
1450
   0, 0, 0, 0, 0, 0},
1440
1451
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1445
1456
{
1446
1457
  const char* readline= "readline";
1447
1458
 
1448
 
  printf(_("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n"),
1449
 
         my_progname, VER, drizzle_get_client_info(),
1450
 
         SYSTEM_TYPE, MACHINE_TYPE,
 
1459
  printf("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n",
 
1460
         my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
1451
1461
         readline, rl_library_version);
1452
1462
 
1453
1463
  if (version)
1454
1464
    return;
1455
 
  printf(_("\
1456
 
Copyright (C) 2000-2008 MySQL AB\n                                      \
 
1465
  printf("\
 
1466
Copyright (C) 2000-2008 Drizzle AB\n                                      \
1457
1467
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n \
1458
 
and you are welcome to modify and redistribute it under the GPL license\n"));
1459
 
  printf(_("Usage: %s [OPTIONS] [database]\n"), my_progname);
 
1468
and you are welcome to modify and redistribute it under the GPL license\n");
 
1469
  printf("Usage: %s [OPTIONS] [database]\n", my_progname);
1460
1470
  my_print_help(my_long_options);
1461
1471
  print_defaults("my", load_default_groups);
1462
1472
  my_print_variables(my_long_options);
1478
1488
  case OPT_DELIMITER:
1479
1489
    if (argument == disabled_my_option)
1480
1490
    {
1481
 
      my_stpcpy(delimiter, DEFAULT_DELIMITER);
 
1491
      strmov(delimiter, DEFAULT_DELIMITER);
1482
1492
    }
1483
1493
    else
1484
1494
    {
1489
1499
      }
1490
1500
      else
1491
1501
      {
1492
 
        put_info(_("DELIMITER cannot contain a backslash character"),
 
1502
        put_info("DELIMITER cannot contain a backslash character",
1493
1503
                 INFO_ERROR,0,0);
1494
1504
        return 0;
1495
1505
      }
1510
1520
      init_tee(argument);
1511
1521
    break;
1512
1522
  case OPT_NOTEE:
1513
 
    printf(_("WARNING: option deprecated; use --disable-tee instead.\n"));
 
1523
    printf("WARNING: option deprecated; use --disable-tee instead.\n");
1514
1524
    if (opt_outfile)
1515
1525
      end_tee();
1516
1526
    break;
1524
1534
      {
1525
1535
        default_pager_set= 1;
1526
1536
        strmake(pager, argument, sizeof(pager) - 1);
1527
 
        my_stpcpy(default_pager, pager);
 
1537
        strmov(default_pager, pager);
1528
1538
      }
1529
1539
      else if (default_pager_set)
1530
 
        my_stpcpy(pager, default_pager);
 
1540
        strmov(pager, default_pager);
1531
1541
      else
1532
1542
        opt_nopager= 1;
1533
1543
    }
1534
1544
    break;
1535
1545
  case OPT_NOPAGER:
1536
 
    printf(_("WARNING: option deprecated; use --disable-pager instead.\n"));
 
1546
    printf("WARNING: option deprecated; use --disable-pager instead.\n");
1537
1547
    opt_nopager= 1;
1538
1548
    break;
 
1549
  case OPT_DRIZZLE_PROTOCOL:
 
1550
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
1551
                                    opt->name);
 
1552
    break;
1539
1553
  case OPT_SERVER_ARG:
1540
 
    printf(_("WARNING: --server-arg option not supported in this configuration.\n"));
 
1554
    printf("WARNING: --server-arg option not supported in this configuration.\n");
1541
1555
    break;
1542
1556
  case 'A':
1543
1557
    opt_rehash= 0;
1565
1579
    if (argument)
1566
1580
    {
1567
1581
      char *start= argument;
1568
 
      free(opt_password);
 
1582
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1569
1583
      opt_password= strdup(argument);
1570
1584
      while (*argument) *argument++= 'x';        // Destroy argument
1571
1585
      if (*start)
1609
1623
{
1610
1624
  char *tmp, *pagpoint;
1611
1625
  int ho_error;
1612
 
  const DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
 
1626
  DRIZZLE_PARAMETERS *drizzle_params= drizzle_get_parameters();
1613
1627
 
1614
 
  tmp= (char *) getenv("DRIZZLE_HOST");
 
1628
  tmp= (char *) getenv("MYSQL_HOST");
1615
1629
  if (tmp)
1616
1630
    current_host= strdup(tmp);
1617
1631
 
1618
1632
  pagpoint= getenv("PAGER");
1619
1633
  if (!((char*) (pagpoint)))
1620
1634
  {
1621
 
    my_stpcpy(pager, "stdout");
 
1635
    strmov(pager, "stdout");
1622
1636
    opt_nopager= 1;
1623
1637
  }
1624
1638
  else
1625
 
    my_stpcpy(pager, pagpoint);
1626
 
  my_stpcpy(default_pager, pager);
 
1639
    strmov(pager, pagpoint);
 
1640
  strmov(default_pager, pager);
1627
1641
 
1628
1642
  opt_max_allowed_packet= *drizzle_params->p_max_allowed_packet;
1629
1643
  opt_net_buffer_length= *drizzle_params->p_net_buffer_length;
1636
1650
 
1637
1651
  if (status.batch) /* disable pager and outfile in this case */
1638
1652
  {
1639
 
    my_stpcpy(default_pager, "stdout");
1640
 
    my_stpcpy(pager, "stdout");
 
1653
    strmov(default_pager, "stdout");
 
1654
    strmov(pager, "stdout");
1641
1655
    opt_nopager= 1;
1642
1656
    default_pager_set= 0;
1643
1657
    opt_outfile= 0;
1645
1659
    connect_flag= 0; /* Not in interactive mode */
1646
1660
  }
1647
1661
 
 
1662
  if (strcmp(default_charset, charset_info->csname) &&
 
1663
      !(charset_info= get_charset_by_csname(default_charset,
 
1664
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
1665
    exit(1);
1648
1666
  if (argc > 1)
1649
1667
  {
1650
1668
    usage(0);
1653
1671
  if (argc == 1)
1654
1672
  {
1655
1673
    skip_updates= 0;
1656
 
    free(current_db);
 
1674
    my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
1657
1675
    current_db= strdup(*argv);
1658
1676
  }
1659
1677
  if (tty_password)
1660
 
    opt_password= get_tty_password(NULL);
 
1678
    opt_password= get_tty_password(NullS);
1661
1679
  if (debug_info_flag)
1662
1680
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1663
1681
  if (debug_check_flag)
1669
1687
{
1670
1688
  char *line;
1671
1689
  char in_string=0;
1672
 
  uint32_t line_number=0;
 
1690
  ulong line_number=0;
1673
1691
  bool ml_comment= 0;
1674
1692
  COMMANDS *com;
1675
1693
  status.exit_status=1;
1686
1704
        you save the file using "Unicode UTF-8" format.
1687
1705
      */
1688
1706
      if (!line_number &&
1689
 
          (unsigned char) line[0] == 0xEF &&
1690
 
          (unsigned char) line[1] == 0xBB &&
1691
 
          (unsigned char) line[2] == 0xBF)
 
1707
          (uchar) line[0] == 0xEF &&
 
1708
          (uchar) line[1] == 0xBB &&
 
1709
          (uchar) line[2] == 0xBF)
1692
1710
        line+= 3;
1693
1711
      line_number++;
1694
 
      if (!glob_buffer->empty())
 
1712
      if (glob_buffer->length!=0)
1695
1713
        status.query_start_line=line_number;
1696
1714
    }
1697
1715
    else
1698
1716
    {
1699
 
      const char *prompt= (const char*) (ml_comment ? "   /*> " :
1700
 
                                         (glob_buffer->empty())
1701
 
                                         ?  construct_prompt()
1702
 
                                         : !in_string ? "    -> " :
1703
 
                                         in_string == '\'' ?
1704
 
                                         "    '> " : (in_string == '`' ?
1705
 
                                                      "    `> " :
1706
 
                                                      "    \"> "));
1707
 
      if (opt_outfile && glob_buffer->empty())
 
1717
      char *prompt= (char*) (ml_comment ? "   /*> " :
 
1718
                             (glob_buffer->length == 0) ?  construct_prompt() :
 
1719
                             !in_string ? "    -> " :
 
1720
                             in_string == '\'' ?
 
1721
                             "    '> " : (in_string == '`' ?
 
1722
                                          "    `> " :
 
1723
                                          "    \"> "));
 
1724
      if (opt_outfile && (glob_buffer->length==0))
1708
1725
        fflush(OUTFILE);
1709
1726
 
1710
1727
      if (opt_outfile)
1728
1745
      Check if line is a drizzle command line
1729
1746
      (We want to allow help, print and clear anywhere at line start
1730
1747
    */
1731
 
    if ((named_cmds || (glob_buffer->empty()))
 
1748
    if ((named_cmds || (glob_buffer->length==0))
1732
1749
        && !ml_comment && !in_string && (com=find_command(line,0)))
1733
1750
    {
1734
1751
      if ((*com->func)(glob_buffer,line) > 0)
1735
1752
        break;
1736
1753
      // If buffer was emptied
1737
 
      if (glob_buffer->empty())
 
1754
      if (glob_buffer->length==0)
1738
1755
        in_string=0;
1739
1756
      if (interactive && status.add_to_history && not_in_history(line))
1740
1757
        add_history(line);
1748
1765
  if (!interactive && !status.exit_status)
1749
1766
  {
1750
1767
    remove_cntrl(glob_buffer);
1751
 
    if (!glob_buffer->empty())
 
1768
    if (glob_buffer->length != 0)
1752
1769
    {
1753
1770
      status.exit_status=1;
1754
1771
      if (com_go(glob_buffer,line) <= 0)
1760
1777
}
1761
1778
 
1762
1779
 
1763
 
static COMMANDS *find_command(const char *name,char cmd_char)
 
1780
static COMMANDS *find_command(char *name,char cmd_char)
1764
1781
{
1765
1782
  uint len;
1766
 
  const char *end;
 
1783
  char *end;
1767
1784
 
1768
1785
  if (!name)
1769
1786
  {
1782
1799
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
1783
1800
                                !(strlen(name) >= 9 &&
1784
1801
                                  !my_strnncoll(charset_info,
1785
 
                                                (unsigned char*) name, 9,
1786
 
                                                (const unsigned char*) "delimiter",
 
1802
                                                (uchar*) name, 9,
 
1803
                                                (const uchar*) "delimiter",
1787
1804
                                                9))))
1788
1805
      return((COMMANDS *) 0);
1789
1806
    if ((end=strcont(name," \t")))
1801
1818
  for (uint i= 0; commands[i].name; i++)
1802
1819
  {
1803
1820
    if (commands[i].func &&
1804
 
        ((name && !my_strnncoll(charset_info,(const unsigned char*)name,len, (const unsigned char*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
 
1821
        ((name && !my_strnncoll(charset_info,(uchar*)name,len, (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || (!name && commands[i].cmd_char == cmd_char)))
1805
1822
    {
1806
1823
      return(&commands[i]);
1807
1824
    }
1810
1827
}
1811
1828
 
1812
1829
 
1813
 
static bool add_line(string *buffer, char *line, char *in_string,
 
1830
static bool add_line(DYNAMIC_STRING *buffer,char *line,char *in_string,
1814
1831
                        bool *ml_comment)
1815
1832
{
1816
 
  unsigned char inchar;
 
1833
  uchar inchar;
1817
1834
  char buff[80], *pos, *out;
1818
1835
  COMMANDS *com;
1819
1836
  bool need_space= 0;
1820
1837
  bool ss_comment= 0;
1821
1838
 
1822
1839
 
1823
 
  if (!line[0] && (buffer->empty()))
 
1840
  if (!line[0] && (buffer->length==0))
1824
1841
    return(0);
1825
1842
  if (status.add_to_history && line[0] && not_in_history(line))
1826
1843
    add_history(line);
1827
1844
  char *end_of_line=line+(uint) strlen(line);
1828
1845
 
1829
 
  for (pos=out=line ; (inchar= (unsigned char) *pos) ; pos++)
 
1846
  for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
1830
1847
  {
1831
1848
    if (!preserve_comments)
1832
1849
    {
1833
1850
      // Skip spaces at the beggining of a statement
1834
1851
      if (my_isspace(charset_info,inchar) && (out == line) &&
1835
 
          (buffer->empty()))
 
1852
          (buffer->length==0))
1836
1853
        continue;
1837
1854
    }
1838
1855
 
1854
1871
    }
1855
1872
#endif
1856
1873
        if (!*ml_comment && inchar == '\\' &&
1857
 
            !(*in_string && (drizzle.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)))
 
1874
        !(drizzle.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES))
1858
1875
    {
1859
1876
      // Found possbile one character command like \c
1860
1877
 
1861
 
      if (!(inchar = (unsigned char) *++pos))
 
1878
      if (!(inchar = (uchar) *++pos))
1862
1879
        break;        // readline adds one '\'
1863
1880
      if (*in_string || inchar == 'N')  // \N is short for NULL
1864
1881
      {          // Don't allow commands in string
1866
1883
        *out++= (char) inchar;
1867
1884
        continue;
1868
1885
      }
1869
 
      if ((com=find_command(NULL,(char) inchar)))
 
1886
      if ((com=find_command(NullS,(char) inchar)))
1870
1887
      {
1871
1888
        // Flush previously accepted characters
1872
1889
        if (out != line)
1873
1890
        {
1874
 
          buffer->append(line, (out-line));
 
1891
          dynstr_append_mem(buffer, line, (out-line));
1875
1892
          out= line;
1876
1893
        }
1877
1894
 
1905
1922
      }
1906
1923
      else
1907
1924
      {
1908
 
        sprintf(buff,_("Unknown command '\\%c'."),inchar);
 
1925
        sprintf(buff,"Unknown command '\\%c'.",inchar);
1909
1926
        if (put_info(buff,INFO_ERROR,0,0) > 0)
1910
1927
          return(1);
1911
1928
        *out++='\\';
1915
1932
    }
1916
1933
    else if (!*ml_comment && !*in_string &&
1917
1934
             (end_of_line - pos) >= 10 &&
1918
 
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
1919
 
                           (const unsigned char*) "delimiter ", 10))
 
1935
             !my_strnncoll(charset_info, (uchar*) pos, 10,
 
1936
                           (const uchar*) "delimiter ", 10))
1920
1937
    {
1921
1938
      // Flush previously accepted characters
1922
1939
      if (out != line)
1923
1940
      {
1924
 
        buffer->append(line, (out - line));
 
1941
        dynstr_append_mem(buffer, line, (out - line));
1925
1942
        out= line;
1926
1943
      }
1927
1944
 
1928
1945
      // Flush possible comments in the buffer
1929
 
      if (!buffer->empty())
 
1946
      if (buffer->length != 0)
1930
1947
      {
1931
1948
        if (com_go(buffer, 0) > 0) // < 0 is not fatal
1932
1949
          return(1);
1933
1950
        assert(buffer!=NULL);
1934
 
        buffer->clear();
 
1951
        dynstr_set(buffer, NULL);
1935
1952
      }
1936
1953
 
1937
1954
      /*
1938
1955
        Delimiter wants the get rest of the given line as argument to
1939
1956
        allow one to change ';' to ';;' and back
1940
1957
      */
1941
 
      buffer->append(pos);
 
1958
      dynstr_append(buffer,pos);
1942
1959
      if (com_delimiter(buffer, pos) > 0)
1943
1960
        return(1);
1944
1961
 
1945
 
      buffer->clear();
 
1962
      dynstr_set(buffer, NULL);
1946
1963
      break;
1947
1964
    }
1948
1965
    else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
1958
1975
      // Flush previously accepted characters
1959
1976
      if (out != line)
1960
1977
      {
1961
 
        buffer->append(line, (out-line));
 
1978
        dynstr_append_mem(buffer, line, (out-line));
1962
1979
        out= line;
1963
1980
      }
1964
1981
 
1968
1985
                                 my_isspace(charset_info, pos[2]))))
1969
1986
      {
1970
1987
        // Add trailing single line comments to this statement
1971
 
        buffer->append(pos);
 
1988
        dynstr_append(buffer, pos);
1972
1989
        pos+= strlen(pos);
1973
1990
      }
1974
1991
 
1975
1992
      pos--;
1976
1993
 
1977
 
      if ((com= find_command(buffer->c_str(), 0)))
 
1994
      if ((com= find_command(buffer->str, 0)))
1978
1995
      {
1979
1996
 
1980
 
        if ((*com->func)(buffer, buffer->c_str()) > 0)
 
1997
        if ((*com->func)(buffer, buffer->str) > 0)
1981
1998
          return(1);                       // Quit
1982
1999
      }
1983
2000
      else
1985
2002
        if (com_go(buffer, 0) > 0)             // < 0 is not fatal
1986
2003
          return(1);
1987
2004
      }
1988
 
      buffer->clear();
 
2005
      dynstr_set(buffer, NULL);
1989
2006
    }
1990
2007
    else if (!*ml_comment
1991
2008
             && (!*in_string
1997
2014
      // Flush previously accepted characters
1998
2015
      if (out != line)
1999
2016
      {
2000
 
        buffer->append(line, (out - line));
 
2017
        dynstr_append_mem(buffer, line, (out - line));
2001
2018
        out= line;
2002
2019
      }
2003
2020
 
2004
2021
      // comment to end of line
2005
2022
      if (preserve_comments)
2006
 
        buffer->append(pos);
 
2023
        dynstr_append(buffer,pos);
2007
2024
 
2008
2025
      break;
2009
2026
    }
2020
2037
      *ml_comment= 1;
2021
2038
      if (out != line)
2022
2039
      {
2023
 
        buffer->append(line, (out-line));
 
2040
        dynstr_append_mem(buffer, line, (out-line));
2024
2041
        out=line;
2025
2042
      }
2026
2043
    }
2036
2053
      *ml_comment= 0;
2037
2054
      if (out != line)
2038
2055
      {
2039
 
        buffer->append(line, (out - line));
 
2056
        dynstr_append_mem(buffer, line, (out - line));
2040
2057
        out= line;
2041
2058
      }
2042
2059
      // Consumed a 2 chars or more, and will add 1 at most,
2065
2082
      }
2066
2083
    }
2067
2084
  }
2068
 
  if (out != line || (buffer->length() > 0))
 
2085
  if (out != line || (buffer->length > 0))
2069
2086
  {
2070
2087
    *out++='\n';
2071
2088
    uint length=(uint) (out-line);
2072
 
    if ((!*ml_comment || preserve_comments))
2073
 
      buffer->append(line, length);
 
2089
    if ((!*ml_comment || preserve_comments)
 
2090
        && dynstr_append_mem(buffer, line, length))
 
2091
      return(1);
2074
2092
  }
2075
2093
  return(0);
2076
2094
}
2097
2115
 
2098
2116
 
2099
2117
/* glues pieces of history back together if in pieces   */
2100
 
static void fix_history(string *final_command)
 
2118
static void fix_history(DYNAMIC_STRING *final_command)
2101
2119
{
2102
2120
  int total_lines = 1;
2103
 
  const char *ptr = final_command->c_str();
 
2121
  const char *ptr = final_command->str;
2104
2122
  char str_char = '\0';  /* Character if we are in a string or not */
2105
2123
 
2106
2124
  /* Converted buffer */
2107
 
  string fixed_buffer;
2108
 
  fixed_buffer.reserve(512);
 
2125
  DYNAMIC_STRING *fixed_buffer=
 
2126
    (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
2127
 
 
2128
  init_dynamic_string(fixed_buffer, "", 512, 512);
2109
2129
 
2110
2130
  /* find out how many lines we have and remove newlines */
2111
2131
  while (*ptr != '\0')
2120
2140
        str_char = *ptr;
2121
2141
      else if (str_char == *ptr)   /* close string */
2122
2142
        str_char = '\0';
2123
 
      fixed_buffer.append(ptr, 1);
 
2143
      dynstr_append_mem(fixed_buffer, ptr, 1);
2124
2144
      break;
2125
2145
    case '\n':
2126
2146
      /*
2127
2147
        not in string, change to space
2128
2148
        if in string, leave it alone
2129
2149
      */
2130
 
      fixed_buffer.append((str_char == '\0') ? " " : "\n");
 
2150
      dynstr_append(fixed_buffer,(str_char == '\0') ? " " : "\n");
2131
2151
      total_lines++;
2132
2152
      break;
2133
2153
    case '\\':
2134
 
      fixed_buffer.append("\\");
 
2154
      dynstr_append(fixed_buffer, "\\");
2135
2155
      /* need to see if the backslash is escaping anything */
2136
2156
      if (str_char)
2137
2157
      {
2138
2158
        ptr++;
2139
2159
        /* special characters that need escaping */
2140
2160
        if (*ptr == '\'' || *ptr == '"' || *ptr == '\\')
2141
 
          fixed_buffer.append(ptr, 1);
 
2161
          dynstr_append_mem(fixed_buffer, ptr, 1);
2142
2162
        else
2143
2163
          ptr--;
2144
2164
      }
2145
2165
      break;
2146
2166
    default:
2147
 
      fixed_buffer.append(ptr, 1);
 
2167
      dynstr_append_mem(fixed_buffer, ptr, 1);
2148
2168
    }
2149
2169
    ptr++;
2150
2170
  }
2151
2171
  if (total_lines > 1)
2152
 
    add_history(fixed_buffer.c_str());
 
2172
    add_history(fixed_buffer->str);
2153
2173
}
2154
2174
 
2155
2175
/*
2167
2187
  return 1;
2168
2188
}
2169
2189
 
2170
 
static void initialize_readline (char *name)
 
2190
static void initialize_readline (const char *name)
2171
2191
{
2172
2192
  /* Allow conditional parsing of the ~/.inputrc file. */
2173
 
  rl_readline_name= name;
 
2193
  rl_readline_name= (char *)name;
2174
2194
 
2175
2195
  /* Tell the completer that we want a crack first. */
2176
2196
  rl_attempted_completion_function= (rl_completion_func_t*)&mysql_completion;
2214
2234
 
2215
2235
      b = find_all_matches(&ht,text,(uint) strlen(text),&len);
2216
2236
      if (!b)
2217
 
        return NULL;
 
2237
        return NullS;
2218
2238
      e = b->pData;
2219
2239
    }
2220
2240
 
2241
2261
        }
2242
2262
      }
2243
2263
    }
2244
 
    ptr= NULL;
 
2264
    ptr= NullS;
2245
2265
    while (e && !ptr)
2246
2266
    {          /* find valid entry in bucket */
2247
2267
      if ((uint) strlen(e->str) == b->nKeyLength)
2270
2290
    if (ptr)
2271
2291
      return ptr;
2272
2292
  }
2273
 
  return NULL;
 
2293
  return NullS;
2274
2294
}
2275
2295
 
2276
2296
 
2332
2352
    {
2333
2353
      if (drizzle_num_rows(tables) > 0 && !opt_silent && write_info)
2334
2354
      {
2335
 
        tee_fprintf(stdout, _("\
 
2355
        tee_fprintf(stdout, "\
2336
2356
Reading table information for completion of table and column names\n    \
2337
 
You can turn off this feature to get a quicker startup with -A\n\n"));
 
2357
You can turn off this feature to get a quicker startup with -A\n\n");
2338
2358
      }
2339
2359
      while ((table_row=drizzle_fetch_row(tables)))
2340
2360
      {
2361
2381
  i=0;
2362
2382
  while ((table_row=drizzle_fetch_row(tables)))
2363
2383
  {
2364
 
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NULL)))
 
2384
    if ((fields=drizzle_list_fields(&drizzle,(const char*) table_row[0],NullS)))
2365
2385
    {
2366
2386
      num_fields=drizzle_num_fields(fields);
2367
2387
      if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
2408
2428
    for (;;)
2409
2429
    {
2410
2430
      if (*s == (char) c) return (char*) s;
2411
 
      if (!*s++) return NULL;
 
2431
      if (!*s++) return NullS;
2412
2432
    }
2413
2433
  }
2414
2434
 
2416
2436
  {
2417
2437
    register char *t;
2418
2438
 
2419
 
    t = NULL;
 
2439
    t = NullS;
2420
2440
    do if (*s == (char) c) t = (char*) s; while (*s++);
2421
2441
    return (char*) t;
2422
2442
  }
2429
2449
  /* purecov: begin tested */
2430
2450
  if (opt_reconnect)
2431
2451
  {
2432
 
    put_info(_("No connection. Trying to reconnect..."),INFO_INFO,0,0);
2433
 
    (void) com_connect((string *)0, 0);
 
2452
    put_info("No connection. Trying to reconnect...",INFO_INFO,0,0);
 
2453
    (void) com_connect((DYNAMIC_STRING *) 0, 0);
2434
2454
    if (opt_rehash)
2435
2455
      com_rehash(NULL, NULL);
2436
2456
  }
2437
2457
  if (!connected)
2438
 
    return put_info(_("Can't connect to the server\n"),INFO_ERROR,0,0);
 
2458
    return put_info("Can't connect to the server\n",INFO_ERROR,0,0);
2439
2459
  /* purecov: end */
2440
2460
  return 0;
2441
2461
}
2444
2464
{
2445
2465
  DRIZZLE_RES *res;
2446
2466
 
2447
 
  free(current_db);
 
2467
  my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
2448
2468
  current_db= NULL;
2449
2469
  /* In case of error below current_db will be NULL */
2450
2470
  if (!drizzle_query(&drizzle, "SELECT DATABASE()") &&
2492
2512
  char ccat= (*cur)[num_cat][0];
2493
2513
  if (*last_char != ccat)
2494
2514
  {
2495
 
    put_info(ccat == 'Y' ? _("categories:") : _("topics:"), INFO_INFO,0,0);
 
2515
    put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO,0,0);
2496
2516
    *last_char= ccat;
2497
2517
  }
2498
2518
  tee_fprintf(PAGER, "   %s\n", (*cur)[num_name]);
2499
2519
}
2500
2520
 
2501
2521
 
2502
 
static int com_server_help(string *buffer,
2503
 
                           const char *line __attribute__((unused)),
 
2522
static int com_server_help(DYNAMIC_STRING *buffer,
 
2523
                           char *line __attribute__((unused)),
2504
2524
                           char *help_arg)
2505
2525
{
2506
2526
  DRIZZLE_ROW cur;
2507
 
  const char *server_cmd= buffer->c_str();
 
2527
  const char *server_cmd= buffer->str;
2508
2528
  char cmd_buf[100];
2509
2529
  DRIZZLE_RES *result;
2510
2530
  int error;
2511
2531
 
2512
2532
  if (help_arg[0] != '\'')
2513
2533
  {
2514
 
    char *end_arg= strchr(help_arg, '\0');
 
2534
    char *end_arg= strend(help_arg);
2515
2535
    if(--end_arg)
2516
2536
    {
2517
2537
      while (my_isspace(charset_info,*end_arg))
2518
2538
        end_arg--;
2519
2539
      *++end_arg= '\0';
2520
2540
    }
2521
 
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NULL);
 
2541
    (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
2522
2542
    server_cmd= cmd_buf;
2523
2543
  }
2524
2544
 
2543
2563
      }
2544
2564
 
2545
2565
      init_pager();
2546
 
      tee_fprintf(PAGER,   _("Name: \'%s\'\n"), cur[0]);
2547
 
      tee_fprintf(PAGER,   _("Description:\n%s"), cur[1]);
 
2566
      tee_fprintf(PAGER,   "Name: \'%s\'\n", cur[0]);
 
2567
      tee_fprintf(PAGER,   "Description:\n%s", cur[1]);
2548
2568
      if (cur[2] && *((char*)cur[2]))
2549
 
        tee_fprintf(PAGER, _("Examples:\n%s"), cur[2]);
 
2569
        tee_fprintf(PAGER, "Examples:\n%s", cur[2]);
2550
2570
      tee_fprintf(PAGER,   "\n");
2551
2571
      end_pager();
2552
2572
    }
2559
2579
 
2560
2580
      if (num_fields == 2)
2561
2581
      {
2562
 
        put_info(_("Many help items for your request exist."), INFO_INFO,0,0);
2563
 
        put_info(_("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following"), INFO_INFO,0,0);
 
2582
        put_info("Many help items for your request exist.", INFO_INFO,0,0);
 
2583
        put_info("To make a more specific request, please type 'help <item>',\nwhere <item> is one of the following", INFO_INFO,0,0);
2564
2584
        num_name= 0;
2565
2585
        num_cat= 1;
2566
2586
      }
2567
2587
      else if ((cur= drizzle_fetch_row(result)))
2568
2588
      {
2569
 
        tee_fprintf(PAGER, _("You asked for help about help category: '%s'\n"), cur[0]);
2570
 
        put_info(_("For more information, type 'help <item>', where <item> is one of the following"), INFO_INFO,0,0);
 
2589
        tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]);
 
2590
        put_info("For more information, type 'help <item>', where <item> is one of the following", INFO_INFO,0,0);
2571
2591
        num_name= 1;
2572
2592
        num_cat= 2;
2573
2593
        print_help_item(&cur,1,2,&last_char);
2580
2600
    }
2581
2601
    else
2582
2602
    {
2583
 
      put_info(_("\nNothing found"), INFO_INFO,0,0);
2584
 
      put_info(_("Please try to run 'help contents' for a list of all accessible topics\n"), INFO_INFO,0,0);
 
2603
      put_info("\nNothing found", INFO_INFO,0,0);
 
2604
      put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO,0,0);
2585
2605
    }
2586
2606
  }
2587
2607
 
2591
2611
}
2592
2612
 
2593
2613
static int
2594
 
com_help(string *buffer __attribute__((unused)),
2595
 
         const char *line __attribute__((unused)))
 
2614
com_help(DYNAMIC_STRING *buffer __attribute__((unused)),
 
2615
         char *line __attribute__((unused)))
2596
2616
{
2597
2617
  register int i, j;
2598
2618
  char * help_arg= strchr(line,' '), buff[32], *end;
2600
2620
  {
2601
2621
    while (my_isspace(charset_info,*help_arg))
2602
2622
      help_arg++;
2603
 
    if (*help_arg) return com_server_help(buffer,line,help_arg);
 
2623
    if (*help_arg)
 
2624
      return com_server_help(buffer,line,help_arg);
2604
2625
  }
2605
2626
 
2606
 
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
 
2627
  put_info("List of all Drizzle commands:", INFO_INFO,0,0);
2607
2628
  if (!named_cmds)
2608
 
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
 
2629
    put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO,0,0);
2609
2630
  for (i = 0; commands[i].name; i++)
2610
2631
  {
2611
 
    end= my_stpcpy(buff, commands[i].name);
 
2632
    end= strmov(buff, commands[i].name);
2612
2633
    for (j= (int)strlen(commands[i].name); j < 10; j++)
2613
 
      end= my_stpcpy(end, " ");
 
2634
      end= strmov(end, " ");
2614
2635
    if (commands[i].func)
2615
2636
      tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
2616
 
                  commands[i].cmd_char, _(commands[i].doc));
 
2637
                  commands[i].cmd_char, commands[i].doc);
2617
2638
  }
2618
2639
  if (connected && drizzle_get_server_version(&drizzle) >= 40100)
2619
 
    put_info(_("\nFor server side help, type 'help contents'\n"), INFO_INFO,0,0);
 
2640
    put_info("\nFor server side help, type 'help contents'\n", INFO_INFO,0,0);
2620
2641
  return 0;
2621
2642
}
2622
2643
 
2623
2644
 
2624
2645
static int
2625
 
com_clear(string *buffer,
2626
 
          const char *line __attribute__((unused)))
 
2646
com_clear(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
2627
2647
{
2628
2648
  if (status.add_to_history)
2629
2649
    fix_history(buffer);
2630
 
  buffer->clear();
 
2650
  dynstr_set(buffer, NULL);
2631
2651
  return 0;
2632
2652
}
2633
2653
 
 
2654
static int
 
2655
com_charset(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
 
2656
{
 
2657
  char buff[256], *param;
 
2658
  CHARSET_INFO * new_cs;
 
2659
  strmake(buff, line, sizeof(buff) - 1);
 
2660
  param= get_arg(buff, 0);
 
2661
  if (!param || !*param)
 
2662
  {
 
2663
    return put_info("Usage: \\C char_setname | charset charset_name",
 
2664
                    INFO_ERROR, 0, 0);
 
2665
  }
 
2666
  new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
 
2667
  if (new_cs)
 
2668
  {
 
2669
    charset_info= new_cs;
 
2670
    drizzle_set_character_set(&drizzle, charset_info->csname);
 
2671
    default_charset= (char *)charset_info->csname;
 
2672
    default_charset_used= 1;
 
2673
    put_info("Charset changed", INFO_INFO,0,0);
 
2674
  }
 
2675
  else put_info("Charset is not found", INFO_INFO,0,0);
 
2676
  return 0;
 
2677
}
2634
2678
 
2635
2679
/*
2636
2680
  Execute command
2639
2683
  1  if fatal error
2640
2684
*/
2641
2685
static int
2642
 
com_go(string *buffer,
2643
 
       const char *line __attribute__((unused)))
 
2686
com_go(DYNAMIC_STRING *buffer,
 
2687
       char *line __attribute__((unused)))
2644
2688
{
2645
2689
  char          buff[200]; /* about 110 chars used so far */
2646
2690
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2647
2691
  DRIZZLE_RES     *result;
2648
 
  uint32_t         timer, warnings= 0;
 
2692
  ulong         timer, warnings= 0;
2649
2693
  uint          error= 0;
2650
2694
  int           err= 0;
2651
2695
 
2654
2698
  /* Remove garbage for nicer messages */
2655
2699
  remove_cntrl(buffer);
2656
2700
 
2657
 
  if (buffer->empty())
 
2701
  if (buffer->length == 0)
2658
2702
  {
2659
2703
    // Ignore empty quries
2660
2704
    if (status.batch)
2661
2705
      return 0;
2662
 
    return put_info(_("No query specified\n"),INFO_ERROR,0,0);
 
2706
    return put_info("No query specified\n",INFO_ERROR,0,0);
2663
2707
 
2664
2708
  }
2665
2709
  if (!connected && reconnect())
2666
2710
  {
2667
2711
    // Remove query on error
2668
 
    buffer->clear();
 
2712
    dynstr_set(buffer, NULL);
2669
2713
    return opt_reconnect ? -1 : 1;          // Fatal error
2670
2714
  }
2671
2715
  if (verbose)
2672
2716
    (void) com_print(buffer, 0);
2673
2717
 
2674
2718
  if (skip_updates &&
2675
 
      ((buffer->length() < 4) || (buffer->find( "SET ") != 0)))
 
2719
      ((buffer->length < 4) || !strncmp(buffer->str, "SET ", 4)))
2676
2720
  {
2677
 
    (void) put_info(_("Ignoring query to other database"),INFO_INFO,0,0);
 
2721
    (void) put_info("Ignoring query to other database",INFO_INFO,0,0);
2678
2722
    return 0;
2679
2723
  }
2680
2724
 
2681
2725
  timer=start_timer();
2682
2726
  executing_query= 1;
2683
 
  error= drizzle_real_query_for_lazy(buffer->c_str(),buffer->length());
 
2727
  error= drizzle_real_query_for_lazy(buffer->str,buffer->length);
2684
2728
 
2685
2729
  if (status.add_to_history)
2686
2730
  {
2687
 
    buffer->append(vertical ? "\\G" : delimiter);
 
2731
    dynstr_append(buffer, vertical ? "\\G" : delimiter);
2688
2732
    /* Append final command onto history */
2689
2733
    fix_history(buffer);
2690
2734
  }
2691
2735
 
2692
 
  buffer->clear();
 
2736
  dynstr_set(buffer, NULL);
2693
2737
 
2694
2738
  if (error)
2695
2739
    goto end;
2723
2767
    {
2724
2768
      if (!drizzle_num_rows(result) && ! quick && !column_types_flag)
2725
2769
      {
2726
 
        my_stpcpy(buff, _("Empty set"));
 
2770
        strmov(buff, "Empty set");
 
2771
        if (opt_xml)
 
2772
        {
 
2773
          /*
 
2774
            We must print XML header and footer
 
2775
            to produce a well-formed XML even if
 
2776
            the result set is empty (Bug#27608).
 
2777
          */
 
2778
          init_pager();
 
2779
          print_table_data_xml(result);
 
2780
          end_pager();
 
2781
        }
2727
2782
      }
2728
2783
      else
2729
2784
      {
2730
2785
        init_pager();
2731
 
        if (vertical || (auto_vertical_output &&
2732
 
                         (terminal_width < get_result_width(result))))
 
2786
        if (opt_html)
 
2787
          print_table_data_html(result);
 
2788
        else if (opt_xml)
 
2789
          print_table_data_xml(result);
 
2790
        else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
2733
2791
          print_table_data_vertically(result);
2734
2792
        else if (opt_silent && verbose <= 2 && !output_tables)
2735
2793
          print_tab_data(result);
2736
2794
        else
2737
2795
          print_table_data(result);
2738
 
        sprintf(buff,
2739
 
                ngettext("%ld row in set","%ld rows in set",
2740
 
                         (long) drizzle_num_rows(result)),
2741
 
                (long) drizzle_num_rows(result));
 
2796
        sprintf(buff,"%ld %s in set",
 
2797
                (long) drizzle_num_rows(result),
 
2798
                (long) drizzle_num_rows(result) == 1 ? "row" : "rows");
2742
2799
        end_pager();
2743
2800
        if (drizzle_errno(&drizzle))
2744
2801
          error= put_error(&drizzle);
2745
2802
      }
2746
2803
    }
2747
2804
    else if (drizzle_affected_rows(&drizzle) == ~(uint64_t) 0)
2748
 
      my_stpcpy(buff,_("Query OK"));
 
2805
      strmov(buff,"Query OK");
2749
2806
    else
2750
 
      sprintf(buff, ngettext("Query OK, %ld row affected",
2751
 
                             "Query OK, %ld rows affected",
2752
 
                             (long) drizzle_affected_rows(&drizzle)),
2753
 
              (long) drizzle_affected_rows(&drizzle));
 
2807
      sprintf(buff,"Query OK, %ld %s affected",
 
2808
              (long) drizzle_affected_rows(&drizzle),
 
2809
              (long) drizzle_affected_rows(&drizzle) == 1 ? "row" : "rows");
2754
2810
 
2755
 
    pos= strchr(buff, '\0');
 
2811
    pos=strend(buff);
2756
2812
    if ((warnings= drizzle_warning_count(&drizzle)))
2757
2813
    {
2758
2814
      *pos++= ',';
2759
2815
      *pos++= ' ';
2760
2816
      pos=int10_to_str(warnings, pos, 10);
2761
 
      pos=my_stpcpy(pos, " warning");
 
2817
      pos=strmov(pos, " warning");
2762
2818
      if (warnings != 1)
2763
2819
        *pos++= 's';
2764
2820
    }
2765
 
    my_stpcpy(pos, time_buff);
 
2821
    strmov(pos, time_buff);
2766
2822
    put_info(buff,INFO_RESULT,0,0);
2767
2823
    if (drizzle_info(&drizzle))
2768
2824
      put_info(drizzle_info(&drizzle),INFO_RESULT,0,0);
2841
2897
 
2842
2898
 
2843
2899
static int
2844
 
com_ego(string *buffer,const char *line)
 
2900
com_ego(DYNAMIC_STRING *buffer,char *line)
2845
2901
{
2846
2902
  int result;
2847
2903
  bool oldvertical=vertical;
2864
2920
    case DRIZZLE_TYPE_LONG:        return "LONG";
2865
2921
    case DRIZZLE_TYPE_LONGLONG:    return "LONGLONG";
2866
2922
    case DRIZZLE_TYPE_NULL:        return "NULL";
 
2923
    case DRIZZLE_TYPE_SET:         return "SET";
 
2924
    case DRIZZLE_TYPE_SHORT:       return "SHORT";
 
2925
    case DRIZZLE_TYPE_STRING:      return "STRING";
2867
2926
    case DRIZZLE_TYPE_TIME:        return "TIME";
2868
2927
    case DRIZZLE_TYPE_TIMESTAMP:   return "TIMESTAMP";
2869
2928
    case DRIZZLE_TYPE_TINY:        return "TINY";
 
2929
    case DRIZZLE_TYPE_VAR_STRING:  return "VAR_STRING";
 
2930
    case DRIZZLE_TYPE_YEAR:        return "YEAR";
2870
2931
    default:                     return "?-unknown-?";
2871
2932
  }
2872
2933
}
2876
2937
  char *s=buf;
2877
2938
  *s=0;
2878
2939
#define ff2s_check_flag(X)                                              \
2879
 
  if (f & X ## _FLAG) { s=my_stpcpy(s, # X " "); f &= ~ X ## _FLAG; }
 
2940
  if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
2880
2941
  ff2s_check_flag(NOT_NULL);
2881
2942
  ff2s_check_flag(PRI_KEY);
2882
2943
  ff2s_check_flag(UNIQUE_KEY);
2883
2944
  ff2s_check_flag(MULTIPLE_KEY);
2884
2945
  ff2s_check_flag(BLOB);
2885
2946
  ff2s_check_flag(UNSIGNED);
 
2947
  ff2s_check_flag(ZEROFILL);
2886
2948
  ff2s_check_flag(BINARY);
2887
2949
  ff2s_check_flag(ENUM);
2888
2950
  ff2s_check_flag(AUTO_INCREMENT);
2937
2999
  DRIZZLE_ROW     cur;
2938
3000
  DRIZZLE_FIELD   *field;
2939
3001
  bool          *num_flag;
2940
 
  string separator;
2941
 
  
2942
 
  separator.reserve(256);
 
3002
  DYNAMIC_STRING *separator=
 
3003
    (DYNAMIC_STRING *)my_malloc(sizeof(DYNAMIC_STRING), MYF(0));
 
3004
  init_dynamic_string(separator, "", 256, 256);
2943
3005
 
2944
3006
  num_flag=(bool*) my_malloc(sizeof(bool)*drizzle_num_fields(result),
2945
3007
                             MYF(MY_WME));
2950
3012
      return;
2951
3013
    drizzle_field_seek(result,0);
2952
3014
  }
2953
 
  separator.append("+");
 
3015
  dynstr_append(separator, "+");
2954
3016
  while ((field = drizzle_fetch_field(result)))
2955
3017
  {
2956
 
    uint32_t length= column_names ? field->name_length : 0;
 
3018
    uint length= column_names ? field->name_length : 0;
2957
3019
    if (quick)
2958
3020
      length=max(length,field->length);
2959
3021
    else
2960
3022
      length=max(length,field->max_length);
2961
 
    if (length < 4 && !(field->flags & NOT_NULL_FLAG))
 
3023
    if (length < 4 && !IS_NOT_NULL(field->flags))
2962
3024
      // Room for "NULL"
2963
3025
      length=4;
2964
3026
    field->max_length=length;
2965
3027
    uint x;
2966
3028
    for (x=0; x< (length+2); x++)
2967
 
      separator.append("-");
2968
 
    separator.append("+");
 
3029
      dynstr_append(separator, "-");
 
3030
    dynstr_append(separator, "+");
2969
3031
  }
2970
3032
 
2971
 
  tee_puts((char*) separator.c_str(), PAGER);
 
3033
  tee_puts((char*) separator->str, PAGER);
2972
3034
  if (column_names)
2973
3035
  {
2974
3036
    drizzle_field_seek(result,0);
2979
3041
      uint numcells= charset_info->cset->numcells(charset_info,
2980
3042
                                                  field->name,
2981
3043
                                                  field->name + name_length);
2982
 
      uint32_t display_length= field->max_length + name_length - numcells;
 
3044
      uint display_length= field->max_length + name_length - numcells;
2983
3045
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
2984
3046
                                             MAX_COLUMN_LENGTH),
2985
3047
                  field->name);
2986
 
      num_flag[off]= ((field->type <= DRIZZLE_TYPE_LONGLONG) || 
2987
 
                      (field->type == DRIZZLE_TYPE_NEWDECIMAL));
 
3048
      num_flag[off]= IS_NUM(field->type);
2988
3049
    }
2989
3050
    (void) tee_fputs("\n", PAGER);
2990
 
    tee_puts((char*) separator.c_str(), PAGER);
 
3051
    tee_puts((char*) separator->str, PAGER);
2991
3052
  }
2992
3053
 
2993
3054
  while ((cur= drizzle_fetch_row(result)))
3044
3105
    }
3045
3106
    (void) tee_fputs("\n", PAGER);
3046
3107
  }
3047
 
  tee_puts(separator.c_str(), PAGER);
3048
 
  free(num_flag);
 
3108
  tee_puts(separator->str, PAGER);
 
3109
  my_free(num_flag, MYF(MY_ALLOW_ZERO_PTR));
3049
3110
}
3050
3111
 
3051
3112
/**
3073
3134
  else
3074
3135
    length= max(length, field->max_length);
3075
3136
 
3076
 
  if (length < 4 && !(field->flags & NOT_NULL_FLAG))
 
3137
  if (length < 4 && !IS_NOT_NULL(field->flags))
3077
3138
    length= 4;        /* Room for "NULL" */
3078
3139
 
3079
3140
  return length;
3135
3196
 
3136
3197
 
3137
3198
static void
 
3199
print_table_data_html(DRIZZLE_RES *result)
 
3200
{
 
3201
  DRIZZLE_ROW  cur;
 
3202
  DRIZZLE_FIELD  *field;
 
3203
 
 
3204
  drizzle_field_seek(result,0);
 
3205
  (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
 
3206
  if (column_names)
 
3207
  {
 
3208
    while((field = drizzle_fetch_field(result)))
 
3209
    {
 
3210
      tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
 
3211
                                         (field->name[0] ? field->name :
 
3212
                                          " &nbsp; ") : "NULL"));
 
3213
    }
 
3214
    (void) tee_fputs("</TR>", PAGER);
 
3215
  }
 
3216
  while ((cur = drizzle_fetch_row(result)))
 
3217
  {
 
3218
    if (interrupted_query)
 
3219
      break;
 
3220
    uint32_t *lengths=drizzle_fetch_lengths(result);
 
3221
    (void) tee_fputs("<TR>", PAGER);
 
3222
    for (uint32_t i= 0; i < drizzle_num_fields(result); i++)
 
3223
    {
 
3224
      (void) tee_fputs("<TD>", PAGER);
 
3225
      safe_put_field(cur[i],lengths[i]);
 
3226
      (void) tee_fputs("</TD>", PAGER);
 
3227
    }
 
3228
    (void) tee_fputs("</TR>", PAGER);
 
3229
  }
 
3230
  (void) tee_fputs("</TABLE>", PAGER);
 
3231
}
 
3232
 
 
3233
 
 
3234
static void
 
3235
print_table_data_xml(DRIZZLE_RES *result)
 
3236
{
 
3237
  DRIZZLE_ROW   cur;
 
3238
  DRIZZLE_FIELD *fields;
 
3239
 
 
3240
  drizzle_field_seek(result,0);
 
3241
 
 
3242
  tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
 
3243
  xmlencode_print(glob_buffer->str, glob_buffer->length);
 
3244
  tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
 
3245
            PAGER);
 
3246
 
 
3247
  fields = drizzle_fetch_fields(result);
 
3248
  while ((cur = drizzle_fetch_row(result)))
 
3249
  {
 
3250
    if (interrupted_query)
 
3251
      break;
 
3252
    uint32_t *lengths=drizzle_fetch_lengths(result);
 
3253
    (void) tee_fputs("\n  <row>\n", PAGER);
 
3254
    for (uint i=0; i < drizzle_num_fields(result); i++)
 
3255
    {
 
3256
      tee_fprintf(PAGER, "\t<field name=\"");
 
3257
      xmlencode_print(fields[i].name, (uint) strlen(fields[i].name));
 
3258
      if (cur[i])
 
3259
      {
 
3260
        tee_fprintf(PAGER, "\">");
 
3261
        xmlencode_print(cur[i], lengths[i]);
 
3262
        tee_fprintf(PAGER, "</field>\n");
 
3263
      }
 
3264
      else
 
3265
        tee_fprintf(PAGER, "\" xsi:nil=\"true\" />\n");
 
3266
    }
 
3267
    (void) tee_fputs("  </row>\n", PAGER);
 
3268
  }
 
3269
  (void) tee_fputs("</resultset>\n", PAGER);
 
3270
}
 
3271
 
 
3272
 
 
3273
static void
3138
3274
print_table_data_vertically(DRIZZLE_RES *result)
3139
3275
{
3140
3276
  DRIZZLE_ROW  cur;
3212
3348
}
3213
3349
 
3214
3350
 
3215
 
static void
3216
 
safe_put_field(const char *pos,uint32_t length)
 
3351
static const char *array_value(const char **array, char key)
 
3352
{
 
3353
  for (; *array; array+= 2)
 
3354
    if (**array == key)
 
3355
      return array[1];
 
3356
  return 0;
 
3357
}
 
3358
 
 
3359
 
 
3360
static void
 
3361
xmlencode_print(const char *src, uint length)
 
3362
{
 
3363
  if (!src)
 
3364
    tee_fputs("NULL", PAGER);
 
3365
  else
 
3366
  {
 
3367
    for (const char *p = src; *p && length; length--)
 
3368
    {
 
3369
      const char *t;
 
3370
      if ((t = array_value(xmlmeta, *p++)))
 
3371
        tee_fputs(t, PAGER);
 
3372
      else
 
3373
        tee_putc(*p, PAGER);
 
3374
    }
 
3375
  }
 
3376
}
 
3377
 
 
3378
 
 
3379
static void
 
3380
safe_put_field(const char *pos,ulong length)
3217
3381
{
3218
3382
  if (!pos)
3219
3383
    tee_fputs("NULL", PAGER);
3281
3445
}
3282
3446
 
3283
3447
static int
3284
 
com_tee(string *buffer __attribute__((unused)), const char *line )
 
3448
com_tee(DYNAMIC_STRING *buffer __attribute__((unused)), char *line )
3285
3449
{
3286
3450
  char file_name[FN_REFLEN], *end, *param;
3287
3451
 
3325
3489
 
3326
3490
 
3327
3491
static int
3328
 
com_notee(string *buffer __attribute__((unused)),
3329
 
          const char *line __attribute__((unused)))
 
3492
com_notee(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3493
          char *line __attribute__((unused)))
3330
3494
{
3331
3495
  if (opt_outfile)
3332
3496
    end_tee();
3339
3503
*/
3340
3504
 
3341
3505
static int
3342
 
com_pager(string *buffer __attribute__((unused)),
3343
 
          const char *line __attribute__((unused)))
 
3506
com_pager(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3507
          char *line __attribute__((unused)))
3344
3508
{
3345
3509
  char pager_name[FN_REFLEN], *end, *param;
3346
3510
 
3360
3524
    {
3361
3525
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3362
3526
      opt_nopager=1;
3363
 
      my_stpcpy(pager, "stdout");
 
3527
      strmov(pager, "stdout");
3364
3528
      PAGER= stdout;
3365
3529
      return 0;
3366
3530
    }
3367
 
    my_stpcpy(pager, default_pager);
 
3531
    strmov(pager, default_pager);
3368
3532
  }
3369
3533
  else
3370
3534
  {
3373
3537
                                my_iscntrl(charset_info,end[-1])))
3374
3538
      end--;
3375
3539
    end[0]=0;
3376
 
    my_stpcpy(pager, pager_name);
3377
 
    my_stpcpy(default_pager, pager_name);
 
3540
    strmov(pager, pager_name);
 
3541
    strmov(default_pager, pager_name);
3378
3542
  }
3379
3543
  opt_nopager=0;
3380
3544
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3383
3547
 
3384
3548
 
3385
3549
static int
3386
 
com_nopager(string *buffer __attribute__((unused)),
3387
 
            const char *line __attribute__((unused)))
 
3550
com_nopager(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3551
            char *line __attribute__((unused)))
3388
3552
{
3389
 
  my_stpcpy(pager, "stdout");
 
3553
  strmov(pager, "stdout");
3390
3554
  opt_nopager=1;
3391
3555
  PAGER= stdout;
3392
3556
  tee_fprintf(stdout, "PAGER set to stdout\n");
3396
3560
/* If arg is given, exit without errors. This happens on command 'quit' */
3397
3561
 
3398
3562
static int
3399
 
com_quit(string *buffer __attribute__((unused)),
3400
 
         const char *line __attribute__((unused)))
 
3563
com_quit(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3564
         char *line __attribute__((unused)))
3401
3565
{
3402
3566
  /* let the screen auto close on a normal shutdown */
3403
3567
  status.exit_status=0;
3405
3569
}
3406
3570
 
3407
3571
static int
3408
 
com_rehash(string *buffer __attribute__((unused)),
3409
 
           const char *line __attribute__((unused)))
 
3572
com_rehash(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3573
           char *line __attribute__((unused)))
3410
3574
{
3411
3575
  build_completion_hash(1, 0);
3412
3576
  return 0;
3415
3579
 
3416
3580
 
3417
3581
static int
3418
 
com_print(string *buffer,const char *line __attribute__((unused)))
 
3582
com_print(DYNAMIC_STRING *buffer,char *line __attribute__((unused)))
3419
3583
{
3420
3584
  tee_puts("--------------", stdout);
3421
 
  (void) tee_fputs(buffer->c_str(), stdout);
3422
 
  if ( (buffer->length() == 0)
3423
 
       || (buffer->c_str())[(buffer->length())-1] != '\n')
 
3585
  (void) tee_fputs(buffer->str, stdout);
 
3586
  if ( (buffer->length == 0)
 
3587
       || (buffer->str)[(buffer->length)-1] != '\n')
3424
3588
    tee_putc('\n', stdout);
3425
3589
  tee_puts("--------------\n", stdout);
3426
3590
  /* If empty buffer */
3429
3593
 
3430
3594
/* ARGSUSED */
3431
3595
static int
3432
 
com_connect(string *buffer, const char *line)
 
3596
com_connect(DYNAMIC_STRING *buffer, char *line)
3433
3597
{
3434
3598
  char *tmp, buff[256];
3435
3599
  bool save_rehash= opt_rehash;
3436
3600
  int error;
3437
3601
 
3438
 
  memset(buff, 0, sizeof(buff));
 
3602
  bzero(buff, sizeof(buff));
3439
3603
  if (buffer)
3440
3604
  {
3441
3605
    /*
3449
3613
    tmp= get_arg(buff, 0);
3450
3614
    if (tmp && *tmp)
3451
3615
    {
3452
 
      free(current_db);
 
3616
      my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
3453
3617
      current_db= strdup(tmp);
3454
3618
      tmp= get_arg(buff, 1);
3455
3619
      if (tmp)
3456
3620
      {
3457
 
        free(current_host);
 
3621
        my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
3458
3622
        current_host=strdup(tmp);
3459
3623
      }
3460
3624
    }
3465
3629
    }
3466
3630
    // command used
3467
3631
    assert(buffer!=NULL);
3468
 
    buffer->clear();
 
3632
    dynstr_set(buffer, NULL);
3469
3633
  }
3470
3634
  else
3471
3635
    opt_rehash= 0;
3484
3648
}
3485
3649
 
3486
3650
 
3487
 
static int com_source(string *buffer __attribute__((unused)), const char *line)
 
3651
static int com_source(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
3488
3652
{
3489
3653
  char source_name[FN_REFLEN], *end, *param;
3490
3654
  LINE_BUFFER *line_buff;
3522
3686
 
3523
3687
  /* Save old status */
3524
3688
  old_status=status;
3525
 
  memset(&status, 0, sizeof(status));
 
3689
  bfill((char*) &status,sizeof(status),(char) 0);
3526
3690
 
3527
3691
  // Run in batch mode
3528
3692
  status.batch=old_status.batch;
3530
3694
  status.file_name=source_name;
3531
3695
  // Empty command buffer
3532
3696
  assert(glob_buffer!=NULL);
3533
 
  glob_buffer->clear();
 
3697
  dynstr_set(glob_buffer, NULL);
3534
3698
  error= read_and_execute(false);
3535
3699
  // Continue as before
3536
3700
  status=old_status;
3542
3706
 
3543
3707
/* ARGSUSED */
3544
3708
static int
3545
 
com_delimiter(string *buffer __attribute__((unused)), const char *line)
 
3709
com_delimiter(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
3546
3710
{
3547
3711
  char buff[256], *tmp;
3548
3712
 
3572
3736
 
3573
3737
/* ARGSUSED */
3574
3738
static int
3575
 
com_use(string *buffer __attribute__((unused)), const char *line)
 
3739
com_use(DYNAMIC_STRING *buffer __attribute__((unused)), char *line)
3576
3740
{
3577
3741
  char *tmp, buff[FN_REFLEN + 1];
3578
3742
  int select_db;
3579
3743
 
3580
 
  memset(buff, 0, sizeof(buff));
 
3744
  bzero(buff, sizeof(buff));
3581
3745
  strmake(buff, line, sizeof(buff) - 1);
3582
3746
  tmp= get_arg(buff, 0);
3583
3747
  if (!tmp || !*tmp)
3633
3797
      if (drizzle_select_db(&drizzle,tmp))
3634
3798
        return put_error(&drizzle);
3635
3799
    }
3636
 
    free(current_db);
 
3800
    my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
3637
3801
    current_db= strdup(tmp);
3638
3802
    if (select_db > 1)
3639
3803
      build_completion_hash(opt_rehash, 1);
3644
3808
}
3645
3809
 
3646
3810
static int
3647
 
com_warnings(string *buffer __attribute__((unused)),
3648
 
             const char *line __attribute__((unused)))
 
3811
com_warnings(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3812
             char *line __attribute__((unused)))
3649
3813
{
3650
3814
  show_warnings = 1;
3651
3815
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3653
3817
}
3654
3818
 
3655
3819
static int
3656
 
com_nowarnings(string *buffer __attribute__((unused)),
3657
 
               const char *line __attribute__((unused)))
 
3820
com_nowarnings(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3821
               char *line __attribute__((unused)))
3658
3822
{
3659
3823
  show_warnings = 0;
3660
3824
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3696
3860
        ptr++;
3697
3861
  }
3698
3862
  if (!*ptr)
3699
 
    return NULL;
 
3863
    return NullS;
3700
3864
  while (my_isspace(charset_info, *ptr))
3701
3865
    ptr++;
3702
3866
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
3710
3874
    if (*ptr == '\\' && ptr[1]) // escaped character
3711
3875
    {
3712
3876
      // Remove the backslash
3713
 
      my_stpcpy(ptr, ptr+1);
 
3877
      strmov(ptr, ptr+1);
3714
3878
    }
3715
3879
    else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
3716
3880
    {
3719
3883
    }
3720
3884
  }
3721
3885
  valid_arg= ptr != start;
3722
 
  return valid_arg ? start : NULL;
 
3886
  return valid_arg ? start : NullS;
3723
3887
}
3724
3888
 
3725
3889
 
3740
3904
                  (char*) &timeout);
3741
3905
  }
3742
3906
  if (opt_compress)
3743
 
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NULL);
 
3907
    drizzle_options(&drizzle,DRIZZLE_OPT_COMPRESS,NullS);
3744
3908
  if (opt_secure_auth)
3745
3909
    drizzle_options(&drizzle, DRIZZLE_SECURE_AUTH, (char *) &opt_secure_auth);
3746
3910
  if (using_opt_local_infile)
3747
3911
    drizzle_options(&drizzle,DRIZZLE_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
 
3912
  if (opt_protocol)
 
3913
    drizzle_options(&drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
3748
3914
  if (safe_updates)
3749
3915
  {
3750
3916
    char init_command[100];
3754
3920
            select_limit, max_join_size);
3755
3921
    drizzle_options(&drizzle, DRIZZLE_INIT_COMMAND, init_command);
3756
3922
  }
 
3923
  if (default_charset_used)
 
3924
    drizzle_options(&drizzle, DRIZZLE_SET_CHARSET_NAME, default_charset);
3757
3925
  if (!drizzle_connect(&drizzle, host, user, password,
3758
3926
                          database, opt_drizzle_port, opt_drizzle_unix_port,
3759
3927
                          connect_flag | CLIENT_MULTI_STATEMENTS))
3776
3944
 
3777
3945
 
3778
3946
static int
3779
 
com_status(string *buffer __attribute__((unused)),
3780
 
           const char *line __attribute__((unused)))
 
3947
com_status(DYNAMIC_STRING *buffer __attribute__((unused)),
 
3948
           char *line __attribute__((unused)))
3781
3949
{
 
3950
  const char *status_str;
3782
3951
  char buff[40];
3783
3952
  uint64_t id;
3784
3953
  DRIZZLE_RES *result;
3841
4010
    }
3842
4011
    drizzle_free_result(result);
3843
4012
  }
 
4013
  else
 
4014
  {
 
4015
    /* Probably pre-4.1 server */
 
4016
    tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname);
 
4017
    tee_fprintf(stdout, "Server characterset:\t%s\n", drizzle.charset->csname);
 
4018
  }
3844
4019
 
3845
4020
  if (strstr(drizzle_get_host_info(&drizzle),"TCP/IP") || ! drizzle.unix_socket)
3846
4021
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle.port);
3849
4024
  if (drizzle.net.compress)
3850
4025
    tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
3851
4026
 
 
4027
  if ((status_str= drizzle_stat(&drizzle)) && !drizzle_error(&drizzle)[0])
 
4028
  {
 
4029
    ulong sec;
 
4030
    const char *pos= strchr(status_str,' ');
 
4031
    /* print label */
 
4032
    tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str);
 
4033
    if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec)))
 
4034
    {
 
4035
      nice_time((double) sec,buff,0);
 
4036
      tee_puts(buff, stdout);      /* print nice time */
 
4037
      while (*status_str == ' ')
 
4038
        status_str++;  /* to next info */
 
4039
      tee_putc('\n', stdout);
 
4040
      tee_puts(status_str, stdout);
 
4041
    }
 
4042
  }
3852
4043
  if (safe_updates)
3853
4044
  {
3854
4045
    vidattr(A_BOLD);
3876
4067
    char *bufp = buf;
3877
4068
    DRIZZLE_RES *result;
3878
4069
 
3879
 
    bufp= my_stpncpy(buf, drizzle_get_server_info(con), sizeof buf);
 
4070
    bufp= strnmov(buf, drizzle_get_server_info(con), sizeof buf);
3880
4071
 
3881
4072
    /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
3882
4073
    if (!drizzle_query(con, "select @@version_comment limit 1") &&
3885
4076
      DRIZZLE_ROW cur = drizzle_fetch_row(result);
3886
4077
      if (cur && cur[0])
3887
4078
      {
3888
 
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NULL);
 
4079
        bufp = strxnmov(bufp, sizeof buf - (bufp - buf), " ", cur[0], NullS);
3889
4080
      }
3890
4081
      drizzle_free_result(result);
3891
4082
    }
3978
4169
}
3979
4170
 
3980
4171
 
3981
 
static void remove_cntrl(string *buffer)
 
4172
static void remove_cntrl(DYNAMIC_STRING *buffer)
3982
4173
{
3983
 
  const char *start=  buffer->c_str();
3984
 
  const char *end= start + (buffer->length());
 
4174
  char *start=  buffer->str;
 
4175
  char *end= start + (buffer->length);
3985
4176
  while (start < end && !my_isgraph(charset_info,end[-1]))
3986
4177
    end--;
3987
 
  uint pos_to_truncate= (end-start);
3988
 
  if (buffer->length() > pos_to_truncate)
3989
 
    buffer->erase(pos_to_truncate);
 
4178
  uint chars_to_truncate = end-start;
 
4179
  if (buffer->length > chars_to_truncate)
 
4180
    dynstr_trunc(buffer, chars_to_truncate);
3990
4181
}
3991
4182
 
3992
4183
 
4039
4230
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
4040
4231
#endif
4041
4232
 
4042
 
static uint32_t start_timer(void)
 
4233
static ulong start_timer(void)
4043
4234
{
4044
4235
  struct tms tms_tmp;
4045
4236
  return times(&tms_tmp);
4054
4245
*/
4055
4246
static void nice_time(double sec,char *buff,bool part_second)
4056
4247
{
4057
 
  uint32_t tmp;
 
4248
  ulong tmp;
4058
4249
  if (sec >= 3600.0*24)
4059
4250
  {
4060
 
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4251
    tmp=(ulong) floor(sec/(3600.0*24));
4061
4252
    sec-=3600.0*24*tmp;
4062
4253
    buff=int10_to_str((long) tmp, buff, 10);
4063
 
    buff=my_stpcpy(buff,tmp > 1 ? " days " : " day ");
 
4254
    buff=strmov(buff,tmp > 1 ? " days " : " day ");
4064
4255
  }
4065
4256
  if (sec >= 3600.0)
4066
4257
  {
4067
 
    tmp=(uint32_t) floor(sec/3600.0);
 
4258
    tmp=(ulong) floor(sec/3600.0);
4068
4259
    sec-=3600.0*tmp;
4069
4260
    buff=int10_to_str((long) tmp, buff, 10);
4070
 
    buff=my_stpcpy(buff,tmp > 1 ? " hours " : " hour ");
 
4261
    buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
4071
4262
  }
4072
4263
  if (sec >= 60.0)
4073
4264
  {
4074
 
    tmp=(uint32_t) floor(sec/60.0);
 
4265
    tmp=(ulong) floor(sec/60.0);
4075
4266
    sec-=60.0*tmp;
4076
4267
    buff=int10_to_str((long) tmp, buff, 10);
4077
 
    buff=my_stpcpy(buff," min ");
 
4268
    buff=strmov(buff," min ");
4078
4269
  }
4079
4270
  if (part_second)
4080
4271
    sprintf(buff,"%.2f sec",sec);
4083
4274
}
4084
4275
 
4085
4276
 
4086
 
static void end_timer(uint32_t start_time,char *buff)
 
4277
static void end_timer(ulong start_time,char *buff)
4087
4278
{
4088
4279
  nice_time((double) (start_timer() - start_time) /
4089
4280
            CLOCKS_PER_SEC,buff,1);
4090
4281
}
4091
4282
 
4092
4283
 
4093
 
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4284
static void drizzle_end_timer(ulong start_time,char *buff)
4094
4285
{
4095
4286
  buff[0]=' ';
4096
4287
  buff[1]='(';
4097
4288
  end_timer(start_time,buff+2);
4098
 
  my_stpcpy(strchr(buff, '\0'),")");
 
4289
  strmov(strend(buff),")");
4099
4290
}
4100
4291
 
4101
4292
static const char * construct_prompt()
4102
4293
{
4103
4294
  // Erase the old prompt
4104
4295
  assert(processed_prompt!=NULL);
4105
 
  processed_prompt->clear();
 
4296
  dynstr_set(processed_prompt, NULL);
4106
4297
 
4107
4298
  // Get the date struct
4108
4299
  time_t  lclock = time(NULL);
4113
4304
  {
4114
4305
    if (*c != PROMPT_CHAR)
4115
4306
    {
4116
 
      processed_prompt->append(c, 1);
 
4307
      dynstr_append_mem(processed_prompt, c, 1);
4117
4308
    }
4118
4309
    else
4119
4310
    {
4130
4321
        break;
4131
4322
      case 'v':
4132
4323
        if (connected)
4133
 
          processed_prompt->append(drizzle_get_server_info(&drizzle));
 
4324
          dynstr_append(processed_prompt, drizzle_get_server_info(&drizzle));
4134
4325
        else
4135
 
          processed_prompt->append("not_connected");
 
4326
          dynstr_append(processed_prompt, "not_connected");
4136
4327
        break;
4137
4328
      case 'd':
4138
 
        processed_prompt->append(current_db ? current_db : "(none)");
 
4329
        dynstr_append(processed_prompt, current_db ? current_db : "(none)");
4139
4330
        break;
4140
4331
      case 'h':
4141
4332
      {
4142
4333
        const char *prompt;
4143
4334
        prompt= connected ? drizzle_get_host_info(&drizzle) : "not_connected";
4144
4335
        if (strstr(prompt, "Localhost"))
4145
 
          processed_prompt->append("localhost");
 
4336
          dynstr_append(processed_prompt, "localhost");
4146
4337
        else
4147
4338
        {
4148
 
          const char *end=strrchr(prompt,' ');
4149
 
          if (end != NULL)
4150
 
            processed_prompt->append(prompt, (end-prompt));
 
4339
          const char *end=strcend(prompt,' ');
 
4340
          dynstr_append_mem(processed_prompt, prompt, (end-prompt));
4151
4341
        }
4152
4342
        break;
4153
4343
      }
4155
4345
      {
4156
4346
        if (!connected)
4157
4347
        {
4158
 
          processed_prompt->append("not_connected");
 
4348
          dynstr_append(processed_prompt, "not_connected");
4159
4349
          break;
4160
4350
        }
4161
4351
 
4162
4352
        const char *host_info = drizzle_get_host_info(&drizzle);
4163
4353
        if (strstr(host_info, "memory"))
4164
4354
        {
4165
 
          processed_prompt->append(drizzle.host);
 
4355
          dynstr_append(processed_prompt, drizzle.host);
4166
4356
        }
4167
4357
        else if (strstr(host_info,"TCP/IP") ||
4168
4358
                 !drizzle.unix_socket)
4170
4360
        else
4171
4361
        {
4172
4362
          char *pos=strrchr(drizzle.unix_socket,'/');
4173
 
          processed_prompt->append(pos ? pos+1 : drizzle.unix_socket);
 
4363
          dynstr_append(processed_prompt, pos ? pos+1 : drizzle.unix_socket);
4174
4364
        }
4175
4365
      }
4176
4366
      break;
4177
4367
      case 'U':
4178
4368
        if (!full_username)
4179
4369
          init_username();
4180
 
        processed_prompt->append(full_username ? full_username :
4181
 
                                 (current_user ?  current_user : "(unknown)"));
 
4370
        dynstr_append(processed_prompt, full_username ? full_username :
 
4371
                        (current_user ?  current_user : "(unknown)"));
4182
4372
        break;
4183
4373
      case 'u':
4184
4374
        if (!full_username)
4185
4375
          init_username();
4186
 
        processed_prompt->append(part_username ? part_username :
4187
 
                                 (current_user ?  current_user : "(unknown)"));
 
4376
        dynstr_append(processed_prompt, part_username ? part_username :
 
4377
                        (current_user ?  current_user : "(unknown)"));
4188
4378
        break;
4189
4379
      case PROMPT_CHAR:
4190
4380
        {
4191
4381
          char c= PROMPT_CHAR;
4192
 
          processed_prompt->append(&c, 1);
 
4382
          dynstr_append_mem(processed_prompt, &c, 1);
4193
4383
        }
4194
4384
        break;
4195
4385
      case 'n':
4196
4386
        {
4197
4387
          char c= '\n';
4198
 
          processed_prompt->append(&c, 1);
 
4388
          dynstr_append_mem(processed_prompt, &c, 1);
4199
4389
        }
4200
4390
        break;
4201
4391
      case ' ':
4202
4392
      case '_':
4203
4393
        {
4204
4394
          char c= ' ';
4205
 
          processed_prompt->append(&c, 1);
 
4395
          dynstr_append_mem(processed_prompt, &c, 1);
4206
4396
        }
4207
4397
        break;
4208
4398
      case 'R':
4234
4424
        break;
4235
4425
      case 'D':
4236
4426
        dateTime = ctime(&lclock);
4237
 
        processed_prompt->append(strtok(dateTime,"\n"));
 
4427
        dynstr_append(processed_prompt, strtok(dateTime,"\n"));
4238
4428
        break;
4239
4429
      case 's':
4240
4430
        if (t->tm_sec < 10)
4242
4432
        add_int_to_prompt(t->tm_sec);
4243
4433
        break;
4244
4434
      case 'w':
4245
 
        processed_prompt->append(day_names[t->tm_wday]);
 
4435
        dynstr_append(processed_prompt, (day_names[t->tm_wday]));
4246
4436
        break;
4247
4437
      case 'P':
4248
 
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
 
4438
        dynstr_append(processed_prompt, t->tm_hour < 12 ? "am" : "pm");
4249
4439
        break;
4250
4440
      case 'o':
4251
4441
        add_int_to_prompt(t->tm_mon+1);
4252
4442
        break;
4253
4443
      case 'O':
4254
 
        processed_prompt->append(month_names[t->tm_mon]);
 
4444
        dynstr_append(processed_prompt, month_names[t->tm_mon]);
4255
4445
        break;
4256
4446
      case '\'':
4257
 
        processed_prompt->append("'");
 
4447
        dynstr_append(processed_prompt, "'");
4258
4448
        break;
4259
4449
      case '"':
4260
 
        processed_prompt->append("\"");
 
4450
        dynstr_append(processed_prompt, "\"");
4261
4451
        break;
4262
4452
      case 'S':
4263
 
        processed_prompt->append(";");
 
4453
        dynstr_append(processed_prompt, ";");
4264
4454
        break;
4265
4455
      case 't':
4266
 
        processed_prompt->append("\t");
 
4456
        dynstr_append(processed_prompt, "\t");
4267
4457
        break;
4268
4458
      case 'l':
4269
 
        processed_prompt->append(delimiter_str);
 
4459
        dynstr_append(processed_prompt, delimiter_str);
4270
4460
        break;
4271
4461
      default:
4272
 
        processed_prompt->append(c, 1);
 
4462
        dynstr_append_mem(processed_prompt, c, 1);
4273
4463
      }
4274
4464
    }
4275
4465
  }
4276
 
  return processed_prompt->c_str();
 
4466
  return processed_prompt->str;
4277
4467
}
4278
4468
 
4279
4469
 
4281
4471
{
4282
4472
  char buffer[16];
4283
4473
  int10_to_str(toadd, buffer, 10);
4284
 
  processed_prompt->append(buffer);
 
4474
  dynstr_append(processed_prompt, buffer);
4285
4475
}
4286
4476
 
4287
4477
static void init_username()
4288
4478
{
4289
 
  free(full_username);
4290
 
  free(part_username);
 
4479
  my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
 
4480
  my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
4291
4481
 
4292
4482
  DRIZZLE_RES *result;
4293
4483
  if (!drizzle_query(&drizzle,"select USER()") &&
4300
4490
  }
4301
4491
}
4302
4492
 
4303
 
static int com_prompt(string *buffer __attribute__((unused)),
4304
 
                      const char *line)
 
4493
static int com_prompt(DYNAMIC_STRING *buffer __attribute__((unused)),
 
4494
                      char *line)
4305
4495
{
4306
4496
  char *ptr=strchr(line, ' ');
4307
4497
  prompt_counter = 0;
4308
 
  free(current_prompt);
 
4498
  my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
4309
4499
  current_prompt= strdup(ptr ? ptr+1 : default_prompt);
4310
4500
  if (!ptr)
4311
4501
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4314
4504
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4315
4505
  return 0;
4316
4506
}
4317
 
 
4318
 
/*
4319
 
    strcont(str, set) if str contanies any character in the string set.
4320
 
    The result is the position of the first found character in str, or NULL
4321
 
    if there isn't anything found.
4322
 
*/
4323
 
 
4324
 
static const char * strcont(register const char *str, register const char *set)
4325
 
{
4326
 
  register const char * start = (const char *) set;
4327
 
 
4328
 
  while (*str)
4329
 
  {
4330
 
    while (*set)
4331
 
    {
4332
 
      if (*set++ == *str)
4333
 
        return ((const char*) str);
4334
 
    }
4335
 
    set=start; str++;
4336
 
  }
4337
 
  return NULL;
4338
 
} /* strcont */