Red Bear OS relibc baseline
From release 0.1.0 pre-patched archive. This includes all Red Bear modifications previously maintained as patches in local/patches/relibc/.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
puts("# mem #");
|
||||
char arr[100];
|
||||
memset(arr, 0, 100); // Compiler builtin, should work
|
||||
arr[50] = 1;
|
||||
if ((size_t)memchr((void *)arr, 1, 100) - (size_t)arr != 50) {
|
||||
puts("Incorrect memchr");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("Correct memchr");
|
||||
if ((size_t)memrchr((void *)arr, 1, 100) - (size_t)arr != 50) {
|
||||
puts("Incorrect memrchr");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("Correct memrchr");
|
||||
char arr2[51];
|
||||
memset(arr2, 0, 51); // Compiler builtin, should work
|
||||
memccpy((void *)arr2, (void *)arr, 1, 51);
|
||||
if (arr[50] != 1) {
|
||||
puts("Incorrect memccpy");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("Correct memccpy");
|
||||
int res;
|
||||
if ((res = memcmp("hello world", "hello world", 11))) {
|
||||
printf("Incorrect memcmp (1), expected 0 found %d\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((res = memcmp("hello world", "hello worlt", 11)) >= 0) {
|
||||
printf("Incorrect memcmp (2), expected -, found %d\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((res = memcmp("hello world", "hallo world", 5)) <= 0) {
|
||||
printf("Incorrect memcmp (3), expected +, found %d\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((res = memcmp("hello world", "henlo world", 5)) >= 0) {
|
||||
printf("Incorrect memcmp (4), expected -, found %d\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
puts("Correct memcmp");
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
int main(void) {
|
||||
const uint8_t UNTOUCHED_BYTE = 0x00;
|
||||
const uint8_t TOUCHED_BYTE = 0xff;
|
||||
// In order to fully exercise the implementation, this should be at least 3 times the largest possible chunk size
|
||||
const size_t BUFFER_LEN = 64;
|
||||
|
||||
uint8_t *s1_buffer = malloc(BUFFER_LEN);
|
||||
uint8_t *s2_buffer = malloc(BUFFER_LEN);
|
||||
|
||||
// Loop through all possible combinations of s1 and s2 alignments and slice length within the buffers allocated
|
||||
for (size_t s1_offset = 0; s1_offset < BUFFER_LEN; s1_offset++) {
|
||||
for (size_t s2_offset = 0; s2_offset < BUFFER_LEN; s2_offset++) {
|
||||
size_t n_max = BUFFER_LEN - MAX(s1_offset, s2_offset);
|
||||
for (size_t n = 1; n <= n_max; n++) {
|
||||
// Clear buffers
|
||||
memset(s1_buffer, UNTOUCHED_BYTE, BUFFER_LEN);
|
||||
memset(s2_buffer, UNTOUCHED_BYTE, BUFFER_LEN);
|
||||
|
||||
// Fill s2 subslice
|
||||
memset(s2_buffer + s2_offset, TOUCHED_BYTE, n);
|
||||
|
||||
// Do the actual memcpy of the slice of interest
|
||||
memcpy(s1_buffer + s1_offset, s2_buffer + s2_offset, n);
|
||||
|
||||
// Check that area below the slice of interest is untouched
|
||||
for (size_t i = 0; i < s1_offset; i++) {
|
||||
assert(s1_buffer[i] == UNTOUCHED_BYTE);
|
||||
}
|
||||
|
||||
// Check that the slice of interest was copied
|
||||
assert(memcmp(s1_buffer + s1_offset, s2_buffer + s2_offset, n) == 0);
|
||||
|
||||
// Check that area above the slice of interest is untouched
|
||||
for (size_t i = s1_offset + n; i < BUFFER_LEN; i++) {
|
||||
assert(s1_buffer[i] == UNTOUCHED_BYTE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(s1_buffer);
|
||||
free(s2_buffer);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
uint8_t haystack[] = {1, 1, 2, 1, 2, 3, 1, 2, 3, 4};
|
||||
uint8_t present_needle[] = {1, 2, 3};
|
||||
uint8_t absent_needle[] = {1, 2, 3, 4, 5};
|
||||
uint8_t long_needle[] = {1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1};
|
||||
|
||||
size_t haystacklen = sizeof(haystack);
|
||||
size_t present_needlelen = sizeof(present_needle);
|
||||
size_t absent_needlelen = sizeof(absent_needle);
|
||||
size_t long_needlelen = sizeof(long_needle);
|
||||
|
||||
uint8_t *present_needle_match_ptr = memmem(haystack, haystacklen, present_needle, present_needlelen);
|
||||
assert(present_needle_match_ptr == haystack + 3);
|
||||
|
||||
uint8_t *absent_needle_match_ptr = memmem(haystack, haystacklen, absent_needle, absent_needlelen);
|
||||
assert(absent_needle_match_ptr == NULL);
|
||||
|
||||
// Explicitly specified to return haystack for needlelen == 0.
|
||||
uint8_t *zero_needle_match_ptr = memmem(haystack, haystacklen, present_needle, 0);
|
||||
assert(zero_needle_match_ptr == haystack);
|
||||
|
||||
uint8_t *long_needle_match_ptr = memmem(haystack, haystacklen, long_needle, long_needlelen);
|
||||
assert(long_needle_match_ptr == NULL);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void test_stpcpy(const char *src, char *dest) {
|
||||
char *end = stpcpy(dest, src);
|
||||
assert(strcmp(dest, src) == 0);
|
||||
assert(*end == '\0');
|
||||
assert(end == dest + strlen(dest));
|
||||
}
|
||||
|
||||
int main() {
|
||||
char dest[20];
|
||||
|
||||
test_stpcpy("Hello, World!", dest);
|
||||
|
||||
// Test case 2: Empty string
|
||||
test_stpcpy("", dest);
|
||||
|
||||
// Test case 3: String with special characters
|
||||
test_stpcpy("Special chars: !@#$%^&*()", dest);
|
||||
|
||||
// Test case 4: String with spaces
|
||||
test_stpcpy("A string with spaces", dest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
// Define some test strings
|
||||
const char *src = "Hello, World!";
|
||||
char dest[50];
|
||||
|
||||
// Test 1: Copy exactly 5 characters from src to dest
|
||||
char *result = stpncpy(dest, src, 5);
|
||||
dest[5] = '\0'; // Ensure the destination string is null-terminated
|
||||
assert(strcmp(dest, "Hello") == 0); // Verify the string in dest
|
||||
assert(result == &dest[5]); // Ensure the return pointer points to the null terminator
|
||||
|
||||
// Test 2: Copy 15 characters from src to dest (more than the length of src)
|
||||
result = stpncpy(dest, src, 15);
|
||||
dest[13] = '\0'; // Ensure the destination string is null-terminated
|
||||
assert(strcmp(dest, "Hello, World!") == 0); // Verify the string in dest
|
||||
assert(result == &dest[13]); // Ensure the return pointer points to the null terminator
|
||||
|
||||
// Test 3: Copy 3 characters from src to dest
|
||||
result = stpncpy(dest, src, 3);
|
||||
dest[3] = '\0'; // Ensure the destination string is null-terminated
|
||||
assert(strcmp(dest, "Hel") == 0); // Verify the string in dest
|
||||
assert(result == &dest[3]); // Ensure the return pointer points to the null terminator
|
||||
|
||||
// Test 4: Copy 0 characters from src to dest
|
||||
result = stpncpy(dest, src, 0);
|
||||
dest[0] = '\0'; // Ensure the destination is explicitly null-terminated
|
||||
assert(dest[0] == '\0'); // Ensure the destination is an empty string
|
||||
assert(result == dest); // Ensure the return pointer points to the start of dest
|
||||
|
||||
// Test 5: Copy exactly the length of the source string
|
||||
result = stpncpy(dest, src, strlen(src));
|
||||
dest[strlen(src)] = '\0'; // Ensure the destination string is null-terminated
|
||||
assert(strcmp(dest, "Hello, World!") == 0); // Verify the string in dest
|
||||
assert(result == &dest[strlen(src)]); // Ensure the return pointer points to the null terminator
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char dest1[12] = "hello";
|
||||
printf("%s\n", strcat(dest1, " world")); // should be hello world
|
||||
|
||||
char dest2[12] = "hello";
|
||||
printf("%s\n", strncat(dest2, " world foobar", 6)); // should be hello world
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
printf("%s\n", strchr("hello", 'e')); // should be ello
|
||||
printf("%s\n", strchr("world", 'l')); // should be ld
|
||||
printf("%s\n", strchr("world", '\0')); // should be an empty, nul-terminated string
|
||||
printf("%p\n", strchr("world", 'x')); // should be a null pointer
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
int main() {
|
||||
// Test 1: Character is present in the string
|
||||
const char *str1 = "Hello, World!";
|
||||
const char *result1 = strchrnul(str1, 'o');
|
||||
assert(result1 == &str1[4]); // 'o' is at position 4 in "Hello, World!"
|
||||
|
||||
// Test 2: Character is not in the string (should return the null terminator)
|
||||
const char *str2 = "Hello, World!";
|
||||
const char *result2 = strchrnul(str2, 'z');
|
||||
assert(result2 == &str2[13]); // 'z' is not present, so it returns the null terminator
|
||||
|
||||
// Test 3: Character is the first character in the string
|
||||
const char *str3 = "abcdef";
|
||||
const char *result3 = strchrnul(str3, 'a');
|
||||
assert(result3 == &str3[0]); // 'a' is at position 0
|
||||
|
||||
// Test 4: Character is the last character in the string
|
||||
const char *str4 = "abcdef";
|
||||
const char *result4 = strchrnul(str4, 'f');
|
||||
assert(result4 == &str4[5]); // 'f' is at position 5, the last character
|
||||
|
||||
// Test 5: Searching for the null terminator itself
|
||||
const char *str5 = "abcdef";
|
||||
const char *result5 = strchrnul(str5, '\0');
|
||||
assert(result5 == &str5[6]); // The null terminator is at position 6 (end of the string)
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char dst[20];
|
||||
|
||||
strcpy(dst, "strcpy works!");
|
||||
puts(dst);
|
||||
strncpy(dst, "strncpy works!", 20);
|
||||
puts(dst);
|
||||
|
||||
// Make sure no NUL is placed
|
||||
memset(dst, 'a', 20);
|
||||
dst[19] = 0;
|
||||
strncpy(dst, "strncpy should work here too", 10);
|
||||
puts(dst);
|
||||
|
||||
// The string should be properly terminated regardless
|
||||
char ndst[28];
|
||||
|
||||
size_t r = strlcpy(ndst, "strlcpy works!", 28);
|
||||
puts(ndst);
|
||||
printf("copied %lu\n", r);
|
||||
r = strlcat(ndst, " and strlcat!", 28);
|
||||
puts(ndst);
|
||||
printf("copied %lu\n", r);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char *world = "world";
|
||||
printf("%ld\n", strcspn("hello", world)); // should be 2
|
||||
printf("%ld\n", strcspn("banana", world)); // should be 6
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char dest1[13] = "hello world!";
|
||||
int dest1_len = strlen(dest1);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 12) {
|
||||
puts("strlen(\"hello world!\") failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char empty[1] = { 0 };
|
||||
int empty_len = strlen(empty);
|
||||
printf("%d\n", empty_len);
|
||||
if(empty_len != 0) {
|
||||
puts("strlen(\"\") failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dest1_len = strnlen(dest1, sizeof(dest1));
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 12) {
|
||||
puts("strnlen(\"hello world!\", 13) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dest1_len = strnlen(dest1, sizeof(dest1) - 1);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 12) {
|
||||
puts("strnlen(\"hello world!\", 12) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dest1_len = strnlen(dest1, 0);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 0) {
|
||||
puts("strnlen(\"hello world!\", 0) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dest1_len = strnlen(dest1, 300);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 12) {
|
||||
puts("strnlen(\"hello world!\", 300) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// no strnlen_s on glibc
|
||||
#ifndef __GLIBC__
|
||||
dest1_len = strnlen_s(dest1, 6);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 6) {
|
||||
puts("strnlen_s(\"hello world!\", 6) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dest1_len = strnlen_s(dest1, 20);
|
||||
printf("%d\n", dest1_len);
|
||||
if(dest1_len != 12) {
|
||||
puts("strnlen_s(\"hello world!\", 20) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int null_len = strnlen_s(NULL, 100);
|
||||
printf("%d\n", null_len);
|
||||
if(null_len != 0) {
|
||||
puts("strnlen_s(NULL, 100) failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
printf("%d\n", strncmp("a", "aa", 2));
|
||||
printf("%d\n", strncmp("a", "aä", 2));
|
||||
printf("%d\n", strncmp("\xFF", "\xFE", 2));
|
||||
printf("%d\n", strncmp("", "\xFF", 1));
|
||||
printf("%d\n", strncmp("a", "c", 1));
|
||||
printf("%d\n", strncmp("a", "a", 2));
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char* source = "The quick drawn fix jumps over the lazy bug";
|
||||
|
||||
// should be "The quick drawn fix jumps over the lazy bug"
|
||||
char* res1 = strpbrk(source, "From The Very Beginning");
|
||||
printf("%s\n", (res1) ? res1 : "NULL");
|
||||
|
||||
// should be "lazy bug"
|
||||
char* res2 = strpbrk(source, "lzbg");
|
||||
printf("%s\n", (res2) ? res2 : "NULL");
|
||||
|
||||
// should be "NULL"
|
||||
char* res3 = strpbrk(source, "404");
|
||||
printf("%s\n", (res3) ? res3 : "NULL");
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char s0[] = "hello, world";
|
||||
char *ptr = strrchr(s0, 'l');
|
||||
if (ptr != &s0[10]) {
|
||||
printf("%p != %p\n", ptr, &s0[10]);
|
||||
puts("strrchr FAIL");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char s1[] = "";
|
||||
ptr = strrchr(s1, 'a');
|
||||
if (ptr != NULL) {
|
||||
printf("%p != 0\n", ptr);
|
||||
puts("strrchr FAIL");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
puts("strrch PASS");
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
// Test case 1: Basic case with multiple tokens
|
||||
char str1[] = "apple,orange,banana";
|
||||
char *delim = ",";
|
||||
char *token = str1;
|
||||
char *result = NULL;
|
||||
|
||||
// First token should be "apple"
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "apple") == 0);
|
||||
|
||||
// Second token should be "orange"
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "orange") == 0);
|
||||
|
||||
// Third token should be "banana"
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "banana") == 0);
|
||||
|
||||
// No more tokens
|
||||
result = strsep(&token, delim);
|
||||
assert(result == NULL);
|
||||
|
||||
// Test case 2: Empty string
|
||||
char str2[] = "";
|
||||
token = str2;
|
||||
result = strsep(&token, delim);
|
||||
|
||||
// Test case 3: String with no delimiter
|
||||
char str3[] = "apple";
|
||||
token = str3;
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "apple") == 0);
|
||||
assert(token == NULL); // No more tokens
|
||||
|
||||
// Test case 4: String starts with delimiter
|
||||
char str4[] = ",apple,orange";
|
||||
token = str4;
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strlen(result) == 0); // First token should be an empty string ("")
|
||||
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "apple") == 0);
|
||||
|
||||
// Test case 5: Multiple delimiters in a row
|
||||
char str5[] = "apple,,orange";
|
||||
token = str5;
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "apple") == 0);
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strlen(result) == 0); // Empty token due to consecutive delimiters
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "orange") == 0);
|
||||
|
||||
// Test case 6: Delimiters at the end of the string
|
||||
char str6[] = "apple,orange,";
|
||||
token = str6;
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "apple") == 0);
|
||||
result = strsep(&token, delim);
|
||||
assert(result != NULL && strcmp(result, "orange") == 0);
|
||||
result = strsep(&token, delim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
puts("# strsignal #");
|
||||
const char *x = strsignal(SIGHUP);
|
||||
if (strcmp(x, "Hangup")) {
|
||||
printf("Incorrect strsignal (1), found: .%s.\n", x);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
x = strsignal(0);
|
||||
if (strcmp(x, "Unknown signal")) {
|
||||
printf("Incorrect strsignal (2), found: .%s.\n", x);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
x = strsignal(100);
|
||||
if (strcmp(x, "Unknown signal")) {
|
||||
printf("Incorrect strsignal (3), found: .%s.\n", x);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char *hello = "hello";
|
||||
char *world = "world";
|
||||
char *banana = "banana";
|
||||
printf("%lu\n", strspn(hello, "hello")); // should be 5
|
||||
printf("%lu\n", strspn(world, "wendy")); // should be 1
|
||||
printf("%lu\n", strspn(banana, "apple")); // should be 0
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
printf("%s\n", strstr("In relibc we trust", "rust"));
|
||||
printf("%s\n", strstr("In relibc we trust", "libc"));
|
||||
printf("%s\n", strstr("In relibc we trust", "bugs"));
|
||||
printf("%s\n", strstr("IN RELIBC WE TRUST", "rust"));
|
||||
printf("%s\n", strcasestr("IN RELIBC WE TRUST", "rust"));
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char source[] = "I'd just like to interject for a moment. What you're referring to as Linux, "
|
||||
"is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux.\n";
|
||||
|
||||
char* token = strtok(source, " ");
|
||||
while (token) {
|
||||
printf("%s", token);
|
||||
if ((token = strtok(NULL, " "))) {
|
||||
printf("_");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
char source[] = "I'd just like to interject for a moment. What you're referring to as Linux, "
|
||||
"is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux.\n";
|
||||
char* sp;
|
||||
|
||||
char* token = strtok_r(source, " ", &sp);
|
||||
while (token) {
|
||||
printf("%s", token);
|
||||
if ((token = strtok_r(NULL, " ", &sp))) {
|
||||
printf("_");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user