[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / native_client_sdk / src / doc / doxygen / rst_index.py
blobcf1a31f10ed3384006ea52a2a159c48403ecc0f9
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 import cStringIO
7 import fnmatch
8 import optparse
9 import os
10 import re
11 import sys
13 VALID_CHANNELS = ('stable', 'beta', 'dev')
15 ROOT_FILE_CONTENTS = """.. _pepper_%(channel)s_index:
17 :orphan:
19 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
21 ########################################
22 Pepper API Reference (%(channel_title)s)
23 ########################################
25 This page lists the API for Pepper %(version)s. Apps that use this API can
26 run in Chrome %(version)s or higher.
28 :ref:`Pepper C API Reference <pepper_%(channel)s_c_index>`
29 ===========================================================
31 :ref:`Pepper C++ API Reference <pepper_%(channel)s_cpp_index>`
32 ===============================================================
34 """
36 C_FILE_CONTENTS = """.. _pepper_%(channel)s_c_index:
38 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
40 ##########################################
41 Pepper C API Reference (%(channel_title)s)
42 ##########################################
44 This page lists the C API for Pepper %(version)s. Apps that use this API can
45 run in Chrome %(version)s or higher.
47 `Interfaces <group___interfaces.html>`_
48 =======================================
49 %(interfaces)s
51 `Structures <group___structs.html>`_
52 ====================================
53 %(structures)s
55 `Functions <group___functions.html>`_
56 =====================================
58 `Enums <group___enums.html>`_
59 =============================
61 `Typedefs <group___typedefs.html>`_
62 ===================================
64 `Macros <globals_defs.html>`_
65 =============================
67 Files
68 =====
69 %(files)s
70 """
72 C_INTERFACE_WILDCARDS = ['struct_p_p_p__*', 'struct_p_p_b__*']
74 C_STRUCT_WILDCARDS = ['struct_p_p__*', 'union_p_p__*']
76 CPP_FILE_CONTENTS = """.. _pepper_%(channel)s_cpp_index:
78 .. DO NOT EDIT! This document is auto-generated by doxygen/rst_index.py.
80 ############################################
81 Pepper C++ API Reference (%(channel_title)s)
82 ############################################
84 This page lists the C++ API for Pepper %(version)s. Apps that use this API can
85 run in Chrome %(version)s or higher.
87 `Classes <inherits.html>`_
88 ==========================
89 %(classes)s
91 Files
92 =====
93 %(files)s
94 """
96 CPP_CLASSES_WILDCARDS = ['classpp_1_1*.html']
97 CPP_CLASSES_EXCLUDES = ['*-members*']
99 FILE_WILDCARDS = ['*_8h.html']
102 def GetName(filename):
103 filename = os.path.splitext(filename)[0]
104 out = ''
105 if filename.startswith('struct_p_p_b__'):
106 mangle = filename[7:] # skip "struct_"
107 elif filename.startswith('struct_p_p_p__'):
108 mangle = filename[7:] # skip "struct_"
109 elif filename.startswith('struct_p_p__'):
110 mangle = filename[7:] # skip "struct_"
111 elif filename.startswith('union_p_p__'):
112 mangle = filename[6:] # skip "union_"
113 elif filename.startswith('classpp_1_1_'):
114 mangle = filename[12:]
115 elif filename.startswith('classpp_1_1ext_1_1_'):
116 out = 'Ext::' # maybe 'ext::' ?
117 mangle = filename[19:]
118 elif filename.startswith('classpp_1_1internal_1_1_'):
119 out = 'Internal::' # maybe 'internal::'
120 mangle = filename[24:]
121 elif filename.startswith('structpp_1_1internal_1_1_'):
122 out = 'Internal::'
123 mangle = filename[25:]
124 elif filename.endswith('_8h'):
125 return filename[:-3].replace('__', '_') + '.h'
126 else:
127 print 'No match: ' + filename
128 cap = True
129 for c in mangle:
130 if c == '_':
131 if cap:
132 # If cap is True, we've already read one underscore. The second means
133 # that we should insert a literal underscore.
134 cap = False
135 else:
136 cap = True
137 continue
138 if cap:
139 c = c.upper()
140 cap = False
141 out += c
143 # Strip trailing version number (e.g. PPB_Audio_1_1 -> PPB_Audio)
144 return re.sub(r'_\d_\d$', '', out)
147 def GetPath(filepath):
148 if os.path.exists(filepath):
149 return filepath
150 raise OSError('Couldnt find: ' + filepath)
153 def MakeReSTListFromFiles(path, matches, excludes=None):
154 dir_files = os.listdir(path)
155 good_files = []
156 for match in matches:
157 good_files.extend(fnmatch.filter(dir_files, match))
159 if excludes:
160 for exclude in excludes:
161 good_files = [filename for filename in good_files
162 if not fnmatch.fnmatch(filename, exclude)]
164 good_files.sort()
165 return '\n'.join(' * `%s <%s>`_\n' % (GetName(f), f) for f in good_files)
168 def MakeTitleCase(s):
169 return s[0].upper() + s[1:]
172 def GenerateRootIndex(channel, version, out_filename):
173 channel_title = MakeTitleCase(channel)
175 # Use StringIO so we don't write out a partial file on error.
176 output = cStringIO.StringIO()
177 output.write(ROOT_FILE_CONTENTS % vars())
179 with open(out_filename, 'w') as f:
180 f.write(output.getvalue())
183 def GenerateCIndex(root_dir, channel, version, out_filename):
184 interfaces = MakeReSTListFromFiles(root_dir, C_INTERFACE_WILDCARDS)
185 structures = MakeReSTListFromFiles(root_dir, C_STRUCT_WILDCARDS)
186 files = MakeReSTListFromFiles(root_dir, FILE_WILDCARDS)
187 channel_title = MakeTitleCase(channel)
189 # Use StringIO so we don't write out a partial file on error.
190 output = cStringIO.StringIO()
191 output.write(C_FILE_CONTENTS % vars())
193 with open(out_filename, 'w') as f:
194 f.write(output.getvalue())
197 def GenerateCppIndex(root_dir, channel, version, out_filename):
198 classes = MakeReSTListFromFiles(root_dir, CPP_CLASSES_WILDCARDS,
199 CPP_CLASSES_EXCLUDES)
200 files = MakeReSTListFromFiles(root_dir, FILE_WILDCARDS)
201 channel_title = MakeTitleCase(channel)
203 # Use StringIO so we don't write out a partial file on error.
204 output = cStringIO.StringIO()
205 output.write(CPP_FILE_CONTENTS % vars())
207 with open(out_filename, 'w') as f:
208 f.write(output.getvalue())
211 def main(argv):
212 usage = 'Usage: %prog [options] <--root|--c|--cpp> directory'
213 parser = optparse.OptionParser(usage=usage)
214 parser.add_option('--channel', help='pepper channel (stable, beta, dev)')
215 parser.add_option('--version', help='pepper version (e.g. 32, 33, 34, etc.)')
216 parser.add_option('--root', help='Generate root API index',
217 action='store_true', default=False)
218 parser.add_option('--c', help='Generate C API index', action='store_true',
219 default=False)
220 parser.add_option('--cpp', help='Generate C++ API index', action='store_true',
221 default=False)
222 parser.add_option('-o', '--output', help='output file.')
223 options, files = parser.parse_args(argv)
225 if len(files) != 1:
226 parser.error('Expected one directory')
228 if not options.output:
229 parser.error('Need output file')
231 if options.channel not in VALID_CHANNELS:
232 parser.error('Expected channel to be one of %s' % ', '.join(VALID_CHANNELS))
234 if sum((options.c, options.cpp, options.root)) != 1:
235 parser.error('Exactly one of --c/--cpp/--root flags is required.')
237 root_dir = files[0]
239 if options.c:
240 GenerateCIndex(root_dir, options.channel, options.version, options.output)
241 elif options.cpp:
242 GenerateCppIndex(root_dir, options.channel, options.version, options.output)
243 elif options.root:
244 GenerateRootIndex(options.channel, options.version, options.output)
245 else:
246 assert(False)
247 return 0
250 if __name__ == '__main__':
251 try:
252 rtn = main(sys.argv[1:])
253 except KeyboardInterrupt:
254 sys.stderr.write('%s: interrupted\n' % os.path.basename(__file__))
255 rtn = 1
256 sys.exit(rtn)