xref: /netbsd-src/external/bsd/elftosb/dist/common/format_string.cpp (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
1 /*
2  * File:	format_string.cpp
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 
8 #include "format_string.h"
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <stdexcept>
12 #include <string.h>
13 #include <stdlib.h>
14 //! Size of the temporary buffer to hold the formatted output string.
15 #define WIN32_FMT_BUF_LEN (512)
16 
17 /*!
18  * \brief Simple template class to free a pointer.
19  */
20 template <typename T>
21 class free_ptr
22 {
23 public:
24 	//! \brief Constructor.
free_ptr(T ptr)25 	free_ptr(T ptr)
26 	:	m_p(ptr)
27 	{
28 	}
29 
30 	//! \brief Destructor.
~free_ptr()31 	~free_ptr()
32 	{
33 		if (m_p)
34 		{
35 			free(m_p);
36 		}
37 	}
38 
39 protected:
40 	T m_p;	//!< The value to free.
41 };
42 
43 //! The purpose of this function to provide a convenient way of generating formatted
44 //! STL strings inline. This is especially useful when throwing exceptions that take
45 //! a std::string for a message. The length of the formatted output string is limited
46 //! only by memory. Memory temporarily allocated for the output string is disposed of
47 //! before returning.
48 //!
49 //! Example usage:
50 //! \code
51 //!		throw std::runtime_error(format_string("error on line %d", line));
52 //! \endcode
53 //!
54 //! \param fmt Format string using printf-style format markers.
55 //! \return An STL string object of the formatted output.
format_string(const char * fmt,...)56 std::string format_string(const char * fmt, ...)
57 {
58 	char * buf = 0;
59 	va_list vargs;
60 	va_start(vargs, fmt);
61 	int result = -1;
62 #if WIN32
63     buf = (char *)malloc(WIN32_FMT_BUF_LEN);
64     if (buf)
65     {
66         result = _vsnprintf(buf, WIN32_FMT_BUF_LEN, fmt, vargs);
67     }
68 #else // WIN32
69 	result = vasprintf(&buf, fmt, vargs);
70 #endif // WIN32
71 	va_end(vargs);
72 	if (result != -1 && buf)
73 	{
74 		free_ptr<char *> freebuf(buf);
75 		return std::string(buf);
76 	}
77 	return "";
78 }
79 
80