grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

119 grub commands not documented in grub.texi


From: Hans Ulrich Niedermann
Subject: 119 grub commands not documented in grub.texi
Date: Sat, 18 Apr 2020 12:53:12 +0200

Hi,

I have noticed that there are two commands documented in grub.texi
which appear not to occur anywhere within the grub source code:
'pxe_unload' and 'uppermem'.

    @node pxe_unload
    @subsection pxe_unload

    @deffn Command pxe_unload
    Unload the PXE environment (@pxref{Network}).

    This command is only available on PC BIOS systems.
    @end deffn

However, judging from the source code ("git grep pxe_unload"),
pxe_unload is not available at all, so the documentation is wrong when
it claims that the command were available on PC BIOS systems.

Should 'pxe_unload' be removed from grub.texi, or does it need a notice
that there are plans to implement it?

Regarding 'uppermem', there is only

    @node uppermem
    @subsection uppermem

    This command is not yet implemented for GRUB 2, although it is planned.

This may be a valid state for the "uppermem" command.

So far for those two commands.

Then, a bit more surprisingly, there appear to be 119 (yes, more than
100) grub commands which are registered within the grub source code but
are not documented within grub.texi.

  * When do I count a command as documented in grub.texi?
    Every @node/@subsection in a "@section * commands" of
    "@chapter Commands".

  * What do I count as a command registered within grub source?
    Whatever string appears as the first argument in a call to any of
    the following functions:

      * grub_register_command
      * grub_register_command_p1
      * grub_register_extcmd

Some of these undocumented commands look like they could be relatively
easily be grouped into a @section and described there (e.g. the 'break',
'continue', 'exit', 'return' commands for a group of shell like
commands, maybe together with '[').

I am absolutely certain that I will not find the time to write useful
documentation for a significant portion of these undocumented commands
within the grub 2.06 release timeframe (i.e. until June 2020), or even
just determine which ones I think actually need to or should be
documented publically.

So if someone wants their favourite commands documented for 2.06, they
will need to write that documentation themselves. I will just try to
add tentative documentation for @command{module2} and
@command{multiboot2} so that booting of a multiboot2 kernel will at
least be mentioned in grub.texi at all.

If you want me to, I can submit a patch for the check-commands.py
script to autogenerate a list of undocumented commands which should be
documented which can then be auto-included in grub.texi and appear in
the generated 'grub.info'. This would give a reader of the grub manual
at least the knowledge that those command actually exist, and could be
coupled with a call for help documenting those commands right inside
grub.texi itself.

Uli


####################################################################


check-commands.py - compare documented and implemented commands
Commands documented in a grub.texi menu but not registered in grub source:
  1. pxe_unload
  2. uppermem
Commands registered in grub source but not documented in a grub.texi node: 
  1. all_functional_test
  2. appleloader
  3. backtrace
  4. boottime
  5. break
  6. cacheinfo
  7. cbmemc
  8. cmosset
  9. continue
  10. coreboot_boottime
  11. cutmem
  12. dump
  13. efiemu_loadcore
  14. efiemu_prepare
  15. efiemu_unload
  16. exit
  17. extract_entries_configfile
  18. extract_entries_source
  19. extract_legacy_entries_configfile
  20. extract_legacy_entries_source
  21. extract_syslinux_entries_configfile
  22. extract_syslinux_entries_source
  23. fakebios
  24. file
  25. fix_video
  26. fpswa
  27. freedos
  28. functional_test
  29. fwsetup
  30. gdbstub
  31. gdbstub_break
  32. gdbstub_stop
  33. hdparm
  34. hello
  35. hexdump
  36. hexdump_random
  37. inb
  38. inl
  39. inw
  40. jpegtest
  41. keymap
  42. kfreebsd
  43. kfreebsd_loadenv
  44. kfreebsd_module
  45. kfreebsd_module_elf
  46. knetbsd
  47. knetbsd_module
  48. knetbsd_module_elf
  49. kopenbsd
  50. kopenbsd_ramdisk
  51. legacy_check_password
  52. legacy_configfile
  53. legacy_initrd
  54. legacy_initrd_nounzip
  55. legacy_kernel
  56. legacy_password
  57. legacy_source
  58. loadbios
  59. lsacpi
  60. lsapm
  61. lscoreboot
  62. lsdev
  63. lsefi
  64. lsefimmap
  65. lsefisystab
  66. lsmmap
  67. lspci
  68. lssal
  69. lsspd
  70. macppcbless
  71. mactelbless
  72. module2
  73. multiboot2
  74. ntldr
  75. outb
  76. outl
  77. outw
  78. pcidump
  79. plan9
  80. pngtest
  81. pxechainloader
  82. read_byte
  83. read_dword
  84. read_word
  85. return
  86. setparams
  87. setpci
  88. shift
  89. suspend
  90. syslinux_configfile
  91. syslinux_source
  92. test_blockarg
  93. testload
  94. testspeed
  95. tgatest
  96. time
  97. tr
  98. truecrypt
  99. usb
  100. vbeinfo
  101. vbetest
  102. videotest
  103. write_byte
  104. write_dword
  105. write_word
  106. xen_cat
  107. xen_ls
  108. xnu_devprop_load
  109. xnu_kernel
  110. xnu_kernel64
  111. xnu_kext
  112. xnu_kextdir
  113. xnu_mkext
  114. xnu_ramdisk
  115. xnu_resume
  116. xnu_splash
  117. xnu_uuid
  118. zfsinfo
  119. zfskey


####################################################################


#!/usr/bin/env python

from __future__ import print_function

import os
import re

import sys


class CommandChecker:

    def __init__(self):
        srcdir, self.prog = os.path.split(__file__)
        self.top_srcdir = os.path.dirname(os.path.abspath(srcdir))

    def read_texi_text_commands(self, texi_filename):
        texi_pathname = os.path.join(self.top_srcdir, 'docs', texi_filename)
        r = re.compile(r'@command\{([a-zA-Z0-9_-]+)\}')
        commands = set()
        with open(texi_pathname) as texi:
            for line in texi.readlines():
                for m in r.finditer(line):
                    commands.add(m[1])
        return commands

    def read_texi_command_menu(self, texi_filename):
        texi_pathname = os.path.join(self.top_srcdir, 'docs', texi_filename)
        r = re.compile(r'\* ([^:]+)::')
        n = re.compile(r'^@node .+ commands$')
        commands = set()
        waiting_for_node = True
        waiting_for_menu = False
        collecting_commands = False
        with open(texi_pathname) as texi:
            for line in texi.readlines():
                line = line.strip()
                if line.startswith('@comment'):
                    continue
                if waiting_for_node:
                    if n.match(line):
                        # print("@comment", line)
                        waiting_for_node = False
                        waiting_for_menu = True
                        continue
                if waiting_for_menu:
                    if line == '@menu':
                        waiting_for_menu = False
                        collecting_commands = True
                        continue
                if collecting_commands:
                    if line == '@end menu':
                        collecting_commands = False
                        waiting_for_node = True
                        continue
                    m = r.match(line)
                    # print("@comment  ", m[1])
                    commands.add(m.group(1))
        return commands

    def read_src_commands(self):
        top = os.path.join(self.top_srcdir, 'grub-core')
        r =
        
re.compile(r'grub_register_(command|command_p1|extcmd)\s*\("([a-z0-9A-Z_\[]+)",')
        commands = set() for dirpath, dirnames, filenames in
        os.walk(top): for fn in filenames:
                fp = os.path.join(dirpath, fn)
                fpe = os.path.splitext(fp)[1]
                if fpe == '.c':
                    with open(fp) as cfile:
                        for line in cfile.readlines():
                            for m in r.finditer(line):
                                commands.add(m.group(2))
        return commands


def write_undocumented_commands(commands):
    print("""\
@node Undocumented commands
@section The list of undocumented commands

These commands still need to be documented and sorted into categories.
""")

    maxlen_str = sorted(list(commands), key=lambda cmd: len(cmd),
                        reverse=True)[0]
    fmt = '* %%-%ds %%s' % (2+len(maxlen_str))

    print("@menu")
    for cmd in sorted(list(commands)):
        print(fmt % ("%s::" % cmd, "Undocumented command"))
    print("@end menu")
    print()

    for cmd in sorted(list(commands)):
        print("@node %s" % cmd)
        print("@subsection %s" % cmd)
        print()
        print("The grub command @command{%s} has not been documented yet." % 
cmd)
        print()


def print_set(st):
    for i, item in enumerate(sorted(list(st)), start=1):
        print("@comment", "  %d." % i, item)


def main():
    cc = CommandChecker()
    print("@comment",
          "%s - compare documented and implemented commands" % cc.prog)

    # texi_text_commands = cc.read_texi_text_commands('grub.texi')
    # print("@comment", "Commands in grub.texi text:")
    # print_set(texi_text_commands)

    texi_menu_commands = cc.read_texi_command_menu('grub.texi')
    # print("@comment", "Commands in grub.texi menu:")
    # print_set(texi_menu_commands)

    src_commands = cc.read_src_commands()
    # print("@comment", "Commands in grub source:")
    # print_set(src_commands)

    doc_without_src = texi_menu_commands - src_commands
    print("@comment",
          "Commands documented in a grub.texi menu but not registered in grub 
source:")
    print_set(doc_without_src)

    src_without_doc = src_commands - texi_menu_commands
    print("@comment",
          "Commands registered in grub source but not documented in a grub.texi 
node:")
    print_set(src_without_doc)

    print()

    write_undocumented_commands(src_without_doc)

    if ((len(doc_without_src) > 0) or (len(src_without_doc) > 0)):
        sys.exit(1)

    sys.exit(0)


if __name__ == '__main__':
    main()


####################################################################



reply via email to

[Prev in Thread] Current Thread [Next in Thread]