summaryrefslogtreecommitdiff
path: root/src/bin/eolian_cxx/safe_strings.hh
blob: 4601af6b85b84f0a950d2f485b10e102916e4b5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

#ifndef EOLIAN_CXX_BIN_SAFE_STRINGS_HH
#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH

#include <string>
#include <algorithm>
#include <cstddef>
#include <cctype>
#include <iterator>

extern "C"
{
#include <Eina.h>
}

/// @brief Safely convert const char* to std::string.
///
inline std::string
safe_str(const char* str)
{
   return (str != NULL) ? str : "";
}

/// @brief Safely convert Eina_Stringshare to std::string.
///
inline std::string
safe_strshare(Eina_Stringshare* strsh)
{
   std::string ret = strsh != NULL ? strsh : "";
   eina_stringshare_del(strsh);
   return ret;
}

/// @brief Get a lower-case copy of string.
///
inline std::string
safe_lower(std::string const& s)
{
   std::string res;
   res.resize(s.size());
   std::transform(s.begin(), s.end(), res.begin(), ::tolower);
   return res;
}

/// @brief Get a lower-case copy of string.
///
inline std::string
safe_lower(const char *s)
{
   return safe_lower(safe_str(s));
}

/// @brief Get a upper-case copy of string.
///
inline std::string
safe_upper(std::string const& s)
{
   std::string res;
   res.resize(s.size());
   std::transform(s.begin(), s.end(), res.begin(), ::toupper);
   return res;
}

/// @brief Get a upper-case copy of string.
///
inline std::string
safe_upper(const char* s)
{
   return safe_upper(safe_str(s));
}

/// @brief Trim both ends of the string and replaces any
/// subsequence of contiguous spaces with a single space.
///
inline std::string
normalize_spaces(std::string const& s)
{
   std::ostringstream os;
   bool prev_is_space = true;
   std::remove_copy_if
     (s.begin(), s.end(),
      std::ostream_iterator<char>(os),
      [&prev_is_space] (char c)
      {
         bool r = ::isspace(c);
         if (r && prev_is_space)
           return true;
            prev_is_space = r;
         return false;
      });
   std::string r = os.str();
   if (!r.empty() && ::isspace(r.back()))
     r.erase(r.end()-1, r.end());
   return r;
}

/// @brief Return the basename of a path.
///
inline std::string
path_base(std::string path)
{
   std::string::reverse_iterator
     slash = std::find(path.rbegin(), path.rend(), '/');
   return std::string(slash.base(), path.end());
}

/// @brief Find-and-replace patterns in a string.
///
inline std::string
find_replace(std::string const& s_,
             std::string const& old,
             std::string const& new_)
{
   std::string s = s_;
   std::string::size_type found = s.find(old);
   std::string::size_type len = new_.length();
   while (found != std::string::npos)
     {
        s.replace(found, len, new_);
        found = s.find(old);
     }
   return s;
}

/// @brief Append '_' if @p key is a C++ keyword.
///
inline std::string
keyword_avoid(std::string const& name)
{
   if (name == "delete" ||
       name == "throw" ||
       name == "break" ||
       name == "friend" ||
       name == "goto" ||
       name == "default" ||
       name == "new" ||
       name == "auto" ||
       name == "do" ||
       name == "sizeof" ||
       name == "try" ||
       name == "this" ||
       name == "virtual" ||
       name == "register" ||
       name == "typename" ||
       name == "template")
     {
        return name + "_"; // XXX Warn?
     }
   return name;
}

/// @brief Append '_' if @p key is a C++ keyword.
///
inline std::string
keyword_avoid(const char* name)
{
   return keyword_avoid(safe_str(name));
}

#endif // EOLIAN_CXX_BIN_SAFE_STRINGS_HH