tomlib 0.5.0 → 0.7.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
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.