mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
Signed-off-by: avivkeller <me@aviv.sh> PR-URL: https://github.com/nodejs/node/pull/65392 Refs: https://openjs-foundation.slack.com/archives/C019Y2T6STH/p1787069174254509 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
116 lines
3.2 KiB
C++
116 lines
3.2 KiB
C++
#ifndef SRC_GLOB_GLOB_PROGRAM_H_
|
|
#define SRC_GLOB_GLOB_PROGRAM_H_
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "glob/glob_ast.h"
|
|
#include "glob/glob_unicode.h"
|
|
|
|
namespace node::glob {
|
|
|
|
struct RxNode {
|
|
enum class Kind : uint8_t {
|
|
kEmpty, // matches ''
|
|
kAssert, // zero-width start guard (see assert_* flags)
|
|
kText, // literal unit run
|
|
kAnyChar, // [^/]
|
|
kStarAny, // [^/]*? (flags below select +? and dot guards)
|
|
kClass,
|
|
kConcat,
|
|
kAlt,
|
|
kOpt, // (?:body)?
|
|
kStar, // (?:body)*
|
|
kPlus, // (?:body)+
|
|
kTwoBody, // (?:first)(?:rest)*? children = [first, rest]
|
|
kNeg, // !(..) group: guard alts + [^/]*? consume
|
|
};
|
|
Kind kind = Kind::kEmpty;
|
|
bool star_no_empty = false; // at least one unit
|
|
bool star_no_dot = false; // (?!\.) at entry
|
|
bool assert_no_dot = false; // `(?!\.)`
|
|
bool assert_no_traversal = false; // `(?!(?:^|/)\.\.?(?:$|/))`
|
|
|
|
struct CharClass {
|
|
CharSet positive;
|
|
CharSet negative;
|
|
bool has_positive = false;
|
|
bool has_negative = false;
|
|
bool negate = false;
|
|
};
|
|
CharClass klass;
|
|
PatternString text;
|
|
std::vector<uint32_t> children;
|
|
};
|
|
|
|
// One compiled path segment.
|
|
struct SegmentProgram {
|
|
enum class Tier : uint8_t {
|
|
kEmpty, // '', which matches only ''
|
|
kLiteral, // f === text
|
|
kStar, // /^\*+$/
|
|
kStarDotExt, // /^\*+([^+@!?*[(]*)$/
|
|
kStarDotStar, // /^\*+\.\*+$/
|
|
kDotStar, // /^\.\*+$/
|
|
kQmarks, // /^\?+([^+@!?*[(]*)?$/
|
|
kRegex, // generic
|
|
};
|
|
Tier tier = Tier::kRegex;
|
|
bool uflag = false; // code-point semantics + 'iu' folding
|
|
bool nocase = false; // fold case (kLiteral: only if !nocase_magic_only)
|
|
bool dot = false;
|
|
|
|
// If kLiteral: the text. If kStarDotExt/kQmarks: the extension.
|
|
PatternString literal;
|
|
PatternString literal_lower;
|
|
|
|
// kQmarks: full pattern length in UTF-16 units ($0.length).
|
|
size_t qmarks_len = 0;
|
|
|
|
// kRegex:
|
|
std::vector<RxNode> nodes;
|
|
uint32_t root = 0;
|
|
bool start_no_dot = false; // (?!\.)
|
|
bool start_no_traversal = false; // rejects '.' and '..'
|
|
bool invalid_regex = false;
|
|
};
|
|
|
|
// One lowered path part.
|
|
struct PartMatcher {
|
|
enum class Kind : uint8_t { kGlobstar, kLiteral, kProgram };
|
|
Kind kind = Kind::kProgram;
|
|
PatternString literal; // kLiteral: '===' comparison (Windows roots etc.)
|
|
|
|
// Source info
|
|
PatternString source;
|
|
SegmentProgram program;
|
|
};
|
|
|
|
struct CompiledPattern {
|
|
bool empty = false; // empty pattern: matches only ''
|
|
CompileFlags flags;
|
|
struct Row {
|
|
std::vector<PartMatcher> parts;
|
|
bool has_globstar = false;
|
|
};
|
|
std::vector<Row> rows;
|
|
|
|
// Set when the pattern does not compile
|
|
CompileError error = CompileError::kNone;
|
|
};
|
|
|
|
using CompiledPatternPtr = std::shared_ptr<CompiledPattern>;
|
|
CompiledPattern CompileProgram(ParsedPattern&& parsed,
|
|
const CompileFlags& flags);
|
|
|
|
// "Lowering", as in toLowerCase-ing
|
|
SegmentProgram LowerSegment(SegmentNode* root,
|
|
const CompileFlags& flags,
|
|
PatternView source);
|
|
|
|
} // namespace node::glob
|
|
|
|
#endif // SRC_GLOB_GLOB_PROGRAM_H_
|