/[gnats]/gnats/gnats/misc.c
ViewVC logotype

Diff of /gnats/gnats/misc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.41 by chewie, Tue Nov 30 15:43:55 2004 UTC revision 1.42 by chewie, Thu Feb 24 21:21:22 2005 UTC
# Line 397  or @var{str} == NULL. Line 397  or @var{str} == NULL.
397  char *  char *
398  xstrndup (const char *str, size_t len)  xstrndup (const char *str, size_t len)
399  {  {
400    if (str == NULL || len < 1)    if (str == NULL)
401      {      {
402        return NULL;        return NULL;
403      }      }
404    else    else
405      {      {
406        char *res = xmalloc (len + 1);        char *res;
407          
408          if (len < 1) {
409            len = 0;
410          }
411          res = xmalloc (len + 1);
412        memcpy (res, str, len);        memcpy (res, str, len);
413        res[len] = '\0';        res[len] = '\0';
414        return res;        return res;
415      }      }
416  }  }
417    
418    /* Allocate a memory with internal error handling. */
419    PTR
420    xmalloc(size_t size)
421    {
422      void *ptr;
423    
424      if (size == (size_t)NULL)
425        size = 1;
426      if ((ptr = malloc(size)) == NULL) {
427        (void)fprintf(stderr, "xmalloc: unable to allocate memory");
428        program_error(__FILE__, __LINE__);
429      }
430      return (ptr);
431    }
432    
433    /* Safely change the size of previously allocated memory area. */
434    PTR
435    xrealloc(PTR ptr, size_t size)
436    {
437      PTR ptr2;
438    
439      if (size == (size_t)NULL)
440        size = 1;
441      if ((ptr2 = realloc(ptr, size)) == NULL) {
442        if (ptr != (PTR)NULL)
443          free(ptr);
444        (void)fprintf(stderr, "xrealloc: unable to relocate memory");
445        program_error(__FILE__, __LINE__);
446      }
447      return(ptr2);
448    }
449    
450    /* Save a copy of a string with internal error handling. */
451    char *
452    xstrdup(const char *str)
453    {
454      char *strc;
455    
456      if ((strc = strdup(str)) == NULL) {
457        (void)fprintf(stderr, "xstrdup: unable to duplicate a string");
458        program_error(__FILE__, __LINE__);
459      }
460      return(strc);
461    }
462    
463  #ifndef HAVE_MKDIR  #ifndef HAVE_MKDIR
464  /* mkdir adapted from GNU tar.  */  /* mkdir adapted from GNU tar.  */
465    
# Line 691  value_is_empty (const char *string) Line 740  value_is_empty (const char *string)
740      return TRUE;      return TRUE;
741    }    }
742  }  }
743    
744    /* The following functions are stolen from libiberty library (-liberty) */
745    
746    #ifndef HAVE_ASPRINTF
747    /*
748    @deftypefn Extension int asprintf (char **@var{resptr}, const char *@var{format}, ...)
749    
750    Like @code{sprintf}, but instead of passing a pointer to a buffer, you
751    pass a pointer to a pointer.  This function will compute the size of
752    the buffer needed, allocate memory with @code{malloc}, and store a
753    pointer to the allocated memory in @code{*@var{resptr}}.  The value
754    returned is the same as @code{sprintf} would return.  If memory could
755    not be allocated, minus one is returned and @code{NULL} is stored in
756    @code{*@var{resptr}}.
757    
758    @end deftypefn
759    */
760    
761    int
762    asprintf VPARAMS ((char **buf, const char *fmt, ...))
763    {
764      int status;
765      VA_OPEN (ap, fmt);
766      VA_FIXEDARG (ap, char **, buf);
767      VA_FIXEDARG (ap, const char *, fmt);
768      status = vasprintf (buf, fmt, ap);
769      VA_CLOSE (ap);
770      return status;
771    }
772    #endif /* HAVE_ASPRINTF */
773    
774    #ifndef HAVE_VASPRINTF
775    /*
776    @deftypefn Extension int vasprintf (char **@var{resptr}, const char *@var{format}, va_list @var{args})
777    
778    Like @code{vsprintf}, but instead of passing a pointer to a buffer,
779    you pass a pointer to a pointer.  This function will compute the size
780    of the buffer needed, allocate memory with @code{malloc}, and store a
781    pointer to the allocated memory in @code{*@var{resptr}}.  The value
782    returned is the same as @code{vsprintf} would return.  If memory could
783    not be allocated, minus one is returned and @code{NULL} is stored in
784    @code{*@var{resptr}}.
785    
786    @end deftypefn
787    */
788    
789    /* This is a vasprintf helper */
790    static int int_vasprintf PARAMS ((char **, const char *, va_list));
791    
792    static int
793    int_vasprintf (result, format, args)
794         char **result;
795         const char *format;
796         va_list args;
797    {
798      const char *p = format;
799      /* Add one to make sure that it is never zero, which might cause malloc
800         to return NULL.  */
801      int total_width = strlen (format) + 1;
802      va_list ap;
803    
804    #ifdef va_copy
805      va_copy (ap, args);
806    #else
807      memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list));
808    #endif
809    
810      while (*p != '\0')
811        {
812          if (*p++ == '%')
813            {
814              while (strchr ("-+ #0", *p))
815                ++p;
816              if (*p == '*')
817                {
818                  ++p;
819                  total_width += abs (va_arg (ap, int));
820                }
821              else
822                total_width += strtoul (p, (char **) &p, 10);
823              if (*p == '.')
824                {
825                  ++p;
826                  if (*p == '*')
827                    {
828                      ++p;
829                      total_width += abs (va_arg (ap, int));
830                    }
831                  else
832                  total_width += strtoul (p, (char **) &p, 10);
833                }
834              while (strchr ("hlL", *p))
835                ++p;
836              /* Should be big enough for any format specifier except %s and floats.  */
837              total_width += 30;
838              switch (*p)
839                {
840                case 'd':
841                case 'i':
842                case 'o':
843                case 'u':
844                case 'x':
845                case 'X':
846                case 'c':
847                  (void) va_arg (ap, int);
848                  break;
849                case 'f':
850                case 'e':
851                case 'E':
852                case 'g':
853                case 'G':
854                  (void) va_arg (ap, double);
855                  /* Since an ieee double can have an exponent of 307, we'll
856                     make the buffer wide enough to cover the gross case. */
857                  total_width += 307;
858                  break;
859                case 's':
860                  total_width += strlen (va_arg (ap, char *));
861                  break;
862                case 'p':
863                case 'n':
864                  (void) va_arg (ap, char *);
865                  break;
866                }
867              p++;
868            }
869        }
870    #ifdef va_copy
871      va_end (ap);
872    #endif
873      *result = (char *) malloc (total_width);
874      if (*result != NULL)
875        return vsprintf (*result, format, args);
876      else
877        return -1;
878    }
879    
880    int
881    vasprintf (result, format, args)
882         char **result;
883         const char *format;
884    #if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
885         _BSD_VA_LIST_ args;
886    #else
887         va_list args;
888    #endif
889    {
890      return int_vasprintf (result, format, args);
891    }
892    #endif /* HAVE_VASPRINTF */
893    
894    #ifndef HAVE_BASENAME
895    /*
896    @deftypefn Supplemental char* basename (const char *@var{name})
897    
898    Returns a pointer to the last component of pathname @var{name}.
899    Behavior is undefined if the pathname ends in a directory separator.
900    
901    @end deftypefn
902    */
903    
904    #ifndef DIR_SEPARATOR
905    #define DIR_SEPARATOR '/'
906    #endif
907    
908    #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
909      defined (__OS2__)
910    #define HAVE_DOS_BASED_FILE_SYSTEM
911    #ifndef DIR_SEPARATOR_2
912    #define DIR_SEPARATOR_2 '\\'
913    #endif
914    #endif
915    
916    /* Define IS_DIR_SEPARATOR.  */
917    #ifndef DIR_SEPARATOR_2
918    # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
919    #else /* DIR_SEPARATOR_2 */
920    # define IS_DIR_SEPARATOR(ch) \
921            (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
922    #endif /* DIR_SEPARATOR_2 */
923    
924    /* Note: to be POSIX-2 compliant "name" have a "char *" type. */
925    char *
926    basename (name)
927         char *name;
928    {
929      const char *base;
930    
931    #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
932      /* Skip over the disk name in MSDOS pathnames. */
933      if (ISALPHA (name[0]) && name[1] == ':')
934        name += 2;
935    #endif
936    
937      for (base = name; *name; name++)
938        {
939          if (IS_DIR_SEPARATOR (*name))
940            {
941              base = name + 1;
942            }
943        }
944      return (char *) base;
945    }
946    #endif /* HAVE_BASENAME */

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26