You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.4 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Simon Richter
  5. * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include "pin_number.h"
  25. namespace {
  26. wxString GetNextComponent( const wxString& str, wxString::size_type& cursor )
  27. {
  28. if( str.size() <= cursor )
  29. return wxEmptyString;
  30. wxString::size_type begin = cursor;
  31. wxUniChar c = str[cursor];
  32. if( isdigit( c ) || c == '+' || c == '-' )
  33. {
  34. // number, possibly with sign
  35. while( ++cursor < str.size() )
  36. {
  37. c = str[cursor];
  38. if( isdigit( c ) || c == 'v' || c == 'V' )
  39. continue;
  40. else
  41. break;
  42. }
  43. }
  44. else
  45. {
  46. while( ++cursor < str.size() )
  47. {
  48. c = str[cursor];
  49. if( isdigit( c ) )
  50. break;
  51. else
  52. continue;
  53. }
  54. }
  55. return str.substr( begin, cursor - begin );
  56. }
  57. }
  58. wxString PinNumbers::GetSummary() const
  59. {
  60. wxString ret;
  61. const_iterator i = begin();
  62. if( i == end() )
  63. return ret;
  64. const_iterator begin_of_range = i;
  65. const_iterator last;
  66. for( ;; )
  67. {
  68. last = i;
  69. ++i;
  70. int rc = ( i != end() ) ? Compare( *last, *i ) : -2;
  71. assert( rc == -1 || rc == -2 );
  72. if( rc == -1 )
  73. // adjacent elements
  74. continue;
  75. ret += *begin_of_range;
  76. if( begin_of_range != last )
  77. {
  78. ret += '-';
  79. ret += *last;
  80. }
  81. if( i == end() )
  82. break;
  83. begin_of_range = i;
  84. ret += ',';
  85. }
  86. return ret;
  87. }
  88. int PinNumbers::Compare( const PinNumber& lhs, const PinNumber& rhs )
  89. {
  90. wxString::size_type cursor1 = 0;
  91. wxString::size_type cursor2 = 0;
  92. wxString comp1, comp2;
  93. for( ; ; )
  94. {
  95. comp1 = GetNextComponent( lhs, cursor1 );
  96. comp2 = GetNextComponent( rhs, cursor2 );
  97. if( comp1.empty() && comp2.empty() )
  98. return 0;
  99. if( comp1.empty() )
  100. return -2;
  101. if( comp2.empty() )
  102. return 2;
  103. wxUniChar c1 = comp1[0];
  104. wxUniChar c2 = comp2[0];
  105. if( isdigit( c1 ) || c1 == '-' || c1 == '+' )
  106. {
  107. if( isdigit( c2 ) || c2 == '-' || c2 == '+' )
  108. {
  109. // numeric comparison
  110. wxString::size_type v1 = comp1.find_first_of( "vV" );
  111. if( v1 != wxString::npos )
  112. comp1[v1] = '.';
  113. wxString::size_type v2 = comp2.find_first_of( "vV" );
  114. if( v2 != wxString::npos )
  115. comp2[v2] = '.';
  116. double val1, val2;
  117. comp1.ToDouble( &val1 );
  118. comp2.ToDouble( &val2 );
  119. if( val1 < val2 )
  120. {
  121. if( val1 == val2 - 1 )
  122. return -1;
  123. else
  124. return -2;
  125. }
  126. if( val1 > val2 )
  127. {
  128. if( val1 == val2 + 1 )
  129. return 1;
  130. else
  131. return 2;
  132. }
  133. }
  134. else
  135. return -2;
  136. }
  137. else
  138. {
  139. if( isdigit( c2 ) || c2 == '-' || c2 == '+' )
  140. return 2;
  141. int res = comp1.Cmp( comp2 );
  142. if( res != 0 )
  143. return res;
  144. }
  145. }
  146. }