28 template <
typename Character>
35 size_t size()
const throw() {
return _last - _first; }
37 Character**
end()
const throw() {
return _last; }
41 errno_t const expand_status = expand_if_necessary();
42 if (expand_status != 0)
57 Character**
const first = _first;
64 for (
auto it = _first; it != _last; ++it)
85 size_t const initial_count = 4;
87 _first = _calloc_crt_t(Character*, initial_count).detach();
92 _end = _first + initial_count;
98 size_t const old_count = _end - _first;
102 size_t const new_count = old_count * 2;
103 __crt_unique_heap_ptr<Character*> new_array(_recalloc_crt_t(Character*, _first, new_count));
107 _first = new_array.detach();
108 _last = _first + old_count;
109 _end = _first + new_count;
125 return reinterpret_cast<char*
>(
_mbsdec(
126 reinterpret_cast<unsigned char*
>(
first),
127 reinterpret_cast<unsigned char*
>(
current)));
137template <
typename Character>
141 size_t const directory_length,
142 argument_list<Character>&
buffer
147 size_t const file_name_count = traits::tcslen(
file_name) + 1;
148 if (file_name_count >
SIZE_MAX - directory_length)
151 size_t const required_count = directory_length + file_name_count + 1;
152 __crt_unique_heap_ptr<Character> argument_buffer(_calloc_crt_t(Character, required_count));
154 if (directory_length > 0)
156 _ERRCHECK(traits::tcsncpy_s(argument_buffer.get(), required_count,
directory, directory_length));
160 argument_buffer.get() + directory_length,
161 required_count - directory_length,
165 return buffer.append(argument_buffer.detach());
211template <
typename Character>
213 Character*
const argument,
214 Character*
const wildcard,
215 argument_list<Character>&
buffer
219 typedef typename traits::win32_find_data_type find_data_type;
221 auto const is_directory_separator = [](Character
const c) {
return c ==
'/' ||
c ==
'\\' ||
c ==
':'; };
224 Character* it = wildcard;
225 while (it != argument && !is_directory_separator(*it))
232 if (*it ==
':' && it != argument + 1)
237 size_t const directory_length = is_directory_separator(*it)
246 get_wide(&wide_file_name, argument),
259 size_t const old_argument_count =
buffer.size();
285 size_t const new_argument_count =
buffer.size();
286 if (old_argument_count == new_argument_count)
293 buffer.begin() + old_argument_count,
294 new_argument_count - old_argument_count,
296 [](
void const* lhs,
void const* rhs) ->
int
298 if (lhs < rhs) { return -1; }
299 if (lhs > rhs) {
return 1; }
307template <
typename Character>
315 argument_list<Character> expansion_buffer;
316 for (Character** it =
argv; *it !=
nullptr; ++it)
318 Character
const wildcard_characters[] = {
'*',
'?',
'\0' };
319 Character*
const wildcard = traits::tcspbrk(*it, wildcard_characters);
327 static_cast<Character*
>(
nullptr),
331 if (append_status != 0)
332 return append_status;
337 if (expand_status != 0)
338 return expand_status;
345 size_t const argument_count = expansion_buffer.size() + 1;
347 for (
auto it = expansion_buffer.begin(); it != expansion_buffer.end(); ++it)
358 Character**
const argument_first =
reinterpret_cast<Character**
>(expanded_argv.get());
359 Character*
const character_first =
reinterpret_cast<Character*
>(
360 expanded_argv.get() +
361 argument_count *
sizeof(Character*));
363 Character** argument_it = argument_first;
364 Character* character_it = character_first;
365 for (
auto it = expansion_buffer.begin(); it != expansion_buffer.end(); ++it)
367 size_t const count = traits::tcslen(*it) + 1;
375 *argument_it++ = character_it;
376 character_it +=
count;
379 *
result =
reinterpret_cast<Character**
>(expanded_argv.detach());
unsigned char *__cdecl __acrt_allocate_buffer_for_argv(size_t const argument_count, size_t const character_count, size_t const character_size)
static errno_t expand_argument_wildcards(Character *const argument, Character *const wildcard, argument_list< Character > &buffer)
static errno_t copy_and_add_argument_to_buffer(_In_z_ Character const *const file_name, _In_z_ Character const *const directory, size_t const directory_length, argument_list< Character > &buffer)
static _Check_return_ char * previous_character(_In_reads_z_(current - first+1) char *const first, _In_z_ char *const current)
static wchar_t * get_wide(__crt_internal_win32_buffer< wchar_t > *const dest, char *const source)
static errno_t common_expand_argv_wildcards(Character **const argv, Character ***const result)
errno_t __acrt_expand_wide_argv_wildcards(wchar_t **const argv, wchar_t ***const result)
errno_t __acrt_expand_narrow_argv_wildcards(char **const argv, char ***const result)
argument_list(argument_list const &)
argument_list & operator=(argument_list const &)
errno_t expand_if_necessary()
Character ** begin() const
errno_t append(Character *const element)
_In_ size_t character_count
errno_t __acrt_mbs_to_wcs_cp(char const *const null_terminated_input_string, __crt_win32_buffer< wchar_t, ResizePolicy > &win32_buffer, unsigned int const code_page)
errno_t __acrt_wcs_to_mbs_cp(wchar_t const *const null_terminated_input_string, __crt_win32_buffer< char, ResizePolicy > &win32_buffer, unsigned int const code_page)
unsigned int __acrt_get_utf8_acp_compatibility_codepage()
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
#define INVALID_HANDLE_VALUE
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
HANDLE WINAPI FindFirstFileExW(IN LPCWSTR lpFileName, IN FINDEX_INFO_LEVELS fInfoLevelId, OUT LPVOID lpFindFileData, IN FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, IN DWORD dwAdditionalFlags)
static char * cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
GLuint GLuint GLsizei count
_Check_return_ _CRTIMP unsigned char *__cdecl _mbsdec(_In_reads_z_(_Pos-_Start+1) const unsigned char *_Start, _In_z_ const unsigned char *_Pos)
#define _VALIDATE_RETURN_ERRCODE(expr, errorcode)
struct task_struct * current