prism 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/Makefile +6 -0
  4. data/README.md +1 -1
  5. data/config.yml +50 -35
  6. data/docs/fuzzing.md +1 -1
  7. data/docs/serialization.md +28 -29
  8. data/ext/prism/api_node.c +802 -770
  9. data/ext/prism/api_pack.c +20 -9
  10. data/ext/prism/extension.c +464 -162
  11. data/ext/prism/extension.h +1 -1
  12. data/include/prism/ast.h +3173 -763
  13. data/include/prism/defines.h +32 -9
  14. data/include/prism/diagnostic.h +36 -3
  15. data/include/prism/enc/pm_encoding.h +118 -28
  16. data/include/prism/node.h +38 -13
  17. data/include/prism/options.h +204 -0
  18. data/include/prism/pack.h +44 -33
  19. data/include/prism/parser.h +445 -200
  20. data/include/prism/prettyprint.h +12 -1
  21. data/include/prism/regexp.h +16 -2
  22. data/include/prism/util/pm_buffer.h +94 -16
  23. data/include/prism/util/pm_char.h +162 -48
  24. data/include/prism/util/pm_constant_pool.h +126 -32
  25. data/include/prism/util/pm_list.h +68 -38
  26. data/include/prism/util/pm_memchr.h +18 -3
  27. data/include/prism/util/pm_newline_list.h +70 -27
  28. data/include/prism/util/pm_state_stack.h +25 -7
  29. data/include/prism/util/pm_string.h +115 -27
  30. data/include/prism/util/pm_string_list.h +25 -6
  31. data/include/prism/util/pm_strncasecmp.h +32 -0
  32. data/include/prism/util/pm_strpbrk.h +31 -17
  33. data/include/prism/version.h +27 -2
  34. data/include/prism.h +224 -31
  35. data/lib/prism/compiler.rb +6 -3
  36. data/lib/prism/debug.rb +23 -7
  37. data/lib/prism/dispatcher.rb +33 -18
  38. data/lib/prism/dsl.rb +10 -5
  39. data/lib/prism/ffi.rb +132 -80
  40. data/lib/prism/lex_compat.rb +25 -15
  41. data/lib/prism/mutation_compiler.rb +10 -5
  42. data/lib/prism/node.rb +370 -135
  43. data/lib/prism/node_ext.rb +1 -1
  44. data/lib/prism/node_inspector.rb +1 -1
  45. data/lib/prism/pack.rb +79 -40
  46. data/lib/prism/parse_result/comments.rb +7 -2
  47. data/lib/prism/parse_result/newlines.rb +4 -0
  48. data/lib/prism/parse_result.rb +150 -30
  49. data/lib/prism/pattern.rb +11 -0
  50. data/lib/prism/ripper_compat.rb +28 -10
  51. data/lib/prism/serialize.rb +86 -54
  52. data/lib/prism/visitor.rb +10 -3
  53. data/lib/prism.rb +20 -2
  54. data/prism.gemspec +4 -2
  55. data/rbi/prism.rbi +104 -60
  56. data/rbi/prism_static.rbi +16 -2
  57. data/sig/prism.rbs +72 -43
  58. data/sig/prism_static.rbs +14 -1
  59. data/src/diagnostic.c +56 -53
  60. data/src/enc/pm_big5.c +1 -0
  61. data/src/enc/pm_euc_jp.c +1 -0
  62. data/src/enc/pm_gbk.c +1 -0
  63. data/src/enc/pm_shift_jis.c +1 -0
  64. data/src/enc/pm_tables.c +316 -80
  65. data/src/enc/pm_unicode.c +53 -8
  66. data/src/enc/pm_windows_31j.c +1 -0
  67. data/src/node.c +334 -321
  68. data/src/options.c +170 -0
  69. data/src/prettyprint.c +74 -47
  70. data/src/prism.c +1642 -856
  71. data/src/regexp.c +151 -95
  72. data/src/serialize.c +44 -20
  73. data/src/token_type.c +3 -1
  74. data/src/util/pm_buffer.c +45 -15
  75. data/src/util/pm_char.c +103 -57
  76. data/src/util/pm_constant_pool.c +51 -21
  77. data/src/util/pm_list.c +12 -4
  78. data/src/util/pm_memchr.c +5 -3
  79. data/src/util/pm_newline_list.c +20 -12
  80. data/src/util/pm_state_stack.c +9 -3
  81. data/src/util/pm_string.c +95 -85
  82. data/src/util/pm_string_list.c +14 -15
  83. data/src/util/pm_strncasecmp.c +10 -3
  84. data/src/util/pm_strpbrk.c +25 -19
  85. metadata +5 -3
  86. data/docs/prism.png +0 -0
@@ -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,9 +57,11 @@ 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. If the offset is not in the
57
- // list, the line and column of the closest offset less than the given offset
58
- // are returned.
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
+ */
59
65
  pm_line_column_t
60
66
  pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor) {
61
67
  assert(cursor >= list->start);
@@ -81,7 +87,9 @@ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor
81
87
  return ((pm_line_column_t) { left - 1, offset - list->offsets[left - 1] });
82
88
  }
83
89
 
84
- // Free the internal memory allocated for the newline list.
90
+ /**
91
+ * Free the internal memory allocated for the newline list.
92
+ */
85
93
  void
86
94
  pm_newline_list_free(pm_newline_list_t *list) {
87
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.16.0
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-30 00:00:00.000000000 Z
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -34,7 +34,6 @@ files:
34
34
  - docs/heredocs.md
35
35
  - docs/javascript.md
36
36
  - docs/mapping.md
37
- - docs/prism.png
38
37
  - docs/releasing.md
39
38
  - docs/ripper.md
40
39
  - docs/ruby_api.md
@@ -51,6 +50,7 @@ files:
51
50
  - include/prism/diagnostic.h
52
51
  - include/prism/enc/pm_encoding.h
53
52
  - include/prism/node.h
53
+ - include/prism/options.h
54
54
  - include/prism/pack.h
55
55
  - include/prism/parser.h
56
56
  - include/prism/prettyprint.h
@@ -64,6 +64,7 @@ files:
64
64
  - include/prism/util/pm_state_stack.h
65
65
  - include/prism/util/pm_string.h
66
66
  - include/prism/util/pm_string_list.h
67
+ - include/prism/util/pm_strncasecmp.h
67
68
  - include/prism/util/pm_strpbrk.h
68
69
  - include/prism/version.h
69
70
  - lib/prism.rb
@@ -100,6 +101,7 @@ files:
100
101
  - src/enc/pm_unicode.c
101
102
  - src/enc/pm_windows_31j.c
102
103
  - src/node.c
104
+ - src/options.c
103
105
  - src/pack.c
104
106
  - src/prettyprint.c
105
107
  - src/prism.c
data/docs/prism.png DELETED
Binary file