summary refs log tree commit diff
path: root/manual/string.texi
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-08-09 02:46:09 +0000
committerUlrich Drepper <drepper@redhat.com>1996-08-09 02:46:09 +0000
commita5113b141cd85a98b4711607c430e6e01775bd9a (patch)
tree5e345c0560b177c68320fa8a467215352996bb35 /manual/string.texi
parent233963756b2ef272f8876afec2a2bb629b425e0c (diff)
downloadglibc-a5113b141cd85a98b4711607c430e6e01775bd9a.tar.gz
glibc-a5113b141cd85a98b4711607c430e6e01775bd9a.tar.xz
glibc-a5113b141cd85a98b4711607c430e6e01775bd9a.zip
Thu Aug  8 16:17:38 1996  Ulrich Drepper  <drepper@cygnus.com>

	* pwd/getpwent.c: Define BUFLEN from NSS_BUFLEN_PASSWD.
	* pwd/getpwent_r.c: Likewise.
	* pwd/getpwnam.c: Likewise.
	* pwd/getpwnam_r.c: Likewise.
	* pwd/getpwuid.c: Likewise.
	* pwd/getpwuid_r.c: Likewise.

	* grp/getgrent.c: Define BUFLEN from NSS_BUFLEN_GROUP.
	* grp/getgrent_r.c: Likewise.
	* grp/getgrgid.c: Likewise.
	* grp/getgrgid_r.c: Likewise.
	* grp/getgrnam.c: Likewise.

	* pwd/fgetpwent_r.c: New file.  Reentrant version of fgetpwent.
	* pwd/fgetpwent.c: Rewrite to use fgetpwent_r.
	* pwd/Makefile (routines): Add fgetpwent_r.
	* pwd/pwd.h: Add prototypes for __fgetpwent_r and fgetpwent_r.

	* grp/fgetgrent_r.c: New file.  Reentrant version of fgetgrent.
	* grp/fgetgrent.c: Rewrite to use fgetgrent_r.
	* grp/Makefile (routines): Add fgetgrent_r.
	* grp/grp.h: Add prototypes for __fgetgrent_r and fgetgrent_r.

	Implement shadow password lookup functions.  This is no complete
	shadow password suite.
	* shadow/Makefile: New file.
	* shadow/fgetspent.c: New file.
	* shadow/fgetspent_r.c: New file.
	* shadow/getspent.c: New file.
	* shadow/getspent_r.c: New file.
	* shadow/getspnam.c: New file.
	* shadow/getspnam_r.c: New file.
	* shadow/putspent.c: New file.
	* shadow/sgetspent.c: New file.
	* shadow/sgetspent_r.c: New file.
	* shadow/shadow.h: New file.
	* shadow/spwd-lookup.c: New file.
	* shadow/nss_files/files-spwd.c: New file.

Thu Aug  8 13:33:45 1996  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/ftime.c: New file.  Available system
 	call is only a stub.
	Reported by Matthias Urlichs.

	* Makeconfig [!default_cflags]: Change default value from `-g'
	to `-g -O'.

	* configure.in: Recognize i686.
	* sysdeps/i386/i686/Implies: Default on i586 optimized code.

Thu Aug  8 12:40:20 1996  Matthias Urlichs  <smurf@smurf.noris.de>

	* Makeconfig [$(build-omitfp) == yes]: Add to CFLAGS-.so
	value of CFLAGS-.o, not CFLAGS-o.

	* sysdeps/unix/sysv/linux/init-first.c (init): Add volatile
	pointer to ourself.  Otherwise `gcc -O3' optimized init away.

	sure that all tables in binary file are word-aligned.
Diffstat (limited to 'manual/string.texi')
-rw-r--r--manual/string.texi109
1 files changed, 87 insertions, 22 deletions
diff --git a/manual/string.texi b/manual/string.texi
index c638912229..8b7e9da96b 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -6,7 +6,7 @@ many programs.  The GNU C library provides an extensive set of string
 utility functions, including functions for copying, concatenating,
 comparing, and searching strings.  Many of these functions can also
 operate on arbitrary regions of storage; for example, the @code{memcpy}
-function can be used to copy the contents of any kind of array.  
+function can be used to copy the contents of any kind of array.
 
 It's fairly common for beginning C programmers to ``reinvent the wheel''
 by duplicating this functionality in their own code, but it pays to
@@ -158,7 +158,7 @@ get the allocation size of the character array that holds a string using
 the @code{sizeof} operator:
 
 @smallexample
-char string[32] = "hello, world"; 
+char string[32] = "hello, world";
 sizeof (string)
     @result{} 32
 strlen (string)
@@ -411,7 +411,7 @@ return a nonzero value if the strings are @emph{not} equivalent rather
 than if they are.  The sign of the value indicates the relative ordering
 of the first characters in the strings that are not equivalent:  a
 negative value indicates that the first string is ``less'' than the
-second, while a positive value indicates that the first string is 
+second, while a positive value indicates that the first string is
 ``greater''.
 
 The most common use of these functions is to check only for equality.
@@ -623,10 +623,10 @@ overlap; see @ref{Copying and Concatenation}.
 
 The return value is the length of the entire transformed string.  This
 value is not affected by the value of @var{size}, but if it is greater
-than @var{size}, it means that the transformed string did not entirely
-fit in the array @var{to}.  In this case, only as much of the string as
-actually fits was stored.  To get the whole transformed string, call
-@code{strxfrm} again with a bigger output array.
+or equal than @var{size}, it means that the transformed string did not
+entirely fit in the array @var{to}.  In this case, only as much of the
+string as actually fits was stored.  To get the whole transformed
+string, call @code{strxfrm} again with a bigger output array.
 
 The transformed string may be longer than the original string, and it
 may also be shorter.
@@ -671,23 +671,32 @@ sort_strings_fast (char **array, int nstrings)
   for (i = 0; i < nstrings; i++)
     @{
       size_t length = strlen (array[i]) * 2;
+      char *transformed;
+      size_t transformed_lenght;
 
       temp_array[i].input = array[i];
 
-      /* @r{Transform @code{array[i]}.}
-         @r{First try a buffer probably big enough.} */
-      while (1)
+      /* @r{First try a buffer perhaps big enough.}  */
+      transformed = (char *) xmalloc (length);
+
+      /* @r{Transform @code{array[i]}.}  */
+      transformed_length = strxfrm (transformed, array[i], length);
+
+      /* @r{If the buffer was not large enough, resize it}
+         @r{and try again.}  */
+      if (transformed_length >= length)
         @{
-          char *transformed = (char *) xmalloc (length);
-          if (strxfrm (transformed, array[i], length) < length)
-            @{
-              temp_array[i].transformed = transformed;
-              break;
-            @}
-          /* @r{Try again with a bigger buffer.} */
-          free (transformed);
-          length *= 2;
+          /* @r{Allocate the needed space. +1 for terminating}
+             @r{@code{NUL} character.}  */
+          transformed = (char *) xrealloc (transformed,
+                                           transformed_length + 1);
+
+          /* @r{The return value is not interesting because we know}
+             @r{how long the transformed string is.}  */
+          (void) strxfrm (transformed, array[i], transformed_length + 1);
         @}
+
+      temp_array[i].transformed = transformed;
     @}
 
   /* @r{Sort @code{temp_array} by comparing transformed strings.} */
@@ -741,7 +750,7 @@ strchr ("hello, world", 'l')
     @result{} "llo, world"
 strchr ("hello, world", '?')
     @result{} NULL
-@end smallexample    
+@end smallexample
 
 The terminating null character is considered to be part of the string,
 so you can use this function get a pointer to the end of a string by
@@ -857,8 +866,6 @@ strpbrk ("hello, world", " \t\n,.;!?")
 @node Finding Tokens in a String,  , Search Functions, String and Array Utilities
 @section Finding Tokens in a String
 
-@c !!! Document strsep, which is a better thing to use than strtok.
-
 @cindex tokenizing strings
 @cindex breaking a string into tokens
 @cindex parsing tokens from a string
@@ -945,3 +952,61 @@ token = strtok (NULL, delimiters);    /* token => "and" */
 token = strtok (NULL, delimiters);    /* token => "punctuation" */
 token = strtok (NULL, delimiters);    /* token => NULL */
 @end smallexample
+
+The GNU C library contains two more functions for tokenizing a string
+which overcome the limitation of non-reentrancy.
+
+@comment string.h
+@comment POSIX
+@deftypefun {char *} strtok_r (char *@var{newstring}, const char *@var{delimiters}, char **@var{save_ptr})
+Just like @code{strtok} this function splits the string into several
+tokens which can be accessed be successive calls to @code{strtok_r}.
+The difference is that the information about the next token is not set
+up in some internal state information.  Instead the caller has to
+provide another argument @var{save_ptr} which is a pointer to a string
+pointer.  Calling @code{strtok_r} with a null pointer for
+@var{newstring} and leaving @var{save_ptr} between the calls unchanged
+does the job without limiting reentrancy.
+
+This function was proposed for POSIX.1b and can be found on many systems
+which support multi-threading.
+@end deftypefun
+
+@comment string.h
+@comment BSD
+@deftypefun {char *} strsep (char **@var{string_ptr}, const char *@var{delimiter})
+A second reentrant approach is to avoid the additional first argument.
+The initialization of the moving pointer has to be done by the user.
+Successive calls of @code{strsep} move the pointer along the tokens
+separated by @var{delimiter}, returning the address of the next token
+and updating @var{string_ptr} to point to the beginning of the next
+token.
+
+This function was introduced in 4.3BSD and therefore is widely available.
+@end deftypefun
+
+Here is how the above example looks like when @code{strsep} is used.
+
+@comment Yes, this example has been tested.
+@smallexample
+#include <string.h>
+#include <stddef.h>
+
+@dots{}
+
+char string[] = "words separated by spaces -- and, punctuation!";
+const char delimiters[] = " .,;:!-";
+char *running;
+char *token;
+
+@dots{}
+
+running = string;
+token = strsep (&running, delimiters);    /* token => "words" */
+token = strsep (&running, delimiters);    /* token => "separated" */
+token = strsep (&running, delimiters);    /* token => "by" */
+token = strsep (&running, delimiters);    /* token => "spaces" */
+token = strsep (&running, delimiters);    /* token => "and" */
+token = strsep (&running, delimiters);    /* token => "punctuation" */
+token = strsep (&running, delimiters);    /* token => NULL */
+@end smallexample