atoi.v: add common_parse_uint2 with error code return values (#6550)
							parent
							
								
									d93b0f047a
								
							
						
					
					
						commit
						c5e46c9e55
					
				|  | @ -19,11 +19,23 @@ pub fn byte_to_lower(c byte) byte { | |||
| // common_parse_uint is called by parse_uint and allows the parsing
 | ||||
| // to stop on non or invalid digit characters and return the result so far
 | ||||
| pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) u64 { | ||||
| 	result, error := common_parse_uint2(s, _base, _bit_size) | ||||
| 	if error != 0 { | ||||
| 		if error > 0 && (error_on_non_digit || error_on_high_digit) { | ||||
| 			return u64(0) | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| // the first returned value contains the parsed value,
 | ||||
| // the second returned value contains the error code (0 = OK, >1 = index of first non-parseable character + 1, -1 = wrong base, -2 = wrong bit size, -3 = overflow)
 | ||||
| pub fn common_parse_uint2(s string, _base int, _bit_size int) (u64, int) { | ||||
| 	mut bit_size := _bit_size | ||||
| 	mut base := _base | ||||
| 	if s.len < 1 || !underscore_ok(s) { | ||||
| 		// return error('parse_uint: syntax error $s')
 | ||||
| 		return u64(0) | ||||
| 		return u64(0), 1 | ||||
| 	} | ||||
| 	base0 := base == 0 | ||||
| 	mut start_index := 0 | ||||
|  | @ -59,14 +71,14 @@ pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit | |||
| 	} | ||||
| 	else { | ||||
| 		// return error('parse_uint: base error $s - $base')
 | ||||
| 		return u64(0) | ||||
| 		return u64(0), -1 | ||||
| 	} | ||||
| 	if bit_size == 0 { | ||||
| 		bit_size = int_size | ||||
| 	} | ||||
| 	else if bit_size < 0 || bit_size > 64 { | ||||
| 		// return error('parse_uint: bitsize error $s - $bit_size')
 | ||||
| 		return u64(0) | ||||
| 		return u64(0), -2 | ||||
| 	} | ||||
| 	// Cutoff is the smallest number such that cutoff*base > maxUint64.
 | ||||
| 	// Use compile-time constants for common cases.
 | ||||
|  | @ -90,42 +102,26 @@ pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit | |||
| 			d = cl - `a` + 10 | ||||
| 		} | ||||
| 		else { | ||||
| 			if error_on_non_digit { | ||||
| 				// return error('parse_uint: syntax error $s')
 | ||||
| 				return u64(0) | ||||
| 			} | ||||
| 			else { | ||||
| 				break | ||||
| 			} | ||||
| 			return n, i + 1 | ||||
| 		} | ||||
| 		if d >= byte(base) { | ||||
| 			if error_on_high_digit { | ||||
| 				// return error('parse_uint: syntax error $s')
 | ||||
| 				return u64(0) | ||||
| 			} | ||||
| 			else { | ||||
| 				break | ||||
| 			} | ||||
| 			return n, i + 1 | ||||
| 		} | ||||
| 		if n >= cutoff { | ||||
| 			// n*base overflows
 | ||||
| 			// return error('parse_uint: range error $s')
 | ||||
| 			return max_val | ||||
| 			return max_val, -3 | ||||
| 		} | ||||
| 		n *= u64(base) | ||||
| 		n1 := n + u64(d) | ||||
| 		if n1 < n || n1 > max_val { | ||||
| 			// n+v overflows
 | ||||
| 			// return error('parse_uint: range error $s')
 | ||||
| 			return max_val | ||||
| 			return max_val, -3 | ||||
| 		} | ||||
| 		n = n1 | ||||
| 	} | ||||
| 	if underscores && !underscore_ok(s) { | ||||
| 		// return error('parse_uint: syntax error $s')
 | ||||
| 		return u64(0) | ||||
| 	} | ||||
| 	return n | ||||
| 	return n, 0 | ||||
| } | ||||
| 
 | ||||
| // parse_uint is like parse_int but for unsigned numbers.
 | ||||
|  |  | |||
|  | @ -26,3 +26,37 @@ fn test_parse_int() { | |||
| 	assert strconv.parse_int('123', 10, 65) == 0 | ||||
| 	assert strconv.parse_int('123', 10, -1) == 0 | ||||
| } | ||||
| 
 | ||||
| fn test_common_parse_uint2() { | ||||
| 	mut result, mut error := strconv.common_parse_uint2('1', 10, 8) | ||||
| 	assert result == 1 | ||||
| 	assert error == 0 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('123', 10, 8) | ||||
| 	assert result == 123 | ||||
| 	assert error == 0 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('123', 10, 65) | ||||
| 	assert result == 0 | ||||
| 	assert error == -2 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('123', 10, -1) | ||||
| 	assert result == 0 | ||||
| 	assert error == -2 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('', 10, 8) | ||||
| 	assert result == 0 | ||||
| 	assert error == 1 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('1a', 10, 8) | ||||
| 	assert result == 1 | ||||
| 	assert error == 2 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('12a', 10, 8) | ||||
| 	assert result == 12 | ||||
| 	assert error == 3 | ||||
| 
 | ||||
| 	result, error = strconv.common_parse_uint2('123a', 10, 8) | ||||
| 	assert result == 123 | ||||
| 	assert error == 4 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue