<commit_before>/*
Copyright © 2015 <NAME>. All rights reserved.
Licensed under the Apache License, Version 2.0
*/

#if defined(__WIN32) || defined(_WIN32)
#include <Windows.h>
#endif

#include <QString>
#include <QTextCodec>
#include <QTextStream>
#include <time.h>
#include "src/getFiles.h"
#include "src/crc16.h"
#include "src/calcMd5.h"
#include "src/quickSearch.h"
#include "consoleMode.h"

namespace CloneHunter
{

static void searchQuick(CloneHunter::FilesInfo& filesInfo);
static void searchDeep(CloneHunter::FilesInfo& filesInfo, const CloneHunter::PROGRAMPARAMS& params);

static unsigned printQuickDupFiles(const CloneHunter::FilesInfo& filesInfo, const bool empty);
static unsigned printDupFiles(const CloneHunter::FilesInfo& filesInfo, const bool quickMode = false);
static void printOtherFiles(const CloneHunter::FilesInfo& filesInfo, const bool quickMode);
static void printEmptyFiles(const CloneHunter::FilesInfo& filesInfo);

int startConsoleMode(const CloneHunter::PROGRAMPARAMS& params)
{
	time_t tStart = time(0);

	consoleOut(QObject::tr("Read files"));

	CloneHunter::FilesInfo filesInfo;
	CloneHunter::getFilesInfo(params, filesInfo);

	int totalFilesCount = filesInfo.count();

	consoleOut(QString(QObject::tr("Total files: %1")).arg(totalFilesCount));

	if (!filesInfo.empty())
	{
		if (params.empty && !params.quick)
		{
			CloneHunter::sortFilesInfoByPath(filesInfo);
			printEmptyFiles(filesInfo);
		}
		else if (params.quick)
		{
			searchQuick(filesInfo);

			CloneHunter::sortFilesInfoByNameSize(filesInfo);

			consoleOut(QObject::tr("Files (without empty):"));
			unsigned notEmptyCount = printQuickDupFiles(filesInfo, params.empty);

			consoleOut(QString(QObject::tr("Total not empty dup files: %1 Total dup files: %2 Total files: %3"))
					   .arg(notEmptyCount)
					   .arg(filesInfo.size())
					   .arg(totalFilesCount));

			if (params.other)
			{
				consoleOut(QObject::tr("Other dup files:"));
				printOtherFiles(filesInfo, true);
			}
		}
		else
		{
			searchDeep(filesInfo, params);
			consoleOut(QObject::tr("Files (without empty):"));
			unsigned notEmptyCount = printDupFiles(filesInfo);

			consoleOut(QString(QObject::tr("Total not empty dup files: %1 Total dup files: %2 Total files: %3"))
					   .arg(notEmptyCount)
					   .arg(filesInfo.size())
					   .arg(totalFilesCount));

			if (params.other)
			{
				consoleOut(QObject::tr("Other files with equal sizes:"));
				CloneHunter::sortFilesInfoBySize(filesInfo);
				printOtherFiles(filesInfo, false);
			}
		}
	}

	consoleOut(QString(QObject::tr("Time: %1")).arg(time(0) - tStart));
	return 0;
}

void consoleOut(const QString& text, QString& lang)
{
	// http://stackoverflow.com/questions/4766301/windows-console-and-qt-unicode-text

	QTextStream out(stdout);

#if defined(__WIN32) || defined(_WIN32)
	if (lang == "ru")
	{
		out.setCodec("cp866"); // for windows console out (hardcoded codec example).
	}

	// Cannot redirect output to file by "prog.exe > filename":
	// WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), text.utf16(),  text.size(), NULL, NULL);

	// CP1251 output: std::cout << text.toLocal8Bit().data() << std::endl;
#endif

	out << text;
	out << endl;<commit_msg>[*] Macro.<commit_after>/*
Copyright © 2015 <NAME>. All rights reserved.
Licensed under the Apache License, Version 2.0
*/

#if defined(__WIN32) || defined(_WIN32)
#include <Windows.h>
#endif

#include <QString>
#include <QTextCodec>
#include <QTextStream>
#include <time.h>
#include "src/getFiles.h"
#include "src/crc16.h"
#include "src/calcMd5.h"
#include "src/quickSearch.h"
#include "consoleMode.h"

namespace CloneHunter
{

static void searchQuick(CloneHunter::FilesInfo& filesInfo);
static void searchDeep(CloneHunter::FilesInfo& filesInfo, const CloneHunter::PROGRAMPARAMS& params);

static unsigned printQuickDupFiles(const CloneHunter::FilesInfo& filesInfo, const bool empty);
static unsigned printDupFiles(const CloneHunter::FilesInfo& filesInfo, const bool quickMode = false);
static void printOtherFiles(const CloneHunter::FilesInfo& filesInfo, const bool quickMode);
static void printEmptyFiles(const CloneHunter::FilesInfo& filesInfo);

int startConsoleMode(const CloneHunter::PROGRAMPARAMS& params)
{
	time_t tStart = time(0);

	consoleOut(QObject::tr("Read files"));

	CloneHunter::FilesInfo filesInfo;
	CloneHunter::getFilesInfo(params, filesInfo);

	int totalFilesCount = filesInfo.count();

	consoleOut(QString(QObject::tr("Total files: %1")).arg(totalFilesCount));

	if (!filesInfo.empty())
	{
		if (params.empty && !params.quick)
		{
			CloneHunter::sortFilesInfoByPath(filesInfo);
			printEmptyFiles(filesInfo);
		}
		else if (params.quick)
		{
			searchQuick(filesInfo);

			CloneHunter::sortFilesInfoByNameSize(filesInfo);

			consoleOut(QObject::tr("Files (without empty):"));
			unsigned notEmptyCount = printQuickDupFiles(filesInfo, params.empty);

			consoleOut(QString(QObject::tr("Total not empty dup files: %1 Total dup files: %2 Total files: %3"))
					   .arg(notEmptyCount)
					   .arg(filesInfo.size())
					   .arg(totalFilesCount));

			if (params.other)
			{
				consoleOut(QObject::tr("Other dup files:"));
				printOtherFiles(filesInfo, true);
			}
		}
		else
		{
			searchDeep(filesInfo, params);
			consoleOut(QObject::tr("Files (without empty):"));
			unsigned notEmptyCount = printDupFiles(filesInfo);

			consoleOut(QString(QObject::tr("Total not empty dup files: %1 Total dup files: %2 Total files: %3"))
					   .arg(notEmptyCount)
					   .arg(filesInfo.size())
					   .arg(totalFilesCount));

			if (params.other)
			{
				consoleOut(QObject::tr("Other files with equal sizes:"));
				CloneHunter::sortFilesInfoBySize(filesInfo);
				printOtherFiles(filesInfo, false);
			}
		}
	}

	consoleOut(QString(QObject::tr("Time: %1")).arg(time(0) - tStart));
	return 0;
}

void consoleOut(const QString& text, QString& lang)
{
	// http://stackoverflow.com/questions/4766301/windows-console-and-qt-unicode-text

	QTextStream out(stdout);

#if defined(Q_OS_WIN)
	if (lang == "ru")
	{
		out.setCodec("cp866"); // for windows console out (hardcoded codec example).
	}

	// Cannot redirect output to file by "prog.exe > filename":
	// WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), text.utf16(),  text.size(), NULL, NULL);

	// CP1251 output: std::cout << text.toLocal8Bit().data() << std::endl;
#endif

	out << text;
	out << endl;
{'fraction_non_alphanumeric': 0.1431042616763642, 'fraction_numerical': 0.013524139015568485, 'mean_word_length': 5.1687681862269645, 'pattern_counts': {'":': 2, '<': 31, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3080449', 'n_tokens_mistral': 2358, 'n_tokens_neox': 2097, 'n_words': 459}