Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
IniFileLib/IniFile.cpp
- Committer:
- CE
- Date:
- 2011-01-06
- Revision:
- 0:0732b16d9a92
File content as of revision 0:0732b16d9a92:
///////////////////////////////////////////////////////////////////////////////
// IniFile: .ini file parser by rinos 2010
///////////////////////////////////////////////////////////////////////////////
#include "IniFile.h"
#include <string.h>
#include <stdlib.h>
////////////////////////////////////////////////////////////////////////////////
// defines
const char INI_DELIM[] = " \t\r\n";
const int INI_LINE_BUF= 256;
////////////////////////////////////////////////////////////////////////////////
// IniFile
IniFile::IniFile(const char* file): m_fp(0) {
if(file) open(file);
}
IniFile::~IniFile(){
close();
}
////////////////////////////////////////////////////////////////////////////////
// internal funcs
IniFile::Status IniFile::strtrim(char* dst, const char* src, int dst_size){
if(!dst_size) return S_BUFFER_TOO_SHORT; // myStrcpy needs more than 1 byte for '\0'.
// Find valid string area
const char* p1 = strchr (src, '"');
const char* p2 = p1? strrchr(++p1, '"') : 0;
if(!p2){
// trim space or tab
for(p1 = src ; *p1 && strchr(INI_DELIM, *p1) ; p1++);
if(!*p1){ // all char is space or tab
*dst = 0;
return S_SUCCESS;
}
for(p2 = p1 + strlen(p1) ; strchr(INI_DELIM, p2[-1]) ; --p2);
}
// Check copy size
Status ret;
if(dst_size > p2 - p1){
dst_size = p2 - p1;
ret = S_SUCCESS;
} else {
dst_size--;
ret = S_BUFFER_TOO_SHORT;
}
// copy buffer
if(dst != p1) memmove(dst, p1, dst_size);
dst[dst_size] = 0;
return ret;
}
////////////////////////////////////////////////////////////////////////////////
// Access methods
IniFile::Status IniFile::open(const char* file){
close();
m_fp = fopen(file, "r");
if(m_fp) return S_SUCCESS;
//printf("IniFile: Can't open %s\n", file);
return S_OPEN_ERROR;
}
IniFile::Status IniFile::close(){
if(!m_fp) return S_NOT_OPENED;
fclose(m_fp);
m_fp = 0;
return S_SUCCESS;
}
IniFile::Status IniFile::get(const char* key, char* ret, int ret_size){
if(!m_fp){
printf("IniFile::get %s S_OPEN_ERROR\n", key);
return S_OPEN_ERROR;
}
rewind(m_fp);
char line[INI_LINE_BUF];
while(fgets(line, sizeof(line), m_fp)){
if(*line == '#') continue; // comment line
char* p = strchr(line, '=');
if(!p || line == p) continue; // invalid line
*p++ = 0;
strtrim(line, line, p - line);
if(strcmp(line, key)) continue; // different key // stricmp?
// check data type
switch(ret_size){
case DTYPE_INT:
strtrim(line, p, INI_LINE_BUF);
*(int*)ret = strtoul(line, &p, 0);
//return p[0]? S_FORMAT_ERROR : S_SUCCESS; // check end
printf("IniFile::get %s INT %d\n", key, *(int*)ret);
return S_SUCCESS; // always success
case DTYPE_BOOL:
strtrim(line, p, INI_LINE_BUF);
switch(line[0]){
case 'T':
case 't': *(bool*)ret = true; break;
case 'F':
case 'f': *(bool*)ret = false; break;
default: *(bool*)ret = strtoul(line, &p, 0)? true : false;
}
printf("IniFile::get %s BOOL %d\n", key, *(bool*)ret);
return S_SUCCESS;
default: // string
{
Status sts = strtrim(ret, p, ret_size);
printf("IniFile::get %s = '%s'\n", key, ret_size? ret : "E");
return sts;
}
}
}
printf("IniFile::get S_NO_KEY'%s'\n", key);
return S_NO_KEY; // No key
}
IniFile::Status IniFile::get(const char* key, int& ret){
return get(key, (char*)&ret, DTYPE_INT);
}
IniFile::Status IniFile::get(const char* key, bool& ret){
return get(key, (char*)&ret, DTYPE_BOOL);
}
IniFile::Status IniFile::get(const IniFile::IniList* inilist){
Status ret = S_SUCCESS;
for(; inilist->key ; ++inilist){
Status sts = get(inilist->key, (char*)inilist->buf, inilist->typelen);
switch(sts){
case S_SUCCESS:
break;
case S_NO_KEY:
ret = sts; // continue
break;
default:
return sts; // fatal error
}
}
return ret;
}