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 |
|
|
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 */ |