• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Class autosprintf - formatted output to an ostream.
2    Copyright (C) 2002, 2013, 2015, 2018 Free Software Foundation, Inc.
3    Written by Bruno Haible <bruno@clisp.org>, 2002.
4 
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU Lesser General Public License as published by
7    the Free Software Foundation; either version 2.1 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17 
18 /* Tell glibc's <stdio.h> to provide a prototype for vasprintf().
19    This must come before <config.h> because <config.h> may include
20    <features.h>, and once <features.h> has been included, it's too late.  */
21 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE    1
23 #endif
24 
25 /* Specification.  */
26 #include "autosprintf.h"
27 
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 /* std::swap() is in <utility> since C++11.  */
33 #if __cplusplus >= 201103L
34 # include <utility>
35 #else
36 # include <algorithm>
37 #endif
38 
39 /* This include must come last, since it contains overrides of functions that
40    the system may provide (namely, vasprintf).  */
41 #include "lib-asprintf.h"
42 
43 namespace gnu
44 {
45 
46   /* Constructor: takes a format string and the printf arguments.  */
autosprintf(const char * format,...)47   autosprintf::autosprintf (const char *format, ...)
48   {
49     va_list args;
50     va_start (args, format);
51     if (vasprintf (&str, format, args) < 0)
52       str = NULL;
53     va_end (args);
54   }
55 
56   /* Copy constructor.  Necessary because the destructor is nontrivial.  */
autosprintf(const autosprintf & src)57   autosprintf::autosprintf (const autosprintf& src)
58   {
59     str = (src.str != NULL ? strdup (src.str) : NULL);
60   }
61 
62   /* Assignment operator.  Necessary because the destructor is nontrivial.  */
operator =(autosprintf temporary)63   autosprintf& autosprintf::operator = (autosprintf temporary)
64   {
65     /* Copy-and-swap idiom.
66        See https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom  */
67     std::swap (temporary.str, this->str);
68     return *this;
69   }
70 
71   /* Destructor: frees the temporarily allocated string.  */
~autosprintf()72   autosprintf::~autosprintf ()
73   {
74     free (str);
75   }
76 
77   /* Conversion to string.  */
operator char*() const78   autosprintf::operator char * () const
79   {
80     if (str != NULL)
81       {
82         size_t length = strlen (str) + 1;
83         char *copy = new char[length];
84         memcpy (copy, str, length);
85         return copy;
86       }
87     else
88       return NULL;
89   }
operator std::string() const90   autosprintf::operator std::string () const
91   {
92     return std::string (str ? str : "(error in autosprintf)");
93   }
94 }
95