xref: /netbsd-src/external/gpl2/gettext/dist/gettext-tools/gnulib-lib/stpncpy.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2006 Free Software Foundation, Inc.
2 
3    NOTE: The canonical source of this file is maintained with the GNU C Library.
4    Bugs can be reported to bug-glibc@gnu.org.
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19 
20 /* This is almost copied from strncpy.c, written by Torbjorn Granlund.  */
21 
22 #include <config.h>
23 
24 /* Specification.  */
25 #include "stpncpy.h"
26 
27 #ifndef weak_alias
28 # define __stpncpy stpncpy
29 #endif
30 
31 /* Copy no more than N bytes of SRC to DST, returning a pointer past the
32    last non-NUL byte written into DST.  */
33 char *
34 __stpncpy (char *dest, const char *src, size_t n)
35 {
36   char c;
37   char *s = dest;
38 
39   if (n >= 4)
40     {
41       size_t n4 = n >> 2;
42 
43       for (;;)
44 	{
45 	  c = *src++;
46 	  *dest++ = c;
47 	  if (c == '\0')
48 	    break;
49 	  c = *src++;
50 	  *dest++ = c;
51 	  if (c == '\0')
52 	    break;
53 	  c = *src++;
54 	  *dest++ = c;
55 	  if (c == '\0')
56 	    break;
57 	  c = *src++;
58 	  *dest++ = c;
59 	  if (c == '\0')
60 	    break;
61 	  if (--n4 == 0)
62 	    goto last_chars;
63 	}
64       n -= dest - s;
65       goto zero_fill;
66     }
67 
68  last_chars:
69   n &= 3;
70   if (n == 0)
71     return dest;
72 
73   for (;;)
74     {
75       c = *src++;
76       --n;
77       *dest++ = c;
78       if (c == '\0')
79 	break;
80       if (n == 0)
81 	return dest;
82     }
83 
84  zero_fill:
85   while (n-- > 0)
86     dest[n] = '\0';
87 
88   return dest - 1;
89 }
90 #ifdef weak_alias
91 weak_alias (__stpncpy, stpncpy)
92 #endif
93