diff --git a/Rakefile b/Rakefile index 39149b607ad..ceac0627ab2 100644 --- a/Rakefile +++ b/Rakefile @@ -53,13 +53,10 @@ end # So `rake clobber` will delete generated files CLOBBER.concat(TEMPLATES) -if RbConfig::CONFIG["host_os"] =~ /darwin/ - so_ext = "dylib" -else - so_ext = "so" -end -CLOBBER << "build/librubyparser.#{so_ext}" -CLOBBER << "lib/yarp.so" + +dylib_extension = RbConfig::CONFIG["host_os"].match?(/darwin/) ? "dylib" : "so" +CLOBBER << "build/librubyparser.#{dylib_extension}" +CLOBBER << "lib/yarp.#{dylib_extension}" TEMPLATES.each do |filepath| desc "Template #{filepath}" @@ -78,13 +75,6 @@ task lex: :compile do results = { passing: [], failing: [] } colorize = ->(code, string) { "\033[#{code}m#{string}\033[0m" } - accepted_encodings = [ - Encoding::ASCII_8BIT, - Encoding::ISO_8859_9, - Encoding::US_ASCII, - Encoding::UTF_8 - ] - filepaths = if ENV["FILEPATHS"] Dir[ENV["FILEPATHS"]] @@ -95,27 +85,13 @@ task lex: :compile do filepaths.each do |filepath| source = File.read(filepath) - # If this file can't be parsed at all, then don't try to compare it to - # ripper's output. - ripper = Ripper.new(source).tap(&:parse) - next if ripper.error? - - # If this file has an encoding that we don't support, then don't try to - # compare it to ripper's output. - unless accepted_encodings.include?(ripper.encoding) + if YARP.lex_ripper(source) == YARP.lex_compat(source) + print colorize.call(32, ".") + results[:passing] << filepath + else print colorize.call(31, "E") results[:failing] << filepath - next end - - result = - YARP.lex_ripper(source).zip(YARP.lex_compat(source)).all? do |(ripper, yarp)| - break false if yarp.nil? - ripper == yarp - end - - print result ? colorize.call(32, ".") : colorize.call(31, "E") - results[result ? :passing : :failing] << filepath end puts "\n\nPASSING=#{results[:passing].length}\nFAILING=#{results[:failing].length}" diff --git a/bin/templates/src/node.c.erb b/bin/templates/src/node.c.erb index 16e9be51d0e..daedd7d6c34 100644 --- a/bin/templates/src/node.c.erb +++ b/bin/templates/src/node.c.erb @@ -159,10 +159,13 @@ yp_node_destroy(yp_parser_t *parser, yp_node_t *node) { <%- raise -%> <%- end -%> <%- end -%> - free(node); break; <%- end -%> + default: + assert(false && "unreachable"); + break; } + free(node); } static void diff --git a/ext/yarp/extension.c b/ext/yarp/extension.c index 12638489e00..d1590106db4 100644 --- a/ext/yarp/extension.c +++ b/ext/yarp/extension.c @@ -128,7 +128,7 @@ lex_source(source_t *source) { }; parser.lex_callback = &lex_callback; - yp_parse(&parser); + yp_node_destroy(&parser, yp_parse(&parser)); yp_parser_free(&parser); return ary; diff --git a/src/diagnostic.c b/src/diagnostic.c index f190fe87c5b..ffab91cff89 100644 --- a/src/diagnostic.c +++ b/src/diagnostic.c @@ -13,13 +13,14 @@ yp_diagnostic_list_append(yp_list_t *list, const char *message, uint32_t positio // Deallocate the internal state of the given diagnostic list. void yp_diagnostic_list_free(yp_list_t *list) { - yp_list_node_t *node = list->head; - yp_list_node_t *next; + yp_list_node_t *node, *next; - while (node != NULL) { + for (node = list->head; node != NULL; node = next) { next = node->next; - yp_string_free(&((yp_diagnostic_t *) node)->message); - free(node); - node = next; + + yp_diagnostic_t *diagnostic = (yp_diagnostic_t *) node; + yp_string_free(&diagnostic->message); + + free(diagnostic); } } diff --git a/src/yarp.c b/src/yarp.c index b009aceac35..fb0fdef1757 100644 --- a/src/yarp.c +++ b/src/yarp.c @@ -5996,7 +5996,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, binding_power_t bin // need foo=. In this case we'll allocate a new owned string, copy // the previous method name in, and append an =. size_t length = yp_string_length(&node->as.call_node.name); - char *name = malloc(length + 1); + char *name = malloc(length + 2); sprintf(name, "%.*s=", (int) length, yp_string_source(&node->as.call_node.name)); // Now switch the name to the new string. @@ -6426,11 +6426,25 @@ yp_parser_register_encoding_decode_callback(yp_parser_t *parser, yp_encoding_dec parser->encoding_decode_callback = callback; } +// Free all of the memory associated with the comment list. +static inline void +yp_comment_list_free(yp_list_t *list) { + yp_list_node_t *node, *next; + + for (node = list->head; node != NULL; node = next) { + next = node->next; + + yp_comment_t *comment = (yp_comment_t *) node; + free(comment); + } +} + // Free any memory associated with the given parser. __attribute__((__visibility__("default"))) extern void yp_parser_free(yp_parser_t *parser) { yp_diagnostic_list_free(&parser->error_list); - yp_list_free(&parser->comment_list); + yp_diagnostic_list_free(&parser->warning_list); + yp_comment_list_free(&parser->comment_list); } // Get the next token type and set its value on the current pointer.