commit ad77d95d3426325ab395efd40afb40be307d9b13
Author:     Laslo Hunhold <[email protected]>
AuthorDate: Fri Feb 24 18:21:02 2023 +0100
Commit:     Laslo Hunhold <[email protected]>
CommitDate: Fri Feb 24 18:23:45 2023 +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]>

diff --git a/benchmark/util.c b/benchmark/util.c
index 94531bb..bdad3a5 100644
--- a/benchmark/util.c
+++ b/benchmark/util.c
@@ -71,10 +71,9 @@ generate_utf8_test_buffer(const struct break_test *test, 
size_t testlen,
 }
 
 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 
*payload, const char *name,
               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, const char *name,
                        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
index 5dcc742..c5284c5 100644
--- a/config.mk
+++ b/config.mk
@@ -14,7 +14,7 @@ SONAME    = 
libgrapheme.so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
 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
index 9d076b2..332be82 100644
--- 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 
nfields,
 {
        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_t nfields,
        }
 
        /* 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;

Reply via email to