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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [Utils/] [common/] [Properties.cpp] - Blame information for rev 174

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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