OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [string/] [strncat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.