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
58 changes: 8 additions & 50 deletions src/analyze/conditional_elements.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "../include/element_source.h"
#include "../include/errors.h"
#include "../include/token_struct.h"
#include "../include/util.h"
#include "../include/util/hb_allocator.h"
#include "../include/util/hb_array.h"
#include "../include/util/hb_string.h"
Expand Down Expand Up @@ -37,38 +36,19 @@ static hb_string_T extract_condition_from_erb_content(AST_NODE_T* erb_node, bool

if (!content_token || hb_string_is_empty(content_token->value)) { return HB_STRING_NULL; }

const char* data = content_token->value.data;
size_t remaining = content_token->value.length;

while (remaining > 0 && is_whitespace(*data)) {
data++;
remaining--;
}
hb_string_T value = hb_string_trim_start(content_token->value);

if (*is_if) {
if (remaining >= 3 && strncmp(data, "if", 2) == 0 && is_whitespace(data[2])) {
data += 3;
remaining -= 3;
}
if (hb_string_starts_with(value, hb_string("if "))) { value = hb_string_slice(value, 3); }
} else {
if (remaining >= 7 && strncmp(data, "unless", 6) == 0 && is_whitespace(data[6])) {
data += 7;
remaining -= 7;
}
if (hb_string_starts_with(value, hb_string("unless "))) { value = hb_string_slice(value, 7); }
}

while (remaining > 0 && is_whitespace(*data)) {
data++;
remaining--;
}
if (remaining == 0) { return HB_STRING_NULL; }
value = hb_string_trim(value);

while (remaining > 0 && is_whitespace(data[remaining - 1])) {
remaining--;
}
if (remaining == 0) { return HB_STRING_NULL; }
if (hb_string_is_empty(value)) { return HB_STRING_NULL; }

return (hb_string_T) { .data = (char*) data, .length = (uint32_t) remaining };
return value;
}

static bool is_simple_erb_conditional(AST_NODE_T* node) {
Expand Down Expand Up @@ -107,18 +87,7 @@ static bool contains_single_open_tag(hb_array_T* statements, AST_HTML_OPEN_TAG_N

if (child->type == AST_HTML_TEXT_NODE) {
AST_HTML_TEXT_NODE_T* text = (AST_HTML_TEXT_NODE_T*) child;
bool whitespace_only = true;

if (!hb_string_is_empty(text->content)) {
for (size_t ci = 0; ci < text->content.length; ci++) {
if (!is_whitespace(text->content.data[ci])) {
whitespace_only = false;
break;
}
}
}

if (whitespace_only) { continue; }
if (hb_string_is_blank(text->content)) { continue; }

return false;
}
Expand Down Expand Up @@ -156,18 +125,7 @@ static bool contains_single_close_tag(hb_array_T* statements, AST_HTML_CLOSE_TAG

if (child->type == AST_HTML_TEXT_NODE) {
AST_HTML_TEXT_NODE_T* text = (AST_HTML_TEXT_NODE_T*) child;
bool whitespace_only = true;

if (!hb_string_is_empty(text->content)) {
for (size_t ci = 0; ci < text->content.length; ci++) {
if (!is_whitespace(text->content.data[ci])) {
whitespace_only = false;
break;
}
}
}

if (whitespace_only) { continue; }
if (hb_string_is_blank(text->content)) { continue; }

return false;
}
Expand Down
14 changes: 1 addition & 13 deletions src/analyze/conditional_open_tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "../include/element_source.h"
#include "../include/errors.h"
#include "../include/token_struct.h"
#include "../include/util.h"
#include "../include/util/hb_allocator.h"
#include "../include/util/hb_array.h"
#include "../include/util/hb_string.h"
Expand Down Expand Up @@ -87,18 +86,7 @@ static single_open_tag_result_T get_single_open_tag_from_statements(hb_array_T*

if (node->type == AST_HTML_TEXT_NODE) {
AST_HTML_TEXT_NODE_T* text = (AST_HTML_TEXT_NODE_T*) node;
bool whitespace_only = true;

if (!hb_string_is_empty(text->content)) {
for (size_t ci = 0; ci < text->content.length; ci++) {
if (!is_whitespace(text->content.data[ci])) {
whitespace_only = false;
break;
}
}
}

if (whitespace_only) { continue; }
if (hb_string_is_blank(text->content)) { continue; }

if (result.tag) {
hb_string_T tag_name = get_open_tag_name(result.tag);
Expand Down
9 changes: 3 additions & 6 deletions src/extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,10 @@ void herb_extract_ruby_to_buffer_with_options(
bool is_inline_comment = false;

if (!extract_options.comments && !is_comment_tag && !hb_string_is_empty(token->value)) {
const char* content = token->value.data;

while (*content == ' ' || *content == '\t') {
content++;
}
hb_string_T trimmed = hb_string_trim_start(token->value);

if (*content == '#' && token->location.start.line == token->location.end.line) {
if (!hb_string_is_empty(trimmed) && trimmed.data[0] == '#'
&& token->location.start.line == token->location.end.line) {
is_comment_tag = true;
is_inline_comment = true;
}
Expand Down
2 changes: 0 additions & 2 deletions src/include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

int is_newline(int character);
int is_whitespace(int character);
const char* skip_whitespace(const char* pointer);

hb_string_T escape_newlines(hb_string_T input);
hb_string_T quoted_string(hb_string_T input);
char* herb_strdup(const char* s);
Expand Down
4 changes: 4 additions & 0 deletions src/include/util/hb_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ bool hb_string_is_empty(hb_string_T string);

hb_string_T hb_string_truncate(hb_string_T string, uint32_t max_length);
hb_string_T hb_string_range(hb_string_T string, uint32_t from, uint32_t to);
hb_string_T hb_string_trim_start(hb_string_T string);
hb_string_T hb_string_trim_end(hb_string_T string);
hb_string_T hb_string_trim(hb_string_T string);
bool hb_string_is_blank(hb_string_T string);
hb_string_T hb_string_copy(hb_string_T string, hb_allocator_T* allocator);

char* hb_string_to_c_string_using_malloc(hb_string_T string);
Expand Down
33 changes: 13 additions & 20 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,8 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T
TOKEN_EOF
)) {
if (token_is(parser, TOKEN_ERB_START)) {
const char* tag = parser->current_token->value.data;
size_t tag_length = parser->current_token->value.length;
bool is_output_tag = (tag_length >= 3 && tag[2] == '=');
hb_string_T tag = parser->current_token->value;
bool is_output_tag = (tag.length >= 3 && tag.data[2] == '=');

if (!is_output_tag) {
bool is_control_flow = parser_lookahead_erb_is_control_flow(parser);
Expand Down Expand Up @@ -921,14 +920,14 @@ static bool parser_lookahead_erb_is_attribute(lexer_T* lexer) {
} while (true);
}

static bool starts_with_keyword(const char* pointer, size_t remaining, const char* keyword) {
size_t length = strlen(keyword);
if (remaining < length) { return false; }
if (strncmp(pointer, keyword, length) != 0) { return false; }
static bool starts_with_keyword(hb_string_T string, const char* keyword) {
hb_string_T prefix = hb_string(keyword);
if (string.length < prefix.length) { return false; }
if (strncmp(string.data, prefix.data, prefix.length) != 0) { return false; }

if (remaining == length) { return true; }
if (string.length == prefix.length) { return true; }

return is_whitespace(pointer[length]);
return is_whitespace(string.data[prefix.length]);
}

// TODO: ideally we could avoid basing this off of strings, and use the step in analyze.c
Expand All @@ -942,18 +941,12 @@ static bool parser_lookahead_erb_is_control_flow(parser_T* parser) {
return false;
}

const char* data = content->value.data;
size_t remaining = content->value.length;
hb_string_T trimmed = hb_string_trim_start(content->value);

while (remaining > 0 && is_whitespace(*data)) {
data++;
remaining--;
}

bool is_control_flow = starts_with_keyword(data, remaining, "end") || starts_with_keyword(data, remaining, "else")
|| starts_with_keyword(data, remaining, "elsif") || starts_with_keyword(data, remaining, "in")
|| starts_with_keyword(data, remaining, "when") || starts_with_keyword(data, remaining, "rescue")
|| starts_with_keyword(data, remaining, "ensure");
bool is_control_flow = starts_with_keyword(trimmed, "end") || starts_with_keyword(trimmed, "else")
|| starts_with_keyword(trimmed, "elsif") || starts_with_keyword(trimmed, "in")
|| starts_with_keyword(trimmed, "when") || starts_with_keyword(trimmed, "rescue")
|| starts_with_keyword(trimmed, "ensure");

token_free(content, parser->allocator);

Expand Down
8 changes: 0 additions & 8 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ int is_whitespace(int character) {
return character == ' ' || character == '\t' || character == '\n' || character == '\r';
}

const char* skip_whitespace(const char* pointer) {
while (is_whitespace(*pointer)) {
pointer++;
}

return pointer;
}

hb_string_T escape_newlines(hb_string_T input) {
hb_buffer_T buffer;

Expand Down
37 changes: 37 additions & 0 deletions src/util/hb_string.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../include/util/hb_string.h"
#include "../include/macros.h"
#include "../include/util.h"

#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -68,6 +69,42 @@ hb_string_T hb_string_range(hb_string_T string, uint32_t from, uint32_t to) {
return hb_string_truncate(hb_string_slice(string, from), to - from);
}

hb_string_T hb_string_trim_start(hb_string_T string) {
if (hb_string_is_empty(string)) { return string; }

uint32_t offset = 0;
while (offset < string.length && is_whitespace(string.data[offset])) {
offset++;
}

return hb_string_slice(string, offset);
}

hb_string_T hb_string_trim_end(hb_string_T string) {
if (hb_string_is_empty(string)) { return string; }

uint32_t length = string.length;
while (length > 0 && is_whitespace(string.data[length - 1])) {
length--;
}

return hb_string_truncate(string, length);
}

hb_string_T hb_string_trim(hb_string_T string) {
return hb_string_trim_end(hb_string_trim_start(string));
}

bool hb_string_is_blank(hb_string_T string) {
if (hb_string_is_empty(string)) { return true; }

for (uint32_t i = 0; i < string.length; i++) {
if (!is_whitespace(string.data[i])) { return false; }
}

return true;
}

hb_string_T hb_string_copy(hb_string_T string, hb_allocator_T* allocator) {
if (hb_string_is_null(string)) { return HB_STRING_NULL; }
if (hb_string_is_empty(string)) { return HB_STRING_EMPTY; }
Expand Down
Loading