Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4921 Serge 1
/*
2
FUNCTION
3
	<>---counted copy string
4
 
5
INDEX
6
	strncpy
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	char *strncpy(char *restrict <[dst]>, const char *restrict <[src]>,
11
                      size_t <[length]>);
12
 
13
TRAD_SYNOPSIS
14
	#include 
15
	char *strncpy(<[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 the initial value of <[dst]>.
31
 
32
PORTABILITY
33
<> is ANSI C.
34
 
35
<> requires no supporting OS subroutines.
36
 
37
QUICKREF
38
	strncpy ansi pure
39
*/
40
 
41
#include 
42
#include 
43
 
44
/*SUPPRESS 560*/
45
/*SUPPRESS 530*/
46
 
47
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
48
#define UNALIGNED(X, Y) \
49
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
50
 
51
#if LONG_MAX == 2147483647L
52
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
53
#else
54
#if LONG_MAX == 9223372036854775807L
55
/* Nonzero if X (a long int) contains a NULL byte. */
56
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
57
#else
58
#error long int is not a 32bit or 64bit type.
59
#endif
60
#endif
61
 
62
#ifndef DETECTNULL
63
#error long int is not a 32bit or 64bit byte
64
#endif
65
 
66
#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
67
 
68
char *
69
_DEFUN (strncpy, (dst0, src0),
70
	char *__restrict dst0 _AND
71
	_CONST char *__restrict src0 _AND
72
	size_t count)
73
{
74
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
75
  char *dscan;
76
  _CONST char *sscan;
77
 
78
  dscan = dst0;
79
  sscan = src0;
80
  while (count > 0)
81
    {
82
      --count;
83
      if ((*dscan++ = *sscan++) == '\0')
84
	break;
85
    }
86
  while (count-- > 0)
87
    *dscan++ = '\0';
88
 
89
  return dst0;
90
#else
91
  char *dst = dst0;
92
  _CONST char *src = src0;
93
  long *aligned_dst;
94
  _CONST long *aligned_src;
95
 
96
  /* If SRC and DEST is aligned and count large enough, then copy words.  */
97
  if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
98
    {
99
      aligned_dst = (long*)dst;
100
      aligned_src = (long*)src;
101
 
102
      /* SRC and DEST are both "long int" aligned, try to do "long int"
103
	 sized copies.  */
104
      while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
105
	{
106
	  count -= sizeof (long int);
107
	  *aligned_dst++ = *aligned_src++;
108
	}
109
 
110
      dst = (char*)aligned_dst;
111
      src = (char*)aligned_src;
112
    }
113
 
114
  while (count > 0)
115
    {
116
      --count;
117
      if ((*dst++ = *src++) == '\0')
118
	break;
119
    }
120
 
121
  while (count-- > 0)
122
    *dst++ = '\0';
123
 
124
  return dst0;
125
#endif /* not PREFER_SIZE_OVER_SPEED */
126
}