You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
-#include <assert.h>
+#include "error.h"
#include "filename.h"
#include <stdlib.h>
#include <ctype.h>
/* PORTME: Everything in this file is system dependent. */
-#if unix
+#ifdef unix
#include <pwd.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#include "stat.h"
#endif
-#if __WIN32__
+#ifdef __WIN32__
#define NOGDI
#define NOUSER
#define NONLS
if (NULL == strchr (input, '$'))
return xstrdup (input);
- ds_init (NULL, &output, strlen (input));
+ ds_init (&output, strlen (input));
for (;;)
switch (*input)
{
case '\0':
- return ds_value (&output);
+ return ds_c_str (&output);
case '$':
input++;
if (*input == '$')
{
- ds_putchar (&output, '$');
+ ds_putc (&output, '$');
input++;
}
else
while (*input && *input != stop
&& (stop || isalpha ((unsigned char) *input)))
- ds_putchar (&output, *input++);
+ ds_putc (&output, *input++);
- value = getenv (ds_value (&output) + start);
+ value = getenv (ds_c_str (&output) + start);
ds_truncate (&output, start);
- ds_concat (&output, value);
+ ds_puts (&output, value);
if (stop && *input == stop)
input++;
}
default:
- ds_putchar (&output, *input++);
+ ds_putc (&output, *input++);
}
}
-#if unix
+#ifdef unix
/* Expands csh tilde notation from the path INPUT into a malloc()'d
returned string. */
char *
if (NULL == strchr (input, '~'))
return xstrdup (input);
- ds_init (NULL, &output, strlen (input));
+ ds_init (&output, strlen (input));
ip = input;
for (ip = input; *ip; )
if (*ip != '~' || (ip != input && ip[-1] != PATH_DELIMITER))
- ds_putchar (&output, *ip++);
+ ds_putc (&output, *ip++);
else
{
static const char stop_set[3] = {DIR_SEPARATOR, PATH_DELIMITER, 0};
pwd = getpwnam (username);
if (!pwd || !pwd->pw_dir)
- ds_putchar (&output, *ip++);
+ ds_putc (&output, *ip++);
else
- ds_concat (&output, pwd->pw_dir);
+ ds_puts (&output, pwd->pw_dir);
}
else
{
const char *home = fn_getenv ("HOME");
if (!home)
- ds_putchar (&output, *ip++);
+ ds_putc (&output, *ip++);
else
- ds_concat (&output, home);
+ ds_puts (&output, home);
}
ip = cp;
}
- return ds_value (&output);
+ return ds_c_str (&output);
}
#else /* !unix */
char *
-fn_tilde_expand (char *input)
+fn_tilde_expand (const char *input)
{
return xstrdup (input);
}
If PREPEND is non-NULL, then it is prepended to each filename;
i.e., it looks like PREPEND/PATH_COMPONENT/NAME. This is not done
with absolute directories in the path. */
-#if unix || __MSDOS__ || __WIN32__
+#if defined (unix) || defined (__MSDOS__) || defined (__WIN32__)
char *
fn_search_path (const char *basename, const char *path, const char *prepend)
{
}
msg (VM (4), _("Searching for `%s'..."), basename);
- ds_init (NULL, &filename, 64);
+ ds_init (&filename, 64);
for (;;)
{
ds_clear (&filename);
if (prepend && !fn_absolute_p (bp))
{
- ds_concat (&filename, prepend);
- ds_putchar (&filename, DIR_SEPARATOR);
+ ds_puts (&filename, prepend);
+ ds_putc (&filename, DIR_SEPARATOR);
}
- ds_concat_buffer (&filename, bp, ep - bp);
+ ds_concat (&filename, bp, ep - bp);
if (ep - bp
- && ds_value (&filename)[ds_length (&filename) - 1] != DIR_SEPARATOR)
- ds_putchar (&filename, DIR_SEPARATOR);
- ds_concat (&filename, basename);
+ && ds_c_str (&filename)[ds_length (&filename) - 1] != DIR_SEPARATOR)
+ ds_putc (&filename, DIR_SEPARATOR);
+ ds_puts (&filename, basename);
- msg (VM (5), " - %s", ds_value (&filename));
- if (fn_exists_p (ds_value (&filename)))
+ msg (VM (5), " - %s", ds_c_str (&filename));
+ if (fn_exists_p (ds_c_str (&filename)))
{
- msg (VM (4), _("Found `%s'."), ds_value (&filename));
+ msg (VM (4), _("Found `%s'."), ds_c_str (&filename));
free (subst_path);
- return ds_value (&filename);
+ return ds_c_str (&filename);
}
if (0 == *ep)
existing file. Returns a malloc()'d copy of the canonical name.
This function must always succeed; if it needs to bail out then it
should return xstrdup(FN1). */
-#if unix
+#ifdef unix
char *
fn_normalize (const char *filename)
{
}
}
}
-#elif __WIN32__
+#elif defined (__WIN32__)
char *
fn_normalize (const char *fn1)
{
}
#endif
\f
+#if unix
/* Returns the current working directory, as a malloc()'d string.
From libc.info. */
char *
buffer = xmalloc (size);
}
}
+#else
+char *
+fn_get_cwd (void)
+{
+ int size = 2;
+ char *buffer = xmalloc (size);
+ if ( buffer)
+ {
+ buffer[0]='.';
+ buffer[1]='\0';
+ }
+
+ return buffer;
+
+}
+#endif
\f
/* Find out information about files. */
int
fn_absolute_p (const char *name)
{
-#if unix
+#ifdef unix
if (name[0] == '/'
|| !strncmp (name, "./", 2)
|| !strncmp (name, "../", 3)
|| name[0] == '~')
return 1;
-#elif __MSDOS__
+#elif defined (__MSDOS__)
if (name[0] == '\\'
|| !strncmp (name, ".\\", 2)
|| !strncmp (name, "..\\", 3)
{
if (!strcmp (filename, "-") || !strcmp (filename, "stdin")
|| !strcmp (filename, "stdout") || !strcmp (filename, "stderr")
-#if unix
+#ifdef unix
|| filename[0] == '|'
|| (*filename && filename[strlen (filename) - 1] == '|')
#endif
int
fn_exists_p (const char *name)
{
-#if unix
+#ifdef unix
struct stat temp;
return stat (name, &temp) == 0;
#endif
}
-#if unix
+#ifdef unix
/* Stolen from libc.info but heavily modified, this is a wrapper
around readlink() that allows for arbitrary filename length. */
char *
else if (mode[0] == 'w' && !strcmp (fn, "stderr"))
return stderr;
-#if unix
+#ifdef unix
if (fn[0] == '|')
{
- if (set_safer)
+ if (safer_mode())
return safety_violation (fn);
return popen (&fn[1], mode);
char *s;
FILE *f;
- if (set_safer)
+ if (safer_mode())
return safety_violation (fn);
s = local_alloc (strlen (fn));
{
if (!strcmp (fn, "-"))
return 0;
-#if unix
+#ifdef unix
else if (fn[0] == '|' || (*fn && fn[strlen (fn) - 1] == '|'))
{
pclose (f);
}
return 1;
}
+
+#ifdef unix
+/* A file's identity. */
+struct file_identity
+ {
+ dev_t device; /* Device number. */
+ ino_t inode; /* Inode number. */
+ };
+
+/* Returns a pointer to a dynamically allocated structure whose
+ value can be used to tell whether two files are actually the
+ same file. Returns a null pointer if no information about the
+ file is available, perhaps because it does not exist. The
+ caller is responsible for freeing the structure with
+ fn_free_identity() when finished. */
+struct file_identity *
+fn_get_identity (const char *filename)
+{
+ struct stat s;
+
+ if (stat (filename, &s) == 0)
+ {
+ struct file_identity *identity = xmalloc (sizeof *identity);
+ identity->device = s.st_dev;
+ identity->inode = s.st_ino;
+ return identity;
+ }
+ else
+ return NULL;
+}
+
+/* Frees IDENTITY obtained from fn_get_identity(). */
+void
+fn_free_identity (struct file_identity *identity)
+{
+ free (identity);
+}
+
+/* Compares A and B, returning a strcmp()-type result. */
+int
+fn_compare_file_identities (const struct file_identity *a,
+ const struct file_identity *b)
+{
+ assert (a != NULL);
+ assert (b != NULL);
+ if (a->device != b->device)
+ return a->device < b->device ? -1 : 1;
+ else
+ return a->inode < b->inode ? -1 : a->inode > b->inode;
+}
+#else /* not unix */
+/* A file's identity. */
+struct file_identity
+ {
+ char *normalized_filename; /* File's normalized name. */
+ };
+
+/* Returns a pointer to a dynamically allocated structure whose
+ value can be used to tell whether two files are actually the
+ same file. Returns a null pointer if no information about the
+ file is available, perhaps because it does not exist. The
+ caller is responsible for freeing the structure with
+ fn_free_identity() when finished. */
+struct file_identity *
+fn_get_identity (const char *filename)
+{
+ struct file_identity *identity = xmalloc (sizeof *identity);
+ identity->normalized_filename = fn_normalize (filename);
+ return identity;
+}
+
+/* Frees IDENTITY obtained from fn_get_identity(). */
+void
+fn_free_identity (struct file_identity *identity)
+{
+ if (identity != NULL)
+ {
+ free (identity->normalized_filename);
+ free (identity);
+ }
+}
+
+/* Compares A and B, returning a strcmp()-type result. */
+int
+fn_compare_file_identities (const struct file_identity *a,
+ const struct file_identity *b)
+{
+ return strcmp (a->normalized_filename, b->normalized_filename);
+}
+#endif /* not unix */