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