preprocessor.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # -*- coding: utf-8 -*-
  2. #
  3. # File : preprocessor.py
  4. # This file is part of RT-Thread RTOS
  5. # COPYRIGHT (C) 2006 - 2025, RT-Thread Development Team
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. # Change Logs:
  22. # Date Author Notes
  23. # 2025-01-05 Assistant Extract SCons PreProcessor patch to independent class
  24. from SCons.Script import *
  25. class SConsPreProcessorPatch:
  26. """
  27. SCons PreProcessor patch class
  28. This class provides methods to patch the SCons PreProcessor
  29. to handle conditional compilation directives properly.
  30. """
  31. def __init__(self):
  32. """Initialize the PreProcessor patch"""
  33. self._patched_preprocessor = None
  34. self._apply_patch()
  35. def _apply_patch(self):
  36. """
  37. Apply the patch to SCons PreProcessor
  38. This method patches the SCons.cpp.PreProcessor class with
  39. custom methods for handling includes during conditional compilation.
  40. """
  41. from SCons import cpp
  42. # Store reference to original PreProcessor
  43. self._patched_preprocessor = cpp.PreProcessor
  44. # Create bound methods for the patch
  45. def start_handling_includes(preprocessor_self, t=None):
  46. d = preprocessor_self.dispatch_table
  47. p = preprocessor_self.stack[-1] if preprocessor_self.stack else preprocessor_self.default_table
  48. for k in ('import', 'include', 'include_next', 'define'):
  49. d[k] = p[k]
  50. def stop_handling_includes(preprocessor_self, t=None):
  51. d = preprocessor_self.dispatch_table
  52. d['import'] = preprocessor_self.do_nothing
  53. d['include'] = preprocessor_self.do_nothing
  54. d['include_next'] = preprocessor_self.do_nothing
  55. d['define'] = preprocessor_self.do_nothing
  56. # Apply the patch methods
  57. self._patched_preprocessor.start_handling_includes = start_handling_includes
  58. self._patched_preprocessor.stop_handling_includes = stop_handling_includes
  59. def get_patched_preprocessor(self):
  60. return self._patched_preprocessor
  61. def create_preprocessor_instance(self):
  62. return self._patched_preprocessor()
  63. # Global instance for easy access
  64. _preprocessor_patch = None
  65. def get_patched_preprocessor():
  66. global _preprocessor_patch
  67. if _preprocessor_patch is None:
  68. _preprocessor_patch = SConsPreProcessorPatch()
  69. return _preprocessor_patch.get_patched_preprocessor()
  70. def create_preprocessor_instance():
  71. global _preprocessor_patch
  72. if _preprocessor_patch is None:
  73. _preprocessor_patch = SConsPreProcessorPatch()
  74. return _preprocessor_patch.create_preprocessor_instance()