02110-1301, USA. */
#include <config.h>
-#include "message.h"
+#include <libpspp/message.h>
#include "filename.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
-#include "alloc.h"
-#include "message.h"
-#include "str.h"
+#include <libpspp/alloc.h>
+#include "intprops.h"
+#include <libpspp/message.h>
+#include <libpspp/str.h>
#include "settings.h"
-#include "version.h"
+#include <libpspp/version.h>
#include "xreadlink.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
-#include "debug-print.h"
-
/* PORTME: Everything in this file is system dependent. */
#ifdef unix
#include <pwd.h>
-#if HAVE_UNISTD_H
#include <unistd.h>
-#endif
#include <sys/stat.h>
#include "stat-macros.h"
#endif
\f
/* Functions for performing operations on filenames. */
-/* Substitutes $variables as defined by GETENV into INPUT and returns
- a copy of the resultant string. Supports $var and ${var} syntaxes;
- $$ substitutes as $. */
-char *
-fn_interp_vars (const char *input, const char *(*getenv) (const char *))
+
+/* 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 *))
{
- struct string output;
+ char *input ;
+ char *s ;
- if (NULL == strchr (input, '$'))
- return xstrdup (input);
+ assert (target);
- ds_init (&output, strlen (input));
+ 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 (*input)
- {
- case '\0':
- return ds_c_str (&output);
+ {
+ switch (*s)
+ {
+ case '\0':
+ goto done ;
- case '$':
- input++;
+ case '$':
+ s++;
- if (*input == '$')
- {
- ds_putc (&output, '$');
- input++;
- }
- else
- {
- int stop;
- int start;
- const char *value;
-
- start = ds_length (&output);
-
- if (*input == '(')
- {
- stop = ')';
- input++;
- }
- else if (*input == '{')
- {
- stop = '}';
- input++;
- }
- else
- stop = 0;
-
- while (*input && *input != stop
- && (stop || isalpha ((unsigned char) *input)))
- ds_putc (&output, *input++);
+ 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 (&output) + start);
- ds_truncate (&output, start);
- ds_puts (&output, value);
+ value = getenv (ds_c_str (target) + start);
+ ds_truncate (target, start);
+ ds_puts (target, value);
- if (stop && *input == stop)
- input++;
- }
+ if (stop && *s == stop)
+ s++;
+ }
+ break;
- default:
- ds_putc (&output, *input++);
- }
+ default:
+ ds_putc (target, *s++);
+ }
+ }
+
+ done:
+ free(input);
+ return;
}
#ifdef unix
return fn_tilde_expand (basename);
{
- char *temp = fn_interp_vars (path, fn_getenv);
- bp = subst_path = fn_tilde_expand (temp);
- free (temp);
+ struct string temp;
+ ds_create(&temp, path);
+
+ fn_interp_vars(&temp, fn_getenv);
+
+ bp = subst_path = fn_tilde_expand (ds_c_str(&temp));
+
+ ds_destroy(&temp);
}
msg (VM (4), _("Searching for `%s'..."), basename);
int size = 2;
char *buffer = xmalloc (size);
if ( buffer)
- {
- buffer[0]='.';
- buffer[1]='\0';
- }
+ {
+ buffer[0]='.';
+ buffer[1]='\0';
+ }
return buffer;
else
return fclose (f);
}
-\f
-/* More extensive file handling. */
-
-/* File open routine that extends fn_open(). Opens or reopens a
- file according to the contents of file_ext F. Returns nonzero on
- success. If 0 is returned, errno is set to a sensible value. */
-int
-fn_open_ext (struct file_ext *f)
-{
- char *p;
-
- p = strstr (f->filename, "%d");
- if (p)
- {
- char *s = local_alloc (strlen (f->filename) + INT_DIGITS - 1);
- char *cp;
-
- memcpy (s, f->filename, p - f->filename);
- cp = spprintf (&s[p - f->filename], "%d", *f->sequence_no);
- strcpy (cp, &p[2]);
-
- if (f->file)
- {
- int error = 0;
-
- if (f->preclose)
- if (f->preclose (f) == 0)
- error = errno;
-
- if (EOF == fn_close (f->filename, f->file) || error)
- {
- f->file = NULL;
- local_free (s);
-
- if (error)
- errno = error;
-
- return 0;
- }
-
- f->file = NULL;
- }
-
- f->file = fn_open (s, f->mode);
- local_free (s);
-
- if (f->file && f->postopen)
- if (f->postopen (f) == 0)
- {
- int error = errno;
- fn_close (f->filename, f->file);
- errno = error;
-
- return 0;
- }
-
- return (f->file != NULL);
- }
- else if (f->file)
- return 1;
- else
- {
- f->file = fn_open (f->filename, f->mode);
-
- if (f->file && f->postopen)
- if (f->postopen (f) == 0)
- {
- int error = errno;
- fn_close (f->filename, f->file);
- errno = error;
-
- return 0;
- }
-
- return (f->file != NULL);
- }
-}
-
-/* Properly closes the file associated with file_ext F, if any.
- Return nonzero on success. If zero is returned, errno is set to a
- sensible value. */
-int
-fn_close_ext (struct file_ext *f)
-{
- if (f->file)
- {
- int error = 0;
-
- if (f->preclose)
- if (f->preclose (f) == 0)
- error = errno;
-
- if (EOF == fn_close (f->filename, f->file) || error)
- {
- f->file = NULL;
-
- if (error)
- errno = error;
-
- return 0;
- }
-
- f->file = NULL;
- }
- return 1;
-}
#ifdef unix
/* A file's identity. */
struct file_identity
- {
- dev_t device; /* Device number. */
- ino_t inode; /* Inode number. */
- };
+{
+ 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
#else /* not unix */
/* A file's identity. */
struct file_identity
- {
- char *normalized_filename; /* File's normalized name. */
- };
+{
+ 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