#include #include #include #include "lib_acl.h" #include "acl_cpp/lib_acl.hpp" static void ls_file(acl::scan_dir& scan, const char* path, bool recursive, bool fullpath) { if (scan.open(path, recursive) == false) { logger_error("open path: %s error: %s", path, acl::last_serror()); return; } int nfiles = 0; const char* filename; while ((filename = scan.next_file(fullpath)) != NULL) { logger("filename: %s, path: %s", filename, scan.curr_path()); nfiles++; } logger("==========================================================="); logger("total file count: %d", nfiles); } static void ls_dir(acl::scan_dir& scan, const char* path, bool recursive, bool fullpath) { if (scan.open(path, recursive) == false) { logger_error("open path: %s error: %s", path, acl::last_serror()); return; } int ndirs = 0; const char* dirname; while ((dirname = scan.next_dir(fullpath)) != NULL) { logger("dirname: %s, path: %s", dirname, scan.curr_path()); ndirs++; } logger("==========================================================="); logger("total dir count: %d", ndirs); } static void ls_all(acl::scan_dir& scan, const char* path, bool recursive, bool fullpath) { if (scan.open(path, recursive) == false) { logger_error("open path: %s error: %s", path, acl::last_serror()); return; } int ndirs = 0, nfiles = 0; const char* name; bool is_file; while ((name = scan.next(fullpath, &is_file)) != NULL) { logger("%s: %s, path: %s", is_file ? "filename" : "dirname", name, scan.curr_path()); if (is_file) nfiles++; else ndirs++; } logger("==========================================================="); logger("total dir count: %d, file count: %d", ndirs, nfiles); } static bool get_relative_path(const char* spath, const char* filepath, acl::string& rpath) { size_t n = strlen(spath); if (strncmp(filepath, spath, n) != 0) return false; filepath += n; if (*filepath == 0) return false; rpath = filepath; return true; } static bool compare_files(const char* sfile, const char* dfile) { acl::string sbuf, dbuf; if (acl::ifstream::load(sfile, &sbuf) == false) { logger_error("load sfile %s error %s", sfile, acl::last_serror()); return false; } if (acl::ifstream::load(dfile, &dbuf) == false) { logger_error("load dfile %s error %s", dfile, acl::last_serror()); return false; } return sbuf == dbuf; } static void diff_path(acl::scan_dir& scan, const char* spath, const char* dpath, bool recursive, const char* file_types, bool show_all) { if (scan.open(spath, recursive) == false) { logger_error("open path: %s error: %s", spath, acl::last_serror()); return; } acl::string buf(file_types); std::vector& types = buf.split2(",;"); const char* filepath; (void) dpath; int n = 0; while ((filepath = scan.next_file(true)) != NULL) { acl::string path; acl::string& file = path.basename(filepath); const char* type = strrchr(file.c_str(), '.'); if (type == NULL || *(++type) == 0) continue; std::vector::const_iterator it = std::find(types.begin(), types.end(), type); if (it == types.end()) continue; path.clear(); if (get_relative_path(spath, filepath, path) == false) continue; acl::string dfilepath; dfilepath << dpath << path; n++; bool equal = compare_files(filepath, dfilepath); if (!equal) { printf("diff %s\t%s\r\n", filepath, dfilepath.c_str()); } else if (show_all) { printf("same %s\t%s\r\n", filepath, dfilepath.c_str()); } } printf("---scan over %d files---\r\n", n); } static void usage(const char* procname) { logger("usage: %s -h [help]\r\n" " -t type[dir|file|all|diff]\r\n" " -s source path\r\n" " -d destination path\r\n" " -e file_types\r\n" " -A [show all status including same files]\r\n" " -r [if recursive, default: false]\r\n" " -a [if get fullpath, default: false]\r\n", procname); } int main(int argc, char* argv[]) { int ch; bool recursive = false, fullpath = false, show_all = false; acl::string dpath, spath, mode, types("c;cpp;cc;cxx;h;hpp;hxx"); acl::log::stdout_open(true); while ((ch = getopt(argc, argv, "hs:d:t:rae:A")) > 0) { switch (ch) { case 'h': usage(argv[0]); return 0; case 's': spath = optarg; break; case 'd': dpath = optarg; break; case 't': mode = optarg; break; case 'r': recursive = true; break; case 'a': fullpath = true; break; case 'e': types = optarg; break; case 'A': show_all = true; break; default: break; } } if (spath.empty()) { usage(argv[0]); return 1; } if (!spath.end_with("/")) spath += "/"; acl::scan_dir scan; if (mode == "dir") ls_dir(scan, spath, recursive, fullpath); else if (mode == "file") ls_file(scan, spath, recursive, fullpath); else if (mode == "diff") { if (dpath.empty()) { usage(argv[0]); return 1; } if (!dpath.end_with("/")) dpath += "/"; diff_path(scan, spath, dpath, recursive, types, show_all); } else ls_all(scan, spath, recursive, fullpath); #ifdef WIN32 logger("==========================================================="); logger("enter any key to exit"); getchar(); #endif return (0); }