snprintf.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * C99-compatible snprintf() and vsnprintf() implementations
  3. * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include <limits.h>
  24. #include <string.h>
  25. #include "compat/va_copy.h"
  26. #include "libavutil/error.h"
  27. #if defined(__MINGW32__)
  28. #define EOVERFLOW EFBIG
  29. #endif
  30. int avpriv_snprintf(char *s, size_t n, const char *fmt, ...)
  31. {
  32. va_list ap;
  33. int ret;
  34. va_start(ap, fmt);
  35. ret = avpriv_vsnprintf(s, n, fmt, ap);
  36. va_end(ap);
  37. return ret;
  38. }
  39. int avpriv_vsnprintf(char *s, size_t n, const char *fmt,
  40. va_list ap)
  41. {
  42. int ret;
  43. va_list ap_copy;
  44. if (n == 0)
  45. return _vscprintf(fmt, ap);
  46. else if (n > INT_MAX)
  47. return AVERROR(EOVERFLOW);
  48. /* we use n - 1 here because if the buffer is not big enough, the MS
  49. * runtime libraries don't add a terminating zero at the end. MSDN
  50. * recommends to provide _snprintf/_vsnprintf() a buffer size that
  51. * is one less than the actual buffer, and zero it before calling
  52. * _snprintf/_vsnprintf() to workaround this problem.
  53. * See https://web.archive.org/web/20151214111935/http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
  54. memset(s, 0, n);
  55. va_copy(ap_copy, ap);
  56. ret = _vsnprintf(s, n - 1, fmt, ap_copy);
  57. va_end(ap_copy);
  58. if (ret == -1)
  59. ret = _vscprintf(fmt, ap);
  60. return ret;
  61. }