Replace all POSIX-features to become fully ISO-C99 - libgrapheme - unicode stri… | |
git clone git://git.suckless.org/libgrapheme | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c0d28c3cad5c9e02dfa93b3ff3e6953ad0f22d75 | |
parent 0e95e5c797b1dc41117e1ea5455f2a7f2932868d | |
Author: Laslo Hunhold <[email protected]> | |
Date: Fri, 24 Feb 2023 18:21:02 +0100 | |
Replace all POSIX-features to become fully ISO-C99 | |
As it turned out, the only things that needed replacing were | |
getline(), strdup() and the timing in the benchmarks. Analogously, | |
we replace -D_DEFAULT_SOURCE with -D_ISOC99_SOURCE. | |
This way we further extend the number of platforms where libgrapheme can | |
be compiled and run on, e.g. MSVC still does not include getline(). | |
Signed-off-by: Laslo Hunhold <[email protected]> | |
Diffstat: | |
M benchmark/util.c | 13 ++++++------- | |
M config.mk | 2 +- | |
M gen/util.c | 59 ++++++++++++++++++++++++++---… | |
3 files changed, 57 insertions(+), 17 deletions(-) | |
--- | |
diff --git a/benchmark/util.c b/benchmark/util.c | |
@@ -71,10 +71,9 @@ generate_utf8_test_buffer(const struct break_test *test, siz… | |
} | |
static double | |
-time_diff(struct timespec *a, struct timespec *b) | |
+time_diff(clock_t a, clock_t b) | |
{ | |
- return (double)(b->tv_sec - a->tv_sec) + | |
- (double)(b->tv_nsec - a->tv_nsec) * 1E-9; | |
+ return (double)(b - a) / CLOCKS_PER_SEC; | |
} | |
void | |
@@ -82,14 +81,14 @@ run_benchmark(void (*func)(const void *), const void *paylo… | |
const char *comment, const char *unit, double *baseline, | |
size_t num_iterations, size_t units_per_iteration) | |
{ | |
- struct timespec start, end; | |
+ clock_t start, end; | |
size_t i; | |
double diff; | |
printf("\t%s ", name); | |
fflush(stdout); | |
- clock_gettime(CLOCK_MONOTONIC, &start); | |
+ start = clock(); | |
for (i = 0; i < num_iterations; i++) { | |
func(payload); | |
@@ -98,8 +97,8 @@ run_benchmark(void (*func)(const void *), const void *payload… | |
fflush(stdout); | |
} | |
} | |
- clock_gettime(CLOCK_MONOTONIC, &end); | |
- diff = time_diff(&start, &end) / (double)num_iterations / | |
+ end = clock(); | |
+ diff = time_diff(start, end) / (double)num_iterations / | |
(double)units_per_iteration; | |
if (isnan(*baseline)) { | |
diff --git a/config.mk b/config.mk | |
@@ -14,7 +14,7 @@ SONAME = libgrapheme.so.$(VERSION_MAJOR).$(VERSION_MINOR).… | |
BINSUFFIX = | |
# flags | |
-CPPFLAGS = -D_DEFAULT_SOURCE | |
+CPPFLAGS = -D_ISOC99_SOURCE | |
CFLAGS = -std=c99 -Os -Wall -Wextra -Wpedantic | |
LDFLAGS = -s | |
diff --git a/gen/util.c b/gen/util.c | |
@@ -146,6 +146,43 @@ range_parse(const char *str, struct range *range) | |
return 0; | |
} | |
+static bool | |
+get_line(char **buf, size_t *bufsize, FILE *fp, size_t *len) | |
+{ | |
+ int ret = EOF; | |
+ | |
+ for (*len = 0;; (*len)++) { | |
+ if (*len > 0 && *buf != NULL && (*buf)[*len - 1] == '\n') { | |
+ /* | |
+ * if the previously read character was a newline, | |
+ * we fake an end-of-file so we NUL-terminate and | |
+ * are done. | |
+ */ | |
+ ret = EOF; | |
+ } else { | |
+ ret = fgetc(fp); | |
+ } | |
+ | |
+ if (*len >= *bufsize) { | |
+ /* the buffer needs to be expanded */ | |
+ *bufsize += 512; | |
+ if ((*buf = realloc(*buf, *bufsize)) == NULL) { | |
+ fprintf(stderr, "get_line: Out of memory.\n"); | |
+ exit(1); | |
+ } | |
+ } | |
+ | |
+ if (ret != EOF) { | |
+ (*buf)[*len] = (char)ret; | |
+ } else { | |
+ (*buf)[*len] = '\0'; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ return *len == 0 && (feof(fp) || ferror(fp)); | |
+} | |
+ | |
void | |
parse_file_with_callback(const char *fname, | |
int (*callback)(const char *, char **, size_t, char *, | |
@@ -154,8 +191,7 @@ parse_file_with_callback(const char *fname, | |
{ | |
FILE *fp; | |
char *line = NULL, **field = NULL, *comment; | |
- size_t linebufsize = 0, i, fieldbufsize = 0, j, nfields; | |
- ssize_t len; | |
+ size_t linebufsize = 0, i, fieldbufsize = 0, j, nfields, len; | |
/* open file */ | |
if (!(fp = fopen(fname, "r"))) { | |
@@ -164,7 +200,7 @@ parse_file_with_callback(const char *fname, | |
exit(1); | |
} | |
- while ((len = getline(&line, &linebufsize, fp)) >= 0) { | |
+ while (!get_line(&line, &linebufsize, fp, &len)) { | |
/* remove trailing newline */ | |
if (len > 0 && line[len - 1] == '\n') { | |
line[len - 1] = '\0'; | |
@@ -654,7 +690,8 @@ break_test_callback(const char *fname, char **field, size_t… | |
{ | |
struct break_test *t, | |
**test = ((struct break_test_payload *)payload)->test; | |
- size_t i, *testlen = ((struct break_test_payload *)payload)->testlen; | |
+ size_t i, *testlen = ((struct break_test_payload *)payload)->testlen, | |
+ commentlen; | |
char *token; | |
(void)fname; | |
@@ -733,11 +770,15 @@ break_test_callback(const char *fname, char **field, size… | |
} | |
/* store comment */ | |
- if (comment != NULL && | |
- ((*test)[*testlen - 1].descr = strdup(comment)) == NULL) { | |
- fprintf(stderr, "break_test_callback: strdup: %s.\n", | |
- strerror(errno)); | |
- return 1; | |
+ if (comment != NULL) { | |
+ commentlen = strlen(comment) + 1; | |
+ if (((*test)[*testlen - 1].descr = malloc(commentlen)) == | |
+ NULL) { | |
+ fprintf(stderr, "break_test_callback: malloc: %s.\n", | |
+ strerror(errno)); | |
+ return 1; | |
+ } | |
+ memcpy((*test)[*testlen - 1].descr, comment, commentlen); | |
} | |
return 0; |