ReactOS 0.4.16-dev-889-g9563c07
argv_wildcards.cpp File Reference
#include <corecrt_internal.h>
#include <ctype.h>
#include <corecrt_internal_traits.h>
#include <limits.h>
#include <mbstring.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <wrl/wrappers/corewrappers.h>
Include dependency graph for argv_wildcards.cpp:

Go to the source code of this file.

Classes

class  anonymous_namespace{argv_wildcards.cpp}::argument_list< Character >
 

Namespaces

namespace  anonymous_namespace{argv_wildcards.cpp}
 

Functions

static _Check_return_ charprevious_character (_In_reads_z_(current - first+1) char *const first, _In_z_ char *const current) throw ()
 
static wchar_tprevious_character (_In_reads_(0) wchar_t *, _In_reads_(0) wchar_t *const current) throw ()
 
template<typename Character >
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) throw ()
 
static wchar_tget_wide (__crt_internal_win32_buffer< wchar_t > *const dest, char *const source)
 
static wchar_tget_wide (__crt_internal_win32_buffer< wchar_t > *, wchar_t *const source)
 
static charget_file_name (__crt_internal_win32_buffer< char > *const dest, wchar_t *const source)
 
static wchar_tget_file_name (__crt_internal_win32_buffer< wchar_t > *, wchar_t *const source)
 
template<typename Character >
static errno_t expand_argument_wildcards (Character *const argument, Character *const wildcard, argument_list< Character > &buffer) throw ()
 
template<typename Character >
static errno_t common_expand_argv_wildcards (Character **const argv, Character ***const result) throw ()
 
errno_t __acrt_expand_narrow_argv_wildcards (char **const argv, char ***const result)
 
errno_t __acrt_expand_wide_argv_wildcards (wchar_t **const argv, wchar_t ***const result)
 

Function Documentation

◆ __acrt_expand_narrow_argv_wildcards()

errno_t __acrt_expand_narrow_argv_wildcards ( char **const  argv,
char ***const  result 
)

Definition at line 383 of file argv_wildcards.cpp.

384{
386}
static errno_t common_expand_argv_wildcards(Character **const argv, Character ***const result)
GLuint64EXT * result
Definition: glext.h:11304
#define argv
Definition: mplay32.c:18

Referenced by expand_argv_wildcards().

◆ __acrt_expand_wide_argv_wildcards()

errno_t __acrt_expand_wide_argv_wildcards ( wchar_t **const  argv,
wchar_t ***const  result 
)

Definition at line 388 of file argv_wildcards.cpp.

389{
391}

Referenced by expand_argv_wildcards().

◆ common_expand_argv_wildcards()

template<typename Character >
static errno_t common_expand_argv_wildcards ( Character **const  argv,
Character ***const  result 
)
throw (
)
static

Definition at line 308 of file argv_wildcards.cpp.

309{
310 typedef __crt_char_traits<Character> traits;
311
313 *result = nullptr;
314
315 argument_list<Character> expansion_buffer;
316 for (Character** it = argv; *it != nullptr; ++it)
317 {
318 Character const wildcard_characters[] = { '*', '?', '\0' };
319 Character* const wildcard = traits::tcspbrk(*it, wildcard_characters);
320
321 // If no wildcard characters were found in the argument string, just
322 // append it to the list and continue on. Otherwise, do the expansion:
323 if (!wildcard)
324 {
325 errno_t const append_status = copy_and_add_argument_to_buffer(
326 *it,
327 static_cast<Character*>(nullptr),
328 0,
329 expansion_buffer);
330
331 if (append_status != 0)
332 return append_status;
333 }
334 else
335 {
336 errno_t const expand_status = expand_argument_wildcards(*it, wildcard, expansion_buffer);
337 if (expand_status != 0)
338 return expand_status;
339 }
340 }
341
342 // Now that we've accumulated the expanded arguments into the expansion
343 // buffer, we want to re-pack them in the form used by the argv parser,
344 // in a single array, with everything "concatenated" together.
345 size_t const argument_count = expansion_buffer.size() + 1;
346 size_t character_count = 0;
347 for (auto it = expansion_buffer.begin(); it != expansion_buffer.end(); ++it)
348 character_count += traits::tcslen(*it) + 1;
349
350 __crt_unique_heap_ptr<unsigned char> expanded_argv(__acrt_allocate_buffer_for_argv(
351 argument_count,
353 sizeof(Character)));
354
355 if (!expanded_argv)
356 return -1;
357
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*));
362
363 Character** argument_it = argument_first;
364 Character* character_it = character_first;
365 for (auto it = expansion_buffer.begin(); it != expansion_buffer.end(); ++it)
366 {
367 size_t const count = traits::tcslen(*it) + 1;
368
369 _ERRCHECK(traits::tcsncpy_s(
370 character_it,
371 character_count - (character_it - character_first),
372 *it,
373 count));
374
375 *argument_it++ = character_it;
376 character_it += count;
377 }
378
379 *result = reinterpret_cast<Character**>(expanded_argv.detach());
380 return 0;
381}
#define EINVAL
Definition: acclib.h:90
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)
_In_ size_t character_count
#define _ERRCHECK(e)
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define _VALIDATE_RETURN_ERRCODE(expr, errorcode)
int errno_t
Definition: corecrt.h:615

Referenced by __acrt_expand_narrow_argv_wildcards(), and __acrt_expand_wide_argv_wildcards().

◆ copy_and_add_argument_to_buffer()

template<typename Character >
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 
)
throw (
)
static

Definition at line 138 of file argv_wildcards.cpp.

144{
145 typedef __crt_char_traits<Character> traits;
146
147 size_t const file_name_count = traits::tcslen(file_name) + 1;
148 if (file_name_count > SIZE_MAX - directory_length)
149 return ENOMEM;
150
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));
153
154 if (directory_length > 0)
155 {
156 _ERRCHECK(traits::tcsncpy_s(argument_buffer.get(), required_count, directory, directory_length));
157 }
158
159 _ERRCHECK(traits::tcsncpy_s(
160 argument_buffer.get() + directory_length,
161 required_count - directory_length,
162 file_name,
163 file_name_count));
164
165 return buffer.append(argument_buffer.detach());
166}
#define ENOMEM
Definition: acclib.h:84
GLuint buffer
Definition: glext.h:5915
static LPCWSTR file_name
Definition: protocol.c:147
#define SIZE_MAX
Definition: compat.h:66

Referenced by common_expand_argv_wildcards(), and expand_argument_wildcards().

◆ expand_argument_wildcards()

template<typename Character >
static errno_t expand_argument_wildcards ( Character *const  argument,
Character *const  wildcard,
argument_list< Character > &  buffer 
)
throw (
)
static

Definition at line 212 of file argv_wildcards.cpp.

217{
218 typedef __crt_char_traits<Character> traits;
219 typedef typename traits::win32_find_data_type find_data_type;
220
221 auto const is_directory_separator = [](Character const c) { return c == '/' || c == '\\' || c == ':'; };
222
223 // Find the first slash or colon before the wildcard:
224 Character* it = wildcard;
225 while (it != argument && !is_directory_separator(*it))
226 {
227 it = previous_character(argument, it);
228 }
229
230 // If we found a colon that can't form a drive name (e.g. it can't be 'D:'),
231 // then just add the argument as-is (we don't know how to expand it):
232 if (*it == ':' && it != argument + 1)
233 {
234 return copy_and_add_argument_to_buffer(argument, static_cast<Character*>(nullptr), 0, buffer);
235 }
236
237 size_t const directory_length = is_directory_separator(*it)
238 ? it - argument + 1 // it points to the separator, so add 1 to include it.
239 : 0;
240
241 // Try to begin the find operation:
242 WIN32_FIND_DATAW findFileDataW;
244
245 __crt_findfile_handle const find_handle(::FindFirstFileExW(
246 get_wide(&wide_file_name, argument),
248 &findFileDataW,
250 nullptr,
251 0));
252
253 // If the find operation failed, there was no match, so just add the argument:
255 {
256 return copy_and_add_argument_to_buffer(argument, static_cast<Character*>(nullptr), 0, buffer);
257 }
258
259 size_t const old_argument_count = buffer.size();
260
261 do
262 {
264 Character* const file_name = get_file_name(&character_buffer, findFileDataW.cFileName);
265 // Skip . and ..:
266 if (file_name[0] == '.' && file_name[1] == '\0')
267 {
268 continue;
269 }
270
271 if (file_name[0] == '.' && file_name[1] == '.' && file_name[2] == '\0')
272 {
273 continue;
274 }
275
276 errno_t const add_status = copy_and_add_argument_to_buffer(file_name, argument, directory_length, buffer);
277 if (add_status != 0)
278 {
279 return add_status;
280 }
281 }
282 while (::FindNextFileW(find_handle.get(), &findFileDataW));
283
284 // If we didn't add any arguments to the buffer, then we're done:
285 size_t const new_argument_count = buffer.size();
286 if (old_argument_count == new_argument_count)
287 {
288 return 0;
289 }
290
291 // If we did add new arguments, let's helpfully sort them:
292 qsort(
293 buffer.begin() + old_argument_count,
294 new_argument_count - old_argument_count,
295 sizeof(Character*),
296 [](void const* lhs, void const* rhs) -> int
297 {
298 if (lhs < rhs) { return -1; }
299 if (lhs > rhs) { return 1; }
300 return 0;
301 });
302
303 return 0;
304}
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)
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 *))
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
HANDLE WINAPI FindFirstFileExW(IN LPCWSTR lpFileName, IN FINDEX_INFO_LEVELS fInfoLevelId, OUT LPVOID lpFindFileData, IN FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, IN DWORD dwAdditionalFlags)
Definition: find.c:649
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
if(dx< 0)
Definition: linetemp.h:194
#define get_file_name
Definition: regproc.h:51
@ FindExSearchNameMatch
Definition: winbase.h:1159
@ FindExInfoStandard
Definition: winbase.h:1153

Referenced by common_expand_argv_wildcards().

◆ get_file_name() [1/2]

static char * get_file_name ( __crt_internal_win32_buffer< char > *const  dest,
wchar_t *const  source 
)
static

Definition at line 190 of file argv_wildcards.cpp.

191{
193 source,
194 *dest,
196 );
197
198 if (cvt != 0)
199 {
200 return nullptr;
201 }
202
203 return dest->data();
204}
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()
static char * cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
Definition: fcvtbuf.c:45
static char * dest
Definition: rtl.c:135

◆ get_file_name() [2/2]

static wchar_t * get_file_name ( __crt_internal_win32_buffer< wchar_t > *  ,
wchar_t *const  source 
)
static

Definition at line 206 of file argv_wildcards.cpp.

207{
208 return source;
209}

◆ get_wide() [1/2]

static wchar_t * get_wide ( __crt_internal_win32_buffer< wchar_t > *  ,
wchar_t *const  source 
)
static

Definition at line 185 of file argv_wildcards.cpp.

186{
187 return source;
188}

◆ get_wide() [2/2]

static wchar_t * get_wide ( __crt_internal_win32_buffer< wchar_t > *const  dest,
char *const  source 
)
static

Definition at line 169 of file argv_wildcards.cpp.

170{
172 source,
173 *dest,
175 );
176
177 if (cvt1 != 0)
178 {
179 return nullptr;
180 }
181
182 return dest->data();
183};
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 const cvt1
Definition: strftime.cpp:139

Referenced by expand_argument_wildcards().

◆ previous_character() [1/2]

static wchar_t * previous_character ( _In_reads_(0) wchar_t ,
_In_reads_(0) wchar_t *const  current 
)
throw (
)
static

Definition at line 130 of file argv_wildcards.cpp.

131{
132 return current - 1;
133}
struct task_struct * current
Definition: linux.c:32

◆ previous_character() [2/2]

static _Check_return_ char * previous_character ( _In_reads_z_(current - first+1) char *const  first,
_In_z_ char *const  current 
)
throw (
)
static

Definition at line 122 of file argv_wildcards.cpp.

124{
125 return reinterpret_cast<char*>(_mbsdec(
126 reinterpret_cast<unsigned char*>(first),
127 reinterpret_cast<unsigned char*>(current)));
128}
const GLint * first
Definition: glext.h:5794
_Check_return_ _CRTIMP unsigned char *__cdecl _mbsdec(_In_reads_z_(_Pos-_Start+1) const unsigned char *_Start, _In_z_ const unsigned char *_Pos)

Referenced by expand_argument_wildcards().