proto-dictionary radius

xlat_purify ~(uint8) 1
match 254

xlat_purify ~(uint8) 2
match 253

#
#  Signed!
#
xlat_purify -(int8) 1
match -1

xlat_purify !1
match false

xlat_purify (uint8) 1 + -(int8) 1
match 0

#
#  xlat_expr, but purified
#
xlat_purify 3 + 4
match 7

xlat_purify 3 * 4
match 12

xlat_purify 2 + 3 * 4
match 14

xlat_purify 2 + 3 * 4 + 5
match 19

#  Same as above with brackets
xlat_purify 2 + (3 * 4) + 5
match 19

# not the same
xlat_purify (2 + 3) * (4 + 5)
match 45

xlat_purify (2 + 3) * 4 + 5
match 25

xlat_purify &NAS-Port + 5
match (&NAS-Port + 5)

xlat_purify &Framed-IP-Address & 0xffff0000
match (&Framed-IP-Address & 0xffff0000)

#
#  Can't parse or cast RHS to nothing.
#
xlat_purify &Framed-IP-Address + 4
match (&Framed-IP-Address + 4)

xlat_purify 1 < 4
match true

#
#  There's sopme bunch of things to fix here:
#
#  * the tokenizer needs to track offsets, so it can return the offset which cause the error.
#
xlat_purify &Service-Type == Framed-User
match (&Service-Type == Framed-User)

xlat_purify 1 + (&Service-Type == Framed-User)
match (1 + (&Service-Type == Framed-User))

#
#  Strings of various forms
#

xlat_purify &Filter-Id == "foo"
match (&Filter-Id == "foo")

xlat_purify "foo" == "bar"
match false

# note '/' is a prefix, not "divide by 24".
# and a useless cast is removed
xlat_purify &Framed-IP-Address < (ipv4prefix) 192.168.0.0/24
match (&Framed-IP-Address < 192.168.0.0/24)

xlat_purify &Framed-IP-Address < (ipv4prefix) 192.168.0.0
match (&Framed-IP-Address < 192.168.0.0/32)

#
#  For IP addresses, the other side is automatically upcast to a prefix
#

xlat_purify &Framed-IP-Address < 192.168.0.0/24
match (&Framed-IP-Address < 192.168.0.0/24)

#  same as above, but swap the order
xlat_purify (ipv4prefix) 192.168.0.0/24 > &Framed-IP-Address
match (192.168.0.0/24 > &Framed-IP-Address)

#
#  Logical && and ||
#
xlat_purify 1 < 2 || 4 > 3
match true

#  Returns the LHS as a "truthy" value.
xlat_purify 2 || (1 > 4)
match 2

xlat_purify &Filter-Id
match &Filter-Id

xlat_purify %md5('foo') + "bar"
match 0xacbd18db4cc2f85cedef654fccc4a4d8626172

#  We can name the xlat's, tho we don't need to
#
#  And naming the xlat's means that they don't set up
#  with the magic token field, so optimizations don't work?
#

xlat_purify (4 + 3) + 6
match 13

#
#  xlat_tokenize() parses it's arguments as XLAT_BOX,
#  of FR_TYPE_STRING.  The binary op instantiation function
#  fixes those up via tmpl_afrom_substr().
#
xlat_purify %op_add(4, 3) + 6
match 13

#
#  useless casts are omitted.
#
xlat_purify 1 < (uint32) 2
match true

#
#  @todo - peephole - for exec, xlat, etc., if we're doing an existence check of
#  string / octets, then the check is for "length>0", NOT for parsing
#  the contents of the data type.
#

#
#  This should likely be a parse error at boot time?
#
xlat_purify 1 < 2 < 3
match true

xlat_purify &Service-Type == 1
match (&Service-Type == 1)

#
#  Convert the RHS to a simpler version
#
xlat_purify &Service-Type == (1 + 2)
match (&Service-Type == 3)

xlat_purify &Reply-Message == "foo"
match (&Reply-Message == "foo")

#
#  Strings are single quoted
#
xlat_purify &Filter-Id == ("foo" + "bar")
match (&Filter-Id == "foobar")

xlat_purify !&User-Name
match !&User-Name

xlat_purify (1 < 2)
match true

xlat_purify !(1 < 2)
match false

xlat_purify !true
match false

#
#  These are just booleans now.  We can subtract and invert them.
#
xlat_purify -fail
match -%expr.rcode('fail')

xlat_purify ~fail
match ~%expr.rcode('fail')

xlat_purify !fail
match !%expr.rcode('fail')

#
#  Casts and such
#
#  @todo - xlat_tokenize() does not call purify
#
xlat_purify (string)(%{1 + 2})
match %cast(string, %{(1 + 2)})

#
#  This is a different code path than the above.
#
xlat_purify (string)%{1 + 2}
match (string)%{(1 + 2)}

xlat_purify "hello"
match "hello"

#
#  String concatenation
#
xlat_purify "hello " + (string)%{1 + 2}
match "hello 3"

xlat_purify "hello " + (string)%{1 + 2} + " bob"
match "hello 3 bob"

#
#  @todo - this seems wrong, but likely a bug in unit_test_attribute.c
#  The real run-time tests work
#
xlat_purify "hello %{1 + 2} bob"
match "hello %{(1 + 2)} bob"

#
#  New syntax!
#
migrate xlat_new_functions = yes

xlat_purify %md5('foo')
match 0xacbd18db4cc2f85cedef654fccc4a4d8

xlat_purify %explode("a,b,c,d", ',')
match "a""b""c""d"

#
# @todo - bare words should probably be disallowed
#
xlat_purify %md5(foo)
match 0xacbd18db4cc2f85cedef654fccc4a4d8

xlat_purify %md5(%md5(foo))
match 0x47847ae721df523d6388aebc9c94d656

xlat_purify %md5('%md5(foo)')
match 0x5e153571422b69cf5c5f7ce5f03985b5

#
#  This is a reference to the contents of &User-Name
#
xlat_purify %md5(%{User-Name})
match %md5(%{User-Name})


xlat_purify %md5('foo')
match 0xacbd18db4cc2f85cedef654fccc4a4d8

xlat_purify %md5("foo")
match 0xacbd18db4cc2f85cedef654fccc4a4d8

count
match 116
