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 #ifndef lint
00039 static const char libbu_bu_tcl_RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/bu_tcl.c,v 14.15 2006/08/31 05:50:24 lbutler Exp $ (ARL)";
00040 #endif
00041
00042 #include "common.h"
00043
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <math.h>
00047 #ifdef HAVE_STRING_H
00048 # include <string.h>
00049 #else
00050 # include <strings.h>
00051 #endif
00052 #include <ctype.h>
00053
00054 #include "tcl.h"
00055 #include "machine.h"
00056 #include "cmd.h"
00057 #include "vmath.h"
00058 #include "bn.h"
00059 #include "bu.h"
00060
00061
00062 extern int Cho_Init(Tcl_Interp *interp);
00063
00064 static struct bu_cmdtab bu_cmds[] = {
00065 {"bu_units_conversion", bu_tcl_units_conversion},
00066 {"bu_brlcad_data", bu_tcl_brlcad_data},
00067 {"bu_brlcad_path", bu_tcl_brlcad_path},
00068 {"bu_brlcad_root", bu_tcl_brlcad_root},
00069 {"bu_mem_barriercheck", bu_tcl_mem_barriercheck},
00070 {"bu_ck_malloc_ptr", bu_tcl_ck_malloc_ptr},
00071 {"bu_malloc_len_roundup", bu_tcl_malloc_len_roundup},
00072 {"bu_prmem", bu_tcl_prmem},
00073 {"bu_printb", bu_tcl_printb,},
00074 {"bu_get_all_keyword_values", bu_get_all_keyword_values},
00075 {"bu_get_value_by_keyword", bu_get_value_by_keyword},
00076 {"bu_rgb_to_hsv", bu_tcl_rgb_to_hsv},
00077 {"bu_hsv_to_rgb", bu_tcl_hsv_to_rgb},
00078 {"bu_key_eq_to_key_val", bu_tcl_key_eq_to_key_val},
00079 {"bu_shader_to_tcl_list", bu_tcl_shader_to_key_val},
00080 {"bu_key_val_to_key_eq", bu_tcl_key_val_to_key_eq},
00081 {"bu_shader_to_key_eq", bu_tcl_shader_to_key_eq},
00082 {(char *)NULL, (int (*)())0 }
00083 };
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void
00106 bu_badmagic_tcl(Tcl_Interp *interp,
00107 const long *ptr,
00108 unsigned long magic,
00109 const char *str,
00110 const char *file,
00111 int line)
00112 {
00113 char buf[256];
00114
00115 if (!(ptr)) {
00116 sprintf(buf, "ERROR: NULL %s pointer in TCL interface, file %s, line %d\n",
00117 str, file, line);
00118 Tcl_AppendResult(interp, buf, NULL);
00119 return;
00120 }
00121 if (*((long *)(ptr)) != (magic)) {
00122 sprintf(buf, "ERROR: bad pointer in TCL interface x%lx: s/b %s(x%lx), was %s(x%lx), file %s, line %d\n",
00123 (long)ptr,
00124 str, magic,
00125 bu_identify_magic( *(ptr) ), *(ptr),
00126 file, line);
00127 Tcl_AppendResult(interp, buf, NULL);
00128 return;
00129 }
00130 Tcl_AppendResult(interp, "bu_badmagic_tcl() mysterious error condition, ", str, " pointer, ", file, "\n", NULL);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void
00156 bu_structparse_get_terse_form(Tcl_Interp *interp,
00157 const struct bu_structparse *sp)
00158 {
00159 struct bu_vls str;
00160 int i;
00161
00162 bu_vls_init(&str);
00163
00164 while (sp->sp_name != NULL) {
00165 Tcl_AppendElement(interp, sp->sp_name);
00166 bu_vls_trunc(&str, 0);
00167
00168 if (strcmp(sp->sp_fmt, "%c") == 0 ||
00169 strcmp(sp->sp_fmt, "%s") == 0 ||
00170 strcmp(sp->sp_fmt, "%S") == 0) {
00171 if (sp->sp_count > 1) {
00172
00173 bu_vls_printf(&str, "%%%lds", sp->sp_count);
00174 } else {
00175
00176 bu_vls_printf(&str, "%%c");
00177 }
00178 } else {
00179
00180 bu_vls_printf(&str, "%s", sp->sp_fmt);
00181 for (i = 1; i < sp->sp_count; i++)
00182 bu_vls_printf(&str, " %s", sp->sp_fmt);
00183 }
00184 Tcl_AppendElement(interp, bu_vls_addr(&str));
00185 ++sp;
00186 }
00187 bu_vls_free(&str);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 #define BU_SP_SKIP_SEP(_cp) \
00200 { while( *(_cp) && (*(_cp) == ' ' || *(_cp) == '\n' || \
00201 *(_cp) == '\t' || *(_cp) == '{' ) ) ++(_cp); }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 int
00226 bu_structparse_argv(Tcl_Interp *interp,
00227 int argc,
00228 char **argv,
00229 const struct bu_structparse *desc,
00230 char *base)
00231 {
00232 register char *cp, *loc;
00233 register const struct bu_structparse *sdp;
00234 register int j;
00235 register int ii;
00236 struct bu_vls str;
00237
00238 if (desc == (struct bu_structparse *)NULL) {
00239 bu_log("bu_structparse_argv: NULL desc pointer\n");
00240 Tcl_AppendResult(interp, "NULL desc pointer", (char *)NULL);
00241 return TCL_ERROR;
00242 }
00243
00244
00245
00246 bu_vls_init(&str);
00247 while (argc > 0) {
00248
00249 for (sdp = desc; sdp->sp_name != NULL; sdp++) {
00250 if (strcmp(sdp->sp_name, *argv) != 0)
00251 continue;
00252
00253
00254
00255
00256
00257 #if CRAY && !__STDC__
00258 loc = (char *)(base+((int)sdp->sp_offset*sizeof(int)));
00259 #else
00260 loc = (char *)(base+((int)sdp->sp_offset));
00261 #endif
00262 if (sdp->sp_fmt[0] != '%') {
00263 bu_log("bu_structparse_argv: unknown format\n");
00264 bu_vls_free(&str);
00265 Tcl_AppendResult(interp, "unknown format",
00266 (char *)NULL);
00267 return TCL_ERROR;
00268 }
00269
00270 --argc;
00271 ++argv;
00272
00273 switch (sdp->sp_fmt[1]) {
00274 case 'c':
00275 case 's':
00276
00277
00278
00279 if (argc < 1) {
00280 bu_vls_trunc(&str, 0);
00281 bu_vls_printf(&str,
00282 "not enough values for \"%s\" argument: should be %ld",
00283 sdp->sp_name,
00284 sdp->sp_count);
00285 Tcl_AppendResult(interp,
00286 bu_vls_addr(&str),
00287 (char *)NULL);
00288 bu_vls_free(&str);
00289 return TCL_ERROR;
00290 }
00291 for (ii = j = 0;
00292 j < sdp->sp_count && argv[0][ii] != '\0';
00293 loc[j++] = argv[0][ii++])
00294 ;
00295 if (ii < sdp->sp_count)
00296 loc[ii] = '\0';
00297 if (sdp->sp_count > 1) {
00298 loc[sdp->sp_count-1] = '\0';
00299 Tcl_AppendResult(interp,
00300 sdp->sp_name, " ",
00301 loc, " ",
00302 (char *)NULL);
00303 } else {
00304 bu_vls_trunc(&str, 0);
00305 bu_vls_printf(&str, "%s %c ",
00306 sdp->sp_name, *loc);
00307 Tcl_AppendResult(interp,
00308 bu_vls_addr(&str),
00309 (char *)NULL);
00310 }
00311 break;
00312 case 'S': {
00313 struct bu_vls *vls = (struct bu_vls *)loc;
00314 bu_vls_init_if_uninit( vls );
00315 bu_vls_strcpy(vls, *argv);
00316 break;
00317 }
00318 case 'i':
00319 #if 0
00320 bu_log(
00321 "Error: %%i not implemented. Contact developers.\n" );
00322 Tcl_AppendResult( interp,
00323 "%%i not implemented yet",
00324 (char *)NULL );
00325 bu_vls_free( &str );
00326 return TCL_ERROR;
00327 #else
00328 {
00329 register short *sh = (short *)loc;
00330 register int tmpi;
00331 register char const *cp;
00332
00333 if( argc < 1 ) {
00334 bu_vls_trunc( &str, 0 );
00335 bu_vls_printf( &str,
00336 "not enough values for \"%s\" argument: should have %ld",
00337 sdp->sp_name,
00338 sdp->sp_count);
00339 Tcl_AppendResult( interp,
00340 bu_vls_addr(&str),
00341 (char *)NULL );
00342 bu_vls_free( &str );
00343 return TCL_ERROR;
00344 }
00345
00346 Tcl_AppendResult( interp, sdp->sp_name, " ",
00347 (char *)NULL );
00348
00349
00350 if( argv[0][0] == '!' ) {
00351 *sh = *sh ? 0 : 1;
00352 bu_vls_trunc( &str, 0 );
00353 bu_vls_printf( &str, "%hd ", *sh );
00354 Tcl_AppendResult( interp,
00355 bu_vls_addr(&str),
00356 (char *)NULL );
00357 break;
00358 }
00359
00360 cp = *argv;
00361 for( ii = 0; ii < sdp->sp_count; ++ii ) {
00362 if( *cp == '\0' ) {
00363 bu_vls_trunc( &str, 0 );
00364 bu_vls_printf( &str,
00365 "not enough values for \"%s\" argument: should have %ld",
00366 sdp->sp_name,
00367 sdp->sp_count );
00368 Tcl_AppendResult( interp,
00369 bu_vls_addr(&str),
00370 (char *)NULL );
00371 bu_vls_free( &str );
00372 return TCL_ERROR;
00373 }
00374
00375 BU_SP_SKIP_SEP(cp);
00376 tmpi = atoi( cp );
00377 if( *cp && (*cp == '+' || *cp == '-') )
00378 cp++;
00379 while( *cp && isdigit(*cp) )
00380 cp++;
00381
00382
00383
00384
00385 if( cp == *argv ||
00386 (cp == *argv+1 &&
00387 (argv[0][0] == '+' ||
00388 argv[0][0] == '-')) ) {
00389 bu_vls_trunc( &str, 0 );
00390 bu_vls_printf( &str,
00391 "value \"%s\" to argument %s isn't an integer",
00392 argv[0],
00393 sdp->sp_name );
00394 Tcl_AppendResult( interp,
00395 bu_vls_addr(&str),
00396 (char *)NULL );
00397 bu_vls_free( &str );
00398 return TCL_ERROR;
00399 } else {
00400 *(sh++) = tmpi;
00401 }
00402 BU_SP_SKIP_SEP(cp);
00403 }
00404 Tcl_AppendResult( interp,
00405 sdp->sp_count > 1 ? "{" : "",
00406 argv[0],
00407 sdp->sp_count > 1 ? "}" : "",
00408 " ", (char *)NULL);
00409 break; }
00410
00411 #endif
00412 case 'd': {
00413 register int *ip = (int *)loc;
00414 register int tmpi;
00415 register char const *cp;
00416
00417 if( argc < 1 ) {
00418 bu_vls_trunc( &str, 0 );
00419 bu_vls_printf( &str,
00420 "not enough values for \"%s\" argument: should have %ld",
00421 sdp->sp_name,
00422 sdp->sp_count);
00423 Tcl_AppendResult( interp,
00424 bu_vls_addr(&str),
00425 (char *)NULL );
00426 bu_vls_free( &str );
00427 return TCL_ERROR;
00428 }
00429
00430 Tcl_AppendResult( interp, sdp->sp_name, " ",
00431 (char *)NULL );
00432
00433
00434 if( argv[0][0] == '!' ) {
00435 *ip = *ip ? 0 : 1;
00436 bu_vls_trunc( &str, 0 );
00437 bu_vls_printf( &str, "%d ", *ip );
00438 Tcl_AppendResult( interp,
00439 bu_vls_addr(&str),
00440 (char *)NULL );
00441 break;
00442 }
00443
00444 cp = *argv;
00445 for( ii = 0; ii < sdp->sp_count; ++ii ) {
00446 if( *cp == '\0' ) {
00447 bu_vls_trunc( &str, 0 );
00448 bu_vls_printf( &str,
00449 "not enough values for \"%s\" argument: should have %ld",
00450 sdp->sp_name,
00451 sdp->sp_count );
00452 Tcl_AppendResult( interp,
00453 bu_vls_addr(&str),
00454 (char *)NULL );
00455 bu_vls_free( &str );
00456 return TCL_ERROR;
00457 }
00458
00459 BU_SP_SKIP_SEP(cp);
00460 tmpi = atoi( cp );
00461 if( *cp && (*cp == '+' || *cp == '-') )
00462 cp++;
00463 while( *cp && isdigit(*cp) )
00464 cp++;
00465
00466
00467
00468
00469 if( cp == *argv ||
00470 (cp == *argv+1 &&
00471 (argv[0][0] == '+' ||
00472 argv[0][0] == '-')) ) {
00473 bu_vls_trunc( &str, 0 );
00474 bu_vls_printf( &str,
00475 "value \"%s\" to argument %s isn't an integer",
00476 argv[0],
00477 sdp->sp_name );
00478 Tcl_AppendResult( interp,
00479 bu_vls_addr(&str),
00480 (char *)NULL );
00481 bu_vls_free( &str );
00482 return TCL_ERROR;
00483 } else {
00484 *(ip++) = tmpi;
00485 }
00486 BU_SP_SKIP_SEP(cp);
00487 }
00488 Tcl_AppendResult( interp,
00489 sdp->sp_count > 1 ? "{" : "",
00490 argv[0],
00491 sdp->sp_count > 1 ? "}" : "",
00492 " ", (char *)NULL);
00493 break; }
00494 case 'f': {
00495 int dot_seen;
00496 double tmp_double;
00497 register double *dp;
00498 char *numstart;
00499
00500 dp = (double *)loc;
00501
00502 if( argc < 1 ) {
00503 bu_vls_trunc( &str, 0 );
00504 bu_vls_printf( &str,
00505 "not enough values for \"%s\" argument: should have %ld, only %d given",
00506 sdp->sp_name,
00507 sdp->sp_count, argc );
00508 Tcl_AppendResult( interp,
00509 bu_vls_addr(&str),
00510 (char *)NULL );
00511 bu_vls_free( &str );
00512 return TCL_ERROR;
00513 }
00514
00515 Tcl_AppendResult( interp, sdp->sp_name, " ",
00516 (char *)NULL );
00517
00518 cp = *argv;
00519 for( ii = 0; ii < sdp->sp_count; ii++ ) {
00520 if( *cp == '\0' ) {
00521 bu_vls_trunc( &str, 0 );
00522 bu_vls_printf( &str,
00523 "not enough values for \"%s\" argument: should have %ld, only %d given",
00524 sdp->sp_name,
00525 sdp->sp_count,
00526 ii );
00527 Tcl_AppendResult( interp,
00528 bu_vls_addr(&str),
00529 (char *)NULL );
00530 bu_vls_free( &str );
00531 return TCL_ERROR;
00532 }
00533
00534 BU_SP_SKIP_SEP(cp);
00535 numstart = cp;
00536 if( *cp == '-' || *cp == '+' ) cp++;
00537
00538
00539 dot_seen = 0;
00540 for( ; *cp ; cp++ ) {
00541 if( *cp == '.' && !dot_seen ) {
00542 dot_seen = 1;
00543 continue;
00544 }
00545 if( !isdigit(*cp) )
00546 break;
00547 }
00548
00549
00550
00551 if( cp == (numstart + dot_seen) ) {
00552 bu_vls_trunc( &str, 0 );
00553 bu_vls_printf( &str,
00554 "value \"%s\" to argument %s isn't a float",
00555 argv[0],
00556 sdp->sp_name );
00557 Tcl_AppendResult( interp,
00558 bu_vls_addr(&str),
00559 (char *)NULL );
00560 bu_vls_free( &str );
00561 return TCL_ERROR;
00562 }
00563
00564
00565
00566 if( *cp == 'E' || *cp == 'e' ) {
00567 cp++;
00568
00569
00570 if (*cp == '+' || *cp == '-')
00571 cp++;
00572 while( isdigit(*cp) )
00573 cp++;
00574 }
00575
00576 bu_vls_trunc( &str, 0 );
00577 bu_vls_strcpy( &str, numstart );
00578 bu_vls_trunc( &str, cp-numstart );
00579 if( sscanf(bu_vls_addr(&str),
00580 "%lf", &tmp_double) != 1 ) {
00581 bu_vls_trunc( &str, 0 );
00582 bu_vls_printf( &str,
00583 "value \"%s\" to argument %s isn't a float",
00584 numstart,
00585 sdp->sp_name );
00586 Tcl_AppendResult( interp,
00587 bu_vls_addr(&str),
00588 (char *)NULL );
00589 bu_vls_free( &str );
00590 return TCL_ERROR;
00591 }
00592
00593 *dp++ = tmp_double;
00594
00595 BU_SP_SKIP_SEP(cp);
00596 }
00597 Tcl_AppendResult( interp,
00598 sdp->sp_count > 1 ? "{" : "",
00599 argv[0],
00600 sdp->sp_count > 1 ? "}" : "",
00601 " ", (char *)NULL );
00602 break; }
00603 default: {
00604 struct bu_vls vls;
00605
00606 bu_vls_init(&vls);
00607 bu_vls_printf(&vls,
00608 "%s line:%d Parse error, unknown format: '%s' for element \"%s\"",
00609 __FILE__, __LINE__, sdp->sp_fmt,
00610 sdp->sp_name);
00611
00612 Tcl_AppendResult( interp, bu_vls_addr(&vls),
00613 (char *)NULL );
00614
00615 bu_vls_free( &vls );
00616 return TCL_ERROR;
00617 }
00618 }
00619
00620 if( sdp->sp_hook ) {
00621 sdp->sp_hook( sdp, sdp->sp_name, base, *argv);
00622
00623 }
00624 --argc;
00625 ++argv;
00626
00627
00628 break;
00629 }
00630
00631
00632 if( sdp->sp_name == NULL ) {
00633 bu_vls_trunc( &str, 0 );
00634 bu_vls_printf( &str, "invalid attribute %s\n", argv[0] );
00635 Tcl_AppendResult( interp, bu_vls_addr(&str),
00636 (char *)NULL );
00637 bu_vls_free( &str );
00638 return TCL_ERROR;
00639 }
00640 }
00641 return TCL_OK;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 int
00659 bu_tcl_mem_barriercheck(ClientData clientData,
00660 Tcl_Interp *interp,
00661 int argc,
00662 char **argv)
00663 {
00664 int ret;
00665
00666 ret = bu_mem_barriercheck();
00667 if (ret < 0) {
00668 Tcl_AppendResult(interp, "bu_mem_barriercheck() failed\n", NULL);
00669 return TCL_ERROR;
00670 }
00671 return TCL_OK;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 int
00688 bu_tcl_ck_malloc_ptr(ClientData clientData,
00689 Tcl_Interp *interp,
00690 int argc,
00691 char **argv)
00692 {
00693 if( argc != 3 ) {
00694 Tcl_AppendResult( interp, "Usage: bu_ck_malloc_ptr ascii-ptr description\n");
00695 return TCL_ERROR;
00696 }
00697 bu_ck_malloc_ptr( (genptr_t)atol(argv[1]), argv[2] );
00698 return TCL_OK;
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 int
00718 bu_tcl_malloc_len_roundup(ClientData clientData,
00719 Tcl_Interp *interp,
00720 int argc,
00721 char **argv)
00722 {
00723 int val;
00724
00725 if( argc != 2 ) {
00726 Tcl_AppendResult(interp, "Usage: bu_malloc_len_roundup nbytes\n", NULL);
00727 return TCL_ERROR;
00728 }
00729 val = bu_malloc_len_roundup(atoi(argv[1]));
00730 sprintf(interp->result, "%d", val);
00731 return TCL_OK;
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 int
00753 bu_tcl_prmem(ClientData clientData,
00754 Tcl_Interp *interp,
00755 int argc,
00756 char **argv)
00757 {
00758 if (argc != 2) {
00759 Tcl_AppendResult(interp, "Usage: bu_prmem title\n");
00760 return TCL_ERROR;
00761 }
00762 bu_prmem(argv[1]);
00763 return TCL_OK;
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 int
00783 bu_tcl_printb(ClientData clientData,
00784 Tcl_Interp *interp,
00785 int argc,
00786 char **argv)
00787 {
00788 struct bu_vls str;
00789
00790 if (argc != 4) {
00791 Tcl_AppendResult(interp, "Usage: bu_printb title integer-to-format bit-format-string\n", NULL);
00792 return TCL_ERROR;
00793 }
00794 bu_vls_init(&str);
00795 bu_vls_printb(&str, argv[1], atoi(argv[2]), argv[3]);
00796 Tcl_SetResult(interp, bu_vls_addr(&str), TCL_VOLATILE);
00797 bu_vls_free(&str);
00798 return TCL_OK;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 int
00833 bu_get_value_by_keyword(ClientData clientData,
00834 Tcl_Interp *interp,
00835 int argc,
00836 char **argv)
00837 {
00838 int listc;
00839 char **listv;
00840 register char *iwant;
00841 char **tofree = (char **)NULL;
00842 int i;
00843
00844 if( argc < 3 ) {
00845 char buf[32];
00846 sprintf(buf, "%d", argc);
00847 Tcl_AppendResult( interp,
00848 "bu_get_value_by_keyword: wrong # of args (", buf, ").\n",
00849 "Usage: bu_get_value_by_keyword iwant {list}\n",
00850 "Usage: bu_get_value_by_keyword iwant key1 val1 key2 val2 ... keyN valN\n",
00851 (char *)NULL );
00852 return TCL_ERROR;
00853 }
00854
00855 iwant = argv[1];
00856
00857 if( argc == 3 ) {
00858 if( Tcl_SplitList( interp, argv[2], &listc, (const char ***)&listv ) != TCL_OK ) {
00859 Tcl_AppendResult( interp,
00860 "bu_get_value_by_keyword: iwant='", iwant,
00861 "', unable to split '",
00862 argv[2], "'\n", (char *)NULL );
00863 return TCL_ERROR;
00864 }
00865 tofree = listv;
00866 } else {
00867
00868 listc = argc - 2;
00869 listv = argv + 2;
00870 }
00871
00872 if( (listc & 1) != 0 ) {
00873 char buf[32];
00874 sprintf(buf, "%d", listc);
00875 Tcl_AppendResult( interp,
00876 "bu_get_value_by_keyword: odd # of items in list (", buf, ").\n",
00877 (char *)NULL );
00878 if(tofree) free( (char *)tofree );
00879 return TCL_ERROR;
00880 }
00881
00882 for( i=0; i < listc; i += 2 ) {
00883 if( strcmp( iwant, listv[i] ) == 0 ) {
00884
00885 if( listv[i+1][0] == '{' ) {
00886 struct bu_vls str;
00887 bu_vls_init( &str );
00888
00889 bu_vls_strcat( &str, &listv[i+1][1] );
00890
00891 bu_vls_trunc( &str, -1 );
00892 Tcl_AppendResult( interp,
00893 bu_vls_addr(&str), (char *)NULL );
00894 bu_vls_free( &str );
00895 } else {
00896 Tcl_AppendResult( interp, listv[i+1], (char *)NULL );
00897 }
00898 if(tofree) free( (char *)tofree );
00899 return TCL_OK;
00900 }
00901 }
00902
00903
00904 Tcl_AppendResult( interp, "bu_get_value_by_keyword: keyword '",
00905 iwant, "' not found in list\n", (char *)NULL );
00906 if(tofree) free( (char *)tofree );
00907 return TCL_ERROR;
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 int
00958 bu_get_all_keyword_values(ClientData clientData,
00959 Tcl_Interp *interp,
00960 int argc,
00961 char **argv)
00962 {
00963 struct bu_vls variable;
00964 int listc;
00965 char **listv;
00966 char **tofree = (char **)NULL;
00967 int i;
00968
00969 if( argc < 2 ) {
00970 char buf[32];
00971 sprintf(buf, "%d", argc);
00972 Tcl_AppendResult( interp,
00973 "bu_get_all_keyword_values: wrong # of args (", buf, ").\n",
00974 "Usage: bu_get_all_keyword_values {list}\n",
00975 "Usage: bu_get_all_keyword_values key1 val1 key2 val2 ... keyN valN\n",
00976 (char *)NULL );
00977 return TCL_ERROR;
00978 }
00979
00980 if( argc == 2 ) {
00981 if( Tcl_SplitList( interp, argv[1], &listc, (const char ***)&listv ) != TCL_OK ) {
00982 Tcl_AppendResult( interp,
00983 "bu_get_all_keyword_values: unable to split '",
00984 argv[1], "'\n", (char *)NULL );
00985 return TCL_ERROR;
00986 }
00987 tofree = listv;
00988 } else {
00989
00990 listc = argc - 1;
00991 listv = argv + 1;
00992 }
00993
00994 if( (listc & 1) != 0 ) {
00995 char buf[32];
00996 sprintf(buf, "%d", listc);
00997 Tcl_AppendResult( interp,
00998 "bu_get_all_keyword_values: odd # of items in list (",
00999 buf, "), aborting.\n",
01000 (char *)NULL );
01001 if(tofree) free( (char *)tofree );
01002 return TCL_ERROR;
01003 }
01004
01005
01006
01007 bu_vls_init( &variable );
01008 for( i=0; i < listc; i += 2 ) {
01009 bu_vls_strcpy( &variable, "key_" );
01010 bu_vls_strcat( &variable, listv[i] );
01011
01012 if( listv[i+1][0] == '{' ) {
01013 struct bu_vls str;
01014 bu_vls_init( &str );
01015
01016 bu_vls_strcat( &str, &listv[i+1][1] );
01017
01018 bu_vls_trunc( &str, -1 );
01019 Tcl_SetVar( interp, bu_vls_addr(&variable),
01020 bu_vls_addr(&str), 0);
01021 bu_vls_free( &str );
01022 } else {
01023 Tcl_SetVar( interp, bu_vls_addr(&variable),
01024 listv[i+1], 0 );
01025 }
01026 Tcl_AppendResult( interp, bu_vls_addr(&variable),
01027 " ", (char *)NULL );
01028 bu_vls_trunc( &variable, 0 );
01029 }
01030
01031
01032 bu_vls_free( &variable );
01033 if(tofree) free( (char *)tofree );
01034 return TCL_OK;
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 int
01054 bu_tcl_rgb_to_hsv(ClientData clientData,
01055 Tcl_Interp *interp,
01056 int argc,
01057 char **argv)
01058 {
01059 int rgb_int[3];
01060 unsigned char rgb[3];
01061 fastf_t hsv[3];
01062 struct bu_vls result;
01063
01064 bu_vls_init(&result);
01065 if( argc != 4 ) {
01066 Tcl_AppendResult( interp, "Usage: bu_rgb_to_hsv R G B\n",
01067 (char *)NULL );
01068 return TCL_ERROR;
01069 }
01070 if (( Tcl_GetInt( interp, argv[1], &rgb_int[0] ) != TCL_OK )
01071 || ( Tcl_GetInt( interp, argv[2], &rgb_int[1] ) != TCL_OK )
01072 || ( Tcl_GetInt( interp, argv[3], &rgb_int[2] ) != TCL_OK )
01073 || ( rgb_int[0] < 0 ) || ( rgb_int[0] > 255 )
01074 || ( rgb_int[1] < 0 ) || ( rgb_int[1] > 255 )
01075 || ( rgb_int[2] < 0 ) || ( rgb_int[2] > 255 )) {
01076 bu_vls_printf(&result, "bu_rgb_to_hsv: Bad RGB (%s, %s, %s)\n",
01077 argv[1], argv[2], argv[3]);
01078 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
01079 bu_vls_free(&result);
01080 return TCL_ERROR;
01081 }
01082 rgb[0] = rgb_int[0];
01083 rgb[1] = rgb_int[1];
01084 rgb[2] = rgb_int[2];
01085
01086 bu_rgb_to_hsv( rgb, hsv );
01087 bu_vls_printf(&result, "%g %g %g", V3ARGS(hsv));
01088 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
01089 bu_vls_free(&result);
01090 return TCL_OK;
01091
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 int
01112 bu_tcl_hsv_to_rgb(ClientData clientData,
01113 Tcl_Interp *interp,
01114 int argc,
01115 char **argv)
01116 {
01117 fastf_t hsv[3];
01118 unsigned char rgb[3];
01119 struct bu_vls result;
01120
01121 if( argc != 4 ) {
01122 Tcl_AppendResult( interp, "Usage: bu_hsv_to_rgb H S V\n",
01123 (char *)NULL );
01124 return TCL_ERROR;
01125 }
01126 bu_vls_init(&result);
01127 if (( Tcl_GetDouble( interp, argv[1], &hsv[0] ) != TCL_OK )
01128 || ( Tcl_GetDouble( interp, argv[2], &hsv[1] ) != TCL_OK )
01129 || ( Tcl_GetDouble( interp, argv[3], &hsv[2] ) != TCL_OK )
01130 || ( bu_hsv_to_rgb( hsv, rgb ) == 0) ) {
01131 bu_vls_printf(&result, "bu_hsv_to_rgb: Bad HSV (%s, %s, %s)\n",
01132 argv[1], argv[2], argv[3]);
01133 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
01134 bu_vls_free(&result);
01135 return TCL_ERROR;
01136 }
01137
01138 bu_vls_printf(&result, "%d %d %d", V3ARGS(rgb));
01139 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
01140 bu_vls_free(&result);
01141 return TCL_OK;
01142
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 int
01162 bu_tcl_key_eq_to_key_val(ClientData clientData,
01163 Tcl_Interp *interp,
01164 int argc,
01165 char **argv)
01166 {
01167 struct bu_vls vls;
01168 char *next;
01169 int i=0;
01170
01171 bu_vls_init( &vls );
01172
01173 while( ++i < argc )
01174 {
01175 if( bu_key_eq_to_key_val( argv[i], &next, &vls ) )
01176 {
01177 bu_vls_free( &vls );
01178 return TCL_ERROR;
01179 }
01180
01181 if( i < argc - 1 )
01182 Tcl_AppendResult(interp, bu_vls_addr( &vls ) , " ", NULL );
01183 else
01184 Tcl_AppendResult(interp, bu_vls_addr( &vls ), NULL );
01185
01186 bu_vls_trunc( &vls, 0 );
01187 }
01188
01189 bu_vls_free( &vls );
01190 return TCL_OK;
01191
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 int
01212 bu_tcl_shader_to_key_val(ClientData clientData,
01213 Tcl_Interp *interp,
01214 int argc,
01215 char **argv)
01216 {
01217 struct bu_vls vls;
01218
01219 bu_vls_init( &vls );
01220
01221 if( bu_shader_to_tcl_list( argv[1], &vls ) )
01222 {
01223 bu_vls_free( &vls );
01224 return( TCL_ERROR );
01225 }
01226
01227 Tcl_AppendResult(interp, bu_vls_addr( &vls ), NULL );
01228
01229 bu_vls_free( &vls );
01230
01231 return TCL_OK;
01232
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 int
01253 bu_tcl_key_val_to_key_eq(ClientData clientData,
01254 Tcl_Interp *interp,
01255 int argc,
01256 char **argv)
01257 {
01258 int i=0;
01259
01260 for( i=1 ; i<argc ; i += 2 )
01261 {
01262 if( i+1 < argc-1 )
01263 Tcl_AppendResult(interp, argv[i], "=", argv[i+1], " ", NULL );
01264 else
01265 Tcl_AppendResult(interp, argv[i], "=", argv[i+1], NULL );
01266
01267 }
01268 return TCL_OK;
01269
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 int
01290 bu_tcl_shader_to_key_eq(ClientData clientData,
01291 Tcl_Interp *interp,
01292 int argc,
01293 char **argv)
01294 {
01295 struct bu_vls vls;
01296
01297
01298 bu_vls_init( &vls );
01299
01300 if( bu_shader_to_key_eq( argv[1], &vls ) )
01301 {
01302 bu_vls_free( &vls );
01303 return TCL_ERROR;
01304 }
01305
01306 Tcl_AppendResult(interp, bu_vls_addr( &vls ), NULL );
01307
01308 bu_vls_free( &vls );
01309
01310 return TCL_OK;
01311 }
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 int
01331 bu_tcl_brlcad_root(ClientData clientData,
01332 Tcl_Interp *interp,
01333 int argc,
01334 char **argv)
01335 {
01336 if (argc != 2) {
01337 Tcl_AppendResult(interp, "Usage: bu_brlcad_root subdir\n",
01338 (char *)NULL);
01339 return TCL_ERROR;
01340 }
01341 Tcl_AppendResult(interp, bu_brlcad_root(argv[1], 0), NULL);
01342 return TCL_OK;
01343 }
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 int
01363 bu_tcl_brlcad_data(ClientData clientData,
01364 Tcl_Interp *interp,
01365 int argc,
01366 char **argv)
01367 {
01368 if (argc != 2) {
01369 Tcl_AppendResult(interp, "Usage: bu_brlcad_data subdir\n",
01370 (char *)NULL);
01371 return TCL_ERROR;
01372 }
01373 Tcl_AppendResult(interp, bu_brlcad_data(argv[1], 0), NULL);
01374 return TCL_OK;
01375 }
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 int
01395 bu_tcl_brlcad_path(ClientData clientData,
01396 Tcl_Interp *interp,
01397 int argc,
01398 char **argv)
01399 {
01400 if (argc != 2) {
01401 Tcl_AppendResult(interp, "Usage: bu_brlcad_path subdir\n",
01402 (char *)NULL);
01403 return TCL_ERROR;
01404 }
01405 Tcl_AppendResult(interp, bu_brlcad_path(argv[1], 0), NULL);
01406 return TCL_OK;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 int
01427 bu_tcl_units_conversion(ClientData clientData,
01428 Tcl_Interp *interp,
01429 int argc,
01430 char **argv)
01431 {
01432 double conv_factor;
01433 struct bu_vls result;
01434
01435 if (argc != 2) {
01436 Tcl_AppendResult(interp, "Usage: bu_units_conversion units_string\n",
01437 (char *)NULL);
01438 return TCL_ERROR;
01439 }
01440
01441 conv_factor = bu_units_conversion(argv[1]);
01442 if (conv_factor == 0.0) {
01443 Tcl_AppendResult(interp, "ERROR: bu_units_conversion: Unrecognized units string: ",
01444 argv[1], "\n", (char *)NULL);
01445 return TCL_ERROR;
01446 }
01447
01448 bu_vls_init(&result);
01449 bu_vls_printf(&result, "%.12e", conv_factor);
01450 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
01451 bu_vls_free(&result);
01452 return TCL_OK;
01453 }
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 void
01471 bu_tcl_setup(Tcl_Interp *interp)
01472 {
01473 bu_register_cmds(interp, bu_cmds);
01474
01475 Tcl_SetVar(interp, "bu_version", (char *)bu_version+5, TCL_GLOBAL_ONLY);
01476 Tcl_SetVar(interp, "BU_DEBUG_FORMAT", BU_DEBUG_FORMAT, TCL_GLOBAL_ONLY);
01477 Tcl_LinkVar(interp, "bu_debug", (char *)&bu_debug, TCL_LINK_INT );
01478
01479
01480 Cho_Init(interp);
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498 int
01499 #ifdef BRLCAD_DEBUG
01500 Bu_d_Init(Tcl_Interp *interp)
01501 #else
01502 Bu_Init(Tcl_Interp *interp)
01503 #endif
01504 {
01505 bu_tcl_setup(interp);
01506 #if 0
01507 bu_hook_list_init(&bu_log_hook_list);
01508 bu_hook_list_init(&bu_bomb_hook_list);
01509 #endif
01510 return TCL_OK;
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521