| ipv4prefix | IPv4 network with address and prefix length
| ipv6prefix | IPv6 network with address and prefix length
| octets | raw binary, printed as hex strings
-| string | printable strings
+| xref:type/string/index.adoc[string] | printable strings
| time_delta | difference between two calendar dates
| uint8 | 8-bit unsigned integer
| uint16 | 16-bit unsigned integer
= Data Types
Unlang supports a number of data types. These data types are used in
-conditional expressions or when assigning a value to an attribute.
+dictionaries, expressions or when assigning a value to an attribute.
== Using Data Types
xref:type/string/single.adoc[single-quoted strings], text within
double quotes can include spaces.
+For normally quoted strings, the quotation character can be placed inside of
+the string by escaping it with a backslash.
+
+For triple quoted strings, the quotation character does not need to be
+escaped. However, if the string does contain an escaped quotation
+character, the quotation character is unescaped, as with normally
+quoted strings.
+
The main difference between the single and double quoted strings is
that the double quoted strings can be dynamically expanded. The syntax
`${...}` is used for parse-time expansion and `%{...}` is used for
`"this has embedded\ncharacters"` +
`"attribute\tvalue\nusername\t%{User-Name}\nreply-message\t%{reply.Reply-Message}"`
`"The result of 'SELECT * FROM foo WHERE 1' is: %sql(SELECT * FROM foo WHERE 1)"`
+`"""this string has a "double quoted" string in the middle of it"""`
// Licenced under CC-by-NC 4.0.
// Copyright (C) 2019 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
.Syntax
`'string'`
+`'''string with 'quote' embedded'''`
A single-quoted string is interpreted without any dynamic string
expansion. The quotes allow the string to contain spaces, among other
-special characters. The single quote character can be placed in such a
-string by escaping it with a backslash.
+special characters.
+
+For normally quoted strings, the quotation character can be placed inside of
+the string by escaping it with a backslash.
+
+For triple quoted strings, the quotation character does not need to be
+escaped. However, if the string does contain an escaped quotation
+character, the quotation character is unescaped, as with normally
+quoted strings.
.Examples
`'foo bar`' +
`'foo\\'bar'` +
`'this is a long string'`
+`'''This is a string with 'embedded' quotes'''`
// Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
char quote;
char close;
int depth;
+ bool triple;
*type = T_INVALID;
* more rigorous check.
*/
skip_string:
+ if ((inlen > 3) && (p[0] == quote) && (p[1] == quote)) {
+ triple = true;
+ p += 2;
+ } else {
+ triple = false;
+ }
*out = p;
+
while (*p) {
+ if (p >= end) goto unterminated;
+
/*
* End of string. Tell the caller the
* length of the data inside of the
* characters to skip.
*/
if (*p == quote) {
- *outlen = p - (*out);
+ if (!triple) {
+ *outlen = p - (*out);
+ p++;
+ return p - in;
+
+ }
+
+ if (((end - p) >= 3) && (p[1] == quote) && (p[2] == quote)) {
+ *outlen = p - (*out);
+ p += 3;
+ return p - in;
+ }
+
p++;
- return p - in;
+ continue;
}
if (*p == '\\') {
* End of input without end of string.
* Point the error to the start of the string.
*/
+ unterminated:
p = *out;
return_P("Unterminated string");
char *s;
char const *p;
char quote;
+ bool triple = false;
unsigned int x;
size_t i;
fr_token_t token;
if (token != T_BARE_WORD) {
quote = *p;
+
+ /*
+ * Triple-quoted strings are copied over verbatim, without escapes.
+ */
+ if ((buflen >= 3) && (p[1] == quote) && (p[2] == quote)) {
+ p += 3;
+ }
+
p++;
}
s = buf;
* Un-escaped quote character. We're done.
*/
if (*p == quote) {
- p++;
- *s++ = 0;
- goto done;
+ if (!triple) {
+ p++;
+ *s++ = 0;
+ goto done;
+
+ }
+
+ if ((buflen >= 3) && (p[1] == quote) && (p[2] == quote)) {
+ p += 3;
+ *s++ = 0;
+ goto done;
+ }
+
+ *s++ = *p++;
+ continue;
}
/*