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:
parent
641cb9c466
commit
8ea08a5285
@ -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 };
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user