BmnRoot
Loading...
Searching...
No Matches
function_set.h
Go to the documentation of this file.
1//============================================================================
2// Name : function_set.h
3// Author : Konstantin Gertsenberger (gertsen@jinr.ru)
4// Description : set of common C++ functions
5// Version : 1.11
6//============================================================================
7#ifndef FUNCTION_SET_H
8#define FUNCTION_SET_H
9
10// C++ includes
11#include <unistd.h>
12#include <iomanip>
13#include <iostream>
14#include <cstring>
15#include <string>
16#include <stdlib.h>
17#include <stdio.h>
18#include <sstream>
19#include <ctime>
20#include <math.h>
21#include <memory>
22#include <limits.h>
23#include <sys/stat.h>
24
25using namespace std;
26
27/* declarations */
28enum BATCH_SYSTEM_NAME {SGE_BATCH_SYSTEM, TORQUE_BATCH_SYSTEM, SLURM_BATCH_SYSTEM}; // 'get_batch_processor_count' function
29
30/* OS FUNCTIONS */
31// execute system command in shell (bash)
32int system_command_linux(string aCommand, string& result);
33// replace all Linux environment variables and tilde in a specified path (input argument)
34string expand_path(string path);
35// get absolute path with replacing environment variables using Linux shell
36string absolute_path(string path);
37// get processor core count on this machine
39// get maximum available processor count on Sun Grid Engine system
40int get_batch_processor_count(BATCH_SYSTEM_NAME batch_system, string queue_name = "");
41
42/* GLOBAL APPLICATION FUNCTIONS */
43// get application name in linux
44string get_app_name_linux();
45// get aplication directory (path without file name) in linux
46string get_app_dir_linux();
47
48/* NUMBER FUNCTIONS */
49// check bit in 'variable' at 'position'
50#define CHECK_BIT(variable,position) ((variable) & (1ULL<<(position)))
51
52/* STRING FUNCTIONS */
53// return string according to the given format and arguments (as for snprintf function)
54template<typename ... Args>
55string string_format(const string& format, Args ... args);
56// convert double number to string with a given precision
57// is_fixed_point: true - {precision = number of decimal digits after point}; false - {precision = number of all decimal digits in the number}
58string double_to_string(double number, int precision, bool is_fixed_point = true);
59// convert integer number to string
60string int_to_string(int number);
61// convert integer (hexadecimal value) to string with hexadecimal presentation without "0x"
62string int_to_hex_string(int number);
63// convert string with hexadecimal presentation without "0x" to integer
64int hex_string_to_int(string hex_string);
65// convert string specified size in bytes to double value; "convert_to" - possible values "BKMGTP"
66double byte_size_to_double(string byte_size_in_string, char convert_to = 'B');
67// convert string specified size in bytes to human-readable format
68string byte_size_to_human(uint64_t byte_size, unsigned precision = 2);
69// is string an integer number?
70bool is_string_number(const string& s);
71// extract first number or last number in string, only positive number by default (result number has string type)
72string find_first_number(string const &str, bool isOnlyPositive = true); string find_first_double_number(string const &str, bool isOnlyPositive = true);
73string find_last_number(string const &str, bool isOnlyPositive = true); string find_last_double_number(string const &str, bool isOnlyPositive = true);
74// extract first number or last number in string, only positive number by default (result number has string type)
75// beg_pos - position of the first character in the string to be assigned before the search for find_first...; returns position of number (string::npos, if not found)
76// end_pos - position of the last character in the string to be assigned before the search for find_last...; returns position of number (string::npos, if not found)
77string find_first_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive = true); string find_first_double_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive = true);
78string find_last_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive = true); string find_last_double_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive = true);
79// convert array of chars to the new lowercase array
80char* convert_pchar_to_lowercase_new(char* input_char_array);
81// replace string 'old_substring' by string 'new_substring' in 'text'
82void replace_string_in_text(string &text, string old_substring, string new_substring);
83// replace string 'old_substring' by integer 'new_subinteger' in 'text'
84void replace_string_in_text(string &text, string old_substring, int new_subinteger);
85// replace char 'find' in array of characters (char*) by another char 'replace'; return number of replacement
86int replace_char(char*& str, char find, char replace);
87// return string without leading and trailing spaces and tabs
88string trim(const string& str, const string& whitespace = " \t\r");
89// return string changing whitespaces and tabs by single whitespace
90string reduce(const string& str, const string& fill = " ", const string& whitespace = " \t\r");
91// is string ('full_str') ending with the given substring ('ending')
92bool endswith(string const &full_str, string const &ending);
93
94/* DIR & FILE FUNCTIONS */
95// check directory exists: 0 - not exists, 1 - exists, -2 - cannot access
96int check_directory_exist(const char* path);
97// check and create directory if not exists: 0 - not existed before, 1 - existed, -1 - errno error, -2 - cannot access
98int create_directory(const char* path);
99// check and create all non-existent directories in the path:
100// 0 - not existed before, 1 - existed, 2 - not required, -1 - errno error, -2 - cannot access
101int create_directory_tree(const char* path);
102// get file name without extension from a path
103string get_file_name(string path);
104// get file name with extension from path
105string get_file_name_with_ext(string path);
106// get directory path without last slash from file path
107string get_directory_path(string file_path);
108// get directory name from file path
109string get_directory_name(string file_path);
110
111/* TIME FUNCTIONS */
112// get current date as string
113string get_current_date();
114// convert string in a given format to datetime struct tm
115tm convert_string_to_datetime(string str_datetime, const char* format = "%d.%m.%Y %H:%M:%S");
116// convert time in double (fractional number of seconds) to a timespec
117struct timespec convert_double_to_timespec(double sec);
118
119
120#ifndef ONLY_DECLARATIONS
121
122/* */
123/* */
124/* OS FUNCTIONS */
125/* */
126/* */
127
128// execute system command in shell (bash) and return output in 'result' (maximum = 4096 chars)
129int system_command_linux(string aCommand, string& result)
130{
131 FILE* f;
132 if ((f = popen(aCommand.c_str(), "r")) == nullptr)
133 {
134 cout<<"system_command_linux error: popen failed"<<endl;
135 return errno;
136 }
137
138 const int BUFSIZE = 4096;
139 char buf[BUFSIZE];
140 if (fgets(buf, BUFSIZE, f) != nullptr)
141 result = buf;
142 else
143 {
144 pclose(f);
145 return errno;
146 }
147
148 pclose(f);
149 return 0;
150}
151
152// replace all Linux environment variables and tilde in a specified path (input argument)
153string expand_path(string path)
154{
155 size_t find_result = path.find('$');
156 if (find_result != string::npos)
157 {
158 string pre = path.substr(0, find_result);
159 bool is_brace = false;
160 if (path[find_result] == '{')
161 {
162 is_brace = true;
163 find_result++;
164 }
165 string post = path.substr(find_result+1);
166
167 if (is_brace) find_result = post.find('}');
168 else find_result = post.find('/');
169 if ((find_result != string::npos) || (!is_brace))
170 {
171 string variable = post.substr(0, find_result);
172 string value = "";
173
174 if (is_brace) find_result++;
175 post = post.substr(find_result);
176
177 const char* v = getenv(variable.c_str());
178 if (v != NULL) value = string(v);
179
180 return expand_path(pre + value + post);
181 }
182 }
183
184 find_result = path.find('~');
185 if (find_result != string::npos)
186 {
187 string value = "";
188 const char* v = getenv("HOME");
189 if (v != NULL) value = string(v);
190
191 do
192 {
193 path.replace(find_result, 1, value);
194 find_result = path.find('~');
195 } while (find_result != string::npos);
196 }
197
198 return path;
199}
200
201// get absolute path with replacing environment variables using Linux shell
202string absolute_path(string path)
203{
204 // check sudo injections
205 size_t find_result = path.find("sudo");
206 if (find_result != string::npos)
207 if ((path[find_result+4] == ' ') || (path[find_result+4] == '\t'))
208 return path;
209
210 string aCommand, result;
211 aCommand = string_format("echo \"$(cd \"$(dirname \"%s\")\" 2>/dev/null; pwd)/$(basename \"%s\")\" 2>/dev/null", path.c_str(), path.c_str());
212 if (system_command_linux(aCommand, result) != 0) result = path;
213
214 return result;
215}
216
217// get processor core count on this machine
219{
220 return sysconf(_SC_NPROCESSORS_ONLN);
221}
222
223// get maximum available processor count of the batch system for the given (default) queue
224int get_batch_processor_count(BATCH_SYSTEM_NAME batch_system, string queue_name)
225{
226 int proc_count = 0;
227
228 const int MAX_BUFFER = 255;
229 char buffer[MAX_BUFFER];
230 string command_line, data, strDiff;
231
232 //define shell command to get string with processor count for the queue
233 if (batch_system == SGE_BATCH_SYSTEM)
234 {
235 if (queue_name == "")
236 queue_name = "all.q";
237 command_line = string("export SGE_SINGLE_LINE=1; qconf -sq ") + queue_name + string(" | grep slots");
238 }
239 if (batch_system == TORQUE_BATCH_SYSTEM)
240 {
241 if (queue_name == "")
242 queue_name = "batch";
243 command_line = string("qstat -f -Q ") + queue_name + string(" | grep max_running");
244 }
245 if (batch_system == SLURM_BATCH_SYSTEM)
246 {
247 if (queue_name == "")
248 queue_name = "interactive";
249 command_line = string("scontrol show partition ") + queue_name + string(" | grep -o 'TotalCPUs=[0-9]*'");
250 }
251
252 // run shell command to define batch processor count
253 FILE* stream = popen(command_line.c_str(), "r");
254 while (fgets(buffer, MAX_BUFFER, stream) != nullptr)
255 data.append(buffer);
256 pclose(stream);
257
258 // parse result string to extract processor count
259 size_t found = data.find("="), found2 = string::npos;
260 if (batch_system == SGE_BATCH_SYSTEM)
261 {
262 while (found != string::npos)
263 {
264 found2 = data.find("]", found);
265 strDiff = data.substr(found+1, found2 - found - 1);
266 proc_count += atoi(strDiff.c_str());
267 strDiff.clear();
268
269 found = data.find("=", found2);
270 }
271 }
272 if (batch_system == TORQUE_BATCH_SYSTEM)
273 {
274 if (found != string::npos)
275 {
276 strDiff = data.substr(found+1, data.length() - found - 1);
277 proc_count = atoi(strDiff.c_str());
278 }
279 }
280 if (batch_system == SLURM_BATCH_SYSTEM)
281 {
282 if (found != string::npos)
283 {
284 strDiff = data.substr(found+1, data.length() - found - 1);
285 proc_count = atoi(strDiff.c_str());
286 }
287 }
288
289 data.clear();
290 //cout<<"Batch processor count: "<<proc_count<<endl;
291 return proc_count;
292}
293
294
295/* */
296/* */
297/* GLOBAL APPLICATION FUNCTIONS */
298/* */
299/* */
300
301// get application name in linux
303{
304 pid_t procpid = getpid();
305 stringstream toCom;
306 toCom << "cat /proc/" << procpid << "/comm";
307 string fRes="";
308 system_command_linux(toCom.str(), fRes);
309 size_t last_pos = fRes.find_last_not_of(" \n\r\t") + 1;
310 if (last_pos != string::npos)
311 fRes.erase(last_pos);
312
313 return fRes;
314}
315
316// get aplication directory (path without file name) in linux
318{
319 pid_t procpid = getpid();
320 string appName = get_app_name_linux();
321 stringstream command;
322 command << "readlink /proc/" << procpid << "/exe | sed \"s/\\(\\/" << appName << "\\)$//\"";
323 string fRes;
324 system_command_linux(command.str(),fRes);
325
326 // remove '\n' from end of the string and add final '/'
327 fRes = fRes.erase(fRes.length()-1, 1);
328 fRes.push_back('/');
329
330 return fRes;
331}
332
333
334/* */
335/* */
336/* NUMBER FUNCTIONS */
337/* */
338/* */
339
340
341
342/* */
343/* */
344/* STRING FUNCTIONS */
345/* */
346/* */
347
348// return string according to the given format and arguments (as for snprintf function)
349template<typename ... Args>
350string string_format(const string& format, Args ... args)
351{
352 int size_s = snprintf(nullptr, 0, format.c_str(), args ...) + 1;
353 if (size_s <= 0) throw runtime_error("Error during formatting.");
354 auto size = static_cast<size_t>(size_s);
355 unique_ptr<char[]> buf(new char[size]);
356 snprintf(buf.get(), size, format.c_str(), args ...);
357 return string(buf.get(), buf.get() + size - 1);
358}
359
360// convert double number to string with a given precision
361// is_fixed_point: true - {precision = number of decimal digits after point}; false - {precision = number of all decimal digits in the number}
362string double_to_string(double number, int precision, bool is_fixed_point)
363{
364 stringstream stream;
365 if (is_fixed_point) stream << std::fixed;
366 stream << std::setprecision(precision) << number;
367 return stream.str();
368}
369
370// convert integer number to string
371string int_to_string(int number)
372{
373 stringstream ss;
374 ss<<number;
375 return ss.str();
376}
377
378// convert integer (hexadecimal value) to string with hexadecimal presentation without "0x"
379string int_to_hex_string(int number)
380{
381 stringstream stream;
382 stream<<std::hex<<number;
383 return stream.str();
384}
385
386// convert string with hexadecimal presentation without "0x" to integer
387int hex_string_to_int(string hex_string)
388{
389 int x;
390 stringstream stream;
391 stream<<std::hex<<hex_string;
392 stream>>x;
393 return x;
394}
395
396// convert string specified size in bytes to double value; "convert_to" - possible values "BKMGTP"
397// return byte size in double or code error if negative
398double byte_size_to_double(string byte_size_in_string, char convert_to)
399{
400 if (byte_size_in_string.empty()) return -1; // empty string
401
402 // remove spaces
403 replace_string_in_text(byte_size_in_string, " ", "");
404 // find text
405 size_t indText = byte_size_in_string.find_first_not_of("0123456789,.");
406 if (indText == 0) return -2; // no number at the beginning
407
408 string units = "BKMGTP";
409
410 size_t convert_dim = units.find(::toupper(convert_to)), value_dim = -1;
411 if (convert_dim == string::npos) convert_dim = 0;
412
413 double number = -3;
414 if (indText == string::npos)
415 {
416 number = atof(byte_size_in_string.c_str());
417 value_dim = 0;
418 }
419 else
420 {
421 number = atof(byte_size_in_string.substr(0, indText).c_str());
422 value_dim = units.find(::toupper(byte_size_in_string[indText]));
423 if (value_dim == string::npos) value_dim = 0;
424 }
425
426 if (convert_dim != value_dim)
427 number *= pow(1024, value_dim - convert_dim);
428
429 return number;
430}
431
432// convert string specified size in bytes to human-readable format
433string byte_size_to_human(uint64_t byte_size, unsigned precision)
434{
435 constexpr const char FILE_SIZE_UNITS[8][3]{
436 "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"
437 };
438
451 // LOGARITHMIC METHOD
452 if (byte_size == 0)
453 return "0 B";
454 else
455 {
456 int order = floor(log(byte_size) / log(1024));
457 float num = ((float) byte_size) / pow(1024, order);
458 return string_format("%.*f %s", precision, num, FILE_SIZE_UNITS[order]);
459 }
460}
461
462// is string an integer number?
463bool is_string_number(const string& s)
464{
465 string::const_iterator it = s.begin();
466 while (it != s.end() && std::isdigit(*it)) ++it;
467 return !s.empty() && it == s.end();
468}
469
470// 8 following functions: extract first number or last number in string, only positive number by default (result number has string type)
471string find_first_number(string const &str, bool isOnlyPositive)
472{
473 size_t n = str.find_first_of("0123456789");
474 if (n != string::npos)
475 {
476 size_t m = str.find_first_not_of("0123456789", n);
477 if ((!isOnlyPositive) && (n > 0) && ((str[n-1] == '+') || (str[n-1] == '-')))
478 n--;
479 return str.substr(n, m != string::npos ? m-n : m);
480 }
481
482 return string();
483}
484
485string find_last_number(string const &str, bool isOnlyPositive)
486{
487 size_t n = str.find_last_of("0123456789");
488 if (n != string::npos)
489 {
490 string temp = str.substr(0, n+1);
491 size_t m = temp.find_last_not_of("0123456789");
492 if (m != string::npos)
493 {
494 if ((!isOnlyPositive) && ((str[m] == '+') || (str[m] == '-')))
495 m--;
496 return temp.substr(m+1, n-m);
497 }
498 return temp;
499 }
500
501 return string();
502}
503
504string find_first_double_number(string const &str, bool isOnlyPositive)
505{
506 size_t n = str.find_first_of("0123456789");
507 if (n != string::npos)
508 {
509 size_t m = str.find_first_not_of("0123456789,.", n);
510 if ((!isOnlyPositive) && (n > 0) && ((str[n-1] == '+') || (str[n-1] == '-')))
511 n--;
512 return str.substr(n, m != string::npos ? m-n : m);
513 }
514
515 return string();
516}
517
518string find_last_double_number(string const &str, bool isOnlyPositive)
519{
520 size_t n = str.find_last_of("0123456789");
521 if (n != string::npos)
522 {
523 string temp = str.substr(0, n+1);
524 size_t m = temp.find_last_not_of("0123456789,.");
525 if (m != string::npos)
526 {
527 if ((!isOnlyPositive) && ((str[m] == '+') || (str[m] == '-')))
528 m--;
529 return temp.substr(m+1, n-m);
530 }
531 return temp;
532 }
533
534 return string();
535}
536
537string find_first_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive)
538{
539 beg_pos = str.find_first_of("0123456789", beg_pos);
540 if (beg_pos != string::npos)
541 {
542 size_t m = str.find_first_not_of("0123456789", beg_pos);
543 end_pos = (m != string::npos ? m-1 : str.length()-1);
544 if ((!isOnlyPositive) && (beg_pos > 0) && ((str[beg_pos-1] == '+') || (str[beg_pos-1] == '-')))
545 beg_pos--;
546 return str.substr(beg_pos, m != string::npos ? m-beg_pos : m);
547 }
548
549 end_pos = string::npos;
550 return string();
551}
552
553string find_last_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive)
554{
555 end_pos = str.find_last_of("0123456789", end_pos);
556 if (end_pos != string::npos)
557 {
558 string temp = str.substr(0, end_pos + 1);
559 size_t m = temp.find_last_not_of("0123456789");
560 beg_pos = (m != string::npos ? m+1 : 0);
561 if (m != string::npos)
562 {
563 if ((!isOnlyPositive) && ((str[m] == '+') || (str[m] == '-')))
564 beg_pos--;
565 return temp.substr(beg_pos, end_pos-beg_pos+1);
566 }
567 return temp;
568 }
569
570 beg_pos = string::npos;
571 return string();
572}
573
574string find_first_double_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive)
575{
576 beg_pos = str.find_first_of("0123456789", beg_pos);
577 if (beg_pos != string::npos)
578 {
579 size_t m = str.find_first_not_of("0123456789,.", beg_pos);
580 end_pos = (m != string::npos ? m-1 : str.length()-1);
581 if ((!isOnlyPositive) && (beg_pos > 0) && ((str[beg_pos-1] == '+') || (str[beg_pos-1] == '-')))
582 beg_pos--;
583 return str.substr(beg_pos, m != string::npos ? m-beg_pos : m);
584 }
585
586 end_pos = string::npos;
587 return string();
588}
589
590string find_last_double_number(string const &str, size_t &beg_pos, size_t &end_pos, bool isOnlyPositive)
591{
592 end_pos = str.find_last_of("0123456789", end_pos);
593 if (end_pos != string::npos)
594 {
595 string temp = str.substr(0, end_pos+1);
596 size_t m = temp.find_last_not_of("0123456789,.");
597 beg_pos = (m != string::npos ? m+1 : 0);
598 if (m != string::npos)
599 {
600 if ((!isOnlyPositive) && ((str[m] == '+') || (str[m] == '-')))
601 beg_pos--;
602 return temp.substr(beg_pos, end_pos-beg_pos+1);
603 }
604 return temp;
605 }
606
607 beg_pos = string::npos;
608 return string();
609}
610
611// convert array of chars to the new lowercase array
612char* convert_pchar_to_lowercase_new(char* input_char_array)
613{
614 if (input_char_array == nullptr)
615 return nullptr;
616
617 const int length = strlen(input_char_array); // get the length of the text
618 char* lower = new char[length + 1]; // allocate 'length' bytes + 1 (for null terminator) and cast to char*
619 lower[length] = 0; // set the last byte to a null terminator
620
621 // copy all character bytes to the new buffer using tolower
622 for( int i = 0; i < length; i++ )
623 lower[i] = tolower(input_char_array[i]);
624
625
626 return lower;
627}
628
629// replace string 'old_substring' by string 'new_substring' in 'text'
630void replace_string_in_text(string &text, string old_substring, string new_substring)
631{
632 int start = -1;
633 do
634 {
635 start = text.find(old_substring, start + 1);
636 if (start > -1)
637 {
638 text.replace(start, old_substring.length(), new_substring.c_str());
639 start += new_substring.length() - old_substring.length();
640 }
641 }
642 while (start > -1);
643}
644
645// replace string 'old_substring' by integer 'new_subinteger' in 'text'
646void replace_string_in_text(string &text, string old_substring, int new_subinteger)
647{
648 string new_substring = "";
649 int start = -1;
650 do
651 {
652 start = text.find(old_substring, start + 1);
653 if (start > -1)
654 {
655 if (new_substring == "")
656 {
657 char buf_int[9];
658 sprintf(buf_int, "%d", new_subinteger);
659 new_substring = buf_int;
660 }
661 text.replace(start, old_substring.length(), new_substring.c_str());
662 start += new_substring.length() - old_substring.length();
663 }
664 }
665 while (start > -1);
666}
667
668// replace char 'find' in string (char* str) by another char 'replace'; return number of replacement
669int replace_char(char*& str, char find, char replace)
670{
671 int replace_count = 0;
672 char* cur_pos = strchr(str, find);
673 while (cur_pos)
674 {
675 *cur_pos = replace;
676 replace_count++;
677 cur_pos = strchr(cur_pos, find);
678 }
679
680 return replace_count;
681}
682
683// return string without leading and trailing spaces and tabs
684string trim(const string& str, const string& whitespace)
685{
686 size_t strBegin = str.find_first_not_of(whitespace);
687 if (strBegin == string::npos)
688 return ""; // no content
689
690 size_t strEnd = str.find_last_not_of(whitespace);
691 size_t strRange = strEnd - strBegin + 1;
692
693 return str.substr(strBegin, strRange);
694}
695
696// return string changing whitespace and tabs by single whitespace
697string reduce(const string& str, const string& fill, const string& whitespace)
698{
699 // trim first
700 string result = trim(str, whitespace);
701
702 // replace sub ranges
703 size_t beginSpace = result.find_first_of(whitespace);
704 while (beginSpace != string::npos)
705 {
706 size_t endSpace = result.find_first_not_of(whitespace, beginSpace);
707 size_t range = endSpace - beginSpace;
708
709 result.replace(beginSpace, range, fill);
710
711 size_t newStart = beginSpace + fill.length();
712 beginSpace = result.find_first_of(whitespace, newStart);
713 }
714
715 return result;
716}
717
718// is string ('full_str') ending with the given susbtring ('ending')
719bool endswith(string const &full_str, string const &ending)
720{
721 if (full_str.length() >= ending.length())
722 return (0 == full_str.compare(full_str.length() - ending.length(), ending.length(), ending));
723 else
724 return false;
725}
726
727
728/* */
729/* */
730/* DIR & FILE FUNCTIONS */
731/* */
732/* */
733
734// check directory exists: 0 - not exists, 1 - exists, -2 - cannot access
735int check_directory_exist(const char* path)
736{
737 struct stat info;
738
739 if (stat(path, &info) != 0)
740 return -2;
741 else if (info.st_mode & S_IFDIR)
742 return 1;
743 else
744 return 0;
745}
746
747// check and create directory if not exists: 0 - not existed before, 1 - existed, -1 - errno error
748int create_directory(const char* path)
749{
750 struct stat info = {0};
751
752 if (stat(path, &info) == -1)
753 {
754 int status = mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
755 return status;
756 }
757 else
758 {
759 if (info.st_mode & S_IFDIR)
760 return 1;
761
762 return -2;
763 }
764}
765
766// check and create all non-existent directories in the path:
767// 0 - not existed before, 1 - existed, -1 - errno error, -2 - cannot access
768int create_directory_tree(const char* path)
769{
770 string str_path(path);
771 size_t pos = str_path.find_last_of('/');
772 if (pos == string::npos)
773 return 1;
774 str_path = str_path.substr(0, pos);
775 int status = check_directory_exist(str_path.c_str());
776 if (status != 0)
777 return status;
778
779 status = create_directory_tree(str_path.c_str());
780 if (status < 0)
781 return status;
782
783 mode_t mode = 0755;
784 status = mkdir(str_path.c_str(), mode);
785 if (status == 0)
786 return 0;
787 switch (errno)
788 {
789 case ENOENT:
790 return -1;
791 case EEXIST:
792 return -2;
793 default:
794 return -1;
795 }
796}
797
798// get file name without extension from a path
799string get_file_name(string path)
800{
801 // Remove directory if present.
802 size_t last_slash_idx = path.find_last_of("\\/");
803 if (last_slash_idx != string::npos)
804 path.erase(0, last_slash_idx + 1);
805
806 // Remove extension if present.
807 size_t period_idx = path.rfind('.');
808 if (period_idx != string::npos)
809 path.erase(period_idx);
810
811 return path;
812}
813
814// get file name with extension from path
815string get_file_name_with_ext(string path)
816{
817 // Remove directory if present.
818 size_t last_slash_idx = path.find_last_of("\\/");
819 if (last_slash_idx != string::npos)
820 path.erase(0, last_slash_idx + 1);
821
822 return path;
823}
824
825// get directory path without last slash from file path
826string get_directory_path(string file_path)
827{
828 string directory = "";
829 const size_t last_slash_idx = file_path.find_last_of("\\/");
830 if (last_slash_idx != string::npos)
831 directory = file_path.substr(0, last_slash_idx);
832
833 return directory;
834}
835
836// get directory name from file path
837string get_directory_name(string file_path)
838{
839 string directory = "";
840 const size_t last_slash_idx = file_path.find_last_of("\\/");
841 if (last_slash_idx != string::npos)
842 {
843 const size_t penult_slash_idx = file_path.find_last_of("\\/", last_slash_idx-1);
844 if (penult_slash_idx != string::npos)
845 directory = file_path.substr(penult_slash_idx+1, last_slash_idx-penult_slash_idx-1);
846 }
847
848 return directory;
849}
850
851
852/* */
853/* */
854/* TIME FUNCTIONS */
855/* */
856/* */
857
858// get current date as string
860{
861 time_t rawtime;
862 time(&rawtime);
863
864 struct tm* timeinfo;
865 timeinfo = localtime(&rawtime);
866
867 char buffer[80];
868 strftime(buffer, 80, "%d-%m-%Y", timeinfo);
869 string str(buffer);
870
871 return str;
872}
873
874// convert string in a given format to datetime struct tm
875tm convert_string_to_datetime(string str_datetime, const char* format)
876{
877 tm tmbuf[1] = {{0}};
878 strptime(str_datetime.c_str(), format, tmbuf);
879
880 return tmbuf[0]; // tmbuf->tm_year, tmbuf->tm_mon+1, tmbuf->tm_mday, tmbuf->tm_hour, tmbuf->tm_min, tmbuf->tm_sec
881}
882
883struct timespec convert_double_to_timespec(double sec)
884{
885 sec += 0.5e-9;
886 struct timespec ts = {
887 .tv_sec = (time_t) sec,
888 .tv_nsec = (long) (sec - (long)(sec)) * 1000000000,
889 };
890
891 return ts;
892}
893
894#endif /* ONLY_DECLARATIONS */
895#endif /* FUNCTION_SET_H */
__m128 v
Definition P4_F32vec4.h:1
int i
Definition P4_F32vec4.h:22
__m128 m
Definition P4_F32vec4.h:27
friend F32vec4 log(const F32vec4 &a)
Definition P4_F32vec4.h:123
float f
Definition P4_F32vec4.h:21
string double_to_string(double number, int precision, bool is_fixed_point=true)
string int_to_string(int number)
string reduce(const string &str, const string &fill=" ", const string &whitespace=" \t\r")
string find_last_double_number(string const &str, bool isOnlyPositive=true)
int check_directory_exist(const char *path)
string get_current_date()
string int_to_hex_string(int number)
int create_directory(const char *path)
string find_first_double_number(string const &str, bool isOnlyPositive=true)
tm convert_string_to_datetime(string str_datetime, const char *format="%d.%m.%Y %H:%M:%S")
char * convert_pchar_to_lowercase_new(char *input_char_array)
BATCH_SYSTEM_NAME
@ TORQUE_BATCH_SYSTEM
@ SGE_BATCH_SYSTEM
@ SLURM_BATCH_SYSTEM
int system_command_linux(string aCommand, string &result)
string find_first_number(string const &str, bool isOnlyPositive=true)
string expand_path(string path)
string get_file_name(string path)
string get_app_name_linux()
struct timespec convert_double_to_timespec(double sec)
string find_last_number(string const &str, bool isOnlyPositive=true)
string get_directory_path(string file_path)
int replace_char(char *&str, char find, char replace)
string get_file_name_with_ext(string path)
bool is_string_number(const string &s)
string absolute_path(string path)
int get_linux_processor_count()
string string_format(const string &format, Args ... args)
int create_directory_tree(const char *path)
int hex_string_to_int(string hex_string)
string get_app_dir_linux()
string trim(const string &str, const string &whitespace=" \t\r")
double byte_size_to_double(string byte_size_in_string, char convert_to='B')
void replace_string_in_text(string &text, string old_substring, string new_substring)
int get_batch_processor_count(BATCH_SYSTEM_NAME batch_system, string queue_name="")
string get_directory_name(string file_path)
bool endswith(string const &full_str, string const &ending)
string byte_size_to_human(uint64_t byte_size, unsigned precision=2)
STL namespace.