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