string_convert.cpp
Go to the documentation of this file.
00001 //
00002 //  Copyright (c) Benjamin Kaufmann
00003 //
00004 //  This is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version. 
00008 // 
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this file; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 #include <program_opts/string_convert.h>
00019 #include <cstdlib>
00020 #include <climits>
00021 #include <cerrno>
00022 #if defined(_MSC_VER) 
00023 #define snprintf _snprintf_s
00024 #endif
00025 namespace bk_lib { 
00026 
00027 static int detectBase(const char* x) {
00028         if (x[0] == '0') {
00029                 if (x[1] == 'x' || x[1] == 'X') return 16;
00030                 if (x[1] >= '0' && x[1] <= '7') return 8;
00031         }
00032         return 10;
00033 }
00034 
00035 static bool empty(const char* x, const char** errPos) {
00036         if (x && *x) return false;
00037         if (errPos) { *errPos = x; }
00038         return true;
00039 }
00040 
00041 static int parsed(int tok, const char* end, const char** errPos) {
00042         if (errPos) *errPos = end;
00043         return tok;
00044 }
00045 
00046 int xconvert(const char* x, bool& out, const char** errPos, int) {
00047         if      (empty(x, errPos))                { return 0; }
00048         else if (*x == '1')                       { out = true;  x += 1; }
00049         else if (*x == '0')                       { out = false; x += 1; }
00050         else if (std::strncmp(x, "no", 2)  == 0)  { out = false; x += 2; }
00051         else if (std::strncmp(x, "on", 2)  == 0)  { out = true;  x += 2; }
00052         else if (std::strncmp(x, "yes", 3) == 0)  { out = true;  x += 3; }
00053         else if (std::strncmp(x, "off", 3) == 0)  { out = false; x += 3; }
00054         else if (std::strncmp(x, "true", 4) == 0) { out = true;  x += 4; }
00055         else if (std::strncmp(x, "false", 5) == 0){ out = false; x += 5; }
00056         return parsed(1, x, errPos);
00057 }
00058 int xconvert(const char* x, char& out, const char** errPos, int) {
00059         if (empty(x, errPos))     { return 0; }
00060         if ((out = *x++) == '\\') {
00061                 switch(*x) {
00062                         case 't': out = '\t'; ++x; break;
00063                         case 'n': out = '\n'; ++x; break;
00064                         case 'v': out = '\v'; ++x; break;
00065                         default: break;
00066                 }
00067         }
00068         return parsed(1, x, errPos);
00069 }
00070 
00071 int xconvert(const char* x, long& out, const char** errPos, int) {
00072         if (empty(x, errPos)) { return 0; }
00073         char* err;
00074         out     = std::strtol(x, &err, detectBase(x));
00075         if ((out == LONG_MAX || out == LONG_MIN) && errno == ERANGE) { err = (char*)x; }
00076         return parsed(err != x, err, errPos);
00077 }
00078 
00079 int xconvert(const char* x, unsigned long& out, const char** errPos, int) {
00080         if (empty(x, errPos)) { return 0; }
00081         char* err;
00082         if (std::strncmp(x, "umax", 4) == 0) {
00083                 out = static_cast<unsigned long>(-1);
00084                 err = (char*)x+4;
00085         }
00086         else if (std::strncmp(x, "-1", 2) == 0) {
00087                 out = static_cast<unsigned long>(-1);
00088                 err = (char*)x+2;
00089         }
00090         else if (*x != '-') {
00091                 out = std::strtoul(x, &err, detectBase(x));
00092                 if (out == ULONG_MAX && errno == ERANGE) { err = (char*)x; }
00093         }
00094         else { err = (char*)x; }
00095         return parsed(err != x, err, errPos);
00096 }
00097 
00098 int xconvert(const char* x, double& out, const char** errPos, int) {
00099         if (empty(x, errPos)) { return 0; }
00100         char* err;
00101         out = std::strtod(x, &err);
00102         return parsed(err != x, err, errPos);
00103 }
00104 
00105 
00106 int xconvert(const char* x, unsigned& out, const char** errPos, int) {
00107         unsigned long temp;
00108         int tok = xconvert(x, temp, errPos, 0);
00109         if (tok == 0 || (temp > UINT_MAX && temp != static_cast<unsigned long>(-1))) {
00110                 return parsed(0, x, errPos);
00111         }
00112         out = (unsigned)temp;
00113         return tok;     
00114 }
00115 int xconvert(const char* x, int& out, const char** errPos, int) {
00116         long temp;
00117         int tok = xconvert(x, temp, errPos, 0);
00118         if (tok == 0 || temp < (long)INT_MIN || temp > (long)INT_MAX) {
00119                 return parsed(0, x, errPos);
00120         }
00121         out = (int)temp;
00122         return tok;
00123 }
00124 
00125 int xconvert(const char* x, const char*& out, const char** errPos, int) {
00126         out = x;
00127         if (errPos) { *errPos = x + std::strlen(x); }
00128         return 1;
00129 }
00130 int xconvert(const char* x, std::string& out, const char** errPos, int sep) {
00131         const char* end;
00132         if (sep == 0 || (end = std::strchr(x, char(sep))) == 0) {
00133                 out = x;
00134         }
00135         else {
00136                 out.assign(x, end - x);
00137         }
00138         if (errPos) { *errPos = x + out.length(); }
00139         return 1;
00140 }
00141 
00142 bad_string_cast::~bad_string_cast() throw() {}
00143 const char* bad_string_cast::what() const throw() { return "bad_string_cast"; }
00144 
00145 }


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:40