Fix MH sequence parser.
* mh/mh_msgset.c (parse_range): Fix resolving non-existing UIDs. * mh/tests/mhseq.at: Add more test cases.
Showing
2 changed files
with
218 additions
and
40 deletions
... | @@ -98,7 +98,6 @@ mh_msgset_single_message (mu_msgset_t msgset) | ... | @@ -98,7 +98,6 @@ mh_msgset_single_message (mu_msgset_t msgset) |
98 | } | 98 | } |
99 | return r->msg_beg == r->msg_end; | 99 | return r->msg_beg == r->msg_end; |
100 | } | 100 | } |
101 | |||
102 | 101 | ||
103 | struct msgset_parser | 102 | struct msgset_parser |
104 | { | 103 | { |
... | @@ -466,22 +465,42 @@ parse_range (struct msgset_parser *parser) | ... | @@ -466,22 +465,42 @@ parse_range (struct msgset_parser *parser) |
466 | return 0; | 465 | return 0; |
467 | if (!validuid) | 466 | if (!validuid) |
468 | { | 467 | { |
469 | size_t total, lastuid; | 468 | if (parser->sign) |
470 | msgset_last (parser->msgset->mbox, &total); | ||
471 | mu_mailbox_translate (parser->msgset->mbox, | ||
472 | MU_MAILBOX_MSGNO_TO_UID, | ||
473 | total, &lastuid); | ||
474 | if (start > lastuid) | ||
475 | { | 469 | { |
476 | if (!parser->sign) | 470 | while (1) |
477 | emptyrange_abort (parser->argv[-1]); | 471 | { |
478 | start = total; | 472 | if (--start == 0) |
473 | emptyrange_abort (parser->argv[-1]); | ||
474 | if (mu_mailbox_translate (parser->msgset->mbox, | ||
475 | MU_MAILBOX_UID_TO_MSGNO, | ||
476 | start, &start) == 0) | ||
477 | break; | ||
478 | } | ||
479 | } | 479 | } |
480 | else | 480 | else |
481 | { | 481 | { |
482 | if (parser->sign) | 482 | size_t total, lastuid; |
483 | |||
484 | msgset_last (parser->msgset->mbox, &total); | ||
485 | mu_mailbox_translate (parser->msgset->mbox, | ||
486 | MU_MAILBOX_MSGNO_TO_UID, | ||
487 | total, &lastuid); | ||
488 | if (start > lastuid) | ||
483 | emptyrange_abort (parser->argv[-1]); | 489 | emptyrange_abort (parser->argv[-1]); |
484 | start = 1; | 490 | else |
491 | while (1) | ||
492 | { | ||
493 | if (start == lastuid) | ||
494 | { | ||
495 | start = total; | ||
496 | break; | ||
497 | } | ||
498 | ++start; | ||
499 | if (mu_mailbox_translate (parser->msgset->mbox, | ||
500 | MU_MAILBOX_UID_TO_MSGNO, | ||
501 | start, &start) == 0) | ||
502 | break; | ||
503 | } | ||
485 | } | 504 | } |
486 | } | 505 | } |
487 | add_messages (parser, start, parser->number, parser->sign); | 506 | add_messages (parser, start, parser->number, parser->sign); |
... | @@ -489,47 +508,92 @@ parse_range (struct msgset_parser *parser) | ... | @@ -489,47 +508,92 @@ parse_range (struct msgset_parser *parser) |
489 | } | 508 | } |
490 | else if (*parser->curp == '-') | 509 | else if (*parser->curp == '-') |
491 | { | 510 | { |
492 | size_t lastuid = 0; | ||
493 | int validuid = parser->validuid; | 511 | int validuid = parser->validuid; |
494 | int rc; | 512 | int rc; |
495 | 513 | ||
496 | parser->curp++; | 514 | parser->curp++; |
497 | if (parse_term (parser, 0) == PARSE_EOF) | 515 | if (parse_term (parser, 0) == PARSE_EOF) |
498 | return 0; | 516 | return 0; |
499 | if (!parser->validuid) | 517 | |
518 | /* If any of UIDs does not exist, try to find the nearest | ||
519 | existing one: */ | ||
520 | if (!validuid || !parser->validuid) | ||
500 | { | 521 | { |
501 | size_t total; | 522 | size_t lastuid, num, maxnum; |
502 | 523 | ||
503 | msgset_last (parser->msgset->mbox, &total); | 524 | /* Order the limits */ |
525 | if (!parser->validuid) | ||
526 | maxnum = parser->number; | ||
527 | else | ||
528 | mu_mailbox_translate (parser->msgset->mbox, | ||
529 | MU_MAILBOX_MSGNO_TO_UID, | ||
530 | parser->number, &maxnum); | ||
531 | if (!validuid) | ||
532 | num = start; | ||
533 | else | ||
534 | mu_mailbox_translate (parser->msgset->mbox, | ||
535 | MU_MAILBOX_MSGNO_TO_UID, | ||
536 | start, &num); | ||
537 | |||
538 | if (num > maxnum) | ||
539 | { | ||
540 | int v; | ||
541 | size_t n; | ||
542 | |||
543 | n = parser->number; | ||
544 | v = parser->validuid; | ||
545 | parser->number = start; | ||
546 | parser->validuid = validuid; | ||
547 | start = n; | ||
548 | validuid = v; | ||
549 | } | ||
550 | |||
551 | /* Adjust upper bound */ | ||
552 | msgset_last (parser->msgset->mbox, &num); | ||
504 | mu_mailbox_translate (parser->msgset->mbox, MU_MAILBOX_MSGNO_TO_UID, | 553 | mu_mailbox_translate (parser->msgset->mbox, MU_MAILBOX_MSGNO_TO_UID, |
505 | total, &lastuid); | 554 | num, &lastuid); |
506 | 555 | ||
507 | if (parser->number > lastuid) | 556 | if (!parser->validuid && parser->number > lastuid) |
508 | parser->number = total; | ||
509 | else if (!validuid) | ||
510 | emptyrange_abort (parser->argv[-1]); | ||
511 | } | ||
512 | if (!validuid) | ||
513 | { | ||
514 | if (!lastuid) | ||
515 | { | 557 | { |
516 | size_t total; | 558 | parser->number = num; |
517 | msgset_last (parser->msgset->mbox, &total); | 559 | parser->validuid = 1; |
518 | mu_mailbox_translate (parser->msgset->mbox, | ||
519 | MU_MAILBOX_MSGNO_TO_UID, | ||
520 | total, &lastuid); | ||
521 | } | 560 | } |
522 | if (start > lastuid && !parser->validuid) | 561 | |
523 | emptyrange_abort (parser->argv[-1]); | 562 | /* Shift the bounds towards each other until they resolve to |
524 | start = 1; | 563 | existing UIDs or clash */ |
525 | } | 564 | do |
526 | rc = mu_msgset_add_range (parser->msgset, start, parser->number, | 565 | { |
527 | MU_MSGSET_NUM); | 566 | if (!validuid) |
528 | if (rc) | 567 | { |
529 | { | 568 | ++start; |
530 | mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc); | 569 | if (start > lastuid) |
531 | exit (1); | 570 | emptyrange_abort (parser->argv[-1]); |
571 | rc = mu_mailbox_translate (parser->msgset->mbox, | ||
572 | MU_MAILBOX_UID_TO_MSGNO, | ||
573 | start, &start); | ||
574 | if (rc == 0) | ||
575 | validuid = 1; | ||
576 | } | ||
577 | if (!parser->validuid) | ||
578 | { | ||
579 | if (parser->number == 1) | ||
580 | emptyrange_abort (parser->argv[-1]); | ||
581 | --parser->number; | ||
582 | rc = mu_mailbox_translate (parser->msgset->mbox, | ||
583 | MU_MAILBOX_UID_TO_MSGNO, | ||
584 | parser->number, &num); | ||
585 | if (rc == 0) | ||
586 | { | ||
587 | lastuid = parser->number; | ||
588 | parser->number = num; | ||
589 | parser->validuid = 1; | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | while (!validuid || !parser->validuid); | ||
532 | } | 594 | } |
595 | mu_msgset_add_range (parser->msgset, start, parser->number, | ||
596 | MU_MSGSET_NUM); | ||
533 | } | 597 | } |
534 | else if (!parser->validuid) | 598 | else if (!parser->validuid) |
535 | { | 599 | { | ... | ... |
... | @@ -406,5 +406,119 @@ mhseq last:2 | ... | @@ -406,5 +406,119 @@ mhseq last:2 |
406 | 5 | 406 | 5 |
407 | ]) | 407 | ]) |
408 | 408 | ||
409 | MH_CHECK([mhseq: sparse increasing message range (left fixup in the middle)], | ||
410 | [mhseq34],[ | ||
411 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
412 | mv Mail/inbox/5 Mail/inbox/20 | ||
413 | mv Mail/inbox/4 Mail/inbox/15 | ||
414 | mv Mail/inbox/3 Mail/inbox/8 | ||
415 | MUT_MBCHMOD(Mail/inbox, 700) | ||
416 | mhseq 5-15 | ||
417 | ], | ||
418 | [0], | ||
419 | [8 | ||
420 | 15 | ||
421 | ]) | ||
422 | |||
423 | MH_CHECK([mhseq: sparse increasing message range (right fixup in the middle)], | ||
424 | [mhseq35],[ | ||
425 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
426 | mv Mail/inbox/5 Mail/inbox/20 | ||
427 | mv Mail/inbox/4 Mail/inbox/15 | ||
428 | mv Mail/inbox/3 Mail/inbox/8 | ||
429 | MUT_MBCHMOD(Mail/inbox, 700) | ||
430 | mhseq 8-17 | ||
431 | ], | ||
432 | [0], | ||
433 | [8 | ||
434 | 15 | ||
435 | ]) | ||
436 | |||
437 | MH_CHECK([mhseq: sparse increasing message range (both fixups in the middle)], | ||
438 | [mhseq36],[ | ||
439 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
440 | mv Mail/inbox/5 Mail/inbox/20 | ||
441 | mv Mail/inbox/4 Mail/inbox/15 | ||
442 | mv Mail/inbox/3 Mail/inbox/8 | ||
443 | MUT_MBCHMOD(Mail/inbox, 700) | ||
444 | mhseq 5-17 | ||
445 | ], | ||
446 | [0], | ||
447 | [8 | ||
448 | 15 | ||
449 | ]) | ||
450 | |||
451 | MH_CHECK([mhseq: sparse decreasing message range (left fixup in the middle)], | ||
452 | [mhseq37],[ | ||
453 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
454 | mv Mail/inbox/5 Mail/inbox/20 | ||
455 | mv Mail/inbox/4 Mail/inbox/15 | ||
456 | mv Mail/inbox/3 Mail/inbox/8 | ||
457 | MUT_MBCHMOD(Mail/inbox, 700) | ||
458 | mhseq 15-5 | ||
459 | ], | ||
460 | [0], | ||
461 | [8 | ||
462 | 15 | ||
463 | ]) | ||
464 | |||
465 | MH_CHECK([mhseq: sparse decreasing message range (right fixup in the middle)], | ||
466 | [mhseq38],[ | ||
467 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
468 | mv Mail/inbox/5 Mail/inbox/20 | ||
469 | mv Mail/inbox/4 Mail/inbox/15 | ||
470 | mv Mail/inbox/3 Mail/inbox/8 | ||
471 | MUT_MBCHMOD(Mail/inbox, 700) | ||
472 | mhseq 17-8 | ||
473 | ], | ||
474 | [0], | ||
475 | [8 | ||
476 | 15 | ||
477 | ]) | ||
478 | |||
479 | MH_CHECK([mhseq: sparse decreasing message range (both fixups in the middle)], | ||
480 | [mhseq39],[ | ||
481 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
482 | mv Mail/inbox/5 Mail/inbox/20 | ||
483 | mv Mail/inbox/4 Mail/inbox/15 | ||
484 | mv Mail/inbox/3 Mail/inbox/8 | ||
485 | MUT_MBCHMOD(Mail/inbox, 700) | ||
486 | mhseq 17-5 | ||
487 | ], | ||
488 | [0], | ||
489 | [8 | ||
490 | 15 | ||
491 | ]) | ||
492 | |||
493 | MH_CHECK([mhseq: sparse counted range (positive, fixup)], | ||
494 | [mhseq40],[ | ||
495 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
496 | mv Mail/inbox/5 Mail/inbox/20 | ||
497 | mv Mail/inbox/4 Mail/inbox/15 | ||
498 | mv Mail/inbox/3 Mail/inbox/8 | ||
499 | MUT_MBCHMOD(Mail/inbox, 700) | ||
500 | mhseq 3:2 | ||
501 | ], | ||
502 | [0], | ||
503 | [8 | ||
504 | 15 | ||
505 | ]) | ||
506 | |||
507 | MH_CHECK([mhseq: sparse counted range (negative, fixup)], | ||
508 | [mhseq41],[ | ||
509 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
510 | mv Mail/inbox/5 Mail/inbox/20 | ||
511 | mv Mail/inbox/4 Mail/inbox/15 | ||
512 | mv Mail/inbox/3 Mail/inbox/8 | ||
513 | MUT_MBCHMOD(Mail/inbox, 700) | ||
514 | mhseq 17:-3 | ||
515 | ], | ||
516 | [0], | ||
517 | [2 | ||
518 | 8 | ||
519 | 15 | ||
520 | ]) | ||
521 | |||
522 | |||
409 | m4_popdef([MH_KEYWORDS]) | 523 | m4_popdef([MH_KEYWORDS]) |
410 | # End of mhseq.at | 524 | # End of mhseq.at |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment