aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/StringUtil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/StringUtil.cc')
-rw-r--r--src/FbTk/StringUtil.cc204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/FbTk/StringUtil.cc b/src/FbTk/StringUtil.cc
new file mode 100644
index 0000000..4d282ad
--- /dev/null
+++ b/src/FbTk/StringUtil.cc
@@ -0,0 +1,204 @@
1// StringUtil.cc for fluxbox
2// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen<at>linuxmail.org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: StringUtil.cc,v 1.9 2003/12/16 17:06:52 fluxgen Exp $
23
24#include "StringUtil.hh"
25
26#include <string>
27#include <cstdio>
28#include <cstdlib>
29#include <cctype>
30#include <cassert>
31#include <memory>
32#include <algorithm>
33
34using namespace std;
35
36namespace FbTk {
37
38namespace StringUtil {
39
40/**
41 Takes a pointer to string *s as an argument,
42 creates a new string n, copies s to n and
43 returns a pointer to n.
44*/
45char *strdup(const char *s) {
46 int l = strlen(s) + 1;
47 char *n = new char[l];
48 strncpy(n, s, l);
49 return n;
50}
51
52/**
53 Tries to find a string in another and
54 ignoring the case of the characters
55 Returns 0 on success else pointer to str.
56*/
57const char *strcasestr(const char *str, const char *ptn) {
58 const char *s2, *p2;
59 for( ; *str; str++) {
60 for(s2=str, p2=ptn; ; s2++,p2++) {
61 // check if we reached the end of ptn, if so, return str
62 if (!*p2)
63 return str;
64 // check if the chars match(ignoring case)
65 if (toupper(*s2) != toupper(*p2))
66 break;
67 }
68 }
69 return 0;
70}
71
72/**
73 if ~ then expand it to home of user
74 returns expanded filename
75*/
76string expandFilename(const std::string &filename) {
77 string retval;
78 size_t pos = filename.find_first_not_of(" \t");
79 if (pos != std::string::npos && filename[pos] == '~') {
80 retval = getenv("HOME");
81 if (pos != filename.size()) {
82 // copy from the character after '~'
83 retval += static_cast<const char *>(filename.c_str() + pos + 1);
84 }
85 } else
86 return filename; //return unmodified value
87
88 return retval;
89}
90
91/**
92 @return string from last "." to end of string
93*/
94string findExtension(const std::string &filename) {
95 //get start of extension
96 std::string::size_type start_pos = filename.find_last_of(".");
97 if (start_pos == std::string::npos && start_pos != filename.size())
98 return "";
99 // return from last . to end of string
100 return filename.substr(start_pos + 1);
101}
102
103/**
104 Parses a string between "first" and "last" characters
105 and ignoring ok_chars as whitespaces. The value is
106 returned in "out".
107 Returns negative value on error and this value is the position
108 in the in-string where the error occured.
109 Returns positive value on success and this value is
110 for the position + 1 in the in-string where the "last"-char value
111 was found.
112*/
113int getStringBetween(std::string& out, const char *instr, const char first, const char last,
114 const char *ok_chars, bool allow_nesting) {
115 assert(first);
116 assert(last);
117 assert(instr);
118
119 std::string::size_type i = 0,
120 total_add=0; //used to add extra if there is a \last to skip
121 std::string in(instr);
122
123 // eat leading whitespace
124 i = in.find_first_not_of(ok_chars);
125 if (i == std::string::npos)
126 return -in.size(); // nothing left but whitespace
127
128 if (in[i]!=first)
129 return -i; //return position to error
130
131 // find the end of the token
132 std::string::size_type j = i, k;
133 int nesting = 0;
134 while (1) {
135 k = in.find_first_of(first, j+1);
136 j = in.find_first_of(last, j+1);
137 if (j==std::string::npos)
138 return -in.size(); //send negative size
139
140 if (allow_nesting && k < j && in[k-1] != '\\') {
141 nesting++;
142 j = k;
143 continue;
144 }
145 //we found the last char, check so it doesn't have a '\' before
146 if (j>1 && in[j-1] != '\\') {
147 if (allow_nesting && nesting > 0) nesting--;
148 else
149 break;
150 } else if (j>1 && !allow_nesting) { // we leave escapes if we're allowing nesting
151 in.erase(j-1, 1); //remove the '\'
152 j--;
153 total_add++; //save numchars removed so we can calculate totalpos
154 }
155 }
156
157 out = in.substr(i+1, j-i-1); //copy the string between first and last
158 //return value to last character
159 return (j+1+total_add);
160}
161
162std::string toLower(const std::string &conv) {
163 std::string ret = conv;
164 std::transform(ret.begin(), ret.end(), ret.begin(), tolower);
165 return ret;
166}
167
168std::string toUpper(const std::string &conv) {
169 std::string ret = conv;
170 std::transform(ret.begin(), ret.end(), ret.begin(), toupper);
171 return ret;
172}
173
174std::string basename(const std::string &filename) {
175 std::string::size_type first_pos = filename.find_last_of("/");
176 if (first_pos != std::string::npos)
177 return filename.substr(first_pos + 1);
178 return filename;
179}
180
181string::size_type removeFirstWhitespace(std::string &str) {
182 string::size_type first_pos = str.find_first_not_of(" \t");
183 if (first_pos != string::npos)
184 str.erase(0, first_pos);
185 return first_pos;
186}
187
188
189string::size_type removeTrailingWhitespace(std::string &str) {
190 // strip trailing whitespace
191 string::size_type first_pos = str.find_first_not_of(" \t");
192 if (first_pos != string::npos) {
193 string::size_type last_pos = str.find_first_of(" \t", first_pos);
194 while (last_pos != string::npos) {
195 str.erase(last_pos);
196 last_pos = str.find_first_of(" \t", last_pos);
197 }
198 }
199 return first_pos;
200}
201
202}; // end namespace StringUtil
203
204}; // end namespace FbTk