Subversion Repositories Kolibri OS

Rev

Rev 4874 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
FUNCTION
3
	<>---counted copy string returning a pointer to its end
4
 
5
INDEX
6
	stpncpy
7
 
8
ANSI_SYNOPSIS
9
	#include 
4921 Serge 10
	char *stpncpy(char *restrict <[dst]>, const char *restrict <[src]>,
11
                      size_t <[length]>);
4349 Serge 12
 
13
TRAD_SYNOPSIS
14
	#include 
15
	char *stpncpy(<[dst]>, <[src]>, <[length]>)
16
	char *<[dst]>;
17
	char *<[src]>;
18
	size_t <[length]>;
19
 
20
DESCRIPTION
21
	<> copies not more than <[length]> characters from the
22
	the string pointed to by <[src]> (including the terminating
23
	null character) to the array pointed to by <[dst]>.  If the
24
	string pointed to by <[src]> is shorter than <[length]>
25
	characters, null characters are appended to the destination
26
	array until a total of <[length]> characters have been
27
	written.
28
 
29
RETURNS
30
	This function returns a pointer to the end of the destination string,
31
	thus pointing to the trailing '\0', or, if the destination string is
32
	not null-terminated, pointing to dst + n.
33
 
34
PORTABILITY
35
<> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
36
 
37
<> requires no supporting OS subroutines.
38
 
39
QUICKREF
40
	stpncpy gnu
41
*/
42
 
43
#include 
44
#include 
45
 
46
/*SUPPRESS 560*/
47
/*SUPPRESS 530*/
48
 
49
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
50
#define UNALIGNED(X, Y) \
51
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
52
 
53
#if LONG_MAX == 2147483647L
54
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
55
#else
56
#if LONG_MAX == 9223372036854775807L
57
/* Nonzero if X (a long int) contains a NULL byte. */
58
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
59
#else
60
#error long int is not a 32bit or 64bit type.
61
#endif
62
#endif
63
 
64
#ifndef DETECTNULL
65
#error long int is not a 32bit or 64bit byte
66
#endif
67
 
68
#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
69
 
70
char *
71
_DEFUN (stpncpy, (dst, src),
4921 Serge 72
	char *__restrict dst _AND
73
	_CONST char *__restrict src _AND
4349 Serge 74
	size_t count)
75
{
76
  char *ret = NULL;
77
 
78
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
79
  long *aligned_dst;
80
  _CONST long *aligned_src;
81
 
82
  /* If SRC and DEST is aligned and count large enough, then copy words.  */
83
  if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
84
    {
85
      aligned_dst = (long*)dst;
86
      aligned_src = (long*)src;
87
 
88
      /* SRC and DEST are both "long int" aligned, try to do "long int"
89
	 sized copies.  */
90
      while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
91
	{
92
	  count -= sizeof (long int);
93
	  *aligned_dst++ = *aligned_src++;
94
	}
95
 
96
      dst = (char*)aligned_dst;
97
      src = (char*)aligned_src;
98
    }
99
#endif /* not PREFER_SIZE_OVER_SPEED */
100
 
101
  while (count > 0)
102
    {
103
      --count;
104
      if ((*dst++ = *src++) == '\0')
105
	{
106
	  ret = dst - 1;
107
	  break;
108
	}
109
    }
110
 
111
  while (count-- > 0)
112
    *dst++ = '\0';
113
 
114
  return ret ? ret : dst;
115
}