| # SPDX-License-Identifier: GPL-2.0-only |
| ######################################################################## |
| # |
| # (C) Copyright 2021, Alejandro Colomar |
| # These functions are free software; you can redistribute them and/or |
| # modify them under the terms of the GNU General Public License |
| # as published by the Free Software Foundation; version 2. |
| # |
| # These functions are distributed in the hope that they will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details |
| # (http://www.gnu.org/licenses/gpl-2.0.html). |
| # |
| ######################################################################## |
| |
| ######################################################################## |
| # Exit status |
| |
| EX_OK=0; |
| EX_USAGE=64; |
| |
| ######################################################################## |
| # Linux kernel |
| |
| # grep_syscall() finds the prototype of a syscall in the kernel sources, |
| # printing the filename, line number, and the prototype. |
| # It should be run from the root of the linux kernel source tree. |
| # Usage example: .../linux$ grep_syscall openat2; |
| |
| function grep_syscall() |
| { |
| if ! [ -v 1 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <syscall>"; |
| return ${EX_USAGE}; |
| fi |
| |
| find * -type f \ |
| |grep '\.c$' \ |
| |sort -V \ |
| |xargs pcregrep -Mn "(?s)^\w*SYSCALL_DEFINE.\(${1},.*?\)" \ |
| |sed -E 's/^[^:]+:[0-9]+:/&\n/'; |
| |
| find * -type f \ |
| |grep '\.[ch]$' \ |
| |sort -V \ |
| |xargs pcregrep -Mn "(?s)^asmlinkage\s+[\w\s]+\**sys_${1}\s*\(.*?\)" \ |
| |sed -E 's/^[^:]+:[0-9]+:/&\n/'; |
| } |
| |
| # grep_syscall_def() finds the definition of a syscall in the kernel sources, |
| # printing the filename, line number, and the function definition. |
| # It should be run from the root of the linux kernel source tree. |
| # Usage example: .../linux$ grep_syscall_def openat2; |
| |
| function grep_syscall_def() |
| { |
| if ! [ -v 1 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <syscall>"; |
| return ${EX_USAGE}; |
| fi |
| |
| find * -type f \ |
| |grep '\.c$' \ |
| |sort -V \ |
| |xargs pcregrep -Mn "(?s)^\w*SYSCALL_DEFINE.\(${1},.*?^}" \ |
| |sed -E 's/^[^:]+:[0-9]+:/&\n/'; |
| } |
| |
| ######################################################################## |
| # Linux man-pages |
| |
| # man_section() prints a specific manual page section (DESCRIPTION, SYNOPSIS, |
| # ...) of all manual pages in a directory (or in a single manual page file). |
| # Usage example: .../man-pages$ man_section man2 SYNOPSIS; |
| |
| function man_section() |
| { |
| if ! [ -v 2 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <dir> <section>"; |
| return ${EX_USAGE}; |
| fi |
| |
| find "${1}" -type f \ |
| |xargs grep -l "\.SH ${2}" \ |
| |sort -V \ |
| |while read -r manpage; do |
| <${manpage} \ |
| sed -n \ |
| -e '/^\.TH/,/^\.SH/{/^\.SH/!p}' \ |
| -e "/^\.SH ${2}/p" \ |
| -e "/^\.SH ${2}/,/^\.SH/{/^\.SH/!p}" \ |
| |man -P cat -l - 2>/dev/null; |
| done; |
| } |
| |
| # man_lsfunc() prints the name of all C functions declared in the SYNOPSIS |
| # of all manual pages in a directory (or in a single manual page file). |
| # Each name is printed in a separate line |
| # Usage example: .../man-pages$ man_lsfunc man2; |
| |
| function man_lsfunc() |
| { |
| if ! [ -v 1 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <dir>"; |
| return ${EX_USAGE}; |
| fi |
| |
| find "${@}" -type f \ |
| |xargs grep -l "\.SH SYNOPSIS" \ |
| |sort -V \ |
| |while read -r manpage; do |
| <${manpage} \ |
| sed -n \ |
| -e '/^\.TH/,/^\.SH/{/^\.SH/!p}' \ |
| -e "/^\.SH SYNOPSIS/p" \ |
| -e "/^\.SH SYNOPSIS/,/^\.SH/{/^\.SH/!p}" \ |
| |sed \ |
| -e '/Feature/,$d' \ |
| -e '/{/,/}/d' \ |
| |man -P cat -l - 2>/dev/null; |
| done \ |
| |sed -n "/^SYNOPSIS/,/^\w/p" \ |
| |grep '^ \w' \ |
| |grep -v ':' \ |
| |sed 's/^[^(]* \**\(\w*\)(.*/\1/' \ |
| |grep '^\w' \ |
| |uniq; |
| } |
| |
| # pdfman() renders a manual page in PDF |
| # Usage example: .../man-pages$ pdfman man2/membarrier.2; |
| |
| function pdfman() |
| { |
| if ! [ -v 1 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <man-page.n>"; |
| return ${EX_USAGE}; |
| fi; |
| |
| local tmp="$(mktemp -t "${1##*/}.XXXXXX")"; |
| |
| <${1} \ |
| man -Tps -l - \ |
| |ps2pdf - - \ |
| >${tmp}; |
| xdg-open ${tmp}; |
| } |
| |
| ######################################################################## |
| # Glibc |
| |
| # grep_glibc_prototype() finds a function prototype in the glibc sources, |
| # printing the filename, line number, and the prototype. |
| # It should be run from the root of the glibc source tree. |
| # Usage example: .../glibc$ grep_glibc_prototype printf; |
| |
| function grep_glibc_prototype() |
| { |
| if ! [ -v 1 ]; then |
| >&2 echo "Usage: ${FUNCNAME[0]} <func>"; |
| return ${EX_USAGE}; |
| fi |
| |
| find * -type f \ |
| |grep '\.h$' \ |
| |sort -V \ |
| |xargs pcregrep -Mn \ |
| "(?s)^[\w[][\w\s(,)[:\]]+\s+\**${1}\s*\([\w\s(,)[\]*]+?(...)?\)[\w\s(,)[:\]]*;" \ |
| |sed -E 's/^[^:]+:[0-9]+:/&\n/'; |
| } |