X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=nucleus%2Flibrary%2Ffilesystem%2Fdirectory_tree.cpp;h=a761172104594bf6d70188acf30b14aba9847217;hb=a4c99c6006b3aa20b5f65f02c2d30db7e790083a;hp=2f267f9b6a8ca6993c13c653eec5b7b004555778;hpb=7a381305a6cd14cf4254b6259a3ffb0e1912b390;p=feisty_meow.git diff --git a/nucleus/library/filesystem/directory_tree.cpp b/nucleus/library/filesystem/directory_tree.cpp index 2f267f9b..a7611721 100644 --- a/nucleus/library/filesystem/directory_tree.cpp +++ b/nucleus/library/filesystem/directory_tree.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -28,16 +29,16 @@ #include using namespace basis; -using namespace structures; +using namespace loggers; using namespace nodes; +using namespace structures; using namespace textual; -#define DEBUG_DIRECTORY_TREE +//#define DEBUG_DIRECTORY_TREE // uncomment for noisier version. #undef LOG -#define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s()) -//CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +#define LOG(to_print) CLASS_EMERGENCY_LOG(program_wide_logger::get(), to_print) ////////////// @@ -50,7 +51,7 @@ public: dir_tree_iterator(const filename_tree *initial, tree::traversal_directions dir) - : filename_tree::iterator(initial, dir), _current(NIL) {} + : filename_tree::iterator(initial, dir), _current(NULL_POINTER) {} }; ////////////// @@ -70,7 +71,7 @@ directory_tree::directory_tree(const astring &path, const char *pattern, : _scanned_okay(false), _path(new astring(path)), _pattern(new astring(pattern)), - _real_tree(NIL), + _real_tree(NULL_POINTER), _ignore_files(ignore_files), _creator(new fname_tree_creator) { @@ -158,14 +159,12 @@ void directory_tree::text_form(astring &target, bool show_files) void directory_tree::traverse(const astring &path, const char *pattern, filename_tree &add_to) { -#ifdef DEBUG_DIRECTORY_TREE FUNCDEF("traverse"); -#endif // prepare the current node. add_to._dirname = filename(path, astring::empty_string()); add_to._files.reset(); #ifdef DEBUG_DIRECTORY_TREE - LOG(astring("working on node ") + add_to._dirname.raw()); + LOG(astring("working on node ") + add_to._dirname); #endif // open the directory. @@ -182,13 +181,15 @@ void directory_tree::traverse(const astring &path, const char *pattern, // and recursively traverse that sub-node also. const string_array &dirs = curr.directories(); for (int i = 0; i < dirs.length(); i++) { - filename_tree *new_branch = NIL; + filename_tree *new_branch = NULL_POINTER; astring new_path = path + filename::default_separator() + dirs[i]; #ifdef DEBUG_DIRECTORY_TREE LOG(astring("seeking path: ") + new_path); #endif if (!filename(new_path).is_normal()) { -LOG(astring("bailing on weird dir: ") + new_path); +//#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("bailing on weird dir: ") + new_path); +//#endif continue; // only regular directories please. } for (int q = 0; q < add_to.branches(); q++) { @@ -222,12 +223,20 @@ LOG(astring("bailing on weird dir: ") + new_path); bool directory_tree::reset(const astring &path, const char *pattern) { + FUNCDEF("reset"); _scanned_okay = false; WHACK(_real_tree); +// filename temp_path(path); +// temp_path.canonicalize(); *_path = path; +//temp_path.raw(); *_pattern = pattern; _real_tree = new filename_tree; +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("dirtree::reset to path: ") + path); +#endif + // check that the top-level is healthy. directory curr(path, "*"); if (!curr.good()) return false; @@ -264,11 +273,10 @@ dir_tree_iterator *directory_tree::start(traversal_types type) const bool directory_tree::jump_to(dir_tree_iterator &scanning, const astring &sub_path) { -#ifdef DEBUG_DIRECTORY_TREE FUNCDEF("jump_to"); -#endif string_array pieces; - filename(sub_path).separate(pieces); + bool rooted; + filename(sub_path).separate(rooted, pieces); for (int i = 0; i < pieces.length(); i++) { filename_tree *curr = dynamic_cast(scanning.current()); #ifdef DEBUG_DIRECTORY_TREE @@ -276,7 +284,7 @@ bool directory_tree::jump_to(dir_tree_iterator &scanning, #endif string_array sub_pieces = pieces.subarray(i, i); filename curr_path; - curr_path.join(sub_pieces); + curr_path.join(rooted, sub_pieces); curr_path = filename(curr->_dirname.raw() + filename::default_separator() + curr_path.raw()); #ifdef DEBUG_DIRECTORY_TREE @@ -316,7 +324,7 @@ filename_tree *directory_tree::goto_current(dir_tree_iterator &scanning) scanning._current = (filename_tree *)scanning.next(); } // now check that we're healthy. - if (!scanning._current) return NIL; // all done. + if (!scanning._current) return NULL_POINTER; // all done. // cast the tree to the right type. return dynamic_cast(scanning._current); @@ -369,7 +377,7 @@ bool directory_tree::current(dir_tree_iterator &scanning, filename_list *directory_tree::access(dir_tree_iterator &scanning) { filename_tree *tof = goto_current(scanning); - if (!tof) return NIL; + if (!tof) return NULL_POINTER; return &tof->_files; } @@ -432,10 +440,16 @@ filename_tree *directory_tree::seek(const astring &dir_name_in, bool found = false; // start looking at all the items in the list, even though we might have // to abandon the iteration if we find a match. - filename_tree *check = NIL; + filename_tree *check = NULL_POINTER; for (posn = 0; posn < examining.length(); posn++) { check = examining[posn]; filename current(check->_dirname); + if (!current.is_normal()) { +//#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("seek: skipping abnormal dir: \"") + current + "\""); +//#endif + continue; + } #ifdef DEBUG_DIRECTORY_TREE LOG(astring("looking at ") + current.raw()); #endif @@ -459,21 +473,21 @@ filename_tree *directory_tree::seek(const astring &dir_name_in, break; } } - if (!found) return NIL; // we found nothing comparable. + if (!found) return NULL_POINTER; // we found nothing comparable. // we found a partial match. that means we should start looking at this // node's children for the exact match. if (!check) { // this is a serious logical error! LOG("serious logical error: tree was not located."); - return NIL; + return NULL_POINTER; } examining.reset(); // clear the existing nodes. for (int i = 0; i < check->branches(); i++) examining += (filename_tree *)check->branch(i); } - return NIL; // we found nothing that looked like that node. + return NULL_POINTER; // we found nothing that looked like that node. } bool directory_tree::calculate(bool just_size) @@ -482,6 +496,9 @@ bool directory_tree::calculate(bool just_size) bool directory_tree::calculate(filename_tree *start, bool just_size) { FUNCDEF("calculate"); +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("calculate: got tree to start with at ") + start->_dirname.raw()); +#endif dir_tree_iterator *ted = start_at(start, directory_tree::postfix); // create our iterator to do a postfix traversal. why postfix? well, // prefix has been used elsewhere and since it doesn't really matter what @@ -492,6 +509,13 @@ bool directory_tree::calculate(filename_tree *start, bool just_size) filename_list *files; // the filenames held at the iterator. while (directory_tree::current_dir(*ted, curr)) { + if (!curr.is_normal()) { +//#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("calculate: skipping abnormal dir: \"") + curr + "\""); +//#endif + directory_tree::next(*ted); + continue; // scary non-simple file type. + } // we have a good directory to show. #ifdef DEBUG_DIRECTORY_TREE LOG(astring("calcing node ") + curr.raw()); @@ -499,6 +523,16 @@ bool directory_tree::calculate(filename_tree *start, bool just_size) files = directory_tree::access(*ted); directory_tree::depth(*ted, depth); for (int i = 0; i < files->elements(); i++) { + filename curr_file = curr + "/" + *files->borrow(i); +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("got a curr file: ") + curr_file); +#endif + if (!curr_file.is_normal()) { +//#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("skipping abnormal file: \"") + curr + "\""); +//#endif + continue; + } if (!files->borrow(i)->calculate(curr.raw(), just_size)) { LOG(astring("failure to calculate ") + files->get(i)->text_form()); } @@ -554,7 +588,8 @@ bool directory_tree::compare_trees(const directory_tree &source, int source_pieces = 0; { string_array temp; - filename(real_source_start).separate(temp); + bool rooted_source; + filename(real_source_start).separate(rooted_source, temp); source_pieces = temp.length(); } @@ -568,7 +603,8 @@ bool directory_tree::compare_trees(const directory_tree &source, #endif string_array pieces; - curr.separate(pieces); // get the components of the current location. + bool curr_rooted; + curr.separate(curr_rooted, pieces); // get the components of the current location. #ifdef DEBUG_DIRECTORY_TREE LOG(astring("name in pieces:") + pieces.text_form()); #endif @@ -576,7 +612,8 @@ bool directory_tree::compare_trees(const directory_tree &source, // snap the root components out of there. filename corresponding_name; - corresponding_name.join(pieces); +//hmmm: is that right decision? + corresponding_name.join(false, pieces); #ifdef DEBUG_DIRECTORY_TREE LOG(astring("computed target name as: ") + corresponding_name); #endif @@ -594,6 +631,11 @@ bool directory_tree::compare_trees(const directory_tree &source, if (target_start.raw().t()) { corresponding_name = filename(target_start.raw() + filename::default_separator() + corresponding_name.raw()); +/*doesn't help, not right yet. } else { + // if they didn't give us a place to start, we start at the top. + corresponding_name = filename(target.path() + + filename::default_separator() + corresponding_name.raw()); +*/ } #ifdef DEBUG_DIRECTORY_TREE LOG(astring("target with start is: ") + corresponding_name); @@ -603,10 +645,10 @@ bool directory_tree::compare_trees(const directory_tree &source, if (!target_now) { // that entire sub-tree is missing. add all of the files here into // the list. -#ifdef DEBUG_DIRECTORY_TREE +//#ifdef DEBUG_DIRECTORY_TREE LOG(astring("could not find dir in target for ") + curr.raw() + " which we computed corresp as " + corresponding_name.raw()); -#endif +//#endif } // now scan across all the files that are in our source list. @@ -614,13 +656,6 @@ bool directory_tree::compare_trees(const directory_tree &source, if (!target_now // there was no node, so we're adding everything... || !target_now->_files.member_with_state(*files[i], how_compare) ) { // ... or we need to add this file since it's missing. -/* -//hmmm: this one might be redundant. we shouldn't add it in the first place. - if (!files[i]->is_normal()) { - LOG(astring("skipping abnormal file: ") + *files[i]); - continue; // wasn't useful to do this one. - } -*/ #ifdef DEBUG_DIRECTORY_TREE LOG(astring("adding record: ") + files[i]->text_form()); #endif @@ -678,9 +713,7 @@ outcome directory_tree::find_common_root(const astring &finding, bool exists, filename_tree * &found, astring &reassembled, string_array &pieces, int &match_place) { -#ifdef DEBUG_DIRECTORY_TREE FUNCDEF("find_common_root"); -#endif // test the path to find what it is. filename adding(finding); if (exists && !adding.good()) @@ -690,13 +723,15 @@ outcome directory_tree::find_common_root(const astring &finding, bool exists, // break up the path into pieces. pieces.reset(); - adding.separate(pieces); + bool rooted; + adding.separate(rooted, pieces); // break up our root into pieces; we must take off components that are // already in the root. string_array root_pieces; + bool root_rooted; filename temp_file(path()); - temp_file.separate(root_pieces); + temp_file.separate(root_rooted, root_pieces); // locate the last place where the path we were given touches our tree. // it could be totally new, partially new, or already contained. @@ -791,27 +826,29 @@ outcome directory_tree::add_path(const astring &new_item, bool just_size) return common::NOT_FOUND; // not an existing path. } if (!adding.is_normal()) { +//#ifdef DEBUG_DIRECTORY_TREE LOG(astring("abnormal new item: ") + new_item); +//#endif return common::BAD_INPUT; // not a good path. } int file_subtract = 0; // if it's a file, then we remove last component. if (!adding.is_directory()) file_subtract = 1; #ifdef DEBUG_DIRECTORY_TREE - if (file_subtract) LOG(astring("adding a file ") + new_item); - else LOG(astring("adding a directory ") + new_item); + if (file_subtract) { LOG(astring("adding a file ") + new_item); } + else { LOG(astring("adding a directory ") + new_item); } #endif // find the common root, break up the path into pieces, and tell us where // we matched. string_array pieces; - filename_tree *last_match = NIL; + filename_tree *last_match = NULL_POINTER; int comp_index; astring reassembled; // this will hold the common root. outcome ret = find_common_root(new_item, true, last_match, reassembled, pieces, comp_index); if (!last_match) { LOG(astring("serious error finding common root for ") + new_item - + ", got NIL tree."); + + ", got null tree."); return common::FAILURE; // something serious isn't right. } @@ -839,7 +876,8 @@ outcome directory_tree::add_path(const astring &new_item, bool just_size) #endif // handle the case for files now that we have our proper node. string_array partial_pieces; - filename(reassembled).separate(partial_pieces); + bool partial_rooted; + filename(reassembled).separate(partial_rooted, partial_pieces); int levels_missing = pieces.length() - partial_pieces.length(); // we loop over all the pieces that were missing in between the last @@ -888,12 +926,10 @@ outcome directory_tree::add_path(const astring &new_item, bool just_size) outcome directory_tree::remove_path(const astring &zap_item) { -#ifdef DEBUG_DIRECTORY_TREE FUNCDEF("remove_path"); -#endif // find the common root, if one exists. if not, we're not going to do this. string_array pieces; - filename_tree *last_match = NIL; + filename_tree *last_match = NULL_POINTER; int comp_index; astring reassembled; outcome ret = find_common_root(zap_item, false, last_match, reassembled, @@ -957,6 +993,46 @@ outcome directory_tree::remove_path(const astring &zap_item) return common::OKAY; } -} //namespace. +basis::outcome directory_tree::make_directories(const basis::astring new_root) +{ + FUNCDEF("make_directories"); + // iterate down the tree, making all the directories requested. + dir_tree_iterator *ted = start(directory_tree::prefix); + + int depth; // current depth in tree. + filename curr; // the current path the iterator is at. + string_array files; // the filenames held at the iterator. + +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("new root is ") + new_root); +#endif + filename old_root = path(); +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("old root was ") + old_root.raw()); +#endif + + while (current(*ted, curr, files)) { + // we have a good directory to show. + directory_tree::depth(*ted, depth); + int found = curr.find(old_root); + if (found < common::OKAY) { + LOG(astring("failed to find prefix of path '") + old_root + + "' in the current directory '" + curr + "'"); + return found; + } + curr = curr.substring(found + old_root.length(), curr.end()); +//LOG(astring("curr now is: ") + curr); + filename dir_to_make(new_root + "/" + curr); +#ifdef DEBUG_DIRECTORY_TREE + LOG(astring("creating dir: ") + dir_to_make.raw()); +#endif + directory::recursive_create(dir_to_make.raw()); + next(*ted); + } + + throw_out(ted); + return common::OKAY; +} +} //namespace.