Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / native_client_sdk / src / doc / doxygen / rst_index.py
blob35e4f020bd681555da30eafbee2b2424249ce2b8
1 #!/usr/bin/env python
2 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Script to generate rst index file doxygen generated html files.
7 """
9 import argparse
10 import cStringIO
11 import fnmatch
12 import os
13 import re
14 import sys
16 VALID_CHANNELS = ('stable', 'beta', 'dev')
18 ROOT_FILE_CONTENTS = """\
19 .. _pepper_%(channel)s_index:
22 :orphan:
24 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
26 ########################################
27 Pepper API Reference (%(channel_title)s)
28 ########################################
30 This page lists the API for Pepper %(version)s. Apps that use this API can
31 run in Chrome %(version)s or higher.
33 :ref:`Pepper C API Reference <pepper_%(channel)s_c_index>`
34 ===========================================================
36 :ref:`Pepper C++ API Reference <pepper_%(channel)s_cpp_index>`
37 ===============================================================
39 """
41 C_FILE_CONTENTS = """\
42 .. _pepper_%(channel)s_c_index:
43 .. _c-api%(channel_alt)s:
45 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
47 ##########################################
48 Pepper C API Reference (%(channel_title)s)
49 ##########################################
51 This page lists the C API for Pepper %(version)s. Apps that use this API can
52 run in Chrome %(version)s or higher.
54 `Interfaces <pepper_%(channel)s/c/group___interfaces.html>`__
55 =============================================================
56 %(interfaces)s
58 `Structures <pepper_%(channel)s/c/group___structs.html>`__
59 ==========================================================
60 %(structures)s
62 `Functions <pepper_%(channel)s/c/group___functions.html>`__
63 ===========================================================
65 `Enums <pepper_%(channel)s/c/group___enums.html>`__
66 ===================================================
68 `Typedefs <pepper_%(channel)s/c/group___typedefs.html>`__
69 =========================================================
71 `Macros <pepper_%(channel)s/c/globals_defs.html>`__
72 ===================================================
74 Files
75 =====
76 %(files)s
77 """
79 C_INTERFACE_WILDCARDS = ['struct_p_p_p__*', 'struct_p_p_b__*']
81 C_STRUCT_WILDCARDS = ['struct_p_p__*', 'union_p_p__*']
83 CPP_FILE_CONTENTS = """\
84 .. _pepper_%(channel)s_cpp_index:
85 .. _cpp-api%(channel_alt)s:
87 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
89 ############################################
90 Pepper C++ API Reference (%(channel_title)s)
91 ############################################
93 This page lists the C++ API for Pepper %(version)s. Apps that use this API can
94 run in Chrome %(version)s or higher.
96 `Classes <pepper_%(channel)s/cpp/inherits.html>`__
97 ==================================================
98 %(classes)s
100 Files
101 =====
102 %(files)s
105 CPP_CLASSES_WILDCARDS = ['classpp_1_1*.html']
106 CPP_CLASSES_EXCLUDES = ['*-members*']
108 FILE_WILDCARDS = ['*_8h.html']
111 def GetName(filename):
112 filename = os.path.splitext(filename)[0]
113 out = ''
114 if filename.startswith('struct_p_p_b__'):
115 mangle = filename[7:] # skip "struct_"
116 elif filename.startswith('struct_p_p_p__'):
117 mangle = filename[7:] # skip "struct_"
118 elif filename.startswith('struct_p_p__'):
119 mangle = filename[7:] # skip "struct_"
120 elif filename.startswith('union_p_p__'):
121 mangle = filename[6:] # skip "union_"
122 elif filename.startswith('classpp_1_1_'):
123 mangle = filename[12:]
124 elif filename.startswith('classpp_1_1ext_1_1_'):
125 out = 'Ext::' # maybe 'ext::' ?
126 mangle = filename[19:]
127 elif filename.startswith('classpp_1_1internal_1_1_'):
128 out = 'Internal::' # maybe 'internal::'
129 mangle = filename[24:]
130 elif filename.startswith('structpp_1_1internal_1_1_'):
131 out = 'Internal::'
132 mangle = filename[25:]
133 elif filename.endswith('_8h'):
134 return filename[:-3].replace('__', '_') + '.h'
135 else:
136 print 'No match: ' + filename
137 cap = True
138 for c in mangle:
139 if c == '_':
140 if cap:
141 # If cap is True, we've already read one underscore. The second means
142 # that we should insert a literal underscore.
143 cap = False
144 else:
145 cap = True
146 continue
147 if cap:
148 c = c.upper()
149 cap = False
150 out += c
152 # Strip trailing version number (e.g. PPB_Audio_1_1 -> PPB_Audio)
153 return re.sub(r'_\d_\d$', '', out)
156 def GetPath(filepath):
157 if os.path.exists(filepath):
158 return filepath
159 raise OSError('Couldn\'t find: ' + filepath)
162 def MakeReSTListFromFiles(prefix, path, matches, excludes=None):
163 dir_files = os.listdir(path)
164 good_files = []
165 for match in matches:
166 good_files.extend(fnmatch.filter(dir_files, match))
168 if excludes:
169 for exclude in excludes:
170 good_files = [filename for filename in good_files
171 if not fnmatch.fnmatch(filename, exclude)]
173 good_files.sort()
174 return '\n'.join(' * `%s <%s/%s>`__\n' % (GetName(f), prefix, f)
175 for f in good_files)
178 def MakeTitleCase(s):
179 return s[0].upper() + s[1:]
181 def MakeChannelAlt(channel):
182 if channel == 'stable':
183 return ''
184 else:
185 return '-' + channel
188 def GenerateRootIndex(channel, version, out_filename):
189 channel_title = MakeTitleCase(channel)
190 channel_alt = MakeChannelAlt(channel)
192 # Use StringIO so we don't write out a partial file on error.
193 output = cStringIO.StringIO()
194 output.write(ROOT_FILE_CONTENTS % vars())
196 with open(out_filename, 'w') as f:
197 f.write(output.getvalue())
200 def GenerateCIndex(root_dir, channel, version, out_filename):
201 prefix = 'pepper_%s/c' % channel
202 interfaces = MakeReSTListFromFiles(prefix, root_dir, C_INTERFACE_WILDCARDS)
203 structures = MakeReSTListFromFiles(prefix, root_dir, C_STRUCT_WILDCARDS)
204 files = MakeReSTListFromFiles(prefix, root_dir, FILE_WILDCARDS)
205 channel_title = MakeTitleCase(channel)
206 channel_alt = MakeChannelAlt(channel)
208 # Use StringIO so we don't write out a partial file on error.
209 output = cStringIO.StringIO()
210 output.write(C_FILE_CONTENTS % vars())
212 with open(out_filename, 'w') as f:
213 f.write(output.getvalue())
216 def GenerateCppIndex(root_dir, channel, version, out_filename):
217 prefix = 'pepper_%s/cpp' % channel
218 classes = MakeReSTListFromFiles(prefix, root_dir, CPP_CLASSES_WILDCARDS,
219 CPP_CLASSES_EXCLUDES)
220 files = MakeReSTListFromFiles(prefix, root_dir, FILE_WILDCARDS)
221 channel_title = MakeTitleCase(channel)
222 channel_alt = MakeChannelAlt(channel)
224 # Use StringIO so we don't write out a partial file on error.
225 output = cStringIO.StringIO()
226 output.write(CPP_FILE_CONTENTS % vars())
228 with open(out_filename, 'w') as f:
229 f.write(output.getvalue())
232 def main(argv):
233 parser = argparse.ArgumentParser(description=__doc__)
234 parser.add_argument('--channel', help='pepper channel (stable, beta, dev)')
235 parser.add_argument('--version', help='pepper version (e.g. 32, 33, etc.)')
236 parser.add_argument('--root', help='Generate root API index',
237 action='store_true', default=False)
238 parser.add_argument('--c', help='Generate C API index', action='store_true',
239 default=False)
240 parser.add_argument('--cpp', help='Generate C++ API index',
241 action='store_true', default=False)
242 parser.add_argument('directory', help='input directory')
243 parser.add_argument('output_file', help='output file')
244 options = parser.parse_args(argv)
246 if options.channel not in VALID_CHANNELS:
247 parser.error('Expected channel to be one of %s' % ', '.join(VALID_CHANNELS))
249 if sum((options.c, options.cpp, options.root)) != 1:
250 parser.error('Exactly one of --c/--cpp/--root flags is required.')
253 if options.c:
254 GenerateCIndex(options.directory, options.channel, options.version,
255 options.output_file)
256 elif options.cpp:
257 GenerateCppIndex(options.directory, options.channel, options.version,
258 options.output_file)
259 elif options.root:
260 GenerateRootIndex(options.channel, options.version,
261 options.output_file)
262 else:
263 assert(False)
264 return 0
267 if __name__ == '__main__':
268 try:
269 rtn = main(sys.argv[1:])
270 except KeyboardInterrupt:
271 sys.stderr.write('%s: interrupted\n' % os.path.basename(__file__))
272 rtn = 1
273 sys.exit(rtn)