This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to add ACONCAT macro to libiberty


This patch adds a new macro to libiberty called ACONCAT.  It is
similar to the concat function but it gets memory from alloca instead
of malloc, (analogous to the new ASTRDUP macro.)

I broke out the guts of concat and exposed separate functions to get
the length of the strings and do the copying.  These are called by the
ACONCAT macro.  The macro itself takes a single double paren
surrounded argument just like PARAMS so that it can take any number of
actual parameters.  However they are evaluated twice, once to get the
length, and once to do the copy into the alloca'ed memory.

Bootstrapped on sparc-sun-solaris2.7, no testsuite regressions.

Ok to install?

		--Kaveh


2001-09-15  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

include:
	* libiberty.h (concatlen, concatcpy, concatcpy2,
	libiberty_concat_ptr, ACONCAT): New.

libiberty:
	* concat.c (vconcatlen, vconcatcpy, concatlen, concatcpy,
	concatcpy2): New functions.
	(concat): Use vconcatlen/vconcatcpy.

gcc:
	* gcc.c (find_file): Use ACONCAT in lieu of alloca/strcpy/strcat.

diff -rcp orig/egcs-CVS20010914/include/libiberty.h egcs-CVS20010914/include/libiberty.h
*** orig/egcs-CVS20010914/include/libiberty.h	Sat Aug 11 07:30:14 2001
--- egcs-CVS20010914/include/libiberty.h	Sat Sep 15 12:07:43 2001
*************** extern const char *lbasename PARAMS ((co
*** 90,95 ****
--- 90,122 ----
  
  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 concatlen 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 *concatcpy 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 *concatcpy2 PARAMS ((const char *, ...));
+ 
+ /* This is the global area used by concatcpy2.  */
+ 
+ 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 (concatlen ACONCAT_PARAMS + 1), \
+    concatcpy2 ACONCAT_PARAMS)
+ 
  /* Check whether two file descriptors refer to the same file.  */
  
  extern int fdmatch PARAMS ((int fd1, int fd2));
diff -rcp orig/egcs-CVS20010914/libiberty/concat.c egcs-CVS20010914/libiberty/concat.c
*** orig/egcs-CVS20010914/libiberty/concat.c	Mon Aug 27 14:53:07 2001
--- egcs-CVS20010914/libiberty/concat.c	Sat Sep 15 12:08:24 2001
*************** NOTES
*** 74,111 ****
  #  endif
  # endif
  
! char *
! concat VPARAMS ((const char *first, ...))
  {
!   register size_t length;
!   register char *newstr;
!   register char *end;
!   register 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);
  
!   /* Now copy the individual pieces to the result string. */
!   VA_OPEN (args, first);
!   VA_FIXEDARG (args, const char *, first);
  
-   end = newstr;
    for (arg = first; arg ; arg = va_arg (args, const char *))
      {
!       length = strlen (arg);
        memcpy (end, arg, length);
        end += length;
      }
    *end = '\000';
    VA_CLOSE (args);
  
    return newstr;
--- 74,171 ----
  #  endif
  # endif
  
! static inline unsigned long vconcatlen PARAMS ((const char *, va_list));
! static inline unsigned long
! vconcatlen (first, args)
!      const char *first;
!      va_list args;
  {
!   unsigned long length = 0;
!   const char *arg;
  
    for (arg = first; arg ; arg = va_arg (args, const char *))
      length += strlen (arg);
  
!   return length;
! }
  
! static inline char *vconcatcpy PARAMS ((char *, const char *, va_list));
! static inline char *
! vconcatcpy (dst, first, args)
!      char *dst;
!      const char *first;
!      va_list args;
! {
!   char *end = dst;
!   const char *arg;
  
    for (arg = first; arg ; arg = va_arg (args, const char *))
      {
!       unsigned long length = strlen (arg);
        memcpy (end, arg, length);
        end += length;
      }
    *end = '\000';
+ 
+   return dst;
+ }
+ 
+ unsigned long
+ concatlen VPARAMS ((const char *first, ...))
+ {
+   unsigned long length;
+ 
+   VA_OPEN (args, first);
+   VA_FIXEDARG (args, const char *, first);
+   length = vconcatlen (first, args);
+   VA_CLOSE (args);
+ 
+   return length;
+ }
+ 
+ char *
+ concatcpy VPARAMS ((char *dst, const char *first, ...))
+ {
+   char *save_dst;
+ 
+   VA_OPEN (args, first);
+   VA_FIXEDARG (args, char *, dst);
+   VA_FIXEDARG (args, const char *, first);
+   vconcatcpy (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 *
+ concatcpy2 VPARAMS ((const char *first, ...))
+ {
+   VA_OPEN (args, first);
+   VA_FIXEDARG (args, const char *, first);
+   vconcatcpy (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 (vconcatlen (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);
+   vconcatcpy (newstr, first, args);
    VA_CLOSE (args);
  
    return newstr;
diff -rcp orig/egcs-CVS20010914/gcc/gcc.c egcs-CVS20010914/gcc/gcc.c
*** orig/egcs-CVS20010914/gcc/gcc.c	Thu Sep 13 10:32:53 2001
--- egcs-CVS20010914/gcc/gcc.c	Sat Sep 15 12:07:13 2001
*************** find_file (name)
*** 5422,5433 ****
    /* Try multilib_dir if it is defined.  */
    if (multilib_dir != NULL)
      {
!       char *try;
! 
!       try = (char *) alloca (strlen (multilib_dir) + strlen (name) + 2);
!       strcpy (try, multilib_dir);
!       strcat (try, dir_separator_str);
!       strcat (try, name);
  
        newname = find_a_file (&startfile_prefixes, try, R_OK);
  
--- 5422,5428 ----
    /* Try multilib_dir if it is defined.  */
    if (multilib_dir != NULL)
      {
!       const char *const try = ACONCAT ((multilib_dir, dir_separator_str, name, NULL));
  
        newname = find_a_file (&startfile_prefixes, try, R_OK);
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]