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.

build_errcodedb.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env python
  2. # Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>.
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License as
  6. # published by the Free Software Foundation; either version 2 of the
  7. # License, or any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but
  10. # WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. import sys
  18. import re
  19. pxenv_status_files = ('../../src/include/errno.h', )
  20. errfile_files = ('../../src/include/ipxe/errfile.h',
  21. '../../src/arch/i386/include/bits/errfile.h')
  22. posix_errno_files = ('../../src/include/errno.h', )
  23. PXENV_STATUS_RE = re.compile(r'^#define\s+(PXENV_STATUS_[^\s]+)\s+(.+)$', re.M)
  24. ERRFILE_RE = re.compile(r'^#define\s+(ERRFILE_[^\s]+)\s+(.+)$', re.M)
  25. POSIX_ERRNO_RE = re.compile(r'^#define\s+(E[A-Z0-9]+)\s+(?:\\\n)?.*(0x[0-9a-f]+).*$', re.M)
  26. def err(msg):
  27. sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  28. sys.exit(1)
  29. def to_pxenv_status(errno):
  30. return errno & 0xff
  31. def to_errfile(errno):
  32. return (errno >> 13) & 0x7ff
  33. def to_posix_errno(errno):
  34. return (errno >> 24) & 0x7f
  35. def load_header_file(filename, regexp):
  36. defines = {}
  37. data = open(filename, 'r').read()
  38. for m in regexp.finditer(data):
  39. key, val = m.groups()
  40. defines[key] = val
  41. return defines
  42. def evaluate(defines, expr):
  43. pyexpr = ''
  44. for token in expr.split():
  45. if token in '()':
  46. pass
  47. elif token.startswith('/*') or token.startswith('//'):
  48. break
  49. elif token.startswith('0x') or token == '|':
  50. pyexpr += token
  51. else:
  52. if token in defines:
  53. pyexpr += '0x%x' % defines[token]
  54. else:
  55. return -1
  56. if not re.match(r'^[0-9a-zA-Z_|]+$', pyexpr):
  57. err('invalid expression')
  58. return eval(pyexpr)
  59. def build(filenames, regexp, selector):
  60. unevaluated = {}
  61. for filename in filenames:
  62. unevaluated.update(load_header_file(filename, regexp))
  63. evaluated = {}
  64. changed = True
  65. while changed:
  66. changed = False
  67. for key in list(unevaluated.keys()):
  68. val = evaluate(evaluated, unevaluated[key])
  69. if val != -1:
  70. del unevaluated[key]
  71. evaluated[key] = val
  72. changed = True
  73. if unevaluated:
  74. err('unable to evaluate all #defines')
  75. lookup = {}
  76. for key, val in evaluated.iteritems():
  77. lookup[selector(val)] = key
  78. return lookup
  79. print 'pxenv_status =', repr(build(pxenv_status_files, PXENV_STATUS_RE, to_pxenv_status))
  80. print 'errfile =', repr(build(errfile_files, ERRFILE_RE, to_errfile))
  81. print 'posix_errno =', repr(build(posix_errno_files, POSIX_ERRNO_RE, to_posix_errno))