Fix error when set_included_ranges is called with an invalid range list
This commit is contained in:
parent
de8877db35
commit
9f63139a10
8 changed files with 284 additions and 150 deletions
|
|
@ -167,7 +167,22 @@ extern "C" {
|
|||
#[doc = " The second and third parameters specify the location and length of an array"]
|
||||
#[doc = " of ranges. The parser does *not* take ownership of these ranges; it copies"]
|
||||
#[doc = " the data, so it doesn\'t matter how these ranges are allocated."]
|
||||
pub fn ts_parser_set_included_ranges(self_: *mut TSParser, ranges: *const TSRange, length: u32);
|
||||
#[doc = ""]
|
||||
#[doc = " If `length` is zero, then the entire document will be parsed. Otherwise,"]
|
||||
#[doc = " the given ranges must be ordered from earliest to latest in the document,"]
|
||||
#[doc = " and they must not overlap. That is, the following must hold for all"]
|
||||
#[doc = " `i` < `length - 1`:"]
|
||||
#[doc = ""]
|
||||
#[doc = " ranges[i].end_byte <= ranges[i + 1].start_byte"]
|
||||
#[doc = ""]
|
||||
#[doc = " If this requirement is not satisfied, the operation will fail, the ranges"]
|
||||
#[doc = " will not be assigned, and this function will return `false`. On success,"]
|
||||
#[doc = " this function returns `true`"]
|
||||
pub fn ts_parser_set_included_ranges(
|
||||
self_: *mut TSParser,
|
||||
ranges: *const TSRange,
|
||||
length: u32,
|
||||
) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Get the ranges of text that the parser will include when parsing."]
|
||||
|
|
@ -659,9 +674,11 @@ extern "C" {
|
|||
) -> *const ::std::os::raw::c_char;
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Disable a certain capture within a query. This prevents the capture"]
|
||||
#[doc = " from being returned in matches, and also avoids any resource usage"]
|
||||
#[doc = " associated with recording the capture."]
|
||||
#[doc = " Disable a certain capture within a query."]
|
||||
#[doc = ""]
|
||||
#[doc = " This prevents the capture from being returned in matches, and also avoids"]
|
||||
#[doc = " any resource usage associated with recording the capture. Currently, there"]
|
||||
#[doc = " is no way to undo this."]
|
||||
pub fn ts_query_disable_capture(
|
||||
arg1: *mut TSQuery,
|
||||
arg2: *const ::std::os::raw::c_char,
|
||||
|
|
@ -669,9 +686,10 @@ extern "C" {
|
|||
);
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Disable a certain pattern within a query. This prevents the pattern"]
|
||||
#[doc = " from matching and removes most of the overhead associated with the"]
|
||||
#[doc = " pattern."]
|
||||
#[doc = " Disable a certain pattern within a query."]
|
||||
#[doc = ""]
|
||||
#[doc = " This prevents the pattern from matching and removes most of the overhead"]
|
||||
#[doc = " associated with the pattern. Currently, there is no way to undo this."]
|
||||
pub fn ts_query_disable_pattern(arg1: *mut TSQuery, arg2: u32);
|
||||
}
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -142,6 +142,10 @@ pub struct LanguageError {
|
|||
version: usize,
|
||||
}
|
||||
|
||||
/// An error that occurred in `Parser::set_included_ranges`.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct IncludedRangesError(pub usize);
|
||||
|
||||
/// An error that occurred when trying to create a `Query`.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum QueryError {
|
||||
|
|
@ -508,16 +512,41 @@ impl Parser {
|
|||
/// allows you to parse only a *portion* of a document but still return a syntax
|
||||
/// tree whose ranges match up with the document as a whole. You can also pass
|
||||
/// multiple disjoint ranges.
|
||||
pub fn set_included_ranges(&mut self, ranges: &[Range]) {
|
||||
///
|
||||
/// If `ranges` is empty, then the entire document will be parsed. Otherwise,
|
||||
/// the given ranges must be ordered from earliest to latest in the document,
|
||||
/// and they must not overlap. That is, the following must hold for all
|
||||
/// `i` < `length - 1`:
|
||||
///
|
||||
/// ranges[i].end_byte <= ranges[i + 1].start_byte
|
||||
///
|
||||
/// If this requirement is not satisfied, method will panic.
|
||||
pub fn set_included_ranges<'a>(
|
||||
&mut self,
|
||||
ranges: &'a [Range],
|
||||
) -> Result<(), IncludedRangesError> {
|
||||
let ts_ranges: Vec<ffi::TSRange> =
|
||||
ranges.iter().cloned().map(|range| range.into()).collect();
|
||||
unsafe {
|
||||
let result = unsafe {
|
||||
ffi::ts_parser_set_included_ranges(
|
||||
self.0.as_ptr(),
|
||||
ts_ranges.as_ptr(),
|
||||
ts_ranges.len() as u32,
|
||||
)
|
||||
};
|
||||
|
||||
if result {
|
||||
Ok(())
|
||||
} else {
|
||||
let mut prev_end_byte = 0;
|
||||
for (i, range) in ranges.iter().enumerate() {
|
||||
if range.start_byte < prev_end_byte || range.end_byte < range.start_byte {
|
||||
return Err(IncludedRangesError(i));
|
||||
}
|
||||
prev_end_byte = range.end_byte;
|
||||
}
|
||||
Err(IncludedRangesError(0))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the parser's current cancellation flag pointer.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue