Mantid
Loading...
Searching...
No Matches
Strings.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include <cstdarg>
11#include <filesystem>
12#include <fstream>
13#include <list>
14#include <memory>
15
16using std::size_t;
17
19
20//------------------------------------------------------------------------------------------------
26std::string loadFile(const std::string &filename) {
27 std::string retVal;
28 std::string str;
29 std::ifstream in;
30 in.open(filename.c_str());
31 getline(in, str);
32 while (in) {
33 retVal += str + "\n";
34 getline(in, str);
35 }
36 in.close();
37 return retVal;
38}
39
40// ------------------------------------------------------------------------------------------------
52std::string shorten(const std::string &input, const size_t max_length) {
53 const std::string ellipsis = " ... ";
54 const size_t ellipsisSize = ellipsis.size();
55 // limit too small or input too small, return input string
56 if ((max_length == 0) || (input.size() < ellipsisSize + 2) || (input.size() <= max_length))
57 return input;
58
59 const size_t end_length = (max_length - ellipsisSize) / 2;
60 std::string retVal = input.substr(0, end_length) + ellipsis + input.substr(input.size() - end_length, end_length);
61 return retVal;
62}
63
64//------------------------------------------------------------------------------------------------
72std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with) {
73 std::string output = input;
74 std::string::size_type pos = 0;
75 while ((pos = output.find(find_what, pos)) != std::string::npos) {
76 output.erase(pos, find_what.length());
77 output.insert(pos, replace_with);
78 pos += replace_with.length();
79 }
80 return output;
81}
82
90MANTID_KERNEL_DLL std::string replaceAll(std::string const &input, char const to_replace, char const substitute) {
91 std::string replaced;
92 replaced.reserve(input.size());
93 std::transform(input.cbegin(), input.cend(), std::back_inserter(replaced),
94 [to_replace, substitute](char c) { return (c == to_replace) ? substitute : c; });
95 return replaced;
96}
97
107MANTID_KERNEL_DLL std::string replaceAll(const std::string &input, const std::string &charStr,
108 const std::string &substitute) {
109 std::string replaced;
110 replaced.reserve(input.size());
111 std::string::const_iterator iend = input.end();
112 for (std::string::const_iterator itr = input.begin(); itr != iend; ++itr) {
113 char inputChar = (*itr);
114 if (charStr.find_first_of(inputChar) == std::string::npos) // Input string
115 // char is not
116 // one of those
117 // to be replaced
118 {
119 replaced.push_back(inputChar);
120 } else {
121 replaced.append(substitute);
122 }
123 }
124 return replaced;
125}
126
129MANTID_KERNEL_DLL std::string toLower(const std::string &input) {
130 std::string output(input);
131 std::transform(output.begin(), output.end(), output.begin(), ::tolower);
132 return output;
133}
134
137MANTID_KERNEL_DLL std::string toUpper(const std::string &input) {
138 std::string output(input);
139 std::transform(output.begin(), output.end(), output.begin(), ::toupper);
140 return output;
141}
142
145MANTID_KERNEL_DLL bool endsWith(std::string const &str, std::string const &suffix) {
146 if (str.size() >= suffix.size()) {
147 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
148 }
149 return false;
150}
151
152//------------------------------------------------------------------------------------------------
160void printHex(std::ostream &OFS, const int n) {
161 std::ios_base::fmtflags PrevFlags = OFS.flags();
162 OFS << "Ox";
163 OFS.width(8);
164 OFS.fill('0');
165 hex(OFS);
166 OFS << n;
167 OFS.flags(PrevFlags);
168}
169
170//------------------------------------------------------------------------------------------------
176std::string stripMultSpc(const std::string &Line) {
177 std::string Out;
178 int spc(1);
179 int lastReal(-1);
180 for (unsigned int i = 0; i < Line.length(); i++) {
181 if (Line[i] != ' ' && Line[i] != '\t' && Line[i] != '\r' && Line[i] != '\n') {
182 lastReal = i;
183 spc = 0;
184 Out += Line[i];
185 } else if (!spc) {
186 spc = 1;
187 Out += ' ';
188 }
189 }
190 lastReal++;
191 if (lastReal < static_cast<int>(Out.length()))
192 Out.erase(lastReal);
193 return Out;
194}
195
196//------------------------------------------------------------------------------------------------
197//------------------------------------------------------------------------------------------------
208int extractWord(std::string &Line, const std::string &Word, const int cnt) {
209 if (Word.empty())
210 return 0;
211
212 size_t minSize(cnt > static_cast<int>(Word.size()) ? Word.size() : cnt);
213 std::string::size_type pos = Line.find(Word.substr(0, minSize));
214 if (pos == std::string::npos)
215 return 0;
216 // Pos == Start of find
217 size_t LinePt = minSize + pos;
218 for (; minSize < Word.size() && LinePt < Line.size() && Word[minSize] == Line[LinePt]; LinePt++, minSize++) {
219 }
220
221 Line.erase(pos, LinePt - (pos - 1));
222 return 1;
223}
224
225//------------------------------------------------------------------------------------------------
232int endsWithInt(const std::string &word) {
233 if (word.empty())
234 return -1;
235 int out = -1;
236 // Find the index of the first number in the string (if any)
237 auto firstNumber = int(word.size());
238 for (int i = int(word.size()) - 1; i >= 0; i--) {
239 char c = word[i];
240 if ((c > '9') || (c < '0'))
241 break;
242 firstNumber = i;
243 }
244 // Convert the string of decimals to an int
245 if (firstNumber < int(word.size())) {
246 std::string part = word.substr(firstNumber, word.size() - firstNumber);
247 if (!convert(part, out))
248 return -1;
249 }
250 return out;
251}
252
253//------------------------------------------------------------------------------------------------
261int confirmStr(const std::string &S, const std::string &fullPhrase) {
262 const size_t nS(S.length());
263 const size_t nC(fullPhrase.length());
264 if (nS > nC || nS == 0)
265 return 0;
266 for (size_t i = 0; i < nS; i++)
267 if (S[i] != fullPhrase[i])
268 return 0;
269 return 1;
270}
271
272//------------------------------------------------------------------------------------------------
284int getPartLine(std::istream &fh, std::string &Out, std::string &Excess, const int spc) {
285 // std::string Line;
286 if (fh.good()) {
287 auto ss = new char[spc + 1];
288 const auto clen = static_cast<int>(spc - Out.length());
289 fh.getline(ss, clen, '\n');
290 ss[clen + 1] = 0; // incase line failed to read completely
291 Out += static_cast<std::string>(ss);
292 delete[] ss;
293 // remove trailing comments
294 std::string::size_type pos = Out.find_first_of("#!");
295 if (pos != std::string::npos) {
296 Out.erase(pos);
297 return 0;
298 }
299 if (fh.gcount() == clen - 1) // cont line
300 {
301 pos = Out.find_last_of("\t ");
302 if (pos != std::string::npos) {
303 Excess = Out.substr(pos, std::string::npos);
304 Out.erase(pos);
305 } else
306 Excess.erase(0, std::string::npos);
307 fh.clear();
308 return 1;
309 }
310 return 0;
311 }
312 return -1;
313}
314
315//------------------------------------------------------------------------------------------------
322std::string removeSpace(const std::string &CLine) {
323 std::string Out;
324 char prev = 'x';
325 for (char character : CLine) {
326 if (!isspace(character) || prev == '\\') {
327 Out += character;
328 prev = character;
329 }
330 }
331 return Out;
332}
333
334//------------------------------------------------------------------------------------------------
341std::string getLine(std::istream &fh) {
342 std::string line;
343 getLine(fh, line);
344 return line;
345}
346
347//------------------------------------------------------------------------------------------------
354void getLine(std::istream &fh, std::string &Line) {
355 if (std::getline(fh, Line)) {
356 // remove trailing comments
357 auto pos = Line.find_first_of("#!");
358 if (pos != std::string::npos)
359 Line.erase(pos);
360 }
361}
362
366std::string peekLine(std::istream &fh) {
367 std::string str;
368 std::streampos pos = fh.tellg();
369 getline(fh, str);
370 fh.seekg(pos);
371
372 return strip(str);
373}
374
375//------------------------------------------------------------------------------------------------
381int isEmpty(const std::string &A) {
382 std::string::size_type pos = A.find_first_not_of(" \t");
383 return (pos != std::string::npos) ? 0 : 1;
384}
385
386//------------------------------------------------------------------------------------------------
392void stripComment(std::string &A) {
393 std::string::size_type posA = A.find("$ ");
394 std::string::size_type posB = A.find("# ");
395 std::string::size_type posC = A.find('!');
396 if (posA > posB)
397 posA = posB;
398 if (posA > posC)
399 posA = posC;
400 if (posA != std::string::npos)
401 A.erase(posA, std::string::npos);
402}
403
404//------------------------------------------------------------------------------------------------
411std::string fullBlock(const std::string &A) { return strip(A); }
412
413//------------------------------------------------------------------------------------------------
419std::string strip(const std::string &A) {
420 std::string result(A);
421 stripInPlace(result);
422 return result;
423}
424
425//------------------------------------------------------------------------------------------------
429void stripInPlace(std::string &A) {
430 A.erase(A.begin(), std::find_if_not(A.begin(), A.end(), ::isspace));
431 A.erase(std::find_if_not(A.rbegin(), A.rend(), ::isspace).base(), A.end());
432}
433
439bool skipLine(const std::string &line) {
440 // Empty or comment
441 return (line.empty() || line.starts_with("#"));
442}
443
444//------------------------------------------------------------------------------------------------
452void writeMCNPX(const std::string &Line, std::ostream &OX) {
453 const int MaxLine(72);
454 std::string::size_type pos(0);
455 std::string X = Line.substr(0, MaxLine);
456 std::string::size_type posB = X.find_last_of(" ,");
457 int spc(0);
458 while (posB != std::string::npos && static_cast<int>(X.length()) >= MaxLine - spc) {
459 pos += posB + 1;
460 if (!isspace(X[posB]))
461 posB++;
462 const std::string Out = X.substr(0, posB);
463 if (!isEmpty(Out)) {
464 if (spc)
465 OX << std::string(spc, ' ');
466 OX << X.substr(0, posB) << '\n';
467 }
468 spc = 8;
469 X = Line.substr(pos, MaxLine - spc);
470 posB = X.find_last_of(" ,");
471 }
472 if (!isEmpty(X)) {
473 if (spc)
474 OX << std::string(spc, ' ');
475 OX << X << '\n';
476 }
477}
478
479//------------------------------------------------------------------------------------------------
490
500std::map<std::string, std::string> splitToKeyValues(const std::string &input, const std::string &keyValSep,
501 const std::string &listSep) {
502 std::map<std::string, std::string> keyValues;
503 const int splitOptions =
505 Mantid::Kernel::StringTokenizer listSplitter(input, listSep);
506 for (const auto &iter : listSplitter) {
507 Mantid::Kernel::StringTokenizer keyValSplitter(iter, keyValSep, splitOptions);
508 if (keyValSplitter.count() == 2) {
509 keyValues[keyValSplitter[0]] = keyValSplitter[1];
510 }
511 }
512
513 return keyValues;
514}
515
516//------------------------------------------------------------------------------------------------
522float getVAXnum(const float A) {
523 union {
524 // char a[4];
525 float f;
526 int ival;
527 } Bd;
528
529 int sign, expt, fmask;
530 float frac;
531 double onum;
532
533 Bd.f = A;
534 sign = (Bd.ival & 0x8000) ? -1 : 1;
535 expt = ((Bd.ival & 0x7f80) >> 7); // reveresed ?
536 if (!expt)
537 return 0.0;
538
539 fmask = ((Bd.ival & 0x7f) << 16) | ((Bd.ival & 0xffff0000) >> 16);
540 expt -= 128;
541 fmask |= 0x800000;
542 frac = static_cast<float>(fmask) / 0x1000000;
543 onum = frac * static_cast<float>(sign) * pow(2.0, expt);
544 return static_cast<float>(onum);
545}
546
547//------------------------------------------------------------------------------------------------
558template <typename T> int sectPartNum(std::string &A, T &out) {
559 if (A.empty())
560 return 0;
561
562 std::istringstream cx;
563 T retval;
564 cx.str(A);
565 cx.clear();
566 cx >> retval;
567 const std::streamoff xpt = cx.tellg();
568 if (xpt < 0)
569 return 0;
570 A.erase(0, static_cast<unsigned int>(xpt));
571 out = retval;
572 return 1;
573}
574
575//------------------------------------------------------------------------------------------------
584template <typename T> int section(char *cA, T &out) {
585 if (!cA)
586 return 0;
587 std::string sA(cA);
588 const int item(section(sA, out));
589 if (item) {
590 strcpy(cA, sA.c_str());
591 return 1;
592 }
593 return 0;
594}
595
604template <typename T> int section(std::string &A, T &out) {
605 if (A.empty())
606 return 0;
607 std::istringstream cx;
608 T retval;
609 cx.str(A);
610 cx.clear();
611 cx >> retval;
612 if (cx.fail())
613 return 0;
614 const std::streamoff xpt = cx.tellg();
615 const auto xc = static_cast<char>(cx.get());
616 if (!cx.fail() && !isspace(xc))
617 return 0;
618 A.erase(0, static_cast<unsigned int>(xpt));
619 out = retval;
620 return 1;
621}
622
634template <typename T> int sectionMCNPX(std::string &A, T &out) {
635 if (A.empty())
636 return 0;
637 std::istringstream cx;
638 T retval;
639 cx.str(A);
640 cx.clear();
641 cx >> retval;
642 if (!cx.fail()) {
643 const std::streamoff xpt = cx.tellg();
644 if (xpt < 0) {
645 return 0;
646 }
647 const auto xc = static_cast<char>(cx.get());
648 if (!cx.fail() && !isspace(xc) && (xc != '-' || xpt < 5)) {
649 return 0;
650 }
651 A.erase(0, static_cast<unsigned int>(xpt));
652 out = retval;
653 return 1;
654 }
655 return 0;
656}
657
658//------------------------------------------------------------------------------------------------
670template <typename T> int convPartNum(const std::string &A, T &out) {
671 if (A.empty())
672 return 0;
673 std::istringstream cx;
674 T retval;
675 cx.str(A);
676 cx.clear();
677 cx >> retval;
678 // If we have reached the end of the stream, then we need to clear the error
679 // as
680 // it will cause the tellg() call to return -1. Not pretty but works for now.
681 cx.clear();
682 const std::streamoff xpt = cx.tellg();
683 if (xpt < 0)
684 return 0;
685 out = retval;
686 return static_cast<int>(xpt);
687}
688
689//------------------------------------------------------------------------------------------------
696template <typename T> int convert(const std::string &A, T &out) {
697 if (A.empty())
698 return 0;
699 std::istringstream cx;
700 T retval;
701 cx.str(A);
702 cx.clear();
703 cx >> retval;
704 if (cx.fail())
705 return 0;
706 const auto clast = static_cast<char>(cx.get());
707 if (!cx.fail() && !isspace(clast))
708 return 0;
709 out = retval;
710 return 1;
711}
712
713//------------------------------------------------------------------------------------------------
720template <typename T> int convert(const char *A, T &out) {
721 // No string, no conversion
722 if (!A)
723 return 0;
724 std::string Cx = A;
725 return convert(Cx, out);
726}
727
728//------------------------------------------------------------------------------------------------
734template <typename T> std::string toString(const T &value) {
735 std::ostringstream mess;
736 mess << value;
737 return mess.str();
738}
739
746template <typename T> std::string toString(const std::vector<T> &value) {
747 std::ostringstream mess;
748 auto it = value.begin();
749 auto last = value.end();
750 T start;
751 T stop;
752 for (; it != last; ++it) {
753 start = *(it);
754 stop = start;
755 for (; it != last; ++it) {
756 if (it + 1 == last)
757 break;
758 else if ((stop + static_cast<T>(1)) == *(it + 1))
759 stop = *(it + 1);
760 else
761 break;
762 }
763 mess << start;
764 if (start != stop)
765 mess << "-" << stop;
766 if (it + 1 != last)
767 mess << ",";
768 }
769 return mess.str();
770}
771
772template <typename T> std::string toString(const std::set<T> &value) {
773 return toString(std::vector<T>(value.begin(), value.end()));
774}
775
776template <> MANTID_KERNEL_DLL std::string toString(const UnitLabel &value) { return value; }
777
781template <> MANTID_KERNEL_DLL std::string toString(const std::vector<std::string> &value) {
782 return join(value.begin(), value.end(), ",");
783}
784
785//------------------------------------------------------------------------------------------------
793template <template <typename T, typename A> class V, typename T, typename A>
794int writeFile(const std::string &Fname, const T &step, const V<T, A> &Y) {
795 V<T, A> Ex; // Empty vector
796 V<T, A> X; // Empty vector
797 for (unsigned int i = 0; i < Y.size(); i++)
798 X.emplace_back(i * step);
799
800 return writeFile(Fname, X, Y, Ex);
801}
802
803//------------------------------------------------------------------------------------------------
811template <template <typename T, typename A> class V, typename T, typename A>
812int writeFile(const std::string &Fname, const V<T, A> &X, const V<T, A> &Y) {
813 V<T, A> Ex; // Empty vector/list
814 return writeFile(Fname, X, Y, Ex); // don't need to specific ??
815}
816
817//------------------------------------------------------------------------------------------------
829template <template <typename T, typename A> class V, typename T, typename A>
830int writeFile(const std::string &Fname, const V<T, A> &X, const V<T, A> &Y, const V<T, A> &Err) {
831 const size_t Npts(X.size() > Y.size() ? Y.size() : X.size());
832 const size_t Epts(Npts > Err.size() ? Err.size() : Npts);
833
834 std::ofstream FX;
835
836 FX.open(Fname.c_str());
837 if (!FX.good())
838 return -1;
839
840 FX << "# " << Npts << " " << Epts << '\n';
841 FX.precision(10);
842 FX.setf(std::ios::scientific, std::ios::floatfield);
843 auto xPt = X.cbegin();
844 auto yPt = Y.cbegin();
845 auto ePt = (Epts ? Err.cbegin() : Y.cbegin());
846
847 // Double loop to include/exclude a short error stack
848 size_t eCount = 0;
849 for (; eCount < Epts; eCount++) {
850 FX << (*xPt) << " " << (*yPt) << " " << (*ePt) << '\n';
851 ++xPt;
852 ++yPt;
853 ++ePt;
854 }
855 for (; eCount < Npts; eCount++) {
856 FX << (*xPt) << " " << (*yPt) << " 0.0\n";
857 ++xPt;
858 ++yPt;
859 }
860 FX.close();
861 return 0;
862}
863
864//------------------------------------------------------------------------------------------------
875template <typename T> int setValues(const std::string &Line, const std::vector<int> &Index, std::vector<T> &Out) {
876 if (Index.empty())
877 return 0;
878
879 if (Out.size() != Index.size())
880 return -1;
881 // throw ColErr::MisMatch<int>(Index.size(),Out.size(),
882 // "Mantid::Kernel::Strings::setValues");
883
884 std::string modLine = Line;
885 std::vector<int> sIndex(Index); // Copy for sorting
886 std::vector<int> OPt(Index.size());
887 for (unsigned int i = 0; i < Index.size(); i++)
888 OPt[i] = i;
889
890 // mathFunc::crossSort(sIndex,OPt);
891
892 using iVecIter = std::vector<int>::const_iterator;
893 std::vector<int>::const_iterator sc = sIndex.begin();
894 std::vector<int>::const_iterator oc = OPt.begin();
895 int cnt(0);
896 T value;
897 std::string dump;
898 while (sc != sIndex.end() && *sc < 0) {
899 ++sc;
900 ++oc;
901 }
902
903 while (sc != sIndex.end()) {
904 if (*sc == cnt) {
905 if (!section(modLine, value))
906 return static_cast<int>(-1 - distance(static_cast<iVecIter>(sIndex.begin()), sc));
907 // this loop handles repeat units
908 do {
909 Out[*oc] = value;
910 ++sc;
911 ++oc;
912 } while (sc != sIndex.end() && *sc == cnt);
913 } else {
914 if (!section(modLine, dump))
915 return static_cast<int>(-1 - distance(static_cast<iVecIter>(sIndex.begin()), sc));
916 }
917 cnt++; // Add only to cnt [sc/oc in while loop]
918 }
919 // Success since loop only gets here if sc is exhaused.
920 return 0;
921}
922
923//-----------------------------------------------------------------------------------------------
931std::string getWord(std::istream &in, bool consumeEOL) {
932 std::string ret;
933 char nextch = 0;
934
935 // Skip leading spaces
936 do {
937 nextch = static_cast<char>(in.get());
938 } while (nextch == ' ');
939
940 // Return an empty string on EOL; optionally consume it
941 if (nextch == '\n' || nextch == '\r') {
942 if (!consumeEOL) {
943 in.unget();
944 } else if ((nextch == '\n' && in.peek() == '\r') || (nextch == '\r' && in.peek() == '\n')) {
945 // Handle CRLF and LFCR on Unix by consuming both
946 in.ignore();
947 }
948
949 return ret;
950 } else { // Non-EOL and non-space character
951 in.unget(); // Put it back on stream
952 }
953
954 // Get next word if stream is still valid
955 if (in.good())
956 in >> ret;
957
958 // Optionally consume EOL character
959 if (consumeEOL) {
960 nextch = static_cast<char>(in.get());
961
962 // Handle CRLF and LFCR on Unix by consuming both
963 if (nextch == '\n' || nextch == '\r') {
964 if ((nextch == '\n' && in.peek() == '\r') || (nextch == '\r' && in.peek() == '\n')) {
965 in.ignore();
966 }
967 } else {
968 in.unget();
969 }
970 }
971
972 return ret;
973}
974
975//-----------------------------------------------------------------------------------------------
982void readToEndOfLine(std::istream &in, bool ConsumeEOL) {
983 while (in.good() && getWord(in, false).length() > 0)
984 getWord(in, false);
985 if (!ConsumeEOL)
986 return;
987 getWord(in, true);
988}
989
1001size_t split_path(const std::string &path, std::vector<std::string> &path_components) {
1002 if (path.empty()) {
1003 path_components.resize(0);
1004 return 0;
1005 }
1006 // convert Windows path into the unix one
1007 std::string working_path(path);
1008 for (size_t i = 0; i < path.size(); i++) {
1009 if (working_path[i] < 0x20 || working_path[i] > 0x7E)
1010 working_path[i] = '_';
1011 if (working_path[i] == '\\')
1012 working_path[i] = '/';
1013 if (working_path[i] == ' ')
1014 working_path[i] = '_';
1015 }
1016
1017 // path start with relative character, and we need to convert it into full
1018 // path
1019 if (path[0] == '.') {
1020 // get absolute path using working directory as base;
1021 std::filesystem::path absol = std::filesystem::absolute(std::filesystem::current_path());
1022 working_path = (absol / working_path).generic_string();
1023 }
1024 // as poco splt using regular expressions is doing some rubbish, we need to do
1025 // split manually
1026 // code below implements perl split(/\\//,string) commamd. (\\ has been
1027 // converted to / above)
1028 std::list<int64_t> split_pos;
1029 split_pos.emplace_back(-1);
1030 size_t path_size = working_path.size();
1031 for (size_t i = 0; i < path_size; i++) {
1032 if (working_path[i] == '/') {
1033 split_pos.emplace_back(i);
1034 }
1035 }
1036 split_pos.emplace_back(path_size);
1037 // allocate target vector to keep folder structure and fill it in
1038 size_t n_folders = split_pos.size() - 1;
1039 path_components.resize(n_folders);
1040 auto it1 = split_pos.begin();
1041 auto it2 = it1;
1042 ++it2;
1043
1044 int64_t ic(0);
1045 for (; it2 != split_pos.end(); ++it2) {
1046 std::string folder = working_path.substr(*it1 + 1, *it2 - *it1 - 1);
1047 if (folder.empty() || (folder.size() == 1 && folder == ".")) { // skip self-references and double slashes;
1048 it1 = it2;
1049 continue;
1050 }
1051 // reprocess up-references;
1052 if (folder == "..") {
1053 ic--;
1054 if (ic < 0)
1055 throw(std::invalid_argument("path contains relative references to a "
1056 "folder outside of the seach tree"));
1057 it1 = it2;
1058 continue;
1059 }
1060 path_components[ic] = folder;
1061 ic++;
1062 it1 = it2;
1063 }
1064
1065 n_folders = size_t(ic);
1066 path_components.resize(n_folders);
1067 return n_folders;
1068}
1069
1080int isMember(const std::vector<std::string> &group, const std::string &candidate) {
1081 int num(-1);
1082 for (size_t i = 0; i < group.size(); i++) {
1083 if (candidate == group[i]) {
1084 num = int(i);
1085 return num;
1086 }
1087 }
1088 return num;
1089}
1090
1101std::vector<int> parseRange(const std::string &str, const std::string &elemSep, const std::string &rangeSep) {
1102 using Tokenizer = Mantid::Kernel::StringTokenizer;
1103
1104 Tokenizer elements;
1105
1106 if (elemSep.find(' ') != std::string::npos) {
1107 // If element separator contains space character it's a special case,
1108 // because in that case
1109 // it is allowed to have element separator inside a range, e.g. "4 - 5", but
1110 // not "4,-5"
1111 Tokenizer ranges(str, rangeSep, Tokenizer::TOK_TRIM);
1112 std::string new_str = join(ranges.begin(), ranges.end(), rangeSep.substr(0, 1));
1113 elements = Tokenizer(new_str, elemSep, Tokenizer::TOK_IGNORE_EMPTY | Tokenizer::TOK_TRIM);
1114 } else {
1115 elements = Tokenizer(str, elemSep, Tokenizer::TOK_IGNORE_EMPTY | Tokenizer::TOK_TRIM);
1116 }
1117
1118 std::vector<int> result;
1119
1120 // Estimation of the resulting number of elements
1121 result.reserve(elements.count());
1122
1123 for (const auto &elementString : elements) {
1124 // See above for the reason space is added
1125 Tokenizer rangeElements(elementString, rangeSep, Tokenizer::TOK_TRIM);
1126
1127 size_t noOfRangeElements = rangeElements.count();
1128
1129 // A single element
1130 if (noOfRangeElements == 1) {
1131 int element;
1132 if (convert(rangeElements[0], element) != 1)
1133 throw std::invalid_argument("Invalid element: " + elementString);
1134 result.emplace_back(element);
1135 }
1136 // A pair
1137 else if (noOfRangeElements == 2) {
1138 int start, end;
1139
1140 if (convert(rangeElements[0], start) != 1 || convert(rangeElements[1], end) != 1)
1141 throw std::invalid_argument("Invalid range: " + elementString);
1142
1143 if (start >= end)
1144 throw std::invalid_argument("Range boundaries are reversed: " + elementString);
1145
1146 for (int i = start; i <= end; i++)
1147 result.emplace_back(i);
1148 }
1149 // Error - e.g. "--""
1150 else {
1151 throw std::invalid_argument("Multiple range separators: " + elementString);
1152 }
1153 }
1154
1155 return result;
1156}
1157
1167std::istream &extractToEOL(std::istream &is, std::string &str) {
1168 // Empty the string
1169 str = "";
1170 char c('\0');
1171 while (is.get(c)) {
1172 if (c == '\r') {
1173 c = static_cast<char>(is.peek());
1174 if (c == '\n') {
1175 // Extract this as well
1176 is.get();
1177 }
1178 break;
1179 } else if (c == '\n') {
1180 break;
1181 } else {
1182 // Accumulate the string
1183 str += c;
1184 }
1185 }
1186 return is;
1187}
1188
1189//------------------------------------------------------------------------------------------------
1190std::string randomString(size_t len) {
1191 static const std::string alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
1192
1193 std::string result;
1194 result.reserve(len);
1195
1196 while (result.size() != len) {
1197 size_t randPos = ((rand() % (alphabet.size() - 1)));
1198 result.push_back(alphabet[randPos]);
1199 }
1200
1201 return result;
1202}
1203
1205std::string strmakef(const char *const fmt, ...) {
1206 std::size_t constexpr BUFSIZE{256};
1207 std::string res{};
1208 if (fmt) { // ensure the format string is not null
1209 char buf[BUFSIZE];
1210 va_list args;
1211 va_start(args, fmt);
1212 // NOTE vsnprintf is limited to only write BUFSIZE chars
1213 int const r = std::vsnprintf(buf, BUFSIZE, fmt, args);
1214 va_end(args);
1215 if (r >= 0) { // conversion succeeded
1216 size_t const len(r);
1217 res.resize(len);
1218 if (len < BUFSIZE) { // output fit into buf; return buf
1219 res.assign(buf, len);
1220 } else { // otherwise, read again with proper size
1221 va_start(args, fmt);
1222 int const r2 = std::vsnprintf(res.data(), len + 1, fmt, args);
1223 va_end(args);
1224 if (r2 < 0 || static_cast<std::size_t>(r2) != len) {
1225 res = ""; // unspecified error due to run-time memory failure
1226 }
1227 }
1228 }
1229 }
1230 return res;
1231}
1232
1234template MANTID_KERNEL_DLL int section(std::string &, double &);
1235template MANTID_KERNEL_DLL int section(std::string &, float &);
1236template MANTID_KERNEL_DLL int section(std::string &, int &);
1237template MANTID_KERNEL_DLL int section(std::string &, std::string &);
1238
1239template MANTID_KERNEL_DLL int sectPartNum(std::string &, double &);
1240template MANTID_KERNEL_DLL int sectPartNum(std::string &, int &);
1241template MANTID_KERNEL_DLL int sectionMCNPX(std::string &, double &);
1242
1243template MANTID_KERNEL_DLL int convert(const std::string &, double &);
1244template MANTID_KERNEL_DLL int convert(const std::string &, float &);
1245template MANTID_KERNEL_DLL int convert(const std::string &, std::string &);
1246template MANTID_KERNEL_DLL int convert(const std::string &, int &);
1247template MANTID_KERNEL_DLL int convert(const std::string &, std::size_t &);
1248template MANTID_KERNEL_DLL int convert(const std::string &, bool &);
1249template MANTID_KERNEL_DLL int convert(const char *, std::string &);
1250template MANTID_KERNEL_DLL int convert(const char *, double &);
1251template MANTID_KERNEL_DLL int convert(const char *, int &);
1252template MANTID_KERNEL_DLL int convert(const char *, std::size_t &);
1253template MANTID_KERNEL_DLL int convert(const char *, bool &);
1254
1255template MANTID_KERNEL_DLL std::string toString(const double &value);
1256template MANTID_KERNEL_DLL std::string toString(const float &value);
1257template MANTID_KERNEL_DLL std::string toString(const int &value);
1258template MANTID_KERNEL_DLL std::string toString(const uint16_t &value);
1259template MANTID_KERNEL_DLL std::string toString(const size_t &value); // Matches uint64_t on Linux 64 & Win 64
1260#if defined(__APPLE__) || (defined(_WIN32) && !defined(_WIN64)) || \
1261 (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler
1262template MANTID_KERNEL_DLL std::string toString(const uint64_t &value);
1263#endif
1264template MANTID_KERNEL_DLL std::string toString(const std::string &value);
1265
1266template MANTID_KERNEL_DLL std::string toString(const std::vector<int> &value);
1267template MANTID_KERNEL_DLL std::string toString(const std::vector<size_t> &value);
1268
1269// this block should generate the vector ones as well
1270template MANTID_KERNEL_DLL std::string toString(const std::set<int> &value);
1271template MANTID_KERNEL_DLL std::string toString(const std::set<int16_t> &value);
1272template MANTID_KERNEL_DLL std::string toString(const std::set<size_t> &value); // Matches uint64_t on Linux 64 & Win 64
1273#if defined(__APPLE__) || (defined(_WIN32) && !defined(_WIN64)) || \
1274 (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler
1275template MANTID_KERNEL_DLL std::string toString(const std::set<uint64_t> &value);
1276#endif
1277
1278template MANTID_KERNEL_DLL int convPartNum(const std::string &, double &);
1279template MANTID_KERNEL_DLL int convPartNum(const std::string &, int &);
1280
1281template MANTID_KERNEL_DLL int setValues(const std::string &, const std::vector<int> &, std::vector<double> &);
1282
1283template MANTID_KERNEL_DLL int writeFile(const std::string &, const double &, const std::vector<double> &);
1284template MANTID_KERNEL_DLL int writeFile(const std::string &, const std::vector<double> &, const std::vector<double> &,
1285 const std::vector<double> &);
1286template MANTID_KERNEL_DLL int writeFile(const std::string &, const std::vector<double> &, const std::vector<double> &);
1287template MANTID_KERNEL_DLL int writeFile(const std::string &, const std::vector<float> &, const std::vector<float> &);
1288template MANTID_KERNEL_DLL int writeFile(const std::string &, const std::vector<float> &, const std::vector<float> &,
1289 const std::vector<float> &);
1291
1292} // namespace Mantid::Kernel::Strings
double value
The value of the point.
Definition FitMW.cpp:51
Impliments a line.
Definition Line.h:43
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
const TokenVec & asVector()
Returns a vector of tokenized strings.
std::size_t count() const
Get the total number of tokens.
A base-class for the a class that is able to return unit labels in different representations.
Definition UnitLabel.h:20
Holds support functions for strings.
MANTID_KERNEL_DLL void stripInPlace(std::string &A)
strip pre/post spaces
Definition Strings.cpp:429
MANTID_KERNEL_DLL std::string removeSpace(const std::string &CLine)
strip all spaces
Definition Strings.cpp:322
MANTID_KERNEL_DLL std::string toLower(const std::string &input)
Converts string to all lowercase.
Definition Strings.cpp:129
MANTID_KERNEL_DLL std::istream & extractToEOL(std::istream &is, std::string &str)
Extract a line from input stream, discarding any EOL characters encountered.
Definition Strings.cpp:1167
MANTID_KERNEL_DLL std::string strmakef(char const *const fmt,...)
This is the constructor that std::string needed to have.
Definition Strings.cpp:1205
int sectPartNum(std::string &A, T &out)
Convert and cut a string.
Definition Strings.cpp:558
MANTID_KERNEL_DLL size_t split_path(const std::string &path, std::vector< std::string > &path_components)
function parses a path, found in input string "path" and returns vector of the folders contributed in...
Definition Strings.cpp:1001
MANTID_KERNEL_DLL int confirmStr(const std::string &S, const std::string &fullPhrase)
determine if a character group exists in a string
Definition Strings.cpp:261
float getVAXnum(const float A)
Convert a VAX number to x86 little eindien.
Definition Strings.cpp:522
MANTID_KERNEL_DLL std::vector< int > parseRange(const std::string &str, const std::string &elemSep=",", const std::string &rangeSep="-")
Parses a number range, e.g.
Definition Strings.cpp:1101
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
Definition Strings.cpp:419
MANTID_KERNEL_DLL std::string shorten(const std::string &input, const size_t max_length)
Converts long strings into "start ... end".
Definition Strings.cpp:52
int convPartNum(const std::string &A, T &out)
Takes a character string and evaluates the first [typename T] object.
Definition Strings.cpp:670
MANTID_KERNEL_DLL int isMember(const std::vector< std::string > &group, const std::string &candidate)
checks if the candidate is the member of the group
Definition Strings.cpp:1080
DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, typename std::enable_if<!(std::is_same< typename std::iterator_traits< ITERATOR_TYPE >::iterator_category, std::random_access_iterator_tag >::value)>::type *=nullptr)
Join a set or vector of (something that turns into a string) together into one string,...
Definition Strings.h:84
MANTID_KERNEL_DLL std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with)
Return a string with all matching occurence-strings.
Definition Strings.cpp:72
MANTID_KERNEL_DLL std::string randomString(const size_t len)
Generates random alpha-numeric string.
Definition Strings.cpp:1190
int section(std::string &A, T &out)
Convert and cut a string.
Definition Strings.cpp:604
MANTID_KERNEL_DLL std::string peekLine(std::istream &fh)
Peek at a line without extracting it from the stream.
Definition Strings.cpp:366
void printHex(std::ostream &OFS, const int n)
Function to convert a number into hex output (and leave the stream un-changed)
Definition Strings.cpp:160
MANTID_KERNEL_DLL std::string replaceAll(std::string const &input, char const to_replace, char const substitute)
Return a string with all occurrences of indicated character replaced by the new character.
Definition Strings.cpp:90
MANTID_KERNEL_DLL void readToEndOfLine(std::istream &in, bool ConsumeEOL)
Eat everything from the stream until the next EOL.
Definition Strings.cpp:982
MANTID_KERNEL_DLL std::string fullBlock(const std::string &A)
strip pre/post spaces
Definition Strings.cpp:411
MANTID_KERNEL_DLL bool skipLine(const std::string &line)
Determines if a string starts with a #.
Definition Strings.cpp:439
std::string stripMultSpc(const std::string &Line)
Removes the multiple spaces in the line.
Definition Strings.cpp:176
int sectionMCNPX(std::string &A, T &out)
Convert and cut a string for MCNPX.
Definition Strings.cpp:634
MANTID_KERNEL_DLL std::string loadFile(const std::string &filename)
Loads the entire contents of a text file into a string.
Definition Strings.cpp:26
MANTID_KERNEL_DLL std::vector< std::string > StrParts(std::string, const boost::regex &)
Split a line into component parts.
MANTID_KERNEL_DLL std::string toUpper(const std::string &input)
Converts string to all uppercase.
Definition Strings.cpp:137
MANTID_KERNEL_DLL bool endsWith(std::string const &str, std::string const &suffix)
Checks if string ends with a suffix.
Definition Strings.cpp:145
MANTID_KERNEL_DLL int endsWithInt(const std::string &word)
Get an int from the end of a word.
Definition Strings.cpp:232
MANTID_KERNEL_DLL void writeMCNPX(const std::string &Line, std::ostream &OX)
Write file in standard MCNPX input form.
Definition Strings.cpp:452
MANTID_KERNEL_DLL std::string getLine(std::istream &fh)
Get a line and strip comments Use only for a single call.
Definition Strings.cpp:341
MANTID_KERNEL_DLL void stripComment(std::string &A)
strip trailling comments
Definition Strings.cpp:392
MANTID_KERNEL_DLL int extractWord(std::string &Line, const std::string &Word, const int cnt=4)
Get a word from a string.
Definition Strings.cpp:208
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition Strings.cpp:696
MANTID_KERNEL_DLL std::map< std::string, std::string > splitToKeyValues(const std::string &input, const std::string &keyValSep="=", const std::string &listSep=",")
Splits a string into key value pairs.
Definition Strings.cpp:500
int setValues(const std::string &Line, const std::vector< int > &Index, std::vector< T > &Out)
Call to read in various values in position x1,x2,x3 from the line.
Definition Strings.cpp:875
MANTID_KERNEL_DLL std::string getWord(std::istream &in, bool consumeEOL)
Returns the next word in the stream.
Definition Strings.cpp:931
MANTID_KERNEL_DLL int isEmpty(const std::string &A)
Determines if a string is only spaces.
Definition Strings.cpp:381
int writeFile(const std::string &Fname, const T &step, const V< T, A > &Y)
Write a set of containers to a file.
Definition Strings.cpp:794
MANTID_KERNEL_DLL int getPartLine(std::istream &fh, std::string &Out, std::string &Excess, const int spc=256)
get a part of a long line
Definition Strings.cpp:284
std::string toString(const T &value)
Convert values to strings.