fork download
  1. #include <stddef.h>
  2. #include <stdio.h>
  3.  
  4. ///
  5. /// @brief Appends contents of array `from` to array `to`.
  6. /// @pre `limit` != `0`
  7. /// @note No operation is performed for a `limit` of `0`.
  8. /// @remarks Resulting array is NUL-terminated.
  9. /// @param [out] to String to be written to.
  10. /// @param limit Maximum number of bytes that string `to` can store, including NUL.
  11. /// @param [in] from String to be copied from.
  12. /// @returns Size of resulting string (NUL not counted).
  13. ///
  14. size_t strscat(char *to, size_t limit, const char *from)
  15. {
  16. size_t s=0;
  17.  
  18. if (limit != 0)
  19. {
  20. while (to[s] != '\0')
  21. ++s;
  22.  
  23. for (size_t i=0; from[i] != '\0' && s < limit - 1; ++i, ++s)
  24. to[s] = from[i];
  25.  
  26. to[s] = '\0';
  27. }
  28.  
  29. return s;
  30. }
  31.  
  32. typedef struct
  33. {
  34. char *to;
  35. size_t limit;
  36. const char *from;
  37. const char *result;
  38. size_t retval;
  39. } test_t;
  40.  
  41. static size_t tests_failed;
  42.  
  43. static void run_test(test_t *t)
  44. {
  45. size_t i=0;
  46.  
  47. if (t->retval != strscat(t->to, t->limit, t->from))
  48. {
  49. ++tests_failed;
  50. return;
  51. }
  52.  
  53. while (t->result[i] != '\0' || t->to[i] != '\0')
  54. if (t->result[i] != t->to[i])
  55. {
  56. ++tests_failed;
  57. break;
  58. }
  59. else
  60. ++i;
  61. }
  62.  
  63. #define RUN_TEST(...) run_test(&(test_t){__VA_ARGS__})
  64.  
  65. int main(void)
  66. {
  67. RUN_TEST(
  68. .to = (char[15]){"The Cutty"},
  69. .limit = 15,
  70. .from = " Sark is a ship dry-docked in London.",
  71. .result = "The Cutty Sark",
  72. .retval = 14
  73. );
  74.  
  75. RUN_TEST(
  76. .to = (char[15]){"The Cutty"},
  77. .limit = 0,
  78. .from = "this won't get appended",
  79. .result = "The Cutty",
  80. .retval = 0
  81. );
  82.  
  83. RUN_TEST(
  84. .to = (char[15]){"The Cutty"},
  85. .limit = 15,
  86. .from = "!",
  87. .result = "The Cutty!",
  88. .retval = 10
  89. );
  90.  
  91. RUN_TEST(
  92. .to = (char[]){"The Cutty Sark"},
  93. .limit = 3,
  94. .from = "this shouldn't get appended",
  95. .result = "The Cutty Sark",
  96. .retval = 14
  97. );
  98.  
  99. RUN_TEST(
  100. .to = (char[]){"The Cutty Sark"},
  101. .limit = 1,
  102. .from = "this shouldn't get appended, either",
  103. .result = "The Cutty Sark",
  104. .retval = 14
  105. );
  106.  
  107. RUN_TEST(
  108. .to = (char[]){""},
  109. .limit = 1,
  110. .from = "this had better not get appended!",
  111. .result = "",
  112. .retval = 0
  113. );
  114.  
  115. (void)fprintf(stderr, "Number of tests failed: %zu.\n", tests_failed);
  116. }
Success #stdin #stdout #stderr 0s 2244KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Number of tests failed: 0.