summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog13
-rw-r--r--include/libiberty.h40
-rw-r--r--libiberty/ChangeLog14
-rw-r--r--libiberty/alloca.c6
-rw-r--r--libiberty/concat.c98
5 files changed, 152 insertions, 19 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 24541e0716..6c25ae3fc9 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,16 @@
+2001-09-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libiberty.h (concat_length, concat_copy, concat_copy2,
+ libiberty_concat_ptr, ACONCAT): New.
+
+ * libiberty.h (ASTRDUP): New macro.
+ libiberty_optr, libiberty_nptr, libiberty_len): Declare.
+
+2001-09-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libiberty.h (ASTRDUP): New macro.
+ libiberty_optr, libiberty_nptr, libiberty_len): Declare.
+
2001-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* ansidecl.h: Update comments reflecting previous change.
diff --git a/include/libiberty.h b/include/libiberty.h
index 8d46e375e3..43f1b7d401 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -90,6 +90,33 @@ extern const char *lbasename PARAMS ((const char *));
extern char *concat PARAMS ((const char *, ...)) ATTRIBUTE_MALLOC;
+/* Determine the length of concatenating an arbitrary number of
+ strings, up to (char *) NULL. */
+
+extern unsigned long concat_length PARAMS ((const char *, ...));
+
+/* Concatenate an arbitrary number of strings into a SUPPLIED area of
+ memory, up to (char *) NULL. The supplied memory is assumed to be
+ large enough. */
+
+extern char *concat_copy PARAMS ((char *, const char *, ...));
+
+/* Concatenate an arbitrary number of strings into a GLOBAL area of
+ memory, up to (char *) NULL. The supplied memory is assumed to be
+ large enough. */
+
+extern char *concat_copy2 PARAMS ((const char *, ...));
+
+/* This is the global area used by concat_copy2. */
+
+extern char *libiberty_concat_ptr;
+
+/* Concatenate an arbitrary number of strings, up to (char *) NULL.
+ Allocates memory using alloca. Arguments are evaluated twice!. */
+#define ACONCAT(ACONCAT_PARAMS) \
+ (libiberty_concat_ptr = alloca (concat_length ACONCAT_PARAMS + 1), \
+ concat_copy2 ACONCAT_PARAMS)
+
/* Check whether two file descriptors refer to the same file. */
extern int fdmatch PARAMS ((int fd1, int fd2));
@@ -246,12 +273,25 @@ extern PTR C_alloca PARAMS((size_t));
#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA
# define alloca(x) __builtin_alloca(x)
# undef C_ALLOCA
+# define ASTRDUP(X) \
+ (__extension__ ({ const char *const libiberty_optr = (X); \
+ const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \
+ char *const libiberty_nptr = alloca (libiberty_len); \
+ (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); }))
#else
# define alloca(x) C_alloca(x)
# undef USE_C_ALLOCA
# define USE_C_ALLOCA 1
# undef C_ALLOCA
# define C_ALLOCA 1
+extern const char *libiberty_optr;
+extern char *libiberty_nptr;
+extern unsigned long libiberty_len;
+# define ASTRDUP(X) \
+ (libiberty_optr = (X), \
+ libiberty_len = strlen (libiberty_optr) + 1, \
+ libiberty_nptr = alloca (libiberty_len), \
+ (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len))
#endif
#ifdef __cplusplus
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 39b3295892..d9dc3dcb8b 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,17 @@
+2001-09-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * concat.c (vconcat_length, vconcat_copy, concat_length,
+ concat_copy, concat_copy2): New functions.
+ (concat): Use vconcat_length/vconcat_copy.
+
+ * alloca.c (libiberty_optr, libiberty_nptr, libiberty_len):
+ Define.
+
+2001-09-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alloca.c (libiberty_optr, libiberty_nptr, libiberty_len):
+ Define.
+
2001-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* asprintf.c: Don't define USE_STDARG. Use VPARAMS, VA_OPEN,
diff --git a/libiberty/alloca.c b/libiberty/alloca.c
index bf105d80f0..822c1dc230 100644
--- a/libiberty/alloca.c
+++ b/libiberty/alloca.c
@@ -34,6 +34,12 @@
#include <stdlib.h>
#endif
+/* These variables are used by the ASTRDUP implementation that relies
+ on C_alloca. */
+const char *libiberty_optr;
+char *libiberty_nptr;
+unsigned long libiberty_len;
+
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
diff --git a/libiberty/concat.c b/libiberty/concat.c
index 2e31e833f4..feed0df819 100644
--- a/libiberty/concat.c
+++ b/libiberty/concat.c
@@ -74,38 +74,98 @@ NOTES
# endif
# endif
-char *
-concat VPARAMS ((const char *first, ...))
+static inline unsigned long vconcat_length PARAMS ((const char *, va_list));
+static inline unsigned long
+vconcat_length (first, args)
+ const char *first;
+ va_list args;
{
- register size_t length;
- register char *newstr;
- register char *end;
- register const char *arg;
+ unsigned long length = 0;
+ const char *arg;
- /* First compute the size of the result and get sufficient memory. */
- VA_OPEN (args, first);
- VA_FIXEDARG (args, const char *, first);
-
- length = 0;
for (arg = first; arg ; arg = va_arg (args, const char *))
length += strlen (arg);
- VA_CLOSE (args);
-
- newstr = (char *) xmalloc (length + 1);
+ return length;
+}
- /* Now copy the individual pieces to the result string. */
- VA_OPEN (args, first);
- VA_FIXEDARG (args, const char *, first);
+static inline char *vconcat_copy PARAMS ((char *, const char *, va_list));
+static inline char *
+vconcat_copy (dst, first, args)
+ char *dst;
+ const char *first;
+ va_list args;
+{
+ char *end = dst;
+ const char *arg;
- end = newstr;
for (arg = first; arg ; arg = va_arg (args, const char *))
{
- length = strlen (arg);
+ unsigned long length = strlen (arg);
memcpy (end, arg, length);
end += length;
}
*end = '\000';
+
+ return dst;
+}
+
+unsigned long
+concat_length VPARAMS ((const char *first, ...))
+{
+ unsigned long length;
+
+ VA_OPEN (args, first);
+ VA_FIXEDARG (args, const char *, first);
+ length = vconcat_length (first, args);
+ VA_CLOSE (args);
+
+ return length;
+}
+
+char *
+concat_copy VPARAMS ((char *dst, const char *first, ...))
+{
+ char *save_dst;
+
+ VA_OPEN (args, first);
+ VA_FIXEDARG (args, char *, dst);
+ VA_FIXEDARG (args, const char *, first);
+ vconcat_copy (dst, first, args);
+ save_dst = dst; /* With K&R C, dst goes out of scope here. */
+ VA_CLOSE (args);
+
+ return save_dst;
+}
+
+char *libiberty_concat_ptr;
+
+char *
+concat_copy2 VPARAMS ((const char *first, ...))
+{
+ VA_OPEN (args, first);
+ VA_FIXEDARG (args, const char *, first);
+ vconcat_copy (libiberty_concat_ptr, first, args);
+ VA_CLOSE (args);
+
+ return libiberty_concat_ptr;
+}
+
+char *
+concat VPARAMS ((const char *first, ...))
+{
+ char *newstr;
+
+ /* First compute the size of the result and get sufficient memory. */
+ VA_OPEN (args, first);
+ VA_FIXEDARG (args, const char *, first);
+ newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
+ VA_CLOSE (args);
+
+ /* Now copy the individual pieces to the result string. */
+ VA_OPEN (args, first);
+ VA_FIXEDARG (args, const char *, first);
+ vconcat_copy (newstr, first, args);
VA_CLOSE (args);
return newstr;