00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef NCL_NXSSTRING_H
00021 #define NCL_NXSSTRING_H
00022
00023
00024 #include <cstring>
00025 #include <cstdio>
00026 #include <functional>
00027 #include <ostream>
00028 #include <string>
00029 #include "ncl/nxsdefs.h"
00030
00031 class IndexSet;
00032
00042 class NxsString
00043 : public std::string
00044 {
00045 public:
00046 enum NxsQuotingRequirements
00047 {
00048 kNoQuotesNeededForNexus = 0,
00049 kSingleQuotesNeededForNexus,
00050 kUnderscoresSufficeForNexus
00051 };
00052
00053 class NxsX_NotANumber {};
00054 static bool case_insensitive_equals(const char *o, const char * t);
00055 static bool to_long(const char *c, long *n);
00056 static bool to_double(const char *c, double *n);
00057 static std::string strip_leading_whitespace(const std::string & s);
00058 static std::string strip_trailing_whitespace(const std::string & s);
00059 static std::string strip_surrounding_whitespace(const std::string & s);
00060 static std::string strip_whitespace(const std::string & s);
00061 static void split(const std::string &s, std::list<std::string> *);
00062 static std::string get_upper(const std::string &s)
00063 {
00064 std::string t(s);
00065 to_upper(t);
00066 return t;
00067 }
00068 static std::string & to_lower(std::string & s);
00069 static std::string & to_upper(std::string & s);
00070 static NxsQuotingRequirements determine_quoting_requirements(const std::string &);
00071 static void blanks_to_underscores(std::string &s);
00072 static void add_nxs_quotes(std::string &s);
00073 static int index_in_vector(const std::string &t, const std::vector<std::string> &v);
00074 static int index_in_array(const std::string &t, const char * * v, const unsigned n);
00075
00076 enum CmpEnum
00077 {
00078 respect_case,
00079 no_respect_case,
00080 abbrev
00081 };
00082
00083 NxsString();
00084 NxsString(const char *s);
00085 NxsString(const NxsString &s);
00086
00087 static std::string GetEscaped(const std::string &s);
00088 static std::string GetEscapedInt(const int &v);
00089 static std::string GetEscapedDouble(const double &v);
00090
00091
00092 bool Abbreviates(const NxsString &s, NxsString::CmpEnum mode = NxsString::no_respect_case) const;
00093 unsigned ConvertToUnsigned() const;
00094 int ConvertToInt() const;
00095 long ConvertToLong() const;
00096 double ConvertToDouble() const;
00097 bool Equals(const NxsString &s, NxsString::CmpEnum mode = respect_case) const;
00098 bool EqualsCaseInsensitive(const NxsString &s) const;
00099 NxsString GetQuoted() const;
00100 bool IsADouble() const;
00101 bool IsALong() const;
00102 bool IsCapAbbreviation(const NxsString &s) const;
00103 bool IsInVector(const NxsStringVector &s, NxsString::CmpEnum mode = respect_case) const;
00104 bool IsStdAbbreviation(const NxsString &s, bool respectCase) const;
00105 static bool IsNexusPunctuation(const char c);
00106 bool QuotesNeeded() const;
00107 NxsString UpperCasePrefix() const;
00108 friend std::ostream &operator<<(std::ostream &out, const NxsString &s);
00109
00110
00111
00112
00113 NxsString &operator=(char);
00114 NxsString &operator=(const char *s);
00115 NxsString &operator+=(const char *s);
00116 NxsString &operator+=(const std::string &s);
00117 NxsString &operator+=(const char c);
00118 NxsString &operator+=(const int i);
00119 NxsString &operator+=(unsigned i);
00120 NxsString &operator+=(unsigned long i);
00121 NxsString &operator+=(const long l);
00122 NxsString &operator+=(const double d);
00123 NxsString &operator+=(const IndexSet &d);
00124 NxsString &operator<<(int i);
00125 NxsString &operator<<(unsigned i);
00126 NxsString &operator<<(long l);
00127 NxsString &operator<<(unsigned long l);
00128 NxsString &operator<<(double d);
00129 NxsString &operator<<(const char *c);
00130 NxsString &operator<<(char c);
00131 NxsString &operator<<(const std::string &s);
00132 NxsString &operator<<(const IndexSet &s);
00133 NxsString &operator<<(NxsString &(*funcPtr)(NxsString &));
00134
00135
00136 void clear();
00137
00138 int PrintF(const char *formatStr, ...);
00139
00140 unsigned char *p_str(unsigned char *) const;
00141
00142 NxsString &AddQuotes();
00143 NxsString &AddTail(char c, unsigned n);
00144 NxsString &NumberThenWord(unsigned i, NxsString s);
00145 NxsString &ShortenTo(unsigned n);
00146 NxsString &AppendDouble(unsigned minFieldFormat, unsigned precFormat, double x);
00147 NxsString &Capitalize();
00148
00149 NxsString &RightJustifyString(const NxsString &s, unsigned w, bool clear_first = false);
00150 NxsString &RightJustifyLong(long x, unsigned w, bool clear_first = false);
00151 NxsString &RightJustifyDbl(double x, unsigned w, unsigned p, bool clear_first = false);
00152
00153 NxsString &ToLower()
00154 {
00155 to_lower(*this);
00156 return *this;
00157 }
00158 NxsString &ToUpper()
00159 {
00160 to_upper(*this);
00161 return *this;
00162 }
00163
00164
00165 NxsString &BlanksToUnderscores();
00166 NxsString &UnderscoresToBlanks();
00167
00168
00169
00170 static NxsString ToHex(long p, unsigned nFours);
00171 };
00172
00173 #if defined (NXS_SUPPORT_OLD_NAMES)
00174 typedef NxsString nxsstring;
00175 #endif
00176
00177
00182 inline NxsString &NxsString::AddQuotes()
00183 {
00184 add_nxs_quotes(*this);
00185 return *this;
00186 }
00187
00188 inline std::string NxsString::GetEscapedDouble(const double &v)
00189 {
00190 NxsString s;
00191 s << v;
00192 return NxsString::GetEscaped(s);
00193 }
00194
00195 inline std::string NxsString::GetEscapedInt(const int &v)
00196 {
00197 NxsString s;
00198 s << v;
00199 return NxsString::GetEscaped(s);
00200 }
00201
00202 inline std::string NxsString::GetEscaped(const std::string &s)
00203 {
00204 NxsQuotingRequirements r = determine_quoting_requirements(s);
00205 if (r == kNoQuotesNeededForNexus)
00206 return s;
00207 std::string x(s.c_str());
00208 if (r == kUnderscoresSufficeForNexus)
00209 blanks_to_underscores(x);
00210 else
00211 add_nxs_quotes(x);
00212 return x;
00213 }
00214
00215
00221 class NStrCaseInsensitiveEquals
00222 {
00223 public :
00224
00225 NStrCaseInsensitiveEquals(const NxsString &s);
00226 bool operator()(const NxsString &s);
00227
00228 protected :
00229
00230 NxsString compStr;
00231 };
00232
00237 class NStrCaseSensitiveEquals
00238 {
00239 public :
00240
00241 NStrCaseSensitiveEquals(const NxsString &s);
00242 bool operator()(const NxsString &s) const;
00243
00244 protected :
00245
00246 NxsString compStr;
00247 };
00248
00252 struct NxsStringEqual
00253 : public std::binary_function<NxsString, NxsString, bool>
00254 {
00255 bool operator()(const NxsString &x, const NxsString &y) const;
00256 };
00257
00258
00259
00263 inline NStrCaseInsensitiveEquals::NStrCaseInsensitiveEquals(
00264 const NxsString &s)
00265 {
00266 compStr = s;
00267 compStr.Capitalize();
00268 }
00269
00275 inline bool NStrCaseInsensitiveEquals::operator()(
00276 const NxsString &s)
00277 {
00278 if (s.length() == compStr.length())
00279 {
00280 NxsString capS(s);
00281 capS.Capitalize();
00282 return capS == compStr;
00283 }
00284 return false;
00285 }
00286
00287
00288
00292 inline NStrCaseSensitiveEquals::NStrCaseSensitiveEquals(
00293 const NxsString &s)
00294 {
00295 compStr = s;
00296 }
00297
00302 inline bool NStrCaseSensitiveEquals::operator()(
00303 const NxsString &s)
00304 const
00305 {
00306 return (compStr == s);
00307 }
00308
00309
00310
00314 inline bool NxsStringEqual::operator()(
00315 const NxsString &x,
00316 const NxsString &y)
00317 const
00318 {
00319 return x.EqualsCaseInsensitive(y);
00320 }
00321
00322
00323
00327 inline NxsString::NxsString()
00328 {
00329 }
00330
00335 inline NxsString NxsString::GetQuoted()
00336 const
00337 {
00338 NxsString s(*this);
00339 s.AddQuotes();
00340 return s;
00341 }
00342
00347 inline void NxsString::clear()
00348 {
00349 erase();
00350 }
00351
00355 inline bool NxsString::IsInVector(
00356 const NxsStringVector &s,
00357 NxsString::CmpEnum mode)
00358 const
00359 {
00360 for (NxsStringVector::const_iterator sIt = s.begin(); sIt != s.end(); sIt++)
00361 {
00362 if (Equals(*sIt, mode))
00363 return true;
00364 }
00365 return false;
00366 }
00367
00371 inline NxsString::NxsString(
00372 const char *s)
00373 {
00374 assign(s);
00375 }
00376
00380 inline NxsString::NxsString(
00381 const NxsString &s)
00382 :std::string()
00383 {
00384 assign(s);
00385 }
00386
00390 inline NxsString &NxsString::operator=(
00391 const char *s)
00392 {
00393 assign(s);
00394 return *this;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00407 inline NxsString &NxsString::operator+=(
00408 const char *s)
00409 {
00410 append(std::string(s));
00411 return *this;
00412 }
00413
00417 inline NxsString &NxsString::operator+=(
00418 const std::string &s)
00419 {
00420 append(s);
00421 return *this;
00422 }
00423
00427 inline NxsString &NxsString::operator+=(
00428 const char c)
00429 {
00430 char s[2];
00431 s[0] = c;
00432 s[1] = '\0';
00433 append(std::string(s));
00434 return *this;
00435 }
00436
00440 inline NxsString &NxsString::operator=(
00441 char c)
00442 {
00443 clear();
00444 return (*this += c);
00445 }
00446
00451 inline NxsString &NxsString::operator+=(
00452 const int i)
00453 {
00454 char tmp[81];
00455 sprintf(tmp, "%d", i);
00456 append(tmp);
00457 return *this;
00458 }
00459
00463 inline NxsString &NxsString::Capitalize()
00464 {
00465 ToUpper();
00466 return *this;
00467 }
00468
00472 inline bool NxsString::Abbreviates(
00473 const NxsString &s,
00474 NxsString::CmpEnum mode)
00475 const
00476 {
00477 if (mode == NxsString::abbrev)
00478 return IsCapAbbreviation(s);
00479 else
00480 return IsStdAbbreviation(s, mode == respect_case);
00481 }
00482
00486 inline NxsString& NxsString::operator+=(
00487 unsigned i)
00488 {
00489 char tmp[81];
00490 sprintf(tmp, "%u", i);
00491 append(tmp);
00492 return *this;
00493 }
00494
00498 inline NxsString& NxsString::operator+=(
00499 const long l)
00500 {
00501 char tmp[81];
00502 sprintf(tmp, "%ld", l);
00503 append(tmp);
00504 return *this;
00505 }
00506
00510 inline NxsString& NxsString::operator+=(
00511 const unsigned long l)
00512 {
00513 char tmp[81];
00514 sprintf(tmp, "%lu", l);
00515 append(tmp);
00516 return *this;
00517 }
00518
00522 inline bool NxsString::Equals(
00523 const NxsString &s,
00524 NxsString::CmpEnum mode)
00525 const
00526 {
00527 switch (mode) {
00528 case NxsString::respect_case :
00529 return (strcmp(this->c_str(), s.c_str()) == 0);
00530 case NxsString::no_respect_case :
00531 return this->EqualsCaseInsensitive(s);
00532 case NxsString::abbrev :
00533 return this->IsCapAbbreviation(s);
00534 default :
00535 NCL_ASSERT(0);
00536 }
00537 return false;
00538 }
00539
00544 inline NxsString &NxsString::operator<<(
00545 NxsString &(*funcPtr)(NxsString &))
00546 {
00547 return funcPtr(*this);
00548 }
00549
00556 inline bool NxsString::IsNexusPunctuation(
00557 const char c)
00558 {
00559 return (strchr("()[]{}/\\,;:=*\'\"`-+<>", c) != NULL);
00560 }
00561
00568 inline NxsString &NxsString::NumberThenWord(
00569 unsigned i,
00570 const NxsString s)
00571 {
00572 (*this).erase();
00573 *this << i << ' ' << s;
00574 if (i != 1)
00575 *this << 's';
00576 return *this;
00577 }
00578
00582 inline NxsString &NxsString::operator<<(
00583 int i)
00584 {
00585 return (*this += i);
00586 }
00587
00591 inline NxsString &NxsString::operator<<(
00592 unsigned i)
00593 {
00594 return (*this += (int) i);
00595 }
00596
00600 inline NxsString &NxsString::operator<<(
00601 long l)
00602 {
00603 return (*this += l);
00604 }
00605
00609 inline NxsString &NxsString::operator<<(
00610 unsigned long l)
00611 {
00612 return (*this += l);
00613 }
00614
00618 inline NxsString &NxsString::operator<<(
00619 double d)
00620 {
00621 return (*this += d);
00622 }
00623
00627 inline NxsString &NxsString::operator<<(
00628 const char *c)
00629 {
00630 return (*this += c);
00631 }
00632
00636 inline NxsString &NxsString::operator<<(
00637 char c)
00638 {
00639 return (*this += c);
00640 }
00641
00645 inline NxsString &NxsString::operator<<(
00646 const std::string &s)
00647 {
00648 return (*this += s);
00649 }
00650
00654 inline unsigned char *NxsString::p_str(
00655 unsigned char *buffer)
00656 const
00657 {
00658 memmove(buffer + 1, c_str(), length());
00659 buffer[0] = (unsigned char)length();
00660 return buffer;
00661 }
00662
00663
00664
00665 # if ! defined(HIDE_NCL_NXSSTRING_ENDL)
00666
00671 inline NxsString &endl(
00672 NxsString &s)
00673 {
00674 return (s += '\n');
00675 }
00676 #endif
00677
00682 inline NxsString &nxsendl(
00683 NxsString &s)
00684 {
00685 return (s += '\n');
00686 }
00687
00691 inline std::ostream &operator<<(
00692 std::ostream &out,
00693 const NxsString &s)
00694 {
00695 out << s.c_str();
00696 return out;
00697 }
00698
00699 NxsStringVector BreakPipeSeparatedList(const NxsString &strList);
00700 NxsStringVector GetVecOfPossibleAbbrevMatches(const NxsString &testStr,const NxsStringVector &possMatches);
00701 bool SetToShortestAbbreviation(NxsStringVector &strVec, bool allowTooShort = false);
00702
00703 #endif