1
+ #include <stdio.h>
2
+ #include <uchar.h>
3
+ #include "utils.h"
4
+
5
+ #ifndef TB_CONFIG_OS_WINDOWS
6
+ #include <unistd.h>
7
+ #endif
8
+
9
+ #if defined(TB_CONFIG_OS_WINDOWS )
10
+ #include <windows.h>
11
+ #elif defined(__COSMOPOLITAN__ )
12
+ #include <windowsesque.h>
13
+ #include <sys/utsname.h>
14
+ #define GetModuleFileNameW GetModuleFileName
15
+ #endif
16
+
17
+ // proc/self
18
+ #if defined(TB_CONFIG_OS_LINUX )
19
+ # define XM_PROC_SELF_FILE "/proc/self/exe"
20
+ #elif defined(TB_CONFIG_OS_BSD ) && !defined(__OpenBSD__ ) && !defined(__FreeBSD__ )
21
+ # if defined(__NetBSD__ )
22
+ # define XM_PROC_SELF_FILE "/proc/curproc/exe"
23
+ # else
24
+ # define XM_PROC_SELF_FILE "/proc/curproc/file"
25
+ # endif
26
+ #endif
27
+
28
+ tb_size_t char16_wcslen (char16_t const * s )
29
+ {
30
+ tb_assert_and_check_return_val (s , 0 );
31
+
32
+ __tb_register__ char16_t const * p = s ;
33
+
34
+ #ifdef __tb_small__
35
+ while (* p ) p ++ ;
36
+ return (p - s );
37
+ #else
38
+ while (1 )
39
+ {
40
+ if (!p [0 ]) return (p - s + 0 );
41
+ if (!p [1 ]) return (p - s + 1 );
42
+ if (!p [2 ]) return (p - s + 2 );
43
+ if (!p [3 ]) return (p - s + 3 );
44
+ p += 4 ;
45
+ }
46
+ return 0 ;
47
+ #endif
48
+ }
49
+
50
+ inline static tb_size_t char16_wcstombs_charset (tb_char_t * s1 , char16_t const * s2 , tb_size_t n )
51
+ {
52
+ // check
53
+ tb_assert_and_check_return_val (s1 && s2 , 0 );
54
+
55
+ // init
56
+ tb_long_t r = 0 ;
57
+ tb_size_t l = char16_wcslen (s2 );
58
+
59
+ // atow
60
+ if (l )
61
+ {
62
+ tb_size_t e = (sizeof (char16_t ) == 4 ) ? TB_CHARSET_TYPE_UTF32 : TB_CHARSET_TYPE_UTF16 ;
63
+ r = tb_charset_conv_data (e | TB_CHARSET_TYPE_LE , TB_CHARSET_TYPE_UTF8 , (tb_byte_t const * )s2 , l * sizeof (char16_t ), (tb_byte_t * )s1 , n );
64
+ }
65
+
66
+ // strip
67
+ if (r >= 0 ) s1 [r ] = '\0' ;
68
+
69
+ // ok?
70
+ return r > 0 ? r : -1 ;
71
+ }
72
+
73
+
74
+ void _get_sys_name (tb_char_t * name ) {
75
+ #if defined(__COSMOPOLITAN__ )
76
+ struct utsname buffer ;
77
+ if (uname (& buffer ) == 0 ) {
78
+ if (tb_strstr (buffer .sysname , "Darwin" ))
79
+ tb_strcpy (name , "macosx" );
80
+ else if (tb_strstr (buffer .sysname , "Linux" ))
81
+ tb_strcpy (name , "linux" );
82
+ else if (tb_strstr (buffer .sysname , "Windows" ))
83
+ tb_strcpy (name , "windows" );
84
+ }
85
+ #elif defined(TB_CONFIG_OS_WINDOWS )
86
+ tb_strcpy (name , "windows" );
87
+ #elif defined(TB_CONFIG_OS_MACOSX )
88
+ tb_strcpy (name , "macosx" );
89
+ #elif defined(TB_CONFIG_OS_LINUX )
90
+ tb_strcpy (name , "linux" );
91
+ #endif
92
+ }
93
+
94
+ void _get_program_file (tb_char_t * path ) {
95
+
96
+ tb_char_t sysname [16 ];
97
+ _get_sys_name (sysname );
98
+ tb_size_t maxn = TB_PATH_MAXN ;
99
+ tb_bool_t ok = tb_false ;
100
+
101
+ if (tb_strstr (sysname , "windows" )) {
102
+ #if defined(TB_CONFIG_OS_WINDOWS ) || defined(__COSMOPOLITAN__ )
103
+ // get the executale file path as program directory
104
+ printf ("%lld\n" , sizeof (tb_wchar_t ));
105
+ #ifdef __COSMOPOLITAN__
106
+ char16_t buf [TB_PATH_MAXN ] = { 0 };
107
+ tb_size_t size = (tb_size_t )GetModuleFileNameW ((int64_t )tb_null , (char16_t * )buf , (DWORD )TB_PATH_MAXN );
108
+ char16_wcstombs_charset (path , buf , maxn );
109
+ #else
110
+ tb_wchar_t buf [TB_PATH_MAXN ] = { 0 };
111
+ tb_size_t size = (tb_size_t )GetModuleFileNameW (tb_null , buf , TB_PATH_MAXN );
112
+ buf [size ] = L'\0' ;
113
+ size = tb_wcstombs (path , buf , maxn );
114
+ #endif
115
+ path [size ] = '\0' ;
116
+ #endif
117
+ }
118
+ else if (tb_strstr (sysname , "linux" )) {
119
+ #if defined(TB_CONFIG_OS_LINUX )
120
+ // get the executale file path as program directory
121
+ ssize_t size = readlink (XM_PROC_SELF_FILE , path , (size_t )maxn );
122
+ if (size > 0 && size < maxn )
123
+ {
124
+ path [size ] = '\0' ;
125
+ ok = tb_true ;
126
+ }
127
+ #endif
128
+ } else if (tb_strstr (sysname , "macosx" )) {
129
+ #if defined(TB_CONFIG_OS_MACOSX )
130
+ /*
131
+ * _NSGetExecutablePath() copies the path of the main executable into the buffer. The bufsize parameter
132
+ * should initially be the size of the buffer. The function returns 0 if the path was successfully copied,
133
+ * and *bufsize is left unchanged. It returns -1 if the buffer is not large enough, and *bufsize is set
134
+ * to the size required.
135
+ *
136
+ * Note that _NSGetExecutablePath will return "a path" to the executable not a "real path" to the executable.
137
+ * That is the path may be a symbolic link and not the real file. With deep directories the total bufsize
138
+ * needed could be more than MAXPATHLEN.
139
+ */
140
+ tb_uint32_t bufsize = (tb_uint32_t )maxn ;
141
+ if (!_NSGetExecutablePath (path , & bufsize ))
142
+ ok = tb_true ;
143
+ #endif
144
+ }
145
+ }
0 commit comments