1 /* =========================================================================== 2 * 3 * PUBLIC DOMAIN NOTICE 4 * National Center for Biotechnology Information 5 * 6 * This software/database is a "United States Government Work" under the 7 * terms of the United States Copyright Act. It was written as part of 8 * the author's official duties as a United States Government employee and 9 * thus cannot be copyrighted. This software/database is freely available 10 * to the public for use. The National Library of Medicine and the U.S. 11 * Government have not placed any restriction on its use or reproduction. 12 * 13 * Although all reasonable efforts have been taken to ensure the accuracy 14 * and reliability of the software and data, the NLM and the U.S. 15 * Government do not and cannot warrant the performance or results that 16 * may be obtained by using this software or data. The NLM and the U.S. 17 * Government disclaim all warranties, express or implied, including 18 * warranties of performance, merchantability or fitness for any particular 19 * purpose. 20 * 21 * Please cite the author in any work or product based on this material. 22 * 23 * =========================================================================== 24 * 25 * Project: 26 * sratools command line tool 27 * 28 * Purpose: 29 * Declare and define compile-time constants (and some functions on them) 30 * 31 */ 32 33 #pragma once 34 35 #include <klib/strings.h> /* SDL_CGI */ 36 37 #include <cassert> 38 #include <algorithm> 39 #include <cstring> 40 #include <cstdlib> 41 42 #include "env_vars.h" 43 #include "util.hpp" 44 45 namespace constants { 46 47 /// @brief constants used for tool names 48 struct tool_name { 49 /// @brief tools names as symbols 50 enum { 51 FASTERQ_DUMP, 52 FASTQ_DUMP, 53 PREFETCH, 54 SAM_DUMP, 55 SRA_PILEUP, 56 SRAPATH, 57 END_ENUM 58 }; 59 60 /// @brief array of tool names in same order as above enum realconstants::tool_name61 static char const *const *real() { 62 static char const *const value[] = { 63 "fasterq-dump-orig", 64 "fastq-dump-orig", 65 "prefetch-orig", 66 "sam-dump-orig", 67 "sra-pileup-orig", 68 "srapath-orig" 69 }; 70 return value; 71 } 72 73 /// @brief array of impersonated tool names in same order as above enum runasNamesconstants::tool_name74 static char const *const *runasNames() { 75 static char const *const value[] = { 76 "fasterq-dump", 77 "fastq-dump", 78 "prefetch", 79 "sam-dump", 80 "sra-pileup", 81 "srapath" 82 }; 83 return value; 84 } 85 86 /// @brief get full path to tool by id pathconstants::tool_name87 static char const *path(int const iid) 88 { 89 extern std::vector<opt_string> load_tool_paths(int n, char const *const *runas, char const *const *real); 90 extern void pathHelp [[noreturn]] (std::string const &toolname); 91 92 static auto const cache = load_tool_paths(END_ENUM, runasNames(), real()); 93 auto const &result = cache.at(iid); 94 if (result) 95 return result.value().c_str(); 96 97 pathHelp(runas(iid)); 98 } 99 100 /// @brief convert id to string 101 /// 102 /// @param iid integer id of tool (range checked) 103 /// 104 /// @returns the real name of the tool in the filesystem realconstants::tool_name105 static char const *real(int const iid) { 106 assert(0 <= iid && iid < END_ENUM); 107 if (0 <= iid && iid < END_ENUM) 108 return real()[iid]; 109 throw std::range_error("unknown tool id"); 110 } 111 112 /// @brief convert id to string 113 /// 114 /// @param iid integer id of tool (range checked) 115 /// 116 /// @returns the impersonated name of the tool runasconstants::tool_name117 static char const *runas(int const iid) { 118 assert(0 <= iid && iid < END_ENUM); 119 if (0 <= iid && iid < END_ENUM) 120 return runasNames()[iid]; 121 throw std::range_error("unknown tool id"); 122 } 123 124 /// @brief convert impersonated name to id 125 /// 126 /// @param qry the impersonated name 127 /// 128 /// @returns the id or -1 if not found lookup_iidconstants::tool_name129 static int lookup_iid(char const *const qry) { 130 auto const values = runasNames(); 131 int f = 0; 132 int e = END_ENUM; 133 134 while (f < e) { 135 auto const m = f + ((e - f) >> 1); 136 auto const c = strcmp(values[m], qry); 137 if (c < 0) 138 f = m + 1; 139 else if (c > 0) 140 e = m; 141 else 142 return m; 143 } 144 return -1; 145 } 146 }; 147 148 /// @brief constants used for calling SRA Data Locator 149 struct resolver { versionconstants::resolver150 static constexpr char const *version() { return "130"; } 151 #ifdef SDL_CGI urlconstants::resolver152 static constexpr char const *url() { return SDL_CGI; } 153 #else urlconstants::resolver154 static constexpr char const *url() { return "https://trace.ncbi.nlm.nih.gov/Traces/sdl/2/retrieve"; } 155 #endif 156 157 /// @brief the current unstable version of SDL response JSON 158 /// 159 /// @Note THIS NEEDS TO TRACK ACTUAL SDL VALUE unstable_versionconstants::resolver160 static constexpr char const *unstable_version() { 161 return "2"; 162 } 163 }; 164 165 /// @brief environment variables for passing information to the driven tool 166 struct env_var { 167 /// @brief environment variables as symbolic names 168 enum { 169 CACHE_NEED_CE, 170 CACHE_NEED_PMT, 171 CACHE_URL, 172 CACHE_VDBCACHE, 173 CE_TOKEN, 174 LOCAL_URL, 175 LOCAL_VDBCACHE, 176 REMOTE_NEED_CE, 177 REMOTE_NEED_PMT, 178 REMOTE_URL, 179 REMOTE_VDBCACHE, 180 SIZE_URL, 181 SIZE_VDBCACHE, 182 END_ENUM 183 }; 184 185 /// @brief array of environment variables in the same order as the enum above. namesconstants::env_var186 static char const *const *names() { 187 static char const *const value[] = { 188 ENV_VAR_CACHE_NEED_CE, 189 ENV_VAR_CACHE_NEED_PMT, 190 ENV_VAR_CACHE_URL, 191 ENV_VAR_CACHE_VDBCACHE, 192 ENV_VAR_CE_TOKEN, 193 ENV_VAR_LOCAL_URL, 194 ENV_VAR_LOCAL_VDBCACHE, 195 ENV_VAR_REMOTE_NEED_CE, 196 ENV_VAR_REMOTE_NEED_PMT, 197 ENV_VAR_REMOTE_URL, 198 ENV_VAR_REMOTE_VDBCACHE, 199 ENV_VAR_SIZE_URL, 200 ENV_VAR_SIZE_VDBCACHE 201 }; 202 return value; 203 } 204 205 /// @brief convert id to string 206 /// 207 /// @param iid integer id of env-var (range checked) 208 /// 209 /// @returns the env-var name as a string nameconstants::env_var210 static char const *name(int const iid) { 211 assert(0 <= iid && iid < END_ENUM); 212 if (0 <= iid && iid < END_ENUM) 213 return names()[iid]; 214 throw std::range_error("unknown environment variable id"); 215 } 216 217 /// @brief convert string to id 218 /// 219 /// @param qry the env-var name 220 /// 221 /// @returns the id or -1 if not found findconstants::env_var222 static int find(char const *qry) { 223 auto const values = names(); 224 int f = 0; 225 int e = END_ENUM; 226 227 while (f < e) { 228 auto const m = f + ((e - f) >> 1); 229 auto const c = strcmp(values[m], qry); 230 if (c < 0) 231 f = m + 1; 232 else if (c > 0) 233 e = m; 234 else 235 return m; 236 } 237 return -1; 238 } 239 240 /// @brief unset environment variable by symbolic id 241 /// 242 /// @param iid the variable to unset unsetconstants::env_var243 static void unset(int const iid) { 244 #if WINDOWS 245 std::string n = name(iid); 246 n += "="; 247 _putenv(n.c_str()); 248 #else 249 unsetenv(name(iid)); 250 #endif 251 } 252 253 /// @brief set (or unset) environment variable by symbolic id 254 /// 255 /// @param iid the variable to set 256 /// @param value the new value, unset if null 257 /// @param overwrite overwrite the value if it is already there, default is to overwrite setconstants::env_var258 static void set(int const iid, char const *value, bool overwrite = true) { 259 auto const envar = name(iid); 260 EnvironmentVariables::set(envar, value ? EnvironmentVariables::Value(value) : EnvironmentVariables::Value()); 261 } 262 }; 263 264 } 265