event/cnxk: add option to configure getwork mode
[dpdk.git] / doc / guides / conf.py
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright(c) 2010-2015 Intel Corporation
4
5 from docutils import nodes
6 from distutils.version import LooseVersion
7 from sphinx import __version__ as sphinx_version
8 from sphinx.highlighting import PygmentsBridge
9 from pygments.formatters.latex import LatexFormatter
10 from os import listdir
11 from os import environ
12 from os.path import basename
13 from os.path import dirname
14 from os.path import join as path_join
15 from sys import argv, stderr
16
17 import configparser
18
19 try:
20     import sphinx_rtd_theme
21
22     html_theme = "sphinx_rtd_theme"
23 except:
24     print('Install the sphinx ReadTheDocs theme for improved html documentation '
25           'layout: https://sphinx-rtd-theme.readthedocs.io/',
26           file=stderr)
27     pass
28
29 stop_on_error = ('-W' in argv)
30
31 project = 'Data Plane Development Kit'
32 html_logo = '../logo/DPDK_logo_vertical_rev_small.png'
33 latex_logo = '../logo/DPDK_logo_horizontal_tag.png'
34 html_add_permalinks = ""
35 html_show_copyright = False
36 highlight_language = 'none'
37
38 release = environ.setdefault('DPDK_VERSION', "None")
39 version = release
40
41 master_doc = 'index'
42
43 # Maximum feature description string length
44 feature_str_len = 30
45
46 # Figures, tables and code-blocks automatically numbered if they have caption
47 numfig = True
48
49 latex_documents = [
50     ('index',
51      'doc.tex',
52      '',
53      '',
54      'manual')
55 ]
56
57 # Latex directives to be included directly in the latex/pdf docs.
58 custom_latex_preamble = r"""
59 \usepackage{textalpha}
60 \RecustomVerbatimEnvironment{Verbatim}{Verbatim}{xleftmargin=5mm}
61 \usepackage{etoolbox}
62 \robustify\(
63 \robustify\)
64 """
65
66 # Configuration for the latex/pdf docs.
67 latex_elements = {
68     'papersize': 'a4paper',
69     'pointsize': '11pt',
70     # remove blank pages
71     'classoptions': ',openany,oneside',
72     'babel': '\\usepackage[english]{babel}',
73     # customize Latex formatting
74     'preamble': custom_latex_preamble
75 }
76
77
78 # Override the default Latex formatter in order to modify the
79 # code/verbatim blocks.
80 class CustomLatexFormatter(LatexFormatter):
81     def __init__(self, **options):
82         super(CustomLatexFormatter, self).__init__(**options)
83         # Use the second smallest font size for code/verbatim blocks.
84         self.verboptions = r'formatcom=\footnotesize'
85
86 # Replace the default latex formatter.
87 PygmentsBridge.latex_formatter = CustomLatexFormatter
88
89 # Configuration for man pages
90 man_pages = [("testpmd_app_ug/run_app", "testpmd",
91               "tests for dpdk pmds", "", 1),
92              ("tools/pdump", "dpdk-pdump",
93               "enable packet capture on dpdk ports", "", 1),
94              ("tools/proc_info", "dpdk-procinfo",
95               "access dpdk port stats and memory info", "", 1),
96              ("tools/pmdinfo", "dpdk-pmdinfo",
97               "dump a PMDs hardware support info", "", 1),
98              ("tools/devbind", "dpdk-devbind",
99               "check device status and bind/unbind them from drivers", "", 8)]
100
101
102 # ####### :numref: fallback ########
103 # The following hook functions add some simple handling for the :numref:
104 # directive for Sphinx versions prior to 1.3.1. The functions replace the
105 # :numref: reference with a link to the target (for all Sphinx doc types).
106 # It doesn't try to label figures/tables.
107 def numref_role(reftype, rawtext, text, lineno, inliner):
108     """
109     Add a Sphinx role to handle numref references. Note, we can't convert
110     the link here because the doctree isn't build and the target information
111     isn't available.
112     """
113     # Add an identifier to distinguish numref from other references.
114     newnode = nodes.reference('',
115                               '',
116                               refuri='_local_numref_#%s' % text,
117                               internal=True)
118     return [newnode], []
119
120
121 def process_numref(app, doctree, from_docname):
122     """
123     Process the numref nodes once the doctree has been built and prior to
124     writing the files. The processing involves replacing the numref with a
125     link plus text to indicate if it is a Figure or Table link.
126     """
127
128     # Iterate over the reference nodes in the doctree.
129     for node in doctree.traverse(nodes.reference):
130         target = node.get('refuri', '')
131
132         # Look for numref nodes.
133         if target.startswith('_local_numref_#'):
134             target = target.replace('_local_numref_#', '')
135
136             # Get the target label and link information from the Sphinx env.
137             data = app.builder.env.domains['std'].data
138             docname, label, _ = data['labels'].get(target, ('', '', ''))
139             relative_url = app.builder.get_relative_uri(from_docname, docname)
140
141             # Add a text label to the link.
142             if target.startswith('figure'):
143                 caption = 'Figure'
144             elif target.startswith('table'):
145                 caption = 'Table'
146             else:
147                 caption = 'Link'
148
149             # New reference node with the updated link information.
150             newnode = nodes.reference('',
151                                       caption,
152                                       refuri='%s#%s' % (relative_url, label),
153                                       internal=True)
154             node.replace_self(newnode)
155
156
157 def generate_overview_table(output_filename, table_id, section, table_name, title):
158     """
159     Function to generate the Overview Table from the ini files that define
160     the features for each driver.
161
162     The default features for the table and their order is defined by the
163     'default.ini' file.
164
165     """
166     # Default warning string.
167     warning = 'Warning generate_overview_table()'
168
169     # Get the default features and order from the 'default.ini' file.
170     ini_path = path_join(dirname(output_filename), 'features')
171     config = configparser.ConfigParser()
172     config.optionxform = str
173     config.read(path_join(ini_path, 'default.ini'))
174     default_features = config.items(section)
175
176     # Create a dict of the valid features to validate the other ini files.
177     valid_features = {}
178     max_feature_length = 0
179     for feature in default_features:
180         key = feature[0]
181         valid_features[key] = ' '
182         max_feature_length = max(max_feature_length, len(key))
183
184     # Get a list of driver ini files, excluding 'default.ini'.
185     ini_files = [basename(file) for file in listdir(ini_path)
186                  if file.endswith('.ini') and file != 'default.ini']
187     ini_files.sort()
188
189     # Build up a list of the table header names from the ini filenames.
190     pmd_names = []
191     for ini_filename in ini_files:
192         name = ini_filename[:-4]
193         name = name.replace('_vf', 'vf')
194         pmd_names.append(name)
195
196     # Pad the table header names.
197     max_header_len = len(max(pmd_names, key=len))
198     header_names = []
199     for name in pmd_names:
200         if '_vec' in name:
201             pmd, vec = name.split('_')
202             name = '{0:{fill}{align}{width}}vec'.format(pmd,
203                     fill='.', align='<', width=max_header_len-3)
204         else:
205             name = '{0:{fill}{align}{width}}'.format(name,
206                     fill=' ', align='<', width=max_header_len)
207         header_names.append(name)
208
209     # Create a dict of the defined features for each driver from the ini files.
210     ini_data = {}
211     for ini_filename in ini_files:
212         config = configparser.ConfigParser()
213         config.optionxform = str
214         config.read(path_join(ini_path, ini_filename))
215
216         # Initialize the dict with the default.ini value.
217         ini_data[ini_filename] = valid_features.copy()
218
219         # Check for a valid ini section.
220         if not config.has_section(section):
221             print("{}: File '{}' has no [{}] secton".format(warning,
222                                                             ini_filename,
223                                                             section),
224                                                             file=stderr)
225             if stop_on_error:
226                 raise Exception('Warning is treated as a failure')
227             continue
228
229         # Check for valid features names.
230         for name, value in config.items(section):
231             if name not in valid_features:
232                 print("{}: Unknown feature '{}' in '{}'".format(warning,
233                                                                 name,
234                                                                 ini_filename),
235                                                                 file=stderr)
236                 if stop_on_error:
237                     raise Exception('Warning is treated as a failure')
238                 continue
239
240             if value:
241                 # Get the first letter only.
242                 ini_data[ini_filename][name] = value[0]
243
244     # Print out the RST Driver Overview table from the ini file data.
245     outfile = open(output_filename, 'w')
246     num_cols = len(header_names)
247
248     print_table_css(outfile, table_id)
249     print('.. table:: ' + table_name + '\n', file=outfile)
250     print_table_header(outfile, num_cols, header_names, title)
251     print_table_body(outfile, num_cols, ini_files, ini_data, default_features)
252
253
254 def print_table_header(outfile, num_cols, header_names, title):
255     """ Print the RST table header. The header names are vertical. """
256     print_table_divider(outfile, num_cols)
257
258     line = ''
259     for name in header_names:
260         line += ' ' + name[0]
261
262     print_table_row(outfile, title, line)
263
264     for i in range(1, len(header_names[0])):
265         line = ''
266         for name in header_names:
267             line += ' ' + name[i]
268
269         print_table_row(outfile, '', line)
270
271     print_table_divider(outfile, num_cols)
272
273
274 def print_table_body(outfile, num_cols, ini_files, ini_data, default_features):
275     """ Print out the body of the table. Each row is a NIC feature. """
276
277     for feature, _ in default_features:
278         line = ''
279
280         for ini_filename in ini_files:
281             line += ' ' + ini_data[ini_filename][feature]
282
283         print_table_row(outfile, feature, line)
284
285     print_table_divider(outfile, num_cols)
286
287
288 def print_table_row(outfile, feature, line):
289     """ Print a single row of the table with fixed formatting. """
290     line = line.rstrip()
291     print('   {:<{}}{}'.format(feature, feature_str_len, line), file=outfile)
292
293
294 def print_table_divider(outfile, num_cols):
295     """ Print the table divider line. """
296     line = ' '
297     column_dividers = ['='] * num_cols
298     line += ' '.join(column_dividers)
299
300     feature = '=' * feature_str_len
301
302     print_table_row(outfile, feature, line)
303
304
305 def print_table_css(outfile, table_id):
306     template = """
307 .. raw:: html
308
309    <style>
310       .wy-nav-content {
311          opacity: .99;
312       }
313       table#idx {
314          cursor: default;
315          overflow: hidden;
316       }
317       table#idx p {
318          margin: 0;
319          line-height: inherit;
320       }
321       table#idx th, table#idx td {
322          text-align: center;
323          border: solid 1px #ddd;
324       }
325       table#idx th {
326          padding: 0.5em 0;
327       }
328       table#idx th, table#idx th p {
329          font-size: 11px;
330          white-space: pre-wrap;
331          vertical-align: top;
332          min-width: 0.9em;
333       }
334       table#idx col:first-child {
335          width: 0;
336       }
337       table#idx th:first-child {
338          vertical-align: bottom;
339       }
340       table#idx td {
341          padding: 1px;
342       }
343       table#idx td, table#idx td p {
344          font-size: 11px;
345       }
346       table#idx td:first-child {
347          padding-left: 1em;
348          text-align: left;
349       }
350       table#idx tr:nth-child(2n-1) td {
351          background-color: rgba(210, 210, 210, 0.2);
352       }
353       table#idx th:not(:first-child):hover,
354       table#idx td:not(:first-child):hover {
355          position: relative;
356       }
357       table#idx th:not(:first-child):hover::after,
358       table#idx td:not(:first-child):hover::after {
359          content: '';
360          height: 6000px;
361          top: -3000px;
362          width: 100%;
363          left: 0;
364          position: absolute;
365          z-index: -1;
366          background-color: #ffb;
367       }
368       table#idx tr:hover td {
369          background-color: #ffb;
370       }
371    </style>
372 """
373     print(template.replace("idx", "id%d" % (table_id)), file=outfile)
374
375
376 def setup(app):
377     table_file = dirname(__file__) + '/nics/overview_table.txt'
378     generate_overview_table(table_file, 1,
379                             'Features',
380                             'Features availability in networking drivers',
381                             'Feature')
382     table_file = dirname(__file__) + '/cryptodevs/overview_feature_table.txt'
383     generate_overview_table(table_file, 1,
384                             'Features',
385                             'Features availability in crypto drivers',
386                             'Feature')
387     table_file = dirname(__file__) + '/cryptodevs/overview_cipher_table.txt'
388     generate_overview_table(table_file, 2,
389                             'Cipher',
390                             'Cipher algorithms in crypto drivers',
391                             'Cipher algorithm')
392     table_file = dirname(__file__) + '/cryptodevs/overview_auth_table.txt'
393     generate_overview_table(table_file, 3,
394                             'Auth',
395                             'Authentication algorithms in crypto drivers',
396                             'Authentication algorithm')
397     table_file = dirname(__file__) + '/cryptodevs/overview_aead_table.txt'
398     generate_overview_table(table_file, 4,
399                             'AEAD',
400                             'AEAD algorithms in crypto drivers',
401                             'AEAD algorithm')
402     table_file = dirname(__file__) + '/cryptodevs/overview_asym_table.txt'
403     generate_overview_table(table_file, 5,
404                             'Asymmetric',
405                             'Asymmetric algorithms in crypto drivers',
406                             'Asymmetric algorithm')
407     table_file = dirname(__file__) + '/compressdevs/overview_feature_table.txt'
408     generate_overview_table(table_file, 1,
409                             'Features',
410                             'Features availability in compression drivers',
411                             'Feature')
412     table_file = dirname(__file__) + '/regexdevs/overview_feature_table.txt'
413     generate_overview_table(table_file, 1,
414                             'Features',
415                             'Features availability in regex drivers',
416                             'Feature')
417     table_file = dirname(__file__) + '/vdpadevs/overview_feature_table.txt'
418     generate_overview_table(table_file, 1,
419                             'Features',
420                             'Features availability in vDPA drivers',
421                             'Feature')
422     table_file = dirname(__file__) + '/bbdevs/overview_feature_table.txt'
423     generate_overview_table(table_file, 1,
424                             'Features',
425                             'Features availability in bbdev drivers',
426                             'Feature')
427
428     if LooseVersion(sphinx_version) < LooseVersion('1.3.1'):
429         print('Upgrade sphinx to version >= 1.3.1 for '
430               'improved Figure/Table number handling.',
431               file=stderr)
432         # Add a role to handle :numref: references.
433         app.add_role('numref', numref_role)
434         # Process the numref references once the doctree has been created.
435         app.connect('doctree-resolved', process_numref)
436
437     try:
438         # New function in sphinx 1.8
439         app.add_css_file('css/custom.css')
440     except:
441         app.add_stylesheet('css/custom.css')