comparison src/vbuf.c @ 70:b12f4e50e2e8

Patch from Joachim Metz <joachim.metz@gmail.com> for 64 bit compile. Signed/unsigned cleanup from 'CFLAGS=-Wextra ./configure' Reindent vbuf.c to make it readable.
author Carl Byington <carl@five-ten-sg.com>
date Sun, 11 May 2008 10:04:33 -0700
parents f6db1f060a95
children 3cb02cb1e6cd
comparison
equal deleted inserted replaced
69:63c02a242ca9 70:b12f4e50e2e8
1 // {{{ includes
2 1
3 #include <ctype.h> 2 #include <ctype.h>
4 //#include "defines.h"
5 #include <errno.h> 3 #include <errno.h>
6 #include <iconv.h> 4 #include <iconv.h>
5 #include <limits.h>
7 #include <malloc.h> 6 #include <malloc.h>
8 #include <signal.h> 7 #include <signal.h>
9 #include <stdarg.h> 8 #include <stdarg.h>
10 #include <stdio.h> 9 #include <stdio.h>
11 #include <stdlib.h> 10 #include <stdlib.h>
15 14
16 #ifdef WITH_DMALLOC 15 #ifdef WITH_DMALLOC
17 #include <dmalloc.h> 16 #include <dmalloc.h>
18 #endif 17 #endif
19 18
20 // }}} 19
21 20 int skip_nl(char *s)
22 int skip_nl( char *s ) // {{{ returns the width of the newline at s[0] 21 {
23 { 22 if (s[0] == '\n')
24 if( s[0] == '\n' ) return 1; 23 return 1;
25 if( s[0] == '\r' && s[1] == '\n' ) return 2; 24 if (s[0] == '\r' && s[1] == '\n')
26 if( s[0] == '\0' ) return 0; 25 return 2;
27 return -1; 26 if (s[0] == '\0')
28 } // }}} 27 return 0;
29 int find_nl( vstr *vs ) // {{{ find newline of type type in b 28 return -1;
30 { 29 }
31 char *nextr, *nextn; 30
32 31
33 nextr = memchr( vs->b, '\r', vs->dlen ); 32 int find_nl(vstr * vs)
34 nextn = memchr( vs->b, '\n', vs->dlen ); 33 {
35 34 char *nextr, *nextn;
36 //case 1: UNIX, we find \n first 35
37 if( nextn && (nextr == NULL || nextr > nextn ) ) { 36 nextr = memchr(vs->b, '\r', vs->dlen);
38 return nextn - vs->b; 37 nextn = memchr(vs->b, '\n', vs->dlen);
39 } 38
40 39 //case 1: UNIX, we find \n first
41 //case 2: DOS, we find \r\n 40 if (nextn && (nextr == NULL || nextr > nextn)) {
42 if( NULL != nextr && NULL != nextn && 1 == (char*)nextn - (char*)nextr ) { 41 return nextn - vs->b;
43 return nextr - vs->b; 42 }
44 } 43 //case 2: DOS, we find \r\n
45 44 if (NULL != nextr && NULL != nextn && 1 == (char *) nextn - (char *) nextr) {
46 //case 3: we find nothing 45 return nextr - vs->b;
47 46 }
48 return -1; 47 //case 3: we find nothing
49 } // }}} 48
50 49 return -1;
51 // {{{ UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals 50 }
51
52
53 // UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals
52 54
53 //TODO: the following should not be 55 //TODO: the following should not be
54 char *wwbuf=NULL; 56 char *wwbuf = NULL;
55 size_t nwwbuf=0; 57 size_t nwwbuf = 0;
56 static int unicode_up=0; 58 static int unicode_up = 0;
57 iconv_t i16to8, i8to16, i8859_1to8, i8toi8859_1; 59 iconv_t i16to8, i8to16, i8859_1to8, i8toi8859_1;
58 60
59 void unicode_init() // {{{ 61
60 { 62 void unicode_init()
61 char *wipe = ""; 63 {
62 char dump[4]; 64 char *wipe = "";
63 65 char dump[4];
64 if( unicode_up ) unicode_close(); 66
65 67 if (unicode_up)
66 if( (iconv_t)-1 == (i16to8 = iconv_open( "UTF-8", "UTF-16" ) ) ) { 68 unicode_close();
67 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-16 to UTF-8.\n"); 69
68 exit( 1 ); 70 if ((iconv_t) - 1 == (i16to8 = iconv_open("UTF-8", "UTF-16"))) {
69 } 71 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-16 to UTF-8.\n");
70 72 exit(1);
71 if( (iconv_t)-1 == (i8to16 = iconv_open( "UTF-16", "UTF-8" ) ) ) { 73 }
72 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to UTF-16.\n"); 74
73 exit( 2 ); 75 if ((iconv_t) - 1 == (i8to16 = iconv_open("UTF-16", "UTF-8"))) {
74 } 76 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to UTF-16.\n");
75 77 exit(2);
76 //iconv will prefix output with an FF FE (utf-16 start seq), the following dumps that. 78 }
77 memset( dump, 'x', 4 ); 79 //iconv will prefix output with an FF FE (utf-16 start seq), the following dumps that.
78 ASSERT( 0 == utf8to16( wipe, 1, dump, 4 ), "unicode_init(): attempt to dump FF FE failed." ); 80 memset(dump, 'x', 4);
79 81 ASSERT(0 == utf8to16(wipe, 1, dump, 4), "unicode_init(): attempt to dump FF FE failed.");
80 if( (iconv_t)-1 == (i8859_1to8 = iconv_open( "UTF-8", "ISO_8859-1" ) ) ) { 82
81 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for ASCII to UTF-8.\n"); 83 if ((iconv_t) - 1 == (i8859_1to8 = iconv_open("UTF-8", "ISO_8859-1"))) {
82 exit( 1 ); 84 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for ASCII to UTF-8.\n");
83 } 85 exit(1);
84 86 }
85 87
86 if( (iconv_t)-1 == (i8toi8859_1 = iconv_open( "ISO_8859-1", "UTF-8" ) ) ) { 88 if ((iconv_t) - 1 == (i8toi8859_1 = iconv_open("ISO_8859-1", "UTF-8"))) {
87 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to ASCII.\n"); 89 fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to ASCII.\n");
88 exit( 1 ); 90 exit(1);
89 } 91 }
90 92
91 unicode_up = 1; 93 unicode_up = 1;
92 } 94 }
93 // }}} 95
94 void unicode_close() // {{{ 96
95 { 97 void unicode_close()
96 unicode_up = 0; 98 {
97 iconv_close( i8to16 ); 99 unicode_up = 0;
98 iconv_close( i16to8 ); 100 iconv_close(i8to16);
99 iconv_close( i8859_1to8 ); 101 iconv_close(i16to8);
100 iconv_close( i8toi8859_1 ); 102 iconv_close(i8859_1to8);
101 } 103 iconv_close(i8toi8859_1);
102 // }}} 104 }
103 105
104 //int utf16_write( FILE* stream, const void *buf, size_t count ) // {{{ write utf-8 or iso_8869-1 to stream after converting it to utf-16 106
107 //int utf16_write( FILE* stream, const void *buf, size_t count ) // write utf-8 or iso_8869-1 to stream after converting it to utf-16
105 //{ 108 //{
106 // 109 //
107 // //TODO: if anything big comes through here we are sunk, should do it 110 // //TODO: if anything big comes through here we are sunk, should do it
108 // //bit-by-bit, not one-big-gulp 111 // //bit-by-bit, not one-big-gulp
109 // 112 //
110 // size_t inbytesleft, outbytesleft; 113 // size_t inbytesleft, outbytesleft;
111 // char *inbuf, *outbuf; 114 // char *inbuf, *outbuf;
112 // size_t icresult; 115 // size_t icresult;
113 // size_t rl; 116 // size_t rl;
114 // 117 //
115 // //do we have enough buffer space? 118 // //do we have enough buffer space?
116 // if( !wwbuf || nwwbuf < (count * 2 + 2) ) { 119 // if( !wwbuf || nwwbuf < (count * 2 + 2) ) {
117 // wwbuf = F_REALLOC( wwbuf, count * 2 +2 ); 120 // wwbuf = F_REALLOC( wwbuf, count * 2 +2 );
118 // 121 //
119 // nwwbuf = count * 2 + 2; 122 // nwwbuf = count * 2 + 2;
120 // } 123 // }
121 // 124 //
122 // inbytesleft = count; outbytesleft = nwwbuf; 125 // inbytesleft = count; outbytesleft = nwwbuf;
123 // inbuf = (char*)buf; outbuf = wwbuf; 126 // inbuf = (char*)buf; outbuf = wwbuf;
124 // 127 //
125 //// fprintf(stderr, "X%s, %dX", (char*)buf, strlen( buf )); 128 //// fprintf(stderr, "X%s, %dX", (char*)buf, strlen( buf ));
126 //// fflush(stderr); 129 //// fflush(stderr);
127 // 130 //
128 // if( (rl = strlen( buf ) + 1) != count ) { 131 // if( (rl = strlen( buf ) + 1) != count ) {
129 // fprintf(stderr, "utf16_write(): reported buffer size (%d) does not match string length (%d)\n", 132 // fprintf(stderr, "utf16_write(): reported buffer size (%d) does not match string length (%d)\n",
130 // count, 133 // count,
131 // rl); 134 // rl);
132 // 135 //
133 // //hexdump( (char*)buf, 0, count, 1 ); 136 // //hexdump( (char*)buf, 0, count, 1 );
134 // 137 //
135 // raise( SIGSEGV ); 138 // raise( SIGSEGV );
136 // inbytesleft = rl; 139 // inbytesleft = rl;
137 // } 140 // }
138 // 141 //
139 //// fprintf(stderr, " attempting to convert:\n"); 142 //// fprintf(stderr, " attempting to convert:\n");
140 //// hexdump( (char*)inbuf, 0, count, 1 ); 143 //// hexdump( (char*)inbuf, 0, count, 1 );
141 // 144 //
142 // icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); 145 // icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
143 // 146 //
144 //// fprintf(stderr, " converted:\n"); 147 //// fprintf(stderr, " converted:\n");
145 //// hexdump( (char*)buf, 0, count, 1 ); 148 //// hexdump( (char*)buf, 0, count, 1 );
146 // 149 //
147 //// fprintf(stderr, " to:\n"); 150 //// fprintf(stderr, " to:\n");
148 //// hexdump( (char*)wwbuf, 0, nwwbuf, 1 ); 151 //// hexdump( (char*)wwbuf, 0, nwwbuf, 1 );
149 // 152 //
150 // if( (size_t)-1 == icresult ) { 153 // if( (size_t)-1 == icresult ) {
151 // fprintf(stderr, "utf16_write(): iconv failure(%d): %s\n", errno, strerror( errno ) ); 154 // fprintf(stderr, "utf16_write(): iconv failure(%d): %s\n", errno, strerror( errno ) );
152 // fprintf(stderr, " attempted to convert:\n"); 155 // fprintf(stderr, " attempted to convert:\n");
153 // hexdump( (char*)inbuf, 0, count, 1 ); 156 // hexdump( (char*)inbuf, 0, count, 1 );
154 // 157 //
155 // fprintf(stderr, " result:\n"); 158 // fprintf(stderr, " result:\n");
156 // hexdump( (char*)outbuf, 0, count, 1 ); 159 // hexdump( (char*)outbuf, 0, count, 1 );
157 // 160 //
158 // fprintf(stderr, "I'm going to segfault now.\n"); 161 // fprintf(stderr, "I'm going to segfault now.\n");
159 // raise( SIGSEGV ); 162 // raise( SIGSEGV );
160 // exit(1); 163 // exit(1);
161 // } 164 // }
162 // 165 //
163 // if( inbytesleft > 0 ) { 166 // if( inbytesleft > 0 ) {
164 // fprintf(stderr, "utf16_write(): iconv returned a short count.\n"); 167 // fprintf(stderr, "utf16_write(): iconv returned a short count.\n");
165 // exit(1); 168 // exit(1);
166 // } 169 // }
167 // 170 //
168 // return fwrite( wwbuf, nwwbuf - outbytesleft - 2, 1, stream ); 171 // return fwrite( wwbuf, nwwbuf - outbytesleft - 2, 1, stream );
169 //} 172 //}
170 // }}}
171 173
172 //char *utf16buf = NULL; 174 //char *utf16buf = NULL;
173 //int utf16buf_len = 0; 175 //int utf16buf_len = 0;
174 // 176 //
175 //int utf16_fprintf( FILE* stream, const char *fmt, ... ) // {{{ 177 //int utf16_fprintf( FILE* stream, const char *fmt, ... )
176 //{ 178 //{
177 // int result=0; 179 // int result=0;
178 // va_list ap; 180 // va_list ap;
179 // 181 //
180 // if( utf16buf == NULL ) { 182 // if( utf16buf == NULL ) {
181 // utf16buf = (char*)F_MALLOC( SZ_MAX + 1 ); 183 // utf16buf = (char*)F_MALLOC( SZ_MAX + 1 );
182 // 184 //
183 // utf16buf_len = SZ_MAX + 1; 185 // utf16buf_len = SZ_MAX + 1;
184 // } 186 // }
185 // 187 //
186 // va_start( ap, fmt ); 188 // va_start( ap, fmt );
187 // 189 //
188 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap ); 190 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap );
189 // 191 //
190 // if( result + 1 > utf16buf_len ) { //didn't have space, realloc() and try again 192 // if( result + 1 > utf16buf_len ) { //didn't have space, realloc() and try again
191 // fprintf(stderr, "utf16_fprintf(): buffer too small (%d), F_MALLOC(%d)\n", utf16buf_len, result); 193 // fprintf(stderr, "utf16_fprintf(): buffer too small (%d), F_MALLOC(%d)\n", utf16buf_len, result);
192 // free( utf16buf ); 194 // free( utf16buf );
193 // utf16buf_len = result + 1; 195 // utf16buf_len = result + 1;
194 // utf16buf = (char*)F_MALLOC( utf16buf_len ); 196 // utf16buf = (char*)F_MALLOC( utf16buf_len );
195 // 197 //
196 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap ); 198 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap );
197 // } 199 // }
198 // 200 //
199 // 201 //
200 // //didn't have space...again...something weird is going on... 202 // //didn't have space...again...something weird is going on...
201 // ASSERT( result + 1 <= utf16buf_len, "utf16_fprintf(): Unpossible error!\n"); 203 // ASSERT( result + 1 <= utf16buf_len, "utf16_fprintf(): Unpossible error!\n");
202 // 204 //
203 // if( 1 != utf16_write( stream, utf16buf, result + 1 ) ) 205 // if( 1 != utf16_write( stream, utf16buf, result + 1 ) )
204 // DIE( "Write error? -> %s or %s\n", strerror( errno ), uerr_str( uerr_get() ) ); 206 // DIE( "Write error? -> %s or %s\n", strerror( errno ), uerr_str( uerr_get() ) );
205 // 207 //
206 // return result; 208 // return result;
207 //} 209 //}
208 //// }}} 210 //
209 //int utf16to8( char *inbuf_o, char *outbuf_o, int length ) // {{{ 211 //int utf16to8( char *inbuf_o, char *outbuf_o, int length )
210 //{ 212 //{
211 // int inbytesleft = length; 213 // int inbytesleft = length;
212 // int outbytesleft = length; 214 // int outbytesleft = length;
213 // char *inbuf = inbuf_o; 215 // char *inbuf = inbuf_o;
214 // char *outbuf = outbuf_o; 216 // char *outbuf = outbuf_o;
215 // int rlen = -1, tlen; 217 // int rlen = -1, tlen;
216 // int icresult = -1; 218 // int icresult = -1;
217 // 219 //
218 // int i, strlen=-1; 220 // int i, strlen=-1;
219 // 221 //
220 // DEBUG( 222 // DEBUG(
221 // fprintf(stderr, " utf16to8(): attempting to convert:\n"); 223 // fprintf(stderr, " utf16to8(): attempting to convert:\n");
222 // //hexdump( (char*)inbuf_o, 0, length, 1 ); 224 // //hexdump( (char*)inbuf_o, 0, length, 1 );
223 // fflush(stderr); 225 // fflush(stderr);
224 // ); 226 // );
225 // 227 //
226 // for( i=0; i<length ; i+=2 ) { 228 // for( i=0; i<length ; i+=2 ) {
227 // if( inbuf_o[i] == 0 && inbuf_o[i + 1] == 0 ) { 229 // if( inbuf_o[i] == 0 && inbuf_o[i + 1] == 0 ) {
228 // //fprintf(stderr, "End of string found at: %d\n", i ); 230 // //fprintf(stderr, "End of string found at: %d\n", i );
229 // strlen = i; 231 // strlen = i;
230 // } 232 // }
231 // } 233 // }
232 // 234 //
233 // //hexdump( (char*)inbuf_o, 0, strlen, 1 ); 235 // //hexdump( (char*)inbuf_o, 0, strlen, 1 );
234 // 236 //
235 // if( -1 == strlen ) WARN("String is not zero-terminated."); 237 // if( -1 == strlen ) WARN("String is not zero-terminated.");
236 // 238 //
237 // //iconv does not like it when the inbytesleft > actual string length 239 // //iconv does not like it when the inbytesleft > actual string length
238 // //enum: zero terminated, length valid 240 // //enum: zero terminated, length valid
239 // // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case 241 // // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case
240 // // zero terminated, length long 242 // // zero terminated, length long
241 // // not zero terminated 243 // // not zero terminated
242 // // TODO: MEMORY BUG HERE! 244 // // TODO: MEMORY BUG HERE!
243 // for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) { 245 // for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) {
244 // if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){ 246 // if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){
245 // rlen = tlen + 2; 247 // rlen = tlen + 2;
246 // tlen = rlen; 248 // tlen = rlen;
247 // break; 249 // break;
248 // } 250 // }
249 // if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n"); 251 // if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n");
250 // } 252 // }
251 // 253 //
252 // if( rlen >= 0 ) 254 // if( rlen >= 0 )
253 // icresult = iconv( i16to8, &inbuf, &rlen, &outbuf, &outbytesleft ); 255 // icresult = iconv( i16to8, &inbuf, &rlen, &outbuf, &outbytesleft );
254 // 256 //
255 // if( icresult == (size_t)-1 ) { 257 // if( icresult == (size_t)-1 ) {
256 // fprintf(stderr, "utf16to8(): iconv failure(%d): %s\n", errno, strerror( errno ) ); 258 // fprintf(stderr, "utf16to8(): iconv failure(%d): %s\n", errno, strerror( errno ) );
257 // fprintf(stderr, " attempted to convert:\n"); 259 // fprintf(stderr, " attempted to convert:\n");
258 // hexdump( (char*)inbuf_o, 0, length, 1 ); 260 // hexdump( (char*)inbuf_o, 0, length, 1 );
259 // fprintf(stderr, " result:\n"); 261 // fprintf(stderr, " result:\n");
260 // hexdump( (char*)outbuf_o, 0, length, 1 ); 262 // hexdump( (char*)outbuf_o, 0, length, 1 );
261 // fprintf(stderr, " MyDirtyOut:\n"); 263 // fprintf(stderr, " MyDirtyOut:\n");
262 // for( i=0; i<length; i++) { 264 // for( i=0; i<length; i++) {
263 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] ); 265 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] );
264 // } 266 // }
265 // 267 //
266 // fprintf( stderr, "\n" ); 268 // fprintf( stderr, "\n" );
267 // raise( SIGSEGV ); 269 // raise( SIGSEGV );
268 // exit(1); 270 // exit(1);
269 // } 271 // }
270 // 272 //
271 // DEBUG( 273 // DEBUG(
272 // fprintf(stderr, " result:\n"); 274 // fprintf(stderr, " result:\n");
273 // hexdump( (char*)outbuf_o, 0, length, 1 ); 275 // hexdump( (char*)outbuf_o, 0, length, 1 );
274 // ) 276 // )
275 // 277 //
276 // //fprintf(stderr, "utf16to8() returning %s\n", outbuf ); 278 // //fprintf(stderr, "utf16to8() returning %s\n", outbuf );
277 // 279 //
278 // return icresult; 280 // return icresult;
279 //} 281 //}
280 //// }}} 282 //
281 int utf16_is_terminated( char *str, int length ) // {{{ 283
282 { 284
283 VSTR_STATIC( errbuf, 100 ); 285 int utf16_is_terminated(char *str, int length)
284 int len = -1; 286 {
285 int i; 287 VSTR_STATIC(errbuf, 100);
286 for( i=0; i<length ; i+=2 ) { 288 int len = -1;
287 if( str[i] == 0 && str[i + 1] == 0 ) { 289 int i;
288 //fprintf(stderr, "End of string found at: %d\n", i ); 290 for (i = 0; i < length; i += 2) {
289 len = i; 291 if (str[i] == 0 && str[i + 1] == 0) {
290 } 292 len = i;
291 } 293 }
292 294 }
293 //hexdump( (char*)inbuf_o, 0, len, 1 ); 295
294 296 if (-1 == len) {
295 if( -1 == len ) { 297 vshexdump(errbuf, str, 0, length, 1);
296 vshexdump( errbuf, str, 0, length, 1 ); 298 WARN("String is not zero terminated (probably broken data from registry) %s.", errbuf->b);
297 WARN("String is not zero terminated (probably broken data from registry) %s.", errbuf->b); 299 }
298 } 300
299 301 return (-1 == len) ? 0 : 1;
300 return (-1 == len )?0:1; 302 }
301 } // }}} 303
302 int vb_utf16to8( vbuf *dest, char *buf, int len ) // {{{ 304
303 { 305 int vb_utf16to8(vbuf * dest, char *buf, int len)
304 int inbytesleft = len; 306 {
305 char *inbuf = buf; 307 size_t inbytesleft = len;
306 //int rlen = -1, tlen; 308 char *inbuf = buf;
307 int icresult = -1; 309 size_t icresult = (size_t)-1;
308 VBUF_STATIC( dumpster, 100 ); 310 VBUF_STATIC(dumpster, 100);
309 311
310 //int i; //, strlen=-1; 312 size_t outbytesleft = 0;
311 int outbytesleft; 313 char *outbuf = NULL;
312 char *outbuf; 314
313 315 ASSERT(unicode_up, "vb_utf16to8() called before unicode started.");
314 ASSERT( unicode_up, "vb_utf16to8() called before unicode started." ); 316
315 317 if (2 > dest->blen)
316 if( 2 > dest->blen ) vbresize( dest, 2 ); 318 vbresize(dest, 2);
317 dest->dlen = 0; 319 dest->dlen = 0;
318 320
319 //Bad Things can happen if a non-zero-terminated utf16 string comes through here 321 //Bad Things can happen if a non-zero-terminated utf16 string comes through here
320 if( !utf16_is_terminated( buf, len ) ) return -1; 322 if (!utf16_is_terminated(buf, len))
321 323 return -1;
322 do { 324
323 outbytesleft = dest->blen - dest->dlen; 325 do {
324 outbuf = dest->b + dest->dlen; 326 outbytesleft = dest->blen - dest->dlen;
325 icresult = iconv( i16to8, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); 327 outbuf = dest->b + dest->dlen;
326 dest->dlen = outbuf - dest->b; 328 icresult = iconv(i16to8, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
327 vbgrow( dest, inbytesleft); 329 dest->dlen = outbuf - dest->b;
328 } while( (size_t)-1 == icresult && E2BIG == errno ); 330 vbgrow(dest, inbytesleft);
329 331 } while ((size_t)-1 == icresult && E2BIG == errno);
330 if( 0 != vb_utf8to16T( dumpster, dest->b, dest->dlen ) ) 332
331 DIE("Reverse conversion failed."); 333 if (0 != vb_utf8to16T(dumpster, dest->b, dest->dlen))
332 334 DIE("Reverse conversion failed.");
333 if( icresult == (size_t)-1 ) { 335
334 //TODO: error 336 if (icresult == (size_t)-1) {
335 //ERR_UNIX( errno, "vb_utf16to8():iconv failure: %s", strerror( errno ) ); 337 //TODO: error
336 unicode_init(); 338 //ERR_UNIX( errno, "vb_utf16to8():iconv failure: %s", strerror( errno ) );
337 return -1; 339 unicode_init();
338 /* 340 return -1;
339 fprintf(stderr, " attempted to convert:\n"); 341 /*
340 hexdump( (char*)cin, 0, inlen, 1 ); 342 fprintf(stderr, " attempted to convert:\n");
341 fprintf(stderr, " result:\n"); 343 hexdump( (char*)cin, 0, inlen, 1 );
342 hexdump( (char*)bout->b, 0, bout->dlen, 1 ); 344 fprintf(stderr, " result:\n");
343 fprintf(stderr, " MyDirtyOut:\n"); 345 hexdump( (char*)bout->b, 0, bout->dlen, 1 );
344 for( i=0; i<inlen; i++) { 346 fprintf(stderr, " MyDirtyOut:\n");
345 if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] ); 347 for( i=0; i<inlen; i++) {
346 } 348 if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] );
347 349 }
348 fprintf( stderr, "\n" ); 350
349 raise( SIGSEGV ); 351 fprintf( stderr, "\n" );
350 exit(1); 352 raise( SIGSEGV );
351 */ 353 exit(1);
352 } 354 */
353 355 }
354 if( icresult ) { 356
355 //ERR_UNIX( EILSEQ, "Uhhhh...vb_utf16to8() returning icresult == %d", icresult ); 357 if (icresult) {
356 return -1; 358 //ERR_UNIX( EILSEQ, "Uhhhh...vb_utf16to8() returning icresult == %d", icresult );
357 } 359 return -1;
358 return icresult; 360 }
359 } 361 return icresult;
360 // }}} 362 }
361 363
362 int utf8to16( char *inbuf_o, int iblen, char *outbuf_o, int oblen) // {{{ iblen, oblen: bytes including \0 364
363 { 365 int utf8to16(char *inbuf_o, int iblen, char *outbuf_o, int oblen) // iblen, oblen: bytes including \0
364 //TODO: this is *only* used to dump the utf16 preamble now... 366 {
365 //TODO: This (and 8to16) are the most horrible things I have ever seen... 367 //TODO: this is *only* used to dump the utf16 preamble now...
366 int inbytesleft; 368 //TODO: This (and 8to16) are the most horrible things I have ever seen...
367 int outbytesleft = oblen; 369 size_t inbytesleft = 0;
368 char *inbuf = inbuf_o; 370 size_t outbytesleft = oblen;
369 char *outbuf = outbuf_o; 371 char *inbuf = inbuf_o;
370 //int rlen = -1, tlen; 372 char *outbuf = outbuf_o;
371 int icresult = -1; 373 size_t icresult = (size_t)-1;
372 374 char *stend;
373 char *stend; 375
374 376 DEBUG(fprintf(stderr, " utf8to16(): attempting to convert:\n");
375 //int i; //, strlen=-1; 377 //hexdump( (char*)inbuf_o, 0, length, 1 );
376 378 fflush(stderr););
377 DEBUG( 379
378 fprintf(stderr, " utf8to16(): attempting to convert:\n"); 380 stend = memchr(inbuf_o, '\0', iblen);
379 //hexdump( (char*)inbuf_o, 0, length, 1 ); 381 ASSERT(NULL != stend, "utf8to16(): in string not zero terminated.");
380 fflush(stderr); 382
381 ); 383 inbytesleft = (stend - inbuf_o + 1 < iblen) ? stend - inbuf_o + 1 : iblen;
382 384
383 stend = memchr( inbuf_o, '\0', iblen ); 385 //iconv does not like it when the inbytesleft > actual string length
384 ASSERT( NULL != stend, "utf8to16(): in string not zero terminated." ); 386 //enum: zero terminated, length valid
385 387 // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case
386 inbytesleft = ( stend - inbuf_o + 1 < iblen )? stend - inbuf_o + 1: iblen; 388 // zero terminated, length long
387 389 // not zero terminated
388 //iconv does not like it when the inbytesleft > actual string length 390 // TODO: MEMORY BUG HERE!
389 //enum: zero terminated, length valid 391 //
390 // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case 392 /*
391 // zero terminated, length long 393 for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) {
392 // not zero terminated 394 if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){
393 // TODO: MEMORY BUG HERE! 395 rlen = tlen + 2;
394 // 396 tlen = rlen;
395 /* 397 break;
396 for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) { 398 }
397 if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){ 399 if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n");
398 rlen = tlen + 2; 400 }
399 tlen = rlen; 401 */
400 break; 402
401 } 403 //if( rlen >= 0 )
402 if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n"); 404 icresult = iconv(i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
403 } 405
404 */ 406 if (icresult == (size_t)-1) {
405 407 DIE("iconv failure(%d): %s\n", errno, strerror(errno));
406 //if( rlen >= 0 ) 408 //fprintf(stderr, " attempted to convert:\n");
407 icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); 409 //hexdump( (char*)inbuf_o, 0, iblen, 1 );
408 410 //fprintf(stderr, " result:\n");
409 if( icresult == (size_t)-1 ) { 411 //hexdump( (char*)outbuf_o, 0, oblen, 1 );
410 DIE("iconv failure(%d): %s\n", errno, strerror( errno ) ); 412 //fprintf(stderr, " MyDirtyOut:\n");
411 //fprintf(stderr, " attempted to convert:\n"); 413 // for( i=0; i<iblen; i++) {
412 //hexdump( (char*)inbuf_o, 0, iblen, 1 ); 414 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] );
413 //fprintf(stderr, " result:\n"); 415 // }
414 //hexdump( (char*)outbuf_o, 0, oblen, 1 ); 416 //
415 //fprintf(stderr, " MyDirtyOut:\n"); 417 // fprintf( stderr, "\n" );
416 // for( i=0; i<iblen; i++) { 418 // raise( SIGSEGV );
417 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] ); 419 // exit(1);
418 // } 420 }
419 // 421 // DEBUG(
420 // fprintf( stderr, "\n" ); 422 // fprintf(stderr, " result:\n");
421 // raise( SIGSEGV ); 423 // hexdump( (char*)outbuf_o, 0, oblen, 1 );
422 // exit(1); 424 // )
423 } 425
424 426 //fprintf(stderr, "utf8to16() returning %s\n", outbuf );
425 // DEBUG( 427
426 // fprintf(stderr, " result:\n"); 428 //TODO: error
427 // hexdump( (char*)outbuf_o, 0, oblen, 1 ); 429 DEBUG(
428 // ) 430 if (icresult)
429 431 printf("Uhhhh...utf8to16() returning icresult == %d\n", icresult);
430 //fprintf(stderr, "utf8to16() returning %s\n", outbuf ); 432 );
431 433
432 //TODO: error 434 if (icresult > (size_t)INT_MAX) {
433 if( icresult ) printf("Uhhhh...utf8to16() returning icresult == %d\n", icresult ); 435 return (-1);
434 return icresult; 436 }
435 } 437 return (int) icresult;
436 // }}} 438 }
437 439
438 int vb_utf8to16T( vbuf *bout, char *cin, int inlen ) // {{{ 440
439 { 441 int vb_utf8to16T(vbuf * bout, char *cin, int inlen)
440 //TODO: This (and 8to16) are the most horrible things I have ever seen... 442 {
441 int inbytesleft = inlen; 443 //TODO: This (and 8to16) are the most horrible things I have ever seen...
442 char *inbuf = cin; 444 size_t inbytesleft = inlen;
443 //int rlen = -1, tlen; 445 char *inbuf = cin;
444 int icresult = -1; 446 //int rlen = -1, tlen;
445 447 size_t icresult = (size_t)-1;
446 //int i; //, strlen=-1; 448 size_t outbytesleft = 0;
447 449 char *outbuf = NULL;
448 //if( rlen >= 0 ) 450
449 int outbytesleft; 451 if (2 > bout->blen)
450 char *outbuf; 452 vbresize(bout, 2);
451 if( 2 > bout->blen ) vbresize( bout, 2 ); 453 bout->dlen = 0;
452 bout->dlen = 0; 454
453 455 do {
454 do { 456 outbytesleft = bout->blen - bout->dlen;
455 outbytesleft = bout->blen - bout->dlen; 457 outbuf = bout->b + bout->dlen;
456 outbuf = bout->b + bout->dlen; 458 icresult = iconv(i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
457 icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); 459 bout->dlen = outbuf - bout->b;
458 bout->dlen = outbuf - bout->b; 460 vbgrow(bout, 20);
459 vbgrow( bout, 20 ); 461 } while ((size_t)-1 == icresult && E2BIG == errno);
460 } while( (size_t)-1 == icresult && E2BIG == errno ); 462
461 463 if (icresult == (size_t)-1) {
462 if( icresult == (size_t)-1 ) { 464 WARN("iconv failure: %s", strerror(errno));
463 WARN("iconv failure: %s", strerror( errno ) ); 465 //ERR_UNIX( errno, "vb_utf8to16():iconv failure: %s", strerror( errno ) );
464 //ERR_UNIX( errno, "vb_utf8to16():iconv failure: %s", strerror( errno ) ); 466 unicode_init();
465 unicode_init(); 467 return -1;
466 return -1; 468 /*
467 /* 469 fprintf(stderr, "vb_utf8to16(): iconv failure(%d == %d?): %s\n", errno, E2BIG, strerror( errno ) );
468 fprintf(stderr, "vb_utf8to16(): iconv failure(%d == %d?): %s\n", errno, E2BIG, strerror( errno ) ); 470 fprintf(stderr, " attempted to convert:\n");
469 fprintf(stderr, " attempted to convert:\n"); 471 hexdump( (char*)cin, 0, inlen, 1 );
470 hexdump( (char*)cin, 0, inlen, 1 ); 472 fprintf(stderr, " result:\n");
471 fprintf(stderr, " result:\n"); 473 hexdump( (char*)bout->b, 0, bout->dlen, 1 );
472 hexdump( (char*)bout->b, 0, bout->dlen, 1 ); 474 fprintf(stderr, " MyDirtyOut:\n");
473 fprintf(stderr, " MyDirtyOut:\n"); 475 for( i=0; i<inlen; i++) {
474 for( i=0; i<inlen; i++) { 476 if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] );
475 if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] ); 477 }
476 } 478
477 479 fprintf( stderr, "\n" );
478 fprintf( stderr, "\n" ); 480 raise( SIGSEGV );
479 raise( SIGSEGV ); 481 exit(1);
480 exit(1); 482 */
481 */ 483 }
482 } 484 DEBUG(
483 485 if (icresult)
484 //TODO: error 486 printf("Uhhhh...vb_utf8to16() returning icresult == %d\n", icresult);
485 if( icresult ) printf("Uhhhh...vb_utf8to16() returning icresult == %d\n", icresult ); 487 );
486 return icresult; 488
487 } 489 if (icresult > (size_t) INT_MAX) {
488 // }}} 490 return (-1);
489 #if 1 491 }
490 void cheap_uni2ascii(char *src, char *dest, int l) /* {{{ Quick and dirty UNICODE to std. ascii */ 492 return icresult;
491 { 493 }
492 494
493 for (; l > 0; l -=2) { 495
494 *dest = *src; 496 /* Quick and dirty UNICODE to std. ascii */
495 dest++; src +=2; 497 void cheap_uni2ascii(char *src, char *dest, int l)
496 } 498 {
497 *dest = 0; 499
498 } 500 for (; l > 0; l -= 2) {
499 // }}} 501 *dest = *src;
500 #endif 502 dest++;
501 503 src += 2;
502 void cheap_ascii2uni(char *src, char *dest, int l) /* {{{ Quick and dirty ascii to unicode */ 504 }
503 { 505 *dest = 0;
504 for (; l > 0; l--) { 506 }
505 *dest++ = *src++; 507
506 *dest++ = 0; 508
507 509 /* Quick and dirty ascii to unicode */
508 } 510 void cheap_ascii2uni(char *src, char *dest, int l)
509 } 511 {
510 // }}} 512 for (; l > 0; l--) {
511 513 *dest++ = *src++;
512 // }}} 514 *dest++ = 0;
513 // {{{ VARBUF Functions 515
514 vbuf *vballoc( size_t len ) // {{{ 516 }
515 { 517 }
516 struct varbuf *result; 518
517 519
518 result = F_MALLOC( sizeof( struct varbuf ) ); 520 vbuf *vballoc(size_t len)
519 521 {
520 result->dlen = 0; 522 struct varbuf *result;
521 result->blen = 0; 523
522 result->buf = NULL; 524 result = F_MALLOC(sizeof(struct varbuf));
523 525
524 vbresize( result, len ); 526 result->dlen = 0;
525 527 result->blen = 0;
526 return result; 528 result->buf = NULL;
527 529
528 } // }}} 530 vbresize(result, len);
529 void vbcheck( vbuf *vb ) // {{{ 531
530 { 532 return result;
531 ASSERT( vb->b - vb->buf <= vb->blen, "vbcheck(): vb->b outside of buffer range."); 533
532 ASSERT( vb->dlen <= vb->blen, "vbcheck(): data length > buffer length."); 534 }
533 535
534 ASSERT( vb->blen < 1024*1024, "vbcheck(): blen is a bit large...hmmm."); 536
535 } // }}} 537 void vbcheck(vbuf * vb)
536 void vbfree( vbuf *vb ) // {{{ 538 {
537 { 539 ASSERT(vb->b >= vb->buf, "vbcheck(): data not inside buffer");
538 free( vb->buf ); 540 ASSERT((size_t)(vb->b - vb->buf) <= vb->blen, "vbcheck(): vb->b outside of buffer range.");
539 free( vb ); 541 ASSERT(vb->dlen <= vb->blen, "vbcheck(): data length > buffer length.");
540 } // }}} 542 ASSERT(vb->blen < 1024 * 1024, "vbcheck(): blen is a bit large...hmmm.");
541 void vbclear( struct varbuf *vb ) // {{{ditch the data, keep the buffer 543 }
542 { 544
543 vbresize( vb, 0 ); 545
544 } // }}} 546 void vbfree(vbuf * vb)
545 void vbresize( struct varbuf *vb, size_t len ) // {{{ DESTRUCTIVELY grow or shrink buffer 547 {
546 { 548 free(vb->buf);
547 vb->dlen = 0; 549 free(vb);
548 550 }
549 if( vb->blen >= len ) { 551
550 vb->b = vb->buf; 552
551 return; 553 void vbclear(struct varbuf *vb) // ditch the data, keep the buffer
552 } 554 {
553 555 vbresize(vb, 0);
554 vb->buf = F_REALLOC( vb->buf, len ); 556 }
555 vb->b = vb->buf; 557
556 vb->blen = len; 558
557 } // }}} 559 void vbresize(struct varbuf *vb, size_t len) // DESTRUCTIVELY grow or shrink buffer
558 int vbavail( vbuf *vb ) // {{{ 560 {
559 { 561 vb->dlen = 0;
560 return vb->blen - ((char*)vb->b - (char*)vb->buf + vb->dlen); 562
561 } // }}} 563 if (vb->blen >= len) {
562 //void vbdump( vbuf *vb ) // {{{ TODO: to stdout? Yuck 564 vb->b = vb->buf;
565 return;
566 }
567
568 vb->buf = F_REALLOC(vb->buf, len);
569 vb->b = vb->buf;
570 vb->blen = len;
571 }
572
573
574 size_t vbavail(vbuf * vb)
575 {
576 return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf);
577 }
578
579
580 //void vbdump( vbuf *vb ) // TODO: to stdout? Yuck
563 //{ 581 //{
564 // printf("vb dump-------------\n"); 582 // printf("vb dump-------------\n");
565 // printf("dlen: %d\n", vb->dlen ); 583 // printf("dlen: %d\n", vb->dlen );
566 // printf("blen: %d\n", vb->blen ); 584 // printf("blen: %d\n", vb->blen );
567 // printf("b - buf: %d\n", vb->b - vb->buf ); 585 // printf("b - buf: %d\n", vb->b - vb->buf );
568 // printf("buf:\n"); 586 // printf("buf:\n");
569 // hexdump( vb->buf, 0, vb->blen, 1 ); 587 // hexdump( vb->buf, 0, vb->blen, 1 );
570 // printf("b:\n"); 588 // printf("b:\n");
571 // hexdump( vb->b, 0, vb->dlen, 1 ); 589 // hexdump( vb->b, 0, vb->dlen, 1 );
572 // printf("^^^^^^^^^^^^^^^^^^^^\n"); 590 // printf("^^^^^^^^^^^^^^^^^^^^\n");
573 //} // }}} 591 //}
574 void vbgrow( struct varbuf *vb, size_t len ) // {{{ out: vbavail(vb) >= len, data are preserved 592
575 { 593
576 if( 0 == len ) return; 594 void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved
577 595 {
578 if( 0 == vb->blen ) { 596 if (0 == len)
579 vbresize( vb, len ); 597 return;
580 return; 598
581 } 599 if (0 == vb->blen) {
582 600 vbresize(vb, len);
583 if( vb->dlen + len > vb->blen ) { 601 return;
584 if( vb->dlen + len < vb->blen * 1.5 ) len = vb->blen * 1.5; 602 }
585 char *nb = F_MALLOC( vb->blen + len ); 603
586 //printf("vbgrow() got %p back from malloc(%d)\n", nb, vb->blen + len); 604 if (vb->dlen + len > vb->blen) {
587 vb->blen = vb->blen + len; 605 if (vb->dlen + len < vb->blen * 1.5)
588 memcpy( nb, vb->b, vb->dlen ); 606 len = vb->blen * 1.5;
589 607 char *nb = F_MALLOC(vb->blen + len);
590 //printf("vbgrow() I am going to free %p\n", vb->buf ); 608 //printf("vbgrow() got %p back from malloc(%d)\n", nb, vb->blen + len);
591 free( vb->buf ); 609 vb->blen = vb->blen + len;
592 vb->buf = nb; 610 memcpy(nb, vb->b, vb->dlen);
593 vb->b = vb->buf; 611
594 } else { 612 //printf("vbgrow() I am going to free %p\n", vb->buf );
595 if( vb->b != vb->buf ) 613 free(vb->buf);
596 memcpy( vb->buf, vb->b, vb->dlen ); 614 vb->buf = nb;
597 } 615 vb->b = vb->buf;
598 616 } else {
599 vb->b = vb->buf; 617 if (vb->b != vb->buf)
600 618 memcpy(vb->buf, vb->b, vb->dlen);
601 ASSERT( vbavail( vb ) >= len, "vbgrow(): I have failed in my mission." ); 619 }
602 } // }}} 620
603 void vbset( vbuf *vb, void *b, size_t len ) // {{{ set vbuf b size=len, resize if necessary, relen = how much to over-allocate 621 vb->b = vb->buf;
604 { 622
605 vbresize( vb, len ); 623 ASSERT(vbavail(vb) >= len, "vbgrow(): I have failed in my mission.");
606 624 }
607 memcpy( vb->b, b, len ); 625
608 vb->dlen = len; 626
609 } // }}} 627 void vbset(vbuf * vb, void *b, size_t len) // set vbuf b size=len, resize if necessary, relen = how much to over-allocate
610 void vsskipws( vstr *vs ) // {{{ 628 {
611 { 629 vbresize(vb, len);
612 char *p = vs->b; 630
613 while( p - vs->b < vs->dlen && isspace( p[0] ) ) p++; 631 memcpy(vb->b, b, len);
614 632 vb->dlen = len;
615 vbskip( (vbuf*)vs, p - vs->b ); 633 }
616 } // }}} 634
617 void vbappend( struct varbuf *vb, void *b, size_t len ) // {{{ append len bytes of b to vbuf, resize if necessary 635
618 { 636 void vsskipws(vstr * vs)
619 if( 0 == vb->dlen ) { 637 {
620 vbset( vb, b, len ); 638 char *p = vs->b;
621 return; 639 while ((size_t)(p - vs->b) < vs->dlen && isspace(p[0]))
622 } 640 p++;
623 641
624 vbgrow( vb, len ); 642 vbskip((vbuf *) vs, p - vs->b);
625 643 }
626 memcpy( vb->b + vb->dlen, b, len ); 644
627 vb->dlen += len; 645
628 646 // append len bytes of b to vbuf, resize if necessary
629 //printf("vbappend() end: >%s/%d<\n", vbuf->b, vbuf->dlen ); 647 void vbappend(struct varbuf *vb, void *b, size_t len)
630 } // }}} 648 {
631 void vbskip( struct varbuf *vb, size_t skip ) // {{{ dumps the first skip bytes from vbuf 649 if (0 == vb->dlen) {
632 { 650 vbset(vb, b, len);
633 ASSERT( skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer." ); 651 return;
634 //memmove( vbuf->b, vbuf->b + skip, vbuf->dlen - skip ); 652 }
635 vb->b += skip; 653 vbgrow(vb, len);
636 vb->dlen -= skip; 654 memcpy(vb->b + vb->dlen, b, len);
637 } // }}} 655 vb->dlen += len;
638 void vboverwrite( struct varbuf *vbdest, struct varbuf *vbsrc ) // {{{ overwrite vbdest with vbsrc 656 }
639 { 657
640 vbresize( vbdest, vbsrc->blen ); 658
641 memcpy( vbdest->b, vbsrc->b, vbsrc->dlen ); 659 // dumps the first skip bytes from vbuf
642 vbdest->blen = vbsrc->blen; 660 void vbskip(struct varbuf *vb, size_t skip)
643 vbdest->dlen = vbsrc->dlen; 661 {
644 } // }}} 662 ASSERT(skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer.");
645 // }}} 663 vb->b += skip;
646 // {{{ VARSTR Functions 664 vb->dlen -= skip;
647 vstr *vsalloc( size_t len ) // {{{ 665 }
648 { 666
649 vstr *result = (vstr*)vballoc( len + 1 ); 667
650 vsset( result, "" ); 668 // overwrite vbdest with vbsrc
651 return result; 669 void vboverwrite(struct varbuf *vbdest, struct varbuf *vbsrc)
652 } // }}} 670 {
653 char *vsstr( vstr *vs ) // {{{ 671 vbresize(vbdest, vbsrc->blen);
654 { 672 memcpy(vbdest->b, vbsrc->b, vbsrc->dlen);
655 return vs->b; 673 vbdest->blen = vbsrc->blen;
656 } // }}} 674 vbdest->dlen = vbsrc->dlen;
657 size_t vslen( vstr *vs ) // {{{ 675 }
658 { 676
659 return strlen( vsstr( vs )); 677
660 } // }}} 678 vstr *vsalloc(size_t len)
661 void vsfree( vstr *vs ) // {{{ 679 {
662 { 680 vstr *result = (vstr *) vballoc(len + 1);
663 vbfree( (vbuf*)vs ); 681 vsset(result, "");
664 } // }}} 682 return result;
665 void vscharcat( vstr *vb, int ch ) // {{{ 683 }
666 { 684
667 vbgrow( (vbuf*)vb, 1); 685
668 vb->b[vb->dlen-1] = ch; 686 char *vsstr(vstr * vs)
669 vb->b[vb->dlen] = '\0'; 687 {
670 vb->dlen++; 688 return vs->b;
671 } // }}} 689 }
672 void vsnprepend( vstr *vb, char *str, size_t len ) // {{{ prependappend string str to vbuf, vbuf must already contain a valid string 690
673 { 691
674 ASSERT( vb->b[vb->dlen-1] == '\0', "vsncat(): attempt to append string to non-string."); 692 size_t vslen(vstr * vs)
675 int sl = strlen( str ); 693 {
676 int n = (sl<len)?sl:len; 694 return strlen(vsstr(vs));
677 //string append 695 }
678 vbgrow( (vbuf*)vb, n + 1 ); 696
679 memmove( vb->b + n, vb->b, vb->dlen - 1 ); 697
680 memcpy( vb->b, str, n ); 698 void vsfree(vstr * vs)
681 //strncat( vb->b, str, n ); 699 {
682 700 vbfree((vbuf *) vs);
683 vb->dlen += n; 701 }
684 vb->b[ vb->dlen - 1 ] = '\0'; 702
685 } // }}} 703
686 void vsskip( vstr *vs, size_t len ) // {{{ len < dlen-1 -> skip len chars, else DIE 704 void vscharcat(vstr * vb, int ch)
687 { 705 {
688 ASSERT( len < vs->dlen - 1, "Attempt to skip past end of string" ); 706 vbgrow((vbuf *) vb, 1);
689 vbskip( (vbuf*)vs, len ); 707 vb->b[vb->dlen - 1] = ch;
690 } // }}} 708 vb->b[vb->dlen] = '\0';
691 int vsskipline( vstr *vs ) // {{{ in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" 709 vb->dlen++;
692 { 710 }
693 int nloff = find_nl( vs ); 711
694 int nll = skip_nl( vs->b + nloff ); 712
695 713 // prependappend string str to vbuf, vbuf must already contain a valid string
696 if( nloff < 0 ) { 714 void vsnprepend(vstr * vb, char *str, size_t len)
697 //TODO: error 715 {
698 printf("vb_skipline(): there seems to be no newline here.\n"); 716 ASSERT(vb->b[vb->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string.");
699 return -1; 717 size_t sl = strlen(str);
700 } 718 size_t n = (sl < len) ? sl : len;
701 if( skip_nl < 0 ) { 719 vbgrow((vbuf *) vb, n + 1);
702 //TODO: error 720 memmove(vb->b + n, vb->b, vb->dlen - 1);
703 printf("vb_skipline(): there seems to be no newline here...except there should be. :P\n"); 721 memcpy(vb->b, str, n);
704 return -1; 722 vb->dlen += n;
705 } 723 vb->b[vb->dlen - 1] = '\0';
706 724 }
707 memmove( vs->b, vs->b + nloff + nll, vs->dlen - nloff - nll ); 725
708 726
709 vs->dlen -= nloff + nll; 727 // len < dlen-1 -> skip len chars, else DIE
710 728 void vsskip(vstr * vs, size_t len)
711 return 0; 729 {
712 } // }}} 730 ASSERT(len < vs->dlen - 1, "Attempt to skip past end of string");
713 int vscatprintf( vstr *vs, char *fmt, ... ) // {{{ 731 vbskip((vbuf *) vs, len);
714 { 732 }
715 int size; 733
716 va_list ap; 734
717 735 // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff"
718 /* Guess we need no more than 100 bytes. */ 736 int vsskipline(vstr * vs)
719 //vsresize( vb, 100 ); 737 {
720 if(!vs->b || vs->dlen == 0) { 738 int nloff = find_nl(vs);
721 vsset( vs, "" ); 739 int nll = skip_nl(vs->b + nloff);
722 } 740
723 741 if (nloff < 0) {
724 while (1) { 742 //TODO: error
725 /* Try to print in the allocated space. */ 743 printf("vb_skipline(): there seems to be no newline here.\n");
726 va_start(ap, fmt); 744 return -1;
727 size = vsnprintf (vs->b + vs->dlen - 1, vs->blen - vs->dlen, fmt, ap); 745 }
728 va_end(ap); 746 if (nll < 0) {
729 747 //TODO: error
730 /* If that worked, return the string. */ 748 printf("vb_skipline(): there seems to be no newline here...except there should be. :P\n");
731 if (size > -1 && size < vs->blen - vs->dlen ) { 749 return -1;
732 vs->dlen += size; 750 }
733 return size; 751
734 } 752 memmove(vs->b, vs->b + nloff + nll, vs->dlen - nloff - nll);
735 /* Else try again with more space. */ 753
736 if ( size >= 0 ) /* glibc 2.1 */ 754 vs->dlen -= nloff + nll;
737 vbgrow( (vbuf*)vs, size+1 ); /* precisely what is needed */ 755
738 else /* glibc 2.0 */ 756 return 0;
739 vbgrow( (vbuf*)vs, vs->blen); 757 }
740 } 758
741 } // }}} 759
742 int vslast( vstr *vs ) // {{{ returns the last character stored in a vstr 760 int vscatprintf(vstr * vs, char *fmt, ...)
743 { 761 {
744 if( vs->dlen < 1 ) return -1; 762 int size;
745 if( vs->b[vs->dlen-1] != '\0' ) return -1; 763 va_list ap;
746 if( vs->dlen == 1 ) return '\0'; 764
747 return vs->b[vs->dlen-2]; 765 /* Guess we need no more than 100 bytes. */
748 } // }}} 766 //vsresize( vb, 100 );
749 void vs_printf( vstr *vs, char *fmt, ... ) // {{{ print over vb 767 if (!vs->b || vs->dlen == 0) {
750 { 768 vsset(vs, "");
751 int size; 769 }
752 va_list ap; 770
753 771 while (1) {
754 /* Guess we need no more than 100 bytes. */ 772 /* Try to print in the allocated space. */
755 vbresize( (vbuf*)vs, 100 ); 773 va_start(ap, fmt);
756 774 size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen, fmt, ap);
757 while (1) { 775 va_end(ap);
758 /* Try to print in the allocated space. */ 776
759 va_start(ap, fmt); 777 /* If that worked, return the string. */
760 size = vsnprintf (vs->b, vs->blen, fmt, ap); 778 if ((size > -1) && ((size_t)size < vs->blen - vs->dlen)) {
761 va_end(ap); 779 vs->dlen += size;
762 780 return size;
763 /* If that worked, return the string. */ 781 }
764 if (size > -1 && size < vs->blen) { 782 /* Else try again with more space. */
765 vs->dlen = size + 1; 783 if (size >= 0) /* glibc 2.1 */
766 return; 784 vbgrow((vbuf *) vs, size + 1); /* precisely what is needed */
767 } 785 else /* glibc 2.0 */
768 /* Else try again with more space. */ 786 vbgrow((vbuf *) vs, vs->blen);
769 if ( size >= 0 ) /* glibc 2.1 */ 787 }
770 vbresize( (vbuf*)vs, size+1 ); /* precisely what is needed */ 788 }
771 else /* glibc 2.0 */ 789
772 vbresize( (vbuf*)vs, vs->blen*2); 790
773 } 791 // returns the last character stored in a vstr
774 } // }}} 792 int vslast(vstr * vs)
775 void vs_printfa( vstr *vs, char *fmt, ... ) // {{{ printf append to vs 793 {
776 { 794 if (vs->dlen < 1)
777 int size; 795 return -1;
778 va_list ap; 796 if (vs->b[vs->dlen - 1] != '\0')
779 797 return -1;
780 if( vs->blen - vs->dlen < 50 ) 798 if (vs->dlen == 1)
781 vbgrow( (vbuf*)vs, 100 ); 799 return '\0';
782 800 return vs->b[vs->dlen - 2];
783 while (1) { 801 }
784 /* Try to print in the allocated space. */ 802
785 va_start(ap, fmt); 803
786 size = vsnprintf (vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap); 804 // print over vb
787 va_end(ap); 805 void vs_printf(vstr * vs, char *fmt, ...)
788 806 {
789 /* If that worked, return the string. */ 807 int size;
790 if (size > -1 && size < vs->blen) { 808 va_list ap;
791 vs->dlen += size; 809
792 return; 810 /* Guess we need no more than 100 bytes. */
793 } 811 vbresize((vbuf *) vs, 100);
794 /* Else try again with more space. */ 812
795 if ( size >= 0 ) /* glibc 2.1 */ 813 while (1) {
796 vbgrow( (vbuf*)vs, size+1 - vs->dlen ); /* precisely what is needed */ 814 /* Try to print in the allocated space. */
797 else /* glibc 2.0 */ 815 va_start(ap, fmt);
798 vbgrow( (vbuf*)vs, size ); 816 size = vsnprintf(vs->b, vs->blen, fmt, ap);
799 } 817 va_end(ap);
800 } // }}} 818
801 void vshexdump( vstr *vs, char *b, size_t start, size_t stop, int ascii ) // {{{ 819 /* If that worked, return the string. */
802 { 820 if ((size > -1) && ((size_t)size < vs->blen)) {
803 char c; 821 vs->dlen = size + 1;
804 int diff,i; 822 return;
805 823 }
806 while (start < stop ) { 824 /* Else try again with more space. */
807 diff = stop - start; 825 if (size >= 0) /* glibc 2.1 */
808 if (diff > 16) diff = 16; 826 vbresize((vbuf *) vs, size + 1); /* precisely what is needed */
809 827 else /* glibc 2.0 */
810 vs_printfa(vs, ":%08X ",start); 828 vbresize((vbuf *) vs, vs->blen * 2);
811 829 }
812 for (i = 0; i < diff; i++) { 830 }
813 if( 8 == i ) vs_printfa( vs, " " ); 831
814 vs_printfa(vs, "%02X ",(unsigned char)*(b+start+i)); 832
815 } 833 // printf append to vs
816 if (ascii) { 834 void vs_printfa(vstr * vs, char *fmt, ...)
817 for (i = diff; i < 16; i++) vs_printfa(vs, " "); 835 {
818 for (i = 0; i < diff; i++) { 836 int size;
819 c = *(b+start+i); 837 va_list ap;
820 vs_printfa(vs, "%c", isprint(c) ? c : '.'); 838
821 } 839 if (vs->blen - vs->dlen < 50)
822 } 840 vbgrow((vbuf *) vs, 100);
823 vs_printfa(vs, "\n"); 841
824 start += 16; 842 while (1) {
825 } 843 /* Try to print in the allocated space. */
826 } // }}} 844 va_start(ap, fmt);
827 void vsset( vstr *vs, char *s ) // {{{ Store string s in vs 845 size = vsnprintf(vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap);
828 { 846 va_end(ap);
829 vsnset( vs, s, strlen( s ) ); 847
830 } // }}} 848 /* If that worked, return the string. */
831 void vsnset( vstr *vs, char *s, size_t n ) // {{{ Store string s in vs 849 if ((size > -1) && ((size_t)size < vs->blen)) {
832 { 850 vs->dlen += size;
833 vbresize( (vbuf*)vs, n + 1 ); 851 return;
834 memcpy( vs->b, s, n); 852 }
835 vs->b[n] = '\0'; 853 /* Else try again with more space. */
836 vs->dlen = n+1; 854 if (size >= 0) /* glibc 2.1 */
837 } // }}} 855 vbgrow((vbuf *) vs, size + 1 - vs->dlen); /* precisely what is needed */
838 void vsgrow( vstr *vs, size_t len ) // {{{ grow buffer by len bytes, data are preserved 856 else /* glibc 2.0 */
839 { 857 vbgrow((vbuf *) vs, size);
840 vbgrow( (vbuf*)vs, len ); 858 }
841 } // }}} 859 }
842 size_t vsavail( vstr *vs ) // {{{ 860
843 { 861
844 return vbavail( (vbuf*)vs ); 862 void vshexdump(vstr * vs, char *b, size_t start, size_t stop, int ascii)
845 } // }}} 863 {
846 void vsnset16( vstr *vs, char *s, size_t len ) // {{{ Like vbstrnset, but for UTF16 864 char c;
847 { 865 int diff, i;
848 vbresize( (vbuf*)vs, len+1 ); 866
849 memcpy( vs->b, s, len ); 867 while (start < stop) {
850 868 diff = stop - start;
851 vs->b[len] = '\0'; 869 if (diff > 16)
852 vs->dlen = len+1; 870 diff = 16;
853 vs->b[len] = '\0'; 871
854 } // }}} 872 vs_printfa(vs, ":%08X ", start);
855 void vscat( vstr *vs, char *str ) // {{{ 873
856 { 874 for (i = 0; i < diff; i++) {
857 vsncat( vs, str, strlen(str ) ); 875 if (8 == i)
858 } // }}} 876 vs_printfa(vs, " ");
859 int vscmp( vstr *vs, char *str ) // {{{ 877 vs_printfa(vs, "%02X ", (unsigned char) *(b + start + i));
860 { 878 }
861 return strcmp( vs->b, str ); 879 if (ascii) {
862 } // }}} 880 for (i = diff; i < 16; i++)
863 void vsncat( vstr *vs, char *str, size_t len ) // {{{ append string str to vstr, vstr must already contain a valid string 881 vs_printfa(vs, " ");
864 { 882 for (i = 0; i < diff; i++) {
865 ASSERT( vs->b[vs->dlen-1] == '\0', "vsncat(): attempt to append string to non-string."); 883 c = *(b + start + i);
866 int sl = strlen( str ); 884 vs_printfa(vs, "%c", isprint(c) ? c : '.');
867 int n = (sl<len)?sl:len; 885 }
868 //string append 886 }
869 vbgrow( (vbuf*)vs, n + 1 ); 887 vs_printfa(vs, "\n");
870 memcpy( vs->b + vs->dlen - 1, str, n ); 888 start += 16;
871 //strncat( vs->b, str, n ); 889 }
872 890 }
873 vs->dlen += n; 891
874 vs->b[ vs->dlen - 1 ] = '\0'; 892
875 } // }}} 893 void vsset(vstr * vs, char *s) // Store string s in vs
876 void vstrunc( vstr *v, int off ) // {{{ Drop chars [off..dlen] 894 {
877 { 895 vsnset(vs, s, strlen(s));
878 if( off >= v->dlen - 1 ) return; //nothing to do 896 }
879 v->b[off] = '\0'; 897
880 v->dlen = off + 1; 898
881 } 899 void vsnset(vstr * vs, char *s, size_t n) // Store string s in vs
882 // }}} 900 {
883 // }}} 901 vbresize((vbuf *) vs, n + 1);
884 // {{{ User input 902 memcpy(vs->b, s, n);
903 vs->b[n] = '\0';
904 vs->dlen = n + 1;
905 }
906
907
908 void vsgrow(vstr * vs, size_t len) // grow buffer by len bytes, data are preserved
909 {
910 vbgrow((vbuf *) vs, len);
911 }
912
913
914 size_t vsavail(vstr * vs)
915 {
916 return vbavail((vbuf *) vs);
917 }
918
919
920 void vsnset16(vstr * vs, char *s, size_t len) // Like vbstrnset, but for UTF16
921 {
922 vbresize((vbuf *) vs, len + 1);
923 memcpy(vs->b, s, len);
924
925 vs->b[len] = '\0';
926 vs->dlen = len + 1;
927 vs->b[len] = '\0';
928 }
929
930
931 void vscat(vstr * vs, char *str)
932 {
933 vsncat(vs, str, strlen(str));
934 }
935
936
937 int vscmp(vstr * vs, char *str)
938 {
939 return strcmp(vs->b, str);
940 }
941
942
943 void vsncat(vstr * vs, char *str, size_t len) // append string str to vstr, vstr must already contain a valid string
944 {
945 ASSERT(vs->b[vs->dlen - 1] == '\0', "vsncat(): attempt to append string to non-string.");
946 size_t sl = strlen(str);
947 size_t n = (sl < len) ? sl : len;
948 //string append
949 vbgrow((vbuf *) vs, n + 1);
950 memcpy(vs->b + vs->dlen - 1, str, n);
951 vs->dlen += n;
952 vs->b[vs->dlen - 1] = '\0';
953 }
954
955
956 void vstrunc(vstr * v, size_t off) // Drop chars [off..dlen]
957 {
958 if (off >= v->dlen - 1)
959 return; //nothing to do
960 v->b[off] = '\0';
961 v->dlen = off + 1;
962 }
963
964
885 // TODO: not sure how useful this stuff is here 965 // TODO: not sure how useful this stuff is here
886 int fmyinput(char *prmpt, char *ibuf, int maxlen) /* {{{ get user input */ 966 int fmyinput(char *prmpt, char *ibuf, int maxlen)
887 { 967 { /* get user input */
888 printf("%s",prmpt); 968 printf("%s", prmpt);
889 969
890 fgets(ibuf,maxlen+1,stdin); 970 fgets(ibuf, maxlen + 1, stdin);
891 971
892 ibuf[strlen(ibuf)-1] = 0; 972 ibuf[strlen(ibuf) - 1] = 0;
893 973
894 return(strlen(ibuf)); 974 return (strlen(ibuf));
895 } 975 }
896 // }}} 976
897 //}}} 977
898 // 978 // String formatting and output to FILE *stream or just stdout, etc
899 //
900 //{{{ String formatting and output to FILE *stream or just stdout, etc
901 // TODO: a lot of old, unused stuff in here 979 // TODO: a lot of old, unused stuff in here
902 void vswinhex8(vstr *vs, unsigned char *hbuf, int start, int stop, int loff ) // {{{ Produce regedit-style hex output */ 980 void vswinhex8(vstr * vs, unsigned char *hbuf, int start, int stop, int loff) // Produce regedit-style hex output */
903 { 981 {
904 int i; 982 int i;
905 int lineflag=0; 983 int lineflag = 0;
906 984
907 for( i=start; i<stop; i++) 985 for (i = start; i < stop; i++) {
908 { 986 loff += vscatprintf(vs, "%02x", hbuf[i]);
909 loff += vscatprintf( vs, "%02x", hbuf[i] ); 987 if (i < stop - 1) {
910 if( i < stop - 1 ) { 988 loff += vscatprintf(vs, ",");
911 loff+=vscatprintf( vs, "," ); 989 switch (lineflag) {
912 switch( lineflag ) { 990 case 0:
913 case 0: 991 if (loff >= 77) {
914 if( loff >= 77) { 992 lineflag = 1;
915 lineflag=1; 993 loff = 0;
916 loff=0; 994 vscatprintf(vs, "\\%s ", STUPID_CR);
917 vscatprintf( vs, "\\%s ", STUPID_CR ); 995 }
918 } 996 break;
919 break; 997 case 1:
920 case 1: 998 if (loff >= 75) {
921 if( loff >= 75 ) { 999 loff = 0;
922 loff=0; 1000 vscatprintf(vs, "\\%s ", STUPID_CR);
923 vscatprintf( vs, "\\%s ", STUPID_CR ); 1001 }
924 } 1002 break;
925 break; 1003 }
926 } 1004 }
927 // if( 24 < i || 0 == (i - 17) % 25 ) fprintf( stream, "\\\n " ); 1005 }
928 } 1006 }
929 }
930
931 // fprintf( stream, "\n" );
932 } // }}}