~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Brian Aker
  • Date: 2008-09-05 23:02:34 UTC
  • mfrom: (379 codestyle)
  • mto: This revision was merged to the branch mainline in revision 383.
  • Revision ID: brian@tangent.org-20080905230234-tq426zr79cnzjwo3
Merge from Monty, cleanup in tabs during merg.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 Drizzle Open Source Development Team 
 
1
/* Copyright (C) 2008 Drizzle Open Source Development Team
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
32
32
*/
33
33
 
34
34
#define MTEST_VERSION "3.3"
 
35
 
 
36
#include <queue>
 
37
#include <map>
 
38
#include <string>
 
39
 
35
40
#include <pcrecpp.h>
36
41
 
37
42
#include "client_priv.h"
41
46
 
42
47
#include "errname.h"
43
48
 
 
49
using namespace std;
 
50
 
44
51
#define MAX_VAR_NAME_LENGTH    256
45
52
#define MAX_COLUMNS            256
46
53
#define MAX_EMBEDDED_SERVER_ARGS 64
137
144
 
138
145
static uint64_t progress_start= 0;
139
146
 
140
 
DYNAMIC_ARRAY q_lines;
 
147
vector<struct st_command*> q_lines;
141
148
 
142
149
typedef struct {
143
150
  int read_lines,current_line;
297
304
  "copy_file",
298
305
  "perl",
299
306
  "die",
300
 
              
 
307
 
301
308
  /* Don't execute any more commands, compare result */
302
309
  "exit",
303
310
  "skip",
356
363
};
357
364
 
358
365
TYPELIB command_typelib= {array_elements(command_names),"",
359
 
        command_names, 0};
 
366
                          command_names, 0};
360
367
 
361
 
DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
 
368
string ds_res, ds_progress, ds_warning_messages;
362
369
 
363
370
char builtin_echo[FN_REFLEN];
364
371
 
382
389
void eval_expr(VAR* v, const char *p, const char** p_end);
383
390
bool match_delimiter(int c, const char *delim, uint length);
384
391
void dump_result_to_reject_file(char *buf, int size);
385
 
void dump_result_to_log_file(char *buf, int size);
 
392
void dump_result_to_log_file(const char *buf, int size);
386
393
void dump_warning_messages(void);
387
394
void dump_progress(void);
388
395
 
389
 
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
 
396
void do_eval(string *query_eval, const char *query,
390
397
             const char *query_end, bool pass_through_escape_chars);
391
 
void str_to_file(const char *fname, char *str, int size);
392
 
void str_to_file2(const char *fname, char *str, int size, bool append);
 
398
void str_to_file(const char *fname, const char *str, int size);
 
399
void str_to_file2(const char *fname, const char *str, int size, bool append);
393
400
 
394
401
/* For replace_column */
395
402
static char *replace_column[MAX_COLUMNS];
415
422
  free_replace_column();
416
423
}
417
424
 
418
 
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
419
 
                               int len);
420
 
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
421
 
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
422
 
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
 
425
void replace_append_mem(string *ds, const char *val,
 
426
                        int len);
 
427
void replace_append(string *ds, const char *val);
 
428
void replace_append_uint(string *ds, uint val);
 
429
void append_sorted(string* ds, string* ds_input);
423
430
 
424
431
void handle_error(struct st_command*,
425
432
                  unsigned int err_errno, const char *err_error,
426
 
                  const char *err_sqlstate, DYNAMIC_STRING *ds);
 
433
                  const char *err_sqlstate, string *ds);
427
434
void handle_no_error(struct st_command*);
428
435
 
429
436
#ifdef EMBEDDED_LIBRARY
492
499
 
493
500
#endif /*EMBEDDED_LIBRARY*/
494
501
 
495
 
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
 
502
void do_eval(string *query_eval, const char *query,
496
503
             const char *query_end, bool pass_through_escape_chars)
497
504
{
498
505
  const char *p;
507
514
    case '$':
508
515
      if (escaped)
509
516
      {
510
 
  escaped= 0;
511
 
  dynstr_append_mem(query_eval, p, 1);
 
517
        escaped= 0;
 
518
        query_eval->append(p, 1);
512
519
      }
513
520
      else
514
521
      {
515
 
  if (!(v= var_get(p, &p, 0, 0)))
516
 
    die("Bad variable in eval");
517
 
  dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
 
522
        if (!(v= var_get(p, &p, 0, 0)))
 
523
          die("Bad variable in eval");
 
524
        query_eval->append(v->str_val, v->str_val_len);
518
525
      }
519
526
      break;
520
527
    case '\\':
521
528
      next_c= *(p+1);
522
529
      if (escaped)
523
530
      {
524
 
  escaped= 0;
525
 
  dynstr_append_mem(query_eval, p, 1);
 
531
        escaped= 0;
 
532
        query_eval->append(p, 1);
526
533
      }
527
534
      else if (next_c == '\\' || next_c == '$' || next_c == '"')
528
535
      {
529
536
        /* Set escaped only if next char is \, " or $ */
530
 
  escaped= 1;
 
537
        escaped= 1;
531
538
 
532
539
        if (pass_through_escape_chars)
533
540
        {
534
541
          /* The escape char should be added to the output string. */
535
 
          dynstr_append_mem(query_eval, p, 1);
 
542
          query_eval->append(p, 1);
536
543
        }
537
544
      }
538
545
      else
539
 
  dynstr_append_mem(query_eval, p, 1);
 
546
        query_eval->append(p, 1);
540
547
      break;
541
548
    default:
542
549
      escaped= 0;
543
 
      dynstr_append_mem(query_eval, p, 1);
 
550
      query_eval->append(p, 1);
544
551
      break;
545
552
    }
546
553
  }
549
556
 
550
557
 
551
558
/*
 
559
  Concatenates any number of strings, escapes any OS quote in the result then
 
560
  surround the whole affair in another set of quotes which is finally appended
 
561
  to specified string.  This function is especially useful when
 
562
  building strings to be executed with the system() function.
 
563
 
 
564
  @param str string which will have addtional strings appended.
 
565
  @param append string to be appended.
 
566
  @param ... Optional. Additional string(s) to be appended.
 
567
 
 
568
  @note The final argument in the list must be NullS even if no additional
 
569
  options are passed.
 
570
*/
 
571
 
 
572
void append_os_quoted(string *str, const char *append, ...)
 
573
{
 
574
  const char *quote_str= "\'";
 
575
  const uint  quote_len= 1;
 
576
 
 
577
  va_list dirty_text;
 
578
 
 
579
  str->append(quote_str, quote_len); /* Leading quote */
 
580
  va_start(dirty_text, append);
 
581
  while (append != NullS)
 
582
  {
 
583
    const char  *cur_pos= append;
 
584
    const char *next_pos= cur_pos;
 
585
 
 
586
    /* Search for quote in each string and replace with escaped quote */
 
587
    while((next_pos= strrchr(cur_pos, quote_str[0])) != NULL)
 
588
    {
 
589
      str->append(cur_pos, next_pos - cur_pos);
 
590
      str->append("\\", 1);
 
591
      str->append(quote_str, quote_len);
 
592
      cur_pos= next_pos + 1;
 
593
    }
 
594
    str->append(cur_pos, next_pos - cur_pos);
 
595
    append= va_arg(dirty_text, char *);
 
596
  }
 
597
  va_end(dirty_text);
 
598
  str->append(quote_str, quote_len); /* Trailing quote */
 
599
}
 
600
 
 
601
 
 
602
/*
552
603
  Run query and dump the result to stdout in vertical format
553
604
 
554
605
  NOTE! This function should be safe to call when an error
694
745
  const char *argname;       /* Name of argument   */
695
746
  enum arg_type type;        /* Type of argument   */
696
747
  bool required;          /* Argument required  */
697
 
  DYNAMIC_STRING *ds;        /* Storage for argument */
 
748
  string *ds;        /* Storage for argument */
698
749
  const char *description;   /* Description of the argument */
699
750
};
700
751
 
724
775
        ptr++;
725
776
      if (ptr > start)
726
777
      {
727
 
        init_dynamic_string(arg->ds, 0, ptr-start, 32);
728
778
        do_eval(arg->ds, start, ptr, false);
729
779
      }
730
780
      else
731
781
      {
732
782
        /* Empty string */
733
 
        init_dynamic_string(arg->ds, "", 0, 0);
 
783
        arg->ds->erase();
734
784
      }
735
785
      command->last_argument= (char*)ptr;
736
786
 
742
792
      /* Rest of line */
743
793
    case ARG_REST:
744
794
      start= ptr;
745
 
      init_dynamic_string(arg->ds, 0, command->query_len, 256);
746
795
      do_eval(arg->ds, start, command->end, false);
747
796
      command->last_argument= command->end;
748
797
      break;
753
802
    }
754
803
 
755
804
    /* Check required arg */
756
 
    if (arg->ds->length == 0 && arg->required)
 
805
    if (arg->ds->length() == 0 && arg->required)
757
806
      die("Missing required argument '%s' to command '%.*s'", arg->argname,
758
807
          command->first_word_len, command->query);
759
808
 
843
892
  close_files();
844
893
  hash_free(&var_hash);
845
894
 
846
 
  for (i= 0 ; i < q_lines.elements ; i++)
 
895
  vector<struct st_command *>::iterator iter;
 
896
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
847
897
  {
848
 
    struct st_command **q= dynamic_element(&q_lines, i, struct st_command**);
849
 
    my_free((*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
850
 
    my_free((*q),MYF(0));
 
898
    struct st_command * q_line= *(iter.base());
 
899
    if (q_line->query_buf != NULL)
 
900
    {
 
901
      free(q_line->query_buf);
 
902
    }
 
903
    free(q_line);
851
904
  }
 
905
 
852
906
  for (i= 0; i < 10; i++)
853
907
  {
854
908
    if (var_reg[i].alloced_len)
856
910
  }
857
911
  while (embedded_server_arg_count > 1)
858
912
    my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
859
 
  delete_dynamic(&q_lines);
860
 
  dynstr_free(&ds_res);
861
 
  dynstr_free(&ds_progress);
862
 
  dynstr_free(&ds_warning_messages);
 
913
 
863
914
  free_all_replace();
864
915
  my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR));
865
916
  free_defaults(default_argv);
887
938
      break;
888
939
    case 62:
889
940
      printf("skipped\n");
890
 
    break;
 
941
      break;
891
942
    default:
892
943
      printf("unknown exit code: %d\n", exit_code);
893
944
      assert(0);
930
981
  fflush(stderr);
931
982
 
932
983
  /* Show results from queries just before failure */
933
 
  if (ds_res.length && opt_tail_lines)
 
984
  if (ds_res.length() && opt_tail_lines)
934
985
  {
935
986
    int tail_lines= opt_tail_lines;
936
 
    char* show_from= ds_res.str + ds_res.length - 1;
937
 
    while(show_from > ds_res.str && tail_lines > 0 )
 
987
    const char* show_from= ds_res.c_str() + ds_res.length() - 1;
 
988
    while(show_from > ds_res.c_str() && tail_lines > 0 )
938
989
    {
939
990
      show_from--;
940
991
      if (*show_from == '\n')
941
992
        tail_lines--;
942
993
    }
943
994
    fprintf(stderr, "\nThe result from queries just before the failure was:\n");
944
 
    if (show_from > ds_res.str)
 
995
    if (show_from > ds_res.c_str())
945
996
      fprintf(stderr, "< snip >");
946
997
    fprintf(stderr, "%s", show_from);
947
998
    fflush(stderr);
948
999
  }
949
1000
 
950
1001
  /* Dump the result that has been accumulated so far to .log file */
951
 
  if (result_file_name && ds_res.length)
952
 
    dump_result_to_log_file(ds_res.str, ds_res.length);
 
1002
  if (result_file_name && ds_res.length())
 
1003
    dump_result_to_log_file(ds_res.c_str(), ds_res.length());
953
1004
 
954
1005
  /* Dump warning messages */
955
 
  if (result_file_name && ds_warning_messages.length)
 
1006
  if (result_file_name && ds_warning_messages.length())
956
1007
    dump_warning_messages();
957
1008
 
958
1009
  /*
1029
1080
 
1030
1081
 
1031
1082
  va_start(args, fmt);
1032
 
  dynstr_append(&ds_warning_messages, "drizzletest: ");
 
1083
  ds_warning_messages.append("drizzletest: ");
1033
1084
  if (start_lineno != 0)
1034
1085
  {
1035
 
    dynstr_append(&ds_warning_messages, "Warning detected ");
 
1086
    ds_warning_messages.append("Warning detected ");
1036
1087
    if (cur_file && cur_file != file_stack)
1037
1088
    {
1038
1089
      len= snprintf(buff, sizeof(buff), "in included file %s ",
1039
 
                       cur_file->file_name);
1040
 
      dynstr_append_mem(&ds_warning_messages,
1041
 
                        buff, len);
 
1090
                    cur_file->file_name);
 
1091
      ds_warning_messages.append(buff, len);
1042
1092
    }
1043
1093
    len= snprintf(buff, sizeof(buff), "at line %d: ",
1044
 
                     start_lineno);
1045
 
    dynstr_append_mem(&ds_warning_messages,
1046
 
                      buff, len);
 
1094
                  start_lineno);
 
1095
    ds_warning_messages.append(buff, len);
1047
1096
  }
1048
1097
 
1049
1098
  len= vsnprintf(buff, sizeof(buff), fmt, args);
1050
 
  dynstr_append_mem(&ds_warning_messages, buff, len);
 
1099
  ds_warning_messages.append(buff, len);
1051
1100
 
1052
 
  dynstr_append(&ds_warning_messages, "\n");
 
1101
  ds_warning_messages.append("\n");
1053
1102
  va_end(args);
1054
1103
 
1055
1104
  return;
1067
1116
  len= vsnprintf(buff, sizeof(buff)-1, fmt, args);
1068
1117
  va_end(args);
1069
1118
 
1070
 
  dynstr_append_mem(&ds_res, buff, len);
1071
 
  dynstr_append(&ds_res, "\n");
 
1119
  ds_res.append(buff, len);
 
1120
  ds_res.append("\n");
1072
1121
 
1073
1122
  return;
1074
1123
}
1084
1133
 
1085
1134
*/
1086
1135
 
1087
 
static void cat_file(DYNAMIC_STRING* ds, const char* filename)
 
1136
static void cat_file(string* ds, const char* filename)
1088
1137
{
1089
1138
  int fd;
1090
1139
  uint len;
1104
1153
        /* Add fake newline instead of cr and output the line */
1105
1154
        *p= '\n';
1106
1155
        p++; /* Step past the "fake" newline */
1107
 
        dynstr_append_mem(ds, start, p-start);
 
1156
        ds->append(start, p-start);
1108
1157
        p++; /* Step past the "fake" newline */
1109
1158
        start= p;
1110
1159
      }
1111
1160
      else
1112
1161
        p++;
1113
1162
    }
1114
 
    /* Output any chars that migh be left */
1115
 
    dynstr_append_mem(ds, start, p-start);
 
1163
    /* Output any chars that might be left */
 
1164
    ds->append(start, p-start);
1116
1165
  }
1117
1166
  my_close(fd, MYF(0));
1118
1167
}
1124
1173
  SYNOPSIS
1125
1174
  run_command
1126
1175
  cmd - command to execute(should be properly quoted
1127
 
  ds_res- pointer to dynamic string where to store the result
 
1176
  result - pointer to string where to store the result
1128
1177
 
1129
1178
*/
1130
1179
 
1131
 
static int run_command(char* cmd,
1132
 
                       DYNAMIC_STRING *ds_res)
 
1180
static int run_command(const char * cmd, string * result)
1133
1181
{
 
1182
  assert(result!=NULL);
1134
1183
  char buf[512]= {0};
1135
1184
  FILE *res_file;
1136
1185
  int error;
1140
1189
 
1141
1190
  while (fgets(buf, sizeof(buf), res_file))
1142
1191
  {
1143
 
    if(ds_res)
1144
 
    {
1145
 
      /* Save the output of this command in the supplied string */
1146
 
      dynstr_append(ds_res, buf);
1147
 
    }
1148
 
    else
1149
 
    {
1150
 
      /* Print it directly on screen */
1151
 
      fprintf(stdout, "%s", buf);
1152
 
    }
 
1192
    /* Save the output of this command in the supplied string */
 
1193
    result->append(buf);
1153
1194
  }
1154
1195
 
1155
1196
  error= pclose(res_file);
1163
1204
  SYNOPSIS
1164
1205
  run_tool
1165
1206
  tool_path - the name of the tool to run
1166
 
  ds_res - pointer to dynamic string where to store the result
 
1207
  result - pointer to dynamic string where to store the result
1167
1208
  ... - variable number of arguments that will be properly
1168
 
        quoted and appended after the tool's name
 
1209
  quoted and appended after the tool's name
1169
1210
 
1170
1211
*/
1171
1212
 
1172
 
static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
 
1213
static int run_tool(const char *tool_path, string * result, ...)
1173
1214
{
1174
1215
  int ret;
1175
1216
  const char* arg;
1176
1217
  va_list args;
1177
 
  DYNAMIC_STRING ds_cmdline;
1178
 
 
1179
 
  if (init_dynamic_string(&ds_cmdline, "", FN_REFLEN, FN_REFLEN))
1180
 
    die("Out of memory");
1181
 
 
1182
 
  dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS);
1183
 
  dynstr_append(&ds_cmdline, " ");
1184
 
 
1185
 
  va_start(args, ds_res);
 
1218
  string ds_cmdline;
 
1219
 
 
1220
 
 
1221
  append_os_quoted(&ds_cmdline, tool_path);
 
1222
  ds_cmdline.append(" ");
 
1223
 
 
1224
  va_start(args, result);
1186
1225
 
1187
1226
  while ((arg= va_arg(args, char *)))
1188
1227
  {
1189
1228
    /* Options should be os quoted */
1190
1229
    if (strncmp(arg, "--", 2) == 0)
1191
 
      dynstr_append_os_quoted(&ds_cmdline, arg, NullS);
 
1230
      append_os_quoted(&ds_cmdline, arg, NullS);
1192
1231
    else
1193
 
      dynstr_append(&ds_cmdline, arg);
1194
 
    dynstr_append(&ds_cmdline, " ");
 
1232
      ds_cmdline.append(arg);
 
1233
    ds_cmdline.append(" ");
1195
1234
  }
1196
1235
 
1197
1236
  va_end(args);
1198
1237
 
1199
 
  ret= run_command(ds_cmdline.str, ds_res);
1200
 
  dynstr_free(&ds_cmdline);
 
1238
  ret= run_command(ds_cmdline.c_str(), result);
1201
1239
  return(ret);
1202
1240
}
1203
1241
 
1215
1253
 
1216
1254
*/
1217
1255
 
1218
 
static void show_diff(DYNAMIC_STRING* ds,
 
1256
static void show_diff(string* ds,
1219
1257
                      const char* filename1, const char* filename2)
1220
1258
{
1221
1259
 
1222
 
  DYNAMIC_STRING ds_tmp;
1223
 
 
1224
 
  if (init_dynamic_string(&ds_tmp, "", 256, 256))
1225
 
    die("Out of memory");
 
1260
  string ds_tmp;
1226
1261
 
1227
1262
  /* First try with unified diff */
1228
1263
  if (run_tool("diff",
1233
1268
               "2>&1",
1234
1269
               NULL) > 1) /* Most "diff" tools return >1 if error */
1235
1270
  {
1236
 
    dynstr_set(&ds_tmp, "");
 
1271
    ds_tmp= "";
1237
1272
 
1238
1273
    /* Fallback to context diff with "diff -c" */
1239
1274
    if (run_tool("diff",
1248
1283
        Fallback to dump both files to result file and inform
1249
1284
        about installing "diff"
1250
1285
      */
1251
 
      dynstr_set(&ds_tmp, "");
1252
 
 
1253
 
      dynstr_append(&ds_tmp,
1254
 
"\n"
1255
 
"The two files differ but it was not possible to execute 'diff' in\n"
1256
 
"order to show only the difference, tried both 'diff -u' or 'diff -c'.\n"
1257
 
"Instead the whole content of the two files was shown for you to diff manually. ;)\n\n"
1258
 
"To get a better report you should install 'diff' on your system, which you\n"
1259
 
"for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n"
1260
 
"\n");
1261
 
 
1262
 
      dynstr_append(&ds_tmp, " --- ");
1263
 
      dynstr_append(&ds_tmp, filename1);
1264
 
      dynstr_append(&ds_tmp, " >>>\n");
 
1286
      ds_tmp= "";
 
1287
 
 
1288
      ds_tmp.append(
 
1289
                    "\n"
 
1290
                    "The two files differ but it was not possible to execute 'diff' in\n"
 
1291
                    "order to show only the difference, tried both 'diff -u' or 'diff -c'.\n"
 
1292
                    "Instead the whole content of the two files was shown for you to diff manually. ;)\n\n"
 
1293
                    "To get a better report you should install 'diff' on your system, which you\n"
 
1294
                    "for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n"
 
1295
                    "\n");
 
1296
 
 
1297
      ds_tmp.append(" --- ");
 
1298
      ds_tmp.append(filename1);
 
1299
      ds_tmp.append(" >>>\n");
1265
1300
      cat_file(&ds_tmp, filename1);
1266
 
      dynstr_append(&ds_tmp, "<<<\n --- ");
1267
 
      dynstr_append(&ds_tmp, filename1);
1268
 
      dynstr_append(&ds_tmp, " >>>\n");
 
1301
      ds_tmp.append("<<<\n --- ");
 
1302
      ds_tmp.append(filename1);
 
1303
      ds_tmp.append(" >>>\n");
1269
1304
      cat_file(&ds_tmp, filename2);
1270
 
      dynstr_append(&ds_tmp, "<<<<\n");
 
1305
      ds_tmp.append("<<<<\n");
1271
1306
    }
1272
1307
  }
1273
1308
 
1274
1309
  if (ds)
1275
1310
  {
1276
1311
    /* Add the diff to output */
1277
 
    dynstr_append_mem(ds, ds_tmp.str, ds_tmp.length);
 
1312
    ds->append(ds_tmp.c_str(), ds_tmp.length());
1278
1313
  }
1279
1314
  else
1280
1315
  {
1281
1316
    /* Print diff directly to stdout */
1282
 
    fprintf(stderr, "%s\n", ds_tmp.str);
 
1317
    fprintf(stderr, "%s\n", ds_tmp.c_str());
1283
1318
  }
1284
1319
 
1285
 
  dynstr_free(&ds_tmp);
1286
 
 
1287
1320
}
1288
1321
 
1289
1322
 
1290
1323
enum compare_files_result_enum {
1291
 
   RESULT_OK= 0,
1292
 
   RESULT_CONTENT_MISMATCH= 1,
1293
 
   RESULT_LENGTH_MISMATCH= 2
 
1324
  RESULT_OK= 0,
 
1325
  RESULT_CONTENT_MISMATCH= 1,
 
1326
  RESULT_LENGTH_MISMATCH= 2
1294
1327
};
1295
1328
 
1296
1329
/*
1388
1421
  Compare content of the string in ds to content of file fname
1389
1422
 
1390
1423
  SYNOPSIS
1391
 
  dyn_string_cmp
 
1424
  string_cmp
1392
1425
  ds - Dynamic string containing the string o be compared
1393
1426
  fname - Name of file to compare with
1394
1427
 
1396
1429
  See 'compare_files2'
1397
1430
*/
1398
1431
 
1399
 
static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
 
1432
static int string_cmp(string* ds, const char *fname)
1400
1433
{
1401
1434
  int error;
1402
1435
  File fd;
1408
1441
    die("Failed to create temporary file for ds");
1409
1442
 
1410
1443
  /* Write ds to temporary file and set file pos to beginning*/
1411
 
  if (my_write(fd, (uchar *) ds->str, ds->length,
 
1444
  if (my_write(fd, (uchar *) ds->c_str(), ds->length(),
1412
1445
               MYF(MY_FNABP | MY_WME)) ||
1413
1446
      my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
1414
1447
  {
1440
1473
 
1441
1474
*/
1442
1475
 
1443
 
static void check_result(DYNAMIC_STRING* ds)
 
1476
static void check_result(string* ds)
1444
1477
{
1445
1478
  const char* mess= "Result content mismatch\n";
1446
1479
 
1450
1483
  if (access(result_file_name, F_OK) != 0)
1451
1484
    die("The specified result file does not exist: '%s'", result_file_name);
1452
1485
 
1453
 
  switch (dyn_string_cmp(ds, result_file_name)) {
 
1486
  switch (string_cmp(ds, result_file_name)) {
1454
1487
  case RESULT_OK:
1455
1488
    break; /* ok */
1456
1489
  case RESULT_LENGTH_MISMATCH:
1478
1511
      fn_format(reject_file, result_file_name, opt_logdir,
1479
1512
                ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
1480
1513
    }
1481
 
    str_to_file(reject_file, ds->str, ds->length);
 
1514
    str_to_file(reject_file, ds->c_str(), ds->length());
1482
1515
 
1483
 
    dynstr_set(ds, NULL); /* Don't create a .log file */
 
1516
    ds->erase(); /* Don't create a .log file */
1484
1517
 
1485
1518
    show_diff(NULL, result_file_name, reject_file);
1486
1519
    die(mess);
1509
1542
 
1510
1543
*/
1511
1544
 
1512
 
static void check_require(DYNAMIC_STRING* ds, const char *fname)
 
1545
static void check_require(string* ds, const char *fname)
1513
1546
{
1514
1547
 
1515
1548
 
1516
 
  if (dyn_string_cmp(ds, fname))
 
1549
  if (string_cmp(ds, fname))
1517
1550
  {
1518
1551
    char reason[FN_REFLEN];
1519
1552
    fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
1524
1557
 
1525
1558
 
1526
1559
/*
1527
 
   Remove surrounding chars from string
 
1560
  Remove surrounding chars from string
1528
1561
 
1529
 
   Return 1 if first character is found but not last
 
1562
  Return 1 if first character is found but not last
1530
1563
*/
1531
1564
static int strip_surrounding(char* str, char c1, char c2)
1532
1565
{
1562
1595
static void strip_parentheses(struct st_command *command)
1563
1596
{
1564
1597
  if (strip_surrounding(command->first_argument, '(', ')'))
1565
 
      die("%.*s - argument list started with '%c' must be ended with '%c'",
1566
 
          command->first_word_len, command->query, '(', ')');
 
1598
    die("%.*s - argument list started with '%c' must be ended with '%c'",
 
1599
        command->first_word_len, command->query, '(', ')');
1567
1600
}
1568
1601
 
1569
1602
 
1636
1669
 
1637
1670
 
1638
1671
VAR* var_get(const char *var_name, const char **var_name_end, bool raw,
1639
 
       bool ignore_not_existing)
 
1672
             bool ignore_not_existing)
1640
1673
{
1641
1674
  int digit;
1642
1675
  VAR *v;
1654
1687
    if (var_name == save_var_name)
1655
1688
    {
1656
1689
      if (ignore_not_existing)
1657
 
  return(0);
 
1690
        return(0);
1658
1691
      die("Empty variable");
1659
1692
    }
1660
1693
    length= (uint) (var_name - save_var_name);
1662
1695
      die("Too long variable name: %s", save_var_name);
1663
1696
 
1664
1697
    if (!(v = (VAR*) hash_search(&var_hash, (const uchar*) save_var_name,
1665
 
                                            length)))
 
1698
                                 length)))
1666
1699
    {
1667
1700
      char buff[MAX_VAR_NAME_LENGTH+1];
1668
1701
      strmake(buff, save_var_name, length);
1738
1771
      v->str_val_len= strlen(v->str_val);
1739
1772
    }
1740
1773
    snprintf(buf, sizeof(buf), "%.*s=%.*s",
1741
 
                v->name_len, v->name,
1742
 
                v->str_val_len, v->str_val);
 
1774
             v->name_len, v->name,
 
1775
             v->str_val_len, v->str_val);
1743
1776
    if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
1744
1777
      die("Out of memory");
1745
1778
    putenv(v->env_s);
1810
1843
 
1811
1844
static void var_query_set(VAR *var, const char *query, const char** query_end)
1812
1845
{
1813
 
  char *end = (char*)((query_end && *query_end) ?
1814
 
          *query_end : query + strlen(query));
 
1846
  const char *end = (char*)((query_end && *query_end) ?
 
1847
                            *query_end : query + strlen(query));
1815
1848
  DRIZZLE_RES *res;
1816
1849
  DRIZZLE_ROW row;
1817
1850
  DRIZZLE *drizzle= &cur_con->drizzle;
1818
 
  DYNAMIC_STRING ds_query;
 
1851
  string ds_query;
1819
1852
 
1820
1853
 
1821
1854
  while (end > query && *end != '`')
1825
1858
  ++query;
1826
1859
 
1827
1860
  /* Eval the query, thus replacing all environment variables */
1828
 
  init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
1829
1861
  do_eval(&ds_query, query, end, false);
1830
1862
 
1831
 
  if (drizzle_real_query(drizzle, ds_query.str, ds_query.length))
1832
 
    die("Error running query '%s': %d %s", ds_query.str,
1833
 
  drizzle_errno(drizzle), drizzle_error(drizzle));
 
1863
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1864
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1865
        drizzle_errno(drizzle), drizzle_error(drizzle));
1834
1866
  if (!(res= drizzle_store_result(drizzle)))
1835
 
    die("Query '%s' didn't return a result set", ds_query.str);
1836
 
  dynstr_free(&ds_query);
 
1867
    die("Query '%s' didn't return a result set", ds_query.c_str());
1837
1868
 
1838
1869
  if ((row= drizzle_fetch_row(res)) && row[0])
1839
1870
  {
1841
1872
      Concatenate all fields in the first row with tab in between
1842
1873
      and assign that string to the $variable
1843
1874
    */
1844
 
    DYNAMIC_STRING result;
 
1875
    string result;
1845
1876
    uint32_t i;
1846
1877
    uint32_t *lengths;
1847
1878
 
1848
 
    init_dynamic_string(&result, "", 512, 512);
1849
1879
    lengths= drizzle_fetch_lengths(res);
1850
1880
    for (i= 0; i < drizzle_num_fields(res); i++)
1851
1881
    {
1852
1882
      if (row[i])
1853
1883
      {
1854
1884
        /* Add column to tab separated string */
1855
 
  dynstr_append_mem(&result, row[i], lengths[i]);
 
1885
        result.append(row[i], lengths[i]);
1856
1886
      }
1857
 
      dynstr_append_mem(&result, "\t", 1);
 
1887
      result.append("\t", 1);
1858
1888
    }
1859
 
    end= result.str + result.length-1;
1860
 
    eval_expr(var, result.str, (const char**) &end);
1861
 
    dynstr_free(&result);
 
1889
    end= result.c_str() + result.length()-1;
 
1890
    eval_expr(var, result.c_str(), (const char**) &end);
1862
1891
  }
1863
1892
  else
1864
1893
    eval_expr(var, "", 0);
1884
1913
 
1885
1914
  <query to run> -    The query that should be sent to the server
1886
1915
  <column name> -     Name of the column that holds the field be compared
1887
 
                      against the expected value
 
1916
  against the expected value
1888
1917
  <row no> -          Number of the row that holds the field to be
1889
 
                      compared against the expected value
 
1918
  compared against the expected value
1890
1919
 
1891
1920
*/
1892
1921
 
1897
1926
  DRIZZLE_RES* res;
1898
1927
  DRIZZLE *drizzle= &cur_con->drizzle;
1899
1928
 
1900
 
  static DYNAMIC_STRING ds_query;
1901
 
  static DYNAMIC_STRING ds_col;
1902
 
  static DYNAMIC_STRING ds_row;
 
1929
  string ds_query;
 
1930
  string ds_col;
 
1931
  string ds_row;
1903
1932
  const struct command_arg query_get_value_args[] = {
1904
1933
    {"query", ARG_STRING, true, &ds_query, "Query to run"},
1905
1934
    {"column name", ARG_STRING, true, &ds_col, "Name of column"},
1914
1943
                     ',');
1915
1944
 
1916
1945
  /* Convert row number to int */
1917
 
  if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
1918
 
    die("Invalid row number: '%s'", ds_row.str);
1919
 
  dynstr_free(&ds_row);
 
1946
  if (!str2int(ds_row.c_str(), 10, (long) 0, (long) INT_MAX, &row_no))
 
1947
    die("Invalid row number: '%s'", ds_row.c_str());
1920
1948
 
1921
1949
  /* Remove any surrounding "'s from the query - if there is any */
1922
 
  if (strip_surrounding(ds_query.str, '"', '"'))
1923
 
    die("Mismatched \"'s around query '%s'", ds_query.str);
 
1950
  // (Don't get me started on this)
 
1951
  char * unstripped_query= strdup(ds_query.c_str());
 
1952
  if (strip_surrounding(unstripped_query, '"', '"'))
 
1953
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
 
1954
  ds_query= unstripped_query;
1924
1955
 
1925
1956
  /* Run the query */
1926
 
  if (drizzle_real_query(drizzle, ds_query.str, ds_query.length))
1927
 
    die("Error running query '%s': %d %s", ds_query.str,
1928
 
  drizzle_errno(drizzle), drizzle_error(drizzle));
 
1957
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
 
1958
    die("Error running query '%s': %d %s", ds_query.c_str(),
 
1959
        drizzle_errno(drizzle), drizzle_error(drizzle));
1929
1960
  if (!(res= drizzle_store_result(drizzle)))
1930
 
    die("Query '%s' didn't return a result set", ds_query.str);
 
1961
    die("Query '%s' didn't return a result set", ds_query.c_str());
1931
1962
 
1932
1963
  {
1933
1964
    /* Find column number from the given column name */
1937
1968
 
1938
1969
    for (i= 0; i < num_fields; i++)
1939
1970
    {
1940
 
      if (strcmp(fields[i].name, ds_col.str) == 0 &&
1941
 
          strlen(fields[i].name) == ds_col.length)
 
1971
      if (strcmp(fields[i].name, ds_col.c_str()) == 0 &&
 
1972
          strlen(fields[i].name) == ds_col.length())
1942
1973
      {
1943
1974
        col_no= i;
1944
1975
        break;
1948
1979
    {
1949
1980
      drizzle_free_result(res);
1950
1981
      die("Could not find column '%s' in the result of '%s'",
1951
 
          ds_col.str, ds_query.str);
 
1982
          ds_col.c_str(), ds_query.c_str());
1952
1983
    }
1953
1984
  }
1954
 
  dynstr_free(&ds_col);
1955
1985
 
1956
1986
  {
1957
1987
    /* Get the value */
1975
2005
    }
1976
2006
    eval_expr(var, value, 0);
1977
2007
  }
1978
 
  dynstr_free(&ds_query);
1979
2008
  drizzle_free_result(res);
1980
2009
 
1981
2010
  return;
2046
2075
        MIN_VAR_ALLOC : new_val_len + 1;
2047
2076
      if (!(v->str_val =
2048
2077
            v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1,
2049
 
                                    MYF(MY_WME)) :
 
2078
                                            MYF(MY_WME)) :
2050
2079
            (char *)my_malloc(v->alloced_len+1, MYF(MY_WME))))
2051
2080
        die("Out of memory");
2052
2081
    }
2101
2130
 
2102
2131
static void do_source(struct st_command *command)
2103
2132
{
2104
 
  static DYNAMIC_STRING ds_filename;
 
2133
  string ds_filename;
2105
2134
  const struct command_arg source_args[] = {
2106
2135
    { "filename", ARG_STRING, true, &ds_filename, "File to source" }
2107
2136
  };
2119
2148
    ; /* Do nothing */
2120
2149
  else
2121
2150
  {
2122
 
    open_file(ds_filename.str);
 
2151
    open_file(ds_filename.c_str());
2123
2152
  }
2124
2153
 
2125
 
  dynstr_free(&ds_filename);
2126
2154
  return;
2127
2155
}
2128
2156
 
2129
2157
 
2130
 
static FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
2131
 
{
2132
 
  return popen(ds_cmd->str, mode);
2133
 
}
2134
 
 
2135
 
 
2136
2158
static void init_builtin_echo(void)
2137
2159
{
2138
2160
  builtin_echo[0]= 0;
2144
2166
  Replace a substring
2145
2167
 
2146
2168
  SYNOPSIS
2147
 
    replace
2148
 
    ds_str      The string to search and perform the replace in
2149
 
    search_str  The string to search for
2150
 
    search_len  Length of the string to search for
2151
 
    replace_str The string to replace with
2152
 
    replace_len Length of the string to replace with
 
2169
  replace
 
2170
  ds_str      The string to search and perform the replace in
 
2171
  search_str  The string to search for
 
2172
  search_len  Length of the string to search for
 
2173
  replace_str The string to replace with
 
2174
  replace_len Length of the string to replace with
2153
2175
 
2154
2176
  RETURN
2155
 
    0 String replaced
2156
 
    1 Could not find search_str in str
 
2177
  0 String replaced
 
2178
  1 Could not find search_str in str
2157
2179
*/
2158
2180
 
2159
 
static int replace(DYNAMIC_STRING *ds_str,
 
2181
static int replace(string *ds_str,
2160
2182
                   const char *search_str, uint32_t search_len,
2161
2183
                   const char *replace_str, uint32_t replace_len)
2162
2184
{
2163
 
  DYNAMIC_STRING ds_tmp;
2164
 
  const char *start= strstr(ds_str->str, search_str);
 
2185
  string ds_tmp;
 
2186
  const char *start= strstr(ds_str->c_str(), search_str);
2165
2187
  if (!start)
2166
2188
    return 1;
2167
 
  init_dynamic_string(&ds_tmp, "",
2168
 
                      ds_str->length + replace_len, 256);
2169
 
  dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str);
2170
 
  dynstr_append_mem(&ds_tmp, replace_str, replace_len);
2171
 
  dynstr_append(&ds_tmp, start + search_len);
2172
 
  dynstr_set(ds_str, ds_tmp.str);
2173
 
  dynstr_free(&ds_tmp);
 
2189
  ds_tmp.append(ds_str->c_str(), start - ds_str->c_str());
 
2190
  ds_tmp.append(replace_str, replace_len);
 
2191
  ds_tmp.append(start + search_len);
 
2192
  *ds_str= ds_tmp;
2174
2193
  return 0;
2175
2194
}
2176
2195
 
2202
2221
  char buf[512];
2203
2222
  FILE *res_file;
2204
2223
  char *cmd= command->first_argument;
2205
 
  DYNAMIC_STRING ds_cmd;
 
2224
  string ds_cmd;
2206
2225
 
2207
2226
  /* Skip leading space */
2208
2227
  while (*cmd && my_isspace(charset_info, *cmd))
2211
2230
    die("Missing argument in exec");
2212
2231
  command->last_argument= command->end;
2213
2232
 
2214
 
  init_dynamic_string(&ds_cmd, 0, command->query_len+256, 256);
2215
2233
  /* Eval the command, thus replacing all environment variables */
2216
2234
  do_eval(&ds_cmd, cmd, command->end, !is_windows);
2217
2235
 
2222
2240
    replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo));
2223
2241
  }
2224
2242
 
2225
 
  if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error)
 
2243
  if (!(res_file= popen(ds_cmd.c_str(), "r")) && command->abort_on_error)
2226
2244
  {
2227
 
    dynstr_free(&ds_cmd);
2228
2245
    die("popen(\"%s\", \"r\") failed", command->first_argument);
2229
2246
  }
2230
2247
 
2236
2253
    }
2237
2254
    else
2238
2255
    {
2239
 
      replace_dynstr_append(&ds_res, buf);
 
2256
      replace_append(&ds_res, buf);
2240
2257
    }
2241
2258
  }
2242
2259
  error= pclose(res_file);
2248
2265
    if (command->abort_on_error)
2249
2266
    {
2250
2267
      log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d",
2251
 
              ds_cmd.str, error, status, errno);
2252
 
      dynstr_free(&ds_cmd);
 
2268
              ds_cmd.c_str(), error, status, errno);
2253
2269
      die("command \"%s\" failed", command->first_argument);
2254
2270
    }
2255
2271
 
2263
2279
    }
2264
2280
    if (!ok)
2265
2281
    {
2266
 
      dynstr_free(&ds_cmd);
2267
2282
      die("command \"%s\" failed with wrong error: %d",
2268
2283
          command->first_argument, status);
2269
2284
    }
2273
2288
  {
2274
2289
    /* Error code we wanted was != 0, i.e. not an expected success */
2275
2290
    log_msg("exec of '%s failed, error: %d, errno: %d",
2276
 
            ds_cmd.str, error, errno);
2277
 
    dynstr_free(&ds_cmd);
 
2291
            ds_cmd.c_str(), error, errno);
2278
2292
    die("command \"%s\" succeeded - should have failed with errno %d...",
2279
2293
        command->first_argument, command->expected_errors.err[0].code.errnum);
2280
2294
  }
2281
2295
 
2282
 
  dynstr_free(&ds_cmd);
2283
2296
  return;
2284
2297
}
2285
2298
 
2333
2346
 
2334
2347
 
2335
2348
/*
2336
 
  Wrapper for 'system' function
2337
 
 
2338
 
  NOTE
2339
 
  If drizzletest is executed from cygwin shell, the command will be
2340
 
  executed in the "windows command interpreter" cmd.exe and we prepend "sh"
2341
 
  to make it be executed by cygwins "bash". Thus commands like "rm",
2342
 
  "mkdir" as well as shellscripts can executed by "system" in Windows.
2343
 
 
2344
 
*/
2345
 
 
2346
 
static int my_system(DYNAMIC_STRING* ds_cmd)
2347
 
{
2348
 
  return system(ds_cmd->str);
2349
 
}
2350
 
 
2351
 
 
2352
 
/*
2353
2349
  SYNOPSIS
2354
2350
  do_system
2355
2351
  command  called command
2364
2360
 
2365
2361
static void do_system(struct st_command *command)
2366
2362
{
2367
 
  DYNAMIC_STRING ds_cmd;
 
2363
  string ds_cmd;
2368
2364
 
2369
2365
 
2370
2366
  if (strlen(command->first_argument) == 0)
2371
2367
    die("Missing arguments to system, nothing to do!");
2372
2368
 
2373
 
  init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256);
2374
 
 
2375
2369
  /* Eval the system command, thus replacing all environment variables */
2376
2370
  do_eval(&ds_cmd, command->first_argument, command->end, !is_windows);
2377
2371
 
2378
 
  if (my_system(&ds_cmd))
 
2372
  if (system(ds_cmd.c_str()))
2379
2373
  {
2380
2374
    if (command->abort_on_error)
2381
2375
      die("system command '%s' failed", command->first_argument);
2382
2376
 
2383
2377
    /* If ! abort_on_error, log message and continue */
2384
 
    dynstr_append(&ds_res, "system command '");
2385
 
    replace_dynstr_append(&ds_res, command->first_argument);
2386
 
    dynstr_append(&ds_res, "' failed\n");
 
2378
    ds_res.append("system command '");
 
2379
    replace_append(&ds_res, command->first_argument);
 
2380
    ds_res.append("' failed\n");
2387
2381
  }
2388
2382
 
2389
2383
  command->last_argument= command->end;
2390
 
  dynstr_free(&ds_cmd);
2391
2384
  return;
2392
2385
}
2393
2386
 
2405
2398
static void do_remove_file(struct st_command *command)
2406
2399
{
2407
2400
  int error;
2408
 
  static DYNAMIC_STRING ds_filename;
 
2401
  string ds_filename;
2409
2402
  const struct command_arg rm_args[] = {
2410
2403
    { "filename", ARG_STRING, true, &ds_filename, "File to delete" }
2411
2404
  };
2415
2408
                     rm_args, sizeof(rm_args)/sizeof(struct command_arg),
2416
2409
                     ' ');
2417
2410
 
2418
 
  error= my_delete(ds_filename.str, MYF(0)) != 0;
 
2411
  error= my_delete(ds_filename.c_str(), MYF(0)) != 0;
2419
2412
  handle_command_error(command, error);
2420
 
  dynstr_free(&ds_filename);
2421
2413
  return;
2422
2414
}
2423
2415
 
2437
2429
static void do_copy_file(struct st_command *command)
2438
2430
{
2439
2431
  int error;
2440
 
  static DYNAMIC_STRING ds_from_file;
2441
 
  static DYNAMIC_STRING ds_to_file;
 
2432
  string ds_from_file;
 
2433
  string ds_to_file;
2442
2434
  const struct command_arg copy_file_args[] = {
2443
2435
    { "from_file", ARG_STRING, true, &ds_from_file, "Filename to copy from" },
2444
2436
    { "to_file", ARG_STRING, true, &ds_to_file, "Filename to copy to" }
2450
2442
                     sizeof(copy_file_args)/sizeof(struct command_arg),
2451
2443
                     ' ');
2452
2444
 
2453
 
  error= (my_copy(ds_from_file.str, ds_to_file.str,
 
2445
  error= (my_copy(ds_from_file.c_str(), ds_to_file.c_str(),
2454
2446
                  MYF(MY_DONT_OVERWRITE_FILE)) != 0);
2455
2447
  handle_command_error(command, error);
2456
 
  dynstr_free(&ds_from_file);
2457
 
  dynstr_free(&ds_to_file);
2458
2448
  return;
2459
2449
}
2460
2450
 
2473
2463
static void do_chmod_file(struct st_command *command)
2474
2464
{
2475
2465
  long mode= 0;
2476
 
  static DYNAMIC_STRING ds_mode;
2477
 
  static DYNAMIC_STRING ds_file;
 
2466
  string ds_mode;
 
2467
  string ds_file;
2478
2468
  const struct command_arg chmod_file_args[] = {
2479
2469
    { "mode", ARG_STRING, true, &ds_mode, "Mode of file(octal) ex. 0660"},
2480
2470
    { "filename", ARG_STRING, true, &ds_file, "Filename of file to modify" }
2487
2477
                     ' ');
2488
2478
 
2489
2479
  /* Parse what mode to set */
2490
 
  if (ds_mode.length != 4 ||
2491
 
      str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS)
 
2480
  if (ds_mode.length() != 4 ||
 
2481
      str2int(ds_mode.c_str(), 8, 0, INT_MAX, &mode) == NullS)
2492
2482
    die("You must write a 4 digit octal number for mode");
2493
2483
 
2494
 
  handle_command_error(command, chmod(ds_file.str, mode));
2495
 
  dynstr_free(&ds_mode);
2496
 
  dynstr_free(&ds_file);
 
2484
  handle_command_error(command, chmod(ds_file.c_str(), mode));
2497
2485
  return;
2498
2486
}
2499
2487
 
2511
2499
static void do_file_exist(struct st_command *command)
2512
2500
{
2513
2501
  int error;
2514
 
  static DYNAMIC_STRING ds_filename;
 
2502
  string ds_filename;
2515
2503
  const struct command_arg file_exist_args[] = {
2516
2504
    { "filename", ARG_STRING, true, &ds_filename, "File to check if it exist" }
2517
2505
  };
2522
2510
                     sizeof(file_exist_args)/sizeof(struct command_arg),
2523
2511
                     ' ');
2524
2512
 
2525
 
  error= (access(ds_filename.str, F_OK) != 0);
 
2513
  error= (access(ds_filename.c_str(), F_OK) != 0);
2526
2514
  handle_command_error(command, error);
2527
 
  dynstr_free(&ds_filename);
2528
2515
  return;
2529
2516
}
2530
2517
 
2542
2529
static void do_mkdir(struct st_command *command)
2543
2530
{
2544
2531
  int error;
2545
 
  static DYNAMIC_STRING ds_dirname;
 
2532
  string ds_dirname;
2546
2533
  const struct command_arg mkdir_args[] = {
2547
2534
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2548
2535
  };
2552
2539
                     mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2553
2540
                     ' ');
2554
2541
 
2555
 
  error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0;
 
2542
  error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
2556
2543
  handle_command_error(command, error);
2557
 
  dynstr_free(&ds_dirname);
2558
2544
  return;
2559
2545
}
2560
2546
 
2571
2557
static void do_rmdir(struct st_command *command)
2572
2558
{
2573
2559
  int error;
2574
 
  static DYNAMIC_STRING ds_dirname;
 
2560
  string ds_dirname;
2575
2561
  const struct command_arg rmdir_args[] = {
2576
2562
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to remove"}
2577
2563
  };
2581
2567
                     rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
2582
2568
                     ' ');
2583
2569
 
2584
 
  error= rmdir(ds_dirname.str) != 0;
 
2570
  error= rmdir(ds_dirname.c_str()) != 0;
2585
2571
  handle_command_error(command, error);
2586
 
  dynstr_free(&ds_dirname);
2587
2572
  return;
2588
2573
}
2589
2574
 
2612
2597
}
2613
2598
 
2614
2599
 
2615
 
static void read_until_delimiter(DYNAMIC_STRING *ds,
2616
 
                                 DYNAMIC_STRING *ds_delimiter)
 
2600
static void read_until_delimiter(string *ds,
 
2601
                                 string *ds_delimiter)
2617
2602
{
2618
2603
  char c;
2619
2604
 
2620
 
  if (ds_delimiter->length > MAX_DELIMITER_LENGTH)
 
2605
  if (ds_delimiter->length() > MAX_DELIMITER_LENGTH)
2621
2606
    die("Max delimiter length(%d) exceeded", MAX_DELIMITER_LENGTH);
2622
2607
 
2623
2608
  /* Read from file until delimiter is found */
2644
2629
 
2645
2630
    if (feof(cur_file->file))
2646
2631
      die("End of file encountered before '%s' delimiter was found",
2647
 
          ds_delimiter->str);
 
2632
          ds_delimiter->c_str());
2648
2633
 
2649
 
    if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length))
 
2634
    if (match_delimiter(c, ds_delimiter->c_str(), ds_delimiter->length()))
2650
2635
      break;
2651
2636
 
2652
 
    dynstr_append_mem(ds, (const char*)&c, 1);
 
2637
    ds->push_back(c);
2653
2638
  }
2654
2639
  return;
2655
2640
}
2657
2642
 
2658
2643
static void do_write_file_command(struct st_command *command, bool append)
2659
2644
{
2660
 
  static DYNAMIC_STRING ds_content;
2661
 
  static DYNAMIC_STRING ds_filename;
2662
 
  static DYNAMIC_STRING ds_delimiter;
 
2645
  string ds_content;
 
2646
  string ds_filename;
 
2647
  string ds_delimiter;
2663
2648
  const struct command_arg write_file_args[] = {
2664
2649
    { "filename", ARG_STRING, true, &ds_filename, "File to write to" },
2665
2650
    { "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" }
2673
2658
                     ' ');
2674
2659
 
2675
2660
  /* If no delimiter was provided, use EOF */
2676
 
  if (ds_delimiter.length == 0)
2677
 
    dynstr_set(&ds_delimiter, "EOF");
 
2661
  if (ds_delimiter.length() == 0)
 
2662
    ds_delimiter= "EOF";
2678
2663
 
2679
 
  if (!append && access(ds_filename.str, F_OK) == 0)
 
2664
  if (!append && access(ds_filename.c_str(), F_OK) == 0)
2680
2665
  {
2681
2666
    /* The file should not be overwritten */
2682
 
    die("File already exist: '%s'", ds_filename.str);
 
2667
    die("File already exist: '%s'", ds_filename.c_str());
2683
2668
  }
2684
2669
 
2685
 
  init_dynamic_string(&ds_content, "", 1024, 1024);
2686
2670
  read_until_delimiter(&ds_content, &ds_delimiter);
2687
 
  str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
2688
 
  dynstr_free(&ds_content);
2689
 
  dynstr_free(&ds_filename);
2690
 
  dynstr_free(&ds_delimiter);
 
2671
  str_to_file2(ds_filename.c_str(), ds_content.c_str(),
 
2672
               ds_content.length(), append);
2691
2673
  return;
2692
2674
}
2693
2675
 
2770
2752
 
2771
2753
static void do_cat_file(struct st_command *command)
2772
2754
{
2773
 
  static DYNAMIC_STRING ds_filename;
 
2755
  static string ds_filename;
2774
2756
  const struct command_arg cat_file_args[] = {
2775
2757
    { "filename", ARG_STRING, true, &ds_filename, "File to read from" }
2776
2758
  };
2782
2764
                     sizeof(cat_file_args)/sizeof(struct command_arg),
2783
2765
                     ' ');
2784
2766
 
2785
 
  cat_file(&ds_res, ds_filename.str);
 
2767
  cat_file(&ds_res, ds_filename.c_str());
2786
2768
 
2787
 
  dynstr_free(&ds_filename);
2788
2769
  return;
2789
2770
}
2790
2771
 
2804
2785
static void do_diff_files(struct st_command *command)
2805
2786
{
2806
2787
  int error= 0;
2807
 
  static DYNAMIC_STRING ds_filename;
2808
 
  static DYNAMIC_STRING ds_filename2;
 
2788
  string ds_filename;
 
2789
  string ds_filename2;
2809
2790
  const struct command_arg diff_file_args[] = {
2810
2791
    { "file1", ARG_STRING, true, &ds_filename, "First file to diff" },
2811
2792
    { "file2", ARG_STRING, true, &ds_filename2, "Second file to diff" }
2818
2799
                     sizeof(diff_file_args)/sizeof(struct command_arg),
2819
2800
                     ' ');
2820
2801
 
2821
 
  if ((error= compare_files(ds_filename.str, ds_filename2.str)))
 
2802
  if ((error= compare_files(ds_filename.c_str(), ds_filename2.c_str())))
2822
2803
  {
2823
2804
    /* Compare of the two files failed, append them to output
2824
2805
       so the failure can be analyzed
2825
2806
    */
2826
 
    show_diff(&ds_res, ds_filename.str, ds_filename2.str);
 
2807
    show_diff(&ds_res, ds_filename.c_str(), ds_filename2.c_str());
2827
2808
  }
2828
2809
 
2829
 
  dynstr_free(&ds_filename);
2830
 
  dynstr_free(&ds_filename2);
2831
2810
  handle_command_error(command, error);
2832
2811
  return;
2833
2812
}
2901
2880
{
2902
2881
  DRIZZLE *drizzle= &cur_con->drizzle;
2903
2882
  /* static keyword to make the NetWare compiler happy. */
2904
 
  static DYNAMIC_STRING ds_user, ds_passwd, ds_db;
 
2883
  string ds_user, ds_passwd, ds_db;
2905
2884
  const struct command_arg change_user_args[] = {
2906
2885
    { "user", ARG_STRING, false, &ds_user, "User to connect as" },
2907
2886
    { "password", ARG_STRING, false, &ds_passwd, "Password used when connecting" },
2915
2894
                     sizeof(change_user_args)/sizeof(struct command_arg),
2916
2895
                     ',');
2917
2896
 
2918
 
  if (!ds_user.length)
2919
 
    dynstr_set(&ds_user, drizzle->user);
2920
 
 
2921
 
  if (!ds_passwd.length)
2922
 
    dynstr_set(&ds_passwd, drizzle->passwd);
2923
 
 
2924
 
  if (!ds_db.length)
2925
 
    dynstr_set(&ds_db, drizzle->db);
2926
 
 
2927
 
  if (drizzle_change_user(drizzle, ds_user.str, ds_passwd.str, ds_db.str))
 
2897
  if (!ds_user.length())
 
2898
    ds_user= drizzle->user;
 
2899
 
 
2900
  if (!ds_passwd.length())
 
2901
    ds_passwd= drizzle->passwd;
 
2902
 
 
2903
  if (!ds_db.length())
 
2904
    ds_db= drizzle->db;
 
2905
 
 
2906
  if (drizzle_change_user(drizzle, ds_user.c_str(),
 
2907
                          ds_passwd.c_str(), ds_db.c_str()))
2928
2908
    die("change user failed: %s", drizzle_error(drizzle));
2929
2909
 
2930
 
  dynstr_free(&ds_user);
2931
 
  dynstr_free(&ds_passwd);
2932
 
  dynstr_free(&ds_db);
2933
2910
 
2934
2911
  return;
2935
2912
}
2961
2938
  FILE *res_file;
2962
2939
  char buf[FN_REFLEN];
2963
2940
  char temp_file_path[FN_REFLEN];
2964
 
  static DYNAMIC_STRING ds_script;
2965
 
  static DYNAMIC_STRING ds_delimiter;
 
2941
  string ds_script;
 
2942
  string ds_delimiter;
2966
2943
  const struct command_arg perl_args[] = {
2967
2944
    { "delimiter", ARG_STRING, false, &ds_delimiter, "Delimiter to read until" }
2968
2945
  };
2975
2952
                     ' ');
2976
2953
 
2977
2954
  /* If no delimiter was provided, use EOF */
2978
 
  if (ds_delimiter.length == 0)
2979
 
    dynstr_set(&ds_delimiter, "EOF");
 
2955
  if (ds_delimiter.length() == 0)
 
2956
    ds_delimiter= "EOF";
2980
2957
 
2981
 
  init_dynamic_string(&ds_script, "", 1024, 1024);
2982
2958
  read_until_delimiter(&ds_script, &ds_delimiter);
2983
2959
 
2984
2960
  /* Create temporary file name */
2988
2964
    die("Failed to create temporary file for perl command");
2989
2965
  my_close(fd, MYF(0));
2990
2966
 
2991
 
  str_to_file(temp_file_path, ds_script.str, ds_script.length);
 
2967
  str_to_file(temp_file_path, ds_script.c_str(), ds_script.length());
2992
2968
 
2993
2969
  /* Format the "perl <filename>" command */
2994
2970
  snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
3001
2977
    if (disable_result_log)
3002
2978
      buf[strlen(buf)-1]=0;
3003
2979
    else
3004
 
      replace_dynstr_append(&ds_res, buf);
 
2980
      replace_append(&ds_res, buf);
3005
2981
  }
3006
2982
  error= pclose(res_file);
3007
2983
 
3009
2985
  my_delete(temp_file_path, MYF(0));
3010
2986
 
3011
2987
  handle_command_error(command, WEXITSTATUS(error));
3012
 
  dynstr_free(&ds_script);
3013
 
  dynstr_free(&ds_delimiter);
3014
2988
  return;
3015
2989
}
3016
2990
 
3018
2992
/*
3019
2993
  Print the content between echo and <delimiter> to result file.
3020
2994
  Evaluate all variables in the string before printing, allow
3021
 
  for variable names to be escaped using \
 
2995
  for variable names to be escaped using        \
3022
2996
 
3023
2997
  SYNOPSIS
3024
2998
  do_echo()
3041
3015
 
3042
3016
static int do_echo(struct st_command *command)
3043
3017
{
3044
 
  DYNAMIC_STRING ds_echo;
3045
 
 
3046
 
 
3047
 
  init_dynamic_string(&ds_echo, "", command->query_len, 256);
 
3018
  string ds_echo;
 
3019
 
 
3020
 
3048
3021
  do_eval(&ds_echo, command->first_argument, command->end, false);
3049
 
  dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length);
3050
 
  dynstr_append_mem(&ds_res, "\n", 1);
3051
 
  dynstr_free(&ds_echo);
 
3022
  ds_res.append(ds_echo.c_str(), ds_echo.length());
 
3023
  ds_res.append("\n");
3052
3024
  command->last_argument= command->end;
3053
3025
  return(0);
3054
3026
}
3066
3038
    int done;
3067
3039
 
3068
3040
    if (drizzle_query(drizzle,"show status like 'Slave_running'") ||
3069
 
  !(res=drizzle_store_result(drizzle)))
 
3041
        !(res=drizzle_store_result(drizzle)))
3070
3042
      die("Query failed while probing slave for stop: %s",
3071
 
    drizzle_error(drizzle));
 
3043
          drizzle_error(drizzle));
3072
3044
    if (!(row=drizzle_fetch_row(res)) || !row[1])
3073
3045
    {
3074
3046
      drizzle_free_result(res);
3096
3068
    die("Calling 'sync_with_master' without calling 'save_master_pos'");
3097
3069
 
3098
3070
  sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
3099
 
    master_pos.pos + offset);
 
3071
          master_pos.pos + offset);
3100
3072
 
3101
3073
wait_for_position:
3102
3074
 
3165
3137
 
3166
3138
  if (drizzle_query(drizzle, query= "show master status"))
3167
3139
    die("failed in 'show master status': %d %s",
3168
 
  drizzle_errno(drizzle), drizzle_error(drizzle));
 
3140
        drizzle_errno(drizzle), drizzle_error(drizzle));
3169
3141
 
3170
3142
  if (!(res = drizzle_store_result(drizzle)))
3171
3143
    die("drizzle_store_result() retuned NULL for '%s'", query);
3201
3173
{
3202
3174
  char *p= command->first_argument;
3203
3175
  char *var_name, *var_name_end;
3204
 
  DYNAMIC_STRING let_rhs_expr;
3205
 
 
3206
 
 
3207
 
  init_dynamic_string(&let_rhs_expr, "", 512, 2048);
 
3176
  string let_rhs_expr;
 
3177
 
3208
3178
 
3209
3179
  /* Find <var_name> */
3210
3180
  if (!*p)
3229
3199
 
3230
3200
  command->last_argument= command->end;
3231
3201
  /* Assign var_val to var_name */
3232
 
  var_set(var_name, var_name_end, let_rhs_expr.str,
3233
 
          (let_rhs_expr.str + let_rhs_expr.length));
3234
 
  dynstr_free(&let_rhs_expr);
 
3202
  var_set(var_name, var_name_end, let_rhs_expr.c_str(),
 
3203
          (let_rhs_expr.c_str() + let_rhs_expr.length()));
3235
3204
  return;
3236
3205
}
3237
3206
 
3243
3212
  do_sleep()
3244
3213
  q         called command
3245
3214
  real_sleep   use the value from opt_sleep as number of seconds to sleep
3246
 
               if real_sleep is false
 
3215
  if real_sleep is false
3247
3216
 
3248
3217
  DESCRIPTION
3249
3218
  sleep <seconds>
3291
3260
 
3292
3261
 
3293
3262
static void do_get_file_name(struct st_command *command,
3294
 
                      char* dest, uint dest_max_len)
 
3263
                             char* dest, uint dest_max_len)
3295
3264
{
3296
3265
  char *p= command->first_argument, *name;
3297
3266
  if (!*p)
3392
3361
        if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p))
3393
3362
          *to_ptr++= *p++;
3394
3363
        else
3395
 
          die("The sqlstate may only consist of digits[0-9] " \
 
3364
          die("The sqlstate may only consist of digits[0-9] "   \
3396
3365
              "and _uppercase_ letters");
3397
3366
      }
3398
3367
 
3422
3391
      while (*p && p != end)
3423
3392
      {
3424
3393
        if (!my_isdigit(charset_info, *p))
3425
 
          die("Invalid argument to error: '%s' - "\
 
3394
          die("Invalid argument to error: '%s' - "              \
3426
3395
              "the errno may only consist of digits[0-9]",
3427
3396
              command->first_argument);
3428
3397
        p++;
3430
3399
 
3431
3400
      /* Convert the sting to int */
3432
3401
      if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
3433
 
  die("Invalid argument to error: '%s'", command->first_argument);
 
3402
        die("Invalid argument to error: '%s'", command->first_argument);
3434
3403
 
3435
3404
      to->code.errnum= (uint) val;
3436
3405
      to->type= ERR_ERRNO;
3489
3458
      /* We can't translate \0 -> ASCII 0 as replace can't handle ASCII 0 */
3490
3459
      switch (*++from) {
3491
3460
      case 'n':
3492
 
  *to++= '\n';
3493
 
  break;
 
3461
        *to++= '\n';
 
3462
        break;
3494
3463
      case 't':
3495
 
  *to++= '\t';
3496
 
  break;
 
3464
        *to++= '\t';
 
3465
        break;
3497
3466
      case 'r':
3498
 
  *to++ = '\r';
3499
 
  break;
 
3467
        *to++ = '\r';
 
3468
        break;
3500
3469
      case 'b':
3501
 
  *to++ = '\b';
3502
 
  break;
 
3470
        *to++ = '\b';
 
3471
        break;
3503
3472
      case 'Z':        /* ^Z must be escaped on Win32 */
3504
 
  *to++='\032';
3505
 
  break;
 
3473
        *to++='\032';
 
3474
        break;
3506
3475
      default:
3507
 
  *to++ = *from;
3508
 
  break;
 
3476
        *to++ = *from;
 
3477
        break;
3509
3478
      }
3510
3479
    }
3511
3480
    else if (c == sep)
3512
3481
    {
3513
3482
      if (c == ' ' || c != *++from)
3514
 
  break;        /* Found end of string */
 
3483
        break;        /* Found end of string */
3515
3484
      *to++=c;        /* Copy duplicated separator */
3516
3485
    }
3517
3486
    else
3651
3620
*/
3652
3621
 
3653
3622
static void safe_connect(DRIZZLE *drizzle, const char *name, const char *host,
3654
 
                  const char *user, const char *pass, const char *db,
3655
 
                  int port)
 
3623
                         const char *user, const char *pass, const char *db,
 
3624
                         int port)
3656
3625
{
3657
3626
  int failed_attempts= 0;
3658
3627
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
3659
3628
 
3660
3629
 
3661
3630
  while(!drizzle_connect(drizzle, host, user, pass, db, port, NULL,
3662
 
                            CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
 
3631
                         CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
3663
3632
  {
3664
3633
    /*
3665
3634
      Connect failed
3717
3686
*/
3718
3687
 
3719
3688
static int connect_n_handle_errors(struct st_command *command,
3720
 
                            DRIZZLE *con, const char* host,
3721
 
                            const char* user, const char* pass,
3722
 
                            const char* db, int port, const char* sock)
 
3689
                                   DRIZZLE *con, const char* host,
 
3690
                                   const char* user, const char* pass,
 
3691
                                   const char* db, int port, const char* sock)
3723
3692
{
3724
 
  DYNAMIC_STRING *ds;
3725
 
 
3726
 
  ds= &ds_res;
3727
3693
 
3728
3694
  /* Only log if an error is expected */
3729
3695
  if (!command->abort_on_error &&
3732
3698
    /*
3733
3699
      Log the connect to result log
3734
3700
    */
3735
 
    dynstr_append_mem(ds, "connect(", 8);
3736
 
    replace_dynstr_append(ds, host);
3737
 
    dynstr_append_mem(ds, ",", 1);
3738
 
    replace_dynstr_append(ds, user);
3739
 
    dynstr_append_mem(ds, ",", 1);
3740
 
    replace_dynstr_append(ds, pass);
3741
 
    dynstr_append_mem(ds, ",", 1);
 
3701
    ds_res.append("connect(");
 
3702
    replace_append(&ds_res, host);
 
3703
    ds_res.append(",");
 
3704
    replace_append(&ds_res, user);
 
3705
    ds_res.append(",");
 
3706
    replace_append(&ds_res, pass);
 
3707
    ds_res.append(",");
3742
3708
    if (db)
3743
 
      replace_dynstr_append(ds, db);
3744
 
    dynstr_append_mem(ds, ",", 1);
3745
 
    replace_dynstr_append_uint(ds, port);
3746
 
    dynstr_append_mem(ds, ",", 1);
 
3709
      replace_append(&ds_res, db);
 
3710
    ds_res.append(",");
 
3711
    replace_append_uint(&ds_res, port);
 
3712
    ds_res.append(",");
3747
3713
    if (sock)
3748
 
      replace_dynstr_append(ds, sock);
3749
 
    dynstr_append_mem(ds, ")", 1);
3750
 
    dynstr_append_mem(ds, delimiter, delimiter_length);
3751
 
    dynstr_append_mem(ds, "\n", 1);
 
3714
      replace_append(&ds_res, sock);
 
3715
    ds_res.append(")");
 
3716
    ds_res.append(delimiter);
 
3717
    ds_res.append("\n");
3752
3718
  }
3753
3719
  if (!drizzle_connect(con, host, user, pass, db, port, 0,
3754
 
                          CLIENT_MULTI_STATEMENTS))
 
3720
                       CLIENT_MULTI_STATEMENTS))
3755
3721
  {
3756
3722
    var_set_errno(drizzle_errno(con));
3757
3723
    handle_error(command, drizzle_errno(con), drizzle_error(con),
3758
 
     drizzle_sqlstate(con), ds);
 
3724
                 drizzle_sqlstate(con), &ds_res);
3759
3725
    return 0; /* Not connected */
3760
3726
  }
3761
3727
 
3785
3751
  <port> - server port
3786
3752
  <sock> - server socket
3787
3753
  <opts> - options to use for the connection
3788
 
   * SSL - use SSL if available
3789
 
   * COMPRESS - use compression if available
 
3754
  * SSL - use SSL if available
 
3755
  * COMPRESS - use compression if available
3790
3756
 
3791
 
*/
 
3757
  */
3792
3758
 
3793
3759
static void do_connect(struct st_command *command)
3794
3760
{
3795
3761
  int con_port= opt_port;
3796
 
  char *con_options;
 
3762
  const char *con_options;
3797
3763
  bool con_ssl= 0, con_compress= 0;
3798
3764
  struct st_connection* con_slot;
3799
3765
 
3800
 
  static DYNAMIC_STRING ds_connection_name;
3801
 
  static DYNAMIC_STRING ds_host;
3802
 
  static DYNAMIC_STRING ds_user;
3803
 
  static DYNAMIC_STRING ds_password;
3804
 
  static DYNAMIC_STRING ds_database;
3805
 
  static DYNAMIC_STRING ds_port;
3806
 
  static DYNAMIC_STRING ds_sock;
3807
 
  static DYNAMIC_STRING ds_options;
 
3766
  string ds_connection_name;
 
3767
  string ds_host;
 
3768
  string ds_user;
 
3769
  string ds_password;
 
3770
  string ds_database;
 
3771
  string ds_port;
 
3772
  string ds_sock;
 
3773
  string ds_options;
3808
3774
  const struct command_arg connect_args[] = {
3809
3775
    { "connection name", ARG_STRING, true, &ds_connection_name, "Name of the connection" },
3810
3776
    { "host", ARG_STRING, true, &ds_host, "Host to connect to" },
3823
3789
                     ',');
3824
3790
 
3825
3791
  /* Port */
3826
 
  if (ds_port.length)
 
3792
  if (ds_port.length())
3827
3793
  {
3828
 
    con_port= atoi(ds_port.str);
 
3794
    con_port= atoi(ds_port.c_str());
3829
3795
    if (con_port == 0)
3830
 
      die("Illegal argument for port: '%s'", ds_port.str);
 
3796
      die("Illegal argument for port: '%s'", ds_port.c_str());
3831
3797
  }
3832
3798
 
3833
3799
  /* Sock */
3834
 
  if (ds_sock.length)
 
3800
  if (!ds_sock.empty())
3835
3801
  {
3836
3802
    /*
3837
3803
      If the socket is specified just as a name without path
3838
3804
      append tmpdir in front
3839
3805
    */
3840
 
    if (*ds_sock.str != FN_LIBCHAR)
 
3806
    if (*ds_sock.c_str() != FN_LIBCHAR)
3841
3807
    {
3842
3808
      char buff[FN_REFLEN];
3843
 
      fn_format(buff, ds_sock.str, TMPDIR, "", 0);
3844
 
      dynstr_set(&ds_sock, buff);
 
3809
      fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
 
3810
      ds_sock= buff;
3845
3811
    }
3846
3812
  }
3847
 
  else
3848
 
  {
3849
 
    /* No socket specified, use default */
3850
 
    dynstr_set(&ds_sock, unix_sock);
3851
 
  }
3852
3813
 
3853
3814
  /* Options */
3854
 
  con_options= ds_options.str;
 
3815
  con_options= ds_options.c_str();
3855
3816
  while (*con_options)
3856
3817
  {
3857
 
    char* end;
 
3818
    const char* end;
3858
3819
    /* Step past any spaces in beginning of option*/
3859
3820
    while (*con_options && my_isspace(charset_info, *con_options))
3860
 
     con_options++;
 
3821
      con_options++;
3861
3822
    /* Find end of this option */
3862
3823
    end= con_options;
3863
3824
    while (*end && !my_isspace(charset_info, *end))
3873
3834
    con_options= end;
3874
3835
  }
3875
3836
 
3876
 
  if (find_connection_by_name(ds_connection_name.str))
3877
 
    die("Connection %s already exists", ds_connection_name.str);
3878
 
   
 
3837
  if (find_connection_by_name(ds_connection_name.c_str()))
 
3838
    die("Connection %s already exists", ds_connection_name.c_str());
 
3839
 
3879
3840
  if (next_con != connections_end)
 
3841
  {
3880
3842
    con_slot= next_con;
 
3843
  }
3881
3844
  else
3882
3845
  {
3883
3846
    if (!(con_slot= find_connection_by_name("-closed_connection-")))
3885
3848
          (int) (sizeof(connections)/sizeof(struct st_connection)));
3886
3849
  }
3887
3850
 
3888
 
#ifdef EMBEDDED_LIBRARY
3889
 
  con_slot->query_done= 1;
3890
 
#endif
3891
3851
  if (!drizzle_create(&con_slot->drizzle))
3892
3852
    die("Failed on drizzle_create()");
3893
3853
  if (opt_compress || con_compress)
3894
3854
    drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_COMPRESS, NullS);
3895
3855
  drizzle_options(&con_slot->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
3896
3856
  drizzle_options(&con_slot->drizzle, DRIZZLE_SET_CHARSET_NAME,
3897
 
                charset_info->csname);
 
3857
                  charset_info->csname);
3898
3858
  int opt_protocol= DRIZZLE_PROTOCOL_TCP;
3899
3859
  drizzle_options(&con_slot->drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
3900
3860
  if (opt_charsets_dir)
3901
3861
    drizzle_options(&con_slot->drizzle, DRIZZLE_SET_CHARSET_DIR,
3902
 
                  opt_charsets_dir);
 
3862
                    opt_charsets_dir);
3903
3863
 
3904
3864
  /* Use default db name */
3905
 
  if (ds_database.length == 0)
3906
 
    dynstr_set(&ds_database, opt_db);
 
3865
  if (ds_database.length() == 0)
 
3866
    ds_database= opt_db;
3907
3867
 
3908
3868
  /* Special database to allow one to connect without a database name */
3909
 
  if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
3910
 
    dynstr_set(&ds_database, "");
 
3869
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
 
3870
    ds_database= "";
3911
3871
 
3912
3872
  if (connect_n_handle_errors(command, &con_slot->drizzle,
3913
 
                              ds_host.str,ds_user.str,
3914
 
                              ds_password.str, ds_database.str,
3915
 
                              con_port, ds_sock.str))
 
3873
                              ds_host.c_str(),ds_user.c_str(),
 
3874
                              ds_password.c_str(), ds_database.c_str(),
 
3875
                              con_port, ds_sock.c_str()))
3916
3876
  {
3917
 
    if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
 
3877
    if (!(con_slot->name= strdup(ds_connection_name.c_str())))
3918
3878
      die("Out of memory");
3919
3879
    cur_con= con_slot;
3920
 
   
 
3880
 
3921
3881
    if (con_slot == next_con)
3922
3882
      next_con++; /* if we used the next_con slot, advance the pointer */
3923
3883
  }
3925
3885
  /* Update $drizzle_get_server_version to that of current connection */
3926
3886
  var_set_drizzle_get_server_version(&cur_con->drizzle);
3927
3887
 
3928
 
  dynstr_free(&ds_connection_name);
3929
 
  dynstr_free(&ds_host);
3930
 
  dynstr_free(&ds_user);
3931
 
  dynstr_free(&ds_password);
3932
 
  dynstr_free(&ds_database);
3933
 
  dynstr_free(&ds_port);
3934
 
  dynstr_free(&ds_sock);
3935
 
  dynstr_free(&ds_options);
3936
3888
  return;
3937
3889
}
3938
3890
 
4080
4032
    return 0;
4081
4033
 
4082
4034
  for (i= 1; i < length &&
4083
 
   (c= my_getc(cur_file->file)) == *(delim + i);
 
4035
         (c= my_getc(cur_file->file)) == *(delim + i);
4084
4036
       i++)
4085
4037
    tmp[i]= c;
4086
4038
 
4144
4096
  found_eof:
4145
4097
      if (cur_file->file != stdin)
4146
4098
      {
4147
 
  my_fclose(cur_file->file, MYF(0));
 
4099
        my_fclose(cur_file->file, MYF(0));
4148
4100
        cur_file->file= 0;
4149
4101
      }
4150
4102
      my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
4179
4131
    case R_NORMAL:
4180
4132
      if (end_of_query(c))
4181
4133
      {
4182
 
  *p= 0;
4183
 
  return(0);
 
4134
        *p= 0;
 
4135
        return(0);
4184
4136
      }
4185
4137
      else if ((c == '{' &&
4186
4138
                (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
4190
4142
      {
4191
4143
        /* Only if and while commands can be terminated by { */
4192
4144
        *p++= c;
4193
 
  *p= 0;
4194
 
  return(0);
 
4145
        *p= 0;
 
4146
        return(0);
4195
4147
      }
4196
4148
      else if (c == '\'' || c == '"' || c == '`')
4197
4149
      {
4198
4150
        last_quote= c;
4199
 
  state= R_Q;
 
4151
        state= R_Q;
4200
4152
      }
4201
4153
      break;
4202
4154
 
4204
4156
      if (c == '\n')
4205
4157
      {
4206
4158
        /* Comments are terminated by newline */
4207
 
  *p= 0;
4208
 
  return(0);
 
4159
        *p= 0;
 
4160
        return(0);
4209
4161
      }
4210
4162
      break;
4211
4163
 
4213
4165
      if (c == '#' || c == '-')
4214
4166
      {
4215
4167
        /* A # or - in the first position of the line - this is a comment */
4216
 
  state = R_COMMENT;
 
4168
        state = R_COMMENT;
4217
4169
      }
4218
4170
      else if (my_isspace(charset_info, c))
4219
4171
      {
4220
4172
        /* Skip all space at begining of line */
4221
 
  if (c == '\n')
 
4173
        if (c == '\n')
4222
4174
        {
4223
4175
          /* Query hasn't started yet */
4224
 
    start_lineno= cur_file->lineno;
 
4176
          start_lineno= cur_file->lineno;
4225
4177
        }
4226
 
  skip_char= 1;
 
4178
        skip_char= 1;
4227
4179
      }
4228
4180
      else if (end_of_query(c))
4229
4181
      {
4230
 
  *p= 0;
4231
 
  return(0);
 
4182
        *p= 0;
 
4183
        return(0);
4232
4184
      }
4233
4185
      else if (c == '}')
4234
4186
      {
4235
4187
        /* A "}" need to be by itself in the begining of a line to terminate */
4236
4188
        *p++= c;
4237
 
  *p= 0;
4238
 
  return(0);
 
4189
        *p= 0;
 
4190
        return(0);
4239
4191
      }
4240
4192
      else if (c == '\'' || c == '"' || c == '`')
4241
4193
      {
4242
4194
        last_quote= c;
4243
 
  state= R_Q;
 
4195
        state= R_Q;
4244
4196
      }
4245
4197
      else
4246
 
  state= R_NORMAL;
 
4198
        state= R_NORMAL;
4247
4199
      break;
4248
4200
 
4249
4201
    case R_Q:
4250
4202
      if (c == last_quote)
4251
 
  state= R_NORMAL;
 
4203
        state= R_NORMAL;
4252
4204
      else if (c == '\\')
4253
 
  state= R_SLASH_IN_Q;
 
4205
        state= R_SLASH_IN_Q;
4254
4206
      break;
4255
4207
 
4256
4208
    case R_SLASH_IN_Q:
4269
4221
      /* completed before we pass buf_end */
4270
4222
      if ((charlen > 1) && (p + charlen) <= buf_end)
4271
4223
      {
4272
 
  int i;
4273
 
  char* mb_start = p;
4274
 
 
4275
 
  *p++ = c;
4276
 
 
4277
 
  for (i= 1; i < charlen; i++)
4278
 
  {
4279
 
    if (feof(cur_file->file))
4280
 
      goto found_eof;
4281
 
    c= my_getc(cur_file->file);
4282
 
    *p++ = c;
4283
 
  }
4284
 
  if (! my_ismbchar(charset_info, mb_start, p))
4285
 
  {
4286
 
    /* It was not a multiline char, push back the characters */
4287
 
    /* We leave first 'c', i.e. pretend it was a normal char */
4288
 
    while (p > mb_start)
4289
 
      my_ungetc(*--p);
4290
 
  }
 
4224
        int i;
 
4225
        char* mb_start = p;
 
4226
 
 
4227
        *p++ = c;
 
4228
 
 
4229
        for (i= 1; i < charlen; i++)
 
4230
        {
 
4231
          if (feof(cur_file->file))
 
4232
            goto found_eof;
 
4233
          c= my_getc(cur_file->file);
 
4234
          *p++ = c;
 
4235
        }
 
4236
        if (! my_ismbchar(charset_info, mb_start, p))
 
4237
        {
 
4238
          /* It was not a multiline char, push back the characters */
 
4239
          /* We leave first 'c', i.e. pretend it was a normal char */
 
4240
          while (p > mb_start)
 
4241
            my_ungetc(*--p);
 
4242
        }
4291
4243
      }
4292
4244
      else
4293
4245
#endif
4294
 
  *p++= c;
 
4246
        *p++= c;
4295
4247
    }
4296
4248
  }
4297
 
  die("The input buffer is too small for this query.x\n" \
 
4249
  die("The input buffer is too small for this query.x\n"        \
4298
4250
      "check your query or increase MAX_QUERY and recompile");
4299
4251
  return(0);
4300
4252
}
4456
4408
  Create a command from a set of lines
4457
4409
 
4458
4410
  SYNOPSIS
4459
 
    read_command()
4460
 
    command_ptr pointer where to return the new query
 
4411
  read_command()
 
4412
  command_ptr pointer where to return the new query
4461
4413
 
4462
4414
  DESCRIPTION
4463
 
    Converts lines returned by read_line into a command, this involves
4464
 
    parsing the first word in the read line to find the command type.
 
4415
  Converts lines returned by read_line into a command, this involves
 
4416
  parsing the first word in the read line to find the command type.
4465
4417
 
4466
4418
  A -- comment may contain a valid query as the first word after the
4467
4419
  comment start. Thus it's always checked to see if that is the case.
4480
4432
 
4481
4433
  if (parser.current_line < parser.read_lines)
4482
4434
  {
4483
 
    get_dynamic(&q_lines, (uchar*) command_ptr, parser.current_line) ;
 
4435
    *command_ptr= q_lines[parser.current_line];
4484
4436
    return(0);
4485
4437
  }
4486
4438
  if (!(*command_ptr= command=
4487
4439
        (struct st_command*) my_malloc(sizeof(*command),
4488
 
                                       MYF(MY_WME|MY_ZEROFILL))) ||
4489
 
      insert_dynamic(&q_lines, (uchar*) &command))
 
4440
                                       MYF(MY_WME|MY_ZEROFILL))))
4490
4441
    die(NullS);
 
4442
  q_lines.push_back(command);
4491
4443
  command->type= Q_UNKNOWN;
4492
4444
 
4493
4445
  read_command_buf[0]= 0;
4614
4566
static void print_version(void)
4615
4567
{
4616
4568
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
4617
 
   drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
 
4569
         drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
4618
4570
}
4619
4571
 
4620
4572
static void usage(void)
4621
4573
{
4622
4574
  print_version();
4623
 
  printf("DRIZZLE AB, by Sasha, Matt, Monty & Jani\n");
 
4575
  printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
4624
4576
  printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
4625
4577
  printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
4626
4578
  printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
4655
4607
    die("Failed to open file '%s'", buff);
4656
4608
 
4657
4609
  while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
4658
 
   (str=fgets(argument,sizeof(argument), file)))
 
4610
         (str=fgets(argument,sizeof(argument), file)))
4659
4611
  {
4660
4612
    *(strchr(str, '\0')-1)=0;        /* Remove end newline */
4661
4613
    if (!(embedded_server_args[embedded_server_arg_count]=
4662
 
    (char*) my_strdup(str,MYF(MY_WME))))
 
4614
          (char*) my_strdup(str,MYF(MY_WME))))
4663
4615
    {
4664
4616
      my_fclose(file,MYF(0));
4665
4617
      die("Out of memory");
4677
4629
 
4678
4630
static bool
4679
4631
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
4680
 
         char *argument)
 
4632
               char *argument)
4681
4633
{
4682
4634
  switch(optid) {
4683
4635
  case 'r':
4790
4742
  append - append to file instead of overwriting old file
4791
4743
*/
4792
4744
 
4793
 
void str_to_file2(const char *fname, char *str, int size, bool append)
 
4745
void str_to_file2(const char *fname, const char *str, int size, bool append)
4794
4746
{
4795
4747
  int fd;
4796
4748
  char buff[FN_REFLEN];
4824
4776
  size - size of content witten to file
4825
4777
*/
4826
4778
 
4827
 
void str_to_file(const char *fname, char *str, int size)
 
4779
void str_to_file(const char *fname, const char *str, int size)
4828
4780
{
4829
4781
  str_to_file2(fname, str, size, false);
4830
4782
}
4831
4783
 
4832
4784
 
4833
 
void dump_result_to_log_file(char *buf, int size)
 
4785
void dump_result_to_log_file(const char *buf, int size)
4834
4786
{
4835
4787
  char log_file[FN_REFLEN];
4836
4788
  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
4848
4800
                        opt_logdir, ".progress",
4849
4801
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4850
4802
                        MY_REPLACE_EXT),
4851
 
              ds_progress.str, ds_progress.length);
 
4803
              ds_progress.c_str(), ds_progress.length());
4852
4804
}
4853
4805
 
4854
4806
void dump_warning_messages(void)
4858
4810
  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
4859
4811
                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
4860
4812
                        MY_REPLACE_EXT),
4861
 
              ds_warning_messages.str, ds_warning_messages.length);
 
4813
              ds_warning_messages.c_str(), ds_warning_messages.length());
4862
4814
}
4863
4815
 
4864
4816
 
4866
4818
  Append the result for one field to the dynamic string ds
4867
4819
*/
4868
4820
 
4869
 
static void append_field(DYNAMIC_STRING *ds, uint col_idx, const DRIZZLE_FIELD* field,
 
4821
static void append_field(string *ds, uint col_idx, const DRIZZLE_FIELD* field,
4870
4822
                         const char* val, uint64_t len, bool is_null)
4871
4823
{
4872
4824
  if (col_idx < max_replace_column && replace_column[col_idx])
4883
4835
  if (!display_result_vertically)
4884
4836
  {
4885
4837
    if (col_idx)
4886
 
      dynstr_append_mem(ds, "\t", 1);
4887
 
    replace_dynstr_append_mem(ds, val, (int)len);
 
4838
      ds->append("\t");
 
4839
    replace_append_mem(ds, val, (int)len);
4888
4840
  }
4889
4841
  else
4890
4842
  {
4891
 
    dynstr_append(ds, field->name);
4892
 
    dynstr_append_mem(ds, "\t", 1);
4893
 
    replace_dynstr_append_mem(ds, val, (int)len);
4894
 
    dynstr_append_mem(ds, "\n", 1);
 
4843
    ds->append(field->name);
 
4844
    ds->append("\t");
 
4845
    replace_append_mem(ds, val, (int)len);
 
4846
    ds->append("\n");
4895
4847
  }
4896
4848
}
4897
4849
 
4901
4853
  Values may be converted with 'replace_column'
4902
4854
*/
4903
4855
 
4904
 
static void append_result(DYNAMIC_STRING *ds, DRIZZLE_RES *res)
 
4856
static void append_result(string *ds, DRIZZLE_RES *res)
4905
4857
{
4906
4858
  DRIZZLE_ROW row;
4907
4859
  uint32_t num_fields= drizzle_num_fields(res);
4916
4868
      append_field(ds, i, &fields[i],
4917
4869
                   (const char*)row[i], lengths[i], !row[i]);
4918
4870
    if (!display_result_vertically)
4919
 
      dynstr_append_mem(ds, "\n", 1);
 
4871
      ds->append("\n");
 
4872
 
4920
4873
  }
4921
4874
}
4922
4875
 
4925
4878
  Append metadata for fields to output
4926
4879
*/
4927
4880
 
4928
 
static void append_metadata(DYNAMIC_STRING *ds,
 
4881
static void append_metadata(string *ds,
4929
4882
                            const DRIZZLE_FIELD *field,
4930
4883
                            uint num_fields)
4931
4884
{
4932
4885
  const DRIZZLE_FIELD *field_end;
4933
 
  dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
4934
 
                "Column_alias\tType\tLength\tMax length\tIs_null\t"
4935
 
                "Flags\tDecimals\tCharsetnr\n");
 
4886
  ds->append("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
 
4887
             "Column_alias\tType\tLength\tMax length\tIs_null\t"
 
4888
             "Flags\tDecimals\tCharsetnr\n");
4936
4889
 
4937
4890
  for (field_end= field+num_fields ;
4938
4891
       field < field_end ;
4939
4892
       field++)
4940
4893
  {
4941
 
    dynstr_append_mem(ds, field->catalog,
4942
 
                      field->catalog_length);
4943
 
    dynstr_append_mem(ds, "\t", 1);
4944
 
    dynstr_append_mem(ds, field->db, field->db_length);
4945
 
    dynstr_append_mem(ds, "\t", 1);
4946
 
    dynstr_append_mem(ds, field->org_table,
4947
 
                      field->org_table_length);
4948
 
    dynstr_append_mem(ds, "\t", 1);
4949
 
    dynstr_append_mem(ds, field->table,
4950
 
                      field->table_length);
4951
 
    dynstr_append_mem(ds, "\t", 1);
4952
 
    dynstr_append_mem(ds, field->org_name,
4953
 
                      field->org_name_length);
4954
 
    dynstr_append_mem(ds, "\t", 1);
4955
 
    dynstr_append_mem(ds, field->name, field->name_length);
4956
 
    dynstr_append_mem(ds, "\t", 1);
4957
 
    replace_dynstr_append_uint(ds, field->type);
4958
 
    dynstr_append_mem(ds, "\t", 1);
4959
 
    replace_dynstr_append_uint(ds, field->length);
4960
 
    dynstr_append_mem(ds, "\t", 1);
4961
 
    replace_dynstr_append_uint(ds, field->max_length);
4962
 
    dynstr_append_mem(ds, "\t", 1);
4963
 
    dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
4964
 
                                   "N" : "Y"), 1);
4965
 
    dynstr_append_mem(ds, "\t", 1);
4966
 
    replace_dynstr_append_uint(ds, field->flags);
4967
 
    dynstr_append_mem(ds, "\t", 1);
4968
 
    replace_dynstr_append_uint(ds, field->decimals);
4969
 
    dynstr_append_mem(ds, "\t", 1);
4970
 
    replace_dynstr_append_uint(ds, field->charsetnr);
4971
 
    dynstr_append_mem(ds, "\n", 1);
 
4894
    ds->append(field->catalog,
 
4895
               field->catalog_length);
 
4896
    ds->append("\t", 1);
 
4897
    ds->append(field->db, field->db_length);
 
4898
    ds->append("\t", 1);
 
4899
    ds->append(field->org_table,
 
4900
               field->org_table_length);
 
4901
    ds->append("\t", 1);
 
4902
    ds->append(field->table,
 
4903
               field->table_length);
 
4904
    ds->append("\t", 1);
 
4905
    ds->append(field->org_name,
 
4906
               field->org_name_length);
 
4907
    ds->append("\t", 1);
 
4908
    ds->append(field->name, field->name_length);
 
4909
    ds->append("\t", 1);
 
4910
    replace_append_uint(ds, field->type);
 
4911
    ds->append("\t", 1);
 
4912
    replace_append_uint(ds, field->length);
 
4913
    ds->append("\t", 1);
 
4914
    replace_append_uint(ds, field->max_length);
 
4915
    ds->append("\t", 1);
 
4916
    ds->append((char*) (IS_NOT_NULL(field->flags) ?
 
4917
                        "N" : "Y"), 1);
 
4918
    ds->append("\t", 1);
 
4919
    replace_append_uint(ds, field->flags);
 
4920
    ds->append("\t", 1);
 
4921
    replace_append_uint(ds, field->decimals);
 
4922
    ds->append("\t", 1);
 
4923
    replace_append_uint(ds, field->charsetnr);
 
4924
    ds->append("\n", 1);
4972
4925
  }
4973
4926
}
4974
4927
 
4977
4930
  Append affected row count and other info to output
4978
4931
*/
4979
4932
 
4980
 
static void append_info(DYNAMIC_STRING *ds, uint64_t affected_rows,
 
4933
static void append_info(string *ds, uint64_t affected_rows,
4981
4934
                        const char *info)
4982
4935
{
4983
4936
  char buf[40], buff2[21];
4984
4937
  sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
4985
 
  dynstr_append(ds, buf);
 
4938
  ds->append(buf);
4986
4939
  if (info)
4987
4940
  {
4988
 
    dynstr_append(ds, "info: ");
4989
 
    dynstr_append(ds, info);
4990
 
    dynstr_append_mem(ds, "\n", 1);
 
4941
    ds->append("info: ");
 
4942
    ds->append(info);
 
4943
    ds->append("\n", 1);
4991
4944
  }
4992
4945
}
4993
4946
 
4996
4949
  Display the table headings with the names tab separated
4997
4950
*/
4998
4951
 
4999
 
static void append_table_headings(DYNAMIC_STRING *ds,
 
4952
static void append_table_headings(string *ds,
5000
4953
                                  const DRIZZLE_FIELD *field,
5001
4954
                                  uint num_fields)
5002
4955
{
5004
4957
  for (col_idx= 0; col_idx < num_fields; col_idx++)
5005
4958
  {
5006
4959
    if (col_idx)
5007
 
      dynstr_append_mem(ds, "\t", 1);
5008
 
    replace_dynstr_append(ds, field[col_idx].name);
 
4960
      ds->append("\t", 1);
 
4961
    replace_append(ds, field[col_idx].name);
5009
4962
  }
5010
 
  dynstr_append_mem(ds, "\n", 1);
 
4963
  ds->append("\n", 1);
5011
4964
}
5012
4965
 
5013
4966
/*
5017
4970
  Number of warnings appended to ds
5018
4971
*/
5019
4972
 
5020
 
static int append_warnings(DYNAMIC_STRING *ds, DRIZZLE *drizzle)
 
4973
static int append_warnings(string *ds, DRIZZLE *drizzle)
5021
4974
{
5022
4975
  uint count;
5023
4976
  DRIZZLE_RES *warn_res;
5038
4991
 
5039
4992
  if (!(warn_res= drizzle_store_result(drizzle)))
5040
4993
    die("Warning count is %u but didn't get any warnings",
5041
 
  count);
 
4994
        count);
5042
4995
 
5043
4996
  append_result(ds, warn_res);
5044
 
  drizzle_free_result(warn_res);
5045
4997
 
5046
4998
  return(count);
5047
4999
}
5051
5003
  Run query using DRIZZLE C API
5052
5004
 
5053
5005
  SYNOPSIS
5054
 
    run_query_normal()
5055
 
    drizzle  DRIZZLE handle
5056
 
    command  current command pointer
5057
 
    flags  flags indicating if we should SEND and/or REAP
5058
 
    query  query string to execute
5059
 
    query_len  length query string to execute
5060
 
    ds    output buffer where to store result form query
 
5006
  run_query_normal()
 
5007
  drizzle  DRIZZLE handle
 
5008
  command  current command pointer
 
5009
  flags  flags indicating if we should SEND and/or REAP
 
5010
  query  query string to execute
 
5011
  query_len  length query string to execute
 
5012
  ds    output buffer where to store result form query
5061
5013
*/
5062
5014
 
5063
5015
static void run_query_normal(struct st_connection *cn,
5064
5016
                             struct st_command *command,
5065
5017
                             int flags, char *query, int query_len,
5066
 
                             DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
 
5018
                             string *ds, string *ds_warnings)
5067
5019
{
5068
5020
  DRIZZLE_RES *res= 0;
5069
5021
  DRIZZLE *drizzle= &cn->drizzle;
5072
5024
  if (flags & QUERY_SEND_FLAG)
5073
5025
  {
5074
5026
    /*
5075
 
      Send the query
5076
 
    */
 
5027
     * Send the query
 
5028
     */
5077
5029
    if (do_send_query(cn, query, query_len, flags))
5078
5030
    {
5079
5031
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5080
 
       drizzle_sqlstate(drizzle), ds);
 
5032
                   drizzle_sqlstate(drizzle), ds);
5081
5033
      goto end;
5082
5034
    }
5083
5035
  }
5084
 
#ifdef EMBEDDED_LIBRARY
5085
 
  /*
5086
 
    Here we handle 'reap' command, so we need to check if the
5087
 
    query's thread was finished and probably wait
5088
 
  */
5089
 
  else if (flags & QUERY_REAP_FLAG)
5090
 
    wait_query_thread_end(cn);
5091
 
#endif /*EMBEDDED_LIBRARY*/
5092
5036
  if (!(flags & QUERY_REAP_FLAG))
5093
5037
    return;
5094
5038
 
5101
5045
    if ((counter==0) && drizzle_read_query_result(drizzle))
5102
5046
    {
5103
5047
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5104
 
       drizzle_sqlstate(drizzle), ds);
 
5048
                   drizzle_sqlstate(drizzle), ds);
5105
5049
      goto end;
5106
5050
 
5107
5051
    }
5112
5056
    if (drizzle_field_count(drizzle) && ((res= drizzle_store_result(drizzle)) == 0))
5113
5057
    {
5114
5058
      handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5115
 
       drizzle_sqlstate(drizzle), ds);
 
5059
                   drizzle_sqlstate(drizzle), ds);
5116
5060
      goto end;
5117
5061
    }
5118
5062
 
5148
5092
      */
5149
5093
      if (!disable_warnings && !drizzle_more_results(drizzle))
5150
5094
      {
5151
 
  if (append_warnings(ds_warnings, drizzle) || ds_warnings->length)
5152
 
  {
5153
 
    dynstr_append_mem(ds, "Warnings:\n", 10);
5154
 
    dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
5155
 
  }
 
5095
        if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
 
5096
        {
 
5097
          ds->append("Warnings:\n", 10);
 
5098
          ds->append(ds_warnings->c_str(), ds_warnings->length());
 
5099
        }
5156
5100
      }
5157
5101
 
5158
5102
      if (!disable_info)
5159
 
  append_info(ds, affected_rows, drizzle_info(drizzle));
 
5103
        append_info(ds, affected_rows, drizzle_info(drizzle));
5160
5104
    }
5161
5105
 
5162
5106
    if (res)
5170
5114
  {
5171
5115
    /* We got an error from drizzle_next_result, maybe expected */
5172
5116
    handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5173
 
     drizzle_sqlstate(drizzle), ds);
 
5117
                 drizzle_sqlstate(drizzle), ds);
5174
5118
    goto end;
5175
5119
  }
5176
5120
  assert(err == -1); /* Successful and there are no more results */
5202
5146
  ds    - dynamic string which is used for output buffer
5203
5147
 
5204
5148
  NOTE
5205
 
    If there is an unexpected error this function will abort drizzletest
5206
 
    immediately.
 
5149
  If there is an unexpected error this function will abort drizzletest
 
5150
  immediately.
5207
5151
*/
5208
5152
 
5209
5153
void handle_error(struct st_command *command,
5210
5154
                  unsigned int err_errno, const char *err_error,
5211
 
                  const char *err_sqlstate, DYNAMIC_STRING *ds)
 
5155
                  const char *err_sqlstate, string *ds)
5212
5156
{
5213
5157
  uint i;
5214
5158
 
5215
5159
 
5216
 
 
5217
5160
  if (command->require_file[0])
5218
5161
  {
5219
5162
    /*
5247
5190
        if (command->expected_errors.count == 1)
5248
5191
        {
5249
5192
          /* Only log error if there is one possible error */
5250
 
          dynstr_append_mem(ds, "ERROR ", 6);
5251
 
          replace_dynstr_append(ds, err_sqlstate);
5252
 
          dynstr_append_mem(ds, ": ", 2);
5253
 
          replace_dynstr_append(ds, err_error);
5254
 
          dynstr_append_mem(ds,"\n",1);
 
5193
          ds->append("ERROR ", 6);
 
5194
          replace_append(ds, err_sqlstate);
 
5195
          ds->append(": ", 2);
 
5196
          replace_append(ds, err_error);
 
5197
          ds->append("\n",1);
5255
5198
        }
5256
5199
        /* Don't log error if we may not get an error */
5257
5200
        else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
5258
5201
                 (command->expected_errors.err[0].type == ERR_ERRNO &&
5259
5202
                  command->expected_errors.err[0].code.errnum != 0))
5260
 
          dynstr_append(ds,"Got one of the listed errors\n");
 
5203
          ds->append("Got one of the listed errors\n");
5261
5204
      }
5262
5205
      /* OK */
5263
5206
      return;
5266
5209
 
5267
5210
  if (!disable_result_log)
5268
5211
  {
5269
 
    dynstr_append_mem(ds, "ERROR ",6);
5270
 
    replace_dynstr_append(ds, err_sqlstate);
5271
 
    dynstr_append_mem(ds, ": ", 2);
5272
 
    replace_dynstr_append(ds, err_error);
5273
 
    dynstr_append_mem(ds, "\n", 1);
 
5212
    ds->append("ERROR ",6);
 
5213
    replace_append(ds, err_sqlstate);
 
5214
    ds->append(": ", 2);
 
5215
    replace_append(ds, err_error);
 
5216
    ds->append("\n", 1);
5274
5217
  }
5275
5218
 
5276
5219
  if (i)
5282
5225
    else
5283
5226
      die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...",
5284
5227
          command->query, err_sqlstate, err_error,
5285
 
    command->expected_errors.err[0].code.sqlstate);
 
5228
          command->expected_errors.err[0].code.sqlstate);
5286
5229
  }
5287
5230
 
5288
5231
  return;
5327
5270
  Run query
5328
5271
 
5329
5272
  SYNPOSIS
5330
 
    run_query()
5331
 
     drizzle  DRIZZLE handle
5332
 
     command  currrent command pointer
 
5273
  run_query()
 
5274
  drizzle  DRIZZLE handle
 
5275
  command  currrent command pointer
5333
5276
 
5334
5277
  flags control the phased/stages of query execution to be performed
5335
5278
  if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
5340
5283
                      struct st_command *command,
5341
5284
                      int flags)
5342
5285
{
5343
 
  DYNAMIC_STRING *ds;
5344
 
  DYNAMIC_STRING *save_ds= NULL;
5345
 
  DYNAMIC_STRING ds_result;
5346
 
  DYNAMIC_STRING ds_sorted;
5347
 
  DYNAMIC_STRING ds_warnings;
5348
 
  DYNAMIC_STRING eval_query;
 
5286
  string *ds= NULL;
 
5287
  string *save_ds= NULL;
 
5288
  string ds_result;
 
5289
  string ds_sorted;
 
5290
  string ds_warnings;
 
5291
  string eval_query;
5349
5292
  char *query;
5350
5293
  int query_len;
5351
5294
 
5352
5295
 
5353
 
  init_dynamic_string(&ds_warnings, NULL, 0, 256);
5354
 
 
5355
5296
  /* Scan for warning before sending to server */
5356
5297
  scan_command_for_warnings(command);
5357
5298
 
5360
5301
  */
5361
5302
  if (command->type == Q_EVAL)
5362
5303
  {
5363
 
    init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
5364
5304
    do_eval(&eval_query, command->query, command->end, false);
5365
 
    query = eval_query.str;
5366
 
    query_len = eval_query.length;
 
5305
    query = strdup(eval_query.c_str());
 
5306
    query_len = eval_query.length();
5367
5307
  }
5368
5308
  else
5369
5309
  {
5379
5319
  */
5380
5320
  if (command->require_file[0])
5381
5321
  {
5382
 
    init_dynamic_string(&ds_result, "", 1024, 1024);
5383
5322
    ds= &ds_result;
5384
5323
  }
5385
5324
  else
 
5325
  {
5386
5326
    ds= &ds_res;
5387
 
 
 
5327
  }
5388
5328
  /*
5389
5329
    Log the query into the output buffer
5390
5330
  */
5391
5331
  if (!disable_query_log && (flags & QUERY_SEND_FLAG))
5392
5332
  {
5393
 
    replace_dynstr_append_mem(ds, query, query_len);
5394
 
    dynstr_append_mem(ds, delimiter, delimiter_length);
5395
 
    dynstr_append_mem(ds, "\n", 1);
 
5333
    replace_append_mem(ds, query, query_len);
 
5334
    ds->append(delimiter, delimiter_length);
 
5335
    ds->append("\n");
5396
5336
  }
5397
5337
 
5398
5338
  if (display_result_sorted)
5399
5339
  {
5400
5340
    /*
5401
 
       Collect the query output in a separate string
5402
 
       that can be sorted before it's added to the
5403
 
       global result string
 
5341
      Collect the query output in a separate string
 
5342
      that can be sorted before it's added to the
 
5343
      global result string
5404
5344
    */
5405
 
    init_dynamic_string(&ds_sorted, "", 1024, 1024);
5406
5345
    save_ds= ds; /* Remember original ds */
5407
5346
    ds= &ds_sorted;
5408
5347
  }
5417
5356
  if (display_result_sorted)
5418
5357
  {
5419
5358
    /* Sort the result set and append it to result */
5420
 
    dynstr_append_sorted(save_ds, &ds_sorted);
 
5359
    append_sorted(save_ds, &ds_sorted);
5421
5360
    ds= save_ds;
5422
 
    dynstr_free(&ds_sorted);
5423
5361
  }
5424
5362
 
5425
5363
  if (command->require_file[0])
5431
5369
    check_require(ds, command->require_file);
5432
5370
  }
5433
5371
 
5434
 
  dynstr_free(&ds_warnings);
5435
 
  if (ds == &ds_result)
5436
 
    dynstr_free(&ds_result);
5437
 
  if (command->type == Q_EVAL)
5438
 
    dynstr_free(&eval_query);
5439
5372
  return;
5440
5373
}
5441
5374
 
5485
5418
    {
5486
5419
      /* -- comment that didn't contain a drizzletest command */
5487
5420
      command->type= Q_COMMENT;
5488
 
      warning_msg("Suspicious command '--%s' detected, was this intentional? "\
 
5421
      warning_msg("Suspicious command '--%s' detected, was this intentional? " \
5489
5422
                  "Use # instead of -- to avoid this warning",
5490
5423
                  command->query);
5491
5424
 
5539
5472
 
5540
5473
  /* Milliseconds since start */
5541
5474
  end= int64_t2str(timer, buf, 10);
5542
 
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
5543
 
  dynstr_append_mem(&ds_progress, "\t", 1);
 
5475
  ds_progress.append(buf, (int)(end-buf));
 
5476
  ds_progress.append("\t", 1);
5544
5477
 
5545
5478
  /* Parser line number */
5546
5479
  end= int10_to_str(line, buf, 10);
5547
 
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
5548
 
  dynstr_append_mem(&ds_progress, "\t", 1);
 
5480
  ds_progress.append(buf, (int)(end-buf));
 
5481
  ds_progress.append("\t", 1);
5549
5482
 
5550
5483
  /* Filename */
5551
 
  dynstr_append(&ds_progress, cur_file->file_name);
5552
 
  dynstr_append_mem(&ds_progress, ":", 1);
 
5484
  ds_progress.append(cur_file->file_name);
 
5485
  ds_progress.append(":", 1);
5553
5486
 
5554
5487
  /* Line in file */
5555
5488
  end= int10_to_str(cur_file->lineno, buf, 10);
5556
 
  dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
5557
 
 
5558
 
 
5559
 
  dynstr_append_mem(&ds_progress, "\n", 1);
 
5489
  ds_progress.append(buf, (int)(end-buf));
 
5490
 
 
5491
 
 
5492
  ds_progress.append("\n", 1);
5560
5493
 
5561
5494
}
5562
5495
 
5582
5515
    (sizeof(connections)/sizeof(struct st_connection)) - 1;
5583
5516
  next_con= connections + 1;
5584
5517
 
5585
 
#ifdef EMBEDDED_LIBRARY
5586
 
  /* set appropriate stack for the 'query' threads */
5587
 
  (void) pthread_attr_init(&cn_thd_attrib);
5588
 
  pthread_attr_setstacksize(&cn_thd_attrib, DEFAULT_THREAD_STACK);
5589
 
#endif /*EMBEDDED_LIBRARY*/
5590
 
 
5591
5518
  /* Init file stack */
5592
5519
  memset(file_stack, 0, sizeof(file_stack));
5593
5520
  file_stack_end=
5602
5529
  cur_block->ok= true; /* Outer block should always be executed */
5603
5530
  cur_block->cmd= cmd_none;
5604
5531
 
5605
 
  my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
5606
 
 
5607
5532
  if (hash_init(&var_hash, charset_info,
5608
5533
                1024, 0, 0, get_var_key, var_free, MYF(0)))
5609
5534
    die("Variable hash initialization failed");
5617
5542
 
5618
5543
  init_builtin_echo();
5619
5544
 
5620
 
  init_dynamic_string(&ds_res, "", 65536, 65536);
5621
 
  init_dynamic_string(&ds_progress, "", 0, 2048);
5622
 
  init_dynamic_string(&ds_warning_messages, "", 0, 2048);
 
5545
  ds_res.reserve(65536);
 
5546
  ds_progress.reserve(2048);
 
5547
  ds_warning_messages.reserve(2048);
 
5548
 
5623
5549
  parse_args(argc, argv);
5624
5550
 
5625
5551
  server_initialized= 1;
5636
5562
    drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NullS);
5637
5563
  drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
5638
5564
  drizzle_options(&cur_con->drizzle, DRIZZLE_SET_CHARSET_NAME,
5639
 
                charset_info->csname);
 
5565
                  charset_info->csname);
5640
5566
  int opt_protocol= DRIZZLE_PROTOCOL_TCP;
5641
5567
  drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
5642
5568
  if (opt_charsets_dir)
5643
5569
    drizzle_options(&cur_con->drizzle, DRIZZLE_SET_CHARSET_DIR,
5644
 
                  opt_charsets_dir);
 
5570
                    opt_charsets_dir);
5645
5571
 
5646
5572
  if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
5647
5573
    die("Out of memory");
5689
5615
      case Q_CONNECT:
5690
5616
        do_connect(command);
5691
5617
        break;
5692
 
      case Q_CONNECTION: select_connection(command); break;
 
5618
      case Q_CONNECTION:
 
5619
        select_connection(command);
 
5620
        break;
5693
5621
      case Q_DISCONNECT:
5694
5622
      case Q_DIRTY_CLOSE:
5695
 
  do_close_connection(command); break;
 
5623
        do_close_connection(command); break;
5696
5624
      case Q_ENABLE_QUERY_LOG:   disable_query_log=0; break;
5697
5625
      case Q_DISABLE_QUERY_LOG:  disable_query_log=1; break;
5698
5626
      case Q_ENABLE_ABORT_ON_ERROR:  abort_on_error=1; break;
5728
5656
      case Q_PERL: do_perl(command); break;
5729
5657
      case Q_DELIMITER:
5730
5658
        do_delimiter(command);
5731
 
  break;
 
5659
        break;
5732
5660
      case Q_DISPLAY_VERTICAL_RESULTS:
5733
5661
        display_result_vertically= true;
5734
5662
        break;
5735
5663
      case Q_DISPLAY_HORIZONTAL_RESULTS:
5736
 
  display_result_vertically= false;
 
5664
        display_result_vertically= false;
5737
5665
        break;
5738
5666
      case Q_SORTED_RESULT:
5739
5667
        /*
5740
5668
          Turn on sorting of result set, will be reset after next
5741
5669
          command
5742
5670
        */
5743
 
  display_result_sorted= true;
 
5671
        display_result_sorted= true;
5744
5672
        break;
5745
5673
      case Q_LET: do_let(command); break;
5746
5674
      case Q_EVAL_RESULT:
5748
5676
      case Q_EVAL:
5749
5677
      case Q_QUERY_VERTICAL:
5750
5678
      case Q_QUERY_HORIZONTAL:
5751
 
  if (command->query == command->query_buf)
 
5679
        if (command->query == command->query_buf)
5752
5680
        {
5753
5681
          /* Skip the first part of command, i.e query_xxx */
5754
 
    command->query= command->first_argument;
 
5682
          command->query= command->first_argument;
5755
5683
          command->first_word_len= 0;
5756
5684
        }
5757
 
  /* fall through */
 
5685
        /* fall through */
5758
5686
      case Q_QUERY:
5759
5687
      case Q_REAP:
5760
5688
      {
5761
 
  bool old_display_result_vertically= display_result_vertically;
 
5689
        bool old_display_result_vertically= display_result_vertically;
5762
5690
        /* Default is full query, both reap and send  */
5763
5691
        int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
5764
5692
 
5776
5704
        /* Check for special property for this query */
5777
5705
        display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5778
5706
 
5779
 
  if (save_file[0])
5780
 
  {
5781
 
    strmake(command->require_file, save_file, sizeof(save_file) - 1);
5782
 
    save_file[0]= 0;
5783
 
  }
5784
 
  run_query(cur_con, command, flags);
5785
 
  command_executed++;
 
5707
        if (save_file[0])
 
5708
        {
 
5709
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
 
5710
          save_file[0]= 0;
 
5711
        }
 
5712
        run_query(cur_con, command, flags);
 
5713
        command_executed++;
5786
5714
        command->last_argument= command->end;
5787
5715
 
5788
5716
        /* Restore settings */
5789
 
  display_result_vertically= old_display_result_vertically;
 
5717
        display_result_vertically= old_display_result_vertically;
5790
5718
 
5791
 
  break;
 
5719
        break;
5792
5720
      }
5793
5721
      case Q_SEND:
5794
5722
        if (!*command->first_argument)
5802
5730
        }
5803
5731
 
5804
5732
        /* Remove "send" if this is first iteration */
5805
 
  if (command->query == command->query_buf)
5806
 
    command->query= command->first_argument;
 
5733
        if (command->query == command->query_buf)
 
5734
          command->query= command->first_argument;
5807
5735
 
5808
 
  /*
5809
 
    run_query() can execute a query partially, depending on the flags.
5810
 
    QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
 
5736
        /*
 
5737
          run_query() can execute a query partially, depending on the flags.
 
5738
          QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
5811
5739
          the query and read the result some time later when reap instruction
5812
 
    is given on this connection.
 
5740
          is given on this connection.
5813
5741
        */
5814
 
  run_query(cur_con, command, QUERY_SEND_FLAG);
5815
 
  command_executed++;
 
5742
        run_query(cur_con, command, QUERY_SEND_FLAG);
 
5743
        command_executed++;
5816
5744
        command->last_argument= command->end;
5817
 
  break;
 
5745
        break;
5818
5746
      case Q_REQUIRE:
5819
 
  do_get_file_name(command, save_file, sizeof(save_file));
5820
 
  break;
 
5747
        do_get_file_name(command, save_file, sizeof(save_file));
 
5748
        break;
5821
5749
      case Q_ERROR:
5822
5750
        do_get_errcodes(command);
5823
 
  break;
 
5751
        break;
5824
5752
      case Q_REPLACE:
5825
 
  do_get_replace(command);
5826
 
  break;
 
5753
        do_get_replace(command);
 
5754
        break;
5827
5755
      case Q_REPLACE_REGEX:
5828
5756
        do_get_replace_regex(command);
5829
5757
        break;
5830
5758
      case Q_REPLACE_COLUMN:
5831
 
  do_get_replace_column(command);
5832
 
  break;
 
5759
        do_get_replace_column(command);
 
5760
        break;
5833
5761
      case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
5834
5762
      case Q_SYNC_WITH_MASTER: do_sync_with_master(command); break;
5835
5763
      case Q_SYNC_SLAVE_WITH_MASTER:
5836
5764
      {
5837
 
  do_save_master_pos();
5838
 
  if (*command->first_argument)
5839
 
    select_connection(command);
5840
 
  else
5841
 
    select_connection_name("slave");
5842
 
  do_sync_with_master2(0);
5843
 
  break;
 
5765
        do_save_master_pos();
 
5766
        if (*command->first_argument)
 
5767
          select_connection(command);
 
5768
        else
 
5769
          select_connection_name("slave");
 
5770
        do_sync_with_master2(0);
 
5771
        break;
5844
5772
      }
5845
5773
      case Q_COMMENT:        /* Ignore row */
5846
5774
        command->last_argument= command->end;
5847
 
  break;
 
5775
        break;
5848
5776
      case Q_PING:
5849
 
  (void) drizzle_ping(&cur_con->drizzle);
5850
 
  break;
 
5777
        (void) drizzle_ping(&cur_con->drizzle);
 
5778
        break;
5851
5779
      case Q_EXEC:
5852
 
  do_exec(command);
5853
 
  command_executed++;
5854
 
  break;
 
5780
        do_exec(command);
 
5781
        command_executed++;
 
5782
        break;
5855
5783
      case Q_START_TIMER:
5856
 
  /* Overwrite possible earlier start of timer */
5857
 
  timer_start= timer_now();
5858
 
  break;
 
5784
        /* Overwrite possible earlier start of timer */
 
5785
        timer_start= timer_now();
 
5786
        break;
5859
5787
      case Q_END_TIMER:
5860
 
  /* End timer before ending drizzletest */
5861
 
  timer_output();
5862
 
  break;
 
5788
        /* End timer before ending drizzletest */
 
5789
        timer_output();
 
5790
        break;
5863
5791
      case Q_CHARACTER_SET:
5864
 
  do_set_charset(command);
5865
 
  break;
 
5792
        do_set_charset(command);
 
5793
        break;
5866
5794
      case Q_DISABLE_RECONNECT:
5867
5795
        set_reconnect(&cur_con->drizzle, 0);
5868
5796
        break;
5958
5886
    Time to compare result or save it to record file.
5959
5887
    The entire output from test is now kept in ds_res.
5960
5888
  */
5961
 
  if (ds_res.length)
 
5889
  if (ds_res.length())
5962
5890
  {
5963
5891
    if (result_file_name)
5964
5892
    {
5966
5894
 
5967
5895
      if (record)
5968
5896
      {
5969
 
  /* Recording - dump the output from test to result file */
5970
 
  str_to_file(result_file_name, ds_res.str, ds_res.length);
 
5897
        /* Recording - dump the output from test to result file */
 
5898
        str_to_file(result_file_name, ds_res.c_str(), ds_res.length());
5971
5899
      }
5972
5900
      else
5973
5901
      {
5974
 
  /* Check that the output from test is equal to result file
5975
 
     - detect missing result file
5976
 
     - detect zero size result file
 
5902
        /* Check that the output from test is equal to result file
 
5903
           - detect missing result file
 
5904
           - detect zero size result file
5977
5905
        */
5978
 
  check_result(&ds_res);
 
5906
        check_result(&ds_res);
5979
5907
      }
5980
5908
    }
5981
5909
    else
5982
5910
    {
5983
5911
      /* No result_file_name specified to compare with, print to stdout */
5984
 
      printf("%s", ds_res.str);
 
5912
      printf("%s", ds_res.c_str());
5985
5913
    }
5986
5914
  }
5987
5915
  else
6006
5934
    dump_progress();
6007
5935
 
6008
5936
  /* Dump warning messages */
6009
 
  if (result_file_name && ds_warning_messages.length)
 
5937
  if (result_file_name && ds_warning_messages.length())
6010
5938
    dump_warning_messages();
6011
5939
 
6012
5940
  timer_output();
6128
6056
 
6129
6057
struct st_replace;
6130
6058
struct st_replace *init_replace(char * *from, char * *to, uint count,
6131
 
        char * word_end_chars);
 
6059
                                char * word_end_chars);
6132
6060
int insert_pointer_name(POINTER_ARRAY *pa,char * name);
6133
 
void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
 
6061
void replace_strings_append(struct st_replace *rep, string* ds,
6134
6062
                            const char *from, int len);
6135
6063
void free_pointer_array(POINTER_ARRAY *pa);
6136
6064
 
6176
6104
      *pos++= i;
6177
6105
  *pos=0;          /* End pointer */
6178
6106
  if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
6179
 
          (char**) to_array.typelib.type_names,
6180
 
          (uint) from_array.typelib.count,
6181
 
          word_end_chars)))
 
6107
                                   (char**) to_array.typelib.type_names,
 
6108
                                   (uint) from_array.typelib.count,
 
6109
                                   word_end_chars)))
6182
6110
    die("Can't initialize replace from '%s'", command->query);
6183
6111
  free_pointer_array(&from_array);
6184
6112
  free_pointer_array(&to_array);
6213
6141
} REPLACE_STRING;
6214
6142
 
6215
6143
 
6216
 
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
6217
 
                            const char *str,
6218
 
                            int len __attribute__((unused)))
 
6144
void replace_strings_append(REPLACE *rep, string* ds,
 
6145
                            const char *str, int len)
6219
6146
{
6220
6147
  register REPLACE *rep_pos;
6221
6148
  register REPLACE_STRING *rep_str;
6234
6161
    if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6235
6162
    {
6236
6163
      /* No match found */
6237
 
      dynstr_append_mem(ds, start, from - start - 1);
 
6164
      ds->append(start, from - start - 1);
6238
6165
      return;
6239
6166
    }
6240
6167
 
6241
6168
    /* Append part of original string before replace string */
6242
 
    dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
 
6169
    ds->append(start, (from - rep_str->to_offset) - start);
6243
6170
 
6244
6171
    /* Append replace string */
6245
 
    dynstr_append_mem(ds, rep_str->replace_string,
6246
 
                      strlen(rep_str->replace_string));
 
6172
    ds->append(rep_str->replace_string,
 
6173
               strlen(rep_str->replace_string));
6247
6174
 
6248
6175
    if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6249
6176
      return;
6630
6557
/* Init a replace structure for further calls */
6631
6558
 
6632
6559
REPLACE *init_replace(char * *from, char * *to,uint count,
6633
 
          char * word_end_chars)
 
6560
                      char * word_end_chars)
6634
6561
{
6635
6562
  static const int SPACE_CHAR= 256;
6636
6563
  static const int START_OF_LINE= 257;
6670
6597
    return(0);
6671
6598
  found_sets=0;
6672
6599
  if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count,
6673
 
            MYF(MY_WME))))
 
6600
                                          MYF(MY_WME))))
6674
6601
  {
6675
6602
    free_sets(&sets);
6676
6603
    return(0);
6695
6622
      internal_set_bit(start_states,states+1);
6696
6623
      if (!from[i][2])
6697
6624
      {
6698
 
  start_states->table_offset=i;
6699
 
  start_states->found_offset=1;
 
6625
        start_states->table_offset=i;
 
6626
        start_states->found_offset=1;
6700
6627
      }
6701
6628
    }
6702
6629
    else if (from[i][0] == '\\' && from[i][1] == '$')
6705
6632
      internal_set_bit(word_states,states);
6706
6633
      if (!from[i][2] && start_states->table_offset == UINT32_MAX)
6707
6634
      {
6708
 
  start_states->table_offset=i;
6709
 
  start_states->found_offset=0;
 
6635
        start_states->table_offset=i;
 
6636
        start_states->found_offset=0;
6710
6637
      }
6711
6638
    }
6712
6639
    else
6713
6640
    {
6714
6641
      internal_set_bit(word_states,states);
6715
6642
      if (from[i][0] == '\\' && (from[i][1] == 'b' && from[i][2]))
6716
 
  internal_set_bit(start_states,states+1);
 
6643
        internal_set_bit(start_states,states+1);
6717
6644
      else
6718
 
  internal_set_bit(start_states,states);
 
6645
        internal_set_bit(start_states,states);
6719
6646
    }
6720
6647
    for (pos=from[i], len=0; *pos ; pos++)
6721
6648
    {
6722
6649
      if (*pos == '\\' && *(pos+1))
6723
6650
      {
6724
 
  pos++;
6725
 
  switch (*pos) {
6726
 
  case 'b':
6727
 
    follow_ptr->chr = SPACE_CHAR;
6728
 
    break;
6729
 
  case '^':
6730
 
    follow_ptr->chr = START_OF_LINE;
6731
 
    break;
6732
 
  case '$':
6733
 
    follow_ptr->chr = END_OF_LINE;
6734
 
    break;
6735
 
  case 'r':
6736
 
    follow_ptr->chr = '\r';
6737
 
    break;
6738
 
  case 't':
6739
 
    follow_ptr->chr = '\t';
6740
 
    break;
6741
 
  case 'v':
6742
 
    follow_ptr->chr = '\v';
6743
 
    break;
6744
 
  default:
6745
 
    follow_ptr->chr = (uchar) *pos;
6746
 
    break;
6747
 
  }
 
6651
        pos++;
 
6652
        switch (*pos) {
 
6653
        case 'b':
 
6654
          follow_ptr->chr = SPACE_CHAR;
 
6655
          break;
 
6656
        case '^':
 
6657
          follow_ptr->chr = START_OF_LINE;
 
6658
          break;
 
6659
        case '$':
 
6660
          follow_ptr->chr = END_OF_LINE;
 
6661
          break;
 
6662
        case 'r':
 
6663
          follow_ptr->chr = '\r';
 
6664
          break;
 
6665
        case 't':
 
6666
          follow_ptr->chr = '\t';
 
6667
          break;
 
6668
        case 'v':
 
6669
          follow_ptr->chr = '\v';
 
6670
          break;
 
6671
        default:
 
6672
          follow_ptr->chr = (uchar) *pos;
 
6673
          break;
 
6674
        }
6748
6675
      }
6749
6676
      else
6750
 
  follow_ptr->chr= (uchar) *pos;
 
6677
        follow_ptr->chr= (uchar) *pos;
6751
6678
      follow_ptr->table_offset=i;
6752
6679
      follow_ptr->len= ++len;
6753
6680
      follow_ptr++;
6771
6698
    {
6772
6699
      if (!follow[i].chr)
6773
6700
      {
6774
 
  if (! default_state)
6775
 
    default_state= find_found(found_set,set->table_offset,
6776
 
            set->found_offset+1);
 
6701
        if (! default_state)
 
6702
          default_state= find_found(found_set,set->table_offset,
 
6703
                                    set->found_offset+1);
6777
6704
      }
6778
6705
    }
6779
6706
    copy_bits(sets.set+used_sets,set);    /* Save set for changes */
6786
6713
    {
6787
6714
      used_chars[follow[i].chr]=1;
6788
6715
      if ((follow[i].chr == SPACE_CHAR && !follow[i+1].chr &&
6789
 
     follow[i].len > 1) || follow[i].chr == END_OF_LINE)
6790
 
  used_chars[0]=1;
 
6716
           follow[i].len > 1) || follow[i].chr == END_OF_LINE)
 
6717
        used_chars[0]=1;
6791
6718
    }
6792
6719
 
6793
6720
    /* Mark word_chars used if \b is in state */
6794
6721
    if (used_chars[SPACE_CHAR])
6795
6722
      for (pos= word_end_chars ; *pos ; pos++)
6796
 
  used_chars[(int) (uchar) *pos] = 1;
 
6723
        used_chars[(int) (uchar) *pos] = 1;
6797
6724
 
6798
6725
    /* Handle other used characters */
6799
6726
    for (chr= 0 ; chr < 256 ; chr++)
6800
6727
    {
6801
6728
      if (! used_chars[chr])
6802
 
  set->next[chr]= chr ? default_state : -1;
 
6729
        set->next[chr]= chr ? default_state : -1;
6803
6730
      else
6804
6731
      {
6805
 
  new_set=make_new_set(&sets);
6806
 
  set=sets.set+set_nr;      /* if realloc */
6807
 
  new_set->table_offset=set->table_offset;
6808
 
  new_set->found_len=set->found_len;
6809
 
  new_set->found_offset=set->found_offset+1;
6810
 
  found_end=0;
 
6732
        new_set=make_new_set(&sets);
 
6733
        set=sets.set+set_nr;      /* if realloc */
 
6734
        new_set->table_offset=set->table_offset;
 
6735
        new_set->found_len=set->found_len;
 
6736
        new_set->found_offset=set->found_offset+1;
 
6737
        found_end=0;
6811
6738
 
6812
 
  for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
6813
 
  {
6814
 
    if (!follow[i].chr || follow[i].chr == chr ||
6815
 
        (follow[i].chr == SPACE_CHAR &&
6816
 
         (is_word_end[chr] ||
6817
 
    (!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
6818
 
        (follow[i].chr == END_OF_LINE && ! chr))
6819
 
    {
6820
 
      if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
6821
 
    follow[i].len > found_end)
6822
 
        found_end=follow[i].len;
6823
 
      if (chr && follow[i].chr)
6824
 
        internal_set_bit(new_set,i+1);    /* To next set */
6825
 
      else
6826
 
        internal_set_bit(new_set,i);
6827
 
    }
6828
 
  }
6829
 
  if (found_end)
6830
 
  {
6831
 
    new_set->found_len=0;      /* Set for testing if first */
6832
 
    bits_set=0;
6833
 
    for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
6834
 
    {
6835
 
      if ((follow[i].chr == SPACE_CHAR ||
6836
 
     follow[i].chr == END_OF_LINE) && ! chr)
6837
 
        bit_nr=i+1;
6838
 
      else
6839
 
        bit_nr=i;
6840
 
      if (follow[bit_nr-1].len < found_end ||
6841
 
    (new_set->found_len &&
6842
 
     (chr == 0 || !follow[bit_nr].chr)))
6843
 
        internal_clear_bit(new_set,i);
6844
 
      else
6845
 
      {
6846
 
        if (chr == 0 || !follow[bit_nr].chr)
6847
 
        {          /* best match  */
6848
 
    new_set->table_offset=follow[bit_nr].table_offset;
6849
 
    if (chr || (follow[i].chr == SPACE_CHAR ||
6850
 
          follow[i].chr == END_OF_LINE))
6851
 
      new_set->found_offset=found_end;  /* New match */
6852
 
    new_set->found_len=found_end;
6853
 
        }
6854
 
        bits_set++;
6855
 
      }
6856
 
    }
6857
 
    if (bits_set == 1)
6858
 
    {
6859
 
      set->next[chr] = find_found(found_set,
6860
 
          new_set->table_offset,
6861
 
          new_set->found_offset);
6862
 
      free_last_set(&sets);
6863
 
    }
6864
 
    else
6865
 
      set->next[chr] = find_set(&sets,new_set);
6866
 
  }
6867
 
  else
6868
 
    set->next[chr] = find_set(&sets,new_set);
 
6739
        for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
 
6740
        {
 
6741
          if (!follow[i].chr || follow[i].chr == chr ||
 
6742
              (follow[i].chr == SPACE_CHAR &&
 
6743
               (is_word_end[chr] ||
 
6744
                (!chr && follow[i].len > 1 && ! follow[i+1].chr))) ||
 
6745
              (follow[i].chr == END_OF_LINE && ! chr))
 
6746
          {
 
6747
            if ((! chr || (follow[i].chr && !follow[i+1].chr)) &&
 
6748
                follow[i].len > found_end)
 
6749
              found_end=follow[i].len;
 
6750
            if (chr && follow[i].chr)
 
6751
              internal_set_bit(new_set,i+1);    /* To next set */
 
6752
            else
 
6753
              internal_set_bit(new_set,i);
 
6754
          }
 
6755
        }
 
6756
        if (found_end)
 
6757
        {
 
6758
          new_set->found_len=0;      /* Set for testing if first */
 
6759
          bits_set=0;
 
6760
          for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
 
6761
          {
 
6762
            if ((follow[i].chr == SPACE_CHAR ||
 
6763
                 follow[i].chr == END_OF_LINE) && ! chr)
 
6764
              bit_nr=i+1;
 
6765
            else
 
6766
              bit_nr=i;
 
6767
            if (follow[bit_nr-1].len < found_end ||
 
6768
                (new_set->found_len &&
 
6769
                 (chr == 0 || !follow[bit_nr].chr)))
 
6770
              internal_clear_bit(new_set,i);
 
6771
            else
 
6772
            {
 
6773
              if (chr == 0 || !follow[bit_nr].chr)
 
6774
              {          /* best match  */
 
6775
                new_set->table_offset=follow[bit_nr].table_offset;
 
6776
                if (chr || (follow[i].chr == SPACE_CHAR ||
 
6777
                            follow[i].chr == END_OF_LINE))
 
6778
                  new_set->found_offset=found_end;  /* New match */
 
6779
                new_set->found_len=found_end;
 
6780
              }
 
6781
              bits_set++;
 
6782
            }
 
6783
          }
 
6784
          if (bits_set == 1)
 
6785
          {
 
6786
            set->next[chr] = find_found(found_set,
 
6787
                                        new_set->table_offset,
 
6788
                                        new_set->found_offset);
 
6789
            free_last_set(&sets);
 
6790
          }
 
6791
          else
 
6792
            set->next[chr] = find_set(&sets,new_set);
 
6793
        }
 
6794
        else
 
6795
          set->next[chr] = find_set(&sets,new_set);
6869
6796
      }
6870
6797
    }
6871
6798
  }
6873
6800
  /* Alloc replace structure for the replace-state-machine */
6874
6801
 
6875
6802
  if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
6876
 
            sizeof(REPLACE_STRING)*(found_sets+1)+
6877
 
            sizeof(char *)*count+result_len,
6878
 
            MYF(MY_WME | MY_ZEROFILL))))
 
6803
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
 
6804
                                    sizeof(char *)*count+result_len,
 
6805
                                    MYF(MY_WME | MY_ZEROFILL))))
6879
6806
  {
6880
6807
    rep_str=(REPLACE_STRING*) (replace+sets.count);
6881
6808
    to_array= (char **) (rep_str+found_sets+1);
6894
6821
      rep_str[i].replace_string=to_array[found_set[i-1].table_offset];
6895
6822
      rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos);
6896
6823
      rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+
6897
 
  end_of_word(pos);
 
6824
        end_of_word(pos);
6898
6825
    }
6899
6826
    for (i=0 ; i < sets.count ; i++)
6900
6827
    {
6901
6828
      for (j=0 ; j < 256 ; j++)
6902
 
  if (sets.set[i].next[j] >= 0)
6903
 
    replace[i].next[j]=replace+sets.set[i].next[j];
6904
 
  else
6905
 
    replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1));
 
6829
        if (sets.set[i].next[j] >= 0)
 
6830
          replace[i].next[j]=replace+sets.set[i].next[j];
 
6831
        else
 
6832
          replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1));
6906
6833
    }
6907
6834
  }
6908
6835
  my_free(follow,MYF(0));
6917
6844
  memset(sets, 0, sizeof(*sets));
6918
6845
  sets->size_of_bits=((states+7)/8);
6919
6846
  if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC,
6920
 
                MYF(MY_WME))))
 
6847
                                              MYF(MY_WME))))
6921
6848
    return 1;
6922
6849
  if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
6923
 
             SET_MALLOC_HUNC,MYF(MY_WME))))
 
6850
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
6924
6851
  {
6925
6852
    my_free(sets->set,MYF(0));
6926
6853
    return 1;
6956
6883
  count=sets->count+sets->invisible+SET_MALLOC_HUNC;
6957
6884
  if (!(set=(REP_SET*) my_realloc((uchar*) sets->set_buffer,
6958
6885
                                  sizeof(REP_SET)*count,
6959
 
          MYF(MY_WME))))
 
6886
                                  MYF(MY_WME))))
6960
6887
    return 0;
6961
6888
  sets->set_buffer=set;
6962
6889
  sets->set=set+sets->invisible;
6963
6890
  if (!(bit_buffer=(uint*) my_realloc((uchar*) sets->bit_buffer,
6964
 
              (sizeof(uint)*sets->size_of_bits)*count,
6965
 
              MYF(MY_WME))))
 
6891
                                      (sizeof(uint)*sets->size_of_bits)*count,
 
6892
                                      MYF(MY_WME))))
6966
6893
    return 0;
6967
6894
  sets->bit_buffer=bit_buffer;
6968
6895
  for (i=0 ; i < count ; i++)
7012
6939
void copy_bits(REP_SET *to,REP_SET *from)
7013
6940
{
7014
6941
  memcpy(to->bits,from->bits,
7015
 
   (size_t) (sizeof(uint) * to->size_of_bits));
 
6942
         (size_t) (sizeof(uint) * to->size_of_bits));
7016
6943
}
7017
6944
 
7018
6945
int cmp_bits(REP_SET *set1,REP_SET *set2)
7074
7001
  int i;
7075
7002
  for (i=0 ; (uint) i < found_sets ; i++)
7076
7003
    if (found_set[i].table_offset == table_offset &&
7077
 
  found_set[i].found_offset == found_offset)
 
7004
        found_set[i].found_offset == found_offset)
7078
7005
      return -i-2;
7079
7006
  found_set[i].table_offset=table_offset;
7080
7007
  found_set[i].found_offset=found_offset;
7114
7041
  if (! pa->typelib.count)
7115
7042
  {
7116
7043
    if (!(pa->typelib.type_names=(const char **)
7117
 
    my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
7118
 
         (sizeof(char *)+sizeof(*pa->flag))*
7119
 
         (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
 
7044
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
 
7045
                     (sizeof(char *)+sizeof(*pa->flag))*
 
7046
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
7120
7047
      return(-1);
7121
7048
    if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
7122
 
             MYF(MY_WME))))
 
7049
                                      MYF(MY_WME))))
7123
7050
    {
7124
7051
      my_free((char*) pa->typelib.type_names,MYF(0));
7125
7052
      return (-1);
7126
7053
    }
7127
7054
    pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+
7128
 
                 sizeof(*pa->flag));
 
7055
                                               sizeof(*pa->flag));
7129
7056
    pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
7130
7057
    pa->length=0;
7131
7058
    pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
7135
7062
  if (pa->length+length >= pa->max_length)
7136
7063
  {
7137
7064
    if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str,
7138
 
              (uint) (pa->max_length+PS_MALLOC),
7139
 
              MYF(MY_WME))))
 
7065
                                       (uint) (pa->max_length+PS_MALLOC),
 
7066
                                       MYF(MY_WME))))
7140
7067
      return(1);
7141
7068
    if (new_pos != pa->str)
7142
7069
    {
7143
7070
      my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
7144
7071
      for (i=0 ; i < pa->typelib.count ; i++)
7145
 
  pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
7146
 
                char*);
 
7072
        pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
 
7073
                                              char*);
7147
7074
      pa->str=new_pos;
7148
7075
    }
7149
7076
    pa->max_length+=PS_MALLOC;
7154
7081
    pa->array_allocs++;
7155
7082
    len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
7156
7083
    if (!(new_array=(const char **) my_realloc((uchar*) pa->typelib.type_names,
7157
 
                 (uint) len/
 
7084
                                               (uint) len/
7158
7085
                                               (sizeof(uchar*)+sizeof(*pa->flag))*
7159
7086
                                               (sizeof(uchar*)+sizeof(*pa->flag)),
7160
7087
                                               MYF(MY_WME))))
7192
7119
/* Functions that uses replace and replace_regex */
7193
7120
 
7194
7121
/* Append the string to ds, with optional replace */
7195
 
void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
7196
 
                               const char *val, int len)
 
7122
void replace_append_mem(string *ds,
 
7123
                        const char *val, int len)
7197
7124
{
 
7125
  char *v= strdup(val);
 
7126
 
7198
7127
  if (glob_replace_regex)
7199
7128
  {
7200
7129
    /* Regex replace */
7201
 
    if (!multi_reg_replace(glob_replace_regex, (char*)val))
 
7130
    if (!multi_reg_replace(glob_replace_regex, v))
7202
7131
    {
7203
 
      val= glob_replace_regex->buf;
7204
 
      len= strlen(val);
 
7132
      v= glob_replace_regex->buf;
 
7133
      len= strlen(v);
7205
7134
    }
7206
7135
  }
7207
7136
 
7208
7137
  if (glob_replace)
7209
7138
  {
7210
7139
    /* Normal replace */
7211
 
    replace_strings_append(glob_replace, ds, val, len);
 
7140
    replace_strings_append(glob_replace, ds, v, len);
7212
7141
  }
7213
7142
  else
7214
 
    dynstr_append_mem(ds, val, len);
 
7143
  {
 
7144
    ds->append(v, len);
 
7145
  }
7215
7146
}
7216
7147
 
7217
7148
 
7218
7149
/* Append zero-terminated string to ds, with optional replace */
7219
 
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
 
7150
void replace_append(string *ds, const char *val)
7220
7151
{
7221
 
  replace_dynstr_append_mem(ds, val, strlen(val));
 
7152
  replace_append_mem(ds, val, strlen(val));
7222
7153
}
7223
7154
 
7224
7155
/* Append uint to ds, with optional replace */
7225
 
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val)
 
7156
void replace_append_uint(string *ds, uint val)
7226
7157
{
7227
7158
  char buff[22]; /* This should be enough for any int */
7228
7159
  char *end= int64_t10_to_str(val, buff, 10);
7229
 
  replace_dynstr_append_mem(ds, buff, end - buff);
 
7160
  replace_append_mem(ds, buff, end - buff);
 
7161
 
7230
7162
}
7231
7163
 
7232
7164
 
7243
7175
 
7244
7176
*/
7245
7177
 
7246
 
static int comp_lines(const char **a, const char **b)
7247
 
{
7248
 
  return (strcmp(*a,*b));
7249
 
}
7250
 
 
7251
 
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
7252
 
{
7253
 
  unsigned i;
7254
 
  char *start= ds_input->str;
7255
 
  DYNAMIC_ARRAY lines;
7256
 
 
7257
 
 
7258
 
  if (!*start)
 
7178
 
 
7179
void append_sorted(string* ds, string *ds_input)
 
7180
{
 
7181
  priority_queue<string> lines;
 
7182
 
 
7183
  if (ds_input->empty())
7259
7184
    return;  /* No input */
7260
7185
 
7261
 
  my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
7262
 
 
7263
 
  /* First line is result header, skip past it */
7264
 
  while (*start && *start != '\n')
7265
 
    start++;
7266
 
  start++; /* Skip past \n */
7267
 
  dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
 
7186
  unsigned long eol_pos= 0;
 
7187
 
 
7188
  eol_pos= ds_input->find_first_of('\n', 0);
 
7189
  if (eol_pos == string::npos)
 
7190
    return; // We should have at least one header here
 
7191
 
 
7192
  ds->append(ds_input->substr(0, eol_pos));
 
7193
 
 
7194
  unsigned long start_pos= eol_pos+1;
7268
7195
 
7269
7196
  /* Insert line(s) in array */
7270
 
  while (*start)
7271
 
  {
7272
 
    char* line_end= (char*)start;
 
7197
  do {
7273
7198
 
 
7199
    eol_pos= ds_input->find_first_of('\n', start_pos);
7274
7200
    /* Find end of line */
7275
 
    while (*line_end && *line_end != '\n')
7276
 
      line_end++;
7277
 
    *line_end= 0;
7278
 
 
7279
 
    /* Insert pointer to the line in array */
7280
 
    if (insert_dynamic(&lines, (uchar*) &start))
7281
 
      die("Out of memory inserting lines to sort");
7282
 
 
7283
 
    start= line_end+1;
7284
 
  }
7285
 
 
7286
 
  /* Sort array */
7287
 
  qsort(lines.buffer, lines.elements,
7288
 
        sizeof(char**), (qsort_cmp)comp_lines);
 
7201
    lines.push(ds_input->substr(start_pos, eol_pos-start_pos));
 
7202
    start_pos= eol_pos+1;
 
7203
 
 
7204
  } while ( eol_pos != string::npos);
7289
7205
 
7290
7206
  /* Create new result */
7291
 
  for (i= 0; i < lines.elements ; i++)
7292
 
  {
7293
 
    const char **line= dynamic_element(&lines, i, const char**);
7294
 
    dynstr_append(ds, *line);
7295
 
    dynstr_append(ds, "\n");
 
7207
  while (!lines.empty()) {
 
7208
    ds->append(lines.top());
 
7209
    lines.pop();
7296
7210
  }
7297
7211
 
7298
 
  delete_dynamic(&lines);
7299
7212
  return;
7300
7213
}