Initial commit
[yaffs-website] / node_modules / node-gyp / gyp / pylib / gyp / MSVSUserFile.py
1 # Copyright (c) 2012 Google Inc. 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 """Visual Studio user preferences file writer."""
6
7 import os
8 import re
9 import socket # for gethostname
10
11 import gyp.common
12 import gyp.easy_xml as easy_xml
13
14
15 #------------------------------------------------------------------------------
16
17 def _FindCommandInPath(command):
18   """If there are no slashes in the command given, this function
19      searches the PATH env to find the given command, and converts it
20      to an absolute path.  We have to do this because MSVS is looking
21      for an actual file to launch a debugger on, not just a command
22      line.  Note that this happens at GYP time, so anything needing to
23      be built needs to have a full path."""
24   if '/' in command or '\\' in command:
25     # If the command already has path elements (either relative or
26     # absolute), then assume it is constructed properly.
27     return command
28   else:
29     # Search through the path list and find an existing file that
30     # we can access.
31     paths = os.environ.get('PATH','').split(os.pathsep)
32     for path in paths:
33       item = os.path.join(path, command)
34       if os.path.isfile(item) and os.access(item, os.X_OK):
35         return item
36   return command
37
38 def _QuoteWin32CommandLineArgs(args):
39   new_args = []
40   for arg in args:
41     # Replace all double-quotes with double-double-quotes to escape
42     # them for cmd shell, and then quote the whole thing if there
43     # are any.
44     if arg.find('"') != -1:
45       arg = '""'.join(arg.split('"'))
46       arg = '"%s"' % arg
47
48     # Otherwise, if there are any spaces, quote the whole arg.
49     elif re.search(r'[ \t\n]', arg):
50       arg = '"%s"' % arg
51     new_args.append(arg)
52   return new_args
53
54 class Writer(object):
55   """Visual Studio XML user user file writer."""
56
57   def __init__(self, user_file_path, version, name):
58     """Initializes the user file.
59
60     Args:
61       user_file_path: Path to the user file.
62       version: Version info.
63       name: Name of the user file.
64     """
65     self.user_file_path = user_file_path
66     self.version = version
67     self.name = name
68     self.configurations = {}
69
70   def AddConfig(self, name):
71     """Adds a configuration to the project.
72
73     Args:
74       name: Configuration name.
75     """
76     self.configurations[name] = ['Configuration', {'Name': name}]
77
78   def AddDebugSettings(self, config_name, command, environment = {},
79                        working_directory=""):
80     """Adds a DebugSettings node to the user file for a particular config.
81
82     Args:
83       command: command line to run.  First element in the list is the
84         executable.  All elements of the command will be quoted if
85         necessary.
86       working_directory: other files which may trigger the rule. (optional)
87     """
88     command = _QuoteWin32CommandLineArgs(command)
89
90     abs_command = _FindCommandInPath(command[0])
91
92     if environment and isinstance(environment, dict):
93       env_list = ['%s="%s"' % (key, val)
94                   for (key,val) in environment.iteritems()]
95       environment = ' '.join(env_list)
96     else:
97       environment = ''
98
99     n_cmd = ['DebugSettings',
100              {'Command': abs_command,
101               'WorkingDirectory': working_directory,
102               'CommandArguments': " ".join(command[1:]),
103               'RemoteMachine': socket.gethostname(),
104               'Environment': environment,
105               'EnvironmentMerge': 'true',
106               # Currently these are all "dummy" values that we're just setting
107               # in the default manner that MSVS does it.  We could use some of
108               # these to add additional capabilities, I suppose, but they might
109               # not have parity with other platforms then.
110               'Attach': 'false',
111               'DebuggerType': '3',  # 'auto' debugger
112               'Remote': '1',
113               'RemoteCommand': '',
114               'HttpUrl': '',
115               'PDBPath': '',
116               'SQLDebugging': '',
117               'DebuggerFlavor': '0',
118               'MPIRunCommand': '',
119               'MPIRunArguments': '',
120               'MPIRunWorkingDirectory': '',
121               'ApplicationCommand': '',
122               'ApplicationArguments': '',
123               'ShimCommand': '',
124               'MPIAcceptMode': '',
125               'MPIAcceptFilter': ''
126              }]
127
128     # Find the config, and add it if it doesn't exist.
129     if config_name not in self.configurations:
130       self.AddConfig(config_name)
131
132     # Add the DebugSettings onto the appropriate config.
133     self.configurations[config_name].append(n_cmd)
134
135   def WriteIfChanged(self):
136     """Writes the user file."""
137     configs = ['Configurations']
138     for config, spec in sorted(self.configurations.iteritems()):
139       configs.append(spec)
140
141     content = ['VisualStudioUserFile',
142                {'Version': self.version.ProjectVersion(),
143                 'Name': self.name
144                },
145                configs]
146     easy_xml.WriteXmlIfChanged(content, self.user_file_path,
147                                encoding="Windows-1252")