Merge pull request #4466 from ScriptDevil/master
Range checking and miscellaneous fixes tin time library
This commit is contained in:
commit
1a226f5807
1 changed files with 34 additions and 33 deletions
|
@ -341,6 +341,16 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
Some((value, pos))
|
Some((value, pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn match_digits_in_range(ss: &str, pos: uint, digits: uint, ws: bool,
|
||||||
|
min: i32, max: i32) -> Option<(i32, uint)> {
|
||||||
|
match match_digits(ss, pos, digits, ws) {
|
||||||
|
Some((val, pos)) if val >= min && val <= max => {
|
||||||
|
Some((val, pos))
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_char(s: &str, pos: uint, c: char) -> Result<uint, ~str> {
|
fn parse_char(s: &str, pos: uint, c: char) -> Result<uint, ~str> {
|
||||||
let range = str::char_range_at(s, pos);
|
let range = str::char_range_at(s, pos);
|
||||||
|
|
||||||
|
@ -414,7 +424,8 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) }
|
||||||
None => Err(~"Invalid month")
|
None => Err(~"Invalid month")
|
||||||
},
|
},
|
||||||
'C' => match match_digits(s, pos, 2u, false) {
|
'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32,
|
||||||
|
99_i32) {
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_year += (v * 100_i32) - 1900_i32;
|
tm.tm_year += (v * 100_i32) - 1900_i32;
|
||||||
|
@ -440,11 +451,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
.chain(|pos| parse_char(s, pos, '/'))
|
.chain(|pos| parse_char(s, pos, '/'))
|
||||||
.chain(|pos| parse_type(s, pos, 'y', &mut *tm))
|
.chain(|pos| parse_type(s, pos, 'y', &mut *tm))
|
||||||
}
|
}
|
||||||
'd' => match match_digits(s, pos, 2u, false) {
|
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
|
||||||
|
31_i32) {
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
||||||
None => Err(~"Invalid day of the month")
|
None => Err(~"Invalid day of the month")
|
||||||
},
|
},
|
||||||
'e' => match match_digits(s, pos, 2u, true) {
|
'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32,
|
||||||
|
31_i32) {
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
|
||||||
None => Err(~"Invalid day of the month")
|
None => Err(~"Invalid day of the month")
|
||||||
},
|
},
|
||||||
|
@ -456,15 +469,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
|
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
|
||||||
}
|
}
|
||||||
'H' => {
|
'H' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
||||||
None => Err(~"Invalid hour")
|
None => Err(~"Invalid hour")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'I' => {
|
'I' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
||||||
|
@ -474,26 +485,23 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'j' => {
|
'j' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 3u, false, 1_i32, 366_i32) {
|
||||||
match match_digits(s, pos, 3u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_yday = v - 1_i32;
|
tm.tm_yday = v - 1_i32;
|
||||||
Ok(pos)
|
Ok(pos)
|
||||||
}
|
}
|
||||||
None => Err(~"Invalid year")
|
None => Err(~"Invalid day of year")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'k' => {
|
'k' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, true, 0_i32, 23_i32) {
|
||||||
match match_digits(s, pos, 2u, true) {
|
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
|
||||||
None => Err(~"Invalid hour")
|
None => Err(~"Invalid hour")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'l' => {
|
'l' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, true, 1_i32, 12_i32) {
|
||||||
match match_digits(s, pos, 2u, true) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
tm.tm_hour = if v == 12_i32 { 0_i32 } else { v };
|
||||||
|
@ -503,15 +511,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'M' => {
|
'M' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 59_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_min = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_min = v; Ok(pos) }
|
||||||
None => Err(~"Invalid minute")
|
None => Err(~"Invalid minute")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'm' => {
|
'm' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_mon = v - 1_i32;
|
tm.tm_mon = v - 1_i32;
|
||||||
|
@ -548,8 +554,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
.chain(|pos| parse_type(s, pos, 'p', &mut *tm))
|
.chain(|pos| parse_type(s, pos, 'p', &mut *tm))
|
||||||
}
|
}
|
||||||
'S' => {
|
'S' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_sec = v;
|
tm.tm_sec = v;
|
||||||
|
@ -568,14 +573,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
}
|
}
|
||||||
't' => parse_char(s, pos, '\t'),
|
't' => parse_char(s, pos, '\t'),
|
||||||
'u' => {
|
'u' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 1u, false, 1_i32, 7_i32) {
|
||||||
match match_digits(s, pos, 1u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_wday = v;
|
tm.tm_wday = v-1_i32;
|
||||||
Ok(pos)
|
Ok(pos)
|
||||||
}
|
}
|
||||||
None => Err(~"Invalid weekday")
|
None => Err(~"Invalid day of week")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'v' => {
|
'v' => {
|
||||||
|
@ -587,34 +591,31 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
||||||
}
|
}
|
||||||
//'W' {}
|
//'W' {}
|
||||||
'w' => {
|
'w' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 1u, false, 0_i32, 6_i32) {
|
||||||
match match_digits(s, pos, 1u, false) {
|
|
||||||
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
|
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
|
||||||
None => Err(~"Invalid weekday")
|
None => Err(~"Invalid day of week")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//'X' {}
|
//'X' {}
|
||||||
//'x' {}
|
//'x' {}
|
||||||
'Y' => {
|
'Y' => {
|
||||||
// FIXME (#2350): range check.
|
|
||||||
match match_digits(s, pos, 4u, false) {
|
match match_digits(s, pos, 4u, false) {
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_year = v - 1900_i32;
|
tm.tm_year = v - 1900_i32;
|
||||||
Ok(pos)
|
Ok(pos)
|
||||||
}
|
}
|
||||||
None => Err(~"Invalid weekday")
|
None => Err(~"Invalid year")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'y' => {
|
'y' => {
|
||||||
// FIXME (#2350): range check.
|
match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) {
|
||||||
match match_digits(s, pos, 2u, false) {
|
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
let (v, pos) = item;
|
let (v, pos) = item;
|
||||||
tm.tm_year = v - 1900_i32;
|
tm.tm_year = v;
|
||||||
Ok(pos)
|
Ok(pos)
|
||||||
}
|
}
|
||||||
None => Err(~"Invalid weekday")
|
None => Err(~"Invalid year")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'Z' => {
|
'Z' => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue