2014-11-19 00:25:21 +08:00
|
|
|
#include <map>
|
2018-10-07 21:35:46 +08:00
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
2018-11-16 11:20:06 +08:00
|
|
|
#include "lib_acl.h"
|
2014-11-19 00:25:21 +08:00
|
|
|
#include "acl_cpp/lib_acl.hpp"
|
|
|
|
|
|
|
|
static void ls_file(acl::scan_dir& scan, const char* path, bool recursive,
|
|
|
|
bool fullpath)
|
|
|
|
{
|
2018-10-07 21:35:46 +08:00
|
|
|
if (scan.open(path, recursive) == false) {
|
2014-11-19 00:25:21 +08:00
|
|
|
logger_error("open path: %s error: %s",
|
|
|
|
path, acl::last_serror());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int nfiles = 0;
|
|
|
|
const char* filename;
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
while ((filename = scan.next_file(fullpath)) != NULL) {
|
2014-11-19 00:25:21 +08:00
|
|
|
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)
|
|
|
|
{
|
2018-10-07 21:35:46 +08:00
|
|
|
if (scan.open(path, recursive) == false) {
|
2014-11-19 00:25:21 +08:00
|
|
|
logger_error("open path: %s error: %s",
|
|
|
|
path, acl::last_serror());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ndirs = 0;
|
|
|
|
const char* dirname;
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
while ((dirname = scan.next_dir(fullpath)) != NULL) {
|
2014-11-19 00:25:21 +08:00
|
|
|
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)
|
|
|
|
{
|
2018-10-07 21:35:46 +08:00
|
|
|
if (scan.open(path, recursive) == false) {
|
2014-11-19 00:25:21 +08:00
|
|
|
logger_error("open path: %s error: %s",
|
|
|
|
path, acl::last_serror());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ndirs = 0, nfiles = 0;
|
|
|
|
const char* name;
|
|
|
|
bool is_file;
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
while ((name = scan.next(fullpath, &is_file)) != NULL) {
|
2014-11-19 00:25:21 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:49:18 +08:00
|
|
|
static void diff_path(acl::scan_dir& scan, const char* spath, const char* dpath,
|
|
|
|
bool recursive, const char* file_types, bool show_all)
|
2018-10-07 21:35:46 +08:00
|
|
|
{
|
|
|
|
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<acl::string>& 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<acl::string>::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);
|
2018-11-24 11:49:18 +08:00
|
|
|
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());
|
|
|
|
}
|
2018-10-07 21:35:46 +08:00
|
|
|
}
|
|
|
|
printf("---scan over %d files---\r\n", n);
|
|
|
|
}
|
|
|
|
|
2014-11-19 00:25:21 +08:00
|
|
|
static void usage(const char* procname)
|
|
|
|
{
|
2018-10-07 21:35:46 +08:00
|
|
|
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"
|
2018-11-24 11:49:18 +08:00
|
|
|
" -A [show all status including same files]\r\n"
|
2018-10-07 21:35:46 +08:00
|
|
|
" -r [if recursive, default: false]\r\n"
|
|
|
|
" -a [if get fullpath, default: false]\r\n", procname);
|
2014-11-19 00:25:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
int ch;
|
2018-11-24 11:49:18 +08:00
|
|
|
bool recursive = false, fullpath = false, show_all = false;
|
2018-10-07 21:35:46 +08:00
|
|
|
acl::string dpath, spath, mode, types("c;cpp;cc;cxx;h;hpp;hxx");
|
2014-11-19 00:25:21 +08:00
|
|
|
acl::log::stdout_open(true);
|
|
|
|
|
2018-11-24 11:49:18 +08:00
|
|
|
while ((ch = getopt(argc, argv, "hs:d:t:rae:A")) > 0) {
|
2018-10-07 21:35:46 +08:00
|
|
|
switch (ch) {
|
2014-11-19 00:25:21 +08:00
|
|
|
case 'h':
|
|
|
|
usage(argv[0]);
|
|
|
|
return 0;
|
2018-10-07 21:35:46 +08:00
|
|
|
case 's':
|
|
|
|
spath = optarg;
|
|
|
|
break;
|
2014-11-19 00:25:21 +08:00
|
|
|
case 'd':
|
2018-10-07 21:35:46 +08:00
|
|
|
dpath = optarg;
|
2014-11-19 00:25:21 +08:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
mode = optarg;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
recursive = true;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
fullpath = true;
|
|
|
|
break;
|
2018-10-07 21:35:46 +08:00
|
|
|
case 'e':
|
|
|
|
types = optarg;
|
|
|
|
break;
|
2018-11-24 11:49:18 +08:00
|
|
|
case 'A':
|
|
|
|
show_all = true;
|
|
|
|
break;
|
2014-11-19 00:25:21 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
if (spath.empty()) {
|
2014-11-19 00:25:21 +08:00
|
|
|
usage(argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-10-07 21:35:46 +08:00
|
|
|
if (!spath.end_with("/"))
|
|
|
|
spath += "/";
|
|
|
|
|
2014-11-19 00:25:21 +08:00
|
|
|
acl::scan_dir scan;
|
|
|
|
|
|
|
|
if (mode == "dir")
|
2018-10-07 21:35:46 +08:00
|
|
|
ls_dir(scan, spath, recursive, fullpath);
|
2014-11-19 00:25:21 +08:00
|
|
|
else if (mode == "file")
|
2018-10-07 21:35:46 +08:00
|
|
|
ls_file(scan, spath, recursive, fullpath);
|
|
|
|
else if (mode == "diff") {
|
|
|
|
if (dpath.empty()) {
|
|
|
|
usage(argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!dpath.end_with("/"))
|
|
|
|
dpath += "/";
|
2018-11-24 11:49:18 +08:00
|
|
|
diff_path(scan, spath, dpath, recursive, types, show_all);
|
2018-10-07 21:35:46 +08:00
|
|
|
} else
|
|
|
|
ls_all(scan, spath, recursive, fullpath);
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
logger("===========================================================");
|
|
|
|
logger("enter any key to exit");
|
|
|
|
getchar();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|