Index: src/build_vehicle_gui.cpp =================================================================== --- src/build_vehicle_gui.cpp (revision 21131) +++ src/build_vehicle_gui.cpp (working copy) @@ -28,6 +28,7 @@ #include "widgets/dropdown_func.h" #include "engine_gui.h" #include "cargotype.h" +#include "strnatcmp.h" #include "table/strings.h" @@ -156,7 +157,7 @@ GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); } - int r = strcmp(last_name[0], last_name[1]); // sort by name + int r = strnatcmp(last_name[0], last_name[1]); // sort by name using natural sorting /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); Index: src/cargotype.cpp =================================================================== --- src/cargotype.cpp (revision 21131) +++ src/cargotype.cpp (working copy) @@ -15,6 +15,7 @@ #include "newgrf_cargo.h" #include "strings_func.h" #include "core/sort_func.hpp" +#include "strnatcmp.h" #include "table/sprites.h" #include "table/strings.h" @@ -134,7 +135,7 @@ GetString(a_name, (*a)->name, lastof(a_name)); GetString(b_name, (*b)->name, lastof(b_name)); - int res = strcmp(a_name, b_name); + int res = strnatcmp(a_name, b_name); // sort by name using natural sorting /* If the names are equal, sort by cargo bitnum. */ return (res != 0) ? res : ((*a)->bitnum - (*b)->bitnum); Index: src/group_gui.cpp =================================================================== --- src/group_gui.cpp (revision 21131) +++ src/group_gui.cpp (working copy) @@ -26,6 +26,7 @@ #include "vehicle_gui_base.h" #include "core/geometry_func.hpp" #include "company_base.h" +#include "strnatcmp.h" #include "table/strings.h" #include "table/sprites.h" @@ -160,7 +161,7 @@ GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1])); } - int r = strcmp(last_name[0], last_name[1]); // sort by name + int r = strnatcmp(last_name[0], last_name[1]); // sort by name using natural sorting if (r == 0) return (*a)->index - (*b)->index; return r; } Index: src/industry_gui.cpp =================================================================== --- src/industry_gui.cpp (revision 21131) +++ src/industry_gui.cpp (working copy) @@ -36,6 +36,7 @@ #include "core/backup_type.hpp" #include "genworld.h" #include "smallmap_gui.h" +#include "strnatcmp.h" #include "table/strings.h" #include "table/sprites.h" @@ -120,7 +121,7 @@ SetDParam(0, indsp2->name); GetString(industry_name[1], STR_JUST_STRING, lastof(industry_name[1])); - int r = strcmp(industry_name[0], industry_name[1]); + int r = strnatcmp(industry_name[0], industry_name[1]); // sort by name using natural sorting /* If the names are equal, sort by industry type. */ return (r != 0) ? r : (*a - *b); @@ -1142,7 +1143,7 @@ GetString(buf_cache, STR_TOWN_NAME, lastof(buf_cache)); } - return strcmp(buf, buf_cache); + return strnatcmp(buf, buf_cache); // sort by name using natural sorting } /** Sort industries by type and name */ Index: src/station_gui.cpp =================================================================== --- src/station_gui.cpp (revision 21131) +++ src/station_gui.cpp (working copy) @@ -29,6 +29,7 @@ #include "sortlist_type.h" #include "core/geometry_func.hpp" #include "vehiclelist.h" +#include "strnatcmp.h" #include "table/strings.h" @@ -275,7 +276,7 @@ GetString(buf_cache, STR_STATION_NAME, lastof(buf_cache)); } - return strcmp(buf, buf_cache); + return strnatcmp(buf, buf_cache); // sort by name using natural sorting } /** Sort stations by their type */ Index: src/strnatcmp.cpp =================================================================== --- src/strnatcmp.cpp (revision 0) +++ src/strnatcmp.cpp (revision 0) @@ -0,0 +1,67 @@ +/* Macro to increase readability */ +#define NATSORT_BETWEEN(a, b, c) (a >= b && a <= c) + +/** + * Compares two strings using case insensitive natural sort + * + * @param s1 string1 + * @param s2 string2 + * @return -1, 0, 1, same as strcmp() + */ +int strnatcmp(const char *s1, const char *s2) +{ + unsigned int i = 0, j, k, s1_int, s2_int, tmp1, tmp2; + + while (s1[i] != 0 && s2[i] != 0) + { + /** + * If we find a digit we have to read the whole number + * (the order of '-' in the ASCII table is lower than '0', so negative numbers already solved) + */ + if (NATSORT_BETWEEN(s1[i], 48, 57) || NATSORT_BETWEEN(s2[i], 48, 57)) + { + j = i; + k = i; + s1_int = 0; + s2_int = 0; + + while (NATSORT_BETWEEN(s1[j], 48, 57)) + { + s1_int = s1_int * 10 + s1[j++] - 48; + } + + while (NATSORT_BETWEEN(s2[k], 48, 57)) + { + s2_int = s2_int * 10 + s2[k++] - 48; + } + + if (s1_int != s2_int) + { + return s1_int < s2_int ? -1 : 1; + } + } + + /** Do case insensivie check */ + tmp1 = NATSORT_BETWEEN(s1[i], 65, 90) ? s1[i] + 32 : s1[i]; + tmp2 = NATSORT_BETWEEN(s2[i], 65, 90) ? s2[i] + 32 : s2[i]; + + if (tmp1 != tmp2) + { + return tmp1 < tmp2 ? -1 : 1; + } + + i++; + } + + /** + * If length of s1 and s2 are different, but the common length + * is the same, the shorter will be sooner + */ + if (s1[i] != s2[i]) + { + return s1[i] == 0 ? -1 : 1; + } + + return 0; +} +#undef NATSORT_BETWEEN \ No newline at end of file Index: src/strnatcmp.h =================================================================== --- src/strnatcmp.h (revision 0) +++ src/strnatcmp.h (revision 0) @@ -0,0 +1,8 @@ +/** + * Compares two strings using case insensitive natural sort + * + * @param s1 string1 + * @param s2 string2 + * @return -1, 0, 1, same as strcmp() + */ +int strnatcmp(const char *s1, const char *s2); \ No newline at end of file Index: src/town_gui.cpp =================================================================== --- src/town_gui.cpp (revision 21131) +++ src/town_gui.cpp (working copy) @@ -35,6 +35,7 @@ #include "core/geometry_func.hpp" #include "genworld.h" #include "sprite.h" +#include "strnatcmp.h" #include "table/sprites.h" #include "table/strings.h" @@ -705,7 +706,7 @@ GetString(buf_cache, STR_TOWN_NAME, lastof(buf_cache)); } - return strcmp(buf, buf_cache); + return strnatcmp(buf, buf_cache); // sort by name using natural sorting } /** Sort by population */ Index: src/vehicle_gui.cpp =================================================================== --- src/vehicle_gui.cpp (revision 21131) +++ src/vehicle_gui.cpp (working copy) @@ -40,6 +40,7 @@ #include "engine_func.h" #include "station_base.h" #include "tilehighlight_func.h" +#include "strnatcmp.h" #include "table/strings.h" @@ -752,7 +753,7 @@ GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1])); } - int r = strcmp(last_name[0], last_name[1]); + int r = strnatcmp(last_name[0], last_name[1]); // sort by name using natural sorting return (r != 0) ? r : VehicleNumberSorter(a, b); }