vsnprintf_p.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*
  34. * $Log$
  35. * Revision 1.3 2009/01/17 11:26:38 haraldkipp
  36. * Getting rid of two remaining BSD types in favor of stdint.
  37. * Replaced 'u_int' by 'unsinged int' and 'uptr_t' by 'uintptr_t'.
  38. *
  39. * Revision 1.2 2004/03/16 16:48:27 haraldkipp
  40. * Added Jan Dubiec's H8/300 port.
  41. *
  42. * Revision 1.1.1.1 2003/05/09 14:40:35 haraldkipp
  43. * Initial using 3.2.1
  44. *
  45. * Revision 1.1 2003/02/04 17:49:09 harald
  46. * *** empty log message ***
  47. *
  48. */
  49. #include "nut_io.h"
  50. #include <string.h>
  51. #include <sys/heap.h>
  52. #define min(a, b) ((a)<(b)?(a):(b))
  53. /*!
  54. * \addtogroup xgCrtStdio
  55. */
  56. /*@{*/
  57. static int _snputb(int fd, const void *buffer, size_t count)
  58. {
  59. size_t n = 0;
  60. struct __memstream *msp = (struct __memstream *) ((uintptr_t) fd);
  61. if (msp->size > 0) {
  62. n = min(msp->size, count);
  63. memcpy(*(msp->spp), buffer, n);
  64. *(msp->spp) += n;
  65. msp->size -= n;
  66. }
  67. return n;
  68. }
  69. #ifdef __HARVARD_ARCH__
  70. int _snputb_P(int fd, PGM_P buffer_P, size_t count)
  71. {
  72. size_t n = 0;
  73. struct __memstream *msp = (struct __memstream *) ((uintptr_t) fd);
  74. if (msp->size > 0) {
  75. n = min(msp->size, count);
  76. memcpy_P(*(msp->spp), buffer_P, n);
  77. *(msp->spp) += n;
  78. msp->size -= n;
  79. }
  80. return n;
  81. }
  82. #endif
  83. /*!
  84. * \brief Write argument list to a string using a given format.
  85. *
  86. * Similar to vsprintf() except that the format string is located in
  87. * program memory.
  88. *
  89. * \param buffer Pointer to a buffer that receives the output string.
  90. * \param size Maximum number of characters to be written, including the trailing \0
  91. * \param fmt Format string in program space containing conversion
  92. * specifications.
  93. * \param ap List of arguments.
  94. *
  95. * \return The number of characters written or a negative value to
  96. * indicate an error.
  97. */
  98. int vsnprintf_P(char *buffer, size_t size, PGM_P fmt, va_list ap)
  99. {
  100. int rc = 0;
  101. char *rp;
  102. size_t rl;
  103. struct __memstream ms;
  104. if (size > 0) {
  105. ms.spp = &buffer;
  106. ms.size = size - 1;
  107. rl = strlen_P(fmt) + 1;
  108. if ((rp = NutHeapAlloc(rl)) == 0)
  109. return -1;
  110. memcpy_P(rp, fmt, rl);
  111. rc = _putf(_snputb,
  112. #ifdef __HARVARD_ARCH__
  113. _snputb_P,
  114. #endif
  115. (int) ((uintptr_t) &ms), rp, ap);
  116. NutHeapFree(rp);
  117. rc = min(rc, size);
  118. *buffer = 0;
  119. }
  120. return rc;
  121. }
  122. /*@}*/