summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>1999-07-04 20:44:58 +0000
committergoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>1999-07-04 20:44:58 +0000
commit60b45d66a082bc7bf84575907723397ce52dff3a (patch)
tree95fed523a75f51e202828171fca81b1f290b37b7
parent3a49de09ea001f18d6e58d236c80e2b39a4b78d0 (diff)
Stuff for the ActiveThorns parameter.
Now need to specify ActiveThorns before any other parameters to list those thorns which are active. No parameters or startup or rfr routines are available from inactive thorns. Note that this isn't quite working yet but I hope to track it down by morning. In the meantime either don't update or be prepared for things to be slightly broken. Tom git-svn-id: http://svn.cactuscode.org/flesh/trunk@645 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--lib/sbin/CST34
-rw-r--r--lib/sbin/CreateImplementationBindings.pl71
-rw-r--r--lib/sbin/schedule_parser.pl10
-rw-r--r--src/include/ActiveThorns.h28
-rw-r--r--src/include/SKBinTree.h47
-rw-r--r--src/include/flesh.h2
-rw-r--r--src/main/ActiveThorns.c327
-rw-r--r--src/main/InitialiseDataStructures.c1
-rw-r--r--src/main/SetParams.c32
-rw-r--r--src/main/make.code.defn4
-rw-r--r--src/util/SKBinTree.c355
-rw-r--r--src/util/make.code.defn4
12 files changed, 896 insertions, 19 deletions
diff --git a/lib/sbin/CST b/lib/sbin/CST
index d483bc85..eb586880 100644
--- a/lib/sbin/CST
+++ b/lib/sbin/CST
@@ -6,7 +6,7 @@
# @desc
# Parses the the configuration files for thorns.
# @enddesc
-# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.18 1999-07-04 12:35:38 allen Exp $
+# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.19 1999-07-04 20:44:58 goodale Exp $
#@@*/
# Global parameter to track the number of errors from the CST
@@ -71,6 +71,7 @@ require "$sbin_dir/output_config.pl";
require "$sbin_dir/Orderer.pl";
require "$sbin_dir/ImpParamConsistency.pl";
require "$sbin_dir/CSTUtils.pl";
+require "$sbin_dir/CreateImplementationBindings.pl";
#######################################################################
#
@@ -99,7 +100,6 @@ if($debug_parameters)
&print_parameter_database(%parameter_database);
}
-
# Create all the bindings
&CreateBindings($bindings_dir, scalar(keys %parameter_database), %parameter_database, %interface_database);
@@ -459,6 +459,7 @@ sub CreateBindings
$start_dir = `pwd`;
# Create the bindings for the subsystems.
+ &CreateImplementationBindings($bindings_dir, $n_param_database, @rest);
&CreateParameterBindings($bindings_dir, $n_param_database, @rest);
&CreateVariableBindings($bindings_dir, %interface_database);
&CreateScheduleBindings($bindings_dir, scalar(keys %thorns), %thorns,%interface_database);
@@ -469,7 +470,7 @@ sub CreateBindings
open (OUT, ">make.code.defn") || die "Cannot open make.code.defn";
print OUT "SRCS = \n";
- print OUT "SUBDIRS = Parameters Variables Schedule\n";
+ print OUT "SUBDIRS = Implementations Parameters Variables Schedule\n";
close OUT;
@@ -714,6 +715,10 @@ int CCTK_BindingsParameterSet(const char *identifier, const char *value)
}
else
{
+
+ if(CCTK_IsThornActive(implementation) ||
+ CCTK_IsImplementationActive(implementation))
+ {
EOT
foreach $routine (keys %routines, "CCTK_BindingsParametersGlobal")
@@ -724,20 +729,26 @@ EOT
if(CCTK_Equals(implementation, \"$routines{$routine}\"))
{
EOT
- print OUT " temp_retval = $routine"."Set(param_name, value);";
+ print OUT " temp_retval = $routine"."Set(param_name, value);";
print OUT <<EOT;
- if(!temp_retval)
- {
- retval = 0;
+ if(!temp_retval)
+ {
+ retval = 0;
+ }
}
- }
EOT
}
print OUT <<EOT;
- }
+ }
+ else
+ {
+ fprintf(stderr, "%s is not active\n", implementation);
+ retval = -2;
+ }
+ }
free(implementation);
free(param_name);
@@ -811,8 +822,8 @@ EOT
print OUT <<EOT;
- if(CCTK_Equals(implementation, \"$routines{$routine}\"))
- {
+ if(CCTK_Equals(implementation, \"$routines{$routine}\"))
+ {
EOT
print OUT " temp_retval = $routine"."Help(param_name, format, file);";
@@ -1046,7 +1057,6 @@ sub CreateScheduleBindings
# Write the contents of BindingsScheduleRegisterSTARTUP.c
- # Joan changes the call to Cactus_Register so it does not send data
&create_RegisterSTARTUP($bindings_dir,split(" ",$startup));
open (OUT, ">BindingsSchedule.c") || die "Cannot open BindingsSchedule.c";
diff --git a/lib/sbin/CreateImplementationBindings.pl b/lib/sbin/CreateImplementationBindings.pl
new file mode 100644
index 00000000..401b8394
--- /dev/null
+++ b/lib/sbin/CreateImplementationBindings.pl
@@ -0,0 +1,71 @@
+#/*@@
+# @file CreateImplementationBindings.pl
+# @date Sun Jul 4 17:09:54 1999
+# @author Tom Goodale
+# @desc
+#
+# @enddesc
+#@@*/
+
+sub CreateImplementationBindings
+{
+ local($bindings_dir, $n_param_database, @rest) = @_;
+ local(%parameter_database);
+ local(%interface_database);
+ local($start_dir);
+ local($thorn);
+ local(@data);
+
+ %parameter_database = @rest[0..(2*$n_param_database)-1];
+ %interface_database = @rest[2*$n_param_database..$#rest];
+
+ if(! -d $bindings_dir)
+ {
+ mkdir("$bindings_dir", 0755) || die "Unable to create $bindings_dir";
+ }
+ $start_dir = `pwd`;
+
+ chdir $bindings_dir;
+
+ if(! -d "Implementations")
+ {
+ mkdir("Implementations", 0755) || die "Unable to create Implementations directory";
+ }
+
+ if(! -d "include")
+ {
+ mkdir("include", 0755) || die "Unable to create include directory";
+ }
+
+ chdir "Implementations";
+
+ @data = ();
+
+ push(@data, "#include \"ActiveThorns.h\"\n\n");
+
+ push(@data, "int CCTK_BindingsImplementationsInitialise(void)\n{\n");
+
+ foreach $thorn (sort split(" ", $interface_database{"THORNS"}))
+ {
+ push(@data, " CCTK_RegisterThorn(\"$thorn\",\"" .
+ $interface_database{"\U$thorn\E IMPLEMENTS"} ."\");\n");
+ }
+
+ push(@data, "\n return 0;\n}\n");
+
+ &OutputFile(".", "ImplementationBindings.c", @data);
+
+
+ open (OUT, ">make.code.defn");
+ print OUT <<EOF;
+
+SRCS = ImplementationBindings.c
+
+EOF
+
+ close OUT;
+
+ chdir $_start_dir;
+}
+
+1;
diff --git a/lib/sbin/schedule_parser.pl b/lib/sbin/schedule_parser.pl
index a96a9fdc..0d13970a 100644
--- a/lib/sbin/schedule_parser.pl
+++ b/lib/sbin/schedule_parser.pl
@@ -61,8 +61,8 @@ sub create_schedule_code
print OUTSTART $out;
# The footer for the thorn RFR routine
- print OUTRFR "}\n";
- print OUTSTART "}\n";
+ print OUTRFR " }\n}\n";
+ print OUTSTART " }\n}\n";
close OUTRFR;
close OUTSTART;
@@ -99,6 +99,7 @@ sub write_rfr_header {
$header .= "#include \"cctk.h\"\n";
$header .= "#include \"flesh.h\"\n";
$header .= "#include \"Comm.h\"\n";
+ $header .= "#include \"ActiveThorns.h\"\n";
$header .= "#include \"Groups.h\"\n";
$header .= "#include \"GroupsOnGH.h\"\n";
$header .= "#include \"rfr_constants.h\"\n";
@@ -110,6 +111,8 @@ sub write_rfr_header {
$header .= " DECLARE_CCTK_PARAMETERS\n";
$header .= " int index;\n\n";
$header .= "\n";
+ $header .= " if(CCTK_IsThornActive(\"$thorn\"))\n";
+ $header .= " {\n\n";
return $header;
@@ -123,6 +126,7 @@ sub write_startup_header {
print OUTSTART "#define THORN_IS_$thorn\n";
print OUTSTART "#include \"cctk.h\"\n";
print OUTSTART "#include \"flesh.h\"\n";
+ print OUTSTART "#include \"ActiveThorns.h\"\n";
print OUTSTART "#include \"rfr_constants.h\"\n";
print OUTSTART "#include \"cctk_parameters.h\"\n";
print OUTSTART "\n";
@@ -130,6 +134,8 @@ sub write_startup_header {
print OUTSTART "{\n";
print OUTSTART " DECLARE_CCTK_PARAMETERS\n";
print OUTSTART "\n";
+ print OUTSTART " if(CCTK_IsThornActive(\"$thorn\"))\n";
+ print OUTSTART " {\n\n";
}
diff --git a/src/include/ActiveThorns.h b/src/include/ActiveThorns.h
new file mode 100644
index 00000000..0abdd287
--- /dev/null
+++ b/src/include/ActiveThorns.h
@@ -0,0 +1,28 @@
+ /*@@
+ @header ActiveThorns.h
+ @date Sun Jul 4 17:39:50 1999
+ @author Tom Goodale
+ @desc
+
+ @enddesc
+ @version $Header$
+ @@*/
+
+#ifndef __ACTIVETHORNS_H_
+#define __ACTIVETHORNS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int CCTK_RegisterThorn(const char *name, const char *imp);
+int CCTK_ActivateThorn(const char *name);
+int CCTK_IsThornActive(const char *name);
+int CCTK_IsImplementationActive(const char *name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ACTIVETHORNS_H_ */
diff --git a/src/include/SKBinTree.h b/src/include/SKBinTree.h
new file mode 100644
index 00000000..6ff6153b
--- /dev/null
+++ b/src/include/SKBinTree.h
@@ -0,0 +1,47 @@
+ /*@@
+ @header BinaryTree.h
+ @date Mon Oct 5 11:01:20 1998
+ @author Tom Goodale
+ @desc
+ Prototypes and data definitions for binary tree routines.
+ @enddesc
+ @@*/
+
+#ifndef _SKBINTREE_H_
+#define _SKBINTREE_H_
+
+typedef struct T_SKTREE
+{
+ struct T_SKTREE *left;
+ struct T_SKTREE *right;
+ struct T_SKTREE *next;
+
+ char *key;
+
+ void *data;
+} t_sktree;
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+t_sktree *SKTreeStoreData(t_sktree *root,
+ t_sktree *subtree,
+ const char *key,
+ void *data);
+
+int SKTreeTraverseInorder(t_sktree *root, int (*process)(void *, void *), void *info);
+
+int SKTreeTraversePreorder(t_sktree *root, int (*process)(void *, void *), void *info);
+
+int SKTreeTraversePostorder(t_sktree *root, int (*process)(void *, void *), void *info);
+
+void SKTreePrintNodes(t_sktree *root, int depth, void (*print_node)(void *, int));
+
+t_sktree *SKTreeFindNode(t_sktree *root, const char *key);
+
+#ifdef _cplusplus
+ }
+#endif
+
+#endif
diff --git a/src/include/flesh.h b/src/include/flesh.h
index 0451c1e5..589c9b2b 100644
--- a/src/include/flesh.h
+++ b/src/include/flesh.h
@@ -104,6 +104,8 @@ int CCTK_VTypeNumber(const char *type);
int CCTK_GTypeNumber(const char *type);
+int CCTK_BindingsImplementationsInitialise(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/main/ActiveThorns.c b/src/main/ActiveThorns.c
new file mode 100644
index 00000000..64f0d331
--- /dev/null
+++ b/src/main/ActiveThorns.c
@@ -0,0 +1,327 @@
+ /*@@
+ @file ActiveThorns.c
+ @date Sun Jul 4 16:15:36 1999
+ @author Tom Goodale
+ @desc
+ Stuff to deal with activethorns.
+ @enddesc
+ @@*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ActiveThorns.h"
+#include "SKBinTree.h"
+
+
+static char *rcsid = "$Header$";
+
+
+static int CCTKi_RegisterImp(const char *name, const char *thorn);
+
+struct THORN
+{
+ int active;
+ char *implementation;
+};
+
+struct IMPLEMENTATION
+{
+ int active;
+};
+
+
+static t_sktree *thornlist = NULL;
+static t_sktree *implist = NULL;
+
+
+ /*@@
+ @routine CCTK_RegisterThorn
+ @date Sun Jul 4 17:44:14 1999
+ @author Tom Goodale
+ @desc
+ Registers a thorn with the flesh.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int CCTK_RegisterThorn(const char *name, const char *imp)
+{
+ int retval;
+ t_sktree *node;
+ t_sktree *temp;
+
+ struct THORN *thorn;
+
+ printf("Registering thorn %s, which provides %s\n", name, imp);
+
+ node = SKTreeFindNode(thornlist, name);
+
+ if(!node)
+ {
+ thorn = (struct THORN *)malloc(sizeof(struct THORN));
+
+ if(thorn)
+ {
+ thorn->implementation = (char *)malloc(sizeof(char)*(strlen(imp)+1));
+
+ if(thorn->implementation)
+ {
+ strcpy(thorn->implementation, imp);
+ thorn->active = 0;
+
+ temp = SKTreeStoreData(thornlist, thornlist, name, thorn);
+
+ if(!thornlist) thornlist = temp;
+
+ if(temp)
+ {
+ CCTKi_RegisterImp(imp, name);
+
+ retval = 0;
+ }
+ else
+ {
+ retval = -4;
+ }
+ }
+ else
+ {
+ retval = -3;
+ }
+ }
+ else
+ {
+ retval = -2;
+ }
+ }
+ else
+ {
+ retval = -1;
+ }
+
+
+ printf("Registration retval is %d\n", retval);
+
+ return retval;
+}
+
+ /*@@
+ @routine CCTK_RegisterImp
+ @date Sun Jul 4 17:44:42 1999
+ @author Tom Goodale
+ @desc
+ Registers an implementation.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+static int CCTKi_RegisterImp(const char *name, const char *thorn)
+{
+ int retval;
+ t_sktree *node;
+ t_sktree *temp;
+
+ struct IMPLEMENTATION *imp;
+
+ printf("Registering implementation %s\n", name);
+
+ node = SKTreeFindNode(implist, name);
+
+ if(!node)
+ {
+ imp = (struct IMPLEMENTATION *)malloc(sizeof(struct IMPLEMENTATION));
+
+ if(imp)
+ {
+ imp->active = 0;
+ temp = SKTreeStoreData(implist, implist, name, imp);
+
+ if(!implist) implist = temp;
+
+ if(temp)
+ {
+ retval = 0;
+ }
+ else
+ {
+ retval = -3;
+ }
+ }
+ else
+ {
+ retval = -2;
+ }
+ }
+ else
+ {
+ retval = -1;
+ }
+
+ printf("Registration retval is %d\n", retval);
+
+ return retval;
+}
+
+
+ /*@@
+ @routine CCTK_ActivateThorn
+ @date Sun Jul 4 17:46:15 1999
+ @author Tom Goodale
+ @desc
+ Activates a thorn and the associated implementation assuming
+ the implementation isn't already active.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int CCTK_ActivateThorn(const char *name)
+{
+ int retval;
+ t_sktree *thornnode;
+ t_sktree *impnode;
+
+ struct THORN *thorn;
+ struct IMPLEMENTATION *imp;
+
+ printf("Activating thorn %s\n", name);
+
+ thornnode = SKTreeFindNode(thornlist, name);
+
+ if(thornnode)
+ {
+ thorn = (struct THORN *)(thornnode->data);
+
+ impnode = SKTreeFindNode(implist, thorn->implementation);
+
+ if(impnode)
+ {
+ imp = (struct IMPLEMENTATION *)(impnode->data);
+
+ if(!thorn->active)
+ {
+ if(!imp->active)
+ {
+
+ printf("Active thorn %s -> imp %s\n", name, thorn->implementation);
+ thorn->active = 1;
+ imp->active = 1;
+ retval = 0;
+ }
+ else
+ {
+ printf("Implementation %s already active\n", thorn->implementation);
+ retval = -4;
+ }
+ }
+ else
+ {
+ printf("Thorn %s already active\n", name);
+ retval = -3;
+ }
+ }
+ else
+ {
+ printf("Internal error - can't find imp %s from thorn %s\n", thorn->implementation, name);
+ retval = -2;
+ }
+ }
+ else
+ {
+ printf("Tried to activate non-existent thorn %s\n", name);
+ retval = -1;
+ }
+
+ return retval;
+
+}
+
+
+/*@@
+ @routine CCTK_IsThornActive
+ @date Sun Jul 4 17:46:56 1999
+ @author Tom Goodale
+ @desc
+ Checks if a thorn is active.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int CCTK_IsThornActive(const char *name)
+{
+ int retval;
+ t_sktree *node;
+
+ struct THORN *thorn;
+
+ node = SKTreeFindNode(thornlist, name);
+
+ retval = 0;
+
+ if(node)
+ {
+ thorn = (struct THORN *)(node->data);
+
+ if(thorn->active)
+ {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
+/*@@
+ @routine CCTK_IsImplementationActive
+ @date Sun Jul 4 17:46:56 1999
+ @author Tom Goodale
+ @desc
+ Checks if an implementation is active.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int CCTK_IsImplementationActive(const char *name)
+{
+ int retval;
+
+ t_sktree *node;
+
+ struct IMPLEMENTATION *imp;
+
+ node = SKTreeFindNode(implist, name);
+
+ retval = 0;
+
+ if(node)
+ {
+ imp = (struct IMPLEMENTATION *)(node->data);
+
+ if(imp->active)
+ {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
diff --git a/src/main/InitialiseDataStructures.c b/src/main/InitialiseDataStructures.c
index 96214863..06de67af 100644
--- a/src/main/InitialiseDataStructures.c
+++ b/src/main/InitialiseDataStructures.c
@@ -44,6 +44,7 @@ int InitialiseDataStructures(tFleshConfig *ConfigData)
/* Initialise appropriate subsystems. */
+ CCTK_BindingsImplementationsInitialise();
CCTK_BindingsParametersInitialise();
CCTK_BindingsVariablesInitialise();
CCTK_BindingsScheduleInitialise();
diff --git a/src/main/SetParams.c b/src/main/SetParams.c
index e1eb3d91..297b66d8 100644
--- a/src/main/SetParams.c
+++ b/src/main/SetParams.c
@@ -28,13 +28,41 @@ static char *rcsid = "$Id$";
int CCTK_SetParameter(const char *parameter, const char *value)
{
int retval;
+ char thornname[101];
+ const char *position;
+ int length;
- retval = CCTK_BindingsParameterSet(parameter, value);
+ if(CCTK_Equals(parameter, "ActiveThorns"))
+ {
+ position = value;
+
+ while(*position)
+ {
+ length=0;
+
+ for(;*position && *position != ' ';position++)
+ {
+ thornname[length] = *position;
+ if(length < 100) length++;
+ }
+ thornname[length] = '\0';
+ CCTK_ActivateThorn(thornname);
+ if(position) position++;
+ }
+ CCTK_ActivateThorn("Cactus");
+ }
+ else
+ {
+ retval = CCTK_BindingsParameterSet(parameter, value);
+ }
if(retval)
{
- fprintf(stderr, "Unknown parameter %s\n", parameter);
+ if(retval == -1)
+ {
+ fprintf(stderr, "Unknown parameter %s\n", parameter);
+ }
}
return retval;
diff --git a/src/main/make.code.defn b/src/main/make.code.defn
index ba042661..0e3320d5 100644
--- a/src/main/make.code.defn
+++ b/src/main/make.code.defn
@@ -15,7 +15,6 @@ ProcessCommandLine.c\
ProcessEnvironment.c\
ProcessParameterDatabase.c\
RecordImplementation.c\
-RegisterThorn.c\
SetParams.c\
ShutdownCactus.c\
flesh.cc\
@@ -26,4 +25,5 @@ rfrInterface.c\
OverloadMain.c\
CommandLine.c\
GHExtensions.c\
-WarnLevel.c
+WarnLevel.c\
+ActiveThorns.c
diff --git a/src/util/SKBinTree.c b/src/util/SKBinTree.c
new file mode 100644
index 00000000..3c166761
--- /dev/null
+++ b/src/util/SKBinTree.c
@@ -0,0 +1,355 @@
+ /*@@
+ @file SKBinTree.c
+ @date Mon Oct 5 11:00:01 1998
+ @author Tom Goodale
+ @desc
+ Routines to deal with binary trees
+ @enddesc
+ @@*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "SKBinTree.h"
+
+int STR_cmpi(const char *string1, const char *string2);
+
+#define STR_CMP(a,b) STR_cmpi(a,b)
+
+static char *rcsid = "$Id$";
+
+
+ /*@@
+ @routine SKTreeStoreData
+ @date Mon Oct 5 11:04:55 1998
+ @author Tom Goodale
+ @desc
+ Stores data in a binary tree.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+t_sktree *SKTreeStoreData(t_sktree *root, t_sktree *subtree,
+ const char *key, void *data)
+{
+ int order;
+
+ if(!subtree)
+ {
+ /* Create a new element. */
+ subtree = (t_sktree *)malloc(sizeof(t_sktree));
+ if(subtree)
+ {
+ subtree->left=NULL;
+ subtree->right=NULL;
+
+ subtree->data = data;
+
+ subtree->key= (char *)malloc(sizeof(char)*(strlen(key)+1));
+ strcpy(subtree->key, key);
+ if(root)
+ {
+ if((order = STR_CMP(key, root->key)) < 0)
+ {
+ root->left = subtree;
+ }
+ else
+ {
+ root->right = subtree;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Go down left or right branch. */
+ if((order = STR_CMP(key, root->key)) < 0)
+ {
+ subtree = SKTreeStoreData(subtree, subtree->left, key, data);
+ }
+ else if(order > 0)
+ {
+ subtree = SKTreeStoreData(subtree, subtree->right, key, data);
+ }
+ else if(order==0)
+ {
+ /* Duplicate key. */
+ subtree = NULL;
+ }
+ }
+
+ /* Return either the new node, or NULL if either a duplicate value or
+ * memory failure.
+ */
+
+ return subtree;
+
+}
+
+ /*@@
+ @routine SKTreeTraverseInorder
+ @date Mon Oct 5 11:05:54 1998
+ @author Tom Goodale
+ @desc
+ Traverse a tree 'inorder'
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int SKTreeTraverseInorder(t_sktree *root, int (*process)(void *, void *), void *info)
+{
+ int terminate;
+
+ terminate = 0;
+
+ if(root)
+ {
+ terminate = SKTreeTraverseInorder(root->left, process, info);
+ if(!terminate) terminate = process(root->data,info);
+ if(!terminate) terminate = SKTreeTraverseInorder(root->right, process, info);
+ }
+
+ return terminate;
+}
+
+ /*@@
+ @routine SKTreeTraversePreorder
+ @date Mon Oct 5 11:05:54 1998
+ @author Tom Goodale
+ @desc
+ Traverse a tree 'preorder'
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int SKTreeTraversePreorder(t_sktree *root, int (*process)(void *, void *), void *info)
+{
+ int terminate;
+
+ terminate = 0;
+
+ if(root)
+ {
+ terminate = process(root->data, info);
+ if(!terminate) terminate = SKTreeTraversePreorder(root->left, process, info);
+ if(!terminate) terminate = SKTreeTraversePreorder(root->right, process,info);
+ }
+
+ return terminate;
+}
+
+ /*@@
+ @routine SKTreeTraversePostorder
+ @date Mon Oct 5 11:05:54 1998
+ @author Tom Goodale
+ @desc
+ Traverse a tree 'postorder'
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+int SKTreeTraversePostorder(t_sktree *root, int (*process)(void *, void *), void *info)
+{
+ int terminate;
+
+ terminate = 0;
+
+ if(root)
+ {
+ terminate = SKTreeTraversePostorder(root->left, process, info);
+ if(!terminate) terminate = SKTreeTraversePostorder(root->right, process, info);
+ if(!terminate) terminate = process(root->data, info);
+ }
+
+ return terminate;
+}
+
+ /*@@
+ @routine SKTreePrintNodes
+ @date Mon Oct 5 11:06:52 1998
+ @author Tom Goodale
+ @desc
+ Allows a binary tree to be printed out.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+void SKTreePrintNodes(t_sktree *root, int depth, void (*print_node)(void *, int))
+{
+ if(root)
+ {
+ SKTreePrintNodes(root->left, depth+1,print_node);
+ print_node(root->data,depth);
+ SKTreePrintNodes(root->right, depth+1, print_node);
+ }
+}
+
+
+t_sktree *SKTreeFindNode(t_sktree *root, const char *key)
+{
+ int order;
+
+ t_sktree *node;
+
+ if(root)
+ {
+ /* Go down left or right branch. */
+ if((order = STR_CMP(key, root->key)) < 0)
+ {
+ node = SKTreeFindNode(root->left, key);
+ }
+ else if(order > 0)
+ {
+ node = SKTreeFindNode(root->right, key);
+ }
+ else if(order==0)
+ {
+ /* Found it. */
+ node = root;
+ }
+ }
+ else
+ {
+ node = NULL;
+ }
+
+ return node;
+}
+
+
+
+int STR_cmpi(const char *string1, const char *string2)
+{
+ int retval;
+ int position;
+
+ retval = 1;
+
+ for(position = 0;
+ position < strlen(string1) && position < strlen(string2);
+ position++)
+ {
+ if(tolower(string1[position]) < tolower(string2[position]))
+ {
+ retval = -1;
+ break;
+ }
+ else if(tolower(string1[position]) > tolower(string2[position]))
+ {
+ retval = 1;
+ }
+ else
+ {
+ retval = 0;
+ }
+ }
+
+ if(retval == 0 && position < strlen(string1))
+ {
+ retval = 1;
+ }
+ else if(retval == 0 && position < strlen(string2))
+ {
+ retval = 1;
+ }
+
+ return retval;
+}
+
+
+/* Stuff to test the routines. */
+
+/*#define TEST_SKBinTree*/
+#ifdef TEST_SKBinTree
+
+typedef struct
+{
+ int i;
+} t_infodata ;
+
+int process(char *data, t_infodata *infodata)
+{
+ printf("%d, %s\n", infodata->i, data);
+
+ infodata->i++;
+
+ return 0;
+}
+
+void print_node(char *data, int depth)
+{
+ int i;
+ for(i=0; i < depth; i++) printf("*");
+ printf("%s\n", data);
+}
+
+int main(void)
+{
+ t_sktree *root;
+ t_infodata infodata;
+ char instring[500];
+ char *newstring;
+ t_sktree *node;
+
+ infodata.i=0;
+
+ root = NULL;
+
+ while(scanf("%s", instring) && strcmp("quit", instring))
+ {
+ newstring = malloc(strlen(instring)*sizeof(char));
+ strcpy(newstring, instring);
+
+ if(!root)
+ {
+ root = SKTreeStoreData(root, root, newstring, (int (*)(const void *, const void *))strcmp);
+ }
+ else
+ {
+ SKTreeStoreData(root, root, newstring, (int (*)(const void *, const void *))strcmp);
+ }
+ }
+
+ SKTreeTraverseInorder(root, (int (*)(void *, void *))process, (void *)&infodata);
+
+ SKTreePrintNodes(root, 0, (void (*)(void *, int))print_node);
+
+ printf("String to find ? ");
+ scanf("%s", instring);
+
+ node = SKTreeFindNode(root, instring, (int (*)(const void *, const void *))strcmp);
+
+ if(node)
+ {
+ printf("Found a node, node->data is %s\n", node->data);
+ }
+ else
+ {
+ printf("Unable to find node with %s\n", instring);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/src/util/make.code.defn b/src/util/make.code.defn
index 7ba5abf1..a11d4721 100644
--- a/src/util/make.code.defn
+++ b/src/util/make.code.defn
@@ -9,7 +9,9 @@ Misc.c\
getopt.c\
getopt1.c\
StoreHandledData.c\
-gnu_regex.c
+gnu_regex.c\
+SKBinTree.c
+