⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 uClinux下用的数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (c) 1995-2001  Hughes Technologies Pty Ltd.  All rights** reserved.  **** Terms under which this software may be used or copied are** provided in the  specific license associated with this product.**** Hughes Technologies disclaims all warranties with regard to this ** software, including all implied warranties of merchantability and ** fitness, in no event shall Hughes Technologies be liable for any ** special, indirect or consequential damages or any damages whatsoever ** resulting from loss of use, data or profits, whether in an action of ** contract, negligence or other tortious action, arising out of or in ** connection with the use or performance of this software.****** $Id: parse.c,v 1.23 2003/01/13 21:21:38 bambi Exp $***//*** Module	: main : parse** Purpose	: ** Exports	: ** Depends Upon	: *//**************************************************************************** STANDARD INCLUDES**************************************************************************/#include <common/config.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#ifdef HAVE_UNISTD_H#  include <unistd.h>#endif#ifdef HAVE_STRING_H#  include <string.h>#endif#ifdef HAVE_STRINGS_H#  include <strings.h>#endif#include <common/portability.h>#include <common/libc_stuff/c_stuff.h>/**************************************************************************** MODULE SPECIFIC INCLUDES**************************************************************************/#include <common/msql_defs.h>#include <common/debug/debug.h>#include <msqld/index/index.h>#include <msqld/includes/msqld.h>#include <msqld/includes/errmsg.h>#include <msqld/main/main.h>#include <msqld/main/yaccer.h>#include <msqld/main/lexer.h>#include <msqld/main/sysvar.h>#include <msqld/main/util.h>#include <msqld/main/net.h>#include <msqld/main/parse.h>#include <msqld/main/memory.h>#include <common/types/types.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************/static	cstk_t 	*condStack = NULL;static	int	insertOffset = 0;int yyparse();unsigned long local_strtoul();/**************************************************************************** PRIVATE ROUTINES**************************************************************************/static void _cleanCond(curCond)	mCond_t 	*curCond;{	mCond_t 	*tmpCond;	while(curCond)	{		if (curCond->subCond != NULL)		{			_cleanCond(curCond->subCond);			curCond->subCond = NULL;		}		parseFreeValue(curCond->value);		curCond->value = NULL;		curCond->op = curCond->bool = 0;		tmpCond = curCond;		curCond = curCond->next;		tmpCond->next = NULL;		memFreeCondition(tmpCond);	}}static void _cleanFields(curField)	mField_t	*curField;{	mField_t	*tmpField;	while(curField)	{		parseFreeValue(curField->value);		if (curField->function)		{			_cleanFields(curField->function->paramHead);			free(curField->function);			curField->function = NULL;		}		curField->value = NULL;		tmpField = curField;		curField = curField->next;		tmpField->next = NULL;		memFreeField(tmpField);	}}static u_char expandEscape(c,remain)	u_char	*c;	int	remain;{	u_char	ret;	switch(*c)	{		case 'n':			ret = '\n';			break;		case 't':			ret = '\t';			break;		case 'r':			ret = '\r';			break;		case 'b':			ret = '\b';			break;		default:			ret = *c;			break;	}	return(ret);}/**************************************************************************** PUBLIC ROUTINES**************************************************************************//****************************************************************************** 	parseCleanQuery - clean out the internal structures****	Purpose	: Free all space and reset structures after a query**	Args	: None**	Returns	: Nothing**	Notes	: Updates all public data structures*/void parseCleanQuery(query)	mQuery_t	*query;{	register mTable_t 	*curTable, *tmpTable;	register mOrder_t 	*curOrder, *tmpOrder;	register mValList_t	*curValue, *tmpValue;	register mField_t	*curField;	extern	u_char		*yyprev, *yytext;	debugTrace(TRACE_IN,"parseCleanQuery()");	if (yyprev)	{		free(yyprev);		yyprev = NULL;	}	yytext = NULL;	/*	** blow away the table list from the query	*/	curTable = query->tableHead;	while(curTable)	{		tmpTable = curTable;		curTable = curTable->next;		tmpTable->next = NULL;		memFreeTable(tmpTable);	}	/*	** Blow away the insert value list	*/	if (query->insertValHead)	{		/* 		** Ensure that none of these value pointers		** are referenced from the field list so that		** we don't double free them		*/		curField = query->fieldHead;		while(curField)		{			curField->value = NULL;			curField = curField->next;		}	}	curValue = query->insertValHead;	while(curValue)	{		tmpValue = curValue;		curValue = curValue->next;		parseFreeValue(tmpValue->value);		tmpValue->next = NULL;		memFreeValList(tmpValue);	}	/*	** blow away the field list from the query	*/	_cleanFields(query->fieldHead);	/*	** Blow away the condition list from the query (recurse for	** subconds)	*/	_cleanCond(query->condHead);	/*	** Blow away the order list from the query	*/	curOrder = query->orderHead;	while(curOrder)	{		curOrder->dir = 0;		tmpOrder = curOrder;		curOrder = curOrder->next;		tmpOrder->next = NULL;		memFreeOrder(tmpOrder);	}	/*	** Reset the list pointers	*/	sysvarResetVariables();	query->fieldHead = NULL;	query->condHead = NULL;	query->tableHead = NULL;	query->orderHead = NULL;	query->insertValHead = NULL;	memFreeQuery(query);	debugTrace(TRACE_OUT,"parseClean()");}mIdent_t *parseCreateIdent(seg1,seg2,query)	char		*seg1,			*seg2;	mQuery_t	*query;{	mIdent_t	*new;	debugTrace(TRACE_IN,"parseCreateIdent()");	if (seg1)	{		if ((int)strlen(seg1) > NAME_LEN)		{			netError(query->clientSock,				"Identifier name '%s' too long\n",seg1);			debugTrace(TRACE_OUT,"parseCreateIdent()");			return(NULL);		}	}	if (seg2)	{		if ((int)strlen(seg2) > NAME_LEN)		{			netError(query->clientSock, 				"Identifier name '%s' too long\n",seg2);			debugTrace(TRACE_OUT,"parseCreateIdent()");			return(NULL);		}	}	new = memMallocIdent();	if (seg1)	{		(void)strncpy(new->seg1,seg1,NAME_LEN);	}	else	{		*(new->seg1) = 0;	}	if (seg2)	{		(void)strncpy(new->seg2,seg2, NAME_LEN);	}	else	{		*(new->seg1) = 0;	}	debugTrace(TRACE_OUT,"parseCreateIdent()");	return(new);}mVal_t *parseCreateValue(textRep,type,tokLen)	u_char	*textRep;	int	type,		tokLen;{	mVal_t	*new;	int	length,		remain,		escCount,		res;	register u_char	*cp,			*cp2;	char	*cp3;	debugTrace(TRACE_IN,"parseCreateValue()");	new = memMallocValue();	new->type = type;	new->dataLen = tokLen;	new->nullVal = 0;	new->precision = 0;	new->val.charVal = NULL;	switch(type)	{		case NULL_TYPE:			new->nullVal = 1;			break;		case IDENT_TYPE:		case SYSVAR_TYPE:			new->val.identVal = (mIdent_t *)textRep;			break;		case CHAR_TYPE:			remain = length = tokLen - 2;			escCount = 0;			new->val.charVal = (u_char *)malloc(length+1);			cp = textRep+1;			cp2 = new->val.charVal;			while(remain)			{				if (*cp == '\\')				{					escCount ++;					remain--;					*cp2 = expandEscape(++cp,remain);					if (*cp2)					{						cp2++;						cp++;						remain--;					}				}				else				{					*cp2++ = *cp++;					remain--;				}			}			*cp2 = 0;			new->dataLen = tokLen - 2 - escCount;			break;		case INT_TYPE:		case INT64_TYPE:			new->type = INT_TYPE;			new->val.intVal=local_strtoul((char *)textRep,NULL,10,				&res);#ifdef HUGE_T			if (res < 0)			{				new->val.intVal = 0;				new->type = INT64_TYPE;				strtohuge((char *)textRep, &new->val.int64Val);			}#endif			break;		case UINT_TYPE:		case UINT64_TYPE:			new->type = UINT_TYPE;			new->val.intVal=local_strtoul((char *)textRep,NULL,10,				&res);#ifdef HUGE_T			if (res < 0)			{				new->val.intVal = 0;				new->type = UINT64_TYPE;				strtohuge((char *)textRep, &new->val.int64Val);			}#endif			break;		case REAL_TYPE:			sscanf((char *)textRep ,"%lg",&new->val.realVal);			cp3 = (char *)index(textRep,'.');			if (cp3)			{				new->precision = strlen(textRep) -					(cp3 - (char *)textRep) - 1;				if (new->precision < 0)					new->precision = 0;			}			break;	}	debugTrace(TRACE_OUT,"parseCreateValue()");	return(new);}mVal_t *parseFillValue(val,type,length)	char	*val;	int	type,		length;{	mVal_t	*new;	char	int8Val;	short	int16Val;	debugTrace(TRACE_IN,"parseFillValue()");	new = memMallocValue();	new->type = type;	new->nullVal = 0;	switch(typeBaseType(type))	{		case CHAR_TYPE:			new->val.charVal = (u_char *)malloc(length+1);			bcopy(val,new->val.charVal,length);			*(new->val.charVal + length) = 0;			new->dataLen = strlen(new->val.charVal);			break;		case INT8_TYPE:		case UINT8_TYPE:			int8Val = *val;			new->val.intVal = int8Val;			new->dataLen = length;			break;		case INT16_TYPE:		case UINT16_TYPE:			bcopy((char *)val, &int16Val, 2);			new->val.intVal = int16Val;			new->dataLen = length;			break;		case INT_TYPE:		case UINT_TYPE:			new->val.intVal = (int) * (int *)val;			new->dataLen = length;			break;#ifdef HUGE_T		case INT64_TYPE:		case UINT64_TYPE:			new->val.int64Val = (HUGE_T) * (HUGE_T *)val;			new->dataLen = length;			break;#endif		case REAL_TYPE:			new->val.realVal = (double) * (double *)val;			new->dataLen = length;			break;		case BYTE_TYPE:			if (length != typeFieldSize(type))			{				fprintf(stderr,					"parseFillValue : Size mismatch\n");				exit(1);			}			new->dataLen = length;			new->val.byteVal = (void*)malloc(length);			bcopy((char *)val, (char *)new->val.byteVal, length);			break;		default:			fprintf(stderr,"parseFillValue : Unknown type %d\n",				typeBaseType(type));			exit(1);	}	debugTrace(TRACE_OUT,"parseFillValue()");	return(new);}int parseCopyValue(cp,value,type,length,nullOK)	char	*cp;	mVal_t	*value;	int	type,		length,		nullOK;{	int	strLen;	if (value->nullVal)	{		if (!nullOK)		{			return(-1);		}		else		{			bzero(cp,length);			return(0);		}	}	switch(typeBaseType(type))	{		case INT_TYPE:    		case UINT_TYPE:			bcopy(&(value->val.intVal),cp,4);			break;#ifdef HUGE_T		case INT64_TYPE:		case UINT64_TYPE:			bcopy(&(value->val.int64Val),cp,sizeof(HUGE_T));			break;#endif		case REAL_TYPE:			bcopy(&(value->val.realVal),cp,8);			break;		case CHAR_TYPE:			value->val.charVal[value->dataLen]=0;			strLen = strlen((char *)value->val.charVal);			if (strLen > length)				strLen = length;			else				strLen++;						bcopy((char *)value->val.charVal,cp, strLen);			break;		case BYTE_TYPE:			strLen = typeFieldSize(type);			if (strLen != length)			{				fprintf(stderr,					"parseFillValue : Size mismatch\n");				exit(1);			}			bcopy((char *)value->val.charVal,cp, strLen);			break;	}	return(0);}mVal_t *parseCreateNullValue(){	mVal_t	*new;	new = memMallocValue();	new->nullVal = 1;	return(new);}void parseFreeValue(val)	mVal_t	*val;{	debugTrace(TRACE_IN,"parseFreeValue()");	if (!val)	{		debugTrace(TRACE_OUT,"parseFreeValue()");		return;	}	if (!val->nullVal)	{		switch(val->type)		{			case IDENT_TYPE:			case SYSVAR_TYPE:				if (val->val.identVal)				{					memFreeIdent(val->val.identVal);					val->val.identVal = NULL;				}				break;			case CHAR_TYPE:			case TEXT_TYPE:				if (val->val.charVal)				{					(void)free(val->val.charVal);					val->val.charVal = NULL;				}				break;		}	}	memFreeValue(val);	debugTrace(TRACE_OUT,"parseFreeValue()");}void parseAddSequence(table, step, val, query)	char	*table;	int	step,		val;	mQuery_t *query;{	debugTrace(TRACE_IN,"parseAddSequence()");	strcpy(query->sequenceDef.table,table);	query->sequenceDef.step = step;	query->sequenceDef.value = val;	debugTrace(TRACE_OUT,"parseAddSequence()");}/****************************************************************************** 	_msqlAddField - add a field definition to the list****	Purpose	: store field details from the query for later use**	Args	: field name, field type, field length, value**	Returns	: Nothing**	Notes	: Depending on the query in process, only some of the**		  args will be supplied.  eg. a SELECT doesn't use the**		  type arg.  The length arg is only used during a create**		  if the field is of type CHAR*/int parseAddField(ident,type,length,notNull,priKey,query)	mIdent_t	*ident;	int 		type;	char		*length;	int		notNull,			priKey;	mQuery_t	*query;{	mField_t	*new;	char		*name,			*table;	debugTrace(TRACE_IN,"ParseAddField()");	name = ident->seg2;	table = ident->seg1;	/*	** Look for duplicate field names on a table create.  If the	** type is set then we know this is a table creation.	*/	if (type != 0)	{		new = query->fieldHead;		while(new)		{			if (strcmp(new->name,name) == 0)			{				netError(query->clientSock,					"Duplicate field name '%s'\n", name);				debugTrace(TRACE_OUT,"parseAddField()");				memFreeIdent(ident);				return(-1);			}			new = new->next;		}	}	/*	** Look for the obsolete prinary key construct	*/	if (priKey)	{		netError(query->clientSock,			"Primary keys are obsolete.  Use CREATE INDEX\n");		memFreeIdent(ident);		debugTrace(TRACE_OUT,"parseAddField()");		return(-1);	}	/*	** Create the new field definition	*/	new = memMallocField();	if (table)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -