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