]>
Commit | Line | Data |
---|---|---|
bb70624e JA |
1 | /* makepath.c - glue PATH and DIR together into a full pathname. */ |
2 | ||
3 | /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GNU Bash, the Bourne Again SHell. | |
6 | ||
3185942a JA |
7 | Bash is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation, either version 3 of the License, or | |
10 | (at your option) any later version. | |
bb70624e | 11 | |
3185942a JA |
12 | Bash is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
bb70624e | 16 | |
3185942a JA |
17 | You should have received a copy of the GNU General Public License |
18 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
bb70624e JA |
20 | |
21 | #include <config.h> | |
22 | ||
23 | #if defined (HAVE_UNISTD_H) | |
24 | # ifdef _MINIX | |
25 | # include <sys/types.h> | |
26 | # endif | |
27 | # include <unistd.h> | |
28 | #endif | |
29 | ||
f73dda09 | 30 | #include <bashansi.h> |
bb70624e JA |
31 | #include "shell.h" |
32 | ||
33 | #include <tilde/tilde.h> | |
34 | ||
35 | #ifndef NULL | |
36 | # define NULL 0 | |
37 | #endif | |
38 | ||
39 | /* MAKE SURE THESE AGREE WITH ../../externs.h. */ | |
40 | ||
41 | #ifndef MP_DOTILDE | |
42 | # define MP_DOTILDE 0x01 | |
43 | # define MP_DOCWD 0x02 | |
44 | # define MP_RMDOT 0x04 | |
3185942a | 45 | # define MP_IGNDOT 0x08 |
bb70624e JA |
46 | #endif |
47 | ||
48 | extern char *get_working_directory __P((char *)); | |
49 | ||
3185942a JA |
50 | static char *nullpath = ""; |
51 | ||
bb70624e JA |
52 | /* Take PATH, an element from, e.g., $CDPATH, and DIR, a directory name, |
53 | and paste them together into PATH/DIR. Tilde expansion is performed on | |
54 | PATH if (flags & MP_DOTILDE) is non-zero. If PATH is NULL or the empty | |
55 | string, it is converted to the current directory. A full pathname is | |
56 | used if (flags & MP_DOCWD) is non-zero, otherwise `./' is used. If | |
57 | (flags & MP_RMDOT) is non-zero, any `./' is removed from the beginning | |
3185942a JA |
58 | of DIR. If (flags & MP_IGNDOT) is non-zero, a PATH that is "." or "./" |
59 | is ignored. */ | |
bb70624e JA |
60 | |
61 | #define MAKEDOT() \ | |
62 | do { \ | |
f73dda09 | 63 | xpath = (char *)xmalloc (2); \ |
bb70624e JA |
64 | xpath[0] = '.'; \ |
65 | xpath[1] = '\0'; \ | |
66 | pathlen = 1; \ | |
67 | } while (0) | |
68 | ||
69 | char * | |
70 | sh_makepath (path, dir, flags) | |
f73dda09 | 71 | const char *path, *dir; |
bb70624e JA |
72 | int flags; |
73 | { | |
74 | int dirlen, pathlen; | |
f73dda09 | 75 | char *ret, *xpath, *xdir, *r, *s; |
bb70624e JA |
76 | |
77 | if (path == 0 || *path == '\0') | |
78 | { | |
79 | if (flags & MP_DOCWD) | |
80 | { | |
81 | xpath = get_working_directory ("sh_makepath"); | |
82 | if (xpath == 0) | |
83 | { | |
84 | ret = get_string_value ("PWD"); | |
85 | if (ret) | |
86 | xpath = savestring (ret); | |
87 | } | |
88 | if (xpath == 0) | |
89 | MAKEDOT(); | |
90 | else | |
91 | pathlen = strlen (xpath); | |
92 | } | |
93 | else | |
94 | MAKEDOT(); | |
95 | } | |
3185942a | 96 | else if ((flags & MP_IGNDOT) && path[0] == '.' && (path[1] == '\0' || |
ac50fbac | 97 | (path[1] == '/' && path[2] == '\0'))) |
3185942a JA |
98 | { |
99 | xpath = nullpath; | |
100 | pathlen = 0; | |
101 | } | |
bb70624e JA |
102 | else |
103 | { | |
7117c2d2 | 104 | xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path, 0) : (char *)path; |
bb70624e JA |
105 | pathlen = strlen (xpath); |
106 | } | |
107 | ||
f73dda09 JA |
108 | xdir = (char *)dir; |
109 | dirlen = strlen (xdir); | |
bb70624e JA |
110 | if ((flags & MP_RMDOT) && dir[0] == '.' && dir[1] == '/') |
111 | { | |
f73dda09 | 112 | xdir += 2; |
bb70624e JA |
113 | dirlen -= 2; |
114 | } | |
115 | ||
f73dda09 | 116 | r = ret = (char *)xmalloc (2 + dirlen + pathlen); |
28ef6c31 JA |
117 | s = xpath; |
118 | while (*s) | |
119 | *r++ = *s++; | |
3185942a | 120 | if (s > xpath && s[-1] != '/') |
28ef6c31 | 121 | *r++ = '/'; |
f73dda09 | 122 | s = xdir; |
28ef6c31 JA |
123 | while (*r++ = *s++) |
124 | ; | |
3185942a | 125 | if (xpath != path && xpath != nullpath) |
bb70624e JA |
126 | free (xpath); |
127 | return (ret); | |
128 | } |