maskaudit.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env python
  2. #
  3. # This file is Copyright 2010 by the GPSD project
  4. # SPDX-License-Identifier: BSD-2-clause
  5. #
  6. # With -p, dump a Python status mask list translated from the C one.
  7. #
  8. # With -c, generate C code to dump masks for debugging purposes.
  9. #
  10. # With -t, tabulate usage of defines to find unused ones. Requires -c or -d.
  11. # This code runs compatibly under Python 2 and 3.x for x >= 2.
  12. # Preserve this property!
  13. from __future__ import absolute_import, print_function, division
  14. import getopt
  15. import glob
  16. import sys
  17. try:
  18. from subprocess import getstatusoutput
  19. except ImportError:
  20. from commands import getstatusoutput
  21. class SourceExtractor(object):
  22. def __init__(self, sourcefile, clientside):
  23. self.sourcefile = sourcefile
  24. self.clientside = clientside
  25. self.daemonfiles = [
  26. "gpsd.c",
  27. "libgpsd_core.c",
  28. "pseudonmea.c",
  29. "drivers.c",
  30. "gpsmon.c",
  31. "subframe.c"
  32. ] + glob.glob("driver_*.c") + glob.glob("monitor_*.c")
  33. self.masks = []
  34. self.primitive_masks = []
  35. for line in open(self.sourcefile):
  36. if (((line.startswith("#define") and
  37. ("_SET" in line or "_IS" in line)))):
  38. fields = line.split()
  39. self.masks.append((fields[1], fields[2]))
  40. if ((fields[2].startswith("(1llu<<") or
  41. fields[2].startswith("INTERNAL_SET"))):
  42. self.primitive_masks.append((fields[1], fields[2]))
  43. def in_library(self, flag):
  44. (status, _output) = getstatusoutput(
  45. "grep '%s' libgps_core.c libgps_json.c gpsctl.c" % flag)
  46. return status == 0
  47. def in_daemon(self, flag):
  48. (status, _output) = getstatusoutput(
  49. "grep '%s' %s" % (flag, " ".join(self.daemonfiles)))
  50. return status == 0
  51. def relevant(self, flag):
  52. if self.clientside:
  53. return self.in_library(flag)
  54. return self.in_daemon(flag)
  55. if __name__ == '__main__':
  56. try:
  57. (options, arguments) = getopt.getopt(sys.argv[1:], "cdpt")
  58. pythonize = tabulate = False
  59. clientgen = daemongen = False
  60. for (switch, val) in options:
  61. if switch == '-p':
  62. pythonize = True
  63. if switch == '-c':
  64. clientgen = True
  65. if switch == '-d':
  66. daemongen = True
  67. if switch == '-t':
  68. tabulate = True
  69. if not arguments:
  70. srcdir = '.'
  71. else:
  72. srcdir = arguments[0]
  73. clientside = SourceExtractor(srcdir + "/gps.h", clientside=True)
  74. daemonside = SourceExtractor(srcdir + "/gpsd.h", clientside=False)
  75. if clientgen:
  76. source = clientside
  77. banner = "Library"
  78. elif daemongen:
  79. source = daemonside
  80. banner = "Daemon"
  81. else:
  82. sys.stderr.write("maskaudit: need -c or -d option\n")
  83. sys.exit(1)
  84. if tabulate:
  85. print("%-14s %8s" % (" ", banner))
  86. for (flag, value) in source.masks:
  87. print("%-14s %8s" % (flag, source.relevant(flag)))
  88. if pythonize:
  89. for (d, v) in source.masks:
  90. if v[-1] == 'u':
  91. v = v[:-1]
  92. print("%-15s\t= %s" % (d, v))
  93. if not pythonize and not tabulate:
  94. maxout = 0
  95. for (d, v) in source.primitive_masks:
  96. if source.relevant(d):
  97. stem = d
  98. if stem.endswith("_SET"):
  99. stem = stem[:-4]
  100. if stem.endswith("_IS"):
  101. stem = stem[:-3]
  102. maxout += len(stem) + 1
  103. print("""/* This code is generated. Do not hand-hack it! */
  104. /*
  105. * Also, beware that it is something of a CPU hog when called on every packet.
  106. * Try to write guards so it is only called at higher log levels.
  107. */
  108. #include \"gpsd_config.h\" /* must be before all includes */
  109. #include <stdio.h>
  110. #include <string.h>
  111. #include \"gpsd.h\"
  112. const char *gps_maskdump(gps_mask_t set)
  113. {
  114. static char buf[%d];
  115. const struct {
  116. gps_mask_t mask;
  117. const char *name;
  118. } *sp, names[] = {""" % (maxout + 3,))
  119. masks = clientside.primitive_masks + daemonside.primitive_masks
  120. for (flag, value) in masks:
  121. stem = flag
  122. if stem.endswith("_SET"):
  123. stem = stem[:-4]
  124. if stem.endswith("_IS"):
  125. stem = stem[:-3]
  126. print(" {%s,\t\"%s\"}," % (flag, stem))
  127. print('''\
  128. };
  129. memset(buf, '\\0', sizeof(buf));
  130. buf[0] = '{';
  131. for (sp = names; sp < names + sizeof(names)/sizeof(names[0]); sp++)
  132. if ((set & sp->mask)!=0) {
  133. (void)strlcat(buf, sp->name, sizeof(buf));
  134. (void)strlcat(buf, "|", sizeof(buf));
  135. }
  136. if (buf[1] != \'\\0\')
  137. buf[strlen(buf)-1] = \'\\0\';
  138. (void)strlcat(buf, "}", sizeof(buf));
  139. return buf;
  140. }
  141. ''')
  142. except KeyboardInterrupt:
  143. pass
  144. # The following sets edit modes for GNU EMACS
  145. # Local Variables:
  146. # mode:python
  147. # End:
  148. # vim: set expandtab shiftwidth=4