append(" ");
if (ix < bytesPerLine - 1
&& (groupWidth == 1 || ix % groupWidth == groupWidth - 1))
- append(" ", 1);
+ appendChar(' ');
if (ix < bytesPerLine - 1 && gapBehind > 0
&& (gapBehind == 1 || ix % gapBehind == gapBehind - 1))
- append(" ", 1);
+ appendChar(' ');
}
if (withAscii){
if (separator != NULL)
&& (gapBehind == 1 || ix % gapBehind == gapBehind - 1))
append(" ", 1);
}
- append("\n", 1);
+ appendChar('\n');
length = length <= (size_t) bytesPerLine ? 0 : length - bytesPerLine;
data += bytesPerLine;
offset += bytesPerLine;
ReByteBuffer& append(const Byte* source, size_t length = -1);
ReByteBuffer& append(const ReByteBuffer& source);
ReByteBuffer& append(double, const char* format = "%f");
+ /** Appends a character.
+ * @param aChar character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendChar(char aChar){
+ setLength(m_length + 1);
+ m_buffer[m_length - 1] = aChar;
+ return *this;
+ }
+ /** Appends a character at least one time.
+ * @param aChar character to append
+ * @param count number of times to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendChar(char aChar, int count){
+ if (count > 0){
+ size_t oldLength = m_length;
+ setLength(m_length + count);
+ memset(m_buffer + oldLength, aChar, count);
+ }
+ return *this;
+ }
ReByteBuffer& appendHexDump(const char* data, size_t length = -1,
int offset = 0, int bytePerLine = 16,
const char* offsetFormat = "%04x: ", bool withAscii = true,
return index >= m_length ? 0 : m_buffer[index];
}
int atoi(size_t start = 0, int end = -1) const;
- /** @brief Returns the buffer.
+ /** @brief Returns the buffer (permitting modifying).
* @return The internal used buffer.
*/
inline Byte* buffer() const{
bool endsWith(const Byte* tail, size_t tailLength = -1,
bool ignoreCase = false) const;
void ensureSize(size_t size);
+ /** After the call the last character is the given.
+ * @param aChar the character which will be the last
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& ensureLastChar(char aChar){
+ if (lastChar() != aChar)
+ appendChar(aChar);
+ return *this;
+ }
/** @brief Tests whether another instance is equal to this instance.
* @param buffer the buffer to compare
* @return <code>true</code>: the buffer's contents are equal
*/
- inline bool equals(const ReByteBuffer& buffer){
+ inline bool equals(const ReByteBuffer& buffer) const{
bool rc = buffer.length() == m_length && _memcmp(buffer.str(), m_buffer, m_length) == 0;
return rc;
}
inline bool insert(size_t ix, const Byte* source, size_t length){
return splice(ix, 0, source, length);
}
+ /** Returns the last character.
+ * @return '\0': empty buffer<br>
+ * otherwise: the last character
+ */
+ inline char lastChar() const {
+ return m_length == 0 ? '\0' : m_buffer[m_length - 1];
+ }
/**@brief Returns the length of the buffer (the count of used bytes).
* @return The count of the allocated bytes in the internal buffer.
*/
inline size_t length() const{
return m_length;
}
+ /** Sets the length to a lower value.
+ * @param decrement the count to reduce the length
+ * @return The count of the allocated bytes in the internal buffer.
+ */
+ inline ReByteBuffer& reduceLength(int decrement = 1){
+ if (decrement > 0 && m_length > 0){
+ if (decrement > m_length)
+ decrement = m_length;
+ setLength(m_length - decrement);
+ }
+ return *this;
+ }
/** @brief Cuts a sequence from the internal buffer.
*
* @param ix The index where the cut/insertion takes place.
}
ReByteBuffer& replaceAll(const Byte* toFind, size_t toFindLength,
const Byte* replacement, size_t replacementLength, int start = 0);
+ /** Removes an unwanted character at the end.
+ * @param aChar character to remove
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& removeLastChar(char aChar){
+ if (m_length > 0 && m_buffer[m_length - 1] == aChar)
+ setLength(m_length - 1);
+ return *this;
+ }
/** @brief Finds the index of the last occurrence of a given byte (reverse index of).
* @param toFind This byte will be searched.
* @param start The first index for searching. If < 0: relative to the end.
#elif defined __WIN32__
struct stat info;
ReByteBuffer thePath(m_path);
- if (m_path.endsWith(OS_SEPARATOR))
- thePath.setLength(thePath.length() - 1);
+ thePath.removeLastChar(OS_SEPARATOR_CHAR);
m_valid = stat(thePath.str(), &info) == 0 && S_ISDIR(info.st_mode);
#endif
- if (m_path.at(m_path.length() - 1) != OS_SEPARATOR_CHAR)
- m_path.append(OS_SEPARATOR, 1);
+ if (m_path.lastChar() != OS_SEPARATOR_CHAR)
+ m_path.appendChar(OS_SEPARATOR_CHAR);
}
/** @brief Sets the flags of the regular expression handling.
ReByteBuffer line;
for (const char** argv = usageList; *argv != NULL; argv++){
line.set(*argv);
- if (line.endsWith("\n"))
- line.setLength(line.length() - 1);
+ line.removeLastChar('\n');
m_usage.append(line.str());
}
if (examples != NULL){
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);
+ properties.append(descr).appendChar('\1');
+ properties.append(&shortOpt, 1).appendChar('\1');
+ properties.append(longOpt, strlen(longOpt)).appendChar('\1');
+ properties.append((char*) &dataType, 1).appendChar('\1');
properties.append(defaultValue == NULL ? "" : defaultValue,
- lengthValue).append("\1", 1);
+ lengthValue).appendChar('\1');
m_properties.put(name, properties.str());
// Mark current value as default:
}
ReByteBuffer buffer;
// First character says: defined.
- buffer.append(" ", 1).append(value, -1);
+ buffer.appendChar(' ').append(value, -1);
m_values.put(name, buffer.str());
}
/** @brief Analyses one or more short name options.
}
if (shortName[0] != HIDDEN_SHORT_NAME){
line.append("-", 1).append(shortName, 1);
- line.append(param.str(), -1).append(" ", 1).append(i18n(" or "), -1);
+ line.append(param.str(), -1).appendChar(' ').append(i18n(" or "), -1);
}
line.append(i18n("--"), -1).append(properties.strOf(IxLong), -1);
if (param.length() > 0){
if (dataType != DT_STRING || properties.strLengthOf(IxDefault) > 0){
line.append(i18n(" Default value: "), -1);
if (dataType == DT_STRING)
- line.append("'", 1);
+ line.appendChar('\'');
line.append(properties.strOf(IxDefault), -1);
if (dataType == DT_STRING)
- line.append("'", 1);
+ line.appendChar('\'');
}
}
lines.append(line.str());
m_buffer.fill('-', 0, col - 1);
else
m_buffer.setLength(0);
- m_buffer.append("^", 1);
+ m_buffer.appendChar('^');
return m_buffer.str();
}
m_args[++m_argNo] = m_argBuffer.length();
// Store the string with trailing '\0':
m_argBuffer.append(value, length);
- m_argBuffer.append("", 1);
+ m_argBuffer.appendChar('\0');
if (m_trigger != NULL)
m_trigger->newArg(m_argNo, m_maxArgNo);
}
# define _snprintf snprintf
# define _memcmp(t,s,n) memcmp(t,s,n)
# define _mkdir(path, mode) mkdir(path, mode)
+# define _rmdir(path) rmdir(path)
# define OS_SEPARATOR_CHAR '/'
# define OS_SEPARATOR "/"
#elif defined __WIN32__
}
private:
void run(){
+ testEnsureLastChar();
+ testLastChar();
+ testReduceLength();
+ testRemoveLastChar();
+ testAppendChar();
testAppendFloat();
testAppendInt64();
testEnsureSize2();
testSplice();
testReplace();
}
+ void testEnsureLastChar(){
+ ReByteBuffer buffer("1/");
+ buffer.ensureLastChar('/');
+ checkEqu(2, buffer.length());
+ checkEqu('/', buffer.lastChar());
+ buffer.ensureLastChar('x');
+ checkEqu(3, buffer.length());
+ checkEqu('x', buffer.lastChar());
+ }
+ void testLastChar(){
+ ReByteBuffer buffer("12345");
+ checkEqu('5', buffer.lastChar());
+ buffer.setLength(0);
+ checkEqu('\0', buffer.lastChar());
+ }
+ void testReduceLength(){
+ ReByteBuffer buffer("12345");
+ buffer.reduceLength();
+ checkEqu(4, buffer.length());
+ checkEqu("1234", buffer.str());
+ buffer.reduceLength(2);
+ checkEqu(2, buffer.length());
+ checkEqu("12", buffer.str());
+ buffer.reduceLength(0).reduceLength(-1);
+ checkEqu(2, buffer.length());
+ checkEqu("12", buffer.str());
+ buffer.reduceLength(99);
+ checkEqu(0, buffer.length());
+ }
+ void testRemoveLastChar(){
+ ReByteBuffer buffer("123");
+ buffer.removeLastChar('x').removeLastChar('3');
+ checkEqu(2, buffer.length());
+ checkEqu("12", buffer.str());
+ }
+ void testAppendChar(){
+ ReByteBuffer buffer;
+ buffer.appendChar('1');
+ checkEqu(1, buffer.length());
+ checkEqu("1", buffer.str());
+ buffer.appendChar('2');
+ checkEqu(2, buffer.length());
+ checkEqu("12", buffer.str());
+
+ buffer.appendChar('x', 1);
+ checkEqu(3, buffer.length());
+ checkEqu("12x", buffer.str());
+
+ buffer.appendChar('y', 3);
+ checkEqu(6, buffer.length());
+ checkEqu("12xyyy", buffer.str());
+
+ buffer.appendChar('x', 0);
+ checkEqu(6, buffer.length());
+ checkEqu("12xyyy", buffer.str());
+
+ buffer.appendChar('x', -1);
+ checkEqu(6, buffer.length());
+ checkEqu("12xyyy", buffer.str());
+
+ }
void testAppendFloat(){
ReByteBuffer buffer;
#include "os/reos.hpp"
static const char* s_empty[] = { NULL };
+// count of seconds from 1.1.1970 until 1.1.1980:
+const int tenYear = (365 * 10 + 2) * 24 * 3600;
class TestReDirTools : public ReTestUnit {
public:
- TestReDirTools() : ReTestUnit("ReTraverser", __FILE__){
+ TestReDirTools() : ReTestUnit("ReDirTools", __FILE__){
m_base = testDir();
ReDirectory::deleteTree(m_base.str());
- m_base.append("traverser").append(OS_SEPARATOR, -1);
+ m_base.append("dirtool");
_mkdir(m_base.str(), ALLPERMS);
+ m_base.append(OS_SEPARATOR, -1);
run();
+ ReDirectory::deleteTree(m_base.str(), true);
}
private:
ReByteBuffer m_base;
void run(){
initTree();
- testTouch();
- testDirStatistic();
+ testBatch();
testToolStatistic();
testBasic();
testCopyFile();
testList();
testToolSync();
+ testBatch();
}
void testList(){
const char* argv[] = { "list", m_base.str(), NULL };
}
void checkRelDate(ReFileTime_t absTime, int relTime){
- int diff = int(time(NULL) - relTime - secOfFileTime(absTime));
+ int diffNow = int(time(NULL) - secOfFileTime(absTime));
+ int diff = diffNow + relTime;
if (diff < 0)
diff = - diff;
checkT(diff < 2);
// local time: +3600
const int DIFF = 3600;
- const int tenYear = (365 * 10 + 2) * 24 * 3600;
checkEqu(tenYear + 24*60*60 - DIFF, secOfFileTime(opts.checkDate("1980.01.02")));
checkEqu(tenYear + 24*60*60+3600-DIFF, secOfFileTime(opts.checkDate("1980.01.02/1")));
checkEqu(tenYear + 24*60*60 + 2*3600 + 33*60 - DIFF, secOfFileTime(opts.checkDate("1980.01.02/02:33")));
- checkRelDate(opts.checkDate("3m"), 3*60);
- checkRelDate(opts.checkDate("7h"), 7*60*60);
- checkRelDate(opts.checkDate("5d"), 5*24*60*60);
+ checkRelDate(opts.checkDate("now-3m"), 3*60);
+ checkRelDate(opts.checkDate("now-7h"), 7*60*60);
+ checkRelDate(opts.checkDate("now-5d"), 5*24*60*60);
checkEqu(125ll, opts.checkSize("125"));
checkEqu(125ll, opts.checkSize("125b"));
opts.setFilterFromProgramArgs(filter);
// local time: +3600
const int DIFF = 3600;
- checkEqu(1*24*3600 - DIFF, secOfFileTime(filter.m_maxAge));
- checkEqu(2*24*3600 - DIFF, secOfFileTime(filter.m_minAge));
+ checkEqu(tenYear + 1*24*3600 - DIFF, secOfFileTime(filter.m_maxAge));
+ checkEqu(tenYear + 2*24*3600 - DIFF, secOfFileTime(filter.m_minAge));
checkEqu(5, (int) filter.m_maxDepth);
checkEqu(1, (int) filter.m_minDepth);
checkEqu(1000ll, filter.m_minSize);
checkT(buffer.endsWith(expected.str()));
buffer.set(list.strOf(1), list.strLengthOf(1));
- checkT(buffer.startsWith(" 0.000054 MB 2 3\t"));
+ checkT(buffer.startsWith(" 0.000008 MB 1 0\t"));
expected.set(m_base.str(), m_base.length()).append("dir2", -1)
.append(OS_SEPARATOR);
checkT(buffer.endsWith(expected.str()));
cols.split(expected.strOf(ix), '*');
if (! line.startsWith(cols.strOf(0)))
checkEqu(cols.strOf(0), line.str());
- if (! line.endsWith(cols.strOf(1)))
- checkEqu(cols.strOf(1), line.str());
+ const char* col2 = cols.strOf(1);
+ if (! line.endsWith(col2)){
+ checkEqu(col2, line.str());
+ }
}
}
void testTouch(){
tools.main(8, (char**) argv);
checkFile(nameCurrent,
- "2015.03.28 10:21:31 *traverser/1.txt\n"
- "2015.03.28 10:21:31 *traverser/dir1/dir1_2/dir1_2_1/x1.txt\n"
- "2015.03.28 10:21:31 *traverser/dir1/dir1_2/dir1_2_1/x2.txt\n"
+ "2015.03.28 10:21:31 *dirtool/1.txt\n"
+ "2015.03.28 10:21:31 *dirtool/dir1/dir1_2/dir1_2_1/x1.txt\n"
+ "2015.03.28 10:21:31 *dirtool/dir1/dir1_2/dir1_2_1/x2.txt\n"
"=== filtered: 3 file(s) 0.000059 MByte 0 dirs(s) */sec\n"
"=== total: 4 file(s) 0.000067 MByte 6 dirs(s) * sec");
- const char* argv2[] = { "dt", "list", "-P;*;-cache", "-tr", "-p;*.txt",
+ const char* argv2[] = { "dt", "list", "-P;*;-cache", "-tr", "-p;*.txt", "-h",
optOutput.str(), m_base.str(), NULL };
- tools.main(7, (char**) argv2);
+ tools.main(8, (char**) argv2);
checkFile(nameCurrent,
- " 0.000005 2015.03.28 10:21:31 02 *traverser/1.txt\n"
- " 0.000027 2015.03.28 10:21:31 02 *traverser/dir1/dir1_2/dir1_2_1/x1.txt\n"
- " 0.000027 2015.03.28 10:21:31 02 *traverser/dir1/dir1_2/dir1_2_1/x2.txt\n"
- "=== 3 file(s) 0.000059 MByte 0 dirs(s) * sec");
+ " 0.000005 2015.03.28 10:21:31 *dirtool/1.txt\n"
+ " 0.000027 2015.03.28 10:21:31 *dirtool/dir1/dir1_2/dir1_2_1/x1.txt\n"
+ " 0.000027 2015.03.28 10:21:31 *dirtool/dir1/dir1_2/dir1_2_1/x2.txt\n"
+ "=== filtered: 3 file(s) 0.000059 MByte 0 dirs(s) */sec\n"
+ "=== total: 4 file(s) 0.000067 MByte 6 dirs(s) * sec");
}
+ void testBatch(){
+ ReByteBuffer nameCurrent;
+ buildFilename("current", nameCurrent);
+ ReByteBuffer optOutput("--output-file=");
+ optOutput.append(nameCurrent);
+ ReDirTools tools;
+ const char* argv[] = { "dt", "batch", "-P;*;-cache", "-td", "-cmyscript",
+ optOutput.str(), m_base.str(), NULL };
+ tools.main(7, (char**) argv);
+ ReByteBuffer content("#! /bin/sh*\n"
+ "myscript '*dirtool/dir1'\n"
+ "myscript '*dirtool/dir2'\n"
+ "myscript '*dirtool/dir1/dir1_1'\n"
+ "myscript '*dirtool/dir1/dir1_2'\n"
+ "myscript '*dirtool/dir1/cache'\n"
+ "myscript '*dirtool/dir1/dir1_2/dir1_2_1'\n"
+ "# === filtered: 0 file(s) 0.000000 MByte 6 dirs(s) */sec\n"
+ "# === total: 4 file(s) 0.000067 MByte 6 dirs(s) * sec");
+#if defined __WIN32__
+ content.replaceAll("'", 1, "\"", 1);
+#endif
+ checkFile(nameCurrent, content.str());
+ }
void testToolStatistic(){
ReDirTools tools;
const char* argv[] = { "dt", "stat", "-P;*;-cache", m_base.str(), "2" };
for(ix = 0; ix < maxKeys; ix++){
rand.nextString(minLength, maxLength, key);
if (hash.get(key, value)){
- value.append("+", 1);
+ value.appendChar('+');
collisions++;
} else {
- value.set(key).append("X", 1);
+ value.set(key).appendChar('X');
}
hash.put(key, value);
}
expectedValue.setLength(0);
for (size_t ix = 0; ix < maxIx; ix++){
expectedTag = (1ll << ix);
- expectedValue.append("x", 1);
+ expectedValue.appendChar('x');
checkT(list.get(ix, value, &tag));
checkEqu(expectedValue.str(), value.str());
checkEqu(expectedTag, tag);
size_t maxIx = 13;
for (size_t ix = 0; ix < maxIx; ix++){
expectedTag = 10*ix;
- expectedValue.append("x", 1);
+ expectedValue.appendChar('x');
list.add(-1, expectedValue.str(), -1, expectedTag);
checkEqu(ix + 1, list.count());
checkT(list.get(ix, value, &tag));
expectedValue.setLength(0);
for (size_t ix = 0; ix < maxIx; ix++){
expectedTag = -1;
- expectedValue.append("x", 1);
+ expectedValue.appendChar('x');
if (ix >= 4)
expectedTag = -1;
checkEqu(ix, list.find(expectedValue.str(), expectedValue.length(), &expectedTag));
public:
TestReTraverser() : ReTestUnit("ReTraverser", __FILE__){
m_base = testDir();
- m_base.append("traverser").append(OS_SEPARATOR, -1);
+ m_base.append("traverser");
_mkdir(m_base.str(), ALLPERMS);
+ m_base.append(OS_SEPARATOR, -1);
run();
+ ReDirectory::deleteTree(m_base.str(), true);
}
private:
ReByteBuffer m_base;
ReTraverser traverser(m_base.str());
RePatternList patterns;
// exclude */cache/*
- ReByteBuffer buffer(";*;-*/cache");
+ ReByteBuffer buffer(";*;-cache");
patterns.set(buffer.str());
traverser.setDirPattern(&patterns);
int level = 0;
// a time distance value:\r
char unit = 'm';\r
int count = 0;\r
- int isNegative = false;\r
- if (theValue.startsWith("now")){\r
- rcTime = time(NULL);\r
+ bool negativeFactor = 1;\r
+ bool fromNow = theValue.startsWith("now");\r
+ if (fromNow){\r
theValue.remove(0, 3);\r
}\r
- if (theValue.str()[0] == '-')\r
- isNegative = true;\r
- else if (theValue.startsWith("+"))\r
+ char cc = theValue.at(0);\r
+ if (cc == '-' || cc == '+'){\r
+ if (cc == '-')\r
+ negativeFactor = -1;\r
theValue.remove(0, 1);\r
+ }\r
switch(sscanf(theValue.str(), "%d%c", &count, &unit)){\r
case 1:\r
case 2:\r
throw ReOptionException(&m_programArgs, \r
i18n("invalid unit $1. expected: s(econds) m(inutes) h(ours) d(ays)"), value);\r
}\r
- rcTime = time(NULL) - count;\r
+ rcTime = count * negativeFactor;\r
break;\r
default:\r
throw ReOptionException(&m_programArgs, \r
i18n("invalid relative time value $1 (<number><unit> expected). <unit>: s m h d"),\r
value);\r
}\r
- if (isNegative)\r
- rcTime -= count;\r
- else\r
- rcTime += count;\r
+ if (fromNow)\r
+ rcTime += time(NULL);\r
}\r
ReFileTime_t rc;\r
ReDirStatus_t::timeToFiletime(rcTime, rc);\r
* Frees the resources.\r
*/\r
void ReDirOptions::close(){\r
- if (m_output != stdout){\r
+ if (m_output != stdout && m_output != stderr){\r
fclose(m_output);\r
- m_output = stdout;\r
}\r
+ m_output = stdout;\r
}\r
\r
/**\r
item.set(list.strOf(ix), -1);\r
if (item.endsWith("/*"))\r
item.setLength(item.length() - 2);\r
- if (item.endsWith("/"))\r
- item.setLength(item.length() - 1);\r
+ item.removeLastChar('/');\r
bool notAnchored = item.startsWith("*/") || item.startsWith("-*/");\r
item.replaceAll("/", 1, OS_SEPARATOR, 1);\r
list.replace(ix, item.str());\r
ReByteBuffer buffer(" ");\r
int duration = int(time(NULL) - m_startTime);\r
buffer.appendInt(duration / 60).appendInt(duration % 60, ":%02d: ");\r
- buffer.appendInt(m_files).append("/", 1).appendInt(m_traverser.directories()).append(" dir(s)");\r
- buffer.appendInt(m_files).append("/", 1).appendInt(m_traverser.files()).append(" file(s)");\r
+ buffer.appendInt(m_files).appendChar('/').appendInt(m_traverser.directories()).append(" dir(s)");\r
+ buffer.appendInt(m_files).appendChar('/').appendInt(m_traverser.files()).append(" file(s)");\r
buffer.append(currentFile);\r
fputs(buffer.str(), stdout);\r
return true;\r
if (protocol.length() == 0)\r
protocol.append(".");\r
else\r
- protocol.setLength(protocol.length() - 1);\r
+ protocol.reduceLength();\r
m_traverser.changeBase(protocol.str());\r
\r
name.append(ext);\r
double rate = duration == 0 ? 0.0 : (m_files + m_directories) / duration;\r
line.append(rate, " %.1f").append(i18n("/sec"), -1);\r
m_traverser.statisticAsString(line2);\r
- line2.append(" ", 1).appendTime(duration).append(" ", 1).append(i18n("sec"));\r
+ line2.appendChar(' ').appendTime(duration).append(" ", 1).append(i18n("sec"));\r
fprintf(m_output, "%s=== filtered: %s\n", prefix == NULL ? "" : prefix, line.str());\r
fprintf(m_output, "%s=== total: %s\n", prefix == NULL ? "" : prefix, line2.str());\r
}\r
ReTool(s_batchUsage, s_batchExamples, 0, 0, 0, true),\r
m_arguments(),\r
m_script(),\r
- m_isExe(false)\r
+ m_isExe(false),\r
+ m_first()\r
{\r
// standard short options: D d O o P p T t v y Z z\r
m_programArgs.addString("first",\r
}\r
// We remove the unwanted delimiters (see above):\r
ReByteBuffer buffer;\r
- buffer.set(delim, -1).append("\x01", 1).append(delim, -1);\r
+ buffer.set(delim, -1).appendChar('\01').append(delim, -1);\r
line.replaceAll(buffer.str(), buffer.length(), "", 0);\r
}\r
/**\r
*/\r
void ReDirBatch::doIt(){\r
ReByteBuffer buffer;\r
- m_arguments.append(m_programArgs.getString("arguments", buffer), -1);\r
- m_script.append(m_programArgs.getString("script", buffer), -1);\r
+ m_programArgs.getString("arguments", m_arguments);\r
+ m_programArgs.getString("script", m_script);\r
if (m_arguments.length() + m_script.length() == 0)\r
help(i18n("one of the option must be set: -a (--arguments) or -c (--script)"));\r
#if defined __WIN32__\r
m_isExe = m_programArgs.getBool("isexe");\r
#endif\r
+ m_programArgs.getString("first", m_first);\r
processFileArguments();\r
- if (m_verboseLevel >= V_SUMMARY){\r
- int duration = int(time(NULL) - m_start);\r
#if defined __linux__\r
- const char* prefix = "#";\r
+ static const char* prefix = "# ";\r
#elif defined __WIN32__\r
- const char* prefix = "rem";\r
+ static const char* prefix = "rem ";\r
#endif\r
- statisticAsString(buffer);\r
- buffer.append(" ").appendTime(duration);\r
- fprintf(m_output, "%s %s\n", buffer.str());\r
- }\r
+ printSummary(prefix);\r
}\r
\r
/**\r
#elif defined __WIN32__\r
static const char* delim = "\"";\r
#endif\r
+ if (m_first.length() > 0){\r
+ fprintf(m_output, "%s\n", m_first.str());\r
+ m_first.setLength(0);\r
+ }\r
if (m_script.length() > 0){\r
#if defined __WIN32__\r
if (! m_isExe)\r
line.append("call ");\r
#endif\r
- line.append(m_script).append(" ").append(delim, -1);\r
+ line.append(m_script).appendChar(' ').appendChar(delim[0]);\r
line.append(entry->m_path).append(entry->node(), -1);\r
- line.append(delim, -1);\r
+ line.appendChar(delim[0]);\r
} else {\r
replaceMakros(m_arguments.str(), entry, delim, line);\r
}\r
*/\r
ReDirList::ReDirList() :\r
ReTool(s_listUsage, s_listExamples, 0, 0, 0, true),\r
- m_shortFormat(false)\r
+ m_shortFormat(false),\r
+ m_hideRights(false),\r
+ m_numerical(false)\r
{\r
+ // standard short options: D d O o P p T t v y Z z\r
m_programArgs.addBool("short", i18n("output is only path and basename"),\r
'1', "--short", false);\r
+ m_programArgs.addBool("rights", i18n("do not show the permission/right info"),\r
+ 'h', "--hide-rights", false);\r
+ m_programArgs.addBool("numerical", i18n("the permission/right info is shown as numbers"),\r
+ 'n', "--numerical", false);\r
addStandardFilterOptions();\r
}\r
\r
*/\r
void ReDirList::doIt(){\r
m_shortFormat = m_programArgs.getBool("short");\r
+ m_hideRights = m_programArgs.getBool("rights");\r
+ m_numerical = m_programArgs.getBool("numerical");\r
processFileArguments();\r
- if (m_verboseLevel >= V_SUMMARY){\r
- int duration = int(time(NULL) - m_start);\r
- ReByteBuffer line;\r
- statisticAsString(line);\r
- line.append(" ", 1).appendTime(duration).append(" ", 1).append(i18n("sec"));\r
- fprintf(m_output, "=== %s\n", line.str());\r
- }\r
+ printSummary();\r
}\r
\r
/**\r
ReByteBuffer bufferTime;\r
if (m_shortFormat)\r
fprintf(m_output, "%s%s\n", entry->m_path.str(), entry->node());\r
- else\r
- fprintf(m_output, "%s %12.6f %s %02x %s%s\n",\r
- entry->rightsAsString(bufferRights),\r
+ else {\r
+ if (! m_hideRights)\r
+ entry->rightsAsString(bufferRights, m_numerical);\r
+ fprintf(m_output, "%c%s %12.6f %s %s%s\n",\r
+ entry->typeAsChar(),\r
+ bufferRights.str(),\r
entry->fileSize() / 1E6,\r
entry->filetimeAsString(bufferTime),\r
- entry->type(),\r
entry->m_path.str(), entry->node());\r
+ }\r
}\r
\r
\r
#if defined __WIN32__\r
start = path.indexOf(':');\r
#endif\r
+ path.ensureLastChar(OS_SEPARATOR_CHAR);\r
int ixSlash = start < 0 ? 0 : start;\r
struct stat info;\r
// for all parents and the full path itself:\r
while(ixSlash >= 0){\r
ixSlash = path.indexOf(OS_SEPARATOR_CHAR, ixSlash + 1);\r
- if (ixSlash >= (int) path.length() - 1)\r
- break;\r
// is the slash in front of the first node, e.g. 'e:\'?\r
if (ixSlash == start + 1)\r
// not a real node: take the next node\r
const char* sep = OS_SEPARATOR;\r
ReByteBuffer buffer;\r
ReByteBuffer target(m_programArgs.getArg(m_programArgs.getArgCount() - 1));\r
- if (target.endsWith(OS_SEPARATOR))\r
- target.setLength(target.length() - 1);\r
+ target.removeLastChar(OS_SEPARATOR_CHAR);\r
if (! exists(target))\r
help(i18n("target does not exist: $1"), target.str());\r
else if (! S_ISDIR(m_statInfo.st_mode))\r
target.setLength(lengthTargetBase);\r
bool endsWithSlash = source.endsWith(sep, 1);\r
if (endsWithSlash)\r
- source.setLength(source.length() - 1);\r
+ source.reduceLength();\r
if (! exists(source))\r
help(i18n("source does not exist: $1"), source.str());\r
else if (! S_ISDIR(m_statInfo.st_mode))\r
if (! endsWithSlash){\r
// the basename of the source will be appended to the target:\r
int startNode = source.rindexOf(sep, 1, 0, source.length() - 1);\r
- target.append(OS_SEPARATOR, 1);\r
+ target.appendChar(OS_SEPARATOR_CHAR);\r
target.append(source.str() + startNode + 1, -1);\r
}\r
size_t ixSourceRelative = source.length();\r
size_t ixTargetRelative = target.length();\r
\r
- ReTraverser traverser(source.str());\r
- traverser.setPropertiesFromFilter(&filter);\r
+ m_traverser.changeBase(source.str());\r
+ m_traverser.setPropertiesFromFilter(&filter);\r
int level;\r
ReDirStatus_t* entry;\r
ReByteBuffer line;\r
- while( (entry = traverser.nextFile(level, &filter)) != NULL){\r
+ while( (entry = m_traverser.nextFile(level, &filter)) != NULL){\r
if (entry->isDirectory())\r
continue;\r
// append the new relative path from source to target:\r
target.setLength(ixTargetRelative);\r
target.append(entry->m_path.str() + ixSourceRelative, -1);\r
if (! exists(target))\r
- makeDirWithParents(target, ixTargetRelative, traverser);\r
+ makeDirWithParents(target, ixTargetRelative, m_traverser);\r
targetFile.set(target).append(entry->node(), -1);\r
const char* targetRelativePath = targetFile.str() + ixTargetRelative + 1;\r
bool targetExists = exists(targetFile);\r
if (! dry)\r
copyFile(entry, targetFile.str());\r
}\r
- treeFiles += traverser.files();\r
- treeDirs += traverser.directories();\r
- treeSumSizes+= traverser.sizes();\r
+ treeFiles += m_traverser.files();\r
+ treeDirs += m_traverser.directories();\r
+ treeSumSizes+= m_traverser.sizes();\r
}\r
if (m_verboseLevel >= V_SUMMARY){\r
int duration = int(time(NULL) - m_start);\r
testAll();\r
}else\r
tools.usage("unknown command: ", argv[1]);\r
- ReLogger::freeGlobalLogger();\r
return 0;\r
}\r
\r
ReByteBuffer m_arguments;
ReByteBuffer m_script;
bool m_isExe;
-
+ ReByteBuffer m_first;
};
/**
virtual void processFile(ReDirStatus_t* entry);
protected:
bool m_shortFormat;
+ bool m_hideRights;
+ bool m_numerical;
};
/**
}\r
\r
/**\r
- * Frees the resources of an instance.\r
- */\r
-void ReDirStatus_t::freeEntry(){\r
-#if defined __linux__\r
- if (m_handle != NULL){\r
- closedir(m_handle);\r
- m_handle = NULL;\r
- }\r
-#elif defined __WIN32__\r
- if (m_handle != INVALID_HANDLE_VALUE){\r
- FindClose(m_handle);\r
- m_handle = INVALID_HANDLE_VALUE;\r
- }\r
-#endif\r
- m_path.setLength(0);\r
- m_fullName.setLength(0);\r
-}\r
-\r
-/**\r
- * Returns the name of the current file (without path).\r
+ * Returns the last access time.\r
*\r
- * @return the name of the current file.\r
+ * @return the last access time\r
*/\r
-const char* ReDirStatus_t::node() const{\r
+const ReFileTime_t* ReDirStatus_t::accessed() {\r
#ifdef __linux__\r
- return m_data->d_name;\r
+ return &(getStatus()->st_atim);\r
#elif defined __WIN32__\r
- return m_data.cFileName;\r
+ return &m_data.ftLastAccessTime;\r
#endif\r
}\r
+\r
/**\r
- * Returns the file rights as a string.\r
+ * Returns the filesize.\r
*\r
- * @param buffer OUT: the file rights\r
- * @return <code>buffer.str()</code> (for chaining)\r
+ * @return the filesize\r
*/\r
-const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer) {\r
- buffer.setLength(0);\r
-#if defined __linux__\r
+ReFileSize_t ReDirStatus_t::fileSize() {\r
+#ifdef __linux__\r
+ return getStatus()->st_size;\r
#elif defined __WIN32__\r
+ return ((int64_t) m_data.nFileSizeHigh << 32) + m_data.nFileSizeLow;\r
#endif\r
- return buffer.str();\r
}\r
\r
/**\r
return filetimeToString(modified(), buffer);\r
}\r
\r
+/**\r
+ * Converts a filetime to a string.\r
+ *\r
+ * @param time the filetime to convert\r
+ * @param buffer OUT: the buffer for the string\r
+ * @return <code>buffer.str()</code>, e.g. "2014.01.07 02:59:43"\r
+ */\r
+const char* ReDirStatus_t::filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer){\r
+ time_t time1 = filetimeToTime(time);\r
+ struct tm* time2 = localtime(&time1);\r
+ buffer.setLength(4+2*2+2*2+1+3*2+2*1);\r
+ strftime(buffer.buffer(), buffer.length(), "%Y.%m.%d %H:%M:%S", time2);\r
+ return buffer.str();\r
+}\r
\r
/**\r
- * Tests whether the instance contains data about "." or "..".\r
+ * Converts a filetime to a unix time (seconds since the Epoche).\r
*\r
- * @return <code>true</code>: an ignorable entry has been found\r
+ * @param filetime the filetime to convert\r
+ * @return the count of seconds since 1.1.1970\r
*/\r
-bool ReDirStatus_t::isDotDir() const{\r
+time_t ReDirStatus_t::filetimeToTime(const ReFileTime_t* filetime){\r
#ifdef __linux__\r
- bool rc = m_data == NULL || (m_data->d_name[0] == '.' && (m_data->d_name[1] == '\0'\r
- || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));\r
+ return filetime->tv_sec;\r
#elif defined __WIN32__\r
- bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0' \r
- || (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0'));\r
+ // 64-bit arithmetic:\r
+ LARGE_INTEGER date, adjust;\r
+ date.HighPart = filetime->dwHighDateTime;\r
+ date.LowPart = filetime->dwLowDateTime;\r
+ // 100-nanoseconds = milliseconds * 10000\r
+ adjust.QuadPart = 11644473600000 * 10000;\r
+ // removes the diff between 1970 and 1601\r
+ date.QuadPart -= adjust.QuadPart;\r
+ // converts back from 100-nanoseconds to seconds\r
+ time_t rc = (time_t) (date.QuadPart / 10000000);\r
+ return rc;\r
#endif\r
- return rc;\r
}\r
\r
/**\r
if (m_handle != INVALID_HANDLE_VALUE)\r
FindClose(m_handle);\r
ReByteBuffer thePath(m_path);\r
- thePath.append(m_path.str()[m_path.length() - 1] == '\\' ? "*" : "\\*");\r
+ thePath.append(m_path.lastChar() == '\\' ? "*" : "\\*");\r
m_handle = FindFirstFileA(thePath.str(), &m_data);\r
rc = m_handle != INVALID_HANDLE_VALUE;\r
#endif\r
}\r
\r
/**\r
- * Returns the type of the entry.\r
- * return the file type, e.g. TF_REGULAR\r
+ * Frees the resources of an instance.\r
*/\r
-ReDirStatus_t::Type_t ReDirStatus_t::type(){\r
- Type_t rc = TF_UNDEF;\r
+void ReDirStatus_t::freeEntry(){\r
#if defined __linux__\r
- int flags = m_status.st_mode;\r
- if (flags == 0 || S_ISREG(flags))\r
- rc = TF_REGULAR;\r
- else if (S_ISDIR(flags)){\r
- rc = TF_SUBDIR;\r
- } else if (S_ISLNK(flags))\r
- rc = TF_LINK;\r
- else if (S_ISCHR(flags))\r
- rc = TF_CHAR;\r
- else if (S_ISBLK(flags))\r
- rc = TF_BLOCK;\r
- else if (S_ISFIFO(flags))\r
- rc = TF_PIPE;\r
- else if (S_ISSOCK(flags))\r
- rc = TF_SOCKET;\r
- else\r
- rc = TF_OTHER;\r
+ if (m_handle != NULL){\r
+ closedir(m_handle);\r
+ m_handle = NULL;\r
+ }\r
#elif defined __WIN32__\r
- int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY\r
- | FILE_ATTRIBUTE_HIDDEN \r
- | FILE_ATTRIBUTE_SYSTEM \r
- | FILE_ATTRIBUTE_ARCHIVE \r
- | FILE_ATTRIBUTE_NORMAL\r
- | FILE_ATTRIBUTE_TEMPORARY \r
- | FILE_ATTRIBUTE_SPARSE_FILE \r
- | FILE_ATTRIBUTE_COMPRESSED \r
- | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED \r
- | FILE_ATTRIBUTE_ENCRYPTED \r
- | FILE_ATTRIBUTE_HIDDEN));\r
-\r
- if (0 == flags)\r
- rc = TF_REGULAR;\r
- else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){\r
- rc = (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))\r
- ? TF_LINK_DIR : TF_SUBDIR;\r
- } else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))\r
- rc = TF_LINK;\r
- else\r
- rc = TF_OTHER;\r
+ if (m_handle != INVALID_HANDLE_VALUE){\r
+ FindClose(m_handle);\r
+ m_handle = INVALID_HANDLE_VALUE;\r
+ }\r
#endif\r
- return rc;\r
+ m_path.setLength(0);\r
+ m_fullName.setLength(0);\r
}\r
\r
/**\r
m_fullName.set(m_path).append(node(), -1);\r
return m_fullName.str();\r
}\r
+\r
/**\r
* Tests whether the instance is a directory.\r
*\r
return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);\r
#endif\r
}\r
+\r
+/**\r
+ * Tests whether the instance contains data about "." or "..".\r
+ *\r
+ * @return <code>true</code>: an ignorable entry has been found\r
+ */\r
+bool ReDirStatus_t::isDotDir() const{\r
+#ifdef __linux__\r
+ bool rc = m_data == NULL || (m_data->d_name[0] == '.' && (m_data->d_name[1] == '\0'\r
+ || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));\r
+#elif defined __WIN32__\r
+ bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0'\r
+ || (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0'));\r
+#endif\r
+ return rc;\r
+}\r
+\r
/**\r
* Tests whether the instance is a symbolic link.\r
*\r
return 0 == (m_data.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));\r
#endif\r
}\r
-/**\r
- * Returns the filesize.\r
- *\r
- * @return the filesize\r
- */\r
-ReFileSize_t ReDirStatus_t::fileSize() {\r
-#ifdef __linux__\r
- return getStatus()->st_size;\r
-#elif defined __WIN32__\r
- return ((int64_t) m_data.nFileSizeHigh << 32) + m_data.nFileSizeLow;\r
-#endif\r
-}\r
/**\r
* Returns the modification time.\r
*\r
}\r
\r
/**\r
- * Returns the last access time.\r
+ * Returns the name of the current file (without path).\r
*\r
- * @return the last access time\r
+ * @return the name of the current file.\r
*/\r
-const ReFileTime_t* ReDirStatus_t::accessed() {\r
+const char* ReDirStatus_t::node() const{\r
#ifdef __linux__\r
- return &(getStatus()->st_atim);\r
+ return m_data->d_name;\r
#elif defined __WIN32__\r
- return &m_data.ftLastAccessTime;\r
+ return m_data.cFileName;\r
#endif\r
}\r
\r
-/**\r
- * Converts a filetime to a string.\r
- *\r
- * @param time the filetime to convert\r
- * @param buffer OUT: the buffer for the string\r
- * @return <code>buffer.str()</code>, e.g. "2014.01.07 02:59:43"\r
- */\r
-const char* ReDirStatus_t::filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer){\r
- time_t time1 = filetimeToTime(time);\r
- struct tm* time2 = localtime(&time1);\r
- buffer.setLength(4+2*2+2*2+1+3*2+2*1);\r
- strftime(buffer.buffer(), buffer.length(), "%Y.%m.%d %H:%M:%S", time2);\r
- return buffer.str();\r
+inline void addRight(int mode, ReByteBuffer& buffer){\r
+ char right;\r
+ switch(mode & 7){\r
+ case 1:\r
+ right = 'x';\r
+ break;\r
+ case 2:\r
+ right = 'w';\r
+ break;\r
+ case 3:\r
+ right = 'X';\r
+ break;\r
+ case 4:\r
+ right = 'r';\r
+ break;\r
+ case 5:\r
+ right = 'R';\r
+ break;\r
+ case 6:\r
+ right = 'W';\r
+ break;\r
+ case 7:\r
+ right = 'A';\r
+ break;\r
+ default:\r
+ right = '-';\r
+ break;\r
+ }\r
+ buffer.appendChar(right);\r
+}\r
+inline void addId(const char* id, int maxLength, ReByteBuffer& buffer){\r
+ int length = strlen(id);\r
+ if (length == maxLength)\r
+ buffer.append(id, length);\r
+ else if (length < maxLength)\r
+ buffer.append(id, length).appendChar(' ', maxLength - length);\r
+ else {\r
+ buffer.append(id, 2);\r
+ buffer.append(id + length - maxLength - 2, maxLength - 2);\r
+ }\r
}\r
-\r
/**\r
- * Converts a filetime to a unix time (seconds since the Epoche).\r
+ * Returns the file rights as a string.\r
*\r
- * @param filetime the filetime to convert\r
- * @return the count of seconds since 1.1.1970\r
+ * @param buffer OUT: the file rights\r
+ * @return <code>buffer.str()</code> (for chaining)\r
*/\r
-time_t ReDirStatus_t::filetimeToTime(const ReFileTime_t* filetime){\r
-#ifdef __linux__\r
- return filetime->tv_sec;\r
+const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer, bool numerical) {\r
+ buffer.setLength(0);\r
+#if defined __linux__\r
+ if (numerical){\r
+ buffer.appendInt(getStatus()->st_mode & ALLPERMS, "%04o");\r
+ buffer.appendInt(getStatus()->st_uid, " %4d");\r
+ buffer.appendInt(getStatus()->st_gid, " %4d");\r
+ } else {\r
+ int mode = getStatus()->st_mode & ALLPERMS;\r
+ addRight(mode >> 6, buffer);\r
+ addRight(mode >> 3, buffer);\r
+ addRight(mode, buffer);\r
+ buffer.appendChar(' ');\r
+ struct passwd* passwd = getpwuid(getStatus()->st_uid);\r
+ if (passwd == NULL)\r
+ buffer.appendInt(getStatus()->st_uid, "%4d");\r
+ else\r
+ addId(passwd->pw_name, 5, buffer);\r
+ buffer.appendChar(' ');\r
+ struct group* group = getgrgid(getStatus()->st_gid);\r
+ if (group == NULL)\r
+ buffer.appendInt(getStatus()->st_gid, "%4d");\r
+ else\r
+ addId(group->gr_name, 5, buffer);\r
+ buffer.appendChar(' ');\r
+ }\r
#elif defined __WIN32__\r
- // 64-bit arithmetic:\r
- LARGE_INTEGER date, adjust;\r
- date.HighPart = filetime->dwHighDateTime;\r
- date.LowPart = filetime->dwLowDateTime;\r
- // 100-nanoseconds = milliseconds * 10000\r
- adjust.QuadPart = 11644473600000 * 10000;\r
- // removes the diff between 1970 and 1601\r
- date.QuadPart -= adjust.QuadPart;\r
- // converts back from 100-nanoseconds to seconds\r
- time_t rc = (time_t) (date.QuadPart / 10000000);\r
- return rc;\r
#endif\r
+ return buffer.str();\r
}\r
+\r
/**\r
* Converts the unix time (time_t) to the file time.\r
*\r
filetime.dwHighDateTime = ll >> 32;\r
#endif\r
}\r
+/**\r
+ * Returns the type of the entry.\r
+ * return the file type, e.g. TF_REGULAR\r
+ */\r
+ReDirStatus_t::Type_t ReDirStatus_t::type(){\r
+ Type_t rc = TF_UNDEF;\r
+#if defined __linux__\r
+ int flags = getStatus()->st_mode;\r
+ if (S_ISDIR(flags))\r
+ rc = TF_SUBDIR;\r
+ else if (flags == 0 || S_ISREG(flags))\r
+ rc = TF_REGULAR;\r
+ else if (S_ISLNK(flags))\r
+ rc = TF_LINK;\r
+ else if (S_ISCHR(flags))\r
+ rc = TF_CHAR;\r
+ else if (S_ISBLK(flags))\r
+ rc = TF_BLOCK;\r
+ else if (S_ISFIFO(flags))\r
+ rc = TF_PIPE;\r
+ else if (S_ISSOCK(flags))\r
+ rc = TF_SOCKET;\r
+ else\r
+ rc = TF_OTHER;\r
+#elif defined __WIN32__\r
+ int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY\r
+ | FILE_ATTRIBUTE_HIDDEN\r
+ | FILE_ATTRIBUTE_SYSTEM\r
+ | FILE_ATTRIBUTE_ARCHIVE\r
+ | FILE_ATTRIBUTE_NORMAL\r
+ | FILE_ATTRIBUTE_TEMPORARY\r
+ | FILE_ATTRIBUTE_SPARSE_FILE\r
+ | FILE_ATTRIBUTE_COMPRESSED\r
+ | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED\r
+ | FILE_ATTRIBUTE_ENCRYPTED\r
+ | FILE_ATTRIBUTE_HIDDEN));\r
+\r
+ if (0 == flags)\r
+ rc = TF_REGULAR;\r
+ else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){\r
+ rc = (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))\r
+ ? TF_LINK_DIR : TF_SUBDIR;\r
+ } else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))\r
+ rc = TF_LINK;\r
+ else\r
+ rc = TF_OTHER;\r
+#endif\r
+ return rc;\r
+}\r
\r
+/**\r
+ * Returns the filetype as a single character.\r
+ *\r
+ * @return the filetype, e.g. 'd' for a directory\r
+ */\r
+char ReDirStatus_t::typeAsChar(){\r
+ char rc = ' ';\r
+ switch(type()){\r
+ case TF_REGULAR:\r
+ rc = ' ';\r
+ break;\r
+ case TF_LINK:\r
+ rc = 'l';\r
+ break;\r
+ case TF_SUBDIR:\r
+ rc = 'd';\r
+ break;\r
+ case TF_CHAR:\r
+ rc = 'c';\r
+ break;\r
+ case TF_BLOCK:\r
+ rc = 'b';\r
+ break;\r
+ case TF_PIPE:\r
+ rc = 'p';\r
+ break;\r
+ case TF_SOCKET:\r
+ rc = 's';\r
+ break;\r
+ default:\r
+ rc = 'o';\r
+ break;\r
+ }\r
+ return rc;\r
+}\r
/**\r
* Constructor.\r
*/\r
if (! append)\r
buffer.setLength(0);\r
buffer.appendInt(m_files, formatFiles);\r
- buffer.append(i18n("file(s)")).append(" ", 1);\r
+ buffer.append(i18n("file(s)")).appendChar(' ');\r
buffer.append(m_sizes / 1000.0 / 1000, formatSizes);\r
- buffer.append(" ", 1).append(i18n("MByte")).append(" ", 1);\r
+ buffer.append(" ", 1).append(i18n("MByte")).appendChar(' ');\r
buffer.appendInt(m_directories, formatDirs);\r
buffer.append(i18n("dirs(s)"));\r
return buffer.str();\r
memset(m_dirs, 0, sizeof m_dirs);\r
m_dirs[0] = new ReDirStatus_t();\r
// remove a preceeding "./". This simplifies the pattern expressions:\r
- if (m_base.startsWith(ReByteBuffer(".").append(OS_SEPARATOR, 1).str())){\r
+ if (m_base.startsWith(ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){\r
m_base.remove(0, 2);\r
}\r
}\r
memset(m_dirs, 0, sizeof m_dirs);\r
m_dirs[0] = new ReDirStatus_t();\r
// remove a preceeding "./". This simplifies the pattern expressions:\r
- if (m_base.startsWith(ReByteBuffer(".").append(OS_SEPARATOR, 1).str())){\r
+ if (m_base.startsWith(ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){\r
m_base.remove(0, 2);\r
}\r
}\r
public:
ReDirStatus_t();
public:
- void freeEntry();
- const char* node() const;
- const char* fullName();
+ const ReFileTime_t* accessed();
+ ReFileSize_t fileSize();
+ const char* filetimeAsString(ReByteBuffer& buffer);
bool findFirst();
bool findNext();
- bool hasData() const;
+ void freeEntry();
+ const char* fullName();
bool isDirectory();
+ bool isDotDir() const;
bool isLink();
bool isRegular();
- ReFileSize_t fileSize();
const ReFileTime_t* modified();
- const ReFileTime_t* accessed();
- bool isDotDir() const;
- const char* rightsAsString(ReByteBuffer& buffer);
- const char* filetimeAsString(ReByteBuffer& buffer);
+ const char* node() const;
+ const char* rightsAsString(ReByteBuffer& buffer, bool numerical);
Type_t type();
+ char typeAsChar();
+public:
+ static time_t filetimeToTime(const ReFileTime_t* time);
+ static void timeToFiletime(time_t time, ReFileTime_t& filetime);
+ static const char* filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer);
public:
ReByteBuffer m_path;
ReByteBuffer m_fullName;
HANDLE m_handle;
WIN32_FIND_DATAA m_data;
#endif
-public:
- static time_t filetimeToTime(const ReFileTime_t* time);
- static void timeToFiletime(time_t time, ReFileTime_t& filetime);
- static const char* filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer);
};
class ReDirEntryFilter_t{
public:
#if defined __linux__
#include "unistd.h"
#include <dirent.h>
+#include <grp.h>
+#include <pwd.h>
#elif defined __WIN32__
#include <tchar.h>
#include "windows.h"