Browse Source

Reorganize package strings

gingerBill 4 years ago
parent
commit
78b6948ff2
3 changed files with 269 additions and 270 deletions
  1. 15 15
      core/runtime/internal.odin
  2. 254 0
      core/strings/conversion.odin
  3. 0 255
      core/strings/strings.odin

+ 15 - 15
core/runtime/internal.odin

@@ -93,18 +93,18 @@ mem_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
 		when ODIN_USE_LLVM_API {
 			when size_of(rawptr) == 8 {
 				@(link_name="llvm.memmove.p0i8.p0i8.i64")
-				llvm_memmove :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) ---;
+				llvm_memmove :: proc "none" (dst, src: rawptr, len: int, is_volatile: bool = false) ---;
 			} else {
 				@(link_name="llvm.memmove.p0i8.p0i8.i32")
-				llvm_memmove :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) ---;
+				llvm_memmove :: proc "none" (dst, src: rawptr, len: int, is_volatile: bool = false) ---;
 			}
 		} else {
 			when size_of(rawptr) == 8 {
 				@(link_name="llvm.memmove.p0i8.p0i8.i64")
-				llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
+				llvm_memmove :: proc "none" (dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
 			} else {
 				@(link_name="llvm.memmove.p0i8.p0i8.i32")
-				llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
+				llvm_memmove :: proc "none" (dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
 			}
 		}
 	}
@@ -121,18 +121,18 @@ mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> r
 		when ODIN_USE_LLVM_API {
 			when size_of(rawptr) == 8 {
 				@(link_name="llvm.memcpy.p0i8.p0i8.i64")
-				llvm_memcpy :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) ---;
+				llvm_memcpy :: proc "none" (dst, src: rawptr, len: int, is_volatile: bool = false) ---;
 			} else {
 				@(link_name="llvm.memcpy.p0i8.p0i8.i32")
-				llvm_memcpy :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) ---;
+				llvm_memcpy :: proc "none" (dst, src: rawptr, len: int, is_volatile: bool = false) ---;
 			}
 		} else {
 			when size_of(rawptr) == 8 {
 				@(link_name="llvm.memcpy.p0i8.p0i8.i64")
-				llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
+				llvm_memcpy :: proc "none" (dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
 			} else {
 				@(link_name="llvm.memcpy.p0i8.p0i8.i32")
-				llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
+				llvm_memcpy :: proc "none" (dst, src: rawptr, len: int, align: i32 = 1, is_volatile: bool = false) ---;
 			}
 		}
 	}
@@ -389,45 +389,45 @@ string_decode_rune :: inline proc "contextless" (s: string) -> (rune, int) {
 	return rune(s0&MASK4)<<18 | rune(b1&MASKX)<<12 | rune(b2&MASKX)<<6 | rune(b3&MASKX), 4;
 }
 
-@(default_calling_convention = "c")
+@(default_calling_convention = "none")
 foreign {
 	@(link_name="llvm.sqrt.f32") _sqrt_f32 :: proc(x: f32) -> f32 ---
 	@(link_name="llvm.sqrt.f64") _sqrt_f64 :: proc(x: f64) -> f64 ---
 }
 abs_f32 :: inline proc "contextless" (x: f32) -> f32 {
 	foreign {
-		@(link_name="llvm.fabs.f32") _abs :: proc "c" (x: f32) -> f32 ---
+		@(link_name="llvm.fabs.f32") _abs :: proc "none" (x: f32) -> f32 ---
 	}
 	return _abs(x);
 }
 abs_f64 :: inline proc "contextless" (x: f64) -> f64 {
 	foreign {
-		@(link_name="llvm.fabs.f64") _abs :: proc "c" (x: f64) -> f64 ---
+		@(link_name="llvm.fabs.f64") _abs :: proc "none" (x: f64) -> f64 ---
 	}
 	return _abs(x);
 }
 
 min_f32 :: proc(a, b: f32) -> f32 {
 	foreign {
-		@(link_name="llvm.minnum.f32") _min :: proc "c" (a, b: f32) -> f32 ---
+		@(link_name="llvm.minnum.f32") _min :: proc "none" (a, b: f32) -> f32 ---
 	}
 	return _min(a, b);
 }
 min_f64 :: proc(a, b: f64) -> f64 {
 	foreign {
-		@(link_name="llvm.minnum.f64") _min :: proc "c" (a, b: f64) -> f64 ---
+		@(link_name="llvm.minnum.f64") _min :: proc "none" (a, b: f64) -> f64 ---
 	}
 	return _min(a, b);
 }
 max_f32 :: proc(a, b: f32) -> f32 {
 	foreign {
-		@(link_name="llvm.maxnum.f32") _max :: proc "c" (a, b: f32) -> f32 ---
+		@(link_name="llvm.maxnum.f32") _max :: proc "none" (a, b: f32) -> f32 ---
 	}
 	return _max(a, b);
 }
 max_f64 :: proc(a, b: f64) -> f64 {
 	foreign {
-		@(link_name="llvm.maxnum.f64") _max :: proc "c" (a, b: f64) -> f64 ---
+		@(link_name="llvm.maxnum.f64") _max :: proc "none" (a, b: f64) -> f64 ---
 	}
 	return _max(a, b);
 }

+ 254 - 0
core/strings/conversion.odin

@@ -0,0 +1,254 @@
+package strings
+
+to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> string {
+	if len(s) == 0 {
+		return "";
+	}
+
+	b := make_builder_len_cap(0, 0, allocator);
+
+	s := s;
+	for c, i in s {
+		if c != utf8.RUNE_ERROR {
+			continue;
+		}
+
+		_, w := utf8.decode_rune_in_string(s[i:]);
+		if w == 1 {
+			grow_builder(&b, len(s) + len(replacement));
+			write_string(&b, s[:i]);
+			s = s[i:];
+			break;
+		}
+	}
+
+	if builder_cap(b) == 0 {
+		return clone(s, allocator);
+	}
+
+	invalid := false;
+
+	for i := 0; i < len(s); /**/ {
+		c := s[i];
+		if c < utf8.RUNE_SELF {
+			i += 1;
+			invalid = false;
+			write_byte(&b, c);
+			continue;
+		}
+
+		_, w := utf8.decode_rune_in_string(s[i:]);
+		if w == 1 {
+			i += 1;
+			if !invalid {
+				invalid = true;
+				write_string(&b, replacement);
+			}
+			continue;
+		}
+		invalid = false;
+		write_string(&b, s[i:][:w]);
+		i += w;
+	}
+	return to_string(b);
+}
+
+to_lower :: proc(s: string, allocator := context.allocator) -> string {
+	b := make_builder(0, len(s), allocator);
+	for r in s {
+		write_rune(&b, unicode.to_lower(r));
+	}
+	return to_string(b);
+}
+to_upper :: proc(s: string, allocator := context.allocator) -> string {
+	b := make_builder(0, len(s), allocator);
+	for r in s {
+		write_rune(&b, unicode.to_upper(r));
+	}
+	return to_string(b);
+}
+
+
+
+
+is_delimiter :: proc(c: rune) -> bool {
+	return c == '-' || c == '_' || is_space(c);
+}
+
+is_separator :: proc(r: rune) -> bool {
+	if r <= 0x7f {
+		switch r {
+		case '0'..'9': return false;
+		case 'a'..'z': return false;
+		case 'A'..'Z': return false;
+		case '_': return false;
+		}
+		return true;
+	}
+
+	// TODO(bill): unicode categories
+	// if unicode.is_letter(r) || unicode.is_digit(r) {
+	// 	return false;
+	// }
+
+	return unicode.is_space(r);
+}
+
+
+string_case_iterator :: proc(b: ^Builder, s: string, callback: proc(b: ^Builder, prev, curr, next: rune)) {
+	prev, curr: rune;
+	for next in s {
+		if curr == 0 {
+			prev = curr;
+			curr = next;
+			continue;
+		}
+
+		callback(b, prev, curr, next);
+
+		prev = curr;
+		curr = next;
+	}
+
+	if len(s) > 0 {
+		callback(b, prev, curr, 0);
+	}
+}
+
+
+to_lower_camel_case :: to_camel_case;
+to_camel_case :: proc(s: string, allocator := context.allocator) -> string {
+	s := s;
+	s = trim_space(s);
+	b := make_builder(0, len(s), allocator);
+
+	string_case_iterator(&b, s, proc(b: ^Builder, prev, curr, next: rune) {
+		if !is_delimiter(curr) {
+			if is_delimiter(prev) {
+				write_rune(b, unicode.to_upper(curr));
+			} else if unicode.is_lower(prev) {
+				write_rune(b, curr);
+			} else {
+				write_rune(b, unicode.to_lower(curr));
+			}
+		}
+	});
+
+	return to_string(b);
+}
+
+to_upper_camel_case :: to_pascal_case;
+to_pascal_case :: proc(s: string, allocator := context.allocator) -> string {
+	s := s;
+	s = trim_space(s);
+	b := make_builder(0, len(s), allocator);
+
+	string_case_iterator(&b, s, proc(b: ^Builder, prev, curr, next: rune) {
+		if !is_delimiter(curr) {
+			if is_delimiter(prev) || prev == 0 {
+				write_rune(b, unicode.to_upper(curr));
+			} else if unicode.is_lower(prev) {
+				write_rune(b, curr);
+			} else {
+				write_rune(b, unicode.to_lower(curr));
+			}
+		}
+	});
+
+	return to_string(b);
+}
+
+to_delimiter_case :: proc(s: string, delimiter: rune, all_upper_case: bool, allocator := context.allocator) -> string {
+	s := s;
+	s = trim_space(s);
+	b := make_builder(0, len(s), allocator);
+
+	adjust_case := unicode.to_upper if all_upper_case else unicode.to_lower;
+
+	prev, curr: rune;
+
+	for next in s {
+		if is_delimiter(curr) {
+			if !is_delimiter(prev) {
+				write_rune(&b, delimiter);
+			}
+		} else if unicode.is_upper(curr) {
+			if unicode.is_lower(prev) || (unicode.is_upper(prev) && unicode.is_lower(next)) {
+				write_rune(&b, delimiter);
+			}
+			write_rune(&b, adjust_case(curr));
+		} else if curr != 0 {
+			write_rune(&b, adjust_case(curr));
+		}
+
+		prev = curr;
+		curr = next;
+	}
+
+	if len(s) > 0 {
+		if unicode.is_upper(curr) && unicode.is_lower(prev) && prev != 0 {
+			write_rune(&b, delimiter);
+		}
+		write_rune(&b, adjust_case(curr));
+	}
+
+	return to_string(b);
+}
+
+
+to_snake_case :: proc(s: string, allocator := context.allocator) -> string {
+	return to_delimiter_case(s, '_', false, allocator);
+}
+
+to_screaming_snake_case :: to_upper_snake_case;
+to_upper_snake_case :: proc(s: string, allocator := context.allocator) -> string {
+	return to_delimiter_case(s, '_', true, allocator);
+}
+
+to_kebab_case :: proc(s: string, allocator := context.allocator) -> string {
+	return to_delimiter_case(s, '-', false, allocator);
+}
+
+to_upper_case :: proc(s: string, allocator := context.allocator) -> string {
+	return to_delimiter_case(s, '-', true, allocator);
+}
+
+to_ada_case :: proc(s: string, allocator := context.allocator) -> string {
+	delimiter :: '_';
+
+	s := s;
+	s = trim_space(s);
+	b := make_builder(0, len(s), allocator);
+
+	prev, curr: rune;
+
+	for next in s {
+		if is_delimiter(curr) {
+			if !is_delimiter(prev) {
+				write_rune(&b, delimiter);
+			}
+		} else if unicode.is_upper(curr) {
+			if unicode.is_lower(prev) || (unicode.is_upper(prev) && unicode.is_lower(next)) {
+				write_rune(&b, delimiter);
+			}
+			write_rune(&b, unicode.to_upper(curr));
+		} else if curr != 0 {
+			write_rune(&b, unicode.to_lower(curr));
+		}
+
+		prev = curr;
+		curr = next;
+	}
+
+	if len(s) > 0 {
+		if unicode.is_upper(curr) && unicode.is_lower(prev) && prev != 0 {
+			write_rune(&b, delimiter);
+			write_rune(&b, unicode.to_upper(curr));
+		} else {
+			write_rune(&b, unicode.to_lower(curr));
+		}
+	}
+
+	return to_string(b);
+}
+

+ 0 - 255
core/strings/strings.odin

@@ -787,207 +787,6 @@ scrub :: proc(s: string, replacement: string, allocator := context.allocator) ->
 }
 
 
-to_lower :: proc(s: string, allocator := context.allocator) -> string {
-	b := make_builder(0, len(s), allocator);
-	for r in s {
-		write_rune(&b, unicode.to_lower(r));
-	}
-	return to_string(b);
-}
-to_upper :: proc(s: string, allocator := context.allocator) -> string {
-	b := make_builder(0, len(s), allocator);
-	for r in s {
-		write_rune(&b, unicode.to_upper(r));
-	}
-	return to_string(b);
-}
-
-
-
-
-is_delimiter :: proc(c: rune) -> bool {
-	return c == '-' || c == '_' || is_space(c);
-}
-
-is_separator :: proc(r: rune) -> bool {
-	if r <= 0x7f {
-		switch r {
-		case '0'..'9': return false;
-		case 'a'..'z': return false;
-		case 'A'..'Z': return false;
-		case '_': return false;
-		}
-		return true;
-	}
-
-	// TODO(bill): unicode categories
-	// if unicode.is_letter(r) || unicode.is_digit(r) {
-	// 	return false;
-	// }
-
-	return unicode.is_space(r);
-}
-
-
-string_case_iterator :: proc(b: ^Builder, s: string, callback: proc(b: ^Builder, prev, curr, next: rune)) {
-	prev, curr: rune;
-	for next in s {
-		if curr == 0 {
-			prev = curr;
-			curr = next;
-			continue;
-		}
-
-		callback(b, prev, curr, next);
-
-		prev = curr;
-		curr = next;
-	}
-
-	if len(s) > 0 {
-		callback(b, prev, curr, 0);
-	}
-}
-
-
-to_lower_camel_case :: to_camel_case;
-to_camel_case :: proc(s: string, allocator := context.allocator) -> string {
-	s := s;
-	s = trim_space(s);
-	b := make_builder(0, len(s), allocator);
-
-	string_case_iterator(&b, s, proc(b: ^Builder, prev, curr, next: rune) {
-		if !is_delimiter(curr) {
-			if is_delimiter(prev) {
-				write_rune(b, unicode.to_upper(curr));
-			} else if unicode.is_lower(prev) {
-				write_rune(b, curr);
-			} else {
-				write_rune(b, unicode.to_lower(curr));
-			}
-		}
-	});
-
-	return to_string(b);
-}
-
-to_upper_camel_case :: to_pascal_case;
-to_pascal_case :: proc(s: string, allocator := context.allocator) -> string {
-	s := s;
-	s = trim_space(s);
-	b := make_builder(0, len(s), allocator);
-
-	string_case_iterator(&b, s, proc(b: ^Builder, prev, curr, next: rune) {
-		if !is_delimiter(curr) {
-			if is_delimiter(prev) || prev == 0 {
-				write_rune(b, unicode.to_upper(curr));
-			} else if unicode.is_lower(prev) {
-				write_rune(b, curr);
-			} else {
-				write_rune(b, unicode.to_lower(curr));
-			}
-		}
-	});
-
-	return to_string(b);
-}
-
-to_delimiter_case :: proc(s: string, delimiter: rune, all_upper_case: bool, allocator := context.allocator) -> string {
-	s := s;
-	s = trim_space(s);
-	b := make_builder(0, len(s), allocator);
-
-	adjust_case := unicode.to_upper if all_upper_case else unicode.to_lower;
-
-	prev, curr: rune;
-
-	for next in s {
-		if is_delimiter(curr) {
-			if !is_delimiter(prev) {
-				write_rune(&b, delimiter);
-			}
-		} else if unicode.is_upper(curr) {
-			if unicode.is_lower(prev) || (unicode.is_upper(prev) && unicode.is_lower(next)) {
-				write_rune(&b, delimiter);
-			}
-			write_rune(&b, adjust_case(curr));
-		} else if curr != 0 {
-			write_rune(&b, adjust_case(curr));
-		}
-
-		prev = curr;
-		curr = next;
-	}
-
-	if len(s) > 0 {
-		if unicode.is_upper(curr) && unicode.is_lower(prev) && prev != 0 {
-			write_rune(&b, delimiter);
-		}
-		write_rune(&b, adjust_case(curr));
-	}
-
-	return to_string(b);
-}
-
-
-to_snake_case :: proc(s: string, allocator := context.allocator) -> string {
-	return to_delimiter_case(s, '_', false, allocator);
-}
-
-to_screaming_snake_case :: to_upper_snake_case;
-to_upper_snake_case :: proc(s: string, allocator := context.allocator) -> string {
-	return to_delimiter_case(s, '_', true, allocator);
-}
-
-to_kebab_case :: proc(s: string, allocator := context.allocator) -> string {
-	return to_delimiter_case(s, '-', false, allocator);
-}
-
-to_upper_case :: proc(s: string, allocator := context.allocator) -> string {
-	return to_delimiter_case(s, '-', true, allocator);
-}
-
-to_ada_case :: proc(s: string, allocator := context.allocator) -> string {
-	delimiter :: '_';
-
-	s := s;
-	s = trim_space(s);
-	b := make_builder(0, len(s), allocator);
-
-	prev, curr: rune;
-
-	for next in s {
-		if is_delimiter(curr) {
-			if !is_delimiter(prev) {
-				write_rune(&b, delimiter);
-			}
-		} else if unicode.is_upper(curr) {
-			if unicode.is_lower(prev) || (unicode.is_upper(prev) && unicode.is_lower(next)) {
-				write_rune(&b, delimiter);
-			}
-			write_rune(&b, unicode.to_upper(curr));
-		} else if curr != 0 {
-			write_rune(&b, unicode.to_lower(curr));
-		}
-
-		prev = curr;
-		curr = next;
-	}
-
-	if len(s) > 0 {
-		if unicode.is_upper(curr) && unicode.is_lower(prev) && prev != 0 {
-			write_rune(&b, delimiter);
-			write_rune(&b, unicode.to_upper(curr));
-		} else {
-			write_rune(&b, unicode.to_lower(curr));
-		}
-	}
-
-	return to_string(b);
-}
-
-
-
 reverse :: proc(s: string, allocator := context.allocator) -> string {
 	str := s;
 	n := len(str);
@@ -1120,60 +919,6 @@ right_justify :: proc(str: string, length: int, pad: string, allocator := contex
 
 
 
-to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> string {
-	if len(s) == 0 {
-		return "";
-	}
-
-	b := make_builder_len_cap(0, 0, allocator);
-
-	s := s;
-	for c, i in s {
-		if c != utf8.RUNE_ERROR {
-			continue;
-		}
-
-		_, w := utf8.decode_rune_in_string(s[i:]);
-		if w == 1 {
-			grow_builder(&b, len(s) + len(replacement));
-			write_string(&b, s[:i]);
-			s = s[i:];
-			break;
-		}
-	}
-
-	if builder_cap(b) == 0 {
-		return clone(s, allocator);
-	}
-
-	invalid := false;
-
-	for i := 0; i < len(s); /**/ {
-		c := s[i];
-		if c < utf8.RUNE_SELF {
-			i += 1;
-			invalid = false;
-			write_byte(&b, c);
-			continue;
-		}
-
-		_, w := utf8.decode_rune_in_string(s[i:]);
-		if w == 1 {
-			i += 1;
-			if !invalid {
-				invalid = true;
-				write_string(&b, replacement);
-			}
-			continue;
-		}
-		invalid = false;
-		write_string(&b, s[i:][:w]);
-		i += w;
-	}
-	return to_string(b);
-}
-
-
 
 @private
 write_pad_string :: proc(b: ^Builder, pad: string, pad_len, remains: int) {