/**	@file	dk3app.h	Application functions prototypes.
The dk3_app_t data type can be used for logging, file search,
internationalization and configuration.

The dk3_app_t type can be used with different application types:
command line applications, GUI applications, daemons, and silent applications.
The main difference between these types is the log output destination.
For command line applications diagnostics go to standard error output
and to the log file. There is one log file per process. By default
the log file is deleted at the end of the program unless there was an
error message, a user can use
preferences to change this.
For GUI applications diagnostics are written to the log file only.
For daemons we append to the same log file again and again.
For silent applications no log file is written.

@section	dk3appopen	Opening and closing an application
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

DK3_MAIN
{
  dk3_app_t *app = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    ... do something ...
    dk3app_close(app);
  }
}
@endcode
In the example we open a command line application using dk3app_open_command().
Use dk3app_open_daemon() to create an application object for a daemon
after the fork()+setsid()/setpgrp() sequence. Use dk3app_open_silent() to
create an application object doing no diagnostics.
The dk3app_open_gui() function is used by the DkWxAppHelper constructor.

@section	dk3appargs	Accessing command line arguments
The dk3app_get_argc() and dk3app_get_argv() functions can be used
to access command line arguments. The dk3_app_t structure has it's own copy
of the command line arguments, any preferences specified on the command
line (i.e. --/log/stderr/level=debug) are removed.
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

DK3_MAIN
{
  dk3_app_t *app = NULL;
  int xargc = 0;
  dkChar const * const *xargv = NULL;
  dkChar buffer[32];
  int i = 0;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    xargc = dk3app_get_argc(app);
    xargv = dk3app_get_argv(app);
    dk3sf_initialize_stdout();
    for(i = 0; i < xargc; i++) {
      dk3sf_sprintf3(buffer, dkT("%05d: "), i);
      dk3sf_fputs(buffer, stdout);
      dk3sf_fputs(xargv[i], stdout);
      dk3sf_fputc(dkT('\n'), stdout);
    }
    dk3app_close(app);
  }
}
@endcode
See the dk3opt.h documentation for the dk3_opt_set_t to process command
line arguments.

@section	dk3appretrieveinformation	Retrieving information

  - dk3app_get_logname()\n
    retrieves the name of the current user.

  - dk3app_get_homedir()\n
    retrieves the home directory of the current user.

  - dk3app_get_language()\n
    retrieves the users language.

  - dk3app_get_region()\n
    retrieves the users region (country).

  - dk3app_get_appname()\n
    retrieves the application name.

  - dk3app_get_appgroup()\n
    retrieves the application group name.

  - dk3app_get_execfilename()\n
    retrieves the name of the executable file.

  - dk3app_get_bindir()\n
    retrieves the name of the binary directory
    (i.e. /usr/bin).

  - dk3app_get_etcdir()\n
    retrieves the name of the system configuration
    directory (i.e. /etc).

  - dk3app_get_sharedir()\n
    retrieves the name of the data root directory
    (i.e. /usr/share).

  - dk3app_get_vardir()\n
    retrieves the name of the local state directory
    (i.e. /var).

  - dk3app_get_encoding()\n
    retrieves the internal encoding used for text
    strings stored in memory, one from: DK3_ENCODING_PLAIN, DK3_ENCODING_UTF8,
    DK3_ENCODING_UTF16, DK3_ENCODING_UNICODE.

  - dk3app_get_input_stdin_encoding()\n
    retrieves the default encoding expected
    for input on stdin: DK3_FILE_ENCODING_ASCII, DK3_FILE_ENCODING_UTF8,
    DK3_FILE_ENCODING_UTF16_MSB_FIRST,
    DK3_FILE_ENCODING_UTF16_LSB_FIRST,
    DK3_FILE_ENCODING_UNICODE_MSB_FIRST,
    DK3_FILE_ENCODING_UNICODE_LSB_FIRST.

  - dk3app_get_input_file_encoding()\n
    retrieves the default encoding expected
    when processing input from files.

  - dk3app_get_output_encoding()\n
    retrieves the default encoding to write
    output files.

@section	dk3appresourcesearch	Resource file search
The dk3app_find_data_file() searches for a file specified by short
file name without leading directory. It searches for a matching file in a
couple of directories, depending on the users language and region. The
full path name of the most relevant file found is copied into the result
buffer on success.

@section	dk3applocalized	Using localized texts
Use the dk3app_messages() function. This function
attempts to load a message text array from the named file. If this fails
the original text array containing the default texts is returned.
The memory for the strings from file is allocated dynamically and released
automatically during dk3app_close().

Note the NULL as the finalizing pointer at the end of the default texts
array.
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
dkT("Hello world"),
dkT("Goodbye world"),
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    dk3sf_initialize_stdout();
    dk3sf_fputs(msg[0], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3sf_fputs(msg[1], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3app_close(app);
  }
}
@endcode
When using the dk3app module in conjunction with dkct you should use a *.ctr
file:
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
$!string-table	macro=dkT,file=myprog.str
#
#  0:	Greeting "Hello world" at start of program.
#
Hello world
#
#  1:	Greeting "Goodbye world" at end of program.
#
Goodbye world
$!end
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    dk3sf_initialize_stdout();
    dk3sf_fputs(msg[0], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3sf_fputs(msg[1], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3app_close(app);
  }
}
@endcode
When dkct is run on the file the $!string-table...$!end construct is converted
to an array of dkChar strings and a myprog.str file is written containing
an english version of the string table. Translators can use this file as
a starting point to create string  tables in other languages.
Note the comments before each text: We comment the index, we need the index
later to select the correct element from the array. Additionally we describe
the context of the text (is it a diagnostic message or a button label...).

@section	dk3apphelp	Localized help texts
The dk3app_help() function can be used to show a help text.
Specify a short file name, the function searches for a file in the users
language. If no such file is found the default help texts are shown.

@section	dk3applog		Logging
@subsection	dk3applogfull	Fully controlled message from multiple parts
The dk3app_log_msg() function issues a log message consisting of
multiple parts.

The arguments are:
  - An appliction object.
  - The log level (DK3_LL_PANIC, DK3_LL_FATAL, DK3_LL_ERROR, DK3_LL_WARNING,
    DK3_LL_INFO, DK3_LL_PROGRESS, or DK3_LL_DEBUG).
  - A pointer to an array of string pointers. The array contains the
    individual messages parts, all parts are concatenated.
  - The number of elements in the array.
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
dkT("Hello world"),
dkT("Goodbye world"),
dkT("This is a"),
dkT(" simple message consisting"),
dkT(" of multiple parts"),
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    {
      dkChar const * logmsg[3];
      logmsg[0] = msg[2];
      logmsg[1] = msg[3];
      logmsg[2] = msg[4];
      dk3app_log_msg(app, DK3_LL_ERROR, (dkChar const * const *)logmsg, 3);
    }
    dk3app_close(app);
  }
}
@endcode

@subsection	dk3applogsimple	Simplified logging
Mostly diagnostic messages consist of fixed parts (i.e.
"Failed to open file:") and variable parts (i.e. the file name to report).
The fixed parts are typically obtained from a localized message text array.

The dk3app_log_1(), dk3app_log_3() and
dk3app_log_5() functions can be used for log messages consisting of
1 constant part, 2 constant parts enclosing one variable part or
3 constant parts enclosing 2 variable parts.
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
dkT("Hello world"),
dkT("Goodbye world"),
dkT("Failed to open file \""),
dkT("\"!"),
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  dkChar const *filename;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    ... set filename ...
    dk3app_log_3(app, DK3_LL_ERROR, msg, 2, 3, filename);
    dk3app_close(app);
  }
}
@endcode

@subsection	dk3appsttfile	Provide english string table file
In the previous example the string defaults were written as an array.
When using dkct there is a special notation available in *.ctr, *.cpt, *.wxc,
and *.mtr files:
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
$!string-table file=myprog.str,macro=dkT
#
#  0: The greeting text to say hello.
#
Hello world
#
#  1: The greeting text to say goodbye.
#
Goodbye world
#
#  2/3: Error message: Failed to open file "..."!
#
Failed to open file "
"!
$!end
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  dkChar const *filename;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    ... set filename ...
    dk3app_log_3(app, DK3_LL_ERROR, msg, 2, 3, filename);
    dk3app_close(app);
  }
}
@endcode
In a $!string-table ... $!end environment you can write a string table
in string table syntax. This string table is converted into an array of
texts when dkct is run.
If the $!string-table command has a file=... argument the original string
table is written to the specified file. Users localizing the software to
their language can use this english string table file as a template.


@subsection	dk3apploginternal	Internal message texts
The dk3app_log_i1(), dk3app_log_i3() and dk3app_log_i5() functions
use constant texts maintained by the dk3app module itself.
I.e. if a file name is too long to be stored into a buffer you can use the
following code to complain about that.
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  dkChar const *filename;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    ... set filename ...
    dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, filename);
    dk3app_close(app);
  }
}
@endcode
See section	@ref dk3appref	below for details about the
messages texts used by the dk3app module.

@subsection	dk3appmaxloglevel	Getting the maximum log level
The dk3app_max_log_level() returns the numeric maximum of the log levels
required to write a diagnostic message to any output direction.
If diagnostic messages require a special preparation - i.e. conversion of
an IP address to text - one can use code like this:
@code
if(dk3app_max_log_level(app) >= DK3_LL_DEBUG) {
  ... convert IP address to text ...
  dk3app_log_3(app, DK3_LL_DEBUG, msg, i1, i2, text);
}
@endcode

@subsection	dk3apperrorposition	Showing the error position
Programs processing text files should show the error position in the
file in diagnostic messages. Use dk3app_set_source_file() and
dk3app_set_source_line() to set the error position. Use
dk3app_get_source_file() and dk3app_get_source_line() to retrieve the
current position (i.e. to save it now and restore it later).

@section	dk3appcfgsearch	Configuration file search
The dk3app_find_config_file() function can be used to search for a
configuration file specified by short filename (without leading
directory information). On success the program returns a pointer to a new
dk3_search_t structure containing the file names found.

When traversing the search results the file names are returned in order
from low priority (most general configuration file) to high priority
(application and user specific).

If you want to process the most relevant file only, use
dk3app_find_config_file_revers() and process the first result only.
This function returns the search results in reversed sort order,
most relevant file first.

@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
dkT("File \""),
dkT("\" found."),
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  dkChar const *fn = NULL;
  dk3_search_t *result = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    result = dk3app_find_config_file(app, dkT("test.conf"));
    if(result) {
      dk3search_reset(result);
      dk3sf_initialize_stdout();
      while((fn = dk3search_next(result)) != NULL) {
        dk3sf_fputs(msg[0], stdout);
	dk3sf_fputs(fn, stdout);
	dk3sf_fputs(msg[1], stdout);
      }
      dk3search_close(result);
    }
    dk3app_log_3(app, DK3_LL_ERROR, msg, 2, 3, filename);
    dk3app_close(app);
  }
}
@endcode

@section	dk3appkeywords	Get keywords (localized or non-localized)
The dk3app module reads a string table containing 350+ texts when a
new dk3_app_t is opened. Applications or other modules can access these
texts by number using dk3app_localized(). Other non-localized texts
are built-in into dk3app, use dk3app_not_localized() to retrieve one of these
texts.

@section	dk3appprefs	Preferences
Preferences are key=value pairs. Preferences can be set in the
dk3pref.conf file, from within the program itself or on the command line.
The dk3app_get_pref() function retrieves preferences, the dk3app_set_pref()
function sets preferences. Preferences set by dk3app_set_pref() are written
back to file $HOME/.dk3app/<i>application</i>/dk3pref.conf
during dk3app_close().

The dk3app_unconfigure() function instructs dk3app_close() to remove
the $HOME/.dk3app/<i>application</i>/dk3pref.conf file instead of writing
an updated file.

The dk3app_get_sys_pref() function retrieves preferences only from
system configuration files (users configuration files and command line
preference overrides are ignored). So only values configured by the
administrator or the program itself are returned.

@section	dk3apptempfiles	Temporary files
The dk3app_get_tmp_file_name() function creates a name for a temporary
file and saves it to a buffer provided as argument.

@section	dk3appstdin	Processing standard input
The dk3app_process_stdin_chars() and dk3app_process_stdin_lines() functions
can be used to process standard input character by character or
line by line. Both functions save standard input to a temporary file first.
The file is inspected for a BOM (byte order marker) at the beginning
of the file to process the file in correct encoding.

@section	dk3apprandom	Random data generation
The functions related to random data generation are declared in dk3app.h,
the implementation is in the dk3appr module in the dk3csrnd library.
Depending on available system functions and libraries a set of
different random data generators can be used:

  - simple (srand()/rand())

  - rand48 (lrand48())

  - random (initstate()/setstate()/random())

  - openssl (PRNG from the OpenSSL library)

The dk3app_rand_init() function must be used to initialize random
number generation. In the <i>il</i> argument you can specify the allowed
PRNG types, i.e. "random,openssl". If one of the PRNG types is available
and can be seeded the function succeeds.

The dk3app_rand_bytes() function can be used to obtain random data.

The dk3app_rand_bytes_non_crypto() can be used to obtain random data
for non-cryptographic purposes.

The dk3app_rand_end() function inidicates that we are done with random
number generation. So wen can attempt to save random seed to a file.
This function is invoked automatically from dk3app_close() when
dk3app_rand_init() was called for the dk3_app_t object.

@section	dk3appchangeuser	Change user for daemon
For a daemon dk3_app_t object we can use dk3app_change_user() to change
ownership for all writable files and directories assigned to the
dk3_app_t object to a new user and group.

@section	dk3appref	Reference
@subsection	dk3applogref	Diagnostic messages reference
<a name="diagnosticsreference"></a>
Use the table contents as follows: If you want to show an error
"Not enough memory" you find one index number (9) in the table. So the
code to show the message is:
@code
dk3app_log_i1(app, DK3_LL_ERROR, 9);
@endcode
If a user specified an unknown digest type for checksumming and you have
the name available in the mdname variable you will find "127, 128, m" in the
table. The message consists of three parts, so the code is
@code
dk3app_log_i3(app, DK3_LL_ERROR, 127, 128, mdname);
@endcode
<table border>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Resources</b></td></tr>
<tr><td align="LEFT" valign="TOP">Not enough memory!</td><td align="LEFT" valign="TOP">9</td></tr>
<tr><td align="LEFT" valign="TOP">Not enough memory, failed to allocate ... bytes!</td><td align="LEFT" valign="TOP">12, 13, text</td></tr>
<tr><td align="LEFT" valign="TOP">Numeric overflow in size calculation!</td><td align="LEFT" valign="TOP">15</td></tr>
<tr><td align="LEFT" valign="TOP">Numeric overflow in size calculation, x elements per y bytes!</td><td align="LEFT" valign="TOP">16, 17, 18, e, n</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to create directory for log file!</td><td align="LEFT" valign="TOP">46</td></tr>
<tr><td align="LEFT" valign="TOP">Too many requests for temporary file names!</td><td align="LEFT" valign="TOP">54</td></tr>
<tr><td align="LEFT" valign="TOP">Process table overflow!</td><td align="LEFT" valign="TOP">276</td></tr>
<tr><td align="LEFT" valign="TOP">Too many open files!</td><td align="LEFT" valign="TOP">277</td></tr>
<tr><td align="LEFT" valign="TOP">Resource shortage!</td><td align="LEFT" valign="TOP">294</td></tr>
<tr><td align="LEFT" valign="TOP">Timeout occured!</td><td align="LEFT" valign="TOP">299</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Memory, string operations, data buffers, data structures</b></td></tr>
<tr><td align="LEFT" valign="TOP">String too long!</td><td align="LEFT" valign="TOP">108</td></tr>
<tr><td align="LEFT" valign="TOP">Command name too long!</td><td align="LEFT" valign="TOP">109</td></tr>
<tr><td align="LEFT" valign="TOP">Destination buffer too small!</td><td align="LEFT" valign="TOP">38</td></tr>
<tr><td align="LEFT" valign="TOP">Directory name ... too long!</td><td align="LEFT" valign="TOP">59, 60, d</td></tr>
<tr><td align="LEFT" valign="TOP">Directory name too long!</td><td align="LEFT" valign="TOP">87</td></tr>
<tr><td align="LEFT" valign="TOP">HOME directory name too long!</td><td align="LEFT" valign="TOP">194</td></tr>
<tr><td align="LEFT" valign="TOP">File name ... too long!</td><td align="LEFT" valign="TOP">65, 66, f</td></tr>
<tr><td align="LEFT" valign="TOP">Command ... is too long!</td><td align="LEFT" valign="TOP">103, 104, c</td></tr>
<tr><td align="LEFT" valign="TOP">Command is too long!</td><td align="LEFT" valign="TOP">105</td></tr>
<tr><td align="LEFT" valign="TOP">File name for log file gets too long!</td><td align="LEFT" valign="TOP">45</td></tr>
<tr><td align="LEFT" valign="TOP">The name of the temporary directory is too long!</td><td align="LEFT" valign="TOP">49</td></tr>
<tr><td align="LEFT" valign="TOP">Preference name too long!</td><td align="LEFT" valign="TOP">51</td></tr>
<tr><td align="LEFT" valign="TOP">Current locale too long!</td><td align="LEFT" valign="TOP">254</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal characters in source string, conversion failed!</td><td align="LEFT" valign="TOP">67</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal characters in source string!</td><td align="LEFT" valign="TOP">112</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal characters in source bufer!</td><td align="LEFT" valign="TOP">113</td></tr>
<tr><td align="LEFT" valign="TOP">String contains non-ISO-LATIN-1 characters!</td><td align="LEFT" valign="TOP">219</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal destination encoding!</td><td align="LEFT" valign="TOP">114</td></tr>
<tr><td align="LEFT" valign="TOP">Conversion to UTF-8 failed!</td><td align="LEFT" valign="TOP">115</td></tr>
<tr><td align="LEFT" valign="TOP">Conversion to UTF-16 failed!</td><td align="LEFT" valign="TOP">116</td></tr>
<tr><td align="LEFT" valign="TOP">UTF-8 decoding failed!</td><td align="LEFT" valign="TOP">118</td></tr>
<tr><td align="LEFT" valign="TOP">UTF-16 decoding failed!</td><td align="LEFT" valign="TOP">119</td></tr>
<tr><td align="LEFT" valign="TOP">Result characters not available for destination encoding!</td><td align="LEFT" valign="TOP">117</td></tr>
<tr><td align="LEFT" valign="TOP">Mismatch between encoding and character size!</td><td align="LEFT" valign="TOP">125</td></tr>
<tr><td align="LEFT" valign="TOP">Unknown message digest type: ...!</td><td align="LEFT" valign="TOP">127, 128, m</td></tr>
<tr><td align="LEFT" valign="TOP">Not support for message digest ...!</td><td align="LEFT" valign="TOP">156, 157, m</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal message digest or encoding!</td><td align="LEFT" valign="TOP">158</td></tr>
<tr><td align="LEFT" valign="TOP">Unknown encoding: ...!</td><td align="LEFT" valign="TOP">129, 130, e</td></tr>
<tr><td align="LEFT" valign="TOP">Encoding not supported by C runtime library!</td><td align="LEFT" valign="TOP">204</td></tr>
<tr><td align="LEFT" valign="TOP">Index out of range!</td><td align="LEFT" valign="TOP">200</td></tr>
<tr><td align="LEFT" valign="TOP">Misconfigured start/end for range!</td><td align="LEFT" valign="TOP">220</td></tr>
<tr><td align="LEFT" valign="TOP">New range conflicts with existing one!</td><td align="LEFT" valign="TOP">221</td></tr>
<tr><td align="LEFT" valign="TOP">Matrix expansion requires a square matrix!</td><td align="LEFT" valign="TOP">201</td></tr>
<tr><td align="LEFT" valign="TOP">Incomplete input sequence!</td><td align="LEFT" valign="TOP">218</td></tr>
<tr><td align="LEFT" valign="TOP">Syntax error!</td><td align="LEFT" valign="TOP">223</td></tr>
<tr><td align="LEFT" valign="TOP">Record too large!</td><td align="LEFT" valign="TOP">245</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to convert timestamp to local time!</td><td align="LEFT" valign="TOP">268</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>File I/O, reading and writing data</b></td></tr>
<tr><td align="LEFT" valign="TOP">Failed to read directory ...!</td><td align="LEFT" valign="TOP">63, 64, d</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to obtain information about file ...!</td><td align="LEFT" valign="TOP">61, 62, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to information about ... (file/directory)!</td><td align="LEFT" valign="TOP">96, 97, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to change into directory: ...!</td><td align="LEFT" valign="TOP">242, 243, d</td></tr>
<tr><td align="LEFT" valign="TOP">Not a regular file: ...!</td><td align="LEFT" valign="TOP">255, 256, f</td></tr>
<tr><td align="LEFT" valign="TOP">No information about a file!</td><td align="LEFT" valign="TOP">98</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to create directory ...!</td><td align="LEFT" valign="TOP">84, 85, d</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to create directory!</td><td align="LEFT" valign="TOP">86</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to remove directory!</td><td align="LEFT" valign="TOP">68</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to remove directory ...!</td><td align="LEFT" valign="TOP">69, 70, d</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to remove file ...!</td><td align="LEFT" valign="TOP">88, 89, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to remove file!</td><td align="LEFT" valign="TOP">90</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to save preference entry k=v!</td><td align="LEFT" valign="TOP">56, 57, 58, k, v</td></tr>
<tr><td align="LEFT" valign="TOP">File ... is a directory!</td><td align="LEFT" valign="TOP">74, 75, f</td></tr>
<tr><td align="LEFT" valign="TOP">File ... exists, but is not a directory!</td><td align="LEFT" valign="TOP">81, 82, f</td></tr>
<tr><td align="LEFT" valign="TOP">Not a directory: ...!</td><td align="LEFT" valign="TOP">202, 203, f</td></tr>
<tr><td align="LEFT" valign="TOP">File exists, but is not a directory!</td><td align="LEFT" valign="TOP">83</td></tr>
<tr><td align="LEFT" valign="TOP">Can not open file, name refers to a directory</td><td align="LEFT" valign="TOP">76</td></tr>
<tr><td align="LEFT" valign="TOP">Symlink owner of ... is not owner of file!</td><td align="LEFT" valign="TOP">100, 101, f</td></tr>
<tr><td align="LEFT" valign="TOP">Symlink owner is not file owner!</td><td align="LEFT" valign="TOP">102</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to open file ...!</td><td align="LEFT" valign="TOP">143, 144, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to open file!</td><td align="LEFT" valign="TOP">145</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to open file ... for write access!</td><td align="LEFT" valign="TOP">77, 78, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to open file for write access!</td><td align="LEFT" valign="TOP">79</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to write data!</td><td align="LEFT" valign="TOP">120</td></tr>
<tr><td align="LEFT" valign="TOP">Write operation failed, ... of ... bytes written!</td><td align="LEFT" valign="TOP">170,171,172,b,s</td></tr>
<tr><td align="LEFT" valign="TOP">Write operation failed, ... of ... elements written!  </td><td align="LEFT" valign="TOP">174,175,176,e,s</td></tr>
<tr><td align="LEFT" valign="TOP">Write operation failed!</td><td align="LEFT" valign="TOP">173</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to write data to file: ...!</td><td align="LEFT" valign="TOP">343, 344, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to read data from file!</td><td align="LEFT" valign="TOP">345</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to read data from file: ...!</td><td align="LEFT" valign="TOP">346, 347, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to flush output!</td><td align="LEFT" valign="TOP">121</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to close data stream object!</td><td align="LEFT" valign="TOP">122</td></tr>
<tr><td align="LEFT" valign="TOP">Error while closing file!</td><td align="LEFT" valign="TOP">340</td></tr>
<tr><td align="LEFT" valign="TOP">Error while closing file ...!</td><td align="LEFT" valign="TOP">341, 342, f</td></tr>
<tr><td align="LEFT" valign="TOP">Stream not opened for write operations!</td><td align="LEFT" valign="TOP">123</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to read data!</td><td align="LEFT" valign="TOP">124</td></tr>
<tr><td align="LEFT" valign="TOP">I/O error occured!</td><td align="LEFT" valign="TOP">329</td></tr>
<tr><td align="LEFT" valign="TOP">Too many symbolic links in path!</td><td align="LEFT" valign="TOP">330</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal pathname (missing a parent directory)!</td><td align="LEFT" valign="TOP">331</td></tr>
<tr><td align="LEFT" valign="TOP">File system is mounted read-only!</td><td align="LEFT" valign="TOP">332</td></tr>
<tr><td align="LEFT" valign="TOP">Stale NFS file handle!</td><td align="LEFT" valign="TOP">333</td></tr>
<tr><td align="LEFT" valign="TOP">Server for remote file not available!</td><td align="LEFT" valign="TOP">334</td></tr>
<tr><td align="LEFT" valign="TOP">No space left on device!</td><td align="LEFT" valign="TOP">335</td></tr>
<tr><td align="LEFT" valign="TOP">Too many .. entries in file name ...!</td><td align="LEFT" valign="TOP">110, 111, f</td></tr>
<tr><td align="LEFT" valign="TOP">Too many .. entries in file name!</td><td align="LEFT" valign="TOP">126</td></tr>
<tr><td align="LEFT" valign="TOP">Checksumming is available for regular files only!</td><td align="LEFT" valign="TOP">159</td></tr>
<tr><td align="LEFT" valign="TOP">Resource file ... not found!</td><td align="LEFT" valign="TOP">150, 151, f</td></tr>
<tr><td align="LEFT" valign="TOP">Configuration file ... not found!</td><td align="LEFT" valign="TOP">154, 155, f</td></tr>
<tr><td align="LEFT" valign="TOP">Too many file names match pattern ..., just one allowed</td><td align="LEFT" valign="TOP">168, 169, p</td></tr>
<tr><td align="LEFT" valign="TOP">No file name matches pattern ...!</td><td align="LEFT" valign="TOP">215, 216, p</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to retrieve console settings!</td><td align="LEFT" valign="TOP">265</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to restore console settings!</td><td align="LEFT" valign="TOP">266</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to modify console settings!</td><td align="LEFT" valign="TOP">267</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to change ownership for file ...!</td><td align="LEFT" valign="TOP">270, 271, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to change file permissions for ...!</td><td align="LEFT" valign="TOP">272, 273, f</td></tr>
<tr><td align="LEFT" valign="TOP">Insufficient permissions!</td><td align="LEFT" valign="TOP">274</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Compression and encoding</b></td></tr>
<tr><td align="LEFT" valign="TOP">Flate compression not supported!</td><td align="LEFT" valign="TOP">262</td></tr>
<tr><td align="LEFT" valign="TOP">Illegal compression cell type used!</td><td align="LEFT" valign="TOP">263</td></tr>
<tr><td align="LEFT" valign="TOP">Error during previous compression operations!</td><td align="LEFT" valign="TOP">264</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Finding information</b></td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find current working directory</td><td align="LEFT" valign="TOP">53</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to obtain the users login name!</td><td align="LEFT" valign="TOP">43</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find the uses home directory!</td><td align="LEFT" valign="TOP">44</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find current host name!</td><td align="LEFT" valign="TOP">131</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to retrieve current locale!</td><td align="LEFT" valign="TOP">253</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find local state (var) directory!</td><td align="LEFT" valign="TOP">50</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to obtain current time!</td><td align="LEFT" valign="TOP">80</td></tr>
<tr><td align="LEFT" valign="TOP">No user record for ...!</td><td align="LEFT" valign="TOP">92, 93, u</td></tr>
<tr><td align="LEFT" valign="TOP">No matching user record found!</td><td align="LEFT" valign="TOP">94</td></tr>
<tr><td align="LEFT" valign="TOP">No user name entry in the record!</td><td align="LEFT" valign="TOP">91</td></tr>
<tr><td align="LEFT" valign="TOP">No home directory entry in user record!</td><td align="LEFT" valign="TOP">95</td></tr>
<tr><td align="LEFT" valign="TOP">The HOMEDRIVE environment variable is not set!</td><td align="LEFT" valign="TOP">71</td></tr>
<tr><td align="LEFT" valign="TOP">The HOMEPATH environment variable is not set</td><td align="LEFT" valign="TOP">72</td></tr>
<tr><td align="LEFT" valign="TOP">The PATH environment variable is not defined!</td><td align="LEFT" valign="TOP">106</td></tr>
<tr><td align="LEFT" valign="TOP">Attempt to read preferences file ... (information).</td><td align="LEFT" valign="TOP">230, 231, f</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to enumerate printers!</td><td align="LEFT" valign="TOP">244</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Options and command line arguments</b></td></tr>
<tr><td align="LEFT" valign="TOP">Errors occured while processing command line options!</td><td align="LEFT" valign="TOP">252</td></tr>
<tr><td align="LEFT" valign="TOP">Malformed preference entry on command line</td><td align="LEFT" valign="TOP">52</td></tr>
<tr><td align="LEFT" valign="TOP">Unknown option ...!</td><td align="LEFT" valign="TOP">139, 140, o</td></tr>
<tr><td align="LEFT" valign="TOP">Option ... requires an argument!</td><td align="LEFT" valign="TOP">133, 134, o</td></tr>
<tr><td align="LEFT" valign="TOP">Option ... too long for processing!</td><td align="LEFT" valign="TOP">135, 136, o</td></tr>
<tr><td align="LEFT" valign="TOP">Not a numeric value: ...!</td><td align="LEFT" valign="TOP">141, 142, o</td></tr>
<tr><td align="LEFT" valign="TOP">Not a boolean value: ...!</td><td align="LEFT" valign="TOP">146, 147, o</td></tr>
<tr><td align="LEFT" valign="TOP">Not a hex number!</td><td align="LEFT" valign="TOP">222</td></tr>
<tr><td align="LEFT" valign="TOP">Ignoring irrelevant argument in ...!</td><td align="LEFT" valign="TOP">137, 138, a</td></tr>
<tr><td align="LEFT" valign="TOP">Option name missing in long option: ...!</td><td align="LEFT" valign="TOP">160, 161, o</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to convert a numeric value to text!</td><td align="LEFT" valign="TOP">162</td></tr>
<tr><td align="LEFT" valign="TOP">Too many command line arguments! Ignoring...</td><td align="LEFT" valign="TOP">164, 165, a</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Images, printing</b></td></tr>
<tr><td align="LEFT" valign="TOP">Image file type unknown or not supported!</td><td align="LEFT" valign="TOP">257</td></tr>
<tr><td align="LEFT" valign="TOP">Bits per component restricted to 16!</td><td align="LEFT" valign="TOP">258</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to set bitmap image frame!</td><td align="LEFT" valign="TOP">261</td></tr>
<tr><td align="LEFT" valign="TOP">Incorrect page setup, no usable space between borders!</td><td align="LEFT" valign="TOP">259</td></tr>
<tr><td align="LEFT" valign="TOP">Mathematical error in size calculations!</td><td align="LEFT" valign="TOP">260</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Databases</b></td></tr>
<tr><td align="LEFT" valign="TOP">File damaged or not a database file!</td><td align="LEFT" valign="TOP">246</td></tr>
<tr><td align="LEFT" valign="TOP">No support for database type ... available!</td><td align="LEFT" valign="TOP">247, 248, t</td></tr>
<tr><td align="LEFT" valign="TOP">Key not found in database!</td><td align="LEFT" valign="TOP">249</td></tr>
<tr><td align="LEFT" valign="TOP">DB entry probably damaged - not a multibyte char string!</td><td align="LEFT" valign="TOP">250</td></tr>
<tr><td align="LEFT" valign="TOP">Database opened for read access only!</td><td align="LEFT" valign="TOP">251</td></tr>
<tr><td align="LEFT" valign="TOP">No file name available for database!</td><td align="LEFT" valign="TOP">269</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Network</b></td></tr>
<tr><td align="LEFT" valign="TOP">Failed to open network socket!</td><td align="LEFT" valign="TOP">279</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to close socket!</td><td align="LEFT" valign="TOP">280</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to connect!</td><td align="LEFT" valign="TOP">282</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to connect to: ...!</td><td align="LEFT" valign="TOP">351, 352, h</td></tr>
<tr><td align="LEFT" valign="TOP">Previous connection attempt not yet completed!</td><td align="LEFT" valign="TOP">295</td></tr>
<tr><td align="LEFT" valign="TOP">Connection refused, port not open on peer!</td><td align="LEFT" valign="TOP">296</td></tr>
<tr><td align="LEFT" valign="TOP">Socket already connected!</td><td align="LEFT" valign="TOP">297</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to bind local address!</td><td align="LEFT" valign="TOP">302</td></tr>
<tr><td align="LEFT" valign="TOP">Socket already bound to local address!</td><td align="LEFT" valign="TOP">304</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to write data to socket!</td><td align="LEFT" valign="TOP">305</td></tr>
<tr><td align="LEFT" valign="TOP">Operation would block!</td><td align="LEFT" valign="TOP">306</td></tr>
<tr><td align="LEFT" valign="TOP">Connection reset by peer!</td><td align="LEFT" valign="TOP">307</td></tr>
<tr><td align="LEFT" valign="TOP">Peer address required for connectionless socket!</td><td align="LEFT" valign="TOP">308</td></tr>
<tr><td align="LEFT" valign="TOP">Peer address specification not allowed for connected socket!</td><td align="LEFT" valign="TOP">309</td></tr>
<tr><td align="LEFT" valign="TOP">Message too large to be sent automatically!</td><td align="LEFT" valign="TOP">310</td></tr>
<tr><td align="LEFT" valign="TOP">Sending queue full for socket!</td><td align="LEFT" valign="TOP">311</td></tr>
<tr><td align="LEFT" valign="TOP">Writing to a pipe without a reader!</td><td align="LEFT" valign="TOP">312</td></tr>
<tr><td align="LEFT" valign="TOP">Less bytes were written than required!</td><td align="LEFT" valign="TOP">313</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to read data from socket!</td><td align="LEFT" valign="TOP">314</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to shut down socket!</td><td align="LEFT" valign="TOP">315</td></tr>
<tr><td align="LEFT" valign="TOP">Socket not connected!</td><td align="LEFT" valign="TOP">316</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to accept incoming connection request!</td><td align="LEFT" valign="TOP">317</td></tr>
<tr><td align="LEFT" valign="TOP">Connection aborted!</td><td align="LEFT" valign="TOP">318</td></tr>
<tr><td align="LEFT" valign="TOP">Network protocol error!</td><td align="LEFT" valign="TOP">319</td></tr>
<tr><td align="LEFT" valign="TOP">Network subsystem not available!</td><td align="LEFT" valign="TOP">320</td></tr>
<tr><td align="LEFT" valign="TOP">Windows sockets not initialized!</td><td align="LEFT" valign="TOP">321</td></tr>
<tr><td align="LEFT" valign="TOP">A blocking WinSock 1.1 operation is in progress!</td><td align="LEFT" valign="TOP">322</td></tr>
<tr><td align="LEFT" valign="TOP">Socket type doesn't correspond to address family!</td><td align="LEFT" valign="TOP">323</td></tr>
<tr><td align="LEFT" valign="TOP">Socket not configured for broadcasts!</td><td align="LEFT" valign="TOP">324</td></tr>
<tr><td align="LEFT" valign="TOP">Requested address is not available!</td><td align="LEFT" valign="TOP">325</td></tr>
<tr><td align="LEFT" valign="TOP">Host unreachable!</td><td align="LEFT" valign="TOP">326</td></tr>
<tr><td align="LEFT" valign="TOP">Windows sockets version not available!</td><td align="LEFT" valign="TOP">327</td></tr>
<tr><td align="LEFT" valign="TOP">Too many processes use Windows sockets at this time!</td><td align="LEFT" valign="TOP">328</td></tr>
<tr><td align="LEFT" valign="TOP">Network unreachable!</td><td align="LEFT" valign="TOP">298</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to listen for incoming requests!</td><td align="LEFT" valign="TOP">283</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to create any listener socket for socket set!</td><td align="LEFT" valign="TOP">364</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to wait for sockets to become ready, timed out!</td><td align="LEFT" valign="TOP">336</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find IP address for: ...!</td><td align="LEFT" valign="TOP">284, 285, h</td></tr>
<tr><td align="LEFT" valign="TOP">No valid socket found in set!</td><td align="LEFT" valign="TOP">359</td></tr>
<tr><td align="LEFT" valign="TOP">Connection from ... accepted (information).</td><td align="LEFT" valign="TOP">360, 361, c</td></tr>
<tr><td align="LEFT" valign="TOP">Connection from ... rejected!</td><td align="LEFT" valign="TOP">362, 363, c</td></tr>
<tr><td align="LEFT" valign="TOP">Host not found!</td><td align="LEFT" valign="TOP">286</td></tr>
<tr><td align="LEFT" valign="TOP">Host exists, but no IP address assigned!</td><td align="LEFT" valign="TOP">287</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to find address for host!</td><td align="LEFT" valign="TOP">338</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to set socket options!</td><td align="LEFT" valign="TOP">339</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to convert text address to address!</td><td align="LEFT" valign="TOP">337</td></tr>
<tr><td align="LEFT" valign="TOP">Local address already in use!</td><td align="LEFT" valign="TOP">293</td></tr>
<tr><td align="LEFT" valign="TOP">Access denied by firewall or due to insufficient permissions!</td><td align="LEFT" valign="TOP">292</td></tr>
<tr><td align="LEFT" valign="TOP">Can not connect to remote port 0!</td><td align="LEFT" valign="TOP">291</td></tr>
<tr><td align="LEFT" valign="TOP">Problem on DNS server!</td><td align="LEFT" valign="TOP">288</td></tr>
<tr><td align="LEFT" valign="TOP">Temporary problem on DNS server, try again later!</td><td align="LEFT" valign="TOP">289</td></tr>
<tr><td align="LEFT" valign="TOP">Not an IP address: ...!</td><td align="LEFT" valign="TOP">348, 349, a</td></tr>
<tr><td align="LEFT" valign="TOP">Not an IP address!</td><td align="LEFT" valign="TOP">350</td></tr>
<tr><td align="LEFT" valign="TOP">Netmask is not a dotted IP addres!</td><td align="LEFT" valign="TOP">354</td></tr>
<tr><td align="LEFT" valign="TOP">Netmask is not a bit number!</td><td align="LEFT" valign="TOP">355</td></tr>
<tr><td align="LEFT" valign="TOP">Netmask is not an IPv6 address!</td><td align="LEFT" valign="TOP">356</td></tr>
<tr><td align="LEFT" valign="TOP">No name resolution available, please specify IP address!</td><td align="LEFT" valign="TOP">357</td></tr>
<tr><td align="LEFT" valign="TOP">Interrupted by signal!</td><td align="LEFT" valign="TOP">281</td></tr>
<tr><td align="LEFT" valign="TOP">Unknown or illegal address family!</td><td align="LEFT" valign="TOP">275</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to retrieve socket state!</td><td align="LEFT" valign="TOP">301</td></tr>
<tr><td align="LEFT" valign="TOP">Protocol not supported!</td><td align="LEFT" valign="TOP">278</td></tr>
<tr><td align="LEFT" valign="TOP">No gethostbyname() function available!</td><td align="LEFT" valign="TOP">290</td></tr>
<tr><td align="LEFT" valign="TOP">No select() function available!</td><td align="LEFT" valign="TOP">358</td></tr>
<tr><td align="LEFT" valign="TOP">No select() function available, timeout settings ignored!</td><td align="LEFT" valign="TOP">300</td></tr>
<tr><td align="LEFT" valign="TOP">No function available to check blocking/non-blocking state!</td><td align="LEFT" valign="TOP">353</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Random data generation</b></td></tr>
<tr><td align="LEFT" valign="TOP">Failed to create random data!</td><td align="LEFT" valign="TOP">177</td></tr>
<tr><td align="LEFT" valign="TOP">No usable PRNG found!</td><td align="LEFT" valign="TOP">178</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to seed simple PRNG!</td><td align="LEFT" valign="TOP">179</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to seed lrand48() PRNG!</td><td align="LEFT" valign="TOP">180</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to seed random() PRNG!</td><td align="LEFT" valign="TOP">181</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to seed OpenSSL PRNG!</td><td align="LEFT" valign="TOP">182</td></tr>
<tr><td align="LEFT" valign="TOP">Seed file ... not used (permissions)!</td><td align="LEFT" valign="TOP">183, 184, f</td></tr>
<tr><td align="LEFT" valign="TOP">Seed file ... not used (symlink owner)!</td><td align="LEFT" valign="TOP">185, 186, f</td></tr>
<tr><td align="LEFT" valign="TOP">Unknown PRNG type: ...!</td><td align="LEFT" valign="TOP">187, 188, p</td></tr>
<tr><td align="LEFT" valign="TOP">The srand()/rand() PRNG ist not available!</td><td align="LEFT" valign="TOP">189</td></tr>
<tr><td align="LEFT" valign="TOP">The srand48()/lrand48() PRNG is not availanble!</td><td align="LEFT" valign="TOP">190</td></tr>
<tr><td align="LEFT" valign="TOP">The random() PRNG is not available!</td><td align="LEFT" valign="TOP">191</td></tr>
<tr><td align="LEFT" valign="TOP">The OpenSSL PRNG is not available!</td><td align="LEFT" valign="TOP">192</td></tr>
<tr><td align="LEFT" valign="TOP">Failed to save random seed data!</td><td align="LEFT" valign="TOP">193</td></tr>
<tr><td align="LEFT" valign="TOP">Attempt to obtain seed data from CryptoAPI (information).</td><td align="LEFT" valign="TOP">227</td></tr>
<tr><td align="LEFT" valign="TOP">Attempt to obtain seed data from screen (information).</td><td align="LEFT" valign="TOP">228</td></tr>
<tr><td align="LEFT" valign="TOP">OpenSSL PRNG seeded successfully (information).</td><td align="LEFT" valign="TOP">229</td></tr>
<tr><td align="LEFT" valign="TOP" colspan="2">&nbsp;<br><b>Text to LaTeX conversion</b></td></tr>
<tr><td align="LEFT" valign="TOP">No directory containing LaTeX encoding tables found!</td><td align="LEFT" valign="TOP">205</td></tr>
<tr><td align="LEFT" valign="TOP">LaTeX table directory: ... (information).</td><td align="LEFT" valign="TOP">232, 233, d</td></tr>
<tr><td align="LEFT" valign="TOP">Reading LaTeX table directory: ... (information).</td><td align="LEFT" valign="TOP">236, 237, d</td></tr>
<tr><td align="LEFT" valign="TOP">Attempting LaTeX table directory: ... (information).</td><td align="LEFT" valign="TOP">234, 235, d</td></tr>
<tr><td align="LEFT" valign="TOP">Registering LaTeX conversion range ... (information).</td><td align="LEFT" valign="TOP">238, 239, r</td></tr>
<tr><td align="LEFT" valign="TOP">Loading LaTeX conversion data file ... (information).</td><td align="LEFT" valign="TOP">240, 241, f</td></tr>
<tr><td align="LEFT" valign="TOP">Redefinition, overwriting ... by ...</td><td align="LEFT" valign="TOP">206,207,208,o,n</td></tr>
<tr><td align="LEFT" valign="TOP">Syntax error, index ... is out of range 0...255.</td><td align="LEFT" valign="TOP">209, 201, i</td></tr>
<tr><td align="LEFT" valign="TOP">Syntax error near ...!</td><td align="LEFT" valign="TOP">211, 212, t</td></tr>
<tr><td align="LEFT" valign="TOP">Syntax error, missing LaTeX encoding</td><td align="LEFT" valign="TOP">213</td></tr>
<tr><td align="LEFT" valign="TOP">Syntax error, missing index!</td><td align="LEFT" valign="TOP">214</td></tr>
<tr><td align="LEFT" valign="TOP">Character redefinition!</td><td align="LEFT" valign="TOP">224</td></tr>
<tr><td align="LEFT" valign="TOP">Range not declared in character directory!</td><td align="LEFT" valign="TOP">225</td></tr>
<tr><td align="LEFT" valign="TOP">Package name conflicts with previous definition!</td><td align="LEFT" valign="TOP">226</td></tr>
</table>
*/

/**	@page	stringtable	String table files.

@section	dk3sttstructure	File structure
The string table file consists of string lines and comment lines.

A comment is started by a raute sign "#" immediately
on the beginning of the line (no leading spaces allowed).

All other lines are string lines, each line is used to build one string
in the string array. The lines are used in order of appearance.

If you need a raute sign at the beginning of a string, use the
backslash + raute sequence "\#".

If you need a string including newlines write "\n" for the newlines.

String table files - as help text files too - must be UTF-8 encoded.

@section	dk3sttstringfilename	File names
The string table file name is specified as short file name (without
leading directory) to dk3app_messages().
The function searches for the file in the following directories and
uses the first file found:

- \$(datarootdir)/<i>programname</i>/<i>language</i>/<i>region</i>
- \$(datarootdir)/<i>programgroup</i>/<i>language</i>/<i>region</i>
- \$(datarootdir)/dk3app/<i>language</i>/<i>region</i>
- \$(datarootdir)/<i>language</i>/<i>region</i>
- \$(datarootdir)/<i>programname</i>/<i>language</i>
- \$(datarootdir)/<i>programgroup</i>/<i>language</i>
- \$(datarootdir)/dk3app/<i>language</i>
- \$(datarootdir)/<i>language</i>
- \$(datarootdir)/<i>programname</i>/en
- \$(datarootdir)/<i>programgroup</i>/en
- \$(datarootdir)/dk3app/en
- \$(datarootdir)/en
- \$(datarootdir)/<i>programname</i>
- \$(datarootdir)/<i>programgroup</i>
- \$(datarootdir)/dk3app
- \$(datarootdir)

@section	dk3sttstringexample	Example
To write an appropriate string table file for
@code
#include <stdio.h>
#include <dk3all.h>

static dkChar const gn[] = { "tests" };

static dkChar const * const mytexts[] = {
dkT("Hello world."),
dkT("Goodbye world."),
NULL
};

DK3_MAIN
{
  dk3_app_t *app = NULL;
  dkChar const * const *msg = NULL;
  app = dk3app_open_command(argc, (dkChar const * const *)argv, gn);
  if(app) {
    msg = dk3app_messages(app, dkT("myprog.str"), (dkChar const **)mytexts);
    dk3sf_initialize_stdout();
    dk3sf_fputs(msg[0], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3sf_fputs(msg[1], stdout);
    dk3sf_fputc(dkT('\n'), stdout);
    dk3app_close(app);
  }
}
@endcode
we could write /usr/local/share/tests/de/de/myprog.str as
@code
#
# 0: Message text: Hello world.
#
Guten Tag.
#
# 1: Message text: Goodbye world.
#
Auf Wiedersehen.
@endcode

Here are some recommendations for comments:
- You should have a comment with the entry (string) number before
  each string.
- Additionally the comment should show the purpose and the original
  message in english language.

*/

