comparison configmix/_speedups.c @ 550:79db28e879f8

Provide a C-implementation of configmix.config.quote() also: fast_quote
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 02 Jan 2022 02:04:07 +0100
parents 84657447ab39
children 39e5d07d8dbc
comparison
equal deleted inserted replaced
549:84657447ab39 550:79db28e879f8
21 struct speedups_state { 21 struct speedups_state {
22 PyObject *DOT; 22 PyObject *DOT;
23 PyObject *QUOTE; 23 PyObject *QUOTE;
24 PyObject *NS_SEPARATOR; 24 PyObject *NS_SEPARATOR;
25 PyObject *EMPTY_STR; 25 PyObject *EMPTY_STR;
26 PyObject *QUOTE_MAP;
26 }; 27 };
27 28
28 29
29 static 30 static
30 int 31 int
400 } 401 }
401 402
402 403
403 static 404 static
404 PyObject * 405 PyObject *
406 fast_quote(PyObject *self, PyObject *s)
407 {
408 Py_ssize_t s_len;
409 Py_ssize_t i;
410 Py_UCS4 c;
411 int need_quoting;
412 struct speedups_state *sstate;
413
414 s_len = PyUnicode_GetLength(s);
415 if (s_len < 0) {
416 return NULL;
417 }
418 if (s_len == 0) {
419 Py_INCREF(s);
420 return s;
421 }
422 need_quoting = 0;
423 for (i=0; i<s_len; i++) {
424 c = PyUnicode_ReadChar(s, i); /* type already checked */
425 switch (c) {
426 case 0x25:
427 case 0x2e:
428 case 0x3a:
429 case 0x23:
430 case 0x7c:
431 case 0x22:
432 case 0x27:
433 case 0x7b:
434 case 0x7d:
435 case 0x5b:
436 case 0x5d:
437 need_quoting = 1;
438 i = s_len; /* break the for-loop */
439 break;
440 default:
441 /* VOID */
442 ;
443 }
444 }
445 if (!need_quoting) {
446 Py_INCREF(s);
447 return s;
448 }
449 sstate = PyModule_GetState(self);
450 if (sstate == NULL) {
451 PyErr_SetString(PyExc_RuntimeError, "no module state available");
452 return NULL;
453 }
454 return PyUnicode_Translate(s, sstate->QUOTE_MAP, "strict");
455 }
456
457
458 static
459 PyObject *
405 fast_pathstr2path(PyObject *self, PyObject *varname) 460 fast_pathstr2path(PyObject *self, PyObject *varname)
406 { 461 {
407 Py_ssize_t varname_len; 462 Py_ssize_t varname_len;
408 PyObject *parts = NULL; 463 PyObject *parts = NULL;
409 Py_ssize_t parts_len; 464 Py_ssize_t parts_len;
518 } 573 }
519 574
520 575
521 static struct PyMethodDef speedups_methods[] = { 576 static struct PyMethodDef speedups_methods[] = {
522 {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")}, 577 {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")},
578 {"fast_quote", fast_quote, METH_O, PyDoc_STR("C-implementation of configmix.quote")},
523 {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")}, 579 {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")},
524 {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")}, 580 {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")},
525 {NULL, NULL, 0, NULL} 581 {NULL, NULL, 0, NULL}
526 }; 582 };
527 583
569 if (sstate->EMPTY_STR == NULL) { 625 if (sstate->EMPTY_STR == NULL) {
570 return -1; 626 return -1;
571 } 627 }
572 PyUnicode_InternInPlace(&(sstate->EMPTY_STR)); 628 PyUnicode_InternInPlace(&(sstate->EMPTY_STR));
573 629
630 sstate->QUOTE_MAP = Py_BuildValue(
631 "{IsIsIsIsIsIsIsIsIsIsIs}",
632 0x25, "%x25", /* QUOTE: % */
633 0x2e, "%x2e", /* DOT: . */
634 0x3a, "%x3a", /* NS_SEPARATOR: : */
635 0x23, "%x23", /* COMMENT/anchor: # */
636 0x7c, "%x7c", /* FILTER_SEPARATOR: | */
637 0x22, "%x22",
638 0x27, "%x27",
639 0x7b, "%x7b",
640 0x7d, "%x7d",
641 0x5b, "%x5b",
642 0x5d, "%x5d");
643 if (sstate->QUOTE_MAP == NULL) {
644 return -1;
645 }
646
574 return 0; 647 return 0;
575 } 648 }
576 649
577 650
578 static 651 static
584 if (sstate != NULL) { 657 if (sstate != NULL) {
585 Py_VISIT(sstate->DOT); 658 Py_VISIT(sstate->DOT);
586 Py_VISIT(sstate->QUOTE); 659 Py_VISIT(sstate->QUOTE);
587 Py_VISIT(sstate->NS_SEPARATOR); 660 Py_VISIT(sstate->NS_SEPARATOR);
588 Py_VISIT(sstate->EMPTY_STR); 661 Py_VISIT(sstate->EMPTY_STR);
662 Py_VISIT(sstate->QUOTE_MAP);
589 } 663 }
590 return 0; 664 return 0;
591 } 665 }
592 666
593 667
600 if (sstate != NULL) { 674 if (sstate != NULL) {
601 Py_CLEAR(sstate->DOT); 675 Py_CLEAR(sstate->DOT);
602 Py_CLEAR(sstate->QUOTE); 676 Py_CLEAR(sstate->QUOTE);
603 Py_CLEAR(sstate->NS_SEPARATOR); 677 Py_CLEAR(sstate->NS_SEPARATOR);
604 Py_CLEAR(sstate->EMPTY_STR); 678 Py_CLEAR(sstate->EMPTY_STR);
679 Py_CLEAR(sstate->QUOTE_MAP);
605 } 680 }
606 return 0; 681 return 0;
607 } 682 }
608 683
609 684