USB/PN532: Fix dissector to use new dissector *data instead of private_data. Bug...
[metze/wireshark/wip.git] / tools / make-tap-reg.py
1 #!/usr/bin/env python
2 #
3 # Looks for registration routines in the taps,
4 # and assembles C code to call all the routines.
5 #
6 # This is a Python version of the make-reg-dotc shell script.
7 # Running the shell script on Win32 is very very slow because of
8 # all the process-launching that goes on --- multiple greps and
9 # seds for each input file.  I wrote this python version so that
10 # less processes would have to be started.
11 #
12 # Copyright 2010 Anders Broman <anders.broman@ericsson.com>
13 #
14 # $Id$
15 #
16 # Wireshark - Network traffic analyzer
17 # By Gerald Combs <gerald@wireshark.org>
18 # Copyright 1998 Gerald Combs
19 #
20 # This program is free software; you can redistribute it and/or
21 # modify it under the terms of the GNU General Public License
22 # as published by the Free Software Foundation; either version 2
23 # of the License, or (at your option) any later version.
24 #
25 # This program is distributed in the hope that it will be useful,
26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 # GNU General Public License for more details.
29 #
30 # You should have received a copy of the GNU General Public License
31 # along with this program; if not, write to the Free Software
32 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33
34 import os
35 import sys
36 import re
37 import pickle
38 from stat import *
39
40 #
41 # The first argument is the directory in which the source files live.
42 #
43 srcdir = sys.argv[1]
44
45 #
46 # The second argument is  "taps".
47 #
48 registertype = sys.argv[2]
49 if registertype == "taps":
50         tmp_filename = "wireshark-tap-register.c-tmp"
51         final_filename = "wireshark-tap-register.c"
52         cache_filename = "wireshark-tap-register-cache.pkl"
53 elif registertype == "tshark-taps":
54         tmp_filename = "tshark-tap-register.c-tmp"
55         final_filename = "tshark-tap-register.c"
56         cache_filename = "tshark-tap-register-cache.pkl"
57 else:
58         print("Unknown output type '%s'" % registertype)
59         sys.exit(1)
60
61
62 #
63 # All subsequent arguments are the files to scan.
64 #
65 files = sys.argv[3:]
66
67 # Create the proper list of filenames
68 filenames = []
69 for file in files:
70         if os.path.isfile(file):
71                 filenames.append(file)
72         else:
73                 filenames.append("%s/%s" % (srcdir, file))
74
75 if len(filenames) < 1:
76         print("No files found")
77         sys.exit(1)
78
79
80 # Look through all files, applying the regex to each line.
81 # If the pattern matches, save the "symbol" section to the
82 # appropriate array.
83 regs = {
84         'tap_reg': [],
85         }
86
87 # For those that don't know Python, r"" indicates a raw string,
88 # devoid of Python escapes.
89 tap_regex0 = r"^(?P<symbol>register_tap_listener_[_A-Za-z0-9]+)\s*\([^;]+$"
90 tap_regex1 = r"void\s+(?P<symbol>register_tap_listener_[_A-Za-z0-9]+)\s*\([^;]+$"
91
92 # This table drives the pattern-matching and symbol-harvesting
93 patterns = [
94         ( 'tap_reg', re.compile(tap_regex0) ),
95         ( 'tap_reg', re.compile(tap_regex1) ),
96         ]
97
98 # Open our registration symbol cache
99 cache = None
100 if cache_filename:
101         try:
102                 cache_file = open(cache_filename, 'rb')
103                 cache = pickle.load(cache_file)
104                 cache_file.close()
105         except:
106                 cache = {}
107
108 # Grep
109 for filename in filenames:
110         file = open(filename)
111         cur_mtime = os.fstat(file.fileno())[ST_MTIME]
112         if cache and filename in cache:
113                 cdict = cache[filename]
114                 if cur_mtime == cdict['mtime']:
115 #                       print "Pulling %s from cache" % (filename)
116                         regs['tap_reg'].extend(cdict['tap_reg'])
117                         file.close()
118                         continue
119         # We don't have a cache entry
120         if cache is not None:
121                 cache[filename] = {
122                         'mtime': cur_mtime,
123                         'tap_reg': [],
124                         }
125 #       print "Searching %s" % (filename)
126         for line in file.readlines():
127                 for action in patterns:
128                         regex = action[1]
129                         match = regex.search(line)
130                         if match:
131                                 symbol = match.group("symbol")
132                                 sym_type = action[0]
133                                 regs[sym_type].append(symbol)
134                                 if cache is not None:
135 #                                       print "Caching %s for %s: %s" % (sym_type, filename, symbol)
136                                         cache[filename][sym_type].append(symbol)
137         file.close()
138
139 if cache is not None and cache_filename is not None:
140         cache_file = open(cache_filename, 'wb')
141         pickle.dump(cache, cache_file)
142         cache_file.close()
143
144 # Make sure we actually processed something
145 if len(regs['tap_reg']) < 1:
146         print("No protocol registrations found")
147         sys.exit(1)
148
149 # Sort the lists to make them pretty
150 regs['tap_reg'].sort()
151
152 reg_code = open(tmp_filename, "w")
153
154 reg_code.write("/* Do not modify this file. Changes will be overwritten.  */\n")
155 reg_code.write("/* Generated automatically from %s  */\n" % (sys.argv[0]))
156
157 # Make the routine to register all taps
158 reg_code.write("""
159 #include "register.h"
160 void register_all_tap_listeners(void) {
161 """);
162
163 for symbol in regs['tap_reg']:
164         line = "  {extern void %s (void); %s ();}\n" % (symbol, symbol)
165         reg_code.write(line)
166
167 reg_code.write("}\n")
168
169
170 # Close the file
171 reg_code.close()
172
173 # Remove the old final_file if it exists.
174 try:
175         os.stat(final_filename)
176         os.remove(final_filename)
177 except OSError:
178         pass
179
180 # Move from tmp file to final file
181 os.rename(tmp_filename, final_filename)