1 /*
2 To compile as a standalone program:
3 gcc -Wall -g -I../.. -DHAVE_CONFIG_H -DSTANDALONE -o abs_path abs_path.c
4 */
5 #ifdef HAVE_CONFIG_H
6 # include "config.h"
7 # define __CDIO_CONFIG_H__ 1
8 #endif
9 #include "cdio_private.h"
10
11 #ifdef HAVE_STRING_H
12 # include <string.h>
13 #endif
14
15 #ifdef HAVE_STDLIB_H
16 # include <stdlib.h>
17 #endif
18
19 #ifdef HAVE_UNISTD_H
20 # include <unistd.h>
21 #endif
22
23 #ifdef HAVE_STDIO_H
24 # include <stdio.h>
25 #endif
26
27 #ifndef PATH_MAX
28 # define PATH_MAX 4096
29 #endif
30
31 #ifndef NULL
32 # define NULL 0
33 #endif
34
35 #ifdef __CYGWIN__
36 # undef DOSISH
37 #endif
38 #if defined __CYGWIN__ || defined DOSISH
39 # define DOSISH_UNC
40 # define DOSISH_DRIVE_LETTER
41 # define FILE_ALT_SEPARATOR '\\'
42 #endif
43
44 #ifndef CDIO_FILE_SEPARATOR
45 # define CDIO_FILE_SEPARATOR '/'
46 #endif
47
48 #if defined __CYGWIN__ || defined DOSISH
49 # define FILE_ALT_SEPARATOR '\\'
50 #endif
51
52 #ifdef CDIO_FILE_ALT_SEPARATOR
53 # define isdirsep(x) ((x) == CDIO_FILE_SEPARATOR || (x) == CDIO_FILE_ALT_SEPARATOR)
54 #else
55 # define isdirsep(x) ((x) == CDIO_FILE_SEPARATOR)
56 #endif
57
58 #define skipprefix(path) (path)
59
60 #if !defined(CharNext) || defined(_MSC_VER) /* defined as CharNext[AW] on Windows. */
61 # undef CharNext
62 # define CharNext(p) ((p) + 1)
63 #endif
64
65 static char *
strrdirsep(const char * path)66 strrdirsep(const char *path)
67 {
68 char *last = NULL;
69 while (*path) {
70 if (isdirsep(*path)) {
71 const char *tmp = path++;
72 while (isdirsep(*path)) path++;
73 if (!*path) break;
74 last = (char *)tmp;
75 }
76 else {
77 path = CharNext(path);
78 }
79 }
80 return last;
81 }
82
83 char *
cdio_dirname(const char * fname)84 cdio_dirname(const char *fname)
85 {
86 const char *p;
87 p = strrdirsep(fname);
88 if (!p) return strdup(".");
89 return strndup(fname, p - fname);
90 }
91
92 /* If fname isn't absolute, add cwd to it. */
93 char *
cdio_abspath(const char * cwd,const char * fname)94 cdio_abspath(const char *cwd, const char *fname)
95 {
96 if (isdirsep(*fname))
97 return strdup(fname);
98 else {
99 size_t len = strlen(cwd) + strlen(fname) + 2;
100 char* result = calloc(sizeof(char), len);
101 snprintf(result, len, "%s%c%s",
102 cwd, CDIO_FILE_SEPARATOR, fname);
103 return result;
104 }
105 }
106
107 #ifdef STANDALONE
main(int argc,char ** argv)108 int main(int argc, char **argv)
109 {
110 char *dest;
111 char *dirname;
112 if (argc != 3) {
113 fprintf(stderr, "Usage: %s FILE REPLACE_BASENAME\n", argv[0]);
114 fprintf(stderr,
115 " Make PATH absolute\n");
116 exit(1);
117 }
118
119 dirname = cdio_dirname(argv[1]);
120 dest = cdio_abspath(dirname, argv[2]);
121 printf("%s -> %s\n", argv[1], dest);
122 free(dirname);
123 free(dest);
124 exit(0);
125 }
126 #endif
127