Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license 2 : : 3 : : #include <locale.h> 4 : : #include "libsupport.h" 5 : : 6 : : #ifndef _OS_WINDOWS_ 7 : : #include <sys/resource.h> 8 : : #endif 9 : : 10 : : #ifdef __cplusplus 11 : : extern "C" { 12 : : #endif 13 : : 14 : 30 : static const char *jl_strchrnul(const char *s, int c) 15 : : { 16 : 30 : char *p = strchr(s, c); 17 [ - + ]: 30 : if (p) 18 : 0 : return p; 19 : 30 : return s + strlen(s); 20 : : } 21 : : 22 : 90 : void libsupport_init(void) 23 : : { 24 : : static int isInitialized = 0; 25 [ + + ]: 90 : if (!isInitialized) { 26 : 30 : ios_init_stdstreams(); 27 : 30 : isInitialized = 1; 28 : : #ifndef _OS_WINDOWS_ 29 : : // Raise the open file descriptor limit. 30 : : { 31 : : struct rlimit rl; 32 [ + - + + ]: 30 : if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_cur != rl.rlim_max) { 33 : : // Do a binary search for the limit. 34 : 14 : rlim_t min = rl.rlim_cur; 35 : 14 : rlim_t max = 1 << 20; 36 : : // But if there's a defined upper bound, don't search, just set it. 37 [ + - ]: 14 : if (rl.rlim_max != RLIM_INFINITY) { 38 : 14 : min = rl.rlim_max; 39 : 14 : max = rl.rlim_max; 40 : : } 41 : : do { 42 : 14 : rl.rlim_cur = min + (max - min) / 2; 43 [ - + ]: 14 : if (setrlimit(RLIMIT_NOFILE, &rl)) { 44 : 0 : max = rl.rlim_cur; 45 : : } else { 46 : 14 : min = rl.rlim_cur; 47 : : } 48 [ - + ]: 14 : } while (min + 1 < max); 49 : : } 50 : : } 51 : : #endif 52 : : // adopt the user's locale for most formatting 53 : 30 : setlocale(LC_ALL, ""); 54 : : // but use locale-independent numeric formats (for parsing) 55 : 30 : setlocale(LC_NUMERIC, "C"); 56 : : // and try to specify ASCII or UTF-8 (preferred) for our Libc and Cstring functions 57 : 30 : char *ctype = setlocale(LC_CTYPE, NULL); 58 [ + - ]: 30 : if (ctype) { 59 : 30 : size_t codeset = jl_strchrnul(ctype, '.') - ctype; 60 [ + - ]: 30 : if (strncmp(ctype + codeset, ".UTF-8", strlen(".UTF-8")) == 0 || 61 [ + - ]: 30 : strncmp(ctype + codeset, ".utf-8", strlen(".utf-8")) == 0 || 62 [ - + ]: 30 : strncmp(ctype + codeset, ".utf8", strlen(".utf8")) == 0) 63 : 0 : return; // already UTF-8 64 : 30 : ctype = (char*)memcpy(malloc_s(codeset + sizeof(".UTF-8")), ctype, codeset); 65 : 30 : strcpy(ctype + codeset, ".UTF-8"); 66 : : } 67 : 30 : setlocale(LC_CTYPE, "C"); // ASCII 68 : : #ifndef _OS_WINDOWS_ 69 [ - + - - ]: 30 : if (setlocale(LC_CTYPE, "C.UTF-8") == NULL && // Linux/FreeBSD name 70 [ # # ]: 0 : setlocale(LC_CTYPE, "en_US.UTF-8") == NULL && // Common name 71 [ # # ]: 0 : setlocale(LC_CTYPE, "UTF-8") == NULL && // Apple name 72 [ # # ]: 0 : (ctype == NULL || setlocale(LC_CTYPE, ctype) == NULL)) { // attempt to form it manually 73 : 0 : ios_puts("WARNING: failed to select UTF-8 encoding, using ASCII\n", ios_stderr); 74 : : } 75 : : #endif 76 [ + - ]: 30 : if (ctype) 77 : 30 : free(ctype); 78 : : } 79 : : } 80 : : 81 : : #ifdef __cplusplus 82 : : } 83 : : #endif