changeset 825:93d6c996250f

val: add val_cmp Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 30 Dec 2020 10:34:10 -0500
parents 562d1c61194e
children 18a4409b6f88
files include/jeffpc/val.h mapfile-vers val.c
diffstat 3 files changed, 53 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/include/jeffpc/val.h	Sat Dec 26 10:43:42 2020 -0500
+++ b/include/jeffpc/val.h	Wed Dec 30 10:34:10 2020 -0500
@@ -266,6 +266,7 @@
 #define str_cmp(a, b)	_strsym_cmp(&(a)->val, &(b)->val)
 #define sym_cmp(a, b)	_strsym_cmp(&(a)->val, &(b)->val)
 extern int _strsym_cmp(const struct val *a, const struct val *b);
+extern int val_cmp(const struct val *a, const struct val *b);
 
 extern struct str *str_cat(size_t n, ...);
 extern struct str *str_printf(const char *fmt, ...)
--- a/mapfile-vers	Sat Dec 26 10:43:42 2020 -0500
+++ b/mapfile-vers	Wed Dec 30 10:34:10 2020 -0500
@@ -314,6 +314,7 @@
 
 		# val
 		__val_typename;
+		val_cmp;
 		val_dump_file;
 		val_free;
 		val_alloc_array;
--- a/val.c	Sat Dec 26 10:43:42 2020 -0500
+++ b/val.c	Wed Dec 30 10:34:10 2020 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2014-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -261,3 +261,53 @@
 
 	return val;
 }
+
+int val_cmp(const struct val *a, const struct val *b)
+{
+	if (a == b)
+		return 0;
+
+	if (a->type != b->type)
+		return (a->type < b->type) ? -1 : +1;
+
+	switch (a->type) {
+		case VT_STR:
+		case VT_SYM:
+			return strcmp(val_cstr(a), val_cstr(b));
+		case VT_INT:
+		case VT_CHAR:
+			if (a->i < b->i)
+				return -1;
+			if (a->i > b->i)
+				return +1;
+			return 0;
+		case VT_BOOL:
+			if (!a->b && b->b)
+				return -1;
+			if (a->b && !b->b)
+				return +1;
+			return 0;
+		case VT_NULL:
+			return 0;
+		case VT_BLOB: {
+			int ret;
+
+			ret = memcmp(a->blob.ptr, b->blob.ptr,
+				     MIN(a->blob.size, b->blob.size));
+			if (ret)
+				return ret;
+
+			if (a->blob.size < b->blob.size)
+				return -1;
+			if (a->blob.size > b->blob.size)
+				return +1;
+			return 0;
+		}
+		case VT_CONS:
+		case VT_ARRAY:
+		case VT_NVL:
+			panic("not yet implemented");
+	}
+
+	panic("unknown val type %d (%s)", a->type, val_typename(a->type));
+}