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']).decode('utf-8').rstrip() 62release = version 63 64master_doc = 'index' 65 66# Figures, tables and code-blocks automatically numbered if they have caption 67numfig = True 68 69latex_documents = [ 70 ('index', 71 'doc.tex', 72 '', 73 '', 74 'manual') 75] 76 77# Latex directives to be included directly in the latex/pdf docs. 78latex_preamble = r""" 79\usepackage[utf8]{inputenc} 80\usepackage[T1]{fontenc} 81\usepackage{helvet} 82\renewcommand{\familydefault}{\sfdefault} 83\RecustomVerbatimEnvironment{Verbatim}{Verbatim}{xleftmargin=5mm} 84""" 85 86# Configuration for the latex/pdf docs. 87latex_elements = { 88 'papersize': 'a4paper', 89 'pointsize': '11pt', 90 # remove blank pages 91 'classoptions': ',openany,oneside', 92 'babel': '\\usepackage[english]{babel}', 93 # customize Latex formatting 94 'preamble': latex_preamble 95} 96 97# Override the default Latex formatter in order to modify the 98# code/verbatim blocks. 99class 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' 104 105# Replace the default latex formatter. 106PygmentsBridge.latex_formatter = CustomLatexFormatter 107 108# Configuration for man pages 109man_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), 115 ("tools/pmdinfo", "dpdk-pmdinfo", 116 "dump a PMDs hardware support info", "", 1), 117 ("tools/devbind", "dpdk-devbind", 118 "check device status and bind/unbind them from drivers", "", 8)] 119 120######## :numref: fallback ######## 121# The following hook functions add some simple handling for the :numref: 122# directive for Sphinx versions prior to 1.3.1. The functions replace the 123# :numref: reference with a link to the target (for all Sphinx doc types). 124# It doesn't try to label figures/tables. 125 126def numref_role(reftype, rawtext, text, lineno, inliner): 127 """ 128 Add a Sphinx role to handle numref references. Note, we can't convert 129 the link here because the doctree isn't build and the target information 130 isn't available. 131 """ 132 # Add an identifier to distinguish numref from other references. 133 newnode = nodes.reference('', 134 '', 135 refuri='_local_numref_#%s' % text, 136 internal=True) 137 return [newnode], [] 138 139def process_numref(app, doctree, from_docname): 140 """ 141 Process the numref nodes once the doctree has been built and prior to 142 writing the files. The processing involves replacing the numref with a 143 link plus text to indicate if it is a Figure or Table link. 144 """ 145 146 # Iterate over the reference nodes in the doctree. 147 for node in doctree.traverse(nodes.reference): 148 target = node.get('refuri', '') 149 150 # Look for numref nodes. 151 if target.startswith('_local_numref_#'): 152 target = target.replace('_local_numref_#', '') 153 154 # Get the target label and link information from the Sphinx env. 155 data = app.builder.env.domains['std'].data 156 docname, label, _ = data['labels'].get(target, ('', '', '')) 157 relative_url = app.builder.get_relative_uri(from_docname, docname) 158 159 # Add a text label to the link. 160 if target.startswith('figure'): 161 caption = 'Figure' 162 elif target.startswith('table'): 163 caption = 'Table' 164 else: 165 caption = 'Link' 166 167 # New reference node with the updated link information. 168 newnode = nodes.reference('', 169 caption, 170 refuri='%s#%s' % (relative_url, label), 171 internal=True) 172 node.replace_self(newnode) 173 174 175def generate_nic_overview_table(output_filename): 176 """ 177 Function to generate the NIC Overview Table from the ini files that define 178 the features for each NIC. 179 180 The default features for the table and their order is defined by the 181 'default.ini' file. 182 183 """ 184 # Default worning string. 185 warning = 'Warning generate_nic_overview_table()' 186 187 # Get the default features and order from the 'default.ini' file. 188 ini_path = path_join(dirname(output_filename), 'features') 189 config = configparser.ConfigParser() 190 config.optionxform = str 191 config.read(path_join(ini_path, 'default.ini')) 192 default_section = 'Features' 193 default_features = config.items(default_section) 194 195 # Create a dict of the valid features to validate the other ini files. 196 valid_features = {} 197 max_feature_length = 0 198 for feature in default_features: 199 key = feature[0] 200 valid_features[key] = ' ' 201 max_feature_length = max(max_feature_length, len(key)) 202 203 # Get a list of NIC ini files, excluding 'default.ini'. 204 ini_files = [basename(file) for file in listdir(ini_path) 205 if file.endswith('.ini') and file != 'default.ini'] 206 ini_files.sort() 207 208 # Build up a list of the table header names from the ini filenames. 209 header_names = [] 210 for ini_filename in ini_files: 211 name = ini_filename[:-4] 212 name = name.replace('_vf', 'vf') 213 214 # Pad the table header names to match the existing format. 215 if '_vec' in name: 216 pmd, vec = name.split('_') 217 name = '{0:{fill}{align}7}vec'.format(pmd, fill='.', align='<') 218 else: 219 name = '{0:{fill}{align}10}'.format(name, fill=' ', align='<') 220 221 header_names.append(name) 222 223 # Create a dict of the defined features for each NIC from the ini files. 224 ini_data = {} 225 for ini_filename in ini_files: 226 config = configparser.ConfigParser() 227 config.optionxform = str 228 config.read(path_join(ini_path, ini_filename)) 229 230 # Initialize the dict with the default.ini value. 231 ini_data[ini_filename] = valid_features.copy() 232 233 # Check for a valid ini section. 234 if not config.has_section(default_section): 235 print("{}: File '{}' has no [{}] secton".format(warning, 236 ini_filename, 237 default_section)) 238 continue 239 240 # Check for valid features names. 241 for name, value in config.items(default_section): 242 if name not in valid_features: 243 print("{}: Unknown feature '{}' in '{}'".format(warning, 244 name, 245 ini_filename)) 246 continue 247 248 if value is not '': 249 # Get the first letter only. 250 ini_data[ini_filename][name] = value[0] 251 252 # Print out the RST NIC Overview table from the ini file data. 253 outfile = open(output_filename, 'w') 254 num_cols = len(header_names) 255 256 print('.. table:: Features availability in networking drivers\n', 257 file=outfile) 258 259 print_table_header(outfile, num_cols, header_names) 260 print_table_body(outfile, num_cols, ini_files, ini_data, default_features) 261 262 263def print_table_header(outfile, num_cols, header_names): 264 """ Print the RST table header. The header names are vertical. """ 265 print_table_divider(outfile, num_cols) 266 267 line = '' 268 for name in header_names: 269 line += ' ' + name[0] 270 271 print_table_row(outfile, 'Feature', line) 272 273 for i in range(1, 10): 274 line = '' 275 for name in header_names: 276 line += ' ' + name[i] 277 278 print_table_row(outfile, '', line) 279 280 print_table_divider(outfile, num_cols) 281 282 283def print_table_body(outfile, num_cols, ini_files, ini_data, default_features): 284 """ Print out the body of the table. Each row is a NIC feature. """ 285 286 for feature, _ in default_features: 287 line = '' 288 289 for ini_filename in ini_files: 290 line += ' ' + ini_data[ini_filename][feature] 291 292 print_table_row(outfile, feature, line) 293 294 print_table_divider(outfile, num_cols) 295 296 297def print_table_row(outfile, feature, line): 298 """ Print a single row of the table with fixed formatting. """ 299 line = line.rstrip() 300 print(' {:<20}{}'.format(feature, line), file=outfile) 301 302 303def print_table_divider(outfile, num_cols): 304 """ Print the table divider line. """ 305 line = ' ' 306 column_dividers = ['='] * num_cols 307 line += ' '.join(column_dividers) 308 309 feature = '=' * 20 310 311 print_table_row(outfile, feature, line) 312 313 314def setup(app): 315 generate_nic_overview_table('doc/guides/nics/overview_table.txt') 316 317 if LooseVersion(sphinx_version) < LooseVersion('1.3.1'): 318 print('Upgrade sphinx to version >= 1.3.1 for ' 319 'improved Figure/Table number handling.') 320 # Add a role to handle :numref: references. 321 app.add_role('numref', numref_role) 322 # Process the numref references once the doctree has been created. 323 app.connect('doctree-resolved', process_numref) 324