1
0
mirror of https://github.com/e621ng/dtext_rb.git synced 2025-03-04 03:03:03 -05:00

Convert StateMachine to class

Last part of 9e46b3e806

Co-Authored-By: evazion <noizave@gmail.com>
This commit is contained in:
Earlopain 2023-03-29 22:12:53 +02:00
parent 641cb9c466
commit 8ea08a5285
No known key found for this signature in database
GPG Key ID: 6CFB948E15246897
3 changed files with 75 additions and 80 deletions

View File

@ -965,7 +965,7 @@ static inline void append_unnamed_url(StateMachine * sm, const char * url_start,
}
static inline void append_named_url(StateMachine * sm, const char * url_start, const char * url_end, const char * title_start, const char * title_end) {
auto parsed_title = parse_basic_inline(title_start, title_end - title_start);
auto parsed_title = sm->parse_basic_inline(title_start, title_end - title_start);
if (url_start[0] == '/' || url_start[0] == '#') {
append(sm, "<a rel=\"nofollow\" class=\"dtext-link\" href=\"");
@ -1199,58 +1199,43 @@ static inline const char* find_boundary_c(const char* c) {
}
}
StateMachine init_machine(const char * src, size_t len) {
StateMachine sm;
StateMachine::StateMachine(const char * src, size_t len, int initial_state, const DTextOptions options) : options(options) {
output.reserve(len * 1.5);
stack.reserve(16);
dstack.reserve(16);
posts.reserve(10);
size_t output_length = len;
if (output_length < (INT16_MAX / 2)) {
output_length *= 2;
}
sm.options = DTextOptions {};
sm.p = src;
sm.pb = sm.p;
sm.pe = sm.p + len;
sm.eof = sm.pe;
sm.ts = NULL;
sm.te = NULL;
sm.cs = dtext_start;
sm.act = 0;
sm.top = 0;
sm.output.reserve(output_length);
sm.stack.reserve(16);
sm.dstack.reserve(16);
sm.posts.reserve(10);
sm.a1 = NULL;
sm.a2 = NULL;
sm.b1 = NULL;
sm.b2 = NULL;
sm.list_nest = 0;
sm.header_mode = false;
return sm;
p = src;
pb = p;
pe = p + len;
eof = pe;
cs = initial_state;
}
std::string parse_basic_inline(const char* dtext, const ssize_t length) {
StateMachine sm = init_machine(dtext, length);
sm.options.f_inline = true;
sm.options.allow_color = false;
sm.options.max_thumbs = 0;
std::string StateMachine::parse_basic_inline(const char* src, const size_t len) {
DTextOptions options = {};
options.f_inline = true;
options.allow_color = false;
options.max_thumbs = 0;
sm.cs = dtext_en_basic_inline;
StateMachine sm(src, len, dtext_en_basic_inline, options);
parse_helper(&sm);
return sm.output;
return sm.parse().dtext;
}
void parse_helper(StateMachine* sm) {
DTextResult StateMachine::parse_dtext(const char* src, const size_t len, DTextOptions options) {
StateMachine sm(src, len, dtext_en_main, options);
return sm.parse();
}
DTextResult StateMachine::parse() {
StateMachine* sm = this;
g_debug("start\n");
%% write init nocs;
%% write exec;
dstack_close_all(sm);
return DTextResult { sm->output, sm->posts };
}

View File

@ -49,35 +49,43 @@ struct DTextOptions {
std::string base_url;
};
typedef struct StateMachine {
struct DTextResult {
std::string dtext;
std::vector<long> posts;
};
class StateMachine {
public:
static DTextResult parse_dtext(const char* src, const size_t len, DTextOptions options);
static std::string parse_basic_inline(const char* src, const size_t len);
DTextOptions options;
size_t top;
int cs;
int act;
const char * p;
const char * pb;
const char * pe;
const char * eof;
const char * ts;
const char * te;
int act = 0;
const char * p = NULL;
const char * pb = NULL;
const char * pe = NULL;
const char * eof = NULL;
const char * ts = NULL;
const char * te = NULL;
const char * a1 = NULL;
const char * a2 = NULL;
const char * b1 = NULL;
const char * b2 = NULL;
bool header_mode = false;
int list_nest = 0;
const char * a1;
const char * a2;
const char * b1;
const char * b2;
bool list_mode;
bool header_mode;
int list_nest;
std::vector<long> posts;
std::string output;
std::vector<int> stack;
std::vector<element_t> dstack;
} StateMachine;
StateMachine init_machine(const char * src, size_t len);
void parse_helper(StateMachine* sm);
std::string parse_basic_inline(const char* dtext, const ssize_t length);
private:
StateMachine(const char * src, size_t len, int initial_state, const DTextOptions options);
DTextResult parse();
};
#endif

View File

@ -12,13 +12,14 @@ static VALUE c_parse(VALUE self, VALUE input, VALUE f_inline, VALUE f_allow_colo
}
StringValue(input);
StateMachine sm = init_machine(RSTRING_PTR(input), RSTRING_LEN(input));
sm.options.f_inline = RTEST(f_inline);
sm.options.allow_color = RTEST(f_allow_color);
sm.options.max_thumbs = FIX2LONG(f_max_thumbs);
DTextOptions options = {};
options.f_inline = RTEST(f_inline);
options.allow_color = RTEST(f_allow_color);
options.max_thumbs = FIX2LONG(f_max_thumbs);
if (!NIL_P(base_url)) {
sm.options.base_url = StringValueCStr(base_url); // base_url.to_str # raises ArgumentError if base_url contains null bytes.
options.base_url = StringValueCStr(base_url); // base_url.to_str # raises ArgumentError if base_url contains null bytes.
}
if (memchr(RSTRING_PTR(input), 0, RSTRING_LEN(input))) {
@ -26,22 +27,23 @@ static VALUE c_parse(VALUE self, VALUE input, VALUE f_inline, VALUE f_allow_colo
}
try {
parse_helper(&sm);
auto result = StateMachine::parse_dtext(RSTRING_PTR(input), RSTRING_LEN(input), options);
VALUE retStr = rb_utf8_str_new(result.dtext.c_str(), result.dtext.size());
VALUE retPostIds = rb_ary_new_capa(result.posts.size());
for (long post_id : result.posts) {
rb_ary_push(retPostIds, LONG2FIX(post_id));
}
VALUE ret = rb_ary_new_capa(2);
rb_ary_push(ret, retStr);
rb_ary_push(ret, retPostIds);
return ret;
} catch (std::exception& e) {
rb_raise(cDTextError, "%s", e.what());
}
VALUE retStr = rb_utf8_str_new(sm.output.c_str(), sm.output.size());
VALUE retPostIds = rb_ary_new_capa(sm.posts.size());
for (long post_id : sm.posts) {
rb_ary_push(retPostIds, LONG2FIX(post_id));
}
VALUE ret = rb_ary_new_capa(2);
rb_ary_push(ret, retStr);
rb_ary_push(ret, retPostIds);
return ret;
}
extern "C" void Init_dtext() {