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 project = 'Data Plane Development Kit'
53 if LooseVersion(sphinx_version) >= LooseVersion('1.3.1'):
54 html_theme = "sphinx_rtd_theme"
55 html_logo = '../logo/DPDK_logo_vertical_rev_small.png'
56 latex_logo = '../logo/DPDK_logo_horizontal_tag.png'
57 html_add_permalinks = ""
58 html_show_copyright = False
59 highlight_language = 'none'
61 version = subprocess.check_output(['make', '-sRrC', '../../', 'showversion']).decode('utf-8').rstrip()
66 # Figures, tables and code-blocks automatically numbered if they have caption
77 # Latex directives to be included directly in the latex/pdf docs.
79 \usepackage[utf8]{inputenc}
80 \usepackage[T1]{fontenc}
82 \renewcommand{\familydefault}{\sfdefault}
83 \RecustomVerbatimEnvironment{Verbatim}{Verbatim}{xleftmargin=5mm}
86 # Configuration for the latex/pdf docs.
88 'papersize': 'a4paper',
91 'classoptions': ',openany,oneside',
92 'babel': '\\usepackage[english]{babel}',
93 # customize Latex formatting
94 'preamble': latex_preamble
97 # Override the default Latex formatter in order to modify the
98 # code/verbatim blocks.
99 class CustomLatexFormatter(LatexFormatter):
100 def __init__(self, **options):
101 super(CustomLatexFormatter, self).__init__(**options)
102 # Use the second smallest font size for code/verbatim blocks.
103 self.verboptions = r'formatcom=\footnotesize'
105 # Replace the default latex formatter.
106 PygmentsBridge.latex_formatter = CustomLatexFormatter
108 # Configuration for man pages
109 man_pages = [("testpmd_app_ug/run_app", "testpmd",
110 "tests for dpdk pmds", "", 1),
111 ("tools/pdump", "dpdk-pdump",
112 "enable packet capture on dpdk ports", "", 1),
113 ("tools/proc_info", "dpdk-procinfo",
114 "access dpdk port stats and memory info", "", 1)]
116 ######## :numref: fallback ########
117 # The following hook functions add some simple handling for the :numref:
118 # directive for Sphinx versions prior to 1.3.1. The functions replace the
119 # :numref: reference with a link to the target (for all Sphinx doc types).
120 # It doesn't try to label figures/tables.
122 def numref_role(reftype, rawtext, text, lineno, inliner):
124 Add a Sphinx role to handle numref references. Note, we can't convert
125 the link here because the doctree isn't build and the target information
128 # Add an identifier to distinguish numref from other references.
129 newnode = nodes.reference('',
131 refuri='_local_numref_#%s' % text,
135 def process_numref(app, doctree, from_docname):
137 Process the numref nodes once the doctree has been built and prior to
138 writing the files. The processing involves replacing the numref with a
139 link plus text to indicate if it is a Figure or Table link.
142 # Iterate over the reference nodes in the doctree.
143 for node in doctree.traverse(nodes.reference):
144 target = node.get('refuri', '')
146 # Look for numref nodes.
147 if target.startswith('_local_numref_#'):
148 target = target.replace('_local_numref_#', '')
150 # Get the target label and link information from the Sphinx env.
151 data = app.builder.env.domains['std'].data
152 docname, label, _ = data['labels'].get(target, ('', '', ''))
153 relative_url = app.builder.get_relative_uri(from_docname, docname)
155 # Add a text label to the link.
156 if target.startswith('figure'):
158 elif target.startswith('table'):
163 # New reference node with the updated link information.
164 newnode = nodes.reference('',
166 refuri='%s#%s' % (relative_url, label),
168 node.replace_self(newnode)
171 def generate_nic_overview_table(output_filename):
173 Function to generate the NIC Overview Table from the ini files that define
174 the features for each NIC.
176 The default features for the table and their order is defined by the
180 # Default worning string.
181 warning = 'Warning generate_nic_overview_table()'
183 # Get the default features and order from the 'default.ini' file.
184 ini_path = path_join(dirname(output_filename), 'features')
185 config = configparser.ConfigParser()
186 config.optionxform = str
187 config.read(path_join(ini_path, 'default.ini'))
188 default_section = 'Features'
189 default_features = config.items(default_section)
191 # Create a dict of the valid features to validate the other ini files.
193 max_feature_length = 0
194 for feature in default_features:
196 valid_features[key] = ' '
197 max_feature_length = max(max_feature_length, len(key))
199 # Get a list of NIC ini files, excluding 'default.ini'.
200 ini_files = [basename(file) for file in listdir(ini_path)
201 if file.endswith('.ini') and file != 'default.ini']
204 # Build up a list of the table header names from the ini filenames.
206 for ini_filename in ini_files:
207 name = ini_filename[:-4]
208 name = name.replace('_vf', 'vf')
210 # Pad the table header names to match the existing format.
212 pmd, vec = name.split('_')
213 name = '{0:{fill}{align}7}vec'.format(pmd, fill='.', align='<')
215 name = '{0:{fill}{align}10}'.format(name, fill=' ', align='<')
217 header_names.append(name)
219 # Create a dict of the defined features for each NIC from the ini files.
221 for ini_filename in ini_files:
222 config = configparser.ConfigParser()
223 config.optionxform = str
224 config.read(path_join(ini_path, ini_filename))
226 # Initialize the dict with the default.ini value.
227 ini_data[ini_filename] = valid_features.copy()
229 # Check for a valid ini section.
230 if not config.has_section(default_section):
231 print("{}: File '{}' has no [{}] secton".format(warning,
236 # Check for valid features names.
237 for name, value in config.items(default_section):
238 if name not in valid_features:
239 print("{}: Unknown feature '{}' in '{}'".format(warning,
245 # Get the first letter only.
246 ini_data[ini_filename][name] = value[0]
248 # Print out the RST NIC Overview table from the ini file data.
249 outfile = open(output_filename, 'w')
250 num_cols = len(header_names)
252 print('.. table:: Features availability in networking drivers\n',
255 print_table_header(outfile, num_cols, header_names)
256 print_table_body(outfile, num_cols, ini_files, ini_data, default_features)
259 def print_table_header(outfile, num_cols, header_names):
260 """ Print the RST table header. The header names are vertical. """
261 print_table_divider(outfile, num_cols)
264 for name in header_names:
265 line += ' ' + name[0]
267 print_table_row(outfile, 'Feature', line)
269 for i in range(1, 10):
271 for name in header_names:
272 line += ' ' + name[i]
274 print_table_row(outfile, '', line)
276 print_table_divider(outfile, num_cols)
279 def print_table_body(outfile, num_cols, ini_files, ini_data, default_features):
280 """ Print out the body of the table. Each row is a NIC feature. """
282 for feature, _ in default_features:
285 for ini_filename in ini_files:
286 line += ' ' + ini_data[ini_filename][feature]
288 print_table_row(outfile, feature, line)
290 print_table_divider(outfile, num_cols)
293 def print_table_row(outfile, feature, line):
294 """ Print a single row of the table with fixed formatting. """
296 print(' {:<20}{}'.format(feature, line), file=outfile)
299 def print_table_divider(outfile, num_cols):
300 """ Print the table divider line. """
302 column_dividers = ['='] * num_cols
303 line += ' '.join(column_dividers)
307 print_table_row(outfile, feature, line)
311 generate_nic_overview_table('doc/guides/nics/overview_table.txt')
313 if LooseVersion(sphinx_version) < LooseVersion('1.3.1'):
314 print('Upgrade sphinx to version >= 1.3.1 for '
315 'improved Figure/Table number handling.')
316 # Add a role to handle :numref: references.
317 app.add_role('numref', numref_role)
318 # Process the numref references once the doctree has been created.
319 app.connect('doctree-resolved', process_numref)