1 //***************************************************************************** 2 // 3 //! @file am_util_string.h 4 //! 5 //! @brief A subset of the functions provided in the C standard string library. 6 //! 7 //! The functions here are reimplementation of some of the standard "string" 8 //! functions. 9 //! 10 //! @addtogroup string String - Ambiq subset of C String Library 11 //! @ingroup utils 12 //! @{ 13 // 14 //***************************************************************************** 15 16 //***************************************************************************** 17 // 18 // Copyright (c) 2023, Ambiq Micro, Inc. 19 // All rights reserved. 20 // 21 // Redistribution and use in source and binary forms, with or without 22 // modification, are permitted provided that the following conditions are met: 23 // 24 // 1. Redistributions of source code must retain the above copyright notice, 25 // this list of conditions and the following disclaimer. 26 // 27 // 2. Redistributions in binary form must reproduce the above copyright 28 // notice, this list of conditions and the following disclaimer in the 29 // documentation and/or other materials provided with the distribution. 30 // 31 // 3. Neither the name of the copyright holder nor the names of its 32 // contributors may be used to endorse or promote products derived from this 33 // software without specific prior written permission. 34 // 35 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 38 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 39 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 // POSSIBILITY OF SUCH DAMAGE. 46 // 47 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package. 48 // 49 //***************************************************************************** 50 #ifndef AM_UTIL_STRING_H 51 #define AM_UTIL_STRING_H 52 53 #ifdef __cplusplus 54 extern "C" 55 { 56 #endif 57 58 59 //***************************************************************************** 60 // 61 // Character attributes lookup table defines. 62 // 63 //***************************************************************************** 64 #define AM_CATTR_NONE 0x00 65 #define AM_CATTR_ALPHA 0x01 66 #define AM_CATTR_LOWER 0x02 67 #define AM_CATTR_UPPER 0x04 68 #define AM_CATTR_DIGIT 0x08 69 #define AM_CATTR_XDIGIT 0x10 70 #define AM_CATTR_WHSPACE 0x20 71 #define AM_CATTR_FILENM83 0x80 72 73 // 74 // Set MINIMIZE_CATTR_TABLE to 1 to configure for minimal CATTR table size, 75 // (256 instead of 512 bytes) but at a cost of slightly larger code size. 76 // However, setting this option also provides an additional level of checking 77 // of the argument; if the argument is not a uint8_t, the functions are 78 // guaranteed to return 0. 79 // 80 #define MINIMIZE_CATTR_TABLE 0 81 82 83 //***************************************************************************** 84 // 85 // Globals 86 // 87 //***************************************************************************** 88 extern const uint8_t am_cattr[]; 89 90 91 //***************************************************************************** 92 // 93 // External function definitions 94 // 95 //***************************************************************************** 96 97 //***************************************************************************** 98 // 99 //! @brief Compare two strings. 100 //! 101 //! @param str1 is the first string to compare. 102 //! @param str2 is the second string to compare 103 //! 104 //! This function steps through a pair of strings, character by character, to 105 //! determine if the strings contain the same characters. If the strings match, 106 //! this function will return a zero. If str1 is alphabetically earlier than 107 //! str2, the return value will be negative. Otherwise, the return value will 108 //! be positive. 109 //! 110 //! @return 0 for a perfect match, negative value if str1<str2, positive value 111 //! if str1>str2. 112 // 113 //***************************************************************************** 114 extern int32_t am_util_string_strcmp(const char *str1, const char *str2); 115 116 //***************************************************************************** 117 // 118 //! @brief Compare two strings with case-insensitivity. 119 //! 120 //! @param str1 is the first string to compare. 121 //! @param str2 is the second string to compare 122 //! 123 //! This function compares each character in the 2 strings, converting all 124 //! alpha characters to lower-case to make the comparison. 125 //! 126 //! To illustrate a possible unexpected outcome due to comparing the strings 127 //! as lower case, consider the example strings "AMBIQ_MICRO" and "AMBIQMICRO". 128 //! For these strings, stricmp() will return a negative value (indicating the 129 //! first as before the second), whereas strcmp() will return a positive value. 130 //! 131 //! @return 0 for a case-insensitive match, negative value if str1<str2, 132 //! positive value if str1>str2. 133 // 134 //***************************************************************************** 135 extern int32_t am_util_string_stricmp(const char *str1, const char *str2); 136 137 //***************************************************************************** 138 // 139 //! @brief Compare two strings with a specified count. 140 //! 141 //! @param str1 is the first string to compare. 142 //! @param str2 is the second string to compare 143 //! @param num is the maximum number of characters to compare. 144 //! 145 //! This function steps through a pair of strings, character by character, to 146 //! determine if the strings contain the same characters. If the strings match, 147 //! this function will return a zero. If str1 is alphabetically earlier than 148 //! str2, the return value will be negative. Otherwise, the return value will 149 //! be positive. 150 //! 151 //! @return 0 for a perfect match, negative value if str1<str2, positive value 152 //! if str1>str2. 153 // 154 //***************************************************************************** 155 extern int32_t am_util_string_strncmp(const char *str1, const char *str2, 156 uint32_t num); 157 158 //***************************************************************************** 159 // 160 //! @brief Compare two strings with a specified count and without regard to 161 //! letter case in the strings. 162 //! 163 //! @param str1 is the first string to compare. 164 //! @param str2 is the second string to compare 165 //! @param num is the maximum number of characters to compare. 166 //! 167 //! This function steps through a pair of strings, character by character, to 168 //! determine if the strings contain the same characters. If the strings match, 169 //! this function will return a zero. If str1 is alphabetically earlier than 170 //! str2, the return value will be negative. Otherwise, the return value will 171 //! be positive. 172 //! 173 //! @return 0 for a perfect match, negative value if str1<str2, positive value 174 //! if str1>str2. 175 // 176 //***************************************************************************** 177 extern int32_t am_util_string_strnicmp(const char *str1, const char *str2, 178 int num); 179 180 //***************************************************************************** 181 // 182 //! @brief Return the length of a string. 183 //! 184 //! @param pcStr pointer to the string. 185 //! 186 //! This function returns the length of the string at pcStr. 187 //! 188 //! @return length of the string pcStr. 189 // 190 //***************************************************************************** 191 extern uint32_t am_util_string_strlen(const char *pcStr); 192 193 //***************************************************************************** 194 // 195 //! @brief Copies a string. 196 //! 197 //! @param pcDst pointer to the destination string. 198 //! @param pcSrc pointer to the source string to be copied to pcDst. 199 //! 200 //! This function copies pcSrc to the location specified by pcDst. 201 //! 202 //! @return pcDst (the location of the destination string). 203 // 204 //***************************************************************************** 205 extern char *am_util_string_strcpy(char *pcDst, const char *pcSrc); 206 207 //***************************************************************************** 208 // 209 //! @brief Copies a specified number of characters of a string. 210 //! 211 //! @param pcDst pointer to the destination string. 212 //! @param pcSrc pointer to the source string to be copied to pcDst. 213 //! @param uNum length of string 214 //! 215 //! This function copies uNum characters of pcSrc to the location specified 216 //! by pcDst. 217 //! If uNum is less than the length of pcSrc, a NULL terminating character 218 //! is not appended to the copied string. Thus the resultant string will be 219 //! exactly uNum chars in length and not terminated. 220 //! If uNum is greater than the length of pcSrc, then pcDst is padded with 221 //! NULL characters up to the uNum length. 222 //! Behavior is undefined if the addresses ranges overlap. 223 //! 224 //! @return pcDst (the location of the destination string). 225 // 226 //***************************************************************************** 227 extern char *am_util_string_strncpy(char *pcDst, const char *pcSrc, uint32_t uNum); 228 229 //***************************************************************************** 230 // 231 //! @brief Concatenate a string. 232 //! 233 //! @param pcDst pointer to the destination string. 234 //! @param pcSrc pointer to the source string to be copied to pcDst. 235 //! 236 //! This function concatenates the string at pcSrc to the existing string 237 //! at pcDst. 238 //! 239 //! Both strings, pcDst and pcSrc, must be NULL-terminated. 240 //! No overflow checking is performed. 241 //! pcDst and pcSrc shall not overlap. 242 //! 243 //! @return pcDst (the location of the destination string). 244 // 245 //***************************************************************************** 246 extern char *am_util_string_strcat(char *pcDst, const char *pcSrc); 247 248 //***************************************************************************** 249 // 250 // Character "is" macros and functions 251 // 252 // By default all of the "is" functions are implemented as macros. To implement 253 // as functions rather than macros, use a global compiler command line (-D) 254 // option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 255 // 256 #ifdef AM_UTIL_STRING_CTYPE_DISABLE_MACROS 257 //***************************************************************************** 258 // 259 //! @brief Check if the integer param is alphanumeric 260 //! 261 //! Tests a given integer value in order to determine 262 //! whether the integer satisfies the test condition. 263 //! This function is based on the C99 standard function. 264 //! 265 //! By default this function is implemented as a macro. To implement 266 //! as a function, use a global compiler command line (-D) 267 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 268 //! 269 //! @param c - integer to test 270 //! 271 //! @return returns a nonzero value if the integer satisfies 272 //! the test condition and 0 if it does not. 273 // 274 //***************************************************************************** 275 extern int am_util_string_isalnum(int c); 276 277 //***************************************************************************** 278 // 279 //! @brief Check if the integer param is alphabetic 280 //! 281 //! Tests a given integer value in order to determine 282 //! whether the integer satisfies the test condition. 283 //! This function is based on the C99 standard function. 284 //! 285 //! By default this function is implemented as a macro. To implement 286 //! as a function, use a global compiler command line (-D) 287 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 288 //! 289 //! @param c - integer to test 290 //! 291 //! @return returns a nonzero value if the integer satisfies 292 //! the test condition and 0 if it does not. 293 // 294 //***************************************************************************** 295 extern int am_util_string_isalpha(int c); 296 297 //***************************************************************************** 298 // 299 //! @brief Check if the integer param is a digit 300 //! 301 //! Tests a given integer value in order to determine 302 //! whether the integer satisfies the test condition. 303 //! This function is based on the C99 standard function. 304 //! 305 //! By default this function is implemented as a macro. To implement 306 //! as a function, use a global compiler command line (-D) 307 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 308 //! 309 //! @param c - integer to test 310 //! 311 //! @return returns a nonzero value if the integer satisfies 312 //! the test condition and 0 if it does not. 313 // 314 //***************************************************************************** 315 extern int am_util_string_isdigit(int c); 316 317 //***************************************************************************** 318 // 319 //! @brief Check if the integer param is lower case 320 //! 321 //! Tests a given integer value in order to determine 322 //! whether the integer satisfies the test condition. 323 //! This function is based on the C99 standard function. 324 //! 325 //! By default this function is implemented as a macro. To implement 326 //! as a function, use a global compiler command line (-D) 327 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 328 //! 329 //! @param c - integer to test 330 //! 331 //! @return returns a nonzero value if the integer satisfies 332 //! the test condition and 0 if it does not. 333 // 334 //***************************************************************************** 335 extern int am_util_string_islower(int c); 336 337 //***************************************************************************** 338 // 339 //! @brief Check if the integer param is the space character 340 //! 341 //! Tests a given integer value in order to determine 342 //! whether the integer satisfies the test condition. 343 //! This function is based on the C99 standard function. 344 //! 345 //! By default this function is implemented as a macro. To implement 346 //! as a function, use a global compiler command line (-D) 347 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 348 //! 349 //! @param c - integer to test 350 //! 351 //! @return returns a nonzero value if the integer satisfies 352 //! the test condition and 0 if it does not. 353 // 354 //***************************************************************************** 355 extern int am_util_string_isspace(int c); 356 357 //***************************************************************************** 358 // 359 //! @brief Check if the integer param is upper case 360 //! 361 //! Tests a given integer value in order to determine 362 //! whether the integer satisfies the test condition. 363 //! This function is based on the C99 standard function. 364 //! 365 //! By default this function is implemented as a macro. To implement 366 //! as a function, use a global compiler command line (-D) 367 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 368 //! 369 //! @param c - integer to test 370 //! 371 //! @return returns a nonzero value if the integer satisfies 372 //! the test condition and 0 if it does not. 373 // 374 //***************************************************************************** 375 extern int am_util_string_isupper(int c); 376 377 //***************************************************************************** 378 // 379 //! @brief Check if the integer param is a hex digit 380 //! 381 //! Tests a given integer value in order to determine 382 //! whether the integer satisfies the test condition. 383 //! This function is based on the C99 standard function. 384 //! 385 //! By default this function is implemented as a macro. To implement 386 //! as a function, use a global compiler command line (-D) 387 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 388 //! 389 //! @param c - integer to test 390 //! 391 //! @return returns a nonzero value if the integer satisfies 392 //! the test condition and 0 if it does not. 393 // 394 //***************************************************************************** 395 extern int am_util_string_isxdigit(int c); 396 397 //***************************************************************************** 398 // 399 //! @brief Converts the character to lower case 400 //! 401 //! Tests a given integer value in order to determine 402 //! whether the integer satisfies the test condition. 403 //! This function is based on the C99 standard function. 404 //! 405 //! By default this function is implemented as a macro. To implement 406 //! as a function, use a global compiler command line (-D) 407 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 408 //! 409 //! @param c - integer to test 410 //! 411 //! @return returns the input param as lower case 412 // 413 //***************************************************************************** 414 extern int am_util_string_tolower(int c); 415 416 //***************************************************************************** 417 // 418 //! @brief Converts the character to upper case 419 //! 420 //! Tests a given integer value in order to determine 421 //! whether the integer satisfies the test condition. 422 //! This function is based on the C99 standard function. 423 //! 424 //! By default this function is implemented as a macro. To implement 425 //! as a function, use a global compiler command line (-D) 426 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 427 //! 428 //! @param c - integer to test 429 //! 430 //! @return returns the input param as upper case 431 // 432 //***************************************************************************** 433 extern int am_util_string_toupper(int c); 434 435 //***************************************************************************** 436 // 437 //! @brief Check if the integer param is part of a filename char 438 //! 439 //! Tests a given integer value in order to determine 440 //! whether the integer satisfies the test condition. 441 //! This function is based on the C99 standard function. 442 //! 443 //! By default this function is implemented as a macro. To implement 444 //! as a function, use a global compiler command line (-D) 445 //! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS. 446 //! 447 //! @param c - integer to test 448 //! 449 //! @return returns a nonzero value if the integer satisfies 450 //! the test condition and 0 if it does not. 451 // 452 //***************************************************************************** 453 extern int am_util_string_isfilenm83(int c); 454 #else 455 #if MINIMIZE_CATTR_TABLE 456 #define am_util_string_isalnum(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT)) ? 1 : 0) 457 #define am_util_string_isalpha(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_ALPHA) ? 1 : 0) 458 #define am_util_string_isdigit(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_DIGIT) ? 1 : 0) 459 #define am_util_string_islower(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_LOWER) ? 1 : 0) 460 #define am_util_string_isspace(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_WHSPACE) ? 1 : 0) 461 #define am_util_string_isupper(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_UPPER) ? 1 : 0) 462 #define am_util_string_isxdigit(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_XDIGIT) ? 1 : 0) 463 #define am_util_string_tolower(c) ((am_cattr[c & 0x7f] & AM_CATTR_UPPER) ? c | 0x20 : c) 464 #define am_util_string_toupper(c) ((am_cattr[c & 0x7f] & AM_CATTR_LOWER) ? c & ~0x20 : c) 465 #else 466 #define am_util_string_isalnum(c) (am_cattr[c & 0xff] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT)) 467 #define am_util_string_isalpha(c) (am_cattr[c & 0xff] & AM_CATTR_ALPHA) 468 #define am_util_string_isdigit(c) (am_cattr[c & 0xff] & AM_CATTR_DIGIT) 469 #define am_util_string_islower(c) (am_cattr[c & 0xff] & AM_CATTR_LOWER) 470 #define am_util_string_isspace(c) (am_cattr[c & 0xff] & AM_CATTR_WHSPACE) 471 #define am_util_string_isupper(c) (am_cattr[c & 0xff] & AM_CATTR_UPPER) 472 #define am_util_string_isxdigit(c) (am_cattr[c & 0xff] & AM_CATTR_XDIGIT) 473 #define am_util_string_tolower(c) ((am_cattr[c & 0xff] & AM_CATTR_UPPER) ? c | 0x20 : c) 474 #define am_util_string_toupper(c) ((am_cattr[c & 0xff] & AM_CATTR_LOWER) ? c & ~0x20 : c) 475 #endif // MINIMIZE_CATTR_TABLE 476 477 #define am_util_string_isfilenm83(c) (am_cattr[c & 0xff] & AM_CATTR_FILENM83) 478 #endif // AM_UTIL_STRING_CTYPE_DISABLE_MACROS 479 480 #ifdef __cplusplus 481 } 482 #endif 483 484 #endif // AM_UTIL_STRING_H 485 486 //***************************************************************************** 487 // 488 // End Doxygen group. 489 //! @} 490 // 491 //***************************************************************************** 492 493