17#pragma warning(disable:__WARNING_POSTCONDITION_NULLTERMINATION_VIOLATION)
23template <
typename Character>
25 Character
const*
const*
const argv,
26 Character**
const command_line_result
31 *command_line_result =
nullptr;
35 size_t const command_line_count = [&]
38 for (Character
const*
const* it =
argv; *it;
n += traits::tcslen(*it++) + 1) { }
45 __crt_unique_heap_ptr<Character> command_line(_calloc_crt_t(Character, command_line_count));
52 Character
const*
const* source_it =
argv;
53 Character* result_it = command_line.get();
56 if (*source_it ==
nullptr)
58 *command_line_result = command_line.detach();
63 while (*source_it !=
nullptr)
65 _ERRCHECK(traits::tcscpy_s(result_it, command_line_count - (result_it - command_line.get()), *source_it));
66 result_it += traits::tcslen(*source_it);
74 *command_line_result = command_line.detach();
84template <
typename Character>
92 *environment_block_result =
nullptr;
104 Character
const system_root_name[] = {
'S',
'y',
's',
't',
'e',
'm',
'R',
'o',
'o',
't',
'\0' };
106 __crt_unique_heap_ptr<Character> system_root_value;
107 if (
_ERRCHECK_EINVAL(traits::tdupenv_s_crt(system_root_value.get_address_of(),
nullptr, system_root_name)) != 0)
110 size_t const system_root_value_count = system_root_value
111 ? traits::tcslen(system_root_value.get()) + 1
114 size_t const system_root_count =
_countof(system_root_name) + system_root_value_count;
118 size_t const envp_count = [&]
121 for (
auto it = envp; *it !=
nullptr;
n += traits::tcslen(*it++) + 1) { }
128 __crt_unique_heap_ptr<Character>
const os_environment(traits::get_environment_from_os());
133 Character*
const first_cwd = [&]
135 Character* it = os_environment.get();
137 it += traits::tcslen(it) + 1;
142 Character*
const last_cwd = [&]
144 Character* it = first_cwd;
145 while (it[0] ==
'=' && it[1] !=
'\0' && it[2] ==
':' && it[3] ==
'=')
146 it += 4 + traits::tcslen(it + 4) + 1;
150 size_t const cwd_count = last_cwd - first_cwd;
154 bool const system_root_defined_in_environment = [&]
156 for (
auto it = envp; *it !=
nullptr; ++it)
158 if (traits::tcsnicmp(*it, system_root_name, traits::tcslen(system_root_name)) == 0)
166 size_t const environment_block_count = system_root_defined_in_environment
167 ? envp_count + cwd_count
168 : envp_count + cwd_count + system_root_count;
170 __crt_unique_heap_ptr<Character> environment_block(_calloc_crt_t(Character, environment_block_count));
171 if (!environment_block)
179 Character* result_it = environment_block.get();
180 size_t remaining_characters = environment_block_count;
185 memcpy(result_it, first_cwd, cwd_count *
sizeof(Character));
186 result_it += cwd_count;
187 remaining_characters -= cwd_count;
191 for (
auto it = envp; *it !=
nullptr; ++it)
193 _ERRCHECK(traits::tcscpy_s(result_it, remaining_characters, *it));
195 size_t const count_copied = traits::tcslen(*it) + 1;
196 result_it += count_copied;
197 remaining_characters -= count_copied;
201 if (!system_root_defined_in_environment)
203 static Character
const equal_sign[] = {
'=',
'\0' };
205 _ERRCHECK(traits::tcscpy_s(result_it, system_root_count, system_root_name));
206 _ERRCHECK(traits::tcscat_s(result_it, system_root_count, equal_sign));
207 if (system_root_value)
209 _ERRCHECK(traits::tcscat_s(result_it, system_root_count, system_root_value.get()));
211 result_it += system_root_count;
216 if (result_it == environment_block.get())
221 *environment_block_result = environment_block.detach();
232template <
typename Character>
244 __crt_unique_heap_ptr<Character> command_line;
248 __crt_unique_heap_ptr<Character> environment_block;
252 *command_line_result = command_line.detach();
253 *environment_block_result = environment_block.detach();
258 char const*
const*
const argv,
259 char const*
const*
const envp,
260 char**
const command_line_result,
261 char**
const environment_block_result
268 wchar_t const*
const*
const argv,
269 wchar_t const*
const*
const envp,
270 wchar_t**
const command_line_result,
271 wchar_t**
const environment_block_result
285template <
typename Character>
287static Character**
__cdecl common_capture_argv(
295 Character**
argv = caller_array;
298 __crt_unique_heap_ptr<Character*> local_array;
301 Character* next_argument =
const_cast<Character*
>(
first_argument);
311 if (
argv == caller_array)
313 local_array = _calloc_crt_t(Character*, argv_count * 2);
318 argv = local_array.get();
324 __crt_unique_heap_ptr<Character*> new_array(_recalloc_crt_t(Character*, local_array.get(), argv_count * 2));
327 local_array.detach();
328 local_array.attach(new_array.detach());
330 argv = local_array.get();
336 argv[
i++] = next_argument;
340#pragma warning(suppress:__WARNING_INCORRECT_ANNOTATION)
347 local_array.detach();
354 char**
const caller_array,
364 wchar_t**
const caller_array,
int __cdecl __acrt_pack_narrow_command_line_and_environment(char const *const *const argv, char const *const *const envp, char **const command_line_result, char **const environment_block_result)
_In_z_ Character const *const first_argument
static errno_t __cdecl construct_command_line(Character const *const *const argv, Character **const command_line_result)
static errno_t __cdecl construct_environment_block(_In_opt_z_ Character const *const *const envp, _Outptr_result_maybenull_ Character **const environment_block_result)
int __cdecl __acrt_pack_wide_command_line_and_environment(wchar_t const *const *const argv, wchar_t const *const *const envp, wchar_t **const command_line_result, wchar_t **const environment_block_result)
wchar_t ** __acrt_capture_wide_argv(va_list *const arglist, wchar_t const *const first_argument, wchar_t **const caller_array, size_t const caller_array_count)
_In_z_ Character const *const _In_ size_t const caller_array_count throw()
static int __cdecl common_pack_argv_and_envp(_In_z_ Character const *const *const argv, _In_opt_z_ Character const *const *const envp, _Outptr_result_maybenull_ Character **const command_line_result, _Outptr_result_maybenull_ Character **const environment_block_result)
char ** __acrt_capture_narrow_argv(va_list *const arglist, char const *const first_argument, char **const caller_array, size_t const caller_array_count)
_Ret_z_ _In_z_ char const _In_ size_t caller_array_count
void __cdecl __acrt_errno_map_os_error(unsigned long)
#define _ERRCHECK_EINVAL(e)
#define ERROR_NOT_ENOUGH_MEMORY
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define _VALIDATE_RETURN_NOEXC(expr, errorcode, retexpr)
#define memcpy(s1, s2, n)
#define _Outptr_result_maybenull_
#define _Ret_range_(l, h)
int CDECL memcpy_s(void *dest, size_t numberOfElements, const void *src, size_t count)