46 #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
49 #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
55 #define dbug_enter( a ) \
56 fprintf( stderr, "%s: Entered %s\n", __FILE__, a );
59 #define dbug_enter( a )
73 int level,
int *offset,
int nargs,
const char** args );
84 Tcl_Interp *
interp,
char *name1,
char *name2,
int flags );
94 MatrixPut_f( ClientData clientData, Tcl_Interp*
interp,
int index,
const char *
string );
97 MatrixGet_f( ClientData clientData, Tcl_Interp*
interp,
int index,
char *
string );
100 MatrixPut_i( ClientData clientData, Tcl_Interp*
interp,
int index,
const char *
string );
103 MatrixGet_i( ClientData clientData, Tcl_Interp*
interp,
int index,
char *
string );
126 int i, j,
new, index, persist = 0, initializer = 0;
132 size_t concatenated_argv_len;
133 char *concatenated_argv;
134 const char *const_concatenated_argv;
140 Tcl_AppendResult( interp,
"wrong # args: should be \"", argv[0],
141 " ?-persist? var type dim1 ?dim2? ?dim3? ...\"", (
char *) NULL );
150 Tcl_InitHashTable( &
matTable, TCL_STRING_KEYS );
155 for ( i = 1; i <
argc; i++ )
158 argv0_length = strlen( argv[i] );
162 if ( ( c ==
'-' ) && ( strncmp( argv[i],
"-persist", argv0_length ) == 0 ) )
166 for ( j = i; j <
argc; j++ )
167 argv[j] = argv[j + 1];
175 matPtr->
fdata = NULL;
176 matPtr->
idata = NULL;
195 if ( Tcl_GetCommandInfo( interp, argv[0], &infoPtr ) )
197 Tcl_AppendResult( interp,
"Matrix operator \"", argv[0],
198 "\" already in use", (
char *) NULL );
199 free( (
void *) matPtr );
203 if ( Tcl_GetVar( interp, argv[0], 0 ) != NULL )
205 Tcl_AppendResult( interp,
"Illegal name for Matrix operator \"",
206 argv[0],
"\": local variable of same name is active",
208 free( (
void *) matPtr );
212 matPtr->
name = (
char *) malloc( strlen( argv[0] ) + 1 );
213 strcpy( matPtr->
name, argv[0] );
219 argv0_length = strlen( argv[0] );
221 if ( ( c ==
'f' ) && ( strncmp( argv[0],
"float", argv0_length ) == 0 ) )
227 else if ( ( c ==
'i' ) && ( strncmp( argv[0],
"int", argv0_length ) == 0 ) )
235 Tcl_AppendResult( interp,
"Matrix type \"", argv[0],
236 "\" not supported, should be \"float\" or \"int\"",
246 for (; argc > 0; argc--, argv++ )
250 if ( strcmp( argv[0],
"=" ) == 0 )
260 if ( matPtr->
dim > MAX_ARRAY_DIM )
262 Tcl_AppendResult( interp,
263 "too many dimensions specified for Matrix operator \"",
264 matPtr->
name,
"\"", (
char *) NULL );
272 index = matPtr->
dim - 1;
273 matPtr->
n[index] =
MAX( 0, atoi( argv[0] ) );
274 matPtr->
len *= matPtr->
n[index];
277 if ( matPtr->
dim < 1 )
279 Tcl_AppendResult( interp,
280 "insufficient dimensions given for Matrix operator \"",
281 matPtr->
name,
"\"", (
char *) NULL );
288 switch ( matPtr->
type )
292 for ( i = 0; i < matPtr->
len; i++ )
293 matPtr->
fdata[i] = 0.0;
298 for ( i = 0; i < matPtr->
len; i++ )
299 matPtr->
idata[i] = 0;
309 Tcl_AppendResult( interp,
310 "no initialization data given after \"=\" for Matrix operator \"",
311 matPtr->
name,
"\"", (
char *) NULL );
319 concatenated_argv_len = 3;
320 for ( i = 0; i <
argc; i++ )
322 concatenated_argv_len += strlen( argv[i] ) + 1;
323 concatenated_argv = (
char *) malloc( concatenated_argv_len *
sizeof (
char ) );
326 concatenated_argv[0] =
'\0';
327 strcat( concatenated_argv,
"{" );
328 for ( i = 0; i <
argc; i++ )
330 strcat( concatenated_argv, argv[i] );
331 strcat( concatenated_argv,
" " );
333 strcat( concatenated_argv,
"}" );
335 const_concatenated_argv = (
const char *) concatenated_argv;
341 if (
MatrixAssign( interp, matPtr, 0, &offset, 1, &const_concatenated_argv ) != TCL_OK )
344 free( (
void *) concatenated_argv );
347 free( (
void *) concatenated_argv );
353 if ( ( matPtr->
indices = (
int *) malloc( (
size_t) ( matPtr->
len ) * sizeof (
int ) ) ) == NULL )
355 Tcl_AppendResult( interp,
356 "memory allocation failed for indices vector associated with Matrix operator \"",
357 matPtr->
name,
"\"", (
char *) NULL );
366 if ( Tcl_SetVar( interp, matPtr->
name,
367 "old_bogus_syntax_please_upgrade", 0 ) == NULL )
369 Tcl_AppendResult( interp,
"unable to schedule Matrix operator \"",
370 matPtr->
name,
"\" for automatic deletion", (
char *) NULL );
375 Tcl_TraceVar( interp, matPtr->
name, TCL_TRACE_UNSETS,
382 fprintf( stderr,
"Creating Matrix operator of name %s\n", matPtr->
name );
384 Tcl_CreateCommand( interp, matPtr->
name, (Tcl_CmdProc *)
MatrixCmd,
395 hPtr = Tcl_CreateHashEntry( &
matTable, matPtr->name, &
new );
398 Tcl_AppendResult( interp,
399 "Unable to create hash table entry for Matrix operator \"",
400 matPtr->name,
"\"", (
char *) NULL );
403 Tcl_SetHashValue( hPtr, matPtr );
405 Tcl_SetResult( interp, matPtr->name, TCL_VOLATILE );
435 hPtr = Tcl_FindHashEntry( &
matTable, matName );
438 Tcl_AppendResult( interp,
"No matrix operator named \"",
439 matName,
"\"", (
char *) NULL );
442 return (
tclMatrix *) Tcl_GetHashValue( hPtr );
480 fprintf( stderr,
"Installing a tclMatrix extension -> %s\n", cmd );
483 new->cmd = malloc( strlen( cmd ) + 1 );
484 strcpy( new->cmd, cmd );
495 tail = tail->
next =
new;
511 int level,
int *offset,
int nargs,
const char** args )
513 static int verbose = 0;
515 const char ** newargs;
521 fprintf( stderr,
"level %d offset %d nargs %d\n", level, *offset, nargs );
522 for ( i = 0; i < nargs; i++ )
524 fprintf( stderr,
"i = %d, args[i] = %s\n", i, args[i] );
530 Tcl_AppendResult( interp,
"too many list levels", (
char *) NULL );
534 for ( i = 0; i < nargs; i++ )
536 if ( Tcl_SplitList( interp, args[i], &numnewargs, &newargs )
545 if ( numnewargs == 1 && strlen( args[i] ) == strlen( newargs[0] ) && strcmp( args[i], newargs[0] ) == 0 )
555 fprintf( stderr,
"\ta[%d] = %s\n", *offset, args[i] );
557 ( m->
put )( (ClientData) m,
interp, *offset, args[i] );
559 ( m->
put )( (ClientData) m, interp, m->
indices[*offset], args[i] );
563 else if (
MatrixAssign( interp, m, level + 1, offset, numnewargs, newargs )
566 Tcl_Free( (
char *) newargs );
569 Tcl_Free( (
char *) newargs );
597 const char *
name = argv[0];
604 int char_converted, change_default_start, change_default_stop;
613 Tcl_AppendResult( interp,
"wrong # args, type: \"",
614 argv[0],
" help\" for more info", (
char *) NULL );
621 stop[i] = matPtr->
n[i];
630 argv0_length = strlen( argv[0] );
635 if ( ( c ==
'd' ) && ( strncmp( argv[0],
"dump", argv0_length ) == 0 ) )
637 for ( i = start[0]; i < stop[0]; i++ )
639 for ( j = start[1]; j < stop[1]; j++ )
641 for ( k = start[2]; k < stop[2]; k++ )
643 ( *matPtr->
get )( (ClientData) matPtr,
interp,
I3D( i, j, k ), tmp );
644 printf(
"%s ", tmp );
646 if ( matPtr->
dim > 2 )
649 if ( matPtr->
dim > 1 )
658 else if ( ( c ==
'd' ) && ( strncmp( argv[0],
"delete", argv0_length ) == 0 ) )
661 fprintf( stderr,
"Deleting array %s\n", name );
663 Tcl_DeleteCommand( interp, name );
670 else if ( ( c ==
'f' ) && ( strncmp( argv[0],
"filter", argv0_length ) == 0 ) )
677 Tcl_AppendResult( interp,
"wrong # args: should be \"",
678 name,
" ", argv[0],
" num-passes\"",
685 Tcl_AppendResult( interp,
"can only filter a 1d float matrix",
690 nfilt = atoi( argv[1] );
693 for ( ifilt = 0; ifilt < nfilt; ifilt++ )
697 j = 0; tmpMat[j] = matPtr->
fdata[0];
698 for ( i = 0; i < matPtr->
len; i++ )
700 j++; tmpMat[j] = matPtr->
fdata[i];
702 j++; tmpMat[j] = matPtr->
fdata[matPtr->
len - 1];
706 for ( i = 0; i < matPtr->
len; i++ )
709 matPtr->
fdata[i] = 0.25 * ( tmpMat[j - 1] + 2 * tmpMat[j] + tmpMat[j + 1] );
713 free( (
void *) tmpMat );
719 else if ( ( c ==
'h' ) && ( strncmp( argv[0],
"help", argv0_length ) == 0 ) )
721 Tcl_AppendResult( interp,
722 "Available subcommands:\n\
723 dump - return the values in the matrix as a string\n\
724 delete - delete the matrix (including the matrix command)\n\
725 filter - apply a three-point averaging (with a number of passes; ome-dimensional only)\n\
726 help - this information\n\
727 info - return the dimensions\n\
728 max - return the maximum value for the entire matrix or for the first N entries\n\
729 min - return the minimum value for the entire matrix or for the first N entries\n\
730 redim - resize the matrix (for one-dimensional matrices only)\n\
731 scale - scale the values by a given factor (for one-dimensional matrices only)\n\
733 Set and get values:\n\
734 matrix m f 3 3 3 - define matrix command \"m\", three-dimensional, floating-point data\n\
735 m 1 2 3 - return the value of matrix element [1,2,3]\n\
736 m 1 2 3 = 2.0 - set the value of matrix element [1,2,3] to 2.0 (do not return the value)\n\
737 m * 2 3 = 2.0 - set a slice consisting of all elements with second index 2 and third index 3 to 2.0",
744 else if ( ( c ==
'i' ) && ( strncmp( argv[0],
"info", argv0_length ) == 0 ) )
746 for ( i = 0; i < matPtr->
dim; i++ )
748 sprintf( tmp,
"%d", matPtr->
n[i] );
750 if ( i < matPtr->dim - 1 )
751 Tcl_AppendResult( interp, tmp,
" ", (
char *) NULL );
753 Tcl_AppendResult( interp, tmp, (
char *) NULL );
760 else if ( ( c ==
'm' ) && ( strncmp( argv[0],
"max", argv0_length ) == 0 ) )
763 if ( argc < 1 || argc > 2 )
765 Tcl_AppendResult( interp,
"wrong # args: should be \"",
766 name,
" ", argv[0],
" ?length?\"",
773 len = atoi( argv[1] );
774 if ( len < 0 || len > matPtr->
len )
776 Tcl_AppendResult( interp,
"specified length out of valid range",
786 Tcl_AppendResult( interp,
"attempt to find maximum of array with zero elements",
791 switch ( matPtr->
type )
795 for ( i = 1; i < len; i++ )
798 Tcl_PrintDouble( interp, max, tmp );
799 Tcl_AppendResult( interp, tmp, (
char *) NULL );
804 for ( i = 1; i < len; i++ )
806 sprintf( tmp,
"%d", max );
807 Tcl_AppendResult( interp, tmp, (
char *) NULL );
816 else if ( ( c ==
'm' ) && ( strncmp( argv[0],
"min", argv0_length ) == 0 ) )
819 if ( argc < 1 || argc > 2 )
821 Tcl_AppendResult( interp,
"wrong # args: should be \"",
822 name,
" ", argv[0],
" ?length?\"",
829 len = atoi( argv[1] );
830 if ( len < 0 || len > matPtr->
len )
832 Tcl_AppendResult( interp,
"specified length out of valid range",
842 Tcl_AppendResult( interp,
"attempt to find minimum of array with zero elements",
847 switch ( matPtr->
type )
851 for ( i = 1; i < len; i++ )
854 Tcl_PrintDouble( interp, min, tmp );
855 Tcl_AppendResult( interp, tmp, (
char *) NULL );
860 for ( i = 1; i < len; i++ )
862 sprintf( tmp,
"%d", min );
863 Tcl_AppendResult( interp, tmp, (
char *) NULL );
873 else if ( ( c ==
'r' ) && ( strncmp( argv[0],
"redim", argv0_length ) == 0 ) )
880 Tcl_AppendResult( interp,
"wrong # args: should be \"",
881 name,
" ", argv[0],
" length\"",
886 if ( matPtr->
dim != 1 )
888 Tcl_AppendResult( interp,
"can only redim a 1d matrix",
893 newlen = atoi( argv[1] );
894 switch ( matPtr->
type )
897 data = realloc( matPtr->
fdata, (
size_t) newlen * sizeof (
Mat_float ) );
898 if ( newlen != 0 && data == NULL )
900 Tcl_AppendResult( interp,
"redim failed!",
905 for ( i = matPtr->
len; i < newlen; i++ )
906 matPtr->
fdata[i] = 0.0;
910 data = realloc( matPtr->
idata, (
size_t) newlen * sizeof (
Mat_int ) );
911 if ( newlen != 0 && data == NULL )
913 Tcl_AppendResult( interp,
"redim failed!",
918 for ( i = matPtr->
len; i < newlen; i++ )
919 matPtr->
idata[i] = 0;
922 matPtr->
n[0] = matPtr->
len = newlen;
926 data = realloc( matPtr->
indices, (
size_t) ( matPtr->
len ) * sizeof (
int ) );
927 if ( newlen != 0 && data == NULL )
929 Tcl_AppendResult( interp,
"redim failed!", (
char *) NULL );
932 matPtr->
indices = (
int *) data;
939 else if ( ( c ==
's' ) && ( strncmp( argv[0],
"scale", argv0_length ) == 0 ) )
945 Tcl_AppendResult( interp,
"wrong # args: should be \"",
946 name,
" ", argv[0],
" scale-factor\"",
951 if ( matPtr->
dim != 1 )
953 Tcl_AppendResult( interp,
"can only scale a 1d matrix",
958 scale = atof( argv[1] );
959 switch ( matPtr->
type )
962 for ( i = 0; i < matPtr->
len; i++ )
963 matPtr->
fdata[i] *= scale;
967 for ( i = 0; i < matPtr->
len; i++ )
978 for (; p; p = p->
next )
980 if ( ( c == p->
cmd[0] ) && ( strncmp( argv[0], p->
cmd, argv0_length ) == 0 ) )
983 fprintf( stderr,
"found a match, invoking %s\n", p->
cmd );
1000 if ( argc < matPtr->dim )
1002 Tcl_AppendResult( interp,
"not enough dimensions specified for \"",
1003 name,
"\"", (
char *) NULL );
1007 for ( i = 0; i < matPtr->
dim; i++ )
1016 argv0_length = strlen( argv[0] );
1024 stop[i] = matPtr->
n[i];
1026 change_default_start = 0;
1027 change_default_stop = 0;
1029 if ( sscanf( argv[0],
"%d%1[:]%d%1[:]%d%n", start + i, c1, stop + i, c2, step + i, &char_converted ) >= 5 )
1033 else if ( sscanf( argv[0],
"%d%1[:]%d%1[:]%n", start + i, c1, stop + i, c2, &char_converted ) >= 4 )
1037 else if ( sscanf( argv[0],
"%d%1[:]%d%n", start + i, c1, stop + i, &char_converted ) >= 3 )
1041 else if ( sscanf( argv[0],
"%d%1[:]%1[:]%d%n", start + i, c1, c2, step + i, &char_converted ) >= 4 )
1045 change_default_stop = 1;
1049 else if ( sscanf( argv[0],
"%d%1[:]%1[:]%n", start + i, c1, c2, &char_converted ) >= 3 )
1053 else if ( sscanf( argv[0],
"%d%1[:]%n", start + i, c1, &char_converted ) >= 2 )
1057 else if ( sscanf( argv[0],
"%1[:]%d%1[:]%d%n", c1, stop + i, c2, step + i, &char_converted ) >= 4 )
1061 change_default_start = 1;
1065 else if ( sscanf( argv[0],
"%1[:]%d%1[:]%n", c1, stop + i, c2, &char_converted ) >= 3 )
1069 else if ( sscanf( argv[0],
"%1[:]%d%n", c1, stop + i, &char_converted ) >= 2 )
1073 else if ( sscanf( argv[0],
"%1[:]%1[:]%d%n", c1, c2, step + i, &char_converted ) >= 3 )
1077 change_default_start = 1;
1078 change_default_stop = 1;
1082 else if ( strcmp( argv[0],
"::" ) == 0 )
1085 else if ( strcmp( argv[0],
":" ) == 0 )
1088 else if ( strcmp( argv[0],
"*" ) == 0 )
1091 else if ( sscanf( argv[0],
"%d%n", start + i, &char_converted ) >= 1 )
1095 start[i] += matPtr->
n[i];
1096 if ( start[i] < 0 || start[i] > matPtr->
n[i] - 1 )
1098 sprintf( tmp,
"Array index %d out of bounds: original string = \"%s\"; transformed = %d; min = 0; max = %d\n",
1099 i, argv[0], start[i], matPtr->
n[i] - 1 );
1100 Tcl_AppendResult( interp, tmp, (
char *) NULL );
1103 stop[i] = start[i] + 1;
1107 sprintf( tmp,
"Array slice for index %d with original string = \"%s\" could not be parsed\n",
1109 Tcl_AppendResult( interp, tmp, (
char *) NULL );
1116 Tcl_AppendResult( interp,
"step part of slice must be non-zero",
1120 sign_step[i] = ( step[i] > 0 ) ? 1 : -1;
1121 if ( (
size_t) char_converted > argv0_length )
1123 Tcl_AppendResult( interp,
"MatrixCmd, internal logic error",
1127 if ( (
size_t) char_converted < argv0_length )
1129 sprintf( tmp,
"Array slice for index %d with original string = \"%s\" "
1130 "had trailing unparsed characters\n", i, argv[0] );
1131 Tcl_AppendResult( interp, tmp, (
char *) NULL );
1135 start[i] += matPtr->
n[i];
1136 start[i] =
MAX( 0,
MIN( matPtr->
n[i] - 1, start[i] ) );
1137 if ( change_default_start )
1138 start[i] = matPtr->
n[i] - 1;
1140 stop[i] += matPtr->
n[i];
1142 stop[i] =
MAX( 0,
MIN( matPtr->
n[i], stop[i] ) );
1144 stop[i] =
MAX( -1,
MIN( matPtr->
n[i], stop[i] ) );
1145 if ( change_default_stop )
1168 fprintf( stderr,
"Array slice for index %d with original string = \"%s\" "
1169 "yielded start[i], stop[i], transformed stop[i], and step[i] = "
1170 "%d, %d, ", i, argv[0], start[i], stop[i] );
1172 stop[i] = sign_step[i] * stop[i];
1174 fprintf( stderr,
"%d, %d\n", stop[i], step[i] );
1184 if ( strcmp( argv[0],
"=" ) == 0 )
1189 Tcl_AppendResult( interp,
"no value specified",
1196 Tcl_AppendResult( interp,
"extra characters after indices: \"",
1197 argv[0],
"\"", (
char *) NULL );
1205 for ( i = start[0]; sign_step[0] * i < stop[0]; i += step[0] )
1207 for ( j = start[1]; sign_step[1] * j < stop[1]; j += step[1] )
1209 for ( k = start[2]; sign_step[2] * k < stop[2]; k += step[2] )
1223 switch ( matPtr->
type )
1226 strtod( argv[0], &endptr );
1229 strtol( argv[0], &endptr, 10 );
1232 if ( argc == 1 && *argv[0] !=
'\0' && *endptr ==
'\0' )
1238 for ( i = 0; i < matPtr->
nindices; i++ )
1239 ( *matPtr->
put )( (ClientData) matPtr, interp, matPtr->
indices[i], argv[0] );
1251 size_t concatenated_argv_len;
1252 char *concatenated_argv;
1253 const char *const_concatenated_argv;
1260 concatenated_argv_len = 3;
1261 for ( i = 0; i <
argc; i++ )
1263 concatenated_argv_len += strlen( argv[i] ) + 1;
1264 concatenated_argv = (
char *) malloc( concatenated_argv_len *
sizeof (
char ) );
1267 concatenated_argv[0] =
'\0';
1268 strcat( concatenated_argv,
"{" );
1269 for ( i = 0; i <
argc; i++ )
1271 strcat( concatenated_argv, argv[i] );
1272 strcat( concatenated_argv,
" " );
1274 strcat( concatenated_argv,
"}" );
1276 const_concatenated_argv = (
const char *) concatenated_argv;
1280 if (
MatrixAssign( interp, matPtr, 0, &offset, 1, &const_concatenated_argv ) != TCL_OK )
1282 free( (
void *) concatenated_argv );
1285 free( (
void *) concatenated_argv );
1291 for ( i = 0; i < matPtr->
nindices; i++ )
1294 if ( i < matPtr->nindices - 1 )
1295 Tcl_AppendResult( interp, tmp,
" ", (
char *) NULL );
1297 Tcl_AppendResult( interp, tmp, (
char *) NULL );
1324 matPtr->
fdata[index] = atof(
string );
1334 Tcl_PrintDouble( interp, value,
string );
1342 if ( ( strlen(
string ) > 2 ) && ( strncmp(
string,
"0x", 2 ) == 0 ) )
1344 matPtr->
idata[index] = (
Mat_int) strtoul( &
string[2], NULL, 16 );
1347 matPtr->
idata[index] = atoi(
string );
1355 sprintf(
string,
"%d", matPtr->
idata[index] );
1378 Tcl_CmdInfo infoPtr;
1386 name = (
char *) malloc( strlen( matPtr->
name ) + 1 );
1387 strcpy( name, matPtr->
name );
1390 if ( Tcl_GetCommandInfo( matPtr->
interp, matPtr->
name, &infoPtr ) )
1392 if ( Tcl_DeleteCommand( matPtr->
interp, matPtr->
name ) == TCL_OK )
1393 fprintf( stderr,
"Deleted command %s\n", name );
1395 fprintf( stderr,
"Unable to delete command %s\n", name );
1398 if ( Tcl_GetCommandInfo( matPtr->
interp, matPtr->
name, &infoPtr ) )
1399 Tcl_DeleteCommand( matPtr->
interp, matPtr->
name );
1401 free( (
void *) name );
1403 return (
char *) NULL;
1432 Tcl_HashEntry *hPtr;
1437 fprintf( stderr,
"Freeing space associated with matrix %s\n", matPtr->
name );
1444 Tcl_DeleteHashEntry( hPtr );
1448 if ( matPtr->
fdata != NULL )
1450 free( (
void *) matPtr->
fdata );
1451 matPtr->
fdata = NULL;
1453 if ( matPtr->
idata != NULL )
1455 free( (
void *) matPtr->
idata );
1456 matPtr->
idata = NULL;
1458 if ( matPtr->
indices != NULL )
1460 free( (
void *) matPtr->
indices );
1468 if ( Tcl_VarTraceInfo( matPtr->
interp, matPtr->
name, TCL_TRACE_UNSETS,
1472 Tcl_UntraceVar( matPtr->
interp, matPtr->
name, TCL_TRACE_UNSETS,
1474 Tcl_UnsetVar( matPtr->interp, matPtr->name, 0 );
1480 if ( matPtr->
name != NULL )
1482 free( (
void *) matPtr->
name );
1483 matPtr->
name = NULL;
1489 free( (
void *) matPtr );
1492 fprintf( stderr,
"OOPS! You just lost %d bytes\n",
sizeof (
tclMatrix ) );
struct tclMatrixXtnsnDescr * next
int(* tclMatrixXtnsnProc)(tclMatrix *pm, Tcl_Interp *interp, int argc, const char *argv[])
int Tcl_MatrixInstallXtnsn(const char *cmd, tclMatrixXtnsnProc proc)
tclMatrix * Tcl_GetMatrixPtr(Tcl_Interp *interp, const char *matName)
void(* put)(ClientData clientData, Tcl_Interp *interp, int index, const char *string)
static void MatrixGet_i(ClientData clientData, Tcl_Interp *interp, int index, char *string)
void(* get)(ClientData clientData, Tcl_Interp *interp, int index, char *string)
int Tcl_MatrixCmd(ClientData PL_UNUSED(clientData), Tcl_Interp *interp, int argc, const char **argv)
static tclMatrixXtnsnDescr * head
static void MatrixGet_f(ClientData clientData, Tcl_Interp *interp, int index, char *string)
static int MatrixCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
static char * DeleteMatrixVar(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
static int matTable_initted
static PLFLT value(double n1, double n2, double hue)
static int MatrixAssign(Tcl_Interp *interp, tclMatrix *m, int level, int *offset, int nargs, const char **args)
static tclMatrixXtnsnDescr * tail
static void DeleteMatrixCmd(ClientData clientData)
static Tcl_HashTable matTable
static Tcl_Interp * interp
static void MatrixPut_f(ClientData clientData, Tcl_Interp *interp, int index, const char *string)
static void MatrixPut_i(ClientData clientData, Tcl_Interp *interp, int index, const char *string)
tclMatrixXtnsnProc cmdproc