const char* ReDirTools::m_version = "2015.01.03";
+static const char* s_empty[] = { NULL };
+
static const char* s_standardFilterUsage[] = {
"-D<n> or --max-depth=<n> Default: 512",
" the depth of the subdirectory is lower or equal <n>",
" <v> 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",
+ "-P<p> or --pathname-pattern=<p>",
+ " 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<p> or --basename-pattern=<p>",
+ " 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<l> or --type=<l>",
" the file type",
" <l> is a list of <v> values:",
" lists the metadata (size, modification date ...) of the selected files",
NULL
};
+const char* s_listExamples[] = {
+ "dirtool list --min-size=10M e:\\data",
+ "dirtool list --type=f -y7d --size=10M -p*.cpp;*.hpp;Makefile*;^*~ /home/data" ,
+ NULL
+};
+
+static const char* s_helpSummary[] = {
+ "dirtool or dt <command> <opts>",
+ " Useful commands around a directry tree",
+ " Type 'dirtool help <command>' for more help",
+ "<command>:",
+ "help shows info about the arguments/options",
+ "list shows the meta data of the selected files",
+ "statistic shows statistics about a direcctory tree",
+ NULL
+};
+
+static const char* s_statisticUsage[] = {
+ "<command>:"
+ "st(atistic) [<opts_stat>] <path> [<depth>]",
+ " shows a statistic about a directory tree",
+ "<path> a directory path: relative or absolute",
+ "<depth> 0: only the summary of <path> will be shown",
+ " 1: shows the summery of each subdir of <path> and the total",
+ " n: shows the summery of each subdir until level <n> and the total",
+ " default: 1",
+ "<opts_stat>:",
+ "-q or --quiet",
+ " does not show additional information, e.g. runtime",
+ "-t<n> or --trace-interval=<n>",
+ " trace the current path every <n> seconds.",
+ " If n<=0: no trace. Default: 60",
+ "-k or --kbyte",
+ " output is '<kbyte> 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",
+ NULL
+};
/**
*/
ReDirOptions::ReDirOptions(const char* usage[], const char* examples[]) :
m_programArgs(usage, examples),
- m_patternList(),
+ m_nodePatterns(),
+ m_pathPatterns(),
m_compoundUsage(NULL),
m_countCompoundUsage(0)
{
* Adds a usage component to the compound usage message list.
* @param usage a string vector containing a part of the usage message
*/
-void ReDirOptions::addCompundUsage(const char** usage){
+void ReDirOptions::addCompoundUsage(const char** usage){
int start = 0;
while(m_compoundUsage[start] != NULL)
assert(++start < m_countCompoundUsage);
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.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);
}
/**
*
* @param filter OUT: the filter to set
*/
-void ReDirOptions::setFilterFromProgramArgs(DirEntryFilter_t& filter){
+void ReDirOptions::setFilterFromProgramArgs(ReDirEntryFilter_t& filter){
ReByteBuffer buffer;
- if (m_programArgs.getString("younger", buffer) != NULL)
- filter.m_maxAge = checkDate(m_programArgs.getString("younger", buffer));
- if (m_programArgs.getString("older", buffer) != NULL)
- filter.m_minAge = checkDate(m_programArgs.getString("older", buffer));
- if (m_programArgs.getString("maxsize", buffer) != NULL)
- filter.m_maxSize = checkSize(m_programArgs.getString("maxsize", buffer));
- if (m_programArgs.getString("minsize", buffer) != NULL)
- filter.m_minSize = checkSize(m_programArgs.getString("minsize", buffer));
+ if (m_programArgs.getString("younger", buffer)[0] != '\0')
+ filter.m_maxAge = checkDate(buffer.str());
+ if (m_programArgs.getString("older", buffer)[0] != '\0')
+ filter.m_minAge = checkDate(buffer.str());
+ if (m_programArgs.getString("maxsize", buffer)[0] != '\0')
+ filter.m_maxSize = checkSize(buffer.str());
+ if (m_programArgs.getString("minsize", buffer)[0] != '\0')
+ filter.m_minSize = checkSize(buffer.str());
filter.m_minDepth = m_programArgs.getInt("mindepth");
filter.m_maxDepth = m_programArgs.getInt("maxdepth");
- if (m_programArgs.getArgCount() > 0)
- {
- m_patternList.set(m_programArgs.getArg(0));
- filter.m_nodePatterns = &m_patternList;
+ if (m_programArgs.getString("nodepattern", buffer) != NULL){
+ m_nodePatterns.set(buffer.str());
+ filter.m_nodePatterns = &m_nodePatterns;
+ }
+ if (m_programArgs.getString("pathpattern", buffer) != NULL){
+ m_pathPatterns.set(buffer.str());
+ filter.m_pathPatterns = &m_nodePatterns;
}
}
+/**
+ * Prints a help message, the error message and exits.
+ *
+ * @param errorMessage the error message.
+ * @param message2 an additional message
+ */
+
+void ReDirOptions::help(const char* errorMessage, const char* message2 ){
+ ReByteBuffer msg(errorMessage, -1);
+ if (message2 != NULL)
+ msg.append(message2, -1);
+ m_programArgs.help(msg.str(), false, stdout);
+ exit(1);
+}
/**
* Checks the correctness of the standard filter options.
*
exit(1);
}
-static const char* statisticCall[] = {
- "<command>:"
- "st(atistic) [<opts_stat>] <path> [<depth>]",
- " shows a statistic about a directory tree",
- "<path> a directory path: relative or absolute",
- "<depth> 0: only the summary of <path> will be shown",
- " 1: shows the summery of each subdir of <path> and the total",
- " n: shows the summery of each subdir until level <n> and the total",
- " default: 1",
- "<opts_stat>:",
- "-q or --quiet",
- " does not show additional information, e.g. runtime",
- "-t<n> or --trace-interval=<n>",
- " trace the current path every <n> seconds.",
- " If n<=0: no trace. Default: 60",
- "-k or --kbyte",
- " output is '<kbyte> path' (like du)",
- NULL
-};
-const char* statisticExamples[] = {
- "Examples:",
- "dirtool st -q -t0 e:\\windows",
- "dirtool statistic --quiet --kbyte --trace-interval=60 ../mail 2",
- "dirtool stat -q --kbyte d:data 2",
- NULL
-};
-
+/**
+ * Prints a vector of lines.
+ *
+ * @param lines a vector of lines without newline ('\n')
+ */
static void printField(const char** lines){
for (int ix = 0; lines[ix] != NULL; ix++){
printf("%s\n", lines[ix]);
* Prints an message how to use the statistic module and exits.
*/
void ReDirTools::statisticUsage(){
- printField(statisticCall);
- printField(statisticExamples);
+ printField(s_statisticUsage);
+ printField(s_statisticExamples);
+}
+
+/**
+ * Constructor.
+ */
+ReDirList::ReDirList() :
+ ReDirOptions(s_empty, s_listExamples)
+{
+ addStandardFilterOptions();
+ initCompoundUsage(sizeof s_listUsage + sizeof s_standardFilterUsage);
+ addCompoundUsage(s_listUsage);
+ addCompoundUsage(s_standardFilterUsage);
+ m_programArgs.setUsage(m_compoundUsage);
+}
+
+/**
+ * Gets the arguments for the "list" command and execute this.
+ *
+ * @param argc the number of arguments
+ * @param argav the argument vector
+ */
+void ReDirList::list(int argc, char* argv[]){
+ ReDirEntryFilter_t filter;
+ try {
+ m_programArgs.init(argc, argv);
+ setFilterFromProgramArgs(filter);
+ if (m_programArgs.getArgCount() == 0)
+ help(i18n("no arguments given (missing path)"));
+ ReByteBuffer bufferRights;
+ ReByteBuffer bufferTime;
+ for (int ix = 0; ix < m_programArgs.getArgCount(); ix++){
+ ReTraverser traverser(m_programArgs.getArg(ix));
+ traverser.setMinLevel(filter.m_maxDepth);
+ traverser.setMaxLevel(filter.m_maxDepth);
+ int level;
+ ReDirStatus_t* entry;
+ while( (entry = traverser.nextFile(level, &filter)) != NULL){
+ if (! printOneFile(entry))
+ printf("%s %12lld %s %s%s\n",
+ entry->rightsAsString(bufferRights), entry->fileSize(),
+ entry->filetimeAsString(bufferTime),
+ entry->m_path.str(), entry->node());
+ }
+ }
+ } catch(ReOptionException& exc){
+ help(exc.getMessage());
+ }
}
/**
* @param argav the argument vector
*/
void ReDirTools::list(int argc, char* argv[]){
+ ReDirList lister;
+ lister.list(argc, argv);
}
*/
void ReDirTools::statistic(int argc, char* argv[]){
time_t start = time(NULL);
- ReProgramArgs args(statisticCall, statisticExamples);
+ ReProgramArgs args(s_statisticUsage, s_statisticExamples);
args.addBool("quiet", "no additional information", 'q', "quiet", false);
args.addBool("kbyte", "output is '<kbyte> <path>'", 'k', "kbyte", false);
args.addInt("trace", "trace each <n> seconds the current path", 't', "trace-interval", 60);
bool rc = fullArg.startsWith(part, -1);
return rc;
}
-static const char* helpSummary[] = {
- "dirtool or dt <command> <opts>",
- "<command>:",
- "help shows info about the arguments/options",
- "list shows info about selected files",
- "statistic shows statistics about a direcctory tree",
- NULL
-};
/**
* Gets the arguments for any command and execute this.
*
ReDirTools tools;
if (argc < 2)
tools.usage("missing arguments");
- if (isArg("list", argv[1]))
- tools.list(argc - 1, argv + 1);
- else if (isArg("help", argv[1]))
- printField(helpSummary);
- else if (isArg("statistic", argv[1]))
- tools.statistic(argc - 1, argv + 1);
- else if (isArg("test", argv[1])){
+ argc--;
+ argv++;
+ const char* arg0 = argv[0];
+ if (isArg("list", arg0))
+ tools.list(argc, argv);
+ else if (isArg("help", arg0))
+ printField(s_helpSummary);
+ else if (isArg("statistic", arg0))
+ tools.statistic(argc, argv);
+ else if (isArg("test", arg0)){
void testAll();
testAll();
}else