Commit d7dec968 d7dec96841e872ffa6924d6c5f93a1be473bf8ff by Sergey Poznyakoff

Fix MH sequence parser.

* mh/mh_msgset.c (parse_range): Fix resolving non-existing UIDs.
* mh/tests/mhseq.at: Add more test cases.
1 parent ae06384d
......@@ -98,7 +98,6 @@ mh_msgset_single_message (mu_msgset_t msgset)
}
return r->msg_beg == r->msg_end;
}
struct msgset_parser
{
......@@ -466,22 +465,42 @@ parse_range (struct msgset_parser *parser)
return 0;
if (!validuid)
{
size_t total, lastuid;
msgset_last (parser->msgset->mbox, &total);
mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
total, &lastuid);
if (start > lastuid)
if (parser->sign)
{
if (!parser->sign)
emptyrange_abort (parser->argv[-1]);
start = total;
while (1)
{
if (--start == 0)
emptyrange_abort (parser->argv[-1]);
if (mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_UID_TO_MSGNO,
start, &start) == 0)
break;
}
}
else
{
if (parser->sign)
size_t total, lastuid;
msgset_last (parser->msgset->mbox, &total);
mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
total, &lastuid);
if (start > lastuid)
emptyrange_abort (parser->argv[-1]);
start = 1;
else
while (1)
{
if (start == lastuid)
{
start = total;
break;
}
++start;
if (mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_UID_TO_MSGNO,
start, &start) == 0)
break;
}
}
}
add_messages (parser, start, parser->number, parser->sign);
......@@ -489,47 +508,92 @@ parse_range (struct msgset_parser *parser)
}
else if (*parser->curp == '-')
{
size_t lastuid = 0;
int validuid = parser->validuid;
int rc;
parser->curp++;
if (parse_term (parser, 0) == PARSE_EOF)
return 0;
if (!parser->validuid)
/* If any of UIDs does not exist, try to find the nearest
existing one: */
if (!validuid || !parser->validuid)
{
size_t total;
size_t lastuid, num, maxnum;
msgset_last (parser->msgset->mbox, &total);
/* Order the limits */
if (!parser->validuid)
maxnum = parser->number;
else
mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
parser->number, &maxnum);
if (!validuid)
num = start;
else
mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
start, &num);
if (num > maxnum)
{
int v;
size_t n;
n = parser->number;
v = parser->validuid;
parser->number = start;
parser->validuid = validuid;
start = n;
validuid = v;
}
/* Adjust upper bound */
msgset_last (parser->msgset->mbox, &num);
mu_mailbox_translate (parser->msgset->mbox, MU_MAILBOX_MSGNO_TO_UID,
total, &lastuid);
num, &lastuid);
if (parser->number > lastuid)
parser->number = total;
else if (!validuid)
emptyrange_abort (parser->argv[-1]);
}
if (!validuid)
{
if (!lastuid)
if (!parser->validuid && parser->number > lastuid)
{
size_t total;
msgset_last (parser->msgset->mbox, &total);
mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_MSGNO_TO_UID,
total, &lastuid);
parser->number = num;
parser->validuid = 1;
}
if (start > lastuid && !parser->validuid)
emptyrange_abort (parser->argv[-1]);
start = 1;
}
rc = mu_msgset_add_range (parser->msgset, start, parser->number,
MU_MSGSET_NUM);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc);
exit (1);
/* Shift the bounds towards each other until they resolve to
existing UIDs or clash */
do
{
if (!validuid)
{
++start;
if (start > lastuid)
emptyrange_abort (parser->argv[-1]);
rc = mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_UID_TO_MSGNO,
start, &start);
if (rc == 0)
validuid = 1;
}
if (!parser->validuid)
{
if (parser->number == 1)
emptyrange_abort (parser->argv[-1]);
--parser->number;
rc = mu_mailbox_translate (parser->msgset->mbox,
MU_MAILBOX_UID_TO_MSGNO,
parser->number, &num);
if (rc == 0)
{
lastuid = parser->number;
parser->number = num;
parser->validuid = 1;
}
}
}
while (!validuid || !parser->validuid);
}
mu_msgset_add_range (parser->msgset, start, parser->number,
MU_MSGSET_NUM);
}
else if (!parser->validuid)
{
......
......@@ -406,5 +406,119 @@ mhseq last:2
5
])
MH_CHECK([mhseq: sparse increasing message range (left fixup in the middle)],
[mhseq34],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 5-15
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse increasing message range (right fixup in the middle)],
[mhseq35],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 8-17
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse increasing message range (both fixups in the middle)],
[mhseq36],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 5-17
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse decreasing message range (left fixup in the middle)],
[mhseq37],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 15-5
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse decreasing message range (right fixup in the middle)],
[mhseq38],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 17-8
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse decreasing message range (both fixups in the middle)],
[mhseq39],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 17-5
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse counted range (positive, fixup)],
[mhseq40],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 3:2
],
[0],
[8
15
])
MH_CHECK([mhseq: sparse counted range (negative, fixup)],
[mhseq41],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
mv Mail/inbox/5 Mail/inbox/20
mv Mail/inbox/4 Mail/inbox/15
mv Mail/inbox/3 Mail/inbox/8
MUT_MBCHMOD(Mail/inbox, 700)
mhseq 17:-3
],
[0],
[2
8
15
])
m4_popdef([MH_KEYWORDS])
# End of mhseq.at
\ No newline at end of file
......