comparison src/vbuf.c @ 73:3cb02cb1e6cd stable-0-6-10

Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them). More changes for Fedora packaging (#434727) Fixes for const correctness.
author Carl Byington <carl@five-ten-sg.com>
date Thu, 29 May 2008 18:51:02 -0700
parents b12f4e50e2e8
children cb14583c119a
comparison
equal deleted inserted replaced
72:c21e9c001256 73:3cb02cb1e6cd
7 #include <signal.h> 7 #include <signal.h>
8 #include <stdarg.h> 8 #include <stdarg.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
11 #include <string.h> 11 #include <string.h>
12
13 #include "define.h"
12 #include "vbuf.h" 14 #include "vbuf.h"
13 #include "generic.h"
14 15
15 #ifdef WITH_DMALLOC 16 #ifdef WITH_DMALLOC
16 #include <dmalloc.h> 17 #include <dmalloc.h>
17 #endif 18 #endif
19
20 #define STUPID_CR "\r\n"
21 #define ASSERT(x,...) { if( !(x) ) DIE(( __VA_ARGS__)); }
18 22
19 23
20 int skip_nl(char *s) 24 int skip_nl(char *s)
21 { 25 {
22 if (s[0] == '\n') 26 if (s[0] == '\n')
102 iconv_close(i8859_1to8); 106 iconv_close(i8859_1to8);
103 iconv_close(i8toi8859_1); 107 iconv_close(i8toi8859_1);
104 } 108 }
105 109
106 110
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
108 //{
109 //
110 // //TODO: if anything big comes through here we are sunk, should do it
111 // //bit-by-bit, not one-big-gulp
112 //
113 // size_t inbytesleft, outbytesleft;
114 // char *inbuf, *outbuf;
115 // size_t icresult;
116 // size_t rl;
117 //
118 // //do we have enough buffer space?
119 // if( !wwbuf || nwwbuf < (count * 2 + 2) ) {
120 // wwbuf = F_REALLOC( wwbuf, count * 2 +2 );
121 //
122 // nwwbuf = count * 2 + 2;
123 // }
124 //
125 // inbytesleft = count; outbytesleft = nwwbuf;
126 // inbuf = (char*)buf; outbuf = wwbuf;
127 //
128 //// fprintf(stderr, "X%s, %dX", (char*)buf, strlen( buf ));
129 //// fflush(stderr);
130 //
131 // if( (rl = strlen( buf ) + 1) != count ) {
132 // fprintf(stderr, "utf16_write(): reported buffer size (%d) does not match string length (%d)\n",
133 // count,
134 // rl);
135 //
136 // //hexdump( (char*)buf, 0, count, 1 );
137 //
138 // raise( SIGSEGV );
139 // inbytesleft = rl;
140 // }
141 //
142 //// fprintf(stderr, " attempting to convert:\n");
143 //// hexdump( (char*)inbuf, 0, count, 1 );
144 //
145 // icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
146 //
147 //// fprintf(stderr, " converted:\n");
148 //// hexdump( (char*)buf, 0, count, 1 );
149 //
150 //// fprintf(stderr, " to:\n");
151 //// hexdump( (char*)wwbuf, 0, nwwbuf, 1 );
152 //
153 // if( (size_t)-1 == icresult ) {
154 // fprintf(stderr, "utf16_write(): iconv failure(%d): %s\n", errno, strerror( errno ) );
155 // fprintf(stderr, " attempted to convert:\n");
156 // hexdump( (char*)inbuf, 0, count, 1 );
157 //
158 // fprintf(stderr, " result:\n");
159 // hexdump( (char*)outbuf, 0, count, 1 );
160 //
161 // fprintf(stderr, "I'm going to segfault now.\n");
162 // raise( SIGSEGV );
163 // exit(1);
164 // }
165 //
166 // if( inbytesleft > 0 ) {
167 // fprintf(stderr, "utf16_write(): iconv returned a short count.\n");
168 // exit(1);
169 // }
170 //
171 // return fwrite( wwbuf, nwwbuf - outbytesleft - 2, 1, stream );
172 //}
173
174 //char *utf16buf = NULL;
175 //int utf16buf_len = 0;
176 //
177 //int utf16_fprintf( FILE* stream, const char *fmt, ... )
178 //{
179 // int result=0;
180 // va_list ap;
181 //
182 // if( utf16buf == NULL ) {
183 // utf16buf = (char*)F_MALLOC( SZ_MAX + 1 );
184 //
185 // utf16buf_len = SZ_MAX + 1;
186 // }
187 //
188 // va_start( ap, fmt );
189 //
190 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap );
191 //
192 // if( result + 1 > utf16buf_len ) { //didn't have space, realloc() and try again
193 // fprintf(stderr, "utf16_fprintf(): buffer too small (%d), F_MALLOC(%d)\n", utf16buf_len, result);
194 // free( utf16buf );
195 // utf16buf_len = result + 1;
196 // utf16buf = (char*)F_MALLOC( utf16buf_len );
197 //
198 // result = vsnprintf( utf16buf, utf16buf_len, fmt, ap );
199 // }
200 //
201 //
202 // //didn't have space...again...something weird is going on...
203 // ASSERT( result + 1 <= utf16buf_len, "utf16_fprintf(): Unpossible error!\n");
204 //
205 // if( 1 != utf16_write( stream, utf16buf, result + 1 ) )
206 // DIE( "Write error? -> %s or %s\n", strerror( errno ), uerr_str( uerr_get() ) );
207 //
208 // return result;
209 //}
210 //
211 //int utf16to8( char *inbuf_o, char *outbuf_o, int length )
212 //{
213 // int inbytesleft = length;
214 // int outbytesleft = length;
215 // char *inbuf = inbuf_o;
216 // char *outbuf = outbuf_o;
217 // int rlen = -1, tlen;
218 // int icresult = -1;
219 //
220 // int i, strlen=-1;
221 //
222 // DEBUG(
223 // fprintf(stderr, " utf16to8(): attempting to convert:\n");
224 // //hexdump( (char*)inbuf_o, 0, length, 1 );
225 // fflush(stderr);
226 // );
227 //
228 // for( i=0; i<length ; i+=2 ) {
229 // if( inbuf_o[i] == 0 && inbuf_o[i + 1] == 0 ) {
230 // //fprintf(stderr, "End of string found at: %d\n", i );
231 // strlen = i;
232 // }
233 // }
234 //
235 // //hexdump( (char*)inbuf_o, 0, strlen, 1 );
236 //
237 // if( -1 == strlen ) WARN("String is not zero-terminated.");
238 //
239 // //iconv does not like it when the inbytesleft > actual string length
240 // //enum: zero terminated, length valid
241 // // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case
242 // // zero terminated, length long
243 // // not zero terminated
244 // // TODO: MEMORY BUG HERE!
245 // for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) {
246 // if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){
247 // rlen = tlen + 2;
248 // tlen = rlen;
249 // break;
250 // }
251 // if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n");
252 // }
253 //
254 // if( rlen >= 0 )
255 // icresult = iconv( i16to8, &inbuf, &rlen, &outbuf, &outbytesleft );
256 //
257 // if( icresult == (size_t)-1 ) {
258 // fprintf(stderr, "utf16to8(): iconv failure(%d): %s\n", errno, strerror( errno ) );
259 // fprintf(stderr, " attempted to convert:\n");
260 // hexdump( (char*)inbuf_o, 0, length, 1 );
261 // fprintf(stderr, " result:\n");
262 // hexdump( (char*)outbuf_o, 0, length, 1 );
263 // fprintf(stderr, " MyDirtyOut:\n");
264 // for( i=0; i<length; i++) {
265 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] );
266 // }
267 //
268 // fprintf( stderr, "\n" );
269 // raise( SIGSEGV );
270 // exit(1);
271 // }
272 //
273 // DEBUG(
274 // fprintf(stderr, " result:\n");
275 // hexdump( (char*)outbuf_o, 0, length, 1 );
276 // )
277 //
278 // //fprintf(stderr, "utf16to8() returning %s\n", outbuf );
279 //
280 // return icresult;
281 //}
282 //
283
284
285 int utf16_is_terminated(char *str, int length) 111 int utf16_is_terminated(char *str, int length)
286 { 112 {
287 VSTR_STATIC(errbuf, 100); 113 VSTR_STATIC(errbuf, 100);
288 int len = -1; 114 int len = -1;
289 int i; 115 int i;
293 } 119 }
294 } 120 }
295 121
296 if (-1 == len) { 122 if (-1 == len) {
297 vshexdump(errbuf, str, 0, length, 1); 123 vshexdump(errbuf, str, 0, length, 1);
298 WARN("String is not zero terminated (probably broken data from registry) %s.", errbuf->b); 124 WARN(("String is not zero terminated (probably broken data from registry) %s.", errbuf->b));
299 } 125 }
300 126
301 return (-1 == len) ? 0 : 1; 127 return (-1 == len) ? 0 : 1;
302 } 128 }
303 129
329 dest->dlen = outbuf - dest->b; 155 dest->dlen = outbuf - dest->b;
330 vbgrow(dest, inbytesleft); 156 vbgrow(dest, inbytesleft);
331 } while ((size_t)-1 == icresult && E2BIG == errno); 157 } while ((size_t)-1 == icresult && E2BIG == errno);
332 158
333 if (0 != vb_utf8to16T(dumpster, dest->b, dest->dlen)) 159 if (0 != vb_utf8to16T(dumpster, dest->b, dest->dlen))
334 DIE("Reverse conversion failed."); 160 DIE(("Reverse conversion failed."));
335 161
336 if (icresult == (size_t)-1) { 162 if (icresult == (size_t)-1) {
337 //TODO: error 163 //TODO: error
338 //ERR_UNIX( errno, "vb_utf16to8():iconv failure: %s", strerror( errno ) ); 164 //ERR_UNIX( errno, "vb_utf16to8():iconv failure: %s", strerror( errno ) );
339 unicode_init(); 165 unicode_init();
371 char *inbuf = inbuf_o; 197 char *inbuf = inbuf_o;
372 char *outbuf = outbuf_o; 198 char *outbuf = outbuf_o;
373 size_t icresult = (size_t)-1; 199 size_t icresult = (size_t)-1;
374 char *stend; 200 char *stend;
375 201
376 DEBUG(fprintf(stderr, " utf8to16(): attempting to convert:\n");
377 //hexdump( (char*)inbuf_o, 0, length, 1 );
378 fflush(stderr););
379
380 stend = memchr(inbuf_o, '\0', iblen); 202 stend = memchr(inbuf_o, '\0', iblen);
381 ASSERT(NULL != stend, "utf8to16(): in string not zero terminated."); 203 ASSERT(NULL != stend, "utf8to16(): in string not zero terminated.");
382
383 inbytesleft = (stend - inbuf_o + 1 < iblen) ? stend - inbuf_o + 1 : iblen; 204 inbytesleft = (stend - inbuf_o + 1 < iblen) ? stend - inbuf_o + 1 : iblen;
384
385 //iconv does not like it when the inbytesleft > actual string length
386 //enum: zero terminated, length valid
387 // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case
388 // zero terminated, length long
389 // not zero terminated
390 // TODO: MEMORY BUG HERE!
391 //
392 /*
393 for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) {
394 if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){
395 rlen = tlen + 2;
396 tlen = rlen;
397 break;
398 }
399 if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n");
400 }
401 */
402
403 //if( rlen >= 0 )
404 icresult = iconv(i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft); 205 icresult = iconv(i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
405 206
406 if (icresult == (size_t)-1) { 207 if (icresult == (size_t)-1) {
407 DIE("iconv failure(%d): %s\n", errno, strerror(errno)); 208 DIE(("iconv failure(%d): %s\n", errno, strerror(errno)));
408 //fprintf(stderr, " attempted to convert:\n"); 209 }
409 //hexdump( (char*)inbuf_o, 0, iblen, 1 );
410 //fprintf(stderr, " result:\n");
411 //hexdump( (char*)outbuf_o, 0, oblen, 1 );
412 //fprintf(stderr, " MyDirtyOut:\n");
413 // for( i=0; i<iblen; i++) {
414 // if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] );
415 // }
416 //
417 // fprintf( stderr, "\n" );
418 // raise( SIGSEGV );
419 // exit(1);
420 }
421 // DEBUG(
422 // fprintf(stderr, " result:\n");
423 // hexdump( (char*)outbuf_o, 0, oblen, 1 );
424 // )
425
426 //fprintf(stderr, "utf8to16() returning %s\n", outbuf );
427
428 //TODO: error
429 DEBUG(
430 if (icresult)
431 printf("Uhhhh...utf8to16() returning icresult == %d\n", icresult);
432 );
433
434 if (icresult > (size_t)INT_MAX) { 210 if (icresult > (size_t)INT_MAX) {
435 return (-1); 211 return (-1);
436 } 212 }
437 return (int) icresult; 213 return (int) icresult;
438 } 214 }
459 bout->dlen = outbuf - bout->b; 235 bout->dlen = outbuf - bout->b;
460 vbgrow(bout, 20); 236 vbgrow(bout, 20);
461 } while ((size_t)-1 == icresult && E2BIG == errno); 237 } while ((size_t)-1 == icresult && E2BIG == errno);
462 238
463 if (icresult == (size_t)-1) { 239 if (icresult == (size_t)-1) {
464 WARN("iconv failure: %s", strerror(errno)); 240 WARN(("iconv failure: %s", strerror(errno)));
465 //ERR_UNIX( errno, "vb_utf8to16():iconv failure: %s", strerror( errno ) );
466 unicode_init(); 241 unicode_init();
467 return -1; 242 return -1;
468 /* 243 }
469 fprintf(stderr, "vb_utf8to16(): iconv failure(%d == %d?): %s\n", errno, E2BIG, strerror( errno ) );
470 fprintf(stderr, " attempted to convert:\n");
471 hexdump( (char*)cin, 0, inlen, 1 );
472 fprintf(stderr, " result:\n");
473 hexdump( (char*)bout->b, 0, bout->dlen, 1 );
474 fprintf(stderr, " MyDirtyOut:\n");
475 for( i=0; i<inlen; i++) {
476 if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] );
477 }
478
479 fprintf( stderr, "\n" );
480 raise( SIGSEGV );
481 exit(1);
482 */
483 }
484 DEBUG(
485 if (icresult)
486 printf("Uhhhh...vb_utf8to16() returning icresult == %d\n", icresult);
487 );
488
489 if (icresult > (size_t) INT_MAX) { 244 if (icresult > (size_t) INT_MAX) {
490 return (-1); 245 return (-1);
491 } 246 }
492 return icresult; 247 return icresult;
493 } 248 }
517 } 272 }
518 273
519 274
520 vbuf *vballoc(size_t len) 275 vbuf *vballoc(size_t len)
521 { 276 {
522 struct varbuf *result; 277 struct varbuf *result = malloc(sizeof(struct varbuf));
523 278 if (result) {
524 result = F_MALLOC(sizeof(struct varbuf)); 279 result->dlen = 0;
525 280 result->blen = 0;
526 result->dlen = 0; 281 result->buf = NULL;
527 result->blen = 0; 282 vbresize(result, len);
528 result->buf = NULL; 283 }
529 284 else DIE(("malloc() failure"));
530 vbresize(result, len);
531
532 return result; 285 return result;
533
534 } 286 }
535 287
536 288
537 void vbcheck(vbuf * vb) 289 void vbcheck(vbuf * vb)
538 { 290 {
563 if (vb->blen >= len) { 315 if (vb->blen >= len) {
564 vb->b = vb->buf; 316 vb->b = vb->buf;
565 return; 317 return;
566 } 318 }
567 319
568 vb->buf = F_REALLOC(vb->buf, len); 320 vb->buf = realloc(vb->buf, len);
569 vb->b = vb->buf; 321 vb->b = vb->buf;
570 vb->blen = len; 322 vb->blen = len;
571 } 323 }
572 324
573 325
574 size_t vbavail(vbuf * vb) 326 size_t vbavail(vbuf * vb)
602 } 354 }
603 355
604 if (vb->dlen + len > vb->blen) { 356 if (vb->dlen + len > vb->blen) {
605 if (vb->dlen + len < vb->blen * 1.5) 357 if (vb->dlen + len < vb->blen * 1.5)
606 len = vb->blen * 1.5; 358 len = vb->blen * 1.5;
607 char *nb = F_MALLOC(vb->blen + len); 359 char *nb = malloc(vb->blen + len);
608 //printf("vbgrow() got %p back from malloc(%d)\n", nb, vb->blen + len); 360 if (!nb) DIE(("malloc() failure"));
609 vb->blen = vb->blen + len; 361 vb->blen = vb->blen + len;
610 memcpy(nb, vb->b, vb->dlen); 362 memcpy(nb, vb->b, vb->dlen);
611 363
612 //printf("vbgrow() I am going to free %p\n", vb->buf );
613 free(vb->buf); 364 free(vb->buf);
614 vb->buf = nb; 365 vb->buf = nb;
615 vb->b = vb->buf; 366 vb->b = vb->buf;
616 } else { 367 } else {
617 if (vb->b != vb->buf) 368 if (vb->b != vb->buf)
960 v->b[off] = '\0'; 711 v->b[off] = '\0';
961 v->dlen = off + 1; 712 v->dlen = off + 1;
962 } 713 }
963 714
964 715
965 // TODO: not sure how useful this stuff is here
966 int fmyinput(char *prmpt, char *ibuf, int maxlen)
967 { /* get user input */
968 printf("%s", prmpt);
969
970 fgets(ibuf, maxlen + 1, stdin);
971
972 ibuf[strlen(ibuf) - 1] = 0;
973
974 return (strlen(ibuf));
975 }
976
977
978 // String formatting and output to FILE *stream or just stdout, etc
979 // TODO: a lot of old, unused stuff in here
980 void vswinhex8(vstr * vs, unsigned char *hbuf, int start, int stop, int loff) // Produce regedit-style hex output */
981 {
982 int i;
983 int lineflag = 0;
984
985 for (i = start; i < stop; i++) {
986 loff += vscatprintf(vs, "%02x", hbuf[i]);
987 if (i < stop - 1) {
988 loff += vscatprintf(vs, ",");
989 switch (lineflag) {
990 case 0:
991 if (loff >= 77) {
992 lineflag = 1;
993 loff = 0;
994 vscatprintf(vs, "\\%s ", STUPID_CR);
995 }
996 break;
997 case 1:
998 if (loff >= 75) {
999 loff = 0;
1000 vscatprintf(vs, "\\%s ", STUPID_CR);
1001 }
1002 break;
1003 }
1004 }
1005 }
1006 }