00001 // Copyright (C) 2006-2007 Benedikt Böhm <hollow@gentoo.org> 00002 // 00003 // This program is free software; you can redistribute it and/or 00004 // modify it under the terms of the GNU General Public License 00005 // as published by the Free Software Foundation; either version 2 00006 // of the License, or (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00016 00017 #include "mem.h" 00018 #include "str.h" 00019 00020 char *str_path_dirname(const char *path) 00021 { 00022 /* empty string or '..' */ 00023 if (str_isempty(path) || str_equal(path, "..")) 00024 return str_dup("."); 00025 00026 /* skip prefixing '/' but preserve exactly one */ 00027 while (*path && *(path+1) && *path == '/' && *(path+1) == '/') 00028 path++; 00029 00030 int found = 0; 00031 char *p, *buf = str_dup(path); 00032 00033 while ((p = str_rchr(buf, '/', str_len(buf)))) { 00034 /* remove trailing slash */ 00035 if (p[1] == 0 && p != buf) 00036 *p = 0; 00037 00038 /* no basename was found until yet */ 00039 else if (!found) { 00040 *p = 0; 00041 found = 1; 00042 } 00043 00044 /* a basename was found and no trailing slash anymore */ 00045 else 00046 break; 00047 } 00048 00049 char *dn; 00050 00051 /* path consists only of basename and slashes */ 00052 if (str_isempty(buf)) 00053 dn = str_dup("/"); 00054 00055 /* path is relative or absolute, basename was stripped */ 00056 else if (p) 00057 dn = str_dup(buf); 00058 00059 /* path is relative, no basename was stripped */ 00060 else 00061 dn = str_dup("."); 00062 00063 mem_free(buf); 00064 00065 return dn; 00066 }