OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [Utils/] [common/] [Properties.cpp] - Blame information for rev 790

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
2
// -------------------------------------------                              
3
// This file is part of the eCos host tools.                                
4
// Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.            
5
//
6
// This program is free software; you can redistribute it and/or modify     
7
// it under the terms of the GNU General Public License as published by     
8
// the Free Software Foundation; either version 2 or (at your option) any   
9
// later version.                                                           
10
//
11
// This program is distributed in the hope that it will be useful, but      
12
// WITHOUT ANY WARRANTY; without even the implied warranty of               
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
14
// General Public License for more details.                                 
15
//
16
// You should have received a copy of the GNU General Public License        
17
// along with this program; if not, write to the                            
18
// Free Software Foundation, Inc., 51 Franklin Street,                      
19
// Fifth Floor, Boston, MA  02110-1301, USA.                                
20
// -------------------------------------------                              
21
// ####ECOSHOSTGPLCOPYRIGHTEND####                                          
22
// Properties.cpp: implementation of the CProperties class.
23
//
24
//////////////////////////////////////////////////////////////////////
25
#include "Properties.h"
26
#include "eCosTrace.h"
27
//////////////////////////////////////////////////////////////////////
28
// Construction/Destruction
29
//////////////////////////////////////////////////////////////////////
30
 
31
CProperties::CProperties()
32
{
33
}
34
 
35
CProperties::~CProperties()
36
{
37
}
38
 
39
#ifdef _WIN32
40
bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey)
41
{
42
  HKEY hKey;
43
  LONG l=RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_QUERY_VALUE, &hKey);
44
  bool rc=(ERROR_SUCCESS==l);
45
  if(rc){
46
    TCHAR szName[256];
47
    DWORD dwSizeName=sizeof szName;
48
    DWORD dwMaxDatalen;
49
    DWORD dwType;
50
    if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxDatalen,NULL,NULL)){
51
      char *Data=new char[dwMaxDatalen];
52
      DWORD dwDatalen=dwMaxDatalen;
53
      for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumValue(hKey, dwIndex, szName, &dwSizeName, NULL, &dwType, (LPBYTE)Data, &dwDatalen);dwIndex++){
54
 
55
        CProperties::CProperty *p=Lookup(szName);
56
        if(p){
57
          switch(p->Type){
58
            case CProperty::Integer:
59
              if(REG_DWORD==dwType){
60
                p->SetValue(*(int *)Data);
61
              } else {
62
                TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType);
63
                rc=false;
64
              }
65
              break;
66
            case CProperty::Bool:
67
              if(REG_DWORD==dwType){
68
                p->SetValue((bool)0!=*(int *)Data);
69
              } else {
70
                TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType);
71
                rc=false;
72
              }
73
              break;
74
            case CProperty::Char:
75
              if(REG_DWORD==dwType){
76
                p->SetValue(*(char *)Data);
77
              } else {
78
                TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType);
79
                rc=false;
80
              }
81
              break;
82
            case CProperty::Short:
83
              if(REG_DWORD==dwType){
84
                p->SetValue(*(short *)Data);
85
              } else {
86
                TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType);
87
                rc=false;
88
              }
89
              break;
90
            case CProperty::Float:
91
            case CProperty::Double:
92
            case CProperty::szString:
93
              if(REG_SZ==dwType){
94
                rc&=p->SetValue((LPCTSTR)Data);
95
              } else {
96
                TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType);
97
                rc=false;
98
              }
99
              break;
100
            case CProperty::Void:
101
              if(REG_BINARY==dwType){
102
                memcpy(p->pData,Data,MIN(dwDatalen,p->nLength));
103
              } else {
104
                TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType);
105
                rc=false;
106
              }
107
              break;
108
          }
109
        } else {
110
          TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s in key %s\n"),szName,szRegKey);
111
          rc=false;
112
        }
113
        dwSizeName=sizeof szName;
114
        dwDatalen=dwMaxDatalen;
115
      }
116
      delete [] Data;
117
      dwSizeName=sizeof szName;
118
    }
119
    RegCloseKey(hKey);
120
  } else {
121
    TRACE(_T("Failed to open %s\n"),szRegKey);
122
  }
123
 
124
  return rc;
125
}
126
 
127
bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey) const
128
{
129
  HKEY hKey;
130
  CreateKey(szRegKey);
131
  bool rc=(ERROR_SUCCESS==RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_SET_VALUE, &hKey));
132
  if(rc){
133
    for(int i=ar.size()-1;i>=0;--i){
134
      // Initializations are simply to avoid compiler warnings.
135
      DWORD dwDatalen=0;
136
      DWORD dwType=REG_DWORD;
137
      BYTE *Data=0;
138
      // strValue and dw *must* be in scope for RegSetValueEx below.
139
      DWORD dw;
140
      String strValue;
141
      const CProperty &p=ar[i];
142
      switch(p.Type){
143
        case CProperties::CProperty::Integer:
144
        case CProperties::CProperty::Bool:
145
        case CProperties::CProperty::Char:
146
        case CProperties::CProperty::Short:
147
          dwType=REG_DWORD;
148
          dwDatalen=sizeof(DWORD);
149
          dw=p.GetValue();
150
          Data=(BYTE *)&dw;
151
          break;
152
        case CProperties::CProperty::Float:
153
        case CProperties::CProperty::Double:
154
        case CProperties::CProperty::szString:
155
          strValue=p.GetStringValue();
156
          Data=(BYTE *)(LPCTSTR)strValue;
157
          dwType=REG_SZ;
158
          dwDatalen=(1+strValue.size())*sizeof(_TCHAR);
159
          break;
160
        case CProperties::CProperty::Void:
161
          Data=(BYTE *)p.pData;
162
          dwType=REG_BINARY;
163
          dwDatalen=p.nLength;
164
          break;
165
        default:
166
          assert(false);
167
          break;
168
      }
169
      rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,p.strName,0,dwType,Data,dwDatalen));
170
    }
171
  }
172
  RegCloseKey(hKey);
173
  return rc;
174
}
175
 
176
// Create all keys down to the one specified
177
bool CProperties::CreateKey(LPCTSTR pszKey,HKEY hKey/*=HKEY_CURRENT_USER*/)
178
{
179
  bool rc=true;
180
  LPCTSTR pcStart=pszKey;
181
  LPCTSTR pcEnd;
182
  do {
183
    HKEY hKey2;
184
    pcEnd=_tcschr(pcStart,_TCHAR('\\'));
185
    if(NULL==pcEnd){
186
      pcEnd=pcStart+_tcslen(pcStart);
187
    }
188
    String strKey(pcStart,pcEnd-pcStart);
189
    if(ERROR_SUCCESS!=RegCreateKeyEx(hKey,                // handle to an open key
190
      strKey,         // address of subkey name
191
      0,           // reserved
192
      0,           // address of class string
193
      REG_OPTION_NON_VOLATILE,          // special options flag
194
      KEY_ALL_ACCESS,        // desired security access
195
      NULL,
196
      // address of key security structure
197
      &hKey2,          // address of buffer for opened handle
198
      NULL// address of disposition value buffer);
199
      )){
200
      rc=false;
201
      break;
202
    }
203
    RegCloseKey(hKey);
204
    hKey=hKey2;
205
    pcStart=pcEnd+1;
206
  } while (_TCHAR('\0')!=*pcEnd);
207
  RegCloseKey(hKey);
208
  return rc;
209
}
210
 
211
#endif
212
 
213
bool CProperties::LoadFromCommandString(LPCTSTR psz)
214
{
215
  bool rc=true;
216
  const TCHAR *cNext;
217
  for(LPCTSTR c=_tcschr(psz,_TCHAR('-'));c;c=_tcschr(cNext,_TCHAR('-'))){
218
    c++;
219
    const TCHAR *pEq=_tcschr(c,_TCHAR('='));
220
    if(NULL==pEq){
221
      TRACE(_T("Failed to find '=' after %s\n"),c);
222
      rc=false;
223
      break;
224
    }
225
    String strName(c,pEq-c);
226
    CProperties::CProperty *p=Lookup(strName);
227
    c=pEq+1;
228
    String str;
229
    if(_TCHAR('"')==*c){
230
      // Value is a quoted string
231
      for(cNext=c+1;_TCHAR('"')!=*cNext;cNext++){
232
        if(_TCHAR('\\')==*cNext){
233
          cNext++;
234
        }
235
        str+=*cNext;
236
      }
237
    } else {
238
      // Value is simply terminated by whitespace
239
      for(cNext=c;_TCHAR('\0')!=*cNext && !_istspace(*cNext);cNext++);
240
      str=String(c,cNext-c);
241
    }
242
    if(p){
243
      rc&=p->SetValue(str);
244
    } else {
245
      TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName);
246
      rc=false;
247
    }
248
    c=cNext;
249
  }
250
  return rc;
251
}
252
 
253
CProperties::CProperty * CProperties::Lookup(LPCTSTR pszName)
254
{
255
  for(int i=ar.size()-1;i>=0;--i){
256
    CProperties::CProperty &p=ar[i];
257
    if(0==_tcsicmp(p.strName,pszName)){
258
      return &p;
259
    }
260
  }
261
  return NULL;
262
}
263
 
264
String CProperties::MakeCommandString() const
265
{
266
  String strResult;
267
  bool bFirst=true;
268
  for(int i=ar.size()-1;i>=0;--i){
269
    String str;
270
    const CProperty &p=ar[i];
271
    switch(p.Type){
272
      case CProperties::CProperty::Integer:
273
      case CProperties::CProperty::Bool:
274
      case CProperties::CProperty::Char:
275
      case CProperties::CProperty::Short:
276
        str.Format(_T("-%s=%u"),(LPCTSTR)p.strName,p.GetValue());
277
        break;
278
      case CProperties::CProperty::szString:
279
        {
280
          // Quote the string, escaping existing quotes as necessary
281
          str.Format(_T("-%s=\""),(LPCTSTR)p.strName);
282
          for(LPCTSTR c=p.GetStringValue();*c;c++){
283
            if(_TCHAR('"')==*c){
284
              str+=_TCHAR('\\');
285
            }
286
            str+=*c;
287
          }
288
          str+=_TCHAR('"');
289
        }
290
        break;
291
      case CProperties::CProperty::Float:
292
      case CProperties::CProperty::Double:
293
      case CProperties::CProperty::Void:
294
        str.Format(_T("-%s=%s"),(LPCTSTR)p.GetStringValue());
295
        break;
296
    }
297
    if(!bFirst){
298
      strResult+=_TCHAR(' ');
299
    }
300
    bFirst=false;
301
    strResult+=str;
302
  }
303
  return strResult;
304
}
305
 
306
bool CProperties::CreatePathToFile(LPCTSTR pszDir)
307
{
308
  // Create intermediate directories
309
#ifdef _WIN32
310
  const TCHAR cSep='\\';
311
#else // UNIX
312
  const TCHAR cSep='/';
313
#endif
314
  for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){
315
#ifdef _WIN32
316
    if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){
317
      continue; // don't attempt to create "C:"
318
    }
319
#endif
320
    String strDir(pszDir,c-pszDir);
321
    struct _stat buf;
322
    if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){
323
      // Need to create directory
324
      bool b=(0==_tmkdir(strDir));
325
      TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b);
326
      if(!b){
327
        return false;
328
      }
329
    }
330
  }
331
  return true;
332
}
333
 
334
bool CProperties::SaveToFile(LPCTSTR pszFileName) const
335
{
336
  CreatePathToFile(pszFileName);
337
  FILE *f=_tfopen(pszFileName,_T("w") MODE_TEXT);
338
  if(f){
339
    for(int i=ar.size()-1;i>=0;--i){
340
      const CProperty &p=ar[i];
341
      String str(p.strName);
342
      str+=_TCHAR('=');
343
      switch(p.Type){
344
        case CProperties::CProperty::Integer:
345
        case CProperties::CProperty::Bool:
346
        case CProperties::CProperty::Char:
347
        case CProperties::CProperty::Short:
348
          str+=String::SFormat(_T("%u"),p.GetValue());
349
          break;
350
        case CProperties::CProperty::Float:
351
        case CProperties::CProperty::Double:
352
        case CProperties::CProperty::szString:
353
        case CProperties::CProperty::Void:
354
          str+=p.GetStringValue();
355
          break;
356
      }
357
      str+=_TCHAR('\n');
358
      _fputts(str,f);
359
    }
360
    fclose(f);
361
  }
362
  return (0!=f);
363
}
364
 
365
bool CProperties::LoadFromFile(LPCTSTR pszFileName)
366
{
367
  FILE *f=_tfopen(pszFileName,_T("r") MODE_TEXT);
368
  bool rc=(0!=f);
369
  if(rc){
370
    TCHAR buf[4096];
371
    int nLine=0;
372
    String str;
373
    while(_fgetts(buf,sizeof(buf)-1,f)){
374
 
375
      nLine++;
376
      int nLen=_tcslen(buf);
377
      if(nLen>0){
378
        // Remove trailing '\n'
379
        if(_TCHAR('\n')==buf[nLen-1]){
380
          buf[--nLen]=_TCHAR('\0');
381
        }
382
        // Remove trailing '\r'
383
        if(_TCHAR('\r')==buf[nLen-1]){
384
          buf[--nLen]=_TCHAR('\0');
385
        }
386
 
387
        // Check for continuation lines
388
        if(_TCHAR('\\')==buf[nLen-1]){
389
          buf[--nLen]=_TCHAR('\0');
390
          str+=buf;
391
        } else {
392
          str+=buf;
393
          LPCTSTR c=(LPCTSTR)str;
394
          const TCHAR *pEq=_tcschr(c,_TCHAR('='));
395
          if(pEq){
396
            const String strName(c,pEq-c);
397
            CProperties::CProperty *p=Lookup(strName);
398
            if(p){
399
              pEq++;
400
              rc&=p->SetValue(pEq);
401
            } else {
402
              ERROR(_T("Unknown attribute %s found in %s line %d\n"),(LPCTSTR)strName,pszFileName,nLine);
403
              rc=false;
404
            }
405
          }
406
          str=_T("");
407
        }
408
      }
409
    }
410
    fclose(f);
411
  }
412
  return rc;
413
}
414
 
415
CProperties::CProperty::CProperty(LPCTSTR pszName,Typetype type,void *_pData):
416
  strName(pszName),
417
  Type(type),
418
  pData(_pData)
419
{
420
}
421
 
422
CProperties::CProperty::~CProperty()
423
{
424
}
425
 
426
void CProperties::Add(LPCTSTR pszName,int &n)
427
{
428
  CProperty p(pszName,CProperty::Integer,&n);
429
  ar.push_back(p);
430
}
431
 
432
void CProperties::Add(LPCTSTR pszName,unsigned int &n)
433
{
434
  CProperty p(pszName,CProperty::Integer,&n);
435
  ar.push_back(p);
436
}
437
 
438
void CProperties::Add(LPCTSTR pszName,bool &b)
439
{
440
  CProperty p(pszName,CProperty::Bool,&b);
441
  ar.push_back(p);
442
}
443
 
444
void CProperties::Add(LPCTSTR pszName,char &c)
445
{
446
  CProperty p(pszName,CProperty::Char,&c);
447
  ar.push_back(p);
448
}
449
 
450
void CProperties::Add(LPCTSTR pszName,unsigned char &c)
451
{
452
  CProperty p(pszName,CProperty::Char,&c);
453
  ar.push_back(p);
454
}
455
 
456
void CProperties::Add(LPCTSTR pszName,short &s)
457
{
458
  CProperty p(pszName,CProperty::Short,&s);
459
  ar.push_back(p);
460
}
461
 
462
void CProperties::Add(LPCTSTR pszName,unsigned short &s)
463
{
464
  CProperty p(pszName,CProperty::Short,&s);
465
  ar.push_back(p);
466
}
467
 
468
void CProperties::Add(LPCTSTR pszName,float &f)
469
{
470
  CProperty p(pszName,CProperty::Float,&f);
471
  ar.push_back(p);
472
}
473
 
474
void CProperties::Add(LPCTSTR pszName,double &f)
475
{
476
  CProperty p(pszName,CProperty::Double,&f);
477
  ar.push_back(p);
478
}
479
 
480
void CProperties::Add(LPCTSTR pszName,void *pv,unsigned int _nLength)
481
{
482
  CProperty p(pszName,CProperty::Void,pv);
483
  p.nLength=_nLength;
484
  ar.push_back(p);
485
}
486
 
487
void CProperties::Add(LPCTSTR pszName,String &s)
488
{
489
  CProperty p(pszName,CProperty::szString,(void *)&s);
490
  ar.push_back(p);
491
}
492
 
493
unsigned long CProperties::CProperty::GetValue() const
494
{
495
  unsigned long dw;
496
  switch(Type){
497
    case Integer:
498
      dw=*(int *)pData;
499
      break;
500
    case Bool:
501
      dw=*(bool *)pData;
502
      break;
503
    case Char:
504
      dw=*(char *)pData;
505
      break;
506
    case Short:
507
      dw=*(short *)pData;
508
      break;
509
    default:
510
      dw=0;
511
      assert(false);
512
  }
513
  return dw;
514
}
515
 
516
const String CProperties::CProperty::GetStringValue() const
517
{
518
  String str;
519
  switch(Type){
520
    case szString:
521
      str=*(String *)pData;
522
      break;
523
    case CProperties::CProperty::Integer:
524
    case CProperties::CProperty::Bool:
525
    case CProperties::CProperty::Char:
526
    case CProperties::CProperty::Short:
527
      str.Format(_T("%u"),GetValue());
528
      break;
529
    case CProperties::CProperty::Float:
530
      str.Format(_T("%e"),*(float *)(pData));
531
      break;
532
    case CProperties::CProperty::Double:
533
      str.Format(_T("%e"),*(double *)(pData));
534
      break;
535
    case CProperties::CProperty::Void:
536
      {
537
        unsigned char *c=(unsigned char *)pData;
538
        for(unsigned int i=0;i<nLength;i++){
539
          TCHAR buf[3];
540
          _tprintf(buf,_T("%02x"),c[i]);
541
          str+=buf;
542
        }
543
      }
544
      break;
545
    default:
546
      break;
547
  }
548
  return str;
549
}
550
 
551
bool CProperties::CProperty::SetValue(int n)
552
{
553
  bool rc=true;
554
  switch(Type){
555
    case Integer:
556
      *(int *)(pData)=n;
557
      break;
558
    case Bool:
559
      *(bool *)(pData)=(0!=n);
560
      break;
561
    case Char:
562
      *(char *)(pData)=(char)n; //FIXME: range checks
563
      break;
564
    case Short:
565
      *(short *)(pData)=(short)n;//FIXME: range checks
566
      break;
567
    default:
568
      TRACE(_T("Failed to set '%s' to integer value '%d'\n"),(LPCTSTR)strName,n);
569
      break;
570
  }
571
  return rc;
572
}
573
 
574
bool CProperties::CProperty::SetValue(double n)
575
{
576
  bool rc=true;
577
  switch(Type){
578
    case Double:
579
      *(float *)(pData)=(float)n;//FIXME: range checks?
580
      break;
581
    case Float:
582
      *(double *)(pData)=n;
583
      break;
584
    default:
585
      TRACE(_T("Failed to set '%s' to double value '%f'\n"),(LPCTSTR)strName,n);
586
      rc=false;
587
      break;
588
  }
589
 
590
  return rc;
591
}
592
 
593
bool CProperties::CProperty::SetValue(LPCTSTR psz)
594
{
595
  bool rc=false;
596
  TCHAR *pEnd;
597
  double d=0.0;
598
  long l=0;
599
  switch(Type){
600
    case szString:
601
      *(String *)pData=psz;
602
      rc=true;
603
      break;
604
    case Float:
605
      d=_tcstod(psz,&pEnd);
606
      rc=(_TCHAR('\0')==*pEnd);
607
      if(rc){
608
        SetValue((float)d);
609
      }
610
      break;
611
    case Double:
612
      d=_tcstod(psz,&pEnd);
613
      rc=(_TCHAR('\0')==*pEnd);
614
      if(rc){
615
        SetValue(d);
616
      }
617
      break;
618
    case Integer:
619
    case Bool:
620
    case Char:
621
    case Short:
622
      l=_tcstol(psz,&pEnd,10);
623
      rc=(_TCHAR('\0')==*pEnd);
624
      if(rc){
625
        SetValue((int)l);
626
      }
627
      break;
628
    default:
629
      TRACE(_T("Failed to set '%s' to string value '%s'\n"),(LPCTSTR)strName,psz);
630
      break;
631
  }
632
  return rc;
633
}
634
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.