From: Ben Pfaff Date: Mon, 17 Apr 2006 01:30:21 +0000 (+0000) Subject: GNU standards require "file name" instead of "filename" in X-Git-Tag: v0.6.0~978 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;ds=sidebyside;h=5f168bf8465ae50ba5c2c761b52f29a0500c0658;p=pspp-builds.git GNU standards require "file name" instead of "filename" in documentation. It's nice for our code to follow the convention too. --- diff --git a/src/data/ChangeLog b/src/data/ChangeLog index c453f178..53067496 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,16 @@ +Sun Apr 16 18:28:35 2006 Ben Pfaff + + GNU standards require "file name" instead of "filename" in + documentation. It's nice for our code to follow the convention + too. + + * filename.c: Rename to file-name.c. + + * filename.h: Rename to file-name.h. Update all inclusions. + Update header guards. + + * automake.mk: Update file names. + Sun Apr 16 16:42:47 2006 Ben Pfaff * filename.c: (fn_dirname) Renamed fn_dir_name(), all references diff --git a/src/data/any-reader.c b/src/data/any-reader.c index df37c8ea..0156d0b5 100644 --- a/src/data/any-reader.c +++ b/src/data/any-reader.c @@ -26,7 +26,7 @@ #include #include #include "file-handle-def.h" -#include "filename.h" +#include "file-name.h" #include "por-file-reader.h" #include "sys-file-reader.h" #include diff --git a/src/data/any-writer.c b/src/data/any-writer.c index 9ee8af91..2aeaa3a5 100644 --- a/src/data/any-writer.c +++ b/src/data/any-writer.c @@ -26,7 +26,7 @@ #include #include #include "file-handle-def.h" -#include "filename.h" +#include "file-name.h" #include "por-file-writer.h" #include "sys-file-writer.h" #include diff --git a/src/data/automake.mk b/src/data/automake.mk index 95507c82..86fcade1 100644 --- a/src/data/automake.mk +++ b/src/data/automake.mk @@ -23,8 +23,8 @@ src_data_libdata_a_SOURCES = \ src/data/dictionary.h \ src/data/file-handle-def.c \ src/data/file-handle-def.h \ - src/data/filename.c \ - src/data/filename.h \ + src/data/file-name.c \ + src/data/file-name.h \ src/data/format.c \ src/data/format.h \ src/data/format.def \ diff --git a/src/data/file-handle-def.c b/src/data/file-handle-def.c index 66ee25f5..152e5d4b 100644 --- a/src/data/file-handle-def.c +++ b/src/data/file-handle-def.c @@ -25,7 +25,7 @@ #include #include #include -#include "filename.h" +#include "file-name.h" #include #include #include "variable.h" diff --git a/src/data/file-name.c b/src/data/file-name.c new file mode 100644 index 00000000..a88f83cf --- /dev/null +++ b/src/data/file-name.c @@ -0,0 +1,790 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include "file-name.h" +#include +#include +#include +#include +#include +#include "intprops.h" +#include +#include +#include "settings.h" +#include +#include "xreadlink.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +/* PORTME: Everything in this file is system dependent. */ + +#ifdef unix +#include +#include +#include +#include "stat-macros.h" +#endif + +#ifdef __WIN32__ +#define NOGDI +#define NOUSER +#define NONLS +#include +#endif + +#if __DJGPP__ +#include +#endif + +/* Initialization. */ + +const char *config_path; + +void +fn_init (void) +{ + config_path = fn_getenv_default ("STAT_CONFIG_PATH", default_config_path); +} + +/* Functions for performing operations on filenames. */ + + +/* Substitutes $variables as defined by GETENV into TARGET. + TARGET must be a string containing the text for which substitution + is required. + Supports $var and ${var} syntaxes; + $$ substitutes as $. +*/ +void +fn_interp_vars (struct string *target, + const char *(*getenv) (const char *)) +{ + char *input ; + char *s ; + + assert (target); + + input = xmalloc(ds_length(target) + 1); + s = input; + + strcpy(input, ds_c_str(target)); + + if (NULL == strchr (ds_c_str(target), '$')) + goto done; + + ds_clear(target); + + for (;;) + { + switch (*s) + { + case '\0': + goto done ; + + case '$': + s++; + + if (*s == '$') + { + ds_putc (target, '$'); + s++; + } + else + { + int stop; + int start; + const char *value; + + start = ds_length (target); + + if (*s == '(') + { + stop = ')'; + s++; + } + else if (*s == '{') + { + stop = '}'; + s++; + } + else + stop = 0; + + while (*s && *s != stop + && (stop || isalpha ((unsigned char) *s))) + { + ds_putc (target, *s++); + } + + value = getenv (ds_c_str (target) + start); + ds_truncate (target, start); + ds_puts (target, value); + + if (stop && *s == stop) + s++; + } + break; + + default: + ds_putc (target, *s++); + } + } + + done: + free(input); + return; +} + +#ifdef unix +/* Expands csh tilde notation from the path INPUT into a malloc()'d + returned string. */ +char * +fn_tilde_expand (const char *input) +{ + struct string output = DS_INITIALIZER; + if (input[0] == '~') + { + const char *home = NULL; + const char *remainder = NULL; + if (input[1] == '/' || input[1] == '\0') + { + home = fn_getenv ("HOME"); + remainder = input + 1; + } + else + { + struct string user_name = DS_INITIALIZER; + struct passwd *pwd; + + ds_assign_buffer (&user_name, input + 1, strcspn (input + 1, "/")); + pwd = getpwnam (ds_c_str (&user_name)); + if (pwd != NULL && pwd->pw_dir[0] != '\0') + { + home = pwd->pw_dir; + remainder = input + 1 + ds_length (&user_name); + } + ds_destroy (&user_name); + } + + if (home != NULL) + { + ds_puts (&output, home); + if (*remainder != '\0') + ds_puts (&output, remainder); + } + } + if (ds_is_empty (&output)) + ds_puts (&output, input); + return ds_c_str (&output); +} +#else /* !unix */ +char * +fn_tilde_expand (const char *input) +{ + return xstrdup (input); +} +#endif /* !unix */ + +/* Searches for a configuration file with name NAME in the path given + by PATH, which is tilde- and environment-interpolated. Directories + in PATH are delimited by PATH_DELIMITER, defined in . + Returns the malloc'd full name of the first file found, or NULL if + none is found. + + If PREFIX is non-NULL, then it is prefixed to each filename; + i.e., it looks like PREFIX/PATH_COMPONENT/NAME. This is not done + with absolute directories in the path. */ +char * +fn_search_path (const char *base_name, const char *path_, const char *prefix) +{ + struct string path; + struct string dir = DS_INITIALIZER; + struct string file = DS_INITIALIZER; + size_t save_idx = 0; + + if (fn_is_absolute (base_name)) + return fn_tilde_expand (base_name); + + /* Interpolate environment variables. */ + ds_create (&path, path_); + fn_interp_vars (&path, fn_getenv); + + verbose_msg (2, _("searching for \"%s\" in path \"%s\""), + base_name, ds_c_str (&path)); + while (ds_separate (&path, &dir, PATH_DELIMITER_STRING, &save_idx)) + { + /* Do tilde expansion. */ + if (ds_first (&dir) == '~') + { + char *tmp_str = fn_tilde_expand (ds_c_str (&dir)); + ds_assign_c_str (&dir, tmp_str); + free (tmp_str); + } + + /* Construct file name. */ + ds_clear (&file); + if (prefix != NULL && !fn_is_absolute (ds_c_str (&dir))) + { + ds_puts (&file, prefix); + ds_putc (&file, DIR_SEPARATOR); + } + ds_puts (&file, ds_c_str (&dir)); + if (ds_length (&dir) && ds_last (&file) != DIR_SEPARATOR) + ds_putc (&file, DIR_SEPARATOR); + ds_puts (&file, base_name); + + /* Check whether file exists. */ + if (fn_exists (ds_c_str (&file))) + { + verbose_msg (2, _("...found \"%s\""), ds_c_str (&file)); + ds_destroy (&path); + ds_destroy (&dir); + return ds_c_str (&file); + } + } + + /* Failure. */ + verbose_msg (2, _("...not found")); + ds_destroy (&path); + ds_destroy (&dir); + ds_destroy (&file); + return NULL; +} + +/* fn_normalize(): This very OS-dependent routine canonicalizes + filename FN1. The filename should not need to be the name of an + 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). */ +#ifdef unix +char * +fn_normalize (const char *filename) +{ + const char *src; + char *fn1, *fn2, *dest; + int maxlen; + + if (fn_is_special (filename)) + return xstrdup (filename); + + fn1 = fn_tilde_expand (filename); + + /* Follow symbolic links. */ + for (;;) + { + fn2 = fn1; + fn1 = fn_readlink (fn1); + if (!fn1) + { + fn1 = fn2; + break; + } + free (fn2); + } + + maxlen = strlen (fn1) * 2; + if (maxlen < 31) + maxlen = 31; + dest = fn2 = xmalloc (maxlen + 1); + src = fn1; + + if (*src == DIR_SEPARATOR) + *dest++ = *src++; + else + { + errno = 0; + while (getcwd (dest, maxlen - (dest - fn2)) == NULL && errno == ERANGE) + { + maxlen *= 2; + dest = fn2 = xrealloc (fn2, maxlen + 1); + errno = 0; + } + if (errno) + { + free (fn1); + free (fn2); + return NULL; + } + dest = strchr (fn2, '\0'); + if (dest - fn2 >= maxlen) + { + int ofs = dest - fn2; + maxlen *= 2; + fn2 = xrealloc (fn2, maxlen + 1); + dest = fn2 + ofs; + } + if (dest[-1] != DIR_SEPARATOR) + *dest++ = DIR_SEPARATOR; + } + + for (;;) + { + int c, f; + + c = *src++; + + f = 0; + if (c == DIR_SEPARATOR || c == 0) + { + /* remove `./', `../' from directory */ + if (dest[-1] == '.' && dest[-2] == DIR_SEPARATOR) + dest--; + else if (dest[-1] == '.' && dest[-2] == '.' && dest[-3] == DIR_SEPARATOR) + { + dest -= 3; + if (dest == fn2) + dest++; + while (dest[-1] != DIR_SEPARATOR) + dest--; + } + else if (dest[-1] != DIR_SEPARATOR) /* remove extra slashes */ + f = 1; + + if (c == 0) + { + if (dest[-1] == DIR_SEPARATOR && dest > fn2 + 1) + dest--; + *dest = 0; + free (fn1); + + return xrealloc (fn2, strlen (fn2) + 1); + } + } + else + f = 1; + + if (f) + { + if (dest - fn2 >= maxlen) + { + int ofs = dest - fn2; + maxlen *= 2; + fn2 = xrealloc (fn2, maxlen + 1); + dest = fn2 + ofs; + } + *dest++ = c; + } + } +} +#elif defined (__WIN32__) +char * +fn_normalize (const char *fn1) +{ + DWORD len; + DWORD success; + char *fn2; + + /* Don't change special filenames. */ + if (is_special_filename (filename)) + return xstrdup (filename); + + /* First find the required buffer length. */ + len = GetFullPathName (fn1, 0, NULL, NULL); + if (!len) + { + fn2 = xstrdup (fn1); + return fn2; + } + + /* Then make a buffer that big. */ + fn2 = xmalloc (len); + success = GetFullPathName (fn1, len, fn2, NULL); + if (success >= len || success == 0) + { + free (fn2); + fn2 = xstrdup (fn1); + return fn2; + } + return fn2; +} +#elif __BORLANDC__ +char * +fn_normalize (const char *fn1) +{ + char *fn2 = _fullpath (NULL, fn1, 0); + if (fn2) + { + char *cp; + for (cp = fn2; *cp; cp++) + *cp = toupper ((unsigned char) (*cp)); + return fn2; + } + return xstrdup (fn1); +} +#elif __DJGPP__ +char * +fn_normalize (const char *fn1) +{ + char *fn2 = xmalloc (1024); + _fixpath (fn1, fn2); + fn2 = xrealloc (fn2, strlen (fn2) + 1); + return fn2; +} +#else /* not Lose32, Unix, or DJGPP */ +char * +fn_normalize (const char *fn) +{ + return xstrdup (fn); +} +#endif /* not Lose32, Unix, or DJGPP */ + +/* Returns the directory part of FILENAME, as a malloc()'d + string. */ +char * +fn_dir_name (const char *filename) +{ + const char *p; + char *s; + size_t len; + + len = strlen (filename); + if (len == 1 && filename[0] == '/') + p = filename + 1; + else if (len && filename[len - 1] == DIR_SEPARATOR) + p = buf_find_reverse (filename, len - 1, filename + len - 1, 1); + else + p = strrchr (filename, DIR_SEPARATOR); + if (p == NULL) + p = filename; + + s = xmalloc (p - filename + 1); + memcpy (s, filename, p - filename); + s[p - filename] = 0; + + return s; +} + +/* Returns the extension part of FILENAME as a malloc()'d string. + If FILENAME does not have an extension, returns an empty + string. */ +char * +fn_extension (const char *filename) +{ + const char *extension = strrchr (filename, '.'); + if (extension == NULL) + extension = ""; + return xstrdup (extension); +} + +#if unix +/* Returns the current working directory, as a malloc()'d string. + From libc.info. */ +char * +fn_get_cwd (void) +{ + int size = 100; + char *buffer = xmalloc (size); + + for (;;) + { + char *value = getcwd (buffer, size); + if (value != 0) + return buffer; + + size *= 2; + free (buffer); + 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 + +/* Find out information about files. */ + +/* Returns nonzero iff NAME specifies an absolute filename. */ +int +fn_is_absolute (const char *name) +{ +#ifdef unix + if (name[0] == '/' + || !strncmp (name, "./", 2) + || !strncmp (name, "../", 3) + || name[0] == '~') + return 1; +#elif defined (__MSDOS__) + if (name[0] == '\\' + || !strncmp (name, ".\\", 2) + || !strncmp (name, "..\\", 3) + || (name[0] && name[1] == ':')) + return 1; +#endif + + return 0; +} + +/* Returns 1 if the filename specified is a virtual file that doesn't + really exist on disk, 0 if it's a real filename. */ +int +fn_is_special (const char *filename) +{ + if (!strcmp (filename, "-") || !strcmp (filename, "stdin") + || !strcmp (filename, "stdout") || !strcmp (filename, "stderr") +#ifdef unix + || filename[0] == '|' + || (*filename && filename[strlen (filename) - 1] == '|') +#endif + ) + return 1; + + return 0; +} + +/* Returns nonzero if file with name NAME exists. */ +int +fn_exists (const char *name) +{ +#ifdef unix + struct stat temp; + + return stat (name, &temp) == 0; +#else + FILE *f = fopen (name, "r"); + if (!f) + return 0; + fclose (f); + return 1; +#endif +} + +/* Returns the symbolic link value for FILENAME as a dynamically + allocated buffer, or a null pointer on failure. */ +char * +fn_readlink (const char *filename) +{ + return xreadlink (filename, 32); +} + +/* Environment variables. */ + +/* Simulates $VER and $ARCH environment variables. */ +const char * +fn_getenv (const char *s) +{ + if (!strcmp (s, "VER")) + return fn_getenv_default ("STAT_VER", bare_version); + else if (!strcmp (s, "ARCH")) + return fn_getenv_default ("STAT_ARCH", host_system); + else + return getenv (s); +} + +/* Returns getenv(KEY) if that's non-NULL; else returns DEF. */ +const char * +fn_getenv_default (const char *key, const char *def) +{ + const char *value = getenv (key); + return value ? value : def; +} + +/* Basic file handling. */ + +/* Used for giving an error message on a set_safer security + violation. */ +static FILE * +safety_violation (const char *fn) +{ + msg (SE, _("Not opening pipe file `%s' because SAFER option set."), fn); + errno = EPERM; + return NULL; +} + +/* As a general comment on the following routines, a `sensible value' + for errno includes 0 if there is no associated system error. The + routines will only set errno to 0 if there is an error in a + callback that sets errno to 0; they themselves won't. */ + +/* File open routine that understands `-' as stdin/stdout and `|cmd' + as a pipe to command `cmd'. Returns resultant FILE on success, + NULL on failure. If NULL is returned then errno is set to a + sensible value. */ +FILE * +fn_open (const char *fn, const char *mode) +{ + assert (mode[0] == 'r' || mode[0] == 'w'); + + if (mode[0] == 'r' && (!strcmp (fn, "stdin") || !strcmp (fn, "-"))) + return stdin; + else if (mode[0] == 'w' && (!strcmp (fn, "stdout") || !strcmp (fn, "-"))) + return stdout; + else if (mode[0] == 'w' && !strcmp (fn, "stderr")) + return stderr; + +#ifdef unix + if (fn[0] == '|') + { + if (get_safer_mode ()) + return safety_violation (fn); + + return popen (&fn[1], mode); + } + else if (*fn && fn[strlen (fn) - 1] == '|') + { + char *s; + FILE *f; + + if (get_safer_mode ()) + return safety_violation (fn); + + s = local_alloc (strlen (fn)); + memcpy (s, fn, strlen (fn) - 1); + s[strlen (fn) - 1] = 0; + + f = popen (s, mode); + + local_free (s); + + return f; + } + else +#endif + { + FILE *f = fopen (fn, mode); + + if (f && mode[0] == 'w') + setvbuf (f, NULL, _IOLBF, 0); + + return f; + } +} + +/* Counterpart to fn_open that closes file F with name FN; returns 0 + on success, EOF on failure. If EOF is returned, errno is set to a + sensible value. */ +int +fn_close (const char *fn, FILE *f) +{ + if (!strcmp (fn, "-")) + return 0; +#ifdef unix + else if (fn[0] == '|' || (*fn && fn[strlen (fn) - 1] == '|')) + { + pclose (f); + return 0; + } +#endif + else + return fclose (f); +} + +#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 */ diff --git a/src/data/file-name.h b/src/data/file-name.h new file mode 100644 index 00000000..f9620b03 --- /dev/null +++ b/src/data/file-name.h @@ -0,0 +1,71 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + Written by Ben Pfaff . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef FILE_NAME_H +#define FILE_NAME_H 1 + +#include + +/* Directory separator and path delimiter for this OS. */ +#ifndef __MSDOS__ +#define DIR_SEPARATOR '/' +#define PATH_DELIMITER ':' +#define DIR_SEPARATOR_STRING "/" +#define PATH_DELIMITER_STRING ":" +#else +#define DIR_SEPARATOR '\\' +#define PATH_DELIMITER ';' +#define DIR_SEPARATOR_STRING "\\" +#define PATH_DELIMITER_STRING ";" +#endif + +/* Search path for configuration files. */ +extern const char *config_path; + +void fn_init (void); + +struct string; +void fn_interp_vars (struct string *target, + const char *(*getenv) (const char *)); +char *fn_tilde_expand (const char *fn); +char *fn_search_path (const char *base_name, const char *path, + const char *prefix); +char *fn_normalize (const char *fn); +char *fn_dir_name (const char *fn); +char *fn_extension (const char *fn); + +char *fn_get_cwd (void); + +int fn_is_absolute (const char *fn); +int fn_is_special (const char *fn); +int fn_exists (const char *fn); +char *fn_readlink (const char *fn); + +const char *fn_getenv (const char *variable); +const char *fn_getenv_default (const char *variable, const char *def); + +FILE *fn_open (const char *fn, const char *mode); +int fn_close (const char *fn, FILE *file); + +struct file_identity *fn_get_identity (const char *filename); +void fn_free_identity (struct file_identity *); +int fn_compare_file_identities (const struct file_identity *, + const struct file_identity *); + +#endif /* file-name.h */ diff --git a/src/data/filename.c b/src/data/filename.c deleted file mode 100644 index 2a0dd947..00000000 --- a/src/data/filename.c +++ /dev/null @@ -1,790 +0,0 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include -#include -#include "filename.h" -#include -#include -#include -#include -#include -#include "intprops.h" -#include -#include -#include "settings.h" -#include -#include "xreadlink.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -/* PORTME: Everything in this file is system dependent. */ - -#ifdef unix -#include -#include -#include -#include "stat-macros.h" -#endif - -#ifdef __WIN32__ -#define NOGDI -#define NOUSER -#define NONLS -#include -#endif - -#if __DJGPP__ -#include -#endif - -/* Initialization. */ - -const char *config_path; - -void -fn_init (void) -{ - config_path = fn_getenv_default ("STAT_CONFIG_PATH", default_config_path); -} - -/* Functions for performing operations on filenames. */ - - -/* Substitutes $variables as defined by GETENV into TARGET. - TARGET must be a string containing the text for which substitution - is required. - Supports $var and ${var} syntaxes; - $$ substitutes as $. -*/ -void -fn_interp_vars (struct string *target, - const char *(*getenv) (const char *)) -{ - char *input ; - char *s ; - - assert (target); - - input = xmalloc(ds_length(target) + 1); - s = input; - - strcpy(input, ds_c_str(target)); - - if (NULL == strchr (ds_c_str(target), '$')) - goto done; - - ds_clear(target); - - for (;;) - { - switch (*s) - { - case '\0': - goto done ; - - case '$': - s++; - - if (*s == '$') - { - ds_putc (target, '$'); - s++; - } - else - { - int stop; - int start; - const char *value; - - start = ds_length (target); - - if (*s == '(') - { - stop = ')'; - s++; - } - else if (*s == '{') - { - stop = '}'; - s++; - } - else - stop = 0; - - while (*s && *s != stop - && (stop || isalpha ((unsigned char) *s))) - { - ds_putc (target, *s++); - } - - value = getenv (ds_c_str (target) + start); - ds_truncate (target, start); - ds_puts (target, value); - - if (stop && *s == stop) - s++; - } - break; - - default: - ds_putc (target, *s++); - } - } - - done: - free(input); - return; -} - -#ifdef unix -/* Expands csh tilde notation from the path INPUT into a malloc()'d - returned string. */ -char * -fn_tilde_expand (const char *input) -{ - struct string output = DS_INITIALIZER; - if (input[0] == '~') - { - const char *home = NULL; - const char *remainder = NULL; - if (input[1] == '/' || input[1] == '\0') - { - home = fn_getenv ("HOME"); - remainder = input + 1; - } - else - { - struct string user_name = DS_INITIALIZER; - struct passwd *pwd; - - ds_assign_buffer (&user_name, input + 1, strcspn (input + 1, "/")); - pwd = getpwnam (ds_c_str (&user_name)); - if (pwd != NULL && pwd->pw_dir[0] != '\0') - { - home = pwd->pw_dir; - remainder = input + 1 + ds_length (&user_name); - } - ds_destroy (&user_name); - } - - if (home != NULL) - { - ds_puts (&output, home); - if (*remainder != '\0') - ds_puts (&output, remainder); - } - } - if (ds_is_empty (&output)) - ds_puts (&output, input); - return ds_c_str (&output); -} -#else /* !unix */ -char * -fn_tilde_expand (const char *input) -{ - return xstrdup (input); -} -#endif /* !unix */ - -/* Searches for a configuration file with name NAME in the path given - by PATH, which is tilde- and environment-interpolated. Directories - in PATH are delimited by PATH_DELIMITER, defined in . - Returns the malloc'd full name of the first file found, or NULL if - none is found. - - If PREFIX is non-NULL, then it is prefixed to each filename; - i.e., it looks like PREFIX/PATH_COMPONENT/NAME. This is not done - with absolute directories in the path. */ -char * -fn_search_path (const char *base_name, const char *path_, const char *prefix) -{ - struct string path; - struct string dir = DS_INITIALIZER; - struct string file = DS_INITIALIZER; - size_t save_idx = 0; - - if (fn_is_absolute (base_name)) - return fn_tilde_expand (base_name); - - /* Interpolate environment variables. */ - ds_create (&path, path_); - fn_interp_vars (&path, fn_getenv); - - verbose_msg (2, _("searching for \"%s\" in path \"%s\""), - base_name, ds_c_str (&path)); - while (ds_separate (&path, &dir, PATH_DELIMITER_STRING, &save_idx)) - { - /* Do tilde expansion. */ - if (ds_first (&dir) == '~') - { - char *tmp_str = fn_tilde_expand (ds_c_str (&dir)); - ds_assign_c_str (&dir, tmp_str); - free (tmp_str); - } - - /* Construct file name. */ - ds_clear (&file); - if (prefix != NULL && !fn_is_absolute (ds_c_str (&dir))) - { - ds_puts (&file, prefix); - ds_putc (&file, DIR_SEPARATOR); - } - ds_puts (&file, ds_c_str (&dir)); - if (ds_length (&dir) && ds_last (&file) != DIR_SEPARATOR) - ds_putc (&file, DIR_SEPARATOR); - ds_puts (&file, base_name); - - /* Check whether file exists. */ - if (fn_exists (ds_c_str (&file))) - { - verbose_msg (2, _("...found \"%s\""), ds_c_str (&file)); - ds_destroy (&path); - ds_destroy (&dir); - return ds_c_str (&file); - } - } - - /* Failure. */ - verbose_msg (2, _("...not found")); - ds_destroy (&path); - ds_destroy (&dir); - ds_destroy (&file); - return NULL; -} - -/* fn_normalize(): This very OS-dependent routine canonicalizes - filename FN1. The filename should not need to be the name of an - 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). */ -#ifdef unix -char * -fn_normalize (const char *filename) -{ - const char *src; - char *fn1, *fn2, *dest; - int maxlen; - - if (fn_is_special (filename)) - return xstrdup (filename); - - fn1 = fn_tilde_expand (filename); - - /* Follow symbolic links. */ - for (;;) - { - fn2 = fn1; - fn1 = fn_readlink (fn1); - if (!fn1) - { - fn1 = fn2; - break; - } - free (fn2); - } - - maxlen = strlen (fn1) * 2; - if (maxlen < 31) - maxlen = 31; - dest = fn2 = xmalloc (maxlen + 1); - src = fn1; - - if (*src == DIR_SEPARATOR) - *dest++ = *src++; - else - { - errno = 0; - while (getcwd (dest, maxlen - (dest - fn2)) == NULL && errno == ERANGE) - { - maxlen *= 2; - dest = fn2 = xrealloc (fn2, maxlen + 1); - errno = 0; - } - if (errno) - { - free (fn1); - free (fn2); - return NULL; - } - dest = strchr (fn2, '\0'); - if (dest - fn2 >= maxlen) - { - int ofs = dest - fn2; - maxlen *= 2; - fn2 = xrealloc (fn2, maxlen + 1); - dest = fn2 + ofs; - } - if (dest[-1] != DIR_SEPARATOR) - *dest++ = DIR_SEPARATOR; - } - - for (;;) - { - int c, f; - - c = *src++; - - f = 0; - if (c == DIR_SEPARATOR || c == 0) - { - /* remove `./', `../' from directory */ - if (dest[-1] == '.' && dest[-2] == DIR_SEPARATOR) - dest--; - else if (dest[-1] == '.' && dest[-2] == '.' && dest[-3] == DIR_SEPARATOR) - { - dest -= 3; - if (dest == fn2) - dest++; - while (dest[-1] != DIR_SEPARATOR) - dest--; - } - else if (dest[-1] != DIR_SEPARATOR) /* remove extra slashes */ - f = 1; - - if (c == 0) - { - if (dest[-1] == DIR_SEPARATOR && dest > fn2 + 1) - dest--; - *dest = 0; - free (fn1); - - return xrealloc (fn2, strlen (fn2) + 1); - } - } - else - f = 1; - - if (f) - { - if (dest - fn2 >= maxlen) - { - int ofs = dest - fn2; - maxlen *= 2; - fn2 = xrealloc (fn2, maxlen + 1); - dest = fn2 + ofs; - } - *dest++ = c; - } - } -} -#elif defined (__WIN32__) -char * -fn_normalize (const char *fn1) -{ - DWORD len; - DWORD success; - char *fn2; - - /* Don't change special filenames. */ - if (is_special_filename (filename)) - return xstrdup (filename); - - /* First find the required buffer length. */ - len = GetFullPathName (fn1, 0, NULL, NULL); - if (!len) - { - fn2 = xstrdup (fn1); - return fn2; - } - - /* Then make a buffer that big. */ - fn2 = xmalloc (len); - success = GetFullPathName (fn1, len, fn2, NULL); - if (success >= len || success == 0) - { - free (fn2); - fn2 = xstrdup (fn1); - return fn2; - } - return fn2; -} -#elif __BORLANDC__ -char * -fn_normalize (const char *fn1) -{ - char *fn2 = _fullpath (NULL, fn1, 0); - if (fn2) - { - char *cp; - for (cp = fn2; *cp; cp++) - *cp = toupper ((unsigned char) (*cp)); - return fn2; - } - return xstrdup (fn1); -} -#elif __DJGPP__ -char * -fn_normalize (const char *fn1) -{ - char *fn2 = xmalloc (1024); - _fixpath (fn1, fn2); - fn2 = xrealloc (fn2, strlen (fn2) + 1); - return fn2; -} -#else /* not Lose32, Unix, or DJGPP */ -char * -fn_normalize (const char *fn) -{ - return xstrdup (fn); -} -#endif /* not Lose32, Unix, or DJGPP */ - -/* Returns the directory part of FILENAME, as a malloc()'d - string. */ -char * -fn_dir_name (const char *filename) -{ - const char *p; - char *s; - size_t len; - - len = strlen (filename); - if (len == 1 && filename[0] == '/') - p = filename + 1; - else if (len && filename[len - 1] == DIR_SEPARATOR) - p = buf_find_reverse (filename, len - 1, filename + len - 1, 1); - else - p = strrchr (filename, DIR_SEPARATOR); - if (p == NULL) - p = filename; - - s = xmalloc (p - filename + 1); - memcpy (s, filename, p - filename); - s[p - filename] = 0; - - return s; -} - -/* Returns the extension part of FILENAME as a malloc()'d string. - If FILENAME does not have an extension, returns an empty - string. */ -char * -fn_extension (const char *filename) -{ - const char *extension = strrchr (filename, '.'); - if (extension == NULL) - extension = ""; - return xstrdup (extension); -} - -#if unix -/* Returns the current working directory, as a malloc()'d string. - From libc.info. */ -char * -fn_get_cwd (void) -{ - int size = 100; - char *buffer = xmalloc (size); - - for (;;) - { - char *value = getcwd (buffer, size); - if (value != 0) - return buffer; - - size *= 2; - free (buffer); - 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 - -/* Find out information about files. */ - -/* Returns nonzero iff NAME specifies an absolute filename. */ -int -fn_is_absolute (const char *name) -{ -#ifdef unix - if (name[0] == '/' - || !strncmp (name, "./", 2) - || !strncmp (name, "../", 3) - || name[0] == '~') - return 1; -#elif defined (__MSDOS__) - if (name[0] == '\\' - || !strncmp (name, ".\\", 2) - || !strncmp (name, "..\\", 3) - || (name[0] && name[1] == ':')) - return 1; -#endif - - return 0; -} - -/* Returns 1 if the filename specified is a virtual file that doesn't - really exist on disk, 0 if it's a real filename. */ -int -fn_is_special (const char *filename) -{ - if (!strcmp (filename, "-") || !strcmp (filename, "stdin") - || !strcmp (filename, "stdout") || !strcmp (filename, "stderr") -#ifdef unix - || filename[0] == '|' - || (*filename && filename[strlen (filename) - 1] == '|') -#endif - ) - return 1; - - return 0; -} - -/* Returns nonzero if file with name NAME exists. */ -int -fn_exists (const char *name) -{ -#ifdef unix - struct stat temp; - - return stat (name, &temp) == 0; -#else - FILE *f = fopen (name, "r"); - if (!f) - return 0; - fclose (f); - return 1; -#endif -} - -/* Returns the symbolic link value for FILENAME as a dynamically - allocated buffer, or a null pointer on failure. */ -char * -fn_readlink (const char *filename) -{ - return xreadlink (filename, 32); -} - -/* Environment variables. */ - -/* Simulates $VER and $ARCH environment variables. */ -const char * -fn_getenv (const char *s) -{ - if (!strcmp (s, "VER")) - return fn_getenv_default ("STAT_VER", bare_version); - else if (!strcmp (s, "ARCH")) - return fn_getenv_default ("STAT_ARCH", host_system); - else - return getenv (s); -} - -/* Returns getenv(KEY) if that's non-NULL; else returns DEF. */ -const char * -fn_getenv_default (const char *key, const char *def) -{ - const char *value = getenv (key); - return value ? value : def; -} - -/* Basic file handling. */ - -/* Used for giving an error message on a set_safer security - violation. */ -static FILE * -safety_violation (const char *fn) -{ - msg (SE, _("Not opening pipe file `%s' because SAFER option set."), fn); - errno = EPERM; - return NULL; -} - -/* As a general comment on the following routines, a `sensible value' - for errno includes 0 if there is no associated system error. The - routines will only set errno to 0 if there is an error in a - callback that sets errno to 0; they themselves won't. */ - -/* File open routine that understands `-' as stdin/stdout and `|cmd' - as a pipe to command `cmd'. Returns resultant FILE on success, - NULL on failure. If NULL is returned then errno is set to a - sensible value. */ -FILE * -fn_open (const char *fn, const char *mode) -{ - assert (mode[0] == 'r' || mode[0] == 'w'); - - if (mode[0] == 'r' && (!strcmp (fn, "stdin") || !strcmp (fn, "-"))) - return stdin; - else if (mode[0] == 'w' && (!strcmp (fn, "stdout") || !strcmp (fn, "-"))) - return stdout; - else if (mode[0] == 'w' && !strcmp (fn, "stderr")) - return stderr; - -#ifdef unix - if (fn[0] == '|') - { - if (get_safer_mode ()) - return safety_violation (fn); - - return popen (&fn[1], mode); - } - else if (*fn && fn[strlen (fn) - 1] == '|') - { - char *s; - FILE *f; - - if (get_safer_mode ()) - return safety_violation (fn); - - s = local_alloc (strlen (fn)); - memcpy (s, fn, strlen (fn) - 1); - s[strlen (fn) - 1] = 0; - - f = popen (s, mode); - - local_free (s); - - return f; - } - else -#endif - { - FILE *f = fopen (fn, mode); - - if (f && mode[0] == 'w') - setvbuf (f, NULL, _IOLBF, 0); - - return f; - } -} - -/* Counterpart to fn_open that closes file F with name FN; returns 0 - on success, EOF on failure. If EOF is returned, errno is set to a - sensible value. */ -int -fn_close (const char *fn, FILE *f) -{ - if (!strcmp (fn, "-")) - return 0; -#ifdef unix - else if (fn[0] == '|' || (*fn && fn[strlen (fn) - 1] == '|')) - { - pclose (f); - return 0; - } -#endif - else - return fclose (f); -} - -#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 */ diff --git a/src/data/filename.h b/src/data/filename.h deleted file mode 100644 index 89b8aca4..00000000 --- a/src/data/filename.h +++ /dev/null @@ -1,71 +0,0 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. - Written by Ben Pfaff . - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#if !filename_h -#define filename_h 1 - -#include - -/* Directory separator and path delimiter for this OS. */ -#ifndef __MSDOS__ -#define DIR_SEPARATOR '/' -#define PATH_DELIMITER ':' -#define DIR_SEPARATOR_STRING "/" -#define PATH_DELIMITER_STRING ":" -#else -#define DIR_SEPARATOR '\\' -#define PATH_DELIMITER ';' -#define DIR_SEPARATOR_STRING "\\" -#define PATH_DELIMITER_STRING ";" -#endif - -/* Search path for configuration files. */ -extern const char *config_path; - -void fn_init (void); - -struct string; -void fn_interp_vars (struct string *target, - const char *(*getenv) (const char *)); -char *fn_tilde_expand (const char *fn); -char *fn_search_path (const char *base_name, const char *path, - const char *prefix); -char *fn_normalize (const char *fn); -char *fn_dir_name (const char *fn); -char *fn_extension (const char *fn); - -char *fn_get_cwd (void); - -int fn_is_absolute (const char *fn); -int fn_is_special (const char *fn); -int fn_exists (const char *fn); -char *fn_readlink (const char *fn); - -const char *fn_getenv (const char *variable); -const char *fn_getenv_default (const char *variable, const char *def); - -FILE *fn_open (const char *fn, const char *mode); -int fn_close (const char *fn, FILE *file); - -struct file_identity *fn_get_identity (const char *filename); -void fn_free_identity (struct file_identity *); -int fn_compare_file_identities (const struct file_identity *, - const struct file_identity *); - -#endif /* filename_h */ diff --git a/src/data/make-file.c b/src/data/make-file.c index 1d32d07e..5f5a224a 100644 --- a/src/data/make-file.c +++ b/src/data/make-file.c @@ -23,7 +23,7 @@ #include #include #include -#include "filename.h" +#include "file-name.h" #include "make-file.h" #include #include diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index 58a885ae..d5fe5c7c 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -36,7 +36,7 @@ #include "case.h" #include "dictionary.h" #include "file-handle-def.h" -#include "filename.h" +#include "file-name.h" #include "format.h" #include "value-labels.h" #include "variable.h" diff --git a/src/language/data-io/data-reader.c b/src/language/data-io/data-reader.c index 8d9dd207..22e15f97 100644 --- a/src/language/data-io/data-reader.c +++ b/src/language/data-io/data-reader.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/language/data-io/data-writer.c b/src/language/data-io/data-writer.c index eb5fe019..9aba2aaf 100644 --- a/src/language/data-io/data-writer.c +++ b/src/language/data-io/data-writer.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "gettext.h" diff --git a/src/language/data-io/file-handle.q b/src/language/data-io/file-handle.q index 09c180dc..e44afbc7 100644 --- a/src/language/data-io/file-handle.q +++ b/src/language/data-io/file-handle.q @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/language/line-buffer.c b/src/language/line-buffer.c index 53a63279..f5a8b30d 100644 --- a/src/language/line-buffer.c +++ b/src/language/line-buffer.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/message.c b/src/message.c index c48b08e8..6985b261 100644 --- a/src/message.c +++ b/src/message.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/output/ascii.c b/src/output/ascii.c index bafe74ac..53610bde 100644 --- a/src/output/ascii.c +++ b/src/output/ascii.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/output/html.c b/src/output/html.c index 3557085f..fd25285a 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "error.h" #include "getline.h" #include "getlogin_r.h" diff --git a/src/output/htmlP.h b/src/output/htmlP.h index fe63843d..1a29caeb 100644 --- a/src/output/htmlP.h +++ b/src/output/htmlP.h @@ -20,7 +20,7 @@ #if !htmlP_h #define htmlP_h 1 -#include +#include /* HTML output driver extension record. */ struct html_driver_ext diff --git a/src/output/output.c b/src/output/output.c index 349b5d3c..d590a38e 100644 --- a/src/output/output.c +++ b/src/output/output.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "htmlP.h" #include "intprops.h" #include diff --git a/src/output/postscript.c b/src/output/postscript.c index 7554dba5..7fea6374 100644 --- a/src/output/postscript.c +++ b/src/output/postscript.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include "afm.h" #include "chart.h" diff --git a/src/ui/terminal/command-line.c b/src/ui/terminal/command-line.c index cf5b660c..2a1fa41c 100644 --- a/src/ui/terminal/command-line.c +++ b/src/ui/terminal/command-line.c @@ -33,7 +33,7 @@ #include #include "read-line.h" #include -#include +#include #include #include diff --git a/src/ui/terminal/main.c b/src/ui/terminal/main.c index 69a7b12b..746fb160 100644 --- a/src/ui/terminal/main.c +++ b/src/ui/terminal/main.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/ui/terminal/read-line.c b/src/ui/terminal/read-line.c index 7122b78d..1a71d77a 100644 --- a/src/ui/terminal/read-line.c +++ b/src/ui/terminal/read-line.c @@ -26,12 +26,12 @@ #include "read-line.h" #include -#include +#include #include #include #include #include -#include +#include #include #include "gettext.h"