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