]>
Commit | Line | Data |
---|---|---|
553cc5f9 | 1 | /* Copyright (C) 2004, 2005 Free Software Foundation, Inc. |
b5cc329c UD |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
15 | License along with the GNU C Library; if not, write to the Free | |
16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
17 | 02111-1307 USA. */ | |
18 | ||
19 | #ifndef _STRING_H | |
20 | # error "Never use <bits/string3.h> directly; include <string.h> instead." | |
21 | #endif | |
22 | ||
23 | /* XXX This is temporarily. We should not redefine any of the symbols | |
24 | and instead integrate the error checking into the original | |
25 | definitions. */ | |
26 | #undef memcpy | |
27 | #undef memmove | |
28 | #undef memset | |
29 | #undef strcat | |
30 | #undef strcpy | |
31 | #undef strncat | |
32 | #undef strncpy | |
33 | #ifdef __USE_GNU | |
34 | # undef mempcpy | |
35 | # undef stpcpy | |
36 | #endif | |
37 | #ifdef __USE_BSD | |
38 | # undef bcopy | |
39 | # undef bzero | |
40 | #endif | |
41 | ||
42 | ||
43 | #define memcpy(dest, src, len) \ | |
44 | ((__bos0 (dest) != (size_t) -1) \ | |
45 | ? __builtin___memcpy_chk (dest, src, len, __bos0 (dest)) \ | |
46 | : __memcpy_ichk (dest, src, len)) | |
88764ae2 | 47 | static __always_inline void * |
a334319f UD |
48 | __memcpy_ichk (void *__restrict __dest, const void *__restrict __src, |
49 | size_t __len) | |
b5cc329c UD |
50 | { |
51 | return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); | |
52 | } | |
53 | ||
54 | ||
55 | #define memmove(dest, src, len) \ | |
56 | ((__bos0 (dest) != (size_t) -1) \ | |
57 | ? __builtin___memmove_chk (dest, src, len, __bos0 (dest)) \ | |
58 | : __memmove_ichk (dest, src, len)) | |
88764ae2 | 59 | static __always_inline void * |
a334319f | 60 | __memmove_ichk (void *__dest, const void *__src, size_t __len) |
b5cc329c UD |
61 | { |
62 | return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); | |
63 | } | |
64 | ||
65 | ||
66 | #ifdef __USE_GNU | |
67 | # define mempcpy(dest, src, len) \ | |
68 | ((__bos0 (dest) != (size_t) -1) \ | |
69 | ? __builtin___mempcpy_chk (dest, src, len, __bos0 (dest)) \ | |
70 | : __mempcpy_ichk (dest, src, len)) | |
88764ae2 | 71 | static __always_inline void * |
a334319f UD |
72 | __mempcpy_ichk (void *__restrict __dest, const void *__restrict __src, |
73 | size_t __len) | |
b5cc329c UD |
74 | { |
75 | return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest)); | |
76 | } | |
77 | #endif | |
78 | ||
79 | ||
553cc5f9 UD |
80 | /* The first two tests here help to catch a somewhat common problem |
81 | where the second and third parameter are transposed. This is | |
82 | especially problematic if the intended fill value is zero. In this | |
83 | case no work is done at all. We detect these problems by referring | |
84 | non-existing functions. */ | |
61062f56 UD |
85 | __warndecl (__warn_memset_zero_len, |
86 | "memset used with constant zero length parameter; this could be due to transposed parameters"); | |
b5cc329c | 87 | #define memset(dest, ch, len) \ |
553cc5f9 | 88 | (__builtin_constant_p (len) && (len) == 0 \ |
61062f56 | 89 | ? (__warn_memset_zero_len (), (void) (ch), (void) (len), (void *) (dest)) \ |
553cc5f9 UD |
90 | : ((__bos0 (dest) != (size_t) -1) \ |
91 | ? __builtin___memset_chk (dest, ch, len, __bos0 (dest)) \ | |
92 | : __memset_ichk (dest, ch, len))) | |
88764ae2 | 93 | static __always_inline void * |
a334319f | 94 | __memset_ichk (void *__dest, int __ch, size_t __len) |
b5cc329c UD |
95 | { |
96 | return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest)); | |
97 | } | |
98 | ||
99 | #ifdef __USE_BSD | |
100 | # define bcopy(src, dest, len) ((void) \ | |
101 | ((__bos0 (dest) != (size_t) -1) \ | |
102 | ? __builtin___memmove_chk (dest, src, len, __bos0 (dest)) \ | |
103 | : __memmove_ichk (dest, src, len))) | |
104 | # define bzero(dest, len) ((void) \ | |
105 | ((__bos0 (dest) != (size_t) -1) \ | |
106 | ? __builtin___memset_chk (dest, '\0', len, __bos0 (dest)) \ | |
107 | : __memset_ichk (dest, '\0', len))) | |
108 | #endif | |
109 | ||
110 | ||
111 | #define strcpy(dest, src) \ | |
112 | ((__bos (dest) != (size_t) -1) \ | |
113 | ? __builtin___strcpy_chk (dest, src, __bos (dest)) \ | |
114 | : __strcpy_ichk (dest, src)) | |
88764ae2 | 115 | static __always_inline char * |
a334319f | 116 | __strcpy_ichk (char *__restrict __dest, const char *__restrict __src) |
b5cc329c UD |
117 | { |
118 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); | |
119 | } | |
120 | ||
121 | ||
122 | #ifdef __USE_GNU | |
123 | # define stpcpy(dest, src) \ | |
124 | ((__bos (dest) != (size_t) -1) \ | |
125 | ? __builtin___stpcpy_chk (dest, src, __bos (dest)) \ | |
126 | : __stpcpy_ichk (dest, src)) | |
88764ae2 | 127 | static __always_inline char * |
a334319f | 128 | __stpcpy_ichk (char *__restrict __dest, const char *__restrict __src) |
b5cc329c UD |
129 | { |
130 | return __builtin___stpcpy_chk (__dest, __src, __bos (__dest)); | |
131 | } | |
132 | #endif | |
133 | ||
134 | ||
135 | #define strncpy(dest, src, len) \ | |
136 | ((__bos (dest) != (size_t) -1) \ | |
137 | ? __builtin___strncpy_chk (dest, src, len, __bos (dest)) \ | |
138 | : __strncpy_ichk (dest, src, len)) | |
88764ae2 | 139 | static __always_inline char * |
a334319f UD |
140 | __strncpy_ichk (char *__restrict __dest, const char *__restrict __src, |
141 | size_t __len) | |
b5cc329c UD |
142 | { |
143 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); | |
144 | } | |
145 | ||
146 | ||
8215c9ec UD |
147 | // XXX We have no corresponding builtin yet. |
148 | extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, | |
149 | size_t __destlen) __THROW; | |
150 | extern char *__REDIRECT (__stpncpy_alias, (char *__dest, const char *__src, | |
151 | size_t __n), stpncpy)__THROW; | |
152 | ||
153 | extern __always_inline char * | |
154 | stpncpy (char *__dest, const char *__src, size_t __n) | |
155 | { | |
156 | if (__bos (__dest) != (size_t) -1 | |
157 | && (!__builtin_constant_p (__n) || __n <= __bos (__dest))) | |
158 | return __stpncpy_chk (__dest, __src, __n, __bos (__dest)); | |
159 | return __stpncpy_alias (__dest, __src, __n); | |
160 | } | |
161 | ||
162 | ||
b5cc329c UD |
163 | #define strcat(dest, src) \ |
164 | ((__bos (dest) != (size_t) -1) \ | |
165 | ? __builtin___strcat_chk (dest, src, __bos (dest)) \ | |
166 | : __strcat_ichk (dest, src)) | |
88764ae2 | 167 | static __always_inline char * |
a334319f | 168 | __strcat_ichk (char *__restrict __dest, const char *__restrict __src) |
b5cc329c UD |
169 | { |
170 | return __builtin___strcat_chk (__dest, __src, __bos (__dest)); | |
171 | } | |
172 | ||
173 | ||
174 | #define strncat(dest, src, len) \ | |
175 | ((__bos (dest) != (size_t) -1) \ | |
176 | ? __builtin___strncat_chk (dest, src, len, __bos (dest)) \ | |
177 | : __strncat_ichk (dest, src, len)) | |
88764ae2 | 178 | static __always_inline char * |
a334319f UD |
179 | __strncat_ichk (char *__restrict __dest, const char *__restrict __src, |
180 | size_t __len) | |
b5cc329c UD |
181 | { |
182 | return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest)); | |
183 | } |