1# BSD LICENSE 2# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 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 14# distribution. 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. 18# 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. 30 31from __future__ import print_function 32import subprocess 33from docutils import nodes 34from distutils.version import LooseVersion 35from sphinx import __version__ as sphinx_version 36from sphinx.highlighting import PygmentsBridge 37from pygments.formatters.latex import LatexFormatter 38from os import listdir 39from os.path import basename 40from os.path import dirname 41from os.path import join as path_join 42 43try: 44 # Python 2. 45 import ConfigParser as configparser 46except: 47 # Python 3. 48 import configparser 49 50 51project = 'Data Plane Development Kit' 52 53if LooseVersion(sphinx_version) >= LooseVersion('1.3.1'): 54 html_theme = "sphinx_rtd_theme" 55html_logo = '../logo/DPDK_logo_vertical_rev_small.png' 56latex_logo = '../logo/DPDK_logo_horizontal_tag.png' 57html_add_permalinks = "" 58html_show_copyright = False 59highlight_language = 'none' 60 61version = subprocess.check_output(['make', '-sRrC', '../../', 'showversion']) 62version = version.decode('utf-8').rstrip() 63release = version 64 65master_doc = 'index' 66 67# Maximum feature description string length 68feature_str_len = 25 69 70# Figures, tables and code-blocks automatically numbered if they have caption 71numfig = True 72 73latex_documents = [ 74 ('index', 75 'doc.tex', 76 '', 77 '', 78 'manual') 79] 80 81# Latex directives to be included directly in the latex/pdf docs. 82custom_latex_preamble = r""" 83\usepackage[utf8]{inputenc} 84\usepackage[T1]{fontenc} 85\usepackage{helvet} 86\renewcommand{\familydefault}{\sfdefault} 87\RecustomVerbatimEnvironment{Verbatim}{Verbatim}{xleftmargin=5mm} 88""" 89 90# Configuration for the latex/pdf docs. 91latex_elements = { 92 'papersize': 'a4paper', 93 'pointsize': '11pt', 94 # remove blank pages 95 'classoptions': ',openany,oneside', 96 'babel': '\\usepackage[english]{babel}', 97 # customize Latex formatting 98 'preamble': custom_latex_preamble 99} 100 101 102# Override the default Latex formatter in order to modify the 103# code/verbatim blocks. 104class CustomLatexFormatter(LatexFormatter): 105 def __init__(self, **options): 106 super(CustomLatexFormatter, self).__init__(**options) 107 # Use the second smallest font size for code/verbatim blocks. 108 self.verboptions = r'formatcom=\footnotesize' 109 110# Replace the default latex formatter. 111PygmentsBridge.latex_formatter = CustomLatexFormatter 112 113# Configuration for man pages 114man_pages = [("testpmd_app_ug/run_app", "testpmd", 115 "tests for dpdk pmds", "", 1), 116 ("tools/pdump", "dpdk-pdump", 117 "enable packet capture on dpdk ports", "", 1), 118 ("tools/proc_info", "dpdk-procinfo", 119 "access dpdk port stats and memory info", "", 1), 120 ("tools/pmdinfo", "dpdk-pmdinfo", 121 "dump a PMDs hardware support info", "", 1), 122 ("tools/devbind", "dpdk-devbind", 123 "check device status and bind/unbind them from drivers", "", 8)] 124 125 126# ####### :numref: fallback ######## 127# The following hook functions add some simple handling for the :numref: 128# directive for Sphinx versions prior to 1.3.1. The functions replace the 129# :numref: reference with a link to the target (for all Sphinx doc types). 130# It doesn't try to label figures/tables. 131def numref_role(reftype, rawtext, text, lineno, inliner): 132 """ 133 Add a Sphinx role to handle numref references. Note, we can't convert 134 the link here because the doctree isn't build and the target information 135 isn't available. 136 """ 137 # Add an identifier to distinguish numref from other references. 138 newnode = nodes.reference('', 139 '', 140 refuri='_local_numref_#%s' % text, 141 internal=True) 142 return [newnode], [] 143 144 145def process_numref(app, doctree, from_docname): 146 """ 147 Process the numref nodes once the doctree has been built and prior to 148 writing the files. The processing involves replacing the numref with a 149 link plus text to indicate if it is a Figure or Table link. 150 """ 151 152 # Iterate over the reference nodes in the doctree. 153 for node in doctree.traverse(nodes.reference): 154 target = node.get('refuri', '') 155 156 # Look for numref nodes. 157 if target.startswith('_local_numref_#'): 158 target = target.replace('_local_numref_#', '') 159 160 # Get the target label and link information from the Sphinx env. 161 data = app.builder.env.domains['std'].data 162 docname, label, _ = data['labels'].get(target, ('', '', '')) 163 relative_url = app.builder.get_relative_uri(from_docname, docname) 164 165 # Add a text label to the link. 166 if target.startswith('figure'): 167 caption = 'Figure' 168 elif target.startswith('table'): 169 caption = 'Table' 170 else: 171 caption = 'Link' 172 173 # New reference node with the updated link information. 174 newnode = nodes.reference('', 175 caption, 176 refuri='%s#%s' % (relative_url, label), 177 internal=True) 178 node.replace_self(newnode) 179 180 181def generate_overview_table(output_filename, section, table_name, title): 182 """ 183 Function to generate the Overview Table from the ini files that define 184 the features for each driver. 185 186 The default features for the table and their order is defined by the 187 'default.ini' file. 188 189 """ 190 # Default warning string. 191 warning = 'Warning generate_overview_table()' 192 193 # Get the default features and order from the 'default.ini' file. 194 ini_path = path_join(dirname(output_filename), 'features') 195 config = configparser.ConfigParser() 196 config.optionxform = str 197 config.read(path_join(ini_path, 'default.ini')) 198 default_features = config.items(section) 199 200 # Create a dict of the valid features to validate the other ini files. 201 valid_features = {} 202 max_feature_length = 0 203 for feature in default_features: 204 key = feature[0] 205 valid_features[key] = ' ' 206 max_feature_length = max(max_feature_length, len(key)) 207 208 # Get a list of driver ini files, excluding 'default.ini'. 209 ini_files = [basename(file) for file in listdir(ini_path) 210 if file.endswith('.ini') and file != 'default.ini'] 211 ini_files.sort() 212 213 # Build up a list of the table header names from the ini filenames. 214 header_names = [] 215 for ini_filename in ini_files: 216 name = ini_filename[:-4] 217 name = name.replace('_vf', 'vf') 218 219 # Pad the table header names to match the existing format. 220 if '_vec' in name: 221 pmd, vec = name.split('_') 222 name = '{0:{fill}{align}7}vec'.format(pmd, fill='.', align='<') 223 else: 224 name = '{0:{fill}{align}10}'.format(name, fill=' ', align='<') 225 226 header_names.append(name) 227 228 # Create a dict of the defined features for each driver from the ini files. 229 ini_data = {} 230 for ini_filename in ini_files: 231 config = configparser.ConfigParser() 232 config.optionxform = str 233 config.read(path_join(ini_path, ini_filename)) 234 235 # Initialize the dict with the default.ini value. 236 ini_data[ini_filename] = valid_features.copy() 237 238 # Check for a valid ini section. 239 if not config.has_section(section): 240 print("{}: File '{}' has no [{}] secton".format(warning, 241 ini_filename, 242 section)) 243 continue 244 245 # Check for valid features names. 246 for name, value in config.items(section): 247 if name not in valid_features: 248 print("{}: Unknown feature '{}' in '{}'".format(warning, 249 name, 250 ini_filename)) 251 continue 252 253 if value is not '': 254 # Get the first letter only. 255 ini_data[ini_filename][name] = value[0] 256 257 # Print out the RST Driver Overview table from the ini file data. 258 outfile = open(output_filename, 'w') 259 num_cols = len(header_names) 260 261 print('.. table:: ' + table_name + '\n', 262 file=outfile) 263 264 print_table_header(outfile, num_cols, header_names, title) 265 print_table_body(outfile, num_cols, ini_files, ini_data, default_features) 266 267 268def print_table_header(outfile, num_cols, header_names, title): 269 """ Print the RST table header. The header names are vertical. """ 270 print_table_divider(outfile, num_cols) 271 272 line = '' 273 for name in header_names: 274 line += ' ' + name[0] 275 276 print_table_row(outfile, title, line) 277 278 for i in range(1, 10): 279 line = '' 280 for name in header_names: 281 line += ' ' + name[i] 282 283 print_table_row(outfile, '', line) 284 285 print_table_divider(outfile, num_cols) 286 287 288def print_table_body(outfile, num_cols, ini_files, ini_data, default_features): 289 """ Print out the body of the table. Each row is a NIC feature. """ 290 291 for feature, _ in default_features: 292 line = '' 293 294 for ini_filename in ini_files: 295 line += ' ' + ini_data[ini_filename][feature] 296 297 print_table_row(outfile, feature, line) 298 299 print_table_divider(outfile, num_cols) 300 301 302def print_table_row(outfile, feature, line): 303 """ Print a single row of the table with fixed formatting. """ 304 line = line.rstrip() 305 print(' {:<{}}{}'.format(feature, feature_str_len, line), file=outfile) 306 307 308def print_table_divider(outfile, num_cols): 309 """ Print the table divider line. """ 310 line = ' ' 311 column_dividers = ['='] * num_cols 312 line += ' '.join(column_dividers) 313 314 feature = '=' * feature_str_len 315 316 print_table_row(outfile, feature, line) 317 318 319def setup(app): 320 table_file = dirname(__file__) + '/nics/overview_table.txt' 321 generate_overview_table(table_file, 322 'Features', 323 'Features availability in networking drivers', 324 'Feature') 325 table_file = dirname(__file__) + '/cryptodevs/overview_feature_table.txt' 326 generate_overview_table(table_file, 327 'Features', 328 'Features availability in crypto drivers', 329 'Feature') 330 table_file = dirname(__file__) + '/cryptodevs/overview_cipher_table.txt' 331 generate_overview_table(table_file, 332 'Cipher', 333 'Cipher algorithms in crypto drivers', 334 'Cipher algorithm') 335 table_file = dirname(__file__) + '/cryptodevs/overview_auth_table.txt' 336 generate_overview_table(table_file, 337 'Auth', 338 'Authentication algorithms in crypto drivers', 339 'Authentication algorithm') 340 table_file = dirname(__file__) + '/cryptodevs/overview_aead_table.txt' 341 generate_overview_table(table_file, 342 'AEAD', 343 'AEAD algorithms in crypto drivers', 344 'AEAD algorithm') 345 346 if LooseVersion(sphinx_version) < LooseVersion('1.3.1'): 347 print('Upgrade sphinx to version >= 1.3.1 for ' 348 'improved Figure/Table number handling.') 349 # Add a role to handle :numref: references. 350 app.add_role('numref', numref_role) 351 # Process the numref references once the doctree has been created. 352 app.connect('doctree-resolved', process_numref) 353