1 /* this is the brisby fancy string */
2 #ifndef __str_h
3 #define __str_h
4 
5 #include "error.h"
6 
7 /* strange quirk of gcc? */
8 #define str_init(s) do { s[0].buf=0;s->used=0; str_need(s,1); s->buf[0] = 0; } while (0)
9 
10 struct str_s {
11 	char *buf;
12 	int used;
13 };
14 
15 typedef struct str_s str_t[1];
16 
17 #define str(x) x->buf
18 
19 #include <string.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 
23 /* Clib */
24 #define __str_clen(s) strlen(s)
25 
str_need(str_t p,int tot)26 static void inline str_need(str_t p, int tot)
27 {
28 	if (tot > p->used) {
29 		/* Clib */
30 		p->buf = realloc(p->buf, tot);
31 		if (!p->buf) {
32 			cfatal("str_need:realloc: %s");
33 		}
34 		p->used = tot;
35 	}
36 }
str_needplus(str_t p,int amu)37 static void inline str_needplus(str_t p, int amu)
38 {
39 	str_need(p, __str_clen(str(p))+amu);
40 }
41 #define str_chop(s) str_chopn(s, 1)
str_chopn(str_t p,int bytes)42 static void inline str_chopn(str_t p, int bytes)
43 {
44 	register int i = __str_clen(str(p)) - (bytes);
45 
46 	if (i > 0)
47 		p->buf[i] = 0;
48 }
49 
50 #define str_catstr(a,b) str_cat(a,str(b))
51 #define str_catbstr(a,b,c) str_catb(a,str(b),c)
str_cat(str_t p,char * s)52 static void inline str_cat(str_t p, char *s) {
53 	str_needplus(p, __str_clen(s)+1);
54 	/* Clib */
55 	strcat(p->buf, s);
56 }
str_catb(str_t p,char * s,int len)57 static void inline str_catb(str_t p, char *s, int len) {
58 	str_needplus(p, len+1);
59 	/* Clib */
60 	strncat(p->buf, s, len);
61 }
62 
63 #define str_copystr(a,b) str_copy(a,str(b))
str_copy(str_t p,char * s)64 static void inline str_copy(str_t p, char *s) {
65 	str_need(p, __str_clen(s)+1);
66 	/* Clib */
67 	strcpy(p->buf, s);
68 }
69 
str_uc(char * s)70 static void inline str_uc(char *s) {
71 	register int i;
72 	for (i = 0; s[i]; i++) {
73 		/* Clib */
74 		s[i] = toupper(((unsigned int)s[i]));
75 	}
76 }
str_lc(char * s)77 static void inline str_lc(char *s) {
78 	register int i;
79 	for (i = 0; s[i]; i++) {
80 		/* Clib */
81 		s[i] = tolower(((unsigned int)s[i]));
82 	}
83 }
84 
85 /* Clib */
86 #define str_ucfirst(s) (s[0] = touppwer(s[0]))
87 #define str_lcfirst(s) (s[0] = tolower(s[0]))
88 
str_addch(str_t p,int ch)89 static void inline str_addch(str_t p, int ch) {
90 	char b[2];
91 
92 	b[0] = ch; b[1] = '\0';
93 	str_cat(p, b);
94 }
95 
str_len(str_t p)96 static int inline str_len(str_t p) {
97 	return __str_clen(str(p));
98 }
99 
100 #define str_equal(a,b) (!str_diff(a,b))
101 #define str_equali(a,b) (!str_diffi(a,b))
102 #define str_diffni(a,b,l) (!str_diffin(a,b,l))
103 #define str_start(a,b) (!str_diffn(a,b,__str_clen(b)))
104 #define str_starti(a,b) (!str_diffin(a,b,__str_clen(b)))
105 #define str_startn(a,b,l) (!str_diffn(a,b,l))
106 #define str_startni(a,b,l) (!str_diffin(a,b,l))
107 #define str_startin(a,b,l) (!str_diffin(a,b,l))
str_diff(char * a,char * b)108 static int inline str_diff(char *a, char *b) {
109 	/* Clib */
110 	return strcmp(a, b);
111 }
str_diffn(char * a,char * b,int l)112 static int inline str_diffn(char *a, char *b, int l) {
113 	/* Clib */
114 	return strncmp(a, b, l);
115 }
str_diffi(char * a,char * b)116 static int inline str_diffi(char *a, char *b) {
117 	/* Clib */
118 	return strcasecmp(a,b);
119 }
str_diffin(char * a,char * b,int l)120 static int inline str_diffin(char *a, char *b, int l) {
121 	/* Clib */
122 	return strncasecmp(a,b, l);
123 }
str_dup(char * s)124 static char inline *str_dup(char *s)
125 {
126 	str_t p;
127 
128 	str_init(p);
129 	str_copy(p, s);
130 
131 	return str(p);
132 }
str_chtoi(int ch)133 static int inline str_chtoi(int ch)
134 {
135 	switch (ch) {
136 	case '1': return 1;
137 	case '2': return 2;
138 	case '3': return 3;
139 	case '4': return 4;
140 	case '5': return 5;
141 	case '6': return 6;
142 	case '7': return 7;
143 	case '8': return 8;
144 	case '9': return 9;
145 	};
146 	return 0;
147 }
148 
149 #endif
150