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.

211 lines
5.0 KiB

3 years ago
3 years ago
3 years ago
  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 The KiCad Developers, see AUTHORS.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_numbers.h"
  25. #include <wx/crt.h>
  26. #include <wx/translation.h>
  27. wxString PIN_NUMBERS::getNextSymbol( const wxString& str, wxString::size_type& cursor )
  28. {
  29. if( str.size() <= cursor )
  30. return wxEmptyString;
  31. wxString::size_type begin = cursor;
  32. wxChar c = str[cursor];
  33. // Need to check that there is a digit in the string before we parse it as a numeric
  34. if( ( wxIsdigit( c ) || ( ( c == '+' || c == '-' ) && ( cursor < str.size() - 1 )
  35. && wxIsdigit( str[cursor + 1] ) ) ) )
  36. {
  37. // number, possibly with sign
  38. while( ++cursor < str.size() )
  39. {
  40. c = str[cursor];
  41. if( wxIsdigit( c ) || c == 'v' || c == 'V' || c == '.' )
  42. continue;
  43. else
  44. break;
  45. }
  46. }
  47. else
  48. {
  49. while( ++cursor < str.size() )
  50. {
  51. c = str[cursor];
  52. if( wxIsdigit( c ) )
  53. break;
  54. else
  55. continue;
  56. }
  57. }
  58. return str.substr( begin, cursor - begin );
  59. }
  60. wxString PIN_NUMBERS::GetSummary() const
  61. {
  62. wxString ret;
  63. const_iterator i = begin();
  64. if( i == end() )
  65. return ret;
  66. const_iterator begin_of_range = i;
  67. const_iterator last;
  68. for( ;; )
  69. {
  70. last = i;
  71. ++i;
  72. int rc = ( i != end() ) ? Compare( *last, *i ) : -2;
  73. assert( rc == -1 || rc == -2 );
  74. if( rc == -1 )
  75. // adjacent elements
  76. continue;
  77. ret += *begin_of_range;
  78. if( begin_of_range != last )
  79. {
  80. ret += '-';
  81. ret += *last;
  82. }
  83. if( i == end() )
  84. break;
  85. begin_of_range = i;
  86. ret += ',';
  87. }
  88. return ret;
  89. }
  90. wxString PIN_NUMBERS::GetDuplicates() const
  91. {
  92. wxString ret;
  93. for( const wxString& pinNumber : duplicate_pins )
  94. {
  95. ret += pinNumber;
  96. ret += ',';
  97. }
  98. // Remove the trailing comma
  99. ret.RemoveLast();
  100. if( ret.IsEmpty() )
  101. ret = _( "none" );
  102. return ret;
  103. }
  104. int PIN_NUMBERS::Compare( const wxString& lhs, const wxString& rhs )
  105. {
  106. wxString::size_type cursor1 = 0;
  107. wxString::size_type cursor2 = 0;
  108. wxString symbol1, symbol2;
  109. for( ; ; )
  110. {
  111. symbol1 = getNextSymbol( lhs, cursor1 );
  112. symbol2 = getNextSymbol( rhs, cursor2 );
  113. if( symbol1.empty() && symbol2.empty() )
  114. return 0;
  115. if( symbol1.empty() )
  116. return -2;
  117. if( symbol2.empty() )
  118. return 2;
  119. bool sym1_isnumeric = symbol1.find_first_of( wxS( "0123456789" ) ) != wxString::npos;
  120. bool sym2_isnumeric = symbol2.find_first_of( wxS( "0123456789" ) ) != wxString::npos;
  121. if( sym1_isnumeric )
  122. {
  123. if( sym2_isnumeric )
  124. {
  125. // numeric comparison
  126. wxString::size_type v1 = symbol1.find_first_of( wxS( "vV" ) );
  127. if( v1 != wxString::npos )
  128. symbol1[v1] = '.';
  129. wxString::size_type v2 = symbol2.find_first_of( wxS( "vV" ) );
  130. if( v2 != wxString::npos )
  131. symbol2[v2] = '.';
  132. double val1, val2;
  133. symbol1.ToCDouble( &val1 );
  134. symbol2.ToCDouble( &val2 );
  135. if( val1 < val2 )
  136. {
  137. if( val1 == val2 - 1 )
  138. return -1;
  139. else
  140. return -2;
  141. }
  142. if( val1 > val2 )
  143. {
  144. if( val1 == val2 + 1 )
  145. return 1;
  146. else
  147. return 2;
  148. }
  149. }
  150. else
  151. {
  152. return -2;
  153. }
  154. }
  155. else
  156. {
  157. if( sym2_isnumeric )
  158. return 2;
  159. int res = symbol1.Cmp( symbol2 );
  160. if( res != 0 )
  161. return res;
  162. }
  163. }
  164. }