Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions CmdlineParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stdexcept>
Copy link
Author

@JurjenBokma JurjenBokma May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File size conversion throws runtime_error on invalid suffix. So we need to include stdexcept.


// project
#include "CmdlineParser.hh"
Expand Down Expand Up @@ -97,3 +98,71 @@ Parser::current_arg_is(const char* what) const
{
return 0 == std::strcmp(get_current_arg(), what);
}

namespace {

enum FILESIZE : long long
{
k = 1024,
K = k,
M = k * k,
G = k * M,
T = k * G,
P = k * T,
E = k * P,
// too big for signed long long // Z = k * E,
// too big for signed long long // Y = k * Z,
// too big for signed long long // R = k * Y,
// too big for signed long long // Q = k * R,
};


Fileinfo::filesizetype value_of_file_size_suffix(char suffix)
{
switch (toupper(suffix))
{
// No 'B': too ambiguous.
case 'K': return FILESIZE::k;
case 'M': return FILESIZE::M;
case 'G': return FILESIZE::G;
case 'T': return FILESIZE::T;
case 'P': return FILESIZE::P;
case 'E': return FILESIZE::E;
// case 'Z': return FILESIZE::Z;
// case 'Y': return FILESIZE::Y;
// case 'R': return FILESIZE::R;
// case 'Q': return FILESIZE::Q;
default: throw std::runtime_error(
"The program only understands file size suffixes "
"K, M, G, T, P or E. Lower case works too.");
};
}

}

Fileinfo::filesizetype long Parser::read_file_size(char const *text)
{

using filesizetype = Fileinfo::filesizetype;

size_t pos = 0;
filesizetype const without_suffix = std::stoll(text, &pos);

size_t const len = strlen(text);
filesizetype const multiplier =
(len - pos > 1) ?
throw std::runtime_error(
"The program only understands single-letter file size suffixes.")
:
(len > pos) ?
value_of_file_size_suffix(text[pos])
:
1;

filesizetype const retval = multiplier * without_suffix;

if (retval / multiplier != without_suffix)
throw std::runtime_error("File size overflows long long.");

return retval;
}
4 changes: 4 additions & 0 deletions CmdlineParser.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef RDFIND_CMDLINEPARSER_HH_
#define RDFIND_CMDLINEPARSER_HH_

#include "Fileinfo.hh" //for filesizetype

/**
* Command line parser, designed to be easy to use for rdfind.
* It will signal user errors by a helpful printout followed by
Expand Down Expand Up @@ -49,6 +51,8 @@ public:

bool current_arg_is(const char* what) const;

static Fileinfo::filesizetype read_file_size(char const *text);

private:
const int m_argc{};
const char** m_argv{};
Expand Down
3 changes: 3 additions & 0 deletions rdfind.1
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Ignore empty files. Setting this to true (the default) is equivalent to
.BR \-minsize " "\fIN\fR
Ignores files with less than N bytes. Default is 1, meaning empty files
are ignored.

File and buffer sizes can be given with suffix k, M, G etc. up to E,
meaning powers of 1024.
.TP
.BR \-maxsize " "\fIN\fR
Ignores files with N bytes or more. Default is 0, which means this check
Expand Down
9 changes: 6 additions & 3 deletions rdfind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ usage()
<< " false implies -minsize 0)\n"
<< " -minsize N (N=1) ignores files with size less than N "
"bytes\n"
<< " For -minsize, -maxsize and -buffersize,\n"
" Suffixes 'K', 'M', 'G' etc. up to 'E'\n"
" are accepted. Factors are 1024, not 1000.\n"
<< " -maxsize N (N=0) ignores files with size N "
"bytes and larger (use 0 to disable this check).\n"
<< " -followsymlinks true |(false) follow symlinks\n"
Expand Down Expand Up @@ -153,13 +156,13 @@ parseOptions(Parser& parser)
o.minimumfilesize = 0;
}
} else if (parser.try_parse_string("-minsize")) {
const long long minsize = std::stoll(parser.get_parsed_string());
const long long minsize = Parser::read_file_size(parser.get_parsed_string());
if (minsize < 0) {
throw std::runtime_error("negative value of minsize not allowed");
}
o.minimumfilesize = minsize;
} else if (parser.try_parse_string("-maxsize")) {
const long long maxsize = std::stoll(parser.get_parsed_string());
const long long maxsize = Parser::read_file_size(parser.get_parsed_string());
if (maxsize < 0) {
throw std::runtime_error("negative value of maxsize not allowed");
}
Expand Down Expand Up @@ -199,7 +202,7 @@ parseOptions(Parser& parser)
std::exit(EXIT_FAILURE);
}
} else if (parser.try_parse_string("-buffersize")) {
const long buffersize = std::stoll(parser.get_parsed_string());
const long buffersize = Parser::read_file_size(parser.get_parsed_string());
constexpr long max_buffersize = 128 << 20;
if (buffersize <= 0) {
std::cerr << "a negative or zero buffersize is not allowed\n";
Expand Down