# # # add_dir "tests/syntax_errors_in_.mtn-ignore" # # add_file "tests/syntax_errors_in_.mtn-ignore/__driver__.lua" # content [40ae692978a4b62a47ad35468cc2e52656a68643] # # add_file "tests/syntax_errors_in_.mtn-ignore/ignore.lua" # content [be1fa03f0468d626df547fe7e8845cc8bd4c7efb] # # add_file "tests/syntax_errors_in_.mtn-ignore/mtn-ignore" # content [3735136dc7e7c64509de51bfb76dbd141d2ae971] # # add_file "tests/syntax_errors_in_.mtn-ignore/stderr-ref" # content [6f474b55e26298e81d8a9365fa5bfd99e580e417] # # add_file "tests/syntax_errors_in_.mtn-ignore/stdout-ref" # content [73bbb241af4f750ff72b0177441ded3d6cb26be4] # # patch "ChangeLog" # from [46322c5ce6d7212ac4d983b7e3ebf934077625e8] # to [634df0a705714eadaa12bd206dc75fb9728956d4] # # patch "lua.cc" # from [584d32c9ad2fd3358d18116d195af8b308c1d469] # to [263bb8fd1c723a448fc03f7632f4b9c9170b686f] # # patch "pcrewrap.cc" # from [5e175ccccd98a56490c4479e634b4547a52eb9e5] # to [dd081644cde0233e19d86e37323b14ff6daf4594] # # patch "std_hooks.lua" # from [51c2c0ca061f8c0ec2ccfaf4b30ead7e8026cc49] # to [8174984c17963cd5aa57748cb3abd90a1be7b8ce] # # patch "testsuite.lua" # from [6586c50e0f73ac0e200f0b0bac97f087da9543c1] # to [b442bbfd5311e6a191225a531e3287aec132856c] # ============================================================ --- tests/syntax_errors_in_.mtn-ignore/__driver__.lua 40ae692978a4b62a47ad35468cc2e52656a68643 +++ tests/syntax_errors_in_.mtn-ignore/__driver__.lua 40ae692978a4b62a47ad35468cc2e52656a68643 @@ -0,0 +1,16 @@ +-- In this test, we put things in .mtn-ignore that trigger every +-- possible syntax error message from the regular expression library, +-- to ensure that the user's view of these errors is sensible. + +mtn_setup() + +writefile("ignoreme") +writefile("dontignoreme") +check(get("mtn-ignore", ".mtn-ignore")) + +check(raw_mtn("ls", "unknown"), 0, true, true) +check(get("stdout-ref")) +check(get("stderr-ref")) + +check(samefile("stdout", "stdout-ref")) +check(samefile("stderr", "stderr-ref")) ============================================================ --- tests/syntax_errors_in_.mtn-ignore/ignore.lua be1fa03f0468d626df547fe7e8845cc8bd4c7efb +++ tests/syntax_errors_in_.mtn-ignore/ignore.lua be1fa03f0468d626df547fe7e8845cc8bd4c7efb @@ -0,0 +1,39 @@ +function ignore_file(name) + -- project specific + io.stderr:write("considering ignoring " .. name .. "\n") + if (ignored_files == nil) then + ignored_files = {} + local ignfile = io.open(".mtn-ignore", "r") + if (ignfile ~= nil) then + for l in ignfile:lines() do table.insert(ignored_files, l) end + ignfile:close() + end + end + local decision = false + for i, line in pairs(ignored_files) + do + if (line ~= nil) then + local pcallstatus, result = pcall(function() return regex.search(line, name) end) + if pcallstatus == true then + -- no error from the regex.search call + if result == true then + io.stderr:write("- ignoring " .. name + .. " due to " .. i .. ", /" .. line .. "/\n") + decision = true + break + end + else + -- regex.search had a problem, warn the user their .mtn-ignore file syntax is wrong + io.stderr:write("WARNING: line " .. i + .. " in your .mtn-ignore file caused error '" + .. result .. "' while matching filename '" .. name + .. "'.\nignoring this regex for all remaining files.\n") + ignored_files[i] = nil + end + end + end + if decision == false then + io.stderr:write("- not ignoring " .. name .. "\n") + end + return decision +end ============================================================ --- tests/syntax_errors_in_.mtn-ignore/mtn-ignore 3735136dc7e7c64509de51bfb76dbd141d2ae971 +++ tests/syntax_errors_in_.mtn-ignore/mtn-ignore 3735136dc7e7c64509de51bfb76dbd141d2ae971 @@ -0,0 +1,32 @@ +\ +\c +x{3,1} +x{99999} +[abc +[z-a] +* +(?h) +[:alpha:] +(abc +abc\3 +(?#abc +) +(?x) +(?P) +\777 +^ignoreme$ ============================================================ --- tests/syntax_errors_in_.mtn-ignore/stderr-ref 6f474b55e26298e81d8a9365fa5bfd99e580e417 +++ tests/syntax_errors_in_.mtn-ignore/stderr-ref 6f474b55e26298e81d8a9365fa5bfd99e580e417 @@ -0,0 +1,63 @@ +mtn: warning: while matching file 'tester.log': +.mtn-ignore:1: warning: error near char 2 of regex "\": \ at end of pattern + - skipping this regex for all remaining files. +.mtn-ignore:2: warning: error near char 1 of regex "\c": \c at end of pattern + - skipping this regex for all remaining files. +.mtn-ignore:3: warning: error near char 6 of regex "x{3,1}": numbers out of order in {} quantifier + - skipping this regex for all remaining files. +.mtn-ignore:4: warning: error near char 8 of regex "x{99999}": number too big in {} quantifier + - skipping this regex for all remaining files. +.mtn-ignore:5: warning: error near char 5 of regex "[abc": missing terminating ] for character class + - skipping this regex for all remaining files. +.mtn-ignore:6: warning: error near char 4 of regex "[z-a]": range out of order in character class + - skipping this regex for all remaining files. +.mtn-ignore:7: warning: error near char 1 of regex "*": nothing to repeat + - skipping this regex for all remaining files. +.mtn-ignore:8: warning: error near char 3 of regex "(?h)": unrecognized character after (? + - skipping this regex for all remaining files. +.mtn-ignore:9: warning: error near char 1 of regex "[:alpha:]": POSIX named classes are supported only within a class + - skipping this regex for all remaining files. +.mtn-ignore:10: warning: error near char 5 of regex "(abc": missing ) + - skipping this regex for all remaining files. +.mtn-ignore:11: warning: error near char 6 of regex "abc\3": reference to non-existent subpattern + - skipping this regex for all remaining files. +.mtn-ignore:12: warning: error near char 7 of regex "(?#abc": missing ) after comment + - skipping this regex for all remaining files. +.mtn-ignore:13: warning: error near char 1 of regex ")": unmatched parentheses + - skipping this regex for all remaining files. +.mtn-ignore:14: warning: error near char 4 of regex "(? 255 + - skipping this regex for all remaining files. +.mtn-ignore:26: warning: error near char 5 of regex "(?C1": closing ) for (?C expected + - skipping this regex for all remaining files. +.mtn-ignore:27: warning: error near char 4 of regex "(?R)": recursive call could loop indefinitely + - skipping this regex for all remaining files. +.mtn-ignore:28: warning: error near char 4 of regex "(?P*)": unrecognized character after (?P + - skipping this regex for all remaining files. +.mtn-ignore:29: warning: error near char 5 of regex "(?P<*>x)": syntax error after (?P + - skipping this regex for all remaining files. +.mtn-ignore:30: warning: error near char 38 of regex "(?P)": subpattern name is too long (maximum 32 characters) + - skipping this regex for all remaining files. +.mtn-ignore:31: warning: error near char 4 of regex "\777": octal value is greater than \377 (not in UTF-8 mode) + - skipping this regex for all remaining files. ============================================================ --- tests/syntax_errors_in_.mtn-ignore/stdout-ref 73bbb241af4f750ff72b0177441ded3d6cb26be4 +++ tests/syntax_errors_in_.mtn-ignore/stdout-ref 73bbb241af4f750ff72b0177441ded3d6cb26be4 @@ -0,0 +1,10 @@ +.mtn-ignore +dontignoreme +keys +keys/address@hidden +min_hooks.lua +test_hooks.lua +tester.log +ts-stderr +ts-stdin +ts-stdout ============================================================ --- ChangeLog 46322c5ce6d7212ac4d983b7e3ebf934077625e8 +++ ChangeLog 634df0a705714eadaa12bd206dc75fb9728956d4 @@ -1,3 +1,15 @@ +2006-12-29 Zack Weinberg + + * pcrewrap.cc (pcre_match_error): Remove "subject" parameter. + All callers changed. + (pcre_compile_error): Improve diagnostics. + * std_hooks.lua (ignore_file): Fix logic to skip malformed regexes + on subsequent calls. Improve diagnostics. + * lua.cc (regex.search): Use bare lua_error, not luaL_error, for + regex compile or match failures. + * tests/syntax_errors_in_.mtn-ignore: New test. + * testsuite.lua: Add it. + 2006-12-27 Zack Weinberg * pcrewrap.hh (pcre::compile_error, pcre::match_error): Simplify. ============================================================ --- lua.cc 584d32c9ad2fd3358d18116d195af8b308c1d469 +++ lua.cc 263bb8fd1c723a448fc03f7632f4b9c9170b686f @@ -551,9 +551,11 @@ LUAEXT(search, regex) try { result = pcre::regex(re).match(str); } catch (pcre::compile_error & e) { - return luaL_error(L, e.what()); + lua_pushstring(L, e.what()); + return lua_error(L); } catch (pcre::match_error & e) { - return luaL_error(L, e.what()); + lua_pushstring(L, e.what()); + return lua_error(L); } lua_pushboolean(L, result); return 1; ============================================================ --- pcrewrap.cc 5e175ccccd98a56490c4479e634b4547a52eb9e5 +++ pcrewrap.cc dd081644cde0233e19d86e37323b14ff6daf4594 @@ -11,7 +11,7 @@ static void pcre_study_error(char const static void pcre_compile_error(char const * err, int erroff, char const * pattern) NORETURN; static void pcre_study_error(char const * err) NORETURN; -static void pcre_match_error(int errcode, string const & subject) NORETURN; +static void pcre_match_error(int errcode) NORETURN; inline unsigned int flags_to_internal(pcre::flags f) @@ -147,7 +147,7 @@ namespace pcre return false; } else - pcre_match_error(rc, subject); + pcre_match_error(rc); } // This overload is for when you don't care about captures, only @@ -170,7 +170,7 @@ namespace pcre else if (rc == PCRE_ERROR_NOMATCH) return false; else - pcre_match_error(rc, subject); + pcre_match_error(rc); } } // namespace pcre @@ -199,10 +199,10 @@ pcre_compile_error(char const *err, int // position-ful variant for all errors, but I'm leaving the == -1 check // here in case PCRE gets fixed. if (erroff == -1) - throw pcre::compile_error(F("Error in regex \"%s\": %s") + throw pcre::compile_error(F("error in regex \"%s\": %s") % pattern % gettext(err)); else - throw pcre::compile_error(F("Error at character %d of regex \"%s\": %s") + throw pcre::compile_error(F("error near char %d of regex \"%s\": %s") % (erroff + 1) % pattern % gettext(err)); } @@ -215,7 +215,7 @@ static void } static void -pcre_match_error(int errcode, string const & subject) +pcre_match_error(int errcode) { // This one actually has error codes! Almost all of which indicate bugs // in monotone. @@ -225,12 +225,11 @@ pcre_match_error(int errcode, string con throw std::bad_alloc(); case PCRE_ERROR_MATCHLIMIT: - throw pcre::match_error(F("backtrack limit exceeded, matching \"%s\"") - % subject); + throw pcre::match_error(F("backtrack limit exceeded")); case PCRE_ERROR_RECURSIONLIMIT: - throw pcre::match_error(F("recursion limit exceeded, matching \"%s\"") - % subject); + throw pcre::match_error(F("recursion limit exceeded")); + default: global_sanity.invariant_failure((FL("pcre_match returned %d") % errcode) .str().c_str(), __FILE__, __LINE__); ============================================================ --- std_hooks.lua 51c2c0ca061f8c0ec2ccfaf4b30ead7e8026cc49 +++ std_hooks.lua 8174984c17963cd5aa57748cb3abd90a1be7b8ce @@ -99,25 +99,33 @@ function ignore_file(name) ignored_files = {} local ignfile = io.open(".mtn-ignore", "r") if (ignfile ~= nil) then - local line = ignfile:read() - while (line ~= nil) do - table.insert(ignored_files, line) - line = ignfile:read() - end - io.close(ignfile) + for l in ignfile:lines() do table.insert(ignored_files, l) end end end + + local warn_reported_file = false for i, line in pairs(ignored_files) do - local pcallstatus, result = pcall(function() return regex.search(line, name) end) - if pcallstatus == true then - -- no error from the regex.search call - if result == true then return true end - else - -- regex.search had a problem, warn the user their .mtn-ignore file syntax is wrong - io.stderr:write("WARNING: the line '" .. line .. "' in your .mtn-ignore file caused error '" .. result .. "'" - .. " while matching filename '" .. name .. "'.\nignoring this regex for all remaining files.\n") - table.remove(ignored_files, i) + if (line ~= nil) then + local pcallstatus, result = pcall(function() + return regex.search(line, name) + end) + if pcallstatus == true then + -- no error from the regex.search call + if result == true then return true end + else + -- regex.search had a problem, warn the user their + -- .mtn-ignore file syntax is wrong + if not warn_reported_file then + io.stderr:write("mtn: warning: while matching file '" + .. name .. "':\n") + warn_reported_file = true + end + io.stderr:write(".mtn-ignore:" .. i .. ": warning: " .. result + .. "\n\t- skipping this regex for " + .. "all remaining files.\n") + ignored_files[i] = nil + end end end ============================================================ --- testsuite.lua 6586c50e0f73ac0e200f0b0bac97f087da9543c1 +++ testsuite.lua b442bbfd5311e6a191225a531e3287aec132856c @@ -691,3 +691,4 @@ table.insert(tests, "spawn_redirected_ho table.insert(tests, "netsync_hook_errcodes") table.insert(tests, "automate_stdio_options") table.insert(tests, "spawn_redirected_hook_helper") +table.insert(tests, "syntax_errors_in_.mtn-ignore")