Nmap/Code Standards
From SecWiki
								< Nmap
												
				Nmap is a large codebase. To keep things manageable, please follow these standards.
Contents
Style guidance
Uniform coding style makes hunting bugs easier, and it makes causing bugs harder.
All languages
-  Whitespace is limited to the space (" ", ASCII 0x20) and newline ("\n", ASCII 0x0a). This means:
- Unix-style line endings ("\n", not "\r\n" or anything else)
- No tabs. Ever.
 
- No trailing whitespace
-  Readable code
- Expressive, but not over-long variable names
- Effective use of whitespace (around operators, after commas, etc.)
- See Python style guidance for more ideas
 
- Keep lines under 80 columns
- UTF-8 encoded source
- Single newline at EOF - this does NOT mean an empty line, just that the final byte in the file should be 0x0A.
C/C++
- Indent with 2 spaces.
- Prefer all lowercase function and variable names, separate terms with underscores. C++ classes should be CamelCase.
- All macro names must be uppercase, no exception.
- No space before parenthesis in function calls
- Opening braces are at the end of the line both for functions and blocks.
- switch/case have one level of indentation for the cases, and another one for the corresponding blocks
- Wrap at 80 columns, unless it gets ugly
Lua
- Indent with 2 spaces.
-  All variables and functions declared local. (Exception for names exported from NSE libraries)
- NSEdoc when appropriate.
- No semicolons.
- Always use explicit endianness in format strings for string.pack and string.unpack
- Scripts should support Nmap structured output.
-  Do not use the deprecated binorbitlibraries. Use Lua 5.3 string packing and bitwise operators instead.
NSEdoc best-practices
-  All exported (non-local) functions and data structures in a library need NSEdoc.
-  You can use NSEdoc on "private" functions, too, but introduce it with --;instead of---to indicate private documentation.
 
-  You can use NSEdoc on "private" functions, too, but introduce it with 
- The first paragraph of a NSEdoc block should be a 1-line summary only.
-  Document tables (as arguments or return values) in a separate @class tableblock, using @name and @see to associate them.
-  @see doesn't work inline. It needs to be on a line by itself.
-  @see can be used in scripts to link to related scripts, but you must append .nseto the name of the script.
 
-  @see can be used in scripts to link to related scripts, but you must append 
- For object methods (e.g. Comm.receive), use @name Class.methodname, otherwise only methodname is used.
Python
Follow PEP 8.
Shell
Use POSIX shell language, not Bash. Not picky on which version (SUSv4, POSIX.1, whatever).
-  Scripts should use #!/bin/shshebang line.
Tools to help
- pep8 tool - https://pypi.python.org/pypi/pep8
- lua-format - Script written by Patrick Donnelly to format Lua programs. Included in Nmap under docs/style/
- lua.vim - Indentation vimscript for auto-indenting: https://gist.github.com/bonsaiviking/8845871
- commit hooks - If you are using git or git-svn, you can use this one: https://gist.github.com/dmiller-nmap/04d166bdd7872993fedb50db7fe90ac5
- check script - Does most of the same checks as the git hooks, but can be run independently and without git with some tweaks: https://gist.github.com/dmiller-nmap/5e0c5b5524d0a594e38785d3cdc8dc07
Sample .vimrc
function SetNmapPrefs ()
    "Get the full dirname of the edited file and
    "Check whether we are in an Nmap source tree
    if expand('%:p:h') =~ "/nmap"
        "Set this to the location of nmap-private-dev, if you want
        let nmap_private_dev = "/home/miller/nmap/nmap-m/nmap-private-dev"
        "proper indentation
        set nocindent
        set autoindent
        set smartindent
        set copyindent
        let ext = expand('%:e')
        " *.nse and *.luadoc are Lua
        if ext == "nse" || ext == "luadoc"
            set ft=lua
        endif
        "PEP 8 specifies 4 spaces for indentation
        if &filetype == "python"
            set tabstop=4
            set softtabstop=4
            set shiftwidth=4
        else
            "Indent is 2 spaces, no tabs
            set tabstop=2
            set softtabstop=2
            set shiftwidth=2
        endif
        set expandtab
        set smarttab
        "Complain about trailing whitespace and tab indentation
        let b:ws = matchadd("SpellBad", '\s\+$')
        "Tabs are fine to indent in Makefiles
        if &filetype != "make"
            let b:tabs = matchadd("SpellBad", '^\s*\t\+')
        endif
        "Source the service-probes syntax highlighting
        if nmap_private_dev != "" && expand('%:t') == "nmap-service-probes"
            execute("source " . nmap_private_dev . "fp/sv-highlight.vim")
        endif
    endif
endfunction
au BufRead,BufNewFile * call SetNmapPrefs()
Converting existing code
- Keep formatting commits separate from code-changing commits
- Strive for whitespace-only commits for changing indentation (diff -w or diff -b show no changes)
- If using lua-format, do a whitespace-only indentation commit first, to keep the lua-format changes visible.

