aboutsummaryrefslogtreecommitdiff
path: root/src/bstrlib.h
blob: c8fa6944958b5d2a82f2e2d3e0c31307b091f04c (plain)
  1. /*
  2.  * This source file is part of the bstring string library. This code was
  3. * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
  4. * BSD open source license or GPL v2.0. Refer to the accompanying documentation
  5. * for details on usage and license.
  6. */
  7. /*
  8. * bstrlib.h
  9. *
  10. * This file is the header file for the core module for implementing the
  11. * bstring functions.
  12. */
  13. #ifndef BSTRLIB_INCLUDE
  14. #define BSTRLIB_INCLUDE
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. #include <stdarg.h>
  19. #include <string.h>
  20. #include <limits.h>
  21. #include <ctype.h>
  22. #if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
  23. # if defined (__TURBOC__) && !defined (__BORLANDC__)
  24. # define BSTRLIB_NOVSNP
  25. # endif
  26. #endif
  27. #define BSTR_ERR (-1)
  28. #define BSTR_OK (0)
  29. #define BSTR_BS_BUFF_LENGTH_GET (0)
  30. typedef struct tagbstring * bstring;
  31. typedef const struct tagbstring * const_bstring;
  32. /* Copy functions */
  33. #define cstr2bstr bfromcstr
  34. extern bstring bfromcstr (const char * str);
  35. extern bstring bfromcstralloc (int mlen, const char * str);
  36. extern bstring blk2bstr (const void * blk, int len);
  37. extern char * bstr2cstr (const_bstring s, char z);
  38. extern int bcstrfree (char * s);
  39. extern bstring bstrcpy (const_bstring b1);
  40. extern int bassign (bstring a, const_bstring b);
  41. extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
  42. extern int bassigncstr (bstring a, const char * str);
  43. extern int bassignblk (bstring a, const void * s, int len);
  44. /* Destroy function */
  45. extern int bdestroy (bstring b);
  46. /* Space allocation hinting functions */
  47. extern int balloc (bstring s, int len);
  48. extern int ballocmin (bstring b, int len);
  49. /* Substring extraction */
  50. extern bstring bmidstr (const_bstring b, int left, int len);
  51. /* Various standard manipulations */
  52. extern int bconcat (bstring b0, const_bstring b1);
  53. extern int bconchar (bstring b0, char c);
  54. extern int bcatcstr (bstring b, const char * s);
  55. extern int bcatblk (bstring b, const void * s, int len);
  56. extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
  57. extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
  58. extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
  59. extern int bdelete (bstring s1, int pos, int len);
  60. extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
  61. extern int btrunc (bstring b, int n);
  62. /* Scan/search functions */
  63. extern int bstricmp (const_bstring b0, const_bstring b1);
  64. extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
  65. extern int biseqcaseless (const_bstring b0, const_bstring b1);
  66. extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
  67. extern int biseq (const_bstring b0, const_bstring b1);
  68. extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
  69. extern int biseqcstr (const_bstring b, const char * s);
  70. extern int biseqcstrcaseless (const_bstring b, const char * s);
  71. extern int bstrcmp (const_bstring b0, const_bstring b1);
  72. extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
  73. extern int binstr (const_bstring s1, int pos, const_bstring s2);
  74. extern int binstrr (const_bstring s1, int pos, const_bstring s2);
  75. extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
  76. extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
  77. extern int bstrchrp (const_bstring b, int c, int pos);
  78. extern int bstrrchrp (const_bstring b, int c, int pos);
  79. #define bstrchr(b,c) bstrchrp ((b), (c), 0)
  80. #define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
  81. extern int binchr (const_bstring b0, int pos, const_bstring b1);
  82. extern int binchrr (const_bstring b0, int pos, const_bstring b1);
  83. extern int bninchr (const_bstring b0, int pos, const_bstring b1);
  84. extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
  85. extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
  86. extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
  87. /* List of string container functions */
  88. struct bstrList {
  89. int qty, mlen;
  90. bstring * entry;
  91. };
  92. extern struct bstrList * bstrListCreate (void);
  93. extern int bstrListDestroy (struct bstrList * sl);
  94. extern int bstrListAlloc (struct bstrList * sl, int msz);
  95. extern int bstrListAllocMin (struct bstrList * sl, int msz);
  96. /* String split and join functions */
  97. extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
  98. extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
  99. extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
  100. extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
  101. extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
  102. int (* cb) (void * parm, int ofs, int len), void * parm);
  103. extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
  104. int (* cb) (void * parm, int ofs, int len), void * parm);
  105. extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
  106. int (* cb) (void * parm, int ofs, int len), void * parm);
  107. /* Miscellaneous functions */
  108. extern int bpattern (bstring b, int len);
  109. extern int btoupper (bstring b);
  110. extern int btolower (bstring b);
  111. extern int bltrimws (bstring b);
  112. extern int brtrimws (bstring b);
  113. extern int btrimws (bstring b);
  114. /* <*>printf format functions */
  115. #if !defined (BSTRLIB_NOVSNP)
  116. extern bstring bformat (const char * fmt, ...);
  117. extern int bformata (bstring b, const char * fmt, ...);
  118. extern int bassignformat (bstring b, const char * fmt, ...);
  119. extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
  120. #define bvformata(ret, b, fmt, lastarg) { \
  121. bstring bstrtmp_b = (b); \
  122. const char * bstrtmp_fmt = (fmt); \
  123. int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
  124. for (;;) { \
  125. va_list bstrtmp_arglist; \
  126. va_start (bstrtmp_arglist, lastarg); \
  127. bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
  128. va_end (bstrtmp_arglist); \
  129. if (bstrtmp_r >= 0) { /* Everything went ok */ \
  130. bstrtmp_r = BSTR_OK; \
  131. break; \
  132. } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
  133. bstrtmp_r = BSTR_ERR; \
  134. break; \
  135. } \
  136. bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
  137. } \
  138. ret = bstrtmp_r; \
  139. }
  140. #endif
  141. typedef int (*bNgetc) (void *parm);
  142. typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
  143. /* Input functions */
  144. extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
  145. extern bstring bread (bNread readPtr, void * parm);
  146. extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
  147. extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
  148. extern int breada (bstring b, bNread readPtr, void * parm);
  149. /* Stream functions */
  150. extern struct bStream * bsopen (bNread readPtr, void * parm);
  151. extern void * bsclose (struct bStream * s);
  152. extern int bsbufflength (struct bStream * s, int sz);
  153. extern int bsreadln (bstring b, struct bStream * s, char terminator);
  154. extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
  155. extern int bsread (bstring b, struct bStream * s, int n);
  156. extern int bsreadlna (bstring b, struct bStream * s, char terminator);
  157. extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
  158. extern int bsreada (bstring b, struct bStream * s, int n);
  159. extern int bsunread (struct bStream * s, const_bstring b);
  160. extern int bspeek (bstring r, const struct bStream * s);
  161. extern int bssplitscb (struct bStream * s, const_bstring splitStr,
  162. int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
  163. extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
  164. int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
  165. extern int bseof (const struct bStream * s);
  166. struct tagbstring {
  167. int mlen;
  168. int slen;
  169. unsigned char * data;
  170. };
  171. /* Accessor macros */
  172. #define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
  173. #define blength(b) (blengthe ((b), 0))
  174. #define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
  175. #define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
  176. #define bdatae(b, e) (bdataofse (b, 0, e))
  177. #define bdata(b) (bdataofs (b, 0))
  178. #define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
  179. #define bchar(b, p) bchare ((b), (p), '\0')
  180. /* Static constant string initialization macro */
  181. #define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
  182. #if defined(_MSC_VER)
  183. /* There are many versions of MSVC which emit __LINE__ as a non-constant. */
  184. # define bsStatic(q) bsStaticMlen(q,-32)
  185. #endif
  186. #ifndef bsStatic
  187. # define bsStatic(q) bsStaticMlen(q,-__LINE__)
  188. #endif
  189. /* Static constant block parameter pair */
  190. #define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
  191. /* Reference building macros */
  192. #define cstr2tbstr btfromcstr
  193. #define btfromcstr(t,s) { \
  194. (t).data = (unsigned char *) (s); \
  195. (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
  196. (t).mlen = -1; \
  197. }
  198. #define blk2tbstr(t,s,l) { \
  199. (t).data = (unsigned char *) (s); \
  200. (t).slen = l; \
  201. (t).mlen = -1; \
  202. }
  203. #define btfromblk(t,s,l) blk2tbstr(t,s,l)
  204. #define bmid2tbstr(t,b,p,l) { \
  205. const_bstring bstrtmp_s = (b); \
  206. if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
  207. int bstrtmp_left = (p); \
  208. int bstrtmp_len = (l); \
  209. if (bstrtmp_left < 0) { \
  210. bstrtmp_len += bstrtmp_left; \
  211. bstrtmp_left = 0; \
  212. } \
  213. if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
  214. bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
  215. if (bstrtmp_len <= 0) { \
  216. (t).data = (unsigned char *)""; \
  217. (t).slen = 0; \
  218. } else { \
  219. (t).data = bstrtmp_s->data + bstrtmp_left; \
  220. (t).slen = bstrtmp_len; \
  221. } \
  222. } else { \
  223. (t).data = (unsigned char *)""; \
  224. (t).slen = 0; \
  225. } \
  226. (t).mlen = -__LINE__; \
  227. }
  228. #define btfromblkltrimws(t,s,l) { \
  229. int bstrtmp_idx = 0, bstrtmp_len = (l); \
  230. unsigned char * bstrtmp_s = (s); \
  231. if (bstrtmp_s && bstrtmp_len >= 0) { \
  232. for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
  233. if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
  234. } \
  235. } \
  236. (t).data = bstrtmp_s + bstrtmp_idx; \
  237. (t).slen = bstrtmp_len - bstrtmp_idx; \
  238. (t).mlen = -__LINE__; \
  239. }
  240. #define btfromblkrtrimws(t,s,l) { \
  241. int bstrtmp_len = (l) - 1; \
  242. unsigned char * bstrtmp_s = (s); \
  243. if (bstrtmp_s && bstrtmp_len >= 0) { \
  244. for (; bstrtmp_len >= 0; bstrtmp_len--) { \
  245. if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
  246. } \
  247. } \
  248. (t).data = bstrtmp_s; \
  249. (t).slen = bstrtmp_len + 1; \
  250. (t).mlen = -__LINE__; \
  251. }
  252. #define btfromblktrimws(t,s,l) { \
  253. int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
  254. unsigned char * bstrtmp_s = (s); \
  255. if (bstrtmp_s && bstrtmp_len >= 0) { \
  256. for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
  257. if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
  258. } \
  259. for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
  260. if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
  261. } \
  262. } \
  263. (t).data = bstrtmp_s + bstrtmp_idx; \
  264. (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
  265. (t).mlen = -__LINE__; \
  266. }
  267. /* Write protection macros */
  268. #define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
  269. #define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
  270. #define biswriteprotected(t) ((t).mlen <= 0)
  271. #ifdef __cplusplus
  272. }
  273. #endif
  274. #endif