solarium/.svn/pristine/0e/0ef7114e0d267f5db15e4e56af114d31cdbdb033.svn-base
2021-04-15 21:07:13 +03:00

1249 lines
53 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/LIB in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/LIB. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* ASCII STRING MANAGEMENT
*
* Filename : lib_str.c
* Version : V1.24
* Programmer(s) : ITJ
* JDH
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define LIB_STR_MODULE
#include <lib_str.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Len()
*
* Description : Calculate length of a string.
*
* Argument(s) : pstr Pointer to string (see Note #1).
*
* Return(s) : Length of string; number of characters in string before terminating NULL character.
*
* Caller(s) : various.
*
* Note(s) : (1) String buffer NOT modified.
*
* (2) String length calculation terminates when :
*
* (a) String pointer points to NULL.
* (1) String buffer overlaps with NULL address.
* (2) String length calculated for string up to but NOT beyond or including
* the NULL address.
*
* (b) Terminating NULL character found.
* (1) String length calculated for string up to but NOT including
* the NULL character.
*********************************************************************************************************
*/
CPU_SIZE_T Str_Len (CPU_CHAR *pstr)
{
CPU_SIZE_T len;
len = 0;
while (( pstr != (CPU_CHAR *)0) && /* Calc str len until NULL ptr (see Note #2a) ... */
(*pstr != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2b). */
len++;
pstr++;
}
return (len);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Copy()
*
* Description : Copy source string to destination string buffer.
*
* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1).
*
* psrc Pointer to source string to copy into destination string buffer.
*
* Return(s) : Pointer to destination string, if NO errors (see Note #2).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
*
* (a) Destination buffer size MUST be large enough to accommodate the entire source
* string size including the terminating NULL character.
*
* (2) String copy terminates when :
*
* (a) Destination/Source string pointer(s) are passed NULL pointers.
* (1) No string copy performed; NULL pointer returned.
*
* (b) Destination/Source string pointer(s) points to NULL.
* (1) String buffer(s) overlap with NULL address.
* (2) Source string copied into destination string buffer up to but NOT beyond or
* including the NULL address; destination string buffer properly terminated
* with NULL character.
*
* (c) Source string's terminating NULL character found.
* (1) Entire source string copied into destination string buffer.
*********************************************************************************************************
*/
CPU_CHAR *Str_Copy (CPU_CHAR *pdest,
CPU_CHAR *psrc)
{
CPU_CHAR *pstr;
CPU_CHAR *pstr_next;
/* Rtn NULL if str ptr(s) NULL (see Note #2a). */
if (pdest == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (psrc == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
pstr = pdest;
pstr_next = pstr;
pstr_next++;
while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */
( psrc != (CPU_CHAR *)0) &&
(*psrc != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2c). */
*pstr = *psrc;
pstr++;
pstr_next++;
psrc++;
}
*pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */
return (pdest);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Copy_N()
*
* Description : Copy source string to destination string buffer, up to a maximum number of characters.
*
* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1).
*
* psrc Pointer to source string to copy into destination string buffer.
*
* len_max Maximum number of characters to copy (see Note #2d).
*
* Return(s) : Pointer to destination string, if NO errors (see Note #2).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
*
* (a) Destination buffer size MUST be large enough to accommodate the entire source
* string size including the terminating NULL character.
*
* (2) String copy terminates when :
*
* (a) Destination/Source string pointer(s) are passed NULL pointers.
* (1) No string copy performed; NULL pointer returned.
*
* (b) Destination/Source string pointer(s) points to NULL.
* (1) String buffer(s) overlap with NULL address.
* (2) Source string copied into destination string buffer up to but NOT beyond or
* including the NULL address; destination string buffer properly terminated
* with NULL character.
*
* (c) Source string's terminating NULL character found.
* (1) Entire source string copied into destination string buffer.
*
* (d) 'len_max' number of characters copied.
* (1) 'len_max' number of characters does NOT include the terminating NULL character.
*
* See also Note #1a.
*********************************************************************************************************
*/
CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest,
CPU_CHAR *psrc,
CPU_SIZE_T len_max)
{
CPU_CHAR *pstr;
CPU_CHAR *pstr_next;
CPU_SIZE_T len_copy;
/* Rtn NULL if str ptr(s) NULL (see Note #2a). */
if (pdest == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (psrc == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if copy len equals zero (see Note #2d). */
return ((CPU_CHAR *)0);
}
pstr = pdest;
pstr_next = pstr;
pstr_next++;
len_copy = 0;
while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */
( psrc != (CPU_CHAR *)0) &&
(*psrc != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2c); ... */
( len_copy < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars copied (see Note #2d). */
*pstr = *psrc;
pstr++;
pstr_next++;
psrc++;
len_copy++;
}
*pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */
return (pdest);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Cat()
*
* Description : Append concatenation string to destination string.
*
* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1).
*
* pstr_cat Pointer to concatenation string to append to destination string.
*
* Return(s) : Pointer to destination string, if NO errors (see Note #2).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller.
*
* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated
* string size including the terminating NULL character.
*
* (2) String concatenation terminates when :
*
* (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
* (1) No string concatenation performed; NULL pointer returned.
*
* (b) Destination string overlaps with NULL address.
* (1) No string concatenation performed; NULL pointer returned.
*
* (c) Destination/Concatenation string pointer(s) points to NULL.
* (1) String buffer(s) overlap with NULL address.
* (2) Concatenation string appended into destination string buffer up to but NOT
* beyond or including the NULL address; destination string buffer properly
* terminated with NULL character.
*
* (d) Concatenation string's terminating NULL character found.
* (1) Entire concatenation string appended to destination string.
*********************************************************************************************************
*/
CPU_CHAR *Str_Cat (CPU_CHAR *pdest,
CPU_CHAR *pstr_cat)
{
CPU_CHAR *pstr;
CPU_CHAR *pstr_next;
/* Rtn NULL if str ptr(s) NULL (see Note #2a). */
if (pdest == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (pstr_cat == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
pstr = pdest;
while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */
(*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */
pstr++;
}
if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */
return ((CPU_CHAR *)0);
}
pstr_next = pstr;
pstr_next++;
while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */
( pstr_cat != (CPU_CHAR *)0) &&
(*pstr_cat != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2d). */
*pstr = *pstr_cat;
pstr++;
pstr_next++;
pstr_cat++;
}
*pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */
return (pdest);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Cat_N()
*
* Description : Append concatenation string to destination string, up to a maximum number of characters.
*
* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1).
*
* pstr_cat Pointer to concatenation string to append to destination string.
*
* len_max Maximum number of characters to concatenate (see Note #2e).
*
* Return(s) : Pointer to destination string, if NO errors (see Note #2).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller.
*
* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated
* string size including the terminating NULL character.
*
* (2) String concatenation terminates when :
*
* (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
* (1) No string concatenation performed; NULL pointer returned.
*
* (b) Destination string overlaps with NULL address.
* (1) No string concatenation performed; NULL pointer returned.
*
* (c) Destination/Concatenation string pointer(s) points to NULL.
* (1) String buffer(s) overlap with NULL address.
* (2) Concatenation string appended into destination string buffer up to but NOT
* beyond or including the NULL address; destination string buffer properly
* terminated with NULL character.
*
* (d) Concatenation string's terminating NULL character found.
* (1) Entire concatenation string appended to destination string.
*
* (e) 'len_max' number of characters concatenated.
* (1) 'len_max' number of characters does NOT include the terminating NULL character.
*
* See also Note #1a.
*********************************************************************************************************
*/
/*$PAGE*/
CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest,
CPU_CHAR *pstr_cat,
CPU_SIZE_T len_max)
{
CPU_CHAR *pstr;
CPU_CHAR *pstr_next;
CPU_SIZE_T len_cat;
/* Rtn NULL if str ptr(s) NULL (see Note #2a). */
if (pdest == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (pstr_cat == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if cat len equals zero (see Note #2e). */
return ((CPU_CHAR *)0);
}
pstr = pdest;
while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */
(*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */
pstr++;
}
if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */
return ((CPU_CHAR *)0);
}
pstr_next = pstr;
pstr_next++;
len_cat = 0;
while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */
( pstr_cat != (CPU_CHAR *)0) &&
(*pstr_cat != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2d); ... */
( len_cat < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars cat'd (see Note #2d). */
*pstr = *pstr_cat;
pstr++;
pstr_next++;
pstr_cat++;
len_cat++;
}
*pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */
return (pdest);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Cmp()
*
* Description : Determine if two strings are identical.
*
* Argument(s) : p1_str Pointer to first string (see Note #1).
*
* p2_str Pointer to second string (see Note #1).
*
* Return(s) : 0, if strings are identical (see Notes #2a, #2e, & #2f).
*
* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d).
*
* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d).
*
* Caller(s) : various.
*
* Note(s) : (1) String buffers NOT modified.
*
* (2) String comparison terminates when :
*
* (a) BOTH string pointer(s) are passed NULL pointers.
* (1) NULL strings identical; return 0.
*
* (b) 'p1_str' passed a NULL pointer.
* (1) Return negative value of character pointed to by 'p2_str'.
*
* (c) 'p2_str' passed a NULL pointer.
* (1) Return positive value of character pointed to by 'p1_str'.
*
* (d) Non-matching characters found.
* (1) Return signed-integer difference of the character pointed to by 'p2_str'
* from the character pointed to by 'p1_str'.
*
* (e) Terminating NULL character found in both strings.
* (1) Strings identical; return 0.
* (2) Only one NULL character test required in conditional since previous condition
* tested character equality.
*
* (f) BOTH strings point to NULL.
* (1) Strings overlap with NULL address.
* (2) Strings identical up to but NOT beyond or including the NULL address; return 0.
*
* (g) 'p1_str_next' points to NULL.
* (1) 'p1_str' overlaps with NULL address.
* (2) Strings compared up to but NOT beyond or including the NULL address.
* (3) Return negative value of character pointed to by 'p2_str_next'.
*
* (h) 'p2_str_next' points to NULL.
* (1) 'p2_str' overlaps with NULL address.
* (2) Strings compared up to but NOT beyond or including the NULL address.
* (3) Return positive value of character pointed to by 'p1_str_next'.
*
* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
* return value, 'CPU_CHAR' native data type size MUST be 8-bit.
*********************************************************************************************************
*/
/*$PAGE*/
CPU_INT16S Str_Cmp (CPU_CHAR *p1_str,
CPU_CHAR *p2_str)
{
CPU_CHAR *p1_str_next;
CPU_CHAR *p2_str_next;
CPU_INT16S cmp_val;
if (p1_str == (CPU_CHAR *)0) {
if (p2_str == (CPU_CHAR *)0) {
return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */
}
cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str);
return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */
}
if (p2_str == (CPU_CHAR *)0) {
cmp_val = (CPU_INT16S)(*p1_str);
return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */
}
p1_str_next = p1_str;
p2_str_next = p2_str;
p1_str_next++;
p2_str_next++;
while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */
(*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */
( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h). */
( p2_str_next != (CPU_CHAR *)0)) {
p1_str_next++;
p2_str_next++;
p1_str++;
p2_str++;
}
if (*p1_str != *p2_str) { /* If strs NOT identical, ... */
cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */
} else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */
cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */
} else {
if (p1_str_next == (CPU_CHAR *)0) {
if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */
cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */
} else { /* If p1_str_next NULL, ... */
cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */
}
} else { /* If p2_str_next NULL, ... */
cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */
}
}
return (cmp_val);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Cmp_N()
*
* Description : Determine if two strings are identical for up to a maximum number of characters.
*
* Argument(s) : p1_str Pointer to first string (see Note #1).
*
* p2_str Pointer to second string (see Note #1).
*
* len_max Maximum number of characters to compare (see Notes #2i & #2j).
*
* Return(s) : 0, if strings are identical (see Notes #2a, #2e, #2f, #2i, & #2j).
*
* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d).
*
* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d).
*
* Caller(s) : various.
*
* Note(s) : (1) String buffers NOT modified.
*
* (2) String comparison terminates when :
*
* (a) BOTH string pointer(s) are passed NULL pointers.
* (1) NULL strings identical; return 0.
*
* (b) 'p1_str' passed a NULL pointer.
* (1) Return negative value of character pointed to by 'p2_str'.
*
* (c) 'p2_str' passed a NULL pointer.
* (1) Return positive value of character pointed to by 'p1_str'.
*
* (d) Non-matching characters found.
* (1) Return signed-integer difference of the character pointed to by 'p2_str'
* from the character pointed to by 'p1_str'.
*
* (e) Terminating NULL character found in both strings.
* (1) Strings identical; return 0.
* (2) Only one NULL character test required in conditional since previous condition
* tested character equality.
*
* (f) BOTH strings point to NULL.
* (1) Strings overlap with NULL address.
* (2) Strings identical up to but NOT beyond or including the NULL address; return 0.
*
* (g) 'p1_str_next' points to NULL.
* (1) 'p1_str' overlaps with NULL address.
* (2) Strings compared up to but NOT beyond or including the NULL address.
* (3) Return negative value of character pointed to by 'p2_str_next'.
*
* (h) 'p2_str_next' points to NULL.
* (1) 'p2_str' overlaps with NULL address.
* (2) Strings compared up to but NOT beyond or including the NULL address.
* (3) Return positive value of character pointed to by 'p1_str_next'.
*
* (i) 'len_max' passed a zero length.
* (1) Zero-length strings identical; return 0.
*
* (j) First 'len_max' number of characters identical.
* (1) Strings identical; return 0.
*
* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
* return value, 'CPU_CHAR' native data type size MUST be 8-bit.
*********************************************************************************************************
*/
/*$PAGE*/
CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str,
CPU_CHAR *p2_str,
CPU_SIZE_T len_max)
{
CPU_CHAR *p1_str_next;
CPU_CHAR *p2_str_next;
CPU_INT16S cmp_val;
CPU_SIZE_T cmp_len;
if (len_max == 0) { /* If cmp len equals zero, rtn 0 (see Note #2i). */
return ((CPU_INT16S)0);
}
if (p1_str == (CPU_CHAR *)0) {
if (p2_str == (CPU_CHAR *)0) {
return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */
}
cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str);
return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */
}
if (p2_str == (CPU_CHAR *)0) {
cmp_val = (CPU_INT16S)(*p1_str);
return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */
}
p1_str_next = p1_str;
p2_str_next = p2_str;
p1_str_next++;
p2_str_next++;
cmp_len = 0;
while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */
(*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */
( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h); */
( p2_str_next != (CPU_CHAR *)0) &&
( cmp_len < (CPU_SIZE_T)len_max)) { /* .. or len nbr chars cmp'd (see Note #2j). */
p1_str_next++;
p2_str_next++;
p1_str++;
p2_str++;
cmp_len++;
}
if (cmp_len == len_max) { /* If strs identical for len nbr of chars, */
return ((CPU_INT16S)0); /* ... rtn 0 (see Note #2j). */
}
if (*p1_str != *p2_str) { /* If strs NOT identical, ... */
cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */
} else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */
cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */
} else {
if (p1_str_next == (CPU_CHAR *)0) {
if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */
cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */
} else { /* If p1_str_next NULL, ... */
cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */
}
} else { /* If p2_str_next NULL, ... */
cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */
}
}
return (cmp_val);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Char()
*
* Description : Search string for first occurrence of specific character.
*
* Argument(s) : pstr Pointer to string (see Note #1).
*
* srch_char Search character.
*
* Return(s) : Pointer to first occurrence of search character in string, if any.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) String buffer NOT modified.
*
* (2) String search terminates when :
*
* (a) String pointer passed a NULL pointer.
* (1) No string search performed; NULL pointer returned.
*
* (b) String pointer points to NULL.
* (1) String overlaps with NULL address.
* (2) String searched up to but NOT beyond or including the NULL address.
*
* (c) String's terminating NULL character found.
* (1) Search character NOT found in search string; NULL pointer returned.
* (2) Applicable ONLY IF search character is NOT the terminating NULL character.
*
* (d) Search character found.
* (1) Return pointer to first occurrence of search character in search string.
*********************************************************************************************************
*/
CPU_CHAR *Str_Char (CPU_CHAR *pstr,
CPU_CHAR srch_char)
{
CPU_CHAR *pstr_next;
if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */
return ((CPU_CHAR *)0);
}
pstr_next = pstr;
pstr_next++;
while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */
(*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */
(*pstr != (CPU_CHAR )srch_char)) { /* ... or srch char found (see Note #2d). */
pstr++;
pstr_next++;
}
if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */
return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */
}
return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Char_N()
*
* Description : Search string for first occurrence of specific character, up to a maximum number of characters.
*
* Argument(s) : pstr Pointer to string (see Note #1).
*
* len_max Maximum number of characters to search (see Notes #2e & #3).
*
* srch_char Search character.
*
* Return(s) : Pointer to first occurrence of search character in string, if any.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) String buffer NOT modified.
*
* (2) String search terminates when :
*
* (a) String pointer passed a NULL pointer.
* (1) No string search performed; NULL pointer returned.
*
* (b) String pointer points to NULL.
* (1) String overlaps with NULL address.
* (2) String searched up to but NOT beyond or including the NULL address.
*
* (c) String's terminating NULL character found.
* (1) Search character NOT found in search string; NULL pointer returned.
* (2) Applicable ONLY IF search character is NOT the terminating NULL character.
*
* (d) Search character found.
* (1) Return pointer to first occurrence of search character in search string.
*
* (e) 'len_max' number of characters searched.
* (1) 'len_max' number of characters does NOT include terminating NULL character.
*
* (3) Ideally, the 'len_max' parameter would be the last parameter in this function's
* paramter list for consistency with all other custom string library functions.
* However, the 'len_max' parameter is ordered to comply with the standard library
* function's parameter list.
*********************************************************************************************************
*/
CPU_CHAR *Str_Char_N (CPU_CHAR *pstr,
CPU_SIZE_T len_max,
CPU_CHAR srch_char)
{
CPU_CHAR *pstr_next;
CPU_SIZE_T len_srch;
if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */
return ((CPU_CHAR *)0);
}
if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if srch len equals zero (see Note #2e). */
return ((CPU_CHAR *)0);
}
pstr_next = pstr;
pstr_next++;
len_srch = 0;
while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */
(*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */
(*pstr != (CPU_CHAR )srch_char) && /* ... or srch char found (see Note #2d); ... */
( len_srch < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars srch'd (see Note #2e). */
pstr++;
pstr_next++;
len_srch++;
}
if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */
return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */
}
return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Char_Last()
*
* Description : Search string for last occurrence of specific character.
*
* Argument(s) : pstr Pointer to string (see Note #1).
*
* srch_char Search character.
*
* Return(s) : Pointer to last occurrence of search character in string, if any.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) String buffer NOT modified.
*
* (2) String search terminates when :
*
* (a) String pointer passed a NULL pointer.
* (1) No string search performed; NULL pointer returned.
*
* (b) String pointer points to NULL.
* (1) String overlaps with NULL address.
* (2) String searched up to but NOT beyond or including the NULL address.
* (3) NULL address boundary handled in Str_Len().
*
* (c) String searched from end to beginning.
* (1) Search character NOT found in search string; NULL pointer returned.
* (2) Applicable ONLY IF search character is NOT the terminating NULL character.
*
* (d) Search character found.
* (1) Return pointer to first occurrence of search character in search string.
*********************************************************************************************************
*/
CPU_CHAR *Str_Char_Last (CPU_CHAR *pstr,
CPU_CHAR srch_char)
{
CPU_CHAR *pstr_next;
CPU_SIZE_T str_len;
if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */
return ((CPU_CHAR *)0);
}
pstr_next = pstr;
str_len = Str_Len(pstr);
pstr_next += str_len;
while (( pstr_next != pstr) && /* Srch str from end until beg (see Note #2c) ... */
(*pstr_next != srch_char)) { /* ... until srch char found (see Note #2d). */
pstr_next--;
}
if (*pstr_next != srch_char) { /* If srch char NOT found, str points to NULL; ... */
return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */
}
return (pstr_next); /* Else rtn ptr to found srch char (see Note #2d). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_Str()
*
* Description : Search string for first occurence of a specific search string.
*
* Argument(s) : pstr Pointer to string (see Note #1).
*
* psrch_str Pointer to search string (see Note #1).
*
* Return(s) : Pointer to first occurrence of search string in string, if any.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) String buffers NOT modified.
*
* (2) String search terminates when :
*
* (a) String pointer passed a NULL pointer.
* (1) No string search performed; NULL pointer returned.
*
* (b) Search string length greater than string length.
* (1) No string search performed; NULL pointer returned.
*
* (c) Search string length equal to zero.
* (1) NULL search string at end of string returned.
*
* (d) Entire string has been searched.
* (1) Maximum size of the search is defined as the subtraction of the
* search string length from the string length.
* (2) Search string not found; NULL pointer returned.
*
* (e) Search string found.
* (1) Search string found according to Str_Cmp_N() return value.
* (2) Return pointer to first occurrence of search string in string.
*********************************************************************************************************
*/
CPU_CHAR *Str_Str (CPU_CHAR *pstr,
CPU_CHAR *psrch_str)
{
CPU_SIZE_T str_len;
CPU_SIZE_T srch_str_len;
CPU_SIZE_T srch_len;
CPU_SIZE_T srch_ix;
CPU_BOOLEAN srch_done;
CPU_INT16S srch_cmp;
CPU_CHAR *pstr_srch_ix;
/* Rtn NULL if str ptr(s) NULL (see Note #2a). */
if (pstr == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
if (psrch_str == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
str_len = Str_Len(pstr);
srch_str_len = Str_Len(psrch_str);
if (srch_str_len > str_len) { /* If srch str len > str len, rtn NULL (see Note #2b). */
return ((CPU_CHAR *)0);
}
if (srch_str_len == 0) { /* If srch str len = 0, srch str equal NULL str; ... */
pstr_srch_ix = (CPU_CHAR *)(pstr + str_len); /* ... rtn ptr to NULL str found in str (see Note #2c). */
return (pstr_srch_ix);
}
srch_len = str_len - srch_str_len; /* Determine srch len (see Note #2d1). */
srch_ix = 0;
srch_done = DEF_NO;
while ((srch_done == DEF_NO) && (srch_ix <= srch_len)) {
pstr_srch_ix = (CPU_CHAR *)(pstr + srch_ix);
srch_cmp = Str_Cmp_N(pstr_srch_ix, psrch_str, srch_str_len);
srch_done = (srch_cmp == 0) ? DEF_YES : DEF_NO;
srch_ix++;
}
if (srch_cmp != 0) { /* If srch str NOT found, rtn NULL (see Note #2d). */
return ((CPU_CHAR *)0);
}
return (pstr_srch_ix); /* Rtn ptr to srch str found in str (see Note #2e). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* Str_FmtNbr_32()
*
* Description : Format number into a multi-digit character string.
*
* Argument(s) : nbr Number to format (see Note #1).
*
* nbr_dig Number of integer digits to format (see Note #2).
*
* nbr_dp Number of decimal point digits to format.
*
* lead_zeros Prepend leading zeros option (DEF_YES/DEF_NO) [see Note #3].
*
* nul NULL-character terminate option (DEF_YES/DEF_NO) [see Note #4].
*
* pstr_fmt Pointer to character array to return formatted number string (see Note #5).
*
* Return(s) : Pointer to formatted string, if NO errors (see Note #6).
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) (a) The maximum accuracy for 32-bit floating-point numbers :
*
*
* Maximum Accuracy log [Internal-Base ^ (Number-Internal-Base-Digits)]
* 32-bit Floating-point Number = -----------------------------------------------------
* log [External-Base]
*
* log [2 ^ 24]
* = --------------
* log [10]
*
* < 7.225 Base-10 Digits
*
* where
* Internal-Base Internal number base of floating-
* point numbers (i.e. 2)
* External-Base External number base of floating-
* point numbers (i.e. 10)
* Number-Internal-Base-Digits Number of internal number base
* significant digits (i.e. 24)
*
* (b) Some compilers' floating-point routines MAY further reduce the maximum accuracy.
*
* (c) If the total number of digits to format ('nbr_dig + nbr_dp') is greater than the
* maximum accuracy; digits following the first, significantly-accurate digits will
* be inaccurate.
*
* (2) (a) If the number of digits to format ('nbr_dig') is less than the number of significant
* integer digits of the number to format ('nbr'); then the most-significant digits of
* the formatted number will be truncated.
*
* Example :
*
* nbr = 23456.789
* nbr_dig = 3
* nbr_dp = 2
*
* pstr_fmt = "456.78"
*
* (b) If number to format ('nbr') is negative but the most-significant digits of the
* formatted number are truncated (see Note #2a); the negative sign still prefixes
* the truncated formatted number.
*
* Example :
*
* nbr = -23456.789
* nbr_dig = 3
* nbr_dp = 2
*
* pstr_fmt = "-456.78"
*
* (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit.
* The number of leading zeros is such that the total number integer digits is
* equal to the requested number of integer digits to format ('nbr_dig').
*
* (b) (1) If leading zeros option DISABLED, ...
* (2) ... number of digits to format is non-zero, ...
* (3) ... & the integer value of the number to format is zero; ...
* (4) ... then one digit of '0' value is formatted.
*
* This is NOT a leading zero; but a single integer digit of '0' value.
*
* (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
* array formatting.
*
* (b) WARNING: Unless 'pstr_fmt' character array is pre-/post-terminated, NULL-character
* terminate option DISABLED will cause character string run-on.
*$PAGE*
* (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
*
* (b) To prevent character buffer overrun :
*
* Character array size MUST be >= ('nbr_dig' +
* 'nbr_dp' +
* 1 negative sign +
* 1 decimal point +
* 1 'NUL' terminator) characters
*
* (6) String format terminates when :
*
* (a) Format string pointer is passed a NULL pointer.
* (1) No string format performed; NULL pointer returned.
*
* (b) Number successfully formatted into character string array.
*********************************************************************************************************
*/
#if (LIB_STR_CFG_FP_EN == DEF_ENABLED)
CPU_CHAR *Str_FmtNbr_32 (CPU_FP32 nbr,
CPU_INT08U nbr_dig,
CPU_INT08U nbr_dp,
CPU_BOOLEAN lead_zeros,
CPU_BOOLEAN nul,
CPU_CHAR *pstr_fmt)
{
CPU_CHAR *pstr;
CPU_INT08U i;
CPU_INT32U dig_nbr;
CPU_INT32U dig_val;
CPU_FP32 dig_exp;
CPU_FP32 dp_exp;
/* Rtn NULL if str ptr NULL (see Note #6a). */
if (pstr_fmt == (CPU_CHAR *)0) {
return ((CPU_CHAR *)0);
}
pstr = pstr_fmt;
if (nbr < 0.0) { /* If nbr neg, ... */
if ((nbr_dig > 0) || /* ... & at least one dig ... */
(nbr_dp > 0)) { /* ... or at least one dp; ... */
nbr = -nbr; /* ... negate nbr & ... */
*pstr++ = '-'; /* ... prefix with neg sign (see Note #2b). */
}
}
if (nbr_dig > 0) {
dig_exp = 1.0;
for (i = 1; i < nbr_dig; i++) {
dig_exp *= 10.0;
}
for (i = nbr_dig; i > 0; i--) { /* Fmt str for desired nbr digs. */
dig_nbr = (CPU_INT32U)(nbr / dig_exp);
if ((dig_nbr > 0) || /* If dig nbr > 0, ... */
(nbr_dig == 1) || /* ... OR exactly 1 dig to fmt, ... */
(i == 1) || /* ... OR on one's dig to fmt, ... */
(lead_zeros == DEF_YES)) { /* ... OR lead zeros opt ENABLED (see Note #3), ... */
/* ... calc & fmt dig val. */
dig_val = (CPU_INT32U)(dig_nbr % 10 );
*pstr++ = (CPU_CHAR )(dig_val + '0');
}
dig_exp /= 10.0; /* Shift to next least-significant dig. */
}
}
if (nbr_dp > 0) {
*pstr++ = '.'; /* Append dp prior to dp conversion. */
dp_exp = 10.0;
for (i = 0; i < nbr_dp; i++) { /* Fmt str for desired nbr dp. */
dig_nbr = (CPU_INT32U)(nbr * dp_exp );
dig_val = (CPU_INT32U)(dig_nbr % 10 );
*pstr++ = (CPU_CHAR )(dig_val + '0');
dp_exp *= 10.0; /* Shift to next least-significant dp. */
}
}
if (nul != DEF_NO) { /* If NOT DISABLED, append NULL char (see Note #4). */
*pstr = (CPU_CHAR)0;
}
return (pstr_fmt);
}
#endif