~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzletest.cc

  • Committer: Mark Atwood
  • Date: 2009-01-05 04:37:22 UTC
  • mto: (758.1.1 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: me@mark.atwood.name-20090105043722-03l4mzcxi4yjjjih
replace sql_print_error etc with errmsg_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
 
39
39
#define MTEST_VERSION "3.3"
40
40
 
41
 
#include "config.h"
 
41
#include "client_priv.h"
42
42
 
43
43
#include <queue>
44
44
#include <map>
45
45
#include <string>
46
 
 
47
 
#include <pcrecpp.h>
48
 
 
49
 
#include "client_priv.h"
 
46
#include <vector>
 
47
 
 
48
#include <pcre.h>
 
49
 
50
50
#include <mysys/hash.h>
51
51
#include <stdarg.h>
52
52
 
53
53
#include "errname.h"
54
54
 
 
55
/* Added this for string translation. */
 
56
#include <drizzled/gettext.h>
 
57
 
55
58
using namespace std;
56
59
 
57
60
#define MAX_VAR_NAME_LENGTH    256
58
61
#define MAX_COLUMNS            256
59
62
#define MAX_EMBEDDED_SERVER_ARGS 64
60
63
#define MAX_DELIMITER_LENGTH 16
61
 
 
62
64
/* Flags controlling send and reap */
63
65
#define QUERY_SEND_FLAG  1
64
66
#define QUERY_REAP_FLAG  2
65
67
 
66
68
enum {
67
69
  OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
68
 
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
 
70
  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
 
71
  OPT_TESTDIR
69
72
};
70
73
 
71
74
static int record= 0, opt_sleep= -1;
72
 
static char *opt_db= 0, *opt_pass= 0;
73
 
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
 
75
static char *opt_db= NULL, *opt_pass= NULL;
 
76
const char *opt_user= NULL, *opt_host= NULL, *unix_sock= NULL,
 
77
           *opt_basedir= "./";
74
78
const char *opt_logdir= "";
75
 
const char *opt_include= 0, *opt_charsets_dir;
76
 
static int opt_port= 0;
 
79
const char *opt_include= NULL, *opt_charsets_dir;
 
80
const char *opt_testdir= NULL;
 
81
static uint32_t opt_port= 0;
77
82
static int opt_max_connect_retries;
78
 
static bool opt_compress= 0, silent= 0, verbose= 0;
79
 
static bool debug_info_flag= 0, debug_check_flag= 0;
80
 
static bool tty_password= 0;
81
 
static bool opt_mark_progress= 0;
82
 
static bool parsing_disabled= 0;
 
83
static bool opt_compress= false, silent= false, verbose= false;
 
84
static bool debug_info_flag= false, debug_check_flag= false;
 
85
static bool tty_password= false;
 
86
static bool opt_mark_progress= false;
 
87
static bool parsing_disabled= false;
83
88
static bool display_result_vertically= false,
84
89
  display_metadata= false, display_result_sorted= false;
85
 
static bool disable_query_log= 0, disable_result_log= 0;
86
 
static bool disable_warnings= 0;
87
 
static bool disable_info= 1;
88
 
static bool abort_on_error= 1;
89
 
static bool server_initialized= 0;
90
 
static bool is_windows= 0;
 
90
static bool disable_query_log= false, disable_result_log= false;
 
91
static bool disable_warnings= false;
 
92
static bool disable_info= true;
 
93
static bool abort_on_error= true;
 
94
static bool server_initialized= false;
 
95
static bool is_windows= false;
91
96
static char **default_argv;
92
97
static const char *load_default_groups[]= { "drizzletest", "client", 0 };
93
98
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
165
170
master_pos_st master_pos;
166
171
 
167
172
/* if set, all results are concated and compared against this file */
168
 
const char *result_file_name= 0;
 
173
const char *result_file_name= NULL;
169
174
 
170
175
typedef struct st_var
171
176
{
227
232
  Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
228
233
  Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT,
229
234
  Q_START_TIMER, Q_END_TIMER,
230
 
  Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
 
235
  Q_CHARACTER_SET,
231
236
  Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
232
237
  Q_IF,
233
238
  Q_DISABLE_PARSING, Q_ENABLE_PARSING,
388
393
VAR* var_from_env(const char *, const char *);
389
394
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
390
395
              int val_len);
391
 
void var_free(void* v);
 
396
extern "C" void var_free(void* v);
392
397
VAR* var_get(const char *var_name, const char** var_name_end,
393
398
             bool raw, bool ignore_not_existing);
394
399
void eval_expr(VAR* v, const char *p, const char** p_end);
533
538
      str->append(quote_str, quote_len);
534
539
      cur_pos= next_pos + 1;
535
540
    }
536
 
    str->append(cur_pos, next_pos - cur_pos);
 
541
    str->append(cur_pos);
537
542
    append= va_arg(dirty_text, char *);
538
543
  }
539
544
  va_end(dirty_text);
837
842
  vector<struct st_command *>::iterator iter;
838
843
  for (iter= q_lines.begin() ; iter < q_lines.end() ; iter++)
839
844
  {
840
 
    struct st_command * q_line= *(iter.base());
 
845
    struct st_command * q_line= *iter;
841
846
    if (q_line->query_buf != NULL)
842
847
    {
843
848
      free(q_line->query_buf);
1156
1161
  string ds_cmdline;
1157
1162
 
1158
1163
 
1159
 
  append_os_quoted(&ds_cmdline, tool_path);
 
1164
  append_os_quoted(&ds_cmdline, tool_path, NULL);
1160
1165
  ds_cmdline.append(" ");
1161
1166
 
1162
1167
  va_start(args, result);
1206
1211
               "2>&1",
1207
1212
               NULL) > 1) /* Most "diff" tools return >1 if error */
1208
1213
  {
1209
 
    ds_tmp= "";
1210
1214
 
1211
1215
    /* Fallback to context diff with "diff -c" */
1212
1216
    if (run_tool("diff",
1221
1225
        Fallback to dump both files to result file and inform
1222
1226
        about installing "diff"
1223
1227
      */
1224
 
      ds_tmp= "";
 
1228
      ds_tmp.clear();
1225
1229
 
1226
1230
      ds_tmp.append(
1227
1231
                    "\n"
1284
1288
  File fd2;
1285
1289
  uint len, len2;
1286
1290
  char buff[512], buff2[512];
 
1291
  const char *fname= filename2;
 
1292
  string tmpfile;
1287
1293
 
1288
 
  if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0)
 
1294
  if ((fd2= my_open(fname, O_RDONLY, MYF(0))) < 0)
1289
1295
  {
1290
1296
    my_close(fd, MYF(0));
1291
 
    die("Failed to open second file: '%s'", filename2);
 
1297
    if (opt_testdir != NULL)
 
1298
    {
 
1299
      tmpfile= opt_testdir;
 
1300
      if (tmpfile[tmpfile.length()] != '/')
 
1301
        tmpfile.append("/");
 
1302
      tmpfile.append(filename2);
 
1303
      fname= tmpfile.c_str();
 
1304
    }
 
1305
    if ((fd2= my_open(fname, O_RDONLY, MYF(0))) < 0)
 
1306
    {
 
1307
      my_close(fd, MYF(0));
 
1308
    
 
1309
      die("Failed to open second file: '%s'", fname);
 
1310
    }
1292
1311
  }
1293
1312
  while((len= my_read(fd, (unsigned char*)&buff,
1294
1313
                      sizeof(buff), MYF(0))) > 0)
1374
1393
  char temp_file_path[FN_REFLEN];
1375
1394
 
1376
1395
  if ((fd= create_temp_file(temp_file_path, NULL,
1377
 
                            "tmp", O_CREAT | O_SHARE | O_RDWR,
 
1396
                            "tmp", O_CREAT | O_RDWR,
1378
1397
                            MYF(MY_WME))) < 0)
1379
1398
    die("Failed to create temporary file for ds");
1380
1399
 
1381
1400
  /* Write ds to temporary file and set file pos to beginning*/
1382
1401
  if (my_write(fd, (unsigned char *) ds->c_str(), ds->length(),
1383
1402
               MYF(MY_FNABP | MY_WME)) ||
1384
 
      my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
 
1403
      lseek(fd, 0, SEEK_SET) == MY_FILEPOS_ERROR)
1385
1404
  {
1386
1405
    my_close(fd, MYF(0));
1387
1406
    /* Remove the temporary file */
1454
1473
    ds->erase(); /* Don't create a .log file */
1455
1474
 
1456
1475
    show_diff(NULL, result_file_name, reject_file);
1457
 
    die(mess);
 
1476
    die("%s",mess);
1458
1477
    break;
1459
1478
  }
1460
1479
  default: /* impossible */
1538
1557
}
1539
1558
 
1540
1559
 
1541
 
static unsigned char *get_var_key(const unsigned char* var, size_t *len,
1542
 
                          bool __attribute__((unused)) t)
 
1560
extern "C"
 
1561
unsigned char *get_var_key(const unsigned char* var, size_t *len, bool)
1543
1562
{
1544
1563
  register char* key;
1545
1564
  key = ((VAR*)var)->name;
1558
1577
  if (!val_len && val)
1559
1578
    val_len = strlen(val) ;
1560
1579
  val_alloc_len = val_len + 16; /* room to grow */
1561
 
  if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
1562
 
                                                  + name_len+1, MYF(MY_WME))))
 
1580
  if (!(tmp_var=v) && !(tmp_var = (VAR*)malloc(sizeof(*tmp_var)
 
1581
                                               + name_len+1)))
1563
1582
    die("Out of memory");
1564
1583
 
1565
1584
  tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
1566
1585
  tmp_var->alloced = (v == 0);
1567
1586
 
1568
 
  if (!(tmp_var->str_val = (char *)my_malloc(val_alloc_len+1, MYF(MY_WME))))
 
1587
  if (!(tmp_var->str_val = (char *)malloc(val_alloc_len+1)))
1569
1588
    die("Out of memory");
1570
1589
 
1571
1590
  memcpy(tmp_var->name, name, name_len);
1636
1655
                                 length)))
1637
1656
    {
1638
1657
      char buff[MAX_VAR_NAME_LENGTH+1];
1639
 
      strmake(buff, save_var_name, length);
 
1658
      strncpy(buff, save_var_name, length);
 
1659
      buff[length]= '\0';
1640
1660
      v= var_from_env(buff, "");
1641
1661
    }
1642
1662
    var_name--;  /* Point at last character */
1711
1731
    snprintf(buf, sizeof(buf), "%.*s=%.*s",
1712
1732
             v->name_len, v->name,
1713
1733
             v->str_val_len, v->str_val);
1714
 
    if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
 
1734
    if (!(v->env_s= strdup(buf)))
1715
1735
      die("Out of memory");
1716
1736
    putenv(v->env_s);
1717
1737
    free(old_env_s);
1889
1909
  char * unstripped_query= strdup(ds_query.c_str());
1890
1910
  if (strip_surrounding(unstripped_query, '"', '"'))
1891
1911
    die("Mismatched \"'s around query '%s'", ds_query.c_str());
1892
 
  ds_query= unstripped_query;
 
1912
  ds_query.clear();
 
1913
  ds_query.append(unstripped_query);
1893
1914
 
1894
1915
  /* Run the query */
1895
1916
  if (drizzle_real_query(drizzle, ds_query.c_str(), ds_query.length()))
1955
1976
  dest->int_dirty= src->int_dirty;
1956
1977
 
1957
1978
  /* Alloc/realloc data for str_val in dest */
1958
 
  if (dest->alloced_len < src->alloced_len &&
1959
 
      !(dest->str_val= dest->str_val
1960
 
        ? (char *)my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
1961
 
        : (char *)my_malloc(src->alloced_len, MYF(MY_WME))))
1962
 
    die("Out of memory");
 
1979
  if (dest->alloced_len < src->alloced_len)
 
1980
  {
 
1981
    char *tmpptr= (char *)realloc(dest->str_val, src->alloced_len);
 
1982
    if (tmpptr == NULL)
 
1983
      die("Out of memory");
 
1984
    dest->str_val= tmpptr;
 
1985
  }
1963
1986
  else
1964
1987
    dest->alloced_len= src->alloced_len;
1965
1988
 
2011
2034
      static int MIN_VAR_ALLOC= 32;
2012
2035
      v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
2013
2036
        MIN_VAR_ALLOC : new_val_len + 1;
2014
 
      if (!(v->str_val =
2015
 
            v->str_val ? (char *)my_realloc(v->str_val, v->alloced_len+1,
2016
 
                                            MYF(MY_WME)) :
2017
 
            (char *)my_malloc(v->alloced_len+1, MYF(MY_WME))))
 
2037
      char *tmpptr= (char *)realloc(v->str_val, v->alloced_len+1);
 
2038
      if (tmpptr == NULL)
2018
2039
        die("Out of memory");
 
2040
      v->str_val= tmpptr;
2019
2041
    }
2020
2042
    v->str_val_len = new_val_len;
2021
2043
    memcpy(v->str_val, p, new_val_len);
2033
2055
 
2034
2056
  if (!test_if_hard_path(name))
2035
2057
  {
2036
 
    strxmov(buff, opt_basedir, name, NULL);
 
2058
    sprintf(buff,"%s%s",opt_basedir,name);
2037
2059
    name=buff;
2038
2060
  }
2039
2061
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
2041
2063
  if (cur_file == file_stack_end)
2042
2064
    die("Source directives are nesting too deep");
2043
2065
  cur_file++;
2044
 
  if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
 
2066
  if (!(cur_file->file = my_fopen(buff, O_RDONLY, MYF(0))))
2045
2067
  {
2046
2068
    cur_file--;
2047
2069
    die("Could not open '%s' for reading", buff);
2048
2070
  }
2049
 
  cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
 
2071
  if (!(cur_file->file_name= strdup(buff)))
 
2072
    die("Out of memory");
2050
2073
  cur_file->lineno=1;
2051
2074
  return(0);
2052
2075
}
2086
2109
    ; /* Do nothing */
2087
2110
  else
2088
2111
  {
 
2112
    if (opt_testdir != NULL)
 
2113
    {
 
2114
      string testdir(opt_testdir);
 
2115
      if (testdir[testdir.length()] != '/')
 
2116
        testdir.append("/");
 
2117
      testdir.append(ds_filename);
 
2118
      ds_filename.swap(testdir);
 
2119
    }
2089
2120
    open_file(ds_filename.c_str());
2090
2121
  }
2091
2122
 
2466
2497
 
2467
2498
static void do_mkdir(struct st_command *command)
2468
2499
{
 
2500
  string ds_dirname;
2469
2501
  int error;
2470
 
  string ds_dirname;
2471
2502
  const struct command_arg mkdir_args[] = {
2472
2503
    {"dirname", ARG_STRING, true, &ds_dirname, "Directory to create"}
2473
2504
  };
2477
2508
                     mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
2478
2509
                     ' ');
2479
2510
 
2480
 
  error= my_mkdir(ds_dirname.c_str(), 0777, MYF(0)) != 0;
 
2511
  error= mkdir(ds_dirname.c_str(), (0777 & my_umask_dir)) != 0;
2481
2512
  handle_command_error(command, error);
2482
2513
  return;
2483
2514
}
2597
2628
 
2598
2629
  /* If no delimiter was provided, use EOF */
2599
2630
  if (ds_delimiter.length() == 0)
2600
 
    ds_delimiter= "EOF";
 
2631
    ds_delimiter.append("EOF");
2601
2632
 
2602
2633
  if (!append && access(ds_filename.c_str(), F_OK) == 0)
2603
2634
  {
2833
2864
                     ',');
2834
2865
 
2835
2866
  if (!ds_user.length())
2836
 
    ds_user= drizzle->user;
 
2867
    ds_user.append(drizzle->user);
2837
2868
 
2838
2869
  if (!ds_passwd.length())
2839
 
    ds_passwd= drizzle->passwd;
 
2870
    ds_passwd.append(drizzle->passwd);
2840
2871
 
2841
2872
  if (!ds_db.length())
2842
 
    ds_db= drizzle->db;
 
2873
    ds_db.append(drizzle->db);
2843
2874
 
2844
2875
  if (drizzle_change_user(drizzle, ds_user.c_str(),
2845
2876
                          ds_passwd.c_str(), ds_db.c_str()))
2891
2922
 
2892
2923
  /* If no delimiter was provided, use EOF */
2893
2924
  if (ds_delimiter.length() == 0)
2894
 
    ds_delimiter= "EOF";
 
2925
    ds_delimiter.append("EOF");
2895
2926
 
2896
2927
  read_until_delimiter(&ds_script, &ds_delimiter);
2897
2928
 
2898
2929
  /* Create temporary file name */
2899
2930
  if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
2900
 
                            "tmp", O_CREAT | O_SHARE | O_RDWR,
 
2931
                            "tmp", O_CREAT | O_RDWR,
2901
2932
                            MYF(MY_WME))) < 0)
2902
2933
    die("Failed to create temporary file for perl command");
2903
2934
  my_close(fd, MYF(0));
2965
2996
 
2966
2997
 
2967
2998
static void
2968
 
do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
 
2999
do_wait_for_slave_to_stop(struct st_command *)
2969
3000
{
2970
3001
  static int SLAVE_POLL_INTERVAL= 300000;
2971
3002
  DRIZZLE *drizzle= &cur_con->drizzle;
2988
3019
    drizzle_free_result(res);
2989
3020
    if (done)
2990
3021
      break;
2991
 
    my_sleep(SLAVE_POLL_INTERVAL);
 
3022
    usleep(SLAVE_POLL_INTERVAL);
2992
3023
  }
2993
3024
  return;
2994
3025
}
3081
3112
    die("drizzle_store_result() retuned NULL for '%s'", query);
3082
3113
  if (!(row = drizzle_fetch_row(res)))
3083
3114
    die("empty result in show master status");
3084
 
  my_stpncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
 
3115
  strncpy(master_pos.file, row[0], sizeof(master_pos.file)-1);
3085
3116
  master_pos.pos = strtoul(row[1], (char**) 0, 10);
3086
3117
  drizzle_free_result(res);
3087
3118
  return(0);
3191
3222
    sleep_val= opt_sleep;
3192
3223
 
3193
3224
  if (sleep_val)
3194
 
    my_sleep((uint32_t) (sleep_val * 1000000L));
 
3225
    usleep((uint32_t) (sleep_val * 1000000L));
3195
3226
  command->last_argument= sleep_end;
3196
3227
  return 0;
3197
3228
}
3209
3240
  if (*p)
3210
3241
    *p++= 0;
3211
3242
  command->last_argument= p;
3212
 
  strmake(dest, name, dest_max_len - 1);
 
3243
  strncpy(dest, name, dest_max_len - 1);
3213
3244
}
3214
3245
 
3215
3246
 
3524
3555
    When the connection is closed set name to "-closed_connection-"
3525
3556
    to make it possible to reuse the connection name.
3526
3557
  */
3527
 
  if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME))))
 
3558
  if (!(con->name = strdup("-closed_connection-")))
3528
3559
    die("Out of memory");
3529
3560
 
3530
3561
  return;
3582
3613
      verbose_msg("Connect attempt %d/%d failed: %d: %s", failed_attempts,
3583
3614
                  opt_max_connect_retries, drizzle_errno(drizzle),
3584
3615
                  drizzle_error(drizzle));
3585
 
      my_sleep(connection_retry_sleep);
 
3616
      usleep(connection_retry_sleep);
3586
3617
    }
3587
3618
    else
3588
3619
    {
3744
3775
    {
3745
3776
      char buff[FN_REFLEN];
3746
3777
      fn_format(buff, ds_sock.c_str(), TMPDIR, "", 0);
3747
 
      ds_sock= buff;
 
3778
      ds_sock.clear();
 
3779
      ds_sock.append(buff);
3748
3780
    }
3749
3781
  }
3750
3782
 
3793
3825
 
3794
3826
  /* Use default db name */
3795
3827
  if (ds_database.length() == 0)
3796
 
    ds_database= opt_db;
 
3828
    ds_database.append(opt_db);
3797
3829
 
3798
3830
  /* Special database to allow one to connect without a database name */
3799
3831
  if (ds_database.length() && !strcmp(ds_database.c_str(),"*NO-ONE*"))
3800
 
    ds_database= "";
 
3832
    ds_database.clear();
3801
3833
 
3802
3834
  if (connect_n_handle_errors(command, &con_slot->drizzle,
3803
3835
                              ds_host.c_str(),ds_user.c_str(),
3945
3977
  if (!(*p))
3946
3978
    die("Can't set empty delimiter");
3947
3979
 
3948
 
  strmake(delimiter, p, sizeof(delimiter) - 1);
 
3980
  strncpy(delimiter, p, sizeof(delimiter) - 1);
3949
3981
  delimiter_length= strlen(delimiter);
3950
3982
 
3951
3983
  command->last_argument= p + delimiter_length;
4366
4398
    return(0);
4367
4399
  }
4368
4400
  if (!(*command_ptr= command=
4369
 
        (struct st_command*) my_malloc(sizeof(*command),
4370
 
                                       MYF(MY_WME|MY_ZEROFILL))))
 
4401
        (struct st_command*) malloc(sizeof(*command))))
4371
4402
    die(NULL);
 
4403
  memset(command, 0, sizeof(*command));
4372
4404
  q_lines.push_back(command);
4373
4405
  command->type= Q_UNKNOWN;
4374
4406
 
4395
4427
  while (*p && my_isspace(charset_info, *p))
4396
4428
    p++;
4397
4429
 
4398
 
  if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
 
4430
  if (!(command->query_buf= command->query= strdup(p)))
4399
4431
    die("Out of memory");
4400
4432
 
4401
4433
  /* Calculate first word length(the command), terminated by space or ( */
4440
4472
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4441
4473
  {"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
4442
4474
   (char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4475
  {"testdir", OPT_TESTDIR, "Path to use to search for test files",
 
4476
   (char**) &opt_testdir,
 
4477
   (char**) &opt_testdir, 0,GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4443
4478
  {"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
4444
4479
   (char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4445
4480
  {"mark-progress", OPT_MARK_PROGRESS,
4450
4485
   "Max number of connection attempts when connecting to server",
4451
4486
   (char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
4452
4487
   GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
4453
 
  {"password", 'p', "Password to use when connecting to server.",
 
4488
  {"password", 'P', "Password to use when connecting to server.",
4454
4489
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4455
 
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
4456
 
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
 
4490
  {"port", 'p', "Port number to use for connection or 0 for default to, in "
 
4491
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
4457
4492
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
4458
 
   (char**) &opt_port,
4459
 
   (char**) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
4493
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4460
4494
  {"quiet", 's', "Suppress all normal output.", (char**) &silent,
4461
4495
   (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4462
4496
  {"record", 'r', "Record output of test_file into result file.",
4523
4557
 
4524
4558
  if (!test_if_hard_path(name))
4525
4559
  {
4526
 
    strxmov(buff, opt_basedir, name, NULL);
 
4560
    sprintf(buff,"%s%s",opt_basedir,name);
4527
4561
    name=buff;
4528
4562
  }
4529
4563
  fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
4533
4567
    embedded_server_arg_count=1;
4534
4568
    embedded_server_args[0]= (char*) "";    /* Progname */
4535
4569
  }
4536
 
  if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
 
4570
  if (!(file=my_fopen(buff, O_RDONLY, MYF(MY_WME))))
4537
4571
    die("Failed to open file '%s'", buff);
4538
4572
 
4539
4573
  while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
4541
4575
  {
4542
4576
    *(strchr(str, '\0')-1)=0;        /* Remove end newline */
4543
4577
    if (!(embedded_server_args[embedded_server_arg_count]=
4544
 
          (char*) my_strdup(str,MYF(MY_WME))))
 
4578
          (char*) strdup(str)))
4545
4579
    {
4546
4580
      my_fclose(file,MYF(0));
4547
4581
      die("Out of memory");
4557
4591
}
4558
4592
 
4559
4593
 
4560
 
static bool
4561
 
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
4562
 
               char *argument)
 
4594
extern "C" bool
 
4595
get_one_option(int optid, const struct my_option *, char *argument)
4563
4596
{
 
4597
  char *endchar= NULL;
 
4598
  uint64_t temp_drizzle_port= 0;
 
4599
 
4564
4600
  switch(optid) {
4565
4601
  case 'r':
4566
4602
    record = 1;
4570
4606
    char buff[FN_REFLEN];
4571
4607
    if (!test_if_hard_path(argument))
4572
4608
    {
4573
 
      strxmov(buff, opt_basedir, argument, NULL);
 
4609
      sprintf(buff,"%s%s",opt_basedir,argument);
4574
4610
      argument= buff;
4575
4611
    }
4576
4612
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4577
4613
    assert(cur_file == file_stack && cur_file->file == 0);
4578
4614
    if (!(cur_file->file=
4579
 
          my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
 
4615
          my_fopen(buff, O_RDONLY, MYF(0))))
4580
4616
      die("Could not open '%s' for reading: errno = %d", buff, errno);
4581
 
    cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
 
4617
    if (!(cur_file->file_name= strdup(buff)))
 
4618
      die("Out of memory");
4582
4619
    cur_file->lineno= 1;
4583
4620
    break;
4584
4621
  }
4587
4624
    static char buff[FN_REFLEN];
4588
4625
    if (!test_if_hard_path(argument))
4589
4626
    {
4590
 
      strxmov(buff, opt_basedir, argument, NULL);
 
4627
      sprintf(buff,"%s%s",opt_basedir,argument);
4591
4628
      argument= buff;
4592
4629
    }
4593
4630
    fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4596
4633
    break;
4597
4634
  }
4598
4635
  case 'p':
 
4636
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
4637
    /* if there is an alpha character this is not a valid port */
 
4638
    if (strlen(endchar) != 0)
 
4639
    {
 
4640
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
 
4641
      exit(1);
 
4642
    }
 
4643
    /* If the port number is > 65535 it is not a valid port
 
4644
       This also helps with potential data loss casting unsigned long to a
 
4645
       uint32_t. */
 
4646
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
4647
    {
 
4648
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
 
4649
      exit(1);
 
4650
    }
 
4651
    else
 
4652
    {
 
4653
      opt_port= (uint32_t) temp_drizzle_port;
 
4654
    }
 
4655
    break;
 
4656
  case 'P':
4599
4657
    if (argument)
4600
4658
    {
4601
 
      free(opt_pass);
4602
 
      opt_pass= my_strdup(argument, MYF(MY_FAE));
4603
 
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
4659
      if (opt_pass)
 
4660
        free(opt_pass);
 
4661
      opt_pass = strdup(argument);
 
4662
      if (opt_pass == NULL)
 
4663
        die("Out of memory");
 
4664
      while (*argument)
 
4665
      {
 
4666
        /* Overwriting password with 'x' */
 
4667
        *argument++= 'x';
 
4668
      }
4604
4669
      tty_password= 0;
4605
4670
    }
4606
4671
    else
4607
4672
      tty_password= 1;
4608
4673
    break;
4609
4674
  case 't':
4610
 
    my_stpncpy(TMPDIR, argument, sizeof(TMPDIR));
 
4675
    strncpy(TMPDIR, argument, sizeof(TMPDIR));
4611
4676
    break;
4612
4677
  case 'A':
4613
4678
    if (!embedded_server_arg_count)
4617
4682
    }
4618
4683
    if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 ||
4619
4684
        !(embedded_server_args[embedded_server_arg_count++]=
4620
 
          my_strdup(argument, MYF(MY_FAE))))
 
4685
          strdup(argument)))
4621
4686
    {
4622
4687
      die("Can't use server argument");
4623
4688
    }
4638
4703
 
4639
4704
static int parse_args(int argc, char **argv)
4640
4705
{
4641
 
  load_defaults("my",load_default_groups,&argc,&argv);
 
4706
  load_defaults("drizzle",load_default_groups,&argc,&argv);
4642
4707
  default_argv= argv;
4643
4708
 
4644
4709
  if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
4679
4744
  int flags= O_WRONLY | O_CREAT;
4680
4745
  if (!test_if_hard_path(fname))
4681
4746
  {
4682
 
    strxmov(buff, opt_basedir, fname, NULL);
 
4747
    sprintf(buff,"%s%s",opt_basedir,fname);
4683
4748
    fname= buff;
4684
4749
  }
4685
4750
  fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
4689
4754
  if ((fd= my_open(buff, flags,
4690
4755
                   MYF(MY_WME | MY_FFNF))) < 0)
4691
4756
    die("Could not open '%s' for writing: errno = %d", buff, errno);
4692
 
  if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
 
4757
  if (append && lseek(fd, 0, SEEK_END) == MY_FILEPOS_ERROR)
4693
4758
    die("Could not find end of file '%s': errno = %d", buff, errno);
4694
4759
  if (my_write(fd, (unsigned char*)str, size, MYF(MY_WME|MY_FNABP)))
4695
4760
    die("write failed");
5391
5456
 
5392
5457
*/
5393
5458
 
5394
 
static void mark_progress(struct st_command* command __attribute__((unused)),
5395
 
                          int line)
 
5459
static void mark_progress(struct st_command*, int line)
5396
5460
{
5397
5461
  char buf[32], *end;
5398
5462
  uint64_t timer= timer_now();
5482
5546
  if (cur_file == file_stack && cur_file->file == 0)
5483
5547
  {
5484
5548
    cur_file->file= stdin;
5485
 
    cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME));
 
5549
    cur_file->file_name= strdup("<stdin>");
 
5550
    if (cur_file->file_name == NULL)
 
5551
      die("Out of memory");
5486
5552
    cur_file->lineno= 1;
5487
5553
  }
5488
5554
  cur_con= connections;
5492
5558
    drizzle_options(&cur_con->drizzle,DRIZZLE_OPT_COMPRESS,NULL);
5493
5559
  drizzle_options(&cur_con->drizzle, DRIZZLE_OPT_LOCAL_INFILE, 0);
5494
5560
 
5495
 
  if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
 
5561
  if (!(cur_con->name = strdup("default")))
5496
5562
    die("Out of memory");
5497
5563
 
5498
5564
  safe_connect(&cur_con->drizzle, cur_con->name, opt_host, opt_user, opt_pass,
5629
5695
 
5630
5696
        if (save_file[0])
5631
5697
        {
5632
 
          strmake(command->require_file, save_file, sizeof(save_file) - 1);
 
5698
          strncpy(command->require_file, save_file, sizeof(save_file) - 1);
5633
5699
          save_file[0]= 0;
5634
5700
        }
5635
5701
        run_query(cur_con, command, flags);
5927
5993
    die("Missing argument in %s", command->query);
5928
5994
 
5929
5995
  /* Allocate a buffer for results */
5930
 
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
 
5996
  start= buff= (char *)malloc(strlen(from)+1);
5931
5997
  while (*from)
5932
5998
  {
5933
5999
    char *to;
5940
6006
      die("Wrong number of arguments to replace_column in '%s'", command->query);
5941
6007
    to= get_string(&buff, &from, command);
5942
6008
    free(replace_column[column_number-1]);
5943
 
    replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
 
6009
    replace_column[column_number-1]= strdup(to);
 
6010
    if (replace_column[column_number-1] == NULL)
 
6011
      die("Out of memory");
5944
6012
    set_if_bigger(max_replace_column, column_number);
5945
6013
  }
5946
6014
  free(start);
6010
6078
  memset(&from_array, 0, sizeof(from_array));
6011
6079
  if (!*from)
6012
6080
    die("Missing argument in %s", command->query);
6013
 
  start= buff= (char *)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
 
6081
  start= buff= (char *)malloc(strlen(from)+1);
6014
6082
  while (*from)
6015
6083
  {
6016
6084
    char *to= buff;
6189
6257
  char last_c = 0;
6190
6258
  struct st_regex reg;
6191
6259
 
6192
 
  /* my_malloc() will die on fail with MY_FAE */
6193
 
  res=(struct st_replace_regex*)my_malloc(
6194
 
                                          sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
 
6260
  res=(st_replace_regex*)malloc(sizeof(*res)+expr_len);
 
6261
  if (!res)
 
6262
    return NULL;
6195
6263
  my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
6196
6264
 
6197
6265
  buf= (char*)res + sizeof(*res);
6248
6316
      die("Out of memory");
6249
6317
  }
6250
6318
  res->odd_buf_len= res->even_buf_len= 8192;
6251
 
  res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE));
6252
 
  res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE));
 
6319
  res->even_buf= (char*)malloc(res->even_buf_len);
 
6320
  res->odd_buf= (char*)malloc(res->odd_buf_len);
6253
6321
  res->buf= res->even_buf;
6254
6322
 
6255
6323
  return res;
6357
6425
 
6358
6426
 
6359
6427
/*
6360
 
  auxiluary macro used by reg_replace
6361
 
  makes sure the result buffer has sufficient length
6362
 
*/
6363
 
#define SECURE_REG_BUF   if (buf_len < need_buf_len)                    \
6364
 
  {                                                                     \
6365
 
    int off= res_p - buf;                                               \
6366
 
    buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE));        \
6367
 
    res_p= buf + off;                                                   \
6368
 
    buf_len= need_buf_len;                                              \
6369
 
  }                                                                     \
6370
 
                                                                        \
6371
 
/*
6372
6428
  Performs a regex substitution
6373
6429
 
6374
6430
  IN:
6384
6440
                char *replace, char *in_string, int icase)
6385
6441
{
6386
6442
  string string_to_match(in_string);
6387
 
  pcrecpp::RE_Options opt;
6388
 
 
6389
 
  if (icase)
6390
 
    opt.set_caseless(true);
6391
 
 
6392
 
  if (!pcrecpp::RE(pattern, opt).Replace(replace,&string_to_match)){
 
6443
  const char *error= NULL;
 
6444
  int erroffset;
 
6445
  int ovector[3];
 
6446
  pcre *re= pcre_compile(pattern,
 
6447
                         icase ? PCRE_CASELESS : 0,
 
6448
                         &error, &erroffset, NULL);
 
6449
  if (re == NULL)
 
6450
    return 1;
 
6451
 
 
6452
  int rc= pcre_exec(re, NULL, in_string, (int)strlen(in_string),
 
6453
                    0, 0, ovector, 3);
 
6454
  if (rc < 0)
 
6455
  {
 
6456
    pcre_free(re);
6393
6457
    return 1;
6394
6458
  }
6395
6459
 
6396
 
  const char * new_str= string_to_match.c_str();
6397
 
  *buf_len_p= strlen(new_str);
 
6460
  char *substring_to_replace= in_string + ovector[0];
 
6461
  int substring_length= ovector[1] - ovector[0];
 
6462
  *buf_len_p= strlen(in_string) - substring_length + strlen(replace);
6398
6463
  char * new_buf = (char *)malloc(*buf_len_p+1);
6399
6464
  if (new_buf == NULL)
6400
6465
  {
 
6466
    pcre_free(re);
6401
6467
    return 1;
6402
6468
  }
6403
 
  strcpy(new_buf, new_str);
6404
 
  buf_p= &new_buf;
6405
 
 
 
6469
 
 
6470
  memset(new_buf, 0, *buf_len_p+1);
 
6471
  strncpy(new_buf, in_string, substring_to_replace-in_string);
 
6472
  strncpy(new_buf+(substring_to_replace-in_string), replace, strlen(replace));
 
6473
  strncpy(new_buf+(substring_to_replace-in_string)+strlen(replace),
 
6474
          substring_to_replace + substring_length,
 
6475
          strlen(in_string)
 
6476
            - substring_length
 
6477
            - (substring_to_replace-in_string));
 
6478
  *buf_p= new_buf;
 
6479
 
 
6480
  pcre_free(re);
6406
6481
  return 0;
6407
6482
}
6408
6483
 
6519
6594
  if (init_sets(&sets,states))
6520
6595
    return(0);
6521
6596
  found_sets=0;
6522
 
  if (!(found_set= (FOUND_SET*) my_malloc(sizeof(FOUND_SET)*max_length*count,
6523
 
                                          MYF(MY_WME))))
 
6597
  if (!(found_set= (FOUND_SET*) malloc(sizeof(FOUND_SET)*max_length*count)))
 
6598
                                
6524
6599
  {
6525
6600
    free_sets(&sets);
6526
6601
    return(0);
6530
6605
  used_sets=-1;
6531
6606
  word_states=make_new_set(&sets);    /* Start of new word */
6532
6607
  start_states=make_new_set(&sets);    /* This is first state */
6533
 
  if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
 
6608
  if (!(follow=(FOLLOWS*) malloc((states+2)*sizeof(FOLLOWS))))
6534
6609
  {
6535
6610
    free_sets(&sets);
6536
6611
    free(found_set);
6722
6797
 
6723
6798
  /* Alloc replace structure for the replace-state-machine */
6724
6799
 
6725
 
  if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
6726
 
                                    sizeof(REPLACE_STRING)*(found_sets+1)+
6727
 
                                    sizeof(char *)*count+result_len,
6728
 
                                    MYF(MY_WME | MY_ZEROFILL))))
 
6800
  if ((replace=(REPLACE*) malloc(sizeof(REPLACE)*(sets.count)+
 
6801
                                 sizeof(REPLACE_STRING)*(found_sets+1)+
 
6802
                                 sizeof(char *)*count+result_len)))
6729
6803
  {
 
6804
    memset(replace, 0, sizeof(REPLACE)*(sets.count)+
 
6805
                       sizeof(REPLACE_STRING)*(found_sets+1)+
 
6806
                       sizeof(char *)*count+result_len);
6730
6807
    rep_str=(REPLACE_STRING*) (replace+sets.count);
6731
6808
    to_array= (char **) (rep_str+found_sets+1);
6732
6809
    to_pos=(char *) (to_array+count);
6733
6810
    for (i=0 ; i < count ; i++)
6734
6811
    {
6735
6812
      to_array[i]=to_pos;
6736
 
      to_pos=my_stpcpy(to_pos,to[i])+1;
 
6813
      to_pos=strcpy(to_pos,to[i])+strlen(to[i])+1;
6737
6814
    }
6738
6815
    rep_str[0].found=1;
6739
6816
    rep_str[0].replace_string=0;
6766
6843
{
6767
6844
  memset(sets, 0, sizeof(*sets));
6768
6845
  sets->size_of_bits=((states+7)/8);
6769
 
  if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC,
6770
 
                                              MYF(MY_WME))))
 
6846
  if (!(sets->set_buffer=(REP_SET*) malloc(sizeof(REP_SET)*SET_MALLOC_HUNC)))
6771
6847
    return 1;
6772
 
  if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
6773
 
                                           SET_MALLOC_HUNC,MYF(MY_WME))))
 
6848
  if (!(sets->bit_buffer=(uint*) malloc(sizeof(uint)*sets->size_of_bits*
 
6849
                                        SET_MALLOC_HUNC)))
6774
6850
  {
6775
6851
    free(sets->set);
6776
6852
    return 1;
6804
6880
    return set;
6805
6881
  }
6806
6882
  count=sets->count+sets->invisible+SET_MALLOC_HUNC;
6807
 
  if (!(set=(REP_SET*) my_realloc((unsigned char*) sets->set_buffer,
6808
 
                                  sizeof(REP_SET)*count,
6809
 
                                  MYF(MY_WME))))
 
6883
  if (!(set=(REP_SET*) realloc((unsigned char*) sets->set_buffer,
 
6884
                                  sizeof(REP_SET)*count)))
6810
6885
    return 0;
6811
6886
  sets->set_buffer=set;
6812
6887
  sets->set=set+sets->invisible;
6813
 
  if (!(bit_buffer=(uint*) my_realloc((unsigned char*) sets->bit_buffer,
6814
 
                                      (sizeof(uint)*sets->size_of_bits)*count,
6815
 
                                      MYF(MY_WME))))
 
6888
  if (!(bit_buffer=(uint*) realloc((unsigned char*) sets->bit_buffer,
 
6889
                                   (sizeof(uint)*sets->size_of_bits)*count)))
6816
6890
    return 0;
6817
6891
  sets->bit_buffer=bit_buffer;
6818
6892
  for (i=0 ; i < count ; i++)
6964
7038
  if (! pa->typelib.count)
6965
7039
  {
6966
7040
    if (!(pa->typelib.type_names=(const char **)
6967
 
          my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
 
7041
          malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
6968
7042
                     (sizeof(char *)+sizeof(*pa->flag))*
6969
 
                     (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME))))
 
7043
                     (sizeof(char *)+sizeof(*pa->flag))))))
6970
7044
      return(-1);
6971
 
    if (!(pa->str= (unsigned char*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
6972
 
                                      MYF(MY_WME))))
 
7045
    if (!(pa->str= (unsigned char*) malloc(PS_MALLOC-MALLOC_OVERHEAD)))
6973
7046
    {
6974
7047
      free((char*) pa->typelib.type_names);
6975
7048
      return (-1);
6984
7057
  length=(uint) strlen(name)+1;
6985
7058
  if (pa->length+length >= pa->max_length)
6986
7059
  {
6987
 
    if (!(new_pos= (unsigned char*) my_realloc((unsigned char*) pa->str,
6988
 
                                       (uint) (pa->max_length+PS_MALLOC),
6989
 
                                       MYF(MY_WME))))
 
7060
    if (!(new_pos= (unsigned char*)realloc((unsigned char*)pa->str,
 
7061
                                           (size_t)(pa->max_length+PS_MALLOC))))
6990
7062
      return(1);
6991
7063
    if (new_pos != pa->str)
6992
7064
    {
7000
7072
  }
7001
7073
  if (pa->typelib.count >= pa->max_count-1)
7002
7074
  {
7003
 
    int len;
 
7075
    size_t len;
7004
7076
    pa->array_allocs++;
7005
7077
    len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
7006
 
    if (!(new_array=(const char **) my_realloc((unsigned char*) pa->typelib.type_names,
7007
 
                                               (uint) len/
7008
 
                                               (sizeof(unsigned char*)+sizeof(*pa->flag))*
7009
 
                                               (sizeof(unsigned char*)+sizeof(*pa->flag)),
7010
 
                                               MYF(MY_WME))))
 
7078
    if (!(new_array=
 
7079
         (const char **)realloc((unsigned char*) pa->typelib.type_names,
 
7080
                                 len/
 
7081
                                  (sizeof(unsigned char*)+sizeof(*pa->flag))*
 
7082
                                  (sizeof(unsigned char*)+sizeof(*pa->flag)))))
7011
7083
      return(1);
7012
7084
    pa->typelib.type_names=new_array;
7013
7085
    old_count=pa->max_count;
7019
7091
  pa->flag[pa->typelib.count]=0;      /* Reset flag */
7020
7092
  pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length;
7021
7093
  pa->typelib.type_names[pa->typelib.count]= NULL;  /* Put end-mark */
7022
 
  my_stpcpy((char*) pa->str+pa->length,name);
 
7094
  strcpy((char*) pa->str+pa->length,name);
7023
7095
  pa->length+=length;
7024
7096
  return(0);
7025
7097
} /* insert_pointer_name */
7101
7173
 
7102
7174
void append_sorted(string* ds, string *ds_input)
7103
7175
{
7104
 
  priority_queue<string> lines;
 
7176
  priority_queue<string, vector<string>, greater<string> > lines;
7105
7177
 
7106
7178
  if (ds_input->empty())
7107
7179
    return;  /* No input */
7112
7184
  if (eol_pos == string::npos)
7113
7185
    return; // We should have at least one header here
7114
7186
 
7115
 
  ds->append(ds_input->substr(0, eol_pos));
 
7187
  ds->append(ds_input->substr(0, eol_pos+1));
7116
7188
 
7117
7189
  unsigned long start_pos= eol_pos+1;
7118
7190
 
7121
7193
 
7122
7194
    eol_pos= ds_input->find_first_of('\n', start_pos);
7123
7195
    /* Find end of line */
7124
 
    lines.push(ds_input->substr(start_pos, eol_pos-start_pos));
 
7196
    lines.push(ds_input->substr(start_pos, eol_pos-start_pos+1));
7125
7197
    start_pos= eol_pos+1;
7126
7198
 
7127
7199
  } while ( eol_pos != string::npos);