= Conditional Expressions

Conditions are evaluated when parsing xref:if.adoc[if] and
xref:elsif.adoc[elsif] statements.  These conditions allow the server to
make complex decisions based on one of a number of possible criteria.

.Syntax
[source,unlang]
----
if ( condition ) { ...

elsif ( condition ) { ...
----

Conditions are expressed using the following syntax:

[options="header"]
|=====
| Syntax | Description
| xref:attr.adoc[&Attribute-Name] | Check for attribute existence.
| xref:condition/return_codes.adoc[rcode] | Check return code of a previous module.
| xref:condition/operands.adoc[data] | Check value of data.
| xref:condition/cmp.adoc[lhs OP rhs] | Compare two kinds of data.
| xref:condition/para.adoc[( condition )] | Check sub-condition
| xref:condition/not.adoc[! condition] | Negate a conditional check
| xref:condition/and.adoc[( condition ) && ...] | Check a condition AND the next one
| xref:condition/or.adoc[( condition ) \|\| ...] | Check a condition OR the next one
|=====


.Examples
[source,unlang]
----
if ( &User-Name == "bob" ) {
    ...
}

if ( &Framed-IP-Address == 127.0.0.1 ) {
    ...
}

if ( &Calling-Station-Id == "%{sql:SELECT ...}" ) {
    ...
}
----

== Load-time Syntax Checks

The server performs a number of checks when it loads the configuration
files.  Unlike version 2, all of the conditions are syntax checked
when the server loads.  This checking greatly aids in creating
configurations that are correct.  Where the configuration is
incorrect, a descriptive error is produced.

This error contains the filename and line number of the syntax error.
In addition, it will print out a portion of the line that caused the
error and will point to the exact character where the error was seen.
These descriptive messages mean that most errors are easy to find and fix.

== Load-time Optimizations

The server performs a number of optimizations when it loads the
configuration files.  Conditions that have static values are
evaluated and replaced with the result of the conditional comparison.

.Example
[source,unlang]
----
if ( 0 == 1 ) {
    ...
}
----

The condition `0 == 1` is static and will evaluate to `false`.  Since
it evaluates to `false`, the configuration inside of the `if`
statement is ignored.  Any modules referenced inside of the `if`
statement will not be loaded.

This optimization is most useful for creating configurations that
selectively load (or not) certain policies.  If the condition above
was used in version 2, then the configuration inside of the `if` statement
would be loaded, even though it would never be used.

// Copyright (C) 2020 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// Development of this documentation was sponsored by Network RADIUS SAS.
