Add utils
authorMikko Rasa <tdb@tdb.fi>
Fri, 16 Mar 2007 21:57:47 +0000 (21:57 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 16 Mar 2007 21:57:47 +0000 (21:57 +0000)
Fix a few bugs in Fmt

source/fmt.cpp
source/utils.cpp [new file with mode: 0644]
source/utils.h [new file with mode: 0644]

index c9f5d6c70eac16ff071acaf9208d9001925f2993..b476c36f6c2def97ec4093e7259ec52d1cad48bc 100644 (file)
@@ -32,7 +32,7 @@ void Fmt::apply(ostream &out) const
 {
        out.flags(((base==HEX) ? ios_base::hex : (base==OCT) ? ios_base::oct : ios_base::dec)
                | ((fmode==SCI) ? ios_base::scientific : (fmode==FIXED) ? ios_base::fixed : ios_base::fmtflags(0))
-               | (fillc ? ios_base::internal : (align==LEFT) ? ios_base::left : ios_base::right)
+               | (fillc=='0' ? ios_base::internal : (align==LEFT) ? ios_base::left : ios_base::right)
                | (sbase ? ios_base::showbase : ios_base::fmtflags(0))
                | (spoint ? ios_base::showpoint : ios_base::fmtflags(0))
                | (spos ? ios_base::showpos : ios_base::fmtflags(0))
@@ -93,11 +93,11 @@ void Fmt::parse(const char *f)
        else if(*f=='o')
                base=OCT;
        else if(*f=='e' || *f=='E')
-               fmode=EXP;
+               fmode=SCI;
        else if(*f=='f' || *f=='F')
                fmode=FIXED;
        else if(*f=='g' || *f=='G')
-               fmode=SCI;
+               fmode=EXP;
        else if(*f=='p')
        {
                base=HEX;
diff --git a/source/utils.cpp b/source/utils.cpp
new file mode 100644 (file)
index 0000000..3ef7b79
--- /dev/null
@@ -0,0 +1,116 @@
+#include <list>
+#include "utils.h"
+
+using namespace std;
+
+namespace Msp {
+
+/**
+Compares two strings, ignoring case.
+
+@param   s1  First string
+@param   s2  Second string
+
+@return  -1 if s1<s2, 0 if s1==s2, 1 if s1>s2
+*/
+int strcasecmp(const string &s1, const string &s2)
+{
+       string::const_iterator i1=s1.begin();
+       string::const_iterator i2=s2.begin();
+       for(; (i1!=s1.end() && i2!=s2.end()); ++i1, ++i2)
+       {
+               const char c1=::tolower(*i1);
+               const char c2=::tolower(*i2);
+               if(c1!=c2) return c1-c2;
+       }
+       if(i1!=s1.end()) return *i1;
+       if(i2!=s2.end()) return -*i2;
+       return 0;
+}
+
+/**
+Returns a lowercase copy of the given string.
+*/
+string tolower(const string &str)
+{
+       string  result(str);
+       transform(result.begin(), result.end(), result.begin(), ::tolower);
+       return result;
+}
+
+/**
+Returns an uppercase copy of the given string.
+*/
+string toupper(const string &str)
+{
+       string  result(str);
+       transform(result.begin(), result.end(), result.begin(), ::toupper);
+       return result;
+}
+
+/**
+Splits a string to parts.
+
+@param   str          String to be split
+@param   sep          A set of separator characters
+@param   allow_empty  Whether or not to produce empty parts for sequences of
+                      more than one separator character
+*/
+vector<string> split(const string &str, const string &sep, bool allow_empty)
+{
+       vector<string> result;
+       unsigned start=str.find_first_not_of(sep);
+       while(start<str.size())
+       {
+               unsigned        end=str.find_first_of(sep, start);
+               result.push_back(str.substr(start, end-start));
+               if(end==string::npos) break;
+               if(allow_empty)
+                       start=end+1;
+               else
+                       start=str.find_first_not_of(sep, end);
+       }
+       return result;
+}
+
+vector<string> split(const string &str, char sep, bool allow_empty)
+{
+       return split(str, string(1,sep), allow_empty);
+}
+
+/**
+Builds a single string from the strings in the given sequence by concatenating
+them.
+
+@param  seq  A sequence of strings
+@param  sep  Separator to be inserted between strings
+*/
+template<typename T>
+string join(const T &seq, const string &sep)
+{
+       string result;
+       for(typename T::const_iterator i=seq.begin(); i!=seq.end(); ++i)
+       {
+               if(i!=seq.begin())
+                       result+=sep;
+               result+=*i;
+       }
+
+       return result;
+}
+template string join<list<string> >(const list<string> &, const string &);
+template string join<vector<string> >(const vector<string> &, const string &);
+
+/**
+Returns a copy of the given string with leading and trailing whitespace
+removed.
+*/
+string strip(const string &s)
+{
+       string result=s;
+       if(!result.erase(0, result.find_first_not_of(" \t\n")).empty())
+               result.erase(result.find_last_not_of(" \t\n")+1);
+       return result;
+}
+
+} // namespace Msp
diff --git a/source/utils.h b/source/utils.h
new file mode 100644 (file)
index 0000000..1823f66
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef MSP_STRINGS_UTILS_H_
+#define MSP_STRINGS_UTILS_H_
+
+#include <string>
+#include <vector>
+
+namespace Msp {
+
+int strcasecmp(const std::string &, const std::string &);
+std::string tolower(const std::string &);
+std::string toupper(const std::string &);
+std::vector<std::string> split(const std::string &, const std::string & =" \t\r\n", bool =false);
+std::vector<std::string> split(const std::string &, char, bool =false);
+template<typename T>
+std::string join(const T &, const std::string & =" ");
+std::string strip(const std::string &);
+
+} // namespace Msp
+
+#endif