[hackers] [libgrapheme] Allow level-array to have different size from line length || Laslo Hunhold

From: <git_AT_suckless.org>
Date: Fri, 12 May 2023 16:36:15 +0200 (CEST)

commit f320b0ad8b7b2bc7ab5b63e91379012adbd19d12
Author: Laslo Hunhold <dev_AT_frign.de>
AuthorDate: Thu May 11 18:16:09 2023 +0200
Commit: Laslo Hunhold <dev_AT_frign.de>
CommitDate: Thu May 11 18:16:09 2023 +0200

    Allow level-array to have different size from line length
    
    This may not be apparent at first, but it allows you to only extract
    as many levels of a line as you need, e.g. only the first 10. Truncation
    is indicated by the return value being larger than levlen.
    
    Signed-off-by: Laslo Hunhold <dev_AT_frign.de>

diff --git a/grapheme.h b/grapheme.h
index 8974d4d..778763c 100644
--- a/grapheme.h
+++ b/grapheme.h
_AT_@ -15,8 +15,9 @@ enum grapheme_bidirectional_override {
         GRAPHEME_BIDIRECTIONAL_OVERRIDE_RTL,
 };
 
-void grapheme_bidirectional_get_line_embedding_levels(const uint_least32_t *,
- size_t, int_least8_t *);
+size_t grapheme_bidirectional_get_line_embedding_levels(const uint_least32_t *,
+ size_t, int_least8_t *,
+ size_t);
 
 size_t grapheme_bidirectional_preprocess(const uint_least32_t *, size_t,
                                          enum grapheme_bidirectional_override,
diff --git a/src/bidirectional.c b/src/bidirectional.c
index c4a5057..f7116ef 100644
--- a/src/bidirectional.c
+++ b/src/bidirectional.c
_AT_@ -1435,23 +1435,29 @@ grapheme_bidirectional_preprocess_utf8(
         return preprocess(&r, override, dest, destlen);
 }
 
-void
+size_t
 grapheme_bidirectional_get_line_embedding_levels(const uint_least32_t *linedata,
                                                  size_t linelen,
- int_least8_t *linelevel)
+ int_least8_t *lev,
+ size_t levlen)
 {
         enum bidi_property prop;
         size_t i, runsince;
+ int_least8_t level;
 
         /* rule L1.4 */
         runsince = SIZE_MAX;
         for (i = 0; i < linelen; i++) {
+ level = (int_least8_t)get_state(STATE_LEVEL, linedata[i]);
                 prop = (uint_least8_t)get_state(STATE_PRESERVED_PROP,
                                                 linedata[i]);
 
- /* write level into level array */
- if ((linelevel[i] = (int_least8_t)get_state(
- STATE_LEVEL, linedata[i])) == -1) {
+ /* write level into level array if we still have space */
+ if (i < levlen) {
+ lev[i] = level;
+ }
+
+ if (level == -1) {
                         /* ignored character */
                         continue;
                 }
_AT_@ -1473,11 +1479,13 @@ grapheme_bidirectional_get_line_embedding_levels(const uint_least32_t *linedata,
                  * we hit the end of the line but were in a run;
                  * reset the line levels to the paragraph level
                  */
- for (i = runsince; i < linelen; i++) {
- if (linelevel[i] != -1) {
- linelevel[i] = (int_least8_t)get_state(
+ for (i = runsince; i < MIN(linelen, levlen); i++) {
+ if (lev[i] != -1) {
+ lev[i] = (int_least8_t)get_state(
                                         STATE_PARAGRAPH_LEVEL, linedata[i]);
                         }
                 }
         }
+
+ return linelen;
 }
diff --git a/test/bidirectional.c b/test/bidirectional.c
index 0a91e62..22a775d 100644
--- a/test/bidirectional.c
+++ b/test/bidirectional.c
_AT_@ -14,9 +14,10 @@ main(int argc, char *argv[])
 {
         uint_least32_t data[512]; /* TODO iterate and get max, allocate */
         int_least8_t lev[512];
- size_t i, num_tests, failed, datalen, ret, j, m;
+ size_t i, num_tests, failed, datalen, levlen, ret, j, m;
 
         datalen = LEN(data);
+ levlen = LEN(lev);
 
         (void)argc;
 
_AT_@ -30,14 +31,19 @@ main(int argc, char *argv[])
                                 bidirectional_test[i].cp,
                                 bidirectional_test[i].cplen,
                                 bidirectional_test[i].mode[m], data, datalen);
- grapheme_bidirectional_get_line_embedding_levels(
- data, ret, lev);
 
                         if (ret != bidirectional_test[i].cplen ||
                             ret > datalen) {
                                 goto err;
                         }
 
+ ret = grapheme_bidirectional_get_line_embedding_levels(
+ data, ret, lev, levlen);
+
+ if (ret > levlen) {
+ goto err;
+ }
+
                         for (j = 0; j < ret; j++) {
                                 if (lev[j] != bidirectional_test[i].level[j]) {
                                         goto err;
Received on Fri May 12 2023 - 16:36:15 CEST

This archive was generated by hypermail 2.3.0 : Fri May 12 2023 - 16:48:36 CEST