notmuch/lib/message-id.c
David Bremner f7130468d2 Import notmuch_0.28.2.orig.tar.gz
[dgit import orig notmuch_0.28.2.orig.tar.gz]
2019-02-17 07:30:33 -04:00

126 lines
2.3 KiB
C

#include "notmuch-private.h"
#include "string-util.h"
/* Advance 'str' past any whitespace or RFC 822 comments. A comment is
* a (potentially nested) parenthesized sequence with '\' used to
* escape any character (including parentheses).
*
* If the sequence to be skipped continues to the end of the string,
* then 'str' will be left pointing at the final terminating '\0'
* character.
*/
static void
skip_space_and_comments (const char **str)
{
const char *s;
s = *str;
while (*s && (isspace (*s) || *s == '(')) {
while (*s && isspace (*s))
s++;
if (*s == '(') {
int nesting = 1;
s++;
while (*s && nesting) {
if (*s == '(') {
nesting++;
} else if (*s == ')') {
nesting--;
} else if (*s == '\\') {
if (*(s+1))
s++;
}
s++;
}
}
}
*str = s;
}
char *
_notmuch_message_id_parse (void *ctx, const char *message_id, const char **next)
{
const char *s, *end;
char *result;
if (message_id == NULL || *message_id == '\0')
return NULL;
s = message_id;
skip_space_and_comments (&s);
/* Skip any unstructured text as well. */
while (*s && *s != '<')
s++;
if (*s == '<') {
s++;
} else {
if (next)
*next = s;
return NULL;
}
skip_space_and_comments (&s);
end = s;
while (*end && *end != '>')
end++;
if (next) {
if (*end)
*next = end + 1;
else
*next = end;
}
if (end > s && *end == '>')
end--;
if (end <= s)
return NULL;
result = talloc_strndup (ctx, s, end - s + 1);
/* Finally, collapse any whitespace that is within the message-id
* itself. */
{
char *r;
int len;
for (r = result, len = strlen (r); *r; r++, len--)
if (*r == ' ' || *r == '\t')
memmove (r, r+1, len);
}
return result;
}
char *
_notmuch_message_id_parse_strict (void *ctx, const char *message_id)
{
const char *s, *end;
if (message_id == NULL || *message_id == '\0')
return NULL;
s = skip_space (message_id);
if (*s == '<')
s++;
else
return NULL;
for (end = s; *end && *end != '>'; end++)
if (isspace (*end))
return NULL;
if (*end != '>')
return NULL;
else {
const char *last = skip_space (end + 1);
if (*last != '\0')
return NULL;
}
return talloc_strndup (ctx, s, end - s);
}