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);