summaryrefslogtreecommitdiff
path: root/lib/driver/abs_path.c
blob: e21bb106a0f60a5d1967221650a7e67e3fa1ee7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
  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
#include "cdio_private.h"

#ifdef HAVE_STRING_H
# include <string.h>
#endif

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif 

#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif

#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)

#if !defined(CharNext) || defined(_MSC_VER) /* defined as CharNext[AW] on Windows. */
# undef CharNext
# define CharNext(p) ((p) + 1)
#endif

#ifndef HAVE_STRNDUP
static inline char *strndup(const char *s, size_t n)
{
    char *result;
    size_t len = strlen (s);
    if (n < len)
        len = n;
    result = (char *) malloc (len + 1);
    if (!result)
        return 0;
    result[len] = '\0';
    return (char *) strncpy (result, s, len);
}
#endif /*HAVE_STRNDUP*/

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_dirname(const char *fname);

const char *
cdio_dirname(const char *fname)
{
    const char *p;
    p = strrdirsep(fname);
    if (!p) return ".";
    return strndup(fname, p - fname);
}

const char *cdio_abspath(const char *cwd, const char *fname);


/* If fname isn't absolute, add cwd to it. */
const char *
cdio_abspath(const char *cwd, const 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;
    }
}

#ifdef STANDALONE
int main(int argc, char **argv)
{
  const char *dest;
  const char *dirname;
  if (argc != 3) {
    fprintf(stderr, "Usage: %s FILE REPLACE_BASENAME\n", argv[0]);
    fprintf(stderr,
     "       Make PATH absolute\n");
    exit(1);
  }

  dirname = cdio_dirname(argv[1]);
  dest = cdio_abspath (dirname, argv[2]);
  printf("%s -> %s\n", argv[1], dest);
  exit(0);
}
#endif