diff --git a/lib/driver/.gitignore b/lib/driver/.gitignore index 0a420e8d..cc9ec468 100644 --- a/lib/driver/.gitignore +++ b/lib/driver/.gitignore @@ -7,6 +7,7 @@ /.libs /Makefile /Makefile.in +/abs_path /follow_symlink /libcdio.la /libcdio.la.ver diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am index b4ee24d1..beee0a6c 100644 --- a/lib/driver/Makefile.am +++ b/lib/driver/Makefile.am @@ -57,6 +57,7 @@ libcdio_sources = \ _cdio_stdio.h \ _cdio_stream.c \ _cdio_stream.h \ + abs_path.c \ aix.c \ bsdi.c \ audio.c \ diff --git a/lib/driver/abs_path.c b/lib/driver/abs_path.c new file mode 100644 index 00000000..71cec1cf --- /dev/null +++ b/lib/driver/abs_path.c @@ -0,0 +1,176 @@ +/* + To compile as a standalone program: + gcc -Wall -g -I../.. -DHAVE_CONFIG_H -DSTANDALONE -o abs_path abs_path.c +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +# define __CDIO_CONFIG_H__ 1 +#endif + +#ifdef HAVE_STRING_H +# include +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#ifdef __CYGWIN__ +#undef DOSISH +#endif +#if defined __CYGWIN__ || defined DOSISH +#define DOSISH_UNC +#define DOSISH_DRIVE_LETTER +#define FILE_ALT_SEPARATOR '\\' +#endif + +#ifndef CDIO_FILE_SEPARATOR +# define CDIO_FILE_SEPARATOR '/' +#endif + +#if defined __CYGWIN__ || defined DOSISH +# define FILE_ALT_SEPARATOR '\\' +#endif + +#ifdef CDIO_FILE_ALT_SEPARATOR +# define isdirsep(x) ((x) == CDIO_FILE_SEPARATOR || (x) == CDIO_FILE_ALT_SEPARATOR) +#else +# define isdirsep(x) ((x) == CDIO_FILE_SEPARATOR) +#endif + +#define skipprefix(path) (path) + +#ifndef CharNext /* defined as CharNext[AW] on Windows. */ +# define CharNext(p) ((p) + 1) +#endif + +static char * +chompdirsep(const char *path) +{ + while (*path) { + if (isdirsep(*path)) { + const char *last = path++; + while (isdirsep(*path)) path++; + if (!*path) return (char *)last; + } + else { + path = CharNext(path); + } + } + return (char *)path; +} + +static char * +strrdirsep(const char *path) +{ + char *last = NULL; + while (*path) { + if (isdirsep(*path)) { + const char *tmp = path++; + while (isdirsep(*path)) path++; + if (!*path) break; + last = (char *)tmp; + } + else { + path = CharNext(path); + } + } + return last; +} + +const char * +cdio_basename(const char *name) +{ + const char *p; +#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC + const char *root; +#endif + long f, n = -1; + + name = skipprefix(name); +#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC + root = name; +#endif + while (isdirsep(*name)) + name++; + if (!*name) { + p = name - 1; + f = 1; +#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC + if (name != root) { + /* has slashes */ + } +#ifdef DOSISH_DRIVE_LETTER + else if (*p == ':') { + p++; + f = 0; + } +#endif +#ifdef DOSISH_UNC + else { + p = CDIO_FILE_SEPARARATOR; + } +#endif +#endif + } + else { + if (!(p = strrdirsep(name))) { + p = name; + } + else { + while (isdirsep(*p)) p++; /* skip last / */ + } + n = chompdirsep(p) - p; + } + + return p; +} + +/* If fname isn't absolute, add cwd to it. */ +char * +cdio_abspath(const char *cwd, char *fname) +{ + if (isdirsep(*fname)) return fname; + { + size_t len = strlen(cwd) + strlen(fname) + 2; + char* result = calloc(sizeof(char), len); + snprintf(result, len, "%s%c%s", + cwd, CDIO_FILE_SEPARATOR, fname); + return result; + } +} + +#define STANDALONE 1 +#ifdef STANDALONE +int main(int argc, char **argv) +{ + char *dest; + char cwd[PATH_MAX]; + + getcwd(cwd, sizeof(cwd)); + + if (argc != 2) { + fprintf(stderr, "Usage: %s PATH\n", argv[0]); + fprintf(stderr, + " Make PATH absolute\n"); + exit(1); + } + dest = cdio_abspath (cwd, argv[1]); + printf("%s -> %s\n", argv[1], dest); + exit(0); +} +#endif diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index c2e0fdcd..374f79b7 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -14,6 +14,7 @@ _cdio_list_prepend _cdio_malloc _cdio_strfreev _cdio_strsplit +cdio_abspath cdio_audio_get_msf_seconds cdio_audio_get_volume cdio_audio_pause