Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
git-svn-id: https://projectname.googlecode.com/svn/trunk@2 c416075f-80b4-e980-4839-00ea3ed24e77
  • Loading branch information
valery.isaev@gmail.com committed Mar 13, 2011
1 parent 5a9200a commit 22a3c1b
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 0 deletions.
25 changes: 25 additions & 0 deletions trunk/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
SRC_DIR = src
PROJECT_NAME = pn
SRCS = $(wildcard $(SRC_DIR)/*.cpp)
LIBS = boost_program_options boost_filesystem boost_system
CFLAGS = -O2 -Wall -pedantic

.PHONY: first debug release makedirs clean
first: debug
debug:
@make makedirs DIR=debug
@make debug/$(PROJECT_NAME) DIR=debug FLAGS=-ggdb
release:
@make makedirs DIR=release
@make release/$(PROJECT_NAME) DIR=release FLAGS=-DNDEBUG
makedirs:
-@mkdir -p $(dir $(subst $(SRC_DIR),$(DIR),$(SRCS))) $(dir $(subst $(SRC_DIR),.depend,$(SRCS)))
clean:
-@rm -rf debug release $(DIR) .depend

-include $(patsubst $(SRC_DIR)/%.cpp, .depend/%.dep, $(SRCS))

$(DIR)/$(PROJECT_NAME): $(patsubst $(SRC_DIR)/%.cpp, $(DIR)/%.o, $(SRCS))
g++ $^ -o $@ $(patsubst %,-l%,$(LIBS))
$(DIR)/%.o: $(SRC_DIR)/%.cpp
g++ $< -c $(CFLAGS) -o $@ $(FLAGS) -MMD -MT $@ -MF .depend/$*.dep
20 changes: 20 additions & 0 deletions trunk/src/binary_functor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _BINARY_FUNCTOR_H_
#define _BINARY_FUNCTOR_H_

#include <vector>

template<typename Elem, typename Iter, typename Cmp>
class binary_functor {
Iter _iter;
Cmp _cmp;
std::vector<Elem> values;
public:
typedef Elem value_type;
binary_functor(const Iter& iter, const Cmp& cmp): _iter(iter), _cmp(cmp) {}
void operator()(const Elem& elem) {
transform(values.begin(), values.end(), _iter, std::bind2nd(_cmp, elem));
values.push_back(elem);
}
};

#endif
35 changes: 35 additions & 0 deletions trunk/src/comparer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <cstring>
#include <iostream>

#include "comparer.h"

comparer::result_type comparer::operator()(const fs::path& filename1, const fs::path& filename2) const {
const int buf_size = 4096;
char buf1[buf_size], buf2[buf_size];
if (fs::file_size(filename1) != fs::file_size(filename2)) {
return result_type();
}
fs::ifstream file1(filename1), file2(filename2);
while (true) {
file1.read(buf1, buf_size);
file2.read(buf2, buf_size);
if (file1.gcount() == file2.gcount()) {
if (std::memcmp(buf1, buf2, file1.gcount()) == 0) {
if (file1.eof() && file2.eof()) {
return result_type(filename1, filename2);
} else
if (!file1.eof() && !file2.eof()) {
continue;
}
}
}
return result_type();
}
}

std::ostream& operator<<(std::ostream& o, const comparer::result_type& r) {
if (!r.file1.empty() && !r.file2.empty()) {
o << "files " << r.file1 << " and " << r.file2 << " are equal\n";
}
return o;
}
23 changes: 23 additions & 0 deletions trunk/src/comparer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _COMPARER_H_
#define _COMPARER_H_

#include <iostream>

#include "filesystem.h"

class comparer {
public:
struct result_type {
fs::path file1;
fs::path file2;
result_type() {}
result_type(const fs::path& f1, const fs::path& f2): file1(f1), file2(f2) {}
};
typedef fs::path first_argument_type;
typedef fs::path second_argument_type;
result_type operator()(const fs::path& file1, const fs::path& file2) const;
};

std::ostream& operator<<(std::ostream& o, const comparer::result_type& r);

#endif
41 changes: 41 additions & 0 deletions trunk/src/filesystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef _FILESYSTEM_H_
#define _FILESYSTEM_H_

#include <iterator>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

#include "logger.h"
#include "functor_iterator.h"

namespace fs {

using namespace boost::filesystem;

template<typename Funct>
class recursive {
Funct _funct;
public:
typedef typename Funct::value_type value_type;
recursive(const Funct& funct): _funct(funct) {}
template<typename T>
void operator()(const T& value) {
if (!exists(value)) {
logger::std_stream() << value << " does not exists" << std::endl;
} else
if (is_directory(value)) {
remove_copy_if(recursive_directory_iterator(value), recursive_directory_iterator(),
functor_iterator<Funct>(_funct),
std::not1(std::ptr_fun((bool(*)(const path&))(&is_regular_file))));
} else
if (is_regular_file(value)) {
_funct(value);
} else {
logger::std_stream() << value << " neither directory nor regular file" << std::endl;
}
}
};

}

#endif
18 changes: 18 additions & 0 deletions trunk/src/functor_iterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _FUNCTOR_ITERATOR_H_
#define _FUNCTOR_ITERATOR_H_

#include <vector>

template<typename Funct>
class functor_iterator {
Funct _funct;
public:
typedef typename Funct::value_type value_type;
functor_iterator(const Funct& funct): _funct(funct) {}
functor_iterator& operator=(const value_type& elem) { _funct(elem); return *this; }
functor_iterator& operator*() { return *this; }
functor_iterator& operator++() { return *this; }
functor_iterator operator++(int) { return *this; }
};

#endif
3 changes: 3 additions & 0 deletions trunk/src/logger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "logger.h"

logger* logger::std_logger = 0;
26 changes: 26 additions & 0 deletions trunk/src/logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _LOGGER_H_
#define _LOGGER_H_

#include <iostream>
#include <string>

class logger {
static logger* std_logger;
public:
virtual void operator()(const std::string& msg) = 0;
virtual std::ostream& stream() const = 0;
static void std(const std::string& msg) { (*std_logger)(msg); }
static logger& std() { return *std_logger; }
static void set_std(logger* l) { std_logger = l; }
static std::ostream& std_stream() { return std_logger->stream(); }
};

class stderr_logger: public logger {
std::string prepend;
public:
stderr_logger(const std::string& p): prepend(p + ": ") {}
void operator()(const std::string& msg) { std::cerr << prepend << msg << std::endl; }
std::ostream& stream() const { return std::cerr << prepend; }
};

#endif
17 changes: 17 additions & 0 deletions trunk/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "logger.h"
#include "program_options.h"
#include "filesystem.h"
#include "binary_functor.h"
#include "comparer.h"

int main(int argc, char* argv[]) {
stderr_logger std_logger(argv[0]);
logger::set_std(&std_logger);

program_options po(argc, argv);

typedef std::ostream_iterator<comparer::result_type> out_iter;
typedef binary_functor<fs::path, out_iter, comparer> bin_funct;
for_each(po.input_files().begin(), po.input_files().end(),
fs::recursive<bin_funct>(bin_funct(out_iter(std::cout), comparer())));
}
42 changes: 42 additions & 0 deletions trunk/src/program_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <exception>

#include "program_options.h"

namespace po = boost::program_options;

program_options::program_options(int argc, char* argv[]) {
const std::string usage = std::string("Usage: ") + argv[0] + " [OPTIONS] FILES\n";
try {
po::options_description visible_options("Available options");
visible_options.add_options()
("help", "Print this message and exit")
;

po::options_description command_line_options;
command_line_options.add(visible_options).add_options()
("files", po::value< std::vector<std::string> >(&_input_files))
;

po::positional_options_description positional_options;
positional_options.add("files", -1);

po::variables_map vm;
po::store(
po::command_line_parser(argc, argv)
.options(command_line_options)
.positional(positional_options)
.run(), vm);
po::notify(vm);

if (vm.count("help")) {
std::cout << usage;
std::cout << visible_options << "\n";
exit(0);
}
} catch(std::exception const& e) {
logger::std(e.what());
exit(1);
}
}
16 changes: 16 additions & 0 deletions trunk/src/program_options.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _PROGRAM_OPTIONS_H_
#define _PROGRAM_OPTIONS_H_

#include <vector>
#include <iostream>

#include "logger.h"

class program_options {
std::vector<std::string> _input_files;
public:
program_options(int argc, char* argv[]);
const std::vector<std::string>& input_files() const { return _input_files; }
};

#endif
22 changes: 22 additions & 0 deletions trunk/todo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
0. Выложить всё в svn и прислать мне адрес.

1. Добавить параметр --extensions jpg,gif,txt - поиск только среди
файлов с этим расширением.

2. Ввести понятие типа файла: текст, картинка, бинарный файл, ... Использовать file.

3. Определить компараторы. Написать фабрику, выдающую компаратор по типу файла.

4. При чтении директории
- создать список файлов (рекурсивно)
- разбить по типам
- для каждого типа провести сравнение по-отдельности.
- для каждого типа может существовать свой дескриптор,
который определятеся компаратором.

5. Думать о том, как сравнивать картинки. Прикрутить библиотеку для
работы с картинками. Magick++

6. Сравнение текстов, простой подход.
Удаляем все пробелы и пунктуацию. Сравниваем получившееся.

0 comments on commit 22a3c1b

Please sign in to comment.