/* Shao Miller, 2012 */
#include <stdio.h>
#include <stdlib.h>
void * pmemcpy(void * s1, const void * s2, size_t n);
void * pmemmove(void * s1, const void * s2, size_t n);
int main(void) {
char test1[] = "0123456789";
char test2[] = "ABCDEFGHIJ";
char * t1;
char * t2;
t1 = pmemmove(test1, test1 + 5, 5);
t2 = pmemmove(test2 + 5, test2, 5);
(void) t2;
printf("%s\n%s\n", t1
, test2
);
return EXIT_SUCCESS;
}
void * pmemcpy(void * s1, const void * s2, size_t n) {
unsigned char * dest;
const unsigned char * src;
if (!s1 || !s2 || !n)
return s1;
dest = s1;
src = s2;
while (n--)
*dest++ = *src++;
return s1;
}
/* Portability wins over performance, here */
void * pmemmove(void * s1, const void * s2, size_t n) {
unsigned char * dest;
const unsigned char * src;
const unsigned char * src_end;
if (!s1 || !s2 || !n || s1 == s2)
return s1;
dest = s1;
src = s2;
/* The only interesting case is where src < dest with overlap */
for (src_end = src + n; src < src_end; ++src) {
if (src == dest)
break;
}
/* Is src > dest or non-overlapping? */
if (src == src_end)
return pmemcpy(s1, s2, n);
/* Otherwise, src < dest with overlap */
dest += n;
src = src_end;
while (n--)
*dest-- = *src--;
return s1;
}
LyogU2hhbyBNaWxsZXIsIDIwMTIgKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+Cgp2b2lkICogcG1lbWNweSh2b2lkICogczEsIGNvbnN0IHZvaWQgKiBzMiwgc2l6ZV90IG4pOwp2b2lkICogcG1lbW1vdmUodm9pZCAqIHMxLCBjb25zdCB2b2lkICogczIsIHNpemVfdCBuKTsKCmludCBtYWluKHZvaWQpIHsKICAgIGNoYXIgdGVzdDFbXSA9ICIwMTIzNDU2Nzg5IjsKICAgIGNoYXIgdGVzdDJbXSA9ICJBQkNERUZHSElKIjsKICAgIGNoYXIgKiB0MTsKICAgIGNoYXIgKiB0MjsKCiAgICB0MSA9IHBtZW1tb3ZlKHRlc3QxLCB0ZXN0MSArIDUsIDUpOwogICAgdDIgPSBwbWVtbW92ZSh0ZXN0MiArIDUsIHRlc3QyLCA1KTsKICAgICh2b2lkKSB0MjsKCiAgICBwcmludGYoIiVzXG4lc1xuIiwgdDEsIHRlc3QyKTsKCiAgICByZXR1cm4gRVhJVF9TVUNDRVNTOwogIH0KCnZvaWQgKiBwbWVtY3B5KHZvaWQgKiBzMSwgY29uc3Qgdm9pZCAqIHMyLCBzaXplX3QgbikgewogICAgdW5zaWduZWQgY2hhciAqIGRlc3Q7CiAgICBjb25zdCB1bnNpZ25lZCBjaGFyICogc3JjOwoKICAgIGlmICghczEgfHwgIXMyIHx8ICFuKQogICAgICByZXR1cm4gczE7CgogICAgZGVzdCA9IHMxOwogICAgc3JjID0gczI7CgogICAgd2hpbGUgKG4tLSkKICAgICAgKmRlc3QrKyA9ICpzcmMrKzsKCiAgICByZXR1cm4gczE7CiAgfQoKLyogUG9ydGFiaWxpdHkgd2lucyBvdmVyIHBlcmZvcm1hbmNlLCBoZXJlICovCnZvaWQgKiBwbWVtbW92ZSh2b2lkICogczEsIGNvbnN0IHZvaWQgKiBzMiwgc2l6ZV90IG4pIHsKICAgIHVuc2lnbmVkIGNoYXIgKiBkZXN0OwogICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHNyYzsKICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBzcmNfZW5kOwoKICAgIGlmICghczEgfHwgIXMyIHx8ICFuIHx8IHMxID09IHMyKQogICAgICByZXR1cm4gczE7CgogICAgZGVzdCA9IHMxOwogICAgc3JjID0gczI7CgogICAgLyogVGhlIG9ubHkgaW50ZXJlc3RpbmcgY2FzZSBpcyB3aGVyZSBzcmMgPCBkZXN0IHdpdGggb3ZlcmxhcCAqLwogICAgZm9yIChzcmNfZW5kID0gc3JjICsgbjsgc3JjIDwgc3JjX2VuZDsgKytzcmMpIHsKICAgICAgICBpZiAoc3JjID09IGRlc3QpCiAgICAgICAgICBicmVhazsKICAgICAgfQoKICAgIC8qIElzIHNyYyA+IGRlc3Qgb3Igbm9uLW92ZXJsYXBwaW5nPyAqLwogICAgaWYgKHNyYyA9PSBzcmNfZW5kKQogICAgICByZXR1cm4gcG1lbWNweShzMSwgczIsIG4pOwoKICAgIC8qIE90aGVyd2lzZSwgc3JjIDwgZGVzdCB3aXRoIG92ZXJsYXAgKi8KICAgIGRlc3QgKz0gbjsKICAgIHNyYyA9IHNyY19lbmQ7CgogICAgd2hpbGUgKG4tLSkKICAgICAgKmRlc3QtLSA9ICpzcmMtLTsKCiAgICByZXR1cm4gczE7CiAgfQo=