Created
July 26, 2018 17:38
-
-
Save olehermanse/f1376a895510ed7d8d86fca03d41ddc0 to your computer and use it in GitHub Desktop.
Alternate implementation of stpncpy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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