mirror of
https://github.com/dimoniche/changer.git
synced 2026-01-30 09:13:31 +03:00
1249 lines
53 KiB
C
1249 lines
53 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* 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
|
||
|