/[suikacvs]/markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src
Suika

Diff of /markup/html/whatpm/Whatpm/HTML/Tokenizer.pm.src

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.14 by wakaba, Fri Oct 17 07:14:29 2008 UTC revision 1.18 by wakaba, Sun Oct 19 06:14:57 2008 UTC
# Line 164  sub BEFORE_MD_NAME_STATE () { 68 } Line 164  sub BEFORE_MD_NAME_STATE () { 68 }
164  sub MD_NAME_STATE () { 69 }  sub MD_NAME_STATE () { 69 }
165  sub DOCTYPE_ENTITY_PARAMETER_BEFORE_STATE () { 70 }  sub DOCTYPE_ENTITY_PARAMETER_BEFORE_STATE () { 70 }
166  sub DOCTYPE_ATTLIST_NAME_AFTER_STATE () { 71 }  sub DOCTYPE_ATTLIST_NAME_AFTER_STATE () { 71 }
167    sub DOCTYPE_ATTLIST_ATTRIBUTE_NAME_STATE () { 72 }
168    sub DOCTYPE_ATTLIST_ATTRIBUTE_NAME_AFTER_STATE () { 73 }
169    sub DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_STATE () { 74 }
170    sub DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_AFTER_STATE () { 75 }
171    sub BEFORE_ALLOWED_TOKEN_STATE () { 76 }
172    sub ALLOWED_TOKEN_STATE () { 77 }
173    sub AFTER_ALLOWED_TOKEN_STATE () { 78 }
174    sub AFTER_ALLOWED_TOKENS_STATE () { 79 }
175    sub BEFORE_ATTR_DEFAULT_STATE () { 80 }
176    sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE () { 81 }
177    sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE () { 82 }
178    sub DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE () { 83 }
179    sub AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE () { 84 }
180    sub BEFORE_NDATA_STATE () { 85 }
181    sub NDATA_STATE () { 86 }
182    sub AFTER_NDATA_STATE () { 87 }
183    sub BEFORE_NOTATION_NAME_STATE () { 88 }
184    sub NOTATION_NAME_STATE () { 89 }
185    sub AFTER_NOTATION_NAME_STATE () { 90 }
186    sub BOGUS_MD_STATE () { 91 }
187    
188  ## Tree constructor state constants (see Whatpm::HTML for the full  ## Tree constructor state constants (see Whatpm::HTML for the full
189  ## list and descriptions)  ## list and descriptions)
# Line 1257  sub _get_next_token ($) { Line 1277  sub _get_next_token ($) {
1277          redo A;          redo A;
1278        }        }
1279      } elsif ($self->{state} == ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE) {      } elsif ($self->{state} == ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE) {
1280        ## XML5: "Tag attribute value double quoted state".        ## XML5: "Tag attribute value double quoted state" and "DOCTYPE
1281          ## ATTLIST attribute value double quoted state".
1282                
1283        if ($self->{nc} == 0x0022) { # "        if ($self->{nc} == 0x0022) { # "
1284          !!!cp (95);          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
1285          ## XML5: "Tag attribute name before state".            !!!cp (95.1);
1286          $self->{state} = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;            ## XML5: "DOCTYPE ATTLIST name after state".
1287              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1288              $self->{state} = AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE;
1289            } else {
1290              !!!cp (95);
1291              ## XML5: "Tag attribute name before state".
1292              $self->{state} = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
1293            }
1294          !!!next-input-character;          !!!next-input-character;
1295          redo A;          redo A;
1296        } elsif ($self->{nc} == 0x0026) { # &        } elsif ($self->{nc} == 0x0026) { # &
# Line 1283  sub _get_next_token ($) { Line 1311  sub _get_next_token ($) {
1311          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
1312            !!!cp (97);            !!!cp (97);
1313            $self->{last_stag_name} = $self->{ct}->{tag_name};            $self->{last_stag_name} = $self->{ct}->{tag_name};
1314    
1315              $self->{state} = DATA_STATE;
1316              $self->{s_kwd} = '';
1317              ## reconsume
1318              !!!emit ($self->{ct}); # start tag
1319              redo A;
1320          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1321            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
1322            if ($self->{ct}->{attributes}) {            if ($self->{ct}->{attributes}) {
# Line 1292  sub _get_next_token ($) { Line 1326  sub _get_next_token ($) {
1326              ## NOTE: This state should never be reached.              ## NOTE: This state should never be reached.
1327              !!!cp (99);              !!!cp (99);
1328            }            }
1329    
1330              $self->{state} = DATA_STATE;
1331              $self->{s_kwd} = '';
1332              ## reconsume
1333              !!!emit ($self->{ct}); # end tag
1334              redo A;
1335            } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1336              ## XML5: No parse error above; not defined yet.
1337              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1338              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1339              ## Reconsume.
1340              !!!emit ($self->{ct}); # ATTLIST
1341              redo A;
1342          } else {          } else {
1343            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
1344          }          }
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
         ## reconsume  
   
         !!!emit ($self->{ct}); # start tag or end tag  
   
         redo A;  
1345        } else {        } else {
1346            ## XML5 [ATTLIST]: Not defined yet.
1347          if ($self->{is_xml} and $self->{nc} == 0x003C) { # <          if ($self->{is_xml} and $self->{nc} == 0x003C) { # <
1348            !!!cp (100);            !!!cp (100);
1349            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1320  sub _get_next_token ($) { Line 1361  sub _get_next_token ($) {
1361          redo A;          redo A;
1362        }        }
1363      } elsif ($self->{state} == ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE) {      } elsif ($self->{state} == ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE) {
1364        ## XML5: "Tag attribute value single quoted state".        ## XML5: "Tag attribute value single quoted state" and "DOCTYPE
1365          ## ATTLIST attribute value single quoted state".
1366    
1367        if ($self->{nc} == 0x0027) { # '        if ($self->{nc} == 0x0027) { # '
1368          !!!cp (101);          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
1369          ## XML5: "Before attribute name state" (sic).            !!!cp (101.1);
1370          $self->{state} = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;            ## XML5: "DOCTYPE ATTLIST name after state".
1371              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1372              $self->{state} = AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE;
1373            } else {
1374              !!!cp (101);
1375              ## XML5: "Before attribute name state" (sic).
1376              $self->{state} = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
1377            }
1378          !!!next-input-character;          !!!next-input-character;
1379          redo A;          redo A;
1380        } elsif ($self->{nc} == 0x0026) { # &        } elsif ($self->{nc} == 0x0026) { # &
# Line 1346  sub _get_next_token ($) { Line 1395  sub _get_next_token ($) {
1395          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
1396            !!!cp (103);            !!!cp (103);
1397            $self->{last_stag_name} = $self->{ct}->{tag_name};            $self->{last_stag_name} = $self->{ct}->{tag_name};
1398    
1399              $self->{state} = DATA_STATE;
1400              $self->{s_kwd} = '';
1401              ## reconsume
1402              !!!emit ($self->{ct}); # start tag
1403              redo A;
1404          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1405            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
1406            if ($self->{ct}->{attributes}) {            if ($self->{ct}->{attributes}) {
# Line 1355  sub _get_next_token ($) { Line 1410  sub _get_next_token ($) {
1410              ## NOTE: This state should never be reached.              ## NOTE: This state should never be reached.
1411              !!!cp (105);              !!!cp (105);
1412            }            }
1413    
1414              $self->{state} = DATA_STATE;
1415              $self->{s_kwd} = '';
1416              ## reconsume
1417              !!!emit ($self->{ct}); # end tag
1418              redo A;
1419            } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1420              ## XML5: No parse error above; not defined yet.
1421              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1422              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1423              ## Reconsume.
1424              !!!emit ($self->{ct}); # ATTLIST
1425              redo A;
1426          } else {          } else {
1427            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
1428          }          }
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
         ## reconsume  
   
         !!!emit ($self->{ct}); # start tag or end tag  
   
         redo A;  
1429        } else {        } else {
1430            ## XML5 [ATTLIST]: Not defined yet.
1431          if ($self->{is_xml} and $self->{nc} == 0x003C) { # <          if ($self->{is_xml} and $self->{nc} == 0x003C) { # <
1432            !!!cp (106);            !!!cp (106);
1433            ## XML5: Not a parse error.            ## XML5: Not a parse error.
# Line 1386  sub _get_next_token ($) { Line 1448  sub _get_next_token ($) {
1448        ## XML5: "Tag attribute value unquoted state".        ## XML5: "Tag attribute value unquoted state".
1449    
1450        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
1451          !!!cp (107);          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
1452          ## XML5: "Tag attribute name before state".            !!!cp (107.1);
1453          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;            push @{$self->{ct}->{attrdefs}}, $self->{ca};
1454              $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
1455            } else {
1456              !!!cp (107);
1457              ## XML5: "Tag attribute name before state".
1458              $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;
1459            }
1460          !!!next-input-character;          !!!next-input-character;
1461          redo A;          redo A;
1462        } elsif ($self->{nc} == 0x0026) { # &        } elsif ($self->{nc} == 0x0026) { # &
# Line 1409  sub _get_next_token ($) { Line 1477  sub _get_next_token ($) {
1477          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
1478            !!!cp (109);            !!!cp (109);
1479            $self->{last_stag_name} = $self->{ct}->{tag_name};            $self->{last_stag_name} = $self->{ct}->{tag_name};
1480    
1481              $self->{state} = DATA_STATE;
1482              $self->{s_kwd} = '';
1483              !!!next-input-character;
1484              !!!emit ($self->{ct}); # start tag
1485              redo A;
1486          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1487            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
1488            if ($self->{ct}->{attributes}) {            if ($self->{ct}->{attributes}) {
# Line 1418  sub _get_next_token ($) { Line 1492  sub _get_next_token ($) {
1492              ## NOTE: This state should never be reached.              ## NOTE: This state should never be reached.
1493              !!!cp (111);              !!!cp (111);
1494            }            }
1495    
1496              $self->{state} = DATA_STATE;
1497              $self->{s_kwd} = '';
1498              !!!next-input-character;
1499              !!!emit ($self->{ct}); # end tag
1500              redo A;
1501            } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1502              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1503              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1504              !!!next-input-character;
1505              !!!emit ($self->{ct}); # ATTLIST
1506              redo A;
1507          } else {          } else {
1508            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
1509          }          }
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
         !!!next-input-character;  
   
         !!!emit ($self->{ct}); # start tag or end tag  
   
         redo A;  
1510        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!parse-error (type => 'unclosed tag');  
1511          if ($self->{ct}->{type} == START_TAG_TOKEN) {          if ($self->{ct}->{type} == START_TAG_TOKEN) {
1512            !!!cp (112);            !!!cp (112);
1513              !!!parse-error (type => 'unclosed tag');
1514            $self->{last_stag_name} = $self->{ct}->{tag_name};            $self->{last_stag_name} = $self->{ct}->{tag_name};
1515    
1516              $self->{state} = DATA_STATE;
1517              $self->{s_kwd} = '';
1518              ## reconsume
1519              !!!emit ($self->{ct}); # start tag
1520              redo A;
1521          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {          } elsif ($self->{ct}->{type} == END_TAG_TOKEN) {
1522              !!!parse-error (type => 'unclosed tag');
1523            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
1524            if ($self->{ct}->{attributes}) {            if ($self->{ct}->{attributes}) {
1525              !!!cp (113);              !!!cp (113);
# Line 1442  sub _get_next_token ($) { Line 1528  sub _get_next_token ($) {
1528              ## NOTE: This state should never be reached.              ## NOTE: This state should never be reached.
1529              !!!cp (114);              !!!cp (114);
1530            }            }
1531    
1532              $self->{state} = DATA_STATE;
1533              $self->{s_kwd} = '';
1534              ## reconsume
1535              !!!emit ($self->{ct}); # end tag
1536              redo A;
1537            } elsif ($self->{ct}->{type} == ATTLIST_TOKEN) {
1538              !!!parse-error (type => 'unclosed md'); ## TODO: type
1539              push @{$self->{ct}->{attrdefs}}, $self->{ca};
1540              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
1541              ## Reconsume.
1542              !!!emit ($self->{ct}); # ATTLIST
1543              redo A;
1544          } else {          } else {
1545            die "$0: $self->{ct}->{type}: Unknown token type";            die "$0: $self->{ct}->{type}: Unknown token type";
1546          }          }
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
         ## reconsume  
   
         !!!emit ($self->{ct}); # start tag or end tag  
   
         redo A;  
1547        } else {        } else {
1548          if ({          if ({
1549               0x0022 => 1, # "               0x0022 => 1, # "
# Line 2127  sub _get_next_token ($) { Line 2219  sub _get_next_token ($) {
2219          !!!next-input-character;          !!!next-input-character;
2220          redo A;          redo A;
2221        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2222          !!!cp (166);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2223          $self->{state} = DATA_STATE;            !!!cp (166);
2224          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2225              $self->{s_kwd} = '';
2226            } else {
2227              !!!cp (166.1);
2228              !!!parse-error (type => 'no md def'); ## TODO: type
2229              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2230            }
2231            
2232          !!!next-input-character;          !!!next-input-character;
2233            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         !!!emit ($self->{ct}); # DOCTYPE  
   
2234          redo A;          redo A;
2235        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2236          !!!cp (167);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2237          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (167);
2238          $self->{state} = DATA_STATE;            !!!parse-error (type => 'unclosed DOCTYPE');
2239          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2240          ## reconsume            $self->{s_kwd} = '';
2241              $self->{ct}->{quirks} = 1;
2242          $self->{ct}->{quirks} = 1;          } else {
2243          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (167.12);
2244              !!!parse-error (type => 'unclosed md'); ## TODO: type
2245              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2246            }
2247            
2248            ## Reconsume.
2249            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2250          redo A;          redo A;
2251        } elsif ($self->{nc} == 0x0050 or # P        } elsif ($self->{nc} == 0x0050 or # P
2252                 $self->{nc} == 0x0070) { # p                 $self->{nc} == 0x0070) { # p
# Line 2160  sub _get_next_token ($) { Line 2262  sub _get_next_token ($) {
2262          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
2263          !!!next-input-character;          !!!next-input-character;
2264          redo A;          redo A;
2265        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [  ## TODO: " and ' for ENTITY
2266          } elsif ($self->{is_xml} and
2267                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2268                   $self->{nc} == 0x005B) { # [
2269          !!!cp (167.3);          !!!cp (167.3);
2270          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2271          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 2169  sub _get_next_token ($) { Line 2274  sub _get_next_token ($) {
2274          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2275          redo A;          redo A;
2276        } else {        } else {
2277          !!!cp (180);          !!!parse-error (type => 'string after DOCTYPE name'); ## TODO: type
2278          !!!parse-error (type => 'string after DOCTYPE name');  
2279          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2280              !!!cp (180);
2281              $self->{ct}->{quirks} = 1;
2282              $self->{state} = BOGUS_DOCTYPE_STATE;
2283            } else {
2284              !!!cp (180.1);
2285              $self->{state} = BOGUS_MD_STATE;
2286            }
2287    
         $self->{state} = BOGUS_DOCTYPE_STATE;  
2288          !!!next-input-character;          !!!next-input-character;
2289          redo A;          redo A;
2290        }        }
# Line 2215  sub _get_next_token ($) { Line 2326  sub _get_next_token ($) {
2326          !!!next-input-character;          !!!next-input-character;
2327          redo A;          redo A;
2328        } else {        } else {
2329          !!!cp (169);          !!!parse-error (type => 'string after DOCTYPE name', ## TODO: type
         !!!parse-error (type => 'string after DOCTYPE name',  
2330                          line => $self->{line_prev},                          line => $self->{line_prev},
2331                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
2332          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2333              !!!cp (169);
2334          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
2335              $self->{state} = BOGUS_DOCTYPE_STATE;
2336            } else {
2337              !!!cp (169.1);
2338              $self->{state} = BOGUS_MD_STATE;
2339            }
2340          ## Reconsume.          ## Reconsume.
2341          redo A;          redo A;
2342        }        }
# Line 2263  sub _get_next_token ($) { Line 2378  sub _get_next_token ($) {
2378          !!!next-input-character;          !!!next-input-character;
2379          redo A;          redo A;
2380        } else {        } else {
2381          !!!cp (172);          !!!parse-error (type => 'string after DOCTYPE name', ## TODO: type
         !!!parse-error (type => 'string after DOCTYPE name',  
2382                          line => $self->{line_prev},                          line => $self->{line_prev},
2383                          column => $self->{column_prev} + 1 - length $self->{kwd});                          column => $self->{column_prev} + 1 - length $self->{kwd});
2384          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2385              !!!cp (172);
2386          $self->{state} = BOGUS_DOCTYPE_STATE;            $self->{ct}->{quirks} = 1;
2387              $self->{state} = BOGUS_DOCTYPE_STATE;
2388            } else {
2389              !!!cp (172.1);
2390              $self->{state} = BOGUS_MD_STATE;
2391            }
2392          ## Reconsume.          ## Reconsume.
2393          redo A;          redo A;
2394        }        }
# Line 2292  sub _get_next_token ($) { Line 2411  sub _get_next_token ($) {
2411          !!!next-input-character;          !!!next-input-character;
2412          redo A;          redo A;
2413        } elsif ($self->{nc} eq 0x003E) { # >        } elsif ($self->{nc} eq 0x003E) { # >
         !!!cp (184);  
2414          !!!parse-error (type => 'no PUBLIC literal');          !!!parse-error (type => 'no PUBLIC literal');
2415            
2416          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2417          $self->{s_kwd} = '';            !!!cp (184);
2418              $self->{state} = DATA_STATE;
2419              $self->{s_kwd} = '';
2420              $self->{ct}->{quirks} = 1;
2421            } else {
2422              !!!cp (184.1);
2423              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2424            }
2425            
2426          !!!next-input-character;          !!!next-input-character;
2427            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2428          redo A;          redo A;
2429        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2430          !!!cp (185);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2431          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (185);
2432              !!!parse-error (type => 'unclosed DOCTYPE');
2433          $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2434          $self->{s_kwd} = '';            $self->{s_kwd} = '';
2435              $self->{ct}->{quirks} = 1;
2436            } else {
2437              !!!cp (185.1);
2438              !!!parse-error (type => 'unclosed md'); ## TODO: type
2439              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2440            }
2441            
2442          ## reconsume          ## reconsume
   
         $self->{ct}->{quirks} = 1;  
2443          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
   
2444          redo A;          redo A;
2445        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2446                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2447                   $self->{nc} == 0x005B) { # [
2448          !!!cp (186.1);          !!!cp (186.1);
2449          !!!parse-error (type => 'no PUBLIC literal');          !!!parse-error (type => 'no PUBLIC literal');
2450          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 2325  sub _get_next_token ($) { Line 2454  sub _get_next_token ($) {
2454          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2455          redo A;          redo A;
2456        } else {        } else {
         !!!cp (186);  
2457          !!!parse-error (type => 'string after PUBLIC');          !!!parse-error (type => 'string after PUBLIC');
         $self->{ct}->{quirks} = 1;  
2458    
2459          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2460              !!!cp (186);
2461              $self->{ct}->{quirks} = 1;
2462              $self->{state} = BOGUS_DOCTYPE_STATE;
2463            } else {
2464              !!!cp (186.2);
2465              $self->{state} = BOGUS_MD_STATE;
2466            }
2467    
2468          !!!next-input-character;          !!!next-input-character;
2469          redo A;          redo A;
2470        }        }
# Line 2340  sub _get_next_token ($) { Line 2475  sub _get_next_token ($) {
2475          !!!next-input-character;          !!!next-input-character;
2476          redo A;          redo A;
2477        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (188);  
2478          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2479    
2480          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2481          $self->{s_kwd} = '';            !!!cp (188);
2482          !!!next-input-character;            $self->{state} = DATA_STATE;
2483              $self->{s_kwd} = '';
2484          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2485          !!!emit ($self->{ct}); # DOCTYPE          } else {
2486              !!!cp (188.1);
2487              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2488            }
2489    
2490            !!!next-input-character;
2491            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2492          redo A;          redo A;
2493        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (189);  
2494          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2495    
2496          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2497          $self->{s_kwd} = '';            !!!cp (189);
2498          ## reconsume            $self->{state} = DATA_STATE;
2499              $self->{s_kwd} = '';
2500          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2501            } else {
2502              !!!cp (189.1);
2503              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2504            }
2505            
2506            ## Reconsume.
2507          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
   
2508          redo A;          redo A;
2509        } else {        } else {
2510          !!!cp (190);          !!!cp (190);
2511          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2512          $self->{read_until}->($self->{ct}->{pubid}, q[">],          $self->{read_until}->($self->{ct}->{pubid}, q[">],
2513                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
2514    
# Line 2381  sub _get_next_token ($) { Line 2523  sub _get_next_token ($) {
2523          !!!next-input-character;          !!!next-input-character;
2524          redo A;          redo A;
2525        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (192);  
2526          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2527    
2528          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2529          $self->{s_kwd} = '';            !!!cp (192);
2530          !!!next-input-character;            $self->{state} = DATA_STATE;
2531              $self->{s_kwd} = '';
2532          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2533          !!!emit ($self->{ct}); # DOCTYPE          } else {
2534              !!!cp (192.1);
2535              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2536            }
2537    
2538            !!!next-input-character;
2539            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2540          redo A;          redo A;
2541        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (193);  
2542          !!!parse-error (type => 'unclosed PUBLIC literal');          !!!parse-error (type => 'unclosed PUBLIC literal');
2543    
2544          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2545          $self->{s_kwd} = '';            !!!cp (193);
2546              $self->{state} = DATA_STATE;
2547              $self->{s_kwd} = '';
2548              $self->{ct}->{quirks} = 1;
2549            } else {
2550              !!!cp (193.1);
2551              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2552            }
2553          
2554          ## reconsume          ## reconsume
2555            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2556          redo A;          redo A;
2557        } else {        } else {
2558          !!!cp (194);          !!!cp (194);
2559          $self->{ct}->{pubid} # DOCTYPE          $self->{ct}->{pubid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2560          $self->{read_until}->($self->{ct}->{pubid}, q['>],          $self->{read_until}->($self->{ct}->{pubid}, q['>],
2561                                length $self->{ct}->{pubid});                                length $self->{ct}->{pubid});
2562    
# Line 2423  sub _get_next_token ($) { Line 2572  sub _get_next_token ($) {
2572          redo A;          redo A;
2573        } elsif ($self->{nc} == 0x0022) { # "        } elsif ($self->{nc} == 0x0022) { # "
2574          !!!cp (196);          !!!cp (196);
2575          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
2576          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
2577          !!!next-input-character;          !!!next-input-character;
2578          redo A;          redo A;
2579        } elsif ($self->{nc} == 0x0027) { # '        } elsif ($self->{nc} == 0x0027) { # '
2580          !!!cp (197);          !!!cp (197);
2581          $self->{ct}->{sysid} = ''; # DOCTYPE          $self->{ct}->{sysid} = ''; # DOCTYPE/ENTITY/NOTATION
2582          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;          $self->{state} = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
2583          !!!next-input-character;          !!!next-input-character;
2584          redo A;          redo A;
2585        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2586          if ($self->{is_xml}) {          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2587            !!!cp (198.1);            if ($self->{is_xml}) {
2588            !!!parse-error (type => 'no SYSTEM literal');              !!!cp (198.1);
2589                !!!parse-error (type => 'no SYSTEM literal');
2590              } else {
2591                !!!cp (198);
2592              }
2593              $self->{state} = DATA_STATE;
2594              $self->{s_kwd} = '';
2595          } else {          } else {
2596            !!!cp (198);            if ($self->{ct}->{type} == NOTATION_TOKEN) {
2597                !!!cp (198.2);
2598              } else {
2599                !!!cp (198.3);
2600                !!!parse-error (type => 'no SYSTEM literal');            
2601              }
2602              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2603          }          }
2604          $self->{state} = DATA_STATE;          
         $self->{s_kwd} = '';  
2605          !!!next-input-character;          !!!next-input-character;
2606            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         !!!emit ($self->{ct}); # DOCTYPE  
   
2607          redo A;          redo A;
2608        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2609          !!!cp (199);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2610          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (199);
2611              !!!parse-error (type => 'unclosed DOCTYPE');
2612          $self->{state} = DATA_STATE;            
2613          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2614              $self->{s_kwd} = '';
2615              $self->{ct}->{quirks} = 1;
2616            } else {
2617              !!!parse-error (type => 'unclosed md'); ## TODO: type
2618              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2619            }
2620            
2621          ## reconsume          ## reconsume
2622            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2623          redo A;          redo A;
2624        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2625                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2626                   $self->{nc} == 0x005B) { # [
2627          !!!cp (200.1);          !!!cp (200.1);
2628          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
2629          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
# Line 2469  sub _get_next_token ($) { Line 2633  sub _get_next_token ($) {
2633          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2634          redo A;          redo A;
2635        } else {        } else {
         !!!cp (200);  
2636          !!!parse-error (type => 'string after PUBLIC literal');          !!!parse-error (type => 'string after PUBLIC literal');
         $self->{ct}->{quirks} = 1;  
2637    
2638          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2639              !!!cp (200);
2640              $self->{ct}->{quirks} = 1;
2641              $self->{state} = BOGUS_DOCTYPE_STATE;
2642            } else {
2643              !!!cp (200.2);
2644              $self->{state} = BOGUS_MD_STATE;
2645            }
2646    
2647          !!!next-input-character;          !!!next-input-character;
2648          redo A;          redo A;
2649        }        }
# Line 2496  sub _get_next_token ($) { Line 2666  sub _get_next_token ($) {
2666          !!!next-input-character;          !!!next-input-character;
2667          redo A;          redo A;
2668        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
         !!!cp (204);  
2669          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
         $self->{state} = DATA_STATE;  
         $self->{s_kwd} = '';  
2670          !!!next-input-character;          !!!next-input-character;
2671    
2672          $self->{ct}->{quirks} = 1;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2673          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (204);
2674              $self->{state} = DATA_STATE;
2675              $self->{s_kwd} = '';
2676              $self->{ct}->{quirks} = 1;
2677            } else {
2678              !!!cp (204.1);
2679              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2680            }
2681    
2682            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2683          redo A;          redo A;
2684        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2685          !!!cp (205);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2686          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (205);
2687              !!!parse-error (type => 'unclosed DOCTYPE');
2688          $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
2689          $self->{s_kwd} = '';            $self->{s_kwd} = '';
2690              $self->{ct}->{quirks} = 1;
2691            } else {
2692              !!!cp (205.1);
2693              !!!parse-error (type => 'unclosed md'); ## TODO: type
2694              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2695            }
2696            
2697          ## reconsume          ## reconsume
2698            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2699          redo A;          redo A;
2700        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2701                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2702                   $self->{nc} == 0x005B) { # [
2703          !!!cp (206.1);          !!!cp (206.1);
2704          !!!parse-error (type => 'no SYSTEM literal');          !!!parse-error (type => 'no SYSTEM literal');
2705    
# Line 2529  sub _get_next_token ($) { Line 2710  sub _get_next_token ($) {
2710          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2711          redo A;          redo A;
2712        } else {        } else {
         !!!cp (206);  
2713          !!!parse-error (type => 'string after SYSTEM');          !!!parse-error (type => 'string after SYSTEM');
         $self->{ct}->{quirks} = 1;  
2714    
2715          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2716              !!!cp (206);          
2717              $self->{ct}->{quirks} = 1;
2718              $self->{state} = BOGUS_DOCTYPE_STATE;
2719            } else {
2720              !!!cp (206.2);
2721              $self->{state} = BOGUS_MD_STATE;
2722            }
2723    
2724          !!!next-input-character;          !!!next-input-character;
2725          redo A;          redo A;
2726        }        }
# Line 2544  sub _get_next_token ($) { Line 2731  sub _get_next_token ($) {
2731          !!!next-input-character;          !!!next-input-character;
2732          redo A;          redo A;
2733        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >        } elsif (not $self->{is_xml} and $self->{nc} == 0x003E) { # >
         !!!cp (208);  
2734          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2735    
2736          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2737          $self->{s_kwd} = '';            !!!cp (208);
2738              $self->{state} = DATA_STATE;
2739              $self->{s_kwd} = '';
2740              $self->{ct}->{quirks} = 1;
2741            } else {
2742              !!!cp (208.1);
2743              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2744            }
2745            
2746          !!!next-input-character;          !!!next-input-character;
2747            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2748          redo A;          redo A;
2749        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (209);  
2750          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2751    
2752          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2753          $self->{s_kwd} = '';            !!!cp (209);
2754              $self->{state} = DATA_STATE;
2755              $self->{s_kwd} = '';
2756              $self->{ct}->{quirks} = 1;
2757            } else {
2758              !!!cp (209.1);
2759              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2760            }
2761            
2762          ## reconsume          ## reconsume
2763            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
         $self->{ct}->{quirks} = 1;  
         !!!emit ($self->{ct}); # DOCTYPE  
   
2764          redo A;          redo A;
2765        } else {        } else {
2766          !!!cp (210);          !!!cp (210);
2767          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2768          $self->{read_until}->($self->{ct}->{sysid}, q[">],          $self->{read_until}->($self->{ct}->{sysid}, q[">],
2769                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
2770    
# Line 2597  sub _get_next_token ($) { Line 2791  sub _get_next_token ($) {
2791    
2792          redo A;          redo A;
2793        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
         !!!cp (213);  
2794          !!!parse-error (type => 'unclosed SYSTEM literal');          !!!parse-error (type => 'unclosed SYSTEM literal');
2795    
2796          $self->{state} = DATA_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2797          $self->{s_kwd} = '';            !!!cp (213);
2798          ## reconsume            $self->{state} = DATA_STATE;
2799              $self->{s_kwd} = '';
2800          $self->{ct}->{quirks} = 1;            $self->{ct}->{quirks} = 1;
2801          !!!emit ($self->{ct}); # DOCTYPE          } else {
2802              !!!cp (213.1);
2803              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2804            }
2805    
2806            ## reconsume
2807            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2808          redo A;          redo A;
2809        } else {        } else {
2810          !!!cp (214);          !!!cp (214);
2811          $self->{ct}->{sysid} # DOCTYPE          $self->{ct}->{sysid} .= chr $self->{nc}; # DOCTYPE/ENTITY/NOTATION
             .= chr $self->{nc};  
2812          $self->{read_until}->($self->{ct}->{sysid}, q['>],          $self->{read_until}->($self->{ct}->{sysid}, q['>],
2813                                length $self->{ct}->{sysid});                                length $self->{ct}->{sysid});
2814    
# Line 2621  sub _get_next_token ($) { Line 2818  sub _get_next_token ($) {
2818        }        }
2819      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2820        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
2821          !!!cp (215);          if ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN) {
2822          ## Stay in the state            !!!cp (215.1);
2823              $self->{state} = BEFORE_NDATA_STATE;
2824            } else {
2825              !!!cp (215);
2826              ## Stay in the state
2827            }
2828          !!!next-input-character;          !!!next-input-character;
2829          redo A;          redo A;
2830        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
2831          !!!cp (216);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2832          $self->{state} = DATA_STATE;            !!!cp (216);
2833          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2834          !!!next-input-character;            $self->{s_kwd} = '';
2835            } else {
2836          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (216.1);
2837              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2838            }
2839    
2840            !!!next-input-character;
2841            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2842            redo A;
2843          } elsif ($self->{ct}->{type} == GENERAL_ENTITY_TOKEN and
2844                   ($self->{nc} == 0x004E or # N
2845                    $self->{nc} == 0x006E)) { # n
2846            !!!cp (216.2);
2847            !!!parse-error (type => 'no space before NDATA'); ## TODO: type
2848            $self->{state} = NDATA_STATE;
2849            $self->{kwd} = chr $self->{nc};
2850            !!!next-input-character;
2851          redo A;          redo A;
2852        } elsif ($self->{nc} == -1) {        } elsif ($self->{nc} == -1) {
2853          !!!cp (217);          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2854          !!!parse-error (type => 'unclosed DOCTYPE');            !!!cp (217);
2855          $self->{state} = DATA_STATE;            !!!parse-error (type => 'unclosed DOCTYPE');
2856          $self->{s_kwd} = '';            $self->{state} = DATA_STATE;
2857          ## reconsume            $self->{s_kwd} = '';
2858              $self->{ct}->{quirks} = 1;
2859          $self->{ct}->{quirks} = 1;          } else {
2860          !!!emit ($self->{ct}); # DOCTYPE            !!!cp (217.1);
2861              !!!parse-error (type => 'unclosed md'); ## TODO: type
2862              $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2863            }
2864    
2865            ## reconsume
2866            !!!emit ($self->{ct}); # DOCTYPE/ENTITY/NOTATION
2867          redo A;          redo A;
2868        } elsif ($self->{is_xml} and $self->{nc} == 0x005B) { # [        } elsif ($self->{is_xml} and
2869                   $self->{ct}->{type} == DOCTYPE_TOKEN and
2870                   $self->{nc} == 0x005B) { # [
2871          !!!cp (218.1);          !!!cp (218.1);
2872          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2873          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE          $self->{ct}->{has_internal_subset} = 1; # DOCTYPE
# Line 2654  sub _get_next_token ($) { Line 2876  sub _get_next_token ($) {
2876          !!!emit ($self->{ct}); # DOCTYPE          !!!emit ($self->{ct}); # DOCTYPE
2877          redo A;          redo A;
2878        } else {        } else {
         !!!cp (218);  
2879          !!!parse-error (type => 'string after SYSTEM literal');          !!!parse-error (type => 'string after SYSTEM literal');
         #$self->{ct}->{quirks} = 1;  
2880    
2881          $self->{state} = BOGUS_DOCTYPE_STATE;          if ($self->{ct}->{type} == DOCTYPE_TOKEN) {
2882              !!!cp (218);
2883              #$self->{ct}->{quirks} = 1;
2884              $self->{state} = BOGUS_DOCTYPE_STATE;
2885            } else {
2886              !!!cp (218.2);
2887              $self->{state} = BOGUS_MD_STATE;
2888            }
2889    
2890            !!!next-input-character;
2891            redo A;
2892          }
2893        } elsif ($self->{state} == BEFORE_NDATA_STATE) {
2894          if ($is_space->{$self->{nc}}) {
2895            !!!cp (218.3);
2896            ## Stay in the state.
2897            !!!next-input-character;
2898            redo A;
2899          } elsif ($self->{nc} == 0x003E) { # >
2900            !!!cp (218.4);
2901            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2902            !!!next-input-character;
2903            !!!emit ($self->{ct}); # ENTITY
2904            redo A;
2905          } elsif ($self->{nc} == 0x004E or # N
2906                   $self->{nc} == 0x006E) { # n
2907            !!!cp (218.5);
2908            $self->{state} = NDATA_STATE;
2909            $self->{kwd} = chr $self->{nc};
2910            !!!next-input-character;
2911            redo A;
2912          } elsif ($self->{nc} == -1) {
2913            !!!cp (218.6);
2914            !!!parse-error (type => 'unclosed md'); ## TODO: type
2915            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
2916            ## reconsume
2917            !!!emit ($self->{ct}); # ENTITY
2918            redo A;
2919          } else {
2920            !!!cp (218.7);
2921            !!!parse-error (type => 'string after SYSTEM literal');
2922            $self->{state} = BOGUS_MD_STATE;
2923          !!!next-input-character;          !!!next-input-character;
2924          redo A;          redo A;
2925        }        }
# Line 3423  sub _get_next_token ($) { Line 3684  sub _get_next_token ($) {
3684          $self->{state} = MD_HYPHEN_STATE;          $self->{state} = MD_HYPHEN_STATE;
3685          !!!next-input-character;          !!!next-input-character;
3686          redo A;          redo A;
3687        } elsif ($self->{nc} == 0x0045) { # E        } elsif ($self->{nc} == 0x0045 or # E
3688                   $self->{nc} == 0x0065) { # e
3689          $self->{state} = MD_E_STATE;          $self->{state} = MD_E_STATE;
3690          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3691          !!!next-input-character;          !!!next-input-character;
3692          redo A;          redo A;
3693        } elsif ($self->{nc} == 0x0041) { # A        } elsif ($self->{nc} == 0x0041 or # A
3694                   $self->{nc} == 0x0061) { # a
3695          $self->{state} = MD_ATTLIST_STATE;          $self->{state} = MD_ATTLIST_STATE;
3696          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3697          !!!next-input-character;          !!!next-input-character;
3698          redo A;          redo A;
3699        } elsif ($self->{nc} == 0x004E) { # N        } elsif ($self->{nc} == 0x004E or # N
3700                   $self->{nc} == 0x006E) { # n
3701          $self->{state} = MD_NOTATION_STATE;          $self->{state} = MD_NOTATION_STATE;
3702          $self->{kwd} = chr $self->{nc};          $self->{kwd} = chr $self->{nc};
3703          !!!next-input-character;          !!!next-input-character;
# Line 3451  sub _get_next_token ($) { Line 3715  sub _get_next_token ($) {
3715        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.        $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded.
3716        redo A;        redo A;
3717      } elsif ($self->{state} == MD_E_STATE) {      } elsif ($self->{state} == MD_E_STATE) {
3718        if ($self->{nc} == 0x004E) { # N        if ($self->{nc} == 0x004E or # N
3719              $self->{nc} == 0x006E) { # n
3720          $self->{state} = MD_ENTITY_STATE;          $self->{state} = MD_ENTITY_STATE;
3721          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3722          !!!next-input-character;          !!!next-input-character;
3723          redo A;          redo A;
3724        } elsif ($self->{nc} == 0x004C) { # L        } elsif ($self->{nc} == 0x004C or # L
3725                   $self->{nc} == 0x006C) { # l
3726          ## XML5: <!ELEMENT> not supported.          ## XML5: <!ELEMENT> not supported.
3727          $self->{state} = MD_ELEMENT_STATE;          $self->{state} = MD_ELEMENT_STATE;
3728          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
# Line 3474  sub _get_next_token ($) { Line 3740  sub _get_next_token ($) {
3740          redo A;          redo A;
3741        }        }
3742      } elsif ($self->{state} == MD_ENTITY_STATE) {      } elsif ($self->{state} == MD_ENTITY_STATE) {
3743        if ($self->{nc} == {        if ($self->{nc} == [
3744              'EN' => 0x0054, # T              undef,
3745              'ENT' => 0x0049, # I              undef,
3746              'ENTI' => 0x0054, # T              0x0054, # T
3747            }->{$self->{kwd}}) {              0x0049, # I
3748                0x0054, # T
3749              ]->[length $self->{kwd}] or
3750              $self->{nc} == [
3751                undef,
3752                undef,
3753                0x0074, # t
3754                0x0069, # i
3755                0x0074, # t
3756              ]->[length $self->{kwd}]) {
3757          ## Stay in the state.          ## Stay in the state.
3758          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3759          !!!next-input-character;          !!!next-input-character;
3760          redo A;          redo A;
3761        } elsif ($self->{kwd} eq 'ENTIT' and        } elsif ((length $self->{kwd}) == 5 and
3762                 $self->{nc} == 0x0059) { # Y                 ($self->{nc} == 0x0059 or # Y
3763          $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '', text => '',                  $self->{nc} == 0x0079)) { # y
3764            if ($self->{kwd} ne 'ENTIT' or $self->{nc} == 0x0079) {
3765              !!!parse-error (type => 'lowercase keyword', ## TODO: type
3766                              text => 'ENTITY',
3767                              line => $self->{line_prev},
3768                              column => $self->{column_prev} - 4);
3769            }
3770            $self->{ct} = {type => GENERAL_ENTITY_TOKEN, name => '',
3771                         line => $self->{line_prev},                         line => $self->{line_prev},
3772                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
3773          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
# Line 3503  sub _get_next_token ($) { Line 3785  sub _get_next_token ($) {
3785          redo A;          redo A;
3786        }        }
3787      } elsif ($self->{state} == MD_ELEMENT_STATE) {      } elsif ($self->{state} == MD_ELEMENT_STATE) {
3788        if ($self->{nc} == {        if ($self->{nc} == [
3789              'EL' => 0x0045, # E             undef,
3790              'ELE' => 0x004D, # M             undef,
3791              'ELEM' => 0x0045, # E             0x0045, # E
3792              'ELEME' => 0x004E, # N             0x004D, # M
3793            }->{$self->{kwd}}) {             0x0045, # E
3794               0x004E, # N
3795              ]->[length $self->{kwd}] or
3796              $self->{nc} == [
3797               undef,
3798               undef,
3799               0x0065, # e
3800               0x006D, # m
3801               0x0065, # e
3802               0x006E, # n
3803              ]->[length $self->{kwd}]) {
3804          ## Stay in the state.          ## Stay in the state.
3805          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3806          !!!next-input-character;          !!!next-input-character;
3807          redo A;          redo A;
3808        } elsif ($self->{kwd} eq 'ELEMEN' and        } elsif ((length $self->{kwd}) == 6 and
3809                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
3810                    $self->{nc} == 0x0074)) { # t
3811            if ($self->{kwd} ne 'ELEMEN' or $self->{nc} == 0x0074) {
3812              !!!parse-error (type => 'lowercase keyword', ## TODO: type
3813                              text => 'ELEMENT',
3814                              line => $self->{line_prev},
3815                              column => $self->{column_prev} - 5);
3816            }
3817          $self->{ct} = {type => ELEMENT_TOKEN, name => '',          $self->{ct} = {type => ELEMENT_TOKEN, name => '',
3818                         line => $self->{line_prev},                         line => $self->{line_prev},
3819                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
# Line 3533  sub _get_next_token ($) { Line 3832  sub _get_next_token ($) {
3832          redo A;          redo A;
3833        }        }
3834      } elsif ($self->{state} == MD_ATTLIST_STATE) {      } elsif ($self->{state} == MD_ATTLIST_STATE) {
3835        if ($self->{nc} == {        if ($self->{nc} == [
3836              'A' => 0x0054, # T             undef,
3837              'AT' => 0x0054, # T             0x0054, # T
3838              'ATT' => 0x004C, # L             0x0054, # T
3839              'ATTL' => 0x0049, # I             0x004C, # L
3840              'ATTLI' => 0x0053, # S             0x0049, # I
3841            }->{$self->{kwd}}) {             0x0053, # S
3842              ]->[length $self->{kwd}] or
3843              $self->{nc} == [
3844               undef,
3845               0x0074, # t
3846               0x0074, # t
3847               0x006C, # l
3848               0x0069, # i
3849               0x0073, # s
3850              ]->[length $self->{kwd}]) {
3851          ## Stay in the state.          ## Stay in the state.
3852          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3853          !!!next-input-character;          !!!next-input-character;
3854          redo A;          redo A;
3855        } elsif ($self->{kwd} eq 'ATTLIS' and        } elsif ((length $self->{kwd}) == 6 and
3856                 $self->{nc} == 0x0054) { # T                 ($self->{nc} == 0x0054 or # T
3857                    $self->{nc} == 0x0074)) { # t
3858            if ($self->{kwd} ne 'ATTLIS' or $self->{nc} == 0x0074) {
3859              !!!parse-error (type => 'lowercase keyword', ## TODO: type
3860                              text => 'ATTLIST',
3861                              line => $self->{line_prev},
3862                              column => $self->{column_prev} - 5);
3863            }
3864          $self->{ct} = {type => ATTLIST_TOKEN, name => '',          $self->{ct} = {type => ATTLIST_TOKEN, name => '',
3865                           attrdefs => [],
3866                         line => $self->{line_prev},                         line => $self->{line_prev},
3867                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
3868          $self->{state} = DOCTYPE_MD_STATE;          $self->{state} = DOCTYPE_MD_STATE;
# Line 3564  sub _get_next_token ($) { Line 3880  sub _get_next_token ($) {
3880          redo A;          redo A;
3881        }        }
3882      } elsif ($self->{state} == MD_NOTATION_STATE) {      } elsif ($self->{state} == MD_NOTATION_STATE) {
3883        if ($self->{nc} == {        if ($self->{nc} == [
3884              'N' => 0x004F, # O             undef,
3885              'NO' => 0x0054, # T             0x004F, # O
3886              'NOT' => 0x0041, # A             0x0054, # T
3887              'NOTA' => 0x0054, # T             0x0041, # A
3888              'NOTAT' => 0x0049, # I             0x0054, # T
3889              'NOTATI' => 0x004F, # O             0x0049, # I
3890            }->{$self->{kwd}}) {             0x004F, # O
3891              ]->[length $self->{kwd}] or
3892              $self->{nc} == [
3893               undef,
3894               0x006F, # o
3895               0x0074, # t
3896               0x0061, # a
3897               0x0074, # t
3898               0x0069, # i
3899               0x006F, # o
3900              ]->[length $self->{kwd}]) {
3901          ## Stay in the state.          ## Stay in the state.
3902          $self->{kwd} .= chr $self->{nc};          $self->{kwd} .= chr $self->{nc};
3903          !!!next-input-character;          !!!next-input-character;
3904          redo A;          redo A;
3905        } elsif ($self->{kwd} eq 'NOTATIO' and        } elsif ((length $self->{kwd}) == 7 and
3906                 $self->{nc} == 0x004E) { # N                 ($self->{nc} == 0x004E or # N
3907                    $self->{nc} == 0x006E)) { # n
3908            if ($self->{kwd} ne 'NOTATIO' or $self->{nc} == 0x006E) {
3909              !!!parse-error (type => 'lowercase keyword', ## TODO: type
3910                              text => 'NOTATION',
3911                              line => $self->{line_prev},
3912                              column => $self->{column_prev} - 6);
3913            }
3914          $self->{ct} = {type => NOTATION_TOKEN, name => '',          $self->{ct} = {type => NOTATION_TOKEN, name => '',
3915                         line => $self->{line_prev},                         line => $self->{line_prev},
3916                         column => $self->{column_prev} - 6};                         column => $self->{column_prev} - 6};
# Line 3689  sub _get_next_token ($) { Line 4022  sub _get_next_token ($) {
4022        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".        ## XML5: "DOCTYPE ENTITY name state" and "DOCTYPE ATTLIST name state".
4023                
4024        if ($is_space->{$self->{nc}}) {        if ($is_space->{$self->{nc}}) {
4025          ## TODO:          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4026          $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4027            } elsif ($self->{ct}->{type} == ELEMENT_TOKEN) {
4028              ## TODO: ...
4029              $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4030            } else { # ENTITY/NOTATION
4031              $self->{state} = AFTER_DOCTYPE_NAME_STATE;
4032            }
4033          !!!next-input-character;          !!!next-input-character;
4034          redo A;          redo A;
4035        } elsif ($self->{nc} == 0x003E) { # >        } elsif ($self->{nc} == 0x003E) { # >
4036          if ($self->{ct}->{type} == ATTLIST_TOKEN) {          if ($self->{ct}->{type} == ATTLIST_TOKEN) {
4037            #            #
4038          } else {          } else {
4039            !!!parse-error (type => 'no md body'); ## TODO: type            !!!parse-error (type => 'no md def'); ## TODO: type
4040          }          }
4041          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4042          !!!next-input-character;          !!!next-input-character;
# Line 3731  sub _get_next_token ($) { Line 4070  sub _get_next_token ($) {
4070          ## XML5: No parse error.          ## XML5: No parse error.
4071          !!!parse-error (type => 'unclosed md'); ## TODO: type          !!!parse-error (type => 'unclosed md'); ## TODO: type
4072          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".          $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4073            !!!emit ($self->{ct});
4074            redo A;
4075          } else {
4076            ## XML5: Not defined yet.
4077            $self->{ca} = {name => chr ($self->{nc}), # attrdef
4078                           tokens => [],
4079                           line => $self->{line}, column => $self->{column}};
4080            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_NAME_STATE;
4081            !!!next-input-character;
4082            redo A;
4083          }
4084        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_NAME_STATE) {
4085          if ($is_space->{$self->{nc}}) {
4086            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_NAME_AFTER_STATE;
4087            !!!next-input-character;
4088            redo A;
4089          } elsif ($self->{nc} == 0x003E) { # >
4090            ## XML5: Same as "anything else".
4091            !!!parse-error (type => 'no attr type'); ## TODO: type
4092            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4093            !!!next-input-character;
4094            !!!emit ($self->{ct}); # ATTLIST
4095            redo A;
4096          } elsif ($self->{nc} == 0x0028) { # (
4097            ## XML5: Same as "anything else".
4098            !!!parse-error (type => 'no space before paren'); ## TODO: type
4099            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4100            !!!next-input-character;
4101            redo A;
4102          } elsif ($self->{nc} == -1) {
4103            ## XML5: No parse error.
4104            !!!parse-error (type => 'unclosed md'); ## TODO: type
4105            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4106            !!!next-input-character;
4107            !!!emit ($self->{ct}); # ATTLIST
4108            redo A;
4109          } else {
4110            ## XML5: Not defined yet.
4111            $self->{ca}->{name} .= chr $self->{nc};
4112            ## Stay in the state.
4113            !!!next-input-character;
4114            redo A;
4115          }
4116        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_NAME_AFTER_STATE) {
4117          if ($is_space->{$self->{nc}}) {
4118            ## Stay in the state.
4119            !!!next-input-character;
4120            redo A;
4121          } elsif ($self->{nc} == 0x003E) { # >
4122            ## XML5: Same as "anything else".
4123            !!!parse-error (type => 'no attr type'); ## TODO: type
4124            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4125            !!!next-input-character;
4126            !!!emit ($self->{ct}); # ATTLIST
4127            redo A;
4128          } elsif ($self->{nc} == 0x0028) { # (
4129            ## XML5: Same as "anything else".
4130            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4131            !!!next-input-character;
4132            redo A;
4133          } elsif ($self->{nc} == -1) {
4134            ## XML5: No parse error.
4135            !!!parse-error (type => 'unclosed md'); ## TODO: type
4136            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4137            !!!next-input-character;
4138            !!!emit ($self->{ct});
4139            redo A;
4140          } else {
4141            ## XML5: Not defined yet.
4142            $self->{ca}->{type} = chr $self->{nc};
4143            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_STATE;
4144            !!!next-input-character;
4145            redo A;
4146          }
4147        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_STATE) {
4148          if ($is_space->{$self->{nc}}) {
4149            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_AFTER_STATE;
4150            !!!next-input-character;
4151            redo A;
4152          } elsif ($self->{nc} == 0x0023) { # #
4153            ## XML5: Same as "anything else".
4154            !!!parse-error (type => 'no space before default value'); ## TODO: type
4155            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE;
4156            !!!next-input-character;
4157            redo A;
4158          } elsif ($self->{nc} == 0x0022) { # "
4159            ## XML5: Same as "anything else".
4160            !!!parse-error (type => 'no space before default value'); ## TODO: type
4161            $self->{ca}->{value} = '';
4162            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4163            !!!next-input-character;
4164            redo A;
4165          } elsif ($self->{nc} == 0x0027) { # '
4166            ## XML5: Same as "anything else".
4167            !!!parse-error (type => 'no space before default value'); ## TODO: type
4168            $self->{ca}->{value} = '';
4169            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4170            !!!next-input-character;
4171            redo A;
4172          } elsif ($self->{nc} == 0x003E) { # >
4173            ## XML5: Same as "anything else".
4174            !!!parse-error (type => 'no attr default'); ## TODO: type
4175            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4176            !!!next-input-character;
4177            !!!emit ($self->{ct}); # ATTLIST
4178            redo A;
4179          } elsif ($self->{nc} == 0x0028) { # (
4180            ## XML5: Same as "anything else".
4181            !!!parse-error (type => 'no space before paren'); ## TODO: type
4182            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4183            !!!next-input-character;
4184            redo A;
4185          } elsif ($self->{nc} == -1) {
4186            ## XML5: No parse error.
4187            !!!parse-error (type => 'unclosed md'); ## TODO: type
4188            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4189            !!!next-input-character;
4190            !!!emit ($self->{ct});
4191            redo A;
4192          } else {
4193            ## XML5: Not defined yet.
4194            $self->{ca}->{type} .= chr $self->{nc};
4195            ## Stay in the state.
4196            !!!next-input-character;
4197            redo A;
4198          }
4199        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_TYPE_AFTER_STATE) {
4200          if ($is_space->{$self->{nc}}) {
4201            ## Stay in the state.
4202            !!!next-input-character;
4203            redo A;
4204          } elsif ($self->{nc} == 0x0028) { # (
4205            ## XML5: Same as "anything else".
4206            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4207            !!!next-input-character;
4208            redo A;
4209          } elsif ($self->{nc} == 0x0023) { # #
4210            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE;
4211            !!!next-input-character;
4212            redo A;
4213          } elsif ($self->{nc} == 0x0022) { # "
4214            ## XML5: Same as "anything else".
4215            $self->{ca}->{value} = '';
4216            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4217            !!!next-input-character;
4218            redo A;
4219          } elsif ($self->{nc} == 0x0027) { # '
4220            ## XML5: Same as "anything else".
4221            $self->{ca}->{value} = '';
4222            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4223            !!!next-input-character;
4224            redo A;
4225          } elsif ($self->{nc} == 0x003E) { # >
4226            ## XML5: Same as "anything else".
4227            !!!parse-error (type => 'no attr default'); ## TODO: type
4228            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4229            !!!next-input-character;
4230            !!!emit ($self->{ct}); # ATTLIST
4231            redo A;
4232          } elsif ($self->{nc} == -1) {
4233            ## XML5: No parse error.
4234            !!!parse-error (type => 'unclosed md'); ## TODO: type
4235            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4236            !!!next-input-character;
4237            !!!emit ($self->{ct});
4238            redo A;
4239          } else {
4240            ## XML5: Switch to the "DOCTYPE bogus comment state".
4241            !!!parse-error (type => 'unquoted attr value'); ## TODO: type
4242            $self->{ca}->{value} = '';
4243            $self->{state} = ATTRIBUTE_VALUE_UNQUOTED_STATE;
4244            ## Reconsume.
4245            redo A;
4246          }
4247        } elsif ($self->{state} == BEFORE_ALLOWED_TOKEN_STATE) {
4248          if ($is_space->{$self->{nc}}) {
4249            ## Stay in the state.
4250            !!!next-input-character;
4251            redo A;
4252          } elsif ($self->{nc} == 0x007C) { # |
4253            !!!parse-error (type => 'empty allowed token'); ## TODO: type
4254            ## Stay in the state.
4255            !!!next-input-character;
4256            redo A;
4257          } elsif ($self->{nc} == 0x0029) { # )
4258            !!!parse-error (type => 'empty allowed token'); ## TODO: type
4259            $self->{state} = AFTER_ALLOWED_TOKENS_STATE;
4260            !!!next-input-character;
4261            redo A;
4262          } elsif ($self->{nc} == 0x003E) { # >
4263            !!!parse-error (type => 'unclosed allowed tokens'); ## TODO: type
4264            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4265            !!!next-input-character;
4266            !!!emit ($self->{ct}); # ATTLIST
4267            redo A;
4268          } elsif ($self->{nc} == -1) {
4269            ## XML5: No parse error.
4270            !!!parse-error (type => 'unclosed md'); ## TODO: type
4271            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4272            !!!next-input-character;
4273            !!!emit ($self->{ct});
4274            redo A;
4275          } else {
4276            push @{$self->{ca}->{tokens}}, chr $self->{nc};
4277            $self->{state} = ALLOWED_TOKEN_STATE;
4278            !!!next-input-character;
4279            redo A;
4280          }
4281        } elsif ($self->{state} == ALLOWED_TOKEN_STATE) {
4282          if ($is_space->{$self->{nc}}) {
4283            $self->{state} = AFTER_ALLOWED_TOKEN_STATE;
4284            !!!next-input-character;
4285            redo A;
4286          } elsif ($self->{nc} == 0x007C) { # |
4287            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4288            !!!next-input-character;
4289            redo A;
4290          } elsif ($self->{nc} == 0x0029) { # )
4291            $self->{state} = AFTER_ALLOWED_TOKENS_STATE;
4292            !!!next-input-character;
4293            redo A;
4294          } elsif ($self->{nc} == 0x003E) { # >
4295            !!!parse-error (type => 'unclosed allowed tokens'); ## TODO: type
4296            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4297            !!!next-input-character;
4298            !!!emit ($self->{ct}); # ATTLIST
4299            redo A;
4300          } elsif ($self->{nc} == -1) {
4301            ## XML5: No parse error.
4302            !!!parse-error (type => 'unclosed md'); ## TODO: type
4303            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4304            !!!next-input-character;
4305            !!!emit ($self->{ct});
4306            redo A;
4307          } else {
4308            $self->{ca}->{tokens}->[-1] .= chr $self->{nc};
4309            ## Stay in the state.
4310            !!!next-input-character;
4311            redo A;
4312          }
4313        } elsif ($self->{state} == AFTER_ALLOWED_TOKEN_STATE) {
4314          if ($is_space->{$self->{nc}}) {
4315            ## Stay in the state.
4316            !!!next-input-character;
4317            redo A;
4318          } elsif ($self->{nc} == 0x007C) { # |
4319            $self->{state} = BEFORE_ALLOWED_TOKEN_STATE;
4320            !!!next-input-character;
4321            redo A;
4322          } elsif ($self->{nc} == 0x0029) { # )
4323            $self->{state} = AFTER_ALLOWED_TOKENS_STATE;
4324            !!!next-input-character;
4325            redo A;
4326          } elsif ($self->{nc} == 0x003E) { # >
4327            !!!parse-error (type => 'unclosed allowed tokens'); ## TODO: type
4328            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4329            !!!next-input-character;
4330            !!!emit ($self->{ct}); # ATTLIST
4331            redo A;
4332          } elsif ($self->{nc} == -1) {
4333            ## XML5: No parse error.
4334            !!!parse-error (type => 'unclosed md'); ## TODO: type
4335            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4336            !!!next-input-character;
4337            !!!emit ($self->{ct});
4338            redo A;
4339          } else {
4340            !!!parse-error (type => 'space in allowed token', ## TODO: type
4341                            line => $self->{line_prev},
4342                            column => $self->{column_prev});
4343            $self->{ca}->{tokens}->[-1] .= ' ' . chr $self->{nc};
4344            $self->{state} = ALLOWED_TOKEN_STATE;
4345            !!!next-input-character;
4346            redo A;
4347          }
4348        } elsif ($self->{state} == AFTER_ALLOWED_TOKENS_STATE) {
4349          if ($is_space->{$self->{nc}}) {
4350            $self->{state} = BEFORE_ATTR_DEFAULT_STATE;
4351            !!!next-input-character;
4352            redo A;
4353          } elsif ($self->{nc} == 0x0023) { # #
4354            !!!parse-error (type => 'no space before default value'); ## TODO: type
4355            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE;
4356            !!!next-input-character;
4357            redo A;
4358          } elsif ($self->{nc} == 0x0022) { # "
4359            !!!parse-error (type => 'no space before default value'); ## TODO: type
4360            $self->{ca}->{value} = '';
4361            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4362            !!!next-input-character;
4363            redo A;
4364          } elsif ($self->{nc} == 0x0027) { # '
4365            !!!parse-error (type => 'no space before default value'); ## TODO: type
4366            $self->{ca}->{value} = '';
4367            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4368            !!!next-input-character;
4369            redo A;
4370          } elsif ($self->{nc} == 0x003E) { # >
4371            !!!parse-error (type => 'no attr default'); ## TODO: type
4372            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4373            !!!next-input-character;
4374            !!!emit ($self->{ct}); # ATTLIST
4375            redo A;
4376          } elsif ($self->{nc} == -1) {
4377            !!!parse-error (type => 'unclosed md'); ## TODO: type
4378            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4379            !!!next-input-character;
4380            !!!emit ($self->{ct});
4381            redo A;
4382          } else {
4383            !!!parse-error (type => 'unquoted attr value'); ## TODO: type
4384            $self->{state} = ATTRIBUTE_VALUE_UNQUOTED_STATE;
4385            ## Reconsume.
4386            redo A;
4387          }
4388        } elsif ($self->{state} == BEFORE_ATTR_DEFAULT_STATE) {
4389          if ($is_space->{$self->{nc}}) {
4390            ## Stay in the state.
4391            !!!next-input-character;
4392            redo A;
4393          } elsif ($self->{nc} == 0x0023) { # #
4394            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE;
4395            !!!next-input-character;
4396            redo A;
4397          } elsif ($self->{nc} == 0x0022) { # "
4398            $self->{ca}->{value} = '';
4399            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4400            !!!next-input-character;
4401            redo A;
4402          } elsif ($self->{nc} == 0x0027) { # '
4403            $self->{ca}->{value} = '';
4404            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4405            !!!next-input-character;
4406            redo A;
4407          } elsif ($self->{nc} == 0x003E) { # >
4408            !!!parse-error (type => 'no attr default'); ## TODO: type
4409            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4410            !!!next-input-character;
4411            !!!emit ($self->{ct}); # ATTLIST
4412            redo A;
4413          } elsif ($self->{nc} == -1) {
4414            !!!parse-error (type => 'unclosed md'); ## TODO: type
4415            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4416            !!!next-input-character;
4417            !!!emit ($self->{ct});
4418            redo A;
4419          } else {
4420            !!!parse-error (type => 'unquoted attr value'); ## TODO: type
4421            $self->{state} = ATTRIBUTE_VALUE_UNQUOTED_STATE;
4422            ## Reconsume.
4423            redo A;
4424          }
4425        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_BEFORE_STATE) {
4426          if ($is_space->{$self->{nc}}) {
4427            ## XML5: No parse error.
4428            !!!parse-error (type => 'no default type'); ## TODO: type
4429            $self->{state} = BOGUS_MD_STATE;
4430            ## Reconsume.
4431            redo A;
4432          } elsif ($self->{nc} == 0x0022) { # "
4433            ## XML5: Same as "anything else".
4434            $self->{ca}->{value} = '';
4435            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4436            !!!next-input-character;
4437            redo A;
4438          } elsif ($self->{nc} == 0x0027) { # '
4439            ## XML5: Same as "anything else".
4440            $self->{ca}->{value} = '';
4441            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4442            !!!next-input-character;
4443            redo A;
4444          } elsif ($self->{nc} == 0x003E) { # >
4445            ## XML5: Same as "anything else".
4446            !!!parse-error (type => 'no attr default'); ## TODO: type
4447            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4448            !!!next-input-character;
4449            !!!emit ($self->{ct}); # ATTLIST
4450            redo A;
4451          } elsif ($self->{nc} == -1) {
4452            ## XML5: No parse error.
4453            !!!parse-error (type => 'unclosed md'); ## TODO: type
4454            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4455            !!!next-input-character;
4456            !!!emit ($self->{ct});
4457            redo A;
4458          } else {
4459            $self->{ca}->{default} = chr $self->{nc};
4460            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE;
4461            !!!next-input-character;
4462            redo A;
4463          }
4464        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_STATE) {
4465          if ($is_space->{$self->{nc}}) {
4466            $self->{state} = DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE;
4467            !!!next-input-character;
4468            redo A;
4469          } elsif ($self->{nc} == 0x0022) { # "
4470            ## XML5: Same as "anything else".
4471            !!!parse-error (type => 'no space before default value'); ## TODO: type
4472            $self->{ca}->{value} = '';
4473            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4474            !!!next-input-character;
4475            redo A;
4476          } elsif ($self->{nc} == 0x0027) { # '
4477            ## XML5: Same as "anything else".
4478            !!!parse-error (type => 'no space before default value'); ## TODO: type
4479            $self->{ca}->{value} = '';
4480            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4481            !!!next-input-character;
4482            redo A;
4483          } elsif ($self->{nc} == 0x003E) { # >
4484            ## XML5: Same as "anything else".
4485            push @{$self->{ct}->{attrdefs}}, $self->{ca};
4486            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4487            !!!next-input-character;
4488            !!!emit ($self->{ct}); # ATTLIST
4489            redo A;
4490          } elsif ($self->{nc} == -1) {
4491            ## XML5: No parse error.
4492            !!!parse-error (type => 'unclosed md'); ## TODO: type
4493            push @{$self->{ct}->{attrdefs}}, $self->{ca};
4494            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4495            !!!next-input-character;
4496            !!!emit ($self->{ct});
4497            redo A;
4498          } else {
4499            $self->{ca}->{default} .= chr $self->{nc};
4500            ## Stay in the state.
4501            !!!next-input-character;
4502            redo A;
4503          }
4504        } elsif ($self->{state} == DOCTYPE_ATTLIST_ATTRIBUTE_DECLARATION_AFTER_STATE) {
4505          if ($is_space->{$self->{nc}}) {
4506            ## Stay in the state.
4507            !!!next-input-character;
4508            redo A;
4509          } elsif ($self->{nc} == 0x0022) { # "
4510            $self->{ca}->{value} = '';
4511            $self->{state} = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
4512            !!!next-input-character;
4513            redo A;
4514          } elsif ($self->{nc} == 0x0027) { # '
4515            $self->{ca}->{value} = '';
4516            $self->{state} = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
4517            !!!next-input-character;
4518            redo A;
4519          } elsif ($self->{nc} == 0x003E) { # >
4520            push @{$self->{ct}->{attrdefs}}, $self->{ca};
4521            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4522            !!!next-input-character;
4523            !!!emit ($self->{ct}); # ATTLIST
4524            redo A;
4525          } elsif ($self->{nc} == -1) {
4526            ## XML5: No parse error.
4527            !!!parse-error (type => 'unclosed md'); ## TODO: type
4528            push @{$self->{ct}->{attrdefs}}, $self->{ca};
4529            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE; ## XML5: "Data state".
4530            !!!next-input-character;
4531            !!!emit ($self->{ct});
4532          redo A;          redo A;
4533        } else {        } else {
4534          ## XML5: Not defined yet.          ## XML5: Not defined yet.
4535            if ($self->{ca}->{default} eq 'FIXED') {
4536              $self->{state} = ATTRIBUTE_VALUE_UNQUOTED_STATE;
4537            } else {
4538              push @{$self->{ct}->{attrdefs}}, $self->{ca};
4539              $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4540            }
4541            ## Reconsume.
4542            redo A;
4543          }
4544        } elsif ($self->{state} == AFTER_ATTLIST_ATTR_VALUE_QUOTED_STATE) {
4545          if ($is_space->{$self->{nc}} or
4546              $self->{nc} == -1 or
4547              $self->{nc} == 0x003E) { # >
4548            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4549            ## Reconsume.
4550            redo A;
4551          } else {
4552            !!!parse-error (type => 'no space before attr name'); ## TODO: type
4553            $self->{state} = DOCTYPE_ATTLIST_NAME_AFTER_STATE;
4554            ## Reconsume.
4555            redo A;
4556          }
4557        } elsif ($self->{state} == NDATA_STATE) {
4558          ## ASCII case-insensitive
4559          if ($self->{nc} == [
4560                undef,
4561                0x0044, # D
4562                0x0041, # A
4563                0x0054, # T
4564              ]->[length $self->{kwd}] or
4565              $self->{nc} == [
4566                undef,
4567                0x0064, # d
4568                0x0061, # a
4569                0x0074, # t
4570              ]->[length $self->{kwd}]) {
4571            !!!cp (172.2);
4572            ## Stay in the state.
4573            $self->{kwd} .= chr $self->{nc};
4574            !!!next-input-character;
4575            redo A;
4576          } elsif ((length $self->{kwd}) == 4 and
4577                   ($self->{nc} == 0x0041 or # A
4578                    $self->{nc} == 0x0061)) { # a
4579            if ($self->{kwd} ne 'NDAT' or $self->{nc} == 0x0061) { # a
4580              !!!cp (172.3);
4581              !!!parse-error (type => 'lowercase keyword', ## TODO: type
4582                              text => 'NDATA',
4583                              line => $self->{line_prev},
4584                              column => $self->{column_prev} - 4);
4585            } else {
4586              !!!cp (172.4);
4587            }
4588            $self->{state} = AFTER_NDATA_STATE;
4589            !!!next-input-character;
4590            redo A;
4591          } else {
4592            !!!parse-error (type => 'string after literal', ## TODO: type
4593                            line => $self->{line_prev},
4594                            column => $self->{column_prev} + 1
4595                                - length $self->{kwd});
4596            !!!cp (172.5);
4597            $self->{state} = BOGUS_MD_STATE;
4598            ## Reconsume.
4599            redo A;
4600          }
4601        } elsif ($self->{state} == AFTER_NDATA_STATE) {
4602          if ($is_space->{$self->{nc}}) {
4603            $self->{state} = BEFORE_NOTATION_NAME_STATE;
4604            !!!next-input-character;
4605            redo A;
4606          } elsif ($self->{nc} == 0x003E) { # >
4607            !!!parse-error (type => 'no notation name'); ## TODO: type
4608            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4609            !!!next-input-character;
4610            !!!emit ($self->{ct}); # ENTITY
4611            redo A;
4612          } elsif ($self->{nc} == -1) {
4613            !!!parse-error (type => 'unclosed md'); ## TODO: type
4614            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4615            !!!next-input-character;
4616            !!!emit ($self->{ct}); # ENTITY
4617            redo A;
4618          } else {
4619            !!!parse-error (type => 'string after literal', ## TODO: type
4620                            line => $self->{line_prev},
4621                            column => $self->{column_prev} + 1
4622                                - length $self->{kwd});
4623            $self->{state} = BOGUS_MD_STATE;
4624            ## Reconsume.
4625            redo A;
4626          }
4627        } elsif ($self->{state} == BEFORE_NOTATION_NAME_STATE) {
4628          if ($is_space->{$self->{nc}}) {
4629            ## Stay in the state.
4630            !!!next-input-character;
4631            redo A;
4632          } elsif ($self->{nc} == 0x003E) { # >
4633            !!!parse-error (type => 'no notation name'); ## TODO: type
4634            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4635            !!!next-input-character;
4636            !!!emit ($self->{ct}); # ENTITY
4637            redo A;
4638          } elsif ($self->{nc} == -1) {
4639            !!!parse-error (type => 'unclosed md'); ## TODO: type
4640            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4641            !!!next-input-character;
4642            !!!emit ($self->{ct}); # ENTITY
4643            redo A;
4644          } else {
4645            $self->{ct}->{notation} = chr $self->{nc}; # ENTITY
4646            $self->{state} = NOTATION_NAME_STATE;
4647            !!!next-input-character;
4648            redo A;
4649          }
4650        } elsif ($self->{state} == NOTATION_NAME_STATE) {
4651          if ($is_space->{$self->{nc}}) {
4652            $self->{state} = AFTER_NOTATION_NAME_STATE;
4653            !!!next-input-character;
4654            redo A;
4655          } elsif ($self->{nc} == 0x003E) { # >
4656            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4657            !!!next-input-character;
4658            !!!emit ($self->{ct}); # ENTITY
4659            redo A;
4660          } elsif ($self->{nc} == -1) {
4661            !!!parse-error (type => 'unclosed md'); ## TODO: type
4662            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4663            !!!next-input-character;
4664            !!!emit ($self->{ct}); # ENTITY
4665            redo A;
4666          } else {
4667            $self->{ct}->{notation} .= chr $self->{nc}; # ENTITY
4668            ## Stay in the state.
4669            !!!next-input-character;
4670            redo A;
4671          }
4672        } elsif ($self->{state} == AFTER_NOTATION_NAME_STATE) {
4673          if ($is_space->{$self->{nc}}) {
4674            ## Stay in the state.
4675            !!!next-input-character;
4676            redo A;
4677          } elsif ($self->{nc} == 0x003E) { # >
4678            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4679            !!!next-input-character;
4680            !!!emit ($self->{ct}); # ENTITY
4681            redo A;
4682          } elsif ($self->{nc} == -1) {
4683            !!!parse-error (type => 'unclosed md'); ## TODO: type
4684            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4685            !!!next-input-character;
4686            !!!emit ($self->{ct}); # ENTITY
4687            redo A;
4688          } else {
4689            !!!parse-error (type => 'string after notation name'); ## TODO: type
4690            $self->{state} = BOGUS_MD_STATE;
4691            ## Reconsume.
4692            redo A;
4693          }
4694    
         ## TODO: ...  
4695    
4696          $self->{state} = BOGUS_COMMENT_STATE;      } elsif ($self->{state} == BOGUS_MD_STATE) {
4697          $self->{ct} = {type => COMMENT_TOKEN, data => ''}; ## Will be discarded        if ($self->{nc} == 0x003E) { # >
4698            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4699            !!!next-input-character;
4700            !!!emit ($self->{ct}); # ATTLIST/ENTITY/NOTATION
4701            redo A;
4702          } elsif ($self->{nc} == -1) {
4703            $self->{state} = DOCTYPE_INTERNAL_SUBSET_STATE;
4704          ## Reconsume.          ## Reconsume.
4705            !!!emit ($self->{ct}); # ATTLIST/ENTITY/NOTATION
4706            redo A;
4707          } else {
4708            ## Stay in the state.
4709            !!!next-input-character;
4710          redo A;          redo A;
4711        }        }
   
4712      } else {      } else {
4713        die "$0: $self->{state}: Unknown state";        die "$0: $self->{state}: Unknown state";
4714      }      }
# Line 3753  sub _get_next_token ($) { Line 4719  sub _get_next_token ($) {
4719    
4720  1;  1;
4721  ## $Date$  ## $Date$
4722                                    

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.18

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24