1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include "as.h"
26: #include "sb.h"
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42: static int dsize = 5;
43: static void sb_check (sb *, int);
44:
45:
46: static int string_count[sb_max_power_two];
47:
48:
49: static struct
50: {
51: sb_element *size[sb_max_power_two];
52: } free_list;
53:
54:
55:
56: static void
57: sb_build (sb *ptr, int size)
58: {
59:
60: sb_element *e;
61:
62: assert (size < sb_max_power_two);
63:
64: e = free_list.size[size];
65: if (!e)
66: {
67:
68: e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
69: e->next = free_list.size[size];
70: e->size = 1 << size;
71: free_list.size[size] = e;
72: string_count[size]++;
73: }
74:
75:
76: free_list.size[size] = e->next;
77:
78:
79: ptr->ptr = e->data;
80: ptr->pot = size;
81: ptr->len = 0;
82: ptr->item = e;
83: }
84:
85: void
86: sb_new (sb *ptr)
87: {
88: sb_build (ptr, dsize);
89: }
90:
91:
92:
93: void
94: sb_kill (sb *ptr)
95: {
96:
97: ptr->item->next = free_list.size[ptr->pot];
98: free_list.size[ptr->pot] = ptr->item;
99: }
100:
101:
102:
103: void
104: sb_add_sb (sb *ptr, sb *s)
105: {
106: sb_check (ptr, s->len);
107: memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
108: ptr->len += s->len;
109: }
110:
111:
112:
113: static sb *sb_to_scrub;
114: static char *scrub_position;
115: static int
116: scrub_from_sb (char *buf, int buflen)
117: {
118: int copy;
119: copy = sb_to_scrub->len - (scrub_position - sb_to_scrub->ptr);
120: if (copy > buflen)
121: copy = buflen;
122: memcpy (buf, scrub_position, copy);
123: scrub_position += copy;
124: return copy;
125: }
126:
127:
128:
129:
130: void
131: sb_scrub_and_add_sb (sb *ptr, sb *s)
132: {
133: sb_to_scrub = s;
134: scrub_position = s->ptr;
135:
136: sb_check (ptr, s->len);
137: ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len);
138:
139: sb_to_scrub = 0;
140: scrub_position = 0;
141: }
142:
143:
144:
145:
146: static void
147: sb_check (sb *ptr, int len)
148: {
149: if (ptr->len + len >= 1 << ptr->pot)
150: {
151: sb tmp;
152: int pot = ptr->pot;
153:
154: while (ptr->len + len >= 1 << pot)
155: pot++;
156: sb_build (&tmp, pot);
157: sb_add_sb (&tmp, ptr);
158: sb_kill (ptr);
159: *ptr = tmp;
160: }
161: }
162:
163:
164:
165: void
166: sb_reset (sb *ptr)
167: {
168: ptr->len = 0;
169: }
170:
171:
172:
173: void
174: sb_add_char (sb *ptr, int c)
175: {
176: sb_check (ptr, 1);
177: ptr->ptr[ptr->len++] = c;
178: }
179:
180:
181:
182: void
183: sb_add_string (sb *ptr, const char *s)
184: {
185: int len = strlen (s);
186: sb_check (ptr, len);
187: memcpy (ptr->ptr + ptr->len, s, len);
188: ptr->len += len;
189: }
190:
191:
192:
193: void
194: sb_add_buffer (sb *ptr, const char *s, int len)
195: {
196: sb_check (ptr, len);
197: memcpy (ptr->ptr + ptr->len, s, len);
198: ptr->len += len;
199: }
200:
201:
202:
203: char *
204: sb_terminate (sb *in)
205: {
206: sb_add_char (in, 0);
207: --in->len;
208: return in->ptr;
209: }
210:
211:
212:
213:
214: int
215: sb_skip_white (int idx, sb *ptr)
216: {
217: while (idx < ptr->len
218: && (ptr->ptr[idx] == ' '
219: || ptr->ptr[idx] == '\t'))
220: idx++;
221: return idx;
222: }
223:
224:
225:
226:
227:
228: int
229: sb_skip_comma (int idx, sb *ptr)
230: {
231: while (idx < ptr->len
232: && (ptr->ptr[idx] == ' '
233: || ptr->ptr[idx] == '\t'))
234: idx++;
235:
236: if (idx < ptr->len
237: && ptr->ptr[idx] == ',')
238: idx++;
239:
240: while (idx < ptr->len
241: && (ptr->ptr[idx] == ' '
242: || ptr->ptr[idx] == '\t'))
243: idx++;
244:
245: return idx;
246: }