Add a debug regex command to dump regex instructions
This commit is contained in:
parent
f10eb9faa3
commit
8438b33175
|
@ -1143,7 +1143,7 @@ const CommandDesc debug_cmd = {
|
|||
[](const Context& context, CompletionFlags flags,
|
||||
const String& prefix, ByteCount cursor_pos) -> Completions {
|
||||
auto c = {"info", "buffers", "options", "memory", "shared-strings",
|
||||
"profile-hash-maps", "faces", "mappings"};
|
||||
"profile-hash-maps", "faces", "mappings", "regex"};
|
||||
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, c) };
|
||||
}),
|
||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||
|
@ -1216,6 +1216,14 @@ const CommandDesc debug_cmd = {
|
|||
keymaps.get_mapping(key, m).docstring));
|
||||
}
|
||||
}
|
||||
else if (parser[0] == "regex")
|
||||
{
|
||||
if (parser.positional_count() != 2)
|
||||
throw runtime_error("expected a regex");
|
||||
|
||||
write_to_debug_buffer(format(" * {}:\n{}",
|
||||
parser[1], dump_regex(compile_regex(parser[1], RegexCompileFlags::None))));
|
||||
}
|
||||
else
|
||||
throw runtime_error(format("no such debug command: '{}'", parser[0]));
|
||||
}
|
||||
|
|
|
@ -992,60 +992,63 @@ private:
|
|||
ParsedRegex& m_parsed_regex;
|
||||
};
|
||||
|
||||
void dump_regex(const CompiledRegex& program)
|
||||
String dump_regex(const CompiledRegex& program)
|
||||
{
|
||||
String res;
|
||||
int count = 0;
|
||||
for (auto& inst : program.instructions)
|
||||
{
|
||||
printf(" %03d ", count++);
|
||||
char buf[10];
|
||||
sprintf(buf, " %03d ", count++);
|
||||
res += buf;
|
||||
switch (inst.op)
|
||||
{
|
||||
case CompiledRegex::Literal:
|
||||
printf("literal %lc\n", inst.param);
|
||||
res += format("literal {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::Literal_IgnoreCase:
|
||||
printf("literal (ignore case) %lc\n", inst.param);
|
||||
res += format("literal (ignore case) {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::AnyChar:
|
||||
printf("any char\n");
|
||||
res += "any char\n";
|
||||
break;
|
||||
case CompiledRegex::Jump:
|
||||
printf("jump %u\n", inst.param);
|
||||
res += format("jump {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::Split_PrioritizeParent:
|
||||
case CompiledRegex::Split_PrioritizeChild:
|
||||
{
|
||||
printf("split (prioritize %s) %u\n",
|
||||
inst.op == CompiledRegex::Split_PrioritizeParent ? "parent" : "child",
|
||||
inst.param);
|
||||
res += format("split (prioritize {}) {}\n",
|
||||
inst.op == CompiledRegex::Split_PrioritizeParent ? "parent" : "child",
|
||||
inst.param);
|
||||
break;
|
||||
}
|
||||
case CompiledRegex::Save:
|
||||
printf("save %d\n", inst.param);
|
||||
res += format("save {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::Class:
|
||||
printf("class %d\n", inst.param);
|
||||
res += format("class {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::CharacterType:
|
||||
printf("character type %d\n", inst.param);
|
||||
res += format("character type {}\n", inst.param);
|
||||
break;
|
||||
case CompiledRegex::LineStart:
|
||||
printf("line start\n");
|
||||
res += "line start\n";
|
||||
break;
|
||||
case CompiledRegex::LineEnd:
|
||||
printf("line end\n");
|
||||
res += "line end\n";
|
||||
break;
|
||||
case CompiledRegex::WordBoundary:
|
||||
printf("word boundary\n");
|
||||
res += "word boundary\n";
|
||||
break;
|
||||
case CompiledRegex::NotWordBoundary:
|
||||
printf("not word boundary\n");
|
||||
res += "not word boundary\n";
|
||||
break;
|
||||
case CompiledRegex::SubjectBegin:
|
||||
printf("subject begin\n");
|
||||
res += "subject begin\n";
|
||||
break;
|
||||
case CompiledRegex::SubjectEnd:
|
||||
printf("subject end\n");
|
||||
res += "subject end\n";
|
||||
break;
|
||||
case CompiledRegex::LookAhead:
|
||||
case CompiledRegex::NegativeLookAhead:
|
||||
|
@ -1078,16 +1081,17 @@ void dump_regex(const CompiledRegex& program)
|
|||
String str;
|
||||
for (auto it = program.lookarounds.begin() + inst.param; *it != -1; ++it)
|
||||
utf8::dump(std::back_inserter(str), *it);
|
||||
printf("%s (%s)\n", name, str.c_str());
|
||||
res += format("{} ({})\n", name, str);
|
||||
break;
|
||||
}
|
||||
case CompiledRegex::FindNextStart:
|
||||
printf("find next start\n");
|
||||
res += "find next start\n";
|
||||
break;
|
||||
case CompiledRegex::Match:
|
||||
printf("match\n");
|
||||
res += "match\n";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
CompiledRegex compile_regex(StringView re, RegexCompileFlags flags)
|
||||
|
@ -1134,7 +1138,7 @@ struct TestVM : CompiledRegex, ThreadedRegexVM<const char*, dir>
|
|||
: CompiledRegex{compile_regex(re, dir == MatchDirection::Forward ?
|
||||
RegexCompileFlags::None : RegexCompileFlags::Backward)},
|
||||
VMType{(const CompiledRegex&)*this}
|
||||
{ if (dump) dump_regex(*this); }
|
||||
{ if (dump) printf(dump_regex(*this).c_str()); }
|
||||
|
||||
bool exec(StringView re, RegexExecFlags flags = RegexExecFlags::AnyMatch)
|
||||
{
|
||||
|
|
|
@ -112,6 +112,8 @@ struct CompiledRegex : RefCountable, UseMemoryDomain<MemoryDomain::Regex>
|
|||
std::unique_ptr<StartDesc> backward_start_desc;
|
||||
};
|
||||
|
||||
String dump_regex(const CompiledRegex& program);
|
||||
|
||||
enum class RegexCompileFlags
|
||||
{
|
||||
None = 0,
|
||||
|
|
|
@ -125,6 +125,13 @@ InplaceString<15> to_string(int val)
|
|||
return res;
|
||||
}
|
||||
|
||||
InplaceString<15> to_string(unsigned val)
|
||||
{
|
||||
InplaceString<15> res;
|
||||
res.m_length = sprintf(res.m_data, "%u", val);
|
||||
return res;
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(long int val)
|
||||
{
|
||||
InplaceString<23> res;
|
||||
|
|
|
@ -72,6 +72,7 @@ struct Hex { size_t val; };
|
|||
constexpr Hex hex(size_t val) { return {val}; }
|
||||
|
||||
InplaceString<15> to_string(int val);
|
||||
InplaceString<15> to_string(unsigned val);
|
||||
InplaceString<23> to_string(long int val);
|
||||
InplaceString<23> to_string(size_t val);
|
||||
InplaceString<23> to_string(long long int val);
|
||||
|
|
Loading…
Reference in New Issue
Block a user