@@ -1346,11 +1346,13 @@ def enable_data
1346
1346
end
1347
1347
1348
1348
# As a workaround for buggy servers, allow a trailing SP:
1349
- # *(SP capapility ) [SP]
1349
+ # *(SP capability ) [SP]
1350
1350
def capability__list
1351
- data = [ ] ; while _ = SP? && capability? do data << _ end ; data
1351
+ list = [ ] ; while SP? && ( capa = capability? ) do list << capa end ; list
1352
1352
end
1353
1353
1354
+ alias resp_code__capability capability__list
1355
+
1354
1356
# capability = ("AUTH=" auth-type) / atom
1355
1357
# ; New capabilities MUST begin with "X" or be
1356
1358
# ; registered with IANA as standard or
@@ -1473,68 +1475,91 @@ def resp_text
1473
1475
end
1474
1476
end
1475
1477
1476
- # See https://www.rfc-editor.org/errata/rfc3501
1478
+ # RFC3501 (See https://www.rfc-editor.org/errata/rfc3501):
1479
+ # resp-text-code = "ALERT" /
1480
+ # "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
1481
+ # capability-data / "PARSE" /
1482
+ # "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
1483
+ # "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1484
+ # "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1485
+ # "UNSEEN" SP nz-number /
1486
+ # atom [SP 1*<any TEXT-CHAR except "]">]
1487
+ # capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1"
1488
+ # *(SP capability)
1489
+ #
1490
+ # RFC5530:
1491
+ # resp-text-code =/ "UNAVAILABLE" / "AUTHENTICATIONFAILED" /
1492
+ # "AUTHORIZATIONFAILED" / "EXPIRED" /
1493
+ # "PRIVACYREQUIRED" / "CONTACTADMIN" / "NOPERM" /
1494
+ # "INUSE" / "EXPUNGEISSUED" / "CORRUPTION" /
1495
+ # "SERVERBUG" / "CLIENTBUG" / "CANNOT" /
1496
+ # "LIMIT" / "OVERQUOTA" / "ALREADYEXISTS" /
1497
+ # "NONEXISTENT"
1498
+ # RFC9051:
1499
+ # resp-text-code = "ALERT" /
1500
+ # "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
1501
+ # capability-data / "PARSE" /
1502
+ # "PERMANENTFLAGS" SP "(" [flag-perm *(SP flag-perm)] ")" /
1503
+ # "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1504
+ # "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1505
+ # resp-code-apnd / resp-code-copy / "UIDNOTSTICKY" /
1506
+ # "UNAVAILABLE" / "AUTHENTICATIONFAILED" /
1507
+ # "AUTHORIZATIONFAILED" / "EXPIRED" /
1508
+ # "PRIVACYREQUIRED" / "CONTACTADMIN" / "NOPERM" /
1509
+ # "INUSE" / "EXPUNGEISSUED" / "CORRUPTION" /
1510
+ # "SERVERBUG" / "CLIENTBUG" / "CANNOT" /
1511
+ # "LIMIT" / "OVERQUOTA" / "ALREADYEXISTS" /
1512
+ # "NONEXISTENT" / "NOTSAVED" / "HASCHILDREN" /
1513
+ # "CLOSED" /
1514
+ # "UNKNOWN-CTE" /
1515
+ # atom [SP 1*<any TEXT-CHAR except "]">]
1516
+ # capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev2"
1517
+ # *(SP capability)
1477
1518
#
1478
- # resp-text-code = "ALERT" /
1479
- # "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
1480
- # capability-data / "PARSE" /
1481
- # "PERMANENTFLAGS" SP "("
1482
- # [flag-perm *(SP flag-perm)] ")" /
1483
- # "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
1484
- # "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
1485
- # "UNSEEN" SP nz-number /
1486
- # atom [SP 1*<any TEXT-CHAR except "]">]
1519
+ # RFC4315 (UIDPLUS), RFC9051 (IMAP4rev2):
1520
+ # resp-code-apnd = "APPENDUID" SP nz-number SP append-uid
1521
+ # resp-code-copy = "COPYUID" SP nz-number SP uid-set SP uid-set
1522
+ # resp-text-code =/ resp-code-apnd / resp-code-copy / "UIDNOTSTICKY"
1487
1523
#
1488
- # +UIDPLUS+ ABNF:: https://www.rfc-editor.org/rfc/rfc4315.html#section-4
1489
- # resp-text-code =/ resp-code-apnd / resp-code-copy / "UIDNOTSTICKY"
1524
+ # RFC7162 (CONDSTORE):
1525
+ # resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value /
1526
+ # "NOMODSEQ" /
1527
+ # "MODIFIED" SP sequence-set
1490
1528
def resp_text_code
1491
- token = match ( T_ATOM )
1492
- name = token . value . upcase
1493
- case name
1494
- when /\A (?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\z /n
1495
- result = ResponseCode . new ( name , nil )
1496
- when /\A (?:BADCHARSET)\z /n
1497
- result = ResponseCode . new ( name , charset_list )
1498
- when /\A (?:CAPABILITY)\z /ni
1499
- result = ResponseCode . new ( name , capability__list )
1500
- when /\A (?:PERMANENTFLAGS)\z /n
1501
- match ( T_SPACE )
1502
- result = ResponseCode . new ( name , flag_list )
1503
- when /\A (?:UIDVALIDITY|UIDNEXT|UNSEEN)\z /n
1504
- match ( T_SPACE )
1505
- result = ResponseCode . new ( name , number )
1506
- when /\A (?:APPENDUID)\z /n
1507
- result = ResponseCode . new ( name , resp_code_apnd__data )
1508
- when /\A (?:COPYUID)\z /n
1509
- result = ResponseCode . new ( name , resp_code_copy__data )
1510
- else
1511
- token = lookahead
1512
- if token . symbol == T_SPACE
1513
- shift_token
1514
- result = ResponseCode . new ( name , text_chars_except_rbra )
1529
+ name = resp_text_code__name
1530
+ data =
1531
+ case name
1532
+ when "CAPABILITY" then resp_code__capability
1533
+ when "PERMANENTFLAGS" then SP? ? flag_perm__list : [ ]
1534
+ when "UIDNEXT" then SP! ; nz_number
1535
+ when "UIDVALIDITY" then SP! ; nz_number
1536
+ when "UNSEEN" then SP! ; nz_number # rev1 only
1537
+ when "APPENDUID" then SP! ; resp_code_apnd__data # rev2, UIDPLUS
1538
+ when "COPYUID" then SP! ; resp_code_copy__data # rev2, UIDPLUS
1539
+ when "BADCHARSET" then SP? ? charset__list : [ ]
1540
+ when "ALERT" , "PARSE" , "READ-ONLY" , "READ-WRITE" , "TRYCREATE" ,
1541
+ "UNAVAILABLE" , "AUTHENTICATIONFAILED" , "AUTHORIZATIONFAILED" ,
1542
+ "EXPIRED" , "PRIVACYREQUIRED" , "CONTACTADMIN" , "NOPERM" , "INUSE" ,
1543
+ "EXPUNGEISSUED" , "CORRUPTION" , "SERVERBUG" , "CLIENTBUG" , "CANNOT" ,
1544
+ "LIMIT" , "OVERQUOTA" , "ALREADYEXISTS" , "NONEXISTENT" , "CLOSED" ,
1545
+ "NOTSAVED" , "UIDNOTSTICKY" , "UNKNOWN-CTE" , "HASCHILDREN"
1546
+ when "NOMODSEQ" # CONDSTORE
1515
1547
else
1516
- result = ResponseCode . new ( name , nil )
1548
+ SP? and text_chars_except_rbra
1517
1549
end
1518
- end
1519
- return result
1550
+ ResponseCode . new ( name , data )
1520
1551
end
1521
1552
1553
+ alias resp_text_code__name case_insensitive__atom
1554
+
1522
1555
# 1*<any TEXT-CHAR except "]">
1523
1556
def text_chars_except_rbra
1524
1557
match_re ( CTEXT_REGEXP , '1*<any TEXT-CHAR except "]">' ) [ 0 ]
1525
1558
end
1526
1559
1527
- def charset_list
1528
- result = [ ]
1529
- if accept ( T_SPACE )
1530
- match ( T_LPAR )
1531
- result << charset
1532
- while accept ( T_SPACE )
1533
- result << charset
1534
- end
1535
- match ( T_RPAR )
1536
- end
1537
- result
1560
+ # "(" charset *(SP charset) ")"
1561
+ def charset__list
1562
+ lpar ; list = [ charset ] ; while SP? do list << charset end ; rpar ; list
1538
1563
end
1539
1564
1540
1565
# already matched: "APPENDUID"
@@ -1550,18 +1575,18 @@ def charset_list
1550
1575
# match uid_set even if that returns a single-member array.
1551
1576
#
1552
1577
def resp_code_apnd__data
1553
- match ( T_SPACE ) ; validity = number
1554
- match ( T_SPACE ) ; dst_uids = uid_set # uniqueid ⊂ uid-set
1578
+ validity = number ; SP!
1579
+ dst_uids = uid_set # uniqueid ⊂ uid-set
1555
1580
UIDPlusData . new ( validity , nil , dst_uids )
1556
1581
end
1557
1582
1558
1583
# already matched: "COPYUID"
1559
1584
#
1560
1585
# resp-code-copy = "COPYUID" SP nz-number SP uid-set SP uid-set
1561
1586
def resp_code_copy__data
1562
- match ( T_SPACE ) ; validity = number
1563
- match ( T_SPACE ) ; src_uids = uid_set
1564
- match ( T_SPACE ) ; dst_uids = uid_set
1587
+ validity = number ; SP!
1588
+ src_uids = uid_set ; SP!
1589
+ dst_uids = uid_set
1565
1590
UIDPlusData . new ( validity , src_uids , dst_uids )
1566
1591
end
1567
1592
@@ -1639,17 +1664,13 @@ def flag_list
1639
1664
end
1640
1665
end
1641
1666
1667
+ # TODO: not quite correct. flag-perm != flag
1668
+ alias flag_perm__list flag_list
1642
1669
1643
1670
# See https://www.rfc-editor.org/errata/rfc3501
1644
1671
#
1645
1672
# charset = atom / quoted
1646
- def charset
1647
- if token = accept ( T_QUOTED )
1648
- token . value
1649
- else
1650
- atom
1651
- end
1652
- end
1673
+ def charset ; quoted? || atom end
1653
1674
1654
1675
# RFC7162:
1655
1676
# mod-sequence-value = 1*DIGIT
0 commit comments