From b7977855e45d53508a8f0d3c48890cc29fc6fa71 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Fri, 29 Sep 2006 11:32:40 +0200 Subject: [PATCH] Add possibility to specify which delimiter to read until in "write_file" and "perl" commands fix memory leaks reported by valgrind --- client/mysqltest.c | 74 +++++++++++++++++++++++++---------- mysql-test/r/mysqltest.result | 4 ++ mysql-test/t/mysqltest.test | 26 ++++++++++++ 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 13d5874628e..d0238fe521f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -16,12 +16,14 @@ /* mysqltest test tool * See the "MySQL Test framework manual" for more information + * http://dev.mysql.com/doc/mysqltest/en/index.html * * Written by: * Sasha Pachev * Matt Wagner * Monty * Jani + * Magnus **/ #define MTEST_VERSION "2.7" @@ -1332,6 +1334,7 @@ static void do_exec(struct st_query *query) query->first_argument, query->expected_errno[0].code.errnum); } + dynstr_free(&ds_cmd); free_replace(); DBUG_VOID_RETURN; } @@ -1757,22 +1760,32 @@ static my_bool match_delimiter(int c, const char* delim, uint length) } -static void read_until_EOF(DYNAMIC_STRING* ds) +static void read_until_delimiter(DYNAMIC_STRING *ds, + DYNAMIC_STRING *ds_delimiter) { int c; - DBUG_ENTER("read_until_EOF"); + DBUG_ENTER("read_until_delimiter"); + DBUG_PRINT("enter", ("delimiter: %s, length: %d", + ds_delimiter->str, ds_delimiter->length)); - /* Read from file until delimiter EOF is found */ + if (ds_delimiter->length > MAX_DELIMITER) + die("Max delimiter length(%d) exceeded", MAX_DELIMITER); + + /* Read from file until delimiter is found */ while (1) { c= my_getc(cur_file->file); - if (feof(cur_file->file)) - die("End of file encountered before 'EOF' delimiter was found"); + if (c == '\n') + cur_file->lineno++; - if (match_delimiter(c, "EOF", 3)) + if (feof(cur_file->file)) + die("End of file encountered before '%s' delimiter was found", + ds_delimiter->str); + + if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length)) { - DBUG_PRINT("exit", ("Found EOF")); + DBUG_PRINT("exit", ("Found delimiter '%s'", ds_delimiter->str)); break; } dynstr_append_mem(ds, (const char*)&c, 1); @@ -1788,7 +1801,7 @@ static void read_until_EOF(DYNAMIC_STRING* ds) command called command DESCRIPTION - write_file ; + write_file []; <...> < what to write line n> @@ -1800,18 +1813,23 @@ static void read_until_EOF(DYNAMIC_STRING* ds) < what to write line n> EOF - Write everything between the "write_file" command and EOF to "file_name" + Write everything between the "write_file" command and 'delimiter' + to "file_name" NOTE! Overwrites existing file + Default is EOF + */ static void do_write_file(struct st_query *command) { DYNAMIC_STRING ds_content; DYNAMIC_STRING ds_filename; + DYNAMIC_STRING ds_delimiter; const struct command_arg write_file_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to write to", + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" }; DBUG_ENTER("do_write_file"); @@ -1820,12 +1838,17 @@ static void do_write_file(struct st_query *command) write_file_args, sizeof(write_file_args)/sizeof(struct command_arg)); + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + init_dynamic_string(&ds_content, "", 1024, 1024); - read_until_EOF(&ds_content); + read_until_delimiter(&ds_content, &ds_delimiter); DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); str_to_file(ds_filename.str, ds_content.str, ds_content.length); dynstr_free(&ds_content); dynstr_free(&ds_filename); + dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -1836,22 +1859,17 @@ static void do_write_file(struct st_query *command) command command handle DESCRIPTION - perl; + perl []; <...> EOF - Execute everything after "perl" until EOF as perl. + Execute everything after "perl" until as perl. Useful for doing more advanced things but still being able to execute it on all platforms. - The function sets delimiter to EOF and remembers that this - is a perl command by setting "perl mode". The following lines - will then be parsed as any normal query, but when searching - for command in get_query_type, this function will be called - again since "perl mode" is on and the perl script can be - executed. + Default is EOF */ static void do_perl(struct st_query *command) @@ -1860,10 +1878,23 @@ static void do_perl(struct st_query *command) char buf[FN_REFLEN]; FILE *res_file; DYNAMIC_STRING ds_script; + DYNAMIC_STRING ds_delimiter; + const struct command_arg perl_args[] = { + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" + }; DBUG_ENTER("do_perl"); + check_command_args(command, + command->first_argument, + perl_args, + sizeof(perl_args)/sizeof(struct command_arg)); + + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + init_dynamic_string(&ds_script, "", 1024, 1024); - read_until_EOF(&ds_script); + read_until_delimiter(&ds_script, &ds_delimiter); DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); @@ -1894,6 +1925,7 @@ static void do_perl(struct st_query *command) error= pclose(res_file); handle_command_error(command, WEXITSTATUS(error)); dynstr_free(&ds_script); + dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -2693,6 +2725,7 @@ static void free_replace_regex() { if (glob_replace_regex) { + delete_dynamic(&glob_replace_regex->regex_arr); my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) glob_replace_regex,MYF(0)); @@ -4163,7 +4196,8 @@ static int reg_replace(char** buf_p, int* buf_len_p, char *pattern, res_p += left_in_str; str_p= str_end; } - } + } + my_free((gptr)subs, MYF(0)); my_regfree(&r); *res_p= 0; *buf_p= buf; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index fdc43e8852b..67634e36ab0 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -478,3 +478,7 @@ mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' hello hello hello +mysqltest: At line 1: Max delimiter length(16) exceeded +hello +hello +End of tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 8aa85937c17..4593955ca54 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1182,6 +1182,18 @@ remove_file non_existing_file; --error 1 --exec echo "write_file filename \";" | $MYSQL_TEST 2>&1 +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +Content for test_file1 +EOF +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp END_DELIMITER; +Content for test_file1 contains EOF +END_DELIMITER +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + # ---------------------------------------------------------------------------- # test for file_exist # ---------------------------------------------------------------------------- @@ -1226,6 +1238,17 @@ remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; print "hello\n"; EOF +--perl EOF +print "hello\n"; +EOF + +--perl DELIMITER +print "hello\n"; +DELIMITER + +--error 1 +--exec echo "perl TOO_LONG_DELIMITER ;" | $MYSQL_TEST 2>&1 + perl; print "hello\n"; EOF @@ -1234,3 +1257,6 @@ perl; # Print "hello" print "hello\n"; EOF + + +--echo End of tests