1 /*
2 This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.
3
4 Author: Uwe Schulzweida
5 Oliver Heidmann
6
7 */
8
9 #include <cassert>
10 #include <cstring>
11 #include <cctype>
12 #include <algorithm>
13 #include <cdi.h>
14
15 #include <regex>
16
17 std::vector<std::string>
split_string(const std::string & str,const std::string & delimiter)18 split_string(const std::string &str, const std::string &delimiter)
19 {
20 std::regex regex(delimiter);
21 return { std::sregex_token_iterator(str.begin(), str.end(), regex, -1), std::sregex_token_iterator() };
22 }
23
24 std::string
string_to_upper(std::string p_str)25 string_to_upper(std::string p_str)
26 {
27 std::transform(p_str.begin(), p_str.end(), p_str.begin(), [](unsigned char c) { return std::toupper(c); });
28 return p_str;
29 }
30
31 std::string
string_to_lower(std::string p_str)32 string_to_lower(std::string p_str)
33 {
34 std::transform(p_str.begin(), p_str.end(), p_str.begin(), [](unsigned char c) { return std::tolower(c); });
35 return p_str;
36 }
37
38 void
cstr_to_lower_case(char * str)39 cstr_to_lower_case(char *str)
40 {
41 if (str)
42 for (size_t i = 0; str[i]; ++i) str[i] = (char) tolower((int) str[i]);
43 }
44
45 void
cstr_to_upper_case(char * str)46 cstr_to_upper_case(char *str)
47 {
48 if (str)
49 for (size_t i = 0; str[i]; ++i) str[i] = (char) toupper((int) str[i]);
50 }
51
52 static void
trim_flt(char * ss)53 trim_flt(char *ss)
54 {
55 char *cp = ss;
56 if (*cp == '-') cp++;
57 while (isdigit((int) *cp) || *cp == '.') cp++;
58 if (*--cp == '.') return;
59
60 char *ep = cp + 1;
61 while (*cp == '0') cp--;
62 cp++;
63 if (cp == ep) return;
64 while (*ep) *cp++ = *ep++;
65 *cp = '\0';
66
67 return;
68 }
69
70 char *
double_to_att_str(int digits,char * attstr,size_t len,double value)71 double_to_att_str(int digits, char *attstr, size_t len, double value)
72 {
73 const int ret = snprintf(attstr, len, "%#.*g", digits, value);
74 assert(ret != -1 && ret < (int) len);
75 trim_flt(attstr);
76 return attstr;
77 }
78
79 const char *
tunit_to_cstr(int tunits)80 tunit_to_cstr(int tunits)
81 {
82 // clang-format off
83 if ( tunits == TUNIT_YEAR ) return "years";
84 else if ( tunits == TUNIT_MONTH ) return "months";
85 else if ( tunits == TUNIT_DAY ) return "days";
86 else if ( tunits == TUNIT_12HOURS ) return "12hours";
87 else if ( tunits == TUNIT_6HOURS ) return "6hours";
88 else if ( tunits == TUNIT_3HOURS ) return "3hours";
89 else if ( tunits == TUNIT_HOUR ) return "hours";
90 else if ( tunits == TUNIT_30MINUTES ) return "30minutes";
91 else if ( tunits == TUNIT_QUARTER ) return "15minutes";
92 else if ( tunits == TUNIT_MINUTE ) return "minutes";
93 else if ( tunits == TUNIT_SECOND ) return "seconds";
94 else return "unknown";
95 // clang-format on
96 }
97
98 const char *
calendar_to_cstr(int calendar)99 calendar_to_cstr(int calendar)
100 {
101 // clang-format off
102 if ( calendar == CALENDAR_STANDARD ) return "standard";
103 else if ( calendar == CALENDAR_GREGORIAN ) return "gregorian";
104 else if ( calendar == CALENDAR_PROLEPTIC ) return "proleptic_gregorian";
105 else if ( calendar == CALENDAR_360DAYS ) return "360_day";
106 else if ( calendar == CALENDAR_365DAYS ) return "365_day";
107 else if ( calendar == CALENDAR_366DAYS ) return "366_day";
108 else return "unknown";
109 // clang-format on
110 }
111