Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1298 lines
23 KiB

  1. /*
  2. * This module contains the definitions for the inline functions used by the
  3. * name undecorator. It is intended that this file should be included
  4. * somewhere in the source file for the undecorator to maximise the chance
  5. * that they will be truly inlined.
  6. */
  7. // The following class is a special node class, used in the implementation
  8. // of the internal chaining mechanism of the 'DName's
  9. class charNode;
  10. class pcharNode;
  11. class pDNameNode;
  12. class DNameStatusNode;
  13. #if ( NO_VIRTUAL )
  14. enum NodeType
  15. {
  16. charNode_t,
  17. pcharNode_t,
  18. pDNameNode_t,
  19. DNameStatusNode_t
  20. };
  21. #endif // NO_VIRTUAL
  22. class DNameNode
  23. {
  24. private:
  25. #if NO_VIRTUAL
  26. NodeType typeIndex;
  27. #endif // NO_VIRTUAL
  28. DNameNode * next;
  29. protected:
  30. #if ( !NO_VIRTUAL )
  31. __near DNameNode ();
  32. #else // } elif NO_VIRTUAL {
  33. __near DNameNode ( NodeType );
  34. #endif // NO_VIRTUAL
  35. __near DNameNode ( const DNameNode & );
  36. public:
  37. virtual int __near length () const PURE;
  38. virtual pchar_t __near getString ( pchar_t, int ) const PURE;
  39. DNameNode * __near clone ();
  40. DNameNode * __near nextNode () const;
  41. DNameNode & __near operator += ( DNameNode * );
  42. };
  43. class charNode : public DNameNode
  44. {
  45. private:
  46. char me;
  47. public:
  48. __near charNode ( char );
  49. virtual int __near length () const;
  50. virtual pchar_t __near getString ( pchar_t, int ) const;
  51. };
  52. class pcharNode : public DNameNode
  53. {
  54. private:
  55. pchar_t me;
  56. int myLen;
  57. public:
  58. __near pcharNode ( pcchar_t, int = 0 );
  59. virtual int __near length () const;
  60. virtual pchar_t __near getString ( pchar_t, int ) const;
  61. };
  62. class pDNameNode : public DNameNode
  63. {
  64. private:
  65. DName * me;
  66. public:
  67. __near pDNameNode ( DName * );
  68. virtual int __near length () const;
  69. virtual pchar_t __near getString ( pchar_t, int ) const;
  70. };
  71. class DNameStatusNode : public DNameNode
  72. {
  73. private:
  74. #define TruncationMessage (" ?? ")
  75. #define TruncationMessageLength (4)
  76. DNameStatus me;
  77. int myLen;
  78. public:
  79. __near DNameStatusNode ( DNameStatus );
  80. virtual int __near length () const;
  81. virtual pchar_t __near getString ( pchar_t, int ) const;
  82. };
  83. // Memory allocation functions
  84. inline void __far * __near __pascal operator new ( size_t sz, HeapManager &, int noBuffer )
  85. { return heap.getMemory ( sz, noBuffer ); }
  86. void __far * __near HeapManager::getMemory ( size_t sz, int noBuffer )
  87. {
  88. FTRACE(HeapManager::getMemory);
  89. // Align the allocation on an appropriate boundary
  90. sz = (( sz + PACK_SIZE ) & ~PACK_SIZE );
  91. if ( noBuffer )
  92. {
  93. #if STDEBUG
  94. actual += sz;
  95. #endif // STDEBUG
  96. #if ( !USE_CRT_HEAP )
  97. return ( *pOpNew )( sz );
  98. #else // } elif USE_CRT_HEAP {
  99. return malloc ( sz );
  100. #endif // USE_CRT_HEAP
  101. } // End of IF then
  102. else
  103. {
  104. // Handler a potential request for no space
  105. if ( !sz )
  106. sz = 1;
  107. #if STDEBUG
  108. requested += sz;
  109. #endif // STDEBUG
  110. if ( blockLeft < sz )
  111. {
  112. // Is the request greater than the largest buffer size ?
  113. if ( sz > memBlockSize )
  114. return 0; // If it is, there is nothing we can do
  115. // Allocate a new block
  116. Block * pNewBlock = rnew Block;
  117. // Did the allocation succeed ? If so connect it up
  118. if ( pNewBlock )
  119. {
  120. // Handle the initial state
  121. if ( tail )
  122. tail = tail->next = pNewBlock;
  123. else
  124. head = tail = pNewBlock;
  125. // Compute the remaining space
  126. blockLeft = memBlockSize - sz;
  127. } // End of IF then
  128. else
  129. return 0; // Oh-oh! Memory allocation failure
  130. } // End of IF then
  131. else
  132. blockLeft -= sz; // Deduct the allocated amount
  133. // And return the buffer address
  134. return &( tail->memBlock[ blockLeft ]);
  135. } // End of IF else
  136. } // End of "HeapManager" FUNCTION "getMemory(unsigned int,int)"
  137. // Friend functions of 'DName'
  138. DName __near __pascal operator + ( char c, const DName & rd )
  139. { return DName ( c ) + rd; }
  140. DName __near __pascal operator + ( DNameStatus st, const DName & rd )
  141. { return DName ( st ) + rd; }
  142. DName __near __pascal operator + ( pcchar_t s, const DName & rd )
  143. { return DName ( s ) + rd; }
  144. // The 'DName' constructors
  145. inline_p3 __near DName::DName () { node = 0; stat = DN_valid; isIndir = 0; isAUDC = 0; }
  146. inline __near DName::DName ( DNameNode * pd ) { node = pd; stat = DN_valid; isIndir = 0; isAUDC = 0; }
  147. __near DName::DName ( char c )
  148. {
  149. FTRACE(DName::DName(char));
  150. stat = DN_valid;
  151. isIndir = 0;
  152. isAUDC = 0;
  153. node = 0;
  154. // The NULL character is boring, do not copy
  155. if ( c )
  156. doPchar ( &c, 1 );
  157. } // End of "DName" CONSTRUCTOR '(char)'
  158. #if 1
  159. __near DName::DName ( const DName & rd )
  160. {
  161. #if STDEBUG
  162. FTRACE(DName::DName(const DName&));
  163. shallowCopies++;
  164. #endif // STDEBUG
  165. stat = rd.stat;
  166. isIndir = rd.isIndir;
  167. isAUDC = rd.isAUDC;
  168. node = rd.node;
  169. } // End of "DName" CONSTRUCTOR '(const DName&)'
  170. #endif
  171. #if ( !VERS_P3 )
  172. __near DName::DName ( DName * pd )
  173. {
  174. FTRACE(DName::DName(DName*));
  175. if ( pd )
  176. {
  177. node = gnew pDNameNode ( pd );
  178. stat = ( node ? DN_valid : ERROR );
  179. } // End of IF else
  180. else
  181. {
  182. stat = DN_valid;
  183. node = 0;
  184. } // End of IF else
  185. isIndir = 0;
  186. isAUDC = 0;
  187. } // End of "DName" CONSTRUCTOR '( DName* )'
  188. #endif // !VERS_P3
  189. __near DName::DName ( pcchar_t s )
  190. {
  191. FTRACE(DName::DName(pcchar_t));
  192. stat = DN_valid;
  193. node = 0;
  194. isIndir = 0;
  195. isAUDC = 0;
  196. if ( s )
  197. doPchar ( s, strlen ( s ));
  198. } // End of "DName" CONSTRUCTOR '(pcchar_t)'
  199. __near DName::DName ( pcchar_t & name, char terminator )
  200. {
  201. FTRACE(DName::DName(pcchar_t&,char));
  202. stat = DN_valid;
  203. isIndir = 0;
  204. isAUDC = 0;
  205. node = 0;
  206. // Is there a string ?
  207. if ( name )
  208. if ( *name )
  209. {
  210. int len = 0;
  211. // How long is the string ?
  212. for ( pcchar_t s = name; *name && ( *name != terminator ); name++ )
  213. if ( isValidIdentChar ( *name ))
  214. len++;
  215. else
  216. {
  217. stat = DN_invalid;
  218. return;
  219. } // End of IF else
  220. // Copy the name string fragment
  221. doPchar ( s, len );
  222. // Now gobble the terminator if present, handle error conditions
  223. if ( *name )
  224. {
  225. if ( *name++ != terminator )
  226. {
  227. stat = ERROR;
  228. node = 0;
  229. } // End of IF then
  230. else
  231. stat = DN_valid;
  232. } // End of IF then
  233. elif ( status () == DN_valid )
  234. stat = DN_truncated;
  235. } // End of IF then
  236. else
  237. stat = DN_truncated;
  238. else
  239. stat = DN_invalid;
  240. } // End of "DName" CONSTRUCTOR '(pcchar_t&,char)'
  241. #if ( !VERS_P3 )
  242. __near DName::DName ( unsigned long num )
  243. {
  244. FTRACE(DName::DName(unsigned long));
  245. char buf[ 11 ];
  246. char * pBuf = buf + 10;
  247. stat = DN_valid;
  248. node = 0;
  249. isIndir = 0;
  250. isAUDC = 0;
  251. // Essentially, 'ultoa ( num, buf, 10 )' :-
  252. *pBuf = 0;
  253. do
  254. {
  255. *( --pBuf ) = (char)(( num % 10 ) + '0' );
  256. num /= 10UL;
  257. } while ( num );
  258. doPchar ( pBuf, ( 10 - (int)( pBuf - buf )));
  259. } // End of "DName" CONSTRUCTOR '(unsigned long)'
  260. #endif // !VERS_P3
  261. __near DName::DName ( DNameStatus st )
  262. {
  263. FTRACE(DName::DName(DNameStatus));
  264. stat = ((( st == DN_invalid ) || ( st == DN_error )) ? st : DN_valid );
  265. node = gnew DNameStatusNode ( st );
  266. isIndir = 0;
  267. isAUDC = 0;
  268. if ( !node )
  269. stat = ERROR;
  270. } // End of "DName" CONSTRUCTOR '(DNameStatus)'
  271. // Now the member functions for 'DName'
  272. int __near DName::isValid () const { return (( status () == DN_valid ) || ( status () == DN_truncated )); }
  273. int __near DName::isEmpty () const { return (( node == 0 ) || !isValid ()); }
  274. inline DNameStatus __near DName::status () const { return (DNameStatus)stat; } // The cast is to keep Glockenspiel quiet
  275. #if ( !VERS_P3 )
  276. inline DName & __near DName::setPtrRef () { isIndir = 1; return *this; }
  277. inline int __near DName::isPtrRef () const { return isIndir; }
  278. inline int __near DName::isUDC () const { return ( !isEmpty () && isAUDC ); }
  279. inline void __near DName::setIsUDC () { if ( !isEmpty ()) isAUDC = TRUE; }
  280. #endif // !VERS_P3
  281. int __near DName::length () const
  282. {
  283. FTRACE(DName::length);
  284. int len = 0;
  285. if ( !isEmpty ())
  286. for ( DNameNode * pNode = node; pNode; pNode = pNode->nextNode ())
  287. len += pNode->length ();
  288. return len;
  289. } // End of "DName" FUNCTION "length"
  290. pchar_t __near DName::getString ( pchar_t buf, int max ) const
  291. {
  292. FTRACE(DName::getString);
  293. if ( !isEmpty ())
  294. {
  295. // Does the caller want a buffer allocated ?
  296. if ( !buf )
  297. {
  298. max = length () + 1;
  299. buf = gnew char[ max ]; // Get a buffer big enough
  300. } // End of IF then
  301. // If memory allocation failure, then return no buffer
  302. if ( buf )
  303. {
  304. // Now, go through the process of filling the buffer (until max is reached)
  305. int curLen = max;
  306. DNameNode * curNode = node;
  307. pchar_t curBuf = buf;
  308. while ( curNode && ( curLen > 0 ))
  309. {
  310. int fragLen = curNode->length ();
  311. pchar_t fragBuf = 0;
  312. // Skip empty nodes
  313. if ( fragLen )
  314. {
  315. // Handle buffer overflow
  316. if (( curLen - fragLen ) < 0 )
  317. fragLen = curLen;
  318. // Now copy 'len' number of bytes of the piece to the buffer
  319. fragBuf = curNode->getString ( curBuf, fragLen );
  320. // Should never happen, but handle it anyway
  321. if ( fragBuf )
  322. {
  323. // Update string position
  324. curLen -= fragLen;
  325. curBuf += fragLen;
  326. } // End of IF
  327. } // End of IF
  328. // Move on to the next name fragment
  329. curNode = curNode->nextNode ();
  330. } // End of WHILE
  331. *curBuf = 0; // Always NULL terminate the resulting string
  332. } // End of IF
  333. } // End of IF then
  334. elif ( buf )
  335. *buf = 0;
  336. // Return the buffer
  337. return buf;
  338. } // End of "DName" FUNCTION "getString(pchar_t,int)"
  339. #if ( !VERS_P3 )
  340. DName __near DName::operator + ( char ch ) const
  341. {
  342. FTRACE(DName::+(char));
  343. DName local ( *this );
  344. if ( local.isEmpty ())
  345. local = ch;
  346. else
  347. local += ch;
  348. // And return the newly formed 'DName'
  349. return local;
  350. } // End of "DName" OPERATOR "+(char)"
  351. #endif // !VERS_P3
  352. DName __near DName::operator + ( pcchar_t str ) const
  353. {
  354. FTRACE(DName::+(pcchar_t));
  355. DName local ( *this );
  356. if ( local.isEmpty ())
  357. local = str;
  358. else
  359. local += str;
  360. // And return the newly formed 'DName'
  361. return local;
  362. } // End of "DName" OPERATOR "+(pcchar_t)"
  363. DName __near DName::operator + ( const DName & rd ) const
  364. {
  365. FTRACE(DName::+(const DName&));
  366. DName local ( *this );
  367. if ( local.isEmpty ())
  368. local = rd;
  369. elif ( rd.isEmpty ())
  370. local += rd.status ();
  371. else
  372. local += rd;
  373. // And return the newly formed 'DName'
  374. return local;
  375. } // End of "DName" OPERATOR "+(const DName&)"
  376. #if ( !VERS_P3 )
  377. DName __near DName::operator + ( DName * pd ) const
  378. {
  379. FTRACE(DName::+(DName*));
  380. DName local ( *this );
  381. if ( local.isEmpty ())
  382. local = pd;
  383. else
  384. local += pd;
  385. // And return the newly formed 'DName'
  386. return local;
  387. } // End of "DName" OPERATOR "+(DName*)"
  388. DName __near DName::operator + ( DNameStatus st ) const
  389. {
  390. FTRACE(DName::+(DNameStatus));
  391. DName local ( *this );
  392. if ( local.isEmpty ())
  393. local = st;
  394. else
  395. local += st;
  396. // And return the newly formed 'DName'
  397. return local;
  398. } // End of "DName" OPERATOR "+(DNameStatus)"
  399. DName & __near DName::operator += ( char ch )
  400. {
  401. FTRACE(DName::+=(char));
  402. if ( ch )
  403. if ( isEmpty ())
  404. *this = ch;
  405. else
  406. {
  407. node = node->clone ();
  408. if ( node )
  409. *node += gnew charNode ( ch );
  410. else
  411. stat = ERROR;
  412. } // End of IF
  413. // And return self
  414. return *this;
  415. } // End of "DName" OPERATOR "+=(char)"
  416. DName & __near DName::operator += ( pcchar_t str )
  417. {
  418. FTRACE(DName::+=(pcchar_t));
  419. if ( str && *str )
  420. if ( isEmpty ())
  421. *this = str;
  422. else
  423. {
  424. node = node->clone ();
  425. if ( node )
  426. *node += gnew pcharNode ( str );
  427. else
  428. stat = ERROR;
  429. } // End of IF
  430. // And return self
  431. return *this;
  432. } // End of "DName" OPERATOR "+=(pcchar_t)"
  433. #endif // !VERS_P3
  434. DName & __near DName::operator += ( const DName & rd )
  435. {
  436. FTRACE(DName::+=(const DName&));
  437. if ( rd.isEmpty ())
  438. *this += rd.status ();
  439. else
  440. if ( isEmpty ())
  441. *this = rd;
  442. else
  443. {
  444. node = node->clone ();
  445. if ( node )
  446. *node += rd.node;
  447. else
  448. stat = ERROR;
  449. } // End of IF
  450. // And return self
  451. return *this;
  452. } // End of "DName" OPERATOR "+=(const DName&)"
  453. #if ( !VERS_P3 )
  454. DName & __near DName::operator += ( DName * pd )
  455. {
  456. FTRACE(DName::+=(DName*));
  457. if ( pd )
  458. if ( isEmpty ())
  459. *this = pd;
  460. elif (( pd->status () == DN_valid ) || ( pd->status () == DN_truncated ))
  461. {
  462. DNameNode * pNew = gnew pDNameNode ( pd );
  463. if ( pNew )
  464. {
  465. node = node->clone ();
  466. if ( node )
  467. *node += pNew;
  468. } // End of IF then
  469. else
  470. node = 0;
  471. if ( !node )
  472. stat = ERROR;
  473. } // End of IF then
  474. else
  475. *this += pd->status ();
  476. // And return self
  477. return *this;
  478. } // End of "DName" OPERATOR "+=(DName*)"
  479. DName & __near DName::operator += ( DNameStatus st )
  480. {
  481. FTRACE(DName::+=(DNameStatus));
  482. if ( isEmpty () || (( st == DN_invalid ) || ( st == DN_error )))
  483. *this = st;
  484. else
  485. {
  486. DNameNode * pNew = gnew DNameStatusNode ( st );
  487. if ( pNew )
  488. {
  489. node = node->clone ();
  490. if ( node )
  491. *node += pNew;
  492. } // End of IF then
  493. else
  494. node = 0;
  495. if ( !node )
  496. stat = ERROR;
  497. } // End of IF else
  498. // Return self
  499. return *this;
  500. } // End of "DName" OPERATOR "+=(DNameStatus)"
  501. DName & __near DName::operator |= ( const DName & rd )
  502. {
  503. FTRACE(DName::=(const DName&));
  504. // Attenuate the error status. Always becomes worse. Don't propogate truncation
  505. if (( status () != DN_error ) && !rd.isValid ())
  506. stat = rd.status ();
  507. // And return self
  508. return *this;
  509. } // End of "DName" OPERATOR '|=(const DName&)'
  510. DName & __near DName::operator = ( char ch )
  511. {
  512. FTRACE(DName::=(char));
  513. isIndir = 0;
  514. isAUDC = 0;
  515. doPchar ( &ch, 1 );
  516. return *this;
  517. } // End of "DName" OPERATOR '=(char)'
  518. #endif // !VERS_P3
  519. DName & __near DName::operator = ( pcchar_t str )
  520. {
  521. FTRACE(DName::=(pcchar_t));
  522. isIndir = 0;
  523. isAUDC = 0;
  524. doPchar ( str, strlen ( str ));
  525. // And return self
  526. return *this;
  527. } // End of "DName" OPERATOR '=(pcchar_t)'
  528. DName & __near DName::operator = ( const DName & rd )
  529. {
  530. FTRACE(DName::=(const DName&));
  531. if (( status () == DN_valid ) || ( status () == DN_truncated ))
  532. {
  533. #if STDEBUG
  534. shallowAssigns++;
  535. #endif // STDEBUG
  536. stat = rd.stat;
  537. isIndir = rd.isIndir;
  538. isAUDC = rd.isAUDC;
  539. node = rd.node;
  540. } // End of IF
  541. // And return self
  542. return *this;
  543. } // End of "DName" OPERATOR '=(const DName&)'
  544. #if ( !VERS_P3 )
  545. DName & __near DName::operator = ( DName * pd )
  546. {
  547. FTRACE(DName::=(DName*));
  548. if (( status () == DN_valid ) || ( status () == DN_truncated ))
  549. if ( pd )
  550. {
  551. isIndir = 0;
  552. isAUDC = 0;
  553. node = gnew pDNameNode ( pd );
  554. if ( !node )
  555. stat = ERROR;
  556. } // End of IF then
  557. else
  558. *this = ERROR;
  559. // And return self
  560. return *this;
  561. } // End of "DName" OPERATOR '=(DName*)'
  562. DName & __near DName::operator = ( DNameStatus st )
  563. {
  564. FTRACE(DName::=(DNameStatus));
  565. if (( st == DN_invalid ) || ( st == DN_error ))
  566. {
  567. node = 0;
  568. if ( status () != DN_error )
  569. stat = st;
  570. } // End of IF then
  571. elif (( status () == DN_valid ) || ( status () == DN_truncated ))
  572. {
  573. isIndir = 0;
  574. isAUDC = 0;
  575. node = gnew DNameStatusNode ( st );
  576. if ( !node )
  577. stat = ERROR;
  578. } // End of ELIF then
  579. // And return self
  580. return *this;
  581. } // End of "DName" OPERATOR '=(DNameStatus)'
  582. #endif // !VERS_P3
  583. // Private implementation functions for 'DName'
  584. void __near DName::doPchar ( pcchar_t str, int len )
  585. {
  586. FTRACE(DName::doPchar);
  587. if ( !(( status () == DN_invalid ) || ( status () == DN_error )))
  588. if ( node )
  589. *this = ERROR;
  590. elif ( str && len )
  591. {
  592. // Allocate as economically as possible
  593. switch ( len )
  594. {
  595. case 0:
  596. stat = ERROR;
  597. break;
  598. case 1:
  599. node = gnew charNode ( *str );
  600. if ( !node )
  601. stat = ERROR;
  602. break;
  603. default:
  604. node = gnew pcharNode ( str, len );
  605. if ( !node )
  606. stat = ERROR;
  607. break;
  608. } // End of SWITCH
  609. } // End of ELIF
  610. else
  611. stat = DN_invalid;
  612. } // End of "DName" FUNCTION "doPchar(pcchar_t,int)"
  613. // The member functions for the 'Replicator'
  614. inline int __near Replicator::isFull () const { return ( index == 9 ); }
  615. inline __near Replicator::Replicator ()
  616. : ErrorDName ( DN_error ), InvalidDName ( DN_invalid )
  617. { index = -1; }
  618. Replicator & __near Replicator::operator += ( const DName & rd )
  619. {
  620. FTRACE(Replicator::+=);
  621. if ( !isFull () && !rd.isEmpty ())
  622. {
  623. DName * pNew = gnew DName ( rd );
  624. // Don't update if failed
  625. if ( pNew )
  626. dNameBuffer[ ++index ] = pNew;
  627. } // End of IF
  628. return *this;
  629. } // End of "Replicator" OPERATOR '+=(const DName&)'
  630. const DName & __near Replicator::operator [] ( int x ) const
  631. {
  632. FTRACE(Replicator::[]);
  633. if (( x < 0 ) || ( x > 9 ))
  634. return ErrorDName;
  635. elif (( index == -1 ) || ( x > index ))
  636. {
  637. (void)ERROR;
  638. return InvalidDName;
  639. } // End of ELIF then
  640. else
  641. return *dNameBuffer[ x ];
  642. } // End of "Replicator" OPERATOR '[](int)'
  643. // The member functions for the 'DNameNode' classes
  644. #if ( !NO_VIRTUAL )
  645. __near DNameNode::DNameNode ()
  646. #else // } elif NO_VIRTUAL {
  647. __near DNameNode::DNameNode ( NodeType ndTy )
  648. : typeIndex ( ndTy )
  649. #endif // NO_VIRTUAL
  650. { next = 0; }
  651. inline __near DNameNode::DNameNode ( const DNameNode & rd ) { next = (( rd.next ) ? rd.next->clone () : 0 ); }
  652. inline DNameNode * __near DNameNode::nextNode () const { return next; }
  653. DNameNode * __near DNameNode::clone ()
  654. {
  655. #if STDEBUG
  656. FTRACE(DNameNode::clone);
  657. clones++;
  658. #endif // STDEBUG
  659. return gnew pDNameNode ( gnew DName ( this ));
  660. }
  661. #if ( STDEBUG || NO_VIRTUAL )
  662. int __near DNameNode::length () const
  663. { // Pure function, should not be called
  664. FTRACE(DNameNode::length);
  665. #if ( NO_VIRTUAL )
  666. switch ( typeIndex )
  667. {
  668. case charNode_t:
  669. return ((charNode*)this )->length ();
  670. case pcharNode_t:
  671. return ((pcharNode*)this )->length ();
  672. case pDNameNode_t:
  673. return ((pDNameNode*)this )->length ();
  674. case DNameStatusNode_t:
  675. return ((DNameStatusNode*)this )->length ();
  676. } // End of SWITCH
  677. #endif // NO_VIRTUAL
  678. return 0;
  679. }
  680. pchar_t __near DNameNode::getString ( pchar_t s, int l ) const
  681. { // Pure function, should not be called
  682. FTRACE(DNameNode::getString);
  683. #if ( NO_VIRTUAL )
  684. switch ( typeIndex )
  685. {
  686. case charNode_t:
  687. return ((charNode*)this )->getString ( s, l );
  688. case pcharNode_t:
  689. return ((pcharNode*)this )->getString ( s, l );
  690. case pDNameNode_t:
  691. return ((pDNameNode*)this )->getString ( s, l );
  692. case DNameStatusNode_t:
  693. return ((DNameStatusNode*)this )->getString ( s, l );
  694. } // End of SWITCH
  695. #endif // NO_VIRTUAL
  696. return 0;
  697. }
  698. #endif // STDEBUG || NO_VIRTUAL
  699. DNameNode & __near DNameNode::operator += ( DNameNode * pNode )
  700. {
  701. FTRACE(DNameNode::+=(DNameNode*));
  702. if ( pNode )
  703. {
  704. if ( next )
  705. {
  706. // Skip to the end of the chain
  707. for ( DNameNode* pScan = next; pScan->next; pScan = pScan->next )
  708. ;
  709. // And append the new node
  710. pScan->next = pNode;
  711. } // End of IF then
  712. else
  713. next = pNode;
  714. } // End of IF
  715. // And return self
  716. return *this;
  717. } // End of "DNameNode" OPERATOR '+=(DNameNode*)'
  718. // The 'charNode' virtual functions
  719. inline_p3 __near charNode::charNode ( char ch )
  720. #if ( NO_VIRTUAL )
  721. : DNameNode ( charNode_t )
  722. #endif // NO_VIRTUAL
  723. { me = ch; }
  724. inline int __near charNode::length () const { return 1; }
  725. inline_pwb
  726. inline_lnk
  727. pchar_t __near charNode::getString ( pchar_t buf, int len ) const
  728. {
  729. FTRACE(charNode::getString);
  730. if ( buf && len )
  731. *buf = me;
  732. else
  733. buf = 0;
  734. // Now return the character
  735. return buf;
  736. } // End of "charNode" FUNCTION "getString(pchar_t,int)"
  737. // The 'pcharNode' virtual functions
  738. inline int __near pcharNode::length () const { return myLen; }
  739. __near pcharNode::pcharNode ( pcchar_t str, int len )
  740. #if ( NO_VIRTUAL )
  741. : DNameNode ( pcharNode_t )
  742. #endif // NO_VIRTUAL
  743. {
  744. FTRACE(pcharNode::pcharNode);
  745. // Get length if not supplied
  746. if ( !len && str )
  747. len = strlen ( str );
  748. // Allocate a new string buffer if valid state
  749. if ( len && str )
  750. {
  751. me = gnew char[ len ];
  752. myLen = len;
  753. if ( me )
  754. strncpy ( me, str, len );
  755. } // End of IF then
  756. else
  757. {
  758. me = 0;
  759. myLen = 0;
  760. } // End of IF else
  761. } // End of "pcharNode" CONSTRUCTOR '(pcchar_t,int)'
  762. inline_pwb
  763. inline_lnk
  764. pchar_t __near pcharNode::getString ( pchar_t buf, int len ) const
  765. {
  766. FTRACE(pcharNode::getString);
  767. // Use the shorter of the two lengths (may not be NULL terminated)
  768. if ( len > pcharNode::length ())
  769. len = pcharNode::length ();
  770. // Do the copy as appropriate
  771. return (( me && buf && len ) ? strncpy ( buf, me, len ) : 0 );
  772. } // End of "pcharNode" FUNCTION "getString(pchar_t,int)"
  773. // The 'pDNameNode' virtual functions
  774. inline_p3 __near pDNameNode::pDNameNode ( DName * pName )
  775. #if ( NO_VIRTUAL )
  776. : DNameNode ( pDNameNode_t )
  777. #endif // NO_VIRTUAL
  778. { me = (( pName && (( pName->status () == DN_invalid ) || ( pName->status () == DN_error ))) ? 0 : pName ); }
  779. inline int __near pDNameNode::length () const { return ( me ? me->length () : 0 ); }
  780. inline_pwb
  781. inline_lnk
  782. pchar_t __near pDNameNode::getString ( pchar_t buf, int len ) const
  783. { return (( me && buf && len ) ? me->getString ( buf, len ) : 0 ); }
  784. // The 'DNameStatusNode' virtual functions
  785. inline_p3 __near DNameStatusNode::DNameStatusNode ( DNameStatus stat )
  786. #if ( NO_VIRTUAL )
  787. : DNameNode ( DNameStatusNode_t )
  788. #endif // NO_VIRTUAL
  789. { me = stat; myLen = (( me == DN_truncated ) ? TruncationMessageLength : 0 ); }
  790. inline int __near DNameStatusNode::length () const { return myLen; }
  791. inline_pwb
  792. inline_lnk
  793. pchar_t __near DNameStatusNode::getString ( pchar_t buf, int len ) const
  794. {
  795. FTRACE(DNameStatusNode::getString);
  796. // Use the shorter of the two lengths (may not be NULL terminated)
  797. if ( len > DNameStatusNode::length ())
  798. len = DNameStatusNode::length ();
  799. // Do the copy as appropriate
  800. return ((( me == DN_truncated ) && buf && len ) ? strncpy ( buf, TruncationMessage, len ) : 0 );
  801. } // End of "DNameStatusNode" FUNCTION "getString(pchar_t,int)"
  802. static unsigned int __near __pascal strlen ( pcchar_t str )
  803. {
  804. for ( unsigned int len = 0; *str; str++ )
  805. len++;
  806. return len;
  807. } // End of FUNCTION "strlen"
  808. static pchar_t __near __pascal strncpy ( pchar_t dst, pcchar_t src, unsigned int len )
  809. {
  810. for ( char __far * d = dst; ( len && ( *d = *src )); d++, src++, len-- )
  811. ;
  812. return dst;
  813. } // End of FUNCTION "strncpy"
  814. #if STDEBUG
  815. void CallTrace::Dump ( const DName & rd, pcchar_t sym, int line )
  816. {
  817. if ( trace && !inTrace )
  818. {
  819. inTrace = 1;
  820. rd.getString ( buf, 512 );
  821. buf[ rd.length ()] = 0;
  822. indent ( mark );
  823. fprintf ( fp, " > DName '%s' #%d: '%s' == '%s'\n", name, line, sym, buf );
  824. fflush ( fp );
  825. inTrace = 0;
  826. }
  827. }
  828. void CallTrace::Dump ( const DNameNode & rd, pcchar_t sym, int line )
  829. {
  830. if ( trace && !inTrace )
  831. {
  832. inTrace = 1;
  833. rd.getString ( buf, 512 );
  834. buf[ rd.length ()] = 0;
  835. indent ( mark );
  836. fprintf ( fp, " > DNameNode '%s' #line %d : '%s' == '%s'\n", name, line, sym, buf );
  837. fflush ( fp );
  838. inTrace = 0;
  839. }
  840. }
  841. void CallTrace::Dump ( unsigned long ul, pcchar_t sym, int line )
  842. {
  843. if ( trace )
  844. {
  845. indent ( mark );
  846. fprintf ( fp, " > ulong '%s' #line %d : '%s' == '0x%08.08LX'\n", name, line, sym, ul );
  847. fflush ( fp );
  848. }
  849. }
  850. void CallTrace::Dump ( void* p, pcchar_t sym, int line )
  851. {
  852. if ( trace )
  853. {
  854. indent ( mark );
  855. fprintf ( fp, " > void* '%s' #line %d : '%s' == '%p'\n", name, line, sym, p );
  856. fflush ( fp );
  857. }
  858. }
  859. void CallTrace::Dump ( const char* p, pcchar_t sym, int line )
  860. {
  861. if ( trace )
  862. {
  863. indent ( mark );
  864. fprintf ( fp, " > char* '%s' #line %d : '%s' == '%s'\n", name, line, sym, p );
  865. fflush ( fp );
  866. }
  867. }
  868. void CallTrace::Track ( pcchar_t file, int line )
  869. {
  870. if ( trace )
  871. {
  872. indent ( mark );
  873. fprintf ( fp, " > Track '%s' : #line %d \"%s\"\n", name, line, file );
  874. fflush ( fp );
  875. }
  876. }
  877. void CallTrace::LogError ( int line )
  878. {
  879. if ( trace )
  880. {
  881. indent ( mark );
  882. fprintf ( fp, " > Log Error '%s' : #line %d\n", name, line );
  883. fflush ( fp );
  884. }
  885. }
  886. void CallTrace::Message ( pcchar_t msg, int line )
  887. {
  888. if ( trace )
  889. {
  890. indent ( mark );
  891. fprintf ( fp, " > Message '%s' : #line %d \"%s\"\n", name, line, msg );
  892. fflush ( fp );
  893. }
  894. }
  895. #endif // STDEBUG