#include "mib_parse.h"

static _line_mark line_mark;
static _mib_file_info mib_file_info;
static _mib_parse_mng mib_parse_mng;
static _import_obj import_obj;

static int parse_word(_line_mark *line_mark,int flag);
static void free_t_node(_node_t *node);

int set_mib_directory(char *dir)
{
	int len;
	
	if(access(dir,F_OK) != 0)
	{
		printf("Directory %s do not exists\n",dir);
		return 0;
	}
	sprintf(mib_directory,"%s",dir);
	
	len=strlen(mib_directory);
	if(mib_directory[len-1] == '/')
		mib_directory[len-1]=0;
	return 1;
}

static int store_mib_object_flag=0;
static int prefix_oidlen=0;
static int global_hookvalue=0;
void set_prefix_oid_length(int poidlen)
{
	prefix_oidlen=poidlen;
}
int load_mib_file(char *filename,int flag,int hookvalue)
{
	FILE *handle;
	char fullfilename[128];
	char readchar;

#if OUTPUT == 1
	printf("---------------------------- FILE: %s -----------------------------\n",filename);
#endif
	store_mib_object_flag=flag;
	global_hookvalue=hookvalue;
	sprintf(fullfilename,"%s/%s",mib_directory,filename);
	handle=fopen(fullfilename,"r");
	if(handle == NULL)
	{
		printf("Load mib file %s fail\n",fullfilename);
		return 0;
	}
	
	memset(&line_mark,0,sizeof(line_mark));
	memset(&mib_file_info,0,sizeof(mib_file_info));
	memset(&mib_parse_mng,0,sizeof(mib_parse_mng));
	
	while(1 == fread(&readchar,1,1,handle))
	{
		line_mark.punctuate_flag=1;
		if(readchar != '"' && line_mark.double_quote_flag)
		{
			if(line_mark.previous_quote_content_pos < 8191)
				line_mark.previous_quote_content[line_mark.previous_quote_content_pos]=readchar;
			line_mark.previous_quote_content_pos++;
			continue;
		}
			
		if(readchar != '\n' && line_mark.comment_flag)
			continue;
		switch(readchar)
		{
		case '-':
			if(line_mark.previous_char == '-')
			{
				line_mark.comment_flag=1;
				line_mark.current_line_word_count=0;
			}
			else
			{
				line_mark.punctuate_flag=0;
			}	
			
			break;
		case ' ':
		case '\t':
			if(line_mark.previous_blank_char_count)
			{
				line_mark.previous_blank_char_count++;
				break;
			}
			break;
		case '\'':
			line_mark.single_quote_flag++;
			line_mark.single_quote_flag%=2;
			break;
		case '"':
			line_mark.double_quote_flag++;
			line_mark.double_quote_flag%=2;
			if(line_mark.double_quote_flag == 0)
			{
				if(line_mark.previous_quote_content_pos < 8191)
					line_mark.previous_quote_content[line_mark.previous_quote_content_pos]=0;
				//printf("desc: %s\n",line_mark.previous_quote_content);
				if(!parse_word(&line_mark,1))
					return 0;
				line_mark.previous_quote_content_pos=0;
			}
			break;
		case '\n':
			line_mark.comment_flag=0;
			line_mark.line_no++;
			break;
		case '(':
			line_mark.bracket_count++;
			break;
		case ')':
			line_mark.bracket_count--;
			if(line_mark.bracket_count < 0)
			{
				printf("\nSyntax error[line %d], there is a '(' sign can not match\n",line_mark.line_no);
				fclose(handle);
				return 0;
			}
			break;
		case '{':
			if(line_mark.brace_flag)
			{
				printf("\nSyntax error[line %d], there is a '{' sign can not match\n",line_mark.line_no);
				fclose(handle);
				return 0;
			}
			line_mark.brace_flag=1;
			
			if(line_mark.previous_word_pos > 1)
			{
				line_mark.previous_word[line_mark.previous_word_pos]=0;
				if(!parse_word(&line_mark,0))
					return 0;
				line_mark.previous_word_pos=0;
				line_mark.current_line_word_count++;
			}
			
			line_mark.previous_word[0]=readchar;
			line_mark.previous_word[1]=0;
			if(!parse_word(&line_mark,0))
				return 0;
			line_mark.previous_word_pos=0;
			line_mark.current_line_word_count++;
			
			break;
		case '}':
			if(!line_mark.brace_flag)
			{
				printf("\nSyntax error[line %d], there is a '}' sign can not match\n",line_mark.line_no);
				fclose(handle);
				return 0;
			}
			line_mark.brace_flag=0;
			
			if(line_mark.previous_word_pos > 1)
			{
				line_mark.previous_word[line_mark.previous_word_pos]=0;
				if(!parse_word(&line_mark,0))
					return 0;
				line_mark.previous_word_pos=0;
				line_mark.current_line_word_count++;
			}
			
			line_mark.previous_word[0]=readchar;
			line_mark.previous_word[1]=0;
			if(!parse_word(&line_mark,0))
				return 0;
			line_mark.previous_word_pos=0;
			line_mark.current_line_word_count++;
			
			break;
		case ',':
		case ';':
		case '|':
			if(line_mark.previous_word_pos > 1)
			{
				line_mark.previous_word[line_mark.previous_word_pos]=0;
				if(!parse_word(&line_mark,0))
					return 0;
				line_mark.previous_word_pos=0;
				line_mark.current_line_word_count++;
			}
			
			line_mark.previous_word[0]=readchar;
			line_mark.previous_word[1]=0;
			if(!parse_word(&line_mark,0))
				return 0;
			line_mark.previous_word_pos=0;
			line_mark.current_line_word_count++;
			break;
		default:
			line_mark.punctuate_flag=0;
			if(line_mark.previous_char == '-')
			{
				line_mark.previous_word[line_mark.previous_word_pos]='-';
				line_mark.previous_word_pos++;
			}
			
			line_mark.previous_word[line_mark.previous_word_pos]=readchar;
			line_mark.previous_word_pos++;
				
			
			break;
		}
		
		if(line_mark.previous_char == '\n')
			line_mark.current_line_word_count=0;
		
		if(line_mark.punctuate_flag)
		{
			line_mark.previous_word[line_mark.previous_word_pos]=0;
			if(line_mark.previous_word_pos)
			{
				//printf("word[%d]: %s\n",line_mark.current_line_word_count,line_mark.previous_word);
				if(!parse_word(&line_mark,0))
					return 0;
				line_mark.current_line_word_count++;
			}
			line_mark.previous_word_pos=0;
		}
		line_mark.previous_char=readchar;
	}
	
	fclose(handle);
	
	if(!parse_mib())
	{
		printf("Critical error:parse_mib error\n");
		return 0;
	}
	//printf("==============list object id %s=========\n",filename);
	//list_object_id();
	find_last_file_oid();
	if(store_mib_object_flag)
		free_last_file_object_node();
	free_word_node();
	return 1;
}

/*
flag 
0-normal word
1-desc word
*/
int parse_word(_line_mark *line_mark,int flag)
{
	_word_t *pword;
	int index,len,clen;
	//skip the all blank word
	len=strlen(line_mark->previous_word);
	clen=0;
	if(flag == 0)
	{
		for(index=0;index<len;index++)
		{
			if(isspace(line_mark->previous_word[index]))
			{
				line_mark->previous_word[index]=0;
				break;
			}
			else
			{
				clen++;
			}
			
		}
		if(clen == 0)
			return 1;
	}
		
	pword=calloc(sizeof(_word_t),1);
	if(pword == NULL)
	{
		printf("parse_word:calloc fail for word\n");
		return 0;
	}
	
		
	if(flag == 0)
	{
		pword->word=calloc(len+1,1);
		if(pword->word == NULL)
		{
			printf("parse_word:calloc fail for word content\n");
			return 0;
		}
		
		sprintf(pword->word,"%s",line_mark->previous_word);
		pword->line_no=line_mark->line_no;
		add_word_node(pword);
		
		//printf("word[%d]: %s\n",line_mark->current_line_word_count,line_mark->previous_word);
	}
	else
	{
		len=strlen(line_mark->previous_quote_content);
		pword->word=calloc(len+1,1);
		if(pword->word == NULL)
		{
			printf("parse_word:calloc fail for word content\n");
			return 0;
		}
		sprintf(pword->word,"%s",line_mark->previous_quote_content);
		pword->line_no=line_mark->line_no;
		add_word_node(pword);
		//printf("desc[%d]: %s\n",line_mark->current_line_word_count,line_mark->previous_quote_content);
	}

	return 1;
} 

static _word_node_link word_node_link;
static _object_node_link object_node_link;
int parse_mib()
{
	MIB_OBJECT *mib_object;
	struct _word_node_t *node;
	static _object_identifier_t *pobject_identifier=NULL;
	static _replace_type_t *replace_type=NULL;
	char tmpstr[512];
	char *pwordstr1,*pwordstr2,*pwordstr3,*pwordstr;
	char *nwordstr1,*nwordstr2,*nwordstr3;
	int index;
	int tmpi;
	unsigned long line_no;
	
	
	node=word_node_link.head;
	while(node)
	{
		//printf("%ld: %s\n",node->data->line_no,node->data->word);
		pwordstr=node->data->word;
		line_no=node->data->line_no;
		
		switch(mib_parse_mng.parse_state)
		{
		case PARSE_STATE_UNCERTAIN:
			
			if(strcmp(pwordstr,ASSIGN_SIGN) == 0)
			{
				pwordstr1=get_prev_word(node,1);
				pwordstr2=get_prev_word(node,2);
				pwordstr3=get_prev_word(node,3);
				//printf("word1=%s,word2=%s,word3=%s\n",pwordstr1,pwordstr2,pwordstr3);
				if((pwordstr1 != NULL) && (strcmp(pwordstr1,"IDENTIFIER") == 0) && (pwordstr2 != NULL) && (strcmp(pwordstr2,"OBJECT") == 0))
				{
					pobject_identifier=calloc(sizeof(_object_identifier_t),1);
					if(pobject_identifier == NULL)
					{
						printf("calloc error[%ld],OBJECT IDENTIFIER\n",line_no);
						return 0;
					}
					sprintf(pobject_identifier->name,"%s",pwordstr3);
	
					mib_parse_mng.parse_state=PARSE_STATE_OBJECT_IDENTIFIER;
					mib_parse_mng.parse_block_state=PARSE_OBJECT_ID_START;
				}
				else if((pwordstr1 != NULL) && (strcmp(pwordstr1,"MACRO") == 0))
				{
#if OUTPUT == 1
	printf("[MACRO: %s]\n",pwordstr2);
#endif
					mib_parse_mng.parse_state=PARSE_STATE_MRCRO;
					mib_parse_mng.parse_block_state=PARSE_MACRO_STATE_BEGIN;
				}
			}
			else if(strcmp(pwordstr,"IMPORTS") == 0)
			{
				mib_parse_mng.parse_state=PARSE_STATE_IMPORT;
				mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_WORD;
				memset(&import_obj,0,sizeof(import_obj));			
			}
			else if(strcmp(pwordstr,"MODULE-IDENTITY") == 0)
			{
				pwordstr1=get_prev_word(node,1);
				pobject_identifier=calloc(sizeof(_object_identifier_t),1);
				if(pobject_identifier == NULL)
				{
					printf("calloc error[%ld],MODULE-IDENTITY\n",line_no);
					return 0;
				}
				sprintf(pobject_identifier->name,"%s",pwordstr1);
				mib_parse_mng.parse_state=PARSE_STATE_MODULE_IDENTITY;
				mib_parse_mng.parse_block_state=PARSE_MODULE_IDENTITY_STATE_SIGN;
			}
			else if(strcmp(pwordstr,"INTEGER") == 0)
			{
				pwordstr1=get_prev_word(node,1);
				pwordstr2=get_prev_word(node,2);
				if((pwordstr1 != NULL) && strcmp(pwordstr1,ASSIGN_SIGN) == 0)
				{
					replace_type=calloc(sizeof(_replace_type_t),1);
					if(replace_type == NULL)
					{
						printf("calloc error[%ld],INTEGER\n",line_no);
						return 0;
					}
					replace_type->type=INTEGER_ENUM_TYPE;
					sprintf(replace_type->type_name,"%s",pwordstr2);
					mib_parse_mng.parse_state=PARSE_STATE_INTEGER;
					mib_parse_mng.parse_block_state=PARSE_INTEGER_STATE_START;
				}
			}
			else if(strcmp(pwordstr,"TEXTUAL-CONVENTION") == 0)
			{
				pwordstr1=get_prev_word(node,1);
				pwordstr2=get_prev_word(node,2);
				if((pwordstr1 != NULL) && strcmp(pwordstr1,ASSIGN_SIGN) == 0)
				{
					replace_type=calloc(sizeof(_replace_type_t),1);
					if(replace_type == NULL)
					{
						printf("calloc error[%ld],TEXTUAL-CONVENTION\n",line_no);
						return 0;
					}
					sprintf(replace_type->type_name,"%s",pwordstr2);
					mib_parse_mng.parse_state=PARSE_STATE_TEXTUAL_CONVENTION;
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_SYNTAX;
				}
			}
			else if(strcmp(pwordstr,"OBJECT-TYPE") == 0)
			{
				pwordstr1=get_prev_word(node,1);
				nwordstr1=get_next_word(node,1);
				if(strcmp(nwordstr1,"MACRO") == 0)
					break;
				if(pwordstr1 != NULL)
				{
					mib_object=calloc(sizeof(MIB_OBJECT),1);
					if(mib_object == NULL)
					{
						printf("calloc error[%ld], OBJECT-TYPE\n",line_no);
						return 0;
					}
					sprintf(mib_object->name,"%s",pwordstr1);
					sprintf(mib_object->minvalue,"0");
					sprintf(mib_object->maxvalue,"0");
					mib_parse_mng.parse_state=PARSE_STATE_OBJECT_TYPE;
					mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_SYNTAX;
				}
			}
			break;
		case PARSE_STATE_OBJECT_IDENTIFIER:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_OBJECT_ID_START:
				if(strcmp(pwordstr,"{") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_OBJECT_ID_PNAME;
				}
				else
				{
					printf("Syntax error[%ld]:miss '{'\n",line_no);
					return 0;
				}
				break;
			case PARSE_OBJECT_ID_PNAME:
				sprintf(pobject_identifier->pname,"%s",pwordstr);
				mib_parse_mng.parse_block_state=PARSE_OBJECT_ID_OID;
				break;
			case PARSE_OBJECT_ID_OID:
				pobject_identifier->oid=atoi(pwordstr);
				if(pobject_identifier->oid == 0)
				{
					printf("Wrong OID[%ld]\n",line_no);
					return 0;
				}
				if(store_mib_object_flag)
					pobject_identifier->file_index=1;
				add_object_node(pobject_identifier);
				mib_parse_mng.parse_block_state=PARSE_OBJECT_ID_FINISH;
				if(store_mib_object_flag)
				{
					mib_object=calloc(sizeof(MIB_OBJECT),1);
					if(mib_object == NULL)
					{
						printf("calloc fail for MIB OBJECT\n");
						return 0;
					}
					mib_object->type=VALUETYPE_OTHER;
					sprintf(mib_object->minvalue,"0");
					sprintf(mib_object->maxvalue,"0");
					sprintf(mib_object->name,"%s",pobject_identifier->name);
					mib_object->need_find_oid=1;
					mib_object->hookvalue=global_hookvalue;
					add_mib_object_node(mib_object);
					//print_object(mib_object);
				}
				
#if OUTPUT == 1
	printf("[OBJECT IDENTIFIER: name=%s, pname=%s, oid=%d]\n",pobject_identifier->name,pobject_identifier->pname,pobject_identifier->oid);
#endif
				break;
			case PARSE_OBJECT_ID_FINISH:
				if(strcmp(pwordstr,"}") == 0)
				{
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				else
				{
					printf("Syntax error[%ld]:miss '}'\n",line_no);
					return 0;
				}
				break;
			}
			break;
		case PARSE_STATE_IMPORT:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_IMPORT_STATE_WORD:
				if(strcasecmp(pwordstr,",") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_COMMA;
				}
				else if(strcasecmp(pwordstr,"FROM") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_FROM;
				}
				else
				{
					sprintf(import_obj.import_word[import_obj.word_index],"%s",pwordstr);
					import_obj.word_index++;
				}
				break;
			case PARSE_IMPORT_STATE_COMMA:
				sprintf(import_obj.import_word[import_obj.word_index],"%s",pwordstr);
				import_obj.word_index++;
				mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_WORD;
				break;
			case PARSE_IMPORT_STATE_FROM:
				for(index=import_obj.file_index;index<import_obj.word_index;index++)
				{
					sprintf(import_obj.import_file[index],"%s",pwordstr);
					import_obj.file_index++;
				}
				mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_SEMICOLON;
				break;
			case PARSE_IMPORT_STATE_SEMICOLON:
				if(strcasecmp(pwordstr,";") == 0)
				{
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				
#if OUTPUT == 1
for(index=0;index<import_obj.word_index;index++)
{
	printf("[IMPORTS: %s, %s]\n",import_obj.import_word[index],import_obj.import_file[index]);
}
#endif
				}
				else
				{
					sprintf(import_obj.import_word[import_obj.word_index],"%s",pwordstr);
					import_obj.word_index++;
					mib_parse_mng.parse_block_state=PARSE_IMPORT_STATE_WORD;
				}
				break;
			}
			break;
		case PARSE_STATE_MRCRO:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_MACRO_STATE_BEGIN:
				if(strcasecmp(pwordstr,"BEGIN") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_MACRO_STATE_END;
				}
				else
				{
					printf("Syntax error[%ld],miss 'BEGIN'\n",line_no);
					return 0;
				}
				break;
			case PARSE_MACRO_STATE_END:
				if(strcasecmp(pwordstr,"END") == 0)
				{
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				break;
			}
			break;
		case PARSE_STATE_MODULE_IDENTITY:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_MODULE_IDENTITY_STATE_SIGN:
				if(strcmp(pwordstr,"MACRO") == 0)
				{
					free(pobject_identifier);
					pobject_identifier=NULL;
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				if(strcmp(pwordstr,ASSIGN_SIGN) == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_MODULE_IDENTITY_STATE_START;
				}
				break;
			case PARSE_MODULE_IDENTITY_STATE_START:
				if(strcmp(pwordstr,"{") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_MODULE_IDENTITY_STATE_PNAME;
				}
				else
				{
					free(pobject_identifier);
					pobject_identifier=NULL;
					printf("Syntax error[%ld]:miss '{'\n",line_no);
					return 0;
				}
				break;
			case PARSE_MODULE_IDENTITY_STATE_PNAME:
				sprintf(pobject_identifier->pname,"%s",pwordstr);
				mib_parse_mng.parse_block_state=PARSE_MODULE_IDENTITY_STATE_OID;
				break;
			case PARSE_MODULE_IDENTITY_STATE_OID:
				pobject_identifier->oid=atoi(pwordstr);
				if(store_mib_object_flag)
					pobject_identifier->file_index=1;
				add_object_node(pobject_identifier);
				mib_parse_mng.parse_block_state=PARSE_MODULE_IDENTITY_STATE_FINISH;
				
				if(store_mib_object_flag)
				{
					mib_object=calloc(sizeof(MIB_OBJECT),1);
					if(mib_object == NULL)
					{
						printf("calloc fail for MIB OBJECT\n");
						return 0;
					}
					mib_object->type=VALUETYPE_OTHER;
					sprintf(mib_object->name,"%s",pobject_identifier->name);
					sprintf(mib_object->minvalue,"0");
					sprintf(mib_object->maxvalue,"0");
					mib_object->need_find_oid=1;
					mib_object->hookvalue=global_hookvalue;
					add_mib_object_node(mib_object);
					//print_object(mib_object);
				}
				
#if OUTPUT == 1
	printf("[MODULE-IDENTITY: name=%s, pname=%s, oid=%d]\n",pobject_identifier->name,pobject_identifier->pname,pobject_identifier->oid);
#endif
				break;
			case PARSE_MODULE_IDENTITY_STATE_FINISH:
				if(strcmp(pwordstr,"}") == 0)
				{
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				else
				{
					printf("Syntax error[%ld]:miss '}'\n",line_no);
					return 0;
				}
				break;
			}
			break;
		case PARSE_STATE_INTEGER:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_INTEGER_STATE_START:
				if(strcmp(pwordstr,"{") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_INTEGER_STATE_LABEL;
				}
				else if(strstr(pwordstr,".."))
				{
					replace_type->type=INTEGER_RANGE_TYPE;
					parse_range(pwordstr,replace_type->start_range,replace_type->end_range);
#if OUTPUT == 1
	printf("[INTEGER: type=%d, name=%s, start=%s, end=%s, desc=%s]\n",replace_type->type,replace_type->type_name,replace_type->start_range,replace_type->end_range,replace_type->replacing_type_desc);
#endif
					add_replace_node(replace_type);
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				else
				{
					if(is_digit_string(pwordstr))
					{
						sprintf(replace_type->start_range,"%s",pwordstr);
						sprintf(replace_type->end_range,"%s",pwordstr);
					}
					else
					{
						sprintf(replace_type->start_range,"0");
						sprintf(replace_type->end_range,"2147483647");
					}
					replace_type->type=INTEGER_RANGE_TYPE;
					add_replace_node(replace_type);
#if OUTPUT == 1
	printf("[INTEGER: type=%d, name=%s, start=%s, end=%s, desc=%s]\n",replace_type->type,replace_type->type_name,replace_type->start_range,replace_type->end_range,replace_type->replacing_type_desc);
#endif
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				break;
			case PARSE_INTEGER_STATE_LABEL:
				if(strcmp(pwordstr,"}") == 0)
				{
					replace_type->replacing_type_desc[strlen(replace_type->replacing_type_desc)-1]=0;
					add_replace_node(replace_type);
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
#if OUTPUT == 1
	printf("[INTEGER: type=%d, name=%s, start=%s, end=%s, desc=%s]\n",replace_type->type,replace_type->type_name,replace_type->start_range,replace_type->end_range,replace_type->replacing_type_desc);
#endif
				}
				else if(strcmp(pwordstr,",") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_INTEGER_STATE_LABEL;
				}
				else
				{
					mib_parse_mng.parse_block_state=PARSE_INTEGER_STATE_VALUE;
					sprintf(tmpstr,"%s=",pwordstr);
					strcat(replace_type->replacing_type_desc,tmpstr);
				}
				break;
			case PARSE_INTEGER_STATE_VALUE:
				sprintf(tmpstr,"%s;",pwordstr);
				strcat(replace_type->replacing_type_desc,tmpstr);
				mib_parse_mng.parse_block_state=PARSE_INTEGER_STATE_LABEL;
				break;
			}
			break;
		case PARSE_STATE_TEXTUAL_CONVENTION:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_TEXTUAL_STATE_SYNTAX:
				if(strcmp(pwordstr,"MACRO") == 0)
				{
					free(replace_type);
					replace_type=NULL;
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				else if(strcmp(pwordstr,"SYNTAX") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_CHECK;
				}
				break;
			case PARSE_TEXTUAL_STATE_CHECK:
				if(strcmp(pwordstr,"INTEGER") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_INTEGER_CHECK;
				}
				else if(strcmp(pwordstr,"OCTET") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_OCTET_STRING;
					replace_type->type=OCTET_STRING_TYPE;
				}
				else
				{
					nwordstr1=get_next_word(node,1);
					replace_type->type=UNKNOWN_TYPE;
					if(strcmp(pwordstr,"OBJECT") == 0 && (nwordstr1 != NULL))
						sprintf(replace_type->replacing_type_desc,"%s %s",pwordstr,nwordstr1);
					else
						sprintf(replace_type->replacing_type_desc,"%s",pwordstr);
					add_replace_node(replace_type);
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, UNKNOWN: name=%s, desc=%s]\n",replace_type->type_name,replace_type->replacing_type_desc);
#endif
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				break;
			case PARSE_TEXTUAL_STATE_INTEGER_CHECK:
				if(strcmp(pwordstr,"{") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_INTEGER_LABEL;
					replace_type->type=INTEGER_ENUM_TYPE;
				}
				else if(strstr(pwordstr,".."))
				{
					//0..2123123123
					replace_type->type=INTEGER_RANGE_TYPE;
					parse_range(pwordstr,replace_type->start_range,replace_type->end_range);
					add_replace_node(replace_type);
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, INTEGER: type=%d, name=%s, start=%s, end=%s]\n",replace_type->type,replace_type->type_name,replace_type->start_range,replace_type->end_range);
#endif
				}
				else
				{
					if(is_digit_string(pwordstr))
					{
						sprintf(replace_type->start_range,"%s",pwordstr);
						sprintf(replace_type->end_range,"%s",pwordstr);
					}
					else
					{
						sprintf(replace_type->start_range,"0");
						sprintf(replace_type->end_range,"2147483647");
					}
					replace_type->type=INTEGER_RANGE_TYPE;
					add_replace_node(replace_type);
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, INTEGER: type=%d, name=%s, start=%s, end=%s]\n",replace_type->type,replace_type->type_name,replace_type->start_range,replace_type->end_range);
#endif
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				break;
			case PARSE_TEXTUAL_STATE_INTEGER_LABEL:
				if(strcmp(pwordstr,"}") == 0)
				{
					replace_type->replacing_type_desc[strlen(replace_type->replacing_type_desc)-1]=0;
					add_replace_node(replace_type);
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, INTEGER: type=%d, name=%s, desc=%s]\n",replace_type->type,replace_type->type_name,replace_type->replacing_type_desc);
#endif
				}
				else if(strcmp(pwordstr,",") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_INTEGER_LABEL;
				}
				else
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_INTEGER_VALUE;
					sprintf(tmpstr,"%s=",pwordstr);
					strcat(replace_type->replacing_type_desc,tmpstr);
				}
				break;
			case PARSE_TEXTUAL_STATE_INTEGER_VALUE:
				sprintf(tmpstr,"%s;",pwordstr);
				strcat(replace_type->replacing_type_desc,tmpstr);
				mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_INTEGER_LABEL;
				break;
			case PARSE_TEXTUAL_STATE_OCTET_STRING:
				if(strcmp(pwordstr,"STRING") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_SIZE;
				}
				else
				{
					printf("Syntax error[%ld]:miss 'STRING'\n",line_no);
					return 0;
				}
				break;
			case PARSE_TEXTUAL_STATE_SIZE:
				if(strcmp(pwordstr,"SIZE") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_TEXTUAL_STATE_RANGE;
				}
				else
				{
					sprintf(replace_type->start_range,"0");
					sprintf(replace_type->end_range,"255");
					add_replace_node(replace_type);
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, OCTET STRING: name=%s, start=%s,end=%s]\n",replace_type->type_name,replace_type->start_range,replace_type->end_range);
#endif
					mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				}
				break;
			case PARSE_TEXTUAL_STATE_RANGE:
				if(strstr(pwordstr,".."))
				{
					parse_range(pwordstr,replace_type->start_range,replace_type->end_range);
					add_replace_node(replace_type);
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, OCTET STRING: name=%s, start=%s,end=%s]\n",replace_type->type_name,replace_type->start_range,replace_type->end_range);
#endif
				}
				else
				{
					if(is_digit_string(pwordstr))
					{
						sprintf(replace_type->start_range,"%s",pwordstr);
						sprintf(replace_type->end_range,"%s",pwordstr);
					}
					else
					{
						sprintf(replace_type->start_range,"0");
						sprintf(replace_type->end_range,"255");
					}
#if OUTPUT == 1
	printf("[TEXTUAL CONVENTION, OCTET STRING: name=%s, start=%s,end=%s]\n",replace_type->type_name,replace_type->start_range,replace_type->end_range);
#endif
					add_replace_node(replace_type);
				}
				mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				break;
			}
			break;
		case PARSE_STATE_OBJECT_TYPE:
			switch(mib_parse_mng.parse_block_state)
			{
			case PARSE_OBJECT_TYPE_STATE_SYNTAX:
				if(strcmp(pwordstr,"SYNTAX") == 0)
				{
					mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_CHECK;
				}
				else
				{
					printf("Syntax error[%ld],miss 'SYNTAX'\n",line_no);
					return 0;
				}
				break;
			case PARSE_OBJECT_TYPE_STATE_CHECK:
				if(strcmp(pwordstr,"INTEGER") == 0 || strcmp(pwordstr,"Integer32") == 0 || strcmp(pwordstr,"Counter32") == 0)
				{
					mib_object->type=VALUETYPE_INTEGER;
					nwordstr1=get_next_word(node,1);
					if(strcmp(nwordstr1,"{") == 0)
					{
						node=node->next;
						do
						{
							nwordstr1=get_next_word(node,1);
							nwordstr2=get_next_word(node,2);
							nwordstr3=get_next_word(node,3);
							sprintf(tmpstr,"%s=%s;",nwordstr1,nwordstr2);
							strcat(mib_object->valuestring,tmpstr);
							if(strcmp(nwordstr3,",") == 0)
							{
								node=node->next;
								node=node->next;
								node=node->next;
							}
							else
							{
								break;
							}
						}while(strcmp(nwordstr1,"}"));
						mib_object->valuestring[strlen(mib_object->valuestring)-1]=0;
					}
					else if(strstr(nwordstr1,".."))
					{
						parse_range(nwordstr1,mib_object->minvalue,mib_object->maxvalue);
					}
					else
					{
						if(is_digit_string(nwordstr1))
						{
							sprintf(mib_object->minvalue,"%s",nwordstr1);
							sprintf(mib_object->maxvalue,"%s",nwordstr1);
						}
						else
						{
							sprintf(mib_object->minvalue,"0");
							sprintf(mib_object->maxvalue,"2147483647");
						}
					}
				}
				else if(strcmp(pwordstr,"OCTET") == 0)
				{
					mib_object->type=VALUETYPE_OCTETSTR;
					nwordstr1=get_next_word(node,1);
					nwordstr2=get_next_word(node,2);
					nwordstr3=get_next_word(node,3);
					if(strcmp(nwordstr1,"STRING"))
					{
						printf("Syntax error[%ld],miss 'STRING'\n",line_no);
						return 0;
					}
					if(strcmp(nwordstr2,"SIZE") == 0)
					{
						if(is_digit_string(nwordstr3))
						{
							sprintf(mib_object->minvalue,"%s",nwordstr3);
							sprintf(mib_object->maxvalue,"%s",nwordstr3);
						}
						else
						{
							parse_range(nwordstr3,mib_object->minvalue,mib_object->maxvalue);
						}
					}
					else
					{
						sprintf(mib_object->minvalue,"0");
						sprintf(mib_object->maxvalue,"255");
					}
				}
				else if(strcmp(pwordstr,"IpAddress") == 0)
				{
					mib_object->type=VALUETYPE_IPADDR;
				}
				else if(strcmp(pwordstr,"Opaque") == 0)
				{
					mib_object->type=VALUETYPE_OPAQUE;
					nwordstr1=get_next_word(node,1);
					nwordstr2=get_next_word(node,2);
					if(strcmp(nwordstr1,"SIZE"))
					{
						printf("Syntax error[%ld],miss 'SIZE'\n",line_no);
						return 0;
					}
					if(strstr(nwordstr2,".."))
					{
						parse_range(nwordstr2,mib_object->minvalue,mib_object->maxvalue);
					}
					else
					{
						if(is_digit_string(nwordstr2))
						{
							sprintf(mib_object->minvalue,"%s",nwordstr2);
							sprintf(mib_object->maxvalue,"%s",nwordstr2);
						}
						else
						{
							printf("Syntax error[%ld],miss range\n",line_no);
							return 0;
						}
					}
				}
				else if(strcmp(pwordstr,"TimeStamp") == 0 || strcmp(pwordstr,"TimeTicks") == 0)
				{
					mib_object->type=VALUETYPE_TIMETICKS;
				}
				else if(strcmp(pwordstr,"SEQUENCE") == 0)
				{
					nwordstr1=get_next_word(node,1);
					if(strcmp(nwordstr1,"OF"))
					{
						printf("Syntax error[%ld],miss 'OF'\n",line_no);
						return 0;
					}
					mib_object->type=VALUETYPE_OTHER;
				}
				else if(strcmp(pwordstr,"OBJECT") == 0)
				{
					nwordstr1=get_next_word(node,1);
					if(strcmp(nwordstr1,"IDENTIFIER"))
					{
						printf("Syntax error[%ld], miss 'IDENTIFIER'\n",line_no);
						return 0;
					}
					mib_object->type=VALUETYPE_OBJID;
				}
				else
				{
					if(strstr(pwordstr,"Entry"))
					{
						mib_object->type=VALUETYPE_OTHER;
					}
					else
					{
						if(!find_syntax_from_textual(pwordstr,mib_object))
						{
							printf("Syntax error[%ld],can not find related syntax type %s\n",line_no,pwordstr);
							return 0;
						}
					}
				}
				
				tmpi=0;
				nwordstr1=get_next_word(node,1);
				while(strcmp(nwordstr1,"MAX-ACCESS"))
				{
					//printf("%s search1 %s\n",mib_object->name,nwordstr1);
					if(tmpi>16)
					{
						printf("Syntax error[%ld]1,miss 'MAX-ACCESS'\n",line_no);
						return 0;
					}
					node=node->next;
					nwordstr1=get_next_word(node,1);
					tmpi++;
				}
				
				mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_ACCESS;
				break;
			case PARSE_OBJECT_TYPE_STATE_ACCESS:
				if(strcmp(pwordstr,"MAX-ACCESS") == 0)
				{
					nwordstr1=get_next_word(node,1);
					if(strcmp(nwordstr1,"read-write") == 0)
					{
						mib_object->access=ACCESS_READWRITE;
					}
					else if(strcmp(nwordstr1,"read-only") == 0)
					{
						mib_object->access=ACCESS_READONLY;
					}
					else if(strcmp(nwordstr1,"not-accessible") == 0)
					{
						mib_object->access=ACCESS_NOACCESS;
					}
					else if(strcmp(nwordstr1,"accessible-for-notify") == 0)
					{
						mib_object->access=ACCESS_NOTIFY;
					}
					else
					{
						printf("Syntax error[%ld],unknow access mode %s\n",line_no,nwordstr1);
						return 0;
					}
				}
				else
				{
					printf("Syntax error[%ld],miss 'MAX-ACCESS'\n",line_no);
					return 0;
				}
				node=node->next;
				mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_STATUS;
				break;
			case PARSE_OBJECT_TYPE_STATE_STATUS:
				nwordstr1=get_next_word(node,1);
				if(strcmp(pwordstr,"STATUS"))
				{
					printf("Syntax error[%ld],miss 'STATUS'\n",line_no);
					return 0;
				}
				if(strcmp(nwordstr1,"current") == 0)
				{
					mib_object->status=STATUS_CURRENT;
				}
				else
				{
					mib_object->status=STATUS_OBSOLETE;
				}
				node=node->next;
				mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_DESC;
				break;
			case PARSE_OBJECT_TYPE_STATE_DESC:
				nwordstr1=get_next_word(node,1);
				if(strcmp(pwordstr,"DESCRIPTION"))
				{
					printf("Syntax error[%ld],miss 'DESCRIPTION'\n",line_no);
					return 0;
				}
				sprintf(mib_object->desc,"%s",nwordstr1);
				
				tmpi=0;
				nwordstr1=get_next_word(node,1);
				while(strcmp(nwordstr1,ASSIGN_SIGN))
				{
					//printf("%s search2 %s\n",mib_object->name,nwordstr1);
					if(tmpi>16)
					{
						printf("Syntax error[%ld]1,miss '::='\n",line_no);
						return 0;
					}
					node=node->next;
					nwordstr1=get_next_word(node,1);
					tmpi++;
				}
				
				mib_parse_mng.parse_block_state=PARSE_OBJECT_TYPE_STATE_OID;
				break;
			case PARSE_OBJECT_TYPE_STATE_OID:
				nwordstr1=get_next_word(node,1);
				nwordstr2=get_next_word(node,2);
				nwordstr3=get_next_word(node,3);
				if(strcmp(pwordstr,ASSIGN_SIGN))
				{
					printf("Syntax error[%ld],miss '::='\n",line_no);
					return 0;
				}
				if(strcmp(nwordstr1,"{"))
				{
					printf("Syntax error[%ld],miss '{'\n",line_no);
					return 0;
				}
				if(strstr(nwordstr2,"Entry") && strstr(mib_object->name,"Index") && mib_object->access == ACCESS_READWRITE)
					mib_object->access=ACCESS_CREATE;
					
				pobject_identifier=calloc(sizeof(_object_identifier_t),1);
				if(pobject_identifier == NULL)
				{
					printf("calloc error[%ld],OBJECT IDENTIFIER\n",line_no);
					return 0;
				}
				sprintf(pobject_identifier->name,"%s",mib_object->name);
				sprintf(pobject_identifier->pname,"%s",nwordstr2);
				pobject_identifier->oid=atoi(nwordstr3);
				if(store_mib_object_flag)
				{
					pobject_identifier->file_index=1;
					mib_object->need_find_oid=1;
				}
				mib_object->hookvalue=global_hookvalue;
				add_object_node(pobject_identifier);
				add_mib_object_node(mib_object);
				mib_parse_mng.parse_state=PARSE_STATE_UNCERTAIN;
				break;
			}
			break;
		}
	
		node=node->next;
	}
	
	return 1;
}

//######################################################
static _tmp_node_link tmp_node_link;
int add_object_node(_object_identifier_t *data)
{
	struct _node_t *node;
	struct _node_t *tmp_node;
	int ret;
	
	node=calloc(sizeof(_node_t),1);
	if(node == NULL)
	{
		printf("add_object_node:calloc fail\n");
		return 0;
	}
	node->data=data;
	if(tmp_node_link.head_node == NULL)
	{
		//printf("add %s %lx\n",data->name,node);
		tmp_node_link.head_node=node;
	}
	else
	{
		tmp_node=tmp_node_link.head_node;
		do
		{
			ret=strcmp(data->name,tmp_node->data->name);
			if(ret == 0)
			{
				printf("Critical warning:Name conflict,%s\n",data->name);
				return 0;
			}
			else if(ret > 0)
			{
				if(tmp_node->right == NULL)
				{
					//printf("add %s in the right of %s,%lx\n",data->name,tmp_node->data->name,node);
					tmp_node->right=node;
					break;
				}
				else
				{
					tmp_node=tmp_node->right;
				}
			}
			else
			{
				if(tmp_node->left == NULL)
				{
					//printf("add %s in the left of %s,%lx\n",data->name,tmp_node->data->name,node);
					tmp_node->left=node;
					break;
				}
				else
				{
					tmp_node=tmp_node->left;
				}
			}
		}while(1);
	}
	return 1;
}

void free_object_node()
{
	if(tmp_node_link.head_node == NULL)
		return;
	free_t_node(tmp_node_link.head_node);
	tmp_node_link.head_node=NULL;
}

void free_t_node(_node_t *node)
{
	if(node->left != NULL)
		free_t_node(node->left);
	
	if(node->right != NULL)
		free_t_node(node->right);
	
	if(node->data != NULL)
	{
		//printf("free %s,%s,%d\n",node->data->name,node->data->pname,node->data->oid);
		free(node->data);
		node->data=NULL;
	}
	
	free(node);
	node=NULL;
}
static _tmp_node_link move_object_node_link;
void free_last_file_object_node()
{
	if(tmp_node_link.head_node == NULL)
		return;
	move_object_node(tmp_node_link.head_node);
	free_object_node();
	tmp_node_link.head_node=move_object_node_link.head_node;
	move_object_node_link.head_node=NULL;
}

void move_object_node(_node_t *node)
{
	if(node->left != NULL)
		move_object_node(node->left);
	
	if(node->right != NULL)
		move_object_node(node->right);
	
	if(node->data != NULL && node->data->file_index == 0)
	{
		add_move_node(node->data);
	}
}


int add_move_node(_object_identifier_t *data)
{
	struct _node_t *node;
	struct _node_t *tmp_node;
	_object_identifier_t *pdata;
	int ret;
	
	node=calloc(sizeof(_node_t),1);
	if(node == NULL)
	{
		printf("add_move_node:calloc fail\n");
		return 0;
	}
	
	pdata=calloc(sizeof(_object_identifier_t),1);
	if(pdata == NULL)
	{
		printf("add_move_node:calloc fail2\n");
		return 0;
	}
	memcpy(pdata,data,sizeof(_object_identifier_t));
	node->data=pdata;
	if(move_object_node_link.head_node == NULL)
	{
		//printf("add %s %lx\n",data->name,node);
		move_object_node_link.head_node=node;
	}
	else
	{
		tmp_node=move_object_node_link.head_node;
		do
		{
			ret=strcmp(pdata->name,tmp_node->data->name);
			if(ret == 0)
			{
				printf("Critical warning:Name conflict,%s\n",data->name);
				return 0;
			}
			else if(ret > 0)
			{
				if(tmp_node->right == NULL)
				{
					//printf("add %s in the right of %s,%lx\n",data->name,tmp_node->data->name,node);
					tmp_node->right=node;
					break;
				}
				else
				{
					tmp_node=tmp_node->right;
				}
			}
			else
			{
				if(tmp_node->left == NULL)
				{
					//printf("add %s in the left of %s,%lx\n",data->name,tmp_node->data->name,node);
					tmp_node->left=node;
					break;
				}
				else
				{
					tmp_node=tmp_node->left;
				}
			}
		}while(1);
	}
	return 1;
}



void list_object_id()
{
	printf("================ OBJECT ID ==============\n");
	if(tmp_node_link.head_node == NULL)
		return;
	list_object(tmp_node_link.head_node);
	printf("\n=========================================\n");
}

void list_object(_node_t *node)
{
	if(node->left != NULL)
		list_object(node->left);
	
	if(node->right != NULL)
		list_object(node->right);
	
	printf("[%s %s %d]\n",node->data->name,node->data->pname,node->data->oid);
}

void lookup_object_oid(char *name,int *oid,int *oidlen)
{
	_node_t* node;
	char *node_name;
	node_name=name;
	*oidlen=0;
	do
	{
		node=find_object_node(tmp_node_link.head_node,node_name);
		if(node == NULL)
		{
			oid[*oidlen]=1;
			(*oidlen)++;
			reverse_oids(oid,oidlen);
			return;
		}
		oid[*oidlen]=node->data->oid;
		(*oidlen)++;

		node_name=node->data->pname;
	}while(strcmp(node->data->name,"iso"));
}

_node_t* find_object_node(_node_t* parent,char *name)
{	
	int ret;
	
	if(parent == NULL)
		return NULL;
	ret=strcmp(name,parent->data->name);
	if(ret == 0)
		return parent;
	
	if(ret > 0)
		return find_object_node(parent->right,name);
	else
		return find_object_node(parent->left,name);
		
	
	return NULL;
}


static _replace_node_link replace_node_link;
int add_replace_node(_replace_type_t *data)
{
	struct _replace_node_t *node;
	
	node=calloc(sizeof(_replace_node_t),1);
	node->data=data;
	if(node == NULL)
	{
		printf("add_replace_node:calloc fail\n");
		return 0;
	}
	if(replace_node_link.head == NULL)
	{
		replace_node_link.head=replace_node_link.tail=node;
	}
	else
	{
		//printf("add replace node=%s\n",data->type_name);
		replace_node_link.tail->next=node;
		replace_node_link.tail=node;
	}
	
	return 1;
}

void free_replace_node()
{
	struct _replace_node_t *node;
	
	while((node=replace_node_link.head) != NULL)
	{
		replace_node_link.head=node->next;
		//printf("free replace node=%s\n",node->data->type_name);
		free(node->data);
		node->data=NULL;
		free(node);
		node=NULL;
	}
}


int add_mib_object_node(MIB_OBJECT *data)
{
	struct _object_node_t *node;
	
	node=calloc(sizeof(_object_node_t),1);
	node->data=data;
	if(node == NULL)
	{
		printf("add_mib_object_node:calloc fail\n");
		return 0;
	}
	if(object_node_link.head == NULL)
	{
		object_node_link.head=object_node_link.tail=node;
	}
	else
	{
		object_node_link.tail->next=node;
		object_node_link.tail=node;
	}
	
	return 1;
}
void free_mib_object_node()
{
	struct _object_node_t *node;
	
	while((node=object_node_link.head) != NULL)
	{
		object_node_link.head=node->next;
		free(node->data);
		node->data=NULL;
		free(node);
		node=NULL;
	}
}

void find_last_file_oid()
{
	struct _object_node_t *node;
	struct _object_node_t *head_node;
	
	head_node=object_node_link.head;
	while((node=head_node) != NULL)
	{
		head_node=node->next;
		if(node->data->need_find_oid && node->data->have_find_oid == 0)
		{
			//printf("lookup_object_oid %s\n",node->data->name);
			lookup_object_oid(node->data->name,node->data->oid,&node->data->oidlen);
			node->data->have_find_oid=1;
		}
	}
}

static _object_node_t *mib_object_head_node;
void prepare_enum()
{
	mib_object_head_node=object_node_link.head;
}

MIB_OBJECT* enum_object()
{
	_object_node_t *node;
	
	node=mib_object_head_node;
	if(node == NULL)
		return NULL;
	if(node->data->have_find_oid == 0)
		lookup_object_oid(node->data->name,node->data->oid,&node->data->oidlen);
	mib_object_head_node=node->next;
	return node->data;
}


int add_word_node(_word_t *data)
{
	struct _word_node_t *node;
	
	node=calloc(sizeof(_word_node_t),1);
	node->data=data;
	if(node == NULL)
	{
		printf("add_word_node:calloc fail\n");
		return 0;
	}
	if(word_node_link.head == NULL)
	{
		word_node_link.head=word_node_link.tail=node;
		//printf("add word node=%s,node address=%x,data address=%x\n",data->word,node,data);
	}
	else
	{
		//printf("add word node=%s,node address=%x,data address=%x\n",data->word,node,data);
		word_node_link.tail->next=node;
		node->prev=word_node_link.tail;
		word_node_link.tail=node;
		
		//node->next=word_node_link.head;
		//word_node_link.head=node;
	}
	
	return 1;
}

void free_word_node()
{
	struct _word_node_t *node;
	
	while((node=word_node_link.head) != NULL)
	{
		word_node_link.head=node->next;
		//printf("free word node=%s,node address=%x,data address=%x\n",node->data->word);
		free(node->data->word);
		node->data->word=NULL;
		free(node->data);
		node->data=NULL;
		free(node);
		node=NULL;
	}
}
//0-head
char *get_next_word(_word_node_t *refer_node,int index)
{
	struct _word_node_t *node;
	
	node=refer_node;
	
	while(index > 0)
	{
		if(node == NULL)
			return NULL;
		
		node=node->next;
		
		index--;
	}
	
	if(node == NULL)
		return NULL;
	return node->data->word;
}

char *get_prev_word(_word_node_t *refer_node,int index)
{
	struct _word_node_t *node;
	
	node=refer_node;
	
	while(index > 0)
	{
		if(node == NULL)
			return NULL;
		
		node=node->prev;
		
		index--;
	}
	
	if(node == NULL)
		return NULL;
	return node->data->word;
}

void parse_range(char *input,char *start,char *end)
{
	char inputstr[64];
	char *pstart;
	char *pend;
	char *ptmp;

	sprintf(inputstr,"%s",input);
	if(strstr(input,".."))
	{
		pstart=inputstr;
		pend=strstr(inputstr,"..");
		ptmp=pend;
		pend+=2;
		*ptmp=0;
		sprintf(start,"%s",pstart);
		sprintf(end,"%s",pend);
	}
	else
	{
		sprintf(start,"%s",input);
		sprintf(end,"%s",input);
	}
}

void free_resource()
{
	free_object_node();
	free_replace_node();
	free_word_node();
	free_mib_object_node();
}

int is_digit_string(char *input)
{
	int index,len;
	len=strlen(input);
	for(index=0;index<len;index++)
		if(!isdigit(input[index]))
			return 0;
	return 1;
}

void reverse_oids(int *oid,int *oidlen)
{
	int index;
	int pos;
	int oid_tmp[64];

	if(*oidlen <= prefix_oidlen)
	{
		memset(oid,0,(*oidlen)*sizeof(int));
		*oidlen=0;
		return;
	}
	
	memcpy(oid_tmp,oid,(*oidlen)*sizeof(int));
	pos=0;
	for(index=0;index<(*oidlen);index++)
	{
		oid[index]=oid_tmp[*oidlen-1-index];
		if(index >= prefix_oidlen)
		{
			oid[pos]=oid_tmp[*oidlen-1-index];
			pos++;
		}
	}
	*oidlen=pos;
}

int find_syntax_from_textual(char *type_name,MIB_OBJECT *pobject)
{
	struct _replace_node_t *node,*head_node;
	
	head_node=replace_node_link.head;
	while((node=head_node) != NULL)
	{
		head_node=node->next;
		if(strcmp(node->data->type_name,type_name) == 0)
		{

			switch(node->data->type)
			{
			case INTEGER_ENUM_TYPE:
				pobject->type=VALUETYPE_INTEGER;
				sprintf(pobject->valuestring,"%s",node->data->replacing_type_desc);
				return 1;
				break;
			case INTEGER_RANGE_TYPE:
				pobject->type=VALUETYPE_INTEGER;
				sprintf(pobject->minvalue,"%s",node->data->start_range);
				sprintf(pobject->maxvalue,"%s",node->data->end_range);
				return 1;
				break;
			case OCTET_STRING_TYPE:
				pobject->type=VALUETYPE_OCTETSTR;
				sprintf(pobject->minvalue,"%s",node->data->start_range);
				sprintf(pobject->maxvalue,"%s",node->data->end_range);
				return 1;
				break;
			default:
				return 0;
				break;
			}
			break;
		}
	}
	return 0;
}

void print_object(MIB_OBJECT *pobject)
{
#if OUTPUT == 1
	int index;
	printf("#############################\n");
	printf("type:%d\n",pobject->type);
	printf("name:%s\n",pobject->name);
	printf("oidlen=%d\n",pobject->oidlen);
	for(index=0;index<pobject->oidlen;index++)
		printf("%d.",pobject->oid[index]);
	printf("\n");
	printf("access:%d\n",pobject->access);
	printf("status:%d\n",pobject->status);
	printf("init value:%s\n",pobject->initvalue);
	printf("valuestring:%s\n",pobject->valuestring);
	printf("min:%s, max:%s\n",pobject->minvalue,pobject->maxvalue);
	printf("hookvalue=%d\n",pobject->hookvalue);
	printf("desc:\n");
	printf("%s\n",pobject->desc);	
#endif
}

