* Parses the metadata string into the metadata C structure. * * Returns 0 on success, -1 on failure. */
| 801 | * Returns 0 on success, -1 on failure. |
| 802 | */ |
| 803 | NPY_NO_EXPORT int |
| 804 | parse_datetime_metadata_from_metastr(char const *metastr, Py_ssize_t len, |
| 805 | PyArray_DatetimeMetaData *out_meta) |
| 806 | { |
| 807 | char const *substr = metastr, *substrend = NULL; |
| 808 | |
| 809 | /* Treat the empty string as generic units */ |
| 810 | if (len == 0) { |
| 811 | out_meta->base = NPY_FR_GENERIC; |
| 812 | out_meta->num = 1; |
| 813 | |
| 814 | return 0; |
| 815 | } |
| 816 | |
| 817 | /* The metadata string must start with a '[' */ |
| 818 | if (len < 3 || *substr++ != '[') { |
| 819 | goto bad_input; |
| 820 | } |
| 821 | |
| 822 | substrend = substr; |
| 823 | while (substrend - metastr < len && *substrend != ']') { |
| 824 | ++substrend; |
| 825 | } |
| 826 | if (substrend - metastr == len || substr == substrend) { |
| 827 | substr = substrend; |
| 828 | goto bad_input; |
| 829 | } |
| 830 | |
| 831 | /* Parse the extended unit inside the [] */ |
| 832 | if (parse_datetime_extended_unit_from_string(substr, substrend-substr, |
| 833 | metastr, out_meta) < 0) { |
| 834 | return -1; |
| 835 | } |
| 836 | |
| 837 | substr = substrend+1; |
| 838 | |
| 839 | if (substr - metastr != len) { |
| 840 | goto bad_input; |
| 841 | } |
| 842 | |
| 843 | return 0; |
| 844 | |
| 845 | bad_input: |
| 846 | if (substr != metastr) { |
| 847 | PyErr_Format(PyExc_TypeError, |
| 848 | "Invalid datetime metadata string \"%s\" at position %zd", |
| 849 | metastr, substr - metastr); |
| 850 | } |
| 851 | else { |
| 852 | PyErr_Format(PyExc_TypeError, |
| 853 | "Invalid datetime metadata string \"%s\"", |
| 854 | metastr); |
| 855 | } |
| 856 | |
| 857 | return -1; |
| 858 | } |
| 859 | |
| 860 | /* |
no test coverage detected