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"
+#include <libpspp/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;
+ assert (target);
- if (NULL == strchr (input, '$'))
- return xstrdup (input);
+ char *input = xmalloc(ds_length(target) + 1);
+ char *s = input;
- ds_init (&output, strlen (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++;
+ }
- 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);
p = strstr (f->filename, "%d");
if (p)
{
- char *s = local_alloc (strlen (f->filename) + INT_DIGITS - 1);
+ char *s = local_alloc (strlen (f->filename)
+ + INT_STRLEN_BOUND (int) - 1);
char *cp;
memcpy (s, f->filename, p - f->filename);