1// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build ignore
16
17#include "flags.h"
18
19#include <stdlib.h>
20#include <unistd.h>
21
22#include "log.h"
23#include "strutil.h"
24
25Flags g_flags;
26
27static bool ParseCommandLineOptionWithArg(StringPiece option,
28                                          char* argv[],
29                                          int* index,
30                                          const char** out_arg) {
31  const char* arg = argv[*index];
32  if (!HasPrefix(arg, option))
33    return false;
34  if (arg[option.size()] == '\0') {
35    ++*index;
36    *out_arg = argv[*index];
37    return true;
38  }
39  if (arg[option.size()] == '=') {
40    *out_arg = arg + option.size() + 1;
41    return true;
42  }
43  // E.g, -j999
44  if (option.size() == 2) {
45    *out_arg = arg + option.size();
46    return true;
47  }
48  return false;
49}
50
51void Flags::Parse(int argc, char** argv) {
52  subkati_args.push_back(argv[0]);
53  num_jobs = num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
54  const char* num_jobs_str;
55
56  if (const char* makeflags = getenv("MAKEFLAGS")) {
57    for (StringPiece tok : WordScanner(makeflags)) {
58      if (!HasPrefix(tok, "-") && tok.find('=') != string::npos)
59        cl_vars.push_back(tok);
60    }
61  }
62
63  for (int i = 1; i < argc; i++) {
64    const char* arg = argv[i];
65    bool should_propagate = true;
66    int pi = i;
67    if (!strcmp(arg, "-f")) {
68      makefile = argv[++i];
69      should_propagate = false;
70    } else if (!strcmp(arg, "-c")) {
71      is_syntax_check_only = true;
72    } else if (!strcmp(arg, "-i")) {
73      is_dry_run = true;
74    } else if (!strcmp(arg, "-s")) {
75      is_silent_mode = true;
76    } else if (!strcmp(arg, "-d")) {
77      enable_debug = true;
78    } else if (!strcmp(arg, "--kati_stats")) {
79      enable_stat_logs = true;
80    } else if (!strcmp(arg, "--warn")) {
81      enable_kati_warnings = true;
82    } else if (!strcmp(arg, "--ninja")) {
83      generate_ninja = true;
84    } else if (!strcmp(arg, "--gen_all_targets")) {
85      gen_all_targets = true;
86    } else if (!strcmp(arg, "--regen")) {
87      // TODO: Make this default.
88      regen = true;
89    } else if (!strcmp(arg, "--regen_debug")) {
90      regen_debug = true;
91    } else if (!strcmp(arg, "--regen_ignoring_kati_binary")) {
92      regen_ignoring_kati_binary = true;
93    } else if (!strcmp(arg, "--dump_kati_stamp")) {
94      dump_kati_stamp = true;
95      regen_debug = true;
96    } else if (!strcmp(arg, "--detect_android_echo")) {
97      detect_android_echo = true;
98    } else if (!strcmp(arg, "--detect_depfiles")) {
99      detect_depfiles = true;
100    } else if (!strcmp(arg, "--color_warnings")) {
101      color_warnings = true;
102    } else if (ParseCommandLineOptionWithArg(
103        "-j", argv, &i, &num_jobs_str)) {
104      num_jobs = strtol(num_jobs_str, NULL, 10);
105      if (num_jobs <= 0) {
106        ERROR("Invalid -j flag: %s", num_jobs_str);
107      }
108    } else if (ParseCommandLineOptionWithArg(
109        "--remote_num_jobs", argv, &i, &num_jobs_str)) {
110      remote_num_jobs = strtol(num_jobs_str, NULL, 10);
111      if (remote_num_jobs <= 0) {
112        ERROR("Invalid -j flag: %s", num_jobs_str);
113      }
114    } else if (ParseCommandLineOptionWithArg(
115        "--ninja_suffix", argv, &i, &ninja_suffix)) {
116    } else if (ParseCommandLineOptionWithArg(
117        "--ninja_dir", argv, &i, &ninja_dir)) {
118    } else if (!strcmp(arg, "--use_find_emulator")) {
119      use_find_emulator = true;
120    } else if (ParseCommandLineOptionWithArg(
121        "--goma_dir", argv, &i, &goma_dir)) {
122    } else if (ParseCommandLineOptionWithArg(
123        "--ignore_optional_include",
124        argv, &i, &ignore_optional_include_pattern)) {
125    } else if (ParseCommandLineOptionWithArg(
126        "--ignore_dirty",
127        argv, &i, &ignore_dirty_pattern)) {
128    } else if (ParseCommandLineOptionWithArg(
129        "--no_ignore_dirty",
130        argv, &i, &no_ignore_dirty_pattern)) {
131    } else if (arg[0] == '-') {
132      ERROR("Unknown flag: %s", arg);
133    } else {
134      if (strchr(arg, '=')) {
135        cl_vars.push_back(arg);
136      } else {
137        should_propagate = false;
138        targets.push_back(Intern(arg));
139      }
140    }
141
142    if (should_propagate) {
143      for (; pi <= i; pi++) {
144        subkati_args.push_back(argv[pi]);
145      }
146    }
147  }
148}
149