summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
+