diff options
Diffstat (limited to 'scripts/check-sysctl-docs')
| -rwxr-xr-x | scripts/check-sysctl-docs | 213 |
1 files changed, 103 insertions, 110 deletions
diff --git a/scripts/check-sysctl-docs b/scripts/check-sysctl-docs index 8bcb9e26c7bc..910fd8a9a268 100755 --- a/scripts/check-sysctl-docs +++ b/scripts/check-sysctl-docs @@ -1,4 +1,4 @@ -#!/usr/bin/gawk -f +#!/usr/bin/env -S gawk -f # SPDX-License-Identifier: GPL-2.0 # Script to check sysctl documentation against source files @@ -8,26 +8,34 @@ # Example invocation: # scripts/check-sysctl-docs -vtable="kernel" \ # Documentation/admin-guide/sysctl/kernel.rst \ -# $(git grep -l register_sysctl_) +# $(git grep -l register_sysctl) # # Specify -vdebug=1 to see debugging information BEGIN { - if (!table) { + if (!table) { print "Please specify the table to look for using the table variable" > "/dev/stderr" exit 1 - } + } + + # Documentation title skiplist + skiplist[0] = "^Documentation for" + skiplist[1] = "Network core options$" + skiplist[2] = "POSIX message queues filesystem$" + skiplist[3] = "Configuration options" + skiplist[4] = ". /proc/sys/fs" + skiplist[5] = "^Introduction$" + skiplist[6] = "^seccomp$" + skiplist[7] = "^pty$" + skiplist[8] = "^firmware_config$" + skiplist[9] = "^random$" } # The following globals are used: -# children: maps ctl_table names and procnames to child ctl_table names # documented: maps documented entries (each key is an entry) # entries: maps ctl_table names and procnames to counts (so # enumerating the subkeys for a given ctl_table lists its # procnames) -# files: maps procnames to source file names -# paths: maps ctl_path names to paths -# curpath: the name of the current ctl_path struct # curtable: the name of the current ctl_table struct # curentry: the name of the current proc entry (procname when parsing # a ctl_table, constructed path when parsing a ctl_path) @@ -35,147 +43,132 @@ BEGIN { # Remove punctuation from the given value function trimpunct(value) { - while (value ~ /^["&]/) { - value = substr(value, 2) - } - while (value ~ /[]["&,}]$/) { - value = substr(value, 1, length(value) - 1) - } - return value + while (value ~ /^["&]/) { + value = substr(value, 2) + } + while (value ~ /[]["&,}]$/) { + value = substr(value, 1, length(value) - 1) + } + return value } # Print the information for the given entry function printentry(entry) { - seen[entry]++ - printf "* %s from %s", entry, file[entry] - if (documented[entry]) { - printf " (documented)" - } - print "" + seen[entry]++ + printf "* %s from %s", entry, file[entry] + if (documented[entry]) { + printf " (documented)" + } + print "" } # Stage 1: build the list of documented entries FNR == NR && /^=+$/ { - if (prevline ~ /Documentation for/) { - # This is the main title - next - } - - # The previous line is a section title, parse it - $0 = prevline - if (debug) print "Parsing " $0 - inbrackets = 0 - for (i = 1; i <= NF; i++) { - if (length($i) == 0) { - continue - } - if (!inbrackets && substr($i, 1, 1) == "(") { - inbrackets = 1 + for (i in skiplist) { + if (prevline ~ skiplist[i]) { + next + } } - if (!inbrackets) { - token = trimpunct($i) - if (length(token) > 0 && token != "and") { - if (debug) print trimpunct($i) - documented[trimpunct($i)]++ - } - } - if (inbrackets && substr($i, length($i), 1) == ")") { - inbrackets = 0 + + # The previous line is a section title, parse it + $0 = prevline + if (debug) print "Parsing " $0 + inbrackets = 0 + for (i = 1; i <= NF; i++) { + if (length($i) == 0) { + continue + } + if (!inbrackets && substr($i, 1, 1) == "(") { + inbrackets = 1 + } + if (!inbrackets) { + token = trimpunct($i) + if (length(token) > 0 && token != "and") { + if (debug) print trimpunct($i) + documented[trimpunct($i)]++ + } + } + if (inbrackets && substr($i, length($i), 1) == ")") { + inbrackets = 0 + } } - } } FNR == NR { - prevline = $0 - next + prevline = $0 + next } # Stage 2: process each file and find all sysctl tables BEGINFILE { - delete children - delete entries - delete paths - curpath = "" - curtable = "" - curentry = "" - if (debug) print "Processing file " FILENAME -} - -/^static struct ctl_path/ { - match($0, /static struct ctl_path ([^][]+)/, tables) - curpath = tables[1] - if (debug) print "Processing path " curpath + delete entries + curtable = "" + curentry = "" + delete vars + if (debug) print "Processing file " FILENAME } -/^static struct ctl_table/ { - match($0, /static struct ctl_table ([^][]+)/, tables) - curtable = tables[1] - if (debug) print "Processing table " curtable +/^static( const)? struct ctl_table/ { + match($0, /static( const)? struct ctl_table ([^][]+)/, tables) + curtable = tables[2] + if (debug) print "Processing table " curtable } /^};$/ { - curpath = "" - curtable = "" - curentry = "" + curtable = "" + curentry = "" + delete vars } -curpath && /\.procname[\t ]*=[\t ]*".+"/ { - match($0, /.procname[\t ]*=[\t ]*"([^"]+)"/, names) - if (curentry) { - curentry = curentry "/" names[1] - } else { +curtable && /\.procname[\t ]*=[\t ]*".+"/ { + match($0, /.procname[\t ]*=[\t ]*"([^"]+)"/, names) curentry = names[1] - } - if (debug) print "Setting path " curpath " to " curentry - paths[curpath] = curentry + if (debug) print "Adding entry " curentry " to table " curtable + entries[curtable][curentry]++ + file[curentry] = FILENAME } -curtable && /\.procname[\t ]*=[\t ]*".+"/ { - match($0, /.procname[\t ]*=[\t ]*"([^"]+)"/, names) - curentry = names[1] - if (debug) print "Adding entry " curentry " to table " curtable - entries[curtable][curentry]++ - file[curentry] = FILENAME +curtable && /UCOUNT_ENTRY.*/ { + match($0, /UCOUNT_ENTRY\("([^"]+)"\)/, names) + curentry = names[1] + if (debug) print "Adding entry " curentry " to table " curtable + entries[curtable][curentry]++ + file[curentry] = FILENAME } -/\.child[\t ]*=/ { - child = trimpunct($NF) - if (debug) print "Linking child " child " to table " curtable " entry " curentry - children[curtable][curentry] = child +/register_sysctl.*/ { + match($0, /register_sysctl(|_init|_sz)\("([^"]+)" *, *([^,)]+)/, tables) + if (debug) print "Registering table " tables[3] " at " tables[2] + if (tables[2] == table) { + for (entry in entries[tables[3]]) { + printentry(entry) + } + } } -/register_sysctl_table\(.*\)/ { - match($0, /register_sysctl_table\(([^)]+)\)/, tables) - if (debug) print "Registering table " tables[1] - if (children[tables[1]][table]) { - for (entry in entries[children[tables[1]][table]]) { - printentry(entry) +/kmemdup.*/ { + match($0, /([^ \t]+) *= *kmemdup\(([^,]+) *,/, names) + if (debug) print "Found variable " names[1] " for table " names[2] + if (names[2] in entries) { + vars[names[1]] = names[2] } - } } -/register_sysctl_paths\(.*\)/ { - match($0, /register_sysctl_paths\(([^)]+), ([^)]+)\)/, tables) - if (debug) print "Attaching table " tables[2] " to path " tables[1] - if (paths[tables[1]] == table) { - for (entry in entries[tables[2]]) { - printentry(entry) +/__register_sysctl_table.*/ { + match($0, /__register_sysctl_table\([^,]+, *"([^"]+)" *, *([^,]+)/, tables) + if (debug) print "Registering variable table " tables[2] " at " tables[1] + if (tables[1] == table && tables[2] in vars) { + for (entry in entries[vars[tables[2]]]) { + printentry(entry) + } } - } - split(paths[tables[1]], components, "/") - if (length(components) > 1 && components[1] == table) { - # Count the first subdirectory as seen - seen[components[2]]++ - } } - END { - for (entry in documented) { - if (!seen[entry]) { - print "No implementation for " entry + for (entry in documented) { + if (!seen[entry]) + print "No implementation for " entry } - } } |
