精减版printf

来源:互联网 发布:辐射3胜利狙击枪数据 编辑:程序博客网 时间:2024/05/22 07:53

转自:http://blog.csdn.net/xgbing/article/details/7642664


sstdio.c

[cpp] view plaincopy
  1. /* ---------------------------------------------------------------------------- 
  2.  *         ATMEL Microcontroller Software Support  
  3.  * ---------------------------------------------------------------------------- 
  4.  * Copyright (c) 2008, Atmel Corporation 
  5.  * 
  6.  * All rights reserved. 
  7.  * 
  8.  * Redistribution and use in source and binary forms, with or without 
  9.  * modification, are permitted provided that the following conditions are met: 
  10.  * 
  11.  * - Redistributions of source code must retain the above copyright notice, 
  12.  * this list of conditions and the disclaimer below. 
  13.  * 
  14.  * Atmel's name may not be used to endorse or promote products derived from 
  15.  * this software without specific prior written permission. 
  16.  * 
  17.  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 
  20.  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
  22.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  23.  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  24.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  25.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
  26.  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  27.  * ---------------------------------------------------------------------------- 
  28.  */  
  29.   
  30. //------------------------------------------------------------------------------  
  31. /// \unit  
  32. ///  
  33. /// !Purpose  
  34. ///  
  35. /// Implementation of several stdio.h methods, such as printf(), sprintf() and  
  36. /// so on. This reduces the memory footprint of the binary when using those  
  37. /// methods, compared to the libc implementation.  
  38. ///  
  39. /// !Usage  
  40. ///  
  41. /// Adds stdio.c to the list of file to compile for the project. This will  
  42. /// automatically replace libc methods by the custom ones.  
  43. //------------------------------------------------------------------------------  
  44.   
  45. //------------------------------------------------------------------------------  
  46. //         Headers  
  47. //------------------------------------------------------------------------------  
  48. #include <stdarg.h>  
  49. #include "sstdio.h"  
  50. #include "debug.h"  
  51.   
  52. //------------------------------------------------------------------------------  
  53. //         Local Definitions  
  54. //------------------------------------------------------------------------------  
  55.   
  56. // Maximum string size allowed (in bytes).  
  57. #define MAX_STRING_SIZE         100  
  58.   
  59. //------------------------------------------------------------------------------  
  60. //         Global Variables  
  61. //------------------------------------------------------------------------------  
  62.   
  63.   
  64.   
  65. //------------------------------------------------------------------------------  
  66. //         Local Functions  
  67. //------------------------------------------------------------------------------  
  68.   
  69. //------------------------------------------------------------------------------  
  70. // Writes a character inside the given string. Returns 1.  
  71. // \param pStr  Storage string.  
  72. // \param c  Character to write.  
  73. //------------------------------------------------------------------------------  
  74. static signed int PutChar(char *pStr, char c)  
  75. {  
  76.     *pStr = c;  
  77.     return 1;  
  78. }  
  79.   
  80. //------------------------------------------------------------------------------  
  81. // Writes a string inside the given string.  
  82. // Returns the size of the written  
  83. // string.  
  84. // \param pStr  Storage string.  
  85. // \param pSource  Source string.  
  86. //------------------------------------------------------------------------------  
  87. static signed int PutString(char *pStr, const char *pSource)  
  88. {  
  89.     signed int num = 0;  
  90.   
  91.     while (*pSource != 0) {  
  92.   
  93.         *pStr++ = *pSource++;  
  94.         num++;  
  95.     }  
  96.   
  97.     return num;  
  98. }  
  99.   
  100. //------------------------------------------------------------------------------  
  101. // Writes an unsigned int inside the given string, using the provided fill &  
  102. // width parameters.  
  103. // Returns the size in characters of the written integer.  
  104. // \param pStr  Storage string.  
  105. // \param fill  Fill character.  
  106. // \param width  Minimum integer width.  
  107. // \param value  Integer value.  
  108. //------------------------------------------------------------------------------  
  109. #if 0  
  110. static signed int PutUnsignedInt(  
  111.     char *pStr,  
  112.     char fill,  
  113.     signed int width,  
  114.     unsigned int value)  
  115. {  
  116.     signed int num = 0;  
  117.   
  118.     // Take current digit into account when calculating width  
  119.     width--;  
  120.   
  121.     // Recursively write upper digits  
  122.     if ((value / 10) > 0) {  
  123.   
  124.         num = PutUnsignedInt(pStr, fill, width, value / 10);  
  125.         pStr += num;  
  126.     }  
  127.     // Write filler characters  
  128.     else {  
  129.   
  130.         while (width > 0) {  
  131.   
  132.             PutChar(pStr, fill);  
  133.             pStr++;  
  134.             num++;  
  135.             width--;  
  136.         }  
  137.     }  
  138.   
  139.     // Write lower digit  
  140.     num += PutChar(pStr, (value % 10) + '0');  
  141.   
  142.     return num;  
  143. }  
  144.   
  145. //------------------------------------------------------------------------------  
  146. // Writes a signed int inside the given string, using the provided fill & width  
  147. // parameters.  
  148. // Returns the size of the written integer.  
  149. // \param pStr  Storage string.  
  150. // \param fill  Fill character.  
  151. // \param width  Minimum integer width.  
  152. // \param value  Signed integer value.  
  153. //------------------------------------------------------------------------------  
  154. static signed int PutSignedInt(  
  155.     char *pStr,  
  156.     char fill,  
  157.     signed int width,  
  158.     signed int value)  
  159. {  
  160.     signed int num = 0;  
  161.     unsigned int absolute;  
  162.   
  163.     // Compute absolute value  
  164.     if (value < 0) {  
  165.   
  166.         absolute = -value;  
  167.     }  
  168.     else {  
  169.   
  170.         absolute = value;  
  171.     }  
  172.   
  173.     // Take current digit into account when calculating width  
  174.     width--;  
  175.   
  176.     // Recursively write upper digits  
  177.     if ((absolute / 10) > 0) {  
  178.   
  179.         if (value < 0) {  
  180.           
  181.             num = PutSignedInt(pStr, fill, width, -(absolute / 10));  
  182.         }  
  183.         else {  
  184.   
  185.             num = PutSignedInt(pStr, fill, width, absolute / 10);  
  186.         }  
  187.         pStr += num;  
  188.     }  
  189.     else {  
  190.   
  191.         // Reserve space for sign  
  192.         if (value < 0) {  
  193.   
  194.             width--;  
  195.         }  
  196.   
  197.         // Write filler characters  
  198.         while (width > 0) {  
  199.   
  200.             PutChar(pStr, fill);  
  201.             pStr++;  
  202.             num++;  
  203.             width--;  
  204.         }  
  205.   
  206.         // Write sign  
  207.         if (value < 0) {  
  208.   
  209.             num += PutChar(pStr, '-');  
  210.             pStr++;  
  211.         }  
  212.     }  
  213.   
  214.     // Write lower digit  
  215.     num += PutChar(pStr, (absolute % 10) + '0');  
  216.   
  217.     return num;  
  218. }  
  219. #endif  
  220.   
  221. //------------------------------------------------------------------------------  
  222. // Writes an hexadecimal value into a string, using the given fill, width &  
  223. // capital parameters.  
  224. // Returns the number of char written.  
  225. // \param pStr  Storage string.  
  226. // \param fill  Fill character.  
  227. // \param width  Minimum integer width.  
  228. // \param maj  Indicates if the letters must be printed in lower- or upper-case.  
  229. // \param value  Hexadecimal value.  
  230. //------------------------------------------------------------------------------  
  231. static signed int PutHexa(  
  232.     char *pStr,  
  233.     char fill,  
  234.     signed int width,  
  235.     unsigned char maj,  
  236.     unsigned int value)  
  237. {  
  238.     signed int num = 0;  
  239.   
  240.     // Decrement width  
  241.     width--;  
  242.   
  243.     // Recursively output upper digits  
  244.     if ((value >> 4) > 0) {  
  245.   
  246.         num += PutHexa(pStr, fill, width, maj, value >> 4);  
  247.         pStr += num;  
  248.     }  
  249.     // Write filler chars  
  250.     else {  
  251.   
  252.         while (width > 0) {  
  253.   
  254.             PutChar(pStr, fill);  
  255.             pStr++;  
  256.             num++;  
  257.             width--;  
  258.         }  
  259.     }  
  260.   
  261.     // Write current digit  
  262.     if ((value & 0xF) < 10) {  
  263.   
  264.         PutChar(pStr, (value & 0xF) + '0');  
  265.     }  
  266.     else if (maj) {  
  267.   
  268.         PutChar(pStr, (value & 0xF) - 10 + 'A');  
  269.     }  
  270.     else {  
  271.   
  272.         PutChar(pStr, (value & 0xF) - 10 + 'a');  
  273.     }  
  274.     num++;  
  275.   
  276.     return num;  
  277. }  
  278.   
  279. //------------------------------------------------------------------------------  
  280. //         Global Functions  
  281. //------------------------------------------------------------------------------  
  282.   
  283. //------------------------------------------------------------------------------  
  284. /// Stores the result of a formatted string into another string. Format  
  285. /// arguments are given in a va_list instance.  
  286. /// Return the number of characters written.  
  287. /// \param pStr    Destination string.  
  288. /// \param length  Length of Destination string.  
  289. /// \param pFormat Format string.  
  290. /// \param ap      Argument list.  
  291. //------------------------------------------------------------------------------  
  292. static signed int t_vsnprintf(char *pStr, unsigned int length, const char *pFormat, va_list ap)  
  293. {  
  294.     char          fill;  
  295.     unsigned char width;  
  296.     signed int    num = 0;  
  297.     signed int    size = 0;  
  298.   
  299.     // Clear the string  
  300.     if (pStr) {  
  301.   
  302.         *pStr = 0;  
  303.     }  
  304.   
  305.     // Phase string  
  306.     while (*pFormat != 0 && size < length) {  
  307.   
  308.         // Normal character  
  309.         if (*pFormat != '%') {  
  310.   
  311.             *pStr++ = *pFormat++;  
  312.             size++;  
  313.         }  
  314.         // Escaped '%'  
  315.         else if (*(pFormat+1) == '%') {  
  316.   
  317.             *pStr++ = '%';  
  318.             pFormat += 2;  
  319.             size++;  
  320.         }  
  321.         // Token delimiter  
  322.         else {  
  323.   
  324.             fill = ' ';  
  325.             width = 0;  
  326.             pFormat++;  
  327.   
  328.             // Parse filler  
  329.             if (*pFormat == '0') {  
  330.   
  331.                 fill = '0';  
  332.                 pFormat++;  
  333.             }  
  334.   
  335.             // Parse width  
  336.             while ((*pFormat >= '0') && (*pFormat <= '9')) {  
  337.           
  338.                 width = (width*10) + *pFormat-'0';  
  339.                 pFormat++;  
  340.             }  
  341.   
  342.             // Check if there is enough space  
  343.             if (size + width > length) {  
  344.   
  345.                 width = length - size;  
  346.             }  
  347.           
  348.             // Parse type  
  349.             switch (*pFormat) {  
  350.             //case 'd':   
  351.             //case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;  
  352.             //case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;  
  353.             case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;  
  354.             case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;  
  355.             case 's': num = PutString(pStr, va_arg(ap, char *)); break;  
  356.             case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break;  
  357.             default:  
  358.                 return -1;  //EOF  
  359.             }  
  360.   
  361.             pFormat++;  
  362.             pStr += num;  
  363.             size += num;  
  364.         }  
  365.     }  
  366.   
  367.     // NULL-terminated (final \0 is not counted)  
  368.     if (size < length) {  
  369.   
  370.         *pStr = 0;  
  371.     }  
  372.     else {  
  373.   
  374.         *(--pStr) = 0;  
  375.         size--;  
  376.     }  
  377.   
  378.     return size;  
  379. }  
  380.   
  381. //------------------------------------------------------------------------------  
  382. /// Stores the result of a formatted string into another string. Format  
  383. /// arguments are given in a va_list instance.  
  384. /// Return the number of characters written.  
  385. /// \param pString  Destination string.  
  386. /// \param pFormat  Format string.  
  387. /// \param ap       Argument list.  
  388. //------------------------------------------------------------------------------  
  389. static signed int t_vsprintf(char *pString, const char *pFormat, va_list ap)  
  390. {  
  391.     return t_vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);  
  392. }  
  393.   
  394. //------------------------------------------------------------------------------  
  395. /// Outputs a string on stdout.  
  396. /// \param pStr  String to output.  
  397. //------------------------------------------------------------------------------  
  398. static signed int t_fputs(const char *pStr)  
  399. {  
  400.     dbg_print(pStr);  
  401.   
  402.     return(0);  
  403. }  
  404.   
  405.   
  406. //------------------------------------------------------------------------------  
  407. /// Outputs a formatted string on the given stream. Format arguments are given  
  408. /// in a va_list instance.  
  409. /// \param pStream  Output stream.  
  410. /// \param pFormat  Format string  
  411. /// \param ap  Argument list.  
  412. //------------------------------------------------------------------------------  
  413. static signed int t_vfprintf(const char *pFormat, va_list ap)  
  414. {  
  415.     char pStr[MAX_STRING_SIZE];  
  416.     char pError[] = "stdio.c: MAX_STRING_SIZE\n\r";  
  417.   
  418.     // Write formatted string in buffer  
  419.     if (t_vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {  
  420.   
  421.         t_fputs(pError);  
  422.         while (1); // Increase MAX_STRING_SIZE  
  423.     }  
  424.   
  425.     // Display string  
  426.     return t_fputs(pStr);  
  427. }  
  428.   
  429. //------------------------------------------------------------------------------  
  430. /// Outputs a formatted string on the DBGU stream. Format arguments are given  
  431. /// in a va_list instance.  
  432. /// \param pFormat  Format string  
  433. /// \param ap  Argument list.  
  434. //------------------------------------------------------------------------------  
  435. static signed int t_vprintf(const char *pFormat, va_list ap)  
  436. {  
  437.     return t_vfprintf(pFormat, ap);  
  438. }  
  439.   
  440. //------------------------------------------------------------------------------  
  441. /// Outputs a formatted string on the DBGU stream, using a variable number of  
  442. /// arguments.  
  443. /// \param pFormat  Format string.  
  444. //------------------------------------------------------------------------------  
  445. signed int trace(const char *pFormat, ...)  
  446. {  
  447.     va_list ap;  
  448.     signed int result;  
  449.   
  450.     // Forward call to vprintf  
  451.     va_start(ap, pFormat);  
  452.     result = t_vprintf(pFormat, ap);  
  453.     va_end(ap);  
  454.   
  455.     return result;  
  456. }  


sstdio.h

[cpp] view plaincopy
  1. #ifndef __SSTDIO_H__  
  2. #define __SSTDIO_H__  
  3.   
  4. signed int trace(const char *pFormat, ...);  
  5.   
  6. #endif  


略加修改,就可以用到嵌入式系统中。


0 0
原创粉丝点击