/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "globals.h"
#include "read_blif.h"
#include "string_cache.h"
#include "netlist_utils.h"

#include "simulator_bit_map.h"
#include "netlist_utils.h"
#include "types.h"
#include "hashtable.h"
#include "netlist_check.h"
#include "simulate_blif.h"
#include "vtr_util.h"
#include "vtr_memory.h"

#define TOKENS     " \t\n"
#define GND_NAME   "gnd"
#define VCC_NAME   "vcc"
#define HBPAD_NAME "unconn"

#define READ_BLIF_BUFFER 1048576 // 1MB

size_t file_line_number;

const char *BLIF_ONE_STRING    = "ONE_VCC_CNS";
const char *BLIF_ZERO_STRING   = "ZERO_GND_ZERO";
const char *BLIF_PAD_STRING    = "ZERO_PAD_ZERO";
const char *DEFAULT_CLOCK_NAME = "top^clock";

// Stores pin names of the form port[pin]
typedef struct {
	int count;
	char **names;
	// Maps name to index.
	hashtable_t *index;
} hard_block_pins;

// Stores port names, and their sizes.
typedef struct {
	char *signature;
	int count;
	int *sizes;
	char **names;
	// Maps portname to index.
	hashtable_t *index;
} hard_block_ports;

// Stores all information pertaining to a hard block model. (.model)
typedef struct {
	char *name;

	hard_block_pins *inputs;
	hard_block_pins *outputs;

	hard_block_ports *input_ports;
	hard_block_ports *output_ports;
} hard_block_model;

// A cache structure for models.
typedef struct {
	hard_block_model **models;
	int count;
	// Maps name to model
	hashtable_t *index;
} hard_block_models;


//netlist_t * verilog_netlist;
short static skip_reading_bit_map=FALSE;

void rb_create_top_driver_nets(const char *instance_name_prefix, hashtable_t *output_nets_hash);
void rb_look_for_clocks();// not sure if this is needed
void add_top_input_nodes(FILE *file, hashtable_t *output_nets_hash);
void rb_create_top_output_nodes(FILE *file);
int read_tokens (char *buffer, hard_block_models *models, FILE *file, hashtable_t *output_nets_hash);
static void dum_parse (char *buffer, FILE *file);
void create_internal_node_and_driver(FILE *file, hashtable_t *output_nets_hash);
short assign_node_type_from_node_name(char * output_name);// function will decide the node->type of the given node
operation_list read_bit_map_find_unknown_gate(int input_count, nnode_t *node, FILE *file, char *parent_node_name);
void create_latch_node_and_driver(FILE *file, hashtable_t *output_nets_hash);
void create_hard_block_nodes(hard_block_models *models, FILE *file, hashtable_t *output_nets_hash);
void hook_up_nets(hashtable_t *output_nets_hash);
void hook_up_node(nnode_t *node, hashtable_t *output_nets_hash);
char* search_clock_name(FILE *file);
void free_hard_block_model(hard_block_model *model);
char *get_hard_block_port_name(char *name);
long get_hard_block_pin_number(char *original_name);
static int compare_hard_block_pin_names(const void *p1, const void *p2);
hard_block_ports *get_hard_block_ports(char **pins, int count);
hashtable_t *index_names(char **names, int count);
hashtable_t *associate_names(char **names1, char **names2, int count);
void free_hard_block_pins(hard_block_pins *p);
void free_hard_block_ports(hard_block_ports *p);


hard_block_model *get_hard_block_model(char *name, hard_block_ports *ports, hard_block_models *models);
void add_hard_block_model(hard_block_model *m, hard_block_ports *ports, hard_block_models *models);
char *generate_hard_block_ports_signature(hard_block_ports *ports);
int verify_hard_block_ports_against_model(hard_block_ports *ports, hard_block_model *model);
hard_block_model *read_hard_block_model(char *name_subckt, hard_block_ports *ports, FILE *file);


void free_hard_block_models(hard_block_models *models);

hard_block_models *create_hard_block_models();

int count_blif_lines(FILE *file);

/*
 * Reads a blif file with the given filename and produces
 * a netlist which is referred to by the global variable
 * "verilog_netlist".
 */
void read_blif(char * blif_file)
{
	char local_blif[255];
	odin_sprintf(local_blif, "%s", blif_file);

	verilog_netlist = allocate_netlist();
	/*Opening the blif file */
	FILE *file = vtr::fopen (local_blif, "r");

	int num_lines = count_blif_lines(file);

	hashtable_t *output_nets_hash = create_hashtable((num_lines) + 1);

	printf("Reading top level module\n"); fflush(stdout);
	/* create the top level module */
	rb_create_top_driver_nets("top", output_nets_hash);

	/* Extracting the netlist by reading the blif file */
	printf("Reading blif netlist..."); fflush(stdout);

	file_line_number  = 0;
	int line_count = 0;
	int position   = -1;
	double time    = wall_time();
	// A cache of hard block models indexed by name. As each one is read, it's stored here to be used again.
	hard_block_models *models = create_hard_block_models();
	printf("\n");
	char buffer[READ_BLIF_BUFFER];
	while (vtr::fgets(buffer, READ_BLIF_BUFFER, file) && read_tokens(buffer, models, file, output_nets_hash))
	{	// Print a progress bar indicating completeness.
		position = print_progress_bar((++line_count)/(double)num_lines, position, 50, wall_time() - time);
	}
	free_hard_block_models(models);
	/* Now look for high-level signals */
	rb_look_for_clocks();
	// We the estimate of completion is rough...make sure we end up at 100%. ;)
	print_progress_bar(1.0, position, 50, wall_time() - time);
	printf("-------------------------------------\n"); fflush(stdout);

	// Outputs netlist graph.
	check_netlist(verilog_netlist);
	output_nets_hash->destroy(output_nets_hash);
	fclose (file);
}

/*---------------------------------------------------------------------------------------------
 * (function: read_tokens)
 *
 * Parses the given line from the blif file. Returns TRUE if there are more lines
 * to read.
 *-------------------------------------------------------------------------------------------*/
int read_tokens (char *buffer, hard_block_models *models, FILE *file, hashtable_t *output_nets_hash)
{
	/* Figures out which, if any token is at the start of this line and *
	 * takes the appropriate action.                                    */
	char *token = vtr::strtok (buffer, TOKENS, file, buffer);

	if (token)
	{
		if(skip_reading_bit_map && !token && ((token[0] == '0') || (token[0] == '1') || (token[0] == '-')))
		{
			dum_parse(buffer, file);
		}
		else
		{
			skip_reading_bit_map= FALSE;
			if (strcmp (token, ".inputs") == 0)
			{
				add_top_input_nodes(file, output_nets_hash);// create the top input nodes
			}
			else if (strcmp (token, ".outputs") == 0)
			{
				rb_create_top_output_nodes(file);// create the top output nodes
			}
			else if (strcmp (token, ".names") == 0)
			{
				create_internal_node_and_driver(file, output_nets_hash);
			}
			else if (strcmp(token,".latch") == 0)
			{
				create_latch_node_and_driver(file, output_nets_hash);
			}
			else if (strcmp(token,".subckt") == 0)
			{
				create_hard_block_nodes(models, file, output_nets_hash);
			}
			else if (strcmp(token,".end")==0)
			{
				// Marks the end of the main module of the blif
				// Call function to hook up the nets
				hook_up_nets(output_nets_hash);
				return FALSE;
			}
			else if (strcmp(token,".model")==0)
			{
				// Ignore models.
				dum_parse(buffer, file);
			}
		}
	}
	return TRUE;
}


/*---------------------------------------------------------------------------------------------
   * function:assign_node_type_from_node_name(char *)
     This function tries to assign the node->type by looking at the name
     Else return GENERIC
*-------------------------------------------------------------------------------------------*/
short assign_node_type_from_node_name(char * output_name)
{
	//variable to extract the type
	int start, end;
	int length_string = strlen(output_name);
	for(start = length_string-1; (start >= 0) && (output_name[start] != '^'); start--);
	for(end   = length_string-1; (end   >= 0) && (output_name[end]   != '~'); end--  );

	if((start < end) && (end))
	{
		// Stores the extracted string
		char last = output_name[end];
		output_name[end] = '\0';
		std::string extracted_string(&output_name[start+1]);
		output_name[end] = last;

		for(short i=NO_OP+1; i<LAST_OP; i++)
		{
			operation_list op = (operation_list)i;
			if( std::string(operation_name(op)) == extracted_string )
				return op;
		}
	}

	return GENERIC;
}

/*---------------------------------------------------------------------------------------------
   * function:create_latch_node_and_driver
     to create an ff node and driver from that node
     format .latch <input> <output> [<type> <control/clock>] <initial val>
*-------------------------------------------------------------------------------------------*/
void create_latch_node_and_driver(FILE *file, hashtable_t *output_nets_hash)
{
	/* Storing the names of the input and the final output in array names */
	char ** names = NULL;       // Store the names of the tokens
	int input_token_count = 0; /*to keep track whether controlling clock is specified or not */
	/*input_token_count=3 it is not and =5 it is */
	char *ptr;
	char buffer[READ_BLIF_BUFFER];
	while ((ptr = vtr::strtok (NULL, TOKENS, file, buffer)) != NULL)
	{
		if(input_token_count == 0)
			names = (char**)vtr::malloc((sizeof(char*)));
		else
			names = (char**)vtr::realloc(names, (sizeof(char*))* (input_token_count + 1));
		names[input_token_count++] = vtr::strdup(ptr);
	}

	/* assigning the new_node */
	if(input_token_count == 5)
	{
		/* supported added for the ABC .latch output without control */
		if(input_token_count == 3)
		{
			char *clock_name = search_clock_name(file);
			input_token_count = 5;
			names = (char**)vtr::realloc(names, sizeof(char*) * input_token_count);

			if(clock_name) names[3] = vtr::strdup(clock_name);
			else           names[3] = NULL;

			names[4] = vtr::strdup(names[2]);
			names[2] = vtr::strdup("re");
		}
		else
		{
			error_message(NETLIST_ERROR,file_line_number,-1, "This .latch Format not supported \n\t required format :.latch <input> <output> [<type> <control/clock>] <initial val>");
		}
	}

	nnode_t *new_node = allocate_nnode();
	new_node->related_ast_node = NULL;
	new_node->type = FF_NODE;

	/* Read in the initial value of the latch.
	   Possible values from a blif file are:
	   0: LOW
	   1: HIGH
	   2: DON'T CARE
	   3: UNKNOWN

	   2 and 3 are treated in the same way */
	int initial_value = atoi(names[4]);
	if(initial_value == 0 || initial_value == 1){
		new_node->initial_value = initial_value;
		new_node->has_initial_value = TRUE;
	}

	/* allocate the output pin (there is always one output pin) */
	allocate_more_output_pins(new_node, 1);
	add_output_port_information(new_node, 1);

	/* allocate the input pin */
	allocate_more_input_pins(new_node,2);/* input[1] is clock */

	/* add the port information */
	int i;
	for(i = 0; i < 2; i++)
	{
		add_input_port_information(new_node,1);
	}

	/* add names and type information to the created input pins */
	npin_t *new_pin = allocate_npin();
	new_pin->name = names[0];
	new_pin->type = INPUT;
	add_input_pin_to_node(new_node, new_pin,0);

	new_pin = allocate_npin();
	new_pin->name = names[3];
	new_pin->type = INPUT;
	add_input_pin_to_node(new_node, new_pin,1);

	/* add a name for the node, keeping the name of the node same as the output */
	new_node->name = make_full_ref_name(names[1],NULL, NULL, NULL,-1);

	/*add this node to verilog_netlist as an ff (flip-flop) node */
	verilog_netlist->ff_nodes = (nnode_t **)vtr::realloc(verilog_netlist->ff_nodes, sizeof(nnode_t*)*(verilog_netlist->num_ff_nodes+1));
	verilog_netlist->ff_nodes[verilog_netlist->num_ff_nodes++] = new_node;

	/*add name information and a net(driver) for the output */
	nnet_t *new_net = allocate_nnet();
	new_net->name = new_node->name;

	new_pin = allocate_npin();
	new_pin->name = new_node->name;
	new_pin->type = OUTPUT;
	add_output_pin_to_node(new_node, new_pin, 0);
	add_driver_pin_to_net(new_net, new_pin);

	output_nets_hash->add(output_nets_hash, new_node->name, strlen(new_node->name)*sizeof(char), new_net);

	/* Free the char** names */
	vtr::free(names);
	vtr::free(ptr);
}

/*---------------------------------------------------------------------------------------------
   * function: search_clock_name
     to search the clock if the control in the latch
     is not mentioned
*-------------------------------------------------------------------------------------------*/
char* search_clock_name(FILE* file)
{
	fpos_t pos;
	int last_line = file_line_number;
	fgetpos(file,&pos);
	rewind(file);

	char ** input_names = NULL;
	int input_names_count = 0;
	int found = 0;
	while(!found)
	{
		char buffer[READ_BLIF_BUFFER];
		vtr::fgets(buffer,READ_BLIF_BUFFER,file);

		// not sure if this is needed
		if(feof(file))
			break;

		char *ptr;
		if((ptr = vtr::strtok(buffer, TOKENS, file, buffer)))
		{
			if(!strcmp(ptr,".end"))
				break;

			if(!strcmp(ptr,".inputs"))
			{
				/* store the inputs in array of string */
				while((ptr = vtr::strtok (NULL, TOKENS, file, buffer)))
				{
					input_names = (char**)vtr::realloc(input_names,sizeof(char*) * (input_names_count + 1));
					input_names[input_names_count++] = vtr::strdup(ptr);
				}
			}
			else if(!strcmp(ptr,".names") || !strcmp(ptr,".latch"))
			{
				while((ptr = vtr::strtok (NULL, TOKENS,file, buffer)))
				{
					int i;
					for(i = 0; i < input_names_count; i++)
					{
						if(!strcmp(ptr,input_names[i]))
						{
							vtr::free(input_names[i]);
							input_names[i] = input_names[--input_names_count];
						}
					}
				}
			}
			else if(input_names_count == 1)
			{
				found = 1;
			}
		}
	}
	file_line_number = last_line;
	fsetpos(file,&pos);

	if (found) return input_names[0];
	else       return vtr::strdup(DEFAULT_CLOCK_NAME);
}



/*---------------------------------------------------------------------------------------------
   * function:create_hard_block_nodes
     to create the hard block nodes
*-------------------------------------------------------------------------------------------*/
void create_hard_block_nodes(hard_block_models *models, FILE *file, hashtable_t *output_nets_hash)
{
	char buffer[READ_BLIF_BUFFER];
	char *subcircuit_name = vtr::strtok (NULL, TOKENS, file, buffer);

	/* storing the names on the formal-actual parameter */
	char *token;
	int count = 0;
	// Contains strings of the form port[pin]=port~pin
	char **names_parameters = NULL;
	while ((token = vtr::strtok (NULL, TOKENS, file, buffer)) != NULL)
  	{
		names_parameters          = (char**)vtr::realloc(names_parameters, sizeof(char*)*(count + 1));
		names_parameters[count++] = vtr::strdup(token);
  	}

	// Split the name parameters at the equals sign.
	char **mappings = (char**)vtr::malloc(sizeof(char*) * count);
	char **names    = (char**)vtr::malloc(sizeof(char*) * count);
	int i = 0;
	for (i = 0; i < count; i++)
	{
		mappings[i] = vtr::strdup(strtok(names_parameters[i], "="));
		names[i]    = vtr::strdup(strtok(NULL, "="));
	}

	// Associate mappings with their connections.
	hashtable_t *mapping_index = associate_names(mappings, names, count);

	// Sort the mappings.
	qsort(mappings,  count,  sizeof(char *), compare_hard_block_pin_names);

	for(i = 0; i < count; i++)
		vtr::free(names_parameters[i]);

	vtr::free(names_parameters);

	// Index the mappings in a hard_block_ports struct.
	hard_block_ports *ports = get_hard_block_ports(mappings, count);

	// Look up the model in the models cache.
 	hard_block_model *model;
 	if (!(model = get_hard_block_model(subcircuit_name, ports, models)))
 	{
 		// If the model isn's present, scan ahead and find it.
 		model = read_hard_block_model(subcircuit_name, ports, file);
 		// Add it to the cache.
 		add_hard_block_model(model, ports, models);
 	}

	nnode_t *new_node = allocate_nnode();

	// Name the node subcircuit_name~hard_block_number so that the name is unique.
	static long hard_block_number = 0;
	odin_sprintf(buffer, "%s~%ld", subcircuit_name, hard_block_number++);
	new_node->name = make_full_ref_name(buffer, NULL, NULL, NULL,-1);

	// Determine the type of hard block.
	char *subcircuit_name_prefix = vtr::strdup(subcircuit_name);
	subcircuit_name_prefix[5] = '\0';
	if (!strcmp(subcircuit_name, "multiply") || !strcmp(subcircuit_name_prefix, "mult_"))
		new_node->type = MULTIPLY;
	else if (!strcmp(subcircuit_name, "adder") || !strcmp(subcircuit_name_prefix, "adder"))
		new_node->type = ADD;
	else if (!strcmp(subcircuit_name, "sub") || !strcmp(subcircuit_name_prefix, "sub"))
			new_node->type = MINUS;
	else
		new_node->type = MEMORY;
	vtr::free(subcircuit_name_prefix);

	/* Add input and output ports to the new node. */
	{
		hard_block_ports *p;
		p = model->input_ports;
		for (i = 0; i < p->count; i++)
			add_input_port_information(new_node, p->sizes[i]);

		p = model->output_ports;
		for (i = 0; i < p->count; i++)
			add_output_port_information(new_node, p->sizes[i]);
	}

	// Allocate pins positions.
	if (model->inputs->count  > 0)
		allocate_more_input_pins (new_node, model->inputs->count);
	if (model->outputs->count > 0)
		allocate_more_output_pins(new_node, model->outputs->count);

	// Add input pins.
  	for(i = 0; i < model->inputs->count; i++)
  	{
  		char *mapping = model->inputs->names[i];
  		char *name    = (char *)mapping_index->get(mapping_index, mapping, strlen(mapping) * sizeof(char));

  		if (!name)
  			error_message(NETLIST_ERROR, file_line_number, -1, "Invalid hard block mapping: %s", mapping);

		npin_t *new_pin = allocate_npin();
		new_pin->name = vtr::strdup(name);
		new_pin->type = INPUT;
		new_pin->mapping = get_hard_block_port_name(mapping);

		add_input_pin_to_node(new_node, new_pin, i);
  	}

	// Add output pins, nets, and index each net.
  	for(i = 0; i < model->outputs->count; i++)
  	{
  		char *mapping = model->outputs->names[i];
  		char *name = (char *)mapping_index->get(mapping_index, mapping, strlen(mapping) * sizeof(char));

  		if (!name) error_message(NETLIST_ERROR, file_line_number, -1,"Invalid hard block mapping: %s", model->outputs->names[i]);

		npin_t *new_pin = allocate_npin();
		new_pin->name = vtr::strdup(name);
		new_pin->type = OUTPUT;
		new_pin->mapping = get_hard_block_port_name(mapping);

		add_output_pin_to_node(new_node, new_pin, i);

		nnet_t *new_net = allocate_nnet();
		new_net->name = vtr::strdup(name);

		add_driver_pin_to_net(new_net,new_pin);

		// Index the net by name.
		output_nets_hash->add(output_nets_hash, name, strlen(name)*sizeof(char), new_net);
	}

  	// Create a fake ast node.
	new_node->related_ast_node = (ast_node_t *)vtr::calloc(1, sizeof(ast_node_t));
	new_node->related_ast_node->children = (ast_node_t **)vtr::calloc(1,sizeof(ast_node_t *));
	new_node->related_ast_node->children[0] = (ast_node_t *)vtr::calloc(1, sizeof(ast_node_t));
	new_node->related_ast_node->children[0]->types.identifier = vtr::strdup(subcircuit_name);

  	/*add this node to verilog_netlist as an internal node */
  	verilog_netlist->internal_nodes = (nnode_t **)vtr::realloc(verilog_netlist->internal_nodes, sizeof(nnode_t*) * (verilog_netlist->num_internal_nodes + 1));
  	verilog_netlist->internal_nodes[verilog_netlist->num_internal_nodes++] = new_node;

  	free_hard_block_ports(ports);
  	mapping_index->destroy_free_items(mapping_index);
  	vtr::free(mappings);
  	vtr::free(names);


}

/*---------------------------------------------------------------------------------------------
   * function:create_internal_node_and_driver
     to create an internal node and driver from that node
*-------------------------------------------------------------------------------------------*/

void create_internal_node_and_driver(FILE *file, hashtable_t *output_nets_hash)
{
	/* Storing the names of the input and the final output in array names */
	char *ptr;
	char **names = NULL; // stores the names of the input and the output, last name stored would be of the output
	int input_count = 0;
	char buffer[READ_BLIF_BUFFER];
	while ((ptr = vtr::strtok (NULL, TOKENS, file, buffer)))
	{
		names = (char**)vtr::realloc(names, sizeof(char*) * (input_count + 1));
		names[input_count++]= vtr::strdup(ptr);
	}

	/* assigning the new_node */
	nnode_t *new_node = allocate_nnode();
	new_node->related_ast_node = NULL;

	/* gnd vcc unconn already created as top module so ignore them */
	if (
			   !strcmp(names[input_count-1],"gnd")
			|| !strcmp(names[input_count-1],"vcc")
			|| !strcmp(names[input_count-1],"unconn")
	)
	{
		skip_reading_bit_map = TRUE;
	}
	else
	{
		/* allocate the input pin (= input_count-1)*/
		if (input_count-1 > 0) // check if there is any input pins
		{
			allocate_more_input_pins(new_node, input_count-1);
			for(int i = 0; i < input_count-1; i++)
				add_input_port_information(new_node, 1);
		}

		/* add names and type information to the created input pins */
		int i;
		for(i = 0; i <= input_count-2; i++)
		{
			npin_t *new_pin = allocate_npin();
			new_pin->name = names[i];
			new_pin->type = INPUT;
			add_input_pin_to_node(new_node, new_pin, i);
		}
		/* add a name for the node, keeping the name of the node same as the output */
		new_node->name = make_full_ref_name(names[input_count-1],NULL, NULL, NULL,-1);

		new_node->type = read_bit_map_find_unknown_gate(input_count-1, new_node, file, new_node->name);
		skip_reading_bit_map = TRUE;
	



		/* add information for the intermediate VCC and GND node (appears in ABC )*/
		if(new_node->type == GND_NODE)
		{
			allocate_more_input_pins(new_node,1);
			add_input_port_information(new_node, 1);

			npin_t *new_pin = allocate_npin();
			new_pin->name = vtr::strdup(GND_NAME);
			new_pin->type = INPUT;
			add_input_pin_to_node(new_node, new_pin,0);
		}

		if(new_node->type == VCC_NODE)
		{
			allocate_more_input_pins(new_node,1);
			add_input_port_information(new_node, 1);

			npin_t *new_pin = allocate_npin();
			new_pin->name = vtr::strdup(VCC_NAME);
			new_pin->type = INPUT;
			add_input_pin_to_node(new_node, new_pin,0);
		}

		/* allocate the output pin (there is always one output pin) */
		allocate_more_output_pins(new_node, 1);
		add_output_port_information(new_node, 1);

		/* add a name for the node, keeping the name of the node same as the output */
		new_node->name = make_full_ref_name(names[input_count-1],NULL, NULL, NULL,-1);

		/*add this node to verilog_netlist as an internal node */
		verilog_netlist->internal_nodes = (nnode_t**)vtr::realloc(verilog_netlist->internal_nodes, sizeof(nnode_t*)*(verilog_netlist->num_internal_nodes+1));
		verilog_netlist->internal_nodes[verilog_netlist->num_internal_nodes++] = new_node;

		/*add name information and a net(driver) for the output */

		npin_t *new_pin = allocate_npin();
		new_pin->name = new_node->name;
		new_pin->type = OUTPUT;

		add_output_pin_to_node(new_node, new_pin, 0);

		nnet_t *new_net = allocate_nnet();
		new_net->name = new_node->name;

		add_driver_pin_to_net(new_net,new_pin);

		output_nets_hash->add(output_nets_hash, new_node->name, strlen(new_node->name)*sizeof(char), new_net);

		/* Free the char** names */
		vtr::free(names);
	}
}

/*
*---------------------------------------------------------------------------------------------
   * function: read_bit_map_find_unknown_gate
     read the bit map for simulation
*-------------------------------------------------------------------------------------------*/
operation_list read_bit_map_find_unknown_gate(int input_count, nnode_t *node, FILE *file, char *parent_node_name)
{
	fpos_t pos;
	int last_line = file_line_number;
	fgetpos(file,&pos);

	if(!input_count)
	{
		char buffer[READ_BLIF_BUFFER];
		vtr::fgets (buffer, READ_BLIF_BUFFER, file);

		file_line_number = last_line;
		fsetpos(file,&pos);

		char *ptr = vtr::strtok(buffer,TOKENS, file, buffer);
		if      (!strcmp(ptr,"0")) return GND_NODE;
		else if (!strcmp(ptr,"1")) return VCC_NODE;
		else if (!ptr)              return GND_NODE;
		else                        return VCC_NODE;
	}

	std::vector<std::string> bit_map;
	std::vector<char> output_bit_map;
	char buffer[READ_BLIF_BUFFER];
	while(1)
	{
		vtr::fgets (buffer, READ_BLIF_BUFFER, file);
		if(!(buffer[0] == '0' || buffer[0] == '1' || buffer[0] == '-'))
			break;

		bit_map.push_back(vtr::strtok(buffer,TOKENS, file, buffer));
		char *tmp = vtr::strtok(NULL,TOKENS, file, buffer);
		output_bit_map.push_back(tmp[0]);
	}

	file_line_number = last_line;
	fsetpos(file,&pos);
	node->orig_bit_map = bit_map;
	node->bit_map = consume_bit_map_line(bit_map, output_bit_map, parent_node_name);

	return GENERIC;
}

/*
*---------------------------------------------------------------------------------------------
   * function: add_top_input_nodes
     to add the top level inputs to the netlist
*-------------------------------------------------------------------------------------------*/
void add_top_input_nodes(FILE *file, hashtable_t *output_nets_hash)
{
	char *ptr;
	char buffer[READ_BLIF_BUFFER];
	while ((ptr = vtr::strtok (NULL, TOKENS, file, buffer)))
	{
		char *temp_string = make_full_ref_name(ptr, NULL, NULL,NULL, -1);

		/* create a new top input node and net*/

		nnode_t *new_node = allocate_nnode();

		new_node->related_ast_node = NULL;
		new_node->type = INPUT_NODE;

		/* add the name of the input variable */
		new_node->name = temp_string;

		/* allocate the pins needed */
		allocate_more_output_pins(new_node, 1);
		add_output_port_information(new_node, 1);

		/* Create the pin connection for the net */
		npin_t *new_pin = allocate_npin();
		new_pin->name = vtr::strdup(temp_string);
		new_pin->type = OUTPUT;

		/* hookup the pin, net, and node */
		add_output_pin_to_node(new_node, new_pin, 0);

		nnet_t *new_net = allocate_nnet();
		new_net->name = vtr::strdup(temp_string);

		add_driver_pin_to_net(new_net, new_pin);

		verilog_netlist->top_input_nodes = (nnode_t**)vtr::realloc(verilog_netlist->top_input_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_input_nodes+1));
		verilog_netlist->top_input_nodes[verilog_netlist->num_top_input_nodes++] = new_node;

		//long sc_spot = sc_add_string(output_nets_sc, temp_string);
		//if (output_nets_sc->data[sc_spot])
		//warning_message(NETLIST_ERROR,linenum,-1, "Net (%s) with the same name already created\n",temp_string);

		//output_nets_sc->data[sc_spot] = new_net;

		output_nets_hash->add(output_nets_hash, temp_string, strlen(temp_string)*sizeof(char), new_net);
	}
}

/*---------------------------------------------------------------------------------------------
   * function: create_top_output_nodes
     to add the top level outputs to the netlist
*-------------------------------------------------------------------------------------------*/
void rb_create_top_output_nodes(FILE *file)
{
	char *ptr;
	char buffer[READ_BLIF_BUFFER];

	while ((ptr = vtr::strtok (NULL, TOKENS, file, buffer)))
	{
		char *temp_string = make_full_ref_name(ptr, NULL, NULL,NULL, -1);;

		/*add_a_fanout_pin_to_net((nnet_t*)output_nets_sc->data[sc_spot], new_pin);*/

		/* create a new top output node and */
		nnode_t *new_node = allocate_nnode();
		new_node->related_ast_node = NULL;
		new_node->type = OUTPUT_NODE;

		/* add the name of the output variable */
		new_node->name = temp_string;

		/* allocate the input pin needed */
		allocate_more_input_pins(new_node, 1);
		add_input_port_information(new_node, 1);

		/* Create the pin connection for the net */
		npin_t *new_pin = allocate_npin();
		new_pin->name   = temp_string;
		/* hookup the pin, net, and node */
		add_input_pin_to_node(new_node, new_pin, 0);

		/*adding the node to the verilog_netlist output nodes
		add_node_to_netlist() function can also be used */
		verilog_netlist->top_output_nodes = (nnode_t**)vtr::realloc(verilog_netlist->top_output_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_output_nodes+1));
		verilog_netlist->top_output_nodes[verilog_netlist->num_top_output_nodes++] = new_node;
	}
}


/*---------------------------------------------------------------------------------------------
   * (function: look_for_clocks)
 *-------------------------------------------------------------------------------------------*/

void rb_look_for_clocks()
{
	int i;
	for (i = 0; i < verilog_netlist->num_ff_nodes; i++)
	{
		if (verilog_netlist->ff_nodes[i]->input_pins[1]->net->driver_pin->node->type != CLOCK_NODE)
		{
			verilog_netlist->ff_nodes[i]->input_pins[1]->net->driver_pin->node->type = CLOCK_NODE;
		}
	}

}

/*
----------------------------------------------------------------------------
function: Creates the drivers for the top module
   Top module is :
                * Special as all inputs are actually drivers.
                * Also make the 0 and 1 constant nodes at this point.
---------------------------------------------------------------------------
*/

void rb_create_top_driver_nets(const char *instance_name_prefix, hashtable_t *output_nets_hash)
{
	npin_t *new_pin;
	/* create the constant nets */

	/* ZERO net */
	/* description given for the zero net is same for other two */
	verilog_netlist->zero_net = allocate_nnet(); // allocate memory to net pointer
	verilog_netlist->gnd_node = allocate_nnode(); // allocate memory to node pointer
	verilog_netlist->gnd_node->type = GND_NODE;  // mark the type
	allocate_more_output_pins(verilog_netlist->gnd_node, 1);// alloacate 1 output pin pointer to this node
	add_output_port_information(verilog_netlist->gnd_node, 1);// add port info. this port has 1 pin ,till now number of port for this is one
	new_pin = allocate_npin();
	add_output_pin_to_node(verilog_netlist->gnd_node, new_pin, 0);// add this pin to output pin pointer array of this node
	add_driver_pin_to_net(verilog_netlist->zero_net,new_pin);// add this pin to net as driver pin

	/*ONE net*/
	verilog_netlist->one_net = allocate_nnet();
	verilog_netlist->vcc_node = allocate_nnode();
	verilog_netlist->vcc_node->type = VCC_NODE;
	allocate_more_output_pins(verilog_netlist->vcc_node, 1);
	add_output_port_information(verilog_netlist->vcc_node, 1);
	new_pin = allocate_npin();
	add_output_pin_to_node(verilog_netlist->vcc_node, new_pin, 0);
	add_driver_pin_to_net(verilog_netlist->one_net, new_pin);

	/* Pad net */
	verilog_netlist->pad_net = allocate_nnet();
	verilog_netlist->pad_node = allocate_nnode();
	verilog_netlist->pad_node->type = PAD_NODE;
	allocate_more_output_pins(verilog_netlist->pad_node, 1);
	add_output_port_information(verilog_netlist->pad_node, 1);
	new_pin = allocate_npin();
	add_output_pin_to_node(verilog_netlist->pad_node, new_pin, 0);
	add_driver_pin_to_net(verilog_netlist->pad_net, new_pin);

	/* CREATE the driver for the ZERO */
	BLIF_ZERO_STRING = make_full_ref_name(instance_name_prefix, NULL, NULL, zero_string, -1);
	verilog_netlist->gnd_node->name = vtr::strdup(GND_NAME);

	output_nets_hash->add(output_nets_hash, (void *)verilog_netlist->gnd_node->name, strlen(verilog_netlist->gnd_node->name)*sizeof(char), verilog_netlist->zero_net);

	verilog_netlist->zero_net->name = vtr::strdup(BLIF_ZERO_STRING);

	/* CREATE the driver for the ONE and store twice */
	BLIF_ONE_STRING = make_full_ref_name(instance_name_prefix, NULL, NULL, one_string, -1);
	verilog_netlist->vcc_node->name = vtr::strdup(VCC_NAME);

	output_nets_hash->add(output_nets_hash, (void *)verilog_netlist->vcc_node->name, strlen(verilog_netlist->vcc_node->name)*sizeof(char), verilog_netlist->one_net);

	verilog_netlist->one_net->name = vtr::strdup(BLIF_ONE_STRING);

	/* CREATE the driver for the PAD */
	BLIF_PAD_STRING = make_full_ref_name(instance_name_prefix, NULL, NULL, pad_string, -1);
	verilog_netlist->pad_node->name = vtr::strdup(HBPAD_NAME);

	output_nets_hash->add(output_nets_hash, (void *)verilog_netlist->pad_node->name, strlen(verilog_netlist->pad_node->name)*sizeof(char), verilog_netlist->pad_net);

	verilog_netlist->pad_net->name = vtr::strdup(BLIF_PAD_STRING);
}

/*---------------------------------------------------------------------------------------------
 * (function: dum_parse)
 *-------------------------------------------------------------------------------------------*/
static void dum_parse (char *buffer, FILE *file)
{
	/* Continue parsing to the end of this (possibly continued) line. */
	while (vtr::strtok (NULL, TOKENS, file, buffer));
}



/*---------------------------------------------------------------------------------------------
 * function: hook_up_nets()
 * find the output nets and add the corresponding nets
 *-------------------------------------------------------------------------------------------*/
void hook_up_nets(hashtable_t *output_nets_hash)
{
	nnode_t **node_sets[] = {verilog_netlist->internal_nodes,     verilog_netlist->ff_nodes,     verilog_netlist->top_output_nodes};
	int          counts[] = {verilog_netlist->num_internal_nodes, verilog_netlist->num_ff_nodes, verilog_netlist->num_top_output_nodes};
	int        num_sets   = 3;

	/* hook all the input pins in all the internal nodes to the net */
	int i;
	for (i = 0; i < num_sets; i++)
	{
		int j;
		for(j = 0; j < counts[i]; j++)
		{
			nnode_t *node = node_sets[i][j];
			hook_up_node(node, output_nets_hash);
		}
	}
}

/*
 * Connect the given node's input pins to their corresponding nets by
 * looking each one up in the output_nets_sc.
 */
void hook_up_node(nnode_t *node, hashtable_t *output_nets_hash)
{
	int j;
	for(j = 0; j < node->num_input_pins; j++)
	{
		npin_t *input_pin = node->input_pins[j];

		nnet_t *output_net = (nnet_t *)output_nets_hash->get(output_nets_hash, (void *)(input_pin->name), strlen(input_pin->name)*sizeof(char));

		if(!output_net)
			error_message(NETLIST_ERROR,file_line_number, -1, "Error: Could not hook up the pin %s: not available.", input_pin->name);

		add_fanout_pin_to_net(output_net, input_pin);
	}
}

/*
 * Scans ahead in the given file to find the
 * model for the hard block by the given name.
 * Returns the file to its original position when finished.
 */
hard_block_model *read_hard_block_model(char *name_subckt, hard_block_ports *ports, FILE *file)
{
	// Store the current position in the file.
	fpos_t pos;
	int last_line = file_line_number;
	fgetpos(file,&pos);

	hard_block_model *model;

	while(1) {
		model = NULL;

		// Search the file for .model followed buy the subcircuit name.
		char buffer[READ_BLIF_BUFFER];
		while (vtr::fgets(buffer, READ_BLIF_BUFFER, file))
		{
			char *token = vtr::strtok(buffer,TOKENS, file, buffer);
			// match .model followed buy the subcircuit name.
			if (token && !strcmp(token,".model") && !strcmp(vtr::strtok(NULL,TOKENS, file, buffer), name_subckt))
			{
				model = (hard_block_model *)vtr::malloc(sizeof(hard_block_model));
				model->name = vtr::strdup(name_subckt);
				model->inputs = (hard_block_pins *)vtr::malloc(sizeof(hard_block_pins));
				model->inputs->count = 0;
				model->inputs->names = NULL;

				model->outputs = (hard_block_pins *)vtr::malloc(sizeof(hard_block_pins));
				model->outputs->count = 0;
				model->outputs->names = NULL;

				// Read the inputs and outputs.
				while (vtr::fgets(buffer, READ_BLIF_BUFFER, file))
				{
					char *first_word = vtr::strtok(buffer, TOKENS, file, buffer);
					if(!strcmp(first_word, ".inputs"))
					{
						char *name;
						while ((name = vtr::strtok(NULL, TOKENS, file, buffer)))
						{
							model->inputs->names = (char **)vtr::realloc(model->inputs->names, sizeof(char *) * (model->inputs->count + 1));
							model->inputs->names[model->inputs->count++] = vtr::strdup(name);
						}
					}
					else if(!strcmp(first_word, ".outputs"))
					{
						char *name;
						while ((name = vtr::strtok(NULL, TOKENS, file, buffer)))
						{
							model->outputs->names = (char **)vtr::realloc(model->outputs->names, sizeof(char *) * (model->outputs->count + 1));
							model->outputs->names[model->outputs->count++] = vtr::strdup(name);
						}
					}
					else if(!strcmp(first_word, ".end"))
					{
						break;
					}
				}
				break;
			}
		}

		if(!model || feof(file))
			error_message(NETLIST_ERROR, last_line, -1, "A subcircuit model for '%s' with matching ports was not found.",name_subckt);

		// Sort the names.
		qsort(model->inputs->names,  model->inputs->count,  sizeof(char *), compare_hard_block_pin_names);
		qsort(model->outputs->names, model->outputs->count, sizeof(char *), compare_hard_block_pin_names);

		// Index the names.
		model->inputs->index  = index_names(model->inputs->names, model->inputs->count);
		model->outputs->index = index_names(model->outputs->names, model->outputs->count);

		// Organise the names into ports.
		model->input_ports  = get_hard_block_ports(model->inputs->names,  model->inputs->count);
		model->output_ports = get_hard_block_ports(model->outputs->names, model->outputs->count);

		// Check that the model we've read matches the ports of the instance we are trying to match.
		if (verify_hard_block_ports_against_model(ports, model))
		{
			break;
		}
		else
		{	// If not, free it, and keep looking.
			free_hard_block_model(model);
		}
	}

	// Restore the original position in the file.
	file_line_number = last_line;
 	fsetpos(file,&pos);

	return model;
}

/*
 * Callback function for qsort which compares pin names
 * of the form port_name[pin_number] primarily
 * on the port_name, and on the pin_number if the port_names
 * are identical.
 */
static int compare_hard_block_pin_names(const void *p1, const void *p2)
{
	char *name1 = *(char * const *)p1;
	char *name2 = *(char * const *)p2;

	char *port_name1 = get_hard_block_port_name(name1);
	char *port_name2 = get_hard_block_port_name(name2);
	int portname_difference = strcmp(port_name1, port_name2);
	vtr::free(port_name1);
	vtr::free(port_name2);

	// If the portnames are the same, compare the pin numbers.
	if (!portname_difference)
	{
		int n1 = get_hard_block_pin_number(name1);
		int n2 = get_hard_block_pin_number(name2);
		return n1 - n2;
	}
	else
	{
		return portname_difference;
	}
}

/*
 * Creates a hashtable index for an array of strings of
 * the form names[i]=>i.
 */
hashtable_t *index_names(char **names, int count)
{
	hashtable_t *index = create_hashtable((count*2) + 1);
	int i;
	for (i = 0; i < count; i++)
	{
		int *offset = (int *)vtr::malloc(sizeof(int));
		*offset = i;
		index->add(index, names[i], sizeof(char) * strlen(names[i]), offset);
	}
	return index;
}

/*
 * Create an associative index of names1[i]=>names2[i]
 */
hashtable_t *associate_names(char **names1, char **names2, int count)
{
	hashtable_t *index = create_hashtable((count*2) + 1);
	int i;
	for (i = 0; i < count; i++)
		index->add(index, names1[i], sizeof(char) * strlen(names1[i]), names2[i]);

	return index;
}


/*
 * Organises the given strings representing pin names on a hard block
 * model into ports, and indexes the ports by name. Returns the organised
 * ports as a hard_block_ports struct.
 */
hard_block_ports *get_hard_block_ports(char **pins, int count)
{
	// Count the input port sizes.
	hard_block_ports *ports = (hard_block_ports *)vtr::malloc(sizeof(hard_block_ports));
	ports->count = 0;
	ports->sizes = 0;
	ports->names = 0;
	char *prev_portname = 0;
	int i;
	for (i = 0; i < count; i++)
	{
		char *portname = get_hard_block_port_name(pins[i]);
		// Compare the part of the name before the "["
		if (!i || strcmp(prev_portname, portname))
		{
			ports->sizes = (int *)vtr::realloc(ports->sizes, sizeof(int) * (ports->count + 1));
			ports->names = (char **)vtr::realloc(ports->names, sizeof(char *) * (ports->count + 1));

			ports->sizes[ports->count] = 0;
			ports->names[ports->count] = portname;
			ports->count++;
		}

		ports->sizes[ports->count-1]++;
		prev_portname = portname;
	}

	ports->signature = generate_hard_block_ports_signature(ports);
	ports->index     = index_names(ports->names, ports->count);

	return ports;
}

/*
 * Check for inconsistencies between the hard block model and the ports found
 * in the hard block instance. Returns false if differences are found.
 */
int verify_hard_block_ports_against_model(hard_block_ports *ports, hard_block_model *model)
{
	hard_block_ports *port_sets[] = {model->input_ports, model->output_ports};
	int i;
	for (i = 0; i < 2; i++)
	{
		hard_block_ports *p = port_sets[i];
		int j;
		for (j = 0; j < p->count; j++)
		{
			// Look up each port from the model in "ports"
			char *name = p->names[j];
			int   size = p->sizes[j];
			int  *idx  = (int *)ports->index->get(ports->index, name, strlen(name) * sizeof(char));
			// Model port not specified in ports.
			if (!idx)
			{
				//printf("Model port not specified in ports. %s\n", name);
				return FALSE;
			}

			// Make sure they match in size.
			int instance_size = ports->sizes[*idx];
			// Port sizes differ.
			if (size != instance_size)
			{
				//printf("Port sizes differ. %s\n", name);
				return FALSE;
			}
		}
	}

	hard_block_ports *in = model->input_ports;
	hard_block_ports *out = model->output_ports;
	int j;
	for (j = 0; j < ports->count; j++)
	{
		// Look up each port from the subckt to make sure it appears in the model.
		char *name   = ports->names[j];
		int *in_idx  = (int *)in->index->get(in->index, name, strlen(name) * sizeof(char));
		int *out_idx = (int *)out->index->get(out->index, name, strlen(name) * sizeof(char));
		// Port does not appear in the model.
		if (!in_idx && !out_idx)
		{
			//printf("Port does not appear in the model. %s\n", name);
			return FALSE;
		}
	}

	return TRUE;
}

/*
 * Generates string which represents the geometry of the given hard block ports.
 */
char *generate_hard_block_ports_signature(hard_block_ports *ports)
{
	char buffer[READ_BLIF_BUFFER];
	buffer[0] = '\0';

	strcat(buffer, "_");

	int j;
	for (j = 0; j < ports->count; j++)
	{
		char buffer1[READ_BLIF_BUFFER];
		odin_sprintf(buffer1, "%s_%d_", ports->names[j], ports->sizes[j]);
		strcat(buffer, buffer1);
	}
	return vtr::strdup(buffer);
}

/*
 * Gets the text in the given string which occurs
 * before the first instance of "[". The string is
 * presumably of the form "port[pin_number]"
 *
 * The retuned string is strduped and must be freed.
 * The original string is unaffected.
 */
char *get_hard_block_port_name(char *name)
{
	name = vtr::strdup(name);
	if (strchr(name,'['))
		return strtok(name,"[");
	else
		return name;
}

/*
 * Parses a port name of the form port[pin_number]
 * and returns the pin number as a long. Returns -1
 * if there is no [pin_number] in the name. Throws an
 * error if pin_number is not parsable as a long.
 *
 * The original string is unaffected.
 */
long get_hard_block_pin_number(char *original_name)
{
	if (!strchr(original_name,'['))
		return -1;

	char *name = vtr::strdup(original_name);
	strtok(name,"[");
	char *endptr;
	char *pin_number_string = strtok(NULL,"]");
	long pin_number = strtol(pin_number_string, &endptr, 10);

	if (pin_number_string == endptr)
		error_message(NETLIST_ERROR,file_line_number, -1,"The given port name \"%s\" does not contain a valid pin number.", original_name);

	vtr::free(name);

	return pin_number;
}

/*
 * Adds the given model to the hard block model cache.
 */
void add_hard_block_model(hard_block_model *m, hard_block_ports *ports, hard_block_models *models)
{
	char needle[READ_BLIF_BUFFER];
	needle[0] = '\0';
	strcat(needle, m->name);
	strcat(needle, ports->signature);
	models->models = (hard_block_model **)vtr::realloc(models->models, (models->count * sizeof(hard_block_model *)) + 1);
	models->models[models->count++] = m;
	models->index->add(models->index, needle, strlen(needle) * sizeof(char), m);
}

/*
 * Looks up a hard block model by name. Returns null if the
 * model is not found.
 */
hard_block_model *get_hard_block_model(char *name, hard_block_ports *ports, hard_block_models *models)
{
	char needle[READ_BLIF_BUFFER];
	needle[0] = '\0';
	strcat(needle, name);
	strcat(needle, ports->signature);
	return (hard_block_model *)models->index->get(models->index, needle, strlen(needle) * sizeof(char));
}

/*
 * Creates a new hard block model cache.
 */
hard_block_models *create_hard_block_models()
{
	hard_block_models *m = (hard_block_models *)vtr::malloc(sizeof(hard_block_models));
	m->models = 0;
	m->count  = 0;
	m->index  = create_hashtable(100);

	return m;
}

/*
 * Counts the number of lines in the given blif file
 * before a .end token is hit.
 */
int count_blif_lines(FILE *file)
{
	int num_lines = 0;
	char buffer[READ_BLIF_BUFFER];
	while (vtr::fgets(buffer, READ_BLIF_BUFFER, file))
	{
		if (strstr(buffer, ".end"))
			break;
		num_lines++;
	}
	rewind(file);
	return num_lines;
}

/*
 * Frees the hard block model cache, freeing
 * all encapsulated hard block models.
 */
void free_hard_block_models(hard_block_models *models)
{
	models->index->destroy(models->index);
	int i;
	for (i = 0; i < models->count; i++)
		free_hard_block_model(models->models[i]);

	vtr::free(models->models);
	vtr::free(models);
}


/*
 * Frees a hard_block_model.
 */
void free_hard_block_model(hard_block_model *model)
{
	free_hard_block_pins(model->inputs);
	free_hard_block_pins(model->outputs);

	free_hard_block_ports(model->input_ports);
	free_hard_block_ports(model->output_ports);

	vtr::free(model);
}

/*
 * Frees hard_block_pins
 */
void free_hard_block_pins(hard_block_pins *p)
{
	while (p->count--)
		vtr::free(p->names[p->count]);

	vtr::free(p->names);

	p->index->destroy_free_items(p->index);
	vtr::free(p);
}

/*
 * Frees hard_block_ports
 */
void free_hard_block_ports(hard_block_ports *p)
{
	while(p->count--)
		vtr::free(p->names[p->count]);

	vtr::free(p->signature);
	vtr::free(p->names);
	vtr::free(p->sizes);

	p->index->destroy_free_items(p->index);
	vtr::free(p);
}
