diff options
-rw-r--r-- | include/ChangeLog | 13 | ||||
-rw-r--r-- | include/libiberty.h | 40 | ||||
-rw-r--r-- | libiberty/ChangeLog | 14 | ||||
-rw-r--r-- | libiberty/alloca.c | 6 | ||||
-rw-r--r-- | libiberty/concat.c | 98 |
5 files changed, 152 insertions, 19 deletions
diff --git a/include/ChangeLog b/include/ChangeLog index 24541e0..6c25ae3 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 8d46e37..43f1b7d 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 39b3295..d9dc3dc 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 bf105d8..822c1dc 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 2e31e83..feed0df 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; |