summaryrefslogtreecommitdiffstats
path: root/src/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.c')
-rw-r--r--src/common.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/common.c b/src/common.c
new file mode 100644
index 0000000..810c2e0
--- /dev/null
+++ b/src/common.c
@@ -0,0 +1,115 @@
+/*
+ * 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 <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#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;
+}