Add rm and strip abilities to atree.
The new line syntax is:
[SRC] [rm|strip] DEST
This allows one to write things like this in atree:
bin/src
bin/src bin/dest
bin/src "bin/another file name"
rm dest/file
rm dest/dir # recursive
strip bin/src
bin/src strip bin/dest
Src and dest can contain spaces if full enclosed in double-quotes.
The strip command can be overridden using the STRIP env var.
Change-Id: I22aae7a87c36c082e1aab87132099a3c644914da
diff --git a/tools/atree/files.cpp b/tools/atree/files.cpp
index d4866d4..df3e987 100644
--- a/tools/atree/files.cpp
+++ b/tools/atree/files.cpp
@@ -62,7 +62,7 @@
split_line(const char* p, vector<string>* out)
{
const char* q = p;
- enum { WHITE, TEXT } state = WHITE;
+ enum { WHITE, TEXT, IN_QUOTE } state = WHITE;
while (*p) {
if (*p == '#') {
break;
@@ -73,13 +73,25 @@
case WHITE:
if (!isspace(*p)) {
q = p;
- state = TEXT;
+ state = (*p == '"') ? IN_QUOTE : TEXT;
}
break;
+ case IN_QUOTE:
+ if (*p == '"') {
+ state = TEXT;
+ break;
+ }
+ // otherwise fall-through to TEXT case
case TEXT:
- if (isspace(*p)) {
+ if (state != IN_QUOTE && isspace(*p)) {
if (q != p) {
- out->push_back(string(q, p-q));
+ const char* start = q;
+ size_t len = p-q;
+ if (len > 2 && *start == '"' && start[len - 1] == '"') {
+ start++;
+ len -= 2;
+ }
+ out->push_back(string(start, len));
}
state = WHITE;
}
@@ -88,17 +100,25 @@
p++;
}
if (state == TEXT) {
- out->push_back(string(q, p-q));
+ const char* start = q;
+ size_t len = p-q;
+ if (len > 2 && *start == '"' && start[len - 1] == '"') {
+ start++;
+ len -= 2;
+ }
+ out->push_back(string(start, len));
}
}
static void
-add_file(vector<FileRecord>* files, const string& listFile, int listLine,
+add_file(vector<FileRecord>* files, const FileOpType fileOp,
+ const string& listFile, int listLine,
const string& sourceName, const string& outName)
{
FileRecord rec;
rec.listFile = listFile;
rec.listLine = listLine;
+ rec.fileOp = fileOp;
rec.sourceName = sourceName;
rec.outName = outName;
files->push_back(rec);
@@ -182,7 +202,7 @@
err = errno;
goto cleanup;
}
-
+
size = ftell(f);
err = fseek(f, 0, SEEK_SET);
@@ -245,35 +265,52 @@
}
printf("]\n");
#endif
-
- if (words.size() == 1) {
- // pattern: DEST
- bool error = false;
- string w0 = replace_variables(words[0], variables, &error);
- if (error) {
- err = 1;
- goto cleanup;
+ FileOpType op = FILE_OP_COPY;
+ string paths[2];
+ int pcount = 0;
+ string errstr;
+ for (vector<string>::iterator it = words.begin(); it != words.end(); ++it) {
+ const string& word = *it;
+ if (word == "rm") {
+ if (op != FILE_OP_COPY) {
+ errstr = "Error: you can only specifiy 'rm' or 'strip' once per line.";
+ break;
+ }
+ op = FILE_OP_REMOVE;
+ } else if (word == "strip") {
+ if (op != FILE_OP_COPY) {
+ errstr = "Error: you can only specifiy 'rm' or 'strip' once per line.";
+ break;
+ }
+ op = FILE_OP_STRIP;
+ } else if (pcount < 2) {
+ bool error = false;
+ paths[pcount++] = replace_variables(word, variables, &error);
+ if (error) {
+ err = 1;
+ goto cleanup;
+ }
+ } else {
+ errstr = "Error: More than 2 paths per line.";
+ break;
}
- add_file(files, filename, i+1, w0, w0);
}
- else if (words.size() == 2) {
- // pattern: SRC DEST
- bool error = false;
- string w0, w1;
- w0 = replace_variables(words[0], variables, &error);
- if (!error) {
- w1 = replace_variables(words[1], variables, &error);
- }
- if (error) {
- err = 1;
- goto cleanup;
- }
- add_file(files, filename, i+1, w0, w1);
+
+ if (pcount == 0 && !errstr.empty()) {
+ errstr = "Error: No path found on line.";
}
- else {
- fprintf(stderr, "%s:%d: bad format: %s\n", filename.c_str(),
- i+1, p);
+
+ if (!errstr.empty()) {
+ fprintf(stderr, "%s:%d: bad format: %s\n%s\nExpected: [SRC] [rm|strip] DEST\n",
+ filename.c_str(), i+1, p, errstr.c_str());
err = 1;
+ } else {
+ if (pcount == 1) {
+ // pattern: [rm|strip] DEST
+ paths[1] = paths[0];
+ }
+
+ add_file(files, op, filename, i+1, paths[0], paths[1]);
}
}
p = q;
@@ -293,6 +330,14 @@
int
locate(FileRecord* rec, const vector<string>& search)
{
+ if (rec->fileOp == FILE_OP_REMOVE) {
+ // Don't touch source files when removing a destination.
+ rec->sourceMod = 0;
+ rec->sourceSize = 0;
+ rec->sourceIsDir = false;
+ return 0;
+ }
+
int err;
for (vector<string>::const_iterator it=search.begin();
@@ -304,6 +349,7 @@
rec->sourceBase = *it;
rec->sourcePath = full;
rec->sourceMod = st.st_mtime;
+ rec->sourceSize = st.st_size;
rec->sourceIsDir = S_ISDIR(st.st_mode);
return 0;
}
@@ -324,9 +370,11 @@
err = stat(rec->outPath.c_str(), &st);
if (err == 0) {
rec->outMod = st.st_mtime;
+ rec->outSize = st.st_size;
rec->outIsDir = S_ISDIR(st.st_mode);
} else {
rec->outMod = 0;
+ rec->outSize = 0;
rec->outIsDir = false;
}
}
@@ -427,3 +475,8 @@
{
return list_dir("", rec, excludes, files);
}
+
+FileRecord::FileRecord() {
+ fileOp = FILE_OP_COPY;
+}
+