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
7   Bash is free software; you can redistribute it and/or modify it under
8   the terms of the GNU General Public License as published by the Free
9   Software Foundation; either version 2, or (at your option) any later
10   version.
11
12   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15   for more details.
16
17   You should have received a copy of the GNU General Public License along
18   with Bash; see the file COPYING.  If not, write to the Free Software
19   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
30#include <bashansi.h>
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
45#endif
46
47extern char *get_working_directory __P((char *));
48
49/* Take PATH, an element from, e.g., $CDPATH, and DIR, a directory name,
50   and paste them together into PATH/DIR.  Tilde expansion is performed on
51   PATH if (flags & MP_DOTILDE) is non-zero.  If PATH is NULL or the empty
52   string, it is converted to the current directory.  A full pathname is
53   used if (flags & MP_DOCWD) is non-zero, otherwise `./' is used.  If
54   (flags & MP_RMDOT) is non-zero, any `./' is removed from the beginning
55   of DIR. */
56
57#define MAKEDOT() \
58  do { \
59    xpath = (char *)xmalloc (2); \
60    xpath[0] = '.'; \
61    xpath[1] = '\0'; \
62    pathlen = 1; \
63  } while (0)
64
65char *
66sh_makepath (path, dir, flags)
67     const char *path, *dir;
68     int flags;
69{
70  int dirlen, pathlen;
71  char *ret, *xpath, *xdir, *r, *s;
72
73  if (path == 0 || *path == '\0')
74    {
75      if (flags & MP_DOCWD)
76	{
77	  xpath = get_working_directory ("sh_makepath");
78	  if (xpath == 0)
79	    {
80	      ret = get_string_value ("PWD");
81	      if (ret)
82		xpath = savestring (ret);
83	    }
84	  if (xpath == 0)
85	    MAKEDOT();
86	  else
87	    pathlen = strlen (xpath);
88	}
89      else
90	MAKEDOT();
91    }
92  else
93    {
94      xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path, 0) : (char *)path;
95      pathlen = strlen (xpath);
96    }
97
98  xdir = (char *)dir;
99  dirlen = strlen (xdir);
100  if ((flags & MP_RMDOT) && dir[0] == '.' && dir[1] == '/')
101    {
102      xdir += 2;
103      dirlen -= 2;
104    }
105
106  r = ret = (char *)xmalloc (2 + dirlen + pathlen);
107  s = xpath;
108  while (*s)
109    *r++ = *s++;
110  if (s[-1] != '/')
111    *r++ = '/';
112  s = xdir;
113  while (*r++ = *s++)
114    ;
115  if (xpath != path)
116    free (xpath);
117  return (ret);
118}
119