📄 cparser.cpp
字号:
if (m_current_pos == 0 ){
// This is first call
// position on first token;
if ( !Rewind() ) {
return false;
}
}
if (!GotoNextToken()){
return false;
}
// Back() implementation:
{
if ( m_back ){
m_current_line = m_last_line;
m_current_pos = m_last_pos;
return true;
}
m_back = false;
m_last_line = m_current_line ;
m_last_pos = m_current_pos;
} // Back() block
const char *tmp = strchr(m_current_pos, CHAR_NEWLINE);
if ( tmp == 0) {
str_safecopy(token_buf, token_len , m_current_pos);
m_current_pos = 0;
return true;
}
size_t len = tmp-m_current_pos;
if (len > token_len-1) {
len = token_len-1;
}
if (len > 0){
memcpy(token_buf,m_current_pos,len);
}
token_buf[len]=0;
return true;
} // End of GetLine()
//*****************************************************************************
// Purpose :
// store next token in client's buffer and advance m_current_pos
// Parameters:
// [out] buffer - holder for token
// [in] buffer size
// Returns:
// bool (false = no more data)
// also returns token in token_buf.
// Guaranteed not to overflow, but may trim long tokens
//*****************************************************************************
bool CParser::GetNextToken(char *token_buf, size_t token_len) {
bool is_in_string = false; // inside string (enclosed in ""),
// do not check for atomic-tokens and space characters
if (token_len == 0){
return false ; // no buffer
}
if (m_current_pos == 0 ){
// This is first call
// position on first token;
if ( !Rewind() ) {
return false;
}
}
if (!GotoNextToken()){
return false;
}
// Back() implementation:
{
if ( m_back ){
m_current_line = m_last_line;
m_current_pos = m_last_pos;
return true;
}
m_back = false;
m_last_line = m_current_line ;
m_last_pos = m_current_pos;
} // Back() block
// Try if it is a section enclosed in "[]"
// skip entire section name and advance to next token
// update m_section_name and m_section_id with new values
TrySection();
if (*m_current_pos == '\"') {
// this is a string beginning with '"'
++m_current_pos;
is_in_string = true;
}else {
// check for other atomic token, such as '=' or '+'
if (strchr(atomic_tokens, *m_current_pos) ) {
*token_buf = *m_current_pos;
++m_current_pos;
++token_buf;
*token_buf=0;
return true;
}
}
char *tmp = token_buf;
while ( token_len > 1 ){
if ( *m_current_pos != 0 ) {
if ( is_in_string ){
// When in string, watch for closing \"
if ( *m_current_pos == '\"' ){
*token_buf=0;
++m_current_pos;
return true;
} else {
if ( *m_current_pos == CHAR_NEWLINE ){
// new line is also not good, terminate string
*token_buf=0;
++m_current_pos;
LOG(LOG_WARNING, CFG_MODULE_NAME, "Line %d: closing '\"' is missing", m_current_line);
++m_current_line;
return true;
}
}
}else {
// not in string,
// watch for atomic tokens and spaces
if ( isspace (*m_current_pos) ) {
*token_buf=0;
if (*m_current_pos == CHAR_NEWLINE) {
++m_current_line;
}
++m_current_pos;
return true;
}
if (strchr(atomic_tokens, *m_current_pos) ) {
*token_buf=0;
return true;
}
}
*token_buf = *m_current_pos;
++m_current_pos;
++token_buf;
--token_len;
} else {
// end of buffer
*token_buf=0;
return true;
}
}
*token_buf=0;
LOG(LOG_ERR1, CFG_MODULE_NAME, "Line %d: The following token is too long %s", m_current_line, tmp);
// skip this long name
while ( !isspace(*m_current_pos)
&& ( *m_current_pos != '=' )
&& ( *m_current_pos != 0 )) {
++m_current_pos;
}
return false;
} // End of GetNextToken()
//*****************************************************************************
// Purpose :
// Determine if specific string(buffer) matches Boolean values
// if yes, store its Boolean representation in *result
// "Yes" or "True" matches true (*result = true)
// "No" or "False" matches false (*result = false)
// Anything else is error (function returns false)
// Parameters:
// [in] buffer - contains token
// [out] result - where to place Boolean value
// Returns:
// bool (false = Syntax error - cant match value)
// true = success, Boolean value is in *result
//*****************************************************************************
bool CParser::GetYesNo(const char *buffer, bool *result){
if ( COMPARE_EQUAL == str_compare("Yes",buffer) ){
*result = true;
} else if ( COMPARE_EQUAL == str_compare("True",buffer) ) {
*result = true;
} else if ( COMPARE_EQUAL == str_compare("No",buffer) ) {
*result = false;
} else if ( COMPARE_EQUAL == str_compare("False",buffer) ) {
*result = false;
}else {
LOG(LOG_ERR2,CFG_MODULE_NAME,
"Line %d: Unknown Boolean value: %s",
GetCurrentLineNumber(), buffer );
return false;
}
return true;
} // End of GetYesNo()
//*****************************************************************************
// Purpose :
// Determine if specific string(buffer) represents numeric value
// Parameters:
// [in] buffer - contains token hex representation 0xnn is Ok
// [out] result - where to place numeric (int) value
// Returns:
// bool (false = Syntax error - buffer does not represent any number)
//*****************************************************************************
bool CParser::GetNumber(const char *buffer, int *result){
bool brc = str_getnumber(buffer, result);
if (!brc) {
LOG(LOG_ERR2,CFG_MODULE_NAME,
"Line %d: Unknown numeric value: %s",
GetCurrentLineNumber(), buffer );
return false;
}
return brc;
} // End of GetNumber()
//*****************************************************************************
// Purpose :
// Determine if specific string(buffer) represents unsigned numeric value
// Parameters:
// [in] buffer - contains token hex representation 0xnn is Ok
// [out] result - where to place numeric (int) value
// Returns:
// bool (false = Syntax error - buffer does not represent any number)
//*****************************************************************************
bool CParser::GetUNumber(const char *buffer, unsigned int *result){
bool brc = str_getunsignednumber(buffer, result);
if (!brc) {
LOG(LOG_ERR2,CFG_MODULE_NAME,
"Line %d: Unknown numeric value: %s",
GetCurrentLineNumber(), buffer );
return false;
}
return brc;
} // End of GetUNumber()
//*****************************************************************************
// Purpose :
// Skip multi line comments /* ... */
// Pay attention to nested comments
// Parameters:
// [in] [out] List of line numbers where comment was opened
// Returns:
// false = failure ( eof reached comment was not closed)
//*****************************************************************************
bool CParser::SkipMultiLineComment(list<int> * bgn_lines ){
while ( bgn_lines->size() ) {
if ( ( *m_current_pos == '/')
&& (m_current_pos[1] == '*')
) {
// Start of multi-line comment
m_current_pos +=2;
bgn_lines->push_back(GetCurrentLineNumber());
}else if ( (*m_current_pos == '*')
&& (m_current_pos[1] == '/')
) {
// closing
bgn_lines->pop_back();
m_current_pos +=2;
}else {
++m_current_pos;
}
if (*m_current_pos == 0 ){
return false;
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -