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