Numerical sort patch from mantis #2654
authorSampo Savolainen <v2@iki.fi>
Wed, 3 Jun 2009 13:11:44 +0000 (13:11 +0000)
committerSampo Savolainen <v2@iki.fi>
Wed, 3 Jun 2009 13:11:44 +0000 (13:11 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5120 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/io.cc

index 2e2482d8f0ebd5e26b27ce5b726dc985b77ccf44..7d9734d6d6c5ef2e01581d03a6fd02ce133d9615 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <cmath>
 
+#include <cstdlib>
+
 /*
   A bug in OS X's cmath that causes isnan() and isinf() to be 
   "undeclared". the following works around that
@@ -93,9 +95,37 @@ static double direct_gain_to_control (gain_t gain) {
        return pow((6.0*log(gain)/log(2.0)+192.0)/198.0, 8.0);
 }
 
-static bool sort_ports_by_name (Port* a, Port* b)
-{
-       return a->name() < b->name();
+static bool sort_ports_by_name (Port* a, Port* b) {
+
+       unsigned int    last_digit_position_a = a->name().size();
+       std::string::const_reverse_iterator     r_iterator = a->name().rbegin();
+
+       while (r_iterator!=a->name().rend() and Glib::Unicode::isdigit(*r_iterator)) {
+               r_iterator++; last_digit_position_a--;
+       }
+
+       unsigned int    last_digit_position_b = b->name().size();
+       r_iterator = b->name().rbegin();
+
+       while (r_iterator!=b->name().rend() and Glib::Unicode::isdigit(*r_iterator)) {
+               r_iterator++; last_digit_position_b--;
+       }
+
+       // if some of the names don't have a number as posfix, compare as strings
+       if (last_digit_position_a == a->name().size() or last_digit_position_b == b->name().size()) {
+               return a->name() < b->name();
+       }
+
+       const std::string       prefix_a = a->name().substr(0, last_digit_position_a - 1);
+       const unsigned int      posfix_a = std::atoi(a->name().substr(last_digit_position_a, a->name().size() - last_digit_position_a).c_str());
+       const std::string       prefix_b = b->name().substr(0, last_digit_position_b - 1);
+       const unsigned int      posfix_b = std::atoi(b->name().substr(last_digit_position_b, b->name().size() - last_digit_position_b).c_str());
+
+       if (prefix_a != prefix_b) {
+               return a->name() < b->name();
+       } else {
+               return posfix_a < posfix_b;
+       }
 }