1 /* String handling <string.h>
2 
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6 
7 #ifndef _PDCLIB_STRING_H
8 #define _PDCLIB_STRING_H _PDCLIB_STRING_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include "pdclib/_PDCLIB_lib_ext1.h"
15 #include "pdclib/_PDCLIB_internal.h"
16 
17 #ifndef _PDCLIB_SIZE_T_DEFINED
18 #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
19 typedef _PDCLIB_size_t size_t;
20 #endif
21 
22 #ifndef _PDCLIB_NULL_DEFINED
23 #define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
24 #define NULL _PDCLIB_NULL
25 #endif
26 
27 /* String function conventions */
28 
29 /*
30    In any of the following functions taking a size_t n to specify the length of
31    an array or size of a memory region, n may be 0, but the pointer arguments to
32    the call shall still be valid unless otherwise stated.
33 */
34 
35 /* Copying functions */
36 
37 /* Copy a number of n characters from the memory area pointed to by s2 to the
38    area pointed to by s1. If the two areas overlap, behaviour is undefined.
39    Returns the value of s1.
40 */
41 _PDCLIB_PUBLIC void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
42 
43 /* Copy a number of n characters from the memory area pointed to by s2 to the
44    area pointed to by s1. The two areas may overlap.
45    Returns the value of s1.
46 */
47 _PDCLIB_PUBLIC void * memmove( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
48 
49 /* Copy the character array s2 (including terminating '\0' byte) into the
50    character array s1.
51    Returns the value of s1.
52 */
53 _PDCLIB_PUBLIC char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
54 
55 /* Copy a maximum of n characters from the character array s2 into the character
56    array s1. If s2 is shorter than n characters, '\0' bytes will be appended to
57    the copy in s1 until n characters have been written. If s2 is longer than n
58    characters, NO terminating '\0' will be written to s1. If the arrays overlap,
59    behaviour is undefined.
60    Returns the value of s1.
61 */
62 _PDCLIB_PUBLIC char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
63 
64 /* Concatenation functions */
65 
66 /* Append the contents of the character array s2 (including terminating '\0') to
67    the character array s1 (first character of s2 overwriting the '\0' of s1). If
68    the arrays overlap, behaviour is undefined.
69    Returns the value of s1.
70 */
71 _PDCLIB_PUBLIC char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
72 
73 /* Append a maximum of n characters from the character array s2 to the character
74    array s1 (first character of s2 overwriting the '\0' of s1). A terminating
75    '\0' is ALWAYS appended, even if the full n characters have already been
76    written. If the arrays overlap, behaviour is undefined.
77    Returns the value of s1.
78 */
79 _PDCLIB_PUBLIC char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
80 
81 /* Comparison functions */
82 
83 /* Compare the first n characters of the memory areas pointed to by s1 and s2.
84    Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
85    s1 > s2.
86 */
87 _PDCLIB_PUBLIC int memcmp( const void * s1, const void * s2, size_t n );
88 
89 /* Compare the character arrays s1 and s2.
90    Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
91    s1 > s2.
92 */
93 _PDCLIB_PUBLIC int strcmp( const char * s1, const char * s2 );
94 
95 /* Compare the character arrays s1 and s2, interpreted as specified by the
96    LC_COLLATE category of the current locale.
97    Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
98    s1 > s2.
99    TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support
100    locales.
101 */
102 _PDCLIB_PUBLIC int strcoll( const char * s1, const char * s2 );
103 
104 /* Compare no more than the first n characters of the character arrays s1 and
105    s2.
106    Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
107    s1 > s2.
108 */
109 _PDCLIB_PUBLIC int strncmp( const char * s1, const char * s2, size_t n );
110 
111 /* Transform the character array s2 as appropriate for the LC_COLLATE setting of
112    the current locale. If length of resulting string is less than n, store it in
113    the character array pointed to by s1. Return the length of the resulting
114    string.
115 */
116 _PDCLIB_PUBLIC size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
117 
118 /* Search functions */
119 
120 /* Search the first n characters in the memory area pointed to by s for the
121    character c (interpreted as unsigned char).
122    Returns a pointer to the first instance found, or NULL.
123 */
124 _PDCLIB_PUBLIC void * memchr( const void * s, int c, size_t n );
125 
126 /* Search the character array s (including terminating '\0') for the character c
127    (interpreted as char).
128    Returns a pointer to the first instance found, or NULL.
129 */
130 _PDCLIB_PUBLIC char * strchr( const char * s, int c );
131 
132 /* Determine the length of the initial substring of character array s1 which
133    consists only of characters not from the character array s2.
134    Returns the length of that substring.
135 */
136 _PDCLIB_PUBLIC size_t strcspn( const char * s1, const char * s2 );
137 
138 /* Search the character array s1 for any character from the character array s2.
139    Returns a pointer to the first occurrence, or NULL.
140 */
141 _PDCLIB_PUBLIC char * strpbrk( const char * s1, const char * s2 );
142 
143 /* Search the character array s (including terminating '\0') for the character c
144    (interpreted as char).
145    Returns a pointer to the last instance found, or NULL.
146 */
147 _PDCLIB_PUBLIC char * strrchr( const char * s, int c );
148 
149 /* Determine the length of the initial substring of character array s1 which
150    consists only of characters from the character array s2.
151    Returns the length of that substring.
152 */
153 _PDCLIB_PUBLIC size_t strspn( const char * s1, const char * s2 );
154 
155 /* Search the character array s1 for the substring in character array s2.
156    Returns a pointer to that sbstring, or NULL. If s2 is of length zero,
157    returns s1.
158 */
159 _PDCLIB_PUBLIC char * strstr( const char * s1, const char * s2 );
160 
161 /* In a series of subsequent calls, parse a C string into tokens.
162    On the first call to strtok(), the first argument is a pointer to the to-be-
163    parsed C string. On subsequent calls, the first argument is NULL unless you
164    want to start parsing a new string. s2 holds an array of separator characters
165    which can differ from call to call. Leading separators are skipped, the first
166    trailing separator overwritten with '\0'.
167    Returns a pointer to the next token.
168    WARNING: This function uses static storage, and as such is not reentrant.
169 */
170 _PDCLIB_PUBLIC char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
171 
172 /* Miscellaneous functions */
173 
174 /* Write the character c (interpreted as unsigned char) to the first n
175    characters of the memory area pointed to by s.
176    Returns s.
177 */
178 _PDCLIB_PUBLIC void * memset( void * s, int c, size_t n );
179 
180 /* Map an error number to a (locale-specific) error message string. Error
181    numbers are typically errno values, but any number is mapped to a message.
182    TODO: PDCLib does not yet support locales.
183 */
184 _PDCLIB_PUBLIC char * strerror( int errnum );
185 
186 /* Returns the length of the string s (excluding terminating '\0').
187 */
188 _PDCLIB_PUBLIC size_t strlen( const char * s );
189 
190 /* Annex K -- Bounds-checking interfaces */
191 
192 #if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
193 
194 #ifndef _PDCLIB_ERRNO_T_DEFINED
195 #define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
196 typedef int errno_t;
197 #endif
198 
199 #ifndef _PDCLIB_RSIZE_T_DEFINED
200 #define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
201 typedef _PDCLIB_size_t rsize_t;
202 #endif
203 
204 /* Copy a number of n characters from the memory area pointed to by s2 to the
205    area pointed to by s1 of size s1max.
206    Returns zero if successful, non-zero otherwise.
207    The following conditions will be considered runtime constraint violations:
208    - s1 or s2 being NULL.
209    - s1max or n being > RSIZE_MAX.
210    - n > s1max (not enough space in s1).
211    - copying between overlapping objects.
212    In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
213    then the first s1max characters of s1 will be set to zero.
214    The currently active constraint violation handler function will be called
215    (see set_constraint_handler_s()).
216 */
217 _PDCLIB_PUBLIC errno_t memcpy_s( void * _PDCLIB_restrict s1, rsize_t s1max, const void * _PDCLIB_restrict s2, rsize_t n );
218 
219 /* Copy a number of n characters from the memory area pointed to by s2 to the
220    area pointed to by s1 of size s1max. The two areas may overlap.
221    Returns zero if successful, non-zero otherwise.
222    The following conditions will be considered runtime constraint violations:
223    - s1 or s2 being NULL.
224    - s1max or n being > RSIZE_MAX.
225    - n > s1max (not enough space in s1).
226    In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
227    then the first s1max characters of s1 will be set to zero.
228    The currently active constraint violation handler function will be called
229    (see set_constraint_handler_s()).
230 */
231 _PDCLIB_PUBLIC errno_t memmove_s( void * _PDCLIB_restrict s1, rsize_t s1max, const void * _PDCLIB_restrict s2, rsize_t n );
232 
233 /* Copy the character array s2 (including terminating '\0' byte) into the
234    character array s1.
235    Returns zero if successful, non-zero otherwise.
236    The following conditions will be considered runtime constraint violations:
237    - s1 or s2 being NULL.
238    - s1max being zero or > RSIZE_MAX.
239    - s1max not greater than strnlen_s( s2, s1max ) (not enough space in s1).
240    - copying between overlapping objects.
241    In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
242    then s1[0] will be set to '\0'.
243    The currently active constraint violation handler function will be called
244    (see set_constraint_handler_s()).
245 */
246 _PDCLIB_PUBLIC errno_t strcpy_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2 );
247 
248 /* Copy a maximum of n characters from the character array s2 into the character
249    array s1. If s2 is longer than n, s1[n] will be set to '\0'.
250    Returns zero if successful, non-zero otherwise.
251 
252    ATTENTION ATTENTION ATTENTION
253 
254    This function differs in two fundamental ways from strncpy():
255    - remaining space in s1 will NOT be zeroed. Their value is unspecified.
256    - s1 WILL be zero-terminated even if there is not enough space to hold
257      all n characters from s2.
258 
259    THANK YOU FOR YOUR ATTENTION.
260 
261    The following conditions will be considered runtime constraint violations:
262    - s1 or s2 being NULL.
263    - s1max or n being > RSIZE_MAX.
264    - s1max being zero.
265    - n >= s1max and s1max <= strnlen_s( s2, s1max ) (not enough space in s1).
266    - copying between overlapping objects.
267    In case of a constraint violation, if s1 is not NULL and s1max is greater
268    zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
269    The currently active constraint violation handler function will be called
270    (see set_constraint_handler_s()).
271 */
272 _PDCLIB_PUBLIC errno_t strncpy_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2, rsize_t n );
273 
274 /* Append the contents of the character array s2 (including terminating '\0') to
275    the character array s1 (first character of s2 overwriting the '\0' of s1).
276    Elements following the terminating null character (if any) take unspecified
277    values.
278    Returns zero if successful, non-zero otherwise.
279    The following conditions will be considered runtime constraint violations:
280    - s1 or s2 being NULL.
281    - s1max being > RSIZE_MAX.
282    - s1max being zero.
283    - not enough space in s1 for both s1 and the characters copied from s2.
284    - copying between overlapping objects.
285    In case of a constraint violation, if s1 is not NULL and s1max is greater
286    zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
287    The currently active constraint violation handler function will be called
288    (see set_constraint_handler_s()).
289 */
290 _PDCLIB_PUBLIC errno_t strcat_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2 );
291 
292 /* Append a maximum of n characters from the character array s2 to the
293    character array s1 (first character of s2 overwriting the '\0' of s1). A
294    terminating '\0' is ALWAYS appended, even if the full n characters have
295    already been written.
296    Elements following the terminating null character (if any) take unspecified
297    values.
298    Returns zero if successful, non-zero otherwise.
299    The following conditions will be considered runtime constraint violations:
300    - s1 or s2 being NULL.
301    - s1max or n being > RSIZE_MAX.
302    - s1max being zero.
303    - not enough space in s1 for both s1 and the characters copied from s2.
304    - copying between overlapping objects.
305    In case of a constraint violation, if s1 is not NULL and s1max is greater
306    zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
307    The currently active constraint violation handler function will be called
308    (see set_constraint_handler_s()).
309 */
310 _PDCLIB_PUBLIC errno_t strncat_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2, rsize_t n );
311 
312 /* In a series of subsequent calls, parse a C string into tokens.
313    On the first call to strtok(), the first argument is a pointer to the to-be-
314    parsed C string of size *s1max. On subsequent calls, the first argument is
315    NULL unless you want to start parsing a new string. s2 holds an array of
316    separator characters which can differ from call to call. Leading separators
317    are skipped, the first trailing separator overwritten with '\0'.
318    Returns a pointer to the next token.
319    The following conditions will be considered runtime constraint violations:
320    - s1max, s2, or ptr being NULL.
321    - s1max or n being > RSIZE_MAX.
322    - s1max being zero.
323    - not enough space in s1 for both s1 and the characters copied from s2.
324    - copying between overlapping objects.
325    In case of a constraint violation, if s1 is not NULL and s1max is greater
326    zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
327    The currently active constraint violation handler function will be called
328    (see set_constraint_handler_s()).
329 */
330 _PDCLIB_PUBLIC char * strtok_s( char * _PDCLIB_restrict s1, rsize_t * _PDCLIB_restrict s1max, const char * _PDCLIB_restrict s2, char ** _PDCLIB_restrict ptr );
331 
332 /* Write the character c (interpreted as unsigned char) to the first n
333    characters of the memory area pointed to by s of size smax.
334    Returns zero if successful, non-zero otherwise.
335    The following conditions will be considered runtime constraint violations:
336    - s being NULL.
337    - smax or n being > RSIZE_MAX.
338    - n being > smax.
339    In case of a constraint violation, if s is not NULL and smax is <= RSIZE_MAX
340    the value of c (interpreted as unsigned char) is written to the first smax
341    characters of s.
342    The currently active constraint violation handler function will be called
343    (see set_constraint_handler_s()).
344 */
345 _PDCLIB_PUBLIC errno_t memset_s( void * s, rsize_t smax, int c, rsize_t n );
346 
347 /* Map an error number to a (locale-specific) error message string. Error
348    numbers are typically errno values, but any number is mapped to a message.
349    TODO: PDCLib does not yet support locales.
350    If the length of the mapped string is < maxsize, the string is copied to s.
351    Otherwise, if maxsize is greater than zero, as much of the string as does
352    fit is copied, and s[maxsize-1] set to '\0'. If maxsize is greater than 3,
353    the partial string is made to end in "...".
354    Returns zero if the string was copied successfully in full, non-zero
355    otherwise.
356    The following conditions will be considered runtime constraint violations:
357    - s being NULL.
358    - maxsize being zero or > RSIZE_MAX.
359    In case of a constraint violation, s is not modified.
360    The currently active constraint violation handler function will be called
361    (see set_constraint_handler_s()).
362 */
363 _PDCLIB_PUBLIC errno_t strerror_s( char * s, rsize_t maxsize, errno_t errnum );
364 
365 /* Map an error number to a (locale-specific) error message string, the same
366    way as strerror_s() would do. Error numbers are typically errno values,
367    but any number is mapped to a message.
368    TODO: PDCLib does not yet support locales.
369    Returns the length of the mapped string.
370 */
371 _PDCLIB_PUBLIC size_t strerrorlen_s( errno_t errnum );
372 
373 /* Returns the length of the string s (excluding terminating '\0').
374    If there is no null character in the first maxsize characters of s,
375    rerturns maxsize. If s is NULL, returns zero.
376    At most the first maxsize characters of s shall be accessed by the
377    function.
378 */
379 _PDCLIB_PUBLIC size_t strnlen_s( const char * s, size_t maxsize );
380 
381 #endif
382 
383 #ifdef __cplusplus
384 }
385 #endif
386 
387 /* Extension hook for downstream projects that want to have non-standard
388    extensions to standard headers.
389 */
390 #ifdef _PDCLIB_EXTEND_STRING_H
391 #include _PDCLIB_EXTEND_STRING_H
392 #endif
393 
394 #endif
395