1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/at_exit.h"
6#include "base/command_line.h"
7#include "base/strings/utf_string_conversions.h"
8#include "tools/gn/commands.h"
9#include "tools/gn/err.h"
10#include "tools/gn/location.h"
11#include "tools/gn/standard_out.h"
12
13// Only the GN-generated build makes this header for now.
14// TODO(brettw) consider adding this if we need it in GYP.
15#if defined(GN_BUILD)
16#include "tools/gn/last_commit_position.h"
17#else
18#define LAST_COMMIT_POSITION "UNKNOWN"
19#endif
20
21namespace {
22
23std::vector<std::string> GetArgs(const CommandLine& cmdline) {
24  CommandLine::StringVector in_args = cmdline.GetArgs();
25#if defined(OS_WIN)
26  std::vector<std::string> out_args;
27  for (size_t i = 0; i < in_args.size(); i++)
28    out_args.push_back(base::WideToUTF8(in_args[i]));
29  return out_args;
30#else
31  return in_args;
32#endif
33}
34
35}  // namespace
36
37int main(int argc, char** argv) {
38  base::AtExitManager at_exit;
39#if defined(OS_WIN)
40  CommandLine::set_slash_is_not_a_switch();
41#endif
42  CommandLine::Init(argc, argv);
43
44  const CommandLine& cmdline = *CommandLine::ForCurrentProcess();
45  std::vector<std::string> args = GetArgs(cmdline);
46
47  std::string command;
48  if (cmdline.HasSwitch("help") || cmdline.HasSwitch("h")) {
49    // Make "-h" and "--help" default to help command.
50    command = commands::kHelp;
51  } else if (cmdline.HasSwitch("version")) {
52    // Make "--version" print the version and exit.
53    OutputString(std::string(LAST_COMMIT_POSITION) + "\n");
54    exit(0);
55  } else if (args.empty()) {
56    // No command, print error and exit.
57    Err(Location(), "No command specified.",
58        "Most commonly you want \"gn gen <out_dir>\" to make a build dir.\n"
59        "Or try \"gn help\" for more commands.").PrintToStdout();
60    return 1;
61  } else {
62    command = args[0];
63    args.erase(args.begin());
64  }
65
66  const commands::CommandInfoMap& command_map = commands::GetCommands();
67  commands::CommandInfoMap::const_iterator found_command =
68      command_map.find(command);
69
70  int retval;
71  if (found_command != command_map.end()) {
72    retval = found_command->second.runner(args);
73  } else {
74    Err(Location(),
75        "Command \"" + command + "\" unknown.").PrintToStdout();
76    commands::RunHelp(std::vector<std::string>());
77    retval = 1;
78  }
79
80  exit(retval);  // Don't free memory, it can be really slow!
81}
82