Subversion Repositories Kolibri OS

Rev

Rev 4874 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4874 Rev 4921
1
/*
1
/*
2
FUNCTION
2
FUNCTION
3
	<>---concatenate strings
3
	<>---concatenate strings
4
 
4
 
5
INDEX
5
INDEX
6
	strncat
6
	strncat
7
 
7
 
8
ANSI_SYNOPSIS
8
ANSI_SYNOPSIS
9
	#include 
9
	#include 
10
	char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>);
10
	char *strncat(char *restrict <[dst]>, const char *restrict <[src]>,
-
 
11
                      size_t <[length]>);
11
 
12
 
12
TRAD_SYNOPSIS
13
TRAD_SYNOPSIS
13
	#include 
14
	#include 
14
	char *strncat(<[dst]>, <[src]>, <[length]>)
15
	char *strncat(<[dst]>, <[src]>, <[length]>)
15
	char *<[dst]>;
16
	char *<[dst]>;
16
	char *<[src]>;
17
	char *<[src]>;
17
	size_t <[length]>;
18
	size_t <[length]>;
18
 
19
 
19
DESCRIPTION
20
DESCRIPTION
20
	<> appends not more than <[length]> characters from
21
	<> appends not more than <[length]> characters from
21
	the string pointed to by <[src]> (including the	terminating
22
	the string pointed to by <[src]> (including the	terminating
22
	null character) to the end of the string pointed to by
23
	null character) to the end of the string pointed to by
23
	<[dst]>.  The initial character of <[src]> overwrites the null
24
	<[dst]>.  The initial character of <[src]> overwrites the null
24
	character at the end of <[dst]>.  A terminating null character
25
	character at the end of <[dst]>.  A terminating null character
25
	is always appended to the result
26
	is always appended to the result
26
 
27
 
27
WARNINGS
28
WARNINGS
28
	Note that a null is always appended, so that if the copy is
29
	Note that a null is always appended, so that if the copy is
29
	limited by the <[length]> argument, the number of characters
30
	limited by the <[length]> argument, the number of characters
30
	appended to <[dst]> is <>.
31
	appended to <[dst]> is <>.
31
 
32
 
32
RETURNS
33
RETURNS
33
	This function returns the initial value of <[dst]>
34
	This function returns the initial value of <[dst]>
34
 
35
 
35
PORTABILITY
36
PORTABILITY
36
<> is ANSI C.
37
<> is ANSI C.
37
 
38
 
38
<> requires no supporting OS subroutines.
39
<> requires no supporting OS subroutines.
39
 
40
 
40
QUICKREF
41
QUICKREF
41
	strncat ansi pure
42
	strncat ansi pure
42
*/
43
*/
43
 
44
 
44
#include 
45
#include 
45
#include 
46
#include 
46
 
47
 
47
/* Nonzero if X is aligned on a "long" boundary.  */
48
/* Nonzero if X is aligned on a "long" boundary.  */
48
#define ALIGNED(X) \
49
#define ALIGNED(X) \
49
  (((long)X & (sizeof (long) - 1)) == 0)
50
  (((long)X & (sizeof (long) - 1)) == 0)
50
 
51
 
51
#if LONG_MAX == 2147483647L
52
#if LONG_MAX == 2147483647L
52
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
53
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
53
#else
54
#else
54
#if LONG_MAX == 9223372036854775807L
55
#if LONG_MAX == 9223372036854775807L
55
/* Nonzero if X (a long int) contains a NULL byte. */
56
/* Nonzero if X (a long int) contains a NULL byte. */
56
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
57
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
57
#else
58
#else
58
#error long int is not a 32bit or 64bit type.
59
#error long int is not a 32bit or 64bit type.
59
#endif
60
#endif
60
#endif
61
#endif
61
 
62
 
62
#ifndef DETECTNULL
63
#ifndef DETECTNULL
63
#error long int is not a 32bit or 64bit byte
64
#error long int is not a 32bit or 64bit byte
64
#endif
65
#endif
65
 
66
 
66
char *
67
char *
67
_DEFUN (strncat, (s1, s2, n),
68
_DEFUN (strncat, (s1, s2, n),
68
	char *s1 _AND
69
	char *__restrict s1 _AND
69
	_CONST char *s2 _AND
70
	_CONST char *__restrict s2 _AND
70
	size_t n)
71
	size_t n)
71
{
72
{
72
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
73
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
73
  char *s = s1;
74
  char *s = s1;
74
 
75
 
75
  while (*s1)
76
  while (*s1)
76
    s1++;
77
    s1++;
77
  while (n-- != 0 && (*s1++ = *s2++))
78
  while (n-- != 0 && (*s1++ = *s2++))
78
    {
79
    {
79
      if (n == 0)
80
      if (n == 0)
80
	*s1 = '\0';
81
	*s1 = '\0';
81
    }
82
    }
82
 
83
 
83
  return s;
84
  return s;
84
#else
85
#else
85
  char *s = s1;
86
  char *s = s1;
86
 
87
 
87
  /* Skip over the data in s1 as quickly as possible.  */
88
  /* Skip over the data in s1 as quickly as possible.  */
88
  if (ALIGNED (s1))
89
  if (ALIGNED (s1))
89
    {
90
    {
90
      unsigned long *aligned_s1 = (unsigned long *)s1;
91
      unsigned long *aligned_s1 = (unsigned long *)s1;
91
      while (!DETECTNULL (*aligned_s1))
92
      while (!DETECTNULL (*aligned_s1))
92
	aligned_s1++;
93
	aligned_s1++;
93
 
94
 
94
      s1 = (char *)aligned_s1;
95
      s1 = (char *)aligned_s1;
95
    }
96
    }
96
 
97
 
97
  while (*s1)
98
  while (*s1)
98
    s1++;
99
    s1++;
99
 
100
 
100
  /* s1 now points to the its trailing null character, now copy
101
  /* s1 now points to the its trailing null character, now copy
101
     up to N bytes from S2 into S1 stopping if a NULL is encountered
102
     up to N bytes from S2 into S1 stopping if a NULL is encountered
102
     in S2.
103
     in S2.
103
 
104
 
104
     It is not safe to use strncpy here since it copies EXACTLY N
105
     It is not safe to use strncpy here since it copies EXACTLY N
105
     characters, NULL padding if necessary.  */
106
     characters, NULL padding if necessary.  */
106
  while (n-- != 0 && (*s1++ = *s2++))
107
  while (n-- != 0 && (*s1++ = *s2++))
107
    {
108
    {
108
      if (n == 0)
109
      if (n == 0)
109
	*s1 = '\0';
110
	*s1 = '\0';
110
    }
111
    }
111
	
112
	
112
  return s;
113
  return s;
113
#endif /* not PREFER_SIZE_OVER_SPEED */
114
#endif /* not PREFER_SIZE_OVER_SPEED */
114
}
115
}