@@ -71,15 +71,7 @@ func compareIgnoreAsciiCase(prev, next []byte) (less, ok bool) {
7171 return
7272}
7373
74- func CompareNumInFilename (prev , next []byte ) (less , ok bool ) {
75- if len (prev ) == 0 && len (next ) == 0 {
76- return false , false
77- } else if len (prev ) == 0 {
78- return true , true
79- } else if len (next ) == 0 {
80- return false , true
81- }
82-
74+ func compareNumString (prev , next []byte ) (less , ok bool ) {
8375 common := findCommonPrefix (prev , next )
8476 if common > 0 {
8577 prev = prev [common :]
@@ -101,7 +93,8 @@ func CompareNumInFilename(prev, next []byte) (less, ok bool) {
10193 return prevDigitsLen < nextDigitsLen , true
10294 }
10395
104- if prevDigitsLen == 0 { // prevDigitsLen and nextDigitsLen is 0
96+ if prevDigitsLen == 0 { // prevDigitsLen == nextDigitsLen == 0
97+ // "." is the beginning of next part, so current part is ended
10598 switch {
10699 case prev [0 ] == '.' && next [0 ] != '.' :
107100 return true , true
@@ -112,10 +105,59 @@ func CompareNumInFilename(prev, next []byte) (less, ok bool) {
112105 }
113106 }
114107
108+ // prevDigitsLen == nextDigitsLen
115109 compareResult := bytes .Compare (prevDigits , nextDigits )
116110 if compareResult != 0 {
117111 return compareResult < 0 , true
118- } else {
119- return CompareNumInFilename (prev [prevDigitsLen :], next [nextDigitsLen :])
120112 }
113+
114+ // prevDigits == nextDigits
115+ prev = prev [prevDigitsLen :]
116+ next = next [nextDigitsLen :]
117+ if len (prev ) == 0 && len (next ) == 0 {
118+ return false , false
119+ } else if len (prev ) == 0 {
120+ return true , true
121+ } else if len (next ) == 0 {
122+ return false , true
123+ }
124+ return compareNumString (prev , next )
125+
126+ }
127+
128+ func isAlnum (b byte ) bool {
129+ return (b >= 'a' && b <= 'z' ) || (b >= 'A' && b <= 'Z' ) || (b >= '0' && b <= '9' )
130+ }
131+
132+ func isDigit (b byte ) bool {
133+ return b >= '0' && b <= '9'
134+ }
135+
136+ func isAlpha (b byte ) bool {
137+ return (b >= 'a' && b <= 'z' ) || (b >= 'A' && b <= 'Z' )
138+ }
139+
140+ func CompareNumInFilename (prev , next []byte ) (less , ok bool ) {
141+ if len (prev ) == 0 && len (next ) == 0 {
142+ return false , false
143+ } else if len (prev ) == 0 {
144+ return true , true
145+ } else if len (next ) == 0 {
146+ return false , true
147+ }
148+
149+ // at very first beginning
150+ // filename starts with "." is prior, then digits, then letters
151+ switch {
152+ case prev [0 ] == '.' && isAlnum (next [0 ]):
153+ return true , true
154+ case next [0 ] == '.' && isAlnum (prev [0 ]):
155+ return false , true
156+ case isDigit (prev [0 ]) && isAlpha (next [0 ]):
157+ return true , true
158+ case isDigit (next [0 ]) && isAlpha (prev [0 ]):
159+ return false , true
160+ }
161+
162+ return compareNumString (prev , next )
121163}
0 commit comments