= Interpreter

The following functions allow inspection and/or manipulation of the `unlang` interpreter as it is running.

== Debug Functions

The following functions allow changing the debug level, or printing out specific lists of attributes.

=== %debug(<level>)

Dynamically change the debug level to something high, recording the old level.

.Return: _string_

.Example

[source,unlang]
----
recv Access-Request {
    if (&request.User-Name == "bob") {
        "%debug(4)"
    } else {
        "%debug(0)"
    }
    ...
}
----

.Output (_extra information only for that condition_)

```
...
(0)  recv Access-Request {
(0)    if (&request.User-Name == "bob") {
(0)      EXPAND %debug(4)
(0)        --> 2
(0)    } # if (&request.User-Name == "bob") (...)
(0)    filter_username {
(0)      if (&State) {
(0)        ...
(0)      }
...
```

=== %debug_attr(<list:[index]>)

Print to debug output all instances of current attribute, or all attributes in a list.
expands to a zero-length string.

.Return: _string_

.Example

[source,unlang]
----
recv Access-Request {
    if (&request.User-Name == "bob") {
        "%debug_attr(request[*])"
    }
    ...
}
----

.Output

```
...
(0)  recv Access-Request {
(0)    if (&request.User-Name == "bob") {
(0)      Attributes matching "request[*]"
(0)        &request.User-Name = bob
(0)        &request.User-Password = hello
(0)        &request.NAS-IP-Address = 127.0.1.1
(0)        &request.NAS-Port = 1
(0)        &request.Message-Authenticator = 0x9210ee447a9f4c522f5300eb8fc15e14
(0)      EXPAND %debug_attr(request[*])
(0)    } # if (&request.User-Name == "bob") (...)
...
```

== State

The state of the interpreter can be queried via the
`%interpreter(<name>)` expansion.  The individual expansions are
documented below.

Each expansion given here can be prefixed with one or more dot (`.`)
characters.  These dots allow the expansion to refer to the current
request via a `name`, or the parent request via `.name`.  If there is
no parent, the expansion returns the string `<underflow>`.

For example `'filename'` is the name of the current file being
executed, while `'..filename'` is the filename of the parent request.

== %interpreter('filename')

Which filename is currently being executed.

== %interpreter('line')

The line number in the current file being executed.

== %interpreter('processing_stage')

Which section of a virtual server is processing the request.


== %interpreter('module')

The current module being executed.  If the expansions is done in an
`unlang` statement and outside of any module, it returns the name of
the previous module which was executed.

== %interpreter('processing_stage')

Which section of a virtual server is processing the request.

== %interpreter('rcode')

The current interpreter return code, e.g. `handle`, or `ok`, etc.

== %interpreter('server')

The name of the virtual server which is running the request.

=== %client(<key>)

Refers to a variable that was defined in the client section for the
current client. See the sections `client { ... }` in `clients.conf`.

.Return: _string_

.Example

[source,unlang]
----
"The client ipaddr is %client(ipaddr)"
----

.Output

```
The client ipaddr is 192.168.5.9
```

// Copyright (C) 2023 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
