2 # Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in
13 # the documentation and/or other materials provided with the
15 # * Neither the name of Intel Corporation nor the names of its
16 # contributors may be used to endorse or promote products derived
17 # from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 from __future__ import print_function
33 from docutils import nodes
34 from distutils.version import LooseVersion
35 from sphinx import __version__ as sphinx_version
36 from sphinx.highlighting import PygmentsBridge
37 from pygments.formatters.latex import LatexFormatter
38 from os import listdir
39 from os.path import basename
40 from os.path import dirname
41 from os.path import join as path_join
45 import ConfigParser as configparser
51 import sphinx_rtd_theme
53 html_theme = "sphinx_rtd_theme"
54 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
56 print('Install the sphinx ReadTheDocs theme for improved html documentation '
57 'layout: pip install sphinx_rtd_theme')
60 project = 'Data Plane Development Kit'
61 html_logo = '../logo/DPDK_logo_vertical_rev_small.png'
62 latex_logo = '../logo/DPDK_logo_horizontal_tag.png'
63 html_add_permalinks = ""
64 html_show_copyright = False
65 highlight_language = 'none'
67 version = subprocess.check_output(['make', '-sRrC', '../../', 'showversion'])
68 version = version.decode('utf-8').rstrip()
73 # Maximum feature description string length
76 # Figures, tables and code-blocks automatically numbered if they have caption
87 # Latex directives to be included directly in the latex/pdf docs.
88 custom_latex_preamble = r"""
89 \usepackage[utf8]{inputenc}
90 \usepackage[T1]{fontenc}
92 \renewcommand{\familydefault}{\sfdefault}
93 \RecustomVerbatimEnvironment{Verbatim}{Verbatim}{xleftmargin=5mm}
96 # Configuration for the latex/pdf docs.
98 'papersize': 'a4paper',
101 'classoptions': ',openany,oneside',
102 'babel': '\\usepackage[english]{babel}',
103 # customize Latex formatting
104 'preamble': custom_latex_preamble
108 # Override the default Latex formatter in order to modify the
109 # code/verbatim blocks.
110 class CustomLatexFormatter(LatexFormatter):
111 def __init__(self, **options):
112 super(CustomLatexFormatter, self).__init__(**options)
113 # Use the second smallest font size for code/verbatim blocks.
114 self.verboptions = r'formatcom=\footnotesize'
116 # Replace the default latex formatter.
117 PygmentsBridge.latex_formatter = CustomLatexFormatter
119 # Configuration for man pages
120 man_pages = [("testpmd_app_ug/run_app", "testpmd",
121 "tests for dpdk pmds", "", 1),
122 ("tools/pdump", "dpdk-pdump",
123 "enable packet capture on dpdk ports", "", 1),
124 ("tools/proc_info", "dpdk-procinfo",
125 "access dpdk port stats and memory info", "", 1),
126 ("tools/pmdinfo", "dpdk-pmdinfo",
127 "dump a PMDs hardware support info", "", 1),
128 ("tools/devbind", "dpdk-devbind",
129 "check device status and bind/unbind them from drivers", "", 8)]
132 # ####### :numref: fallback ########
133 # The following hook functions add some simple handling for the :numref:
134 # directive for Sphinx versions prior to 1.3.1. The functions replace the
135 # :numref: reference with a link to the target (for all Sphinx doc types).
136 # It doesn't try to label figures/tables.
137 def numref_role(reftype, rawtext, text, lineno, inliner):
139 Add a Sphinx role to handle numref references. Note, we can't convert
140 the link here because the doctree isn't build and the target information
143 # Add an identifier to distinguish numref from other references.
144 newnode = nodes.reference('',
146 refuri='_local_numref_#%s' % text,
151 def process_numref(app, doctree, from_docname):
153 Process the numref nodes once the doctree has been built and prior to
154 writing the files. The processing involves replacing the numref with a
155 link plus text to indicate if it is a Figure or Table link.
158 # Iterate over the reference nodes in the doctree.
159 for node in doctree.traverse(nodes.reference):
160 target = node.get('refuri', '')
162 # Look for numref nodes.
163 if target.startswith('_local_numref_#'):
164 target = target.replace('_local_numref_#', '')
166 # Get the target label and link information from the Sphinx env.
167 data = app.builder.env.domains['std'].data
168 docname, label, _ = data['labels'].get(target, ('', '', ''))
169 relative_url = app.builder.get_relative_uri(from_docname, docname)
171 # Add a text label to the link.
172 if target.startswith('figure'):
174 elif target.startswith('table'):
179 # New reference node with the updated link information.
180 newnode = nodes.reference('',
182 refuri='%s#%s' % (relative_url, label),
184 node.replace_self(newnode)
187 def generate_overview_table(output_filename, table_id, section, table_name, title):
189 Function to generate the Overview Table from the ini files that define
190 the features for each driver.
192 The default features for the table and their order is defined by the
196 # Default warning string.
197 warning = 'Warning generate_overview_table()'
199 # Get the default features and order from the 'default.ini' file.
200 ini_path = path_join(dirname(output_filename), 'features')
201 config = configparser.ConfigParser()
202 config.optionxform = str
203 config.read(path_join(ini_path, 'default.ini'))
204 default_features = config.items(section)
206 # Create a dict of the valid features to validate the other ini files.
208 max_feature_length = 0
209 for feature in default_features:
211 valid_features[key] = ' '
212 max_feature_length = max(max_feature_length, len(key))
214 # Get a list of driver ini files, excluding 'default.ini'.
215 ini_files = [basename(file) for file in listdir(ini_path)
216 if file.endswith('.ini') and file != 'default.ini']
219 # Build up a list of the table header names from the ini filenames.
221 for ini_filename in ini_files:
222 name = ini_filename[:-4]
223 name = name.replace('_vf', 'vf')
225 # Pad the table header names to match the existing format.
227 pmd, vec = name.split('_')
228 name = '{0:{fill}{align}7}vec'.format(pmd, fill='.', align='<')
230 name = '{0:{fill}{align}10}'.format(name, fill=' ', align='<')
232 header_names.append(name)
234 # Create a dict of the defined features for each driver from the ini files.
236 for ini_filename in ini_files:
237 config = configparser.ConfigParser()
238 config.optionxform = str
239 config.read(path_join(ini_path, ini_filename))
241 # Initialize the dict with the default.ini value.
242 ini_data[ini_filename] = valid_features.copy()
244 # Check for a valid ini section.
245 if not config.has_section(section):
246 print("{}: File '{}' has no [{}] secton".format(warning,
251 # Check for valid features names.
252 for name, value in config.items(section):
253 if name not in valid_features:
254 print("{}: Unknown feature '{}' in '{}'".format(warning,
260 # Get the first letter only.
261 ini_data[ini_filename][name] = value[0]
263 # Print out the RST Driver Overview table from the ini file data.
264 outfile = open(output_filename, 'w')
265 num_cols = len(header_names)
267 print_table_css(outfile, table_id)
268 print('.. table:: ' + table_name + '\n', file=outfile)
269 print_table_header(outfile, num_cols, header_names, title)
270 print_table_body(outfile, num_cols, ini_files, ini_data, default_features)
273 def print_table_header(outfile, num_cols, header_names, title):
274 """ Print the RST table header. The header names are vertical. """
275 print_table_divider(outfile, num_cols)
278 for name in header_names:
279 line += ' ' + name[0]
281 print_table_row(outfile, title, line)
283 for i in range(1, 10):
285 for name in header_names:
286 line += ' ' + name[i]
288 print_table_row(outfile, '', line)
290 print_table_divider(outfile, num_cols)
293 def print_table_body(outfile, num_cols, ini_files, ini_data, default_features):
294 """ Print out the body of the table. Each row is a NIC feature. """
296 for feature, _ in default_features:
299 for ini_filename in ini_files:
300 line += ' ' + ini_data[ini_filename][feature]
302 print_table_row(outfile, feature, line)
304 print_table_divider(outfile, num_cols)
307 def print_table_row(outfile, feature, line):
308 """ Print a single row of the table with fixed formatting. """
310 print(' {:<{}}{}'.format(feature, feature_str_len, line), file=outfile)
313 def print_table_divider(outfile, num_cols):
314 """ Print the table divider line. """
316 column_dividers = ['='] * num_cols
317 line += ' '.join(column_dividers)
319 feature = '=' * feature_str_len
321 print_table_row(outfile, feature, line)
324 def print_table_css(outfile, table_id):
336 table#idx th, table#idx td {
341 white-space: pre-wrap;
345 table#idx th:first-child {
346 vertical-align: bottom;
352 table#idx td:first-child {
356 table#idx tr:nth-child(2n-1) td {
357 background-color: rgba(210, 210, 210, 0.2);
359 table#idx th:not(:first-child):hover,
360 table#idx td:not(:first-child):hover {
363 table#idx th:not(:first-child):hover::after,
364 table#idx td:not(:first-child):hover::after {
372 background-color: #ffb;
374 table#idx tr:hover td {
375 background-color: #ffb;
379 print(template.replace("idx", "id%d" % (table_id)), file=outfile)
383 table_file = dirname(__file__) + '/nics/overview_table.txt'
384 generate_overview_table(table_file, 1,
386 'Features availability in networking drivers',
388 table_file = dirname(__file__) + '/cryptodevs/overview_feature_table.txt'
389 generate_overview_table(table_file, 1,
391 'Features availability in crypto drivers',
393 table_file = dirname(__file__) + '/cryptodevs/overview_cipher_table.txt'
394 generate_overview_table(table_file, 2,
396 'Cipher algorithms in crypto drivers',
398 table_file = dirname(__file__) + '/cryptodevs/overview_auth_table.txt'
399 generate_overview_table(table_file, 3,
401 'Authentication algorithms in crypto drivers',
402 'Authentication algorithm')
403 table_file = dirname(__file__) + '/cryptodevs/overview_aead_table.txt'
404 generate_overview_table(table_file, 4,
406 'AEAD algorithms in crypto drivers',
409 if LooseVersion(sphinx_version) < LooseVersion('1.3.1'):
410 print('Upgrade sphinx to version >= 1.3.1 for '
411 'improved Figure/Table number handling.')
412 # Add a role to handle :numref: references.
413 app.add_role('numref', numref_role)
414 # Process the numref references once the doctree has been created.
415 app.connect('doctree-resolved', process_numref)