The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #13497 from dra27/caml_stat_strndup

Add `caml_stat_char_array_{to,of}_os`

authored by

Gabriel Scherer and committed by
GitHub
be96495a 137dd26a

+161 -18
+7
Changes
··· 14 14 15 15 ### Runtime system: 16 16 17 + * #11449, #13497: Add caml_stat_char_array_{to,of}_os functions allowing 18 + conversion of string data which may contain NUL characters. Correct 19 + implementation of caml_stat_strdup_to_utf16 to raise Out_of_memory instead of 20 + returning of NULL (the behaviour of caml_stat_strdup_to_os was inconsistent 21 + between Unix/Windows). 22 + (David Allsopp, review by Nick Barnes, Antonin Décimo and Miod Vallat) 23 + 17 24 - #13352: Concurrency refactors and cleanups. 18 25 (Antonin Décimo, review by Gabriel Scherer, David Allsopp, and Miod Vallat) 19 26
+10
runtime/caml/memory.h
··· 166 166 CAMLextern wchar_t* caml_stat_wcsdup_noexc(const wchar_t *s); 167 167 #endif 168 168 169 + /* [caml_stat_memdup(s, size, &out_size)] returns a copy of the first [size] 170 + bytes of [s] (which may include NUL characters). If [out_size] is not [NULL], 171 + then [size] is stored in [*out_size]. This function is the "dummy" Unix 172 + implementation of the Windows-only functions 173 + caml_stat_char_array_{to,from}_utf16. 174 + */ 175 + CAMLmalloc(caml_stat_free, 1, 2) CAMLreturns_nonnull() 176 + CAMLextern caml_stat_string caml_stat_memdup(const char *s, asize_t size, 177 + asize_t *out_size); 178 + 169 179 /* [caml_stat_strconcat(nargs, strings)] concatenates null-terminated [strings] 170 180 (an array of [char*] of size [nargs]) into a new string, dropping all NULs, 171 181 except for the very last one. It throws an OCaml exception in case the
+6
runtime/caml/misc.h
··· 523 523 #define caml_stat_strconcat_os caml_stat_wcsconcat 524 524 525 525 #define caml_stat_strdup_to_os caml_stat_strdup_to_utf16 526 + #define caml_stat_strdup_noexc_to_os caml_stat_strdup_noexc_to_utf16 526 527 #define caml_stat_strdup_of_os caml_stat_strdup_of_utf16 527 528 #define caml_stat_strdup_noexc_of_os caml_stat_strdup_noexc_of_utf16 529 + #define caml_stat_char_array_to_os caml_stat_char_array_to_utf16 530 + #define caml_stat_char_array_of_os caml_stat_char_array_of_utf16 528 531 #define caml_copy_string_of_os caml_copy_string_of_utf16 529 532 530 533 #else /* _WIN32 */ ··· 565 568 #define caml_stat_strconcat_os caml_stat_strconcat 566 569 567 570 #define caml_stat_strdup_to_os caml_stat_strdup 571 + #define caml_stat_strdup_noexc_to_os caml_stat_strdup_noexc 568 572 #define caml_stat_strdup_of_os caml_stat_strdup 569 573 #define caml_stat_strdup_noexc_of_os caml_stat_strdup_noexc 574 + #define caml_stat_char_array_to_os caml_stat_memdup 575 + #define caml_stat_char_array_of_os caml_stat_memdup 570 576 #define caml_copy_string_of_os caml_copy_string 571 577 572 578 #endif /* _WIN32 */
+72 -11
runtime/caml/osdeps.h
··· 164 164 extern unsigned short caml_win32_build; 165 165 extern unsigned short caml_win32_revision; 166 166 167 - /* [caml_stat_strdup_to_utf16(s)] returns a null-terminated copy of [s], 167 + /* [caml_stat_strdup_noexc_to_utf16(s)] returns a NUL-terminated copy of [s], 168 168 re-encoded in UTF-16. The encoding of [s] is assumed to be UTF-8 if 169 169 [caml_windows_unicode_runtime_enabled] is non-zero **and** [s] is valid 170 170 UTF-8, or the current Windows code page otherwise. 171 171 172 - The returned string is allocated with [caml_stat_alloc], so it should be free 173 - using [caml_stat_free]. 172 + The returned string is allocated with [caml_stat_alloc_noexc], so it should 173 + be freed using [caml_stat_free]. 174 + 175 + If allocation fails, this returns NULL. This function never raises any 176 + exceptions when [s] is valid UTF-8 but may raise [Sys_error] if it is not. 174 177 */ 178 + CAMLalloc(caml_stat_free, 1) 179 + CAMLextern wchar_t* caml_stat_strdup_noexc_to_utf16(const char *s); 180 + 181 + /* [caml_stat_strdup_to_utf16(s)] returns a NUL-terminated copy of [s], 182 + re-encoded in UTF-16. The encoding of [s] is assumed to be UTF-8 if 183 + [caml_windows_unicode_runtime_enabled] is non-zero **and** [s] is valid 184 + UTF-8, or the current Windows code page otherwise. 185 + 186 + The returned string is allocated with [caml_stat_alloc], so it should be 187 + freed using [caml_stat_free]. 188 + 189 + If allocation fails, this raises Out_of_memory. This function may also raise 190 + [Sys_error] if [s] is not valid UTF-8. 191 + */ 192 + CAMLalloc(caml_stat_free, 1) CAMLreturns_nonnull() 175 193 CAMLextern wchar_t* caml_stat_strdup_to_utf16(const char *s); 176 194 177 - /* [caml_stat_strdup_noexc_of_utf16(s)] returns a null-terminated copy of [s], 195 + /* [caml_stat_strdup_noexc_of_utf16(s)] returns a NUL-terminated copy of [s], 178 196 re-encoded in UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero or 179 197 the current Windows code page otherwise. 180 198 181 - The returned string is allocated with [caml_stat_alloc_noexc], so 182 - it should be freed using [caml_stat_free]. 199 + The returned string is allocated with [caml_stat_alloc_noexc], so it should 200 + be freed using [caml_stat_free]. 183 201 184 - If allocation fails, this returns NULL. 202 + If allocation fails, this returns NULL. This function never raises any 203 + exceptions when [s] is valid UTF-16 but may raise [Sys_error] if it is not. 185 204 */ 205 + CAMLalloc(caml_stat_free, 1) 186 206 CAMLextern char* caml_stat_strdup_noexc_of_utf16(const wchar_t *s); 187 207 188 - /* [caml_stat_strdup_of_utf16(s)] returns a null-terminated copy of [s], 208 + /* [caml_stat_strdup_of_utf16(s)] returns a NUL-terminated copy of [s], 189 209 re-encoded in UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero or 190 210 the current Windows code page otherwise. 191 211 192 - The returned string is allocated with [caml_stat_alloc_noexc], so 193 - it should be freed using [caml_stat_free]. 212 + The returned string is allocated with [caml_stat_alloc], so it should be 213 + freed using [caml_stat_free]. 194 214 195 - If allocation fails, this raises Out_of_memory. 215 + If allocation fails, this raises Out_of_memory. This function may also raise 216 + [Sys_error] if [s] is not valid UTF-16. 196 217 */ 218 + CAMLalloc(caml_stat_free, 1) CAMLreturns_nonnull() 197 219 CAMLextern char* caml_stat_strdup_of_utf16(const wchar_t *s); 220 + 221 + /* [caml_stat_char_array_to_utf16(s, size, &out_size)] returns a copy of the 222 + first [size] bytes of [s] re-encoded in UTF-16. [s] does not have to be NUL- 223 + terminated and may contain embedded NUL characters. The encoding of [s] is 224 + assumed to be UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero 225 + **and** [s] is valid UTF-8, or the current Windows code page otherwise. If 226 + [out_size] is not [NULL], then the number of UTF-16 code units in the result 227 + is recorded in [*out_size]. 228 + 229 + [size] must be greater than zero. 230 + 231 + The returned buffer is allocated with [caml_stat_alloc], so it should be 232 + freed using [caml_stat_free]. 233 + 234 + If allocation fails, this raises Out_of_memory. This function may also raise 235 + [Sys_error] if [s] is not valid UTF-8. 236 + */ 237 + CAMLmalloc(caml_stat_free, 1, 2) CAMLreturns_nonnull() 238 + CAMLextern wchar_t *caml_stat_char_array_to_utf16(const char *s, size_t size, 239 + size_t *out_size); 240 + 241 + /* [caml_stat_char_array_of_utf16(s, size, &out_size)] returns a copy of the 242 + first [size] UTF-16 code units of [s] re-encoded in UTF-8 if 243 + [caml_windows_unicode_runtime_enabled] is non-zero or the current Windows 244 + code page otherwise. [s] does not have to be NUL-terminated and may contain 245 + embedded NUL characters. If [out_size] is not [NULL], then the size of the 246 + result in bytes recorded in [*out_size]. 247 + 248 + [size] must be greater than zero. 249 + 250 + The returned buffer is allocated with [caml_stat_alloc], so it should be 251 + freed using [caml_stat_free]. 252 + 253 + If allocation fails, this raises Out_of_memory. This function may also raise 254 + [Sys_error] if [s] is not valid UTF-16. 255 + */ 256 + CAMLalloc(caml_stat_free, 1) CAMLreturns_nonnull() 257 + CAMLextern char *caml_stat_char_array_of_utf16(const wchar_t *s, size_t size, 258 + size_t *out_size); 198 259 199 260 /* [caml_copy_string_of_utf16(s)] returns an OCaml string containing a copy of 200 261 [s] re-encoded in UTF-8 if [caml_windows_unicode_runtime_enabled] is non-zero
+11
runtime/memory.c
··· 729 729 return result; 730 730 } 731 731 732 + CAMLexport caml_stat_string caml_stat_memdup(const char *s, asize_t size, 733 + asize_t *out_size) 734 + { 735 + CAMLassert(size > 0); 736 + caml_stat_block result = caml_stat_alloc(size); 737 + memcpy(result, s, size); 738 + if (out_size != NULL) 739 + *out_size = size; 740 + return result; 741 + } 742 + 732 743 #ifdef _WIN32 733 744 734 745 CAMLexport wchar_t * caml_stat_wcsdup_noexc(const wchar_t *s)
+55 -7
runtime/win32.c
··· 951 951 return v; 952 952 } 953 953 954 - CAMLexport wchar_t* caml_stat_strdup_to_utf16(const char *s) 954 + Caml_inline wchar_t *char_array_to_utf16_noexc(const char *s, 955 + int slen, size_t *out_size) 955 956 { 956 957 wchar_t * ws; 957 958 int retcode; 958 959 959 - retcode = caml_win32_multi_byte_to_wide_char(s, -1, NULL, 0); 960 - ws = caml_stat_alloc_noexc(retcode * sizeof(*ws)); 961 - caml_win32_multi_byte_to_wide_char(s, -1, ws, retcode); 960 + retcode = caml_win32_multi_byte_to_wide_char(s, slen, NULL, 0); 961 + ws = caml_stat_alloc_noexc(retcode * sizeof(wchar_t)); 962 + if (ws != NULL) { 963 + caml_win32_multi_byte_to_wide_char(s, slen, ws, retcode); 964 + if (out_size != NULL) 965 + *out_size = retcode; 966 + } 962 967 963 968 return ws; 964 969 } 965 970 966 - CAMLexport caml_stat_string caml_stat_strdup_noexc_of_utf16(const wchar_t *s) 971 + CAMLexport wchar_t *caml_stat_strdup_noexc_to_utf16(const char *s) 972 + { 973 + return char_array_to_utf16_noexc(s, -1, NULL); 974 + } 975 + 976 + CAMLexport wchar_t *caml_stat_strdup_to_utf16(const char *s) 977 + { 978 + wchar_t *out = caml_stat_strdup_noexc_to_utf16(s); 979 + if (out == NULL) 980 + caml_raise_out_of_memory(); 981 + return out; 982 + } 983 + 984 + CAMLexport wchar_t *caml_stat_char_array_to_utf16(const char *s, size_t size, 985 + size_t *out_size) 986 + { 987 + CAMLassert(size > 0); 988 + wchar_t *out = char_array_to_utf16_noexc(s, size, out_size); 989 + if (out == NULL) 990 + caml_raise_out_of_memory(); 991 + return out; 992 + } 993 + 994 + Caml_inline caml_stat_string char_array_of_utf16_noexc(const wchar_t *s, 995 + int slen, 996 + size_t *out_size) 967 997 { 968 998 caml_stat_string out; 969 999 int retcode; 970 1000 971 - retcode = caml_win32_wide_char_to_multi_byte(s, -1, NULL, 0); 1001 + retcode = caml_win32_wide_char_to_multi_byte(s, slen, NULL, 0); 972 1002 out = caml_stat_alloc_noexc(retcode); 973 1003 if (out != NULL) { 974 - caml_win32_wide_char_to_multi_byte(s, -1, out, retcode); 1004 + caml_win32_wide_char_to_multi_byte(s, slen, out, retcode); 1005 + if (out_size != NULL) 1006 + *out_size = retcode; 975 1007 } 976 1008 977 1009 return out; 978 1010 } 979 1011 1012 + CAMLexport caml_stat_string caml_stat_strdup_noexc_of_utf16(const wchar_t *s) 1013 + { 1014 + return char_array_of_utf16_noexc(s, -1, NULL); 1015 + } 1016 + 980 1017 CAMLexport caml_stat_string caml_stat_strdup_of_utf16(const wchar_t *s) 981 1018 { 982 1019 caml_stat_string out = caml_stat_strdup_noexc_of_utf16(s); 1020 + if (out == NULL) 1021 + caml_raise_out_of_memory(); 1022 + return out; 1023 + } 1024 + 1025 + CAMLexport caml_stat_string caml_stat_char_array_of_utf16(const wchar_t *s, 1026 + size_t size, 1027 + size_t *out_size) 1028 + { 1029 + CAMLassert(size > 0); 1030 + caml_stat_string out = char_array_of_utf16_noexc(s, size, out_size); 983 1031 if (out == NULL) 984 1032 caml_raise_out_of_memory(); 985 1033 return out;