Logging
-------

Aloop.sh can log debugging/tracing messages to stderr. By default logging is
disabled. Enable it option --log or -l. In this case the GUI should
capture aloop's stderr output. To add log messages to the source code use:
  log "some message"

Flow
----

Script initialization sets shell option -f to prevent pathname expansion
since it isn't necessary actually needed, and it could interfere with string
operations should input data include shell metacharacters.
Then it sets global variables:

PRODUCTNAME="Unified Kindle Launcher"
EXTENSIONDIR=/mnt/us/extensions
SEPARATOR=$'\x01' # character code 1
COLORMAX=0

and determines Kindle busybox version to load model-specific support.

Function main() generates a list of config.xml files then calls loop() in $pipe
for each XML file. loop() calls xml_var() and json_parse() to parse values in
config.xml and its associated json menu file. The parsers store values in
global variables xml_<name> and json_<name> where each <name>s correspond to
XML tags and json keys.
Run aloop.sh -f=debuginfo to see an actual list of <name>s / values.

Then loop() calls a processing function $proc that generates the output label and
executable action for each set of xml_ / json_ variables. Several processing
functions are available, and can be selected with option -f.
For instance, function default_output() generate simple labels suitable for
a flat (non-nested) menu. Processing function two_level() is more advanced and
produces labels suitable for a two-level (nested) menu.
Before exiting loop() checks to see if at least one valid menu item was found.
If not, loop() installs a test applet and outputs its menu item. So the GUI
can safely assume that there is at least one item to display.
Note that the test applet is automatically uninstalled each time aloop starts.

Finally main() in $pipe applies predefined options to optionally sort and
'colorize' the output list.

More On Processing Functions
----------------------------

Adding a new processing function is a matter of assembling the available
xml_ and json_ variables to build the output record format that the GUI
module expects, for instance:
  pretty_label="$xml_name : $json_name"
would result in pretty_label "Orientation : Portrait"
if such are the values that a sample json menu file declares.
generating the command string would look similar to:
  command="$json_action $json_params"
which would result in command "bin/setorientation.sh U"

Default_output Processing Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Default_output() builds an output record which consists of:
  json_name,action' 'json_params
As its name implies, this is the default output when another format isn't
specified with option -f. The default output format is best suited for
single-item json files. It is probably less appealing for nested menus,
because the group menu name isn't displayed, and sorting the list results
in scattering sub-items that the developer of the menu really meant to keep
together. The default_output format was the standard format of Unified Kindle
Launcher up to version 0.3.

Two_level Processing Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Two_level() vs default_output() adds a group menu (the $json_name_ if set, the
$xml_name otherwise), which is suitable for identifying nested menus. When
option -c=N with N>0 specifies a maximum color value, two_level also prepends a
cyclical 'color' index ($cindex) modulo $COLORMAX, which the GUI could use for
displaying groups in zebra-style strips. cindex increments when the the group
name changes, so all json_names in the same group share the cindex. The GUI
could map each cindex value to a different background color and fill the page
with zebra stripes to help visually identifying groups of menu sub-items.
Each stripe is as tall as the number of sub-items that belong to a menu group.
Possibly the GUI could display information more concisely by (inline)
prefixing the group name on the first item label only. This device is useful
when the GUI page layout consists of tabular text only (no icons or navigable
menus). Cindex output can be serialized by specifying -c=999 or disabled
altogether with -c=0 or by leaving out option -c.

Note: for two_level() to group menus correctly all json_names belonging
to the same group must come in an uninterrupted sequence of calls to two_level.
Such is the case when function loop() does the calling.

Example for $COLORMAX=3, '-' is the field separator
0 - Orientation - Up - bin/turn.sh U
0 - Orientation - Down - bin/turn.sh D
1 - Komic - Sort books - bin/komic.sh -sort
1 - Komic - Delete book - bin/komic.sh -del
2 - kterm - KTerm - bin/kterm
0 - XTerm - XTerm - bin/xterm
1 - Helper - 411 - ...
1 - Helper - 711 - ...
1 - Helper - Gray menu - ...
2 - System - Restart framework - ...
etc.

Touch_runner Processing Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Touch_runner() outputs action,json_params,group'.'json_name with ';' as the 
separator character. This format is compatible with version 3.0 of launcher
TouchRunner's configuration file format /mnt/us/touchrunner/commands.txt
Ref. https://github.com/CrazyCoder/coolreader-kindle-qt/downloads
Ref. http://www.mobileread.com/forums/showpost.php?p=2388962&postcount=297

Kindle Compatibility
--------------------

The Kindle 3/DX busybox binaries do not support several ash capabilities that
newer ash versions feature. Aloop.sh keeps compatible with all kindle models
by sourcing a model-specific file, which encapsulates model-centric changes.
Necessarily the main aloop.sh script file is restricted to using the smallest
common set of capabilities only. The current model-specific files are (id):

(3) compat-K3.sh for busybox 1.7.2 Kindle 3 & Kindle DX US/Int/Graphite models
(5) compat-K5.sh for busybox 1.17.1 Kindle Touch and Kindle PaperWhite models.

Performance Comparison
~~~~~~~~~~~~~~~~~~~~~~

aloop.sh revision 20130127,a,stepk on identical input data
(test-tree-kindle.tgz, 10 extensions) running on a KT 5.1.2.
The first set below shows K5 (Touch and PaperWhite) compatibility, while the
second set shows K3 compatibility; the K5 script version ran roughly 350%
faster than the K3 script (real time). 

[root@kindle root]# time /bin/ash /mnt/us/opt/bin/aloop.sh -l -f=twolevel >/dev/null
aloop.sh: system Linux kindle 2.6.31-rt11-lab126 armv7l
aloop.sh: exit(0)
real	0m 0.96s
user	0m 0.44s
sys	0m 0.23s

[root@kindle root]# time /mnt/us/opt/bin/busybox-dx ash /mnt/us/opt/bin/aloop.sh -l -f=twolevel >/dev/null
aloop.sh: system Linux kindle 2.6.31-rt11-lab126 armv7l
aloop.sh: exit(0)
real	0m 3.89s
user	0m 0.60s
sys	0m 1.74s


The Test Applet
---------------

Currently the test applet is just a stub that runs "network info 411".
Ideally it should be something that reinforces a positive user experience, and
that all kindles can run.

References
----------
. Can a bash script determine where it is? Includes handlink symlinks.
  http://hintsforums.macworld.com/archive/index.php/t-73839.html


