00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef lint
00055 static const char RCSparse[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/parse.c,v 14.13 2006/09/03 15:14:07 lbutler Exp $ (BRL)";
00056 #endif
00057
00058 #include "common.h"
00059
00060 #include <stdlib.h>
00061 #include <stdio.h>
00062 #include <ctype.h>
00063 #include <math.h>
00064 #ifdef HAVE_STRING_H
00065 # include <string.h>
00066 #else
00067 # include <strings.h>
00068 #endif
00069
00070 #include "machine.h"
00071 #include "bu.h"
00072
00073
00074 #define CKMEM( _len ) { \
00075 register int offset; \
00076 if( (offset = (ep - cp) - (_len)) < 0 ) { \
00077 do { \
00078 offset += ext->ext_nbytes; \
00079 ext->ext_nbytes <<= 1; \
00080 } while( offset < 0 ); \
00081 offset = cp - (char *)ext->ext_buf; \
00082 ext->ext_buf = (genptr_t)bu_realloc( (char *) ext->ext_buf, \
00083 ext->ext_nbytes, "bu_struct_export" ); \
00084 ep = (char *) ext->ext_buf + ext->ext_nbytes; \
00085 cp = (char *) ext->ext_buf + offset; \
00086 } }
00087
00088 #define BU_GETPUT_MAGIC_1 0x15cb
00089 #define BU_GETPUT_MAGIC_2 0xbc51
00090 #define BU_INIT_GETPUT_1(_p) { \
00091 BU_CK_EXTERNAL(_p); \
00092 ((unsigned char *) _p->ext_buf)[1] = (BU_GETPUT_MAGIC_1 & 0xFF); \
00093 ((unsigned char *) _p->ext_buf)[0] = (BU_GETPUT_MAGIC_1 >> 8) & 0xFF; \
00094 }
00095 #define BU_INIT_GETPUT_2(_p,_l) {\
00096 BU_CK_EXTERNAL(_p); \
00097 ((unsigned char *) _p->ext_buf)[_l-1] = (BU_GETPUT_MAGIC_2 & 0xFF); \
00098 ((unsigned char *) _p->ext_buf)[_l-2] = (BU_GETPUT_MAGIC_2 >> 8) & 0xFF; \
00099 }
00100
00101 #define BU_CK_GETPUT(_p) {\
00102 register long _i; \
00103 register long _len; \
00104 BU_CK_EXTERNAL(_p); \
00105 if ( !(_p->ext_buf) ) { \
00106 bu_log("ERROR: BU_CK_GETPUT null ext_buf, file %s, line %d\n", \
00107 __FILE__, __LINE__); \
00108 bu_bomb("NULL pointer"); \
00109 } \
00110 if ( _p->ext_nbytes < 6 ) { \
00111 bu_log("ERROR: BU_CK_GETPUT buffer only %d bytes, file %s, line %d\n", \
00112 _p->ext_nbytes, __FILE__, __LINE__); \
00113 bu_bomb("getput buffer too small"); \
00114 } \
00115 _i = (((unsigned char *)(_p->ext_buf))[0] << 8) | \
00116 ((unsigned char *)(_p->ext_buf))[1]; \
00117 if ( _i != BU_GETPUT_MAGIC_1) { \
00118 bu_log("ERROR: BU_CK_GETPUT buffer x%x, magic1 s/b x%x, was %s(x%x), file %s, line %d\n", \
00119 _p->ext_buf, BU_GETPUT_MAGIC_1, \
00120 bu_identify_magic( _i), _i, __FILE__, __LINE__); \
00121 bu_bomb("Bad getput buffer"); \
00122 } \
00123 _len = (((unsigned char *)(_p->ext_buf))[2] << 24) | \
00124 (((unsigned char *)(_p->ext_buf))[3] << 16) | \
00125 (((unsigned char *)(_p->ext_buf))[4] << 8) | \
00126 ((unsigned char *)(_p->ext_buf))[5]; \
00127 if (_len > _p->ext_nbytes) { \
00128 bu_log("ERROR: BU_CK_GETPUT buffer x%x, expected len=%d, ext_nbytes=%d, file %s, line %d\n", \
00129 _p->ext_buf, _len, _p->ext_nbytes, \
00130 __FILE__, __LINE__); \
00131 bu_bomb("Bad getput buffer"); \
00132 } \
00133 _i = (((unsigned char *)(_p->ext_buf))[_len-2] << 8) | \
00134 ((unsigned char *)(_p->ext_buf))[_len-1]; \
00135 if ( _i != BU_GETPUT_MAGIC_2) { \
00136 bu_log("ERROR: BU_CK_GETPUT buffer x%x, magic2 s/b x%x, was %s(x%x), file %s, line %d\n", \
00137 _p->ext_buf, BU_GETPUT_MAGIC_2, \
00138 bu_identify_magic( _i), _i, __FILE__, __LINE__); \
00139 bu_bomb("Bad getput buffer"); \
00140 } \
00141 }
00142
00143
00144
00145
00146 int
00147 bu_struct_export(struct bu_external *ext, const genptr_t base, const struct bu_structparse *imp)
00148 {
00149 register char *cp;
00150 char *ep;
00151 const struct bu_structparse *ip;
00152 char *loc;
00153 int len;
00154 register int i;
00155
00156 BU_INIT_EXTERNAL(ext);
00157
00158 ext->ext_nbytes = 480;
00159 ext->ext_buf = (genptr_t)bu_malloc( ext->ext_nbytes,
00160 "bu_struct_export output ext->ext_buf" );
00161 BU_INIT_GETPUT_1(ext);
00162 cp = (char *) ext->ext_buf + 6;
00163 ep = cp + ext->ext_nbytes;
00164
00165 for( ip = imp; ip->sp_fmt[0] != '\0'; ip++ ) {
00166
00167 #if CRAY && !__STDC__
00168 loc = ((char *)base) + ((int)ip->sp_offset*sizeof(int));
00169 #else
00170 loc = ((char *)base) + ip->sp_offset;
00171 #endif
00172
00173 switch( ip->sp_fmt[0] ) {
00174 case 'i':
00175
00176
00177 bu_free( (char *) ext->ext_buf, "output ext_buf" );
00178 return( 0 );
00179 case '%':
00180
00181 break;
00182 default:
00183
00184 bu_free( (char *) ext->ext_buf, "output ext_buf" );
00185 return( 0 );
00186 }
00187
00188 switch( ip->sp_fmt[1] ) {
00189 case 'f':
00190
00191 len = ip->sp_count * 8;
00192 CKMEM( len );
00193 htond( (unsigned char *)cp, (unsigned char *)loc, ip->sp_count );
00194 cp += len;
00195 continue;
00196 case 'd':
00197
00198 CKMEM( ip->sp_count * 4 );
00199 {
00200 register unsigned long l;
00201 for( i = ip->sp_count-1; i >= 0; i-- ) {
00202 l = *((int *)loc);
00203 cp[3] = l;
00204 cp[2] = l >> 8;
00205 cp[1] = l >> 16;
00206 cp[0] = l >> 24;
00207 loc += sizeof(int);
00208 cp += 4;
00209 }
00210 }
00211 continue;
00212 case 'i':
00213
00214 CKMEM( ip->sp_count * 2 );
00215 {
00216 register unsigned short s;
00217 for( i = ip->sp_count-1; i >= 0; i-- ) {
00218 s = *((int *)loc);
00219 cp[1] = s;
00220 cp[0] = s >> 8;
00221 loc += sizeof(int);
00222 cp += 2;
00223 }
00224 }
00225 continue;
00226 case 's':
00227 {
00228
00229
00230
00231
00232
00233
00234
00235
00236 register int lenstr;
00237
00238
00239 lenstr = strlen( loc ) + 1;
00240
00241 len = lenstr;
00242
00243
00244 if ((len & 0x03) != 0)
00245 len += 4 - (len & 0x03);
00246
00247 CKMEM( len + 4 );
00248
00249
00250
00251
00252 cp[3] = len;
00253 cp[2] = len >> 8;
00254 cp[1] = len >> 16;
00255 cp[0] = len >> 24;
00256
00257 cp += 4;
00258
00259 bcopy( loc, cp, lenstr );
00260 cp += lenstr;
00261 while (lenstr++ < len) *cp++ = '\0';
00262 }
00263 continue;
00264 case 'c':
00265 {
00266 CKMEM( ip->sp_count + 4 );
00267 cp[3] = ip->sp_count;
00268 cp[2] = ip->sp_count >> 8;
00269 cp[1] = ip->sp_count >> 16;
00270 cp[0] = ip->sp_count >> 24;
00271 cp += 4;
00272 bcopy( loc, cp, ip->sp_count);
00273 cp += ip->sp_count;
00274 }
00275 continue;
00276 default:
00277 bu_free( (char *) ext->ext_buf, "output ext_buf" );
00278 return( 0 );
00279 }
00280 }
00281 CKMEM( 2);
00282 cp += 2;
00283
00284 i = cp - (char *)ext->ext_buf;
00285
00286 ((char *)ext->ext_buf)[5] = i;
00287 ((char *)ext->ext_buf)[4] = i >> 8;
00288 ((char *)ext->ext_buf)[3] = i >>16;
00289 ((char *)ext->ext_buf)[2] = i >>24;
00290 BU_INIT_GETPUT_2(ext, i);
00291 ext->ext_nbytes = i;
00292 return( 1 );
00293 }
00294
00295
00296
00297
00298 int
00299 bu_struct_import(genptr_t base, const struct bu_structparse *imp, const struct bu_external *ext)
00300 {
00301 register const unsigned char *cp;
00302 const struct bu_structparse *ip;
00303 char *loc;
00304 int len;
00305 int bytes_used;
00306 register int i;
00307
00308 BU_CK_GETPUT(ext);
00309
00310 cp = (unsigned char *)ext->ext_buf+6;
00311 bytes_used = 0;
00312 for( ip = imp; ip->sp_fmt[0] != '\0'; ip++ ) {
00313
00314 #if CRAY && !__STDC__
00315 loc = ((char *)base) + ((int)ip->sp_offset*sizeof(int));
00316 #else
00317 loc = ((char *)base) + ip->sp_offset;
00318 #endif
00319
00320 switch( ip->sp_fmt[0] ) {
00321 case 'i':
00322
00323
00324 return( -1 );
00325 case '%':
00326
00327 break;
00328 default:
00329
00330 return( -1 );
00331 }
00332
00333 switch( ip->sp_fmt[1] ) {
00334 case 'f':
00335
00336 len = ip->sp_count * 8;
00337 ntohd( (unsigned char *)loc, cp, ip->sp_count );
00338 cp += len;
00339 bytes_used += len;
00340 break;
00341 case 'd':
00342
00343 {
00344 register long l;
00345 for( i = ip->sp_count-1; i >= 0; i-- ) {
00346 l = (cp[0] << 24) |
00347 (cp[1] << 16) |
00348 (cp[2] << 8) |
00349 cp[3];
00350 *(int *)loc = l;
00351 loc += sizeof(int);
00352 cp += 4;
00353 }
00354 bytes_used += ip->sp_count * 4;
00355 }
00356 break;
00357 case 'i':
00358
00359 for( i = ip->sp_count-1; i >= 0; i-- ) {
00360 *(int *)loc = (cp[0] << 8) |
00361 cp[1];
00362 loc += sizeof(int);
00363 cp += 2;
00364 }
00365 bytes_used += ip->sp_count * 2;
00366 break;
00367 case 's':
00368 {
00369
00370
00371
00372
00373
00374 register unsigned long lenstr;
00375
00376 lenstr = (cp[0] << 24) |
00377 (cp[1] << 16) |
00378 (cp[2] << 8) |
00379 cp[3];
00380
00381 cp += 4;
00382
00383
00384 if (ip->sp_count < lenstr)
00385 bcopy( cp, loc, ip->sp_count);
00386 else
00387 bcopy( cp, loc, lenstr );
00388
00389
00390 loc[ip->sp_count-1] = '\0';
00391
00392 cp += lenstr;
00393 bytes_used += lenstr;
00394 }
00395 break;
00396 case 'c':
00397 {
00398 register unsigned long lenarray;
00399
00400 lenarray = (cp[0] << 24) |
00401 (cp[1] << 16) |
00402 (cp[2] << 8) |
00403 cp[3];
00404 cp += 4;
00405
00406 if (ip->sp_count < lenarray) {
00407 bcopy( cp, loc, ip->sp_count);
00408 } else {
00409 bcopy( cp, loc, lenarray );
00410 }
00411 cp += lenarray;
00412 bytes_used += lenarray;
00413 }
00414 break;
00415 default:
00416 return( -1 );
00417 }
00418 if ( ip->sp_hook ) {
00419
00420 ip->sp_hook (ip, ip->sp_name, base, (char *)NULL);
00421 }
00422 }
00423
00424
00425 return( bytes_used );
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 int
00435 bu_struct_put(FILE *fp, const struct bu_external *ext)
00436 {
00437 BU_CK_GETPUT(ext);
00438
00439 return(fwrite(ext->ext_buf, 1, ext->ext_nbytes, fp));
00440 }
00441
00442
00443
00444
00445
00446
00447 int
00448 bu_struct_get(struct bu_external *ext, FILE *fp)
00449 {
00450 register long i, len;
00451
00452 BU_INIT_EXTERNAL(ext);
00453 ext->ext_buf = (genptr_t) bu_malloc( 6, "bu_struct_get buffer head");
00454 bu_semaphore_acquire( BU_SEM_SYSCALL );
00455
00456 i=fread( (char *) ext->ext_buf, 1, 6, fp);
00457 bu_semaphore_release( BU_SEM_SYSCALL );
00458
00459 if (i != 6 ) {
00460 if (i == 0) return(0);
00461 bu_log("ERROR: bu_struct_get bad fread (%d), file %s, line %d\n",
00462 i, __FILE__, __LINE__);
00463 bu_bomb("Bad fread");
00464 }
00465 i = (((unsigned char *)(ext->ext_buf))[0] << 8) |
00466 ((unsigned char *)(ext->ext_buf))[1];
00467 len = (((unsigned char *)(ext->ext_buf))[2] << 24) |
00468 (((unsigned char *)(ext->ext_buf))[3] << 16) |
00469 (((unsigned char *)(ext->ext_buf))[4] << 8) |
00470 ((unsigned char *)(ext->ext_buf))[5];
00471 if ( i != BU_GETPUT_MAGIC_1) {
00472 bu_log("ERROR: bad getput buffer header x%x, s/b x%x, was %s(x%x), file %s, line %d\n",
00473 ext->ext_buf, BU_GETPUT_MAGIC_1,
00474 bu_identify_magic( i), i, __FILE__, __LINE__);
00475 bu_bomb("bad getput buffer");
00476 }
00477 ext->ext_nbytes = len;
00478 ext->ext_buf = (genptr_t) bu_realloc((char *) ext->ext_buf, len,
00479 "bu_struct_get full buffer");
00480 bu_semaphore_acquire( BU_SEM_SYSCALL );
00481 i=fread((char *) ext->ext_buf + 6, 1 , len-6, fp);
00482 bu_semaphore_release( BU_SEM_SYSCALL );
00483 if (i != len-6) {
00484 bu_log("ERROR: bu_struct_get bad fread (%d), file %s, line %d\n",
00485 i, __FILE__, __LINE__);
00486 bu_bomb("Bad fread");
00487 }
00488 i = (((unsigned char *)(ext->ext_buf))[len-2] <<8) |
00489 ((unsigned char *)(ext->ext_buf))[len-1];
00490 if ( i != BU_GETPUT_MAGIC_2) {
00491 bu_log("ERROR: bad getput buffer x%x, s/b x%x, was %s(x%x), file %s, line %d\n",
00492 ext->ext_buf, BU_GETPUT_MAGIC_2,
00493 bu_identify_magic( i), i, __FILE__, __LINE__);
00494 bu_bomb("Bad getput buffer");
00495 }
00496 return(1);
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 void
00509 bu_struct_wrap_buf(struct bu_external *ext, genptr_t buf)
00510 {
00511 register long i, len;
00512
00513 BU_INIT_EXTERNAL(ext);
00514 ext->ext_buf = buf;
00515 i = (((unsigned char *)(ext->ext_buf))[0] << 8) |
00516 ((unsigned char *)(ext->ext_buf))[1];
00517 len = (((unsigned char *)(ext->ext_buf))[2] << 24) |
00518 (((unsigned char *)(ext->ext_buf))[3] << 16) |
00519 (((unsigned char *)(ext->ext_buf))[4] << 8) |
00520 ((unsigned char *)(ext->ext_buf))[5];
00521 if ( i != BU_GETPUT_MAGIC_1) {
00522 bu_log("ERROR: bad getput buffer header x%x, s/b x%x, was %s(x%x), file %s, line %d\n",
00523 ext->ext_buf, BU_GETPUT_MAGIC_1,
00524 bu_identify_magic( i), i, __FILE__, __LINE__);
00525 bu_bomb("bad getput buffer");
00526 }
00527 ext->ext_nbytes = len;
00528 i = (((unsigned char *)(ext->ext_buf))[len-2] <<8) |
00529 ((unsigned char *)(ext->ext_buf))[len-1];
00530 if ( i != BU_GETPUT_MAGIC_2) {
00531 bu_log("ERROR: bad getput buffer x%x, s/b x%x, was %s(x%x), file %s, line %s\n",
00532 ext->ext_buf, BU_GETPUT_MAGIC_2,
00533 bu_identify_magic( i), i, __FILE__, __LINE__);
00534 bu_bomb("Bad getput buffer");
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 HIDDEN int
00555 bu_parse_double(const char *str, long int count, double *loc)
00556 {
00557 long i;
00558 int dot_seen;
00559 const char *numstart;
00560 double tmp_double;
00561 char buf[128];
00562 int len;
00563
00564 for (i=0 ; i < count && *str ; ++i){
00565 numstart = str;
00566
00567
00568 if (*str == '-' || *str == '+') str++;
00569
00570
00571 dot_seen = 0;
00572 for ( ; *str ; str++ ) {
00573 if (*str == '.' && !dot_seen) {
00574 dot_seen = 1;
00575 continue;
00576 }
00577 if (!isdigit(*str))
00578 break;
00579
00580 }
00581
00582
00583 if (str == (numstart + dot_seen) )
00584 return -1;
00585
00586
00587 if (*str == 'E' || *str == 'e') {
00588 str++;
00589
00590
00591 if (*str == '+' || *str == '-') str++;
00592
00593 while (isdigit(*str)) str++;
00594 }
00595
00596 len = str - numstart;
00597 if( len > sizeof(buf)-1 ) len = sizeof(buf)-1;
00598 strncpy( buf, numstart, len );
00599 buf[len] = '\0';
00600
00601 if( sscanf( buf, "%lf", &tmp_double ) != 1 )
00602 return -1;
00603
00604 *loc++ = tmp_double;
00605
00606
00607 if (*str) str++;
00608 }
00609 return 0;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 HIDDEN int
00621 bu_struct_lookup(register const struct bu_structparse *sdp, register const char *name, const char *base, const char *const value)
00622
00623
00624
00625
00626 {
00627 register char *loc;
00628 int i, retval = 0;
00629
00630 for( ; sdp->sp_name != (char *)0; sdp++ ) {
00631
00632 if( strcmp( sdp->sp_name, name ) != 0
00633 && sdp->sp_fmt[0] != 'i' )
00634
00635 continue;
00636
00637
00638
00639
00640
00641 #if CRAY && !__STDC__
00642 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00643 #else
00644 loc = (char *)(base + sdp->sp_offset);
00645 #endif
00646
00647 if (sdp->sp_fmt[0] == 'i') {
00648
00649 if( bu_struct_lookup(
00650 (struct bu_structparse *)sdp->sp_count,
00651 name, base, value )
00652 == 0 )
00653 return(0);
00654 else
00655 continue;
00656 }
00657 if (sdp->sp_fmt[0] != '%') {
00658 bu_log("bu_struct_lookup(%s): unknown format '%s'\n",
00659 name, sdp->sp_fmt );
00660 return(-1);
00661 }
00662
00663 switch( sdp->sp_fmt[1] ) {
00664 case 'c':
00665 case 's':
00666 { register int i, j;
00667
00668
00669
00670
00671 for(i=j=0 ;
00672 j < sdp->sp_count && value[i] != '\0' ;
00673 loc[j++] = value[i++])
00674 if (value[i] == '\\' &&
00675 value[i+1] == '"')
00676 ++i;
00677
00678
00679 if (sdp->sp_count > 1) {
00680
00681 if( j < sdp->sp_count-1 )
00682 loc[j] = '\0';
00683 else
00684 loc[sdp->sp_count-1] = '\0';
00685 }
00686 }
00687 break;
00688 case 'S':
00689 { struct bu_vls *vls = (struct bu_vls *)loc;
00690 bu_vls_init_if_uninit( vls );
00691 bu_vls_strcpy(vls, value);
00692 }
00693 break;
00694 case 'i':
00695 { register short *ip = (short *)loc;
00696 register short tmpi;
00697 register const char *cp;
00698 register const char *pv = value;
00699
00700 for (i=0 ; i < sdp->sp_count && *pv ; ++i){
00701 tmpi = atoi( pv );
00702
00703 cp = pv;
00704 if (*cp && (*cp == '+' || *cp == '-'))
00705 cp++;
00706
00707 while (*cp && isdigit(*cp) )
00708 cp++;
00709
00710
00711
00712
00713 if (cp == pv ||
00714 (cp == pv+1 &&
00715 (*pv == '+' || *pv == '-'))){
00716 retval = -2;
00717 break;
00718 } else {
00719 *(ip++) = tmpi;
00720 pv = cp;
00721 }
00722
00723 if (*pv) pv++;
00724 }
00725 }
00726 break;
00727 case 'd':
00728 { register int *ip = (int *)loc;
00729 register int tmpi;
00730 register char const *cp;
00731 register const char *pv = value;
00732
00733
00734 if( *pv == '!' ) {
00735 *ip = *ip ? 0 : 1;
00736 pv++;
00737 break;
00738 }
00739
00740 for (i=0 ; i < sdp->sp_count && *pv ; ++i){
00741 tmpi = atoi( pv );
00742
00743 cp = pv;
00744 if (*cp && (*cp == '+' || *cp == '-'))
00745 cp++;
00746
00747 while (*cp && isdigit(*cp) )
00748 cp++;
00749
00750
00751
00752
00753 if (cp == pv ||
00754 (cp == pv+1 &&
00755 (*pv == '+' || *pv == '-'))){
00756 retval = -2;
00757 break;
00758 } else {
00759 *(ip++) = tmpi;
00760 pv = cp;
00761 }
00762
00763 if (*pv) pv++;
00764 }
00765 }
00766 break;
00767 case 'f':
00768 retval = bu_parse_double(value, sdp->sp_count,
00769 (double *)loc);
00770 break;
00771 default:
00772 bu_log("bu_struct_lookup(%s): unknown format '%s'\n",
00773 name, sdp->sp_fmt );
00774 return(-1);
00775 }
00776 if( sdp->sp_hook ) {
00777 sdp->sp_hook( sdp, name, base, value );
00778 }
00779 return(retval);
00780 }
00781 return(-1);
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 int
00795 bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base)
00796
00797
00798
00799 {
00800 struct bu_vls vls;
00801 register char *cp;
00802 char *name;
00803 char *value;
00804 int retval;
00805
00806 BU_CK_VLS(in_vls);
00807 if (desc == (struct bu_structparse *)NULL) {
00808 bu_log( "Null \"struct bu_structparse\" pointer\n");
00809 return(-1);
00810 }
00811
00812
00813 bu_vls_init( &vls );
00814 bu_vls_vlscat( &vls, in_vls );
00815 cp = bu_vls_addr( &vls );
00816
00817 while( *cp ) {
00818
00819
00820
00821 while( *cp != '\0' && isascii(*cp) && isspace(*cp) )
00822 cp++;
00823
00824
00825 name = cp;
00826 while ( *cp != '\0' && *cp != '=' )
00827 cp++;
00828
00829 if( *cp == '\0' ) {
00830 if( name == cp ) break;
00831
00832
00833 bu_log("bu_structparse: input keyword '%s' is not followed by '=' in '%s'\nInput must be in keyword=value format.\n",
00834 name, bu_vls_addr(in_vls) );
00835 bu_vls_free( &vls );
00836 return(-2);
00837 }
00838
00839 *cp++ = '\0';
00840
00841
00842 if (*cp == '"') {
00843
00844
00845
00846
00847 for (value = ++cp ; *cp != '\0' ; ++cp)
00848 if (*cp == '"' &&
00849 (cp == value || *(cp-1) != '\\') )
00850 break;
00851
00852 if (*cp != '"') {
00853 bu_log("bu_structparse: keyword '%s'=\" without closing \"\n",
00854 name);
00855 bu_vls_free( &vls );
00856 return(-3);
00857 }
00858 } else {
00859
00860 value = cp;
00861 while( *cp != '\0' && isascii(*cp) && !isspace(*cp) )
00862 cp++;
00863 }
00864
00865 if( *cp != '\0' )
00866 *cp++ = '\0';
00867
00868
00869 retval = bu_struct_lookup( desc, name, base, value );
00870 if( retval == -1 ) {
00871 bu_log("bu_structparse: '%s=%s', keyword not found in:\n",
00872 name, value);
00873 bu_struct_print( "troublesome one", desc, base );
00874 } else if( retval == -2 ) {
00875 bu_vls_free( &vls );
00876 return -2;
00877 }
00878
00879 }
00880 bu_vls_free( &vls );
00881 return(0);
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891 HIDDEN void
00892 bu_matprint(const char *name, register const double *mat)
00893 {
00894 int delta = strlen(name)+2;
00895
00896
00897 bu_log_indent_delta(delta);
00898
00899 bu_log(" %s=%12E %12E %12E %12E\n",
00900 name, mat[0], mat[1], mat[2], mat[3]);
00901
00902 bu_log("%12E %12E %12E %12E\n",
00903 mat[4], mat[5], mat[6], mat[7]);
00904
00905 bu_log("%12E %12E %12E %12E\n",
00906 mat[8], mat[9], mat[10], mat[11]);
00907
00908 bu_log_indent_delta(-delta);
00909
00910 bu_log("%12E %12E %12E %12E\n",
00911 mat[12], mat[13], mat[14], mat[15]);
00912 }
00913
00914
00915
00916
00917 HIDDEN void
00918 bu_vls_matprint(struct bu_vls *vls,
00919 const char *name,
00920 register const double *mat)
00921 {
00922 int delta = strlen(name)+2;
00923
00924
00925 bu_log_indent_delta(delta);
00926
00927 bu_vls_printf(vls, " %s=%12E %12E %12E %12E\n",
00928 name, mat[0], mat[1], mat[2], mat[3]);
00929 bu_log_indent_vls(vls);
00930
00931 bu_vls_printf(vls, "%12E %12E %12E %12E\n",
00932 mat[4], mat[5], mat[6], mat[7]);
00933 bu_log_indent_vls(vls);
00934
00935 bu_vls_printf(vls, "%12E %12E %12E %12E\n",
00936 mat[8], mat[9], mat[10], mat[11]);
00937 bu_log_indent_vls(vls);
00938
00939 bu_log_indent_delta(-delta);
00940
00941 bu_vls_printf(vls, "%12E %12E %12E %12E\n",
00942 mat[12], mat[13], mat[14], mat[15]);
00943 }
00944
00945
00946
00947
00948
00949
00950 void
00951 bu_vls_struct_item(struct bu_vls *vp, const struct bu_structparse *sdp, const char *base, int sep_char)
00952
00953
00954
00955
00956 {
00957 register char *loc;
00958
00959 if (sdp == (struct bu_structparse *)NULL) {
00960 bu_log( "Null \"struct bu_structparse\" pointer\n");
00961 return;
00962 }
00963
00964 #if CRAY && !__STDC__
00965 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
00966 #else
00967 loc = (char *)(base + sdp->sp_offset);
00968 #endif
00969
00970 if (sdp->sp_fmt[0] == 'i' ) {
00971 bu_log( "Cannot print type 'i' yet!\n" );
00972 return;
00973 }
00974
00975 if ( sdp->sp_fmt[0] != '%') {
00976 bu_log("bu_vls_struct_item: %s: unknown format '%s'\n",
00977 sdp->sp_name, sdp->sp_fmt );
00978 return;
00979 }
00980
00981 switch( sdp->sp_fmt[1] ) {
00982 case 'c':
00983 case 's':
00984 if (sdp->sp_count < 1)
00985 break;
00986 if (sdp->sp_count == 1)
00987 bu_vls_printf( vp, "%c", *loc );
00988 else
00989 bu_vls_printf( vp, "%s", (char *)loc );
00990 break;
00991 case 'S': {
00992 register struct bu_vls *vls = (struct bu_vls *)loc;
00993
00994 bu_vls_vlscat( vp, vls ); }
00995 break;
00996 case 'i': {
00997 register int i = sdp->sp_count;
00998 register short *sp = (short *)loc;
00999
01000 bu_vls_printf( vp, "%d", *sp++ );
01001 while( --i > 0 ) bu_vls_printf( vp, "%c%d", sep_char, *sp++ ); }
01002 break;
01003 case 'd': {
01004 register int i = sdp->sp_count;
01005 register int *dp = (int *)loc;
01006
01007 bu_vls_printf( vp, "%d", *dp++ );
01008 while( --i > 0 ) bu_vls_printf( vp, "%c%d", sep_char, *dp++ ); }
01009 break;
01010 case 'f': {
01011 register int i = sdp->sp_count;
01012 register double *dp = (double *)loc;
01013
01014 bu_vls_printf( vp, "%.25G", *dp++ );
01015 while( --i > 0 ) bu_vls_printf( vp, "%c%.25G", sep_char, *dp++ ); }
01016 break;
01017 case 'x': {
01018 register int i = sdp->sp_count;
01019 register int *dp = (int *)loc;
01020
01021 bu_vls_printf( vp, "%08x", *dp++ );
01022 while( --i > 0 ) bu_vls_printf( vp, "%c%08x", sep_char, *dp++ ); }
01023 break;
01024 default:
01025 break;
01026 }
01027 }
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 int
01038 bu_vls_struct_item_named(struct bu_vls *vp, const struct bu_structparse *parsetab, const char *name, const char *base, int sep_char)
01039 {
01040 register const struct bu_structparse *sdp;
01041
01042 for( sdp = parsetab; sdp->sp_name != NULL; sdp++ )
01043 if( strcmp(sdp->sp_name, name) == 0 ) {
01044 bu_vls_struct_item( vp, sdp, base, sep_char );
01045 return 0;
01046 }
01047
01048 return -1;
01049 }
01050
01051
01052
01053
01054
01055 void
01056 bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
01057
01058
01059
01060 {
01061 register const struct bu_structparse *sdp;
01062 register char *loc;
01063 register int lastoff = -1;
01064
01065 bu_log( "%s\n", title );
01066 if (parsetab == (struct bu_structparse *)NULL) {
01067 bu_log( "Null \"struct bu_structparse\" pointer\n");
01068 return;
01069 }
01070 for( sdp = parsetab; sdp->sp_name != (char *)0; sdp++ ) {
01071
01072
01073 if( lastoff == sdp->sp_offset )
01074 continue;
01075 lastoff = sdp->sp_offset;
01076
01077 #if CRAY && !__STDC__
01078 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
01079 #else
01080 loc = (char *)(base + sdp->sp_offset);
01081 #endif
01082
01083 if (sdp->sp_fmt[0] == 'i' ) {
01084 bu_struct_print( sdp->sp_name,
01085 (struct bu_structparse *)sdp->sp_count,
01086 base );
01087 continue;
01088 }
01089
01090 if ( sdp->sp_fmt[0] != '%') {
01091 bu_log("bu_struct_print: %s: unknown format '%s'\n",
01092 sdp->sp_name, sdp->sp_fmt );
01093 continue;
01094 }
01095 #if 0
01096 bu_vls_trunc( &vls, 0 );
01097 bu_vls_struct_item( &vls, sdp, base, ',' );
01098 bu_log( " %s=%s\n", sdp->sp_name, bu_vls_addr(&vls) );
01099 #else
01100 switch( sdp->sp_fmt[1] ) {
01101 case 'c':
01102 case 's':
01103 if (sdp->sp_count < 1)
01104 break;
01105 if (sdp->sp_count == 1)
01106 bu_log( " %s='%c'\n", sdp->sp_name, *loc);
01107 else
01108 bu_log( " %s=\"%s\"\n", sdp->sp_name,
01109 (char *)loc );
01110 break;
01111 case 'S':
01112 {
01113 int delta = strlen(sdp->sp_name)+2;
01114 register struct bu_vls *vls =
01115 (struct bu_vls *)loc;
01116
01117 bu_log_indent_delta(delta);
01118 bu_log(" %s=(vls_magic)%d (vls_offset)%d (vls_len)%d (vls_max)%d\n",
01119 sdp->sp_name, vls->vls_magic,
01120 vls->vls_offset,
01121 vls->vls_len, vls->vls_max);
01122 bu_log_indent_delta(-delta);
01123 bu_log("\"%s\"\n", vls->vls_str+vls->vls_offset);
01124 }
01125 break;
01126 case 'i':
01127 { register int i = sdp->sp_count;
01128 register short *sp = (short *)loc;
01129
01130 bu_log( " %s=%d", sdp->sp_name, *sp++ );
01131
01132 while (--i > 0) bu_log( ",%d", *sp++ );
01133
01134 bu_log("\n");
01135 }
01136 break;
01137 case 'd':
01138 { register int i = sdp->sp_count;
01139 register int *dp = (int *)loc;
01140
01141 bu_log( " %s=%d", sdp->sp_name, *dp++ );
01142
01143 while (--i > 0) bu_log( ",%d", *dp++ );
01144
01145 bu_log("\n");
01146 }
01147 break;
01148 case 'f':
01149 { register int i = sdp->sp_count;
01150 register double *dp = (double *)loc;
01151
01152 if (sdp->sp_count == 16) {
01153 bu_matprint(sdp->sp_name, dp);
01154 } else if (sdp->sp_count <= 3){
01155 bu_log( " %s=%.25G", sdp->sp_name, *dp++ );
01156
01157 while (--i > 0)
01158 bu_log( ",%.25G", *dp++ );
01159
01160 bu_log("\n");
01161 }else {
01162 int delta = strlen(sdp->sp_name)+2;
01163
01164 bu_log_indent_delta(delta);
01165
01166 bu_log( " %s=%.25G\n", sdp->sp_name, *dp++ );
01167
01168 while (--i > 1)
01169 bu_log( "%.25G\n", *dp++ );
01170
01171 bu_log_indent_delta(-delta);
01172 bu_log( "%.25G\n", *dp );
01173 }
01174 }
01175 break;
01176 case 'x':
01177 { register int i = sdp->sp_count;
01178 register int *dp = (int *)loc;
01179
01180 bu_log( " %s=%08x", sdp->sp_name, *dp++ );
01181
01182 while (--i > 0) bu_log( ",%08x", *dp++ );
01183
01184 bu_log("\n");
01185 }
01186 break;
01187 default:
01188 bu_log( " bu_struct_print: Unknown format: %s=%s??\n",
01189 sdp->sp_name, sdp->sp_fmt );
01190 break;
01191 }
01192 #endif
01193 }
01194 }
01195
01196
01197
01198
01199 HIDDEN void
01200 bu_vls_print_double(struct bu_vls *vls, const char *name, register long int count, register const double *dp)
01201 {
01202 register int tmpi;
01203 register char *cp;
01204
01205 bu_vls_extend(vls, strlen(name) + 3 + 32 * count);
01206
01207 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01208 sprintf(cp, "%s%s=%.27G", (vls->vls_len?" ":""), name, *dp++);
01209 tmpi = strlen(cp);
01210 vls->vls_len += tmpi;
01211
01212 while (--count > 0) {
01213 cp += tmpi;
01214 sprintf(cp, ",%.27G", *dp++);
01215 tmpi = strlen(cp);
01216 vls->vls_len += tmpi;
01217 }
01218 }
01219
01220
01221
01222
01223
01224
01225
01226 void
01227 bu_vls_struct_print(struct bu_vls *vls, register const struct bu_structparse *sdp, const char *base)
01228
01229
01230
01231 {
01232 register char *loc;
01233 register int lastoff = -1;
01234 register char *cp;
01235
01236 BU_CK_VLS(vls);
01237
01238 if (sdp == (struct bu_structparse *)NULL) {
01239 bu_log( "Null \"struct bu_structparse\" pointer\n");
01240 return;
01241 }
01242
01243 for ( ; sdp->sp_name != (char*)NULL ; sdp++) {
01244
01245
01246 if( lastoff == sdp->sp_offset )
01247 continue;
01248 lastoff = sdp->sp_offset;
01249
01250 #if CRAY && !__STDC__
01251 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
01252 #else
01253 loc = (char *)(base + sdp->sp_offset);
01254 #endif
01255
01256 if (sdp->sp_fmt[0] == 'i') {
01257 struct bu_vls sub_str;
01258
01259 bu_vls_init(&sub_str);
01260 bu_vls_struct_print( &sub_str,
01261 (struct bu_structparse *)sdp->sp_count,
01262 base );
01263
01264 bu_vls_vlscat(vls, &sub_str);
01265 bu_vls_free( &sub_str );
01266 continue;
01267 }
01268
01269 if ( sdp->sp_fmt[0] != '%' ) {
01270 bu_log("bu_struct_print: %s: unknown format '%s'\n",
01271 sdp->sp_name, sdp->sp_fmt );
01272 break;
01273 }
01274
01275 switch( sdp->sp_fmt[1] ) {
01276 case 'c':
01277 case 's':
01278 if (sdp->sp_count < 1)
01279 break;
01280 if (sdp->sp_count == 1) {
01281 bu_vls_extend(vls, strlen(sdp->sp_name)+6);
01282 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01283 if (*loc == '"')
01284 sprintf(cp, "%s%s=\"%s\"",
01285 (vls->vls_len?" ":""),
01286 sdp->sp_name, "\\\"");
01287 else
01288 sprintf(cp, "%s%s=\"%c\"",
01289 (vls->vls_len?" ":""),
01290 sdp->sp_name,
01291 *loc);
01292 } else {
01293 register char *p;
01294 register int count=0;
01295
01296
01297 p = loc;
01298 while ((p=strchr(p, '"')) != (char *)NULL) {
01299 ++p;
01300 ++count;
01301 }
01302 bu_vls_extend(vls, strlen(sdp->sp_name)+
01303 strlen(loc)+5+count);
01304
01305 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01306 if (vls->vls_len) (void)strcat(cp, " ");
01307 (void)strcat(cp, sdp->sp_name);
01308 (void)strcat(cp, "=\"");
01309
01310
01311
01312
01313 p = &cp[strlen(cp)];
01314 while (*loc) {
01315 if (*loc == '"') {
01316 *p++ = '\\';
01317 }
01318 *p++ = *loc++;
01319 }
01320 *p++ = '"';
01321 *p = '\0';
01322 }
01323 vls->vls_len += strlen(cp);
01324 break;
01325 case 'S':
01326 { register struct bu_vls *vls_p =
01327 (struct bu_vls *)loc;
01328
01329 bu_vls_extend(vls, bu_vls_strlen(vls_p) + 5 +
01330 strlen(sdp->sp_name) );
01331
01332 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01333 sprintf(cp, "%s%s=\"%s\"",
01334 (vls->vls_len?" ":""),
01335 sdp->sp_name,
01336 bu_vls_addr(vls_p) );
01337 vls->vls_len += strlen(cp);
01338 }
01339 break;
01340 case 'i':
01341 { register int i = sdp->sp_count;
01342 register short *sp = (short *)loc;
01343 register int tmpi;
01344
01345 bu_vls_extend(vls,
01346 64 * i + strlen(sdp->sp_name) + 3 );
01347
01348 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01349 sprintf(cp, "%s%s=%d",
01350 (vls->vls_len?" ":""),
01351 sdp->sp_name, *sp++);
01352 tmpi = strlen(cp);
01353 vls->vls_len += tmpi;
01354
01355 while (--i > 0) {
01356 cp += tmpi;
01357 sprintf(cp, ",%d", *sp++);
01358 tmpi = strlen(cp);
01359 vls->vls_len += tmpi;
01360 }
01361 }
01362 break;
01363 case 'd':
01364 { register int i = sdp->sp_count;
01365 register int *dp = (int *)loc;
01366 register int tmpi;
01367
01368 bu_vls_extend(vls,
01369 64 * i + strlen(sdp->sp_name) + 3 );
01370
01371 cp = vls->vls_str + vls->vls_offset + vls->vls_len;
01372 sprintf(cp, "%s%s=%d",
01373 (vls->vls_len?" ":""),
01374 sdp->sp_name, *dp++);
01375 tmpi = strlen(cp);
01376 vls->vls_len += tmpi;
01377
01378 while (--i > 0) {
01379 cp += tmpi;
01380 sprintf(cp, ",%d", *dp++);
01381 tmpi = strlen(cp);
01382 vls->vls_len += tmpi;
01383 }
01384 }
01385 break;
01386 case 'f':
01387 bu_vls_print_double(vls, sdp->sp_name, sdp->sp_count,
01388 (double *)loc);
01389 break;
01390 default:
01391 bu_log( " %s=%s??\n", sdp->sp_name, sdp->sp_fmt );
01392 bu_bomb("unexpected case encountered in bu_vls_struct_print\n");
01393 break;
01394 }
01395 }
01396 }
01397
01398
01399
01400
01401
01402
01403
01404 void
01405 bu_vls_struct_print2(struct bu_vls *vls_out,
01406 const char *title,
01407 const struct bu_structparse *parsetab,
01408 const char *base)
01409 {
01410 register const struct bu_structparse *sdp;
01411 register char *loc;
01412 register int lastoff = -1;
01413
01414 bu_vls_printf(vls_out, "%s\n", title);
01415 if (parsetab == (struct bu_structparse *)NULL) {
01416 bu_vls_printf(vls_out, "Null \"struct bu_structparse\" pointer\n");
01417 return;
01418 }
01419
01420 for (sdp = parsetab; sdp->sp_name != (char *)0; sdp++) {
01421
01422
01423 if (lastoff == sdp->sp_offset)
01424 continue;
01425 lastoff = sdp->sp_offset;
01426
01427 #if CRAY && !__STDC__
01428 loc = (char *)(base + ((int)sdp->sp_offset*sizeof(int)));
01429 #else
01430 loc = (char *)(base + sdp->sp_offset);
01431 #endif
01432
01433 if (sdp->sp_fmt[0] == 'i' ) {
01434 bu_vls_struct_print2(vls_out, sdp->sp_name,
01435 (struct bu_structparse *)sdp->sp_count,
01436 base);
01437 continue;
01438 }
01439
01440 if (sdp->sp_fmt[0] != '%') {
01441 bu_vls_printf(vls_out, "bu_vls_struct_print: %s: unknown format '%s'\n",
01442 sdp->sp_name, sdp->sp_fmt );
01443 continue;
01444 }
01445
01446 switch( sdp->sp_fmt[1] ) {
01447 case 'c':
01448 case 's':
01449 if (sdp->sp_count < 1)
01450 break;
01451 if (sdp->sp_count == 1)
01452 bu_vls_printf(vls_out, " %s='%c'\n", sdp->sp_name, *loc);
01453 else
01454 bu_vls_printf(vls_out, " %s=\"%s\"\n", sdp->sp_name,
01455 (char *)loc );
01456 break;
01457 case 'S':
01458 {
01459 int delta = strlen(sdp->sp_name)+2;
01460 register struct bu_vls *vls =
01461 (struct bu_vls *)loc;
01462
01463 bu_log_indent_delta(delta);
01464 bu_vls_printf(vls_out, " %s=(vls_magic)%ld (vls_offset)%d (vls_len)%d (vls_max)%d\n",
01465 sdp->sp_name, vls->vls_magic,
01466 vls->vls_offset,
01467 vls->vls_len, vls->vls_max);
01468 bu_log_indent_vls(vls_out);
01469 bu_log_indent_delta(-delta);
01470 bu_vls_printf(vls_out, "\"%s\"\n", vls->vls_str+vls->vls_offset);
01471 }
01472 break;
01473 case 'i':
01474 { register int i = sdp->sp_count;
01475 register short *sp = (short *)loc;
01476
01477 bu_vls_printf(vls_out, " %s=%d", sdp->sp_name, *sp++ );
01478
01479 while (--i > 0)
01480 bu_vls_printf(vls_out, ",%d", *sp++ );
01481
01482 bu_vls_printf(vls_out, "\n");
01483 }
01484 break;
01485 case 'd':
01486 { register int i = sdp->sp_count;
01487 register int *dp = (int *)loc;
01488
01489 bu_vls_printf(vls_out, " %s=%d", sdp->sp_name, *dp++ );
01490
01491 while (--i > 0)
01492 bu_vls_printf(vls_out, ",%d", *dp++ );
01493
01494 bu_vls_printf(vls_out, "\n");
01495 }
01496 break;
01497 case 'f':
01498 { register int i = sdp->sp_count;
01499 register double *dp = (double *)loc;
01500
01501 if (sdp->sp_count == 16) {
01502 bu_vls_matprint(vls_out, sdp->sp_name, dp);
01503 } else if (sdp->sp_count <= 3){
01504 bu_vls_printf(vls_out, " %s=%.25G", sdp->sp_name, *dp++ );
01505
01506 while (--i > 0)
01507 bu_vls_printf(vls_out, ",%.25G", *dp++ );
01508
01509 bu_vls_printf(vls_out, "\n");
01510 }else {
01511 int delta = strlen(sdp->sp_name)+2;
01512
01513 bu_log_indent_delta(delta);
01514 bu_vls_printf(vls_out, " %s=%.25G\n", sdp->sp_name, *dp++ );
01515 bu_log_indent_vls(vls_out);
01516
01517 while (--i > 1) {
01518 bu_vls_printf(vls_out, "%.25G\n", *dp++ );
01519 bu_log_indent_vls(vls_out);
01520 }
01521
01522 bu_log_indent_delta(-delta);
01523 bu_vls_printf(vls_out, "%.25G\n", *dp );
01524 }
01525 }
01526 break;
01527 case 'x':
01528 { register int i = sdp->sp_count;
01529 register int *dp = (int *)loc;
01530
01531 bu_vls_printf(vls_out, " %s=%08x", sdp->sp_name, *dp++ );
01532
01533 while (--i > 0)
01534 bu_vls_printf(vls_out, ",%08x", *dp++ );
01535
01536 bu_vls_printf(vls_out, "\n");
01537 }
01538 break;
01539 default:
01540 bu_vls_printf(vls_out, " bu_vls_struct_print2: Unknown format: %s=%s??\n",
01541 sdp->sp_name, sdp->sp_fmt );
01542 break;
01543 }
01544 }
01545 }
01546
01547
01548
01549
01550
01551
01552 void
01553 bu_parse_mm(register const struct bu_structparse *sdp, register const char *name, char *base, const char *value)
01554
01555
01556
01557
01558 {
01559 double *p = (double *)(base+sdp->sp_offset);
01560
01561
01562 *p = bu_mm_value(value);
01563 }
01564
01565 #define STATE_UNKNOWN 0
01566 #define STATE_IN_KEYWORD 1
01567 #define STATE_IN_VALUE 2
01568 #define STATE_IN_QUOTED_VALUE 3
01569
01570
01571
01572
01573 int
01574 bu_key_eq_to_key_val(char *in, char **next, struct bu_vls *vls)
01575 {
01576 char *iptr=in;
01577 char *start;
01578 int state=STATE_IN_KEYWORD;
01579
01580 BU_CK_VLS( vls );
01581
01582 *next = NULL;
01583
01584 while ( *iptr )
01585 {
01586 char *prev='\0';
01587
01588 switch( state )
01589 {
01590 case STATE_IN_KEYWORD:
01591
01592 while( isspace( *iptr ) )
01593 iptr++;
01594
01595 if( !(*iptr) )
01596 break;
01597
01598 if( *iptr == ';' )
01599 {
01600
01601 *next = iptr+1;
01602 return( 0 );
01603 }
01604
01605
01606 start = iptr;
01607 while( *iptr && *iptr != '=' )
01608 iptr++;
01609
01610 bu_vls_strncat( vls, start, iptr - start );
01611
01612
01613 bu_vls_putc( vls, ' ' );
01614
01615 if( !*iptr )
01616 break;
01617
01618
01619 iptr++;
01620
01621
01622 state = STATE_IN_VALUE;
01623
01624 break;
01625 case STATE_IN_VALUE:
01626
01627 while( isspace( *iptr ) )
01628 iptr++;
01629
01630
01631 if( *iptr == '"' )
01632 {
01633
01634 state = STATE_IN_QUOTED_VALUE;
01635
01636
01637 iptr++;
01638
01639 break;
01640 }
01641
01642
01643 start = iptr;
01644 while( *iptr && *iptr != ';' && !isspace( *iptr ) )
01645 iptr++;
01646
01647 bu_vls_strncat( vls, start, iptr - start );
01648
01649 if( *iptr )
01650 {
01651 bu_vls_putc( vls, ' ' );
01652
01653
01654 state = STATE_IN_KEYWORD;
01655 }
01656
01657 break;
01658 case STATE_IN_QUOTED_VALUE:
01659
01660
01661
01662 bu_vls_strcat( vls, " {" );
01663 while( 1 )
01664 {
01665 if( *iptr == '"' && *prev != '\\' )
01666 {
01667 bu_vls_putc( vls, '}' );
01668 iptr++;
01669 break;
01670 }
01671 bu_vls_putc( vls, *iptr );
01672 prev = iptr++;
01673 }
01674
01675 if( *iptr && *iptr != ';' )
01676 bu_vls_putc( vls, ' ' );
01677
01678
01679 state = STATE_IN_KEYWORD;
01680
01681 break;
01682 }
01683 }
01684 return( 0 );
01685 }
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707 int
01708 bu_shader_to_tcl_list(char *in, struct bu_vls *vls)
01709 {
01710 char *iptr;
01711 char *next=in;
01712 char *shader;
01713 int shader_name_len=0;
01714 int is_stack=0;
01715 int len;
01716
01717
01718 BU_CK_VLS( vls );
01719
01720 while( next )
01721 {
01722 iptr = next;
01723
01724
01725 while( isspace( *iptr ) )
01726 iptr++;
01727
01728
01729 shader = iptr;
01730
01731
01732 while( *iptr && !isspace( *iptr ) && *iptr != ';' )
01733 iptr++;
01734 shader_name_len = iptr - shader;
01735
01736 if( !strncmp( shader, "stack", 5 ) )
01737 {
01738
01739 int done=0;
01740
01741 bu_vls_strcat( vls, "stack {" );
01742
01743 while( !done )
01744 {
01745 char *shade1;
01746
01747 while( isspace( *iptr ) )
01748 iptr++;
01749 if( *iptr == '\0' )
01750 break;
01751 shade1 = iptr;
01752 while( *iptr && *iptr != ';' )
01753 iptr++;
01754 if( *iptr == '\0' )
01755 done = 1;
01756 *iptr = '\0';
01757
01758 bu_vls_putc( vls, '{' );
01759
01760 if( bu_shader_to_tcl_list( shade1, vls ) )
01761 return( 1 );
01762
01763 bu_vls_strcat( vls, "} " );
01764
01765 if( !done )
01766 iptr++;
01767 }
01768 bu_vls_putc( vls, '}' );
01769 return( 0 );
01770 }
01771 else if( !strncmp( shader, "envmap", 6 ) )
01772 {
01773 bu_vls_strcat( vls, "envmap {" );
01774 if( bu_shader_to_tcl_list( iptr, vls ) )
01775 return( 1 );
01776 bu_vls_putc( vls, '}' );
01777 return( 0 );
01778 }
01779
01780 if( is_stack )
01781 bu_vls_strcat( vls, " {" );
01782
01783 bu_vls_strncat( vls, shader, shader_name_len );
01784
01785
01786 while( *iptr && isspace( *iptr ) )
01787 iptr++;
01788
01789
01790 if( *iptr && *iptr != ';' )
01791 {
01792 bu_vls_strcat( vls, " {" );
01793 len = bu_vls_strlen( vls );
01794 if( bu_key_eq_to_key_val( iptr, &next, vls ) )
01795 return( 1 );
01796 if( bu_vls_strlen( vls ) > len )
01797 bu_vls_putc( vls, '}' );
01798 else
01799 bu_vls_trunc( vls, len-2 );
01800 }
01801 else if( *iptr && *iptr == ';' )
01802 next = ++iptr;
01803 else
01804 next = (char *)NULL;
01805
01806 if( is_stack )
01807 bu_vls_putc( vls, '}' );
01808 }
01809
01810 if( is_stack )
01811 bu_vls_putc( vls, '}' );
01812
01813 return( 0 );
01814 }
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825 char *
01826 bu_list_elem( const char *in, int index )
01827 {
01828 int depth=0;
01829 int count=0;
01830 int len=0;
01831 const char *ptr=in;
01832 const char *prev=NULL;
01833 const char *start=NULL;
01834 const char *end=NULL;
01835 char *out=NULL;
01836
01837 while( *ptr )
01838 {
01839
01840 while( *ptr && isspace( *ptr ) )
01841 {
01842 prev = ptr;
01843 ptr++;
01844 }
01845
01846 if( !*ptr )
01847 break;
01848
01849 if( depth == 0 && count == index )
01850 start = ptr;
01851
01852 if( *ptr == '{' )
01853 {
01854 depth++;
01855 prev = ptr;
01856 ptr++;
01857 }
01858 else if( *ptr == '}' )
01859 {
01860 depth--;
01861 if( depth == 0 )
01862 count++;
01863 if( start && depth == 0 )
01864 {
01865 end = ptr;
01866 break;
01867 }
01868 prev = ptr;
01869 ptr++;
01870 }
01871 else
01872 {
01873 while( *ptr &&
01874 (!isspace( *ptr ) || *prev == '\\') &&
01875 (*ptr != '}' || *prev == '\\') &&
01876 (*ptr != '{' || *prev == '\\') )
01877 {
01878 prev = ptr;
01879 ptr++;
01880 }
01881 if( depth == 0 )
01882 count++;
01883
01884 if( start && depth == 0 )
01885 {
01886 end = ptr-1;
01887 break;
01888 }
01889 }
01890 }
01891
01892 if( !start )
01893 return( (char *)NULL );
01894
01895 if( *start == '{' )
01896 {
01897 if( !end || *end != '}' )
01898 {
01899 bu_log( "Error in list (uneven braces?): %s\n", in );
01900 return( (char *)NULL );
01901 }
01902
01903
01904 start++;
01905 while( start < end && isspace( *start ) )
01906 start++;
01907
01908 end--;
01909 while( end > start && isspace( *end ) && *(end-1) != '\\' )
01910 end--;
01911
01912 if( start == end )
01913 return( (char *)NULL );
01914 }
01915
01916 len = end - start + 1;
01917 out = bu_malloc( len+1, "bu_list_elem:out" );
01918 strncpy( out, start, len );
01919 *(out + len) = '\0';
01920
01921 return( out );
01922 }
01923
01924
01925
01926
01927
01928
01929 int
01930 bu_tcl_list_length( const char *in )
01931 {
01932 int count=0;
01933 int depth=0;
01934 const char *ptr=in;
01935 const char *prev=NULL;
01936
01937 while( *ptr )
01938 {
01939
01940 while( *ptr && isspace( *ptr ) )
01941 {
01942 prev = ptr;
01943 ptr++;
01944 }
01945
01946 if( !*ptr )
01947 break;
01948
01949 if( *ptr == '{' )
01950 {
01951 if( depth == 0 )
01952 count++;
01953 depth++;
01954 prev = ptr;
01955 ptr++;
01956 }
01957 else if( *ptr == '}' )
01958 {
01959 depth--;
01960 prev = ptr;
01961 ptr++;
01962 }
01963 else
01964 {
01965 if( depth == 0 )
01966 count++;
01967
01968 while( *ptr &&
01969 (!isspace( *ptr ) || *prev == '\\') &&
01970 (*ptr != '}' || *prev == '\\') &&
01971 (*ptr != '{' || *prev == '\\') )
01972 {
01973 prev = ptr;
01974 ptr++;
01975 }
01976 }
01977 }
01978
01979 return( count );
01980 }
01981
01982
01983
01984
01985 int
01986 bu_key_val_to_vls(struct bu_vls *vls, char *params)
01987 {
01988 int len;
01989 int j;
01990
01991 len = bu_tcl_list_length( params );
01992
01993 if( len == 1 )
01994 {
01995 bu_vls_putc( vls, ' ' );
01996 bu_vls_strcat( vls, params );
01997 return( 0 );
01998 }
01999
02000 if( len%2 )
02001 {
02002 bu_log( "bu_key_val_to_vls: Error: shader parameters must be even numbered!!\n\t%s\n", params );
02003 return( 1 );
02004 }
02005
02006 for( j=0 ; j<len ; j += 2 )
02007 {
02008 char *keyword;
02009 char *value;
02010
02011 keyword = bu_list_elem( params, j );
02012 value = bu_list_elem( params, j+1 );
02013
02014 bu_vls_putc( vls, ' ' );
02015 bu_vls_strcat( vls, keyword );
02016 bu_vls_putc( vls, '=' );
02017 if( bu_tcl_list_length( value ) > 1 )
02018 {
02019 bu_vls_putc( vls, '"' );
02020 bu_vls_strcat( vls, value );
02021 bu_vls_putc( vls, '"' );
02022 }
02023 else
02024 bu_vls_strcat( vls, value );
02025
02026 bu_free( keyword, "bu_key_val_to_vls() keyword");
02027 bu_free( value, "bu_key_val_to_vls() value");
02028
02029 }
02030 return( 0 );
02031 }
02032
02033
02034
02035
02036 int
02037 bu_shader_to_key_eq(char *in, struct bu_vls *vls)
02038 {
02039 int len;
02040 int ret=0;
02041 char *shader;
02042 char *params;
02043
02044 BU_CK_VLS( vls );
02045
02046 len = bu_tcl_list_length( in );
02047
02048 if( len == 0 )
02049 return( 0 );
02050
02051 if( len == 1 )
02052 {
02053
02054 if( bu_vls_strlen( vls ) )
02055 bu_vls_putc( vls, ' ' );
02056 bu_vls_strcat( vls, in );
02057 return( 0 );
02058 }
02059
02060 if( len != 2 )
02061 {
02062 bu_log( "bu_shader_to_key_eq: Error: shader must have two elements (not %d)!!\n\t%s\n", len, in );
02063 return 1;
02064 }
02065
02066 shader = bu_list_elem( in, 0 );
02067 params = bu_list_elem( in, 1 );
02068
02069 if( !strcmp( shader, "envmap" ) )
02070 {
02071
02072
02073 if( bu_vls_strlen( vls ) )
02074 bu_vls_putc( vls, ' ' );
02075 bu_vls_strcat( vls, "envmap" );
02076
02077 bu_shader_to_key_eq( params, vls );
02078 }
02079 else if( !strcmp( shader, "stack" ) )
02080 {
02081
02082
02083 int i;
02084
02085 if( bu_vls_strlen( vls ) )
02086 bu_vls_putc( vls, ' ' );
02087 bu_vls_strcat( vls, "stack" );
02088
02089
02090 len = bu_tcl_list_length( params );
02091
02092
02093 for( i=0 ; i<len ; i++ )
02094 {
02095 char *shader1;
02096
02097
02098 shader1 = bu_list_elem( params, i );
02099
02100 if( i > 0 )
02101 bu_vls_putc( vls, ';' );
02102 bu_shader_to_key_eq( shader1, vls );
02103 bu_free( shader1, "shader1" );
02104 }
02105 }
02106 else
02107 {
02108 if( bu_vls_strlen( vls ) )
02109 bu_vls_putc( vls, ' ' );
02110 bu_vls_strcat( vls, shader );
02111 ret = bu_key_val_to_vls( vls, params );
02112 }
02113
02114 bu_free( shader, "shader" );
02115 bu_free( params, "params" );
02116
02117 return( ret );
02118 }
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133 int
02134 bu_fwrite_external( FILE *fp, const struct bu_external *ep )
02135 {
02136 size_t got;
02137
02138 BU_CK_EXTERNAL(ep);
02139
02140 if( (got = fwrite( ep->ext_buf, 1, ep->ext_nbytes, fp )) != ep->ext_nbytes ) {
02141 perror("fwrite");
02142 bu_log("bu_fwrite_external() attempted to write %ld, got %ld\n", (long)ep->ext_nbytes, (long)got );
02143 return -1;
02144 }
02145 return 0;
02146 }
02147
02148
02149
02150
02151 void
02152 bu_hexdump_external( FILE *fp, const struct bu_external *ep, const char *str)
02153 {
02154 const unsigned char *cp;
02155 const unsigned char *endp;
02156 int i, j, k;
02157
02158 BU_CK_EXTERNAL(ep);
02159
02160 fprintf(fp, "%s:\n", str);
02161 if( ep->ext_nbytes <= 0 ) fprintf(fp, "\tWarning: 0 length external buffer\n");
02162
02163 cp = ep->ext_buf;
02164 endp = cp + ep->ext_nbytes;
02165 for( i=0; i < ep->ext_nbytes; i += 16 ) {
02166 const unsigned char *sp = cp;
02167
02168 for( j=0; j < 4; j++ ) {
02169 for( k=0; k < 4; k++ ) {
02170 if( cp >= endp )
02171 fprintf(fp, " ");
02172 else
02173 fprintf(fp, "%2.2x ", *cp++ );
02174 }
02175 fprintf(fp, " ");
02176 }
02177 fprintf(fp, " |");
02178
02179 for( j=0; j < 16; j++,sp++ ) {
02180 if( sp >= endp ) break;
02181 if( isprint(*sp) )
02182 putc(*sp, fp);
02183 else
02184 putc('.', fp);
02185 }
02186
02187 fprintf(fp, "|\n");
02188 }
02189 }
02190
02191
02192
02193
02194 void
02195 bu_free_external( register struct bu_external *ep)
02196 {
02197 BU_CK_EXTERNAL(ep);
02198 if( ep->ext_buf ) {
02199 bu_free( ep->ext_buf, "bu_external ext_buf" );
02200 ep->ext_buf = GENPTR_NULL;
02201 }
02202 }
02203
02204
02205
02206
02207 void
02208 bu_copy_external(struct bu_external *op, const struct bu_external *ip)
02209 {
02210 BU_CK_EXTERNAL(ip);
02211 BU_INIT_EXTERNAL(op);
02212
02213 if( op == ip ) return;
02214
02215 op->ext_nbytes = ip->ext_nbytes;
02216 op->ext_buf = bu_malloc( ip->ext_nbytes, "bu_copy_external" );
02217 bcopy( ip->ext_buf, op->ext_buf, ip->ext_nbytes );
02218 }
02219
02220
02221
02222
02223
02224
02225
02226 char *
02227 bu_next_token( char *str )
02228 {
02229 char *ret;
02230
02231 ret = str;
02232 while( !isspace( *ret ) && *ret !='\0' )
02233 ret++;
02234 while( isspace( *ret ) )
02235 ret++;
02236
02237 return( ret );
02238 }
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248