/** * Change the name of the president. * @param tile unused * @param flags operation to perform * @param p1 unused * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { bool reset = StrEmpty(text); if (!reset) { if (Utf8StringLength(text) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) return CMD_ERROR; if (!IsUniquePresidentName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE); } if (flags & DC_EXEC) { Company *c = Company::Get(_current_company); free(c->president_name); if (reset) { c->president_name = NULL; } else { c->president_name = stredup(text); if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) { char buf[80]; seprintf(buf, lastof(buf), "%s Transport", text); DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf); } } MarkWholeScreenDirty(); CompanyAdminUpdate(c); } return CommandCost(); }
/** * Callback used while walking up the stack. * @param pc program counter * @param sig 'active' signal (unused) * @param params parameters * @return always 0, continue walking up the stack */ static int SunOSStackWalker(uintptr_t pc, int sig, void *params) { StackWalkerParams *wp = (StackWalkerParams *)params; /* Resolve program counter to file and nearest symbol (if possible) */ Dl_info dli; if (dladdr((void *)pc, &dli) != 0) { *wp->bufptr += seprintf(*wp->bufptr, wp->last, " [%02i] %s(%s+0x%x) [0x%x]\n", wp->counter, dli.dli_fname, dli.dli_sname, (int)((byte *)pc - (byte *)dli.dli_saddr), (uint)pc); } else { *wp->bufptr += seprintf(*wp->bufptr, wp->last, " [%02i] [0x%x]\n", wp->counter, (uint)pc); } wp->counter++; return 0; }
/** * Get the address as a string, e.g. 127.0.0.1:12345. * @param buffer the buffer to write to * @param last the last element in the buffer * @param with_family whether to add the family (e.g. IPvX). */ void NetworkAddress::GetAddressAsString(char *buffer, const char *last, bool with_family) { if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "[", last); buffer = strecpy(buffer, this->GetHostname(), last); if (this->GetAddress()->ss_family == AF_INET6) buffer = strecpy(buffer, "]", last); buffer += seprintf(buffer, last, ":%d", this->GetPort()); if (with_family) { char family; switch (this->address.ss_family) { case AF_INET: family = '4'; break; case AF_INET6: family = '6'; break; default: family = '?'; break; } seprintf(buffer, last, " (IPv%c)", family); } }
/** * Convert the md5sum to a hexadecimal string representation * @param buf buffer to put the md5sum into * @param last last character of buffer (usually lastof(buf)) * @param md5sum the md5sum itself * @return a pointer to the next character after the md5sum */ char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16]) { char *p = buf; for (uint i = 0; i < 16; i++) { p += seprintf(p, last, "%02X", md5sum[i]); } return p; }
/* virtual */ char *LogOSVersion(char *buffer, const char *last) const { struct utsname name; if (uname(&name) < 0) { return buffer + seprintf(buffer, last, "Could not get OS version: %s\n", strerror(errno)); } return buffer + seprintf(buffer, last, "Operating system:\n" " Name: %s\n" " Release: %s\n" " Version: %s\n" " Machine: %s\n", name.sysname, name.release, name.version, name.machine ); }
char *ScriptText::_GetEncodedText(char *p, char *lastofp) { p += Utf8Encode(p, SCC_ENCODED); p += seprintf(p, lastofp, "%X", this->string); for (int i = 0; i < this->paramc; i++) { if (this->params[i] != NULL) { p += seprintf(p, lastofp, ":\"%s\"", this->params[i]); continue; } if (this->paramt[i] != NULL) { p += seprintf(p, lastofp, ":"); p = this->paramt[i]->_GetEncodedText(p, lastofp); continue; } p += seprintf(p, lastofp,":%X", this->parami[i]); } return p; }
static long cputyperead(struct chan *unused, void *a, long n, int64_t off) { char buf[512], *s, *e; int i, k; error(ENOSYS, NULL); #if 0 e = buf + sizeof buf; s = seprintf(buf, e, "%s %d\n", "AMD64", 0); k = m->ncpuinfoe - m->ncpuinfos; if (k > 4) k = 4; for (i = 0; i < k; i++) s = seprintf(s, e, "%#8.8ux %#8.8ux %#8.8ux %#8.8ux\n", m->cpuinfo[i][0], m->cpuinfo[i][1], m->cpuinfo[i][2], m->cpuinfo[i][3]); return readstr(off, a, n, buf); #endif }
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback) { if (!FcInit()) return false; bool ret = false; /* Fontconfig doesn't handle full language isocodes, only the part * before the _ of e.g. en_GB is used, so "remove" everything after * the _. */ char lang[16]; seprintf(lang, lastof(lang), ":lang=%s", language_isocode); char *split = strchr(lang, '_'); if (split != NULL) *split = '\0'; /* First create a pattern to match the wanted language. */ FcPattern *pat = FcNameParse((FcChar8*)lang); /* We only want to know the filename. */ FcObjectSet *os = FcObjectSetBuild(FC_FILE, NULL); /* Get the list of filenames matching the wanted language. */ FcFontSet *fs = FcFontList(NULL, pat, os); /* We don't need these anymore. */ FcObjectSetDestroy(os); FcPatternDestroy(pat); if (fs != NULL) { for (int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; FcChar8 *file = NULL; FcResult res = FcPatternGetString(font, FC_FILE, 0, &file); if (res != FcResultMatch || file == NULL) { continue; } strecpy(settings->small_font, (const char*)file, lastof(settings->small_font)); strecpy(settings->medium_font, (const char*)file, lastof(settings->medium_font)); strecpy(settings->large_font, (const char*)file, lastof(settings->large_font)); bool missing = callback(NULL); DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no"); if (!missing) { ret = true; break; } } /* Clean up the list of filenames. */ FcFontSetDestroy(fs); } FcFini(); return ret; }
/** * Build a human readable list of available drivers, grouped by type. */ char *DriverFactoryBase::GetDriversInfo(char *p, const char *last) { for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) { p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type)); for (int priority = 10; priority >= 0; priority--) { Drivers::iterator it = GetDrivers().begin(); for (; it != GetDrivers().end(); it++) { DriverFactoryBase *d = (*it).second; if (d->type != type) continue; if (d->priority != priority) continue; p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription()); } } p += seprintf(p, last, "\n"); } return p; }
/* virtual */ char *LogError(char *buffer, const char *last, const char *message) const { return buffer + seprintf(buffer, last, "Crash reason:\n" " Signal: %s (%d)\n" " Message: %s\n\n", strsignal(this->signum), this->signum, message == NULL ? "<none>" : message ); }
bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) { char filename[MAX_PATH]; int res; #if defined(__MORPHOS__) || defined(__AMIGAOS__) /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */ if (FiosIsRoot(path)) { res = seprintf(filename, lastof(filename), "%s:%s", path, ent->d_name); } else // XXX - only next line! #else assert(path[strlen(path) - 1] == PATHSEPCHAR); if (strlen(path) > 2) assert(path[strlen(path) - 2] != PATHSEPCHAR); #endif res = seprintf(filename, lastof(filename), "%s%s", path, ent->d_name); /* Could we fully concatenate the path and filename? */ if (res >= (int)lengthof(filename) || res < 0) return false; return stat(filename, sb) == 0; }
/** * Checks whether the MD5 checksums of the files are correct. * * @note Also checks sample.cat and other required non-NewGRF GRFs for corruption. */ void CheckExternalFiles() { if (BaseGraphics::GetUsedSet() == NULL || BaseSounds::GetUsedSet() == NULL) return; const GraphicsSet *used_set = BaseGraphics::GetUsedSet(); DEBUG(grf, 1, "Using the %s base graphics set", used_set->name); static const size_t ERROR_MESSAGE_LENGTH = 256; static const size_t MISSING_FILE_MESSAGE_LENGTH = 128; /* Allocate for a message for each missing file and for one error * message per set. */ char error_msg[MISSING_FILE_MESSAGE_LENGTH * (GraphicsSet::NUM_FILES + SoundsSet::NUM_FILES) + 2 * ERROR_MESSAGE_LENGTH]; error_msg[0] = '\0'; char *add_pos = error_msg; const char *last = lastof(error_msg); if (used_set->GetNumInvalid() != 0) { /* Not all files were loaded successfully, see which ones */ add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", used_set->name); for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) { MD5File::ChecksumResult res = used_set->files[i].CheckMD5(BASESET_DIR); if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning); } add_pos += seprintf(add_pos, last, "\n"); } const SoundsSet *sounds_set = BaseSounds::GetUsedSet(); if (sounds_set->GetNumInvalid() != 0) { add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", sounds_set->name); assert_compile(SoundsSet::NUM_FILES == 1); /* No need to loop each file, as long as there is only a single * sound file. */ add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename, sounds_set->files->CheckMD5(BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning); } if (add_pos != error_msg) ShowInfoF("%s", error_msg); }
/** Build a string containing space separated parameter values, and terminate */ char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last) { uint i; /* Return an empty string if there are no parameters */ if (c->num_params == 0) return strecpy(dst, "", last); for (i = 0; i < c->num_params; i++) { if (i > 0) dst = strecpy(dst, " ", last); dst += seprintf(dst, last, "%d", c->param[i]); } return dst; }
AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version) { /* Internally we store libraries as 'library.version' */ char library_name[1024]; seprintf(library_name, lastof(library_name), "%s.%d", library, version); strtolower(library_name); /* Check if the library + version exists */ ScriptInfoList::iterator iter = this->info_list.find(library_name); if (iter == this->info_list.end()) return NULL; return static_cast<AILibrary *>((*iter).second); }
void FiosGetDrives(FileList &file_list) { TCHAR drives[256]; const TCHAR *s; GetLogicalDriveStrings(lengthof(drives), drives); for (s = drives; *s != '\0';) { FiosItem *fios = file_list.Append(); fios->type = FIOS_TYPE_DRIVE; fios->mtime = 0; seprintf(fios->name, lastof(fios->name), "%c:", s[0] & 0xFF); strecpy(fios->title, fios->name, lastof(fios->title)); while (*s++ != '\0') { /* Nothing */ } } }
/* virtual */ char *CrashLogWindows::LogError(char *buffer, const char *last, const char *message) const { return buffer + seprintf(buffer, last, "Crash reason:\n" " Exception: %.8X\n" #ifdef _M_AMD64 " Location: %.16IX\n" #else " Location: %.8X\n" #endif " Message: %s\n\n", (int)ep->ExceptionRecord->ExceptionCode, (size_t)ep->ExceptionRecord->ExceptionAddress, message == NULL ? "<none>" : message ); }
void Squirrel::CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column) { SQChar buf[1024]; seprintf(buf, lastof(buf), "Error %s:" OTTD_PRINTF64 "/" OTTD_PRINTF64 ": %s", source, line, column, desc); /* Check if we have a custom print function */ Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); engine->crashed = true; SQPrintFunc *func = engine->print_func; if (func == NULL) { DEBUG(misc, 0, "[Squirrel] Compile error: %s", buf); } else { (*func)(true, buf); } }
/* virtual */ char *CrashLogWindows::LogOSVersion(char *buffer, const char *last) const { _OSVERSIONINFOA os; os.dwOSVersionInfoSize = sizeof(os); GetVersionExA(&os); return buffer + seprintf(buffer, last, "Operating system:\n" " Name: Windows\n" " Release: %d.%d.%d (%s)\n", (int)os.dwMajorVersion, (int)os.dwMinorVersion, (int)os.dwBuildNumber, os.szCSDVersion ); }
AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) { if (this->info_list.size() == 0) return NULL; if (nameParam == NULL) return NULL; char ai_name[1024]; strecpy(ai_name, nameParam, lastof(ai_name)); strtolower(ai_name); AIInfo *info = NULL; int version = -1; if (versionParam == -1) { /* We want to load the latest version of this AI; so find it */ if (this->info_single_list.find(ai_name) != this->info_single_list.end()) return static_cast<AIInfo *>(this->info_single_list[ai_name]); /* If we didn't find a match AI, maybe the user included a version */ char *e = strrchr(ai_name, '.'); if (e == NULL) return NULL; *e = '\0'; e++; versionParam = atoi(e); /* FALL THROUGH, like we were calling this function with a version. */ } if (force_exact_match) { /* Try to find a direct 'name.version' match */ char ai_name_tmp[1024]; seprintf(ai_name_tmp, lastof(ai_name_tmp), "%s.%d", ai_name, versionParam); strtolower(ai_name_tmp); if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return static_cast<AIInfo *>(this->info_list[ai_name_tmp]); } /* See if there is a compatible AI which goes by that name, with the highest * version which allows loading the requested version */ ScriptInfoList::iterator it = this->info_list.begin(); for (; it != this->info_list.end(); it++) { AIInfo *i = static_cast<AIInfo *>((*it).second); if (strcasecmp(ai_name, i->GetName()) == 0 && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) { version = (*it).second->GetVersion(); info = i; } } return info; }
/* The final argument _must_ be NULL. */ void ntx_homedir(char *sub, ...) { va_list args; char ntxroot[FILE_MAX], *path; char *subd; va_start(args, sub); if(!(path = getenv("NTXROOT"))) { seprintf(ntxroot, FILE_MAX, "%s/"NTX_DIR, getenv("HOME")); path = ntxroot; } if(chdir(path) == -1) { mkdir(path, S_IRWXU); if(chdir(path) == -1) die("Unable to enter directory %s.\n", path); for(subd = sub; subd; subd = va_arg(args, char *)) if(mkdir(subd, S_IRWXU) == -1) die("Cannot make directory %s.\n", subd); }
static bool CreateMainSurface(uint w, uint h) { int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals"); set_color_depth(bpp); GetAvailableVideoMode(&w, &h); if (set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, w, h, 0, 0) != 0) { DEBUG(driver, 0, "Allegro: Couldn't allocate a window to draw on '%s'", allegro_error); return false; } /* The size of the screen might be bigger than the part we can actually draw on! * So calculate the size based on the top, bottom, left and right */ _allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct); _screen.width = _allegro_screen->w; _screen.height = _allegro_screen->h; _screen.pitch = ((byte*)screen->line[1] - (byte*)screen->line[0]) / (bpp / 8); _screen.dst_ptr = _allegro_screen->line[0]; /* Initialise the screen so we don't blit garbage to the screen */ memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch); /* Set the mouse at the place where we expect it */ poll_mouse(); _cursor.pos.x = mouse_x; _cursor.pos.y = mouse_y; BlitterFactory::GetCurrentBlitter()->PostResize(); InitPalette(); char caption[32]; seprintf(caption, lastof(caption), "OpenTTD %s", _openttd_revision); set_window_title(caption); enable_hardware_cursor(); select_mouse_cursor(MOUSE_CURSOR_ARROW); show_mouse(_allegro_screen); GameSizeChanged(); return true; }
/** * Clone the custom name of a vehicle, adding or incrementing a number. * @param src Source vehicle, with a custom name. * @param dst Destination vehicle. */ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) { char buf[256]; /* Find the position of the first digit in the last group of digits. */ size_t number_position; for (number_position = strlen(src->name); number_position > 0; number_position--) { /* The design of UTF-8 lets this work simply without having to check * for UTF-8 sequences. */ if (src->name[number_position - 1] < '0' || src->name[number_position - 1] > '9') break; } /* Format buffer and determine starting number. */ int num; byte padding = 0; if (number_position == strlen(src->name)) { /* No digit at the end, so start at number 2. */ strecpy(buf, src->name, lastof(buf)); strecat(buf, " ", lastof(buf)); number_position = strlen(buf); num = 2; } else { /* Found digits, parse them and start at the next number. */ strecpy(buf, src->name, lastof(buf)); buf[number_position] = '\0'; char *endptr; num = strtol(&src->name[number_position], &endptr, 10) + 1; padding = endptr - &src->name[number_position]; } /* Check if this name is already taken. */ for (int max_iterations = 1000; max_iterations > 0; max_iterations--, num++) { /* Attach the number to the temporary name. */ seprintf(&buf[number_position], lastof(buf), "%0*d", padding, num); /* Check the name is unique. */ if (IsUniqueVehicleName(buf)) { dst->name = strdup(buf); break; } } /* All done. If we didn't find a name, it'll just use its default. */ }
/* static */ SQInteger AIInfo::DummyConstructor(HSQUIRRELVM vm) { /* Get the AIInfo */ SQUserPointer instance; sq_getinstanceup(vm, 2, &instance, 0); AIInfo *info = (AIInfo *)instance; info->api_version = NULL; SQInteger res = AIFileInfo::Constructor(vm, info); if (res != 0) return res; char buf[8]; seprintf(buf, lastof(buf), "%d.%d", GB(_openttd_newgrf_version, 28, 4), GB(_openttd_newgrf_version, 24, 4)); info->api_version = strdup(buf); /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ sq_setinstanceup(vm, 2, NULL); /* Register the AI to the base system */ info->base->SetDummyAI(info); return 0; }
/** * Create an autosave. The default name is "autosave#.sav". However with * the setting 'keep_all_autosave' the name defaults to company-name + date */ static void DoAutosave() { char buf[MAX_PATH]; if (_settings_client.gui.keep_all_autosave) { GenerateDefaultSaveName(buf, lastof(buf)); strecat(buf, ".sav", lastof(buf)); } else { static int _autosave_ctr = 0; /* generate a savegame name and number according to _settings_client.gui.max_num_autosaves */ seprintf(buf, lastof(buf), "autosave%d.sav", _autosave_ctr); if (++_autosave_ctr >= _settings_client.gui.max_num_autosaves) _autosave_ctr = 0; } DEBUG(sl, 2, "Autosaving to '%s'", buf); if (SaveOrLoad(buf, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR) != SL_OK) { ShowErrorMessage(STR_ERROR_AUTOSAVE_FAILED, INVALID_STRING_ID, WL_ERROR); } }
bool ScriptInstance::LoadCompatibilityScripts(const char *api_version, Subdirectory dir) { char script_name[32]; seprintf(script_name, lastof(script_name), "compat_%s.nut", api_version); char buf[MAX_PATH]; Searchpath sp; FOR_ALL_SEARCHPATHS(sp) { FioAppendDirectory(buf, MAX_PATH, sp, dir); ttd_strlcat(buf, script_name, MAX_PATH); if (!FileExists(buf)) continue; if (this->engine->LoadScript(buf)) return true; ScriptLog::Error("Failed to load API compatibility script"); DEBUG(script, 0, "Error compiling / running API compatibility script: %s", buf); return false; } ScriptLog::Warning("API compatibility script not found"); return true; }
static int install_iptables_rule(const char *fmt, ...) { char commandbuf[1024], *ptr = commandbuf, *ebuf = commandbuf + sizeof(commandbuf); ptr = seprintf(ptr, ebuf, IPTABLES" -A "CHAIN" "); va_list ap; va_start(ap, fmt); ptr = vseprintf(ptr, ebuf, fmt, ap); va_end(ap); if(ptr == ebuf) { LL_PRINT("ERROR: commandbuf too small\n"); return -ENOSPC; } int res = shell(commandbuf); if(res == EXIT_SUCCESS) return 0; LL_PRINT("ERROR: Failed to execute '%s'\n", commandbuf); return -EINVAL; }
void Squirrel::RunError(HSQUIRRELVM vm, const SQChar *error) { /* Set the print function to something that prints to stderr */ SQPRINTFUNCTION pf = sq_getprintfunc(vm); sq_setprintfunc(vm, &Squirrel::ErrorPrintFunc); /* Check if we have a custom print function */ SQChar buf[1024]; seprintf(buf, lastof(buf), "Your script made an error: %s\n", error); Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); SQPrintFunc *func = engine->print_func; if (func == NULL) { fprintf(stderr, "%s", buf); } else { (*func)(true, buf); } /* Print below the error the stack, so the users knows what is happening */ sqstd_printcallstack(vm); /* Reset the old print function */ sq_setprintfunc(vm, pf); }
void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const ContentIDList &content) { uint count = content.Length(); /* Allocate memory for the whole request. * Requests are "id\nid\n..." (as strings), so assume the maximum ID, * which is uint32 so 10 characters long. Then the newlines and * multiply that all with the count and then add the '\0'. */ uint bytes = (10 + 1) * count + 1; char *content_request = MallocT<char>(bytes); const char *lastof = content_request + bytes - 1; char *p = content_request; for (const ContentID *id = content.Begin(); id != content.End(); id++) { p += seprintf(p, lastof, "%d\n", *id); } this->http_response_index = -1; NetworkAddress address(NETWORK_CONTENT_MIRROR_HOST, NETWORK_CONTENT_MIRROR_PORT); new NetworkHTTPContentConnecter(address, this, NETWORK_CONTENT_MIRROR_URL, content_request); /* NetworkHTTPContentConnecter takes over freeing of content_request! */ }
/** * Check whether the AI given in info is the same as in ci based * on the shortname and md5 sum. * @param ci the information to compare to * @param md5sum whether to check the MD5 checksum * @param info the AI to get the shortname and md5 sum from * @return true iff they're the same */ static bool IsSameAI(const ContentInfo *ci, bool md5sum, AIFileInfo *info) { uint32 id = 0; const char *str = info->GetShortName(); for (int j = 0; j < 4 && *str != '\0'; j++, str++) id |= *str << (8 * j); if (id != ci->unique_id) return false; if (!md5sum) return true; AIFileChecksumCreator checksum; char path[MAX_PATH]; strecpy(path, info->GetMainScript(), lastof(path)); /* There'll always be at least 2 path separator characters in an AI's * main script name as the search algorithm requires the main script to * be in a subdirectory of the AI directory; so ai/<path>/main.nut. */ *strrchr(path, PATHSEPCHAR) = '\0'; *strrchr(path, PATHSEPCHAR) = '\0'; TarList::iterator iter = _tar_list.find(path); if (iter != _tar_list.end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the MD5 checksumming. */ TarFileList::iterator tar; FOR_ALL_TARS(tar) { /* Not in the same tar. */ if (tar->second.tar_filename != iter->first) continue; /* Check the extension. */ const char *ext = strrchr(tar->first.c_str(), '.'); if (ext == NULL || strcasecmp(ext, ".nut") != 0) continue; /* Create the full path name, */ seprintf(path, lastof(path), "%s%c%s", tar->second.tar_filename, PATHSEPCHAR, tar->first.c_str()); checksum.AddFile(path, 0); } } else {
/* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook, bool prepend_API_name) { Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); int oldtop = sq_gettop(vm); /* First, find the class */ sq_pushroottable(vm); if (prepend_API_name) { size_t len = strlen(class_name) + strlen(engine->GetAPIName()) + 1; char *class_name2 = (char *)alloca(len); seprintf(class_name2, class_name2 + len - 1, "%s%s", engine->GetAPIName(), class_name); sq_pushstring(vm, class_name2, -1); } else { sq_pushstring(vm, class_name, -1); } if (SQ_FAILED(sq_get(vm, -2))) { DEBUG(misc, 0, "[squirrel] Failed to find class by the name '%s%s'", prepend_API_name ? engine->GetAPIName() : "", class_name); sq_settop(vm, oldtop); return false; } /* Create the instance */ if (SQ_FAILED(sq_createinstance(vm, -1))) { DEBUG(misc, 0, "[squirrel] Failed to create instance for class '%s%s'", prepend_API_name ? engine->GetAPIName() : "", class_name); sq_settop(vm, oldtop); return false; } if (instance != NULL) { /* Find our instance */ sq_getstackobj(vm, -1, instance); /* Add a reference to it, so it survives for ever */ sq_addref(vm, instance); } sq_remove(vm, -2); // Class-name sq_remove(vm, -2); // Root-table /* Store it in the class */ sq_setinstanceup(vm, -1, real_instance); if (release_hook != NULL) sq_setreleasehook(vm, -1, release_hook); if (instance != NULL) sq_settop(vm, oldtop); return true; }