Re: [PATCH v5 2/5] stpecpy.3, stpecpyx.3, ustpcpy.3, ustr2stp.3, zustr2stp.3, zustr2ustp.3: Add new links to string_copy(7)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Stefan,

On 12/16/22 19:47, Stefan Puiu wrote:
Hi Alex!

On Thu, Dec 15, 2022 at 2:46 AM Alejandro Colomar
<alx.manpages@xxxxxxxxx> wrote:

Formatted strpcy(3):

strcpy(3)                  Library Functions Manual                  strcpy(3)

NAME
         strcpy - copy or catenate a string

LIBRARY
         Standard C library (libc, -lc)

SYNOPSIS
         #include <string.h>

         char *stpcpy(char *restrict dst, const char *restrict src);
         char *strcpy(char *restrict dst, const char *restrict src);
         char *strcat(char *restrict dst, const char *restrict src);

     Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

         stpcpy():
             Since glibc 2.10:
                 _POSIX_C_SOURCE >= 200809L
             Before glibc 2.10:
                 _GNU_SOURCE

DESCRIPTION
         stpcpy()
         strcpy()
                These functions copy the string pointed to by src, into a string
                at  the buffer pointed to by dst.  The programmer is responsible
                for allocating a buffer large enough, that is, strlen(src) +  1.
                They only differ in the return value.

A destination buffer large enough? It's not that obvious to me from
the text, but maybe I'm tired :).

Sure.  Thanks!

I was also a bit at a loss about the difference between the two; maybe
you can say "For the difference between the two, see RETURN VALUE"?

That can make sense, yes.



         strcat()
                This function catenates the string pointed to by src, at the end
                of  the string pointed to by dst.  The programmer is responsible
                for allocating a buffer large enough,  that  is,  strlen(dst)  +
                strlen(src) + 1.

Ditto here.

:)



         An implementation of these functions might be:

             char *
             stpcpy(char *restrict dst, const char *restrict src)
             {
                 char  *end;

                 end = mempcpy(dst, src, strlen(src));
                 *end = '\0';

                 return end;
             }

             char *
             strcpy(char *restrict dst, const char *restrict src)
             {
                 stpcpy(dst, src);
                 return dst;
             }

             char *
             strcat(char *restrict dst, const char *restrict src)
             {
                 stpcpy(dst + strlen(dst), src);
                 return dst;
             }

Are you sure this section adds any value? I think good documentation
should explain how a function works without delving into the
interpretation.

To be honest, this page doesn't benefit too much from it. strcpy(3)/strcat(3) are dead simple, and the explanations above should be enough.

However, the same thing in strncpy(3) and strncat(3) is very helpful, IMO. For consistency I just showed trivial implementations in all of the pages. (And in fact, there was an example implementation in the old strncat(3) and maybe a few others, IIRC.)

Also, people might get confused and think this is the
actual implementation.

I don't think there's any problem if one believes this is the implementation. Except for stpcpy(3), in which I preferred readability, they are actually quite good implementations. A faster implementation of stpcpy(3) might be done in terms of memccpy(3).

Funnily enough, I just checked what musl libc does, and it's the same as shown here:


alx@debian:~/src/musl/musl$ grepc -tfd strcpy
./src/string/strcpy.c:3:
char *strcpy(char *restrict dest, const char *restrict src)
{
	__stpcpy(dest, src);
	return dest;
}
alx@debian:~/src/musl/musl$ grepc -tfd strcat
./src/string/strcat.c:3:
char *strcat(char *restrict dest, const char *restrict src)
{
	strcpy(dest + strlen(dest), src);
	return dest;
}




RETURN VALUE
         stpcpy()
                This  function returns a pointer to the terminating null byte at
                the end of the copied string.

         strcpy()
         strcat()
                These functions return dest.

ATTRIBUTES
         For an explanation of the terms  used  in  this  section,  see  attrib‐
         utes(7).
         ┌────────────────────────────────────────────┬───────────────┬─────────┐
         │Interface                                   │ Attribute     │ Value   │
         ├────────────────────────────────────────────┼───────────────┼─────────┤
         │stpcpy(), strcpy(), strcat()                │ Thread safety │ MT‐Safe │
         └────────────────────────────────────────────┴───────────────┴─────────┘

STANDARDS
         stpcpy()
                POSIX.1‐2008.

         strcpy()
         strcat()
                POSIX.1‐2001, POSIX.1‐2008, C89, C99, SVr4, 4.3BSD.

CAVEATS
         The strings src and dst may not overlap.

         If  the  destination  buffer is not large enough, the behavior is unde‐
         fined.  See _FORTIFY_SOURCE in feature_test_macros(7).

BUGS
         strcat()
                This function can be  very  inefficient.   Read  about  Shlemiel
                the      painter     ⟨https://www.joelonsoftware.com/2001/12/11/
                back-to-basics/⟩.

I'm not sure this is a bug, rather a design limitation. Maybe it
belongs in NOTES or CAVEATS?

Yeah, I had been thinking of downgrading it.  I'll do it.

Also, I think this can be summarized
along the lines of 'strcat needs to walk the destination buffer to
find the null terminator, so it has linear complexity with respect to
the size of the destination buffer up to the terminator' (hmm, I'm
sure this can be expressed more concisely), so the page is more self
contained. Outside links sometimes go dead, like on Wikipedia, so I
think just in case, it helps to make explicit the point that you want
the reader to study further in the URL.

I wasn't inspired to write it short enough to not be too verbose. Maybe I'll write something based on your suggestion.


Regards,
Stefan.

Thanks for the review!

Cheers,

Alex



EXAMPLES
         #include <stdio.h>
         #include <stdlib.h>
         #include <string.h>

         int
         main(void)
         {
             char    *p;
             char    buf1[BUFSIZ];
             char    buf2[BUFSIZ];
             size_t  len;

             p = buf1;
             p = stpcpy(p, "Hello ");
             p = stpcpy(p, "world");
             p = stpcpy(p, "!");
             len = p - buf1;

             printf("[len = %zu]: ", len);
             puts(buf1);  // "Hello world!"

             strcpy(buf2, "Hello ");
             strcat(buf2, "world");
             strcat(buf2, "!");
             len = strlen(buf2);

             printf("[len = %zu]: ", len);
             puts(buf2);  // "Hello world!"

             exit(EXIT_SUCCESS);
         }

SEE ALSO
         strdup(3), string(3), wcscpy(3), string_copy(7)

Linux man‐pages (unreleased)        (date)                           strcpy(3)

--
<http://www.alejandro-colomar.es/>

--
<http://www.alejandro-colomar.es/>

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux