strutil.cc revision 32750621508da5e68f53bf14f944ad524627eb50
1#include "strutil.h" 2 3#include <ctype.h> 4#include <string.h> 5 6#include <unordered_map> 7#include <utility> 8 9WordScanner::Iterator& WordScanner::Iterator::operator++() { 10 int len = static_cast<int>(in->size()); 11 for (s = i; s < len; s++) { 12 if (!isspace((*in)[s])) 13 break; 14 } 15 if (s == len) { 16 in = NULL; 17 s = 0; 18 i = 0; 19 return *this; 20 } 21 for (i = s; i < len; i++) { 22 if (isspace((*in)[i])) 23 break; 24 } 25 return *this; 26} 27 28StringPiece WordScanner::Iterator::operator*() const { 29 return in->substr(s, i - s); 30} 31 32WordScanner::WordScanner(StringPiece in) 33 : in_(in) { 34} 35 36WordScanner::Iterator WordScanner::begin() const { 37 Iterator iter; 38 iter.in = &in_; 39 iter.s = 0; 40 iter.i = 0; 41 ++iter; 42 return iter; 43} 44 45WordScanner::Iterator WordScanner::end() const { 46 Iterator iter; 47 iter.in = NULL; 48 iter.s = 0; 49 iter.i = 0; 50 return iter; 51} 52 53WordWriter::WordWriter(string* o) 54 : out_(o), 55 needs_space_(false) { 56} 57 58void WordWriter::MaybeAddWhitespace() { 59 if (needs_space_) { 60 out_->push_back(' '); 61 } else { 62 needs_space_ = true; 63 } 64} 65 66void WordWriter::Write(StringPiece s) { 67 MaybeAddWhitespace(); 68 AppendString(s, out_); 69} 70 71static unordered_map<StringPiece, char*>* g_symtab; 72 73void InitSymtab() { 74 g_symtab = new unordered_map<StringPiece, char*>; 75} 76 77void QuitSymtab() { 78 for (auto p : *g_symtab) { 79 free(p.second); 80 } 81 delete g_symtab; 82} 83 84StringPiece Intern(StringPiece s) { 85 auto found = g_symtab->find(s); 86 if (found != g_symtab->end()) 87 return found->first; 88 89 char* b = static_cast<char*>(malloc(s.size()+1)); 90 memcpy(b, s.data(), s.size()); 91 s = StringPiece(b, s.size()); 92 (*g_symtab)[s] = b; 93 return s; 94} 95 96void AppendString(StringPiece str, string* out) { 97 out->append(str.begin(), str.end()); 98} 99 100bool HasPrefix(StringPiece str, StringPiece prefix) { 101 ssize_t size_diff = str.size() - prefix.size(); 102 return size_diff >= 0 && str.substr(0, prefix.size()) == prefix; 103} 104 105bool HasSuffix(StringPiece str, StringPiece suffix) { 106 ssize_t size_diff = str.size() - suffix.size(); 107 return size_diff >= 0 && str.substr(size_diff) == suffix; 108} 109 110StringPiece TrimSuffix(StringPiece str, StringPiece suffix) { 111 ssize_t size_diff = str.size() - suffix.size(); 112 if (size_diff < 0 || str.substr(size_diff) != suffix) 113 return str; 114 return str.substr(0, size_diff); 115} 116 117void AppendSubstPattern(StringPiece str, StringPiece pat, StringPiece subst, 118 string* out) { 119 size_t pat_percent_index = pat.find('%'); 120 if (pat_percent_index == string::npos) { 121 if (str == pat) { 122 AppendString(subst, out); 123 return; 124 } else { 125 AppendString(str, out); 126 return; 127 } 128 } 129 130 if (HasPrefix(str, pat.substr(0, pat_percent_index)) && 131 HasSuffix(str, pat.substr(pat_percent_index + 1))) { 132 size_t subst_percent_index = subst.find('%'); 133 if (subst_percent_index == string::npos) { 134 AppendString(subst, out); 135 return; 136 } else { 137 AppendString(subst.substr(0, subst_percent_index), out); 138 AppendString(str.substr(pat_percent_index, 139 str.size() - pat.size() + 1), out); 140 AppendString(subst.substr(subst_percent_index + 1), out); 141 return; 142 } 143 } 144 AppendString(str, out); 145} 146 147void AppendSubstRef(StringPiece str, StringPiece pat, StringPiece subst, 148 string* out) { 149 if (pat.find('%') != string::npos && subst.find('%') != string::npos) { 150 AppendSubstPattern(str, pat, subst, out); 151 return; 152 } 153 StringPiece s = TrimSuffix(str, pat); 154 out->append(s.begin(), s.end()); 155 out->append(subst.begin(), subst.end()); 156} 157 158string NoLineBreak(const string& s) { 159 size_t index = s.find('\n'); 160 if (index == string::npos) 161 return s; 162 string r = s; 163 while (index != string::npos) { 164 r = s.substr(0, index) + "\\n" + s.substr(index + 1); 165 index = s.find('\n', index + 2); 166 } 167 return r; 168} 169 170StringPiece TrimLeftSpace(StringPiece s) { 171 size_t i = 0; 172 while (i < s.size() && isspace(s[i])) 173 i++; 174 return s.substr(i, s.size() - i); 175} 176 177StringPiece TrimRightSpace(StringPiece s) { 178 size_t i = 0; 179 while (i < s.size() && isspace(s[s.size() - 1 - i])) 180 i++; 181 return s.substr(0, s.size() - i); 182} 183 184StringPiece TrimSpace(StringPiece s) { 185 return TrimRightSpace(TrimLeftSpace(s)); 186} 187