* Sets the following fields in the PyUFuncObject 'ufunc': * * Field Type Array Length * core_enabled int (effectively bool) N/A * core_num_dim_ix int N/A * core_dim_flags npy_uint32 * core_num_dim_ix * core_dim_sizes npy_intp * core_num_dim_ix * core_num_dims int * nargs (i.e
| 643 | * Returns 0 unless an error occurred. |
| 644 | */ |
| 645 | static int |
| 646 | _parse_signature(PyUFuncObject *ufunc, const char *signature) |
| 647 | { |
| 648 | size_t len; |
| 649 | char const **var_names; |
| 650 | int nd = 0; /* number of dimension of the current argument */ |
| 651 | int cur_arg = 0; /* index into core_num_dims&core_offsets */ |
| 652 | int cur_core_dim = 0; /* index into core_dim_ixs */ |
| 653 | int i = 0; |
| 654 | char *parse_error = NULL; |
| 655 | |
| 656 | if (signature == NULL) { |
| 657 | PyErr_SetString(PyExc_RuntimeError, |
| 658 | "_parse_signature with NULL signature"); |
| 659 | return -1; |
| 660 | } |
| 661 | len = strlen(signature); |
| 662 | ufunc->core_signature = PyArray_malloc(sizeof(char) * (len+1)); |
| 663 | if (ufunc->core_signature) { |
| 664 | strcpy(ufunc->core_signature, signature); |
| 665 | } |
| 666 | /* Allocate sufficient memory to store pointers to all dimension names */ |
| 667 | var_names = PyArray_malloc(sizeof(char const*) * len); |
| 668 | if (var_names == NULL) { |
| 669 | PyErr_NoMemory(); |
| 670 | return -1; |
| 671 | } |
| 672 | |
| 673 | ufunc->core_enabled = 1; |
| 674 | ufunc->core_num_dim_ix = 0; |
| 675 | ufunc->core_num_dims = PyArray_malloc(sizeof(int) * ufunc->nargs); |
| 676 | ufunc->core_offsets = PyArray_malloc(sizeof(int) * ufunc->nargs); |
| 677 | /* The next three items will be shrunk later */ |
| 678 | ufunc->core_dim_ixs = PyArray_malloc(sizeof(int) * len); |
| 679 | ufunc->core_dim_sizes = PyArray_malloc(sizeof(npy_intp) * len); |
| 680 | ufunc->core_dim_flags = PyArray_malloc(sizeof(npy_uint32) * len); |
| 681 | |
| 682 | if (ufunc->core_num_dims == NULL || ufunc->core_dim_ixs == NULL || |
| 683 | ufunc->core_offsets == NULL || |
| 684 | ufunc->core_dim_sizes == NULL || |
| 685 | ufunc->core_dim_flags == NULL) { |
| 686 | PyErr_NoMemory(); |
| 687 | goto fail; |
| 688 | } |
| 689 | for (size_t j = 0; j < len; j++) { |
| 690 | ufunc->core_dim_flags[j] = 0; |
| 691 | } |
| 692 | |
| 693 | i = _next_non_white_space(signature, 0); |
| 694 | while (signature[i] != '\0') { |
| 695 | /* loop over input/output arguments */ |
| 696 | if (cur_arg == ufunc->nin) { |
| 697 | /* expect "->" */ |
| 698 | if (signature[i] != '-' || signature[i+1] != '>') { |
| 699 | parse_error = "expect '->'"; |
| 700 | goto fail; |
| 701 | } |
| 702 | i = _next_non_white_space(signature, i + 2); |
no test coverage detected