248 lines
7.9 KiB
C
248 lines
7.9 KiB
C
#include "getcfg.h"
|
||
#include "string.h"
|
||
|
||
typedef char PARAMBUF[MAX_LEN_BYTES_OF_LINE+1];
|
||
/*
|
||
return first visible char pointer from a string.
|
||
*/
|
||
|
||
#ifndef MIN
|
||
#define MIN(a,b) a<b?a:b
|
||
#endif
|
||
|
||
|
||
#if 0
|
||
char pLine[MAX_LEN_BYTES_OF_LINE+1], pOneSectionName[MAX_LEN_BYTES_OF_LINE+1];//??为什么要加1
|
||
int i,j,nIsMatch;
|
||
char *pLineHead = NULL, *pValueHead = NULL,
|
||
*pSectionNameHead = NULL, *pSectionTail = NULL, *pEquelMark = NULL;//等号=
|
||
char QuotationMark;//引号[]
|
||
unsigned long nRetIndex, dwRet = R_USE_DEFAULT;
|
||
#endif
|
||
|
||
|
||
ConfigurationTokens g_DefaultConfigurationTokens = DEFAULT_CONFIG_TOKENS;
|
||
|
||
static ConfigurationTokens g_ConfigurationTokens = DEFAULT_CONFIG_TOKENS;
|
||
|
||
void SetConfigTokens( const ConfigurationTokens * pTokens )
|
||
{
|
||
g_ConfigurationTokens = *pTokens;
|
||
}
|
||
void SetConfigTokensDefault( ConfigurationTokens * pTokens )
|
||
{
|
||
*pTokens = g_DefaultConfigurationTokens;
|
||
}
|
||
char * FirstVisibleBYTE( char* pStr)
|
||
{
|
||
while( pStr )
|
||
{
|
||
switch( *pStr )
|
||
{
|
||
case '\t' : break;
|
||
case ' ' : break;
|
||
default : return pStr;
|
||
}
|
||
++pStr;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
/******************************************************************************
|
||
***ret : Return value
|
||
***buffer : Source
|
||
***line_token : Posible token of a line. token-标记
|
||
***return : Position next search should be
|
||
******************************************************************************/
|
||
|
||
const char * ReadLnFromBuf(char *ret, int maxlen, const char *buffer, const char *line_token)
|
||
{ //ReadLnFromBuf( pLine, MAX_LEN_BYTES_OF_LINE, pBuffer, g_ConfigurationTokens.LineEnd )
|
||
char * sz;
|
||
int i=0;
|
||
|
||
sz = ret;
|
||
for( i=0; (i<maxlen) && (*buffer); i++, sz++, buffer++ )
|
||
{
|
||
if( strchr( line_token, *buffer )) /* The char is a token 查找line_token出现在buffer中的位置*/
|
||
{
|
||
for(;strchr( line_token, *buffer );buffer++);/* Skip tocken char */
|
||
break;
|
||
}
|
||
else
|
||
*sz = *buffer;
|
||
}
|
||
*sz = '\0';
|
||
return buffer;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
***GetConfiguration: Get configuration value from buffer
|
||
***success: return 0
|
||
***get failed, use default value: return R_USE_DEFAULT
|
||
*****************************************************************************/
|
||
/* ret = GetConfigFromBuf("local", //section名称
|
||
"ip", //key
|
||
"172.16.17.14",
|
||
(char *)g_device_local_ip,
|
||
sizeof(g_device_local_ip),
|
||
(char *)config_buff*/
|
||
unsigned long GetConfigFromBuf( const char *pSectionName, // section name
|
||
const char *pKeyName, // key name
|
||
const char *pDefault, // default string
|
||
char *pReturnedString, // destination buffer
|
||
unsigned long nSize, // size of destination buffer
|
||
const char *pBuffer // Source configuration data buffer
|
||
)
|
||
{
|
||
#if 1
|
||
static char pLine[MAX_LEN_BYTES_OF_LINE+1], pOneSectionName[MAX_LEN_BYTES_OF_LINE+1];//??为什么要加1
|
||
int i,j,nIsMatch;
|
||
char *pLineHead = NULL, *pValueHead = NULL,
|
||
*pSectionNameHead = NULL, *pSectionTail = NULL, *pEquelMark = NULL;//等号=
|
||
char QuotationMark;//引号[]
|
||
unsigned long nRetIndex, dwRet = R_USE_DEFAULT;
|
||
#endif
|
||
memset( pLine, 0, MAX_LEN_BYTES_OF_LINE+1 );//将数组清0
|
||
memset( pOneSectionName, 0, MAX_LEN_BYTES_OF_LINE+1 );
|
||
memset( pReturnedString, 0, nSize );
|
||
|
||
if( ( pSectionName ) && ( *pSectionName ) ) /*Want find section*/
|
||
{
|
||
while( pBuffer && (*pBuffer) )
|
||
{//===1
|
||
//取一行的数据
|
||
pBuffer = ReadLnFromBuf( pLine, MAX_LEN_BYTES_OF_LINE, pBuffer, g_ConfigurationTokens.LineEnd );
|
||
//一行数据的第一个字节
|
||
pLineHead = FirstVisibleBYTE( pLine );
|
||
//如果取出的一行数据的起始首字节是0
|
||
if( !pLineHead )
|
||
continue;//如果第一个字节为0则跳出单次循环 执行while判断
|
||
//如果取出的一行数据的起始首字节是连接符“#”
|
||
if( strchr( g_ConfigurationTokens.CommentLineBegin, *pLineHead ) )
|
||
continue; /*Comment line*/
|
||
//如果取出的一行数据的起始首字节不是起始符“[”
|
||
if( !strchr( g_ConfigurationTokens.SectionBegin, *pLineHead ) )/* Not a section head*[]*/
|
||
continue;
|
||
//判断section是否为空,如果不为空返回section名称的首字节
|
||
pSectionNameHead = FirstVisibleBYTE( pLineHead + 1 );/*Parse one section name*parse: 解析*/
|
||
if( !pSectionNameHead )
|
||
continue;
|
||
|
||
i = 0;
|
||
nIsMatch = 1;
|
||
|
||
while( pSectionNameHead[i] && ( !strchr( g_ConfigurationTokens.SectionEnd, *pSectionTail) )
|
||
&& pSectionName[i])
|
||
{
|
||
//判断提取的section名称是不是需要找的名称
|
||
if( pSectionNameHead[i] != pSectionName[i] )
|
||
{
|
||
nIsMatch = 0;
|
||
break;
|
||
}
|
||
i++;
|
||
}
|
||
//如果提取的section名称不是需要查找的名称
|
||
if( !nIsMatch )
|
||
continue;
|
||
//判断输入section名称最后一个字符后面是不是空,即确定已经将提取出的section名称
|
||
//和输入的指定section名称做了完整的比较
|
||
if( pSectionName[i] != '\0' ) /*Not full match*/
|
||
continue;
|
||
//判断末尾是不是“]”结尾
|
||
pSectionTail = FirstVisibleBYTE( &pSectionNameHead[i] );//tail:尾巴
|
||
if( ! pSectionTail )
|
||
continue;
|
||
if( !strchr( g_ConfigurationTokens.SectionEnd, *pSectionTail) ) /*This char is not section end char*/
|
||
continue;
|
||
else
|
||
break;
|
||
}//===1
|
||
}
|
||
|
||
while( pBuffer && (*pBuffer) ) /*Want find key*/
|
||
{
|
||
pBuffer = ReadLnFromBuf( pLine, MAX_LEN_BYTES_OF_LINE, pBuffer, g_ConfigurationTokens.LineEnd );
|
||
pLineHead = FirstVisibleBYTE( pLine );
|
||
if( !pLineHead ) continue;
|
||
if( strchr( g_ConfigurationTokens.CommentLineBegin, *pLineHead ) ) continue; /*Comment line*/
|
||
if( ( pSectionName ) && ( *pSectionName ) )
|
||
if( strchr( g_ConfigurationTokens.SectionBegin, *pLineHead ) ) break; /* Next section */
|
||
|
||
i=0;
|
||
nIsMatch = 1;
|
||
while( pLineHead[i] && pKeyName[i] )
|
||
{
|
||
if( pLineHead[i] != pKeyName[i] )
|
||
{
|
||
nIsMatch = 0;
|
||
break;
|
||
}
|
||
i++;
|
||
}
|
||
if( !nIsMatch )
|
||
continue;
|
||
pEquelMark = FirstVisibleBYTE( &pLineHead[i] );
|
||
if( !pEquelMark )
|
||
continue;
|
||
if( (*pEquelMark) != '=' ) /*Not full match key name*/
|
||
continue;
|
||
|
||
/*Key name found and founded char '='*/
|
||
pValueHead = FirstVisibleBYTE( pEquelMark+1 ); /*Get value addr*/
|
||
nRetIndex = 0;
|
||
if( ! pValueHead ) /*Empty value*/
|
||
{
|
||
*pReturnedString = '\0';
|
||
dwRet = 0;
|
||
goto end;
|
||
}
|
||
|
||
if( pValueHead[0] == '\'' || pValueHead[0] == '\"' ) /* Format "****" or '****' */
|
||
{
|
||
QuotationMark = pValueHead[0];
|
||
j = 1;
|
||
while( pValueHead[j] && ( nRetIndex < nSize)
|
||
&& ( pValueHead[j] != QuotationMark ) )
|
||
{
|
||
if( pValueHead[j] == '\\' )
|
||
{
|
||
switch( pValueHead[j+1] )
|
||
{
|
||
case '\'' :pReturnedString[nRetIndex] = '\'';break;
|
||
case 't' :pReturnedString[nRetIndex] = '\t';break;
|
||
case 'n' :pReturnedString[nRetIndex] = '\n';break;
|
||
case 'r' :pReturnedString[nRetIndex] = '\r';break;
|
||
case '\"' :pReturnedString[nRetIndex] = '\"';break;
|
||
case '\\' :pReturnedString[nRetIndex] = '\\';break;
|
||
case '\0' :pReturnedString[nRetIndex] = '\0';break;
|
||
default :pReturnedString[nRetIndex] = pValueHead[j+1];break;
|
||
}
|
||
j+=2;nRetIndex++;
|
||
}
|
||
else
|
||
{
|
||
pReturnedString[nRetIndex] = pValueHead[j];
|
||
j++; nRetIndex++;
|
||
}
|
||
}
|
||
dwRet = 0;
|
||
goto end;
|
||
}
|
||
else
|
||
{
|
||
strncpy( pReturnedString, pValueHead, nSize );//copy
|
||
dwRet = 0;
|
||
goto end;
|
||
}
|
||
}
|
||
end:
|
||
if( dwRet != 0 )
|
||
if( pDefault )
|
||
strncpy( pReturnedString, pDefault, nSize );//strncpy char * strncpy(char *s1,char *s2,size_t n);
|
||
//将字符串s2中最多n个字符复制到字符数组s1中,返回指向s1的指针
|
||
return dwRet;
|
||
}
|
||
|
||
|