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