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,
  1473                 (Tcl_VarTraceProc *) DeleteMatrixVar, (ClientData) matPtr );
  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
void(* get)(ClientData clientData, Tcl_Interp *interp, int index, char *string)
void(* put)(ClientData clientData, Tcl_Interp *interp, int index, const char *string)
int Tcl_MatrixInstallXtnsn(const char *cmd, tclMatrixXtnsnProc proc)
tclMatrix * Tcl_GetMatrixPtr(Tcl_Interp *interp, const char *matName)
int(* tclMatrixXtnsnProc)(tclMatrix *pm, Tcl_Interp *interp, int argc, const char *argv[])
static void MatrixGet_i(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 PLFLT value(double n1, double n2, double hue)
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 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