Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/_speedups.c @ 656:2b1c7a68f913
Enable indexed access to lists in the configuration using an access path string representation like "~NNN~"
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 30 May 2022 09:31:29 +0200 |
| parents | 999cfca55d25 |
| children | 193a616e0b3c |
comparison
equal
deleted
inserted
replaced
| 655:b74f20e19c01 | 656:2b1c7a68f913 |
|---|---|
| 69 } | 69 } |
| 70 } | 70 } |
| 71 } | 71 } |
| 72 } | 72 } |
| 73 *result = r; | 73 *result = r; |
| 74 return 0; /* success */ | |
| 75 } | |
| 76 | |
| 77 | |
| 78 static | |
| 79 int | |
| 80 _dec2num(PyObject *s, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *result) | |
| 81 { | |
| 82 Py_ssize_t i; | |
| 83 Py_UCS4 c; | |
| 84 Py_ssize_t r = 0; | |
| 85 int sign = 0; | |
| 86 | |
| 87 for (i=start; i<=end; i++) { | |
| 88 /* Overflow error check */ | |
| 89 if (r > 3275) { | |
| 90 PyErr_SetString(PyExc_OverflowError, "index too large"); | |
| 91 return -1; | |
| 92 } | |
| 93 r *= 10; | |
| 94 c = PyUnicode_ReadChar(s, i); | |
| 95 if ((c >= 48) && (c <= 57)) { /* 0 - 9 */ | |
| 96 r += (c - 48); | |
| 97 } | |
| 98 else { | |
| 99 if (i == start) { | |
| 100 /* check for number sign (but only at the first index) */ | |
| 101 if (c == 0x2d) { | |
| 102 sign = -1; | |
| 103 continue; | |
| 104 } | |
| 105 else { | |
| 106 if (c == 0x2b) { | |
| 107 sign = 1; | |
| 108 continue; | |
| 109 } | |
| 110 } | |
| 111 } | |
| 112 PyErr_Format(PyExc_ValueError, "invalid base-10 literal: %c", (int)c); | |
| 113 return -1; | |
| 114 } | |
| 115 } | |
| 116 if (sign >= 0) { | |
| 117 *result = r; | |
| 118 } | |
| 119 else { | |
| 120 *result = -r; | |
| 121 } | |
| 74 return 0; /* success */ | 122 return 0; /* success */ |
| 75 } | 123 } |
| 76 | 124 |
| 77 | 125 |
| 78 #if defined(Py_LIMITED_API) | 126 #if defined(Py_LIMITED_API) |
| 290 } | 338 } |
| 291 } | 339 } |
| 292 if (s_len == 0) { | 340 if (s_len == 0) { |
| 293 return Py_NewRef(s); | 341 return Py_NewRef(s); |
| 294 } | 342 } |
| 343 if (s_len > 2) { | |
| 344 /* Check for ~NNN~ syntax */ | |
| 345 c = PyUnicode_ReadChar(s, 0); | |
| 346 if (c == 0x7e) { | |
| 347 c = PyUnicode_ReadChar(s, s_len - 1); | |
| 348 if (c == 0x7e) { | |
| 349 if (_dec2num(s, 1, s_len - 2, &i) == 0) { | |
| 350 return PyLong_FromSsize_t(i); | |
| 351 } | |
| 352 PyErr_Clear(); | |
| 353 } | |
| 354 } | |
| 355 } | |
| 295 find = PyUnicode_FindChar(s, '%', 0, s_len, 1); | 356 find = PyUnicode_FindChar(s, '%', 0, s_len, 1); |
| 296 if (find == -2) { | 357 if (find == -2) { |
| 297 return NULL; | 358 return NULL; |
| 298 } | 359 } |
| 299 if (find == -1) { | 360 if (find == -1) { |
| 427 int need_quoting; | 488 int need_quoting; |
| 428 struct speedups_state *sstate; | 489 struct speedups_state *sstate; |
| 429 | 490 |
| 430 s_len = PyUnicode_GetLength(s); | 491 s_len = PyUnicode_GetLength(s); |
| 431 if (s_len < 0) { | 492 if (s_len < 0) { |
| 493 if (PyObject_IsInstance(s, (PyObject *)&PyLong_Type)) { | |
| 494 PyErr_Clear(); | |
| 495 return PyUnicode_FromFormat("~%S~", s); | |
| 496 } | |
| 497 PyErr_SetString(PyExc_TypeError, "given object has no len()"); | |
| 432 return NULL; | 498 return NULL; |
| 433 } | 499 } |
| 434 if (s_len == 0) { | 500 if (s_len == 0) { |
| 435 return Py_NewRef(s); | 501 return Py_NewRef(s); |
| 436 } | 502 } |
| 447 case 0x27: | 513 case 0x27: |
| 448 case 0x7b: | 514 case 0x7b: |
| 449 case 0x7d: | 515 case 0x7d: |
| 450 case 0x5b: | 516 case 0x5b: |
| 451 case 0x5d: | 517 case 0x5d: |
| 518 case 0x7e: | |
| 452 need_quoting = 1; | 519 need_quoting = 1; |
| 453 i = s_len; /* break the for-loop */ | 520 i = s_len; /* break the for-loop */ |
| 454 break; | 521 break; |
| 455 default: | 522 default: |
| 456 /* VOID */ | 523 /* VOID */ |
| 1636 return -1; | 1703 return -1; |
| 1637 } | 1704 } |
| 1638 PyUnicode_InternInPlace(&(sstate->EMPTY_STR)); | 1705 PyUnicode_InternInPlace(&(sstate->EMPTY_STR)); |
| 1639 | 1706 |
| 1640 sstate->QUOTE_MAP = Py_BuildValue( | 1707 sstate->QUOTE_MAP = Py_BuildValue( |
| 1641 "{IsIsIsIsIsIsIsIsIsIsIs}", | 1708 "{IsIsIsIsIsIsIsIsIsIsIsIs}", |
| 1642 0x25, "%x25", /* QUOTE: % */ | 1709 0x25, "%x25", /* QUOTE: % */ |
| 1643 0x2e, "%x2e", /* DOT: . */ | 1710 0x2e, "%x2e", /* DOT: . */ |
| 1644 0x3a, "%x3a", /* NS_SEPARATOR: : */ | 1711 0x3a, "%x3a", /* NS_SEPARATOR: : */ |
| 1645 0x23, "%x23", /* COMMENT/anchor: # */ | 1712 0x23, "%x23", /* COMMENT/anchor: # */ |
| 1646 0x7c, "%x7c", /* FILTER_SEPARATOR: | */ | 1713 0x7c, "%x7c", /* FILTER_SEPARATOR: | */ |
| 1647 0x22, "%x22", | 1714 0x22, "%x22", |
| 1648 0x27, "%x27", | 1715 0x27, "%x27", |
| 1649 0x7b, "%x7b", | 1716 0x7b, "%x7b", |
| 1650 0x7d, "%x7d", | 1717 0x7d, "%x7d", |
| 1651 0x5b, "%x5b", | 1718 0x5b, "%x5b", |
| 1652 0x5d, "%x5d"); | 1719 0x5d, "%x5d", |
| 1720 0x7e, "%x7e"); /* tilde ~ */ | |
| 1653 if (sstate->QUOTE_MAP == NULL) { | 1721 if (sstate->QUOTE_MAP == NULL) { |
| 1654 return -1; | 1722 return -1; |
| 1655 } | 1723 } |
| 1656 | 1724 |
| 1657 sstate->STARTTOK = PyUnicode_FromStringAndSize("{{", 2); | 1725 sstate->STARTTOK = PyUnicode_FromStringAndSize("{{", 2); |
