version_sorter 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a70fd7cdb6644724f9e56ec43763ab434869157e
4
- data.tar.gz: 158a5dca9eb719f7a70cfc31c4e25939869c2953
2
+ SHA256:
3
+ metadata.gz: ac54da2224203400008bdcc488a07f6014466645135dba8447a328b88d01a5c3
4
+ data.tar.gz: fb4f9564c440553d0a5ac8a1580b3545c5d394219c9169547765d07dc3610a41
5
5
  SHA512:
6
- metadata.gz: 7b129cf5ded38073805a6893b2dc1d9eb2c5d5ed18f5306dd277a042a7f3e6ce066e30b1ee9c181945acc93a4dfbf0a21349b5e29745915ab0879c46339547cb
7
- data.tar.gz: b827661988f7d51796a24b6e08d376b8a8e43477c02a81a19f1f5ab2373a4225243f430f3a85ffd767e4c5a61748b1509b751c6a3c7b5ef7486c5b75ebac7707
6
+ metadata.gz: 9e7a5716f656e8bbad48a61d8d82c2c7330b9027eb7bc7a45ce1bd6f40f0717e46515e0243a938e524ac2e024263fd84202d267ffba4efa61567f209c2e9eec0
7
+ data.tar.gz: 20018a183745d8b1d139181b061307e095add6cc77e4d5120d27c93b31081120ffef00c784cada52681b4491acfca2b3db7db42b8c1cf000fccf0a36ce7a64ad
@@ -15,6 +15,7 @@
15
15
  #include <ruby.h>
16
16
 
17
17
  #define min(a, b) ((a) < (b) ? (a) : (b))
18
+ #define max(a, b) ((a) > (b) ? (a) : (b))
18
19
  typedef int compare_callback_t(const void *, const void *);
19
20
 
20
21
  struct version_number {
@@ -56,7 +57,8 @@ compare_version_number(const struct version_number *a,
56
57
  int cmp = 0;
57
58
 
58
59
  if (num_a) {
59
- cmp = (int)ca->number - (int)cb->number;
60
+ int64_t cmp64 = (int64_t)ca->number - (int64_t)cb->number;
61
+ cmp = (int)max(-1, min(1, cmp64));
60
62
  } else {
61
63
  cmp = strchunk_cmp(
62
64
  a->original, &ca->string,
@@ -69,6 +71,10 @@ compare_version_number(const struct version_number *a,
69
71
  }
70
72
  }
71
73
 
74
+ if (max_n == 0) {
75
+ return strcmp(a->original, b->original);
76
+ }
77
+
72
78
  if (a->size < b->size)
73
79
  return (b->num_flags & (1ull << n)) ? -1 : 1;
74
80
 
@@ -138,7 +144,7 @@ parse_version_number(const char *string)
138
144
  version->comp[comp_n].string.len = offset - start;
139
145
  } else {
140
146
  version->comp[comp_n].number = number;
141
- num_flags |= (1 << comp_n);
147
+ num_flags |= (1ull << comp_n);
142
148
  }
143
149
  comp_n++;
144
150
  continue;
@@ -147,10 +153,7 @@ parse_version_number(const char *string)
147
153
  if (string[offset] == '-' || isalpha(string[offset])) {
148
154
  uint16_t start = offset;
149
155
 
150
- if (string[offset] == '-')
151
- offset++;
152
-
153
- while (isalpha(string[offset]))
156
+ while (string[offset] == '-' || isalpha(string[offset]))
154
157
  offset++;
155
158
 
156
159
  version->comp[comp_n].string.offset = start;
@@ -169,43 +172,75 @@ parse_version_number(const char *string)
169
172
  return version;
170
173
  }
171
174
 
175
+ struct sort_context {
176
+ VALUE rb_self;
177
+ VALUE rb_version_array;
178
+ compare_callback_t *cmp;
179
+ struct version_number **versions;
180
+ };
181
+
172
182
  static VALUE
173
- rb_version_sort_1(VALUE rb_self, VALUE rb_version_array, compare_callback_t cmp)
183
+ rb_version_sort_1_cb(VALUE arg)
174
184
  {
175
- struct version_number **versions;
185
+ struct sort_context *context = (struct sort_context *)arg;
176
186
  long length, i;
177
187
  VALUE *rb_version_ptr;
178
188
 
179
- Check_Type(rb_version_array, T_ARRAY);
180
-
181
- length = RARRAY_LEN(rb_version_array);
182
- if (!length)
183
- return rb_ary_new();
184
-
185
- versions = xcalloc(length, sizeof(struct version_number *));
186
-
189
+ length = RARRAY_LEN(context->rb_version_array);
187
190
  for (i = 0; i < length; ++i) {
188
191
  VALUE rb_version, rb_version_string;
189
192
 
190
- rb_version = rb_ary_entry(rb_version_array, i);
193
+ rb_version = rb_ary_entry(context->rb_version_array, i);
191
194
  if (rb_block_given_p())
192
195
  rb_version_string = rb_yield(rb_version);
193
196
  else
194
197
  rb_version_string = rb_version;
195
198
 
196
- versions[i] = parse_version_number(StringValuePtr(rb_version_string));
197
- versions[i]->rb_version = rb_version;
199
+ context->versions[i] = parse_version_number(StringValueCStr(rb_version_string));
200
+ context->versions[i]->rb_version = rb_version;
201
+ }
202
+
203
+ qsort(context->versions, length, sizeof(struct version_number *), context->cmp);
204
+ rb_version_ptr = RARRAY_PTR(context->rb_version_array);
205
+
206
+ for (i = 0; i < length; ++i) {
207
+ rb_version_ptr[i] = context->versions[i]->rb_version;
198
208
  }
199
209
 
200
- qsort(versions, length, sizeof(struct version_number *), cmp);
201
- rb_version_ptr = RARRAY_PTR(rb_version_array);
210
+ return context->rb_version_array;
211
+ }
212
+
213
+ static VALUE
214
+ rb_version_sort_1(VALUE rb_self, VALUE rb_version_array, compare_callback_t cmp)
215
+ {
216
+ long length, i;
217
+ int exception;
218
+
219
+ Check_Type(rb_version_array, T_ARRAY);
220
+
221
+ length = RARRAY_LEN(rb_version_array);
222
+ if (!length)
223
+ return rb_ary_new();
224
+
225
+ struct sort_context context = {
226
+ rb_self,
227
+ rb_version_array,
228
+ cmp,
229
+ xcalloc(length, sizeof(struct version_number *)),
230
+ };
231
+
232
+ VALUE result = rb_protect(rb_version_sort_1_cb, (VALUE)&context, &exception);
202
233
 
203
234
  for (i = 0; i < length; ++i) {
204
- rb_version_ptr[i] = versions[i]->rb_version;
205
- xfree(versions[i]);
235
+ xfree(context.versions[i]);
236
+ }
237
+ xfree(context.versions);
238
+
239
+ if (exception) {
240
+ rb_jump_tag(exception);
206
241
  }
207
- xfree(versions);
208
- return rb_version_array;
242
+
243
+ return result;
209
244
  }
210
245
 
211
246
  static VALUE
@@ -232,12 +267,41 @@ rb_version_sort_r_bang(VALUE rb_self, VALUE rb_versions)
232
267
  return rb_version_sort_1(rb_self, rb_versions, version_compare_cb_r);
233
268
  }
234
269
 
270
+ struct compare_context {
271
+ VALUE rb_version_a, rb_version_b;
272
+ struct version_number *version_a, *version_b;
273
+ };
274
+
275
+ static VALUE
276
+ rb_version_compare_cb(VALUE arg)
277
+ {
278
+ struct compare_context *context = (struct compare_context *)arg;
279
+
280
+ context->version_a = parse_version_number(StringValueCStr(context->rb_version_a));
281
+ context->version_b = parse_version_number(StringValueCStr(context->rb_version_b));
282
+
283
+ return INT2NUM(version_compare_cb(&context->version_a, &context->version_b));
284
+ }
285
+
235
286
  static VALUE
236
287
  rb_version_compare(VALUE rb_self, VALUE rb_version_a, VALUE rb_version_b)
237
288
  {
238
- struct version_number *version_a = parse_version_number(StringValuePtr(rb_version_a));
239
- struct version_number *version_b = parse_version_number(StringValuePtr(rb_version_b));
240
- return INT2NUM(version_compare_cb(&version_a, &version_b));
289
+ int exception;
290
+ struct compare_context context = {
291
+ rb_version_a, rb_version_b,
292
+ NULL, NULL,
293
+ };
294
+
295
+ VALUE result = rb_protect(rb_version_compare_cb, (VALUE)&context, &exception);
296
+
297
+ xfree(context.version_a);
298
+ xfree(context.version_b);
299
+
300
+ if (exception) {
301
+ rb_jump_tag(exception);
302
+ }
303
+
304
+ return result;
241
305
  }
242
306
 
243
307
  void Init_version_sorter(void)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: version_sorter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
8
8
  - K. Adam Christensen
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-06-21 00:00:00.000000000 Z
12
+ date: 2021-10-20 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: VersionSorter is a C extension that does fast sorting of large sets of
15
15
  version strings.
@@ -26,7 +26,7 @@ homepage: https://github.com/github/version_sorter#readme
26
26
  licenses:
27
27
  - MIT
28
28
  metadata: {}
29
- post_install_message:
29
+ post_install_message:
30
30
  rdoc_options: []
31
31
  require_paths:
32
32
  - lib
@@ -41,9 +41,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.4.5.1
46
- signing_key:
44
+ rubygems_version: 3.2.15
45
+ signing_key:
47
46
  specification_version: 4
48
47
  summary: Fast sorting of version strings
49
48
  test_files: []