+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_REGEX
+ *
+ * NAME
+ *
+ * #define SILC_STR_REGEX() ...
+ *
+ * DESCRIPTION
+ *
+ * Regular expression matching within the buffer.
+ *
+ * Formatting: SILC_STR_REGEX(char *regex, SilcBufferRegexFlags flags)
+ * Unformatting: SILC_STR_REGEX(char *regex, SilcBufferRegexFlags flags)
+ *
+ * SILC_STR_REGEX can be used to do regular expression matching within
+ * the SilcBuffer. When the string in the buffer matches the regular
+ * expression the position of the buffer is advanced to the position of
+ * the first match (rest of the buffer remains intact). If the regular
+ * expression does not match it is skipped, unless the flags specify
+ * otherwise. If flags are not needed they can be set to 0.
+ *
+ * In addition of matching regular expressions it can be used in a
+ * Stream Editor (sed) and Awk like fashion. The regular expression can be
+ * matched and then edited by any of the SILC_STR_* macros. The flags
+ * can be used to perform complex operations on the data. Some sed
+ * features that cannot be directly done with the flags can be done with
+ * SILC_STR_FUNC and other macros (the SILC_STR_FUNC could do anything
+ * after the match).
+ *
+ * The SILC_STR_REGEX itself is used as an opening of a block of encoding
+ * macros and must be closed with SILC_STR_END. This means that for
+ * each SILC_STR_REGEX there must be one SILC_STR_END. See examples for
+ * more information.
+ *
+ * The SILC_STR_REGEX can be used in buffer unformatting also to do
+ * string matching and parsing, but not editing, except with SILC_STR_FUNC
+ * macro, which can do anything caller wants.
+ *
+ * EXAMPLE
+ *
+ * // sed 's/foo/bar/', replace first foo with bar
+ * silc_buffer_format(buffer,
+ * SILC_STR_REGEX("foo", 0),
+ * SILC_STR_STRING("bar"),
+ * SILC_STR_END, SILC_STR_END);
+ *
+ * // sed 's/foo/barbar/g', replace all foo's with barbar, without
+ * // overwriting any data in the buffer, but appending it. The match
+ * // must be SILC_STR_REGEX_INCLUSIVE to make appending work.
+ * silc_buffer_format(buffer,
+ * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL |
+ * SILC_STR_REGEX_INCLUSIVE),
+ * SILC_STR_STRING_APPEND("barbar"),
+ * SILC_STR_END, SILC_STR_END);
+ *
+ * // sed '/baz/s/foo/bar/g, replace all foo's with bar on lines with baz
+ * silc_buffer_format(buffer,
+ * SILC_STR_REGEX("baz", SILC_STR_REGEX_NL),
+ * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL),
+ * SILC_STR_STRING("bar"),
+ * SILC_STR_END,
+ * SILC_STR_END, SILC_STR_END);
+ *
+ * // Print all lines that start with 'R'
+ * int print(SilcStack stack, SilcBuffer buf, void *value, void *context)
+ * {
+ * return fwrite(silc_buffer_data(buf), 1, silc_buffer_len(buf), stdout);
+ * }
+ *
+ * silc_buffer_unformat(buffer,
+ * SILC_STR_REGEX("^R", SILC_STR_REGEX_NL),
+ * SILC_STR_FUNC(print, NULL, NULL),
+ * SILC_STR_END, SILC_STR_END);
+ *
+ ***/
+#define SILC_STR_REGEX(regex, flags) SILC_PARAM_REGEX, (regex), (flags)
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET
+ *
+ * NAME
+ *
+ * #define SILC_STR_OFFSET() ...
+ *
+ * DESCRIPTION
+ *
+ * Offset in buffer. This can be used in formatting and unformatting to
+ * move the data pointer of the buffer either forwards (positive offset)
+ * or backwards (negative offset). It can be used to for example skip
+ * some types during unformatting.
+ *
+ * Example:
+ *
+ * ..., SILC_STR_OFFSET(5), ...
+ * ..., SILC_STR_OFFSET(-3), ...
+ *
+ * Moves the data pointer at the point of the offset either forward
+ * or backward and then moves to the next type. Multiple SILC_STR_OFFSETs
+ * can be used in formatting and unformatting at the same time.
+ *
+ ***/
+#define SILC_STR_OFFSET(x) SILC_PARAM_OFFSET, (x)
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET_START
+ *
+ * NAME
+ *
+ * #define SILC_STR_OFFSET_START ...
+ *
+ * DESCRIPTION
+ *
+ * Moves the buffer position to the start of the data area.
+ *
+ * Example:
+ *
+ * ..., SILC_STR_OFFSET_START, ...
+ *
+ ***/
+#define SILC_STR_OFFSET_START SILC_PARAM_OFFSET_START
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET_END
+ *
+ * NAME
+ *
+ * #define SILC_STR_OFFSET_END ...
+ *
+ * DESCRIPTION
+ *
+ * Moves the buffer position to the end of the data area.
+ *
+ * Example:
+ *
+ * ..., SILC_STR_OFFSET_END, ...
+ *
+ ***/
+#define SILC_STR_OFFSET_END SILC_PARAM_OFFSET_END
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_ADVANCE
+ *
+ * NAME
+ *
+ * #define SILC_STR_ADVANCE ...
+ *
+ * DESCRIPTION
+ *
+ * Advance the buffer to the end of the data after the formatting is
+ * done. In normal operation when the formatted data is written the
+ * buffer is positioned at the start of the data. With SILC_STR_ADVANCE
+ * the buffer will be positioned at the end of the data. This makes it
+ * easy to add new data immediately after the previously added data.
+ * The SILC_STR_ADVANCE may also be used in unformatting.
+ *
+ * EXAMPLE
+ *
+ * do {
+ * len = read(fd, buf, sizeof(buf));
+ * if (len > 0)
+ * // Add read data to the buffer
+ * silc_buffer_format(buffer,
+ * SILC_STR_ADVANCE,
+ * SILC_STR_DATA(buf, len),
+ * SILC_STR_END);
+ * } while (len > 0);
+ *
+ * // Move to beginning of buffer
+ * silc_buffer_start(buffer);
+ *
+ ***/
+#define SILC_STR_ADVANCE SILC_PARAM_ADVANCE
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_END
+ *
+ * NAME
+ *
+ * #define SILC_STR_END ...
+ *
+ * DESCRIPTION
+ *
+ * Marks end of the argument list. This must be at the end of the
+ * argument list or error will occur.
+ *
+ ***/
+#define SILC_STR_END SILC_PARAM_END
+
+/****d* silcutil/SilcBufferFormatAPI/SILC_STRFMT_END
+ *
+ * NAME
+ *
+ * #define SILC_STRFMT_END ...
+ *
+ * DESCRIPTION
+ *
+ * Marks end of the argument list in silc_buffer_strformat function.
+ * This must be at the end of the argument list or error will occur.
+ *
+ ***/
+#define SILC_STRFMT_END (void *)SILC_STR_END