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