sfmt.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2005-2007 University of Southern California
00006 // Rob Peters <rjpeters at klab dot caltech dot edu>
00007 //
00008 // created: Tue Jul  5 11:02:46 2005
00009 // commit: $Id: sfmt.cc 10065 2007-04-12 05:54:56Z rjpeters $
00010 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/sfmt.cc $
00011 //
00012 // --------------------------------------------------------------------
00013 //
00014 // This file is part of GroovX.
00015 //   [http://www.klab.caltech.edu/rjpeters/groovx/]
00016 //
00017 // GroovX is free software; you can redistribute it and/or modify it
00018 // under the terms of the GNU General Public License as published by
00019 // the Free Software Foundation; either version 2 of the License, or
00020 // (at your option) any later version.
00021 //
00022 // GroovX is distributed in the hope that it will be useful, but
00023 // WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025 // General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with GroovX; if not, write to the Free Software Foundation,
00029 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00030 //
00032 
00033 #ifndef GROOVX_RUTZ_SFMT_CC_UTC20050705180246_DEFINED
00034 #define GROOVX_RUTZ_SFMT_CC_UTC20050705180246_DEFINED
00035 
00036 #include "rutz/sfmt.h"
00037 
00038 #include "rutz/compat_snprintf.h"
00039 #include "rutz/error.h"
00040 
00041 #include "rutz/debug.h"
00042 
00043 using rutz::fstring;
00044 
00045 fstring rutz::vsfmt(const char* fmt, va_list ap)
00046 {
00047   // if we have a null pointer or an empty string, then just return an
00048   // empty fstring
00049   if (fmt == 0 || fmt[0] == '\0')
00050     {
00051       return fstring();
00052     }
00053 
00054   size_t bufsize = 512;
00055   while (1)
00056     {
00057       // relying on a gcc extension to create stack arrays whose size
00058       // is not a compile-time constant -- could also use alloca or
00059       // std::vector here
00060       char buf[bufsize];
00061 
00062       const int nchars = vsnprintf(buf, bufsize, fmt, ap);
00063 
00064       if (nchars < 0)
00065         {
00066           // a negative return code from vsnprintf() means there was
00067           // an actual formatting error (i.e., not just a too-short
00068           // buffer)
00069           char errbuf[1024];
00070           snprintf(&errbuf[0], sizeof(errbuf),
00071                    "vsnprintf failed with format string '%s' "
00072                    "and bufsize %lu", fmt, (unsigned long) bufsize);
00073           throw rutz::error(&errbuf[0], SRC_POS);
00074         }
00075       else if (static_cast<size_t>(nchars) >= bufsize)
00076         {
00077           // buffer was too small, so let's double the bufsize and try
00078           // again:
00079           const size_t new_bufsize = bufsize * 2;
00080           // make sure that we haven't overflow the unsigned int
00081           // size_t:
00082           if (new_bufsize < bufsize)
00083             {
00084               char errbuf[1024];
00085               snprintf(&errbuf[0], sizeof(errbuf),
00086                        "buffer size overflow with format string '%s' "
00087                        "and bufsize %lu", fmt, (unsigned long) bufsize);
00088               throw rutz::error(&errbuf[0], SRC_POS);
00089             }
00090 
00091           bufsize = new_bufsize;
00092           continue;
00093         }
00094       else
00095         {
00096           // OK, the vsnprintf() succeeded:
00097           return fstring(rutz::char_range(&buf[0], nchars));
00098         }
00099     }
00100   // should never get here:
00101   GVX_ASSERT(0);
00102   /* can't happen: */ return fstring();
00103 }
00104 
00105 fstring rutz::sfmt(const char* fmt, ...)
00106 {
00107   va_list a;
00108   va_start(a, fmt);
00109   const fstring result = rutz::vsfmt(fmt, a);
00110   va_end(a);
00111   return result;
00112 }
00113 
00114 static const char __attribute__((used)) vcid_groovx_rutz_sfmt_cc_utc20050705180246[] = "$Id: sfmt.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00115 #endif // !GROOVX_RUTZ_SFMT_CC_UTC20050705180246DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.