+Sat Jan 5 20:19:28 EET 2008 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added SILC_STR_DELETE buffer format macro. Added support for
+ deleting data after regex match with SILC_STR_REGEX. Affected
+ files are lib/silcutil/silcbuffmt.[ch].
+
Sat Jan 5 18:00:06 EET 2008 Pekka Riikonen <priikone@silcnet.org>
* Added silc_buffer_equal to lib/silcutil/silcbuffer.h.
{
const char *regex = va_arg(ap, char *);
SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
- SilcBufferStruct match, saved;
+ SilcBufferStruct match;
SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
SilcBool ret;
- SilcUInt32 inclusive_pos = 0;
+ SilcUInt32 saved_pos = 0, inclusive_pos = 0;
int matched = 0, ret_len;
va_list cp;
if (!regex)
goto fail;
- memset(&saved, 0, sizeof(saved));
-
if (match_nl) {
start_nl_match:
/* Match for '\n' in the buffer. If not found, treat as line
without '\n' (buffer has only one line, or this is last line). */
- saved = *dst;
+ saved_pos = silc_buffer_headlen(dst) + silc_buffer_len(dst);
if (silc_regex_buffer(dst, "\n", &match, NULL))
dst->tail = match.tail;
}
flen += (dst->tail - dst->data);
if (!silc_buffer_pull(dst, (dst->tail - dst->data)))
goto fail;
- if (!silc_buffer_pull_tail(dst, (saved.tail - dst->tail)))
+ if (!silc_buffer_pull_tail(dst, (saved_pos -
+ silc_buffer_headlen(dst) +
+ silc_buffer_len(dst))))
goto fail;
if (silc_buffer_len(dst) > 0)
}
break;
+ case SILC_PARAM_DELETE:
+ {
+ int n = va_arg(ap, int);
+
+ if (!process)
+ break;
+
+ if (n == -1) {
+ /* Move all data from tail to data area */
+ if (dst->data != dst->tail) {
+ memmove(dst->data, dst->tail, silc_buffer_taillen(dst));
+ memset(dst->end - silc_buffer_len(dst), 0, silc_buffer_len(dst));
+ silc_buffer_push_tail(dst, silc_buffer_len(dst));
+ }
+ break;
+ }
+
+ if (n > silc_buffer_len(dst))
+ goto fail;
+
+ memmove(dst->data, dst->data + n, (silc_buffer_len(dst) - n) +
+ silc_buffer_taillen(dst));
+ memset(dst->end - n, 0, n);
+ silc_buffer_push_tail(dst, silc_buffer_len(dst) - n);
+
+ break;
+ }
+
case SILC_PARAM_OFFSET:
{
int offst = va_arg(ap, int);
{
const char *regex = va_arg(ap, char *);
SilcBufferRegexFlags rflags = va_arg(ap, SilcUInt32);
- SilcBufferStruct match, saved;
+ SilcBufferStruct match;
SilcBool match_all = (rflags & SILC_STR_REGEX_ALL) != 0;
SilcBool match_nl = (rflags & SILC_STR_REGEX_NL) != 0;
SilcBool ret;
- SilcUInt32 inclusive_pos = 0;
+ SilcUInt32 saved_pos = 0, inclusive_pos = 0;
int matched = 0, ret_len;
va_list cp;
if (!regex)
goto fail;
- memset(&saved, 0, sizeof(saved));
if (match_nl) {
start_nl_match:
/* Match for '\n' in the buffer. If not found, treat as line
without '\n' (buffer has only one line, or this is last line). */
- saved = *src;
+ saved_pos = silc_buffer_headlen(src) + silc_buffer_len(src);
if (silc_regex_buffer(src, "\n", &match, NULL))
src->tail = match.tail;
}
UNFORMAT_HAS_SPACE(src, src->tail - src->data);
if (!silc_buffer_pull(src, (src->tail - src->data)))
goto fail;
- if (!silc_buffer_pull_tail(src, (saved.tail - src->tail)))
+ if (!silc_buffer_pull_tail(src, (saved_pos -
+ silc_buffer_headlen(src) +
+ silc_buffer_len(src))))
goto fail;
if (silc_buffer_len(src) > 0)
goto ok;
break;
+ case SILC_PARAM_DELETE:
+ break;
+
default:
SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not "
"format the data.", fmt));
*
* // 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.
+ * // must be 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 's/foo/B/', replace foo with B, deleting rest of the match from
+ * // the buffer. The match must be inclusive to make deleting work.
+ * silc_buffer_format(buffer,
+ * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL |
+ * SILC_STR_REGEX_INCLUSIVE),
+ * SILC_STR_STRING("B"),
+ * SILC_STR_DELETE(-1),
+ * 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),
***/
#define SILC_STR_REGEX(regex, flags) SILC_PARAM_REGEX, (regex), (flags)
+/****d* silcutil/SilcBufferFormatAPI/SILC_STR_DELETE
+ *
+ * NAME
+ *
+ * #define SILC_STR_DELETE(n) ...
+ *
+ * DESCRIPTION
+ *
+ * Deletes bytes from the buffer by moving data in order to delete it.
+ * The size of the buffer remains same but the tail area of the buffer
+ * will get larger as data is deleted from the current data area.
+ *
+ * The `n' specifies the number of bytes to delete from the current
+ * data area. If `n' is -1 this deletes all bytes from the data area.
+ * This effectively moves the data from the tail area into the current
+ * data area. The length of the data area after this is 0 and the tail
+ * area is larger.
+ *
+ * Use this only for formatting.
+ *
+ * Formatting: SILC_STR_DELETE(int bytes)
+ *
+ * EXAMPLE
+ *
+ * // sed 's/foo/B/', replace foo with B, deleting rest of the match from
+ * // the buffer. The match must be inclusive to make deleting work.
+ * silc_buffer_format(buffer,
+ * SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL |
+ * SILC_STR_REGEX_INCLUSIVE),
+ * SILC_STR_STRING("B"),
+ * SILC_STR_DELETE(-1),
+ * SILC_STR_END, SILC_STR_END);
+ *
+ ***/
+#define SILC_STR_DELETE(x) SILC_PARAM_DELETE, (x)
+
/****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET
*
* NAME
#define SILC_PARAM_END 0xfeeefff1 /* End of parameters */
/***/
-/* Internal parameter types, not publicly documented */
+/* Internal parameter types, not publicly documented, used mainly by the
+ SILC Buffer Format API (silcbuffmt.h). */
#define SILC_PARAM_UI8_STRING 100 /* String (max len 8-bits) */
#define SILC_PARAM_UI16_STRING 101 /* String (max len 16-bits) */
#define SILC_PARAM_UI32_STRING 102 /* String (max len 32-bits) */
#define SILC_PARAM_OFFSET_START 110
#define SILC_PARAM_OFFSET_END 111
#define SILC_PARAM_APPEND 112
+#define SILC_PARAM_DELETE 113
#define SILC_PARAM_ALLOC 0x00010000 /* Allocate, bitmask */
/* Macros */
{
SilcBool success = FALSE;
char string[1024], *astring;
- SilcBufferStruct buf, buf2;
+ SilcBufferStruct buf;
if (argc > 1 && !strcmp(argv[1], "-d")) {
silc_log_debug(TRUE);
goto err;
silc_buffer_purge(&buf);
+ silc_snprintf(string, sizeof(string), "This is foobar string foo!!");
+ astring = silc_memdup(string, strlen(string));
+ silc_buffer_set(&buf, astring, strlen(astring) + 1);
+ SILC_LOG_DEBUG(("sed 's/foo//g'"));
+ SILC_LOG_DEBUG(("string: %s", astring));
+ if (silc_buffer_format(&buf,
+ SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL |
+ SILC_STR_REGEX_INCLUSIVE),
+ SILC_STR_DELETE(-1),
+ SILC_STR_END,
+ SILC_STR_END) < 0)
+ goto err;
+ silc_buffer_printf(&buf, TRUE);
+ if (strcmp("This is bar string !!", silc_buffer_data(&buf)))
+ goto err;
+ silc_buffer_purge(&buf);
+
silc_snprintf(string, sizeof(string), "This is foobar\n");
silc_buffer_set(&buf, string, strlen(string));
SILC_LOG_DEBUG(("sed 's/\\n/\\0/'"));