summaryrefslogtreecommitdiff
path: root/tools/bit/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bit/util.cpp')
-rw-r--r--tools/bit/util.cpp254
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;
+}
+
+