fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4.  
  5.  
  6. typedef struct String String;
  7. struct String
  8. {
  9. size_t len;
  10. size_t cap;
  11. char *bytes;
  12. };
  13.  
  14. int
  15. Sinit(String *s, size_t cap)
  16. {
  17. char *bytes;
  18.  
  19. if (cap == 0)
  20. cap = 32;
  21. bytes = malloc(cap);
  22. if (bytes == NULL)
  23. return 0;
  24. s->len = 0;
  25. s->cap = cap;
  26. s->bytes = bytes;
  27. s->bytes[0] = '\0';
  28. return 1;
  29. }
  30.  
  31. void
  32. Sterm(String *s)
  33. {
  34. free(s->bytes);
  35. s->len = 0;
  36. s->cap = 0;
  37. }
  38.  
  39. int
  40. Sextend(String *s)
  41. {
  42. size_t cap;
  43. char *bytes;
  44.  
  45. cap = s->cap * 2;
  46. bytes = realloc(s->bytes, cap);
  47. if (bytes == NULL)
  48. return 0;
  49. s->cap = cap;
  50. s->bytes = bytes;
  51. return 1;
  52. }
  53.  
  54. int
  55. Sappend(String *s, char c)
  56. {
  57. if (s->len+1 == s->cap && !Sextend(s))
  58. return 0;
  59. s->bytes[s->len] = c;
  60. s->len++;
  61. s->bytes[s->len] = '\0';
  62. return 1;
  63. }
  64.  
  65. size_t
  66. Slen(String *s)
  67. {
  68. return s->len;
  69. }
  70.  
  71. char *
  72. Schars(String *s)
  73. {
  74. return s->bytes;
  75. }
  76.  
  77. void
  78. Sclear(String *s)
  79. {
  80. s->bytes[0] = '\0';
  81. s->len = 0;
  82. }
  83.  
  84. int
  85. Scopy(String *dst, String *src)
  86. {
  87. size_t cap;
  88.  
  89. while (src->len > dst->cap)
  90. if (!Sextend(dst))
  91. return 0;
  92. strcpy(dst->bytes, src->bytes);
  93. dst->bytes[src->len] = '\0';
  94. dst->len = src->len;
  95. return 1;
  96. }
  97.  
  98. /* -------------------------------- */
  99.  
  100. typedef struct Text Text;
  101. struct Text
  102. {
  103. size_t len;
  104. size_t cap;
  105. String *lines;
  106. };
  107.  
  108. int
  109. Tinit(Text *t, size_t cap)
  110. {
  111. String *lines;
  112.  
  113. if (cap == 0)
  114. cap = 4;
  115. lines = malloc(cap * sizeof(String));
  116. if (lines == NULL)
  117. return 0;
  118. t->cap = cap;
  119. t->len = 0;
  120. t->lines = lines;
  121. return 1;
  122. }
  123.  
  124. void
  125. Tterm(Text *t)
  126. {
  127. size_t i, len;
  128. String *line;
  129.  
  130. len = t->len;
  131. line = t->lines;
  132. for (i = 0; i < len; i++, line++)
  133. Sterm(line);
  134. free(t->lines);
  135. t->len = 0;
  136. t->cap = 0;
  137. }
  138.  
  139. int
  140. Textend(Text *t)
  141. {
  142. size_t cap;
  143. String *lines;
  144.  
  145. cap = t->cap * 2;
  146. lines = realloc(t->lines, cap * sizeof(String));
  147. if (lines == NULL)
  148. return 0;
  149. t->cap = cap;
  150. t->lines = lines;
  151. return 1;
  152. }
  153.  
  154. int
  155. Tappend(Text *t, String *s)
  156. {
  157. if (t->len == t->cap && !Textend(t))
  158. return 0;
  159. if (!Sinit(&t->lines[t->len], Slen(s)+1))
  160. return 0;
  161. Scopy(&t->lines[t->len], s);
  162. t->len++;
  163. return 1;
  164. }
  165.  
  166. size_t
  167. Tlen(Text *t)
  168. {
  169. return t->len;
  170. }
  171.  
  172. String *
  173. Tline(Text *t, size_t i)
  174. {
  175. return &t->lines[i];
  176. }
  177.  
  178. /* -------------------------------- */
  179.  
  180. #define IN 1
  181. #define OUT 0
  182.  
  183. int
  184. main(void)
  185. {
  186. int i, state, result;
  187. char c;
  188. String s;
  189. Text t;
  190.  
  191. if (!Tinit(&t, 0)) {
  192. result = 1;
  193. goto errT;
  194. }
  195. if (!Sinit(&s, 0)) {
  196. result = 1;
  197. goto errS;
  198. }
  199. state = OUT;
  200. result = 0;
  201. while ((c = getchar()) != EOF) {
  202. if (isspace(c)) {
  203. if (state == IN) {
  204. state = OUT;
  205. if (!Tappend(&t, &s)) {
  206. result = 1;
  207. goto end;
  208. }
  209. Sclear(&s);
  210. }
  211. } else {
  212. state = IN;
  213. if (!Sappend(&s, c)) {
  214. result = 1;
  215. goto end;
  216. }
  217. }
  218. }
  219.  
  220. if (state == IN)
  221. if (!Tappend(&t, &s)) {
  222. result = 1;
  223. goto end;
  224. }
  225.  
  226. for (i = 0; i < Tlen(&t); i++)
  227. printf("%s\n", Schars(Tline(&t, i)));
  228.  
  229. end:
  230. Tterm(&t);
  231. errS:
  232. Sterm(&s);
  233. errT:
  234. return result;
  235. }
Success #stdin #stdout 0s 2384KB
stdin
The quick brown fox
jumps over the lazy dog
stdout
The
quick
brown
fox
jumps
over
the
lazy
dog