# # # patch "ChangeLog" # from [053ae7a1e4c83e2758d49a690221e267f8f979ba] # to [6112a7ff07eee44f462e2ecfe5e021f88d22ca82] # # patch "automate.cc" # from [fb0db1dbda16a3056b64570590a919d9dcab9292] # to [60c650f8ded7c4ba0225129600b8517f44eb9731] # # patch "cmd_diff_log.cc" # from [fb75f33c9b28b0d4084395c05202f1f717336677] # to [5b89fe46b77f87f89cb871fb96170dd8a5352fd4] # # patch "cmd_list.cc" # from [cfc890edde48be2b2e6921caa121401c45c5147e] # to [d8d4030f369130dce1f5bd2e9d4218a72d05af33] # # patch "cmd_ws_commit.cc" # from [7ae041351f7337172fa93d9c81867a9bd9651c49] # to [a00894c21c0ae9527f31ccd5531047f32b740f3a] # # patch "restrictions.cc" # from [2519c8819e4c4be1a3bbdbfcfc0598c110cf414f] # to [bb5efc2766f768004afd8a505e122b6b912e1898] # # patch "restrictions.hh" # from [051f3e2ececf3be1ffb28860a4d9d283181190da] # to [d660af577632f975f9c155e11744c7c0f5d0aa44] # # patch "roster.cc" # from [f478f2dca70407b7b277810d8b20177e889e7217] # to [6df282421f592efa3dc67c0e889a1d8abc480fbd] # # patch "roster.hh" # from [0601b6f9e2675eb4082475a47077973d1f03ad2f] # to [7789b477fbc1249740d9ca6a665bd535c6d3a5b8] # # patch "tests/ls_unknown_of_unknown_subdir/__driver__.lua" # from [55ac47ece4bb28da40f6780e2a7c3cbdb101ec67] # to [370a5ef9abba265eda98d3e2c04fe11f74c7f449] # # patch "work.cc" # from [ee392842f0609f5e685d18b26ab2dcad3462ac78] # to [fefb3952854fc1ff54beed99ee9526768f707c5e] # # patch "work.hh" # from [928f220fa9f884a00f71b02a54eae904ba833c3a] # to [6db6ed0ed8317563b0cf56a97925f2bf41f4f07b] # ============================================================ --- ChangeLog 053ae7a1e4c83e2758d49a690221e267f8f979ba +++ ChangeLog 6112a7ff07eee44f462e2ecfe5e021f88d22ca82 @@ -1,3 +1,24 @@ +2006-06-19 Derek Scherger + + * automate.cc (inventory): use path_restriction + * cmd_diff_log.cc (diff,log): + * cmd_list.cc (ls_known,ls_changed): + * cmd_ws_commit.cc (revert,status,commit): use node_restrictions + * restrictions.{cc,hh} (restriction): subclass into ... + (node_restriction): ... this, operating on roster nodes and + validated against roster paths + (path_restriction): ... and this, operating on split paths and + validated against workspace paths ; the unit_tests currently + create directories {x,y}/{x,y} wherever they run to pass workspace + path validation and this should probably be cleaned up + * roster.{cc,hh} (make_restricted_csets, + update_current_roster_from_filesystem, + extract_path_set): use node_restrictions + * work.{cc,hh} (find_missing): use node_restriction + (find_unknown_and_ignored): use path_restriction + * tests/ls_unknown_of_unknown_subdir/__driver__.lua: un-xfail + and add output checks + 2006-06-18 Derek Scherger * cmd_ws_commit.cc (checkout): replace size check with call to ============================================================ --- automate.cc fb0db1dbda16a3056b64570590a919d9dcab9292 +++ automate.cc 60c650f8ded7c4ba0225129600b8517f44eb9731 @@ -672,7 +672,7 @@ classify_roster_paths(curr, unchanged, changed, missing, app); curr.extract_path_set(known); - restriction mask(app); + path_restriction mask(app); file_itemizer u(app, known, unknown, ignored, mask); walk_tree(file_path(), u); ============================================================ --- cmd_diff_log.cc fb75f33c9b28b0d4084395c05202f1f717336677 +++ cmd_diff_log.cc 5b89fe46b77f87f89cb871fb96170dd8a5352fd4 @@ -383,8 +383,8 @@ nis, app); get_revision_id(old_rid); - restriction mask(args, app.exclude_patterns, - old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, @@ -412,7 +412,8 @@ // FIXME: handle no ancestor case // N(r_new.edges.size() == 1, F("current revision has no ancestor")); - restriction mask(args, app.exclude_patterns, old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, @@ -438,7 +439,8 @@ app.db.get_roster(r_old_id, old_roster); app.db.get_roster(r_new_id, new_roster); - restriction mask(args, app.exclude_patterns, old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); // FIXME: this is *possibly* a UI bug, insofar as we // look at the restriction name(s) you provided on the command @@ -585,7 +587,7 @@ } } - restriction mask(app); + node_restriction mask(app); if (args.size() > 0) { @@ -600,11 +602,10 @@ // FIXME_RESTRICTIONS: should this add paths from the rosters of // all selected revs? - mask = restriction(args, app.exclude_patterns, - old_roster, new_roster, app); + mask = node_restriction(args, app.exclude_patterns, + old_roster, new_roster, app); } - cert_name author_name(author_cert_name); cert_name date_name(date_cert_name); cert_name branch_name(branch_cert_name); ============================================================ --- cmd_list.cc cfc890edde48be2b2e6921caa121401c45c5147e +++ cmd_list.cc d8d4030f369130dce1f5bd2e9d4218a72d05af33 @@ -346,7 +346,7 @@ app.require_workspace(); get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, new_roster, app); + node_restriction mask(args, app.exclude_patterns, new_roster, app); node_map const & nodes = new_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); @@ -409,7 +409,8 @@ get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, ============================================================ --- cmd_ws_commit.cc 7ae041351f7337172fa93d9c81867a9bd9651c49 +++ cmd_ws_commit.cc a00894c21c0ae9527f31ccd5531047f32b740f3a @@ -94,7 +94,7 @@ } get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(includes, excludes, old_roster, new_roster, app); + node_restriction mask(includes, excludes, old_roster, new_roster, app); make_restricted_csets(old_roster, new_roster, included, excluded, mask); @@ -333,8 +333,8 @@ app.require_workspace(); get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, - old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, @@ -627,8 +627,8 @@ app.require_workspace(); get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, - old_roster, new_roster, app); + node_restriction mask(args, app.exclude_patterns, + old_roster, new_roster, app); update_current_roster_from_filesystem(new_roster, mask, app); make_restricted_csets(old_roster, new_roster, ============================================================ --- restrictions.cc 2519c8819e4c4be1a3bbdbfcfc0598c110cf414f +++ restrictions.cc bb5efc2766f768004afd8a505e122b6b912e1898 @@ -23,10 +23,11 @@ // TODO: add check for relevant rosters to be used by log // -// i.e. as log goes back through older and older rosters it may hit one that -// pre-dates any of the nodes in the restriction. the nodes that the restriction -// includes or excludes may not have been born in a sufficiently old roster. at -// this point log should stop because no earlier roster will include these nodes. +// i.e. as log goes back through older and older rosters it may hit one +// that pre-dates any of the nodes in the restriction. the nodes that the +// restriction includes or excludes may not have been born in a sufficiently +// old roster. at this point log should stop because no earlier roster will +// include these nodes. static void make_path_set(vector const & args, path_set & paths) @@ -40,84 +41,66 @@ } static void -add_paths(map & path_map, - path_set const & paths, - path_state const state) -{ - for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) - { - map::iterator p = path_map.find(*i); - if (p != path_map.end()) - N(p->second == state, - F("conflicting include/exclude on path '%s'") % *i); - else - path_map.insert(make_pair(*i, state)); - } -} - -static void -add_nodes(map & node_map, +map_nodes(map & node_map, roster_t const & roster, path_set const & paths, - path_set & known, - path_state const state) + path_set & known_paths, + restricted_path::status const status) { for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) { if (roster.has_node(*i)) { - known.insert(*i); + known_paths.insert(*i); node_id nid = roster.get_node(*i)->self; - map::iterator n = node_map.find(nid); + map::iterator n = node_map.find(nid); if (n != node_map.end()) - N(n->second == state, + N(n->second == status, F("conflicting include/exclude on path '%s'") % *i); else - node_map.insert(make_pair(nid, state)); + node_map.insert(make_pair(nid, status)); } } } -//////////////////////////////////////////////////////////////////////////////// -// construction helpers -//////////////////////////////////////////////////////////////////////////////// - -void -restriction::map_paths(vector const & include_args, - vector const & exclude_args) +static void +map_paths(map & path_map, + path_set const & paths, + restricted_path::status const status) { - make_path_set(include_args, included_paths); - make_path_set(exclude_args, excluded_paths); - - add_paths(path_map, included_paths, included); - add_paths(path_map, excluded_paths, excluded); + for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i) + { + map::iterator p = path_map.find(*i); + if (p != path_map.end()) + N(p->second == status, + F("conflicting include/exclude on path '%s'") % *i); + else + path_map.insert(make_pair(*i, status)); + } } -void -restriction::map_nodes(roster_t const & roster) +static void +validate_roster_paths(path_set const & included_paths, + path_set const & excluded_paths, + path_set const & known_paths, + app_state & app) { - add_nodes(node_map, roster, included_paths, known_paths, included); - add_nodes(node_map, roster, excluded_paths, known_paths, excluded); -} - -void -restriction::validate() -{ int bad = 0; for (path_set::const_iterator i = included_paths.begin(); i != included_paths.end(); ++i) { - // ignored paths are allowed into the restriction but are not considered - // invalid if they are found in none of the restriction's rosters + // ignored paths are allowed into the restriction but are not + // considered invalid if they are found in none of the restriction's + // rosters if (known_paths.find(*i) == known_paths.end()) { file_path fp(*i); if (!app.lua.hook_ignore_file(fp)) { bad++; - W(F("unknown path included %s") % *i); + W(F("restriction includes unknown path '%s'") % *i); } } } @@ -128,19 +111,110 @@ if (known_paths.find(*i) == known_paths.end()) { bad++; - W(F("unknown path excluded %s") % *i); + W(F("restriction excludes unknown path '%s'") % *i); } } N(bad == 0, F("%d unknown paths") % bad); } -//////////////////////////////////////////////////////////////////////////////// -// public api -//////////////////////////////////////////////////////////////////////////////// +void +validate_workspace_paths(path_set const & included_paths, + path_set const & excluded_paths, + app_state & app) +{ + int bad = 0; + for (path_set::const_iterator i = included_paths.begin(); + i != included_paths.end(); ++i) + { + if (workspace_root(*i)) + continue; + + // ignored paths are allowed into the restriction but are not + // considered invalid if they are found in none of the restriction's + // rosters + file_path fp(*i); + if (!path_exists(fp) && !app.lua.hook_ignore_file(fp)) + { + bad++; + W(F("restriction includes unknown path '%s'") % *i); + } + } + + for (path_set::const_iterator i = excluded_paths.begin(); + i != excluded_paths.end(); ++i) + { + if (workspace_root(*i)) + continue; + + file_path fp(*i); + if (!path_exists(fp)) + { + bad++; + W(F("restriction excludes unknown path '%s'") % *i); + } + } + + N(bad == 0, F("%d unknown paths") % bad); +} + +restriction::restriction(std::vector const & includes, + std::vector const & excludes, + app_state & a) : + app(a) +{ + make_path_set(includes, included_paths); + make_path_set(excludes, excluded_paths); +} + +node_restriction::node_restriction(std::vector const & includes, + std::vector const & excludes, + roster_t const & roster, + app_state & a) : + restriction(includes, excludes, a) +{ + map_nodes(node_map, roster, included_paths, known_paths, + restricted_path::included); + map_nodes(node_map, roster, excluded_paths, known_paths, + restricted_path::excluded); + + validate_roster_paths(included_paths, excluded_paths, known_paths, app); +} + +node_restriction::node_restriction(std::vector const & includes, + std::vector const & excludes, + roster_t const & roster1, + roster_t const & roster2, + app_state & a) : + restriction(includes, excludes, a) +{ + map_nodes(node_map, roster1, included_paths, known_paths, + restricted_path::included); + map_nodes(node_map, roster1, excluded_paths, known_paths, + restricted_path::excluded); + + map_nodes(node_map, roster2, included_paths, known_paths, + restricted_path::included); + map_nodes(node_map, roster2, excluded_paths, known_paths, + restricted_path::excluded); + + validate_roster_paths(included_paths, excluded_paths, known_paths, app); +} + +path_restriction::path_restriction(std::vector const & includes, + std::vector const & excludes, + app_state & a) : + restriction(includes, excludes, a) +{ + map_paths(path_map, included_paths, restricted_path::included); + map_paths(path_map, excluded_paths, restricted_path::excluded); + + validate_workspace_paths(included_paths, excluded_paths, app); +} + bool -restriction::includes(roster_t const & roster, node_id nid) const +node_restriction::includes(roster_t const & roster, node_id nid) const { MM(roster); I(roster.has_node(nid)); @@ -159,24 +233,28 @@ int depth = 0; // FIXME: this uses app.depth+1 because the old semantics of depth=0 were - // something like "the current directory and its immediate children". it seems - // somewhat more reasonable here to use depth=0 to mean "exactly this - // directory" and depth=1 to mean "this directory and its immediate children" + // something like "the current directory and its immediate children". it + // seems somewhat more reasonable here to use depth=0 to mean "exactly + // this directory" and depth=1 to mean "this directory and its immediate + // children" while (!null_node(current) && (app.depth == -1 || depth <= app.depth + 1)) { - map::const_iterator r = node_map.find(current); + map::const_iterator + r = node_map.find(current); if (r != node_map.end()) { switch (r->second) { - case included: - L(FL("explicit include of nid %d path '%s'") % current % file_path(sp)); + case restricted_path::included: + L(FL("explicit include of nid %d path '%s'") + % current % file_path(sp)); return true; - case excluded: - L(FL("explicit exclude of nid %d path '%s'") % current % file_path(sp)); + case restricted_path::excluded: + L(FL("explicit exclude of nid %d path '%s'") + % current % file_path(sp)); return false; } } @@ -188,18 +266,20 @@ if (included_paths.empty()) { - L(FL("default include of nid %d path '%s'") % nid % file_path(sp)); + L(FL("default include of nid %d path '%s'") + % nid % file_path(sp)); return true; } else { - L(FL("default exclude of nid %d path '%s'") % nid % file_path(sp)); + L(FL("default exclude of nid %d path '%s'") + % nid % file_path(sp)); return false; } } bool -restriction::includes(split_path const & sp) const +path_restriction::includes(split_path const & sp) const { // empty restriction includes everything if (empty()) @@ -212,24 +292,28 @@ int depth = 0; // FIXME: this uses app.depth+1 because the old semantics of depth=0 were - // something like "the current directory and its immediate children". it seems - // somewhat more reasonable here to use depth=0 to mean "exactly this - // directory" and depth=1 to mean "this directory and its immediate children" + // something like "the current directory and its immediate children". it + // seems somewhat more reasonable here to use depth=0 to mean "exactly + // this directory" and depth=1 to mean "this directory and its immediate + // children" while (!current.empty() && (app.depth == -1 || depth <= app.depth + 1)) { - map::const_iterator r = path_map.find(current); + map::const_iterator + r = path_map.find(current); if (r != path_map.end()) { switch (r->second) { - case included: - L(FL("explicit include of path '%s'") % file_path(sp)); + case restricted_path::included: + L(FL("explicit include of path '%s'") + % file_path(sp)); return true; - case excluded: - L(FL("explicit exclude of path '%s'") % file_path(sp)); + case restricted_path::excluded: + L(FL("explicit exclude of path '%s'") + % file_path(sp)); return false; } } @@ -240,19 +324,21 @@ if (included_paths.empty()) { - L(FL("default include of path '%s'") % file_path(sp)); + L(FL("default include of path '%s'") + % file_path(sp)); return true; } else { - L(FL("default exclude of path '%s'") % file_path(sp)); + L(FL("default exclude of path '%s'") + % file_path(sp)); return false; } } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// // tests -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// #ifdef BUILD_UNIT_TESTS #include "app_state.hh" @@ -359,6 +445,15 @@ file_path_internal("y/y/f").split(sp_yyf); file_path_internal("y/y/g").split(sp_yyg); + // these directories must exist for the path_restrictions to be valid. it + // is a bit lame to be creating directories arbitrarily like this. perhaps + // unit_tests should run in a unit_tests.dir or something. + + mkdir_p(file_path_internal("x/x")); + mkdir_p(file_path_internal("x/y")); + mkdir_p(file_path_internal("y/x")); + mkdir_p(file_path_internal("y/y")); + nid_root = roster.create_dir_node(nis); nid_f = roster.create_file_node(fid_f, nis); nid_g = roster.create_file_node(fid_g, nis); @@ -406,6 +501,7 @@ roster.attach_node(nid_yy, sp_yy); roster.attach_node(nid_yyf, sp_yyf); roster.attach_node(nid_yyg, sp_yyg); + } static void @@ -415,59 +511,66 @@ setup(roster); app_state app; - restriction mask(app); - BOOST_CHECK(mask.empty()); - // check restricted nodes - BOOST_CHECK(mask.includes(roster, nid_root)); - BOOST_CHECK(mask.includes(roster, nid_f)); - BOOST_CHECK(mask.includes(roster, nid_g)); - BOOST_CHECK(mask.includes(roster, nid_x)); - BOOST_CHECK(mask.includes(roster, nid_xf)); - BOOST_CHECK(mask.includes(roster, nid_xg)); - BOOST_CHECK(mask.includes(roster, nid_xx)); - BOOST_CHECK(mask.includes(roster, nid_xxf)); - BOOST_CHECK(mask.includes(roster, nid_xxg)); - BOOST_CHECK(mask.includes(roster, nid_xy)); - BOOST_CHECK(mask.includes(roster, nid_xyf)); - BOOST_CHECK(mask.includes(roster, nid_xyg)); + node_restriction nmask(app); - BOOST_CHECK(mask.includes(roster, nid_y)); - BOOST_CHECK(mask.includes(roster, nid_yf)); - BOOST_CHECK(mask.includes(roster, nid_yg)); - BOOST_CHECK(mask.includes(roster, nid_yx)); - BOOST_CHECK(mask.includes(roster, nid_yxf)); - BOOST_CHECK(mask.includes(roster, nid_yxg)); - BOOST_CHECK(mask.includes(roster, nid_yy)); - BOOST_CHECK(mask.includes(roster, nid_yyf)); - BOOST_CHECK(mask.includes(roster, nid_yyg)); + BOOST_CHECK(nmask.empty()); + BOOST_CHECK(nmask.includes(roster, nid_root)); + BOOST_CHECK(nmask.includes(roster, nid_f)); + BOOST_CHECK(nmask.includes(roster, nid_g)); + + BOOST_CHECK(nmask.includes(roster, nid_x)); + BOOST_CHECK(nmask.includes(roster, nid_xf)); + BOOST_CHECK(nmask.includes(roster, nid_xg)); + BOOST_CHECK(nmask.includes(roster, nid_xx)); + BOOST_CHECK(nmask.includes(roster, nid_xxf)); + BOOST_CHECK(nmask.includes(roster, nid_xxg)); + BOOST_CHECK(nmask.includes(roster, nid_xy)); + BOOST_CHECK(nmask.includes(roster, nid_xyf)); + BOOST_CHECK(nmask.includes(roster, nid_xyg)); + + BOOST_CHECK(nmask.includes(roster, nid_y)); + BOOST_CHECK(nmask.includes(roster, nid_yf)); + BOOST_CHECK(nmask.includes(roster, nid_yg)); + BOOST_CHECK(nmask.includes(roster, nid_yx)); + BOOST_CHECK(nmask.includes(roster, nid_yxf)); + BOOST_CHECK(nmask.includes(roster, nid_yxg)); + BOOST_CHECK(nmask.includes(roster, nid_yy)); + BOOST_CHECK(nmask.includes(roster, nid_yyf)); + BOOST_CHECK(nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(mask.includes(sp_root)); - BOOST_CHECK(mask.includes(sp_f)); - BOOST_CHECK(mask.includes(sp_g)); - BOOST_CHECK(mask.includes(sp_x)); - BOOST_CHECK(mask.includes(sp_xf)); - BOOST_CHECK(mask.includes(sp_xg)); - BOOST_CHECK(mask.includes(sp_xx)); - BOOST_CHECK(mask.includes(sp_xxf)); - BOOST_CHECK(mask.includes(sp_xxg)); - BOOST_CHECK(mask.includes(sp_xy)); - BOOST_CHECK(mask.includes(sp_xyf)); - BOOST_CHECK(mask.includes(sp_xyg)); + path_restriction pmask(app); - BOOST_CHECK(mask.includes(sp_y)); - BOOST_CHECK(mask.includes(sp_yf)); - BOOST_CHECK(mask.includes(sp_yg)); - BOOST_CHECK(mask.includes(sp_yx)); - BOOST_CHECK(mask.includes(sp_yxf)); - BOOST_CHECK(mask.includes(sp_yxg)); - BOOST_CHECK(mask.includes(sp_yy)); - BOOST_CHECK(mask.includes(sp_yyf)); - BOOST_CHECK(mask.includes(sp_yyg)); + BOOST_CHECK(pmask.empty()); + + BOOST_CHECK(pmask.includes(sp_root)); + BOOST_CHECK(pmask.includes(sp_f)); + BOOST_CHECK(pmask.includes(sp_g)); + + BOOST_CHECK(pmask.includes(sp_x)); + BOOST_CHECK(pmask.includes(sp_xf)); + BOOST_CHECK(pmask.includes(sp_xg)); + BOOST_CHECK(pmask.includes(sp_xx)); + BOOST_CHECK(pmask.includes(sp_xxf)); + BOOST_CHECK(pmask.includes(sp_xxg)); + BOOST_CHECK(pmask.includes(sp_xy)); + BOOST_CHECK(pmask.includes(sp_xyf)); + BOOST_CHECK(pmask.includes(sp_xyg)); + + BOOST_CHECK(pmask.includes(sp_y)); + BOOST_CHECK(pmask.includes(sp_yf)); + BOOST_CHECK(pmask.includes(sp_yg)); + BOOST_CHECK(pmask.includes(sp_yx)); + BOOST_CHECK(pmask.includes(sp_yxf)); + BOOST_CHECK(pmask.includes(sp_yxg)); + BOOST_CHECK(pmask.includes(sp_yy)); + BOOST_CHECK(pmask.includes(sp_yyf)); + BOOST_CHECK(pmask.includes(sp_yyg)); } static void @@ -481,59 +584,66 @@ includes.push_back(utf8(string("y/y"))); app_state app; - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); - // check restricted nodes - BOOST_CHECK(!mask.includes(roster, nid_root)); - BOOST_CHECK(!mask.includes(roster, nid_f)); - BOOST_CHECK(!mask.includes(roster, nid_g)); - BOOST_CHECK(!mask.includes(roster, nid_x)); - BOOST_CHECK(!mask.includes(roster, nid_xf)); - BOOST_CHECK(!mask.includes(roster, nid_xg)); - BOOST_CHECK( mask.includes(roster, nid_xx)); - BOOST_CHECK( mask.includes(roster, nid_xxf)); - BOOST_CHECK( mask.includes(roster, nid_xxg)); - BOOST_CHECK(!mask.includes(roster, nid_xy)); - BOOST_CHECK(!mask.includes(roster, nid_xyf)); - BOOST_CHECK(!mask.includes(roster, nid_xyg)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK(!mask.includes(roster, nid_y)); - BOOST_CHECK(!mask.includes(roster, nid_yf)); - BOOST_CHECK(!mask.includes(roster, nid_yg)); - BOOST_CHECK(!mask.includes(roster, nid_yx)); - BOOST_CHECK(!mask.includes(roster, nid_yxf)); - BOOST_CHECK(!mask.includes(roster, nid_yxg)); - BOOST_CHECK( mask.includes(roster, nid_yy)); - BOOST_CHECK( mask.includes(roster, nid_yyf)); - BOOST_CHECK( mask.includes(roster, nid_yyg)); + BOOST_CHECK(!nmask.empty()); + BOOST_CHECK(!nmask.includes(roster, nid_root)); + BOOST_CHECK(!nmask.includes(roster, nid_f)); + BOOST_CHECK(!nmask.includes(roster, nid_g)); + + BOOST_CHECK(!nmask.includes(roster, nid_x)); + BOOST_CHECK(!nmask.includes(roster, nid_xf)); + BOOST_CHECK(!nmask.includes(roster, nid_xg)); + BOOST_CHECK( nmask.includes(roster, nid_xx)); + BOOST_CHECK( nmask.includes(roster, nid_xxf)); + BOOST_CHECK( nmask.includes(roster, nid_xxg)); + BOOST_CHECK(!nmask.includes(roster, nid_xy)); + BOOST_CHECK(!nmask.includes(roster, nid_xyf)); + BOOST_CHECK(!nmask.includes(roster, nid_xyg)); + + BOOST_CHECK(!nmask.includes(roster, nid_y)); + BOOST_CHECK(!nmask.includes(roster, nid_yf)); + BOOST_CHECK(!nmask.includes(roster, nid_yg)); + BOOST_CHECK(!nmask.includes(roster, nid_yx)); + BOOST_CHECK(!nmask.includes(roster, nid_yxf)); + BOOST_CHECK(!nmask.includes(roster, nid_yxg)); + BOOST_CHECK( nmask.includes(roster, nid_yy)); + BOOST_CHECK( nmask.includes(roster, nid_yyf)); + BOOST_CHECK( nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(!mask.includes(sp_root)); - BOOST_CHECK(!mask.includes(sp_f)); - BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK(!mask.includes(sp_x)); - BOOST_CHECK(!mask.includes(sp_xf)); - BOOST_CHECK(!mask.includes(sp_xg)); - BOOST_CHECK( mask.includes(sp_xx)); - BOOST_CHECK( mask.includes(sp_xxf)); - BOOST_CHECK( mask.includes(sp_xxg)); - BOOST_CHECK(!mask.includes(sp_xy)); - BOOST_CHECK(!mask.includes(sp_xyf)); - BOOST_CHECK(!mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK(!mask.includes(sp_y)); - BOOST_CHECK(!mask.includes(sp_yf)); - BOOST_CHECK(!mask.includes(sp_yg)); - BOOST_CHECK(!mask.includes(sp_yx)); - BOOST_CHECK(!mask.includes(sp_yxf)); - BOOST_CHECK(!mask.includes(sp_yxg)); - BOOST_CHECK( mask.includes(sp_yy)); - BOOST_CHECK( mask.includes(sp_yyf)); - BOOST_CHECK( mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK(!pmask.includes(sp_root)); + BOOST_CHECK(!pmask.includes(sp_f)); + BOOST_CHECK(!pmask.includes(sp_g)); + + BOOST_CHECK(!pmask.includes(sp_x)); + BOOST_CHECK(!pmask.includes(sp_xf)); + BOOST_CHECK(!pmask.includes(sp_xg)); + BOOST_CHECK( pmask.includes(sp_xx)); + BOOST_CHECK( pmask.includes(sp_xxf)); + BOOST_CHECK( pmask.includes(sp_xxg)); + BOOST_CHECK(!pmask.includes(sp_xy)); + BOOST_CHECK(!pmask.includes(sp_xyf)); + BOOST_CHECK(!pmask.includes(sp_xyg)); + + BOOST_CHECK(!pmask.includes(sp_y)); + BOOST_CHECK(!pmask.includes(sp_yf)); + BOOST_CHECK(!pmask.includes(sp_yg)); + BOOST_CHECK(!pmask.includes(sp_yx)); + BOOST_CHECK(!pmask.includes(sp_yxf)); + BOOST_CHECK(!pmask.includes(sp_yxg)); + BOOST_CHECK( pmask.includes(sp_yy)); + BOOST_CHECK( pmask.includes(sp_yyf)); + BOOST_CHECK( pmask.includes(sp_yyg)); } static void @@ -547,59 +657,66 @@ excludes.push_back(utf8(string("y/y"))); app_state app; - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); + // check restricted nodes - // check restricted nodes - BOOST_CHECK( mask.includes(roster, nid_root)); - BOOST_CHECK( mask.includes(roster, nid_f)); - BOOST_CHECK( mask.includes(roster, nid_g)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK( mask.includes(roster, nid_x)); - BOOST_CHECK( mask.includes(roster, nid_xf)); - BOOST_CHECK( mask.includes(roster, nid_xg)); - BOOST_CHECK(!mask.includes(roster, nid_xx)); - BOOST_CHECK(!mask.includes(roster, nid_xxf)); - BOOST_CHECK(!mask.includes(roster, nid_xxg)); - BOOST_CHECK( mask.includes(roster, nid_xy)); - BOOST_CHECK( mask.includes(roster, nid_xyf)); - BOOST_CHECK( mask.includes(roster, nid_xyg)); + BOOST_CHECK(!nmask.empty()); - BOOST_CHECK( mask.includes(roster, nid_y)); - BOOST_CHECK( mask.includes(roster, nid_yf)); - BOOST_CHECK( mask.includes(roster, nid_yg)); - BOOST_CHECK( mask.includes(roster, nid_yx)); - BOOST_CHECK( mask.includes(roster, nid_yxf)); - BOOST_CHECK( mask.includes(roster, nid_yxg)); - BOOST_CHECK(!mask.includes(roster, nid_yy)); - BOOST_CHECK(!mask.includes(roster, nid_yyf)); - BOOST_CHECK(!mask.includes(roster, nid_yyg)); + BOOST_CHECK( nmask.includes(roster, nid_root)); + BOOST_CHECK( nmask.includes(roster, nid_f)); + BOOST_CHECK( nmask.includes(roster, nid_g)); + BOOST_CHECK( nmask.includes(roster, nid_x)); + BOOST_CHECK( nmask.includes(roster, nid_xf)); + BOOST_CHECK( nmask.includes(roster, nid_xg)); + BOOST_CHECK(!nmask.includes(roster, nid_xx)); + BOOST_CHECK(!nmask.includes(roster, nid_xxf)); + BOOST_CHECK(!nmask.includes(roster, nid_xxg)); + BOOST_CHECK( nmask.includes(roster, nid_xy)); + BOOST_CHECK( nmask.includes(roster, nid_xyf)); + BOOST_CHECK( nmask.includes(roster, nid_xyg)); + + BOOST_CHECK( nmask.includes(roster, nid_y)); + BOOST_CHECK( nmask.includes(roster, nid_yf)); + BOOST_CHECK( nmask.includes(roster, nid_yg)); + BOOST_CHECK( nmask.includes(roster, nid_yx)); + BOOST_CHECK( nmask.includes(roster, nid_yxf)); + BOOST_CHECK( nmask.includes(roster, nid_yxg)); + BOOST_CHECK(!nmask.includes(roster, nid_yy)); + BOOST_CHECK(!nmask.includes(roster, nid_yyf)); + BOOST_CHECK(!nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK( mask.includes(sp_root)); - BOOST_CHECK( mask.includes(sp_f)); - BOOST_CHECK( mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); - BOOST_CHECK( mask.includes(sp_xf)); - BOOST_CHECK( mask.includes(sp_xg)); - BOOST_CHECK(!mask.includes(sp_xx)); - BOOST_CHECK(!mask.includes(sp_xxf)); - BOOST_CHECK(!mask.includes(sp_xxg)); - BOOST_CHECK( mask.includes(sp_xy)); - BOOST_CHECK( mask.includes(sp_xyf)); - BOOST_CHECK( mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK( mask.includes(sp_y)); - BOOST_CHECK( mask.includes(sp_yf)); - BOOST_CHECK( mask.includes(sp_yg)); - BOOST_CHECK( mask.includes(sp_yx)); - BOOST_CHECK( mask.includes(sp_yxf)); - BOOST_CHECK( mask.includes(sp_yxg)); - BOOST_CHECK(!mask.includes(sp_yy)); - BOOST_CHECK(!mask.includes(sp_yyf)); - BOOST_CHECK(!mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK( pmask.includes(sp_root)); + BOOST_CHECK( pmask.includes(sp_f)); + BOOST_CHECK( pmask.includes(sp_g)); + + BOOST_CHECK( pmask.includes(sp_x)); + BOOST_CHECK( pmask.includes(sp_xf)); + BOOST_CHECK( pmask.includes(sp_xg)); + BOOST_CHECK(!pmask.includes(sp_xx)); + BOOST_CHECK(!pmask.includes(sp_xxf)); + BOOST_CHECK(!pmask.includes(sp_xxg)); + BOOST_CHECK( pmask.includes(sp_xy)); + BOOST_CHECK( pmask.includes(sp_xyf)); + BOOST_CHECK( pmask.includes(sp_xyg)); + + BOOST_CHECK( pmask.includes(sp_y)); + BOOST_CHECK( pmask.includes(sp_yf)); + BOOST_CHECK( pmask.includes(sp_yg)); + BOOST_CHECK( pmask.includes(sp_yx)); + BOOST_CHECK( pmask.includes(sp_yxf)); + BOOST_CHECK( pmask.includes(sp_yxg)); + BOOST_CHECK(!pmask.includes(sp_yy)); + BOOST_CHECK(!pmask.includes(sp_yyf)); + BOOST_CHECK(!pmask.includes(sp_yyg)); } static void @@ -615,59 +732,66 @@ excludes.push_back(utf8(string("y/y"))); app_state app; - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); - // check restricted nodes - BOOST_CHECK(!mask.includes(roster, nid_root)); - BOOST_CHECK(!mask.includes(roster, nid_f)); - BOOST_CHECK(!mask.includes(roster, nid_g)); - BOOST_CHECK( mask.includes(roster, nid_x)); - BOOST_CHECK( mask.includes(roster, nid_xf)); - BOOST_CHECK( mask.includes(roster, nid_xg)); - BOOST_CHECK(!mask.includes(roster, nid_xx)); - BOOST_CHECK(!mask.includes(roster, nid_xxf)); - BOOST_CHECK(!mask.includes(roster, nid_xxg)); - BOOST_CHECK( mask.includes(roster, nid_xy)); - BOOST_CHECK( mask.includes(roster, nid_xyf)); - BOOST_CHECK( mask.includes(roster, nid_xyg)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK( mask.includes(roster, nid_y)); - BOOST_CHECK( mask.includes(roster, nid_yf)); - BOOST_CHECK( mask.includes(roster, nid_yg)); - BOOST_CHECK( mask.includes(roster, nid_yx)); - BOOST_CHECK( mask.includes(roster, nid_yxf)); - BOOST_CHECK( mask.includes(roster, nid_yxg)); - BOOST_CHECK(!mask.includes(roster, nid_yy)); - BOOST_CHECK(!mask.includes(roster, nid_yyf)); - BOOST_CHECK(!mask.includes(roster, nid_yyg)); + BOOST_CHECK(!nmask.empty()); + BOOST_CHECK(!nmask.includes(roster, nid_root)); + BOOST_CHECK(!nmask.includes(roster, nid_f)); + BOOST_CHECK(!nmask.includes(roster, nid_g)); + + BOOST_CHECK( nmask.includes(roster, nid_x)); + BOOST_CHECK( nmask.includes(roster, nid_xf)); + BOOST_CHECK( nmask.includes(roster, nid_xg)); + BOOST_CHECK(!nmask.includes(roster, nid_xx)); + BOOST_CHECK(!nmask.includes(roster, nid_xxf)); + BOOST_CHECK(!nmask.includes(roster, nid_xxg)); + BOOST_CHECK( nmask.includes(roster, nid_xy)); + BOOST_CHECK( nmask.includes(roster, nid_xyf)); + BOOST_CHECK( nmask.includes(roster, nid_xyg)); + + BOOST_CHECK( nmask.includes(roster, nid_y)); + BOOST_CHECK( nmask.includes(roster, nid_yf)); + BOOST_CHECK( nmask.includes(roster, nid_yg)); + BOOST_CHECK( nmask.includes(roster, nid_yx)); + BOOST_CHECK( nmask.includes(roster, nid_yxf)); + BOOST_CHECK( nmask.includes(roster, nid_yxg)); + BOOST_CHECK(!nmask.includes(roster, nid_yy)); + BOOST_CHECK(!nmask.includes(roster, nid_yyf)); + BOOST_CHECK(!nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(!mask.includes(sp_root)); - BOOST_CHECK(!mask.includes(sp_f)); - BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); - BOOST_CHECK( mask.includes(sp_xf)); - BOOST_CHECK( mask.includes(sp_xg)); - BOOST_CHECK(!mask.includes(sp_xx)); - BOOST_CHECK(!mask.includes(sp_xxf)); - BOOST_CHECK(!mask.includes(sp_xxg)); - BOOST_CHECK( mask.includes(sp_xy)); - BOOST_CHECK( mask.includes(sp_xyf)); - BOOST_CHECK( mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK( mask.includes(sp_y)); - BOOST_CHECK( mask.includes(sp_yf)); - BOOST_CHECK( mask.includes(sp_yg)); - BOOST_CHECK( mask.includes(sp_yx)); - BOOST_CHECK( mask.includes(sp_yxf)); - BOOST_CHECK( mask.includes(sp_yxg)); - BOOST_CHECK(!mask.includes(sp_yy)); - BOOST_CHECK(!mask.includes(sp_yyf)); - BOOST_CHECK(!mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK(!pmask.includes(sp_root)); + BOOST_CHECK(!pmask.includes(sp_f)); + BOOST_CHECK(!pmask.includes(sp_g)); + + BOOST_CHECK( pmask.includes(sp_x)); + BOOST_CHECK( pmask.includes(sp_xf)); + BOOST_CHECK( pmask.includes(sp_xg)); + BOOST_CHECK(!pmask.includes(sp_xx)); + BOOST_CHECK(!pmask.includes(sp_xxf)); + BOOST_CHECK(!pmask.includes(sp_xxg)); + BOOST_CHECK( pmask.includes(sp_xy)); + BOOST_CHECK( pmask.includes(sp_xyf)); + BOOST_CHECK( pmask.includes(sp_xyg)); + + BOOST_CHECK( pmask.includes(sp_y)); + BOOST_CHECK( pmask.includes(sp_yf)); + BOOST_CHECK( pmask.includes(sp_yg)); + BOOST_CHECK( pmask.includes(sp_yx)); + BOOST_CHECK( pmask.includes(sp_yxf)); + BOOST_CHECK( pmask.includes(sp_yxg)); + BOOST_CHECK(!pmask.includes(sp_yy)); + BOOST_CHECK(!pmask.includes(sp_yyf)); + BOOST_CHECK(!pmask.includes(sp_yyg)); } static void @@ -686,63 +810,70 @@ includes.push_back(utf8(string("y/y"))); app_state app; - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); + // check restricted nodes - // check restricted nodes - BOOST_CHECK(!mask.includes(roster, nid_root)); - BOOST_CHECK(!mask.includes(roster, nid_f)); - BOOST_CHECK(!mask.includes(roster, nid_g)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK(!mask.includes(roster, nid_x)); - BOOST_CHECK(!mask.includes(roster, nid_xf)); - BOOST_CHECK(!mask.includes(roster, nid_xg)); - BOOST_CHECK( mask.includes(roster, nid_xx)); - BOOST_CHECK( mask.includes(roster, nid_xxf)); - BOOST_CHECK( mask.includes(roster, nid_xxg)); - BOOST_CHECK(!mask.includes(roster, nid_xy)); - BOOST_CHECK(!mask.includes(roster, nid_xyf)); - BOOST_CHECK(!mask.includes(roster, nid_xyg)); + BOOST_CHECK(!nmask.empty()); - BOOST_CHECK(!mask.includes(roster, nid_y)); - BOOST_CHECK(!mask.includes(roster, nid_yf)); - BOOST_CHECK(!mask.includes(roster, nid_yg)); - BOOST_CHECK(!mask.includes(roster, nid_yx)); - BOOST_CHECK(!mask.includes(roster, nid_yxf)); - BOOST_CHECK(!mask.includes(roster, nid_yxg)); - BOOST_CHECK( mask.includes(roster, nid_yy)); - BOOST_CHECK( mask.includes(roster, nid_yyf)); - BOOST_CHECK( mask.includes(roster, nid_yyg)); + BOOST_CHECK(!nmask.includes(roster, nid_root)); + BOOST_CHECK(!nmask.includes(roster, nid_f)); + BOOST_CHECK(!nmask.includes(roster, nid_g)); + BOOST_CHECK(!nmask.includes(roster, nid_x)); + BOOST_CHECK(!nmask.includes(roster, nid_xf)); + BOOST_CHECK(!nmask.includes(roster, nid_xg)); + BOOST_CHECK( nmask.includes(roster, nid_xx)); + BOOST_CHECK( nmask.includes(roster, nid_xxf)); + BOOST_CHECK( nmask.includes(roster, nid_xxg)); + BOOST_CHECK(!nmask.includes(roster, nid_xy)); + BOOST_CHECK(!nmask.includes(roster, nid_xyf)); + BOOST_CHECK(!nmask.includes(roster, nid_xyg)); + + BOOST_CHECK(!nmask.includes(roster, nid_y)); + BOOST_CHECK(!nmask.includes(roster, nid_yf)); + BOOST_CHECK(!nmask.includes(roster, nid_yg)); + BOOST_CHECK(!nmask.includes(roster, nid_yx)); + BOOST_CHECK(!nmask.includes(roster, nid_yxf)); + BOOST_CHECK(!nmask.includes(roster, nid_yxg)); + BOOST_CHECK( nmask.includes(roster, nid_yy)); + BOOST_CHECK( nmask.includes(roster, nid_yyf)); + BOOST_CHECK( nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(!mask.includes(sp_root)); - BOOST_CHECK(!mask.includes(sp_f)); - BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK(!mask.includes(sp_x)); - BOOST_CHECK(!mask.includes(sp_xf)); - BOOST_CHECK(!mask.includes(sp_xg)); - BOOST_CHECK( mask.includes(sp_xx)); - BOOST_CHECK( mask.includes(sp_xxf)); - BOOST_CHECK( mask.includes(sp_xxg)); - BOOST_CHECK(!mask.includes(sp_xy)); - BOOST_CHECK(!mask.includes(sp_xyf)); - BOOST_CHECK(!mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK(!mask.includes(sp_y)); - BOOST_CHECK(!mask.includes(sp_yf)); - BOOST_CHECK(!mask.includes(sp_yg)); - BOOST_CHECK(!mask.includes(sp_yx)); - BOOST_CHECK(!mask.includes(sp_yxf)); - BOOST_CHECK(!mask.includes(sp_yxg)); - BOOST_CHECK( mask.includes(sp_yy)); - BOOST_CHECK( mask.includes(sp_yyf)); - BOOST_CHECK( mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK(!pmask.includes(sp_root)); + BOOST_CHECK(!pmask.includes(sp_f)); + BOOST_CHECK(!pmask.includes(sp_g)); + + BOOST_CHECK(!pmask.includes(sp_x)); + BOOST_CHECK(!pmask.includes(sp_xf)); + BOOST_CHECK(!pmask.includes(sp_xg)); + BOOST_CHECK( pmask.includes(sp_xx)); + BOOST_CHECK( pmask.includes(sp_xxf)); + BOOST_CHECK( pmask.includes(sp_xxg)); + BOOST_CHECK(!pmask.includes(sp_xy)); + BOOST_CHECK(!pmask.includes(sp_xyf)); + BOOST_CHECK(!pmask.includes(sp_xyg)); + + BOOST_CHECK(!pmask.includes(sp_y)); + BOOST_CHECK(!pmask.includes(sp_yf)); + BOOST_CHECK(!pmask.includes(sp_yg)); + BOOST_CHECK(!pmask.includes(sp_yx)); + BOOST_CHECK(!pmask.includes(sp_yxf)); + BOOST_CHECK(!pmask.includes(sp_yxg)); + BOOST_CHECK( pmask.includes(sp_yy)); + BOOST_CHECK( pmask.includes(sp_yyf)); + BOOST_CHECK( pmask.includes(sp_yyg)); } static void -test_invalid_paths() +test_invalid_roster_paths() { roster_t roster; setup(roster); @@ -752,10 +883,26 @@ excludes.push_back(utf8(string("bar"))); app_state app; - BOOST_CHECK_THROW(restriction(includes, excludes, roster, app), informative_failure); + BOOST_CHECK_THROW(node_restriction(includes, excludes, roster, app), + informative_failure); } static void +test_invalid_workspace_paths() +{ + roster_t roster; + setup(roster); + + vector includes, excludes; + includes.push_back(utf8(string("foo"))); + excludes.push_back(utf8(string("bar"))); + + app_state app; + BOOST_CHECK_THROW(path_restriction(includes, excludes, app), + informative_failure); +} + +static void test_include_depth_0() { roster_t roster; @@ -770,59 +917,66 @@ // this should be changed to mean just the named directory but for // compatibility with old restrictions this behaviour has been preserved app.set_depth(0); - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); + // check restricted nodes - // check restricted nodes - BOOST_CHECK(!mask.includes(roster, nid_root)); - BOOST_CHECK(!mask.includes(roster, nid_f)); - BOOST_CHECK(!mask.includes(roster, nid_g)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK( mask.includes(roster, nid_x)); - BOOST_CHECK( mask.includes(roster, nid_xf)); - BOOST_CHECK( mask.includes(roster, nid_xg)); - BOOST_CHECK( mask.includes(roster, nid_xx)); - BOOST_CHECK(!mask.includes(roster, nid_xxf)); - BOOST_CHECK(!mask.includes(roster, nid_xxg)); - BOOST_CHECK( mask.includes(roster, nid_xy)); - BOOST_CHECK(!mask.includes(roster, nid_xyf)); - BOOST_CHECK(!mask.includes(roster, nid_xyg)); + BOOST_CHECK(!nmask.empty()); - BOOST_CHECK( mask.includes(roster, nid_y)); - BOOST_CHECK( mask.includes(roster, nid_yf)); - BOOST_CHECK( mask.includes(roster, nid_yg)); - BOOST_CHECK( mask.includes(roster, nid_yx)); - BOOST_CHECK(!mask.includes(roster, nid_yxf)); - BOOST_CHECK(!mask.includes(roster, nid_yxg)); - BOOST_CHECK( mask.includes(roster, nid_yy)); - BOOST_CHECK(!mask.includes(roster, nid_yyf)); - BOOST_CHECK(!mask.includes(roster, nid_yyg)); + BOOST_CHECK(!nmask.includes(roster, nid_root)); + BOOST_CHECK(!nmask.includes(roster, nid_f)); + BOOST_CHECK(!nmask.includes(roster, nid_g)); + BOOST_CHECK( nmask.includes(roster, nid_x)); + BOOST_CHECK( nmask.includes(roster, nid_xf)); + BOOST_CHECK( nmask.includes(roster, nid_xg)); + BOOST_CHECK( nmask.includes(roster, nid_xx)); + BOOST_CHECK(!nmask.includes(roster, nid_xxf)); + BOOST_CHECK(!nmask.includes(roster, nid_xxg)); + BOOST_CHECK( nmask.includes(roster, nid_xy)); + BOOST_CHECK(!nmask.includes(roster, nid_xyf)); + BOOST_CHECK(!nmask.includes(roster, nid_xyg)); + + BOOST_CHECK( nmask.includes(roster, nid_y)); + BOOST_CHECK( nmask.includes(roster, nid_yf)); + BOOST_CHECK( nmask.includes(roster, nid_yg)); + BOOST_CHECK( nmask.includes(roster, nid_yx)); + BOOST_CHECK(!nmask.includes(roster, nid_yxf)); + BOOST_CHECK(!nmask.includes(roster, nid_yxg)); + BOOST_CHECK( nmask.includes(roster, nid_yy)); + BOOST_CHECK(!nmask.includes(roster, nid_yyf)); + BOOST_CHECK(!nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(!mask.includes(sp_root)); - BOOST_CHECK(!mask.includes(sp_f)); - BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); - BOOST_CHECK( mask.includes(sp_xf)); - BOOST_CHECK( mask.includes(sp_xg)); - BOOST_CHECK( mask.includes(sp_xx)); - BOOST_CHECK(!mask.includes(sp_xxf)); - BOOST_CHECK(!mask.includes(sp_xxg)); - BOOST_CHECK( mask.includes(sp_xy)); - BOOST_CHECK(!mask.includes(sp_xyf)); - BOOST_CHECK(!mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK( mask.includes(sp_y)); - BOOST_CHECK( mask.includes(sp_yf)); - BOOST_CHECK( mask.includes(sp_yg)); - BOOST_CHECK( mask.includes(sp_yx)); - BOOST_CHECK(!mask.includes(sp_yxf)); - BOOST_CHECK(!mask.includes(sp_yxg)); - BOOST_CHECK( mask.includes(sp_yy)); - BOOST_CHECK(!mask.includes(sp_yyf)); - BOOST_CHECK(!mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK(!pmask.includes(sp_root)); + BOOST_CHECK(!pmask.includes(sp_f)); + BOOST_CHECK(!pmask.includes(sp_g)); + + BOOST_CHECK( pmask.includes(sp_x)); + BOOST_CHECK( pmask.includes(sp_xf)); + BOOST_CHECK( pmask.includes(sp_xg)); + BOOST_CHECK( pmask.includes(sp_xx)); + BOOST_CHECK(!pmask.includes(sp_xxf)); + BOOST_CHECK(!pmask.includes(sp_xxg)); + BOOST_CHECK( pmask.includes(sp_xy)); + BOOST_CHECK(!pmask.includes(sp_xyf)); + BOOST_CHECK(!pmask.includes(sp_xyg)); + + BOOST_CHECK( pmask.includes(sp_y)); + BOOST_CHECK( pmask.includes(sp_yf)); + BOOST_CHECK( pmask.includes(sp_yg)); + BOOST_CHECK( pmask.includes(sp_yx)); + BOOST_CHECK(!pmask.includes(sp_yxf)); + BOOST_CHECK(!pmask.includes(sp_yxg)); + BOOST_CHECK( pmask.includes(sp_yy)); + BOOST_CHECK(!pmask.includes(sp_yyf)); + BOOST_CHECK(!pmask.includes(sp_yyg)); } static void @@ -840,59 +994,66 @@ // this should be changed to mean directory + immediate children but for // compatibility with old restrictions this behaviour has been preserved app.set_depth(1); - restriction mask(includes, excludes, roster, app); - BOOST_CHECK(!mask.empty()); + // check restricted nodes - // check restricted nodes - BOOST_CHECK(!mask.includes(roster, nid_root)); - BOOST_CHECK(!mask.includes(roster, nid_f)); - BOOST_CHECK(!mask.includes(roster, nid_g)); + node_restriction nmask(includes, excludes, roster, app); - BOOST_CHECK( mask.includes(roster, nid_x)); - BOOST_CHECK( mask.includes(roster, nid_xf)); - BOOST_CHECK( mask.includes(roster, nid_xg)); - BOOST_CHECK( mask.includes(roster, nid_xx)); - BOOST_CHECK( mask.includes(roster, nid_xxf)); - BOOST_CHECK( mask.includes(roster, nid_xxg)); - BOOST_CHECK( mask.includes(roster, nid_xy)); - BOOST_CHECK( mask.includes(roster, nid_xyf)); - BOOST_CHECK( mask.includes(roster, nid_xyg)); + BOOST_CHECK(!nmask.empty()); - BOOST_CHECK( mask.includes(roster, nid_y)); - BOOST_CHECK( mask.includes(roster, nid_yf)); - BOOST_CHECK( mask.includes(roster, nid_yg)); - BOOST_CHECK( mask.includes(roster, nid_yx)); - BOOST_CHECK( mask.includes(roster, nid_yxf)); - BOOST_CHECK( mask.includes(roster, nid_yxg)); - BOOST_CHECK( mask.includes(roster, nid_yy)); - BOOST_CHECK( mask.includes(roster, nid_yyf)); - BOOST_CHECK( mask.includes(roster, nid_yyg)); + BOOST_CHECK(!nmask.includes(roster, nid_root)); + BOOST_CHECK(!nmask.includes(roster, nid_f)); + BOOST_CHECK(!nmask.includes(roster, nid_g)); + BOOST_CHECK( nmask.includes(roster, nid_x)); + BOOST_CHECK( nmask.includes(roster, nid_xf)); + BOOST_CHECK( nmask.includes(roster, nid_xg)); + BOOST_CHECK( nmask.includes(roster, nid_xx)); + BOOST_CHECK( nmask.includes(roster, nid_xxf)); + BOOST_CHECK( nmask.includes(roster, nid_xxg)); + BOOST_CHECK( nmask.includes(roster, nid_xy)); + BOOST_CHECK( nmask.includes(roster, nid_xyf)); + BOOST_CHECK( nmask.includes(roster, nid_xyg)); + + BOOST_CHECK( nmask.includes(roster, nid_y)); + BOOST_CHECK( nmask.includes(roster, nid_yf)); + BOOST_CHECK( nmask.includes(roster, nid_yg)); + BOOST_CHECK( nmask.includes(roster, nid_yx)); + BOOST_CHECK( nmask.includes(roster, nid_yxf)); + BOOST_CHECK( nmask.includes(roster, nid_yxg)); + BOOST_CHECK( nmask.includes(roster, nid_yy)); + BOOST_CHECK( nmask.includes(roster, nid_yyf)); + BOOST_CHECK( nmask.includes(roster, nid_yyg)); + // check restricted paths - BOOST_CHECK(!mask.includes(sp_root)); - BOOST_CHECK(!mask.includes(sp_f)); - BOOST_CHECK(!mask.includes(sp_g)); - BOOST_CHECK( mask.includes(sp_x)); - BOOST_CHECK( mask.includes(sp_xf)); - BOOST_CHECK( mask.includes(sp_xg)); - BOOST_CHECK( mask.includes(sp_xx)); - BOOST_CHECK( mask.includes(sp_xxf)); - BOOST_CHECK( mask.includes(sp_xxg)); - BOOST_CHECK( mask.includes(sp_xy)); - BOOST_CHECK( mask.includes(sp_xyf)); - BOOST_CHECK( mask.includes(sp_xyg)); + path_restriction pmask(includes, excludes, app); - BOOST_CHECK( mask.includes(sp_y)); - BOOST_CHECK( mask.includes(sp_yf)); - BOOST_CHECK( mask.includes(sp_yg)); - BOOST_CHECK( mask.includes(sp_yx)); - BOOST_CHECK( mask.includes(sp_yxf)); - BOOST_CHECK( mask.includes(sp_yxg)); - BOOST_CHECK( mask.includes(sp_yy)); - BOOST_CHECK( mask.includes(sp_yyf)); - BOOST_CHECK( mask.includes(sp_yyg)); + BOOST_CHECK(!pmask.empty()); + + BOOST_CHECK(!pmask.includes(sp_root)); + BOOST_CHECK(!pmask.includes(sp_f)); + BOOST_CHECK(!pmask.includes(sp_g)); + + BOOST_CHECK( pmask.includes(sp_x)); + BOOST_CHECK( pmask.includes(sp_xf)); + BOOST_CHECK( pmask.includes(sp_xg)); + BOOST_CHECK( pmask.includes(sp_xx)); + BOOST_CHECK( pmask.includes(sp_xxf)); + BOOST_CHECK( pmask.includes(sp_xxg)); + BOOST_CHECK( pmask.includes(sp_xy)); + BOOST_CHECK( pmask.includes(sp_xyf)); + BOOST_CHECK( pmask.includes(sp_xyg)); + + BOOST_CHECK( pmask.includes(sp_y)); + BOOST_CHECK( pmask.includes(sp_yf)); + BOOST_CHECK( pmask.includes(sp_yg)); + BOOST_CHECK( pmask.includes(sp_yx)); + BOOST_CHECK( pmask.includes(sp_yxf)); + BOOST_CHECK( pmask.includes(sp_yxg)); + BOOST_CHECK( pmask.includes(sp_yy)); + BOOST_CHECK( pmask.includes(sp_yyf)); + BOOST_CHECK( pmask.includes(sp_yyg)); } void @@ -904,7 +1065,8 @@ suite->add(BOOST_TEST_CASE(&test_simple_exclude)); suite->add(BOOST_TEST_CASE(&test_include_exclude)); suite->add(BOOST_TEST_CASE(&test_exclude_include)); - suite->add(BOOST_TEST_CASE(&test_invalid_paths)); + suite->add(BOOST_TEST_CASE(&test_invalid_roster_paths)); + suite->add(BOOST_TEST_CASE(&test_invalid_workspace_paths)); suite->add(BOOST_TEST_CASE(&test_include_depth_0)); suite->add(BOOST_TEST_CASE(&test_include_depth_1)); ============================================================ --- restrictions.hh 051f3e2ececf3be1ffb28860a4d9d283181190da +++ restrictions.hh d660af577632f975f9c155e11744c7c0f5d0aa44 @@ -51,70 +51,72 @@ // // revision A ... included ... revision X ... excluded ... revision B -enum path_state { included, excluded }; +namespace restricted_path +{ + enum status { included, excluded }; +} class restriction { public: + bool empty() const { return included_paths.empty() && excluded_paths.empty(); } + + protected: restriction(app_state & a) : app(a) {} restriction(std::vector const & includes, std::vector const & excludes, - roster_t const & roster, - app_state & a) : - app(a) - { - map_paths(includes, excludes); - map_nodes(roster); - validate(); - } + app_state & a); - restriction(std::vector const & includes, - std::vector const & excludes, - roster_t const & roster1, - roster_t const & roster2, - app_state & a) : - app(a) - { - map_paths(includes, excludes); - map_nodes(roster1); - map_nodes(roster2); - validate(); - } + app_state & app; + path_set included_paths, excluded_paths; +}; - bool includes(roster_t const & roster, node_id nid) const; +class node_restriction : public restriction +{ + public: + node_restriction(app_state & a) : restriction(a) {} - bool includes(split_path const & sp) const; + node_restriction(std::vector const & includes, + std::vector const & excludes, + roster_t const & roster, + app_state & a); - bool empty() const { return included_paths.empty() && excluded_paths.empty(); } + node_restriction(std::vector const & includes, + std::vector const & excludes, + roster_t const & roster1, + roster_t const & roster2, + app_state & a); - restriction & operator=(restriction const & other) + bool includes(roster_t const & roster, node_id nid) const; + + node_restriction & operator=(node_restriction const & other) { included_paths = other.included_paths; excluded_paths = other.excluded_paths; known_paths = other.known_paths; node_map = other.node_map; - path_map = other.path_map; return *this; } private: + path_set known_paths; + std::map node_map; +}; - app_state & app; - path_set included_paths, excluded_paths, known_paths; +class path_restriction : public restriction +{ + public: + path_restriction(app_state & a) : restriction(a) {} - // we maintain maps by node_id and also by split_path, which is not - // particularly nice, but paths are required for checking unknown and ignored - // files - std::map node_map; - std::map path_map; + path_restriction(std::vector const & includes, + std::vector const & excludes, + app_state & a); - void map_paths(std::vector const & includes, - std::vector const & excludes); + bool includes(split_path const & sp) const; - void map_nodes(roster_t const & roster); - - void validate(); + private: + std::map path_map; }; // Local Variables: ============================================================ --- roster.cc f478f2dca70407b7b277810d8b20177e889e7217 +++ roster.cc 6df282421f592efa3dc67c0e889a1d8abc480fbd @@ -1916,7 +1916,7 @@ void make_restricted_csets(roster_t const & from, roster_t const & to, cset & included, cset & excluded, - restriction const & mask) + node_restriction const & mask) { included.clear(); excluded.clear(); @@ -2173,7 +2173,7 @@ void update_current_roster_from_filesystem(roster_t & ros, - restriction const & mask, + node_restriction const & mask, app_state & app) { temp_node_id_source nis; @@ -2239,7 +2239,7 @@ update_current_roster_from_filesystem(roster_t & ros, app_state & app) { - restriction tmp(app); + node_restriction tmp(app); update_current_roster_from_filesystem(ros, tmp, app); } ============================================================ --- roster.hh 0601b6f9e2675eb4082475a47077973d1f03ad2f +++ roster.hh 7789b477fbc1249740d9ca6a665bd535c6d3a5b8 @@ -337,12 +337,12 @@ // various (circular?) dependencies prevent inclusion of restrictions.hh -class restriction; +class node_restriction; void make_restricted_csets(roster_t const & from, roster_t const & to, cset & included, cset & excluded, - restriction const & mask); + node_restriction const & mask); void check_restricted_cset(roster_t const & roster, cset const & cs); @@ -362,7 +362,7 @@ void update_current_roster_from_filesystem(roster_t & ros, - restriction const & mask, + node_restriction const & mask, app_state & app); void ============================================================ --- tests/ls_unknown_of_unknown_subdir/__driver__.lua 55ac47ece4bb28da40f6780e2a7c3cbdb101ec67 +++ tests/ls_unknown_of_unknown_subdir/__driver__.lua 370a5ef9abba265eda98d3e2c04fe11f74c7f449 @@ -1,9 +1,11 @@ mtn_setup() mkdir("foo") writefile("foo/a", "aaa") writefile("foo/b", "bbb") --- this fails complaining that foo is an unknown path +check(mtn("ls", "unknown", "foo"), 0, true, false) +check(grep('foo$', "stdout"), 0, false, false) +check(grep('foo/a$', "stdout"), 0, false, false) +check(grep('foo/b$', "stdout"), 0, false, false) -xfail_if(true, mtn("ls", "unknown", "foo"), 0) ============================================================ --- work.cc ee392842f0609f5e685d18b26ab2dcad3462ac78 +++ work.cc fefb3952854fc1ff54beed99ee9526768f707c5e @@ -79,7 +79,7 @@ get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, new_roster, app); + node_restriction mask(args, app.exclude_patterns, new_roster, app); node_map const & nodes = new_roster.all_nodes(); for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i) @@ -109,7 +109,7 @@ get_base_and_current_roster_shape(old_roster, new_roster, nis, app); - restriction mask(args, app.exclude_patterns, old_roster, new_roster, app); + path_restriction mask(args, app.exclude_patterns, app); new_roster.extract_path_set(known); ============================================================ --- work.hh 928f220fa9f884a00f71b02a54eae904ba833c3a +++ work.hh 6db6ed0ed8317563b0cf56a97925f2bf41f4f07b @@ -51,14 +51,17 @@ // // _MTN/inodeprints, if present, can be used to speed up this last step. +class path_restriction; + struct file_itemizer : public tree_walker { app_state & app; path_set & known; path_set & unknown; path_set & ignored; - restriction const & mask; - file_itemizer(app_state & a, path_set & k, path_set & u, path_set & i, restriction const & r) + path_restriction const & mask; + file_itemizer(app_state & a, path_set & k, path_set & u, path_set & i, + path_restriction const & r) : app(a), known(k), unknown(u), ignored(i), mask(r) {} virtual void visit_dir(file_path const & path); virtual void visit_file(file_path const & path);