/*
* Copyright 2008-2013 Various Authors
* Copyright 2004 Timo Hirvonen
*
* 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 2 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 "path.h"
#include "xmalloc.h"
#include
#include
const char *get_extension(const char *filename)
{
const char *ext;
ext = filename + strlen(filename) - 1;
while (ext >= filename && *ext != '/') {
if (*ext == '.') {
ext++;
return ext;
}
ext--;
}
return NULL;
}
const char *path_basename(const char *path)
{
const char *f;
f = strrchr(path, '/');
return f ? f + 1 : path;
}
char *path_dirname(const char *path)
{
const char *f;
f = strrchr(path, '/');
return f ? xstrndup(path, f - path) : xstrdup(".");
}
void path_strip(char *str)
{
int i, s, d;
i = 0;
if (str[0] == '/')
i = 1;
while (str[i]) {
if (str[i] == '/') {
d = i;
s = i + 1;
while (str[s] && str[s] == '/')
s++;
s--;
do {
str[d++] = str[++s];
} while (str[s]);
} else if (i && str[i] == '.') {
if (str[i + 1] == '/') {
d = i;
s = i + 1;
do {
str[d++] = str[++s];
} while (str[s]);
} else if (str[i + 1] == 0) {
str[i] = 0;
break;
} else if (str[i + 1] == '.' &&
(str[i + 2] == '/' || str[i + 2] == 0)) {
/* aaa/bbb/../ccc */
/* aaa/ccc */
if (str[i + 2]) {
s = i + 3; /* ccc */
} else {
s = i + 2;
}
d = i - 1; /* /../ccc */
do {
if (d == 0)
break;
d--;
} while (str[d] != '/');
d++;
/* std[d] is bbb/../ccc */
i = d;
s--;
do {
str[d++] = str[++s];
} while (str[s]);
} else {
while (str[i] && str[i] != '/')
i++;
if (str[i])
i++;
}
} else {
while (str[i] && str[i] != '/')
i++;
if (str[i])
i++;
}
}
if (i > 1 && str[i - 1] == '/')
str[i - 1] = 0;
}
char *path_absolute_cwd(const char *src, const char *cwd)
{
char *str;
if (src[0] == '/') {
/* already absolute */
str = xstrdup(src);
} else {
int src_len;
int cwd_len;
src_len = strlen(src);
cwd_len = strlen(cwd);
str = xnew(char, cwd_len + 1 + src_len + 1);
memcpy(str, cwd, cwd_len);
str[cwd_len] = '/';
memcpy(str + cwd_len + 1, src, src_len + 1);
}
path_strip(str);
return str;
}
char *path_absolute(const char *src)
{
char cwd[1024];
if (!getcwd(cwd, sizeof(cwd))) {
cwd[0] = '/';
cwd[1] = 0;
}
return path_absolute_cwd(src, cwd);
}