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#ifndef TOOLS_GN_PATH_OUTPUT_H_
6#define TOOLS_GN_PATH_OUTPUT_H_
7
8#include <iosfwd>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/strings/string_piece.h"
13#include "tools/gn/escape.h"
14#include "tools/gn/source_dir.h"
15
16class OutputFile;
17class SourceFile;
18
19namespace base {
20class FilePath;
21}
22
23// Writes file names to streams assuming a certain input directory and
24// escaping rules. This gives us a central place for managing this state.
25class PathOutput {
26 public:
27  // Controls whether writing directory names include the trailing slash.
28  // Often we don't want the trailing slash when writing out to a command line,
29  // especially on Windows where it's a backslash and might be interpreted as
30  // escaping the thing following it.
31  enum DirSlashEnding {
32    DIR_INCLUDE_LAST_SLASH,
33    DIR_NO_LAST_SLASH,
34  };
35
36  PathOutput(const SourceDir& current_dir, EscapingMode escaping);
37  ~PathOutput();
38
39  // Read-only since inverse_current_dir_ is computed depending on this.
40  EscapingMode escaping_mode() const { return options_.mode; }
41
42  const SourceDir& current_dir() const { return current_dir_; }
43
44  // Getter/setters for flags inside the escape options.
45  bool inhibit_quoting() const { return options_.inhibit_quoting; }
46  void set_inhibit_quoting(bool iq) { options_.inhibit_quoting = iq; }
47  void set_escape_platform(EscapingPlatform p) { options_.platform = p; }
48
49  void WriteFile(std::ostream& out, const SourceFile& file) const;
50  void WriteFile(std::ostream& out, const OutputFile& file) const;
51  void WriteFile(std::ostream& out, const base::FilePath& file) const;
52
53  // Writes the given OutputFiles with spaces separating them. This will also
54  // write an initial space before the first item.
55  void WriteFiles(std::ostream& out,
56                  const std::vector<OutputFile>& files) const;
57
58  // This variant assumes the dir ends in a trailing slash or is empty.
59  void WriteDir(std::ostream& out,
60                const SourceDir& dir,
61                DirSlashEnding slash_ending) const;
62
63  void WriteDir(std::ostream& out,
64                const OutputFile& file,
65                DirSlashEnding slash_ending) const;
66
67  // Backend for WriteFile and WriteDir. This appends the given file or
68  // directory string to the file.
69  void WritePathStr(std::ostream& out, const base::StringPiece& str) const;
70
71 private:
72  // Takes the given string and writes it out, appending to the inverse
73  // current dir. This assumes leading slashes have been trimmed.
74  void WriteSourceRelativeString(std::ostream& out,
75                                 const base::StringPiece& str) const;
76
77  SourceDir current_dir_;
78
79  // Uses system slashes if convert_slashes_to_system_.
80  std::string inverse_current_dir_;
81
82  // Since the inverse_current_dir_ depends on some of these, we don't expose
83  // this directly to modification.
84  EscapeOptions options_;
85};
86
87#endif  // TOOLS_GN_PATH_OUTPUT_H_
88