static int GM_CDECL gmStringGetPath(gmThread * a_thread) { GM_INT_PARAM(keepSlash, 0, 0); const gmVariable * var = a_thread->GetThis(); GM_ASSERT(var->m_type == GM_STRING); gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); const char * str = (const char *) *strObj; int strLength = strObj->GetLength(); char * buffer = (char *) alloca(strLength + 1); memcpy(buffer, str, strLength + 1); //Copy old string char *lpsz = buffer + strLength; while (--lpsz >= buffer && *lpsz != '\\' && *lpsz != '/') {} if(*lpsz == '\\' || *lpsz == '/') { if(keepSlash) lpsz[1] = 0; else lpsz[0] = 0; a_thread->PushNewString(buffer); } else { a_thread->PushNewString(""); } return GM_OK; }
static int GM_CDECL gmStringGetExtension(gmThread * a_thread) { GM_INT_PARAM(keepDot, 0, 0); const gmVariable * var = a_thread->GetThis(); GM_ASSERT(var->m_type == GM_STRING); gmStringObject * strObj = (gmStringObject *) GM_OBJECT(var->m_value.m_ref); const char * str = (const char *) *strObj; int strLength = strObj->GetLength(); const char *lpsz = str + strLength; while (--lpsz >= str && *lpsz != '.') {} if(*lpsz == '.') { if(!keepDot) { ++lpsz; } a_thread->PushNewString(lpsz); } else { a_thread->PushNewString(""); } return GM_OK; }
static int GM_CDECL gmfLog(gmThread * a_thread) { GM_CHECK_STRING_PARAM(text, 0); GM_INT_PARAM(newLine, 1, 1); VirtualMachine::Get()->GetConsole().Log(text, newLine!=0 ); return GM_OK; }
static int GM_CDECL gmfFileOpenText(gmThread * a_thread) // path, readonly(true), return 1 on success. { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(filename, 0); GM_INT_PARAM(readonly, 1, 1); gmUserObject * fileObject = a_thread->ThisUserObject(); GM_ASSERT(fileObject->m_userType == s_gmFileType); if(fileObject->m_user) fclose((FILE *) fileObject->m_user); fileObject->m_user = (void *) fopen(filename, (readonly) ? "r" : "w"); if(fileObject->m_user) a_thread->PushInt(1); else a_thread->PushInt(0); return GM_OK; }
static int GM_CDECL gmfDeleteFolder(gmThread * a_thread) { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(path, 0); GM_INT_PARAM(removeSubFolders, 1, 0); if(removeSubFolders) { a_thread->PushInt(RecurseDeletePath(path) ? 1 : 0); } else { a_thread->PushInt(RemoveDirectory(path) ? 1 : 0); } return GM_OK; }
static int GM_CDECL gmfFormatTime(gmThread * a_thread) { GM_INT_PARAM(t, 0, -1); GM_STRING_PARAM(format, 1, "%A %d %B %Y, %I:%M:%S %p"); char buffer[256]; if(t == -1) { time_t lt; time(<); t = (int) lt; } struct tm * ct = localtime((time_t *) &t); strftime(buffer, 256, format, ct); a_thread->PushNewString(buffer); return GM_OK; }
// string.RemoveInvalidChars(a_replaceChar, a_invalidSet) // eg. "File Name#1.tga".RemoveInvalidChars("_","# ") returns "File_Name_1.tga" // Note: Parameters are optional. static int GM_CDECL gmfStringReplaceCharsInSet(gmThread * a_thread) { GM_INT_PARAM(repCharInt, 0, '_'); GM_STRING_PARAM(invalidCharSet, 1, " \\/:-+"); char repChar = (char)repCharInt; //Convert full int to char const gmVariable * varA = a_thread->GetThis(); GM_ASSERT(varA->m_type == GM_STRING); gmStringObject * strObjA = (gmStringObject *) GM_OBJECT(varA->m_value.m_ref); const char* cStrA = strObjA->GetString(); int lenA = strObjA->GetLength(); //Alloc buffer on stack is fine, path strings cannot be long char * buffer = (char *) alloca(lenA + 1); memcpy(buffer, cStrA, lenA + 1); int validPos; //Check that replacement char is NOT in invalid set, otherwise endless loop... if(strchr(invalidCharSet, repChar)) { return GM_EXCEPTION; } for(;;) { validPos = strcspn(buffer, invalidCharSet); if(validPos != lenA) { buffer[validPos] = repChar; } else { break; } } a_thread->PushNewString(buffer, lenA); return GM_OK; }
static int GM_CDECL gmfDoFile(gmThread * a_thread) // filename, now (1), return thread id, null on error, exception on compile error. { GM_CHECK_NUM_PARAMS(1); GM_CHECK_STRING_PARAM(filename, 0); GM_INT_PARAM(now, 1, 1); gmVariable paramThis = a_thread->Param(2, gmVariable::s_null); // 3rd param is 'this' int id = GM_INVALID_THREAD; if(filename) { char * string = NULL; FILE * fp = fopen(filename, "rb"); if(fp) { fseek(fp, 0, SEEK_END); int size = ftell(fp); rewind(fp); string = new char[size + 1]; fread(string, 1, size, fp); string[size] = 0; fclose(fp); } else { GM_EXCEPTION_MSG("failed to open file '%s'", filename); return GM_EXCEPTION; } if(string == NULL) return GM_OK; int errors = a_thread->GetMachine()->ExecuteString(string, &id, (now) ? true : false, filename, ¶mThis); delete[] string; if(errors) { return GM_EXCEPTION; } else { a_thread->PushInt(id); } } return GM_OK; }
static int GM_CDECL gmfFileReadLine(gmThread * a_thread) // flag keep \n (0), return string, or null on eof { GM_INT_PARAM(keepLF, 0, 0); const int len = GM_SYSTEM_LIB_MAX_LINE; char buffer[len]; gmUserObject * fileObject = a_thread->ThisUserObject(); GM_ASSERT(fileObject->m_userType == s_gmFileType); if(fileObject->m_user) { char * str = fgets(buffer, len, (FILE *) fileObject->m_user); if(str) { int slen = (int)strlen(str); if(!keepLF) { if(!feof((FILE *) fileObject->m_user)) str[--slen] = '\0'; } a_thread->PushNewString(str, slen); } } return GM_OK; }