lib_str.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:55k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                               uC/LIB
  4. *                                       CUSTOM LIBRARY MODULES
  5. *
  6. *                          (c) Copyright 2004-2008; Micrium, Inc.; Weston, FL
  7. *
  8. *               All rights reserved.  Protected by international copyright laws.
  9. *
  10. *               uC/LIB is provided in source form for FREE evaluation, for educational
  11. *               use or peaceful research.  If you plan on using uC/LIB in a commercial
  12. *               product you need to contact Micrium to properly license its use in your
  13. *               product.  We provide ALL the source code for your convenience and to
  14. *               help you experience uC/LIB.  The fact that the source code is provided
  15. *               does NOT mean that you can use it without paying a licensing fee.
  16. *
  17. *               Knowledge of the source code may NOT be used to develop a similar product.
  18. *
  19. *               Please help us continue to provide the Embedded community with the finest
  20. *               software available.  Your honesty is greatly appreciated.
  21. *********************************************************************************************************
  22. */
  23. /*
  24. *********************************************************************************************************
  25. *
  26. *                                       ASCII STRING MANAGEMENT
  27. *
  28. * Filename      : lib_str.c
  29. * Version       : V1.25
  30. * Programmer(s) : ITJ
  31. *                 JDH
  32. *********************************************************************************************************
  33. * Note(s)       : (1) NO compiler-supplied standard library functions are used in library or product software.
  34. *
  35. *                     (a) ALL standard library functions are implemented in the custom library modules :
  36. *
  37. *                         (1) <Custom Library Directory>lib*.*
  38. *
  39. *                         (2) <Custom Library Directory>Ports<cpu><compiler>lib*_a.*
  40. *
  41. *                               where
  42. *                                       <Custom Library Directory>      directory path for custom library software
  43. *                                       <cpu>                           directory name for specific processor (CPU)
  44. *                                       <compiler>                      directory name for specific compiler
  45. *
  46. *                     (b) Product-specific library functions are implemented in individual products.
  47. *********************************************************************************************************
  48. */
  49. /*
  50. *********************************************************************************************************
  51. *                                            INCLUDE FILES
  52. *********************************************************************************************************
  53. */
  54. #define    LIB_STR_MODULE
  55. #include  <lib_str.h>
  56. /*$PAGE*/
  57. /*
  58. *********************************************************************************************************
  59. *                                            LOCAL DEFINES
  60. *********************************************************************************************************
  61. */
  62. /*
  63. *********************************************************************************************************
  64. *                                           LOCAL CONSTANTS
  65. *********************************************************************************************************
  66. */
  67. /*
  68. *********************************************************************************************************
  69. *                                          LOCAL DATA TYPES
  70. *********************************************************************************************************
  71. */
  72. /*
  73. *********************************************************************************************************
  74. *                                            LOCAL TABLES
  75. *********************************************************************************************************
  76. */
  77. /*
  78. *********************************************************************************************************
  79. *                                       LOCAL GLOBAL VARIABLES
  80. *********************************************************************************************************
  81. */
  82. /*
  83. *********************************************************************************************************
  84. *                                      LOCAL FUNCTION PROTOTYPES
  85. *********************************************************************************************************
  86. */
  87. /*
  88. *********************************************************************************************************
  89. *                                     LOCAL CONFIGURATION ERRORS
  90. *********************************************************************************************************
  91. */
  92. /*$PAGE*/
  93. /*
  94. *********************************************************************************************************
  95. *                                              Str_Len()
  96. *
  97. * Description : Calculate length of a string.
  98. *
  99. * Argument(s) : pstr        Pointer to string (see Note #1).
  100. *
  101. * Return(s)   : Length of string; number of characters in string before terminating NULL character.
  102. *
  103. * Caller(s)   : Application.
  104. *
  105. * Note(s)     : (1) String buffer NOT modified.
  106. *
  107. *               (2) String length calculation terminates when :
  108. *
  109. *                   (a) String pointer points to NULL.
  110. *                       (1) String buffer overlaps with NULL address.
  111. *                       (2) String length calculated for string up to but NOT beyond or including
  112. *                           the NULL address.
  113. *
  114. *                   (b) Terminating NULL character found.
  115. *                       (1) String length calculated for string up to but NOT           including
  116. *                           the NULL character.
  117. *********************************************************************************************************
  118. */
  119. CPU_SIZE_T  Str_Len (CPU_CHAR  *pstr)
  120. {
  121.     CPU_SIZE_T  len;
  122.     len = 0;
  123.     while (( pstr != (CPU_CHAR *)0) &&                          /* Calc str len until NULL ptr (see Note #2a) ...       */
  124.            (*pstr != (CPU_CHAR  )0)) {                          /* ... or NULL char found      (see Note #2b).          */
  125.         len++;
  126.         pstr++;
  127.     }
  128.     return (len);
  129. }
  130. /*$PAGE*/
  131. /*
  132. *********************************************************************************************************
  133. *                                             Str_Copy()
  134. *
  135. * Description : Copy source string to destination string buffer.
  136. *
  137. * Argument(s) : pdest       Pointer to destination string buffer to receive source string copy (see Note #1).
  138. *
  139. *               psrc        Pointer to source      string to copy into destination string buffer.
  140. *
  141. * Return(s)   : Pointer to destination string, if NO errors (see Note #2).
  142. *
  143. *               Pointer to NULL,               otherwise.
  144. *
  145. * Caller(s)   : Application.
  146. *
  147. * Note(s)     : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
  148. *
  149. *                   (a) Destination buffer size MUST be large enough to accommodate the entire source 
  150. *                       string size including the terminating NULL character.
  151. *
  152. *               (2) String copy terminates when :
  153. *
  154. *                   (a) Destination/Source string pointer(s) are passed NULL pointers.
  155. *                       (1) No string copy performed; NULL pointer returned.
  156. *
  157. *                   (b) Destination/Source string pointer(s) points to NULL.
  158. *                       (1) String buffer(s) overlap with NULL address.
  159. *                       (2) Source string copied into destination string buffer up to but NOT beyond or
  160. *                           including the NULL address; destination string buffer properly terminated
  161. *                           with NULL character.
  162. *
  163. *                   (c) Source string's terminating NULL character found.
  164. *                       (1) Entire source string copied into destination string buffer.
  165. *********************************************************************************************************
  166. */
  167. CPU_CHAR  *Str_Copy (CPU_CHAR  *pdest,
  168.                      CPU_CHAR  *psrc)
  169. {
  170.     CPU_CHAR  *pstr;
  171.     CPU_CHAR  *pstr_next;
  172.                                                                 /* Rtn NULL if str ptr(s) NULL (see Note #2a).          */
  173.     if (pdest == (CPU_CHAR *)0) {
  174.         return  ((CPU_CHAR *)0);
  175.     }
  176.     if (psrc  == (CPU_CHAR *)0) {
  177.         return  ((CPU_CHAR *)0);
  178.     }
  179.     pstr      = pdest;
  180.     pstr_next = pstr;
  181.     pstr_next++;
  182.     while (( pstr_next != (CPU_CHAR *)0) &&                     /* Copy str until NULL ptr(s) (see Note #2b) ...        */
  183.            ( psrc      != (CPU_CHAR *)0) &&
  184.            (*psrc      != (CPU_CHAR  )0)) {                     /* ... or NULL char found     (see Note #2c).           */
  185.        *pstr = *psrc;
  186.         pstr++;
  187.         pstr_next++;
  188.         psrc++;
  189.     }
  190.    *pstr = (CPU_CHAR)0;                                         /* Append NULL char (see Note #2b2).                    */
  191.     return (pdest);
  192. }
  193. /*$PAGE*/
  194. /*
  195. *********************************************************************************************************
  196. *                                            Str_Copy_N()
  197. *
  198. * Description : Copy source string to destination string buffer, up to a maximum number of characters.
  199. *
  200. * Argument(s) : pdest       Pointer to destination string buffer to receive source string copy (see Note #1).
  201. *
  202. *               psrc        Pointer to source      string to copy into destination string buffer.
  203. *
  204. *               len_max     Maximum number of characters to copy (see Note #2d).
  205. *
  206. * Return(s)   : Pointer to destination string, if NO errors (see Note #2).
  207. *
  208. *               Pointer to NULL,               otherwise.
  209. *
  210. * Caller(s)   : Application.
  211. *
  212. * Note(s)     : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller.
  213. *
  214. *                   (a) Destination buffer size MUST be large enough to accommodate the entire source 
  215. *                       string size including the terminating NULL character.
  216. *
  217. *               (2) String copy terminates when :
  218. *
  219. *                   (a) Destination/Source string pointer(s) are passed NULL pointers.
  220. *                       (1) No string copy performed; NULL pointer returned.
  221. *
  222. *                   (b) Destination/Source string pointer(s) points to NULL.
  223. *                       (1) String buffer(s) overlap with NULL address.
  224. *                       (2) Source string copied into destination string buffer up to but NOT beyond or
  225. *                           including the NULL address; destination string buffer properly terminated
  226. *                           with NULL character.
  227. *
  228. *                   (c) Source string's terminating NULL character found.
  229. *                       (1) Entire source string copied into destination string buffer.
  230. *
  231. *                   (d) 'len_max' number of characters copied.
  232. *                       (1) 'len_max' number of characters does NOT include the terminating NULL character.
  233. *
  234. *                           See also Note #1a.
  235. *********************************************************************************************************
  236. */
  237. CPU_CHAR  *Str_Copy_N (CPU_CHAR    *pdest,
  238.                        CPU_CHAR    *psrc,
  239.                        CPU_SIZE_T   len_max)
  240. {
  241.     CPU_CHAR    *pstr;
  242.     CPU_CHAR    *pstr_next;
  243.     CPU_SIZE_T   len_copy;
  244.                                                                 /* Rtn NULL if str ptr(s) NULL      (see Note #2a).     */
  245.     if (pdest == (CPU_CHAR *)0) {
  246.         return  ((CPU_CHAR *)0);
  247.     }
  248.     if (psrc  == (CPU_CHAR *)0) {
  249.         return  ((CPU_CHAR *)0);
  250.     }
  251.     if (len_max == (CPU_SIZE_T)0) {                             /* Rtn NULL if copy len equals zero (see Note #2d).     */
  252.         return  ((CPU_CHAR *)0);
  253.     }
  254.     pstr      = pdest;
  255.     pstr_next = pstr;
  256.     pstr_next++;
  257.     len_copy  = 0;
  258.     while (( pstr_next != (CPU_CHAR *)0) &&                     /* Copy str until NULL ptr(s)  (see Note #2b)  ...      */
  259.            ( psrc      != (CPU_CHAR *)0) &&
  260.            (*psrc      != (CPU_CHAR  )0) &&                     /* ... or NULL char found      (see Note #2c); ...      */
  261.            ( len_copy  <  (CPU_SIZE_T)len_max)) {               /* ... or max nbr chars copied (see Note #2d).          */
  262.        *pstr = *psrc;
  263.         pstr++;
  264.         pstr_next++;
  265.         psrc++;
  266.         len_copy++;
  267.     }
  268.    *pstr = (CPU_CHAR)0;                                         /* Append NULL char (see Note #2b2).                    */
  269.     return (pdest);
  270. }
  271. /*$PAGE*/
  272. /*
  273. *********************************************************************************************************
  274. *                                              Str_Cat()
  275. *
  276. * Description : Append concatenation string to destination string.
  277. *
  278. * Argument(s) : pdest       Pointer to destination   string to append concatenation  string (see Note #1).
  279. *
  280. *               pstr_cat    Pointer to concatenation string to append to destination string.
  281. *
  282. * Return(s)   : Pointer to destination string, if NO errors (see Note #2).
  283. *
  284. *               Pointer to NULL,               otherwise.
  285. *
  286. * Caller(s)   : Application.
  287. *
  288. * Note(s)     : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller.
  289. *
  290. *                   (a) Destination buffer size MUST be large enough to accommodate the entire concatenated
  291. *                       string size including the terminating NULL character.
  292. *
  293. *               (2) String concatenation terminates when :
  294. *
  295. *                   (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
  296. *                       (1) No string concatenation performed; NULL pointer returned.
  297. *
  298. *                   (b) Destination string overlaps with NULL address.
  299. *                       (1) No string concatenation performed; NULL pointer returned.
  300. *
  301. *                   (c) Destination/Concatenation string pointer(s) points to NULL.
  302. *                       (1) String buffer(s) overlap with NULL address.
  303. *                       (2) Concatenation string appended into destination string buffer up to but NOT
  304. *                           beyond or including the NULL address; destination string buffer properly
  305. *                           terminated with NULL character.
  306. *
  307. *                   (d) Concatenation string's terminating NULL character found.
  308. *                       (1) Entire concatenation string appended to destination string.
  309. *********************************************************************************************************
  310. */
  311. CPU_CHAR  *Str_Cat (CPU_CHAR  *pdest,
  312.                     CPU_CHAR  *pstr_cat)
  313. {
  314.     CPU_CHAR  *pstr;
  315.     CPU_CHAR  *pstr_next;
  316.                                                                 /* Rtn NULL if str ptr(s) NULL (see Note #2a).          */
  317.     if (pdest == (CPU_CHAR *)0) {
  318.         return  ((CPU_CHAR *)0);
  319.     }
  320.     if (pstr_cat == (CPU_CHAR *)0) {
  321.         return  ((CPU_CHAR *)0);
  322.     }
  323.     pstr = pdest;
  324.     while (( pstr != (CPU_CHAR *)0) &&                          /* Adv to end of cur dest str until NULL ptr ...        */
  325.            (*pstr != (CPU_CHAR  )0)) {                          /* ... or NULL char found..                             */
  326.         pstr++;
  327.     }
  328.     if (pstr == (CPU_CHAR *)0) {                                /* If NULL str overrun, rtn NULL (see Note #2b).        */
  329.         return ((CPU_CHAR *)0);
  330.     }
  331.     pstr_next = pstr;
  332.     pstr_next++;
  333.     while (( pstr_next != (CPU_CHAR *)0) &&                     /* Cat str until NULL ptr(s) (see Note #2c) ...         */
  334.            ( pstr_cat  != (CPU_CHAR *)0) &&
  335.            (*pstr_cat  != (CPU_CHAR  )0)) {                     /* ... or NULL char found    (see Note #2d).            */
  336.        *pstr = *pstr_cat;
  337.         pstr++;
  338.         pstr_next++;
  339.         pstr_cat++;
  340.     }
  341.    *pstr = (CPU_CHAR)0;                                         /* Append NULL char (see Note #2c2).                    */
  342.     return (pdest);
  343. }
  344. /*$PAGE*/
  345. /*
  346. *********************************************************************************************************
  347. *                                             Str_Cat_N()
  348. *
  349. * Description : Append concatenation string to destination string, up to a maximum number of characters.
  350. *
  351. * Argument(s) : pdest       Pointer to destination   string to append concatenation  string (see Note #1).
  352. *
  353. *               pstr_cat    Pointer to concatenation string to append to destination string.
  354. *
  355. *               len_max     Maximum number of characters to concatenate (see Note #2e).
  356. *
  357. * Return(s)   : Pointer to destination string, if NO errors (see Note #2).
  358. *
  359. *               Pointer to NULL,               otherwise.
  360. *
  361. * Caller(s)   : Application.
  362. *
  363. * Note(s)     : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller.
  364. *
  365. *                   (a) Destination buffer size MUST be large enough to accommodate the entire concatenated
  366. *                       string size including the terminating NULL character.
  367. *
  368. *               (2) String concatenation terminates when :
  369. *
  370. *                   (a) Destination/Concatenation string pointer(s) are passed NULL pointers.
  371. *                       (1) No string concatenation performed; NULL pointer returned.
  372. *
  373. *                   (b) Destination string overlaps with NULL address.
  374. *                       (1) No string concatenation performed; NULL pointer returned.
  375. *
  376. *                   (c) Destination/Concatenation string pointer(s) points to NULL.
  377. *                       (1) String buffer(s) overlap with NULL address.
  378. *                       (2) Concatenation string appended into destination string buffer up to but NOT
  379. *                           beyond or including the NULL address; destination string buffer properly
  380. *                           terminated with NULL character.
  381. *
  382. *                   (d) Concatenation string's terminating NULL character found.
  383. *                       (1) Entire concatenation string appended to destination string.
  384. *
  385. *                   (e) 'len_max' number of characters concatenated.
  386. *                       (1) 'len_max' number of characters does NOT include the terminating NULL character.
  387. *
  388. *                           See also Note #1a.
  389. *********************************************************************************************************
  390. */
  391. /*$PAGE*/
  392. CPU_CHAR  *Str_Cat_N (CPU_CHAR    *pdest,
  393.                       CPU_CHAR    *pstr_cat,
  394.                       CPU_SIZE_T   len_max)
  395. {
  396.     CPU_CHAR    *pstr;
  397.     CPU_CHAR    *pstr_next;
  398.     CPU_SIZE_T   len_cat;
  399.                                                                 /* Rtn NULL if str ptr(s) NULL     (see Note #2a).      */
  400.     if (pdest == (CPU_CHAR *)0) {
  401.         return  ((CPU_CHAR *)0);
  402.     }
  403.     if (pstr_cat == (CPU_CHAR *)0) {
  404.         return  ((CPU_CHAR *)0);
  405.     }
  406.     if (len_max == (CPU_SIZE_T)0) {                             /* Rtn NULL if cat len equals zero (see Note #2e).      */
  407.         return  ((CPU_CHAR *)0);
  408.     }
  409.     pstr = pdest;
  410.     while (( pstr != (CPU_CHAR *)0) &&                          /* Adv to end of cur dest str until NULL ptr ...        */
  411.            (*pstr != (CPU_CHAR  )0)) {                          /* ... or NULL char found..                             */
  412.         pstr++;
  413.     }
  414.     if (pstr == (CPU_CHAR *)0) {                                /* If NULL str overrun, rtn NULL (see Note #2b).        */
  415.         return ((CPU_CHAR *)0);
  416.     }
  417.     pstr_next = pstr;
  418.     pstr_next++;
  419.     len_cat   = 0;
  420.     while (( pstr_next != (CPU_CHAR *)0) &&                     /* Cat str until NULL ptr(s)  (see Note #2c)  ...       */
  421.            ( pstr_cat  != (CPU_CHAR *)0) &&
  422.            (*pstr_cat  != (CPU_CHAR  )0) &&                     /* ... or NULL char found     (see Note #2d); ...       */
  423.            ( len_cat   <  (CPU_SIZE_T)len_max)) {               /* ... or max nbr chars cat'd (see Note #2d).           */
  424.        *pstr = *pstr_cat;
  425.         pstr++;
  426.         pstr_next++;
  427.         pstr_cat++;
  428.         len_cat++;
  429.     }
  430.    *pstr = (CPU_CHAR)0;                                         /* Append NULL char (see Note #2c2).                    */
  431.     return (pdest);
  432. }
  433. /*$PAGE*/
  434. /*
  435. *********************************************************************************************************
  436. *                                              Str_Cmp()
  437. *
  438. * Description : Determine if two strings are identical.
  439. *
  440. * Argument(s) : p1_str      Pointer to first  string (see Note #1).
  441. *
  442. *               p2_str      Pointer to second string (see Note #1).
  443. *
  444. * Return(s)   : 0,              if strings are identical             (see Notes #2a, #2e, & #2f).
  445. *
  446. *               Negative value, if 'p1_str' is less    than 'p2_str' (see Notes #2b, #2g, & #2d).
  447. *
  448. *               Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d).
  449. *
  450. * Caller(s)   : Application.
  451. *
  452. * Note(s)     : (1) String buffers NOT modified.
  453. *
  454. *               (2) String comparison terminates when :
  455. *
  456. *                   (a) BOTH string pointer(s) are passed NULL pointers.
  457. *                       (1) NULL strings identical; return 0.
  458. *
  459. *                   (b) 'p1_str' passed a NULL pointer.
  460. *                       (1) Return negative value of character pointed to by 'p2_str'.
  461. *
  462. *                   (c) 'p2_str' passed a NULL pointer.
  463. *                       (1) Return positive value of character pointed to by 'p1_str'.
  464. *
  465. *                   (d) Non-matching characters found.
  466. *                       (1) Return signed-integer difference of the character pointed to by 'p2_str'
  467. *                           from the character pointed to by 'p1_str'.
  468. *
  469. *                   (e) Terminating NULL character found in both strings.
  470. *                       (1) Strings identical; return 0.
  471. *                       (2) Only one NULL character test required in conditional since previous condition
  472. *                           tested character equality.
  473. *
  474. *                   (f) BOTH strings point to NULL.
  475. *                       (1) Strings overlap with NULL address.
  476. *                       (2) Strings identical up to but NOT beyond or including the NULL address; return 0.
  477. *
  478. *                   (g) 'p1_str_next' points to NULL.
  479. *                       (1) 'p1_str' overlaps with NULL address.
  480. *                       (2) Strings compared up to but NOT beyond or including the NULL address.
  481. *                       (3) Return  negative value of character pointed to by 'p2_str_next'.
  482. *
  483. *                   (h) 'p2_str_next' points to NULL.
  484. *                       (1) 'p2_str' overlaps with NULL address.
  485. *                       (2) Strings compared up to but NOT beyond or including the NULL address.
  486. *                       (3) Return  positive value of character pointed to by 'p1_str_next'.
  487. *
  488. *               (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
  489. *                   return value, 'CPU_CHAR' native data type size MUST be 8-bit.
  490. *********************************************************************************************************
  491. */
  492. /*$PAGE*/
  493. CPU_INT16S  Str_Cmp (CPU_CHAR  *p1_str,
  494.                      CPU_CHAR  *p2_str)
  495. {
  496.     CPU_CHAR    *p1_str_next;
  497.     CPU_CHAR    *p2_str_next;
  498.     CPU_INT16S   cmp_val;
  499.     if (p1_str == (CPU_CHAR *)0) {
  500.         if (p2_str == (CPU_CHAR *)0) {
  501.             return ((CPU_INT16S)0);                             /* If BOTH str ptrs NULL, rtn 0 (see Note #2a).         */
  502.         }
  503.         cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str);
  504.         return (cmp_val);                                       /* If p1_str NULL, rtn neg p2_str val (see Note #2b).   */
  505.     }
  506.     if (p2_str == (CPU_CHAR *)0) {
  507.         cmp_val = (CPU_INT16S)(*p1_str);
  508.         return (cmp_val);                                       /* If p2_str NULL, rtn pos p1_str val (see Note #2c).   */
  509.     }
  510.     p1_str_next = p1_str;
  511.     p2_str_next = p2_str;
  512.     p1_str_next++;
  513.     p2_str_next++;
  514.     while ((*p1_str      == *p2_str)       &&                   /* Cmp strs until non-matching char (see Note #2d) ..   */
  515.            (*p1_str      != (CPU_CHAR  )0) &&                   /* .. or NULL char(s)               (see Note #2e) ..   */
  516.            ( p1_str_next != (CPU_CHAR *)0) &&                   /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h). */
  517.            ( p2_str_next != (CPU_CHAR *)0)) {
  518.         p1_str_next++;
  519.         p2_str_next++;
  520.         p1_str++;
  521.         p2_str++;
  522.     }
  523.     if (*p1_str != *p2_str) {                                           /* If strs NOT identical, ...                   */
  524.          cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str);       /* ... calc & rtn char diff  (see Note #2d1).   */
  525.     } else if (*p1_str == (CPU_CHAR)0) {                                /* If NULL char(s) found, ...                   */
  526.          cmp_val = 0;                                                   /* ... strs identical; rtn 0 (see Note #2e).    */
  527.     } else {
  528.         if (p1_str_next == (CPU_CHAR *)0) {
  529.             if (p2_str_next == (CPU_CHAR *)0) {                         /* If BOTH next str ptrs NULL, ...              */
  530.                 cmp_val = (CPU_INT16S)0;                                /* ... rtn 0                   (see Note #2f).  */
  531.             } else {                                                    /* If p1_str_next NULL, ...                     */
  532.                 cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next);   /* ... rtn neg p2_str_next val (see Note #2g).  */
  533.             }
  534.         } else {                                                        /* If p2_str_next NULL, ...                     */
  535.             cmp_val = (CPU_INT16S)(*p1_str_next);                       /* ... rtn pos p1_str_next val (see Note #2h).  */
  536.         }
  537.     }
  538.     return (cmp_val);
  539. }
  540. /*$PAGE*/
  541. /*
  542. *********************************************************************************************************
  543. *                                             Str_Cmp_N()
  544. *
  545. * Description : Determine if two strings are identical for up to a maximum number of characters.
  546. *
  547. * Argument(s) : p1_str      Pointer to first  string (see Note #1).
  548. *
  549. *               p2_str      Pointer to second string (see Note #1).
  550. *
  551. *               len_max     Maximum number of characters to compare  (see Notes #2i & #2j).
  552. *
  553. * Return(s)   : 0,              if strings are identical             (see Notes #2a, #2e, #2f, #2i, & #2j).
  554. *
  555. *               Negative value, if 'p1_str' is less    than 'p2_str' (see Notes #2b, #2g, & #2d).
  556. *
  557. *               Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d).
  558. *
  559. * Caller(s)   : Application.
  560. *
  561. * Note(s)     : (1) String buffers NOT modified.
  562. *
  563. *               (2) String comparison terminates when :
  564. *
  565. *                   (a) BOTH string pointer(s) are passed NULL pointers.
  566. *                       (1) NULL strings identical; return 0.
  567. *
  568. *                   (b) 'p1_str' passed a NULL pointer.
  569. *                       (1) Return negative value of character pointed to by 'p2_str'.
  570. *
  571. *                   (c) 'p2_str' passed a NULL pointer.
  572. *                       (1) Return positive value of character pointed to by 'p1_str'.
  573. *
  574. *                   (d) Non-matching characters found.
  575. *                       (1) Return signed-integer difference of the character pointed to by 'p2_str'
  576. *                           from the character pointed to by 'p1_str'.
  577. *
  578. *                   (e) Terminating NULL character found in both strings.
  579. *                       (1) Strings identical; return 0.
  580. *                       (2) Only one NULL character test required in conditional since previous condition
  581. *                           tested character equality.
  582. *
  583. *                   (f) BOTH strings point to NULL.
  584. *                       (1) Strings overlap with NULL address.
  585. *                       (2) Strings identical up to but NOT beyond or including the NULL address; return 0.
  586. *
  587. *                   (g) 'p1_str_next' points to NULL.
  588. *                       (1) 'p1_str' overlaps with NULL address.
  589. *                       (2) Strings compared up to but NOT beyond or including the NULL address.
  590. *                       (3) Return  negative value of character pointed to by 'p2_str_next'.
  591. *
  592. *                   (h) 'p2_str_next' points to NULL.
  593. *                       (1) 'p2_str' overlaps with NULL address.
  594. *                       (2) Strings compared up to but NOT beyond or including the NULL address.
  595. *                       (3) Return  positive value of character pointed to by 'p1_str_next'.
  596. *
  597. *                   (i) 'len_max' passed a zero length.
  598. *                       (1) Zero-length strings identical; return 0.
  599. *
  600. *                   (j) First 'len_max' number of characters identical.
  601. *                       (1) Strings identical; return 0.
  602. *
  603. *               (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison
  604. *                   return value, 'CPU_CHAR' native data type size MUST be 8-bit.
  605. *********************************************************************************************************
  606. */
  607. /*$PAGE*/
  608. CPU_INT16S  Str_Cmp_N (CPU_CHAR    *p1_str,
  609.                        CPU_CHAR    *p2_str,
  610.                        CPU_SIZE_T   len_max)
  611. {
  612.     CPU_CHAR    *p1_str_next;
  613.     CPU_CHAR    *p2_str_next;
  614.     CPU_INT16S   cmp_val;
  615.     CPU_SIZE_T   cmp_len;
  616.     if (len_max == 0) {                                         /* If cmp len equals zero, rtn 0      (see Note #2i).   */
  617.         return ((CPU_INT16S)0);
  618.     }
  619.     if (p1_str == (CPU_CHAR *)0) {
  620.         if (p2_str == (CPU_CHAR *)0) {
  621.             return ((CPU_INT16S)0);                             /* If BOTH str ptrs NULL,  rtn 0      (see Note #2a).   */
  622.         }
  623.         cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str);
  624.         return (cmp_val);                                       /* If p1_str NULL, rtn neg p2_str val (see Note #2b).   */
  625.     }
  626.     if (p2_str == (CPU_CHAR *)0) {
  627.         cmp_val = (CPU_INT16S)(*p1_str);
  628.         return (cmp_val);                                       /* If p2_str NULL, rtn pos p1_str val (see Note #2c).   */
  629.     }
  630.     p1_str_next = p1_str;
  631.     p2_str_next = p2_str;
  632.     p1_str_next++;
  633.     p2_str_next++;
  634.     cmp_len     = 0;
  635.     while ((*p1_str      == *p2_str)       &&                   /* Cmp strs until non-matching char (see Note #2d) ..   */
  636.            (*p1_str      != (CPU_CHAR  )0) &&                   /* .. or NULL char(s)               (see Note #2e) ..   */
  637.            ( p1_str_next != (CPU_CHAR *)0) &&                   /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h); */
  638.            ( p2_str_next != (CPU_CHAR *)0) &&
  639.            ( cmp_len     <  (CPU_SIZE_T)len_max)) {             /* .. or len nbr chars cmp'd        (see Note #2j).     */
  640.         p1_str_next++;
  641.         p2_str_next++;
  642.         p1_str++;
  643.         p2_str++;
  644.         cmp_len++;
  645.     }
  646.     if (cmp_len == len_max) {                                           /* If strs     identical for len nbr of chars,  */
  647.         return ((CPU_INT16S)0);                                         /* ... rtn 0 (see Note #2j).                    */
  648.     }
  649.     if (*p1_str != *p2_str) {                                           /* If strs NOT identical, ...                   */
  650.          cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str);       /* ... calc & rtn char diff  (see Note #2d1).   */
  651.     } else if (*p1_str == (CPU_CHAR)0) {                                /* If NULL char(s) found, ...                   */
  652.          cmp_val = 0;                                                   /* ... strs identical; rtn 0 (see Note #2e).    */
  653.     } else {
  654.         if (p1_str_next == (CPU_CHAR *)0) {
  655.             if (p2_str_next == (CPU_CHAR *)0) {                         /* If BOTH next str ptrs NULL, ...              */
  656.                 cmp_val = (CPU_INT16S)0;                                /* ... rtn 0                   (see Note #2f).  */
  657.             } else {                                                    /* If p1_str_next NULL, ...                     */
  658.                 cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next);   /* ... rtn neg p2_str_next val (see Note #2g).  */
  659.             }
  660.         } else {                                                        /* If p2_str_next NULL, ...                     */
  661.             cmp_val = (CPU_INT16S)(*p1_str_next);                       /* ... rtn pos p1_str_next val (see Note #2h).  */
  662.         }
  663.     }
  664.     return (cmp_val);
  665. }
  666. /*$PAGE*/
  667. /*
  668. *********************************************************************************************************
  669. *                                             Str_Char()
  670. *
  671. * Description : Search string for first occurrence of specific character.
  672. *
  673. * Argument(s) : pstr            Pointer to string (see Note #1).
  674. *
  675. *               srch_char       Search character.
  676. *
  677. * Return(s)   : Pointer to first occurrence of search character in string, if any.
  678. *
  679. *               Pointer to NULL,                                           otherwise.
  680. *
  681. * Caller(s)   : Application.
  682. *
  683. * Note(s)     : (1) String buffer NOT modified.
  684. *
  685. *               (2) String search terminates when :
  686. *
  687. *                   (a) String pointer passed a NULL pointer.
  688. *                       (1) No string search performed; NULL pointer returned.
  689. *
  690. *                   (b) String pointer points to NULL.
  691. *                       (1) String overlaps with NULL address.
  692. *                       (2) String searched up to but NOT beyond or including the NULL address.
  693. *
  694. *                   (c) String's terminating NULL character found.
  695. *                       (1) Search character NOT found in search string; NULL pointer returned.
  696. *                       (2) Applicable ONLY IF search character is NOT the terminating NULL character.
  697. *
  698. *                   (d) Search character found.
  699. *                       (1) Return pointer to first occurrence of search character in search string.
  700. *********************************************************************************************************
  701. */
  702. CPU_CHAR  *Str_Char (CPU_CHAR  *pstr,
  703.                      CPU_CHAR   srch_char)
  704. {
  705.     CPU_CHAR  *pstr_next;
  706.     if (pstr == (CPU_CHAR *)0) {                                /* Rtn NULL if srch str ptr NULL (see Note #2a).        */
  707.         return ((CPU_CHAR *)0);
  708.     }
  709.     pstr_next = pstr;
  710.     pstr_next++;
  711.     while (( pstr_next != (CPU_CHAR *)0) &&                     /* Srch str until NULL ptr(s) (see Note #2b) ...        */
  712.            (*pstr      != (CPU_CHAR  )0) &&                     /* ... or NULL char           (see Note #2c) ...        */
  713.            (*pstr      != (CPU_CHAR  )srch_char)) {             /* ... or srch char found     (see Note #2d).           */
  714.         pstr++;
  715.         pstr_next++;
  716.     }
  717.     if (*pstr != srch_char) {                                   /* If srch char NOT found, str points to NULL; ...      */
  718.         return ((CPU_CHAR *)0);                                 /* ... rtn NULL (see Notes #2b & #2c).                  */
  719.     }
  720.     return (pstr);                                              /* Else rtn ptr to found srch char (see Note #2d).      */
  721. }
  722. /*$PAGE*/
  723. /*
  724. *********************************************************************************************************
  725. *                                            Str_Char_N()
  726. *
  727. * Description : Search string for first occurrence of specific character, up to a maximum number of characters.
  728. *
  729. * Argument(s) : pstr            Pointer to string (see Note #1).
  730. *
  731. *               len_max         Maximum number of characters to search (see Notes #2e & #3).
  732. *
  733. *               srch_char       Search character.
  734. *
  735. * Return(s)   : Pointer to first occurrence of search character in string, if any.
  736. *
  737. *               Pointer to NULL,                                           otherwise.
  738. *
  739. * Caller(s)   : Application.
  740. *
  741. * Note(s)     : (1) String buffer NOT modified.
  742. *
  743. *               (2) String search terminates when :
  744. *
  745. *                   (a) String pointer passed a NULL pointer.
  746. *                       (1) No string search performed; NULL pointer returned.
  747. *
  748. *                   (b) String pointer points to NULL.
  749. *                       (1) String overlaps with NULL address.
  750. *                       (2) String searched up to but NOT beyond or including the NULL address.
  751. *
  752. *                   (c) String's terminating NULL character found.
  753. *                       (1) Search character NOT found in search string; NULL pointer returned.
  754. *                       (2) Applicable ONLY IF search character is NOT the terminating NULL character.
  755. *
  756. *                   (d) Search character found.
  757. *                       (1) Return pointer to first occurrence of search character in search string.
  758. *
  759. *                   (e) 'len_max' number of characters searched.
  760. *                       (1) 'len_max' number of characters does NOT include terminating NULL character.
  761. *
  762. *               (3) Ideally, the 'len_max' parameter would be the last parameter in this function's
  763. *                   paramter list for consistency with all other custom string library functions.
  764. *                   However, the 'len_max' parameter is ordered to comply with the standard library
  765. *                   function's parameter list.
  766. *********************************************************************************************************
  767. */
  768. CPU_CHAR  *Str_Char_N (CPU_CHAR    *pstr,
  769.                        CPU_SIZE_T   len_max,
  770.                        CPU_CHAR     srch_char)
  771. {
  772.     CPU_CHAR    *pstr_next;
  773.     CPU_SIZE_T   len_srch;
  774.     if (pstr == (CPU_CHAR *)0) {                                /* Rtn NULL if srch str ptr NULL    (see Note #2a).     */
  775.         return ((CPU_CHAR *)0);
  776.     }
  777.     if (len_max == (CPU_SIZE_T)0) {                             /* Rtn NULL if srch len equals zero (see Note #2e).     */
  778.         return ((CPU_CHAR *)0);
  779.     }
  780.     pstr_next = pstr;
  781.     pstr_next++;
  782.     len_srch  = 0;
  783.     while (( pstr_next != (CPU_CHAR *)0)         &&             /* Srch str until NULL ptr(s)  (see Note #2b)  ...      */
  784.            (*pstr      != (CPU_CHAR  )0)         &&             /* ... or NULL char            (see Note #2c)  ...      */
  785.            (*pstr      != (CPU_CHAR  )srch_char) &&             /* ... or srch char found      (see Note #2d); ...      */
  786.            ( len_srch  <  (CPU_SIZE_T)len_max)) {               /* ... or max nbr chars srch'd (see Note #2e).          */
  787.         pstr++;
  788.         pstr_next++;
  789.         len_srch++;
  790.     }
  791.     if (*pstr != srch_char) {                                   /* If srch char NOT found, str points to NULL; ...      */
  792.         return ((CPU_CHAR *)0);                                 /* ... rtn NULL (see Notes #2b & #2c).                  */
  793.     }
  794.     return (pstr);                                              /* Else rtn ptr to found srch char (see Note #2d).      */
  795. }
  796. /*$PAGE*/
  797. /*
  798. *********************************************************************************************************
  799. *                                           Str_Char_Last()
  800. *
  801. * Description : Search string for last occurrence of specific character.
  802. *
  803. * Argument(s) : pstr            Pointer to string (see Note #1).
  804. *
  805. *               srch_char       Search character.
  806. *
  807. * Return(s)   : Pointer to last occurrence of search character in string, if any.
  808. *
  809. *               Pointer to NULL,                                          otherwise.
  810. *
  811. * Caller(s)   : Application.
  812. *
  813. * Note(s)     : (1) String buffer NOT modified.
  814. *
  815. *               (2) String search terminates when :
  816. *
  817. *                   (a) String pointer passed a NULL pointer.
  818. *                       (1) No string search performed; NULL pointer returned.
  819. *
  820. *                   (b) String pointer points to NULL.
  821. *                       (1) String overlaps with NULL address.
  822. *                       (2) String searched up to but NOT beyond or including the NULL address.
  823. *                       (3) NULL address boundary handled in Str_Len().
  824. *
  825. *                   (c) String searched from end to beginning.
  826. *                       (1) Search character NOT found in search string; NULL pointer returned.
  827. *                       (2) Applicable ONLY IF search character is NOT the terminating NULL character.
  828. *
  829. *                   (d) Search character found.
  830. *                       (1) Return pointer to first occurrence of search character in search string.
  831. *********************************************************************************************************
  832. */
  833. CPU_CHAR  *Str_Char_Last (CPU_CHAR  *pstr,
  834.                           CPU_CHAR   srch_char)
  835. {
  836.     CPU_CHAR    *pstr_next;
  837.     CPU_SIZE_T   str_len;
  838.     if (pstr == (CPU_CHAR *)0) {                                /* Rtn NULL if srch str ptr NULL (see Note #2a).        */
  839.         return ((CPU_CHAR *)0);
  840.     }
  841.     pstr_next  = pstr;
  842.     str_len    = Str_Len(pstr);
  843.     pstr_next += str_len;
  844.     while (( pstr_next != pstr) &&                              /* Srch str from end until beg (see Note #2c) ...       */
  845.            (*pstr_next != srch_char)) {                         /* ... until srch char found   (see Note #2d).          */
  846.         pstr_next--;
  847.     }
  848.     if (*pstr_next != srch_char) {                              /* If srch char NOT found, str points to NULL; ...      */
  849.         return ((CPU_CHAR *)0);                                 /* ... rtn NULL (see Notes #2b & #2c).                  */
  850.     }
  851.     return (pstr_next);                                         /* Else rtn ptr to found srch char (see Note #2d).      */
  852. }
  853. /*$PAGE*/
  854. /*
  855. *********************************************************************************************************
  856. *                                             Str_Str()
  857. *
  858. * Description : Search string for first occurence of a specific search string.
  859. *
  860. * Argument(s) : pstr            Pointer to        string (see Note #1).
  861. *
  862. *               psrch_str       Pointer to search string (see Note #1).
  863. *
  864. * Return(s)   : Pointer to first occurrence of search string in string, if any.
  865. *
  866. *               Pointer to NULL,                                        otherwise.
  867. *
  868. * Caller(s)   : Application.
  869. *
  870. * Note(s)     : (1) String buffers NOT modified.
  871. *
  872. *               (2) String search terminates when :
  873. *
  874. *                   (a) String pointer passed a NULL pointer.
  875. *                       (1) No string search performed; NULL pointer returned.
  876. *
  877. *                   (b) Search string length greater than string length.
  878. *                       (1) No string search performed; NULL pointer returned.
  879. *
  880. *                   (c) Search string length equal to zero.
  881. *                       (1) NULL search string at end of string returned.
  882. *
  883. *                   (d) Entire string has been searched.
  884. *                       (1) Maximum size of the search is defined as the subtraction of the
  885. *                           search string length from the string length.
  886. *                       (2) Search string not found; NULL pointer returned.
  887. *
  888. *                   (e) Search string found.
  889. *                       (1) Search string found according to Str_Cmp_N() return value.
  890. *                       (2) Return pointer to first occurrence of search string in string.
  891. *********************************************************************************************************
  892. */
  893. CPU_CHAR  *Str_Str (CPU_CHAR  *pstr,
  894.                     CPU_CHAR  *psrch_str)
  895. {
  896.     CPU_SIZE_T    str_len;
  897.     CPU_SIZE_T    srch_str_len;
  898.     CPU_SIZE_T    srch_len;
  899.     CPU_SIZE_T    srch_ix;
  900.     CPU_BOOLEAN   srch_done;
  901.     CPU_INT16S    srch_cmp = 0;
  902.     CPU_CHAR     *pstr_srch_ix = (void *)0;
  903.                                                                 /* Rtn NULL if str ptr(s) NULL (see Note #2a).          */
  904.     if (pstr == (CPU_CHAR *)0) {
  905.         return ((CPU_CHAR *)0);
  906.     }
  907.     if (psrch_str == (CPU_CHAR *)0) {
  908.         return ((CPU_CHAR *)0);
  909.     }
  910.     str_len      = Str_Len(pstr);
  911.     srch_str_len = Str_Len(psrch_str);
  912.     if (srch_str_len > str_len) {                               /* If srch str len > str len, rtn NULL  (see Note #2b). */
  913.         return ((CPU_CHAR *)0);
  914.     }
  915.     if (srch_str_len == 0) {                                    /* If srch str len = 0, srch str equal NULL str; ...    */
  916.         pstr_srch_ix = (CPU_CHAR *)(pstr + str_len);            /* ... rtn ptr to NULL str found in str (see Note #2c). */
  917.         return (pstr_srch_ix);
  918.     }
  919.     srch_len  = str_len - srch_str_len;                         /* Determine srch len (see Note #2d1).                  */
  920.     srch_ix   = 0;
  921.     srch_done = DEF_NO;
  922.     while ((srch_done == DEF_NO) && (srch_ix <= srch_len)) {
  923.         pstr_srch_ix = (CPU_CHAR *)(pstr + srch_ix);
  924.         srch_cmp     =  Str_Cmp_N(pstr_srch_ix, psrch_str, srch_str_len);
  925.         srch_done    = (srch_cmp == 0) ? DEF_YES : DEF_NO;
  926.         srch_ix++;
  927.     }
  928.     if (srch_cmp != 0) {                                        /* If srch str NOT found, rtn NULL  (see Note #2d).     */
  929.         return ((CPU_CHAR *)0);
  930.     }
  931.     return (pstr_srch_ix);                                      /* Rtn ptr to srch str found in str (see Note #2e).     */
  932. }
  933. /*$PAGE*/
  934. /*
  935. *********************************************************************************************************
  936. *                                           Str_FmtNbr_32()
  937. *
  938. * Description : Format number into a multi-digit character string.
  939. *
  940. * Argument(s) : nbr             Number                          to format (see Note #1).
  941. *
  942. *               nbr_dig         Number of integer        digits to format (see Note #2).
  943. *
  944. *               nbr_dp          Number of decimal point  digits to format.
  945. *
  946. *               lead_zeros      Prepend leading zeros    option (DEF_YES/DEF_NO) [see Note #3].
  947. *
  948. *               nul             NULL-character terminate option (DEF_YES/DEF_NO) [see Note #4].
  949. *
  950. *               pstr_fmt        Pointer to character array to return formatted number string (see Note #5).
  951. *
  952. * Return(s)   : Pointer to formatted string, if NO errors (see Note #6).
  953. *
  954. *               Pointer to NULL,             otherwise.
  955. *
  956. * Caller(s)   : Application.
  957. *
  958. * Note(s)     : (1) (a) The maximum accuracy for 32-bit floating-point numbers :
  959. *
  960. *
  961. *                                 Maximum Accuracy            log [Internal-Base ^ (Number-Internal-Base-Digits)]
  962. *                           32-bit Floating-point Number  =  -----------------------------------------------------
  963. *                                                                             log [External-Base]
  964. *
  965. *                                                             log [2 ^ 24]
  966. *                                                         =  --------------
  967. *                                                               log [10]
  968. *
  969. *                                                         <  7.225  Base-10 Digits
  970. *
  971. *                               where
  972. *                                       Internal-Base                   Internal number base of floating-
  973. *                                                                           point numbers (i.e.  2)
  974. *                                       External-Base                   External number base of floating-
  975. *                                                                           point numbers (i.e. 10)
  976. *                                       Number-Internal-Base-Digits     Number of internal number base
  977. *                                                                           significant digits (i.e. 24)
  978. *
  979. *                   (b) Some compilers' floating-point routines MAY further reduce the maximum accuracy.
  980. *
  981. *                   (c) If the total number of digits to format ('nbr_dig + nbr_dp') is greater than the 
  982. *                       maximum accuracy; digits following the first, significantly-accurate digits will
  983. *                       be inaccurate.
  984. *
  985. *               (2) (a) If the number of digits to format ('nbr_dig') is less than the number of significant
  986. *                       integer digits of the number to format ('nbr'); then the most-significant digits of
  987. *                       the formatted number will be truncated.
  988. *
  989. *                           Example :
  990. *
  991. *                               nbr      = 23456.789
  992. *                               nbr_dig  = 3
  993. *                               nbr_dp   = 2
  994. *
  995. *                               pstr_fmt = "456.78"
  996. *
  997. *                   (b) If number to format ('nbr') is negative but the most-significant digits of the
  998. *                       formatted number are truncated (see Note #2a); the negative sign still prefixes
  999. *                       the truncated formatted number.
  1000. *
  1001. *                           Example :
  1002. *
  1003. *                               nbr      = -23456.789
  1004. *                               nbr_dig  =  3
  1005. *                               nbr_dp   =  2
  1006. *
  1007. *                               pstr_fmt = "-456.78"
  1008. *
  1009. *               (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit.
  1010. *                       The number of leading zeros is such that the total number integer digits is
  1011. *                       equal to the requested number of integer digits to format ('nbr_dig').
  1012. *
  1013. *                   (b) (1) If leading zeros option DISABLED,                        ...
  1014. *                       (2) ... number of digits to format is non-zero,              ...
  1015. *                       (3) ... & the integer value of the number to format is zero; ...
  1016. *                       (4) ... then one digit of '0' value is formatted.
  1017. *
  1018. *                           This is NOT a leading zero; but a single integer digit of '0' value.
  1019. *
  1020. *               (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character
  1021. *                       array formatting.
  1022. *
  1023. *                   (b) WARNING: Unless 'pstr_fmt' character array is pre-/post-terminated, NULL-character
  1024. *                       terminate option DISABLED will cause character string run-on.
  1025. *$PAGE*
  1026. *               (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller.
  1027. *
  1028. *                   (b) To prevent character buffer overrun :
  1029. *
  1030. *                           Character array size MUST be  >=  ('nbr_dig'         +
  1031. *                                                              'nbr_dp'          +
  1032. *                                                              1 negative sign   +
  1033. *                                                              1 decimal point   +
  1034. *                                                              1 'NUL' terminator)  characters
  1035. *
  1036. *               (6) String format terminates when :
  1037. *
  1038. *                   (a) Format string pointer is passed a NULL pointer.
  1039. *                       (1) No string format performed; NULL pointer returned.
  1040. *
  1041. *                   (b) Number successfully formatted into character string array.
  1042. *********************************************************************************************************
  1043. */
  1044. #if (LIB_STR_CFG_FP_EN == DEF_ENABLED)
  1045. CPU_CHAR  *Str_FmtNbr_32 (CPU_FP32      nbr,
  1046.                           CPU_INT08U    nbr_dig,
  1047.                           CPU_INT08U    nbr_dp,
  1048.                           CPU_BOOLEAN   lead_zeros,
  1049.                           CPU_BOOLEAN   nul,
  1050.                           CPU_CHAR     *pstr_fmt)
  1051. {
  1052.     CPU_CHAR    *pstr;
  1053.     CPU_INT08U   i;
  1054.     CPU_INT32U   dig_nbr;
  1055.     CPU_INT32U   dig_val;
  1056.     CPU_FP32     dig_exp;
  1057.     CPU_FP32     dp_exp;
  1058.                                                                 /* Rtn NULL if str ptr NULL (see Note #6a).             */
  1059.     if (pstr_fmt == (CPU_CHAR *)0) {
  1060.         return ((CPU_CHAR *)0);
  1061.     }
  1062.     pstr = pstr_fmt;
  1063.     if (nbr < 0.0) {                                            /* If nbr neg,             ...                          */
  1064.         if ((nbr_dig > 0) ||                                    /* ... &  at least one dig ...                          */
  1065.             (nbr_dp  > 0)) {                                    /* ... or at least one dp; ...                          */
  1066.              nbr     = -nbr;                                    /* ... negate nbr &        ...                          */
  1067.             *pstr++  = '-';                                     /* ... prefix with neg sign (see Note #2b).             */
  1068.         }
  1069.     }
  1070.     if (nbr_dig > 0) {
  1071.         dig_exp = 1.0;
  1072.         for (i = 1; i < nbr_dig; i++) {
  1073.             dig_exp *= 10.0;
  1074.         }
  1075.         for (i = nbr_dig; i > 0; i--) {                         /* Fmt str for desired nbr digs.                        */
  1076.             dig_nbr = (CPU_INT32U)(nbr / dig_exp);
  1077.             if ((dig_nbr >  0) ||                               /* If dig nbr > 0,                              ...     */
  1078.                 (nbr_dig == 1) ||                               /* ... OR exactly 1 dig to fmt,                 ...     */
  1079.                 (i       == 1) ||                               /* ... OR on one's  dig to fmt,                 ...     */
  1080.                 (lead_zeros == DEF_YES)) {                      /* ... OR lead zeros opt ENABLED (see Note #3), ...     */
  1081.                                                                 /* ... calc & fmt dig val.                              */
  1082.                  dig_val = (CPU_INT32U)(dig_nbr % 10 );
  1083.                 *pstr++  = (CPU_CHAR  )(dig_val + '0');
  1084.             }
  1085.             dig_exp /= 10.0;                                    /* Shift to next least-significant dig.                 */
  1086.         }
  1087.     }
  1088.     if (nbr_dp > 0) {
  1089.        *pstr++ = '.';                                           /* Append dp prior to dp conversion.                    */
  1090.         dp_exp = 10.0;
  1091.         for (i = 0; i < nbr_dp; i++) {                          /* Fmt str for desired nbr dp.                          */
  1092.             dig_nbr  = (CPU_INT32U)(nbr * dp_exp );
  1093.             dig_val  = (CPU_INT32U)(dig_nbr % 10 );
  1094.            *pstr++   = (CPU_CHAR  )(dig_val + '0');
  1095.             dp_exp  *=  10.0;                                   /* Shift to next least-significant dp.                  */
  1096.         }
  1097.     }
  1098.     if (nul != DEF_NO) {                                        /* If NOT DISABLED, append NULL char (see Note #4).     */
  1099.        *pstr = (CPU_CHAR)0;
  1100.     }
  1101.     return (pstr_fmt);
  1102. }
  1103. #endif