// // aegis - project change supervisor // Copyright (C) 1998, 1999, 2003-2006, 2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include static string_ty * stripdot(string_ty *s, int strip_left_slash) { const char *cp; size_t len; cp = s->str_text; len = s->str_length; for (;;) { if (len > 1 && cp[len - 1] == '/') { --len; continue; } if (len >= 2 && cp[len - 2] == '/' && cp[len - 1] == '.') { --len; continue; } if (len > 2 && cp[0] == '.' && cp[1] == '/') { cp += 2; len -= 2; while (*cp == '/') { ++cp; --len; } } if (strip_left_slash && len >= 1 && cp[0] == '/') { ++cp; --len; } break; } if (len == 0) return str_from_c("."); return str_n_from_c(cp, len); } string_ty * os_path_cat(string_ty *s1, string_ty *s2) { static string_ty *dot; static string_ty *slash; string_ty *ss1; string_ty *ss2; string_ty *result; if (!dot) dot = str_from_c("."); if (!s1->str_length) s1 = dot; if (!s2->str_length) s2 = dot; ss1 = stripdot(s1, 0); ss2 = stripdot(s2, 1); if (str_equal(ss1, dot)) { str_free(ss1); return ss2; } if (str_equal(ss2, dot)) { str_free(ss2); return ss1; } if (!slash) slash = str_from_c("/"); if (str_equal(ss1, slash)) result = str_catenate(ss1, ss2); else result = str_cat_three(ss1, slash, ss2); str_free(ss1); str_free(ss2); return result; } static nstring stripdot(const nstring &s, bool strip_left_slash) { const char *cp = s.c_str(); size_t len = s.size(); for (;;) { if (len > 1 && cp[len - 1] == '/') { --len; continue; } if (len >= 2 && cp[len - 2] == '/' && cp[len - 1] == '.') { --len; continue; } if (len > 2 && cp[0] == '.' && cp[1] == '/') { cp += 2; len -= 2; while (*cp == '/') { ++cp; --len; } } if (strip_left_slash && len >= 1 && cp[0] == '/') { ++cp; --len; } break; } if (len == 0) return "."; return nstring(cp, len); } nstring os_path_cat(const nstring &s1, const nstring &s2) { nstring dot("."); nstring ss1(stripdot((s1.empty() ? dot : s1), false)); nstring ss2(stripdot((s2.empty() ? dot : s2), true)); if (ss1 == dot) { return ss2; } if (ss2 == dot) { return ss1; } nstring slash("/"); if (ss1 == slash) return (ss1 + ss2); return (ss1 + slash + ss2); } string_ty * os_path_rel2abs(string_ty *root, string_ty *path) { if (path->str_text[0] == '/') return str_copy(path); return os_path_cat(root, path); } nstring os_path_rel2abs(const nstring &root, const nstring &path) { if (path[0] == '/') return path; return os_path_cat(root, path); }