2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright(c) 2010-2015 Intel Corporation
5 from docutils import nodes
6 from distutils.version import LooseVersion
7 from sphinx import __version__ as sphinx_version
10 from os.path import basename
11 from os.path import dirname
12 from os.path import join as path_join
13 from sys import argv, stderr
18 import sphinx_rtd_theme
20 html_theme = "sphinx_rtd_theme"
22 print('Install the sphinx ReadTheDocs theme for improved html documentation '
23 'layout: https://sphinx-rtd-theme.readthedocs.io/',
27 stop_on_error = ('-W' in argv)
29 project = 'Data Plane Development Kit'
30 html_logo = '../logo/DPDK_logo_vertical_rev_small.png'
31 if LooseVersion(sphinx_version) >= LooseVersion('3.5'):
32 html_permalinks = False
34 html_add_permalinks = ""
35 html_show_copyright = False
36 highlight_language = 'none'
38 release = environ.setdefault('DPDK_VERSION', "None")
43 # Maximum feature description string length
46 # Figures, tables and code-blocks automatically numbered if they have caption
49 # Configuration for man pages
50 man_pages = [("testpmd_app_ug/run_app", "testpmd",
51 "tests for dpdk pmds", "", 1),
52 ("tools/pdump", "dpdk-pdump",
53 "enable packet capture on dpdk ports", "", 1),
54 ("tools/proc_info", "dpdk-procinfo",
55 "access dpdk port stats and memory info", "", 1),
56 ("tools/pmdinfo", "dpdk-pmdinfo",
57 "dump a PMDs hardware support info", "", 1),
58 ("tools/devbind", "dpdk-devbind",
59 "check device status and bind/unbind them from drivers", "", 8)]
62 # ####### :numref: fallback ########
63 # The following hook functions add some simple handling for the :numref:
64 # directive for Sphinx versions prior to 1.3.1. The functions replace the
65 # :numref: reference with a link to the target (for all Sphinx doc types).
66 # It doesn't try to label figures/tables.
67 def numref_role(reftype, rawtext, text, lineno, inliner):
69 Add a Sphinx role to handle numref references. Note, we can't convert
70 the link here because the doctree isn't build and the target information
73 # Add an identifier to distinguish numref from other references.
74 newnode = nodes.reference('',
76 refuri='_local_numref_#%s' % text,
81 def process_numref(app, doctree, from_docname):
83 Process the numref nodes once the doctree has been built and prior to
84 writing the files. The processing involves replacing the numref with a
85 link plus text to indicate if it is a Figure or Table link.
88 # Iterate over the reference nodes in the doctree.
89 for node in doctree.traverse(nodes.reference):
90 target = node.get('refuri', '')
92 # Look for numref nodes.
93 if target.startswith('_local_numref_#'):
94 target = target.replace('_local_numref_#', '')
96 # Get the target label and link information from the Sphinx env.
97 data = app.builder.env.domains['std'].data
98 docname, label, _ = data['labels'].get(target, ('', '', ''))
99 relative_url = app.builder.get_relative_uri(from_docname, docname)
101 # Add a text label to the link.
102 if target.startswith('figure'):
104 elif target.startswith('table'):
109 # New reference node with the updated link information.
110 newnode = nodes.reference('',
112 refuri='%s#%s' % (relative_url, label),
114 node.replace_self(newnode)
117 def generate_overview_table(output_filename, table_id, section, table_name, title):
119 Function to generate the Overview Table from the ini files that define
120 the features for each driver.
122 The default features for the table and their order is defined by the
126 # Default warning string.
127 warning = 'Warning generate_overview_table()'
129 # Get the default features and order from the 'default.ini' file.
130 ini_path = path_join(dirname(output_filename), 'features')
131 config = configparser.ConfigParser()
132 config.optionxform = str
133 config.read(path_join(ini_path, 'default.ini'))
134 default_features = config.items(section)
136 # Create a dict of the valid features to validate the other ini files.
138 max_feature_length = 0
139 for feature in default_features:
141 valid_features[key] = ' '
142 max_feature_length = max(max_feature_length, len(key))
144 # Get a list of driver ini files, excluding 'default.ini'.
145 ini_files = [basename(file) for file in listdir(ini_path)
146 if file.endswith('.ini') and file != 'default.ini']
149 # Build up a list of the table header names from the ini filenames.
151 for ini_filename in ini_files:
152 name = ini_filename[:-4]
153 name = name.replace('_vf', 'vf')
154 pmd_names.append(name)
156 # Pad the table header names.
157 max_header_len = len(max(pmd_names, key=len))
159 for name in pmd_names:
161 pmd, vec = name.split('_')
162 name = '{0:{fill}{align}{width}}vec'.format(pmd,
163 fill='.', align='<', width=max_header_len-3)
165 name = '{0:{fill}{align}{width}}'.format(name,
166 fill=' ', align='<', width=max_header_len)
167 header_names.append(name)
169 # Create a dict of the defined features for each driver from the ini files.
171 for ini_filename in ini_files:
172 config = configparser.ConfigParser()
173 config.optionxform = str
174 config.read(path_join(ini_path, ini_filename))
176 # Initialize the dict with the default.ini value.
177 ini_data[ini_filename] = valid_features.copy()
179 # Check for a valid ini section.
180 if not config.has_section(section):
181 print("{}: File '{}' has no [{}] secton".format(warning,
186 raise Exception('Warning is treated as a failure')
189 # Check for valid features names.
190 for name, value in config.items(section):
191 if name not in valid_features:
192 print("{}: Unknown feature '{}' in '{}'".format(warning,
197 raise Exception('Warning is treated as a failure')
201 # Get the first letter only.
202 ini_data[ini_filename][name] = value[0]
204 # Print out the RST Driver Overview table from the ini file data.
205 outfile = open(output_filename, 'w')
206 num_cols = len(header_names)
208 print_table_css(outfile, table_id)
209 print('.. table:: ' + table_name + '\n', file=outfile)
210 print_table_header(outfile, num_cols, header_names, title)
211 print_table_body(outfile, num_cols, ini_files, ini_data, default_features)
214 def print_table_header(outfile, num_cols, header_names, title):
215 """ Print the RST table header. The header names are vertical. """
216 print_table_divider(outfile, num_cols)
219 for name in header_names:
220 line += ' ' + name[0]
222 print_table_row(outfile, title, line)
224 for i in range(1, len(header_names[0])):
226 for name in header_names:
227 line += ' ' + name[i]
229 print_table_row(outfile, '', line)
231 print_table_divider(outfile, num_cols)
234 def print_table_body(outfile, num_cols, ini_files, ini_data, default_features):
235 """ Print out the body of the table. Each row is a NIC feature. """
237 for feature, _ in default_features:
240 for ini_filename in ini_files:
241 line += ' ' + ini_data[ini_filename][feature]
243 print_table_row(outfile, feature, line)
245 print_table_divider(outfile, num_cols)
248 def print_table_row(outfile, feature, line):
249 """ Print a single row of the table with fixed formatting. """
251 print(' {:<{}}{}'.format(feature, feature_str_len, line), file=outfile)
254 def print_table_divider(outfile, num_cols):
255 """ Print the table divider line. """
257 column_dividers = ['='] * num_cols
258 line += ' '.join(column_dividers)
260 feature = '=' * feature_str_len
262 print_table_row(outfile, feature, line)
265 def print_table_css(outfile, table_id):
279 line-height: inherit;
281 table#idx th, table#idx td {
283 border: solid 1px #ddd;
288 table#idx th, table#idx th p {
290 white-space: pre-wrap;
294 table#idx col:first-child {
297 table#idx th:first-child {
298 vertical-align: bottom;
303 table#idx td, table#idx td p {
306 table#idx td:first-child {
310 table#idx tr:nth-child(2n-1) td {
311 background-color: rgba(210, 210, 210, 0.2);
313 table#idx th:not(:first-child):hover,
314 table#idx td:not(:first-child):hover {
317 table#idx th:not(:first-child):hover::after,
318 table#idx td:not(:first-child):hover::after {
326 background-color: #ffb;
328 table#idx tr:hover td {
329 background-color: #ffb;
333 print(template.replace("idx", "id%d" % (table_id)), file=outfile)
337 table_file = dirname(__file__) + '/nics/overview_table.txt'
338 generate_overview_table(table_file, 1,
340 'Features availability in networking drivers',
342 table_file = dirname(__file__) + '/cryptodevs/overview_feature_table.txt'
343 generate_overview_table(table_file, 1,
345 'Features availability in crypto drivers',
347 table_file = dirname(__file__) + '/cryptodevs/overview_cipher_table.txt'
348 generate_overview_table(table_file, 2,
350 'Cipher algorithms in crypto drivers',
352 table_file = dirname(__file__) + '/cryptodevs/overview_auth_table.txt'
353 generate_overview_table(table_file, 3,
355 'Authentication algorithms in crypto drivers',
356 'Authentication algorithm')
357 table_file = dirname(__file__) + '/cryptodevs/overview_aead_table.txt'
358 generate_overview_table(table_file, 4,
360 'AEAD algorithms in crypto drivers',
362 table_file = dirname(__file__) + '/cryptodevs/overview_asym_table.txt'
363 generate_overview_table(table_file, 5,
365 'Asymmetric algorithms in crypto drivers',
366 'Asymmetric algorithm')
367 table_file = dirname(__file__) + '/compressdevs/overview_feature_table.txt'
368 generate_overview_table(table_file, 1,
370 'Features availability in compression drivers',
372 table_file = dirname(__file__) + '/regexdevs/overview_feature_table.txt'
373 generate_overview_table(table_file, 1,
375 'Features availability in regex drivers',
377 table_file = dirname(__file__) + '/vdpadevs/overview_feature_table.txt'
378 generate_overview_table(table_file, 1,
380 'Features availability in vDPA drivers',
382 table_file = dirname(__file__) + '/bbdevs/overview_feature_table.txt'
383 generate_overview_table(table_file, 1,
385 'Features availability in bbdev drivers',
388 if LooseVersion(sphinx_version) < LooseVersion('1.3.1'):
389 print('Upgrade sphinx to version >= 1.3.1 for '
390 'improved Figure/Table number handling.',
392 # Add a role to handle :numref: references.
393 app.add_role('numref', numref_role)
394 # Process the numref references once the doctree has been created.
395 app.connect('doctree-resolved', process_numref)
398 # New function in sphinx 1.8
399 app.add_css_file('css/custom.css')
401 app.add_stylesheet('css/custom.css')