Skip to content

Commit

Permalink
Allow typing label names on Windows by not treating things that start…
Browse files Browse the repository at this point in the history
… with slashes as arguments rather than switches.

The old command line parsing is still run so some code could get confused later since / will also be treated as a switch if you ask for it. This seems not as likely to happen that the label will match a switch. If it does, we'll have to change the CommandLine class to make the "/" behavior optional.

Fix a "desc" crash attributing blame due to a null pointer.

BUG=
R=scottmg@chromium.org, thakis@chromium.org

Review URL: https://codereview.chromium.org/24613003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225277 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
brettw@chromium.org committed Sep 25, 2013
1 parent fe6d23e commit bf98a0e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
16 changes: 15 additions & 1 deletion base/command_line.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ CommandLine* CommandLine::current_process_commandline_ = NULL;
namespace {
const CommandLine::CharType kSwitchTerminator[] = FILE_PATH_LITERAL("--");
const CommandLine::CharType kSwitchValueSeparator[] = FILE_PATH_LITERAL("=");

// Since we use a lazy match, make sure that longer versions (like "--") are
// listed before shorter versions (like "-") of similar prefixes.
#if defined(OS_WIN)
// By putting slash last, we can control whether it is treaded as a switch
// value by changing the value of switch_prefix_count to be one less than
// the array size.
const CommandLine::CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"};
#elif defined(OS_POSIX)
// Unixes don't use slash as a switch.
const CommandLine::CharType* const kSwitchPrefixes[] = {"--", "-"};
#endif
size_t switch_prefix_count = arraysize(kSwitchPrefixes);

size_t GetSwitchPrefixLength(const CommandLine::StringType& string) {
for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) {
for (size_t i = 0; i < switch_prefix_count; ++i) {
CommandLine::StringType prefix(kSwitchPrefixes[i]);
if (string.compare(0, prefix.length(), prefix) == 0)
return prefix.length();
Expand Down Expand Up @@ -169,6 +174,15 @@ CommandLine::CommandLine(const StringVector& argv)
CommandLine::~CommandLine() {
}

#if defined(OS_WIN)
// static
void CommandLine::set_slash_is_not_a_switch() {
// The last switch prefix should be slash, so adjust the size to skip it.
DCHECK(wcscmp(kSwitchPrefixes[arraysize(kSwitchPrefixes) - 1], L"/") == 0);
switch_prefix_count = arraysize(kSwitchPrefixes) - 1;
}
#endif

// static
bool CommandLine::Init(int argc, const char* const* argv) {
if (current_process_commandline_) {
Expand Down
11 changes: 11 additions & 0 deletions base/command_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ class BASE_EXPORT CommandLine {

~CommandLine();

#if defined(OS_WIN)
// By default this class will treat command-line arguments beginning with
// slashes as switches on Windows, but not other platforms.
//
// If this behavior is inappropriate for your application, you can call this
// function BEFORE initializing the current process' global command line
// object and the behavior will be the same as Posix systems (only hyphens
// begin switches, everything else will be an arg).
static void set_slash_is_not_a_switch();
#endif

// Initialize the current process CommandLine singleton. On Windows, ignores
// its arguments (we instead parse GetCommandLineW() directly) because we
// don't trust the CRT's parsing of the command line, but it still must be
Expand Down
2 changes: 1 addition & 1 deletion tools/gn/command_desc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@ template<typename T> void OutputRecursiveTargetConfig(
if (config) {
// Source of this value is a config.
out << " From " << config->label().GetUserVisibleName(false) << "\n";
OutputSourceOfDep(target, config->label(), out);
} else {
// Source of this value is the target itself.
out << " From " << target->label().GetUserVisibleName(false) << "\n";
}
OutputSourceOfDep(target, config->label(), out);
}

// Actual values.
Expand Down
3 changes: 3 additions & 0 deletions tools/gn/gn_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ std::vector<std::string> GetArgs(const CommandLine& cmdline) {

int main(int argc, char** argv) {
base::AtExitManager at_exit;
#if defined(OS_WIN)
CommandLine::set_slash_is_not_a_switch();
#endif
CommandLine::Init(argc, argv);

const CommandLine& cmdline = *CommandLine::ForCurrentProcess();
Expand Down

0 comments on commit bf98a0e

Please sign in to comment.