/* * common.c * contains some common functions * * Copyright (c) 2026 Nikias Bassen, All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "common.h" size_t dtostr(char *buf, size_t bufsize, double realval) { int slen = 0; if (isnan(realval)) { slen = snprintf(buf, bufsize, "nan"); } else if (isinf(realval)) { slen = snprintf(buf, bufsize, "%cinfinity", (realval > 0.0) ? '+' : '-'); } else if (realval == 0.0f) { slen = snprintf(buf, bufsize, "0.0"); } else { slen = snprintf(buf, bufsize, "%.*g", 17, realval); if (slen < 0) { return 0; } if (!buf || bufsize == 0) { return (size_t)slen; } size_t len = (size_t)slen; if (len >= bufsize) { len = bufsize - 1; } size_t i = 0; for (i = 0; i < len; i++) { if (buf[i] == ',') { buf[i] = '.'; break; } else if (buf[i] == '.') { break; } } return len; } if (slen < 0) { return 0; } return (size_t)slen; } /* based on https://stackoverflow.com/a/4143288 */ #define PO10i_LIMIT (INT64_MAX/10) int num_digits_i(int64_t i) { int n; int64_t po10; n=1; if (i < 0) { i = (i == INT64_MIN) ? INT64_MAX : -i; n++; } po10=10; while (i>=po10) { n++; if (po10 > PO10i_LIMIT) break; po10*=10; } return n; } #undef PO10i_LIMIT /* based on https://stackoverflow.com/a/4143288 */ #define PO10u_LIMIT (UINT64_MAX/10) int num_digits_u(uint64_t i) { int n; uint64_t po10; n=1; po10=10; while (i>=po10) { n++; if (po10 > PO10u_LIMIT) break; po10*=10; } return n; } #undef PO10u_LIMIT int plist_real_to_time64(double realval, Time64_T *timev) { if (!timev || !isfinite(realval)) { return -1; } if (realval < (double)TIME64_MIN - (double)MAC_EPOCH || realval > (double)TIME64_MAX - (double)MAC_EPOCH) { return -1; } *timev = (Time64_T)realval + MAC_EPOCH; return 0; }