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() #################################################################### _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel