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