[363] | 1 | /*
|
---|
| 2 | * TOPPERS/JSP Kernel
|
---|
| 3 | * Toyohashi Open Platform for Embedded Real-Time Systems/
|
---|
| 4 | * Just Standard Profile Kernel
|
---|
| 5 | *
|
---|
| 6 | * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
|
---|
| 7 | * Toyohashi Univ. of Technology, JAPAN
|
---|
| 8 | *
|
---|
| 9 | * ä¸è¨èä½æ¨©è
|
---|
| 10 | ã¯ï¼ä»¥ä¸ã® (1)ã(4) ã®æ¡ä»¶ãï¼Free Software Foundation
|
---|
| 11 | * ã«ãã£ã¦å
|
---|
| 12 | ¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
|
---|
| 13 | * è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
|
---|
| 14 | * ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ã使ç¨ã»è¤è£½ã»æ¹å¤ã»åé
|
---|
| 15 | å¸ï¼ä»¥ä¸ï¼
|
---|
| 16 | * å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
|
---|
| 17 | * (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
|
---|
| 18 | * 権表示ï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
|
---|
| 19 | * ã¹ã³ã¼ãä¸ã«å«ã¾ãã¦ãããã¨ï¼
|
---|
| 20 | * (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
| 21 | * ç¨ã§ããå½¢ã§åé
|
---|
| 22 | å¸ããå ´åã«ã¯ï¼åé
|
---|
| 23 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨
|
---|
| 24 | * è
|
---|
| 25 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
|
---|
| 26 | * ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
| 27 | * (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
| 28 | * ç¨ã§ããªãå½¢ã§åé
|
---|
| 29 | å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
|
---|
| 30 | * ã¨ï¼
|
---|
| 31 | * (a) åé
|
---|
| 32 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨è
|
---|
| 33 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
|
---|
| 34 | * ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
| 35 | * (b) åé
|
---|
| 36 | å¸ã®å½¢æ
|
---|
| 37 | ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSããã¸ã§ã¯ãã«
|
---|
| 38 | * å ±åãããã¨ï¼
|
---|
| 39 | * (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
|
---|
| 40 | * 害ãããï¼ä¸è¨èä½æ¨©è
|
---|
| 41 | ããã³TOPPERSããã¸ã§ã¯ããå
|
---|
| 42 | 責ãããã¨ï¼
|
---|
| 43 | *
|
---|
| 44 | * æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
|
---|
| 45 | ã
|
---|
| 46 | * ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
|
---|
| 47 | * å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
|
---|
| 48 | * æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
|
---|
| 49 | *
|
---|
| 50 | * @(#) $Id: directorymap.cpp,v 1.12 2003/12/15 07:32:13 takayuki Exp $
|
---|
| 51 | */
|
---|
| 52 |
|
---|
| 53 |
|
---|
| 54 | // $Header: /home/CVS/configurator/base/directorymap.cpp,v 1.12 2003/12/15 07:32:13 takayuki Exp $
|
---|
| 55 |
|
---|
| 56 | /* MEMO:ã¡ã¢æ¸ã
|
---|
| 57 | Q: ããããã¯ã©ã¹ã¯ãã³ãã¬ã¼ãã«ããã»ããããã¨æãã?
|
---|
| 58 | A: ãã¡ã¤ã«ã«åãåºããå¾ãèªã¿åºããã¨ãã«ã©ããã£ã¦ã¯ã©ã¹çæãã¹ãããããããªã
|
---|
| 59 | (ã¯ã©ã¹ãã¡ã¯ããªãä½ãã®ã¯ãããã)
|
---|
| 60 | ä»ã¨éãåã代å
|
---|
| 61 | ¥ãããã¨ãã®å¯¾å¦æ³ãããããªã
|
---|
| 62 | */
|
---|
| 63 |
|
---|
| 64 |
|
---|
| 65 | #include "base/directorymap.h"
|
---|
| 66 | #include "base/message.h"
|
---|
| 67 | #include <stdarg.h>
|
---|
| 68 | #include <typeinfo>
|
---|
| 69 | #include <cassert>
|
---|
| 70 | #include <cstdio>
|
---|
| 71 |
|
---|
| 72 | #ifdef _MSC_VER
|
---|
| 73 | #pragma warning(disable:4786)
|
---|
| 74 | #endif
|
---|
| 75 |
|
---|
| 76 | using namespace std;
|
---|
| 77 |
|
---|
| 78 | int Directory::defaultflag = Directory::NOTHING;
|
---|
| 79 |
|
---|
| 80 | Directory::Directory(const Directory & src)
|
---|
| 81 | {
|
---|
| 82 | parent = 0;
|
---|
| 83 | flag = defaultflag;
|
---|
| 84 | defaultflag &= ~DESTRUCT;
|
---|
| 85 |
|
---|
| 86 | type = src.type;
|
---|
| 87 | switch(type)
|
---|
| 88 | {
|
---|
| 89 | case LITERAL:
|
---|
| 90 | content.literal = new string(*src.content.literal);
|
---|
| 91 | break;
|
---|
| 92 | default:
|
---|
| 93 | content = src.content;
|
---|
| 94 | break;
|
---|
| 95 | }
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | Directory::~Directory(void)
|
---|
| 99 | {
|
---|
| 100 | disconnect(); //親ã¨ã®é£çµã解é¤
|
---|
| 101 | map<string,Directory*>::clear(); //åãã¼ãã®åé¤
|
---|
| 102 | clearContent(); //èªåã®ä¸èº«ãåé¤ãã
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | void Directory::clearContent(void)
|
---|
| 106 | {
|
---|
| 107 | switch(this->getType())
|
---|
| 108 | {
|
---|
| 109 | case LITERAL:
|
---|
| 110 | delete content.literal;
|
---|
| 111 | break;
|
---|
| 112 | case OBJECT:
|
---|
| 113 | delete content.instance;
|
---|
| 114 | break;
|
---|
| 115 | default:
|
---|
| 116 | break;
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | type = UNKNOWN;
|
---|
| 120 | content.pointer = 0;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | Directory * Directory::findNode(bool automatic_creation, const string & path)
|
---|
| 124 | {
|
---|
| 125 | string::size_type top, tail, length;
|
---|
| 126 | string work;
|
---|
| 127 | Directory::iterator scope;
|
---|
| 128 | Directory * node = this;
|
---|
| 129 |
|
---|
| 130 | if(this == NULL)
|
---|
| 131 | return NULL;
|
---|
| 132 |
|
---|
| 133 | if(path.empty())
|
---|
| 134 | return this;
|
---|
| 135 |
|
---|
| 136 | length = path.length();
|
---|
| 137 | top = 0;
|
---|
| 138 | if(path[0] == '/')
|
---|
| 139 | {
|
---|
| 140 | while(node->getParent() != 0)
|
---|
| 141 | node = node->getParent();
|
---|
| 142 | if(path.size() == 1)
|
---|
| 143 | return node;
|
---|
| 144 | top = 1;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | do {
|
---|
| 148 | tail = path.find_first_of('/', top);
|
---|
| 149 | if(tail == string::npos)
|
---|
| 150 | work = path.substr(top);
|
---|
| 151 | else
|
---|
| 152 | work = path.substr(top, tail-top);
|
---|
| 153 |
|
---|
| 154 | if(work.compare(".") == 0 || work.compare("..") == 0)
|
---|
| 155 | {
|
---|
| 156 | if(work.size() > 1 && node->getParent() != 0)
|
---|
| 157 | node = node->getParent();
|
---|
| 158 | }else
|
---|
| 159 | {
|
---|
| 160 | scope = node->begin();
|
---|
| 161 | while(scope != node->end())
|
---|
| 162 | {
|
---|
| 163 | if(work.compare((*scope).first) == 0)
|
---|
| 164 | break;
|
---|
| 165 | ++ scope;
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | if(scope == node->end())
|
---|
| 169 | {
|
---|
| 170 | if(!automatic_creation)
|
---|
| 171 | return 0;
|
---|
| 172 | node = node->addChild(work, new Directory);
|
---|
| 173 | }else
|
---|
| 174 | node = (*scope).second;
|
---|
| 175 | }
|
---|
| 176 | top = tail + 1;
|
---|
| 177 | } while( tail != string::npos && top < length );
|
---|
| 178 |
|
---|
| 179 | return node;
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 | Directory * Directory::findNode(bool automatic_creation, const char * key, va_list vl)
|
---|
| 183 | {
|
---|
| 184 | Directory::iterator scope;
|
---|
| 185 | Directory * node = this;
|
---|
| 186 |
|
---|
| 187 | if(this == NULL)
|
---|
| 188 | return NULL;
|
---|
| 189 |
|
---|
| 190 | if(key == NULL)
|
---|
| 191 | return this;
|
---|
| 192 |
|
---|
| 193 | if(*key == '/' && *(key+1) == '\x0')
|
---|
| 194 | {
|
---|
| 195 | while(node->getParent() != 0)
|
---|
| 196 | node = node->getParent();
|
---|
| 197 | if(vl == 0)
|
---|
| 198 | return node;
|
---|
| 199 | key = va_arg(vl, const char *);
|
---|
| 200 | }
|
---|
| 201 |
|
---|
| 202 | do {
|
---|
| 203 | if(strcmp(key,".") != 0)
|
---|
| 204 | {
|
---|
| 205 | if(strcmp(key,"..") == 0)
|
---|
| 206 | {
|
---|
| 207 | node = node->parent;
|
---|
| 208 | }else
|
---|
| 209 | {
|
---|
| 210 | scope = node->begin();
|
---|
| 211 | while(scope != node->end())
|
---|
| 212 | {
|
---|
| 213 | if((*scope).first.compare(key) == 0)
|
---|
| 214 | break;
|
---|
| 215 | ++ scope;
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | if(scope == node->end())
|
---|
| 219 | {
|
---|
| 220 | if(!automatic_creation)
|
---|
| 221 | return 0;
|
---|
| 222 | node = node->addChild(key, new Directory);
|
---|
| 223 | }else
|
---|
| 224 | node = (*scope).second;
|
---|
| 225 | }
|
---|
| 226 | }
|
---|
| 227 | if(vl != 0)
|
---|
| 228 | key = va_arg(vl, const char *);
|
---|
| 229 | else
|
---|
| 230 | break;
|
---|
| 231 | } while( key != 0 && node != 0);
|
---|
| 232 |
|
---|
| 233 | return node;
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 | Directory & Directory::operator =(void * pointer)
|
---|
| 237 | {
|
---|
| 238 | if(this->getType() != UNKNOWN && this->getType() != POINTER)
|
---|
| 239 | clearContent();
|
---|
| 240 |
|
---|
| 241 | type = POINTER;
|
---|
| 242 | content.pointer = pointer;
|
---|
| 243 | return *this;
|
---|
| 244 | }
|
---|
| 245 |
|
---|
| 246 | Directory & Directory::operator =(long value)
|
---|
| 247 | {
|
---|
| 248 | if(this->getType() != UNKNOWN && this->getType() != INTEGER)
|
---|
| 249 | clearContent();
|
---|
| 250 |
|
---|
| 251 | type = INTEGER;
|
---|
| 252 | content.value = value;
|
---|
| 253 | return *this;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | Directory & Directory::operator =(const string & literal)
|
---|
| 257 | {
|
---|
| 258 | if(this->getType() != UNKNOWN && this->getType() != LITERAL)
|
---|
| 259 | clearContent();
|
---|
| 260 |
|
---|
| 261 | type = LITERAL;
|
---|
| 262 | content.literal = new string(literal);
|
---|
| 263 |
|
---|
| 264 | return *this;
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | Directory & Directory::operator =(const char * constliteral)
|
---|
| 268 | {
|
---|
| 269 | if(this->getType() != UNKNOWN && this->getType() != CONSTLITERAL)
|
---|
| 270 | clearContent();
|
---|
| 271 |
|
---|
| 272 | type = CONSTLITERAL;
|
---|
| 273 | content.const_literal = constliteral;
|
---|
| 274 | return *this;
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | Directory & Directory::operator =(Garbage * instance)
|
---|
| 278 | {
|
---|
| 279 | if(this->getType() != UNKNOWN)
|
---|
| 280 | clearContent();
|
---|
| 281 |
|
---|
| 282 | type = OBJECT;
|
---|
| 283 | content.instance = instance;
|
---|
| 284 | return *this;
|
---|
| 285 | }
|
---|
| 286 |
|
---|
| 287 | void * Directory::operator new(size_t sz)
|
---|
| 288 | {
|
---|
| 289 | defaultflag |= DESTRUCT;
|
---|
| 290 | return ::operator new(sz);
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | void * Directory::operator new(size_t sz, nothrow_t)
|
---|
| 294 | {
|
---|
| 295 | defaultflag |= DESTRUCT;
|
---|
| 296 | return ::operator new(sz, nothrow);
|
---|
| 297 | }
|
---|
| 298 |
|
---|
| 299 | Directory::operator const long(void) const
|
---|
| 300 | {
|
---|
| 301 | if( type == UNKNOWN )
|
---|
| 302 | ExceptionMessage("Bad cast exception","ä¸æ£ãã£ã¹ãä¾å¤") << throwException;
|
---|
| 303 | return content.value;
|
---|
| 304 | }
|
---|
| 305 |
|
---|
| 306 | void * Directory::operator * (void) const
|
---|
| 307 | {
|
---|
| 308 | if( type == UNKNOWN )
|
---|
| 309 | ExceptionMessage("Bad cast exception","ä¸æ£ãã£ã¹ãä¾å¤") << throwException;
|
---|
| 310 | return content.pointer;
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | Directory * Directory::addChild(const std::string & key, Directory * node)
|
---|
| 314 | {
|
---|
| 315 | iterator scope;
|
---|
| 316 | std::pair<iterator, bool> work;
|
---|
| 317 |
|
---|
| 318 | if(node == 0)
|
---|
| 319 | node = new Directory;
|
---|
| 320 | else
|
---|
| 321 | if(node->parent != 0)
|
---|
| 322 | node->disconnect();
|
---|
| 323 |
|
---|
| 324 | node->parent = this;
|
---|
| 325 | if((scope = find(key)) != end())
|
---|
| 326 | {
|
---|
| 327 | Directory * old = (*scope).second;
|
---|
| 328 | old->disconnect();
|
---|
| 329 | old->erase();
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | work = insert(value_type(key, node));
|
---|
| 333 | node->myself = work.first;
|
---|
| 334 |
|
---|
| 335 | return node;
|
---|
| 336 | }
|
---|
| 337 |
|
---|
| 338 | Directory::iterator Directory::erase(iterator it)
|
---|
| 339 | {
|
---|
| 340 | iterator result;
|
---|
| 341 | Directory * scope = (*it).second;
|
---|
| 342 |
|
---|
| 343 | //æ»ãå¤ã®ä½æ
|
---|
| 344 | if((result = it) == begin())
|
---|
| 345 | ++ result;
|
---|
| 346 | else
|
---|
| 347 | -- result;
|
---|
| 348 |
|
---|
| 349 | //å¤ãããã¼ãã®å¾å§æ«
|
---|
| 350 | if((scope->flag & DESTRUCT) != 0)
|
---|
| 351 | delete scope;
|
---|
| 352 | else
|
---|
| 353 | scope->erase();
|
---|
| 354 |
|
---|
| 355 | return result;
|
---|
| 356 | }
|
---|
| 357 |
|
---|
| 358 | void Directory::erase(void)
|
---|
| 359 | {
|
---|
| 360 | iterator scope;
|
---|
| 361 |
|
---|
| 362 | if(this != NULL)
|
---|
| 363 | {
|
---|
| 364 | if(parent != 0)
|
---|
| 365 | {
|
---|
| 366 | parent->erase(myself);
|
---|
| 367 | }else
|
---|
| 368 | {
|
---|
| 369 | while(!empty())
|
---|
| 370 | {
|
---|
| 371 | scope = begin();
|
---|
| 372 | if((scope->second->flag & DESTRUCT) != 0)
|
---|
| 373 | delete scope->second;
|
---|
| 374 | else
|
---|
| 375 | scope->second->erase();
|
---|
| 376 | }
|
---|
| 377 | }
|
---|
| 378 | }
|
---|
| 379 | }
|
---|
| 380 |
|
---|
| 381 | void Directory::disconnect(void)
|
---|
| 382 | {
|
---|
| 383 | if(parent != 0)
|
---|
| 384 | {
|
---|
| 385 | parent->map<string,Directory*>::erase(myself);
|
---|
| 386 | parent = 0;
|
---|
| 387 | }
|
---|
| 388 | }
|
---|
| 389 |
|
---|
| 390 | Directory * Directory::getNext(void) const
|
---|
| 391 | {
|
---|
| 392 | if(parent == 0)
|
---|
| 393 | return 0;
|
---|
| 394 |
|
---|
| 395 | iterator scope;
|
---|
| 396 | scope = myself;
|
---|
| 397 | ++ scope;
|
---|
| 398 | if(scope == parent->end())
|
---|
| 399 | return 0;
|
---|
| 400 |
|
---|
| 401 | return (*scope).second;
|
---|
| 402 | }
|
---|
| 403 |
|
---|
| 404 | Directory * Directory::getPrev(void) const
|
---|
| 405 | {
|
---|
| 406 | if(parent == 0 && myself == parent->begin())
|
---|
| 407 | return 0;
|
---|
| 408 |
|
---|
| 409 | reverse_iterator scope;
|
---|
| 410 |
|
---|
| 411 | scope = parent->rbegin();
|
---|
| 412 | while(scope != parent->rend() && (*scope).second != (*myself).second)
|
---|
| 413 | ++ scope;
|
---|
| 414 |
|
---|
| 415 | ++ scope;
|
---|
| 416 | return scope != parent->rend() ? (*scope).second : 0;
|
---|
| 417 | }
|
---|
| 418 |
|
---|
| 419 | bool Directory::changeKey(const string & key)
|
---|
| 420 | {
|
---|
| 421 | Directory * scope;
|
---|
| 422 |
|
---|
| 423 | if( key.size() == 0)
|
---|
| 424 | return false;
|
---|
| 425 |
|
---|
| 426 | scope = parent;
|
---|
| 427 |
|
---|
| 428 | disconnect();
|
---|
| 429 | scope->addChild(key, this);
|
---|
| 430 | return true;
|
---|
| 431 | }
|
---|
| 432 |
|
---|
| 433 |
|
---|
| 434 | void Directory::drawTree(ostream * out, int level, string * link)
|
---|
| 435 | {
|
---|
| 436 | iterator scope;
|
---|
| 437 | iterator scope2;
|
---|
| 438 |
|
---|
| 439 | if(level == 0)
|
---|
| 440 | link = new string;
|
---|
| 441 | else
|
---|
| 442 | *out << (*link).substr(0, (level-1)*3) << " +-";
|
---|
| 443 |
|
---|
| 444 | *out << '[' << getKey() << ']';
|
---|
| 445 | switch(type)
|
---|
| 446 | {
|
---|
| 447 | case POINTER:
|
---|
| 448 | out->setf(ios::hex);
|
---|
| 449 | *out << " : PTR [" << content.pointer << "]";
|
---|
| 450 | break;
|
---|
| 451 | case INTEGER:
|
---|
| 452 | out->setf(ios::dec);
|
---|
| 453 | *out << " : INT [" << content.value << "]";
|
---|
| 454 | break;
|
---|
| 455 | case LITERAL:
|
---|
| 456 | *out << " : STR [" << *content.literal << "]";
|
---|
| 457 | break;
|
---|
| 458 | case CONSTLITERAL:
|
---|
| 459 | *out << " : CSTR[" << content.const_literal << "]";
|
---|
| 460 | break;
|
---|
| 461 | case OBJECT:
|
---|
| 462 | {
|
---|
| 463 | *out << " : OBJ";
|
---|
| 464 | break;
|
---|
| 465 | }
|
---|
| 466 | case UNKNOWN:
|
---|
| 467 | break;
|
---|
| 468 | default:
|
---|
| 469 | *out << "UNKNOWN";
|
---|
| 470 | }
|
---|
| 471 | *out << '\n';
|
---|
| 472 | (*link) += " | ";
|
---|
| 473 | scope = begin();
|
---|
| 474 | while(scope != end())
|
---|
| 475 | {
|
---|
| 476 | scope2 = scope;
|
---|
| 477 | ++ scope;
|
---|
| 478 |
|
---|
| 479 | if(scope == end())
|
---|
| 480 | (*link)[level*3+1] = ' ';
|
---|
| 481 | (*scope2).second->drawTree(out, level+1, link);
|
---|
| 482 | }
|
---|
| 483 |
|
---|
| 484 |
|
---|
| 485 | link->erase(level*3);
|
---|
| 486 | if(level == 0)
|
---|
| 487 | delete link;
|
---|
| 488 | }
|
---|
| 489 |
|
---|
| 490 | static string escapeXMLLiterals(const string & src)
|
---|
| 491 | {
|
---|
| 492 | int index;
|
---|
| 493 | string::size_type pos;
|
---|
| 494 | string result;
|
---|
| 495 | const char literal[4] ="&<>";
|
---|
| 496 | const char * escape[3] = {"&","<",">"};
|
---|
| 497 |
|
---|
| 498 | result = src;
|
---|
| 499 | for(index = 0; index < 3; index++)
|
---|
| 500 | {
|
---|
| 501 | pos = 0;
|
---|
| 502 | while((pos = result.find_first_of(literal[index],pos)) != string::npos)
|
---|
| 503 | {
|
---|
| 504 | result.erase(pos,1);
|
---|
| 505 | result.insert(pos, escape[index]);
|
---|
| 506 | ++ pos;
|
---|
| 507 | }
|
---|
| 508 | }
|
---|
| 509 |
|
---|
| 510 | return result;
|
---|
| 511 | }
|
---|
| 512 |
|
---|
| 513 | static string encloseAttributes(const string & src)
|
---|
| 514 | {
|
---|
| 515 | if(src.find_first_of('"') != string::npos)
|
---|
| 516 | return string("'") + src + "'";
|
---|
| 517 | return string("\"") + src + "\"";
|
---|
| 518 | }
|
---|
| 519 |
|
---|
| 520 | void Directory::drawTree_byXML(ostream * out, int level)
|
---|
| 521 | {
|
---|
| 522 | iterator scope;
|
---|
| 523 |
|
---|
| 524 | if(level == 0)
|
---|
| 525 | *out << "<?xml version='1.0' encoding='Shift_JIS' ?>\n<?xml-stylesheet type='text/xsl' href='basic.xsl' ?>\n";
|
---|
| 526 |
|
---|
| 527 | *out << "<node key=" << encloseAttributes(escapeXMLLiterals(getKey())) << " type='";
|
---|
| 528 |
|
---|
| 529 | switch(type)
|
---|
| 530 | {
|
---|
| 531 | case POINTER:
|
---|
| 532 | out->setf(ios::hex);
|
---|
| 533 | *out << "PTR'><value>" << content.pointer << "</value>";
|
---|
| 534 | break;
|
---|
| 535 | case INTEGER:
|
---|
| 536 | out->setf(ios::dec);
|
---|
| 537 | *out << "INT'><value>" << content.value << "</value>";
|
---|
| 538 | break;
|
---|
| 539 | case LITERAL:
|
---|
| 540 | *out << "STR'><value>" << escapeXMLLiterals(*content.literal) << "</value>";
|
---|
| 541 | break;
|
---|
| 542 | case CONSTLITERAL:
|
---|
| 543 | *out << "CSTR'><value>" << escapeXMLLiterals(content.const_literal) << "</value>";
|
---|
| 544 | break;
|
---|
| 545 | case OBJECT:
|
---|
| 546 | *out << "OBJ'>";
|
---|
| 547 | break;
|
---|
| 548 | case UNKNOWN:
|
---|
| 549 | *out << "'>";
|
---|
| 550 | break;
|
---|
| 551 | default:
|
---|
| 552 | *out << "UNKNOWN'>";
|
---|
| 553 | }
|
---|
| 554 | *out << '\n';
|
---|
| 555 |
|
---|
| 556 | scope = begin();
|
---|
| 557 | if(scope != end())
|
---|
| 558 | {
|
---|
| 559 | *out << "<child>\n";
|
---|
| 560 | do{
|
---|
| 561 | scope->second->drawTree_byXML(out, level+1);
|
---|
| 562 | ++ scope;
|
---|
| 563 | }while(scope != end());
|
---|
| 564 | *out << "</child>\n";
|
---|
| 565 | }
|
---|
| 566 | *out << "</node>\n";
|
---|
| 567 | }
|
---|
| 568 |
|
---|
| 569 | Directory * Directory::findChild(const char * key)
|
---|
| 570 | {
|
---|
| 571 | string work(key);
|
---|
| 572 | if(work.find_first_of('/') != string::npos)
|
---|
| 573 | return findChild(work);
|
---|
| 574 | return findNode(false, key, 0);
|
---|
| 575 | }
|
---|
| 576 |
|
---|
| 577 | Directory * Directory::findChild(const char * key, const char * second, ... )
|
---|
| 578 | {
|
---|
| 579 | va_list vl;
|
---|
| 580 | va_start(vl, second);
|
---|
| 581 | return findNode(false, key, 0)->findNode(false,second, vl);
|
---|
| 582 | }
|
---|
| 583 |
|
---|
| 584 | Directory * Directory::openChild(const char * key)
|
---|
| 585 | {
|
---|
| 586 | string work(key);
|
---|
| 587 | if(work.find_first_of('/') != string::npos)
|
---|
| 588 | return openChild(work);
|
---|
| 589 | return findNode(true, key, 0);
|
---|
| 590 | }
|
---|
| 591 |
|
---|
| 592 |
|
---|
| 593 | Directory * Directory::openChild(const char * key, const char * second, ... )
|
---|
| 594 | {
|
---|
| 595 | va_list vl;
|
---|
| 596 | va_start(vl, second);
|
---|
| 597 | return findNode(true, key, 0)->findNode(true, second, vl);
|
---|
| 598 | }
|
---|
| 599 |
|
---|
| 600 | //æå®ãããã¼ãæã¤åå«ãæ¢ãããµã¼ãé ã¯ä¸é
|
---|
| 601 | Directory * Directory::findDescandant(const string & key, unsigned int level) const
|
---|
| 602 | {
|
---|
| 603 | Directory::const_iterator scope;
|
---|
| 604 | const Directory * node = this;
|
---|
| 605 |
|
---|
| 606 | if(empty())
|
---|
| 607 | return 0;
|
---|
| 608 |
|
---|
| 609 | //åã§æ¢ã
|
---|
| 610 | scope = begin();
|
---|
| 611 | while( scope != end() )
|
---|
| 612 | {
|
---|
| 613 | if((*scope).first.compare(key) == 0)
|
---|
| 614 | return const_cast<Directory *>((*scope).second);
|
---|
| 615 | ++ scope;
|
---|
| 616 | }
|
---|
| 617 |
|
---|
| 618 | if(level > 0)
|
---|
| 619 | {
|
---|
| 620 | scope = begin();
|
---|
| 621 | while( scope != end() )
|
---|
| 622 | {
|
---|
| 623 | if((node = (*scope).second->findDescandant(key, level-1)) != 0)
|
---|
| 624 | return const_cast<Directory *>(node);
|
---|
| 625 | ++ scope;
|
---|
| 626 | }
|
---|
| 627 | }
|
---|
| 628 | return 0;
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | void Directory::copyTo(Directory * dest, int nest)
|
---|
| 632 | {
|
---|
| 633 | Directory::iterator scope;
|
---|
| 634 | Directory * node;
|
---|
| 635 |
|
---|
| 636 | if(this == NULL)
|
---|
| 637 | return;
|
---|
| 638 |
|
---|
| 639 | assert(dest != NULL);
|
---|
| 640 |
|
---|
| 641 | node = dest;
|
---|
| 642 | while(node != 0)
|
---|
| 643 | {
|
---|
| 644 | if(node == this)
|
---|
| 645 | ExceptionMessage("CopyTo: dest must not be a descendant node.","CopyTo: åå«ãã¼ãã¸ã®ã³ãã¼ã¯ã§ãã¾ãã") << throwException;
|
---|
| 646 | node = node->getParent();
|
---|
| 647 | }
|
---|
| 648 |
|
---|
| 649 | scope = begin();
|
---|
| 650 | while(scope != end())
|
---|
| 651 | {
|
---|
| 652 | node = dest->findChild((*scope).first);
|
---|
| 653 | if(node != 0)
|
---|
| 654 | node->erase();
|
---|
| 655 |
|
---|
| 656 | node = dest->addChild((*scope).first, new Directory(*(*scope).second));
|
---|
| 657 | if(nest > 0)
|
---|
| 658 | (*scope).second->copyTo(node, nest-1);
|
---|
| 659 |
|
---|
| 660 | ++ scope;
|
---|
| 661 | }
|
---|
| 662 | }
|
---|
| 663 |
|
---|
| 664 | void Directory::Store(ostream * out)
|
---|
| 665 | {
|
---|
| 666 | int i;
|
---|
| 667 | Directory * node;
|
---|
| 668 |
|
---|
| 669 | out->write((const char *)&type, sizeof(type));
|
---|
| 670 | switch(type)
|
---|
| 671 | {
|
---|
| 672 | case INTEGER:
|
---|
| 673 | out->write((const char *)&content.value, sizeof(content.value));
|
---|
| 674 | break;
|
---|
| 675 | case LITERAL:
|
---|
| 676 | i = content.literal->size();
|
---|
| 677 | out->write((const char *)&i, sizeof(int));
|
---|
| 678 | out->write(content.literal->c_str(), i);
|
---|
| 679 | break;
|
---|
| 680 | case CONSTLITERAL:
|
---|
| 681 | i = strlen(content.const_literal);
|
---|
| 682 | out->write((const char *)&i, sizeof(int));
|
---|
| 683 | out->write(content.const_literal, i);
|
---|
| 684 | break;
|
---|
| 685 | default:
|
---|
| 686 | out->write((const char *)&content.pointer, sizeof(content.pointer));
|
---|
| 687 | }
|
---|
| 688 | i = size();
|
---|
| 689 | out->write((const char *)&i, sizeof(int));
|
---|
| 690 | for(node = getFirstChild(); node != 0; node = node->getNext())
|
---|
| 691 | {
|
---|
| 692 | const string & work = node->getKey();
|
---|
| 693 | i = work.size();
|
---|
| 694 | out->write((const char *)&i, sizeof(int));
|
---|
| 695 | out->write(work.c_str(), i);
|
---|
| 696 | node->Store(out);
|
---|
| 697 | }
|
---|
| 698 | }
|
---|
| 699 |
|
---|
| 700 | void Directory::Load(istream * in)
|
---|
| 701 | {
|
---|
| 702 | int i;
|
---|
| 703 | int count;
|
---|
| 704 | char buffer[1024];
|
---|
| 705 |
|
---|
| 706 | in->read((char *)&type, sizeof(type));
|
---|
| 707 | switch(type)
|
---|
| 708 | {
|
---|
| 709 | case INTEGER:
|
---|
| 710 | in->read((char *)&content.value, sizeof(content.value));
|
---|
| 711 | break;
|
---|
| 712 | case CONSTLITERAL:
|
---|
| 713 | case LITERAL:
|
---|
| 714 | in->read((char *)&i, sizeof(int));
|
---|
| 715 | in->read(buffer, i);
|
---|
| 716 | buffer[i] = '\x0';
|
---|
| 717 | *this = string(buffer);
|
---|
| 718 | break;
|
---|
| 719 | default:
|
---|
| 720 | in->read((char *)&content.pointer, sizeof(content.pointer));
|
---|
| 721 | }
|
---|
| 722 | in->read((char *)&count, sizeof(int));
|
---|
| 723 | while(count-- > 0)
|
---|
| 724 | {
|
---|
| 725 | in->read((char *)&i, sizeof(int));
|
---|
| 726 | in->read(buffer, i);
|
---|
| 727 | buffer[i] = '\x0';
|
---|
| 728 |
|
---|
| 729 | addChild(buffer)->Load(in);
|
---|
| 730 | }
|
---|
| 731 | }
|
---|
| 732 |
|
---|
| 733 | string Directory::toString(const string & default_value) const
|
---|
| 734 | {
|
---|
| 735 | if(this == 0)
|
---|
| 736 | return default_value;
|
---|
| 737 |
|
---|
| 738 | switch(type)
|
---|
| 739 | {
|
---|
| 740 | case POINTER:
|
---|
| 741 | case OBJECT:
|
---|
| 742 | {
|
---|
| 743 | char buffer[256];
|
---|
| 744 | sprintf(buffer,"%08lx", (long)content.pointer);
|
---|
| 745 | return string(buffer);
|
---|
| 746 | }
|
---|
| 747 | case INTEGER:
|
---|
| 748 | {
|
---|
| 749 | char buffer[256];
|
---|
| 750 | sprintf(buffer,"%ld", content.value);
|
---|
| 751 | return string(buffer);
|
---|
| 752 | }
|
---|
| 753 | case CONSTLITERAL:
|
---|
| 754 | return string(content.const_literal);
|
---|
| 755 | case LITERAL:
|
---|
| 756 | return string(*content.literal);
|
---|
| 757 | default:
|
---|
| 758 | return default_value;
|
---|
| 759 | }
|
---|
| 760 |
|
---|
| 761 | return default_value;
|
---|
| 762 | }
|
---|
| 763 |
|
---|
| 764 | void * Directory::toPointer(const void * default_value) const
|
---|
| 765 | {
|
---|
| 766 | if(this == 0)
|
---|
| 767 | return (void *)default_value;
|
---|
| 768 |
|
---|
| 769 | switch(type)
|
---|
| 770 | {
|
---|
| 771 | case INTEGER:
|
---|
| 772 | return (void *)&content.value;
|
---|
| 773 | case CONSTLITERAL:
|
---|
| 774 | return (void *)content.const_literal;
|
---|
| 775 | case LITERAL:
|
---|
| 776 | return (void *)content.literal->c_str();
|
---|
| 777 | case POINTER:
|
---|
| 778 | return (void *)content.pointer;
|
---|
| 779 | case OBJECT:
|
---|
| 780 | return (void *)content.instance;
|
---|
| 781 | default:
|
---|
| 782 | return (void *)default_value;
|
---|
| 783 | }
|
---|
| 784 |
|
---|
| 785 | return (void *)default_value;
|
---|
| 786 | }
|
---|
| 787 |
|
---|
| 788 | long Directory::toInteger(const long default_value) const
|
---|
| 789 | {
|
---|
| 790 | bool minus = false;
|
---|
| 791 | long work;
|
---|
| 792 | const char * str;
|
---|
| 793 |
|
---|
| 794 | if(this == 0)
|
---|
| 795 | return default_value;
|
---|
| 796 |
|
---|
| 797 | switch(type)
|
---|
| 798 | {
|
---|
| 799 | case INTEGER:
|
---|
| 800 | return content.value;
|
---|
| 801 |
|
---|
| 802 | case POINTER:
|
---|
| 803 | return (long)content.pointer;
|
---|
| 804 |
|
---|
| 805 | case LITERAL:
|
---|
| 806 | case CONSTLITERAL:
|
---|
| 807 | if(type == CONSTLITERAL)
|
---|
| 808 | str = content.const_literal;
|
---|
| 809 | else
|
---|
| 810 | str = content.literal->c_str();
|
---|
| 811 |
|
---|
| 812 | if(*str == '-')
|
---|
| 813 | {
|
---|
| 814 | minus = true;
|
---|
| 815 | str ++;
|
---|
| 816 | }
|
---|
| 817 |
|
---|
| 818 | if(*str == '0')
|
---|
| 819 | {
|
---|
| 820 | str ++;
|
---|
| 821 | if(*str == 'x' || *str == 'X')
|
---|
| 822 | {
|
---|
| 823 | if(sscanf(str+1, "%ux", (int *)&work) == 0)
|
---|
| 824 | return default_value;
|
---|
| 825 | }else
|
---|
| 826 | if(*str != '\x0')
|
---|
| 827 | {
|
---|
| 828 | if(sscanf(str, "%o", (int *)&work) == 0)
|
---|
| 829 | return default_value;
|
---|
| 830 | }else
|
---|
| 831 | return 0;
|
---|
| 832 | }else
|
---|
| 833 | if(sscanf(str, "%d", (int *)&work) == 0)
|
---|
| 834 | return default_value;
|
---|
| 835 |
|
---|
| 836 | if(minus)
|
---|
| 837 | work = -work;
|
---|
| 838 | return work;
|
---|
| 839 | default:
|
---|
| 840 | return default_value;
|
---|
| 841 | }
|
---|
| 842 |
|
---|
| 843 | return default_value;
|
---|
| 844 | }
|
---|
| 845 |
|
---|
| 846 | static string::size_type find_corresponding_parenthesis(const string & target, string::size_type pos = 0, char left = '(', char right = ')')
|
---|
| 847 | {
|
---|
| 848 | int nest;
|
---|
| 849 |
|
---|
| 850 | nest = 1;
|
---|
| 851 | do {
|
---|
| 852 | if(target[pos] == left)
|
---|
| 853 | {
|
---|
| 854 | ++ nest;
|
---|
| 855 | }else
|
---|
| 856 | {
|
---|
| 857 | if(target[pos] == right)
|
---|
| 858 | {
|
---|
| 859 | -- nest;
|
---|
| 860 | if(nest == 0)
|
---|
| 861 | return static_cast<int>(pos);
|
---|
| 862 | }
|
---|
| 863 | }
|
---|
| 864 | ++ pos;
|
---|
| 865 | }while(pos < target.size());
|
---|
| 866 |
|
---|
| 867 | return string::npos;
|
---|
| 868 | }
|
---|
| 869 |
|
---|
| 870 |
|
---|
| 871 | string Directory::format(const string & fmt, int mode)
|
---|
| 872 | {
|
---|
| 873 | Directory * node;
|
---|
| 874 | string work;
|
---|
| 875 | string key;
|
---|
| 876 | string default_value;
|
---|
| 877 | string::size_type top,tail;
|
---|
| 878 | string::size_type pos;
|
---|
| 879 | int i;
|
---|
| 880 |
|
---|
| 881 | default_value.assign("(null)");
|
---|
| 882 | tail = 0;
|
---|
| 883 | while((top = fmt.find_first_of('$', tail)) != string::npos)
|
---|
| 884 | {
|
---|
| 885 | if(top != tail)
|
---|
| 886 | work += fmt.substr(tail, top - tail);
|
---|
| 887 |
|
---|
| 888 | switch(fmt[top+1])
|
---|
| 889 | {
|
---|
| 890 | case '$':
|
---|
| 891 | tail = top+2;
|
---|
| 892 | work += '$';
|
---|
| 893 | break;
|
---|
| 894 |
|
---|
| 895 | case '@':
|
---|
| 896 | work += (*myself).first;
|
---|
| 897 | tail = top + 2;
|
---|
| 898 | break;
|
---|
| 899 |
|
---|
| 900 | case '(':
|
---|
| 901 | top += 2;
|
---|
| 902 | i = find_corresponding_parenthesis(fmt, top);
|
---|
| 903 | key = fmt.substr(top, i - top);
|
---|
| 904 |
|
---|
| 905 | if(key.find_first_of('$') != string::npos)
|
---|
| 906 | key = format(key,mode);
|
---|
| 907 |
|
---|
| 908 | pos = key.find_first_of(',');
|
---|
| 909 | if(pos != string::npos)
|
---|
| 910 | {
|
---|
| 911 | default_value = key.substr(pos+1);
|
---|
| 912 | key.erase(pos);
|
---|
| 913 | }
|
---|
| 914 |
|
---|
| 915 | node = findNode(false,key);
|
---|
| 916 | if((mode & PTRPREFIX) != 0 && (node != NULL && node->type == POINTER))
|
---|
| 917 | work += "0x";
|
---|
| 918 | work += node->toString(default_value);
|
---|
| 919 |
|
---|
| 920 | tail = i+1;
|
---|
| 921 | break;
|
---|
| 922 | }
|
---|
| 923 | }
|
---|
| 924 |
|
---|
| 925 | work += fmt.substr(tail);
|
---|
| 926 |
|
---|
| 927 | return work;
|
---|
| 928 | }
|
---|
| 929 |
|
---|
| 930 | map<std::string, Directory *>::size_type Directory::size(map<string, Directory *>::size_type defval) const
|
---|
| 931 | {
|
---|
| 932 | size_type i;
|
---|
| 933 | const_iterator scope;
|
---|
| 934 |
|
---|
| 935 | if(this == NULL)
|
---|
| 936 | return defval;
|
---|
| 937 |
|
---|
| 938 | i = 0;
|
---|
| 939 | scope = begin();
|
---|
| 940 | while(scope != end())
|
---|
| 941 | ++ i, ++ scope;
|
---|
| 942 |
|
---|
| 943 | return i;
|
---|
| 944 | }
|
---|
| 945 |
|
---|