Using GCD actually makes the code slower — it might have to do with locking overhead from std::shared_ptr and onig_region_new/region_free.
Worth trying again once use of std::shared_ptr has been removed from the parser, and oniguruma regions are preallocated.
Previously we had to test if the patterns contained \A, \G, or \z, and if so, rewrite those anchors based on wether or not the current line/match position could match them.
This is instead of keeping a std::set with rule identifiers. Keeping the information in the grammar is a lot faster (about 25%) as we can update the status in O(1) without any memory allocation.
The downside is that the grammar is now being mutated by the parser. This is currently safe because only a single thread is used for parsing. When we switch to allowing multiple threads to perform parsing, we should make a copy of the grammar for each instance.
Another downside is that we only tag rules that have begin/match patterns, so rules that are wrappers for a set of rules, or rules that are including another rule, are never rejected, even if already visited, but the target rules they resolve to will be, though if an include (indirectly) include itself, we will no longer break such cycle (though it is clearly a bug in the grammar, if this happens, and we could preprocess the grammar to catch it).
This allows overriding “native” rules via injecting.
This commit drops support for using ‘.’ as (injection) scope selector to match everywhere. Instead use ‘*’.
The content scope is the portion of the scope created while parsing the document content, unlike scope attributes, document, project, SCM, and dynamic scopes (appended to the content scope).
Unfortunately a printf precision specifier (‘%.*s’) can not come with a width specifier so we have to cast to int. The width specifier ‘t’ is used for ptrdiff_t.
The int → NSInteger change fixed a bug with popup menu positioning, but there was no associated warning or error. It's possible there are more such bugs that we haven't found yet!