/* Copyright (C) Hola 2012, 2013
*
* Welcome to TheCodeIL.com Challenge!
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
/**
* @brief Copy a string. Allocate memory if need.
*
* If buffer is not initialized (passed pointer to NULL as first parameter),
* str_cpy allocates buffer with @code len_src = strlen( src ) + 1 @endcode bytes of memory.
*
* If buffer is not valid pointer to memory block beginning, that leads to memory heap corruption.
*
* If src is not a valid string (or points to unallocated memory), it leads to undefined behaviuor.
* If src is NULL, the function deallocates dst.
*
* After execution if src is valid string, dst is allocated
* with len_src bytes of memory and contains copy of src.
*
* @param[out] dst Pointer to buffer where need to copy src.
* @param[in] src String (null-terminated char array) that being copied.
*
* @return dst destination
*/
char** str_cpy(char **dst, const char *src);
/**
* @brief Concatenate two strings.
*
* If dst is not initialized (passed pointer to NULL as first parameter),
* or there is an empty string in dst, procedure just copies second string to dst using str_cpy.
*
* If buffer is not valid pointer to memory block beginning, that leads to memory heap corruption.
*
* If src is not a valid string (or points to unallocated memory), it leads to undefined behaviuor.
* If src is NULL pointer, dst will not be changed.
*
* After execution, if *dst and src were valid strings, buffer is allocated
* with (len_dst + len_src - 1) bytes of memory and contains null-terminated strcat(*dst, src).
*
* @param[in, out] dst Pointer to buffer where the first part of string stores.
* @param[in] src The second part of string.
*
* @return dst destination
*/
char** str_cat(char **dst, const char *src);
/**
* No need to implement
*/
void str_printf(char **dst, const char *fmt, ...);
/**
* No need to implement
*/
void str_free(char **str);
/**
* @return number of bytes of null-terminated string (with '\0')
* 0, if not a pointer to char array passed (i.e. str = NULL)
*/
size_t str_len(const char *str);
int test00()
{
char *s = NULL;
str_cpy(&s, NULL); // check cpy NULL to NULL
return s != NULL;
}
int test0()
{
char *s = NULL;
str_cat(&s, NULL); // check cat NULL to NULL
return s != NULL;
}
int test1()
{
int ans;
char check[] = "Hola Hola";
char *s = NULL;
str_cpy(&s, check); // check allocation
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test2()
{
int ans;
char check[] = "Hola Hola";
char *s = (char*)calloc(1, strlen(check)+1);
str_cpy(&s, check); // check reallocation (needed more space)
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test3()
{
int ans;
char check[] = "Hola Hola";
char *s = (char*)calloc(1, 1);
str_cpy(&s, check); // simple str_cpy
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test4()
{
int ans;
char check[] = "Hola";
char words[] = "Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cpy(&s, s); // str_cpy with dst as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test5()
{
int ans;
char check[] = "Hola";
char words[] = "Hola Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cpy(&s, s+5); // str_cpy with shifted dst as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test6()
{
int ans;
char check[] = "";
char words[] = "Hola Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cpy(&s, ""); // str_cpy with "" as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test7()
{
char words[] = "Hola Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cpy(&s, NULL); // str_cpy with NULL as src
return s != NULL;
}
int test8()
{
int ans;
char check[] = "Hola";
char appnd[] = "Hola";
char *s = NULL;
str_cat(&s, appnd); // check allocation with str_cat
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test9()
{
int ans;
char check[] = "Hola";
char appnd[] = "Hola";
char *s = (char*)calloc(1, 1);
str_cat(&s, appnd); // check reallocation with str_cat
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test10()
{
int ans;
char check[] = "Hola World";
char words[] = "Hola";
char appnd[] = " World";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cat(&s, appnd); // simple str_cat
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test11()
{
int ans;
char check[] = "Hola Hola ";
char words[] = "Hola ";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cat(&s, s); // str_cat with dst as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test12()
{
int ans;
char check[] = "Hola World World";
char words[] = "Hola World";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cat(&s, s + 4); // str_cat with shifted dst as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test13()
{
int ans;
char check[] = "Hola";
char words[] = "Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cat(&s, ""); // str_cat with "" as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test14()
{
int ans;
char check[] = "Hola";
char words[] = "Hola";
char *s = (char*)calloc(1, strlen(words)+1);
strcpy(s, words);
str_cat(&s, NULL); // str_cat with NULL as src
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test15() // complex test 1
{
int ans;
char check[] = "Hola World";
char *s = NULL;
str_cpy(&s, "Hola Hola");
str_cpy(&s, s+5);
str_cat(&s, " World");
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test16() // complex test 2
{
int ans;
char check[] = "Hola ";
char words[] = "Hola ";
char *s = NULL;
int i;
str_cpy(&s, words);
for ( i = 0; i < 5; ++i ) {
str_cat(&s, s);
}
for ( i = 0; i < 31; ++i ) {
str_cpy(&s, s+5);
}
ans = strcmp(s, check);
str_free(&s);
return ans;
}
int test17()
{
int ans;
char check[] = "World";
char *s = NULL; // nesting str_cpy with str_cpy
ans = strcmp(*str_cpy(str_cpy(&s, "Hola "), "World"), check);
str_free(&s);
return ans;
}
int test18()
{
int ans;
char check[] = "Hola World";
char *s = NULL; // nesting str_cat with str_cpy
ans = strcmp(*str_cat(str_cpy(&s, "Hola "), "World"), check);
str_free(&s);
return ans;
}
int test19()
{
int ans;
char check[] = "Hola World";
char *s = NULL; // nesting str_cat with str_cat
ans = strcmp(*str_cat(str_cat(&s, "Hola "), "World"), check);
str_free(&s);
return ans;
}
int test20()
{
int ans;
char check[] = "World";
char *s = NULL; // nesting str_cpy with str_cat
ans = strcmp(*str_cpy(str_cat(&s, "Hola "), "World"), check);
str_free(&s);
return ans;
}
#define CHECK(x) \
if ( !x ) printf("%s : succeed\n", #x); \
else printf("%s : failed\n", #x);
int main(int argc, char *argv[])
{
CHECK(test00());
CHECK(test0());
CHECK(test1());
CHECK(test2());
CHECK(test3());
CHECK(test4());
CHECK(test5());
CHECK(test6());
CHECK(test7());
CHECK(test8());
CHECK(test9());
CHECK(test10());
CHECK(test11());
CHECK(test12());
CHECK(test13());
CHECK(test14());
CHECK(test15());
CHECK(test16());
CHECK(test17());
CHECK(test18());
CHECK(test19());
CHECK(test20());
getchar();
return 0;
}