diff options
| author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-06-18 07:05:58 +0900 |
|---|---|---|
| committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-06-18 11:25:45 +0900 |
| commit | 8a96358d16ab0c435820d07472e301e9d3b2c03a (patch) | |
| tree | 12c6e6216bfed55a545ef8d2d9c6f46f5eec64a3 /strutil.cc | |
| parent | 5d694f0d17ac2016415bb7adbd589ca4a989a98b (diff) | |
[C++] Implement abspath
Diffstat (limited to 'strutil.cc')
| -rw-r--r-- | strutil.cc | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -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); +} |
