The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
################################################################################
##
##  $Revision: 7 $
##  $Author: mhx $
##  $Date: 2010/03/07 13:15:45 +0100 $
##
################################################################################
##
##  Version 3.x, Copyright (C) 2004-2010, Marcus Holland-Moritz.
##  Version 2.x, Copyright (C) 2001, Paul Marquess.
##  Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
##
##  This program is free software; you can redistribute it and/or
##  modify it under the same terms as Perl itself.
##
################################################################################

=provides

my_strlcat
my_strlcpy

=implementation

#if !defined(my_strlcat)
#if { NEED my_strlcat }

Size_t
my_strlcat(char *dst, const char *src, Size_t size)
{
    Size_t used, length, copy;

    used = strlen(dst);
    length = strlen(src);
    if (size > 0 && used < size - 1) {
        copy = (length >= size - used) ? size - used - 1 : length;
        memcpy(dst + used, src, copy);
        dst[used + copy] = '\0';
    }
    return used + length;
}
#endif
#endif

#if !defined(my_strlcpy)
#if { NEED my_strlcpy }

Size_t
my_strlcpy(char *dst, const char *src, Size_t size)
{
    Size_t length, copy;

    length = strlen(src);
    if (size > 0) {
        copy = (length >= size) ? size - 1 : length;
        memcpy(dst, src, copy);
        dst[copy] = '\0';
    }
    return length;
}

#endif
#endif

=xsinit

#define NEED_my_strlcat
#define NEED_my_strlcpy

=xsubs

void
my_strlfunc()
	PREINIT:
		char buf[8];
		int len;
	PPCODE:
                len = my_strlcpy(buf, "foo", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		len = my_strlcat(buf, "bar", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		len = my_strlcat(buf, "baz", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		len = my_strlcpy(buf, "1234567890", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		len = my_strlcpy(buf, "1234", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		len = my_strlcat(buf, "567890123456", sizeof(buf));
		mXPUSHi(len);
		mXPUSHs(newSVpv(buf, 0));
		XSRETURN(12);

=tests plan => 13

my @e = (3, 'foo',
         6, 'foobar',
         9, 'foobarb',
         10, '1234567',
         4, '1234',
         16, '1234567',
        );
my @r = Devel::PPPort::my_strlfunc();

ok(@e == @r);

for (0 .. $#e) {
  ok($r[$_], $e[$_]);
}