]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - reference/newlib-c/strcpy.c
Import the Linaro Cortex Strings library from
[FreeBSD/FreeBSD.git] / reference / newlib-c / strcpy.c
1 /*
2 FUNCTION
3         <<strcpy>>---copy string
4
5 INDEX
6         strcpy
7
8 ANSI_SYNOPSIS
9         #include <string.h>
10         char *strcpy(char *<[dst]>, const char *<[src]>);
11
12 TRAD_SYNOPSIS
13         #include <string.h>
14         char *strcpy(<[dst]>, <[src]>)
15         char *<[dst]>;
16         char *<[src]>;
17
18 DESCRIPTION
19         <<strcpy>> copies the string pointed to by <[src]>
20         (including the terminating null character) to the array
21         pointed to by <[dst]>.
22
23 RETURNS
24         This function returns the initial value of <[dst]>.
25
26 PORTABILITY
27 <<strcpy>> is ANSI C.
28
29 <<strcpy>> requires no supporting OS subroutines.
30
31 QUICKREF
32         strcpy ansi pure
33 */
34
35 #include "shim.h"
36 #include <string.h>
37 #include <limits.h>
38
39 /*SUPPRESS 560*/
40 /*SUPPRESS 530*/
41
42 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
43 #define UNALIGNED(X, Y) \
44   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
46 #if LONG_MAX == 2147483647L
47 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
48 #else
49 #if LONG_MAX == 9223372036854775807L
50 /* Nonzero if X (a long int) contains a NULL byte. */
51 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
52 #else
53 #error long int is not a 32bit or 64bit type.
54 #endif
55 #endif
56
57 #ifndef DETECTNULL
58 #error long int is not a 32bit or 64bit byte
59 #endif
60
61 char*
62 _DEFUN (strcpy, (dst0, src0),
63         char *dst0 _AND
64         _CONST char *src0)
65 {
66 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
67   char *s = dst0;
68
69   while (*dst0++ = *src0++)
70     ;
71
72   return s;
73 #else
74   char *dst = dst0;
75   _CONST char *src = src0;
76   long *aligned_dst;
77   _CONST long *aligned_src;
78
79   /* If SRC or DEST is unaligned, then copy bytes.  */
80   if (!UNALIGNED (src, dst))
81     {
82       aligned_dst = (long*)dst;
83       aligned_src = (long*)src;
84
85       /* SRC and DEST are both "long int" aligned, try to do "long int"
86          sized copies.  */
87       while (!DETECTNULL(*aligned_src))
88         {
89           *aligned_dst++ = *aligned_src++;
90         }
91
92       dst = (char*)aligned_dst;
93       src = (char*)aligned_src;
94     }
95
96   while ((*dst++ = *src++))
97     ;
98   return dst0;
99 #endif /* not PREFER_SIZE_OVER_SPEED */
100 }