version_sorter 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/version_sorter/extconf.rb +1 -0
- data/ext/version_sorter/rb_version_sorter.c +8 -6
- data/ext/version_sorter/version_sorter.c +31 -27
- data/ext/version_sorter/version_sorter.h +10 -3
- data/lib/version_sorter/version.rb +1 -1
- data/test/version_sorter_test.rb +7 -0
- metadata +23 -35
- data/.gitignore +0 -4
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0b1041937013eee0cb93a83330c30e3f6c8b84c5
|
4
|
+
data.tar.gz: d3f4d2a6834e1e0d79f6ef71cd58da5941c372ae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e2d9d09fc0cdc43726e65d197ab5f768e46d2581706fd738c460ab0d90ae9ad893e0241ebc8eeb452691c92f2072412133050026144c92738a19b5df3f62acd6
|
7
|
+
data.tar.gz: d60d1df2d3bec7574541036ee0cd486aa448a82e8cd74d176a85d288d78b0f53debcf3d82f0dfa5b00e3368042331df58f164cc8a03c14b34cebc977a1035fef
|
@@ -26,19 +26,21 @@ rb_sort(VALUE obj, VALUE list)
|
|
26
26
|
long len = RARRAY_LEN(list);
|
27
27
|
long i;
|
28
28
|
char **c_list = calloc(len, sizeof(char *));
|
29
|
+
int *ordering;
|
29
30
|
VALUE rb_str, dest;
|
30
|
-
|
31
|
+
|
31
32
|
for (i = 0; i < len; i++) {
|
32
33
|
rb_str = rb_ary_entry(list, i);
|
33
34
|
c_list[i] = StringValuePtr(rb_str);
|
34
35
|
}
|
35
|
-
version_sorter_sort(c_list, len);
|
36
|
-
|
36
|
+
ordering = version_sorter_sort(c_list, len);
|
37
|
+
|
37
38
|
dest = rb_ary_new2(len);
|
38
39
|
for (i = 0; i < len; i++) {
|
39
|
-
rb_ary_store(dest, i,
|
40
|
+
rb_ary_store(dest, i, rb_ary_entry(list, ordering[i]));
|
40
41
|
}
|
41
|
-
|
42
|
+
free(ordering);
|
43
|
+
|
42
44
|
return dest;
|
43
45
|
}
|
44
46
|
|
@@ -56,4 +58,4 @@ Init_version_sorter(void)
|
|
56
58
|
rb_version_sorter_module = rb_define_module("VersionSorter");
|
57
59
|
rb_define_module_function(rb_version_sorter_module, "sort", rb_sort, 1);
|
58
60
|
rb_define_module_function(rb_version_sorter_module, "rsort", rb_rsort, 1);
|
59
|
-
}
|
61
|
+
}
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#include "version_sorter.h"
|
15
15
|
|
16
16
|
|
17
|
-
static VersionSortingItem * version_sorting_item_init(const char
|
17
|
+
static VersionSortingItem * version_sorting_item_init(const char *, int);
|
18
18
|
static void version_sorting_item_free(VersionSortingItem *);
|
19
19
|
static void version_sorting_item_add_piece(VersionSortingItem *, char *);
|
20
20
|
static void parse_version_word(VersionSortingItem *);
|
@@ -24,7 +24,7 @@ static enum scan_state scan_state_get(const char);
|
|
24
24
|
|
25
25
|
|
26
26
|
VersionSortingItem *
|
27
|
-
version_sorting_item_init(const char *original)
|
27
|
+
version_sorting_item_init(const char *original, int idx)
|
28
28
|
{
|
29
29
|
VersionSortingItem *vsi = malloc(sizeof(VersionSortingItem));
|
30
30
|
if (vsi == NULL) {
|
@@ -36,9 +36,10 @@ version_sorting_item_init(const char *original)
|
|
36
36
|
vsi->widest_len = 0;
|
37
37
|
vsi->original = original;
|
38
38
|
vsi->original_len = strlen(original);
|
39
|
-
|
39
|
+
vsi->original_idx = idx;
|
40
|
+
vsi->normalized = NULL;
|
40
41
|
parse_version_word(vsi);
|
41
|
-
|
42
|
+
|
42
43
|
return vsi;
|
43
44
|
}
|
44
45
|
|
@@ -48,12 +49,12 @@ version_sorting_item_free(VersionSortingItem *vsi)
|
|
48
49
|
VersionPiece *cur;
|
49
50
|
while (cur = vsi->head) {
|
50
51
|
vsi->head = cur->next;
|
51
|
-
|
52
|
+
free(cur->str);
|
52
53
|
free(cur);
|
53
54
|
}
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
if (vsi->normalized != NULL) {
|
56
|
+
free(vsi->normalized);
|
57
|
+
}
|
57
58
|
free(vsi);
|
58
59
|
}
|
59
60
|
|
@@ -67,7 +68,7 @@ version_sorting_item_add_piece(VersionSortingItem *vsi, char *str)
|
|
67
68
|
piece->str = str;
|
68
69
|
piece->len = strlen(str);
|
69
70
|
piece->next = NULL;
|
70
|
-
|
71
|
+
|
71
72
|
if (vsi->head == NULL) {
|
72
73
|
vsi->head = piece;
|
73
74
|
vsi->tail = piece;
|
@@ -101,16 +102,16 @@ parse_version_word(VersionSortingItem *vsi)
|
|
101
102
|
char current_char, next_char;
|
102
103
|
char *part;
|
103
104
|
enum scan_state current_state, next_state;
|
104
|
-
|
105
|
+
|
105
106
|
while ((current_char = vsi->original[start]) != '\0') {
|
106
107
|
current_state = scan_state_get(current_char);
|
107
|
-
|
108
|
+
|
108
109
|
if (current_state == other) {
|
109
110
|
start++;
|
110
111
|
end = start;
|
111
112
|
continue;
|
112
113
|
}
|
113
|
-
|
114
|
+
|
114
115
|
do {
|
115
116
|
end++;
|
116
117
|
next_char = vsi->original[end];
|
@@ -118,17 +119,17 @@ parse_version_word(VersionSortingItem *vsi)
|
|
118
119
|
} while (next_char != '\0' && current_state == next_state);
|
119
120
|
|
120
121
|
size = end - start;
|
121
|
-
|
122
|
+
|
122
123
|
part = malloc((size+1) * sizeof(char));
|
123
124
|
if (part == NULL) {
|
124
125
|
DIE("ERROR: Not enough memory to allocate word")
|
125
126
|
}
|
126
|
-
|
127
|
+
|
127
128
|
memcpy(part, vsi->original+start, size);
|
128
129
|
part[size] = '\0';
|
129
|
-
|
130
|
+
|
130
131
|
version_sorting_item_add_piece(vsi, part);
|
131
|
-
|
132
|
+
|
132
133
|
start = end;
|
133
134
|
}
|
134
135
|
}
|
@@ -136,18 +137,18 @@ parse_version_word(VersionSortingItem *vsi)
|
|
136
137
|
void
|
137
138
|
create_normalized_version(VersionSortingItem *vsi, const int widest_len)
|
138
139
|
{
|
139
|
-
VersionPiece *cur;
|
140
|
+
VersionPiece *cur;
|
140
141
|
int pos, i;
|
141
|
-
|
142
|
+
|
142
143
|
char *result = malloc(((vsi->node_len * widest_len) + 1) * sizeof(char));
|
143
144
|
if (result == NULL) {
|
144
145
|
DIE("ERROR: Unable to allocate memory")
|
145
146
|
}
|
146
147
|
result[0] = '\0';
|
147
148
|
pos = 0;
|
148
|
-
|
149
|
+
|
149
150
|
for (cur = vsi->head; cur; cur = cur->next) {
|
150
|
-
|
151
|
+
|
151
152
|
/* Left-Pad digits with a space */
|
152
153
|
if (cur->len < widest_len && isdigit(cur->str[0])) {
|
153
154
|
for (i = 0; i < widest_len - cur->len; i++) {
|
@@ -178,32 +179,35 @@ compare_by_version(const void *a, const void *b)
|
|
178
179
|
return strcmp((*(const VersionSortingItem **)a)->normalized, (*(const VersionSortingItem **)b)->normalized);
|
179
180
|
}
|
180
181
|
|
181
|
-
|
182
|
+
int*
|
182
183
|
version_sorter_sort(char **list, size_t list_len)
|
183
184
|
{
|
184
185
|
int i, widest_len = 0;
|
185
186
|
VersionSortingItem *vsi;
|
186
187
|
VersionSortingItem **sorting_list = calloc(list_len, sizeof(VersionSortingItem *));
|
188
|
+
int *ordering = calloc(list_len, sizeof(int));
|
187
189
|
|
188
190
|
for (i = 0; i < list_len; i++) {
|
189
|
-
vsi = version_sorting_item_init(list[i]);
|
191
|
+
vsi = version_sorting_item_init(list[i], i);
|
190
192
|
if (vsi->widest_len > widest_len) {
|
191
193
|
widest_len = vsi->widest_len;
|
192
194
|
}
|
193
195
|
sorting_list[i] = vsi;
|
194
196
|
}
|
195
|
-
|
197
|
+
|
196
198
|
for (i = 0; i < list_len; i++) {
|
197
199
|
create_normalized_version(sorting_list[i], widest_len);
|
198
200
|
}
|
199
201
|
|
200
202
|
qsort((void *) sorting_list, list_len, sizeof(VersionSortingItem *), &compare_by_version);
|
201
|
-
|
203
|
+
|
202
204
|
for (i = 0; i < list_len; i++) {
|
203
205
|
vsi = sorting_list[i];
|
204
206
|
list[i] = (char *) vsi->original;
|
205
|
-
|
206
|
-
|
207
|
+
ordering[i] = vsi->original_idx;
|
208
|
+
version_sorting_item_free(vsi);
|
207
209
|
}
|
208
210
|
free(sorting_list);
|
209
|
-
|
211
|
+
|
212
|
+
return ordering;
|
213
|
+
}
|
@@ -25,9 +25,15 @@
|
|
25
25
|
|
26
26
|
#endif
|
27
27
|
|
28
|
+
#if defined(BUILD_FOR_RUBY)
|
29
|
+
#include <ruby.h>
|
30
|
+
#define DIE(msg) \
|
31
|
+
rb_raise(rb_eRuntimeError, "%s", msg);
|
32
|
+
#else
|
28
33
|
#define DIE(msg) \
|
29
34
|
fprintf(stderr, msg);\
|
30
|
-
exit(EXIT_FAILURE)
|
35
|
+
exit(EXIT_FAILURE);
|
36
|
+
#endif
|
31
37
|
|
32
38
|
typedef struct _VersionSortingItem {
|
33
39
|
struct _VersionPiece *head;
|
@@ -37,6 +43,7 @@ typedef struct _VersionSortingItem {
|
|
37
43
|
char *normalized;
|
38
44
|
const char *original;
|
39
45
|
size_t original_len;
|
46
|
+
int original_idx;
|
40
47
|
} VersionSortingItem;
|
41
48
|
|
42
49
|
typedef struct _VersionPiece {
|
@@ -49,6 +56,6 @@ enum scan_state {
|
|
49
56
|
digit, alpha, other
|
50
57
|
};
|
51
58
|
|
52
|
-
extern
|
59
|
+
extern int* version_sorter_sort(char **, size_t);
|
53
60
|
|
54
|
-
#endif /* _VERSION_SORTER_H */
|
61
|
+
#endif /* _VERSION_SORTER_H */
|
data/test/version_sorter_test.rb
CHANGED
@@ -12,6 +12,13 @@ class VersionSorterTest < Test::Unit::TestCase
|
|
12
12
|
assert_equal sorted_versions, sort(versions)
|
13
13
|
end
|
14
14
|
|
15
|
+
def test_returns_same_object
|
16
|
+
versions = %w( 2.0 1.0 0.5 )
|
17
|
+
sorted = sort(versions)
|
18
|
+
|
19
|
+
assert_equal versions[2].object_id, sorted[0].object_id
|
20
|
+
end
|
21
|
+
|
15
22
|
def test_reverse_sorts_verisons_correctly
|
16
23
|
versions = %w(1.0.9 1.0.10 2.0 3.1.4.2 1.0.9a)
|
17
24
|
sorted_versions = %w( 3.1.4.2 2.0 1.0.10 1.0.9a 1.0.9 )
|
metadata
CHANGED
@@ -1,30 +1,25 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: version_sorter
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Chris Wanstrath
|
8
8
|
- K. Adam Christensen
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2009-10-14 00:00:00 -07:00
|
14
|
-
default_executable:
|
12
|
+
date: 2015-02-18 00:00:00.000000000 Z
|
15
13
|
dependencies: []
|
16
|
-
|
17
14
|
description: Fast sorting of version strings
|
18
15
|
email: chris@ozmm.org
|
19
16
|
executables: []
|
20
|
-
|
21
|
-
extensions:
|
17
|
+
extensions:
|
22
18
|
- ext/version_sorter/extconf.rb
|
23
|
-
extra_rdoc_files:
|
19
|
+
extra_rdoc_files:
|
24
20
|
- README.markdown
|
25
|
-
files:
|
26
|
-
- .gitattributes
|
27
|
-
- .gitignore
|
21
|
+
files:
|
22
|
+
- ".gitattributes"
|
28
23
|
- README.markdown
|
29
24
|
- Rakefile
|
30
25
|
- ext/version_sorter/extconf.rb
|
@@ -42,35 +37,28 @@ files:
|
|
42
37
|
- test/tags.rb
|
43
38
|
- test/tags.txt
|
44
39
|
- test/version_sorter_test.rb
|
45
|
-
has_rdoc: true
|
46
40
|
homepage: http://github.com/defunkt/version_sorter
|
47
41
|
licenses: []
|
48
|
-
|
42
|
+
metadata: {}
|
49
43
|
post_install_message:
|
50
|
-
rdoc_options:
|
51
|
-
|
52
|
-
require_paths:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
53
46
|
- lib
|
54
47
|
- ext
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
57
50
|
- - ">="
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version:
|
60
|
-
|
61
|
-
|
62
|
-
requirements:
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
63
55
|
- - ">="
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version:
|
66
|
-
version:
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
67
58
|
requirements: []
|
68
|
-
|
69
59
|
rubyforge_project:
|
70
|
-
rubygems_version:
|
60
|
+
rubygems_version: 2.2.2
|
71
61
|
signing_key:
|
72
|
-
specification_version:
|
62
|
+
specification_version: 4
|
73
63
|
summary: Fast sorting of version strings
|
74
|
-
test_files:
|
75
|
-
- test/tags.rb
|
76
|
-
- test/version_sorter_test.rb
|
64
|
+
test_files: []
|
data/.gitignore
DELETED