scriptFilename.cpp
Engine/source/console/scriptFilename.cpp
Classes:
class
class
Namespaces:
namespace
This namespace contains the core of the console functionality.
Public Functions
ConsoleToolFunction(collapseFilename , const char * , 2 , 2 , "(string filename)" "@internal Editor use only" )
ConsoleToolFunction(isScriptPathExpando , bool , 2 , 2 , "(string expando)" "@internal Editor use only" )
ConsoleToolFunction(removeScriptPathExpando , void , 2 , 2 , "(string expando)" "@internal Editor use only" )
ConsoleToolFunction(setScriptPathExpando , void , 3 , 4 , "(string expando, string path[, bool toolsOnly])" "@internal Editor use only" )
DefineEngineFunction(expandFilename , const char * , (const char *filename) , "@brief Grabs the full path of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">file\n\n</a>" "@param filename Name of the local <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">locate\n</a>" "@return <a href="/coding/class/classstring/">String</a> containing the full filepath on <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">disk\n</a>" "@ingroup FileSystem" )
DefineEngineFunction(expandOldFilename , const char * , (const char *filename) , "@brief Retrofits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> filepath that uses old Torque <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">style\n\n</a>" "@return <a href="/coding/class/classstring/">String</a> containing filepath with <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">formatting\n</a>" "@ingroup FileSystem" )
Detailed Description
Public Functions
ConsoleToolFunction(collapseFilename , const char * , 2 , 2 , "(string filename)" "@internal Editor use only" )
ConsoleToolFunction(isScriptPathExpando , bool , 2 , 2 , "(string expando)" "@internal Editor use only" )
ConsoleToolFunction(removeScriptPathExpando , void , 2 , 2 , "(string expando)" "@internal Editor use only" )
ConsoleToolFunction(setScriptPathExpando , void , 3 , 4 , "(string expando, string path[, bool toolsOnly])" "@internal Editor use only" )
DefineEngineFunction(expandFilename , const char * , (const char *filename) , "@brief Grabs the full path of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">file\n\n</a>" "@param filename Name of the local <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">locate\n</a>" "@return <a href="/coding/class/classstring/">String</a> containing the full filepath on <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">disk\n</a>" "@ingroup FileSystem" )
DefineEngineFunction(expandOldFilename , const char * , (const char *filename) , "@brief Retrofits <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> filepath that uses old Torque <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">style\n\n</a>" "@return <a href="/coding/class/classstring/">String</a> containing filepath with <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">formatting\n</a>" "@ingroup FileSystem" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "console/scriptFilename.h" 26 27#include "core/frameAllocator.h" 28#include "core/tSimpleHashTable.h" 29#include "core/strings/stringFunctions.h" 30#include "core/stringTable.h" 31#include "console/engineAPI.h" 32#include "console/compiler.h" 33 34 35namespace Con 36{ 37//----------------------------------------------------------------------------- 38// Local Globals 39//----------------------------------------------------------------------------- 40 41struct PathExpando 42{ 43 StringTableEntry mPath; 44 bool mIsToolsOnly; 45}; 46 47static SimpleHashTable<PathExpando> sgPathExpandos(64, false); 48 49//----------------------------------------------------------------------------- 50// Global Functions 51//----------------------------------------------------------------------------- 52 53void setScriptPathExpando(const char *expando, const char *path, bool toolsOnly /*= false*/) 54{ 55 PathExpando *exp = sgPathExpandos.retreive(expando); 56 if(exp) 57 { 58 exp->mPath = StringTable->insert(path); 59 exp->mIsToolsOnly = toolsOnly; 60 } 61 else 62 { 63 exp = new PathExpando; 64 exp->mPath = StringTable->insert(path); 65 exp->mIsToolsOnly = toolsOnly; 66 sgPathExpandos.insert(exp, expando); 67 } 68} 69 70void removeScriptPathExpando(const char *expando) 71{ 72 PathExpando *exp = sgPathExpandos.remove(expando); 73 if(exp) 74 delete exp; 75} 76 77bool isScriptPathExpando(const char *expando) 78{ 79 PathExpando *exp = sgPathExpandos.retreive(expando); 80 return ( exp != NULL); 81} 82 83//----------------------------------------------------------------------------- 84 85// [tom, 5/18/2006] FIXME: This needs some bounds checking 86bool expandToolScriptFilename(char *filename, U32 size, const char *src) 87{ 88 // [tom, 10/16/2006] Note: I am purposefully not early-outing here in the 89 // same way the old code did as it is now possible that something could 90 // be expanded if the name or mod is NULL. This was previously not the case. 91 92 const StringTableEntry cbMod = CodeBlock::getCurrentCodeBlockModName(); 93 const StringTableEntry cbFullPath = CodeBlock::getCurrentCodeBlockFullPath(); 94 95 char varBuf[1024], modBuf[1024]; 96 const char *ptr = src; 97 char *retPtr = filename; 98 char *slash; 99 100 const char *catPath = NULL; 101 102#ifndef TORQUE_DEBUG 103 bool isTools = Con::isCurrentScriptToolScript(); 104#endif 105 106 // Check leading character 107 switch(*ptr) 108 { 109 case '^': 110 { 111 // Variable 112 const char *varPtr = ptr+1; 113 char *insertPtr = varBuf; 114 bool valid = true; 115 while(*varPtr != '/') 116 { 117 if(*varPtr == 0) 118 { 119 valid = false; 120 break; 121 } 122 *insertPtr++ = *varPtr++; 123 } 124 125 if(valid) 126 { 127 // Got a valid variable 128 *insertPtr = 0; 129 130 PathExpando *exp = sgPathExpandos.retreive(varBuf); 131 132 if(exp == NULL) 133 { 134 Con::errorf("expandScriptFilename - Ignoring invalid path expando \"%s\"", varBuf); 135 break; 136 } 137 138#ifndef TORQUE_DEBUG 139 // [tom, 12/13/2006] This stops tools expandos from working in the console, 140 // which is useful behavior when debugging so I'm ifdefing this out for debug builds. 141 142 if(! isTools && exp->mIsToolsOnly) 143 { 144 Con::errorf("expandScriptFilename - attempting to use tools only expando \"%s\" from outside of tools", varBuf); 145 146 *filename = 0; 147 return false; 148 } 149#endif 150 151 catPath = exp ? exp->mPath : ""; 152 // swallow the expando and the slash after the expando 153 ptr += dStrlen(varBuf) + 1; 154 if(*ptr == '/') 155 ptr++; 156 } 157 } 158 break; 159 160 case '~': 161 // Relative to mod 162 if(cbMod && cbFullPath) 163 { 164 Platform::makeFullPathName(cbMod, modBuf, sizeof(modBuf)); 165 catPath = modBuf; 166 } 167 else 168 { 169 // Probably not a mod, so we'll use the ^game expando 170 PathExpando *exp = sgPathExpandos.retreive("game"); 171 172 if(exp == NULL) 173 { 174 Con::errorf("expandScriptFilename - ~ expansion failed for mod and ^game when processing '%s'", src); 175 break; 176 } 177 178 catPath = exp ? exp->mPath : ""; 179 } 180 // swallow ~ and optional slash 181 switch(ptr[1]) 182 { 183 case '/': ptr += 2; break; 184 default: ptr++; 185 } 186 187 break; 188 189 case '.': 190 // Relative to script directory 191 if(cbFullPath) 192 { 193 dStrcpy(varBuf, cbFullPath, 1024); 194 slash = dStrrchr(varBuf, '/'); 195 if(slash) *slash = 0; 196 197 catPath = varBuf; 198 199 // swallow dot and optional slash, but dont swallow .. relative path token 200 switch(ptr[1]) 201 { 202 case '.': break; 203 case '/': ptr += 2; break; 204 default: ptr++; 205 } 206 } 207 break; 208 } 209 210 // [tom, 11/20/2006] Handing off to makeFullPathName() allows us to process .. correctly. 211 Platform::makeFullPathName(ptr, retPtr, size, catPath); 212 213 return true; 214} 215 216//----------------------------------------------------------------------------- 217 218bool expandOldScriptFilename(char *filename, U32 size, const char *src) 219{ 220 const StringTableEntry cbName = CodeBlock::getCurrentCodeBlockName(); 221 if (!cbName) 222 { 223 dStrcpy(filename, src, size); 224 return true; 225 } 226 227 const char *slash; 228 if (dStrncmp(src, "~/", 2) == 0) 229 // tilde path means load from current codeblock/mod root 230 slash = dStrchr(cbName, '/'); 231 else if (dStrncmp(src, "./", 2) == 0) 232 // dot path means load from current codeblock/mod path 233 slash = dStrrchr(cbName, '/'); 234 else if (dStrncmp(src, "^", 1) == 0) 235 { 236 Platform::makeFullPathName(src + 1, filename, size); 237 return true; 238 } 239 else 240 { 241 // otherwise path must be fully specified 242 if (dStrlen(src) > size) 243 { 244 Con::errorf("Buffer overflow attempting to expand filename: %s", src); 245 *filename = 0; 246 return false; 247 } 248 dStrcpy(filename, src, size); 249 return true; 250 } 251 252 if (slash == NULL) 253 { 254 Con::errorf("Illegal CodeBlock path detected (no mod directory): %s", cbName); 255 *filename = 0; 256 return false; 257 } 258 259 U32 length = slash-cbName; 260 if ((length+dStrlen(src)) > size) 261 { 262 Con::errorf("Buffer overflow attempting to expand filename: %s", src); 263 *filename = 0; 264 return false; 265 } 266 267 dStrncpy(filename, cbName, length); 268 dStrcpy(filename+length, src+1, size - length); 269 return true; 270} 271 272//----------------------------------------------------------------------------- 273 274bool expandScriptFilename(char *filename, U32 size, const char *src) 275{ 276#ifndef TORQUE2D_TOOLS_FIXME 277 return expandOldScriptFilename(filename, size, src); 278#else 279 return expandToolScriptFilename(filename, size, src); 280#endif 281} 282 283//----------------------------------------------------------------------------- 284 285static StringTableEntry tryGetBasePath(const char *path, const char *base) 286{ 287 U32 len = dStrlen(base); 288 if(dStrnicmp(path, base, len) == 0) 289 { 290 if(*(path + len) == '/') --len; 291 return StringTable->insertn(path, len, true); 292 } 293 return NULL; 294} 295 296struct CollapseTest 297{ 298 const char *path; 299 const char *replace; 300}; 301 302bool collapseScriptFilename(char *filename, U32 size, const char *src) 303{ 304 PathExpando *tools = sgPathExpandos.retreive("tools"); 305 PathExpando *game = sgPathExpandos.retreive("game"); 306 307 CollapseTest test[]= 308 { 309 { game ? game->mPath : NULL, "~" }, 310 { tools ? tools->mPath : NULL, "^tools" }, 311 { Platform::getCurrentDirectory(), "" }, 312 { Platform::getMainDotCsDir(), "" }, 313 { NULL, NULL } 314 }; 315 316 for(S32 i = 0;!(test[i].path == NULL && test[i].replace == NULL);++i) 317 { 318 if(test[i].path == NULL) continue; 319 320 StringTableEntry base = tryGetBasePath(src, test[i].path); 321 if(base == NULL) 322 continue; 323 324 StringTableEntry rel = Platform::makeRelativePathName(src, test[i].path); 325 326 *filename = 0; 327 if(*test[i].replace) 328 dSprintf(filename, size, "%s/", test[i].replace); 329 dStrcat(filename, rel, size); 330 return true; 331 } 332 333 dStrncpy(filename, src, size - 1); 334 filename[size-1] = 0; 335 return true; 336} 337 338//----------------------------------------------------------------------------- 339 340} // end namespace Con 341 342//----------------------------------------------------------------------------- 343// Console Functions 344//----------------------------------------------------------------------------- 345 346DefineEngineFunction(expandFilename, const char*, (const char* filename),, 347 "@brief Grabs the full path of a specified file\n\n" 348 "@param filename Name of the local file to locate\n" 349 "@return String containing the full filepath on disk\n" 350 "@ingroup FileSystem") 351{ 352 static const U32 bufSize = 1024; 353 char* ret = Con::getReturnBuffer(bufSize); 354 Con::expandScriptFilename(ret, bufSize, filename); 355 return ret; 356} 357 358DefineEngineFunction(expandOldFilename, const char*, (const char* filename),, 359 "@brief Retrofits a filepath that uses old Torque style\n\n" 360 "@return String containing filepath with new formatting\n" 361 "@ingroup FileSystem") 362{ 363 static const U32 bufSize = 1024; 364 char* ret = Con::getReturnBuffer(bufSize); 365 Con::expandOldScriptFilename(ret, bufSize, filename); 366 return ret; 367} 368 369//----------------------------------------------------------------------------- 370// Tool Functions 371//----------------------------------------------------------------------------- 372 373ConsoleToolFunction(collapseFilename, const char*, 2, 2, "(string filename)" 374 "@internal Editor use only") 375{ 376 TORQUE_UNUSED(argc); 377 static const U32 bufSize = 1024; 378 char* ret = Con::getReturnBuffer( bufSize ); 379 Con::collapseScriptFilename(ret, bufSize, argv[1]); 380 return ret; 381} 382 383ConsoleToolFunction(setScriptPathExpando, void, 3, 4, "(string expando, string path[, bool toolsOnly])" 384 "@internal Editor use only") 385{ 386 if(argc == 4) 387 Con::setScriptPathExpando(argv[1], argv[2], dAtob(argv[3])); 388 else 389 Con::setScriptPathExpando(argv[1], argv[2]); 390} 391 392ConsoleToolFunction(removeScriptPathExpando, void, 2, 2, "(string expando)" 393 "@internal Editor use only") 394{ 395 Con::removeScriptPathExpando(argv[1]); 396} 397 398ConsoleToolFunction(isScriptPathExpando, bool, 2, 2, "(string expando)" 399 "@internal Editor use only") 400{ 401 return Con::isScriptPathExpando(argv[1]); 402} 403