aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-12-21 14:08:57 +0100
committerMattias Andrée <m@maandree.se>2025-12-21 14:13:45 +0100
commit095193a9905caff27509a299d895d399d42c06aa (patch)
tree48b1bcf860866029d9081cf9ecd72388658cfbb9
parentAdd range print functions (diff)
downloadlibcmap-095193a9905caff27509a299d895d399d42c06aa.tar.gz
libcmap-095193a9905caff27509a299d895d399d42c06aa.tar.bz2
libcmap-095193a9905caff27509a299d895d399d42c06aa.tar.xz
Fix truncation issue in libcmap_sprintf_range, and add LIBCMAP_ULTIMATE_CODEPOINT and LIBCMAP_UNIVERSE_RANGE
Signed-off-by: Mattias Andrée <m@maandree.se>
-rw-r--r--Blocks.parse.c10
-rw-r--r--Makefile3
-rw-r--r--Scripts.parse.c6
-rw-r--r--common.h15
-rw-r--r--libcmap.h4
-rw-r--r--libcmap_block_list.c2
-rw-r--r--libcmap_find_block.c2
-rw-r--r--libcmap_find_in_no_block.c2
-rw-r--r--libcmap_find_script.c2
-rw-r--r--libcmap_script_list.c2
-rw-r--r--libcmap_snprint_range.c12
-rw-r--r--libcmap_sprint_range.c10
-rw-r--r--parse-common.c3
13 files changed, 48 insertions, 25 deletions
diff --git a/Blocks.parse.c b/Blocks.parse.c
index bb61704..3f93764 100644
--- a/Blocks.parse.c
+++ b/Blocks.parse.c
@@ -28,13 +28,13 @@ parse_line(char *text, size_t lineno)
}
high = low = strtoul(text, &text, 16);
- if (errno || low > 0x10FFFFUL)
+ if (errno || low > ULTIMATE_CODEPOINT)
goto malformat;
if (text[0] == '.' && text[1] == '.') {
if (!isxdigit(text[2]))
goto malformat;
high = strtoul(&text[2], &text, 16);
- if (errno || high > 0x10FFFFUL || high < low)
+ if (errno || high > ULTIMATE_CODEPOINT || high < low)
goto malformat;
}
while (isspace(*text))
@@ -116,7 +116,7 @@ output(void)
for (i = 1U; i < nblocks; i++)
if (blocks[i].low > blocks[i - 1U].high + 1U)
break;
- if (i == nblocks && blocks[i - 1U].high == 0x10FFFFUL) {
+ if (i == nblocks && blocks[i - 1U].high == ULTIMATE_CODEPOINT) {
x |= printf("const struct libcmap_script libcmap_no_block = {\"No Block\", NULL, 0};\n");
} else {
x |= printf("static const struct libcmap_range No_Block[] = {\n");
@@ -124,8 +124,8 @@ output(void)
for (i++; i < nblocks; i++)
if (blocks[i].low > blocks[i - 1U].high + 1)
x |= printf(",\n\t{0x%04lX, 0x%04lX}", blocks[i - 1U].high + 1U, blocks[i].low - 1U);
- if (blocks[i - 1U].high < 0x10FFFFUL)
- x |= printf(",\n\t{0x%04lX, 0x10FFFFUL}", blocks[i - 1U].high + 1U);
+ if (blocks[i - 1U].high < ULTIMATE_CODEPOINT)
+ x |= printf(",\n\t{0x%04lX, LIBCMAP_ULTIMATE_CODEPOINT}", blocks[i - 1U].high + 1U);
x |= printf("\n};\n");
x |= printf("const struct libcmap_script libcmap_no_block = ");
x |= printf("{\"No Block\", No_Block, sizeof(No_Block) / sizeof(*No_Block)};\n");
diff --git a/Makefile b/Makefile
index 8f20ec3..4966165 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,8 @@ OBJ =\
libcmap_snprint_range.o
HDR =\
- libcmap.h
+ libcmap.h\
+ common.h
LOBJ = $(OBJ:.o=.lo)
diff --git a/Scripts.parse.c b/Scripts.parse.c
index d5d167b..60ddfe9 100644
--- a/Scripts.parse.c
+++ b/Scripts.parse.c
@@ -79,13 +79,13 @@ parse_line(char *text, size_t lineno)
}
high = low = strtoul(text, &text, 16);
- if (errno || low > 0x10FFFFUL)
+ if (errno || low > ULTIMATE_CODEPOINT)
goto malformat;
if (text[0] == '.' && text[1] == '.') {
if (!isxdigit(text[2]))
goto malformat;
high = strtoul(&text[2], &text, 16);
- if (errno || high > 0x10FFFFUL || high < low)
+ if (errno || high > ULTIMATE_CODEPOINT || high < low)
goto malformat;
}
while (isspace(*text))
@@ -218,7 +218,7 @@ output(void)
}
nranges = 1U;
ranges[0].low = 0;
- ranges[0].high = 0x10FFFF;
+ ranges[0].high = ULTIMATE_CODEPOINT;
for (i = 0; i < nscripts; i++) {
scripts[i].nranges = join_ranges(scripts[i].ranges, scripts[i].nranges);
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..c5fc285
--- /dev/null
+++ b/common.h
@@ -0,0 +1,15 @@
+/* See LICENSE file for copyright and license details. */
+#include "libcmap.h"
+#include <limits.h>
+#include <stdio.h>
+
+
+#define SINGLETON_RANGE_FMT "U+%04lX"
+#define SINGLETON_RANGE_ARGS(RANGE)\
+ (unsigned long int)((RANGE)->first)
+
+#define RANGE_FMT "U+%04lX%sU+%04lX"
+#define RANGE_ARGS(RANGE, ENDASH)\
+ (unsigned long int)((RANGE)->first),\
+ ((ENDASH) ? (ENDASH) : "–"),\
+ (unsigned long int)((RANGE)->last)
diff --git a/libcmap.h b/libcmap.h
index e849ffb..78c0a53 100644
--- a/libcmap.h
+++ b/libcmap.h
@@ -14,6 +14,10 @@
#endif
+#define LIBCMAP_ULTIMATE_CODEPOINT UINT32_C(0x10FFFF)
+#define LIBCMAP_UNIVERSE_RANGE {0, LIBCMAP_ULTIMATE_CODEPOINT}
+
+
struct libcmap_range {
uint32_t first;
uint32_t last;
diff --git a/libcmap_block_list.c b/libcmap_block_list.c
index c0d9214..aaee33d 100644
--- a/libcmap_block_list.c
+++ b/libcmap_block_list.c
@@ -1,5 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
+#include "common.h"
#include "Blocks.txt.c"
diff --git a/libcmap_find_block.c b/libcmap_find_block.c
index 974297d..75c93e5 100644
--- a/libcmap_find_block.c
+++ b/libcmap_find_block.c
@@ -1,5 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
+#include "common.h"
const struct libcmap_block *
diff --git a/libcmap_find_in_no_block.c b/libcmap_find_in_no_block.c
index 216aaa0..d443ba0 100644
--- a/libcmap_find_in_no_block.c
+++ b/libcmap_find_in_no_block.c
@@ -1,5 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
+#include "common.h"
int
diff --git a/libcmap_find_script.c b/libcmap_find_script.c
index f8787f8..844188e 100644
--- a/libcmap_find_script.c
+++ b/libcmap_find_script.c
@@ -1,5 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
+#include "common.h"
const struct libcmap_script *
diff --git a/libcmap_script_list.c b/libcmap_script_list.c
index b692073..8ccc9a5 100644
--- a/libcmap_script_list.c
+++ b/libcmap_script_list.c
@@ -1,5 +1,5 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
+#include "common.h"
#include "Scripts.txt.c"
diff --git a/libcmap_snprint_range.c b/libcmap_snprint_range.c
index 268a80e..5dd8a7e 100644
--- a/libcmap_snprint_range.c
+++ b/libcmap_snprint_range.c
@@ -1,16 +1,12 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
-#include <stdio.h>
+#include "common.h"
int
libcmap_snprint_range(char *buf, size_t bufsize, const struct libcmap_range *range, const char *endash)
{
- unsigned long int first = (unsigned long int)range->first;
- unsigned long int last = (unsigned long int)range->last;
-
- if (first == last)
- return snprintf(buf, bufsize, "U+%04lX", first);
+ if (range->first == range->last)
+ return snprintf(buf, bufsize, SINGLETON_RANGE_FMT, SINGLETON_RANGE_ARGS(range));
else
- return snprintf(buf, bufsize, "U+%04lX%sU+%04lX", first, endash ? endash : "–", last);
+ return snprintf(buf, bufsize, RANGE_FMT, RANGE_ARGS(range, endash));
}
diff --git a/libcmap_sprint_range.c b/libcmap_sprint_range.c
index 800fee5..64d762a 100644
--- a/libcmap_sprint_range.c
+++ b/libcmap_sprint_range.c
@@ -1,10 +1,14 @@
/* See LICENSE file for copyright and license details. */
-#include "libcmap.h"
-#include <limits.h>
+#include "common.h"
int
libcmap_sprint_range(char *buf, const struct libcmap_range *range, const char *endash)
{
- return libcmap_snprint_range(buf, buf ? SIZE_MAX : (size_t)0, range, endash);
+ if (!buf)
+ return libcmap_snprint_range(NULL, 0, range, endash);
+ else if (range->first == range->last)
+ return sprintf(buf, SINGLETON_RANGE_FMT, SINGLETON_RANGE_ARGS(range));
+ else
+ return sprintf(buf, RANGE_FMT, RANGE_ARGS(range, endash));
}
diff --git a/parse-common.c b/parse-common.c
index 2333a1c..4e271c6 100644
--- a/parse-common.c
+++ b/parse-common.c
@@ -7,6 +7,9 @@
#include <unistd.h>
+#define ULTIMATE_CODEPOINT 0x10FFFFUL
+
+
static const char *argv0;