SpectMorph
smutils.hh
1 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl-2.1.html
2 
3 #ifndef SPECTMORPH_UTIL_HH
4 #define SPECTMORPH_UTIL_HH
5 
6 #include <string>
7 #include <vector>
8 #include <stdint.h>
9 
10 // operating system: one of these three
11 #if WIN32
12  #define SM_OS_WINDOWS
13 #elif __APPLE__
14  #define SM_OS_MACOS
15 #elif __linux__
16  #define SM_OS_LINUX
17 #else
18  #error "unsupported platform"
19 #endif
20 
21 // detect compiler
22 #if __clang__
23  #define SM_COMP_CLANG
24 #elif __GNUC__ > 2
25  #define SM_COMP_GCC
26 #else
27  #error "unsupported compiler"
28 #endif
29 
30 #ifdef SM_OS_WINDOWS
31 #include "windows.h"
32 #endif
33 
34 namespace SpectMorph
35 {
36 
37 /* integer types */
38 typedef uint8_t uint8;
39 typedef uint32_t uint32;
40 typedef int64_t int64;
41 typedef uint64_t uint64;
42 typedef unsigned int uint;
43 
44 #define SPECTMORPH_CLASS_NON_COPYABLE(Class) \
45  Class (const Class&) = delete; \
46  Class& operator= (const Class&) = delete
47 
48 #ifdef SM_COMP_GCC
49  #define SPECTMORPH_PRINTF(format_idx, arg_idx) __attribute__ ((__format__ (gnu_printf, format_idx, arg_idx)))
50 #else
51  #define SPECTMORPH_PRINTF(format_idx, arg_idx) __attribute__ ((__format__ (__printf__, format_idx, arg_idx)))
52 #endif
53 
54 std::string string_printf (const char *format, ...) SPECTMORPH_PRINTF (1, 2);
55 std::string string_vprintf (const char *format, va_list vargs);
56 
57 std::string string_locale_printf (const char *format, ...) SPECTMORPH_PRINTF (1, 2);
58 
59 void sm_printf (const char *format, ...) SPECTMORPH_PRINTF (1, 2);
60 
61 static constexpr int AVOID_ARRAY_UB = 1; // add this to variable length array size (must be more than zero elements)
62 
63 enum InstallDir
64 {
65  INSTALL_DIR_BIN,
66  INSTALL_DIR_TEMPLATES,
67  INSTALL_DIR_INSTRUMENTS,
68  INSTALL_DIR_FONTS
69 };
70 
71 std::string sm_get_install_dir (InstallDir p);
72 
73 // data directory is relocatable
74 void sm_set_pkg_data_dir (const std::string& data_dir);
75 
76 enum UserDir
77 {
78  USER_DIR_INSTRUMENTS,
79  USER_DIR_CACHE, /* FIXME: unify with sm_get_cache_dir */
80  USER_DIR_DATA
81 };
82 
83 std::string sm_get_user_dir (UserDir p);
84 std::string sm_get_default_plan();
85 std::string sm_get_cache_dir();
86 
87 #ifdef SM_OS_MACOS
88 std::string sm_mac_documents_dir();
89 std::string sm_mac_application_support_dir_user();
90 std::string sm_mac_application_support_dir_system();
91 void set_macos_data_dir();
92 #endif
93 
94 enum DocumentsDir
95 {
96  DOCUMENTS_DIR_INSTRUMENTS
97 };
98 
99 std::string sm_get_documents_dir (DocumentsDir p);
100 
101 class Error
102 {
103 public:
104  enum class Code {
105  NONE,
106  FILE_NOT_FOUND,
107  FORMAT_INVALID,
108  PARSE_ERROR,
109  STR
110  };
111 
112  Error (Code code) :
113  m_code (code)
114  {
115  switch (code)
116  {
117  case Code::NONE:
118  m_message = "OK";
119  break;
120 
121  case Code::FILE_NOT_FOUND:
122  m_message = "No such file, device or directory";
123  break;
124 
125  case Code::FORMAT_INVALID:
126  m_message = "Invalid format";
127  break;
128 
129  case Code::PARSE_ERROR:
130  m_message = "Parsing error";
131  break;
132 
133  default:
134  m_message = "Unknown error";
135  }
136  }
137  explicit
138  Error (const std::string& message) :
139  m_code (Code::STR),
140  m_message (message)
141  {
142  }
143 
144  Code
145  code()
146  {
147  return m_code;
148  }
149  const char *
150  message()
151  {
152  return m_message.c_str();
153  }
154  operator bool()
155  {
156  return m_code != Code::NONE;
157  }
158 private:
159  Code m_code;
160  std::string m_message;
161 };
162 
163 #ifdef SM_OS_WINDOWS
164 std::string sm_resolve_link (const std::string& link_file);
165 void set_windows_data_dir (HMODULE hInstance);
166 #endif
167 
168 #ifdef SM_OS_WINDOWS
169 #define SM_SET_OS_DATA_DIR() set_windows_data_dir (hInstance)
170 #endif
171 
172 #ifdef SM_OS_MACOS
173 #define SM_SET_OS_DATA_DIR() set_macos_data_dir()
174 #endif
175 
176 #ifdef SM_OS_LINUX
177 void set_static_linux_data_dir();
178 
179 #ifdef SM_STATIC_LINUX
180 #define SM_SET_OS_DATA_DIR() set_static_linux_data_dir()
181 #else
182 // on linux (not statically linked), plugin data directory is defined during build
183 #define SM_SET_OS_DATA_DIR()
184 #endif
185 
186 #endif
187 
188 std::string sha1_hash (const unsigned char *data, size_t len);
189 std::string sha1_hash (const std::string& str);
190 
191 double get_time();
192 
193 std::string to_utf8 (const std::u32string& str);
194 std::u32string to_utf32 (const std::string& utf8);
195 
196 Error read_dir (const std::string& dirname, std::vector<std::string>& files);
197 bool file_exists (const std::string& filename);
198 bool dir_exists (const std::string& dirname);
199 
200 double sm_atof (const char *str); // always use . as decimal seperator
201 double sm_atof_any (const char *str); // allow . or locale as decimal separator
202 
203 } // namespace SpectMorph
204 
205 /* we want to be able to use sm_debug without extra includes */
206 #include "smdebug.hh"
207 
208 #endif
Definition: smutils.hh:102