]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - wimboot/wimboot-2.7.3/src/string.c
2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 * @v dest Destination address
37 * @v src Source address
39 * @ret dest Destination address
41 void * memcpy ( void *dest
, const void *src
, size_t len
) {
43 const void *esi
= src
;
46 /* Perform dword-based copy for bulk, then byte-based for remainder */
47 __asm__
__volatile__ ( "rep movsl"
48 : "=&D" ( edi
), "=&S" ( esi
),
50 : "0" ( edi
), "1" ( esi
), "2" ( len
>> 2 )
52 __asm__
__volatile__ ( "rep movsb"
53 : "=&D" ( edi
), "=&S" ( esi
),
55 : "0" ( edi
), "1" ( esi
), "2" ( len
& 3 )
61 * Copy memory area backwards
63 * @v dest Destination address
64 * @v src Source address
66 * @ret dest Destination address
68 static void * memcpy_reverse ( void *dest
, const void *src
, size_t len
) {
69 void *edi
= ( dest
+ len
- 1 );
70 const void *esi
= ( src
+ len
- 1 );
73 /* Assume memmove() is not performance-critical, and perform a
74 * bytewise copy for simplicity.
76 * Disable interrupts to avoid known problems on platforms
77 * that assume the direction flag always remains cleared.
79 __asm__
__volatile__ ( "pushf\n\t"
84 : "=&D" ( edi
), "=&S" ( esi
),
86 : "0" ( edi
), "1" ( esi
),
93 * Copy (possibly overlapping) memory area
95 * @v dest Destination address
96 * @v src Source address
98 * @ret dest Destination address
100 void * memmove ( void *dest
, const void *src
, size_t len
) {
103 return memcpy ( dest
, src
, len
);
105 return memcpy_reverse ( dest
, src
, len
);
112 * @v dest Destination address
113 * @v src Source address
115 * @ret dest Destination address
117 void * memset ( void *dest
, int c
, size_t len
) {
122 /* Expand byte to whole dword */
124 eax
|= ( eax
<< 16 );
126 /* Perform dword-based set for bulk, then byte-based for remainder */
127 __asm__
__volatile__ ( "rep stosl"
128 : "=&D" ( edi
), "=&a" ( eax
),
129 "=&c" ( discard_ecx
)
130 : "0" ( edi
), "1" ( eax
), "2" ( len
>> 2 )
132 __asm__
__volatile__ ( "rep stosb"
133 : "=&D" ( edi
), "=&a" ( eax
),
134 "=&c" ( discard_ecx
)
135 : "0" ( edi
), "1" ( eax
), "2" ( len
& 3 )
141 * Compare memory areas
143 * @v src1 First source area
144 * @v src2 Second source area
146 * @ret diff Difference
148 int memcmp ( const void *src1
, const void *src2
, size_t len
) {
149 const uint8_t *bytes1
= src1
;
150 const uint8_t *bytes2
= src2
;
154 if ( ( diff
= ( *(bytes1
++) - *(bytes2
++) ) ) )
161 * Compare two strings
163 * @v str1 First string
164 * @v str2 Second string
165 * @ret diff Difference
167 int strcmp ( const char *str1
, const char *str2
) {
174 } while ( ( c1
!= '\0' ) && ( c1
== c2
) );
180 * Compare two strings, case-insensitively
182 * @v str1 First string
183 * @v str2 Second string
184 * @ret diff Difference
186 int strcasecmp ( const char *str1
, const char *str2
) {
191 c1
= toupper ( *(str1
++) );
192 c2
= toupper ( *(str2
++) );
193 } while ( ( c1
!= '\0' ) && ( c1
== c2
) );
199 * Compare two wide-character strings, case-insensitively
201 * @v str1 First string
202 * @v str2 Second string
203 * @ret diff Difference
205 int wcscasecmp ( const wchar_t *str1
, const wchar_t *str2
) {
210 c1
= towupper ( *(str1
++) );
211 c2
= towupper ( *(str2
++) );
212 } while ( ( c1
!= L
'\0' ) && ( c1
== c2
) );
218 * Get length of string
223 size_t strlen ( const char *str
) {
232 * Get length of wide-character string
235 * @ret len Length (in characters)
237 size_t wcslen ( const wchar_t *str
) {
246 * Find character in wide-character string
249 * @v c Wide character
250 * @ret first First occurrence of wide character in string, or NULL
252 wchar_t * wcschr ( const wchar_t *str
, wchar_t c
) {
254 for ( ; *str
; str
++ ) {
256 return ( ( wchar_t * )str
);
261 char *strchr(const char *str
, char c
) {
262 for ( ; *str
; str
++ ) {
264 return ( ( char * )str
);
270 * Check to see if character is a space
273 * @ret isspace Character is a space
275 int isspace ( int c
) {
290 * Convert a string to an unsigned integer
293 * @v endptr End pointer to fill in (or NULL)
294 * @v base Numeric base
297 unsigned long strtoul ( const char *nptr
, char **endptr
, int base
) {
298 unsigned long val
= 0;
302 /* Skip any leading whitespace */
303 while ( isspace ( *nptr
) )
306 /* Parse sign, if present */
307 if ( *nptr
== '+' ) {
309 } else if ( *nptr
== '-' ) {
317 /* Default to decimal */
320 /* Check for octal or hexadecimal markers */
321 if ( *nptr
== '0' ) {
324 if ( ( *nptr
| 0x20 ) == 'x' ) {
334 if ( digit
>= 'a' ) {
335 digit
= ( digit
- 'a' + 10 );
336 } else if ( digit
>= 'A' ) {
337 digit
= ( digit
- 'A' + 10 );
338 } else if ( digit
<= '9' ) {
339 digit
= ( digit
- '0' );
341 if ( digit
>= ( unsigned int ) base
)
343 val
= ( ( val
* base
) + digit
);
346 /* Record end marker, if applicable */
348 *endptr
= ( ( char * ) nptr
);
351 return ( negate
? -val
: val
);