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);
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);
394
401
/* For replace_column */
395
402
static char *replace_column[MAX_COLUMNS];
415
422
free_replace_column();
418
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
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,
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);
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*);
429
436
#ifdef EMBEDDED_LIBRARY
511
dynstr_append_mem(query_eval, p, 1);
518
query_eval->append(p, 1);
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);
525
dynstr_append_mem(query_eval, p, 1);
532
query_eval->append(p, 1);
527
534
else if (next_c == '\\' || next_c == '$' || next_c == '"')
529
536
/* Set escaped only if next char is \, " or $ */
532
539
if (pass_through_escape_chars)
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);
539
dynstr_append_mem(query_eval, p, 1);
546
query_eval->append(p, 1);
543
dynstr_append_mem(query_eval, p, 1);
550
query_eval->append(p, 1);
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.
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.
568
@note The final argument in the list must be NullS even if no additional
572
void append_os_quoted(string *str, const char *append, ...)
574
const char *quote_str= "\'";
575
const uint quote_len= 1;
579
str->append(quote_str, quote_len); /* Leading quote */
580
va_start(dirty_text, append);
581
while (append != NullS)
583
const char *cur_pos= append;
584
const char *next_pos= cur_pos;
586
/* Search for quote in each string and replace with escaped quote */
587
while((next_pos= strrchr(cur_pos, quote_str[0])) != NULL)
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;
594
str->append(cur_pos, next_pos - cur_pos);
595
append= va_arg(dirty_text, char *);
598
str->append(quote_str, quote_len); /* Trailing quote */
552
603
Run query and dump the result to stdout in vertical format
554
605
NOTE! This function should be safe to call when an error
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)
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 )
940
991
if (*show_from == '\n')
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);
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());
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();
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)
1035
dynstr_append(&ds_warning_messages, "Warning detected ");
1086
ds_warning_messages.append("Warning detected ");
1036
1087
if (cur_file && cur_file != file_stack)
1038
1089
len= snprintf(buff, sizeof(buff), "in included file %s ",
1039
cur_file->file_name);
1040
dynstr_append_mem(&ds_warning_messages,
1090
cur_file->file_name);
1091
ds_warning_messages.append(buff, len);
1043
1093
len= snprintf(buff, sizeof(buff), "at line %d: ",
1045
dynstr_append_mem(&ds_warning_messages,
1095
ds_warning_messages.append(buff, len);
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);
1052
dynstr_append(&ds_warning_messages, "\n");
1101
ds_warning_messages.append("\n");
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
1172
static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
1213
static int run_tool(const char *tool_path, string * result, ...)
1175
1216
const char* arg;
1177
DYNAMIC_STRING ds_cmdline;
1179
if (init_dynamic_string(&ds_cmdline, "", FN_REFLEN, FN_REFLEN))
1180
die("Out of memory");
1182
dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS);
1183
dynstr_append(&ds_cmdline, " ");
1185
va_start(args, ds_res);
1221
append_os_quoted(&ds_cmdline, tool_path);
1222
ds_cmdline.append(" ");
1224
va_start(args, result);
1187
1226
while ((arg= va_arg(args, char *)))
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);
1193
dynstr_append(&ds_cmdline, arg);
1194
dynstr_append(&ds_cmdline, " ");
1232
ds_cmdline.append(arg);
1233
ds_cmdline.append(" ");
1199
ret= run_command(ds_cmdline.str, ds_res);
1200
dynstr_free(&ds_cmdline);
1238
ret= run_command(ds_cmdline.c_str(), result);
1248
1283
Fallback to dump both files to result file and inform
1249
1284
about installing "diff"
1251
dynstr_set(&ds_tmp, "");
1253
dynstr_append(&ds_tmp,
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"
1262
dynstr_append(&ds_tmp, " --- ");
1263
dynstr_append(&ds_tmp, filename1);
1264
dynstr_append(&ds_tmp, " >>>\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"
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");
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());
1281
1316
/* Print diff directly to stdout */
1282
fprintf(stderr, "%s\n", ds_tmp.str);
1317
fprintf(stderr, "%s\n", ds_tmp.c_str());
1285
dynstr_free(&ds_tmp);
1290
1323
enum compare_files_result_enum {
1292
RESULT_CONTENT_MISMATCH= 1,
1293
RESULT_LENGTH_MISMATCH= 2
1325
RESULT_CONTENT_MISMATCH= 1,
1326
RESULT_LENGTH_MISMATCH= 2
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);
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());
1838
1869
if ((row= drizzle_fetch_row(res)) && row[0])
1841
1872
Concatenate all fields in the first row with tab in between
1842
1873
and assign that string to the $variable
1844
DYNAMIC_STRING result;
1846
1877
uint32_t *lengths;
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++)
1854
1884
/* Add column to tab separated string */
1855
dynstr_append_mem(&result, row[i], lengths[i]);
1885
result.append(row[i], lengths[i]);
1857
dynstr_append_mem(&result, "\t", 1);
1887
result.append("\t", 1);
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);
1864
1893
eval_expr(var, "", 0);
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());
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;
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());
1933
1964
/* Find column number from the given column name */
2144
2166
Replace a substring
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
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
2156
1 Could not find search_str in str
2178
1 Could not find search_str in str
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)
2163
DYNAMIC_STRING ds_tmp;
2164
const char *start= strstr(ds_str->str, search_str);
2186
const char *start= strstr(ds_str->c_str(), search_str);
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);
2365
2361
static void do_system(struct st_command *command)
2367
DYNAMIC_STRING ds_cmd;
2370
2366
if (strlen(command->first_argument) == 0)
2371
2367
die("Missing arguments to system, nothing to do!");
2373
init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256);
2375
2369
/* Eval the system command, thus replacing all environment variables */
2376
2370
do_eval(&ds_cmd, command->first_argument, command->end, !is_windows);
2378
if (my_system(&ds_cmd))
2372
if (system(ds_cmd.c_str()))
2380
2374
if (command->abort_on_error)
2381
2375
die("system command '%s' failed", command->first_argument);
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");
2389
2383
command->last_argument= command->end;
2390
dynstr_free(&ds_cmd);
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");
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));
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";
2679
if (!append && access(ds_filename.str, F_OK) == 0)
2664
if (!append && access(ds_filename.c_str(), F_OK) == 0)
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());
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);
2818
2799
sizeof(diff_file_args)/sizeof(struct command_arg),
2821
if ((error= compare_files(ds_filename.str, ds_filename2.str)))
2802
if ((error= compare_files(ds_filename.c_str(), ds_filename2.c_str())))
2823
2804
/* Compare of the two files failed, append them to output
2824
2805
so the failure can be analyzed
2826
show_diff(&ds_res, ds_filename.str, ds_filename2.str);
2807
show_diff(&ds_res, ds_filename.c_str(), ds_filename2.c_str());
2829
dynstr_free(&ds_filename);
2830
dynstr_free(&ds_filename2);
2831
2810
handle_command_error(command, error);
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),
2918
if (!ds_user.length)
2919
dynstr_set(&ds_user, drizzle->user);
2921
if (!ds_passwd.length)
2922
dynstr_set(&ds_passwd, drizzle->passwd);
2925
dynstr_set(&ds_db, drizzle->db);
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;
2900
if (!ds_passwd.length())
2901
ds_passwd= drizzle->passwd;
2903
if (!ds_db.length())
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));
2930
dynstr_free(&ds_user);
2931
dynstr_free(&ds_passwd);
2932
dynstr_free(&ds_db);
3653
3622
static void safe_connect(DRIZZLE *drizzle, const char *name, const char *host,
3654
const char *user, const char *pass, const char *db,
3623
const char *user, const char *pass, const char *db,
3657
3626
int failed_attempts= 0;
3658
3627
static uint32_t connection_retry_sleep= 100000; /* Microseconds */
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))
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)
3728
3694
/* Only log if an error is expected */
3729
3695
if (!command->abort_on_error &&
3733
3699
Log the connect to result log
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);
3704
replace_append(&ds_res, user);
3706
replace_append(&ds_res, pass);
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);
3711
replace_append_uint(&ds_res, port);
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);
3716
ds_res.append(delimiter);
3717
ds_res.append("\n");
3753
3719
if (!drizzle_connect(con, host, user, pass, db, port, 0,
3754
CLIENT_MULTI_STATEMENTS))
3720
CLIENT_MULTI_STATEMENTS))
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 */
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
3793
3759
static void do_connect(struct st_command *command)
3795
3761
int con_port= opt_port;
3762
const char *con_options;
3797
3763
bool con_ssl= 0, con_compress= 0;
3798
3764
struct st_connection* con_slot;
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;
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" },
3792
if (ds_port.length())
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());
3800
if (!ds_sock.empty())
3837
3803
If the socket is specified just as a name without path
3838
3804
append tmpdir in front
3840
if (*ds_sock.str != FN_LIBCHAR)
3806
if (*ds_sock.c_str() != FN_LIBCHAR)
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);
3849
/* No socket specified, use default */
3850
dynstr_set(&ds_sock, unix_sock);
3854
con_options= ds_options.str;
3815
con_options= ds_options.c_str();
3855
3816
while (*con_options)
3858
3819
/* Step past any spaces in beginning of option*/
3859
3820
while (*con_options && my_isspace(charset_info, *con_options))
3861
3822
/* Find end of this option */
3862
3823
end= con_options;
3863
3824
while (*end && !my_isspace(charset_info, *end))
3885
3848
(int) (sizeof(connections)/sizeof(struct st_connection)));
3888
#ifdef EMBEDDED_LIBRARY
3889
con_slot->query_done= 1;
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,
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;
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*"))
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()))
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;
3921
3881
if (con_slot == next_con)
3922
3882
next_con++; /* if we used the next_con slot, advance the pointer */
4269
4221
/* completed before we pass buf_end */
4270
4222
if ((charlen > 1) && (p + charlen) <= buf_end)
4277
for (i= 1; i < charlen; i++)
4279
if (feof(cur_file->file))
4281
c= my_getc(cur_file->file);
4284
if (! my_ismbchar(charset_info, mb_start, p))
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)
4229
for (i= 1; i < charlen; i++)
4231
if (feof(cur_file->file))
4233
c= my_getc(cur_file->file);
4236
if (! my_ismbchar(charset_info, mb_start, p))
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)
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");
4614
4566
static void print_version(void)
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);
4620
4572
static void usage(void)
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);
4824
4776
size - size of content witten to file
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)
4829
4781
str_to_file2(fname, str, size, false);
4833
void dump_result_to_log_file(char *buf, int size)
4785
void dump_result_to_log_file(const char *buf, int size)
4835
4787
char log_file[FN_REFLEN];
4836
4788
str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
4883
4835
if (!display_result_vertically)
4886
dynstr_append_mem(ds, "\t", 1);
4887
replace_dynstr_append_mem(ds, val, (int)len);
4839
replace_append_mem(ds, val, (int)len);
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);
4845
replace_append_mem(ds, val, (int)len);
4925
4878
Append metadata for fields to output
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)
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");
4937
4890
for (field_end= field+num_fields ;
4938
4891
field < field_end ;
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) ?
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) ?
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);
5051
5003
Run query using DRIZZLE C API
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
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
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)
5068
5020
DRIZZLE_RES *res= 0;
5069
5021
DRIZZLE *drizzle= &cn->drizzle;
5072
5024
if (flags & QUERY_SEND_FLAG)
5077
5029
if (do_send_query(cn, query, query_len, flags))
5079
5031
handle_error(command, drizzle_errno(drizzle), drizzle_error(drizzle),
5080
drizzle_sqlstate(drizzle), ds);
5032
drizzle_sqlstate(drizzle), ds);
5084
#ifdef EMBEDDED_LIBRARY
5086
Here we handle 'reap' command, so we need to check if the
5087
query's thread was finished and probably wait
5089
else if (flags & QUERY_REAP_FLAG)
5090
wait_query_thread_end(cn);
5091
#endif /*EMBEDDED_LIBRARY*/
5092
5036
if (!(flags & QUERY_REAP_FLAG))
5149
5093
if (!disable_warnings && !drizzle_more_results(drizzle))
5151
if (append_warnings(ds_warnings, drizzle) || ds_warnings->length)
5153
dynstr_append_mem(ds, "Warnings:\n", 10);
5154
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
5095
if (append_warnings(ds_warnings, drizzle) || ds_warnings->length())
5097
ds->append("Warnings:\n", 10);
5098
ds->append(ds_warnings->c_str(), ds_warnings->length());
5158
5102
if (!disable_info)
5159
append_info(ds, affected_rows, drizzle_info(drizzle));
5103
append_info(ds, affected_rows, drizzle_info(drizzle));
5247
5190
if (command->expected_errors.count == 1)
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);
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");
5380
5320
if (command->require_file[0])
5382
init_dynamic_string(&ds_result, "", 1024, 1024);
5383
5322
ds= &ds_result;
5389
5329
Log the query into the output buffer
5391
5331
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
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);
5398
5338
if (display_result_sorted)
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
5405
init_dynamic_string(&ds_sorted, "", 1024, 1024);
5406
5345
save_ds= ds; /* Remember original ds */
5407
5346
ds= &ds_sorted;
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);
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);
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);
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));
5559
dynstr_append_mem(&ds_progress, "\n", 1);
5489
ds_progress.append(buf, (int)(end-buf));
5492
ds_progress.append("\n", 1);
5776
5704
/* Check for special property for this query */
5777
5705
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
5781
strmake(command->require_file, save_file, sizeof(save_file) - 1);
5784
run_query(cur_con, command, flags);
5709
strmake(command->require_file, save_file, sizeof(save_file) - 1);
5712
run_query(cur_con, command, flags);
5786
5714
command->last_argument= command->end;
5788
5716
/* Restore settings */
5789
display_result_vertically= old_display_result_vertically;
5717
display_result_vertically= old_display_result_vertically;
5794
5722
if (!*command->first_argument)
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;
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
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.
5814
run_query(cur_con, command, QUERY_SEND_FLAG);
5742
run_query(cur_con, command, QUERY_SEND_FLAG);
5816
5744
command->last_argument= command->end;
5818
5746
case Q_REQUIRE:
5819
do_get_file_name(command, save_file, sizeof(save_file));
5747
do_get_file_name(command, save_file, sizeof(save_file));
5822
5750
do_get_errcodes(command);
5824
5752
case Q_REPLACE:
5825
do_get_replace(command);
5753
do_get_replace(command);
5827
5755
case Q_REPLACE_REGEX:
5828
5756
do_get_replace_regex(command);
5830
5758
case Q_REPLACE_COLUMN:
5831
do_get_replace_column(command);
5759
do_get_replace_column(command);
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:
5837
do_save_master_pos();
5838
if (*command->first_argument)
5839
select_connection(command);
5841
select_connection_name("slave");
5842
do_sync_with_master2(0);
5765
do_save_master_pos();
5766
if (*command->first_argument)
5767
select_connection(command);
5769
select_connection_name("slave");
5770
do_sync_with_master2(0);
5845
5773
case Q_COMMENT: /* Ignore row */
5846
5774
command->last_argument= command->end;
5849
(void) drizzle_ping(&cur_con->drizzle);
5777
(void) drizzle_ping(&cur_con->drizzle);
5855
5783
case Q_START_TIMER:
5856
/* Overwrite possible earlier start of timer */
5857
timer_start= timer_now();
5784
/* Overwrite possible earlier start of timer */
5785
timer_start= timer_now();
5859
5787
case Q_END_TIMER:
5860
/* End timer before ending drizzletest */
5788
/* End timer before ending drizzletest */
5863
5791
case Q_CHARACTER_SET:
5864
do_set_charset(command);
5792
do_set_charset(command);
5866
5794
case Q_DISABLE_RECONNECT:
5867
5795
set_reconnect(&cur_con->drizzle, 0);
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());
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
5978
check_result(&ds_res);
5906
check_result(&ds_res);
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());
6234
6161
if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
6236
6163
/* No match found */
6237
dynstr_append_mem(ds, start, from - start - 1);
6164
ds->append(start, from - start - 1);
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);
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));
6248
6175
if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
6705
6632
internal_set_bit(word_states,states);
6706
6633
if (!from[i][2] && start_states->table_offset == UINT32_MAX)
6708
start_states->table_offset=i;
6709
start_states->found_offset=0;
6635
start_states->table_offset=i;
6636
start_states->found_offset=0;
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);
6718
internal_set_bit(start_states,states);
6645
internal_set_bit(start_states,states);
6720
6647
for (pos=from[i], len=0; *pos ; pos++)
6722
6649
if (*pos == '\\' && *(pos+1))
6727
follow_ptr->chr = SPACE_CHAR;
6730
follow_ptr->chr = START_OF_LINE;
6733
follow_ptr->chr = END_OF_LINE;
6736
follow_ptr->chr = '\r';
6739
follow_ptr->chr = '\t';
6742
follow_ptr->chr = '\v';
6745
follow_ptr->chr = (uchar) *pos;
6654
follow_ptr->chr = SPACE_CHAR;
6657
follow_ptr->chr = START_OF_LINE;
6660
follow_ptr->chr = END_OF_LINE;
6663
follow_ptr->chr = '\r';
6666
follow_ptr->chr = '\t';
6669
follow_ptr->chr = '\v';
6672
follow_ptr->chr = (uchar) *pos;
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;
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)
6716
follow[i].len > 1) || follow[i].chr == END_OF_LINE)
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;
6798
6725
/* Handle other used characters */
6799
6726
for (chr= 0 ; chr < 256 ; chr++)
6801
6728
if (! used_chars[chr])
6802
set->next[chr]= chr ? default_state : -1;
6729
set->next[chr]= chr ? default_state : -1;
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;
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;
6812
for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
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))
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 */
6826
internal_set_bit(new_set,i);
6831
new_set->found_len=0; /* Set for testing if first */
6833
for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
6835
if ((follow[i].chr == SPACE_CHAR ||
6836
follow[i].chr == END_OF_LINE) && ! chr)
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);
6846
if (chr == 0 || !follow[bit_nr].chr)
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;
6859
set->next[chr] = find_found(found_set,
6860
new_set->table_offset,
6861
new_set->found_offset);
6862
free_last_set(&sets);
6865
set->next[chr] = find_set(&sets,new_set);
6868
set->next[chr] = find_set(&sets,new_set);
6739
for (i= UINT32_MAX ; (i=get_next_bit(sets.set+used_sets,i)) ; )
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))
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 */
6753
internal_set_bit(new_set,i);
6758
new_set->found_len=0; /* Set for testing if first */
6760
for (i= UINT32_MAX; (i=get_next_bit(new_set,i)) ;)
6762
if ((follow[i].chr == SPACE_CHAR ||
6763
follow[i].chr == END_OF_LINE) && ! chr)
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);
6773
if (chr == 0 || !follow[bit_nr].chr)
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;
6786
set->next[chr] = find_found(found_set,
6787
new_set->table_offset,
6788
new_set->found_offset);
6789
free_last_set(&sets);
6792
set->next[chr] = find_set(&sets,new_set);
6795
set->next[chr] = find_set(&sets,new_set);
7114
7041
if (! pa->typelib.count)
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))))
7121
7048
if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
7124
7051
my_free((char*) pa->typelib.type_names,MYF(0));
7127
7054
pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+
7129
7056
pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
7131
7058
pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
7192
7119
/* Functions that uses replace and replace_regex */
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)
7125
char *v= strdup(val);
7198
7127
if (glob_replace_regex)
7200
7129
/* Regex replace */
7201
if (!multi_reg_replace(glob_replace_regex, (char*)val))
7130
if (!multi_reg_replace(glob_replace_regex, v))
7203
val= glob_replace_regex->buf;
7132
v= glob_replace_regex->buf;
7208
7137
if (glob_replace)
7210
7139
/* Normal replace */
7211
replace_strings_append(glob_replace, ds, val, len);
7140
replace_strings_append(glob_replace, ds, v, len);
7214
dynstr_append_mem(ds, val, len);
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)
7221
replace_dynstr_append_mem(ds, val, strlen(val));
7152
replace_append_mem(ds, val, strlen(val));
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)
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);
7246
static int comp_lines(const char **a, const char **b)
7248
return (strcmp(*a,*b));
7251
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
7254
char *start= ds_input->str;
7255
DYNAMIC_ARRAY lines;
7179
void append_sorted(string* ds, string *ds_input)
7181
priority_queue<string> lines;
7183
if (ds_input->empty())
7259
7184
return; /* No input */
7261
my_init_dynamic_array(&lines, sizeof(const char*), 32, 32);
7263
/* First line is result header, skip past it */
7264
while (*start && *start != '\n')
7266
start++; /* Skip past \n */
7267
dynstr_append_mem(ds, ds_input->str, start - ds_input->str);
7186
unsigned long eol_pos= 0;
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
7192
ds->append(ds_input->substr(0, eol_pos));
7194
unsigned long start_pos= eol_pos+1;
7269
7196
/* Insert line(s) in array */
7272
char* line_end= (char*)start;
7199
eol_pos= ds_input->find_first_of('\n', start_pos);
7274
7200
/* Find end of line */
7275
while (*line_end && *line_end != '\n')
7279
/* Insert pointer to the line in array */
7280
if (insert_dynamic(&lines, (uchar*) &start))
7281
die("Out of memory inserting lines to sort");
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;
7204
} while ( eol_pos != string::npos);
7290
7206
/* Create new result */
7291
for (i= 0; i < lines.elements ; i++)
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());
7298
delete_dynamic(&lines);