---
name: "dacsexpr"
section: "1"
platform: "linux"
package: "dacs"
version: "1.4.40-2"
release: "Debian 10 (Buster)"
platforms: ["linux"]
url: "https://new.carta.tech/dacsexpr"
---

# dacsexpr(1)

DACS expression language shell and interpreter

## NAME

dacsexpr - **DACS** expression language shell and interpreter

## SYNOPSIS

**dacsexpr** \[**-x**\] \[**dacsoptions**\[1\]\] \[**-dl**\] \[**-e** *expr*\] \[**-n**\] \[**-p**\] \[**-s**\] \[**-h** \| **-help**\] \[**-test**\]\
 \[**--**\] \[*filename*\] \[*script-arg*...\]

## DESCRIPTION

This program is part of the **DACS** suite.

The **dacsexpr** utility evaluates **DACS** expressions (see **[dacs.exprs(5)](/dacs.exprs/5.md)**\[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 **DACS**.

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 **-q** flag is given (one of the *dacsoptions*\[1\]), nothing is printed, expression evaluation errors are suppressed, and the program terminates with an appropriate **exit status**\[3\]; otherwise the result is written to the standard output. If neither a **-q** 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.

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 **help** for assistance. If the **[readline(3)](/readline/3.md)**\[4\] functionality was configured when the program was built, command line editing and history are available in interactive mode.

A script can be executed through the system's "#!" mechanism:

```
#!/usr/local/dacs/bin/dacsexpr
printf("%s\n", "Hello, world.")
```

Such programs always use the script file as input, therefore no expression or other file can be specified on the "#!" line.

Command line arguments can be passed to a script. If dig-it contains:

```
#!/usr/local/dacs/bin/dacsexpr
if (${Argv::#} != 3) {
  printf("Usage: dig-it digest-name msg\n");
  exit(1);
}
printf("%s\n", digest(${Argv::2}, 0, ${Argv::1}));
```

then running the script produces:

```
% ./dig-it sha3-224 mymsg
88fdaa49d0371a79efa2d6e8a55d27d62cd39ad393309d9a18665763
```

The *Env* namespace is initialized from the program's environment. For example, if the value of the environment variable **LOGNAME** is bobo, then *${Env::LOGNAME}* will be instantiated with that value. Syntactically invalid variable names are silently ignored.

An empty *Expr* namespace is created. In interactive use, the prompt string can be changed by assigning a string to *${Expr::prompt}* and the continuation prompt can be changed by setting *${Expr::prompt2}*.

**Note**\

Configuration directives and the *Conf* variable namespace are available only if a configuration file is processed (e.g., by giving the **-uj** command line flag). This is relevant, for example, if the **http()**\[5\] function is called using the https scheme because proper operation will require the **SSL\_PROG**\[6\] directive to be configured. See **[dacs.conf(5)](/dacs.conf/5.md)**\[7\].

## OPTIONS

If an expression or file has not already been specified, a filename may appear as the last argument. If *filename* is "-", the standard input is read.

- **-dl**

  Print debugging information to stderr.

- **-e** *expr*

  The given expression is evaluated.

- **-h** **-help**

  Display a help message and exit.

- **-n**

  Do not evaluate any expressions, only check for syntax errors.

- **-p**

  Print the final result to the standard output, unless it has been suppressed by **-q** or **-n**. Without this flag, the result would have to be output by the program.

- \-s

  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.

- **-test**

  The input is a test case:

  ```
  #!/usr/local/dacs/bin/dacsexpr -test
  // expect-exact:17
  ${x} = 17;
  ```

  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:

  ```
  { whitespace* "//" whitespace* option-name ":" option-value end-of-line }*
  ```

  No whitespace is allowed before or after the ":". As a special case, lines having the following format are ignored:

  ```
  whitespace* "///" .* end-of-line
  ```

  The first non-option line terminates the options and is the first line of the expression to be evaluated.

  Here is an example:

  ```
  /// Test bitwise shifts
  // expect-exact:1024
  1 << 10
  ```

  An option controls how the test is to be performed and gives the expected result:

  expect:*regex*\
   expect-regex:*regex*

  The result string must match *regex*. These two option names are equivalent.

  expect-identical:*string*

  The result string must match *string* exactly.

  expect-exact:*string*

  The result string must match *string* exactly, except that C-style character constants (preceded by a backslash) in *string* are interpolated.

  expect-code:*code*

  The result code must match *code*, which is 0 if the result is **True**, 1 if the result is **False**, and 2 if an error occurs. If this option is not given, a default code of 0 is assumed.

  expect-type:*type*

  The type of the result must match *type*, which can be integer, real, string, bstring, literal, or undef.

  expect-flags:*flags*

  Currently, the only recognized values for *flags* are rw\_namespaces and ro\_namespaces. The former allows the test to create or modify variables in the *DACS*, *Args*, or *Env* namespace; by default, these namespaces are read-only. This might be useful when testing **from()**\[8\], for instance, because it allows the test to set a value for *${DACS::REMOTE\_ADDR}*. The default behaviour can be explicitly selected by specifying ro\_namespaces.

  show-result:{yes \| no}

  The result is printed to the standard output only if the option value is yes.

  If the test fails, a descriptive message is printed to the standard error. The program's exit status will be 0 if the test was successful, 1 otherwise.

  This example should succeed without displaying the result:

  ```
  // expect-exact:2
  // expect-type:integer
  /// show-result:yes
  1 + 1
  ```

  **Note**\
   The **DACS** 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 **[dacs.exprs(5)](/dacs.exprs/5.md)**\[2\] are also used internally by **DACS**, so it is critical that all tests are successful even for functions that are not used from the user level.

- \-x

  If this is the very first flag it indicates that **dacsexpr** is being executed as a script via the system's "#!" mechanism. This might be useful if the program's heuristic for determining this is incorrect. The last argument must be a filename.

- \--

  This argument explicitly marks the last flag argument. A filename argument might follow.

## EXAMPLES

The following command evaluates the expression argument (note that it is a single argument to the command) and outputs the result to stdout:

```
% dacsexpr -e "1+1"
2
% dacsexpr -e '${Env::USER}'
"bobo"
% dacsexpr -u example.com -e '"FEDERATION_NAME=" . ${Conf::FEDERATION_NAME}'
"FEDERATION_NAME=EXAMPLE"
% dacsexpr - a b c <<HERE
? print("First arg is \"\${Argv::1}\"")
? HERE
First arg is "a"
% cat ex
#!/usr/local/dacs/bin/dacsexpr
print("Argv[2] is ${Argv::2}");
% chmod 0755 ex
% ./ex foo bar baz
Argv[2] is bar
```

## DIAGNOSTICS

If an error occurs, a message may be written to stderr, depending on the logging level. In general, the program exits 0 if and only if everything was fine. If a command line expression is evaluated, the program exits 0 if the expression evaluates to **True**, 1 if it evaluates to **False**, and 2 if an error occurs. If an explicit call to **exit()** is made and no true error condition occurred, then the program will exit with the argument value.

## SEE ALSO

**[dacs.exprs(5)](/dacs.exprs/5.md)**\[2\]

## BUGS

New and little-used features should be used with care. This advice applies to all software.

## AUTHOR

Distributed Systems Software (**www.dss.ca**\[9\])

## COPYING

Copyright © 2003-2018 Distributed Systems Software. See the **LICENSE**\[10\] file that accompanies the distribution for licensing information.

## NOTES

- 1\.

  dacsoptions

  http://dacs.dss.ca/man/dacs.1.html#dacsoptions

- 2\.

  [dacs.exprs(5)](/dacs.exprs/5.md)

  http://dacs.dss.ca/man/dacs.exprs.5.html

- 3\.

  exit status

  http://dacs.dss.ca/man/#diagnostics

- 4\.

  [readline(3)](/readline/3.md)

  https://www.freebsd.org/cgi/man.cgi?query=readline&apropos=0&sektion=3&manpath=FreeBSD+10.3-RELEASE&format=html

- 5\.

  http()

  http://dacs.dss.ca/man/dacs.exprs.5.html#http

- 6\.

  SSL\_PROG

  http://dacs.dss.ca/man/dacs.conf.5.html#SSL\_PROG

- 7\.

  [dacs.conf(5)](/dacs.conf/5.md)

  http://dacs.dss.ca/man/dacs.conf.5.html

- 8\.

  from()

  http://dacs.dss.ca/man/dacs.exprs.5.html#from

- 9\.

  www.dss.ca

  http://www.dss.ca

- 10\.

  LICENSE

  http://dacs.dss.ca/man/../misc/LICENSE
