X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Flibpspp%2Fstr.c;h=86e7fd9199a5b9e22fba9fa2ac2eec4e9e7ff1c7;hb=e609c7d767ffd600fd844327b292590259cbb0de;hp=a58473192e44c1f7dc3cc59c2ac7b3e0deed373a;hpb=8c76dd167f2b63b3c97606c53667c391c17fae10;p=pspp diff --git a/src/libpspp/str.c b/src/libpspp/str.c index a58473192e..86e7fd9199 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -301,6 +301,39 @@ overflow: return false; } +/* Copies IN to buffer OUT with size OUT_SIZE, appending a null terminator. If + IN is too long for OUT, or if IN contains a new-line, replaces the tail with + "...". + + OUT_SIZE must be at least 16. */ +void +str_ellipsize (struct substring in, char *out, size_t out_size) +{ + assert (out_size >= 16); + + size_t out_maxlen = out_size - 1; + if (in.length > out_maxlen - 3) + out_maxlen -= 3; + + size_t out_len = 0; + while (out_len < in.length + && in.string[out_len] != '\n' + && in.string[out_len] != '\0' + && (in.string[out_len] != '\r' + || out_len + 1 >= in.length + || in.string[out_len + 1] != '\n')) + { + int mblen = u8_mblen (CHAR_CAST (const uint8_t *, in.string + out_len), + in.length - out_len); + if (mblen < 0 || out_len + mblen > out_maxlen) + break; + out_len += mblen; + } + + memcpy (out, in.string, out_len); + strcpy (&out[out_len], out_len < in.length ? "..." : ""); +} + /* Sets the SIZE bytes starting at BLOCK to C, and returns the byte following BLOCK. */ void * @@ -392,6 +425,15 @@ ss_dealloc (struct substring *ss) free (ss->string); } +/* Exchanges the contents of A and B. */ +void +ss_swap (struct substring *a, struct substring *b) +{ + struct substring tmp = *a; + *a = *b; + *b = tmp; +} + /* Truncates SS to at most CNT bytes in length. */ void ss_truncate (struct substring *ss, size_t cnt) @@ -1481,7 +1523,8 @@ ds_put_cstr (struct string *st, const char *s) void ds_put_substring (struct string *st, struct substring ss) { - memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss)); + if (ss.length) + memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss)); } /* Returns ds_end(ST) and THEN increases the length by INCR. */