0e04795f4bd41f97c83814b621ae1b53b13ec029
[obnox/wireshark/wip.git] / tools / make-dissector-reg.py
1 #!/usr/bin/env python
2 #
3 # Looks for registration routines in the protocol dissectors,
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 # $Id$
13
14 import os
15 import sys
16 import re
17
18 #
19 # The first argument is the directory in which the source files live.
20 #
21 srcdir = sys.argv[1]
22
23 #
24 # The second argument is either "plugin" or "dissectors"; if it's
25 # "plugin", we build a plugin.c for a plugin, and if it's
26 # "dissectors", we build a register.c for libethereal.
27 #
28 registertype = sys.argv[2]
29 if registertype == "plugin":
30         tmp_filename = "plugin.c-tmp"
31         final_filename = "plugin.c"
32 elif registertype == "dissectors":
33         tmp_filename = "register.c-tmp"
34         final_filename = "register.c"
35 else:
36         print "Unknown output type '%s'" % registertype
37         sys.exit(1)
38         
39
40 #
41 # All subsequent arguments are the files to scan.
42 #
43 files = sys.argv[3:]
44
45 # Create the proper list of filenames
46 filenames = []
47 for file in files:
48         if os.path.isfile(file):
49                 filenames.append(file)
50         else:
51                 filenames.append("%s/%s" % (srcdir, file))
52
53
54 # Look through all files, applying the regex to each line.
55 # If the pattern matches, save the "symbol" section to the
56 # appropriate array.
57 proto_reg = []
58 handoff_reg = []
59
60 # For those that don't know Python, r"" indicates a raw string,
61 # devoid of Python escapes.
62 proto_regex0 = r"^(?P<symbol>proto_register_[_A-Za-z0-9]+)\s*\([^;]+$"
63 proto_regex1 = r"void\s+(?P<symbol>proto_register_[_A-Za-z0-9]+)\s*\([^;]+$"
64
65 handoff_regex0 = r"^(?P<symbol>proto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$"
66 handoff_regex1 = r"void\s+(?P<symbol>proto_reg_handoff_[_A-Za-z0-9]+)\s*\([^;]+$"
67
68 # This table drives the pattern-matching and symbol-harvesting
69 patterns = [
70         ( proto_reg, re.compile(proto_regex0) ),
71         ( proto_reg, re.compile(proto_regex1) ),
72         ( handoff_reg, re.compile(handoff_regex0) ),
73         ( handoff_reg, re.compile(handoff_regex1) ),
74         ]
75
76 # Grep
77 for filename in filenames:
78         file = open(filename)
79 #       print "Searching %s" % (filename)
80         for line in file.readlines():
81                 for action in patterns:
82                         regex = action[1]
83                         match = regex.search(line)
84                         if match:
85                                 symbol = match.group("symbol")
86                                 list = action[0]
87                                 list.append(symbol)
88         file.close()
89
90 # Sort the lists to make them pretty
91 proto_reg.sort()
92 handoff_reg.sort()
93
94 reg_code = open(tmp_filename, "w")
95
96 reg_code.write("/* Do not modify this file.  */\n")
97 reg_code.write("/* It is created automatically by the Makefile.  */\n")
98
99 # Make the routine to register all protocols
100 if registertype == "plugin":
101         reg_code.write("""
102 #ifdef HAVE_CONFIG_H
103 # include "config.h"
104 #endif
105
106 #include <gmodule.h>
107
108 #include "moduleinfo.h"
109
110 #ifndef ENABLE_STATIC
111 G_MODULE_EXPORT const gchar version[] = VERSION;
112
113 /* Start the functions we need for the plugin stuff */
114
115 G_MODULE_EXPORT void
116 plugin_register (void)
117 {
118 """);
119 else:
120         reg_code.write("""
121 #include "register.h"
122 void
123 register_all_protocols(void)
124 {
125 """);
126
127 for symbol in proto_reg:
128         line = "  {extern void %s (void); %s ();}\n" % (symbol, symbol)
129         reg_code.write(line)
130
131 reg_code.write("}\n")
132
133
134 # Make the routine to register all protocol handoffs
135 if registertype == "plugin":
136         reg_code.write("""
137 G_MODULE_EXPORT void
138 plugin_reg_handoff(void)
139 {
140 """);
141 else:
142         reg_code.write("""
143 void
144 register_all_protocol_handoffs(void)
145 {
146 """);
147
148 for symbol in handoff_reg:
149         line = "  {extern void %s (void); %s ();}\n" % (symbol, symbol)
150         reg_code.write(line)
151
152 reg_code.write("}\n")
153
154 if registertype == "plugin":
155         reg_code.write("#endif\n");
156
157 # Close the file
158 reg_code.close()
159
160 # Remove the old final_file if it exists.
161 try:
162         os.stat(final_filename)
163         os.remove(final_filename)
164 except OSError:
165         pass
166
167 # Move from tmp file to final file
168 os.rename(tmp_filename, final_filename)
169
170