Blame | Last modification | View Log | Download | RSS feed
/* contains the database functions that store the pin configurations
*
* $Header: c:\\cygwin\\cvsroot/Vert03/vertlib/database.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
* $Log: database.c,v $
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.13 2003/01/02 21:37:15 mjames
* Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
* properties on the nets so that pin jumpers can be made without a problem.
*
* Still need to sort out pin assignments made to these not_routable nets
* which will become legal in some cases so that pullups and pulldown
* pins can be used on the FPGA.
*
* Revision 1.12 2002/09/30 13:26:49 MJAMES
* Upgraded nets to include 'lhs_expression' being the range on the
* left hand side of a signal connection to a port
*
* std_logic_vector (0) <= std_logic , on a port of a chip
*
* Revision 1.11 2002/08/06 12:52:54 mjames
* Merge in from latest version
*
*
* Revision 1.11 2002/03/21 17:13:05 mjames
* Added search path to vertical file opening for read
*
* Revision 1.10 2002/01/15 12:32:42 mjames
* DLL declarations put in,
*
* #ident used
*
* Revision 1.9 2001/11/19 09:45:25 mjames
* Corrected some case statments with no default action
*
* Revision 1.8 2001/10/31 22:20:02 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.7 2001/10/31 16:22:55 mjames
* Added a datastructure to hide regular expression information from programs.
* Changed call to regexec to indicate 0 subexpressions to be matched
* rather than a number dependent on strlen(string) which was wrong.
* Net disconnection works on routed and named nets
*
* Revision 1.6 2001/10/23 21:12:43 mjames
* Created preliminary 'disconnect_node' function
*
* Revision 1.5 2001/10/10 20:18:24 mjames
* Added a vert_regcomp function to compile regular expressions
* with '^' (match start string) and '$' (match end string) bracketing
* this => wildcard must match entire string not just a part of it.
*
* Revision 1.4 2001/10/07 20:50:53 mjames
* Added wildcard checking (warn user about
* using wildcard '*' on the end of a string in stead of wildcard '.*')
*
* Revision 1.3 2001/09/25 23:15:24 mjames
* Converted wildcards to use proper regexp pattern match library
*
* Revision 1.2 2001/06/06 12:10:24 mjames
* Move from HPUX
*
* Revision 1.1.1.1 2000/10/19 21:58:35 mjames
* Mike put it here
*
*
* Revision 1.61 2000/10/04 10:37:03 10:37:03 mjames (Mike James)
* COnversion to Vertical2, supports signals and components
*
* Revision 1.61 2000/10/04 10:37:03 10:37:03 mjames (Mike James)
* Part of Release PSAVAT01
*
* Revision 1.60 2000/10/03 10:05:27 10:05:27 mjames (Mike James)
* Added CONSTANTS and SIGNALS to architecture
*
* Revision 1.58 2000/09/27 14:42:11 14:42:11 mjames (Mike James)
* Part of Release Sep_27_ST_2000
*
* Revision 1.57 2000/09/21 10:15:40 10:15:40 mjames (Mike James)
* Part of Release Sep21Alpha
*
* Revision 1.56 2000/09/21 09:44:29 09:44:29 mjames (Mike James)
* Added in code to deal with pin equivalents, and removed some
* spurious diagnostic puts() calls .
*
* Revision 1.55 2000/08/25 09:57:09 09:57:09 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.54 2000/08/16 08:57:26 08:57:26 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.53 2000/08/14 14:45:07 14:45:07 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.52 2000/08/11 08:30:28 08:30:28 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.51 2000/08/09 10:31:41 10:31:41 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.50 2000/05/31 11:42:48 11:42:48 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.49 2000/05/08 17:01:33 17:01:33 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.48 2000/05/08 16:59:26 16:59:26 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.47 2000/05/08 16:57:03 16:57:03 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.46 2000/03/08 16:18:48 16:18:48 mjames (Mike James)
* New version including PC
*
* Revision 1.43 2000/02/18 15:45:24 15:45:24 mjames (Mike James)
* Amended to support PC
*
* Revision 1.42 2000/01/20 15:58:41 15:58:41 mjames (Mike James)
* Part of Release R22
*
* Revision 1.41 99/12/22 11:15:22 11:15:22 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.40 99/06/25 14:34:42 14:34:42 mjames (Mike James)
* Added in reference to expression.h, but no changes made
* to the function of acfread yet.
*
* Revision 1.39 99/06/18 09:23:19 09:23:19 mjames (Mike James)
*
* Revision 1.38 99/05/04 09:50:36 09:50:36 mjames (Mike James)
* General checkin
*
* Revision 1.34 98/08/12 14:19:52 14:19:52 mjames (Mike James)
* Changed pin definition code to work with VHDL
* parsing
* as well as include file list being updated
*
* Revision 1.33 98/06/15 14:17:51 14:17:51 mjames (Mike James)
* Added socket templating pointers - reference to parent template
* for child template.
*
* Revision 1.32 98/02/11 11:25:52 11:25:52 mjames (Mike James)
* Checked in for version 6.2a
*
* Revision 1.31 98/01/13 11:33:35 11:33:35 mjames (Mike James)
* Added the bility to use a VHDL template file
* containing $ENT$ and $ARCH$ in the position where one
* wants the entity and architecture to be given.
*
* Revision 1.30 97/04/23 08:42:49 08:42:49 mjames (Mike James)
* CHecked in for release rel23041997
*
* Revision 1.29 96/12/23 15:13:48 15:13:48 mjames (Mike James)
* Added reverse pointer to show which unrouted net was
* responsible for the fixing of the pins.
*
* Revision 1.28 96/12/23 10:24:02 10:24:02 mjames (Mike James)
* Altered to make it sort the results
* of listing COMPONENTS and CHIP pins.
* /
*
* Revision 1.27 96/12/13 08:43:08 08:43:08 mjames (Mike James)
* Update to v5.1, added Write ID , exact routing
*
* Revision 1.26 96/08/06 13:38:51 13:38:51 mjames (Mike James)
* Added FIX_LOCATION pin attribute to netlist
*
* Revision 1.25 96/07/19 14:38:43 14:38:43 mjames (Mike James)
* Update to give to PRL
*
* Revision 1.24 1996/07/12 15:52:12 mjames
* Sorted out things like Alias and Jumpers
* Work Correctly
* Print COrrectly
*
* Revision 1.23 96/07/09 15:53:59 15:53:59 mjames (Mike James)
* Altered aliasing to make it hierarchical, also for jumpering
*
* Revision 1.22 96/06/17 11:02:43 11:02:43 mjames (Mike James)
* Altered the printing of JUMPERED and ALIASED nets
* ,
*
* Revision 1.21 96/06/11 14:11:44 14:11:44 mjames (Mike James)
* Added hierarchical jumpering
*
* Revision 1.20 96/06/04 11:53:18 11:53:18 mjames (Mike James)
* Added the ability to jumper nets by reference to a node on the nets
*
* Revision 1.19 96/05/29 10:52:29 10:52:29 mjames (Mike James)
* Added name suffixing to socket ID's and net ID's
*
* Revision 1.18 96/04/26 16:01:30 16:01:30 mjames (Mike James)
* Added SET PORT to force ports on partition
* ,
*
* Revision 1.17 96/04/15 14:19:24 14:19:24 mjames (Mike James)
* Checkin before datatype printing
* modifications
*
* Revision 1.16 96/03/29 14:46:05 14:46:05 mjames (Mike James)
* Added VHDL netlist writing to the capabilities of ACFREAD
*
* Revision 1.14 96/03/18 13:50:28 13:50:28 mjames (Mike James)
* Real Revision 2.1
*
* Revision 1.11 96/03/13 15:35:30 15:35:30 mjames (Mike James)
* Changed the name_pref filed to reflect how a net has been routed
*
* Revision 1.10 96/02/13 09:13:28 09:13:28 mjames (Mike James)
* Updated to be version 2.0 with net joining
*
* Revision 1.9 96/02/09 10:50:24 10:50:24 mjames (Mike James)
* Added different behaviour for 'write id' and 'write name'
* 'write id' now writes all pins including unused ones
* 'write name' only writes used pins in the ACF file
*
* .
*
*
* Revision 1.8 96/02/08 15:28:29 15:28:29 mjames (Mike James)
* First release
*
* Revision 1.7 96/02/07 16:01:34 16:01:34 mjames (Mike James)
* Added correct RCS header
*
* Revision 1.6 96/02/07 15:50:44 15:50:44 mjames (Mike James)
* Added RCS ident message
*
* Revision 1.5 96/02/07 11:04:07 11:04:07 mjames (Mike James)
* Checkin before adding new command parsing to program
*
* Revision 1.4 96/01/10 13:14:11 13:14:11 mjames (Mike James)
* Works in debug mode with EPLD listings and PCB layout
*
* Revision 1.3 96/01/08 15:22:51 15:22:51 mjames (Mike James)
* Managing to make sense of things now
*
* Revision 1.2 96/01/07 20:22:29 Mike_James
* extending database routines
*
* Revision 1.1 96/01/07 12:38:12 Mike_James
* Initial revision
*
* Revision 1.2 96/01/04 17:55:52 17:55:52 mjames (Mike James)
* Correcly reading ACF
*
* Revision 1.1 96/01/04 11:37:22 11:37:22 mjames (Mike James)
* Initial revision
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <regex.h>
#include "vertcl_main.h"
#include "expression.h"
#include "generic.h"
#include "database.h"
#include "lx_support.h"
#include "cmdparse.h"
#include "cmdlog.h"
#include "acf_yacc.h"
#include "chck_names.h"
#include "sorting.h"
#include "version.h"
#ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/database.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $"
vhdl_t * default_vhdl_datatype;
vhdl_t * default_vhdl_bustype;
/* string constants used around the place*/
char nullstr[] = "";
/* database pointers */
__declspec (dllexport) socket_t * socket_head = NULL;
__declspec (dllexport)socket_t * template_head = NULL;
net_t * routed_list = NULL;
net_t * named_list = NULL;
net_t * named_tail = NULL; /* as routed nets are moved to the named list */
net_t * unrouted_list = NULL;
/* these are ident counters. The first counts net identifiers */
static int n_idents = 1; /* net identifiers */
static int s_idents = 1; /* socket identifiers */
static int i_idents = 1; /* pin identifiers */
/* compares two strings case insensitive with a pointer sanity check */
int strcmp2(char * s, char * t)
{
if(!s || !t)
return(-1);
for(;tolower(*s) == tolower(*t);s++,t++)
if(*s==0)
return(0);
return(tolower(*s) - tolower(*t));
}
/* allocates a space for a string */
#if !defined allocstr
/* we now use strdup.... */
char * allocstr(char * s)
{
char * t;
/* added a check for allocating null string
* (its strlen that bombs in CygWin) */
if (!s) return NULL;
t=malloc(strlen(s)+1);
strcpy(t,s);
return t;
}
#endif
/* allocates a space for a string and a suffix dependent on property */
#if defined USE_ALLOCSTR_PROP
static char * allocstr_prop(char * s,property_t prop)
{
char * t;
switch (prop) {
case Ident:
case Type:
case Name:
case Value: t=strdup(s);
break;
}
return t;
}
#endif
/* this is a check on a socket ident - if absent, generates one */
__declspec (dllexport) void ensure_socket_ident(socket_t * chip)
{
char id[10];
if (chip->identifier == nullstr)
{
sprintf(id,"ID%d",s_idents++);
set_socket(chip,Ident,id);
};
}
/* set a socket property */
__declspec (dllexport)void set_socket(socket_t * chip,property_t prop,char * str)
{
char * s;
s = strdup(str);
/* printf("(Set socket prop%d to %s)",prop,s); */
switch(prop)
{
case Ident: chip->identifier = s; break;
case Type: chip->type = s; break;
case Name: chip->name = s; break;
case Value: chip->value = s; break;
default: break;
};
}
/* find a socket property */
__declspec (dllexport) socket_t * find_socket(property_t prop,
char * str,
int srchonly,
socket_t ** headref)
{
socket_t * c=*headref, *p=NULL;
int f=0;
/* printf("-- Socket %s : prop %d pointer=%p\n",str,prop,c); */
while(c)
{
switch(prop)
{
case Ident: f=strcmp2(c->identifier,str)==0;/*puts(c->identifier); */ break;
case Type: f=strcmp2(c->type,str)==0; break;
case Name: f=strcmp2(c->name,str)==0; /*puts(c->name);*/ break;
case Value: f=strcmp2(c->value,str)==0; break;
default : break; /* never find if wrong field specified */
};
if(f) break;
p=c;
c=c->next;
};
if(srchonly || f )
return(c);
c=calloc(1,sizeof(socket_t)); /* all pointers are set to be null */
c->identifier = nullstr;
c->type = nullstr;
c->name = nullstr;
c->value = nullstr;
set_socket(c,prop,allocstr(str));
/* link in otherwise */
if(p)
p->next = c;
if (!(*headref))
*headref = c;
return c;
}
/* matches s into a table of n strings r[], default value is d */
int str_to_int(char * s,char * r[],int n,int d)
{
int i;
for(i=0;i<n;i++)
if(strcmp2(s,r[i])==0)
{
d=i;
break;
};
return d;
}
char * decode_how_routed[]= {
"FREE_NAME",
"MATCHED_NAME",
"USED_WIRES",
"USED_FIXED_WIRES",
"USED_EXACT_WIRES",
"CREATED_NET",
"CREATED_JUMPER",
"FIXED_PINS",
"NOT_ROUTABLE",
"NOT_ROUTABLE_L", /* additions V16.5 onward */
"NOT_ROUTABLE_H"
};
/* set a net property */
__declspec (dllexport) void set_net(net_t * net,property_t prop,char * str)
{
char * s;
s = strdup(str);
switch(prop)
{
case Ident: net->identifier = s; break;
case Name: net->name = s; break;
/*
case Datatype: net->datatype = s; break;
*/
case How_Routed:
net->how_routed = (HowRouted_t)str_to_int(str,
decode_how_routed,
sizeof(decode_how_routed)/sizeof(char *),
0);
break;
default: break;
};
}
/* find a net by property, in a list pointed to by a pointer referred to
by net_head */
__declspec (dllexport) net_t * find_net(net_t ** net_head,property_t prop,char * str,int srchonly )
{
net_t * c, *p;
int f=0;
c= *net_head;
p=NULL;
while(c)
{
switch(prop)
{
case Ident: f=strcmp2(c->identifier,str)==0; break;
case Name: f=strcmp2(c->name,str)==0; break;
default: break;
};
if(f)
break;
p=c;
c=c->next;
};
if(srchonly || f)
return(c);
c=calloc(1,sizeof(net_t)); /* all pointers are set to be null */
c->name = nullstr;
c->identifier = nullstr;
c->list_ref = net_head; /* record which list this net is a member of */
c->nodecount = 0; /* calloc does this : put here for readability : Oct 2000 */
c->type_defined= 0;
set_net(c,prop,str);
c->list_ref = net_head; /* which list does this net begin life on */
/* link at end of list otherwise */
if(p)
p->next = c;
c->prev = p; /* and refer back to it */
if (!(*net_head))
*net_head = c;
return c;
}
/* set a node property */
__declspec (dllexport) void set_node(node_t * node,property_t prop,char * str)
{
char * s;
s = strdup(str);
switch(prop)
{
case Ident: node->identifier = s; break;
case Name: node->name = s; break;
/*
case Datatype: node->datatype = s; break;
*/
default: break;
};
}
/* locate a node on a chip by a property */
__declspec (dllexport) node_t * find_node(socket_t * socket,
property_t prop,
char * str,
int srchonly)
{
node_t * c, *p;
int f=0;
/* catch null pointer reference 23 May 2001 */
if (!socket)
return NULL;
c=socket->nodes;
p=NULL;
while(c)
{
switch(prop)
{
case Ident: f=strcmp2(c->identifier,str)==0; break;
case Name: f=strcmp2(c->name,str)==0; break;
/* case Datatype: f=strcmp2(c->datatype,str)==0; break; */
default: break;
};
if(f)
break;
p=c;
c=c->sktnext;
};
if(srchonly || f)
return(c);
c=calloc(1,sizeof(node_t)); /* all pointers are set to be null */
c->name = nullstr;
c->identifier = nullstr;
c->socket = socket;
set_node(c,prop,str);
/* link at end of list otherwise */
if(p)
p->sktnext = c;
if(!socket->nodes)
socket->nodes = c;
socket->lastnode = c;
return c;
}
/* this connects the node to the list of node references on the net and
connects the net to the list of net references on the node */
__declspec (dllexport) void connect_node_net( char * orig_name,
node_t * cnode,
net_t * cnet,
pindir_t pintype,
vhdl_t * vhdl,
vhdl_t * orig_vhdl,
expression_t * lhs_expr)
{
noderef_t * noderef;
cnet->nodecount++; /* one more node on this net */
cnode->net = cnet; /* refer back to net this node is on */
cnode->refcount++; /* and count references */
noderef = calloc(1,sizeof(noderef_t));
noderef->net = cnet; /* this node reference refers back to its parent net */
noderef->pindir = pintype; /* the reference has the pin direction _wanted_ */
noderef->orig_name = orig_name; /* copy any alias over */
/* remeved reference to datatype */
noderef->vhdltype = vhdl;
noderef->orig_vhdltype = orig_vhdl;
noderef->base_noderef = noderef; /* its original reference is itself */
noderef->lhs_expr = lhs_expr;
/* link node reference to the net */
noderef->next = cnet->nodes;
cnet->nodes = noderef; /* place reference on head of list */
noderef->node = cnode;
}
/* disconnect a node from the netlist */
/* this intends to remove chip node from net in the routed list. If anyone has made a reference to the node
in a manner which results in this node reappearing then there will be a problem as it will
reappear (some route algorithms eg. create will do this) */
__declspec (dllexport) void disconnect_node(socket_t * chip, node_t * node)
{
noderef_t * ref, * last_ref;
/* locate the net on the routed or named list */
if(node->net && (node->net->list_ref== &routed_list || node->net->list_ref== &named_list))
{
net_t * net;
net = node->net;
ref = net->nodes;
last_ref = NULL;
/* locate the reference made */
while(ref)
{
if (ref->node == node)
break;
last_ref = ref;
ref = ref->next;
}
/* reference is located. Remove from list of node references,
also patch up list head if needed */
if(ref)
{
if(last_ref == NULL)
{
net->nodes = ref->next;
}
else
{
last_ref->next = ref->next;
}
free(ref);
node->net = NULL; /* disconnect the ned from the node */
node->refcount = node->refcount ? node->refcount--: 0 ;
}
}
}
__declspec (dllexport) void define_pin(net_t ** net_head,
socket_t * chip,
char * i_name,
int pin_type,
int pin_group,
char * i_identifier,
vhdl_t * vhdl,
expression_t * lhs_expr)
{
unrouted_ref_t * ref, *ptr;
int null_name;
char name[MAXIDLEN];
char identifier[MAXIDLEN];
/* actions here are :
1: find a new node;
2: attach a reference to it to the socket pin list;
3: find the net it is joined to by name;
*/
null_name = ISNULLSTR(i_name);
/* if the name is not given, then dont create a net for it as it
is a waste of time */
if(null_name)
/* count another ident for posisble use */
sprintf(name,"NE%d",n_idents++);
else
strcpy(name,i_name);
if(ISNULLSTR(i_identifier))
/* count another ident for posisble use */
sprintf(identifier,"ID%d",i_idents++);
else
strcpy(identifier,i_identifier);
/* printf("-- Joining name %s to pin %s\n",name,identifier );
*/
/* at this stage, simply create a potential reference */
ref = calloc(1,sizeof(unrouted_ref_t));
ref->pindir = pin_type; /* the reference has the pin direction _wanted_ */
ref->pin_group = pin_group;
/* removed reference to datatype */
ref->vhdltype = copy_vhdl(vhdl,chip);
ref->orig_vhdltype = NULL;
ref->identifier = allocstr(identifier);
ref->name = allocstr(name);
ref->orig_name = NULL;
ref->listref = net_head; /* identify the list context */
ref->lhs_expr = lhs_expr;
ref->next = NULL;
if(!chip->unrouted_refs)
chip->unrouted_refs = ref;
else {
ptr = chip->unrouted_refs;
while(ptr->next)
ptr=ptr->next;
ptr->next = ref;
}
/* splice the unrouted reference on */
ref->next = NULL;
}
/* this function clears the name fields on identified nets */
static void del_list_net_names(net_t * list,char * template )
{
int rc,found;
char * pattern;
/* compile regular expression */
vert_regex_t * preg;
if (template)
{
pattern = template;
}
else
{
pattern = ".*";
}
rc = vert_regcomp(&preg,pattern);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,preg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,pattern);
return /*TCL_ERROR*/;
}
Log(LOG_GENERAL,"-- Beginning clearing name fields : net ID prefix '%s' --\n",
template?template:"[ALL ID's]");
while(list) {
found = regexec(preg->preg,list->identifier,0,preg->regpatt,0);
if(!found) {
Log(LOG_GENERAL,"-- Cleared name field for net ID '%s'\n",list->identifier);
list->name = nullstr;
}
list = list->next;
}
Log(LOG_GENERAL,"-- Finished clearing name fields --\n");
vert_regfree(&preg);
}
__declspec (dllexport)void del_net_names(char * template )
{
del_list_net_names(routed_list,template );
}
/* added 8 March 2000 for PC support */
__declspec (dllexport) void ensure_env_var(char * name, char * defval) {
generic_info_t gen[1];
if (get_generic_value(&global_generics, name,gen) != IS_STRING) {
char sbuff [MAXIDLEN];
gen->name = name;
gen->typename = "env_string";
/* cannot use $(1) type command line variables as
*they are not passed here : argc = 0 , argv = NULL*/
expand_string(defval , sbuff,0 , NULL);
gen->expr = compile_string(sbuff);
gen->g_type = IS_ENV_VAL;
gen->g_class = DEFAULT;
set_generic_value(&global_generics,gen );
};
}
/* initialise default information used around the design database */
__declspec (dllexport) void InitialiseData(void) {
generic_info_t gen[1];
InitialiseVersionStrings();
if (!default_vhdl_datatype)
default_vhdl_datatype= calloc(1,sizeof(vhdl_t));
if (!default_vhdl_bustype)
default_vhdl_bustype = calloc(1,sizeof(vhdl_t));
/* if we are using VHDL then look at the VHDL bus formatting tail*/
if (get_generic_value(&global_generics, "vhdl_bit_type",gen) == IS_STRING) {
default_vhdl_datatype->basetype = strdup( gen->expr->left.s );
}
else
default_vhdl_datatype->basetype = "std_logic";
/* if we are using VHDL then look at the VHDL bus formatting tail*/
if (get_generic_value(&global_generics, "vhdl_bus_type",gen) == IS_STRING) {
default_vhdl_bustype->basetype = strdup( gen->expr->left.s);
}
else
default_vhdl_bustype->basetype = "std_logic_vector";
default_vhdl_bustype->expr = compile_expression(TO,compile_constant(0),compile_constant(0));
default_vhdl_bustype->is_vector=1; /* is this port a vector */
default_vhdl_bustype->is_downto=1; /* is the vector X TO Y or X DOWNTO Y */
/* look up VERTICAL_INIT and give it a default value if unknown */
ensure_env_var("VERTICAL_INIT",VERTICAL_INI_PATH);
ensure_env_var("VERTICAL_PATH",VERTICAL_PATH);
}
__declspec (dllexport) char * decode_which_list(net_t ** list_head) {
if(list_head == NULL) return "No List";
if(list_head == &routed_list) return "routed list";
if(list_head == &named_list) return "named list";
if(list_head == &unrouted_list) return "unrouted list";
return "ERROR : unknown";
}