URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [Utils/] [common/] [Properties.cpp] - Rev 174
Compare with Previous | Blame | View Log
//####COPYRIGHTBEGIN#### // // ---------------------------------------------------------------------------- // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // // This program is part of the eCos host tools. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // You should have received a copy of the GNU General Public License along with // this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### // Properties.cpp: implementation of the CProperties class. // ////////////////////////////////////////////////////////////////////// #include "Properties.h" #include "eCosTrace.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CProperties::CProperties() { } CProperties::~CProperties() { } #ifdef _WIN32 bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey) { HKEY hKey; LONG l=RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_QUERY_VALUE, &hKey); bool rc=(ERROR_SUCCESS==l); if(rc){ TCHAR szName[256]; DWORD dwSizeName=sizeof szName; DWORD dwMaxDatalen; DWORD dwType; if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxDatalen,NULL,NULL)){ char *Data=new char[dwMaxDatalen]; DWORD dwDatalen=dwMaxDatalen; for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumValue(hKey, dwIndex, szName, &dwSizeName, NULL, &dwType, (LPBYTE)Data, &dwDatalen);dwIndex++){ CProperties::CProperty *p=Lookup(szName); if(p){ switch(p->Type){ case CProperty::Integer: if(REG_DWORD==dwType){ p->SetValue(*(int *)Data); } else { TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Bool: if(REG_DWORD==dwType){ p->SetValue((bool)0!=*(int *)Data); } else { TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Char: if(REG_DWORD==dwType){ p->SetValue(*(char *)Data); } else { TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Short: if(REG_DWORD==dwType){ p->SetValue(*(short *)Data); } else { TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Float: case CProperty::Double: case CProperty::szString: if(REG_SZ==dwType){ rc&=p->SetValue((LPCTSTR)Data); } else { TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Void: if(REG_BINARY==dwType){ memcpy(p->pData,Data,MIN(dwDatalen,p->nLength)); } else { TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; } } else { TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s in key %s\n"),szName,szRegKey); rc=false; } dwSizeName=sizeof szName; dwDatalen=dwMaxDatalen; } delete [] Data; dwSizeName=sizeof szName; } RegCloseKey(hKey); } else { TRACE(_T("Failed to open %s\n"),szRegKey); } return rc; } bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey) const { HKEY hKey; CreateKey(szRegKey); bool rc=(ERROR_SUCCESS==RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_SET_VALUE, &hKey)); if(rc){ for(int i=ar.size()-1;i>=0;--i){ // Initializations are simply to avoid compiler warnings. DWORD dwDatalen=0; DWORD dwType=REG_DWORD; BYTE *Data=0; // strValue and dw *must* be in scope for RegSetValueEx below. DWORD dw; String strValue; const CProperty &p=ar[i]; switch(p.Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: dwType=REG_DWORD; dwDatalen=sizeof(DWORD); dw=p.GetValue(); Data=(BYTE *)&dw; break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::szString: strValue=p.GetStringValue(); Data=(BYTE *)(LPCTSTR)strValue; dwType=REG_SZ; dwDatalen=(1+strValue.size())*sizeof(_TCHAR); break; case CProperties::CProperty::Void: Data=(BYTE *)p.pData; dwType=REG_BINARY; dwDatalen=p.nLength; break; default: assert(false); break; } rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,p.strName,0,dwType,Data,dwDatalen)); } } RegCloseKey(hKey); return rc; } // Create all keys down to the one specified bool CProperties::CreateKey(LPCTSTR pszKey,HKEY hKey/*=HKEY_CURRENT_USER*/) { bool rc=true; LPCTSTR pcStart=pszKey; LPCTSTR pcEnd; do { HKEY hKey2; pcEnd=_tcschr(pcStart,_TCHAR('\\')); if(NULL==pcEnd){ pcEnd=pcStart+_tcslen(pcStart); } String strKey(pcStart,pcEnd-pcStart); if(ERROR_SUCCESS!=RegCreateKeyEx(hKey, // handle to an open key strKey, // address of subkey name 0, // reserved 0, // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure &hKey2, // address of buffer for opened handle NULL// address of disposition value buffer); )){ rc=false; break; } RegCloseKey(hKey); hKey=hKey2; pcStart=pcEnd+1; } while (_TCHAR('\0')!=*pcEnd); RegCloseKey(hKey); return rc; } #endif bool CProperties::LoadFromCommandString(LPCTSTR psz) { bool rc=true; const TCHAR *cNext; for(LPCTSTR c=_tcschr(psz,_TCHAR('-'));c;c=_tcschr(cNext,_TCHAR('-'))){ c++; const TCHAR *pEq=_tcschr(c,_TCHAR('=')); if(NULL==pEq){ TRACE(_T("Failed to find '=' after %s\n"),c); rc=false; break; } String strName(c,pEq-c); CProperties::CProperty *p=Lookup(strName); c=pEq+1; String str; if(_TCHAR('"')==*c){ // Value is a quoted string for(cNext=c+1;_TCHAR('"')!=*cNext;cNext++){ if(_TCHAR('\\')==*cNext){ cNext++; } str+=*cNext; } } else { // Value is simply terminated by whitespace for(cNext=c;_TCHAR('\0')!=*cNext && !_istspace(*cNext);cNext++); str=String(c,cNext-c); } if(p){ rc&=p->SetValue(str); } else { TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName); rc=false; } c=cNext; } return rc; } CProperties::CProperty * CProperties::Lookup(LPCTSTR pszName) { for(int i=ar.size()-1;i>=0;--i){ CProperties::CProperty &p=ar[i]; if(0==_tcsicmp(p.strName,pszName)){ return &p; } } return NULL; } String CProperties::MakeCommandString() const { String strResult; bool bFirst=true; for(int i=ar.size()-1;i>=0;--i){ String str; const CProperty &p=ar[i]; switch(p.Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: str.Format(_T("-%s=%u"),(LPCTSTR)p.strName,p.GetValue()); break; case CProperties::CProperty::szString: { // Quote the string, escaping existing quotes as necessary str.Format(_T("-%s=\""),(LPCTSTR)p.strName); for(LPCTSTR c=p.GetStringValue();*c;c++){ if(_TCHAR('"')==*c){ str+=_TCHAR('\\'); } str+=*c; } str+=_TCHAR('"'); } break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::Void: str.Format(_T("-%s=%s"),(LPCTSTR)p.GetStringValue()); break; } if(!bFirst){ strResult+=_TCHAR(' '); } bFirst=false; strResult+=str; } return strResult; } bool CProperties::CreatePathToFile(LPCTSTR pszDir) { // Create intermediate directories #ifdef _WIN32 const TCHAR cSep='\\'; #else // UNIX const TCHAR cSep='/'; #endif for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){ #ifdef _WIN32 if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ continue; // don't attempt to create "C:" } #endif String strDir(pszDir,c-pszDir); struct _stat buf; if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){ // Need to create directory bool b=(0==_tmkdir(strDir)); TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b); if(!b){ return false; } } } return true; } bool CProperties::SaveToFile(LPCTSTR pszFileName) const { CreatePathToFile(pszFileName); FILE *f=_tfopen(pszFileName,_T("w") MODE_TEXT); if(f){ for(int i=ar.size()-1;i>=0;--i){ const CProperty &p=ar[i]; String str(p.strName); str+=_TCHAR('='); switch(p.Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: str+=String::SFormat(_T("%u"),p.GetValue()); break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::szString: case CProperties::CProperty::Void: str+=p.GetStringValue(); break; } str+=_TCHAR('\n'); _fputts(str,f); } fclose(f); } return (0!=f); } bool CProperties::LoadFromFile(LPCTSTR pszFileName) { FILE *f=_tfopen(pszFileName,_T("r") MODE_TEXT); bool rc=(0!=f); if(rc){ TCHAR buf[4096]; int nLine=0; String str; while(_fgetts(buf,sizeof(buf)-1,f)){ nLine++; int nLen=_tcslen(buf); if(nLen>0){ // Remove trailing '\n' if(_TCHAR('\n')==buf[nLen-1]){ buf[--nLen]=_TCHAR('\0'); } // Remove trailing '\r' if(_TCHAR('\r')==buf[nLen-1]){ buf[--nLen]=_TCHAR('\0'); } // Check for continuation lines if(_TCHAR('\\')==buf[nLen-1]){ buf[--nLen]=_TCHAR('\0'); str+=buf; } else { str+=buf; LPCTSTR c=(LPCTSTR)str; const TCHAR *pEq=_tcschr(c,_TCHAR('=')); if(pEq){ const String strName(c,pEq-c); CProperties::CProperty *p=Lookup(strName); if(p){ pEq++; rc&=p->SetValue(pEq); } else { ERROR(_T("Unknown attribute %s found in %s line %d\n"),(LPCTSTR)strName,pszFileName,nLine); rc=false; } } str=_T(""); } } } fclose(f); } return rc; } CProperties::CProperty::CProperty(LPCTSTR pszName,Typetype type,void *_pData): strName(pszName), Type(type), pData(_pData) { } CProperties::CProperty::~CProperty() { } void CProperties::Add(LPCTSTR pszName,int &n) { CProperty p(pszName,CProperty::Integer,&n); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,unsigned int &n) { CProperty p(pszName,CProperty::Integer,&n); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,bool &b) { CProperty p(pszName,CProperty::Bool,&b); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,char &c) { CProperty p(pszName,CProperty::Char,&c); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,unsigned char &c) { CProperty p(pszName,CProperty::Char,&c); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,short &s) { CProperty p(pszName,CProperty::Short,&s); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,unsigned short &s) { CProperty p(pszName,CProperty::Short,&s); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,float &f) { CProperty p(pszName,CProperty::Float,&f); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,double &f) { CProperty p(pszName,CProperty::Double,&f); ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,void *pv,unsigned int _nLength) { CProperty p(pszName,CProperty::Void,pv); p.nLength=_nLength; ar.push_back(p); } void CProperties::Add(LPCTSTR pszName,String &s) { CProperty p(pszName,CProperty::szString,(void *)&s); ar.push_back(p); } unsigned long CProperties::CProperty::GetValue() const { unsigned long dw; switch(Type){ case Integer: dw=*(int *)pData; break; case Bool: dw=*(bool *)pData; break; case Char: dw=*(char *)pData; break; case Short: dw=*(short *)pData; break; default: dw=0; assert(false); } return dw; } const String CProperties::CProperty::GetStringValue() const { String str; switch(Type){ case szString: str=*(String *)pData; break; case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: str.Format(_T("%u"),GetValue()); break; case CProperties::CProperty::Float: str.Format(_T("%e"),*(float *)(pData)); break; case CProperties::CProperty::Double: str.Format(_T("%e"),*(double *)(pData)); break; case CProperties::CProperty::Void: { unsigned char *c=(unsigned char *)pData; for(unsigned int i=0;i<nLength;i++){ TCHAR buf[3]; _tprintf(buf,_T("%02x"),c[i]); str+=buf; } } break; default: break; } return str; } bool CProperties::CProperty::SetValue(int n) { bool rc=true; switch(Type){ case Integer: *(int *)(pData)=n; break; case Bool: *(bool *)(pData)=(0!=n); break; case Char: *(char *)(pData)=(char)n; //FIXME: range checks break; case Short: *(short *)(pData)=(short)n;//FIXME: range checks break; default: TRACE(_T("Failed to set '%s' to integer value '%d'\n"),(LPCTSTR)strName,n); break; } return rc; } bool CProperties::CProperty::SetValue(double n) { bool rc=true; switch(Type){ case Double: *(float *)(pData)=(float)n;//FIXME: range checks? break; case Float: *(double *)(pData)=n; break; default: TRACE(_T("Failed to set '%s' to double value '%f'\n"),(LPCTSTR)strName,n); rc=false; break; } return rc; } bool CProperties::CProperty::SetValue(LPCTSTR psz) { bool rc=false; TCHAR *pEnd; double d=0.0; long l=0; switch(Type){ case szString: *(String *)pData=psz; rc=true; break; case Float: d=_tcstod(psz,&pEnd); rc=(_TCHAR('\0')==*pEnd); if(rc){ SetValue((float)d); } break; case Double: d=_tcstod(psz,&pEnd); rc=(_TCHAR('\0')==*pEnd); if(rc){ SetValue(d); } break; case Integer: case Bool: case Char: case Short: l=_tcstol(psz,&pEnd,10); rc=(_TCHAR('\0')==*pEnd); if(rc){ SetValue((int)l); } break; default: TRACE(_T("Failed to set '%s' to string value '%s'\n"),(LPCTSTR)strName,psz); break; } return rc; }