* Clone the custom name of a vehicle, adding or incrementing a number. * @param src Source vehicle, with a custom name. * @param dst Destination vehicle. */
| 773 | * @param dst Destination vehicle. |
| 774 | */ |
| 775 | static void CloneVehicleName(const Vehicle *src, Vehicle *dst) |
| 776 | { |
| 777 | std::string buf; |
| 778 | |
| 779 | /* Find the position of the first digit in the last group of digits. */ |
| 780 | size_t number_position; |
| 781 | for (number_position = src->name.length(); number_position > 0; number_position--) { |
| 782 | /* The design of UTF-8 lets this work simply without having to check |
| 783 | * for UTF-8 sequences. */ |
| 784 | if (src->name[number_position - 1] < '0' || src->name[number_position - 1] > '9') break; |
| 785 | } |
| 786 | |
| 787 | /* Format buffer and determine starting number. */ |
| 788 | long num; |
| 789 | uint8_t padding = 0; |
| 790 | if (number_position == src->name.length()) { |
| 791 | /* No digit at the end, so start at number 2. */ |
| 792 | buf = src->name; |
| 793 | buf += " "; |
| 794 | number_position = buf.length(); |
| 795 | num = 2; |
| 796 | } else { |
| 797 | /* Found digits, parse them and start at the next number. */ |
| 798 | buf = src->name.substr(0, number_position); |
| 799 | |
| 800 | auto num_str = std::string_view(src->name).substr(number_position); |
| 801 | padding = (uint8_t)num_str.length(); |
| 802 | |
| 803 | [[maybe_unused]] auto err = std::from_chars(num_str.data(), num_str.data() + num_str.size(), num, 10).ec; |
| 804 | assert(err == std::errc()); |
| 805 | num++; |
| 806 | } |
| 807 | |
| 808 | /* Check if this name is already taken. */ |
| 809 | for (int max_iterations = 1000; max_iterations > 0; max_iterations--, num++) { |
| 810 | std::string new_name = fmt::format("{}{:0{}}", buf, num, padding); |
| 811 | |
| 812 | /* Check the name is unique. */ |
| 813 | if (IsUniqueVehicleName(new_name)) { |
| 814 | dst->name = std::move(new_name); |
| 815 | break; |
| 816 | } |
| 817 | } |
| 818 | |
| 819 | /* All done. If we didn't find a name, it'll just use its default. */ |
| 820 | } |
| 821 | |
| 822 | /** |
| 823 | * Clone a vehicle. If it is a train, it will clone all the cars too |
no test coverage detected