1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 /** ****************************************************************************
12 *** \file    utils.cpp
13 *** \author  Tyler Olsen, roots@allacrost.org
14 *** \author  Yohann Ferreira, yohann ferreira orange fr
15 *** \brief   Source file for the utility code.
16 *** ***************************************************************************/
17 
18 #include "utils_strings.h"
19 
20 #include <algorithm>
21 #include <cstdarg>
22 
23 // Fix linkage when using vsnprintf by undefining the libintl equivalent function.
24 #ifndef DISABLE_TRANSLATIONS
25 #undef vsnprintf
26 #endif
27 
28 namespace vt_utils
29 {
30 
Upcase(std::string text)31 std::string Upcase(std::string text)
32 {
33     std::transform(text.begin(), text.end(), text.begin(), ::toupper);
34     return text;
35 }
36 
UpcaseFirst(std::string text)37 std::string UpcaseFirst(std::string text)
38 {
39     std::transform(text.begin(), ++text.begin(), text.begin(), ::toupper);
40     return text;
41 }
42 
strprintf(char const * format,...)43 std::string strprintf(char const *format, ...)
44 {
45     char buf[256];
46     va_list args;
47     va_start(args, format);
48     int nb = vsnprintf(buf, 256, format, args);
49     va_end(args);
50     if (nb < 256)
51     {
52         return buf;
53     }
54     // The static size was not big enough, try again with a dynamic allocation.
55     ++nb;
56     char *buf2 = new char[nb];
57     va_start(args, format);
58     vsnprintf(buf2, nb, format, args);
59     va_end(args);
60     std::string res(buf2);
61     delete [] buf2;
62     return res;
63 }
64 
65 // Returns true if the given text is a number
IsStringNumeric(const std::string & text)66 bool IsStringNumeric(const std::string &text)
67 {
68     if(text.empty())
69         return false;
70 
71     // Keep track of whether decimal point is allowed.
72     // It is allowed to be present in the text zero or one times only.
73     bool decimal_allowed = true;
74 
75     size_t len = text.length();
76 
77     // Check each character of the string one at a time
78     for(size_t c = 0; c < len; ++c) {
79         // The only non numeric characters allowed are a - or + as the first character, and one decimal point anywhere
80         bool numeric_char = (isdigit(static_cast<int32_t>(text[c]))) || (c == 0 && (text[c] == '-' || text[c] == '+'));
81 
82         if(!numeric_char) {
83             // Check if the 'bad' character is a decimal point first before labeling the string invalid
84             if(decimal_allowed && text[c] == '.') {
85                 decimal_allowed = false; // Decimal points are now invalid for the rest of the string
86             } else {
87                 return false;
88             }
89         }
90     }
91 
92     return true;
93 } // bool IsStringNumeric(const string& text)
94 
95 } // namespace utils
96