merge from gcc
authorDJ Delorie <dj@redhat.com>
Wed, 10 Oct 2012 03:11:33 +0000 (03:11 +0000)
committerDJ Delorie <dj@redhat.com>
Wed, 10 Oct 2012 03:11:33 +0000 (03:11 +0000)
13 files changed:
include/ChangeLog
include/demangle.h
include/objalloc.h
libiberty/ChangeLog
libiberty/Makefile.in
libiberty/config.in
libiberty/configure
libiberty/configure.ac
libiberty/cp-demangle.c
libiberty/functions.texi
libiberty/maint-tool
libiberty/objalloc.c
libiberty/strnlen.c [new file with mode: 0644]

index 4a535eb2535f985936fa01564418eb62a59a34b6..e702ebe6189bd0513453d71a4206ddb94e1c6a96 100644 (file)
@@ -1,3 +1,13 @@
+2012-10-08  Jason Merrill  <jason@redhat.com>
+
+       * demangle.h (enum demangle_component_type): Add
+       DEMANGLE_COMPONENT_TLS_INIT and DEMANGLE_COMPONENT_TLS_WRAPPER.
+
+2012-09-18  Florian Weimer  <fweimer@redhat.com>
+
+       PR other/54411
+       * objalloc.h (objalloc_alloc): Do not use fast path on wraparound.
+
 2012-09-27  Anthony Green  <green@moxielogic.com>
 
        * opcode/moxie.h (MOXIE_BAD): New define.
index 34b3ed3cde9af3bb2716ed601cf59d283b39cda8..5da79d85221d303b1cec75904859193b94014c9c 100644 (file)
@@ -272,6 +272,9 @@ enum demangle_component_type
   /* A guard variable.  This has one subtree, the name for which this
      is a guard variable.  */
   DEMANGLE_COMPONENT_GUARD,
+  /* The init and wrapper functions for C++11 thread_local variables.  */
+  DEMANGLE_COMPONENT_TLS_INIT,
+  DEMANGLE_COMPONENT_TLS_WRAPPER,
   /* A reference temporary.  This has one subtree, the name for which
      this is a temporary.  */
   DEMANGLE_COMPONENT_REFTEMP,
index 36772d17b50d24ab04ca2b3ec7c623911e7f9de7..52857663ba249df23a0e0d545c6b31a4a671289f 100644 (file)
@@ -1,5 +1,5 @@
 /* objalloc.h -- routines to allocate memory for objects
-   Copyright 1997, 2001 Free Software Foundation, Inc.
+   Copyright 1997-2012 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Solutions.
 
 This program is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@ extern void *_objalloc_alloc (struct objalloc *, unsigned long);
      if (__len == 0)                                                   \
        __len = 1;                                                      \
      __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);     \
-     (__len <= __o->current_space                                      \
+     (__len != 0 && __len <= __o->current_space                                \
       ? (__o->current_ptr += __len,                                    \
         __o->current_space -= __len,                                   \
         (void *) (__o->current_ptr - __len))                           \
index 9afed43585581a14f2c1c43b8361273605a472f3..303dda23cae01088f4eba47d34e7c5c8ab0fa49b 100644 (file)
@@ -1,3 +1,26 @@
+2012-10-08  Jason Merrill  <jason@redhat.com>
+
+       * cp-demangle.c (d_special_name, d_dump): Handle TH and TW.
+       (d_make_comp, d_print_comp): Likewise.
+
+2012-09-18  Ian Lance Taylor  <iant@google.com>
+
+       * strnlen.c: New file.
+       * configure.ac: Check for strnlen, add it to AC_LIBOBJ if it's not
+       present.
+       * Makefile.in: Rebuild dependencies.
+       (CFILES): Add strnlen.c.
+       (CONFIGURED_OFILES): Add ./strnlen.$(objext).
+       * configure, config.in, functions.texi: Rebuild.
+
+       * maint-tool: Accept .def files in the include directory.
+
+2012-09-18  Florian Weimer  <fweimer@redhat.com>
+
+       PR other/54411
+       * objalloc.c (_objalloc_alloc): Add overflow check covering
+       alignment and CHUNK_HEADER_SIZE addition.
+
 2011-08-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        * argv.c (dupargv): Replace malloc with xmalloc.  Don't check
index 0a5da3178b17ea7a8ebccc59e17913ffbc314d1a..1ba8cf1ccb2a31e111186ed1ac3bbc0c69c4c8a3 100644 (file)
@@ -151,7 +151,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c                                \
         spaces.c splay-tree.c stack-limit.c stpcpy.c stpncpy.c         \
         strcasecmp.c strchr.c strdup.c strerror.c strncasecmp.c        \
         strncmp.c strrchr.c strsignal.c strstr.c strtod.c strtol.c     \
-        strtoul.c strndup.c strverscmp.c                               \
+        strtoul.c strndup.c strnlen.c strverscmp.c                     \
        timeval-utils.c tmpnam.c                                        \
        unlink-if-ordinary.c                                            \
        vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \
@@ -215,9 +215,9 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext)         \
         ./sigsetmask.$(objext) ./snprintf.$(objext)                    \
         ./stpcpy.$(objext) ./stpncpy.$(objext) ./strcasecmp.$(objext)  \
         ./strchr.$(objext) ./strdup.$(objext) ./strncasecmp.$(objext)  \
-        ./strncmp.$(objext) ./strndup.$(objext) ./strrchr.$(objext)    \
-        ./strstr.$(objext) ./strtod.$(objext) ./strtol.$(objext)       \
-        ./strtoul.$(objext) ./strverscmp.$(objext)                     \
+        ./strncmp.$(objext) ./strndup.$(objext) ./strnlen.$(objext)    \
+        ./strrchr.$(objext) ./strstr.$(objext) ./strtod.$(objext)      \
+        ./strtol.$(objext) ./strtoul.$(objext) ./strverscmp.$(objext)  \
        ./tmpnam.$(objext)                                              \
        ./vasprintf.$(objext) ./vfork.$(objext) ./vfprintf.$(objext)    \
         ./vprintf.$(objext) ./vsnprintf.$(objext) ./vsprintf.$(objext) \
@@ -622,8 +622,8 @@ $(CONFIGURED_OFILES): stamp-picdir
        else true; fi
        $(COMPILE.c) $(srcdir)/crc32.c $(OUTPUT_OPTION)
 
-./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.h \
-       $(INCDIR)/dwarf2.def
+./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.def \
+       $(INCDIR)/dwarf2.h
        if [ x"$(PICFLAG)" != x ]; then \
          $(COMPILE.c) $(PICFLAG) $(srcdir)/dwarfnames.c -o pic/$@; \
        else true; fi
@@ -656,7 +656,8 @@ $(CONFIGURED_OFILES): stamp-picdir
        else true; fi
        $(COMPILE.c) $(srcdir)/fibheap.c $(OUTPUT_OPTION)
 
-./filename_cmp.$(objext): $(srcdir)/filename_cmp.c config.h $(INCDIR)/filenames.h \
+./filename_cmp.$(objext): $(srcdir)/filename_cmp.c config.h $(INCDIR)/ansidecl.h \
+       $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
        $(INCDIR)/safe-ctype.h
        if [ x"$(PICFLAG)" != x ]; then \
          $(COMPILE.c) $(PICFLAG) $(srcdir)/filename_cmp.c -o pic/$@; \
@@ -757,7 +758,7 @@ $(CONFIGURED_OFILES): stamp-picdir
        $(COMPILE.c) $(srcdir)/insque.c $(OUTPUT_OPTION)
 
 ./lbasename.$(objext): $(srcdir)/lbasename.c config.h $(INCDIR)/ansidecl.h \
-       $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
+       $(INCDIR)/filenames.h $(INCDIR)/hashtab.h $(INCDIR)/libiberty.h \
        $(INCDIR)/safe-ctype.h
        if [ x"$(PICFLAG)" != x ]; then \
          $(COMPILE.c) $(PICFLAG) $(srcdir)/lbasename.c -o pic/$@; \
@@ -1043,7 +1044,7 @@ $(CONFIGURED_OFILES): stamp-picdir
        else true; fi
        $(COMPILE.c) $(srcdir)/splay-tree.c $(OUTPUT_OPTION)
 
-./stack-limit.$(objext): $(srcdir)/stack-limit.c config.h
+./stack-limit.$(objext): $(srcdir)/stack-limit.c config.h $(INCDIR)/ansidecl.h
        if [ x"$(PICFLAG)" != x ]; then \
          $(COMPILE.c) $(PICFLAG) $(srcdir)/stack-limit.c -o pic/$@; \
        else true; fi
@@ -1104,6 +1105,12 @@ $(CONFIGURED_OFILES): stamp-picdir
        else true; fi
        $(COMPILE.c) $(srcdir)/strndup.c $(OUTPUT_OPTION)
 
+./strnlen.$(objext): $(srcdir)/strnlen.c config.h
+       if [ x"$(PICFLAG)" != x ]; then \
+         $(COMPILE.c) $(PICFLAG) $(srcdir)/strnlen.c -o pic/$@; \
+       else true; fi
+       $(COMPILE.c) $(srcdir)/strnlen.c $(OUTPUT_OPTION)
+
 ./strrchr.$(objext): $(srcdir)/strrchr.c $(INCDIR)/ansidecl.h
        if [ x"$(PICFLAG)" != x ]; then \
          $(COMPILE.c) $(PICFLAG) $(srcdir)/strrchr.c -o pic/$@; \
index 17c4c2e4414a2fa1f58f0644316632f8372a43f6..1cf9c11b6ee7735bd0d7cac2fc07d9b513626d73 100644 (file)
 /* Define to 1 if you have the `strndup' function. */
 #undef HAVE_STRNDUP
 
+/* Define to 1 if you have the `strnlen' function. */
+#undef HAVE_STRNLEN
+
 /* Define to 1 if you have the `strrchr' function. */
 #undef HAVE_STRRCHR
 
index 6e98352f356ffdc22ecdba010b6378a1d307b659..536702742dd418b60431890a472681ef0bedf84d 100755 (executable)
@@ -5340,6 +5340,7 @@ funcs="$funcs strchr"
 funcs="$funcs strdup"
 funcs="$funcs strncasecmp"
 funcs="$funcs strndup"
+funcs="$funcs strnlen"
 funcs="$funcs strrchr"
 funcs="$funcs strstr"
 funcs="$funcs strtod"
@@ -5380,8 +5381,8 @@ if test "x" = "y"; then
     random realpath rename rindex \
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
-     strerror strncasecmp strndup strrchr strsignal strstr strtod strtol \
-     strtoul strverscmp sysconf sysctl sysmp \
+     strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
+     strtol strtoul strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid
@@ -5662,6 +5663,12 @@ esac
  ;;
 esac
 
+    case " $LIBOBJS " in
+  *" strnlen.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strnlen.$ac_objext"
+ ;;
+esac
+
     case " $LIBOBJS " in
   *" strverscmp.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS strverscmp.$ac_objext"
@@ -5683,7 +5690,7 @@ esac
 
     for f in $funcs; do
       case "$f" in
-       asprintf | basename | bcmp | bcopy | bzero | clock | ffs | getpagesize | index | insque | mempcpy | mkstemps | random | rindex | sigsetmask | stpcpy | stpncpy | strdup | strndup | strverscmp | vasprintf | waitpid)
+       asprintf | basename | bcmp | bcopy | bzero | clock | ffs | getpagesize | index | insque | mempcpy | mkstemps | random | rindex | sigsetmask | stpcpy | stpncpy | strdup | strndup | strnlen | strverscmp | vasprintf | waitpid)
          ;;
        *)
          n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
index 754b66a061930c9e86c4b974fd2db0c17c291a3a..c76389426447c6881c71d9f1e06b9700bcce0b87 100644 (file)
@@ -322,6 +322,7 @@ funcs="$funcs strchr"
 funcs="$funcs strdup"
 funcs="$funcs strncasecmp"
 funcs="$funcs strndup"
+funcs="$funcs strnlen"
 funcs="$funcs strrchr"
 funcs="$funcs strstr"
 funcs="$funcs strtod"
@@ -362,8 +363,8 @@ if test "x" = "y"; then
     random realpath rename rindex \
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
-     strerror strncasecmp strndup strrchr strsignal strstr strtod strtol \
-     strtoul strverscmp sysconf sysctl sysmp \
+     strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
+     strtol strtoul strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid)
@@ -442,13 +443,14 @@ if test -n "${with_target_subdir}"; then
     AC_LIBOBJ([stpcpy])
     AC_LIBOBJ([stpncpy])
     AC_LIBOBJ([strndup])
+    AC_LIBOBJ([strnlen])
     AC_LIBOBJ([strverscmp])
     AC_LIBOBJ([vasprintf])
     AC_LIBOBJ([waitpid])
 
     for f in $funcs; do
       case "$f" in
-       asprintf | basename | bcmp | bcopy | bzero | clock | ffs | getpagesize | index | insque | mempcpy | mkstemps | random | rindex | sigsetmask | stpcpy | stpncpy | strdup | strndup | strverscmp | vasprintf | waitpid)
+       asprintf | basename | bcmp | bcopy | bzero | clock | ffs | getpagesize | index | insque | mempcpy | mkstemps | random | rindex | sigsetmask | stpcpy | stpncpy | strdup | strndup | strnlen | strverscmp | vasprintf | waitpid)
          ;;
        *)
          n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
index 258aaa715504a293a677cc5d087b4929855a6bdf..32df38c6024b1fa499d06c305b9dd5954772231b 100644 (file)
@@ -696,6 +696,12 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_PACK_EXPANSION:
       printf ("pack expansion\n");
       break;
+    case DEMANGLE_COMPONENT_TLS_INIT:
+      printf ("tls init function\n");
+      break;
+    case DEMANGLE_COMPONENT_TLS_WRAPPER:
+      printf ("tls wrapper function\n");
+      break;
     }
 
   d_dump (d_left (dc), indent + 2);
@@ -832,6 +838,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_COVARIANT_THUNK:
     case DEMANGLE_COMPONENT_JAVA_CLASS:
     case DEMANGLE_COMPONENT_GUARD:
+    case DEMANGLE_COMPONENT_TLS_INIT:
+    case DEMANGLE_COMPONENT_TLS_WRAPPER:
     case DEMANGLE_COMPONENT_REFTEMP:
     case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
     case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
@@ -1867,6 +1875,14 @@ d_special_name (struct d_info *di)
          return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
                              cplus_demangle_type (di), NULL);
 
+       case 'H':
+         return d_make_comp (di, DEMANGLE_COMPONENT_TLS_INIT,
+                             d_name (di), NULL);
+
+       case 'W':
+         return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER,
+                             d_name (di), NULL);
+
        default:
          return NULL;
        }
@@ -4072,6 +4088,16 @@ d_print_comp (struct d_print_info *dpi, int options,
       d_print_comp (dpi, options, d_left (dc));
       return;
 
+    case DEMANGLE_COMPONENT_TLS_INIT:
+      d_append_string (dpi, "TLS init function for ");
+      d_print_comp (dpi, options, d_left (dc));
+      return;
+
+    case DEMANGLE_COMPONENT_TLS_WRAPPER:
+      d_append_string (dpi, "TLS wrapper function for ");
+      d_print_comp (dpi, options, d_left (dc));
+      return;
+
     case DEMANGLE_COMPONENT_REFTEMP:
       d_append_string (dpi, "reference temporary #");
       d_print_comp (dpi, options, d_right (dc));
index c9df186be0f87df701ea02893e1f06d3801aa3d2..9323ff9f2e4f3098081d066b9105ed86ae8ca217 100644 (file)
@@ -84,7 +84,7 @@ is respectively less than, matching, or greater than the array member.
 
 @end deftypefn
 
-@c argv.c:142
+@c argv.c:135
 @deftypefn Extension char** buildargv (char *@var{sp})
 
 Given a pointer to a string, parse the string extracting fields
@@ -95,7 +95,7 @@ remains unchanged.  The last element of the vector is followed by a
 @code{NULL} element.
 
 All of the memory for the pointer array and copies of the string
-is obtained from @code{malloc}.  All of the memory can be returned to the
+is obtained from @code{xmalloc}.  All of the memory can be returned to the
 system with the single function call @code{freeargv}, which takes the
 returned result of @code{buildargv}, as it's argument.
 
@@ -166,6 +166,14 @@ pointer encountered.  Pointers to empty strings are ignored.
 
 @end deftypefn
 
+@c argv.c:470
+@deftypefn Extension int countargv (char **@var{argv})
+
+Return the number of elements in @var{argv}.
+Returns zero if @var{argv} is NULL.
+
+@end deftypefn
+
 @c crc32.c:141
 @deftypefn Extension {unsigned int} crc32 (const unsigned char *@var{buf}, @
   int @var{len}, unsigned int @var{init})
@@ -224,7 +232,7 @@ symbolic name or message.
 
 @end deftypefn
 
-@c argv.c:361
+@c argv.c:341
 @deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
 
 The @var{argcp} and @code{argvp} arguments are pointers to the usual
@@ -296,7 +304,24 @@ and backward slashes are equal.
 
 @end deftypefn
 
-@c filename_cmp.c:81
+@c filename_cmp.c:178
+@deftypefn Extension int filename_eq (const void *@var{s1}, const void *@var{s2})
+
+Return non-zero if file names @var{s1} and @var{s2} are equivalent.
+This function is for use with hashtab.c hash tables.
+
+@end deftypefn
+
+@c filename_cmp.c:147
+@deftypefn Extension hashval_t filename_hash (const void *@var{s})
+
+Return the hash value for file name @var{s} that will be compared
+using filename_cmp.
+This function is for use with hashtab.c hash tables.
+
+@end deftypefn
+
+@c filename_cmp.c:89
 @deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
 
 Return zero if the two file names @var{s1} and @var{s2} are equivalent
@@ -376,7 +401,7 @@ unchanged.
 
 @end deftypefn
 
-@c argv.c:97
+@c argv.c:90
 @deftypefn Extension void freeargv (char **@var{vector})
 
 Free an argument vector that was built using @code{buildargv}.  Simply
@@ -1465,6 +1490,13 @@ deallocate values.
 
 @end deftypefn
 
+@c stack-limit.c:28
+@deftypefn Extension void stack_limit_increase (unsigned long @var{pref})
+
+Attempt to increase stack size limit to @var{pref} bytes if possible.
+
+@end deftypefn
+
 @c stpcpy.c:23
 @deftypefn Supplemental char* stpcpy (char *@var{dst}, const char *@var{src})
 
@@ -1574,6 +1606,16 @@ memory was available.  The result is always NUL terminated.
 
 @end deftypefn
 
+@c strnlen.c:6
+@deftypefn Supplemental size_t strnlen (const char *@var{s}, size_t @var{maxlen})
+
+Returns the length of @var{s}, as with @code{strlen}, but never looks
+past the first @var{maxlen} characters in the string.  If there is no
+'\0' character in the first @var{maxlen} characters, returns
+@var{maxlen}.
+
+@end deftypefn
+
 @c strrchr.c:6
 @deftypefn Supplemental char* strrchr (const char *@var{s}, int @var{c})
 
@@ -1728,6 +1770,22 @@ This function is especially useful when dealing with filename sorting,
 because filenames frequently hold indices/version numbers.
 @end deftypefun
 
+@c timeval-utils.c:43
+@deftypefn Extension void timeval_add (struct timeval *@var{a}, @
+  struct timeval *@var{b}, struct timeval *@var{result})
+
+Adds @var{a} to @var{b} and stores the result in @var{result}.
+
+@end deftypefn
+
+@c timeval-utils.c:67
+@deftypefn Extension void timeval_sub (struct timeval *@var{a}, @
+  struct timeval *@var{b}, struct timeval *@var{result})
+
+Subtracts @var{b} from @var{a} and stores the result in @var{result}.
+
+@end deftypefn
+
 @c tmpnam.c:3
 @deftypefn Supplemental char* tmpnam (char *@var{s})
 
@@ -1829,7 +1887,7 @@ does the return value.  The third argument is unused in @libib{}.
 
 @end deftypefn
 
-@c argv.c:306
+@c argv.c:286
 @deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file})
 
 Write each member of ARGV, handling all necessary quoting, to the file
index 36b92034f33c2c9e055094e4686e0952678e3ad6..d50f8959a388f70efe2c3653cf508808e8886a85 100644 (file)
@@ -222,7 +222,7 @@ sub deps {
 
     opendir(INC, $incdir);
     while ($f = readdir INC) {
-       next unless $f =~ /\.h$/;
+       next unless $f =~ /\.h$/ || $f =~ /\.def$/;
        $mine{$f} = "\$(INCDIR)/$f";
        $deps{$f} = join(' ', &deps_for("$incdir/$f"));
     }
index 3ddac2ce4cbfbda496aa320d4578203391d7956f..72e92d2ddce986820c9f8adaf1678ee75d588ac0 100644 (file)
@@ -1,5 +1,5 @@
 /* objalloc.c -- routines to allocate memory for objects
-   Copyright 1997 Free Software Foundation, Inc.
+   Copyright 1997-2012 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Solutions.
 
 This program is free software; you can redistribute it and/or modify it
@@ -112,8 +112,10 @@ objalloc_create (void)
 /* Allocate space from an objalloc structure.  */
 
 PTR
-_objalloc_alloc (struct objalloc *o, unsigned long len)
+_objalloc_alloc (struct objalloc *o, unsigned long original_len)
 {
+  unsigned long len = original_len;
+
   /* We avoid confusion from zero sized objects by always allocating
      at least 1 byte.  */
   if (len == 0)
@@ -121,6 +123,11 @@ _objalloc_alloc (struct objalloc *o, unsigned long len)
 
   len = (len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);
 
+  /* Check for overflow in the alignment operation above and the
+     malloc argument below. */
+  if (len + CHUNK_HEADER_SIZE < original_len)
+    return NULL;
+
   if (len <= o->current_space)
     {
       o->current_ptr += len;
diff --git a/libiberty/strnlen.c b/libiberty/strnlen.c
new file mode 100644 (file)
index 0000000..4934973
--- /dev/null
@@ -0,0 +1,30 @@
+/* Portable version of strnlen.
+   This function is in the public domain.  */
+
+/*
+
+@deftypefn Supplemental size_t strnlen (const char *@var{s}, size_t @var{maxlen})
+
+Returns the length of @var{s}, as with @code{strlen}, but never looks
+past the first @var{maxlen} characters in the string.  If there is no
+'\0' character in the first @var{maxlen} characters, returns
+@var{maxlen}.
+
+@end deftypefn
+
+*/
+
+#include "config.h"
+
+#include <stddef.h>
+
+size_t
+strnlen (const char *s, size_t maxlen)
+{
+  size_t i;
+
+  for (i = 0; i < maxlen; ++i)
+    if (s[i] == '\0')
+      break;
+  return i;
+}