3 # Looks for registration routines in the protocol dissectors,
4 # and assembles C code to call all the routines.
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.
21 VERSION_KEY
= '_VERSION'
25 # The first argument is the directory in which the source files live.
30 # The second argument is either "plugin" or "dissectors"; if it's
31 # "plugin", we build a plugin.c for a plugin, and if it's
32 # "dissectors", we build a register.c for libwireshark.
34 registertype
= sys
.argv
[2]
35 if registertype
== "plugin" or registertype
== "plugin_wtap":
36 final_filename
= "plugin.c"
40 * Do not modify this file. Changes will be overwritten.
42 * Generated automatically from %s.
45 elif registertype
== "dissectors":
46 final_filename
= "register.c"
47 cache_filename
= "register-cache.pkl"
50 * Do not modify this file. Changes will be overwritten.
52 * Generated automatically by the "register.c" target in
53 * epan/dissectors/Makefile or Makefile.nmake using
55 * and information in epan/dissectors/register-cache.pkl.
57 * You can force this file to be regenerated completely by deleting
58 * it along with epan/dissectors/register-cache.pkl.
62 print(("Unknown output type '%s'" % registertype
))
67 # All subsequent arguments are the files to scan.
71 # Create the proper list of filenames
74 if os
.path
.isfile(file):
75 filenames
.append(file)
77 filenames
.append(os
.path
.join(srcdir
, file))
79 if len(filenames
) < 1:
80 print("No files found")
84 # Look through all files, applying the regex to each line.
85 # If the pattern matches, save the "symbol" section to the
90 'wtap_register': set(),
93 # For those that don't know Python, r"" indicates a raw string,
94 # devoid of Python escapes.
95 proto_regex
= r
"(?P<symbol>proto_register_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
97 handoff_regex
= r
"(?P<symbol>proto_reg_handoff_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$"
99 wtap_reg_regex
= r
"(?P<symbol>wtap_register_[_A-Za-z0-9]+)\s*\([^;]+$"
101 # This table drives the pattern-matching and symbol-harvesting
103 ( 'proto_reg', re
.compile(proto_regex
, re
.MULTILINE
) ),
104 ( 'handoff_reg', re
.compile(handoff_regex
, re
.MULTILINE
) ),
105 ( 'wtap_register', re
.compile(wtap_reg_regex
, re
.MULTILINE
) ),
108 # Open our registration symbol cache
112 cache_file
= open(cache_filename
, 'rb')
113 cache
= pickle
.load(cache_file
)
115 if VERSION_KEY
not in cache
or cache
[VERSION_KEY
] != CUR_VERSION
:
116 cache
= {VERSION_KEY
: CUR_VERSION
}
118 cache
= {VERSION_KEY
: CUR_VERSION
}
120 print(("Registering %d files, %d cached" % (len(filenames
), len(list(cache
.keys()))-1)))
125 for filename
in filenames
:
126 file = open(filename
)
127 cur_mtime
= os
.fstat(file.fileno())[ST_MTIME
]
128 if cache
and filename
in cache
:
129 cdict
= cache
[filename
]
130 if cur_mtime
== cdict
['mtime']:
132 # print "Pulling %s from cache" % (filename)
133 regs
['proto_reg'] |
= set(cdict
['proto_reg'])
134 regs
['handoff_reg'] |
= set(cdict
['handoff_reg'])
135 regs
['wtap_register'] |
= set(cdict
['wtap_register'])
138 # We don't have a cache entry
139 if cache
is not None:
147 # print "Searching %s" % (filename)
148 # Read the whole file into memory
149 contents
= file.read()
150 for action
in patterns
:
152 for match
in regex
.finditer(contents
):
153 symbol
= match
.group("symbol")
155 regs
[sym_type
].add(symbol
)
156 if cache
is not None:
157 # print "Caching %s for %s: %s" % (sym_type, filename, symbol)
158 cache
[filename
][sym_type
].append(symbol
)
159 # We're done with the file contents
164 if cache
is not None and cache_filename
is not None:
165 cache_file
= open(cache_filename
, 'wb')
166 pickle
.dump(cache
, cache_file
)
168 print(("Cache hits: %d, misses: %d" % (cache_hits
, cache_misses
)))
170 # Make sure we actually processed something
171 if len(regs
['proto_reg']) < 1:
172 print("No protocol registrations found")
175 # Convert the sets into sorted lists to make the output pretty
176 regs
['proto_reg'] = sorted(regs
['proto_reg'])
177 regs
['handoff_reg'] = sorted(regs
['handoff_reg'])
178 regs
['wtap_register'] = sorted(regs
['wtap_register'])
184 # Make the routine to register all protocols
185 if registertype
== "plugin" or registertype
== "plugin_wtap":
191 #include "moduleinfo.h"
193 /* plugins are DLLs */
195 #include "ws_symbol_export.h"
197 #ifndef ENABLE_STATIC
198 WS_DLL_PUBLIC_DEF const gchar version[] = VERSION;
200 /* Start the functions we need for the plugin stuff */
202 WS_DLL_PUBLIC_DEF void
203 plugin_register (void)
208 #include "register.h"
210 register_all_protocols(register_cb cb, gpointer client_data)
214 for symbol
in regs
['proto_reg']:
215 if registertype
== "plugin" or registertype
== "plugin_wtap":
216 reg_code
+= " {extern void %s (void); %s ();}\n" % (symbol
, symbol
)
218 reg_code
+= " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol
, symbol
, symbol
)
223 # Make the routine to register all protocol handoffs
224 if registertype
== "plugin" or registertype
== "plugin_wtap":
226 WS_DLL_PUBLIC_DEF void
227 plugin_reg_handoff(void)
233 register_all_protocol_handoffs(register_cb cb, gpointer client_data)
237 for symbol
in regs
['handoff_reg']:
238 if registertype
== "plugin" or registertype
== "plugin_wtap":
239 reg_code
+= " {extern void %s (void); %s ();}\n" % (symbol
, symbol
)
241 reg_code
+= " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol
, symbol
, symbol
)
245 if registertype
== "plugin":
246 reg_code
+= "#endif\n"
247 elif registertype
== "plugin_wtap":
249 WS_DLL_PUBLIC_DEF void
250 register_wtap_module(void)
254 for symbol
in regs
['wtap_register']:
255 line
= " {extern void %s (void); %s ();}\n" % (symbol
, symbol
)
265 static gulong proto_reg_count(void)
267 return %(proto_reg_len)d;
270 static gulong handoff_reg_count(void)
272 return %(handoff_reg_len)d;
275 gulong register_count(void)
277 return proto_reg_count() + handoff_reg_count();
281 'proto_reg_len': len(regs
['proto_reg']),
282 'handoff_reg_len': len(regs
['handoff_reg'])
286 # Compare current and new content and update the file if anything has changed.
288 try: # Python >= 2.6, >= 3.0
289 reg_code_bytes
= bytes(reg_code
.encode('utf-8'))
291 reg_code_bytes
= reg_code
293 new_hash
= hashlib
.sha1(reg_code_bytes
).hexdigest()
296 fh
= open(final_filename
, 'rb')
297 cur_hash
= hashlib
.sha1(fh
.read()).hexdigest()
303 if new_hash
!= cur_hash
:
304 print(('Updating ' + final_filename
))
305 fh
= open(final_filename
, 'w')
309 print((final_filename
+ ' unchanged.'))
310 os
.utime(final_filename
, None)
312 sys
.exit('Unable to write ' + final_filename
+ '.\n')
315 # Editor modelines - http://www.wireshark.org/tools/modelines.html
320 # indent-tabs-mode: t
323 # vi: set shiftwidth=8 tabstop=8 noexpandtab:
324 # :indentSize=8:tabSize=8:noTabs=false: