-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TESTED: Tested on 10.4-10.5 ppc, 10.4-10.6 i386, 10.5-10.6 ppc (i386 Rosetta), 10.5-12.x x86_64, 11.x-14.x arm64. Fails on <10.7 without added stpncpy(); passes with.
- Loading branch information
Showing
1 changed file
with
103 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (c) 2024 Frederick H. G. Wright II <[email protected]> | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
/* | ||
* This provides rudimentary tests for stpncpy(). Given that | ||
* the implementation is taken almost verbatim from Apple's code for 10.7+, | ||
* exhaustive testing of corner cases shouldn't be necessary. This just | ||
* tests a few cases, primarily to verify that the function can be used at all | ||
* (which is not true prior to 10.7 without this package), though the framework | ||
* should be valid for all possible test cases. | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
const char *test_str = "The Quick Brown Fox"; | ||
|
||
#define BUF_LEN 128 /* Generously longer than test_str */ | ||
|
||
static int save_errno; | ||
static char *save_ret; | ||
static char dest[BUF_LEN], save_dest[BUF_LEN]; | ||
|
||
/* Reference implementation of stpncpy() */ | ||
static char * | ||
ref_stpncpy(char *dst, const char *src, size_t n) | ||
{ | ||
char *ret; | ||
|
||
if (n <= 0) return dst; | ||
|
||
while (n) { | ||
if ((*dst++ = *src++) == 0) break; | ||
--n; | ||
} | ||
ret = dst - 1; | ||
while (n--) *dst++ = 0; | ||
return *ret ? ret + 1 : ret; | ||
} | ||
|
||
/* Setup prior to test case */ | ||
static void | ||
setup(void) | ||
{ | ||
errno = 0; | ||
memset(dest, -1, BUF_LEN); | ||
} | ||
|
||
/* Save all results from first version */ | ||
static void | ||
save(char *ret) | ||
{ | ||
save_errno = errno; | ||
save_ret = ret; | ||
memcpy(save_dest, dest, BUF_LEN); | ||
} | ||
|
||
/* Compare results from both versions */ | ||
static void | ||
check(char *ret) | ||
{ | ||
assert(errno == save_errno); | ||
assert(ret == save_ret); | ||
assert(memcmp(save_dest, dest, BUF_LEN) == 0); | ||
} | ||
|
||
/* Run one test case */ | ||
static void | ||
test_stpncpy(char *dst, const char *src, size_t n) | ||
{ | ||
setup(); | ||
save(ref_stpncpy(dst, src, n)); | ||
check(stpncpy(dst, src, n)); | ||
} | ||
|
||
int | ||
main(int argc, char *argv[]) | ||
{ | ||
int test_len = strlen(test_str); | ||
int n; | ||
|
||
(void) argc; (void) argv; | ||
|
||
for (n = test_len - 2; n <= test_len + 2; ++n) { | ||
test_stpncpy(&dest[1], test_str, n); | ||
} | ||
|
||
return 0; | ||
} |