Compiling udev rules
====================

The compilation of udev rules is done by means of a newlisp script
suite, starting in `compile-udev-rules.lsp`. The script takes command
line arguments in the following usage:

    Usage: [ options ] -- rules
      -i:X = Name the ignore file. (default: ignore-lines.txt)
	  -h:X = Name the hwdb stanzas file. (default: 99-hwdb-stanzas.hwdb)
	  -o:X = Name the unhandled rules file. (default: todo.txt)
      -cX = Delete the files first. (default: nil)

The "compilation" is a relatively trivial mapping from the given rules
into the three files:

- ignore file, which is both input and output. It contains verbatim
  rule lines to ignore from the input, and it's rewritten at end to
  include all rule lines that have been dealt with.

- hwdb stanzas file, which contains data lines in a sutable format to
  be included in the hwdb generation.

- unhandle rules file, which contains a dump of the unhandled rules
  together with a summary of their recognized "active" terms in
  "sexpr" form.

Compiler Script Design Notes
----------------------------

The compilation script suite consists of five scripts, including the
main script `compile-udev-rules.lsp`. The other four (sub) scripts
are:

- `command-line.lsp`, which defines the processing of the command line
  arguments, i.e., the capture of options and rules filenmames.

- `load-rules.lsp`, which defines the loading of rules files into a
  list of rule exressions.

- `ignore.lsp`, which defines the use of the ignore file.

- `classifications.lsp`, which defines the mapping from rules to hwdb
  stanzas. Note that the udev pattern language means that a single
  rule can result in several hwdb entries, for combinations of vendor
  and product values.

The overall processing is staged into the following sequence:

- first, the intial loading of all the input rules, with essentially
  every input rule line resulting in a rule expression. One exception
  is input lines ending with backslash, which get concatenated.
  Another exception is input lines starting with LABEL terms, which
  get split up into separate rule sepxr.

- next, the rules collection is reduced into only those with some
  action terms. The `load-rules.lsp` script includes the definition of
  which terms are then considered action terms; this involves
  selectively ignoring certain terms.

- next, the rules collection is further reduced by discarding those of
  the ignore file.

- then the remaining rules are processed one by one into their hwdb
  stanzas, which are emitted to the hwdb stanzas file, and rules
  without hwdb stanza are logged into the unhandled rules file. The
  handled rules are also collated into the ignore table, which also is
  written out in full at the end to the ignore file.

The details of the translation into hwdb stanzas is contained in the
`classifications.lsp` script. Essentially it means to discover the
vendor and product attributes as well as associated property settings,
and distribute those settings for all possible vendor and product id
matches as defined by the patterns from the rule.

2016-09-25
----------

The trial of 2016-09-25 is based on the udev rules files of a fairly
standard Devuan 1.0.0 installation, including a small range of
packages. The rule files of `/lib/ydev/rules.d/*` were copied into a
local directory, `20160925`, and in the successive process given a
slight touch up by removing duplicate rules, and a couple of bug
fixes. The actual, modified rules are packed up into `20160925.tgz`.

The rules where processed in subsets according to their "home"
packages, which was obtained using `dpkg -S`, as in:

    # dpkg -S /lib/udev/rules.d/*.rules > origins

The resulting hwdb files where then copied for inclusion into the
building of hwdb.sqashfs. It results in a small range of new HWDB
properties for specific USB devices based on vendor/product id:

  - CATEGORY - this is an "abstraction" obtained by detecting
    assignments of `ENV{ID_SMARTCARD_READER}`, `ENV{ID_MEDIA_PLAYER}`,
    and `ENV{ID_MEDIA_PLAYER}`, which are mapped into `smartcard`,
    `mediaplayer:<mode>` and `scanner` respectively. A further
    analysis should probably be done so as to map them further to the
    other properties as appropriate for the respective category.

  - GROUP - this is obtained directly from `GROUP` assignments.

  - OWNER - this is obtained directly from `OWNER` assignments.

  - RUN - this is obtained directly from `RUN` assignments. Note that
    some RUN values include `%b`, `%k` and `%p`, which need to be
    translated appropriately by the associated vdevd action.

  - SYMLINK - this is obtained directly from `SYMLINK` assignments.
    Note that some SYMLINK values include `%k`, which needs to be
    translated appropriately by the associated vdevd action.

TODO: There should be associated vdevd actions that handle device
events appropriately with respect to the properties.

Newlisp
=======

[Newlisp](http://www.newlisp.org/) is a script interpreter for a
Lisp-like language, available under GNU GPL Version 3, and copyright
owner is [Lutz Mueller](http://www.nuevatec.com).

Newlisp is written in C, and depends on `libffi`, `libreadline` and
`libc`. It is used here only for the compilation of udev rules, and it
is not included in the binary distribution of vdev packages.
