.\" Copyright (c) 2003-2012
.\" Distributed Systems Software. All rights reserved.
.\" See the file LICENSE for redistribution information.
.\" $Id: copyright-nr 2564 2012-03-02 00:17:08Z brachman $
'\" t
.\" Title: dacsexpr
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 08/23/2020
.\" Manual: DACS Commands Manual
.\" Source: DACS 1.4.40
.\" Language: English
.\"
.TH "DACSEXPR" "1" "08/23/2020" "DACS 1.4.40" "DACS Commands Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dacsexpr \- \fBDACS\fR expression language shell and interpreter
.SH "SYNOPSIS"
.HP \w'\fBdacsexpr\fR\ 'u
\fBdacsexpr\fR [\fB\-x\fR] [\fI\m[blue]\fBdacsoptions\fR\m[]\&\s-2\u[1]\d\s+2\fR] [\fB\-dl\fR] [\fB\-e\fR\ \fIexpr\fR] [\fB\-n\fR] [\fB\-p\fR] [\fB\-s\fR] [\fB\-h\fR | \fB\-help\fR] [\fB\-test\fR]
.br
[\fB\-\-\fR] [\fIfilename\fR] [\fIscript\-arg\fR...]
.SH "DESCRIPTION"
.PP
This program is part of the
\fBDACS\fR
suite\&.
.PP
The
\fBdacsexpr\fR
utility evaluates
\fBDACS\fR
expressions (see
\m[blue]\fBdacs\&.exprs(5)\fR\m[]\&\s-2\u[2]\d\s+2)\&. It is often a useful aid when composing or testing expressions to be used in access control rules, or when debugging ACLs and configuration directives\&. While they continue to be referred to as "expressions" for historical reasons, it has become possible to write small programs, and the language can also be useful as a simple scripting language independent of the rest of
\fBDACS\fR\&.
.PP
If an expression is provided, it is evaluated and the result is printed to the standard output\&. At most one expression can be specified\&. If the
\fB\-q\fR
flag is given (one of the
\m[blue]\fB\fIdacsoptions\fR\fR\m[]\&\s-2\u[1]\d\s+2), nothing is printed, expression evaluation errors are suppressed, and the program terminates with an appropriate
\m[blue]\fBexit status\fR\m[]\&\s-2\u[3]\d\s+2; otherwise the result is written to the standard output\&. If neither a
\fB\-q\fR
flag is given nor any flag that controls the logging level, then the logging level is set to
warn
overriding any configuration file logging level directive; this behaviour is usually convenient\&.
.PP
If no expression is provided, the program reads its standard input\&. If the input is not coming from a terminal type device, the program runs in "batch mode" and prompting is suppressed; otherwise, the program runs in "interactive mode"\&. When prompted in interactive mode, enter
\fBhelp\fR
for assistance\&. If the
\m[blue]\fBreadline(3)\fR\m[]\&\s-2\u[4]\d\s+2
functionality was configured when the program was built, command line editing and history are available in interactive mode\&.
.PP
A script can be executed through the system\*(Aqs "#!" mechanism:
.sp
.if n \{\
.RS 4
.\}
.nf
#!/usr/local/dacs/bin/dacsexpr
printf("%s\en", "Hello, world\&.")
.fi
.if n \{\
.RE
.\}
.sp
Such programs always use the script file as input, therefore no expression or other file can be specified on the "#!" line\&.
.PP
Command line arguments can be passed to a script\&. If
dig\-it
contains:
.sp
.if n \{\
.RS 4
.\}
.nf
#!/usr/local/dacs/bin/dacsexpr
if (${Argv::#} != 3) {
printf("Usage: dig\-it digest\-name msg\en");
exit(1);
}
printf("%s\en", digest(${Argv::2}, 0, ${Argv::1}));
.fi
.if n \{\
.RE
.\}
.sp
then running the script produces:
.sp
.if n \{\
.RS 4
.\}
.nf
% \&./dig\-it sha3\-224 mymsg
88fdaa49d0371a79efa2d6e8a55d27d62cd39ad393309d9a18665763
.fi
.if n \{\
.RE
.\}
.PP
The
\fIEnv\fR
namespace is initialized from the program\*(Aqs environment\&. For example, if the value of the environment variable
\fBLOGNAME\fR
is
bobo, then
\fI${Env::LOGNAME}\fR
will be instantiated with that value\&. Syntactically invalid variable names are silently ignored\&.
.PP
An empty
\fIExpr\fR
namespace is created\&. In interactive use, the prompt string can be changed by assigning a string to
\fI${Expr::prompt}\fR
and the continuation prompt can be changed by setting
\fI${Expr::prompt2}\fR\&.
.if n \{\
.sp
.\}
.RS 4
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBNote\fR
.ps -1
.br
.PP
Configuration directives and the
\fIConf\fR
variable namespace are available only if a configuration file is processed (e\&.g\&., by giving the
\fB\-uj\fR
command line flag)\&. This is relevant, for example, if the
\m[blue]\fBhttp()\fR\m[]\&\s-2\u[5]\d\s+2
function is called using the
https
scheme because proper operation will require the
\m[blue]\fBSSL_PROG\fR\m[]\&\s-2\u[6]\d\s+2
directive to be configured\&. See
\m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[7]\d\s+2\&.
.sp .5v
.RE
.SH "OPTIONS"
.PP
If an expression or file has not already been specified, a filename may appear as the last argument\&. If
\fIfilename\fR
is "\-", the standard input is read\&.
.PP
\fB\-dl\fR
.RS 4
Print debugging information to
stderr\&.
.RE
.PP
\fB\-e\fR \fIexpr\fR
.RS 4
The given expression is evaluated\&.
.RE
.PP
\fB\-h\fR
.br
\fB\-help\fR
.RS 4
Display a help message and exit\&.
.RE
.PP
\fB\-n\fR
.RS 4
Do not evaluate any expressions, only check for syntax errors\&.
.RE
.PP
\fB\-p\fR
.RS 4
Print the final result to the standard output, unless it has been suppressed by
\fB\-q\fR
or
\fB\-n\fR\&. Without this flag, the result would have to be output by the program\&.
.RE
.PP
\-s
.RS 4
If a single expression is being evaluated from the command line or a file and the result of evaluation is a string or bstring, the output will be surrounded by quotes unless this flag is specified\&.
.RE
.PP
\fB\-test\fR
.RS 4
The input is a test case:
.sp
.if n \{\
.RS 4
.\}
.nf
#!/usr/local/dacs/bin/dacsexpr \-test
// expect\-exact:17
${x} = 17;
.fi
.if n \{\
.RE
.\}
.sp
A test case consists of options followed by an expression\&. There can be zero or more options, one per line, embedded within a
//
style comment:
.sp
.if n \{\
.RS 4
.\}
.nf
{ whitespace* "//" whitespace* \fIoption\-name\fR ":" \fIoption\-value\fR end\-of\-line }*
.fi
.if n \{\
.RE
.\}
.sp
No whitespace is allowed before or after the ":"\&. As a special case, lines having the following format are ignored:
.sp
.if n \{\
.RS 4
.\}
.nf
whitespace* "///" \&.* end\-of\-line
.fi
.if n \{\
.RE
.\}
.sp
The first non\-option line terminates the options and is the first line of the expression to be evaluated\&.
.sp
Here is an example:
.sp
.if n \{\
.RS 4
.\}
.nf
/// Test bitwise shifts
// expect\-exact:1024
1 << 10
.fi
.if n \{\
.RE
.\}
.sp
An option controls how the test is to be performed and gives the expected result:
.PP
expect:\fIregex\fR
.br
expect\-regex:\fIregex\fR
.RS 4
The result string must match
\fIregex\fR\&. These two option names are equivalent\&.
.RE
.PP
expect\-identical:\fIstring\fR
.RS 4
The result string must match
\fIstring\fR
exactly\&.
.RE
.PP
expect\-exact:\fIstring\fR
.RS 4
The result string must match
\fIstring\fR
exactly, except that C\-style character constants (preceded by a backslash) in
\fIstring\fR
are interpolated\&.
.RE
.PP
expect\-code:\fIcode\fR
.RS 4
The result code must match
\fIcode\fR, which is 0 if the result is
\fBTrue\fR, 1 if the result is
\fBFalse\fR, and 2 if an error occurs\&. If this option is not given, a default code of 0 is assumed\&.
.RE
.PP
expect\-type:\fItype\fR
.RS 4
The type of the result must match
\fItype\fR, which can be
integer,
real,
string,
bstring,
literal, or
undef\&.
.RE
.PP
expect\-flags:\fIflags\fR
.RS 4
Currently, the only recognized values for
\fIflags\fR
are
rw_namespaces
and
ro_namespaces\&. The former allows the test to create or modify variables in the
\fIDACS\fR,
\fIArgs\fR, or
\fIEnv\fR
namespace; by default, these namespaces are read\-only\&. This might be useful when testing
\m[blue]\fBfrom()\fR\m[]\&\s-2\u[8]\d\s+2, for instance, because it allows the test to set a value for
\fI${DACS::REMOTE_ADDR}\fR\&. The default behaviour can be explicitly selected by specifying
ro_namespaces\&.
.RE
.PP
show\-result:{yes | no}
.RS 4
The result is printed to the standard output only if the option value is
yes\&.
.RE
.sp
If the test fails, a descriptive message is printed to the standard error\&. The program\*(Aqs exit status will be
0
if the test was successful,
1
otherwise\&.
.sp
This example should succeed without displaying the result:
.sp
.if n \{\
.RS 4
.\}
.nf
// expect\-exact:2
// expect\-type:integer
/// show\-result:yes
1 + 1
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.sp
.\}
.RS 4
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBNote\fR
.ps -1
.br
The
\fBDACS\fR
distribution includes a set of test cases in the
src/tests
directory that can be run for regression testing (do "make tests" from the
src
directory)\&. Some of the functions provided by
\m[blue]\fBdacs\&.exprs(5)\fR\m[]\&\s-2\u[2]\d\s+2
are also used internally by
\fBDACS\fR, so it is critical that all tests are successful even for functions that are not used from the user level\&.
.sp .5v
.RE
.RE
.PP
\-x
.RS 4
If this is the very first flag it indicates that
\fBdacsexpr\fR
is being executed as a script via the system\*(Aqs "#!" mechanism\&. This might be useful if the program\*(Aqs heuristic for determining this is incorrect\&. The last argument must be a filename\&.
.RE
.PP
\-\-
.RS 4
This argument explicitly marks the last flag argument\&. A filename argument might follow\&.
.RE
.SH "EXAMPLES"
.PP
The following command evaluates the expression argument (note that it is a single argument to the command) and outputs the result to
stdout:
.sp
.if n \{\
.RS 4
.\}
.nf
% dacsexpr \-e "1+1"
2
% dacsexpr \-e \*(Aq${Env::USER}\*(Aq
"bobo"
% dacsexpr \-u example\&.com \-e \*(Aq"FEDERATION_NAME=" \&. ${Conf::FEDERATION_NAME}\*(Aq
"FEDERATION_NAME=EXAMPLE"
% dacsexpr \- a b c <