bstring  0.1.1
 All Data Structures Files Functions Macros Pages
bstrlib.h
Go to the documentation of this file.
1 /* Copyright 2002-2010 Paul Hsieh
2  * This file is part of Bstrlib.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of bstrlib nor the names of its contributors may be
15  * used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Alternatively, the contents of this file may be used under the terms of
31  * GNU General Public License Version 2 (the "GPL").
32  */
33 
42 #ifndef BSTRLIB_H
43 #define BSTRLIB_H
44 
45 #if __GNUC__ >= 4
46 #define BSTR_PUBLIC \
47  __attribute__ ((visibility ("default")))
48 #define BSTR_PRIVATE \
49  __attribute__ ((visibility ("hidden")))
50 #else
51 #define BSTR_PUBLIC
52 #define BSTR_PRIVATE
53 #endif
54 
55 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
56 #define BSTR_PRINTF(format, argument) \
57  __attribute__ ((__format__ (__printf__, format, argument)))
58 #define BSTR_UNUSED \
59  __attribute__ ((__unused__))
60 #else
61 #define BSTR_PRINTF(format, argument)
62 #define BSTR_UNUSED
63 #endif
64 
65 #ifdef __cplusplus
66 extern "C" {
67 #endif
68 
69 #include <stdarg.h>
70 #include <string.h>
71 #include <limits.h>
72 #include <ctype.h>
73 
74 #define BSTR_ERR (-1)
75 #define BSTR_OK (0)
76 #define BSTR_BS_BUFF_LENGTH_GET (0)
77 
78 typedef struct tagbstring *bstring;
79 
80 struct tagbstring {
81  int mlen;
82  int slen;
83  unsigned char *data;
84 };
85 
86 /* Copy functions */
87 #define cstr2bstr bfromcstr
88 
104 BSTR_PUBLIC bstring
105 bfromcstr(const char *str);
106 
126 BSTR_PUBLIC bstring
127 bfromcstralloc(int mlen, const char *str);
128 
137 BSTR_PUBLIC bstring
138 blk2bstr(const void *blk, int len);
139 
148 BSTR_PUBLIC char *
149 bstr2cstr(const bstring s, char z);
150 
161 BSTR_PUBLIC int
162 bcstrfree(char *s);
163 
170 BSTR_PUBLIC bstring
171 bstrcpy(const bstring b1);
172 
179 BSTR_PUBLIC int
180 bassign(bstring a, const bstring b);
181 
190 BSTR_PUBLIC int
191 bassignmidstr(bstring a, const bstring b, int left, int len);
192 
199 BSTR_PUBLIC int
200 bassigncstr(bstring a, const char *str);
201 
210 BSTR_PUBLIC int
211 bassignblk(bstring a, const void *s, int len);
212 
213 /* Destroy function */
214 
227 BSTR_PUBLIC int
228 bdestroy(bstring b);
229 
230 /* Space allocation hinting functions */
231 
262 BSTR_PUBLIC int
263 balloc(bstring s, int len);
264 
289 BSTR_PUBLIC int
290 ballocmin(bstring b, int len);
291 
292 /* Substring extraction */
293 
301 BSTR_PUBLIC bstring
302 bmidstr(const bstring b, int left, int len);
303 
304 /*Various standard manipulations */
305 
312 BSTR_PUBLIC int
313 bconcat(bstring b0, const bstring b1);
314 
321 BSTR_PUBLIC int
322 bconchar(bstring b0, char c);
323 
330 BSTR_PUBLIC int
331 bcatcstr(bstring b, const char *s);
332 
339 BSTR_PUBLIC int
340 bcatblk(bstring b, const void *s, int len);
341 
350 BSTR_PUBLIC int
351 binsert(bstring s1, int pos, const bstring s2, unsigned char fill);
352 
362 BSTR_PUBLIC int
363 binsertch(bstring s1, int pos, int len, unsigned char fill);
364 
372 BSTR_PUBLIC int
373 breplace(bstring b1, int pos, int len, const bstring b2, unsigned char fill);
374 
384 BSTR_PUBLIC int
385 bdelete(bstring s1, int pos, int len);
386 
395 BSTR_PUBLIC int
396 bsetstr(bstring b0, int pos, const bstring b1, unsigned char fill);
397 
404 BSTR_PUBLIC int
405 btrunc(bstring b, int n);
406 
407 /*Scan/search functions */
408 
418 BSTR_PUBLIC int
419 bstricmp(const bstring b0, const bstring b1);
420 
431 BSTR_PUBLIC int
432 bstrnicmp(const bstring b0, const bstring b1, int n);
433 
442 BSTR_PUBLIC int
443 biseqcaseless(const bstring b0, const bstring b1);
444 
453 BSTR_PUBLIC int
454 bisstemeqcaselessblk(const bstring b0, const void *blk, int len);
455 
467 BSTR_PUBLIC int
468 biseq(const bstring b0, const bstring b1);
469 
478 BSTR_PUBLIC int
479 bisstemeqblk(const bstring b0, const void *blk, int len);
480 
492 BSTR_PUBLIC int
493 biseqcstr(const bstring b, const char *s);
494 
507 BSTR_PUBLIC int
508 biseqcstrcaseless(const bstring b, const char *s);
509 
532 BSTR_PUBLIC int
533 bstrcmp(const bstring b0, const bstring b1);
534 
549 BSTR_PUBLIC int
550 bstrncmp(const bstring b0, const bstring b1, int n);
551 
560 BSTR_PUBLIC int
561 binstr(const bstring s1, int pos, const bstring s2);
562 
573 BSTR_PUBLIC int
574 binstrr(const bstring s1, int pos, const bstring s2);
575 
584 BSTR_PUBLIC int
585 binstrcaseless(const bstring s1, int pos, const bstring s2);
586 
597 BSTR_PUBLIC int
598 binstrrcaseless(const bstring s1, int pos, const bstring s2);
599 
606 BSTR_PUBLIC int
607 bstrchrp(const bstring b, int c, int pos);
608 
615 BSTR_PUBLIC int
616 bstrrchrp(const bstring b, int c, int pos);
617 
624 #define bstrchr(b, c) \
625  bstrchrp((b), (c), 0)
626 
633 #define bstrrchr(b, c) \
634  bstrrchrp((b), (c), blength(b) - 1)
635 
643 BSTR_PUBLIC int
644 binchr(const bstring b0, int pos, const bstring b1);
645 
653 BSTR_PUBLIC int
654 binchrr(const bstring b0, int pos, const bstring b1);
655 
663 BSTR_PUBLIC int
664 bninchr(const bstring b0, int pos, const bstring b1);
665 
673 BSTR_PUBLIC int
674 bninchrr(const bstring b0, int pos, const bstring b1);
675 
697 BSTR_PUBLIC int
698 bfindreplace(bstring b, const bstring find, const bstring repl, int pos);
699 
721 BSTR_PUBLIC int
722 bfindreplacecaseless(bstring b, const bstring find, const bstring repl,
723  int pos);
724 
725 /* List of string container functions */
726 struct bstrList {
727  int qty, mlen;
728  bstring *entry;
729 };
730 
753 BSTR_PUBLIC struct bstrList *
754 bstrListCreate(void);
755 
761 BSTR_PUBLIC int
762 bstrListDestroy(struct bstrList *sl);
763 
768 BSTR_PUBLIC int
769 bstrListAlloc(struct bstrList *sl, int msz);
770 
775 BSTR_PUBLIC int
776 bstrListAllocMin(struct bstrList *sl, int msz);
777 
778 /* String split and join functions */
779 
789 BSTR_PUBLIC struct bstrList *
790 bsplit(const bstring str, unsigned char splitChar);
791 
799 BSTR_PUBLIC struct bstrList *
800 bsplits(const bstring str, const bstring splitStr);
801 
809 BSTR_PUBLIC struct bstrList *
810 bsplitstr(const bstring str, const bstring splitStr);
811 
826 BSTR_PUBLIC bstring
827 bjoin(const struct bstrList *bl, const bstring sep);
828 
849 BSTR_PUBLIC int
850 bsplitcb(const bstring str,
851  unsigned char splitChar,
852  int pos,
853  int(*cb)(void *parm, int ofs, int len),
854  void *parm);
855 
876 BSTR_PUBLIC int
877 bsplitscb(const bstring str,
878  const bstring splitStr,
879  int pos,
880  int(*cb)(void *parm, int ofs, int len),
881  void *parm);
882 
903 BSTR_PUBLIC int
904 bsplitstrcb(const bstring str,
905  const bstring splitStr,
906  int pos,
907  int(*cb)(void *parm, int ofs, int len), void *parm);
908 
909 /* Miscellaneous functions */
910 
918 BSTR_PUBLIC int
919 bpattern(bstring b, int len);
920 
927 BSTR_PUBLIC int
928 btoupper(bstring b);
929 
936 BSTR_PUBLIC int
937 btolower(bstring b);
938 
945 BSTR_PUBLIC int
946 bltrimws(bstring b);
947 
954 BSTR_PUBLIC int
955 brtrimws(bstring b);
956 
963 BSTR_PUBLIC int
964 btrimws(bstring b);
965 
966 /* *printf format functions */
986 BSTR_PUBLIC bstring
987 bformat(const char *fmt, ...);
988 
1008 BSTR_PUBLIC int
1009 bformata(bstring b, const char *fmt, ...);
1010 
1030 BSTR_PUBLIC int
1031 bassignformat(bstring b, const char *fmt, ...);
1032 
1058 BSTR_PUBLIC int
1059 bvcformata(bstring b, int count, const char *fmt, va_list arglist);
1060 
1086 #define bvformata(ret, b, fmt, lastarg) \
1087 do { \
1088  bstring bstrtmp_b =(b); \
1089  const char *bstrtmp_fmt = (fmt); \
1090  int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
1091  for (;;) { \
1092  va_list bstrtmp_arglist; \
1093  va_start(bstrtmp_arglist, lastarg); \
1094  bstrtmp_r = bvcformata(bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, \
1095  bstrtmp_arglist); \
1096  va_end(bstrtmp_arglist); \
1097  if(bstrtmp_r >= 0) { \
1098  /* Everything went ok */ \
1099  bstrtmp_r = BSTR_OK; \
1100  break; \
1101  } else if(-bstrtmp_r <= bstrtmp_sz) { \
1102  /* A real error? */ \
1103  bstrtmp_r = BSTR_ERR; \
1104  break; \
1105  } \
1106  /* Doubled or target size */ \
1107  bstrtmp_sz = -bstrtmp_r; \
1108  } \
1109  ret = bstrtmp_r; \
1110 } while (0);
1111 
1112 typedef int (*bNgetc)(void *parm);
1113 
1114 typedef size_t (*bNread)(void *buff, size_t elsize, size_t nelem, void *parm);
1115 
1116 /* Input functions */
1117 
1152 BSTR_PUBLIC bstring
1153 bgets(bNgetc getcPtr, void *parm, char terminator);
1154 
1168 BSTR_PUBLIC bstring
1169 bread(bNread readPtr, void *parm);
1170 
1179 BSTR_PUBLIC int
1180 bgetsa(bstring b, bNgetc getcPtr, void *parm, char terminator);
1181 
1190 BSTR_PUBLIC int
1191 bassigngets(bstring b, bNgetc getcPtr, void *parm, char terminator);
1192 
1199 BSTR_PUBLIC int
1200 breada(bstring b, bNread readPtr, void *parm);
1201 
1202 /* Stream functions */
1203 
1209 BSTR_PUBLIC struct bStream *
1210 bsopen(bNread readPtr, void *parm);
1211 
1218 BSTR_PUBLIC void *
1219 bsclose(struct bStream *s);
1220 
1228 BSTR_PUBLIC int
1229 bsbufflength(struct bStream *s, int sz);
1230 
1242 BSTR_PUBLIC int
1243 bsreadln(bstring b, struct bStream *s, char terminator);
1244 
1253 BSTR_PUBLIC int
1254 bsreadlns(bstring r, struct bStream *s, const bstring term);
1255 
1264 BSTR_PUBLIC int
1265 bsread(bstring b, struct bStream *s, int n);
1266 
1278 BSTR_PUBLIC int
1279 bsreadlna(bstring b, struct bStream *s, char terminator);
1280 
1291 BSTR_PUBLIC int
1292 bsreadlnsa(bstring r, struct bStream *s, const bstring term);
1293 
1302 BSTR_PUBLIC int
1303 bsreada(bstring b, struct bStream *s, int n);
1304 
1311 BSTR_PUBLIC int
1312 bsunread(struct bStream *s, const bstring b);
1313 
1319 BSTR_PUBLIC int
1320 bspeek(bstring r, const struct bStream *s);
1321 
1346 BSTR_PUBLIC int
1347 bssplitscb(struct bStream *s,
1348  const bstring splitStr,
1349  int(*cb)(void *parm, int ofs, const bstring entry),
1350  void *parm);
1351 
1376 BSTR_PUBLIC int
1377 bssplitstrcb(struct bStream *s,
1378  const bstring splitStr,
1379  int(*cb)(void *parm, int ofs, const bstring entry),
1380  void *parm);
1381 
1399 BSTR_PUBLIC int
1400 bseof(const struct bStream *s);
1401 
1402 /* Accessor macros */
1403 
1409 #define blengthe(b, e) \
1410  (((b) == (void *)0 || (b)->slen < 0) \
1411  ? (int)(e) \
1412  : ((b)->slen))
1413 
1419 #define blength(b) \
1420  (blengthe((b), 0))
1421 
1427 #define bdataofse(b, o, e) \
1428  (((b) == (void *)0 || (b)->data == (void *)0) \
1429  ? (char *)(e) \
1430  : ((char *)(b)->data) + (o))
1431 
1437 #define bdataofs(b, o) \
1438  (bdataofse((b),(o),(void *)0))
1439 
1445 #define bdatae(b, e) \
1446  (bdataofse(b, 0, e))
1447 
1453 #define bdata(b) \
1454  (bdataofs(b, 0))
1455 
1462 #define bchare(b, p, e) \
1463  ((((unsigned)(p)) < (unsigned)blength(b)) \
1464  ? ((b)->data[(p)]) \
1465  : (e))
1466 
1473 #define bchar(b, p) \
1474  bchare((b), (p), '\0')
1475 
1476 /* Static constant string initialization macro */
1477 
1480 #define bsStaticMlen(q, m) { (m), (int)sizeof(q) - 1, (unsigned char *)("" q "") }
1481 
1482 #if defined (_MSC_VER)
1483 /* There are many versions of MSVC which emit __LINE__ as a non-constant. */
1497 #define bsStatic(q) bsStaticMlen(q, -32)
1498 #endif /* defined (_MSC_VER) */
1499 
1500 #ifndef bsStatic
1501 
1503 #define bsStatic(q) bsStaticMlen(q, -__LINE__)
1504 #endif /* bsStatic */
1505 
1506 /* Static constant block parameter pair */
1507 
1526 #define bsStaticBlkParms(q) \
1527  ((void *)("" q "")), ((int)sizeof(q) -1)
1528 
1529 /* Reference building macros */
1530 
1533 #define cstr2tbstr btfromcstr
1534 
1548 #define btfromcstr(t, s) \
1549 do { \
1550  (t).data = (unsigned char *)(s); \
1551  (t).slen = ((t).data) \
1552  ? ((int)(strlen)((char *)(t).data)) \
1553  : 0; \
1554  (t).mlen = -1; \
1555 } while (0)
1556 
1559 #define blk2tbstr(t, s, l) \
1560 do { \
1561  (t).data = (unsigned char *)(s); \
1562  (t).slen = l; \
1563  (t).mlen = -1; \
1564 } while (0)
1565 
1580 #define btfromblk(t, s, l) blk2tbstr(t, s, l)
1581 
1597 #define bmid2tbstr(t, b, p, l) \
1598 do { \
1599  const bstring bstrtmp_s =(b); \
1600  if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
1601  int bstrtmp_left = (p); \
1602  int bstrtmp_len = (l); \
1603  if (bstrtmp_left < 0) { \
1604  bstrtmp_len += bstrtmp_left; \
1605  bstrtmp_left = 0; \
1606  } \
1607  if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) { \
1608  bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
1609  } \
1610  if(bstrtmp_len <= 0) { \
1611  (t).data =(unsigned char *)""; \
1612  (t).slen = 0; \
1613  } else { \
1614  (t).data = bstrtmp_s->data + bstrtmp_left; \
1615  (t).slen = bstrtmp_len; \
1616  } \
1617  } else { \
1618  (t).data = (unsigned char *)""; \
1619  (t).slen = 0; \
1620  } \
1621  (t).mlen = -__LINE__; \
1622 } while (0);
1623 
1638 #define btfromblkltrimws(t, s, l) \
1639 do { \
1640  int bstrtmp_idx = 0, bstrtmp_len =(l); \
1641  unsigned char *bstrtmp_s = (s); \
1642  if (bstrtmp_s && bstrtmp_len >= 0) { \
1643  for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
1644  if (!isspace(bstrtmp_s[bstrtmp_idx])) { \
1645  break; \
1646  } \
1647  } \
1648  } \
1649  (t).data = bstrtmp_s + bstrtmp_idx; \
1650  (t).slen = bstrtmp_len - bstrtmp_idx; \
1651  (t).mlen = -__LINE__; \
1652 } while (0);
1653 
1668 #define btfromblkrtrimws(t, s, l) \
1669 do { \
1670  int bstrtmp_len = (l) - 1; \
1671  unsigned char *bstrtmp_s = (s); \
1672  if (bstrtmp_s && bstrtmp_len >= 0) { \
1673  for (; bstrtmp_len >= 0; bstrtmp_len--) { \
1674  if (!isspace(bstrtmp_s[bstrtmp_len])) { \
1675  break; \
1676  } \
1677  } \
1678  } \
1679  (t).data = bstrtmp_s; \
1680  (t).slen = bstrtmp_len + 1; \
1681  (t).mlen = -__LINE__; \
1682 } while (0);
1683 
1698 #define btfromblktrimws(t, s, l) \
1699 do { \
1700  int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
1701  unsigned char *bstrtmp_s = (s); \
1702  if (bstrtmp_s && bstrtmp_len >= 0) { \
1703  for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
1704  if(!isspace(bstrtmp_s[bstrtmp_idx])) { \
1705  break; \
1706  } \
1707  } \
1708  for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
1709  if (!isspace(bstrtmp_s[bstrtmp_len])) { \
1710  break; \
1711  } \
1712  } \
1713  } \
1714  (t).data = bstrtmp_s + bstrtmp_idx; \
1715  (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
1716  (t).mlen = -__LINE__; \
1717 } while (0);
1718 
1719 /* Write protection macros */
1720 
1729 #define bwriteprotect(t) \
1730 do { \
1731  if ((t).mlen >= 0) { \
1732  (t).mlen = -1; \
1733  } \
1734 } while (0);
1735 
1748 #define bwriteallow(t) \
1749 do { \
1750  if ((t).mlen == -1) { \
1751  (t).mlen = (t).slen + ((t).slen == 0); \
1752  } \
1753 } while (0);
1754 
1758 #define biswriteprotected(t) \
1759  ((t).mlen <= 0)
1760 
1761 #ifdef __cplusplus
1762 }
1763 #endif
1764 
1765 #endif /* BSTRLIB_H */