tomlib 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9598af874f419d93b421990cfced654f3787aa1feb30cb73c10bd42088917e9c
4
- data.tar.gz: ac5980031b22fc23911e1555ce323fff74e4540071ba26960808325548b5290b
3
+ metadata.gz: 02730e4ee5dcfc0fe85a52e1909e42c88163e0d736545a7cf5c967dd11231b54
4
+ data.tar.gz: e5db101613da4dcd21db1450076df866ddf664338463f5520dbee8782bedae8d
5
5
  SHA512:
6
- metadata.gz: 8eb4fe0b0054e2f3e446a62a212d211678c10a55360ea1523b38de9900e76163ec7811ba2b96a3e46db96818ca4d3c9188fe69f3c5107cead1da8fbef4360b76
7
- data.tar.gz: b22db5ff36ebc41ac9a4d39798ed78a510e1793c05ec2e3c74ad91bb61eb8c92e7325902d592ce909e8d5ce289cbc9b6de624a2b471edfbb098b77252db8cf85
6
+ metadata.gz: 95b11c6a6f6af42b4a91710cb82fa192ac9ee1ca6b1487f2970f9694e3deae87ee4afc015947ca9be5d9fea49c32ed02acd852d18ccf98c896bae0690f8c4b01
7
+ data.tar.gz: 30991beebc111fef5d8c504eb42532d7ee4d7b4b09c094cd16981a28104f09e13283bad8e63a69d44a6aaad42f86d86032973a50933ff6ee5a81437c9d0067c8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## [0.7.0] - 2024-02-10
2
+
3
+ - Update tomlc99 to the latest version
4
+ - Parse very large numbers as Infinity
5
+ - Add support for Ruby 3.3
6
+ - Drop support for Ruby 2.7 and 2.7
7
+
8
+ ## [0.6.0] - 2023-05-05
9
+
10
+ - Correctly escape special characters
11
+
1
12
  ## [0.5.0] - 2022-08-16
2
13
 
3
14
  - Add support for Ruby 2.6
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Tomlib
2
2
 
3
- Tomlib is a TOML parser and generator for Ruby. It is fast and standards-compliant by relying
4
- on native [tomlc99](https://github.com/cktan/tomlc99) parser.
3
+ Tomlib is a TOML parser and generator for Ruby. It uses native C extension based on
4
+ fast and standards-compliant [tomlc99](https://github.com/cktan/tomlc99) parser.
5
5
 
6
6
  ## Compliance
7
7
 
@@ -11,7 +11,7 @@ It passes both [BurntSushi/toml-test](https://github.com/BurntSushi/toml-test) a
11
11
 
12
12
  ## Installation
13
13
 
14
- Tomlib supports Ruby (MRI) 2.6+
14
+ Tomlib supports Ruby (MRI) 3.0+
15
15
 
16
16
  Add this line to your application's Gemfile:
17
17
 
@@ -118,10 +118,11 @@ Tomlib.dump(hash, indent: false)
118
118
 
119
119
  ## Performance
120
120
 
121
- `Tomlib` parsing is ~300x faster than `toml-rb`, ~15x faster than `Tomlrb`
122
- and ~3x faster than `perfect_toml` for usual use case (~5KB TOML document size).
121
+ When parsing documents, `Tomlib` is more than 600x (400x with yjit) faster than `toml-rb`,
122
+ 23x (17x with yjit) faster than `Tomlrb` and almost 5x (3.5x with yjit)
123
+ faster than `perfect_toml` (~5KB TOML document size).
123
124
 
124
- Generating TOML document is about 2x faster than `toml-rb`.
125
+ When generating TOML documents, it is about 1.5x (1.7x with yjit) faster than `toml-rb`.
125
126
 
126
127
  For full comparison take a look at
127
128
  [benchmarks](https://github.com/kgiszczak/tomlib/tree/master/benchmarks)
data/ext/tomlib/toml.c CHANGED
@@ -45,6 +45,7 @@ void toml_set_memutil(void *(*xxmalloc)(size_t), void (*xxfree)(void *)) {
45
45
  ppfree = xxfree;
46
46
  }
47
47
 
48
+ #define ALIGN8(sz) (((sz) + 7) & ~7)
48
49
  #define MALLOC(a) ppmalloc(a)
49
50
  #define FREE(a) ppfree(a)
50
51
 
@@ -53,7 +54,7 @@ void toml_set_memutil(void *(*xxmalloc)(size_t), void (*xxfree)(void *)) {
53
54
  #define calloc(x, y) error - forbidden - use CALLOC instead
54
55
 
55
56
  static void *CALLOC(size_t nmemb, size_t sz) {
56
- int nb = sz * nmemb;
57
+ int nb = ALIGN8(sz) * nmemb;
57
58
  void *p = MALLOC(nb);
58
59
  if (p) {
59
60
  memset(p, 0, nb);
@@ -220,8 +221,8 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
220
221
  110xxxxx 10xxxxxx
221
222
  */
222
223
  if (code <= 0x000007FF) {
223
- buf[0] = (unsigned char) (0xc0 | (code >> 6));
224
- buf[1] = (unsigned char) (0x80 | (code & 0x3f));
224
+ buf[0] = (unsigned char)(0xc0 | (code >> 6));
225
+ buf[1] = (unsigned char)(0x80 | (code & 0x3f));
225
226
  return 2;
226
227
  }
227
228
 
@@ -229,9 +230,9 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
229
230
  1110xxxx 10xxxxxx 10xxxxxx
230
231
  */
231
232
  if (code <= 0x0000FFFF) {
232
- buf[0] = (unsigned char) (0xe0 | (code >> 12));
233
- buf[1] = (unsigned char) (0x80 | ((code >> 6) & 0x3f));
234
- buf[2] = (unsigned char) (0x80 | (code & 0x3f));
233
+ buf[0] = (unsigned char)(0xe0 | (code >> 12));
234
+ buf[1] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
235
+ buf[2] = (unsigned char)(0x80 | (code & 0x3f));
235
236
  return 3;
236
237
  }
237
238
 
@@ -239,10 +240,10 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
239
240
  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
240
241
  */
241
242
  if (code <= 0x001FFFFF) {
242
- buf[0] = (unsigned char) (0xf0 | (code >> 18));
243
- buf[1] = (unsigned char) (0x80 | ((code >> 12) & 0x3f));
244
- buf[2] = (unsigned char) (0x80 | ((code >> 6) & 0x3f));
245
- buf[3] = (unsigned char) (0x80 | (code & 0x3f));
243
+ buf[0] = (unsigned char)(0xf0 | (code >> 18));
244
+ buf[1] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
245
+ buf[2] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
246
+ buf[3] = (unsigned char)(0x80 | (code & 0x3f));
246
247
  return 4;
247
248
  }
248
249
 
@@ -250,11 +251,11 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
250
251
  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
251
252
  */
252
253
  if (code <= 0x03FFFFFF) {
253
- buf[0] = (unsigned char) (0xf8 | (code >> 24));
254
- buf[1] = (unsigned char) (0x80 | ((code >> 18) & 0x3f));
255
- buf[2] = (unsigned char) (0x80 | ((code >> 12) & 0x3f));
256
- buf[3] = (unsigned char) (0x80 | ((code >> 6) & 0x3f));
257
- buf[4] = (unsigned char) (0x80 | (code & 0x3f));
254
+ buf[0] = (unsigned char)(0xf8 | (code >> 24));
255
+ buf[1] = (unsigned char)(0x80 | ((code >> 18) & 0x3f));
256
+ buf[2] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
257
+ buf[3] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
258
+ buf[4] = (unsigned char)(0x80 | (code & 0x3f));
258
259
  return 5;
259
260
  }
260
261
 
@@ -262,12 +263,12 @@ int toml_ucs_to_utf8(int64_t code, char buf[6]) {
262
263
  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
263
264
  */
264
265
  if (code <= 0x7FFFFFFF) {
265
- buf[0] = (unsigned char) (0xfc | (code >> 30));
266
- buf[1] = (unsigned char) (0x80 | ((code >> 24) & 0x3f));
267
- buf[2] = (unsigned char) (0x80 | ((code >> 18) & 0x3f));
268
- buf[3] = (unsigned char) (0x80 | ((code >> 12) & 0x3f));
269
- buf[4] = (unsigned char) (0x80 | ((code >> 6) & 0x3f));
270
- buf[5] = (unsigned char) (0x80 | (code & 0x3f));
266
+ buf[0] = (unsigned char)(0xfc | (code >> 30));
267
+ buf[1] = (unsigned char)(0x80 | ((code >> 24) & 0x3f));
268
+ buf[2] = (unsigned char)(0x80 | ((code >> 18) & 0x3f));
269
+ buf[3] = (unsigned char)(0x80 | ((code >> 12) & 0x3f));
270
+ buf[4] = (unsigned char)(0x80 | ((code >> 6) & 0x3f));
271
+ buf[5] = (unsigned char)(0x80 | (code & 0x3f));
271
272
  return 6;
272
273
  }
273
274
 
@@ -411,8 +412,10 @@ static void *expand(void *p, int sz, int newsz) {
411
412
  if (!s)
412
413
  return 0;
413
414
 
414
- memcpy(s, p, sz);
415
- FREE(p);
415
+ if (p) {
416
+ memcpy(s, p, sz);
417
+ FREE(p);
418
+ }
416
419
  return s;
417
420
  }
418
421
 
@@ -422,8 +425,10 @@ static void **expand_ptrarr(void **p, int n) {
422
425
  return 0;
423
426
 
424
427
  s[n] = 0;
425
- memcpy(s, p, n * sizeof(void *));
426
- FREE(p);
428
+ if (p) {
429
+ memcpy(s, p, n * sizeof(void *));
430
+ FREE(p);
431
+ }
427
432
  return s;
428
433
  }
429
434
 
@@ -2198,7 +2203,7 @@ int toml_rtod_ex(toml_raw_t src, double *ret_, char *buf, int buflen) {
2198
2203
  }
2199
2204
 
2200
2205
  int toml_rtod(toml_raw_t src, double *ret_) {
2201
- char buf[100];
2206
+ char buf[400];
2202
2207
  return toml_rtod_ex(src, ret_, buf, sizeof(buf));
2203
2208
  }
2204
2209
 
@@ -2211,6 +2216,7 @@ int toml_rtos(toml_raw_t src, char **ret) {
2211
2216
  if (!src)
2212
2217
  return -1;
2213
2218
 
2219
+ // for strings, first char must be a s-quote or d-quote
2214
2220
  int qchar = src[0];
2215
2221
  int srclen = strlen(src);
2216
2222
  if (!(qchar == '\'' || qchar == '"')) {
@@ -2219,12 +2225,14 @@ int toml_rtos(toml_raw_t src, char **ret) {
2219
2225
 
2220
2226
  // triple quotes?
2221
2227
  if (qchar == src[1] && qchar == src[2]) {
2222
- multiline = 1;
2223
- sp = src + 3;
2224
- sq = src + srclen - 3;
2225
- /* last 3 chars in src must be qchar */
2226
- if (!(sp <= sq && sq[0] == qchar && sq[1] == qchar && sq[2] == qchar))
2228
+ multiline = 1; // triple-quote implies multiline
2229
+ sp = src + 3; // first char after quote
2230
+ sq = src + srclen - 3; // first char of ending quote
2231
+
2232
+ if (!(sp <= sq && sq[0] == qchar && sq[1] == qchar && sq[2] == qchar)) {
2233
+ // last 3 chars in src must be qchar
2227
2234
  return -1;
2235
+ }
2228
2236
 
2229
2237
  /* skip new line immediate after qchar */
2230
2238
  if (sp[0] == '\n')
@@ -2233,13 +2241,18 @@ int toml_rtos(toml_raw_t src, char **ret) {
2233
2241
  sp += 2;
2234
2242
 
2235
2243
  } else {
2236
- sp = src + 1;
2237
- sq = src + srclen - 1;
2238
- /* last char in src must be qchar */
2239
- if (!(sp <= sq && *sq == qchar))
2244
+ sp = src + 1; // first char after quote
2245
+ sq = src + srclen - 1; // ending quote
2246
+ if (!(sp <= sq && *sq == qchar)) {
2247
+ /* last char in src must be qchar */
2240
2248
  return -1;
2249
+ }
2241
2250
  }
2242
2251
 
2252
+ // at this point:
2253
+ // sp points to first valid char after quote.
2254
+ // sq points to one char beyond last valid char.
2255
+ // string len is (sq - sp).
2243
2256
  if (qchar == '\'') {
2244
2257
  *ret = norm_lit_str(sp, sq - sp, multiline, 0, 0);
2245
2258
  } else {
data/ext/tomlib/toml.h CHANGED
@@ -26,7 +26,7 @@
26
26
  #define TOML_H
27
27
 
28
28
  #ifdef _MSC_VER
29
- #pragma warning(disable: 4996)
29
+ #pragma warning(disable : 4996)
30
30
  #endif
31
31
 
32
32
  #include <stdint.h>
data/ext/tomlib/tomlib.c CHANGED
@@ -187,7 +187,7 @@ static VALUE toml_table_key_to_rb_value(const toml_table_t *table, const char *k
187
187
 
188
188
  datum = toml_double_in(table, key);
189
189
 
190
- if (datum.ok) {
190
+ if (datum.ok || datum.u.d == INFINITY || datum.u.d == -INFINITY) {
191
191
  return DBL2NUM(datum.u.d);
192
192
  }
193
193
 
@@ -320,7 +320,7 @@ static VALUE tomlib_key_type(VALUE self, VALUE rb_key) {
320
320
 
321
321
  if (str_len == 0) return sym_escape;
322
322
 
323
- for(long i = 0; i < str_len; i++) {
323
+ for (long i = 0; i < str_len; i++) {
324
324
  const char c = *(str + i);
325
325
 
326
326
  if (c == '\n') {
data/lib/tomlib/dumper.rb CHANGED
@@ -27,6 +27,22 @@ module Tomlib
27
27
  # @api private
28
28
  NAN = 'nan'.freeze
29
29
 
30
+ # Regex to match escape chars
31
+ # @api private
32
+ ESCAPE_CHARS_REGEX = /[\x00-\x1F\x22\x5C\x7F]/.freeze
33
+
34
+ # Escape chars mapping
35
+ # @api private
36
+ ESCAPE_CHARS = {
37
+ "\b" => 'b',
38
+ "\t" => 't',
39
+ "\n" => 'n',
40
+ "\f" => 'f',
41
+ "\r" => 'r',
42
+ '"' => '"',
43
+ '\\' => '\\',
44
+ }.freeze
45
+
30
46
  def initialize(use_indent: true)
31
47
  @use_indent = use_indent
32
48
  end
@@ -106,7 +122,7 @@ module Tomlib
106
122
 
107
123
  case key_type(key)
108
124
  when :quoted
109
- key.inspect
125
+ escape_string(key)
110
126
  when :escape
111
127
  key.dump.gsub('\n', '\\\\\n')
112
128
  else
@@ -138,7 +154,7 @@ module Tomlib
138
154
  def to_toml_value(value)
139
155
  case value
140
156
  when String
141
- value.inspect
157
+ escape_string(value)
142
158
  when Float, BigDecimal
143
159
  to_toml_float(value)
144
160
  when Time, DateTime
@@ -170,5 +186,26 @@ module Tomlib
170
186
 
171
187
  value.to_s
172
188
  end
189
+
190
+ # Escapes TOML special characters
191
+ #
192
+ # @param [String] str
193
+ #
194
+ # @return [String]
195
+ #
196
+ # @api private
197
+ def escape_string(str)
198
+ str = str.gsub(ESCAPE_CHARS_REGEX) do |chr|
199
+ c = ESCAPE_CHARS[chr]
200
+
201
+ if c
202
+ '\\' << c
203
+ else
204
+ format('\\u%04X', chr.ord)
205
+ end
206
+ end
207
+
208
+ '"' << str << '"'.freeze
209
+ end
173
210
  end
174
211
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Tomlib
4
4
  # @api private
5
- VERSION = '0.5.0'
5
+ VERSION = '0.7.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomlib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kamil Giszczak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-16 00:00:00.000000000 Z
11
+ date: 2024-02-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Fast TOML parser and generator with native extension.
14
14
  email:
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  requirements: []
57
- rubygems_version: 3.3.7
57
+ rubygems_version: 3.5.3
58
58
  signing_key:
59
59
  specification_version: 4
60
60
  summary: Fast TOML parser and generator with native extension.