1 /* 2 3 string replacement function 4 5 copyright (c) 2006 squell <squell@alumina.nl> 6 7 use, modification, copying and distribution of this software is permitted 8 under the conditions described in the file 'COPYING'. 9 10 Usage: 11 12 stredit::function is an abtract class for string-to-string mapping 13 14 Using stredit::format, any "%x"'s found will be processed; actual variables 15 will be passed on to a descendant class. 16 17 Optional modifiers to %x: 18 "+" Pass Throught A Capitalization Function 19 "-" convert to lower case 20 "_" Don't_eliminate_underscores_and don't compress spaces 21 "#" Pad numbers with (number of #'s-1) zero's. 22 "|alt|" Replace with alternate text if substitution would fail. 23 24 Special forms: 25 "%%" -> % 26 "%?" -> used for %| alt || alt? || alt? |? 27 28 stredit::array() will instantiate a formatter which looks up %0 to %9 in 29 the array passed as its argument. 30 31 Example: 32 33 char* tab[] = { "foo", "bar" }; 34 string s = array(tab)("%1, %+0"); // "bar, Foo" 35 36 */ 37 38 #ifndef __ZF_NSEDIT_HPP 39 #define __ZF_NSEDIT_HPP 40 41 #include <string> 42 #include "charconv.h" 43 44 namespace stredit { 45 46 class function { 47 public: 48 struct result : charset::conv<char> { resultresult49 result(const charset::conv<>& s, bool ok) 50 : charset::conv<char>(s), m_good(ok) { } resultresult51 result(const charset::conv<>& s) 52 : charset::conv<char>(s), m_good(!s.empty()) { } resultresult53 result(const std::string& s) 54 : charset::conv<char>(s), m_good(!s.empty()) { } resultresult55 result(const char* p) 56 : charset::conv<char>(p), m_good(*p) { } m_goodresult57 result(int ok = 0) : m_good(ok) { } goodresult58 bool good() const { return m_good; } 59 operator charset::conv<char> const*() const 60 { return good()? this : 0; } 61 private: 62 bool m_good; 63 }; 64 65 virtual result operator()(const charset::conv<char>&) const = 0; 66 }; 67 68 class identity : public function { operator()69 virtual result operator()(const charset::conv<char>& s) const 70 { return result(s,1); } 71 }; 72 73 class format : public function { 74 public: 75 static char const prefix = '%'; 76 operator()77 virtual result operator()(const charset::conv<char>& s) const 78 { return edit(charset::conv<wchar_t>(s), false); } 79 protected: 80 result edit(const std::wstring&, bool atomic) const; 81 82 typedef std::wstring::const_iterator ptr; 83 // on entry, p != end 84 virtual result code (ptr& p, ptr end) const; 85 virtual result var (ptr& p, ptr end) const = 0; 86 virtual ptr matching(ptr p, ptr end) const; 87 }; 88 89 template<class T> struct format_wrapper : format { format_wrapperformat_wrapper90 format_wrapper(T& i) : f(i) { } varformat_wrapper91 virtual result var(ptr& p, ptr) const 92 { return (charset::conv<char>) f(*p++); } 93 private: 94 T& f; 95 }; 96 97 template<class F> wrap(F & fun)98 format_wrapper<F> wrap(F& fun) { return fun; } 99 100 template<class T> struct format_array : format { format_arrayformat_array101 format_array(T i) : cont(i) { } varformat_array102 virtual result var(ptr& p, ptr) const 103 { return (charset::conv<char>) cont[*p++ - '0']; } 104 private: 105 T cont; 106 }; 107 108 template<class A> array(A & arr)109 format_array<A&> array(A& arr) { return format_array<A&>(arr); } 110 template<class A> array(A * arr)111 format_array<A*> array(A* arr) { return format_array<A*>(arr); } 112 } 113 114 #endif 115 116