diff options
Diffstat (limited to 'tools/bit/util.cpp')
-rw-r--r-- | tools/bit/util.cpp | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/tools/bit/util.cpp b/tools/bit/util.cpp new file mode 100644 index 000000000000..fc93bcb8c935 --- /dev/null +++ b/tools/bit/util.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <string.h> +#include <unistd.h> + + +FileInfo::FileInfo() +{ + memset(this, 0, sizeof(FileInfo)); +} + +FileInfo::FileInfo(const FileInfo& that) +{ + memcpy(this, &that, sizeof(FileInfo)); +} + +FileInfo::FileInfo(const string& filename) +{ + struct stat st; + int err = stat(filename.c_str(), &st); + if (err != 0) { + memset(this, 0, sizeof(FileInfo)); + } else { + exists = true; + mtime = st.st_mtime; + ctime = st.st_ctime; + size = st.st_size; + } +} + +bool +FileInfo::operator==(const FileInfo& that) const +{ + return exists == that.exists + && mtime == that.mtime + && ctime == that.ctime + && size == that.size; +} + +bool +FileInfo::operator!=(const FileInfo& that) const +{ + return exists != that.exists + || mtime != that.mtime + || ctime != that.ctime + || size != that.size; +} + +FileInfo::~FileInfo() +{ +} + +TrackedFile::TrackedFile() + :filename(), + fileInfo() +{ +} + +TrackedFile::TrackedFile(const TrackedFile& that) +{ + filename = that.filename; + fileInfo = that.fileInfo; +} + +TrackedFile::TrackedFile(const string& file) + :filename(file), + fileInfo(file) +{ +} + +TrackedFile::~TrackedFile() +{ +} + +bool +TrackedFile::HasChanged() const +{ + FileInfo updated(filename); + return !updated.exists || fileInfo != updated; +} + +void +get_directory_contents(const string& name, map<string,FileInfo>* results) +{ + int err; + DIR* dir = opendir(name.c_str()); + if (dir == NULL) { + return; + } + + dirent* entry; + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + continue; + } + if (entry->d_type == DT_DIR) { + string subdir = name + "/" + entry->d_name; + get_directory_contents(subdir, results); + } else if (entry->d_type == DT_LNK || entry->d_type == DT_REG) { + string filename(name + "/" + entry->d_name); + (*results)[filename] = FileInfo(filename); + } + } + + closedir(dir); +} + +bool +directory_contents_differ(const map<string,FileInfo>& before, const map<string,FileInfo>& after) +{ + if (before.size() != after.size()) { + return true; + } + map<string,FileInfo>::const_iterator b = before.begin(); + map<string,FileInfo>::const_iterator a = after.begin(); + while (b != before.end() && a != after.end()) { + if (b->first != a->first) { + return true; + } + if (a->second != b->second) { + return true; + } + a++; + b++; + } + return false; +} + +string +escape_quotes(const char* str) +{ + string result; + while (*str) { + if (*str == '"') { + result += '\\'; + result += '"'; + } else { + result += *str; + } + } + return result; +} + +string +escape_for_commandline(const char* str) +{ + if (strchr(str, '"') != NULL || strchr(str, ' ') != NULL + || strchr(str, '\t') != NULL) { + return escape_quotes(str); + } else { + return str; + } +} + +static bool +spacechr(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +string +trim(const string& str) +{ + const ssize_t N = (ssize_t)str.size(); + ssize_t begin = 0; + while (begin < N && spacechr(str[begin])) { + begin++; + } + ssize_t end = N - 1; + while (end >= begin && spacechr(str[end])) { + end--; + } + return string(str, begin, end-begin+1); +} + +bool +starts_with(const string& str, const string& prefix) +{ + return str.compare(0, prefix.length(), prefix) == 0; +} + +bool +ends_with(const string& str, const string& suffix) +{ + if (str.length() < suffix.length()) { + return false; + } else { + return str.compare(str.length()-suffix.length(), suffix.length(), suffix) == 0; + } +} + +void +split_lines(vector<string>* result, const string& str) +{ + const int N = str.length(); + int begin = 0; + int end = 0; + for (; end < N; end++) { + const char c = str[end]; + if (c == '\r' || c == '\n') { + if (begin != end) { + result->push_back(string(str, begin, end-begin)); + } + begin = end+1; + } + } + if (begin != end) { + result->push_back(string(str, begin, end-begin)); + } +} + +string +read_file(const string& filename) +{ + FILE* file = fopen(filename.c_str(), "r"); + if (file == NULL) { + return string(); + } + + fseek(file, 0, SEEK_END); + int size = ftell(file); + fseek(file, 0, SEEK_SET); + + char* buf = (char*)malloc(size); + fread(buf, 1, size, file); + + string result(buf, size); + + free(buf); + fclose(file); + + return result; +} + + |