Skip to content

Instantly share code, notes, and snippets.

@olehermanse
Created July 26, 2018 17:38
Show Gist options
  • Save olehermanse/f1376a895510ed7d8d86fca03d41ddc0 to your computer and use it in GitHub Desktop.
Save olehermanse/f1376a895510ed7d8d86fca03d41ddc0 to your computer and use it in GitHub Desktop.
Alternate implementation of stpncpy
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
// Copy at most len bytes, including NUL terminating byte
// if src is too long don't terminate
// if src is shorter than len, fill remainder with zeroes
// return pointer to terminator in dst
// if no terminator, return dst + len (address after last byte written)
//
// This is not the fastest way to implement stpncpy, and it is only
// used where it is missing (mingw/windows)
char *__stpncpy(char *dst, const char *src, size_t len)
{
for (int i = 0; i < len; ++i)
{
const char copy_byte = src[i];
dst[i] = copy_byte;
if (copy_byte == '\0')
{
// Zero fill and return:
for (int j = i+1; j < len; ++j)
{
dst[j] = '\0';
}
return dst + i;
}
}
return dst + len;
}
bool string_equal(const char *const a, const char *const b)
{
return (strcmp(a, b) == 0);
}
bool memory_equal(const void *a, const void *b, size_t n)
{
return (memcmp(a, b, n) == 0);
}
#define test_str(str, num) \
{ \
printf("stpncpy(\"%s\", %d): ", str, num); \
char buf_a[1000]; \
memset(buf_a, 0, 1000); \
buf_a[500] = buf_a[0] = 'X'; \
char buf_b[1000]; \
memset(buf_b, 0, 1000); \
buf_b[500] = buf_b[0] = 'X'; \
char *r_a = stpncpy(buf_a, str, num); \
char *r_b = stpncpy_windows(buf_b, str, num); \
if (!string_equal(buf_a, buf_b)) \
{ \
printf("'%s' != '%s'\n", buf_a, buf_b); \
} \
else \
{ \
printf("'%s' == '%s'\n", buf_a, buf_b); \
} \
assert(string_equal(buf_a, buf_b)); \
assert(memory_equal(buf_a, buf_b, 1000)); \
r_b = stpncpy_windows(buf_a, str, num); \
assert(r_a == r_b); \
}
#define test_loop(str, num) \
{ \
for (int i = 0; i < num; ++i) \
{ \
test_str(str, i); \
} \
}
int main()
{
test_loop("", 16);
test_loop(" ", 16);
test_loop(" ", 16);
test_loop("\t\t ", 16);
test_loop("Hello, world!", 16);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment