prism 0.15.1 → 0.17.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -1
  3. data/Makefile +12 -0
  4. data/README.md +3 -1
  5. data/config.yml +66 -50
  6. data/docs/configuration.md +2 -0
  7. data/docs/fuzzing.md +1 -1
  8. data/docs/javascript.md +90 -0
  9. data/docs/releasing.md +27 -0
  10. data/docs/ruby_api.md +2 -0
  11. data/docs/serialization.md +28 -29
  12. data/ext/prism/api_node.c +856 -826
  13. data/ext/prism/api_pack.c +20 -9
  14. data/ext/prism/extension.c +494 -119
  15. data/ext/prism/extension.h +1 -1
  16. data/include/prism/ast.h +3157 -747
  17. data/include/prism/defines.h +40 -8
  18. data/include/prism/diagnostic.h +36 -3
  19. data/include/prism/enc/pm_encoding.h +119 -28
  20. data/include/prism/node.h +38 -30
  21. data/include/prism/options.h +204 -0
  22. data/include/prism/pack.h +44 -33
  23. data/include/prism/parser.h +445 -199
  24. data/include/prism/prettyprint.h +26 -0
  25. data/include/prism/regexp.h +16 -2
  26. data/include/prism/util/pm_buffer.h +102 -18
  27. data/include/prism/util/pm_char.h +162 -48
  28. data/include/prism/util/pm_constant_pool.h +128 -34
  29. data/include/prism/util/pm_list.h +68 -38
  30. data/include/prism/util/pm_memchr.h +18 -3
  31. data/include/prism/util/pm_newline_list.h +71 -28
  32. data/include/prism/util/pm_state_stack.h +25 -7
  33. data/include/prism/util/pm_string.h +115 -27
  34. data/include/prism/util/pm_string_list.h +25 -6
  35. data/include/prism/util/pm_strncasecmp.h +32 -0
  36. data/include/prism/util/pm_strpbrk.h +31 -17
  37. data/include/prism/version.h +28 -3
  38. data/include/prism.h +229 -36
  39. data/lib/prism/compiler.rb +5 -5
  40. data/lib/prism/debug.rb +43 -13
  41. data/lib/prism/desugar_compiler.rb +1 -1
  42. data/lib/prism/dispatcher.rb +27 -26
  43. data/lib/prism/dsl.rb +16 -16
  44. data/lib/prism/ffi.rb +138 -61
  45. data/lib/prism/lex_compat.rb +26 -16
  46. data/lib/prism/mutation_compiler.rb +11 -11
  47. data/lib/prism/node.rb +426 -227
  48. data/lib/prism/node_ext.rb +23 -16
  49. data/lib/prism/node_inspector.rb +1 -1
  50. data/lib/prism/pack.rb +79 -40
  51. data/lib/prism/parse_result/comments.rb +7 -2
  52. data/lib/prism/parse_result/newlines.rb +4 -0
  53. data/lib/prism/parse_result.rb +157 -21
  54. data/lib/prism/pattern.rb +14 -3
  55. data/lib/prism/ripper_compat.rb +28 -10
  56. data/lib/prism/serialize.rb +935 -307
  57. data/lib/prism/visitor.rb +9 -5
  58. data/lib/prism.rb +20 -2
  59. data/prism.gemspec +11 -2
  60. data/rbi/prism.rbi +7305 -0
  61. data/rbi/prism_static.rbi +196 -0
  62. data/sig/prism.rbs +4468 -0
  63. data/sig/prism_static.rbs +123 -0
  64. data/src/diagnostic.c +56 -53
  65. data/src/enc/pm_big5.c +1 -0
  66. data/src/enc/pm_euc_jp.c +1 -0
  67. data/src/enc/pm_gbk.c +1 -0
  68. data/src/enc/pm_shift_jis.c +1 -0
  69. data/src/enc/pm_tables.c +316 -80
  70. data/src/enc/pm_unicode.c +54 -9
  71. data/src/enc/pm_windows_31j.c +1 -0
  72. data/src/node.c +357 -345
  73. data/src/options.c +170 -0
  74. data/src/prettyprint.c +7697 -1643
  75. data/src/prism.c +1964 -1125
  76. data/src/regexp.c +153 -95
  77. data/src/serialize.c +432 -397
  78. data/src/token_type.c +3 -1
  79. data/src/util/pm_buffer.c +88 -23
  80. data/src/util/pm_char.c +103 -57
  81. data/src/util/pm_constant_pool.c +52 -22
  82. data/src/util/pm_list.c +12 -4
  83. data/src/util/pm_memchr.c +5 -3
  84. data/src/util/pm_newline_list.c +25 -63
  85. data/src/util/pm_state_stack.c +9 -3
  86. data/src/util/pm_string.c +95 -85
  87. data/src/util/pm_string_list.c +14 -15
  88. data/src/util/pm_strncasecmp.c +10 -3
  89. data/src/util/pm_strpbrk.c +25 -19
  90. metadata +12 -3
  91. data/docs/prism.png +0 -0
data/src/util/pm_list.c CHANGED
@@ -1,18 +1,24 @@
1
1
  #include "prism/util/pm_list.h"
2
2
 
3
- // Returns true if the given list is empty.
3
+ /**
4
+ * Returns true if the given list is empty.
5
+ */
4
6
  PRISM_EXPORTED_FUNCTION bool
5
7
  pm_list_empty_p(pm_list_t *list) {
6
8
  return list->head == NULL;
7
9
  }
8
10
 
9
- // Returns the size of the list.
11
+ /**
12
+ * Returns the size of the list.
13
+ */
10
14
  PRISM_EXPORTED_FUNCTION size_t
11
15
  pm_list_size(pm_list_t *list) {
12
16
  return list->size;
13
17
  }
14
18
 
15
- // Append a node to the given list.
19
+ /**
20
+ * Append a node to the given list.
21
+ */
16
22
  void
17
23
  pm_list_append(pm_list_t *list, pm_list_node_t *node) {
18
24
  if (list->head == NULL) {
@@ -25,7 +31,9 @@ pm_list_append(pm_list_t *list, pm_list_node_t *node) {
25
31
  list->size++;
26
32
  }
27
33
 
28
- // Deallocate the internal state of the given list.
34
+ /**
35
+ * Deallocate the internal state of the given list.
36
+ */
29
37
  PRISM_EXPORTED_FUNCTION void
30
38
  pm_list_free(pm_list_t *list) {
31
39
  pm_list_node_t *node = list->head;
data/src/util/pm_memchr.c CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  #define PRISM_MEMCHR_TRAILING_BYTE_MINIMUM 0x40
4
4
 
5
- // We need to roll our own memchr to handle cases where the encoding changes and
6
- // we need to search for a character in a buffer that could be the trailing byte
7
- // of a multibyte character.
5
+ /**
6
+ * We need to roll our own memchr to handle cases where the encoding changes and
7
+ * we need to search for a character in a buffer that could be the trailing byte
8
+ * of a multibyte character.
9
+ */
8
10
  void *
9
11
  pm_memchr(const void *memory, int character, size_t number, bool encoding_changed, pm_encoding_t *encoding) {
10
12
  if (encoding_changed && encoding->multibyte && character >= PRISM_MEMCHR_TRAILING_BYTE_MINIMUM) {
@@ -1,7 +1,9 @@
1
1
  #include "prism/util/pm_newline_list.h"
2
2
 
3
- // Initialize a new newline list with the given capacity. Returns true if the
4
- // allocation of the offsets succeeds, otherwise returns false.
3
+ /**
4
+ * Initialize a new newline list with the given capacity. Returns true if the
5
+ * allocation of the offsets succeeds, otherwise returns false.
6
+ */
5
7
  bool
6
8
  pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity) {
7
9
  list->offsets = (size_t *) calloc(capacity, sizeof(size_t));
@@ -14,14 +16,13 @@ pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capac
14
16
  list->size = 1;
15
17
  list->capacity = capacity;
16
18
 
17
- list->last_index = 0;
18
- list->last_offset = 0;
19
-
20
19
  return true;
21
20
  }
22
21
 
23
- // Append a new offset to the newline list. Returns true if the reallocation of
24
- // the offsets succeeds (if one was necessary), otherwise returns false.
22
+ /**
23
+ * Append a new offset to the newline list. Returns true if the reallocation of
24
+ * the offsets succeeds (if one was necessary), otherwise returns false.
25
+ */
25
26
  bool
26
27
  pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) {
27
28
  if (list->size == list->capacity) {
@@ -44,7 +45,10 @@ pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) {
44
45
  return true;
45
46
  }
46
47
 
47
- // Conditionally append a new offset to the newline list, if the value passed in is a newline.
48
+ /**
49
+ * Conditionally append a new offset to the newline list, if the value passed in
50
+ * is a newline.
51
+ */
48
52
  bool
49
53
  pm_newline_list_check_append(pm_newline_list_t *list, const uint8_t *cursor) {
50
54
  if (*cursor != '\n') {
@@ -53,10 +57,16 @@ pm_newline_list_check_append(pm_newline_list_t *list, const uint8_t *cursor) {
53
57
  return pm_newline_list_append(list, cursor);
54
58
  }
55
59
 
56
- // Returns the line and column of the given offset, assuming we don't have any
57
- // information about the previous index that we found.
58
- static pm_line_column_t
59
- pm_newline_list_line_column_search(pm_newline_list_t *list, size_t offset) {
60
+ /**
61
+ * Returns the line and column of the given offset. If the offset is not in the
62
+ * list, the line and column of the closest offset less than the given offset
63
+ * are returned.
64
+ */
65
+ pm_line_column_t
66
+ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor) {
67
+ assert(cursor >= list->start);
68
+ size_t offset = (size_t) (cursor - list->start);
69
+
60
70
  size_t left = 0;
61
71
  size_t right = list->size - 1;
62
72
 
@@ -77,57 +87,9 @@ pm_newline_list_line_column_search(pm_newline_list_t *list, size_t offset) {
77
87
  return ((pm_line_column_t) { left - 1, offset - list->offsets[left - 1] });
78
88
  }
79
89
 
80
- // Returns the line and column of the given offset, assuming we know the last
81
- // index that we found.
82
- static pm_line_column_t
83
- pm_newline_list_line_column_scan(pm_newline_list_t *list, size_t offset) {
84
- if (offset > list->last_offset) {
85
- size_t index = list->last_index;
86
- while (index < list->size && list->offsets[index] < offset) {
87
- index++;
88
- }
89
-
90
- if (index == list->size) {
91
- return ((pm_line_column_t) { index - 1, offset - list->offsets[index - 1] });
92
- }
93
-
94
- return ((pm_line_column_t) { index, 0 });
95
- } else {
96
- size_t index = list->last_index;
97
- while (index > 0 && list->offsets[index] > offset) {
98
- index--;
99
- }
100
-
101
- if (index == 0) {
102
- return ((pm_line_column_t) { 0, offset });
103
- }
104
-
105
- return ((pm_line_column_t) { index, offset - list->offsets[index - 1] });
106
- }
107
- }
108
-
109
- // Returns the line and column of the given offset. If the offset is not in the
110
- // list, the line and column of the closest offset less than the given offset
111
- // are returned.
112
- pm_line_column_t
113
- pm_newline_list_line_column(pm_newline_list_t *list, const uint8_t *cursor) {
114
- assert(cursor >= list->start);
115
- size_t offset = (size_t) (cursor - list->start);
116
- pm_line_column_t result;
117
-
118
- if (list->last_offset == 0) {
119
- result = pm_newline_list_line_column_search(list, offset);
120
- } else {
121
- result = pm_newline_list_line_column_scan(list, offset);
122
- }
123
-
124
- list->last_index = result.line;
125
- list->last_offset = offset;
126
-
127
- return result;
128
- }
129
-
130
- // Free the internal memory allocated for the newline list.
90
+ /**
91
+ * Free the internal memory allocated for the newline list.
92
+ */
131
93
  void
132
94
  pm_newline_list_free(pm_newline_list_t *list) {
133
95
  free(list->offsets);
@@ -1,18 +1,24 @@
1
1
  #include "prism/util/pm_state_stack.h"
2
2
 
3
- // Pushes a value onto the stack.
3
+ /**
4
+ * Pushes a value onto the stack.
5
+ */
4
6
  void
5
7
  pm_state_stack_push(pm_state_stack_t *stack, bool value) {
6
8
  *stack = (*stack << 1) | (value & 1);
7
9
  }
8
10
 
9
- // Pops a value off the stack.
11
+ /**
12
+ * Pops a value off the stack.
13
+ */
10
14
  void
11
15
  pm_state_stack_pop(pm_state_stack_t *stack) {
12
16
  *stack >>= 1;
13
17
  }
14
18
 
15
- // Returns the value at the top of the stack.
19
+ /**
20
+ * Returns the value at the top of the stack.
21
+ */
16
22
  bool
17
23
  pm_state_stack_p(pm_state_stack_t *stack) {
18
24
  return *stack & 1;
data/src/util/pm_string.c CHANGED
@@ -1,16 +1,17 @@
1
1
  #include "prism/util/pm_string.h"
2
2
 
3
- // The following headers are necessary to read files using demand paging.
4
- #ifdef _WIN32
5
- #include <windows.h>
6
- #else
7
- #include <fcntl.h>
8
- #include <sys/mman.h>
9
- #include <sys/stat.h>
10
- #include <unistd.h>
11
- #endif
3
+ /**
4
+ * Returns the size of the pm_string_t struct. This is necessary to allocate the
5
+ * correct amount of memory in the FFI backend.
6
+ */
7
+ PRISM_EXPORTED_FUNCTION size_t
8
+ pm_string_sizeof(void) {
9
+ return sizeof(pm_string_t);
10
+ }
12
11
 
13
- // Initialize a shared string that is based on initial input.
12
+ /**
13
+ * Initialize a shared string that is based on initial input.
14
+ */
14
15
  void
15
16
  pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end) {
16
17
  assert(start <= end);
@@ -22,7 +23,9 @@ pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *
22
23
  };
23
24
  }
24
25
 
25
- // Initialize an owned string that is responsible for freeing allocated memory.
26
+ /**
27
+ * Initialize an owned string that is responsible for freeing allocated memory.
28
+ */
26
29
  void
27
30
  pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length) {
28
31
  *string = (pm_string_t) {
@@ -32,7 +35,9 @@ pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length) {
32
35
  };
33
36
  }
34
37
 
35
- // Initialize a constant string that doesn't own its memory source.
38
+ /**
39
+ * Initialize a constant string that doesn't own its memory source.
40
+ */
36
41
  void
37
42
  pm_string_constant_init(pm_string_t *string, const char *source, size_t length) {
38
43
  *string = (pm_string_t) {
@@ -42,69 +47,17 @@ pm_string_constant_init(pm_string_t *string, const char *source, size_t length)
42
47
  };
43
48
  }
44
49
 
45
- static void
46
- pm_string_mapped_init_internal(pm_string_t *string, uint8_t *source, size_t length) {
47
- *string = (pm_string_t) {
48
- .type = PM_STRING_MAPPED,
49
- .source = source,
50
- .length = length
51
- };
52
- }
53
-
54
- // Returns the memory size associated with the string.
55
- size_t
56
- pm_string_memsize(const pm_string_t *string) {
57
- size_t size = sizeof(pm_string_t);
58
- if (string->type == PM_STRING_OWNED) {
59
- size += string->length;
60
- }
61
- return size;
62
- }
63
-
64
- // Ensure the string is owned. If it is not, then reinitialize it as owned and
65
- // copy over the previous source.
66
- void
67
- pm_string_ensure_owned(pm_string_t *string) {
68
- if (string->type == PM_STRING_OWNED) return;
69
-
70
- size_t length = pm_string_length(string);
71
- const uint8_t *source = pm_string_source(string);
72
-
73
- uint8_t *memory = malloc(length);
74
- if (!memory) return;
75
-
76
- pm_string_owned_init(string, memory, length);
77
- memcpy((void *) string->source, source, length);
78
- }
79
-
80
- // Returns the length associated with the string.
81
- PRISM_EXPORTED_FUNCTION size_t
82
- pm_string_length(const pm_string_t *string) {
83
- return string->length;
84
- }
85
-
86
- // Returns the start pointer associated with the string.
87
- PRISM_EXPORTED_FUNCTION const uint8_t *
88
- pm_string_source(const pm_string_t *string) {
89
- return string->source;
90
- }
91
-
92
- // Free the associated memory of the given string.
93
- PRISM_EXPORTED_FUNCTION void
94
- pm_string_free(pm_string_t *string) {
95
- void *memory = (void *) string->source;
96
-
97
- if (string->type == PM_STRING_OWNED) {
98
- free(memory);
99
- } else if (string->type == PM_STRING_MAPPED && string->length) {
100
- #if defined(_WIN32)
101
- UnmapViewOfFile(memory);
102
- #else
103
- munmap(memory, string->length);
104
- #endif
105
- }
106
- }
107
-
50
+ /**
51
+ * Read the file indicated by the filepath parameter into source and load its
52
+ * contents and size into the given `pm_string_t`. The given `pm_string_t`
53
+ * should be freed using `pm_string_free` when it is no longer used.
54
+ *
55
+ * We want to use demand paging as much as possible in order to avoid having to
56
+ * read the entire file into memory (which could be detrimental to performance
57
+ * for large files). This means that if we're on windows we'll use
58
+ * `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
59
+ * `mmap`, and on other POSIX systems we'll use `read`.
60
+ */
108
61
  bool
109
62
  pm_string_mapped_init(pm_string_t *string, const char *filepath) {
110
63
  #ifdef _WIN32
@@ -128,8 +81,8 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
128
81
  // the source to a constant empty string and return.
129
82
  if (file_size == 0) {
130
83
  CloseHandle(file);
131
- uint8_t empty[] = "";
132
- pm_string_mapped_init_internal(string, empty, 0);
84
+ const uint8_t source[] = "";
85
+ *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
133
86
  return true;
134
87
  }
135
88
 
@@ -151,7 +104,7 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
151
104
  return false;
152
105
  }
153
106
 
154
- pm_string_mapped_init_internal(string, source, (size_t) file_size);
107
+ *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size };
155
108
  return true;
156
109
  #else
157
110
  // Open the file for reading
@@ -175,8 +128,8 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
175
128
 
176
129
  if (size == 0) {
177
130
  close(fd);
178
- uint8_t empty[] = "";
179
- pm_string_mapped_init_internal(string, empty, 0);
131
+ const uint8_t source[] = "";
132
+ *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
180
133
  return true;
181
134
  }
182
135
 
@@ -187,14 +140,71 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
187
140
  }
188
141
 
189
142
  close(fd);
190
- pm_string_mapped_init_internal(string, source, size);
143
+ *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = size };
191
144
  return true;
192
145
  #endif
193
146
  }
194
147
 
195
- // Returns the size of the pm_string_t struct. This is necessary to allocate the
196
- // correct amount of memory in the FFI backend.
148
+ /**
149
+ * Returns the memory size associated with the string.
150
+ */
151
+ size_t
152
+ pm_string_memsize(const pm_string_t *string) {
153
+ size_t size = sizeof(pm_string_t);
154
+ if (string->type == PM_STRING_OWNED) {
155
+ size += string->length;
156
+ }
157
+ return size;
158
+ }
159
+
160
+ /**
161
+ * Ensure the string is owned. If it is not, then reinitialize it as owned and
162
+ * copy over the previous source.
163
+ */
164
+ void
165
+ pm_string_ensure_owned(pm_string_t *string) {
166
+ if (string->type == PM_STRING_OWNED) return;
167
+
168
+ size_t length = pm_string_length(string);
169
+ const uint8_t *source = pm_string_source(string);
170
+
171
+ uint8_t *memory = malloc(length);
172
+ if (!memory) return;
173
+
174
+ pm_string_owned_init(string, memory, length);
175
+ memcpy((void *) string->source, source, length);
176
+ }
177
+
178
+ /**
179
+ * Returns the length associated with the string.
180
+ */
197
181
  PRISM_EXPORTED_FUNCTION size_t
198
- pm_string_sizeof(void) {
199
- return sizeof(pm_string_t);
182
+ pm_string_length(const pm_string_t *string) {
183
+ return string->length;
184
+ }
185
+
186
+ /**
187
+ * Returns the start pointer associated with the string.
188
+ */
189
+ PRISM_EXPORTED_FUNCTION const uint8_t *
190
+ pm_string_source(const pm_string_t *string) {
191
+ return string->source;
192
+ }
193
+
194
+ /**
195
+ * Free the associated memory of the given string.
196
+ */
197
+ PRISM_EXPORTED_FUNCTION void
198
+ pm_string_free(pm_string_t *string) {
199
+ void *memory = (void *) string->source;
200
+
201
+ if (string->type == PM_STRING_OWNED) {
202
+ free(memory);
203
+ } else if (string->type == PM_STRING_MAPPED && string->length) {
204
+ #if defined(_WIN32)
205
+ UnmapViewOfFile(memory);
206
+ #else
207
+ munmap(memory, string->length);
208
+ #endif
209
+ }
200
210
  }
@@ -1,28 +1,27 @@
1
1
  #include "prism/util/pm_string_list.h"
2
2
 
3
- // Initialize a pm_string_list_t with its default values.
4
- void
5
- pm_string_list_init(pm_string_list_t *string_list) {
6
- string_list->strings = (pm_string_t *) malloc(sizeof(pm_string_t));
7
- string_list->length = 0;
8
- string_list->capacity = 1;
9
- }
10
-
11
- // Append a pm_string_t to the given string list.
3
+ /**
4
+ * Append a pm_string_t to the given string list.
5
+ */
12
6
  void
13
7
  pm_string_list_append(pm_string_list_t *string_list, pm_string_t *string) {
14
8
  if (string_list->length + 1 > string_list->capacity) {
15
- pm_string_t *original_string = string_list->strings;
16
- string_list->capacity *= 2;
17
- string_list->strings = (pm_string_t *) malloc(string_list->capacity * sizeof(pm_string_t));
18
- memcpy(string_list->strings, original_string, (string_list->length) * sizeof(pm_string_t));
19
- free(original_string);
9
+ if (string_list->capacity == 0) {
10
+ string_list->capacity = 1;
11
+ } else {
12
+ string_list->capacity *= 2;
13
+ }
14
+
15
+ string_list->strings = realloc(string_list->strings, string_list->capacity * sizeof(pm_string_t));
16
+ if (string_list->strings == NULL) abort();
20
17
  }
21
18
 
22
19
  string_list->strings[string_list->length++] = *string;
23
20
  }
24
21
 
25
- // Free the memory associated with the string list.
22
+ /**
23
+ * Free the memory associated with the string list
24
+ */
26
25
  void
27
26
  pm_string_list_free(pm_string_list_t *string_list) {
28
27
  free(string_list->strings);
@@ -1,7 +1,14 @@
1
- #include <ctype.h>
2
- #include <stddef.h>
3
- #include <stdint.h>
1
+ #include "prism/util/pm_strncasecmp.h"
4
2
 
3
+ /**
4
+ * Compare two strings, ignoring case, up to the given length. Returns 0 if the
5
+ * strings are equal, a negative number if string1 is less than string2, or a
6
+ * positive number if string1 is greater than string2.
7
+ *
8
+ * Note that this is effectively our own implementation of strncasecmp, but it's
9
+ * not available on all of the platforms we want to support so we're rolling it
10
+ * here.
11
+ */
5
12
  int
6
13
  pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length) {
7
14
  size_t offset = 0;
@@ -1,6 +1,8 @@
1
1
  #include "prism/util/pm_strpbrk.h"
2
2
 
3
- // This is the slow path that does care about the encoding.
3
+ /**
4
+ * This is the slow path that does care about the encoding.
5
+ */
4
6
  static inline const uint8_t *
5
7
  pm_strpbrk_multi_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum) {
6
8
  size_t index = 0;
@@ -21,7 +23,9 @@ pm_strpbrk_multi_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t
21
23
  return NULL;
22
24
  }
23
25
 
24
- // This is the fast path that does not care about the encoding.
26
+ /**
27
+ * This is the fast path that does not care about the encoding.
28
+ */
25
29
  static inline const uint8_t *
26
30
  pm_strpbrk_single_byte(const uint8_t *source, const uint8_t *charset, size_t maximum) {
27
31
  size_t index = 0;
@@ -37,23 +41,25 @@ pm_strpbrk_single_byte(const uint8_t *source, const uint8_t *charset, size_t max
37
41
  return NULL;
38
42
  }
39
43
 
40
- // Here we have rolled our own version of strpbrk. The standard library strpbrk
41
- // has undefined behavior when the source string is not null-terminated. We want
42
- // to support strings that are not null-terminated because pm_parse does not
43
- // have the contract that the string is null-terminated. (This is desirable
44
- // because it means the extension can call pm_parse with the result of a call to
45
- // mmap).
46
- //
47
- // The standard library strpbrk also does not support passing a maximum length
48
- // to search. We want to support this for the reason mentioned above, but we
49
- // also don't want it to stop on null bytes. Ruby actually allows null bytes
50
- // within strings, comments, regular expressions, etc. So we need to be able to
51
- // skip past them.
52
- //
53
- // Finally, we want to support encodings wherein the charset could contain
54
- // characters that are trailing bytes of multi-byte characters. For example, in
55
- // Shift-JIS, the backslash character can be a trailing byte. In that case we
56
- // need to take a slower path and iterate one multi-byte character at a time.
44
+ /**
45
+ * Here we have rolled our own version of strpbrk. The standard library strpbrk
46
+ * has undefined behavior when the source string is not null-terminated. We want
47
+ * to support strings that are not null-terminated because pm_parse does not
48
+ * have the contract that the string is null-terminated. (This is desirable
49
+ * because it means the extension can call pm_parse with the result of a call to
50
+ * mmap).
51
+ *
52
+ * The standard library strpbrk also does not support passing a maximum length
53
+ * to search. We want to support this for the reason mentioned above, but we
54
+ * also don't want it to stop on null bytes. Ruby actually allows null bytes
55
+ * within strings, comments, regular expressions, etc. So we need to be able to
56
+ * skip past them.
57
+ *
58
+ * Finally, we want to support encodings wherein the charset could contain
59
+ * characters that are trailing bytes of multi-byte characters. For example, in
60
+ * Shift-JIS, the backslash character can be a trailing byte. In that case we
61
+ * need to take a slower path and iterate one multi-byte character at a time.
62
+ */
57
63
  const uint8_t *
58
64
  pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length) {
59
65
  if (length <= 0) {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-18 00:00:00.000000000 Z
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -32,8 +32,9 @@ files:
32
32
  - docs/encoding.md
33
33
  - docs/fuzzing.md
34
34
  - docs/heredocs.md
35
+ - docs/javascript.md
35
36
  - docs/mapping.md
36
- - docs/prism.png
37
+ - docs/releasing.md
37
38
  - docs/ripper.md
38
39
  - docs/ruby_api.md
39
40
  - docs/serialization.md
@@ -49,8 +50,10 @@ files:
49
50
  - include/prism/diagnostic.h
50
51
  - include/prism/enc/pm_encoding.h
51
52
  - include/prism/node.h
53
+ - include/prism/options.h
52
54
  - include/prism/pack.h
53
55
  - include/prism/parser.h
56
+ - include/prism/prettyprint.h
54
57
  - include/prism/regexp.h
55
58
  - include/prism/util/pm_buffer.h
56
59
  - include/prism/util/pm_char.h
@@ -61,6 +64,7 @@ files:
61
64
  - include/prism/util/pm_state_stack.h
62
65
  - include/prism/util/pm_string.h
63
66
  - include/prism/util/pm_string_list.h
67
+ - include/prism/util/pm_strncasecmp.h
64
68
  - include/prism/util/pm_strpbrk.h
65
69
  - include/prism/version.h
66
70
  - lib/prism.rb
@@ -84,6 +88,10 @@ files:
84
88
  - lib/prism/serialize.rb
85
89
  - lib/prism/visitor.rb
86
90
  - prism.gemspec
91
+ - rbi/prism.rbi
92
+ - rbi/prism_static.rbi
93
+ - sig/prism.rbs
94
+ - sig/prism_static.rbs
87
95
  - src/diagnostic.c
88
96
  - src/enc/pm_big5.c
89
97
  - src/enc/pm_euc_jp.c
@@ -93,6 +101,7 @@ files:
93
101
  - src/enc/pm_unicode.c
94
102
  - src/enc/pm_windows_31j.c
95
103
  - src/node.c
104
+ - src/options.c
96
105
  - src/pack.c
97
106
  - src/prettyprint.c
98
107
  - src/prism.c
data/docs/prism.png DELETED
Binary file