Reactos
at listview 111 lines 3.5 kB view raw
1/*** 2*wincmdln.c - process command line for WinMain 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* Prepare command line to be passed to [w]WinMain. 8* 9*******************************************************************************/ 10 11#include <corecrt_internal.h> 12#include <mbstring.h> 13 14 15 16// In the function below, we need to ensure that we've initialized the mbc table 17// before we start performing character transformations. 18static void do_locale_initialization(unsigned char) throw() { __acrt_initialize_multibyte(); } 19static void do_locale_initialization(wchar_t) throw() { /* no-op */ } 20 21static unsigned char* get_command_line(unsigned char) throw() 22{ 23 return reinterpret_cast<unsigned char *>(_acmdln); 24} 25 26static wchar_t* get_command_line(wchar_t) throw() { return _wcmdln; } 27 28 29// should_copy_another_character is *ONLY* checking for DBCS lead bytes to see if there 30// might be a following trail byte. This works because the callers are only concerned 31// about escaped quote sequences and other codepages aren't using those quotes. 32static bool __cdecl should_copy_another_character(unsigned char const c) throw() 33{ 34 // This is OK for UTF-8 as a quote is never a trail byte. 35 return _ismbblead(c) != 0; 36} 37 38static bool __cdecl should_copy_another_character(wchar_t) throw() 39{ 40 // This is OK for UTF-16 as a quote is never part of a surrogate pair. 41 return false; 42} 43 44 45 46/*** 47*_[w]wincmdln 48* 49*Purpose: 50* Extract the command line tail to be passed to WinMain. 51* 52* Be warned! This code was originally implemented by the NT group and 53* has remained pretty much unchanged since 12-91. It should be changed 54* only with extreme care since there are undoubtedly many apps which 55* depend on its historical behavior. 56* 57*Entry: 58* The global variable _[a|w]cmdln is set to point at the complete 59* command line. 60* 61*Exit: 62* Returns a pointer to the command line tail. 63* 64*Exceptions: 65* 66*******************************************************************************/ 67template <typename Character> 68static Character* __cdecl common_wincmdln() throw() 69{ 70 do_locale_initialization(Character()); 71 72 static Character empty_string[] = { '\0' }; 73 74 Character* command_line = get_command_line(Character()) == nullptr 75 ? empty_string 76 : get_command_line(Character()); 77 78 // Skip past the program name (the first token in the command line) and 79 // check for and handle a quoted program name: 80 bool in_double_quotes = false; 81 while (*command_line > ' ' || (*command_line != '\0' && in_double_quotes)) 82 { 83 // Toggle the in_double_quotes flag if the current character is '"' 84 if (*command_line == '"') 85 in_double_quotes = !in_double_quotes; 86 87 if (should_copy_another_character(*command_line)) 88 ++command_line; 89 90 ++command_line; 91 } 92 93 // Skip past any whitespace preceding the next token: 94 while (*command_line != '\0' && *command_line <= ' ') 95 ++command_line; 96 97 return command_line; 98} 99 100 101 102extern "C" char* __cdecl _get_narrow_winmain_command_line() 103{ // Need to use unsigned char so that we correctly handle ASCII characters 104 // above 127, in particular the comparison to ' ' (space - 0x20). 105 return reinterpret_cast<char *>(common_wincmdln<unsigned char>()); 106} 107 108extern "C" wchar_t* __cdecl _get_wide_winmain_command_line() 109{ 110 return common_wincmdln<wchar_t>(); 111}