You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.4 KiB

6 years ago
  1. """scons.Node.Python
  2. Python nodes.
  3. """
  4. #
  5. # Copyright (c) 2001 - 2017 The SCons Foundation
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining
  8. # a copy of this software and associated documentation files (the
  9. # "Software"), to deal in the Software without restriction, including
  10. # without limitation the rights to use, copy, modify, merge, publish,
  11. # distribute, sublicense, and/or sell copies of the Software, and to
  12. # permit persons to whom the Software is furnished to do so, subject to
  13. # the following conditions:
  14. #
  15. # The above copyright notice and this permission notice shall be included
  16. # in all copies or substantial portions of the Software.
  17. #
  18. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  19. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. #
  26. __revision__ = "src/engine/SCons/Node/Python.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
  27. import SCons.Node
  28. class ValueNodeInfo(SCons.Node.NodeInfoBase):
  29. __slots__ = ('csig',)
  30. current_version_id = 2
  31. field_list = ['csig']
  32. def str_to_node(self, s):
  33. return Value(s)
  34. def __getstate__(self):
  35. """
  36. Return all fields that shall be pickled. Walk the slots in the class
  37. hierarchy and add those to the state dictionary. If a '__dict__' slot is
  38. available, copy all entries to the dictionary. Also include the version
  39. id, which is fixed for all instances of a class.
  40. """
  41. state = getattr(self, '__dict__', {}).copy()
  42. for obj in type(self).mro():
  43. for name in getattr(obj,'__slots__',()):
  44. if hasattr(self, name):
  45. state[name] = getattr(self, name)
  46. state['_version_id'] = self.current_version_id
  47. try:
  48. del state['__weakref__']
  49. except KeyError:
  50. pass
  51. return state
  52. def __setstate__(self, state):
  53. """
  54. Restore the attributes from a pickled state.
  55. """
  56. # TODO check or discard version
  57. del state['_version_id']
  58. for key, value in state.items():
  59. if key not in ('__weakref__',):
  60. setattr(self, key, value)
  61. class ValueBuildInfo(SCons.Node.BuildInfoBase):
  62. __slots__ = ()
  63. current_version_id = 2
  64. class Value(SCons.Node.Node):
  65. """A class for Python variables, typically passed on the command line
  66. or generated by a script, but not from a file or some other source.
  67. """
  68. NodeInfo = ValueNodeInfo
  69. BuildInfo = ValueBuildInfo
  70. def __init__(self, value, built_value=None):
  71. SCons.Node.Node.__init__(self)
  72. self.value = value
  73. self.changed_since_last_build = 6
  74. self.store_info = 0
  75. if built_value is not None:
  76. self.built_value = built_value
  77. def str_for_display(self):
  78. return repr(self.value)
  79. def __str__(self):
  80. return str(self.value)
  81. def make_ready(self):
  82. self.get_csig()
  83. def build(self, **kw):
  84. if not hasattr(self, 'built_value'):
  85. SCons.Node.Node.build(self, **kw)
  86. is_up_to_date = SCons.Node.Node.children_are_up_to_date
  87. def is_under(self, dir):
  88. # Make Value nodes get built regardless of
  89. # what directory scons was run from. Value nodes
  90. # are outside the filesystem:
  91. return 1
  92. def write(self, built_value):
  93. """Set the value of the node."""
  94. self.built_value = built_value
  95. def read(self):
  96. """Return the value. If necessary, the value is built."""
  97. self.build()
  98. if not hasattr(self, 'built_value'):
  99. self.built_value = self.value
  100. return self.built_value
  101. def get_text_contents(self):
  102. """By the assumption that the node.built_value is a
  103. deterministic product of the sources, the contents of a Value
  104. are the concatenation of all the contents of its sources. As
  105. the value need not be built when get_contents() is called, we
  106. cannot use the actual node.built_value."""
  107. ###TODO: something reasonable about universal newlines
  108. contents = str(self.value)
  109. for kid in self.children(None):
  110. contents = contents + kid.get_contents().decode()
  111. return contents
  112. def get_contents(self):
  113. text_contents = self.get_text_contents()
  114. try:
  115. return text_contents.encode()
  116. except UnicodeDecodeError:
  117. # Already encoded as python2 str are bytes
  118. return text_contents
  119. def changed_since_last_build(self, target, prev_ni):
  120. cur_csig = self.get_csig()
  121. try:
  122. return cur_csig != prev_ni.csig
  123. except AttributeError:
  124. return 1
  125. def get_csig(self, calc=None):
  126. """Because we're a Python value node and don't have a real
  127. timestamp, we get to ignore the calculator and just use the
  128. value contents."""
  129. try:
  130. return self.ninfo.csig
  131. except AttributeError:
  132. pass
  133. contents = self.get_contents()
  134. self.get_ninfo().csig = contents
  135. return contents
  136. # Local Variables:
  137. # tab-width:4
  138. # indent-tabs-mode:nil
  139. # End:
  140. # vim: set expandtab tabstop=4 shiftwidth=4: