/** * Create a new GRFError that is a deep copy of an existing error message. * @param error The GRFError object to make a copy of. */ GRFError::GRFError(const GRFError &error) : ZeroedMemoryAllocator(), custom_message(error.custom_message), data(error.data), message(error.message), severity(error.severity) { if (error.custom_message != NULL) this->custom_message = stredup(error.custom_message); if (error.data != NULL) this->data = stredup(error.data); memcpy(this->param_value, error.param_value, sizeof(this->param_value)); }
void DetermineBasePaths(const char *exe) { char tmp[MAX_PATH]; TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_PERSONAL_DIR] = stredup(tmp); } else { _searchpaths[SP_PERSONAL_DIR] = NULL; } if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_SHARED_DIR] = stredup(tmp); } else { _searchpaths[SP_SHARED_DIR] = NULL; } #else _searchpaths[SP_PERSONAL_DIR] = NULL; _searchpaths[SP_SHARED_DIR] = NULL; #endif /* Get the path to working directory of OpenTTD */ getcwd(tmp, lengthof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_WORKING_DIR] = stredup(tmp); if (!GetModuleFileName(NULL, path, lengthof(path))) { DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { TCHAR exec_dir[MAX_PATH]; _tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path)); if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) { DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); *(s + 1) = '\0'; _searchpaths[SP_BINARY_DIR] = stredup(tmp); } } _searchpaths[SP_INSTALLATION_DIR] = NULL; _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; }
/** * Construct the blitter, and register it. * @param name The name of the blitter. * @param description A longer description for the blitter. * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them. * @pre name != nullptr. * @pre description != nullptr. * @pre There is no blitter registered with this name. */ BlitterFactory(const char *name, const char *description, bool usable = true) : name(stredup(name)), description(stredup(description)) { if (usable) { /* * Only add when the blitter is usable. Do not bail out or * do more special things since the blitters are always * instantiated upon start anyhow and freed upon shutdown. */ std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this)); assert(P.second); } else { DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name); } }
/** * 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(); }
OskWindow(WindowDesc *desc, Window *parent, int button) : Window(desc) { this->parent = parent; assert(parent != NULL); NWidgetCore *par_wid = parent->GetWidget<NWidgetCore>(button); assert(par_wid != NULL); assert(parent->querystrings.Contains(button)); this->qs = parent->querystrings.Find(button)->second; this->caption = (par_wid->widget_data != STR_NULL) ? par_wid->widget_data : this->qs->caption; this->text_btn = button; this->text = &this->qs->text; this->querystrings[WID_OSK_TEXT] = this->qs; /* make a copy in case we need to reset later */ this->orig_str_buf = stredup(this->qs->text.buf); this->InitNested(0); this->SetFocusedWidget(WID_OSK_TEXT); /* Not needed by default. */ this->DisableWidget(WID_OSK_SPECIAL); this->UpdateOskState(); }
/** * Construct a new in-memory group of an Ini file. * @param parent the file we belong to * @param name the name of the group * @param last the last element of the name of the group */ IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : next(nullptr), type(IGT_VARIABLES), item(nullptr), comment(nullptr) { this->name = stredup(name, last); str_validate(this->name, this->name + strlen(this->name)); this->last_item = &this->item; *parent->last_group = this; parent->last_group = &this->next; if (parent->list_group_names != nullptr) { for (uint i = 0; parent->list_group_names[i] != nullptr; i++) { if (strcmp(this->name, parent->list_group_names[i]) == 0) { this->type = IGT_LIST; return; } } } if (parent->seq_group_names != nullptr) { for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) { if (strcmp(this->name, parent->seq_group_names[i]) == 0) { this->type = IGT_SEQUENCE; return; } } } }
/** * Marks subsidy as awarded, creates news and AI event * @param company awarded company */ void Subsidy::AwardTo(CompanyID company) { assert(!this->IsAwarded()); this->awarded = company; this->remaining = SUBSIDY_CONTRACT_MONTHS; char company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH]; SetDParam(0, company); GetString(company_name, STR_COMPANY_NAME, lastof(company_name)); char *cn = stredup(company_name); /* Add a news item */ Pair reftype = SetupSubsidyDecodeParam(this, false); InjectDParam(1); SetDParamStr(0, cn); AddNewsItem( STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, NT_SUBSIDIES, NF_NORMAL, (NewsReferenceType)reftype.a, this->src, (NewsReferenceType)reftype.b, this->dst, cn ); AI::BroadcastNewEvent(new ScriptEventSubsidyAwarded(this->index)); Game::NewEvent(new ScriptEventSubsidyAwarded(this->index)); InvalidateWindowData(WC_SUBSIDIES_LIST, 0); }
/** * Rename a sign. If the new name of the sign is empty, we assume * the user wanted to delete it. So delete it. Ownership of signs * has no meaning/effect whatsoever except for eyecandy * @param tile unused * @param flags type of operation * @param p1 index of the sign to be renamed/removed * @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 CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Sign *si = Sign::GetIfValid(p1); if (si == NULL) return CMD_ERROR; if (si->owner == OWNER_DEITY && _current_company != OWNER_DEITY && _game_mode != GM_EDITOR) return CMD_ERROR; /* Rename the signs when empty, otherwise remove it */ if (!StrEmpty(text)) { if (Utf8StringLength(text) >= MAX_LENGTH_SIGN_NAME_CHARS) return CMD_ERROR; if (flags & DC_EXEC) { /* Delete the old name */ free(si->name); /* Assign the new one */ si->name = stredup(text); if (_game_mode != GM_EDITOR) si->owner = _current_company; si->UpdateVirtCoord(); InvalidateWindowData(WC_SIGN_LIST, 0, 1); } } else { // Delete sign if (flags & DC_EXEC) { si->sign.MarkDirty(); delete si; InvalidateWindowData(WC_SIGN_LIST, 0, 0); } } return CommandCost(); }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int argc; char *argv[64]; // max 64 command line arguments CrashLog::InitialiseCrashLog(); #if defined(UNICODE) /* Check if a win9x user started the win32 version */ if (HasBit(GetVersion(), 31)) usererror("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again."); #endif /* Convert the command line to UTF-8. We need a dedicated buffer * for this because argv[] points into this buffer and this needs to * be available between subsequent calls to FS2OTTD(). */ char *cmdline = stredup(FS2OTTD(GetCommandLine())); #if defined(_DEBUG) CreateConsole(); #endif _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox /* setup random seed to something quite random */ SetRandomSeed(GetTickCount()); argc = ParseCommandLine(cmdline, argv, lengthof(argv)); /* Make sure our arguments contain only valid UTF-8 characters. */ for (int i = 0; i < argc; i++) ValidateString(argv[i]); openttd_main(argc, argv); free(cmdline); return 0; }
/** * Change the configured music set and reset playback * @param index Index of music set to switch to */ void ChangeMusicSet(int index) { if (BaseMusic::GetIndexOfUsedSet() == index) return; /* Resume playback after switching? * Always if music is already playing, and also if the user is switching * away from an empty music set. * If the user switches away from an empty set, assume it's because they * want to hear music now. */ bool shouldplay = _song_is_active || (BaseMusic::GetUsedSet()->num_available == 0); StopMusic(); const char *name = BaseMusic::GetSet(index)->name; BaseMusic::SetSet(name); free(BaseMusic::ini_set); BaseMusic::ini_set = stredup(name); InitializeMusic(); ResetPlaylist(); _settings_client.music.playing = shouldplay; InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0); InvalidateWindowData(WC_MUSIC_WINDOW, 0); InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_GAME_OPTIONS, 0, true); }
/** * Copy data from temporary engine array into the real engine pool. */ void CopyTempEngineData() { Engine *e; FOR_ALL_ENGINES(e) { if (e->index >= _temp_engine.size()) break; const Engine *se = GetTempDataEngine(e->index); e->intro_date = se->intro_date; e->age = se->age; e->reliability = se->reliability; e->reliability_spd_dec = se->reliability_spd_dec; e->reliability_start = se->reliability_start; e->reliability_max = se->reliability_max; e->reliability_final = se->reliability_final; e->duration_phase_1 = se->duration_phase_1; e->duration_phase_2 = se->duration_phase_2; e->duration_phase_3 = se->duration_phase_3; e->flags = se->flags; e->preview_asked = se->preview_asked; e->preview_company = se->preview_company; e->preview_wait = se->preview_wait; e->company_avail = se->company_avail; e->company_hidden = se->company_hidden; if (se->name != NULL) e->name = stredup(se->name); } /* Get rid of temporary data */ _temp_engine.clear(); }
/** * Create a new GRFConfig that is a deep copy of an existing config. * @param config The GRFConfig object to make a copy of. */ GRFConfig::GRFConfig(const GRFConfig &config) : ZeroedMemoryAllocator(), ident(config.ident), name(config.name), info(config.info), url(config.url), version(config.version), min_loadable_version(config.min_loadable_version), flags(config.flags & ~(1 << GCF_COPY)), status(config.status), grf_bugs(config.grf_bugs), num_params(config.num_params), num_valid_params(config.num_valid_params), palette(config.palette), has_param_defaults(config.has_param_defaults) { MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT<uint32>(this->param, config.param, lengthof(this->param)); if (config.filename != NULL) this->filename = stredup(config.filename); this->name->AddRef(); this->info->AddRef(); this->url->AddRef(); if (config.error != NULL) this->error = new GRFError(*config.error); for (uint i = 0; i < config.param_info.Length(); i++) { if (config.param_info[i] == NULL) { *this->param_info.Append() = NULL; } else { *this->param_info.Append() = new GRFParameterInfo(*config.param_info[i]); } } }
/** * Rename a waypoint. * @param tile unused * @param flags type of operation * @param p1 id of waypoint * @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 CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Waypoint *wp = Waypoint::GetIfValid(p1); if (wp == NULL) return CMD_ERROR; if (wp->owner != OWNER_NONE) { CommandCost ret = CheckOwnership(wp->owner); if (ret.Failed()) return ret; } bool reset = StrEmpty(text); if (!reset) { if (Utf8StringLength(text) >= MAX_LENGTH_STATION_NAME_CHARS) return CMD_ERROR; if (!IsUniqueWaypointName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE); } if (flags & DC_EXEC) { free(wp->name); wp->name = reset ? NULL : stredup(text); wp->UpdateVirtCoord(); } return CommandCost(); }
/** * Place a sign at the given coordinates. Ownership of sign has * no effect whatsoever except for the colour the sign gets for easy recognition, * but everybody is able to rename/remove it. * @param tile tile to place sign at * @param flags type of operation * @param p1 unused * @param p2 unused * @param text unused * @return the cost of this operation or an error */ CommandCost CmdPlaceSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { /* Try to locate a new sign */ if (!Sign::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_SIGNS); /* Check sign text length if any */ if (!StrEmpty(text) && Utf8StringLength(text) >= MAX_LENGTH_SIGN_NAME_CHARS) return CMD_ERROR; /* When we execute, really make the sign */ if (flags & DC_EXEC) { Sign *si = new Sign(_game_mode == GM_EDITOR ? OWNER_DEITY : _current_company); int x = TileX(tile) * TILE_SIZE; int y = TileY(tile) * TILE_SIZE; si->x = x; si->y = y; si->z = GetSlopePixelZ(x, y); if (!StrEmpty(text)) { si->name = stredup(text); } si->UpdateVirtCoord(); InvalidateWindowData(WC_SIGN_LIST, 0, 0); _new_sign_id = si->index; } return CommandCost(); }
/** * Register a an alias for an already existing command in the console * @param name name of the alias that will be used * @param cmd name of the command that 'name' will be alias of */ void IConsoleAliasRegister(const char *name, const char *cmd) { if (IConsoleAliasGet(name) != NULL) { IConsoleError("an alias with this name already exists; insertion aborted"); return; } char *new_alias = RemoveUnderscores(stredup(name)); char *cmd_aliased = stredup(cmd); IConsoleAlias *item_new = MallocT<IConsoleAlias>(1); item_new->next = NULL; item_new->cmdline = cmd_aliased; item_new->name = new_alias; IConsoleAddSorted(&_iconsole_aliases, item_new); }
/** * Construct a new in-memory item of an Ini file. * @param parent the group we belong to * @param name the name of the item * @param last the last element of the name of the item */ IniItem::IniItem(IniGroup *parent, const char *name, const char *last) : next(nullptr), value(nullptr), comment(nullptr) { this->name = stredup(name, last); str_validate(this->name, this->name + strlen(this->name)); *parent->last_item = this; parent->last_item = &this->next; }
bool Squirrel::CallStringMethodStrdup(HSQOBJECT instance, const char *method_name, const char **res, int suspend) { HSQOBJECT ret; if (!this->CallMethod(instance, method_name, &ret, suspend)) return false; if (ret._type != OT_STRING) return false; *res = stredup(ObjectToString(&ret)); ValidateString(*res); return true; }
void AIScannerInfo::Initialize() { ScriptScanner::Initialize("AIScanner"); /* Create the dummy AI */ free(this->main_script); this->main_script = stredup("%_dummy"); extern void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir); Script_CreateDummyInfo(this->engine->GetVM(), "AI", "ai"); }
/** * Updates the original text of the OSK so when the 'parent' changes the * original and you press on cancel you won't get the 'old' original text * but the updated one. * @param parent window that just updated its orignal text * @param button widget number of parent's textbox to update */ void UpdateOSKOriginalText(const Window *parent, int button) { OskWindow *osk = dynamic_cast<OskWindow *>(FindWindowById(WC_OSK, 0)); if (osk == NULL || osk->parent != parent || osk->text_btn != button) return; free(osk->orig_str_buf); osk->orig_str_buf = stredup(osk->qs->text.buf); osk->SetDirty(); }
/** * Copy and convert old custom names to UTF-8. * They were all stored in a 512 by 32 (200 by 24 for TTO) long string array * and are now stored with stations, waypoints and other places with names. * @param id the StringID of the custom name to clone. * @return the clones custom name. */ char *CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return NULL; if (IsSavegameVersionBefore(SLV_37)) { /* Allow for expansion when converted to UTF-8. */ char tmp[LEN_OLD_STRINGS * MAX_CHAR_LENGTH]; uint offs = _savegame_type == SGT_TTO ? LEN_OLD_STRINGS_TTO * GB(id, 0, 8) : LEN_OLD_STRINGS * GB(id, 0, 9); const char *strfrom = &_old_name_array[offs]; char *strto = tmp; for (; *strfrom != '\0'; strfrom++) { WChar c = (byte)*strfrom; /* Map from non-ISO8859-15 characters to UTF-8. */ switch (c) { case 0xA4: c = 0x20AC; break; // Euro case 0xA6: c = 0x0160; break; // S with caron case 0xA8: c = 0x0161; break; // s with caron case 0xB4: c = 0x017D; break; // Z with caron case 0xB8: c = 0x017E; break; // z with caron case 0xBC: c = 0x0152; break; // OE ligature case 0xBD: c = 0x0153; break; // oe ligature case 0xBE: c = 0x0178; break; // Y with diaresis default: break; } /* Check character will fit into our buffer. */ if (strto + Utf8CharLen(c) > lastof(tmp)) break; strto += Utf8Encode(strto, c); } /* Terminate the new string and copy it back to the name array */ *strto = '\0'; return stredup(tmp); } else { /* Name will already be in UTF-8. */ return stredup(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]); } }
/** * Copy the given data into our instance. * @param data The data to copy. */ ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) { *this = data; for (size_t i = 0; i < lengthof(this->strings); i++) { if (this->strings[i] != NULL) { this->strings[i] = stredup(this->strings[i]); this->decode_params[i] = (size_t)this->strings[i]; } } }
/** * Register a new command to be used in the console * @param name name of the command that will be used * @param proc function that will be called upon execution of command */ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook) { IConsoleCmd *item_new = MallocT<IConsoleCmd>(1); item_new->name = RemoveUnderscores(stredup(name)); item_new->next = NULL; item_new->proc = proc; item_new->hook = hook; IConsoleAddSorted(&_iconsole_cmds, item_new); }
/** * Create a new GRFConfig. * @param filename Set the filename of this GRFConfig to filename. The argument * is copied so the original string isn't needed after the constructor. */ GRFConfig::GRFConfig(const char *filename) : name(new GRFTextWrapper()), info(new GRFTextWrapper()), url(new GRFTextWrapper()), num_valid_params(lengthof(param)) { if (filename != NULL) this->filename = stredup(filename); this->name->AddRef(); this->info->AddRef(); this->url->AddRef(); }
/** * Change to named music set, and reset playback. * @param set_name Name of music set to select */ void MusicSystem::ChangeMusicSet(const char *set_name) { BaseMusic::SetSet(set_name); free(BaseMusic::ini_set); BaseMusic::ini_set = stredup(set_name); this->BuildPlaylists(); this->ChangePlaylist(this->selected_playlist); InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_GAME_OPTIONS, 0, true); }
/** * Construct the blitter, and register it. * @param name The name of the blitter. * @param description A longer description for the blitter. * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them. * @pre name != NULL. * @pre description != NULL. * @pre There is no blitter registered with this name. */ BlitterFactory(const char *name, const char *description, bool usable = true) : name(stredup(name)), description(stredup(description)) { //stredup,相当于malloc©str /*strdup()函数是c语言中常用的一种字符串拷贝库函数,一般和free()函数成对出现。 */ if (usable) { /* * Only add when the blitter is usable. Do not bail out or * do more special things since the blitters are always * instantiated upon start anyhow and freed upon shutdown. */ /*std::map的insert函数,返回结果有两个,iterator和bool,其中iterator应该是当前插入的对象的访问迭代器. bool,表示这一次插入是否成功. */ std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this)); assert(P.second); } else { DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name); } }
/** * Read all the raw language strings from the given file. * @param file The file to read from. * @return The raw strings, or NULL upon error. */ LanguageStrings *ReadRawLanguageStrings(const char *file) { LanguageStrings *ret = NULL; FILE *fh = NULL; try { size_t to_read; fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read); if (fh == NULL) { return NULL; } const char *langname = strrchr(file, PATHSEPCHAR); if (langname == NULL) { langname = file; } else { langname++; } /* Check for invalid empty filename */ if (*langname == '.' || *langname == 0) { fclose(fh); return NULL; } ret = new LanguageStrings(langname, strchr(langname, '.')); char buffer[2048]; while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != NULL) { size_t len = strlen(buffer); /* Remove trailing spaces/newlines from the string. */ size_t i = len; while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--; buffer[i] = '\0'; *ret->lines.Append() = stredup(buffer, buffer + to_read - 1); if (len > to_read) { to_read = 0; } else { to_read -= len; } } fclose(fh); return ret; } catch (...) { if (fh != NULL) fclose(fh); delete ret; return NULL; } }
/** * Create a new custom news item. * @param tile unused * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - NewsType of the message. * - p1 = (bit 8 - 15) - NewsReferenceType of first reference. * - p1 = (bit 16 - 23) - Company this news message is for. * @param p2 First reference of the news message. * @param text The text of the news message. * @return the cost of this operation or an error */ CommandCost CmdCustomNewsItem(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; NewsType type = (NewsType)GB(p1, 0, 8); NewsReferenceType reftype1 = (NewsReferenceType)GB(p1, 8, 8); CompanyID company = (CompanyID)GB(p1, 16, 8); if (company != INVALID_OWNER && !Company::IsValidID(company)) return CMD_ERROR; if (type >= NT_END) return CMD_ERROR; if (StrEmpty(text)) return CMD_ERROR; switch (reftype1) { case NR_NONE: break; case NR_TILE: if (!IsValidTile(p2)) return CMD_ERROR; break; case NR_VEHICLE: if (!Vehicle::IsValidID(p2)) return CMD_ERROR; break; case NR_STATION: if (!Station::IsValidID(p2)) return CMD_ERROR; break; case NR_INDUSTRY: if (!Industry::IsValidID(p2)) return CMD_ERROR; break; case NR_TOWN: if (!Town::IsValidID(p2)) return CMD_ERROR; break; case NR_ENGINE: if (!Engine::IsValidID(p2)) return CMD_ERROR; break; default: return CMD_ERROR; } if (company != INVALID_OWNER && company != _local_company) return CommandCost(); if (flags & DC_EXEC) { char *news = stredup(text); SetDParamStr(0, news); AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, p2, NR_NONE, UINT32_MAX, news); } return CommandCost(); }
const char *MusicDriver_ExtMidi::Start(const char * const * parm) { if (strcmp(VideoDriver::GetInstance()->GetName(), "allegro") == 0 || strcmp(SoundDriver::GetInstance()->GetName(), "allegro") == 0) { return "the extmidi driver does not work when Allegro is loaded."; } const char *command = GetDriverParam(parm, "cmd"); if (StrEmpty(command)) command = EXTERNAL_PLAYER; this->command = stredup(command); this->song[0] = '\0'; this->pid = -1; return NULL; }
/** * Get the group with the given name. If it doesn't exist * and \a create_new is \c true create a new group. * @param name name of the group to find. * @param len the maximum length of said name (\c 0 means length of the string). * @param create_new Allow creation of group if it does not exist. * @return The requested group if it exists or was created, else \c nullptr. */ IniGroup *IniLoadFile::GetGroup(const char *name, size_t len, bool create_new) { if (len == 0) len = strlen(name); /* does it exist already? */ for (IniGroup *group = this->group; group != nullptr; group = group->next) { if (!strncmp(group->name, name, len) && group->name[len] == 0) { return group; } } if (!create_new) return nullptr; /* otherwise make a new one */ IniGroup *group = new IniGroup(this, name, name + len - 1); group->comment = stredup("\n"); return group; }
/** * 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 = stredup(buf); break; } } /* All done. If we didn't find a name, it'll just use its default. */ }