aboutsummaryrefslogtreecommitdiff
path: root/strutil.cc
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-18 07:05:58 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-18 11:25:45 +0900
commit8a96358d16ab0c435820d07472e301e9d3b2c03a (patch)
tree12c6e6216bfed55a545ef8d2d9c6f46f5eec64a3 /strutil.cc
parent5d694f0d17ac2016415bb7adbd589ca4a989a98b (diff)
[C++] Implement abspath
Diffstat (limited to 'strutil.cc')
-rw-r--r--strutil.cc51
1 files changed, 51 insertions, 0 deletions
diff --git a/strutil.cc b/strutil.cc
index 0548f62..d09abda 100644
--- a/strutil.cc
+++ b/strutil.cc
@@ -1,11 +1,15 @@
#include "strutil.h"
#include <ctype.h>
+#include <limits.h>
#include <string.h>
+#include <unistd.h>
#include <unordered_map>
#include <utility>
+#include "log.h"
+
WordScanner::Iterator& WordScanner::Iterator::operator++() {
int len = static_cast<int>(in->size());
for (s = i; s < len; s++) {
@@ -228,3 +232,50 @@ StringPiece StripExt(StringPiece s) {
return s;
return s.substr(0, found);
}
+
+void AbsPath(StringPiece s, string* o) {
+ if (s.get(0) == '/') {
+ o->clear();
+ } else {
+ char buf[PATH_MAX];
+ if (!getcwd(buf, PATH_MAX)) {
+ fprintf(stderr, "getcwd failed\n");
+ CHECK(false);
+ }
+
+ CHECK(buf[0] == '/');
+ *o = buf;
+ *o += '/';
+ }
+ AppendString(s, o);
+
+ size_t j = 1;
+ size_t prev_start = 1;
+ for (size_t i = 1; i < o->size(); i++) {
+ char c= (*o)[i];
+ if (c != '/') {
+ (*o)[j] = c;
+ j++;
+ continue;
+ }
+
+ StringPiece prev_dir = StringPiece(o->data() + prev_start, j - prev_start);
+ if (prev_dir == ".") {
+ j--;
+ } else if (prev_dir == "..") {
+ j -= 4;
+ j = o->rfind('/', j);
+ if (j == string::npos) {
+ j = 1;
+ } else {
+ j++;
+ }
+ } else if (!prev_dir.empty()) {
+ (*o)[j] = c;
+ j++;
+ }
+ LOG("%zu => %zu", prev_start, j);
+ prev_start = j;
+ }
+ o->resize(j);
+}