Skip to content

Commit

Permalink
WIP Port to docoptcpp
Browse files Browse the repository at this point in the history
  • Loading branch information
mgautierfr committed Aug 28, 2024
1 parent 283f27f commit d2347e8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 162 deletions.
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define VERSION "undefined"
#endif

void printVersions(std::ostream& out = std::cout) {
inline void printVersions(std::ostream& out = std::cout) {
out << "zim-tools " << VERSION << std::endl;
out << std::endl;
zim::printVersions(out);
Expand Down
52 changes: 48 additions & 4 deletions src/zimcheck/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,55 @@
* MA 02110-1301, USA.
*/

#include <vector>
#include <docopt/docopt.h>
#include "../version.h"

int zimcheck (const std::vector<const char*>& args);

int main (int argc, char **argv)
static const char USAGE[] =
R"(
Zimcheck checks the quality of a ZIM file.
Usage:
zimcheck -A0CIMFPRUXDBJLW <nb_thread> ZIM_FILE
zimdump -H | --help
zimdump -V | --version
Options:
-A, --all run all tests. Default if no flags are given.
-0, --empty Empty content
-C, --checksum Internal CheckSum Test
-I, --integrity Low-level correctness/integrity checks
-M, --metadata MetaData Entries
-F, --favicon Favicon
-P, --main Main page
-R, --redundant Redundant data check
-U, --url_internal URL check - Internal URLs
-X, --url_external URL check - External URLs
-D, --details Details of error
-B, --progress Print progress report
-J, --json Output in JSON format
-H, --help Displays Help
-V, --version Displays software version
-L, --redirect_loop Checks for the existence of redirect loops
-W, --threads <nb_thead> count of threads to utilize [default: 1]
Examples:
zimcheck -A wikipedia.zim
zimcheck --checksum --redundant wikipedia.zim
zimcheck -F -R wikipedia.zim
zimcheck -M --favicon wikipedia.zim\n
)";

extern int zimcheck (const std::map<std::string, docopt::value>&);

int main (int argc, char *argv[])
{
return zimcheck(std::vector<const char*>(argv, argv+argc));
auto args = docopt::docopt(
USAGE,
{ argv + 1, argv + argc },
true,
std::string(VERSION)
);

return zimcheck(args);
}
2 changes: 1 addition & 1 deletion src/zimcheck/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ executable('zimcheck',
'../tools.cpp',
'../metadata.cpp',
include_directories : inc,
dependencies: [libzim_dep, icu_dep, thread_dep],
dependencies: [libzim_dep, icu_dep, thread_dep, docopt_dep],
install: true)


186 changes: 30 additions & 156 deletions src/zimcheck/zimcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/

#include <zim/archive.h>
#include <getopt.h>
#include <docopt/docopt.h>
#include <iostream>
#include <sstream>
#include <string>
Expand All @@ -43,36 +43,8 @@
#include "../tools.h"
#include "checks.h"

void displayHelp()
{
std::cout<<"\n"
"zimcheck checks the quality of a ZIM file.\n\n"
"Usage: zimcheck [options] zimfile\n"
"options:\n"
"-A , --all run all tests. Default if no flags are given.\n"
"-0 , --empty Empty content\n"
"-C , --checksum Internal CheckSum Test\n"
"-I , --integrity Low-level correctness/integrity checks\n"
"-M , --metadata MetaData Entries\n"
"-F , --favicon Favicon\n"
"-P , --main Main page\n"
"-R , --redundant Redundant data check\n"
"-U , --url_internal URL check - Internal URLs\n"
"-X , --url_external URL check - External URLs\n"
"-D , --details Details of error\n"
"-B , --progress Print progress report\n"
"-J , --json Output in JSON format\n"
"-H , --help Displays Help\n"
"-V , --version Displays software version\n"
"-L , --redirect_loop Checks for the existence of redirect loops\n"
"-W , --threads count of threads to utilize (default: 1)\n"
"examples:\n"
"zimcheck -A wikipedia.zim\n"
"zimcheck --checksum --redundant wikipedia.zim\n"
"zimcheck -F -R wikipedia.zim\n"
"zimcheck -M --favicon wikipedia.zim\n";
return;
}



template<class T>
std::string stringify(const T& x)
Expand All @@ -82,11 +54,8 @@ std::string stringify(const T& x)
return ss.str();
}

int zimcheck (const std::vector<const char*>& args)
int zimcheck(const std::map<std::string, docopt::value>& args)
{
const int argc = args.size();
const char* const* argv = &args[0];

// To calculate the total time taken by the program to run.
const auto starttime = std::chrono::steady_clock::now();

Expand All @@ -106,158 +75,63 @@ int zimcheck (const std::vector<const char*>& args)
ProgressBar progress(1);

StatusCode status_code = PASS;

//Parsing through arguments using getopt_long(). Both long and short arguments are allowed.
optind = 1; // reset getopt_long(), so that zimcheck() works correctly if
// called more than once
opterr = 0; // silence getopt_long()
while (1)
{
static struct option long_options[] =
{
{ "all", no_argument, 0, 'A'},
{ "progress", no_argument, 0, 'B'},
{ "empty", no_argument, 0, '0'},
{ "checksum", no_argument, 0, 'C'},
{ "integrity", no_argument, 0, 'I'},
{ "metadata", no_argument, 0, 'M'},
{ "favicon", no_argument, 0, 'F'},
{ "main", no_argument, 0, 'P'},
{ "redundant", no_argument, 0, 'R'},
{ "url_internal", no_argument, 0, 'U'},
{ "url_external", no_argument, 0, 'X'},
{ "details", no_argument, 0, 'D'},
{ "json", no_argument, 0, 'J'},
{ "threads", required_argument, 0, 'w'},
{ "help", no_argument, 0, 'H'},
{ "version", no_argument, 0, 'V'},
{ "redirect_loop",no_argument, 0, 'L'},
{ 0, 0, 0, 0}
};
int option_index = 0;
int c = getopt_long (argc, const_cast<char**>(argv), "ACIJMFPRUXLEDHBVW:acijmfpruxledhbvw:0",
long_options, &option_index);
//c = getopt (argc, argv, "ACMFPRUXED");
if(c == -1)
break;
switch (c)
{
case 'A':
case 'a':

for(auto const& arg: args) {
if (arg.first == "--all" && arg.second.asBool()) {
run_all = true;
no_args = false;
break;
case '0':
} else if (arg.first == "--empty" && arg.second.asBool()) {
enabled_tests.enable(TestType::EMPTY);
no_args = false;
break;
case 'C':
case 'c':
} else if (arg.first == "--checksum" && arg.second.asBool()) {
enabled_tests.enable(TestType::CHECKSUM);
no_args = false;
break;
case 'I':
case 'i':
} else if (arg.first == "--integrity" && arg.second.asBool()) {
enabled_tests.enable(TestType::INTEGRITY);
no_args = false;
break;
case 'M':
case 'm':
} else if (arg.first == "--metadata" && arg.second.asBool()) {
enabled_tests.enable(TestType::METADATA);
no_args = false;
break;
case 'B':
case 'b':
progress.set_progress_report(true);
break;
case 'F':
case 'f':
} else if (arg.first == "--progress") {
progress.set_progress_report(arg.second.asBool());
} else if (arg.first == "--favicon" && arg.second.asBool()) {
enabled_tests.enable(TestType::FAVICON);
no_args = false;
break;
case 'P':
case 'p':
} else if (arg.first == "--main" && arg.second.asBool()) {
enabled_tests.enable(TestType::MAIN_PAGE);
no_args = false;
break;
case 'R':
case 'r':
} else if (arg.first == "--redundant" && arg.second.asBool()) {
enabled_tests.enable(TestType::REDUNDANT);
no_args = false;
break;
case 'U':
case 'u':
} else if (arg.first == "--url_internal" && arg.second.asBool()) {
enabled_tests.enable(TestType::URL_INTERNAL);
no_args = false;
break;
case 'X':
case 'x':
} else if (arg.first == "--url_external" && arg.second.asBool()) {
enabled_tests.enable(TestType::URL_EXTERNAL);
no_args = false;
break;
case 'L':
case 'l':
} else if (arg.first == "--redirect_loop" && arg.second.asBool()) {
enabled_tests.enable(TestType::REDIRECT);
no_args = false;
break;
case 'D':
case 'd':
error_details = true;
break;
case 'J':
case 'j':
json = true;
break;
case 'W':
case 'w':
thread_count = atoi(optarg);
break;
case 'H':
case 'h':
help=true;
break;
case '?':
std::cerr<<"Unknown option `" << argv[optind-1] << "'\n";
displayHelp();
return 1;
case 'V':
case 'v':
printVersions();
return 0;
default:
abort ();
} else if (arg.first == "--details") {
error_details = arg.second.asBool();
} else if (arg.first == "--json") {
json = arg.second.asBool();
} else if (arg.first == "--threads") {
thread_count = arg.second.asLong();
} else if (arg.first == "ZIM_FILE") {
filename = arg.second.asString();
} else if (arg.first == "--version" && arg.second.asBool()) {
printVersions();
return 0;
}
}

//Displaying Help for --help argument
if(help)
{
displayHelp();
return -1;
}

//If no arguments are given to the program, all the tests are performed.
if ( run_all || no_args )
{
enabled_tests.enableAll();
}

//Obtaining filename from argument list
filename = "";
for(int i = 0; i < argc; i++)
{
if( (argv[i][0] != '-') && (i != 0))
{
filename = argv[i];
}
}
if(filename == "")
{
std::cerr<<"No file provided as argument\n";
displayHelp();
return -1;
}

ErrorLogger error(json);
error.addInfo("zimcheck_version", std::string(VERSION));
//Tests.
Expand Down

0 comments on commit d2347e8

Please sign in to comment.