validate_boards.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python3
  2. #
  3. # buildroot/share/scripts/validate_boards.py
  4. # Assert standards for boards.h and pins.h
  5. #
  6. import sys, re
  7. do_log = False
  8. def logmsg(msg, line):
  9. if do_log: print(msg, line)
  10. # Print a formatted error
  11. def err(board, msg):
  12. print(f'[ERROR] {board:30} {msg}')
  13. # Print a formatted warning
  14. def warn(board, msg):
  15. print(f'[WARNING] {board:30} {msg}')
  16. def bshort(board):
  17. return board.replace('BOARD_', '')
  18. #
  19. # Run standards checks on boards.h and pins.h
  20. #
  21. def boards_checks(argv):
  22. ERRS = 0
  23. src_file = 'Marlin/src/core/boards.h'
  24. scnt = 0
  25. for arg in argv:
  26. if arg == '-v':
  27. global do_log
  28. do_log = True
  29. elif scnt == 0:
  30. src_file = arg
  31. scnt += 1
  32. logmsg('Checking boards file:', src_file)
  33. # Open the file
  34. with open(src_file, 'r') as f:
  35. lines = f.readlines()
  36. # Get the board names and numbers
  37. boards = []
  38. for line in lines:
  39. m = re.match(r'^\s*#define\s+(BO\w+)\s+(\d+)(\s+//\s*(.+))?', line)
  40. if not m: continue
  41. board, number, comment = m.group(1), int(m.group(2)), m.group(4)
  42. boards.append((board, number, comment))
  43. #
  44. # Examine boards.h to check the formatting of the file
  45. #
  46. last_number, last_groun = (-1, -1)
  47. for board, number, comment in boards:
  48. logmsg('Checking:', board)
  49. group = int(number / 100)
  50. if not re.match(r'^BOARD_\w+$', board):
  51. err(board, 'is not of the form BOARD_NAME')
  52. ERRS += 1
  53. if number != last_number + 1:
  54. if int(number / 100) != int(last_number / 100):
  55. if number % 100 != 0 and number < 9900:
  56. err(board, f'is {number} (should be {group * 100}?)')
  57. ERRS += 1
  58. elif number > 1040:
  59. err(board, f'is {number} but previous board is {last_number}')
  60. ERRS += 1
  61. if not comment:
  62. err(board, ' has no comment')
  63. ERRS += 1
  64. else:
  65. cshor = bshort(board)
  66. cbore = cshor.replace('_', '')
  67. if comment == board or comment == cshor or comment == cbore:
  68. warn(board, f'comment needs more detail')
  69. last_number = number
  70. last_group = number % 100
  71. #
  72. # Validate that pins.h has all the boards mentioned in it
  73. #
  74. pins_boards = []
  75. with open('Marlin/src/pins/pins.h', 'r') as f:
  76. lines = f.readlines()
  77. if_count = 0
  78. for line in lines:
  79. m = re.search(r'#(if|elif)\s+MB\(([^)]+)\)', line)
  80. if not m: continue
  81. if (m.group(1) == 'if'):
  82. if_count += 1
  83. if if_count == 3: break
  84. if if_count == 2:
  85. mb_items = m.group(2).split(',')
  86. for board in mb_items:
  87. pins_boards.append('BOARD_' + board.strip())
  88. # Check that the list from boards.h matches the list from pins.h
  89. boards_boards = [b[0] for b in boards]
  90. if set(pins_boards) != set(boards_boards):
  91. ERRS += 1
  92. print(f'[ERROR] Boards in pins.h do not match boards.h')
  93. # Show the differences only
  94. for b in boards:
  95. if b[0] not in pins_boards:
  96. print(f' pins.h missing: {b[0]}')
  97. for b in pins_boards:
  98. if b not in boards_boards:
  99. print(f' boards.h missing: {b}')
  100. # Check that boards_boards and pins_boards are in the same order
  101. for i in range(len(boards_boards)):
  102. if boards_boards[i] != pins_boards[i]:
  103. ERRS += 1
  104. print(f'[ERROR] Non-matching boards order in pins.h. Expected {bshort(boards_boards[i])} but got {bshort(pins_boards[i])}')
  105. break
  106. return ERRS;
  107. if __name__ == '__main__':
  108. ERR_COUNT = boards_checks(sys.argv[1:])
  109. if ERR_COUNT:
  110. print(f'\nFound {ERR_COUNT} errors')
  111. sys.exit(1)