* str: added str_nlen and str_ncpy
authorUrban Wallasch <urban.wallasch@freenet.de>
Mon, 28 Oct 2019 18:32:16 +0000 (19:32 +0100)
committerUrban Wallasch <urban.wallasch@freenet.de>
Mon, 28 Oct 2019 18:32:16 +0000 (19:32 +0100)
str/str.h
str/str_test.c

index 04ce8782f22c13d85681d41f0f24862d747ee1f3..849d80e4aebf07d22f7b2b1886a8cff3b22c6249 100644 (file)
--- a/str/str.h
+++ b/str/str.h
  * str_toupper,
  * str_tolower - convert case of characters in string
  *
+ * str_nlen   - determine the length of a fixed-size string
+ *
+ * str_ncpy  - copy initial part of a string (a better strncpy)
+ *
  */
 
 #ifndef STR_H_
@@ -371,6 +375,44 @@ static inline char *str_tolower(char *s) {
     return s;
 }
 
+/*
+ * str_nlen - determine the length of a fixed-size string
+ *
+ * The strnlen() function returns the number of characters in the string
+ * s, excluding the terminating null byte ('\0'), but at most maxlen.
+ * In doing so, strnlen() never looks beyond the first maxlen characters
+ * in s.
+ *
+ * The strnlen() function returns strlen(s), if that is less than maxlen,
+ * or maxlen if there is no null byte ('\0') among the first maxlen
+ * characters in string s.
+ */
+static size_t str_nlen(char *s, size_t maxlen) {
+    size_t n;
+    for (n = 0; n < maxlen && s[n]; ++n)
+        ;
+    return n;
+}
+
+/*
+ * str_ncpy - copy initial part of a string (a better strncpy)
+ *
+ * The str_ncpy() function copies characters from src up until a null
+ * byte is encountered or n characters were copied, whichever happens
+ * first.  The buffer src does not need to be null-terminated, if it
+ * contains n or more bytes.  The resulting string in dest will always
+ * be null-terminated.
+ *
+ * The str_ncpy() function returns a pointer to the copied string.
+ *
+ * CAVEAT:
+ * The buffer dest must be large enough to hold at least n+1 characters.
+ */
+static inline char *str_ncpy(char *dest, const char *src, size_t n) {
+    *dest = '\0';
+    return strncat(dest, src, n);
+}
+
 
 #ifdef cplusplus
 }
index ca33ed57e86bc82f147d5e95df787146ffbae1a7..81117bb51986d2102081ed31820b0f896db325b1 100644 (file)
@@ -367,6 +367,36 @@ int main(void) {
 
     /*****************************************/
 
+    {
+        H("str_nlen");
+        T(str_nlen("foobar", 10) == 6);
+        T(str_nlen("foobar", 6) == 6);
+        T(str_nlen("foobar", 5) == 5);
+        T(str_nlen("", 1) == 0);
+        T(str_nlen("bar", 1) == 1);
+        T(str_nlen("bar", 0) == 0);
+    }
+
+    /*****************************************/
+
+    {
+        H("str_ncpy");
+        char s[11] = { 0 };
+        D(s);
+        T(strcmp(str_ncpy(s, "foobar", 10), "foobar") == 0);
+        D(s);
+        T(strcmp(str_ncpy(s, "123456789012", 10), "1234567890") == 0);
+        D(s);
+        T(strcmp(str_ncpy(s, "foobar", 3), "foo") == 0);
+        D(s);
+        T(strcmp(str_ncpy(s, "", 333), "") == 0);
+        D(s);
+        T(strcmp(str_ncpy(s, "bar", 333), "bar") == 0);
+        D(s);
+    }
+
+    /*****************************************/
+
     H("All tests passed.");
     return 0;
 }