… | |
… | |
77 | |
77 | |
78 | enum { |
78 | enum { |
79 | INCR_M_WS = 0, // initial whitespace skipping, must be 0 |
79 | INCR_M_WS = 0, // initial whitespace skipping, must be 0 |
80 | INCR_M_STR, // inside string |
80 | INCR_M_STR, // inside string |
81 | INCR_M_BS, // inside backslash |
81 | INCR_M_BS, // inside backslash |
|
|
82 | INCR_M_C0, // inside comment in initial whitespace sequence |
|
|
83 | INCR_M_C1, // inside comment in other places |
82 | INCR_M_JSON // outside anything, count nesting |
84 | INCR_M_JSON // outside anything, count nesting |
83 | }; |
85 | }; |
84 | |
86 | |
85 | #define INCR_DONE(json) ((json)->incr_nest <= 0 && (json)->incr_mode == INCR_M_JSON) |
87 | #define INCR_DONE(json) ((json)->incr_nest <= 0 && (json)->incr_mode == INCR_M_JSON) |
86 | |
88 | |
… | |
… | |
1526 | static void |
1528 | static void |
1527 | incr_parse (JSON *self) |
1529 | incr_parse (JSON *self) |
1528 | { |
1530 | { |
1529 | const char *p = SvPVX (self->incr_text) + self->incr_pos; |
1531 | const char *p = SvPVX (self->incr_text) + self->incr_pos; |
1530 | |
1532 | |
|
|
1533 | // the state machine here is a bit convoluted and could be simplified a lot |
|
|
1534 | // but this would make it slower, so... |
|
|
1535 | |
1531 | for (;;) |
1536 | for (;;) |
1532 | { |
1537 | { |
1533 | //printf ("loop pod %d *p<%c><%s>, mode %d nest %d\n", p - SvPVX (self->incr_text), *p, p, self->incr_mode, self->incr_nest);//D |
1538 | //printf ("loop pod %d *p<%c><%s>, mode %d nest %d\n", p - SvPVX (self->incr_text), *p, p, self->incr_mode, self->incr_nest);//D |
1534 | switch (self->incr_mode) |
1539 | switch (self->incr_mode) |
1535 | { |
1540 | { |
1536 | // only used for intiial whitespace skipping |
1541 | // only used for initial whitespace skipping |
1537 | case INCR_M_WS: |
1542 | case INCR_M_WS: |
1538 | for (;;) |
1543 | for (;;) |
1539 | { |
1544 | { |
1540 | if (*p > 0x20) |
1545 | if (*p > 0x20) |
1541 | { |
1546 | { |
|
|
1547 | if (*p == '#') |
|
|
1548 | { |
|
|
1549 | self->incr_mode = INCR_M_C0; |
|
|
1550 | goto incr_m_c; |
|
|
1551 | } |
|
|
1552 | else |
|
|
1553 | { |
1542 | self->incr_mode = INCR_M_JSON; |
1554 | self->incr_mode = INCR_M_JSON; |
1543 | goto incr_m_json; |
1555 | goto incr_m_json; |
|
|
1556 | } |
1544 | } |
1557 | } |
1545 | else if (!*p) |
1558 | else if (!*p) |
1546 | goto interrupt; |
1559 | goto interrupt; |
1547 | |
1560 | |
1548 | ++p; |
1561 | ++p; |
… | |
… | |
1554 | goto interrupt; |
1567 | goto interrupt; |
1555 | |
1568 | |
1556 | ++p; |
1569 | ++p; |
1557 | self->incr_mode = INCR_M_STR; |
1570 | self->incr_mode = INCR_M_STR; |
1558 | goto incr_m_str; |
1571 | goto incr_m_str; |
|
|
1572 | |
|
|
1573 | // inside #-style comments |
|
|
1574 | case INCR_M_C0: |
|
|
1575 | case INCR_M_C1: |
|
|
1576 | incr_m_c: |
|
|
1577 | for (;;) |
|
|
1578 | { |
|
|
1579 | if (*p == '\n') |
|
|
1580 | { |
|
|
1581 | self->incr_mode = self->incr_mode == INCR_M_C0 ? INCR_M_WS : INCR_M_JSON; |
|
|
1582 | break; |
|
|
1583 | } |
|
|
1584 | else if (!*p) |
|
|
1585 | goto interrupt; |
|
|
1586 | |
|
|
1587 | ++p; |
|
|
1588 | } |
|
|
1589 | |
|
|
1590 | break; |
1559 | |
1591 | |
1560 | // inside a string |
1592 | // inside a string |
1561 | case INCR_M_STR: |
1593 | case INCR_M_STR: |
1562 | incr_m_str: |
1594 | incr_m_str: |
1563 | for (;;) |
1595 | for (;;) |
… | |
… | |
1622 | |
1654 | |
1623 | case ']': |
1655 | case ']': |
1624 | case '}': |
1656 | case '}': |
1625 | if (--self->incr_nest <= 0) |
1657 | if (--self->incr_nest <= 0) |
1626 | goto interrupt; |
1658 | goto interrupt; |
|
|
1659 | break; |
|
|
1660 | |
|
|
1661 | case '#': |
|
|
1662 | self->incr_mode = INCR_M_C1; |
|
|
1663 | goto incr_m_c; |
1627 | } |
1664 | } |
1628 | } |
1665 | } |
1629 | } |
1666 | } |
1630 | |
1667 | |
1631 | modechange: |
1668 | modechange: |
1632 | ; |
1669 | ; |
1633 | } |
1670 | } |
1634 | |
1671 | |
1635 | interrupt: |
1672 | interrupt: |
1636 | self->incr_pos = p - SvPVX (self->incr_text); |
1673 | self->incr_pos = p - SvPVX (self->incr_text); |
|
|
1674 | //printf ("interrupt<%.*s>\n", self->incr_pos, SvPVX(self->incr_text));//D |
1637 | //printf ("return pos %d mode %d nest %d\n", self->incr_pos, self->incr_mode, self->incr_nest);//D |
1675 | //printf ("return pos %d mode %d nest %d\n", self->incr_pos, self->incr_mode, self->incr_nest);//D |
1638 | } |
1676 | } |
1639 | |
1677 | |
1640 | ///////////////////////////////////////////////////////////////////////////// |
1678 | ///////////////////////////////////////////////////////////////////////////// |
1641 | // XS interface functions |
1679 | // XS interface functions |