Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions ext/herb/extension.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <ruby.h>

#include "../../src/include/util/hb_allocator.h"
#include "../../src/include/util/hb_arena_debug.h"

#include "error_helpers.h"
#include "extension.h"
Expand Down Expand Up @@ -80,8 +81,18 @@ static VALUE buffer_cleanup(VALUE arg) {
return Qnil;
}

static VALUE Herb_lex(VALUE self, VALUE source) {
static VALUE Herb_lex(int argc, VALUE* argv, VALUE self) {
VALUE source, options;
rb_scan_args(argc, argv, "1:", &source, &options);

char* string = (char*) check_string(source);
bool print_arena_stats = false;

if (!NIL_P(options)) {
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
}

lex_args_T args = { 0 };
args.source = source;
Expand All @@ -90,11 +101,23 @@ static VALUE Herb_lex(VALUE self, VALUE source) {

args.tokens = herb_lex(string, &args.allocator);

if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }

return rb_ensure(lex_convert_body, (VALUE) &args, lex_cleanup, (VALUE) &args);
}

static VALUE Herb_lex_file(VALUE self, VALUE path) {
static VALUE Herb_lex_file(int argc, VALUE* argv, VALUE self) {
VALUE path, options;
rb_scan_args(argc, argv, "1:", &path, &options);

char* file_path = (char*) check_string(path);
bool print_arena_stats = false;

if (!NIL_P(options)) {
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
}

lex_args_T args = { 0 };
args.source = read_file_to_ruby_string(file_path);
Expand All @@ -103,6 +126,8 @@ static VALUE Herb_lex_file(VALUE self, VALUE path) {

args.tokens = herb_lex_file(file_path, &args.allocator);

if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }

return rb_ensure(lex_convert_body, (VALUE) &args, lex_cleanup, (VALUE) &args);
}

Expand All @@ -111,6 +136,7 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
rb_scan_args(argc, argv, "1:", &source, &options);

char* string = (char*) check_string(source);
bool print_arena_stats = false;

parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;

Expand All @@ -126,6 +152,10 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
VALUE strict = rb_hash_lookup(options, rb_utf8_str_new_cstr("strict"));
if (NIL_P(strict)) { strict = rb_hash_lookup(options, ID2SYM(rb_intern("strict"))); }
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }

VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
}

parse_args_T args = { 0 };
Expand All @@ -136,6 +166,8 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {

args.root = herb_parse(string, &parser_options, &args.allocator);

if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }

return rb_ensure(parse_convert_body, (VALUE) &args, parse_cleanup, (VALUE) &args);
}

Expand All @@ -144,6 +176,7 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {
rb_scan_args(argc, argv, "1:", &path, &options);

char* file_path = (char*) check_string(path);
bool print_arena_stats = false;

VALUE source_value = read_file_to_ruby_string(file_path);
char* string = (char*) check_string(source_value);
Expand All @@ -162,6 +195,10 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {
VALUE strict = rb_hash_lookup(options, rb_utf8_str_new_cstr("strict"));
if (NIL_P(strict)) { strict = rb_hash_lookup(options, ID2SYM(rb_intern("strict"))); }
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }

VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
}

parse_args_T args = { 0 };
Expand All @@ -172,6 +209,8 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {

args.root = herb_parse(string, &parser_options, &args.allocator);

if (print_arena_stats) { hb_arena_print_stats((hb_arena_T*) args.allocator.context); }

return rb_ensure(parse_convert_body, (VALUE) &args, parse_cleanup, (VALUE) &args);
}

Expand Down Expand Up @@ -256,9 +295,9 @@ __attribute__((__visibility__("default"))) void Init_herb(void) {
rb_init_error_classes();

rb_define_singleton_method(mHerb, "parse", Herb_parse, -1);
rb_define_singleton_method(mHerb, "lex", Herb_lex, 1);
rb_define_singleton_method(mHerb, "lex", Herb_lex, -1);
rb_define_singleton_method(mHerb, "parse_file", Herb_parse_file, -1);
rb_define_singleton_method(mHerb, "lex_file", Herb_lex_file, 1);
rb_define_singleton_method(mHerb, "lex_file", Herb_lex_file, -1);
rb_define_singleton_method(mHerb, "extract_ruby", Herb_extract_ruby, -1);
rb_define_singleton_method(mHerb, "extract_html", Herb_extract_html, 1);
rb_define_singleton_method(mHerb, "version", Herb_version, 0);
Expand Down
10 changes: 7 additions & 3 deletions lib/herb/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class Herb::CLI
include Herb::Colors

attr_accessor :json, :silent, :log_file, :no_timing, :local, :escape, :no_escape, :freeze, :debug, :tool, :strict, :analyze, :track_whitespace, :verbose, :isolate
attr_accessor :json, :silent, :log_file, :no_timing, :local, :escape, :no_escape, :freeze, :debug, :tool, :strict, :analyze, :track_whitespace, :verbose, :isolate, :arena_stats

def initialize(args)
@args = args
Expand Down Expand Up @@ -158,13 +158,13 @@ def result
show_config
exit(0)
when "parse"
Herb.parse(file_content, strict: strict.nil? || strict, analyze: analyze.nil? || analyze, track_whitespace: track_whitespace || false)
Herb.parse(file_content, strict: strict.nil? || strict, analyze: analyze.nil? || analyze, track_whitespace: track_whitespace || false, arena_stats: arena_stats)
when "compile"
compile_template
when "render"
render_template
when "lex"
Herb.lex(file_content)
Herb.lex(file_content, arena_stats: arena_stats)
when "ruby"
puts Herb.extract_ruby(file_content)
exit(0)
Expand Down Expand Up @@ -299,6 +299,10 @@ def option_parser
parser.on("--tool TOOL", "Show config for specific tool: linter, formatter (for config command)") do |t|
self.tool = t.to_sym
end

parser.on("--arena-stats", "Print arena memory statistics (for lex/parse commands)") do
self.arena_stats = true
end
end
end

Expand Down
Loading