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