* The leading spaces and zeros are now actually skipped, instead of copied first

and then replaced.
* Now considers a space to end a number chunk. In the future, we might want to
  think about sorting fractional amounts correctly as well, but I guess that's
  not that important for Tracker.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38013 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-08-11 10:29:00 +00:00
parent 6a960972b5
commit b232302077
+28 -34
View File
@@ -32,9 +32,11 @@ names are registered trademarks or trademarks of their respective holders.
All rights reserved. All rights reserved.
*/ */
#ifndef _UTILITIES_H #ifndef _UTILITIES_H
#define _UTILITIES_H #define _UTILITIES_H
#include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
@@ -195,42 +197,37 @@ struct natural_chunk {
}; };
inline bool inline int32
IsNaturalDigit(const char c)
{
return (c >= '0' && c <= '9') || c == ' ';
}
inline void
FetchNaturalChunk(natural_chunk& chunk, const char* source) FetchNaturalChunk(natural_chunk& chunk, const char* source)
{ {
if (chunk.type == natural_chunk::ASCII) { if (chunk.type == natural_chunk::ASCII) {
// string chunk // string chunk
int32 pos = 0; int32 pos = 0;
while (!IsNaturalDigit(source[pos]) && source[pos] != '\0') { while (!isdigit(source[pos]) && !isspace(source[pos])
&& source[pos] != '\0') {
pos++; pos++;
} }
strlcpy(chunk.buffer, source, pos + 1); strlcpy(chunk.buffer, source, pos + 1);
chunk.length = pos; chunk.length = pos;
} else { return pos;
// number chunk
int32 pos = 0;
while (IsNaturalDigit(source[pos]) && source[pos] != '\0') {
pos++;
}
strlcpy(&chunk.buffer[sizeof(chunk.buffer) - 1 - pos], source, pos + 1);
chunk.length = pos;
// replace leading zeros with spaces
for (pos = sizeof(chunk.buffer) - 1 - pos;
pos < (int32)sizeof(chunk.buffer) - 1; pos++) {
if (chunk.buffer[pos] != ' ' && chunk.buffer[pos] != '0')
break;
chunk.buffer[pos] = ' ';
}
} }
// skip leading zeros and spaces
int32 skip = 0;
while (source[0] == '0' || source[0] == ' ') {
source++;
skip++;
}
// number chunk (stop at next white space)
int32 pos = 0;
while (isdigit(source[pos]) && source[pos] != '\0') {
pos++;
}
strlcpy(&chunk.buffer[sizeof(chunk.buffer) - 1 - pos], source, pos + 1);
chunk.length = pos;
return pos + skip;
} }
@@ -264,14 +261,14 @@ NaturalCompare(const char* stringA, const char* stringB)
// Determine type of next chunks in each string based on first char // Determine type of next chunks in each string based on first char
if (stringA[indexA] == '\0') if (stringA[indexA] == '\0')
a.type = natural_chunk::END; a.type = natural_chunk::END;
else if (IsNaturalDigit(stringA[indexA])) else if (isdigit(stringA[indexA]) || isspace(stringA[indexA]))
a.type = natural_chunk::NUMBER; a.type = natural_chunk::NUMBER;
else else
a.type = natural_chunk::ASCII; a.type = natural_chunk::ASCII;
if (stringB[indexB] == '\0') if (stringB[indexB] == '\0')
b.type = natural_chunk::END; b.type = natural_chunk::END;
else if (IsNaturalDigit(stringB[indexB])) else if (isdigit(stringB[indexB]) || isspace(stringB[indexB]))
b.type = natural_chunk::NUMBER; b.type = natural_chunk::NUMBER;
else else
b.type = natural_chunk::ASCII; b.type = natural_chunk::ASCII;
@@ -288,11 +285,8 @@ NaturalCompare(const char* stringA, const char* stringB)
} }
// Fetch the next chunks // Fetch the next chunks
FetchNaturalChunk(a, &stringA[indexA]); indexA += FetchNaturalChunk(a, &stringA[indexA]);
FetchNaturalChunk(b, &stringB[indexB]); indexB += FetchNaturalChunk(b, &stringB[indexB]);
indexA += a.length;
indexB += b.length;
// Compare the two chunks based on their type // Compare the two chunks based on their type
if (a.type == natural_chunk::ASCII) { if (a.type == natural_chunk::ASCII) {