esh.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. #include "esh.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. /* Returns true if the string is in an unusable state, false if not. */
  5. int esh_bad_p(char **me, size_t * size, size_t * space) {
  6. if (!me) return !0;
  7. if (!*me) return !0;
  8. if (!size) return !0;
  9. if (!space) return !0;
  10. return 0;
  11. }
  12. /* Makes the string an empty string by writing a nul character at positon 0
  13. * and setting size to 0. */
  14. char * esh_make_empty(char ** me, size_t * size, size_t * space) {
  15. if (esh_bad_p(me, size, space)) return NULL;
  16. if ((*space) < 1) return NULL;
  17. (*me)[0] = '\0';
  18. (*size) = 0;
  19. return (*me);
  20. }
  21. /* Ensures the string is NUL terminated. */
  22. char * esh_nul_terminate(char ** me, size_t * size, size_t * space) {
  23. if (esh_bad_p(me, size, space)) return NULL;
  24. if (((*size) + 1) > (*space)) {
  25. (*me)[(*space)] = '\0';
  26. (*size) = (*space) - 1;
  27. } else {
  28. (*me)[(*size)+1] = '\0';
  29. }
  30. return (*me);
  31. }
  32. /* allocates a new string buffer with init_space. If init_space == 0
  33. * uses 1024 in stead.*/
  34. char * esh_alloc(char ** me, size_t * size, size_t * space, size_t init_space) {
  35. if (!me) return NULL;
  36. if (!space) return NULL;
  37. if (!size) return NULL;
  38. if (init_space < 1) init_space = 1024;
  39. (*me) = calloc(init_space, 1);
  40. (*space) = init_space;
  41. if (!*me) return NULL;
  42. return esh_make_empty(me, size, space);
  43. }
  44. /* Grows the given string's space. */
  45. char * esh_grow(char ** me, size_t * size, size_t * space, size_t new_space) {
  46. char * aid;
  47. (void) size;
  48. if (!me) return NULL;
  49. if (!*me) return NULL;
  50. if (new_space <= (*space)) return NULL;
  51. aid = realloc(*me, new_space);
  52. if (!aid) return NULL;
  53. memset(aid + (*space), '\0', new_space - (*space));
  54. (*space) = new_space;
  55. (*me) = aid;
  56. return (*me);
  57. }
  58. /* Makes sure there is enough space to add amount characters. */
  59. char * esh_ensure_space(char ** me, size_t * size, size_t * space, size_t grow_by) {
  60. if (!me) return NULL;
  61. if (!*me) return NULL;
  62. if (!size) return NULL;
  63. if (!space) return NULL;
  64. if ((*space) < ((*size) + grow_by)) {
  65. if (!esh_grow(me, size, space, (*space) + grow_by + 255)) return NULL;
  66. }
  67. return (*me);
  68. }
  69. char * esh_append_char(char ** me, size_t * size, size_t * space, char ch) {
  70. if (!esh_ensure_space(me, size, space, 1)) return NULL;
  71. (*me)[(*size)] = ch;
  72. (*size) = (*size) + 1;
  73. return (*me);
  74. }
  75. char * esh_append_buf(char ** me, size_t * size, size_t * space, char * buf, size_t bufsize) {
  76. if (!esh_ensure_space(me, size, space, bufsize + 1)) return NULL;
  77. strncpy((*me) + (*size), buf, bufsize);
  78. (*size) = (*size) + bufsize;
  79. return esh_nul_terminate(me, size, space);
  80. }
  81. char * esh_append_cstr(char ** me, size_t * size, size_t * space, char * str) {
  82. return esh_append_buf(me, size, space, str, strlen(str));
  83. }
  84. char * esh_init_buf(char ** me, size_t * size, size_t * space, char * buf, size_t bufsize) {
  85. if (!size) return NULL;
  86. if (!esh_make_empty(me, size, space)) return NULL;
  87. return esh_append_buf(me, size, space, buf, bufsize);
  88. }
  89. char * esh_init_cstr(char ** me, size_t * size, size_t * space, char * buf) {
  90. return esh_init_buf(me, size, space, buf, strlen(buf));
  91. }
  92. char * esh_new_cstr(char **me, size_t * size, size_t * space, char * buf) {
  93. size_t bufsize;
  94. if (!buf) return esh_new_empty(me, size, space);
  95. bufsize = strlen(buf);
  96. return esh_new_buf(me, size, space, buf, bufsize);
  97. }
  98. char * esh_new_buf(char **me, size_t * size, size_t * space, char * buf, size_t bufsize) {
  99. if (!esh_alloc(me, size, space, bufsize)) return NULL;
  100. return esh_init_buf(me, size, space, buf, bufsize);
  101. }
  102. /* Creates a new string with the given space and initialies it from init. */
  103. char * esh_new(char **me, size_t * size, size_t * space, char * init) {
  104. return esh_new_buf(me, size, space, init, strlen(init));
  105. }
  106. /* Creates a new empty string with enough space. */
  107. char * esh_new_empty(char **me, size_t * size, size_t * space) {
  108. return esh_new(me, size, space, "");
  109. }
  110. /* Frees the string and sets it to NULL. */
  111. char * esh_free(char ** me, size_t * size, size_t * space) {
  112. if (!me) return NULL;
  113. if (!*me) return NULL;
  114. free(*me);
  115. *me = NULL;
  116. *size = 0;
  117. *space = 0;
  118. return NULL;
  119. }
  120. /** Reads in a file into the buffer. */
  121. char * esh_read_file(char ** me, size_t * size, size_t * space, FILE * file) {
  122. char aid[1024];
  123. int read;
  124. if (esh_bad_p(me, size, space)) return NULL;
  125. if (!file) return NULL;
  126. while(!feof(file)) {
  127. read = fread(aid, 1, sizeof(aid), file);
  128. if (read > 0) {
  129. esh_append_buf(me, size, space, aid, read);
  130. }
  131. }
  132. return (*me);
  133. }
  134. /** Reads a named file into the buffer. */
  135. char * esh_read_filename(char ** me, size_t * size, size_t * space, char * fn) {
  136. char * res;
  137. FILE * file = fopen(fn, "r");
  138. res = esh_read_file(me, size, space, file);
  139. if (file) fclose(file);
  140. return res;
  141. }
  142. /** Joins a NULL terminated list onto va*/
  143. char * esh_join_va(char ** me, size_t * size, size_t * space, va_list strings) {
  144. char * next;
  145. while ( (next = va_arg(strings, char *)) ) {
  146. if (!esh_append_cstr(me, size, space, next)) return NULL;
  147. }
  148. return *me;
  149. }
  150. /* Joins a NULL terminated lists of strings onto me */
  151. char * esh_join(char ** me, size_t * size, size_t * space, ...) {
  152. char * res;
  153. va_list strings;
  154. va_start(strings, space);
  155. res = esh_join_va(me, size, space, strings);
  156. va_end(strings);
  157. return res;
  158. }
  159. char * esh_init_join_cstr_va(char ** me, size_t * size, size_t * space, char * first, va_list strings) {
  160. if (!esh_init_cstr(me, size, space, first)) return NULL;
  161. return esh_join_va(me, size, space, strings);
  162. }
  163. char * esh_init_join_cstr(char ** me, size_t * size, size_t * space, char * first, ...)
  164. {
  165. char * res;
  166. va_list strings;
  167. va_start(strings, first);
  168. res = esh_init_join_cstr_va(me, size, space, first, strings);
  169. va_end(strings);
  170. return res;
  171. }
  172. char * esh_new_join_cstr_va(char ** me, size_t * size, size_t * space, char * first, va_list strings) {
  173. if (!esh_new_cstr(me, size, space, first)) return NULL;
  174. return esh_join_va(me, size, space, strings);
  175. }
  176. char * esh_new_join_cstr(char ** me, size_t * size, size_t * space, char * first, ...)
  177. {
  178. char * res;
  179. va_list strings;
  180. va_start(strings, first);
  181. res = esh_init_join_cstr_va(me, size, space, first, strings);
  182. va_end(strings);
  183. return res;
  184. }
  185. /** Deletes n bytes */
  186. #define SWIS_EXPAND(SWIS) &((SWIS)->text), &((SWIS)->size), &((SWIS)->space)
  187. int woesb_bad_p(struct woesb * me) {
  188. return (esh_bad_p(SWIS_EXPAND(me)));
  189. }
  190. struct woesb * woesb_make_empty(struct woesb * me) {
  191. if(!esh_make_empty(SWIS_EXPAND(me))) return NULL;
  192. return me;
  193. }
  194. struct woesb * woesb_nul_terminate(struct woesb * me) {
  195. if(!esh_nul_terminate(SWIS_EXPAND(me))) return NULL;
  196. return me;
  197. }
  198. struct woesb * woesb_alloc(struct woesb * me, size_t init_space) {
  199. if(!esh_alloc(SWIS_EXPAND(me), init_space)) return NULL;
  200. return me;
  201. }
  202. struct woesb * woesb_grow(struct woesb * me, size_t new_space) {
  203. if(!esh_grow(SWIS_EXPAND(me), new_space)) return NULL;
  204. return me;
  205. }
  206. struct woesb * woesb_ensure_space(struct woesb * me, size_t grow_by) {
  207. if(!esh_ensure_space(SWIS_EXPAND(me), grow_by)) return NULL;
  208. return me;
  209. }
  210. struct woesb * woesb_append_char(struct woesb * me, char ch) {
  211. if(!esh_append_char(SWIS_EXPAND(me), ch)) return NULL;
  212. return me;
  213. }
  214. struct woesb * woesb_append_buf(struct woesb * me, char * buf, size_t bufsize) {
  215. if(!esh_append_buf(SWIS_EXPAND(me), buf, bufsize)) return NULL;
  216. return me;
  217. }
  218. struct woesb * woesb_append_cstr(struct woesb * me, char * str) {
  219. if(!esh_append_cstr(SWIS_EXPAND(me), str)) return NULL;
  220. return me;
  221. }
  222. struct woesb * woesb_init_buf(struct woesb * me, char * buf, size_t bufsize) {
  223. if(!esh_init_buf(SWIS_EXPAND(me), buf, bufsize)) return NULL;
  224. return me;
  225. }
  226. struct woesb * woesb_init_cstr(struct woesb * me, char * buf) {
  227. if(!esh_init_cstr(SWIS_EXPAND(me), buf)) return NULL;
  228. return me;
  229. }
  230. struct woesb * woesb_new_buf(struct woesb * me, char * buf, size_t bufsize) {
  231. if(!esh_new_buf(SWIS_EXPAND(me), buf, bufsize)) return NULL;
  232. return me;
  233. }
  234. struct woesb * woesb_new(struct woesb * me, char * init) {
  235. if(!esh_new(SWIS_EXPAND(me), init)) return NULL;
  236. return me;
  237. }
  238. struct woesb * woesb_new_empty(struct woesb * me) {
  239. if(!esh_new_empty(SWIS_EXPAND(me))) return NULL;
  240. return me;
  241. }
  242. struct woesb * woesb_free(struct woesb * me) {
  243. esh_free(SWIS_EXPAND(me));
  244. return NULL;
  245. }
  246. struct woesb * woesb_read_file(struct woesb * me, FILE * file) {
  247. if(!esh_read_file(SWIS_EXPAND(me), file)) return NULL;
  248. return me;
  249. }
  250. struct woesb * woesb_read_filename(struct woesb * me, char * fn) {
  251. if(!esh_read_filename(SWIS_EXPAND(me), fn)) return NULL;
  252. return me;
  253. }
  254. struct woesb * woesb_join_va(struct woesb * me, va_list strings) {
  255. if (!esh_join_va(SWIS_EXPAND(me), strings)) return NULL;
  256. return me;
  257. }
  258. struct woesb * woesb_join(struct woesb * me, ...) {
  259. struct woesb * res;
  260. va_list strings;
  261. va_start(strings, me);
  262. res = woesb_join_va(me, strings);
  263. va_end(strings);
  264. return res;
  265. }
  266. struct woesb * woesb_init_join_va(struct woesb * me, char * first, va_list strings) {
  267. if (!esh_init_join_cstr_va(SWIS_EXPAND(me), first, strings)) return NULL;
  268. return me;
  269. }
  270. struct woesb * woesb_init_join(struct woesb * me, char * first, ...) {
  271. struct woesb * res;
  272. va_list strings;
  273. va_start(strings, first);
  274. res = woesb_init_join_va(me, first, strings);
  275. va_end(strings);
  276. return res;
  277. }
  278. struct woesb * woesb_new_join_va(struct woesb * me, char * first, va_list strings) {
  279. if (!esh_new_join_cstr_va(SWIS_EXPAND(me), first, strings)) return NULL;
  280. return me;
  281. }
  282. struct woesb * woesb_new_join(struct woesb * me, char * first, ...) {
  283. struct woesb * res;
  284. va_list strings;
  285. va_start(strings, first);
  286. res = woesb_new_join_va(me, first, strings);
  287. va_end(strings);
  288. return res;
  289. }