From: kawi Date: Sun, 4 Jan 2015 16:59:33 +0000 (+0100) Subject: dirtool help stuff improvements X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=685d6bbf90369d59a338c5579ce5f5d492050e5c;p=crepublib dirtool help stuff improvements --- diff --git a/base/ReProgramArgs.cpp b/base/ReProgramArgs.cpp index ba9d8d1..f8dcdb4 100644 --- a/base/ReProgramArgs.cpp +++ b/base/ReProgramArgs.cpp @@ -7,6 +7,7 @@ #include "base/rebase.hpp" +const char* ReProgramArgs::PREFIX_LINE_OPTION = " "; /** @brief Constructor. * @@ -129,7 +130,11 @@ void ReProgramArgs::setUsage(const char* usage[]){ void ReProgramArgs::addProperties(const char*name, const char* description, char shortOpt, const char* longOpt, DataType dataType, const char* defaultValue, size_t lengthValue){ ReByteBuffer properties; - properties.append(description, strlen(description)).append("\1", 1); + ReByteBuffer descr(description, -1); + ReByteBuffer replacement("\n", 1); + replacement.append(PREFIX_LINE_OPTION); + descr.replaceAll("\n", 1, replacement.str(), replacement.length()); + properties.append(descr).append("\1", 1); properties.append(&shortOpt, 1).append("\1", 1); properties.append(longOpt, strlen(longOpt)).append("\1", 1); properties.append((char*) &dataType, 1).append("\1", 1); @@ -571,15 +576,23 @@ void ReProgramArgs::help(const char* message, bool issueLastError, ReStringList& line.append(param.str(), -1).append(" ", 1).append(i18n(" or "), -1); } line.append(i18n("--"), -1).append(properties.strOf(IxLong), -1); - if (param.length() > 0) - line.append("=", -1).append(param.str(), -1) - .append(i18n(" Default value: "), -1).append(properties.strOf(IxDefault), -1); + if (param.length() > 0){ + line.append("=", -1).append(param.str(), -1); + if (dataType != DT_STRING || properties.strLengthOf(IxDefault) > 0){ + line.append(i18n(" Default value: "), -1); + if (dataType == DT_STRING) + line.append("'", 1); + line.append(properties.strOf(IxDefault), -1); + if (dataType == DT_STRING) + line.append("'", 1); + } + } lines.append(line.str()); - line.set("\t", 1).append(properties.strOf(IxDescr), -1); + line.set(PREFIX_LINE_OPTION, -1).append(properties.strOf(IxDescr), -1); lines.append(line.str()); } if (m_examples.count() > 0){ - lines.append(i18n("Example:")); + lines.append(i18n("Example(s):")); lines.append(m_examples); } if (issueLastError && m_lastError.length() > 0){ @@ -587,7 +600,7 @@ void ReProgramArgs::help(const char* message, bool issueLastError, ReStringList& lines.append(line.str()); } - if (message != NULL){ + if (message != NULL && message[0] != '\0'){ line.set("+++ ", 4).append(message, -1); lines.append(line.str()); } diff --git a/base/ReProgramArgs.hpp b/base/ReProgramArgs.hpp index b5243d4..97e1018 100644 --- a/base/ReProgramArgs.hpp +++ b/base/ReProgramArgs.hpp @@ -35,6 +35,7 @@ public: *

The connection between definition and retrieval are names.

*/ class ReProgramArgs { + static const char* PREFIX_LINE_OPTION; public: enum DataType { DT_UNDEF = 0, diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index 0989152..e236801 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -11,63 +11,6 @@ const char* ReDirTools::m_version = "2015.01.03"; static const char* s_empty[] = { NULL }; - -static const char* s_standardFilterUsage[] = { - "-D or --max-depth= Default: 512", - " the depth of the subdirectory is lower or equal ", - " 0: search is done only in the base directory", - "-d or --min-depth= Default: 0", - " the depth of the subdirectory is greater or equal ", - " 0: search is done in all subdirectories", - "-o or --older-than=", - " the modification date is older than ", - " is a date (e.g. 2015.02.17) or number followed by an unit", - " units: m(inutes) h(hours), d(days). Default: m(inutes)", - " examples: -o25 --older-than=30d -o24h -o2009.3.2/12:00 -o1999.01.01", - "-q or --quiet", - " no additional information like runtime", - "-P

or --pathname-pattern=

", - " a list of patterns for the path (without basename) separated by ';'", - " Each pattern can contain '*' as wildcard", - " If the first character is '^' the pattern is a 'not pattern':" - " A directory will be entered if at least one of the positive patterns", - " and none of the 'not patterns' matches", - " examples: '*;^*/.git/' '*/cache/;*/temp/", - "-p

or --basename-pattern=

", - " a list of patterns for the basename (filename without path) separated by ';'", - " Each pattern can contain '*' as wildcard", - " If the first character is '^' the pattern is a 'not pattern':" - " A file will be found if at least one of the positive patterns and none", - " of the 'not patterns' matches", - " examples: '*.cpp;*.hpp;Make*' '*;^*.bak;^*~", - "-t or --trace-interval= Default: 0", - " all seconds the current path will be traced", - " 0: no trace", - "-t or --type=", - " the file type", - " is a list of values:", - " : b(lock) c(har) d(irectory) (l)i(nkdir) l(ink) o(ther)", - " p(ipe) s(ocket) r(egular)", - " -sets: S(pecial)=bcspo N(ondir)=Slr", - " examples: -td --type=dr -tNi", - "-y or --younger-than=", - " the modification date is younger than ", - " is a date (e.g. 2015.02.17) or number followed by an unit", - " units: m(inutes) h(hours), d(days). Default: m(inutes)", - " examples: -y25 --younger-than=30d -y1999.12.31", - "-Z or --max-size=", - " the filesize is greater or equal ", - " is a number followed by an unit", - " units: k(Byte) K(iByte) m(Byte), M(iByte), g(Byte) G(iByte)", - " example: -Z50m --max-size=1G", - "-z or --min-size=", - " the filesize is greater or equal ", - " is a number followed by an unit", - " units: k(Byte) K(iByte) m(Byte), M(iByte), g(Byte) G(iByte)", - " example: -z50m --min-size=1G", - NULL -}; - const char* s_listUsage[] = { ": list", " lists the metadata (size, modification date ...) of the selected files", @@ -100,17 +43,9 @@ static const char* s_statisticUsage[] = { " n: shows the summery of each subdir until level and the total", " default: 1", ":", - "-q or --quiet", - " does not show additional information, e.g. runtime", - "-t or --trace-interval=", - " trace the current path every seconds.", - " If n<=0: no trace. Default: 60", - "-k or --kbyte", - " output is ' path' (like du)", NULL }; const char* s_statisticExamples[] = { - "Examples:", "dirtool st -q -t0 e:\\windows", "dirtool statistic --quiet --kbyte --trace-interval=60 ../mail 2", "dirtool stat -q --kbyte d:data 2", @@ -168,17 +103,68 @@ void ReDirOptions::addCompoundUsage(const char** usage){ * Adds the standard filter options. */ void ReDirOptions::addStandardFilterOptions(){ - m_programArgs.addInt("maxdepth", "maximal subdir depth", 'D', "max-depth", 512); - m_programArgs.addInt("mindepth", "minimal subdir depth", 'd', "min-depth", 512); - m_programArgs.addString("older", "older than", 'o', "older-than", false, NULL); - m_programArgs.addString("nodepattern", "pattern list for the basename", 'p', "basename-pattern", false, NULL); - m_programArgs.addString("pathpattern", "pattern list for the path", 'P', "path-pattern", false, NULL); - m_programArgs.addBool("quiet", "suppress additional info", 'q', "quiet", false); - m_programArgs.addInt("trace", "trace interval", 'T', "trace-interval", 0); - m_programArgs.addString("type", "file type", 't', "type", false, NULL); - m_programArgs.addString("younger", "younger than", 'y', "younger-than", false, NULL); - m_programArgs.addString("maxsize", "maximal filesize", 'Z', "max-size", false, NULL); - m_programArgs.addString("minsize", "minimal filesize", 'z', "min-size", false, NULL); + m_programArgs.addInt("maxdepth", + i18n("the depth of the subdirectory is lower or equal \n" + "0: search is done only in the base directory"), + 'D', "max-depth", 512); + m_programArgs.addInt("mindepth", + i18n("the depth of the subdirectory is greater or equal \n" + "0: search is done in all subdirectories"), + 'd', "min-depth", 512); + m_programArgs.addString("older", + i18n("the modification date is older than \n" + " is a date (e.g. 2015.02.17) or number followed by an unit\n" + "units: m(inutes) h(hours), d(days). Default: m(inutes)\n" + "examples: -o25 --older-than=30d -o24h -o2009.3.2/12:00 -o1999.01.01"), + 'o', "older-than", false, NULL); + m_programArgs.addString("pathpattern", + i18n("a list of patterns for the path (without basename) separated by ';'\n" + "Each pattern can contain '*' as wildcard\n" + "If the first character is '^' the pattern is a 'not pattern':\n" + "A directory will be entered if at least one of the positive patterns\n" + "and none of the 'not patterns' matches\n" + "examples: '*;^*/.git/' '*/cache/;*/temp/"), + 'P', "path-pattern", false, NULL); + m_programArgs.addString("nodepattern", + i18n("a list of patterns for the basename (name without path) separated by ';'\n" + "Each pattern can contain '*' as wildcard\n" + "If the first character is '^' the pattern is a 'not pattern':\n" + "A file will be found if at least one of the positive patterns and none\n" + "of the 'not patterns' matches\n" + "examples: '*.cpp;*.hpp;Make*' '*;^*.bak;^*~"), + 'p', "basename-pattern", false, NULL); + m_programArgs.addBool("quiet", + i18n("no additional information like runtime"), + 'q', "quiet", false); + m_programArgs.addInt("trace", + i18n("all seconds the current path will be traced\n" + "0: no trace"), + 'T', "trace-interval", 0); + m_programArgs.addString("type", + i18n("the file type\n" + " is a list of values:\n" + ": b(lock) c(har) d(irectory) (l)i(nkdir) l(ink) o(ther)\n" + " p(ipe) s(ocket) r(egular)\n" + "-sets: S(pecial)=bcspo N(ondir)=Slr\n" + "examples: -td --type=dr -tNi"), + 't', "type", false, NULL); + m_programArgs.addString("younger", + i18n("the modification date is younger than \n" + " is a date (e.g. 2015.02.17) or number followed by an unit\n" + "units: m(inutes) h(hours), d(days). Default: m(inutes)"), + 'y', "younger-than", false, NULL); + m_programArgs.addString("maxsize", + i18n("the filesize is greater or equal \n" + " is a number followed by an unit\n" + "units: b(yte) k(Byte) K(iByte) m(Byte), M(iByte), g(Byte) G(iByte)\n" + "examples: -Z50m --max-size=1G"), + 'Z', "max-size", false, NULL); + m_programArgs.addString("minsize", + i18n("the filesize is greater or equal \n" + " is a number followed by an unit\n" + "units: b(yte) k(Byte) K(iByte) m(Byte), M(iByte), g(Byte) G(iByte)\n" + "examples: -z50m --min-size=1G"), + 'z', "min-size", false, NULL); } /** @@ -398,7 +384,9 @@ void ReDirOptions::setFilterFromProgramArgs(ReDirEntryFilter_t& filter){ */ void ReDirOptions::help(const char* errorMessage, const char* message2 ){ - ReByteBuffer msg(errorMessage, -1); + ReByteBuffer msg; + if (errorMessage != 0) + msg.append(errorMessage, -1); if (message2 != NULL) msg.append(message2, -1); m_programArgs.help(msg.str(), false, stdout); @@ -480,18 +468,66 @@ ReDirStatisticData& ReDirStatisticData::add(const ReDirStatisticData& source){ * Constructor. */ ReDirStatistic::ReDirStatistic(int deltaList, int deltaBuffer) : + ReDirOptions(s_statisticUsage, s_statisticExamples), m_list(deltaList, deltaBuffer), m_traceInterval(0), m_lastTrace(0) { + m_programArgs.addBool("quiet", + i18n("does not show additional information, e.g. runtime"), + 'q', "quiet", false); + m_programArgs.addBool("kbyte", + i18n("output is ' ' (like unix 'du' command)"), + 'k', "kbyte", false); + m_programArgs.addInt("trace", + i18n("trace the current path every seconds.\n" + "0: no trace"), + 't', "trace-interval", 60); } /** * Destructor. */ ReDirStatistic::~ReDirStatistic(){ - } +/** + * Build the statistic and print the results. + * + * @param arc count of arguments in argv + * @param argv the program arguments. + */ +void ReDirStatistic::run(int argc, char* argv[]){ + time_t start = time(NULL); + try { + m_programArgs.init(argc, argv); + if (m_programArgs.getArgCount() < 1) + m_programArgs.help("statistic: missing path", false, stdout); + int depth = 1; + if (m_programArgs.getArgCount() > 1) + depth = atol(m_programArgs.getArg(1)); + ReDirStatistic statistic; + statistic.setTraceInterval(m_programArgs.getInt("trace")); + void (*proc) (const ReDirStatisticData& data, + ReDirStatistic& parent, ReByteBuffer& line) = &formatWithSizeFilesAndDirs; + if (m_programArgs.getBool("kbyte")) + proc = &formatLikeDu; + const ReStringList& list = statistic.calculate(m_programArgs.getArg(0), depth, proc); + ReByteBuffer buffer; + for (size_t ix = 0; ix < list.count(); ix++){ + buffer.set(list.strOf(ix), list.strLengthOf(ix)); + printf("%s\n", buffer.str()); + } + if (! m_programArgs.getBool("quiet")){ + int duration = int(time(NULL) - start); + printf("Duration: "); + if (duration >= 3600) + printf("%d:", duration / 3600); + printf("%02d:%02d\n", duration % 3600 / 60, duration % 60); + } + } catch (ReOptionException& exc) { + m_programArgs.help(exc.getMessage(), false, stdout); + } +} /** * Calculates the statistic of a directory tree. * @@ -650,21 +686,19 @@ static void printField(const char** lines){ * Prints an message how to use the statistic module and exits. */ void ReDirTools::statisticUsage(){ - printField(s_statisticUsage); - printField(s_statisticExamples); + ReDirStatistic statistic; + statistic.programArgs().help(NULL, false, stdout); } /** * Constructor. */ ReDirList::ReDirList() : - ReDirOptions(s_empty, s_listExamples) + ReDirOptions(s_listUsage, s_listExamples) { + m_programArgs.addBool("short", i18n("output is only path and basename"), + '1', "--short", false); addStandardFilterOptions(); - initCompoundUsage(sizeof s_listUsage + sizeof s_standardFilterUsage); - addCompoundUsage(s_listUsage); - addCompoundUsage(s_standardFilterUsage); - m_programArgs.setUsage(m_compoundUsage); } /** @@ -679,6 +713,7 @@ void ReDirList::list(int argc, char* argv[]){ time_t start = time(NULL); m_programArgs.init(argc, argv); bool verbose = ! m_programArgs.getBool("quiet"); + bool shortOutput = m_programArgs.getBool("short"); setFilterFromProgramArgs(filter); if (m_programArgs.getArgCount() == 0) help(i18n("no arguments given (missing path)")); @@ -700,12 +735,17 @@ void ReDirList::list(int argc, char* argv[]){ files++; sumSizes += entry->fileSize(); } - if (! printOneFile(entry)) - printf("%s %12.6f %s %02x %s%s\n", - entry->rightsAsString(bufferRights), entry->fileSize() / 1E6, - entry->filetimeAsString(bufferTime), - entry->type(), - entry->m_path.str(), entry->node()); + if (! printOneFile(entry)){ + if (shortOutput) + printf("%s%s\n", entry->m_path.str(), entry->node()); + else + printf("%s %12.6f %s %02x %s%s\n", + entry->rightsAsString(bufferRights), + entry->fileSize() / 1E6, + entry->filetimeAsString(bufferTime), + entry->type(), + entry->m_path.str(), entry->node()); + } } } if (verbose){ @@ -729,61 +769,56 @@ void ReDirTools::list(int argc, char* argv[]){ lister.list(argc, argv); } +/** + * Tests whether a abrevation of an argument is given. + * @param full the full name + * @param part the part to test + * @return true: part is a prefix of full + */ +static bool isArg(const char* full, const char* part){ + ReByteBuffer fullArg(full); + bool rc = fullArg.startsWith(part, -1); + return rc; +} /** - * Gets the arguments for the "statistic" command and execute this. + * Gets the arguments for the "help" command and execute this. * * @param argc the number of arguments * @param argav the argument vector */ -void ReDirTools::statistic(int argc, char* argv[]){ - time_t start = time(NULL); - ReProgramArgs args(s_statisticUsage, s_statisticExamples); - args.addBool("quiet", "no additional information", 'q', "quiet", false); - args.addBool("kbyte", "output is ' '", 'k', "kbyte", false); - args.addInt("trace", "trace each seconds the current path", 't', "trace-interval", 60); - try { - args.init(argc, argv); - if (args.getArgCount() < 1) - usage("statistic: missing path"); - int depth = 1; - if (args.getArgCount() > 1) - depth = atol(args.getArg(1)); - ReDirStatistic statistic; - statistic.setTraceInterval(args.getInt("trace")); - void (*proc) (const ReDirStatisticData& data, - ReDirStatistic& parent, ReByteBuffer& line) = &formatWithSizeFilesAndDirs; - if (args.getBool("kbyte")) - proc = &formatLikeDu; - const ReStringList& list = statistic.calculate(args.getArg(0), depth, proc); - ReByteBuffer buffer; - for (size_t ix = 0; ix < list.count(); ix++){ - buffer.set(list.strOf(ix), list.strLengthOf(ix)); - printf("%s\n", buffer.str()); - } - if (! args.getBool("quiet")){ - int duration = int(time(NULL) - start); - printf("Duration: "); - if (duration >= 3600) - printf("%d:", duration / 3600); - printf("%02d:%02d\n", duration % 3600 / 60, duration % 60); - } - } catch (ReOptionException& exc) { - usage(exc.getMessage()); +void ReDirTools::help(int argc, char* argv[]){ + if (argc < 1) + printField(s_helpSummary); + else { + argc--; + argv++; + const char* arg0 = argv[0]; + if (isArg("list", arg0)){ + ReDirList list; + list.help(NULL); + } else if (isArg("help", arg0)) + printField(s_helpSummary); + else if (isArg("statistic", arg0)){ + ReDirStatistic stat; + stat.help(NULL); + } else if (isArg("test", arg0)){ + void testAll(); + testAll(); + } else + printf("+++ unknown sub command: %s\n", arg0); } } /** - * Tests whether a abrevation of an argument is given. - * @param full the full name - * @param part the part to test - * @return true: part is a prefix of full + * Gets the arguments for the "statistic" command and execute this. + * + * @param argc the number of arguments + * @param argav the argument vector */ -static bool isArg(const char* full, const char* part){ - ReByteBuffer fullArg(full); - bool rc = fullArg.startsWith(part, -1); - return rc; +void ReDirTools::statistic(int argc, char* argv[]){ } + /** * Gets the arguments for any command and execute this. * @@ -800,7 +835,7 @@ int ReDirTools::main(int argc, char* argv[]){ if (isArg("list", arg0)) tools.list(argc, argv); else if (isArg("help", arg0)) - printField(s_helpSummary); + tools.help(argc, argv); else if (isArg("statistic", arg0)) tools.statistic(argc, argv); else if (isArg("test", arg0)){ diff --git a/os/ReDirTools.hpp b/os/ReDirTools.hpp index 7e1b2fd..37c0351 100644 --- a/os/ReDirTools.hpp +++ b/os/ReDirTools.hpp @@ -66,7 +66,7 @@ extern void formatWithSizeFilesAndDirs(const ReDirStatisticData& data, /** * Calculates a statistic of a directory tree. */ -class ReDirStatistic { +class ReDirStatistic : public ReDirOptions { public: ReDirStatistic(int deltaList = 512, int deltaBuffer = 0x10000); ~ReDirStatistic(); @@ -74,6 +74,7 @@ public: const ReStringList& calculate(const char* base, int depth, void (*format)(const ReDirStatisticData& data, ReDirStatistic& parent, ReByteBuffer& line) = formatLikeDu); + void run(int argc, char* argv[]); void setTraceInterval(int interval){ m_traceInterval = interval; } @@ -88,6 +89,7 @@ class ReDirTools { public: virtual void usage(const char* msg, const char* msg2 = NULL); void dirListUsage(); + void help(int argc, char* argv[]); void list(int argc, char* argv[]); void statisticUsage(); void statistic(int argc, char* argv[]);