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.

541 lines
10 KiB

  1. // Copyright (c) 1993-1999 Microsoft Corporation
  2. #pragma warning ( disable : 4514 4710 )
  3. #include "nulldefs.h"
  4. #include <basetsd.h>
  5. #include <stdio.h>
  6. #include <stdarg.h>
  7. #include <string.h>
  8. #include <share.h>
  9. #include <memory.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <limits.h>
  13. #include "stream.hxx"
  14. #include "errors.hxx"
  15. #include "cmdana.hxx"
  16. STREAM::~STREAM()
  17. {
  18. Close();
  19. }
  20. STREAM::STREAM(
  21. IN char * pFileName,
  22. IN unsigned char SProt )
  23. {
  24. ResetConsoleStream();
  25. ResetIgnore();
  26. pSpecialCommentString = NULL;
  27. // no alternate file to begin with
  28. StreamOpenStatus = FILE_STATUS_OK;
  29. if( !pFileName )
  30. {
  31. SetStreamType( STREAM_NULL );
  32. ResetError();
  33. ResetEnd();
  34. return;
  35. }
  36. else if( *(pFileName+2) == '-' )
  37. {
  38. S.F.pHandle = stdout;
  39. SetConsoleStream();
  40. }
  41. else // named file stream
  42. {
  43. // if this is a not a file to overwrite, and it exists, don't overwrite it
  44. // substitute a temp file instead
  45. if ( (SProt != FILE_STREAM_OVERWRITE) &&
  46. !_access( pFileName, 0 ) )
  47. {
  48. if ( SProt == FILE_STREAM_REWRITE )
  49. {
  50. // note that tmpfile is opened w+b
  51. S.F.pHandle = tmpfile();
  52. StreamOpenStatus = FILE_STATUS_TEMP;
  53. }
  54. else // write-once file already exists, do nothing
  55. {
  56. S.F.pHandle = NULL;
  57. StreamOpenStatus = FILE_STATUS_NO_WRITE;
  58. SetStreamType( STREAM_NULL );
  59. ResetError();
  60. ResetEnd();
  61. return;
  62. }
  63. }
  64. else // overwritable file...
  65. {
  66. if ( pCommand->HasAppend64() || pCommand->Is2ndCodegenRun() )
  67. {
  68. S.F.pHandle = _fsopen( pFileName, "r+t", SH_DENYWR);
  69. if( S.F.pHandle )
  70. {
  71. // Position at the end of the file.
  72. if ( 0 != fseek( S.F.pHandle, 0, SEEK_END ) )
  73. {
  74. fclose( S.F.pHandle );
  75. S.F.pHandle = NULL;
  76. }
  77. }
  78. else
  79. {
  80. // May be the file does not exist, let's open to write.
  81. // (it happens only when -append64 is used in the first run).
  82. S.F.pHandle = _fsopen( pFileName, "wt", SH_DENYWR);
  83. }
  84. }
  85. else
  86. S.F.pHandle = _fsopen( pFileName, "wt", SH_DENYWR);
  87. }
  88. if ( S.F.pHandle )
  89. {
  90. setvbuf( S.F.pHandle, NULL, _IOFBF, 32768 );
  91. }
  92. }
  93. if( S.F.pHandle == (FILE *)0 )
  94. {
  95. RpcError( (char *)NULL,
  96. 0,
  97. ERROR_WRITING_FILE,
  98. pFileName );
  99. exit( ERROR_WRITING_FILE );
  100. }
  101. else
  102. {
  103. SetStreamType( STREAM_FILE );
  104. SetStreamMode( STREAM_TEXT );
  105. ResetError();
  106. ResetEnd();
  107. }
  108. }
  109. STREAM::STREAM(
  110. IN FILE * pFile )
  111. {
  112. S.F.pHandle = pFile;
  113. SetStreamType( STREAM_FILE );
  114. SetStreamMode( STREAM_TEXT );
  115. ResetError();
  116. ResetEnd();
  117. ResetIgnore();
  118. ResetConsoleStream();
  119. pSpecialCommentString = NULL;
  120. // no alternate file to begin with
  121. StreamOpenStatus = FILE_STATUS_OK;
  122. }
  123. STREAM::STREAM()
  124. {
  125. S.F.pHandle = NULL;
  126. SetStreamType( STREAM_MEMORY );
  127. SetStreamMode( STREAM_TEXT );
  128. ResetEnd();
  129. ResetError();
  130. ResetIgnore();
  131. ResetConsoleStream();
  132. StreamOpenStatus = FILE_STATUS_OK;
  133. pSpecialCommentString = NULL;
  134. SetCurrentPtr( new char[ SetInitialSize( DEFAULT_MEM_SIZE_FOR_STREAM ) ] );
  135. SetInitialIncr( DEFAULT_MEM_INCR_FOR_STREAM );
  136. SetStart( GetCurrentPtr() );
  137. SetMemStreamEnd( GetCurrentPtr() + GetInitialSize() );
  138. }
  139. STREAM::STREAM(
  140. int InitialSize,
  141. int InitialIncr )
  142. {
  143. S.F.pHandle = NULL;
  144. SetStreamType( STREAM_MEMORY );
  145. SetStreamMode( STREAM_TEXT );
  146. ResetEnd();
  147. ResetError();
  148. ResetIgnore();
  149. ResetConsoleStream();
  150. StreamOpenStatus = FILE_STATUS_OK;
  151. pSpecialCommentString = NULL;
  152. SetCurrentPtr( new char[ SetInitialSize( InitialSize ) ] );
  153. SetInitialIncr( InitialIncr );
  154. SetStart( GetCurrentPtr() );
  155. SetMemStreamEnd( GetCurrentPtr() + GetInitialSize() );
  156. }
  157. void
  158. STREAM::SetStreamMode(
  159. STREAM_MODE mode)
  160. {
  161. StreamMode = mode;
  162. int newmode = ( mode == STREAM_BINARY ) ? _O_BINARY : _O_TEXT;
  163. if (S.F.pHandle)
  164. _setmode( _fileno( S.F.pHandle ), newmode );
  165. }
  166. #if 0
  167. void
  168. STREAM::Write(
  169. IN char C )
  170. {
  171. if( (GetStreamType() == STREAM_FILE ) && !IsError() )
  172. putc( C, S.F.pHandle );
  173. else
  174. {
  175. if( S.M.pCurrent >= S.M.pEnd )
  176. {
  177. Expand();
  178. }
  179. *(S.M.pCurrent)++ = C;
  180. }
  181. }
  182. #endif // 0
  183. void
  184. STREAM::Write(
  185. IN const void * p,
  186. IN int Len)
  187. {
  188. if ( ( GetStreamType() == STREAM_NULL ) || IsError() || IsIgnore() )
  189. return;
  190. if( (GetStreamType() == STREAM_FILE ) )
  191. {
  192. fwrite( p, 1, Len, S.F.pHandle );
  193. if( IsConsoleStream() )
  194. fflush( S.F.pHandle );
  195. }
  196. else
  197. {
  198. if( (GetCurrentPtr() + Len) >= S.M.pEnd )
  199. {
  200. ExpandBy( short( Len + GetInitialIncr() ) );
  201. }
  202. memcpy( GetCurrentPtr(), p, Len );
  203. SetCurrentPtr( GetCurrentPtr() + Len );
  204. }
  205. }
  206. void
  207. STREAM::Write(
  208. IN const char * const string)
  209. {
  210. if ( string )
  211. Write( (void *) string, strlen( string ) );
  212. if ( GetStreamMode() == STREAM_BINARY )
  213. Write( '\0' );
  214. }
  215. void
  216. STREAM::WriteNumber(
  217. IN const char * pFmt,
  218. IN const unsigned long ul )
  219. {
  220. char buffer[128];
  221. if ( ( GetStreamType() == STREAM_NULL ) || IsError() || IsIgnore() )
  222. return;
  223. if( (GetStreamType() == STREAM_FILE ) )
  224. {
  225. fprintf( S.F.pHandle, pFmt, ul );
  226. if( IsConsoleStream() )
  227. fflush( S.F.pHandle );
  228. }
  229. else
  230. {
  231. sprintf( buffer, pFmt, ul );
  232. short Len = (short) strlen( buffer );
  233. if( (GetCurrentPtr() + Len) >= S.M.pEnd )
  234. {
  235. ExpandBy( short( Len + GetInitialIncr() ) );
  236. }
  237. memcpy( GetCurrentPtr(), buffer, Len );
  238. SetCurrentPtr( GetCurrentPtr() + Len );
  239. }
  240. }
  241. void
  242. STREAM::WriteFormat(
  243. const char * pFmt,
  244. ... )
  245. {
  246. char buffer[128];
  247. if ( ( GetStreamType() == STREAM_NULL ) || IsError() || IsIgnore() )
  248. return;
  249. va_list Arguments;
  250. va_start( Arguments, pFmt );
  251. if( (GetStreamType() == STREAM_FILE ) )
  252. {
  253. vfprintf( S.F.pHandle, pFmt, Arguments );
  254. if( IsConsoleStream() )
  255. fflush( S.F.pHandle );
  256. }
  257. else
  258. {
  259. vsprintf( buffer, pFmt, Arguments );
  260. short Len = (short) strlen( buffer );
  261. if( (GetCurrentPtr() + Len) >= S.M.pEnd )
  262. {
  263. ExpandBy( short( Len + GetInitialIncr() ) );
  264. }
  265. memcpy( GetCurrentPtr(), buffer, Len );
  266. SetCurrentPtr( GetCurrentPtr() + Len );
  267. }
  268. va_end( Arguments );
  269. }
  270. void
  271. STREAM::Flush()
  272. {
  273. if( (GetStreamType() == STREAM_FILE ) && !IsError() )
  274. if( IsConsoleStream() )
  275. fflush( S.F.pHandle );
  276. }
  277. void
  278. STREAM::Close()
  279. {
  280. if( (GetStreamType() == STREAM_FILE ) )
  281. fclose( S.F.pHandle );
  282. }
  283. int
  284. STREAM::SetInitialSize(
  285. int InitialSize )
  286. {
  287. if( GetStreamType() == STREAM_MEMORY )
  288. return (S.M.InitialSize = InitialSize);
  289. return 0;
  290. }
  291. int
  292. STREAM::GetInitialSize()
  293. {
  294. if( GetStreamType() == STREAM_MEMORY )
  295. return S.M.InitialSize;
  296. return 0;
  297. }
  298. int
  299. STREAM::SetInitialIncr(
  300. int InitialIncr )
  301. {
  302. if( GetStreamType() == STREAM_MEMORY )
  303. return (S.M.Increment = InitialIncr);
  304. return 0;
  305. }
  306. int
  307. STREAM::GetInitialIncr()
  308. {
  309. if( GetStreamType() == STREAM_MEMORY )
  310. return S.M.Increment;
  311. return 0;
  312. }
  313. char *
  314. STREAM::Expand()
  315. {
  316. if( GetStreamType() == STREAM_MEMORY )
  317. {
  318. int Len = GetInitialSize();
  319. char * pTemp = GetStart();
  320. SetStart( new char[ SetInitialSize( Len + GetInitialIncr() ) ] );
  321. memcpy( GetStart(), pTemp, Len );
  322. SetCurrentPtr( GetStart() + Len );
  323. delete pTemp;
  324. return GetCurrentPtr();
  325. }
  326. return 0;
  327. }
  328. char *
  329. STREAM::ExpandBy( short Amt)
  330. {
  331. if( GetStreamType() == STREAM_MEMORY )
  332. {
  333. int Len = GetInitialSize();
  334. char * pTemp = GetStart();
  335. SetStart( new char[ SetInitialSize( Len + GetInitialIncr() + Amt ) ] );
  336. memcpy( GetStart(), pTemp, Len );
  337. SetCurrentPtr( GetStart() + Len );
  338. delete pTemp;
  339. return GetCurrentPtr();
  340. }
  341. return 0;
  342. }
  343. char *
  344. STREAM::NewCopy()
  345. {
  346. if( GetStreamType() == STREAM_MEMORY )
  347. {
  348. MIDL_ASSERT( (S.M.pCurrent - S.M.pMem + 1) <= INT_MAX );
  349. int Len = (int) (S.M.pCurrent - S.M.pMem + 1);
  350. char * p = new char[ Len ];
  351. memcpy( p, S.M.pMem, Len );
  352. return p;
  353. }
  354. return 0;
  355. }
  356. char *
  357. STREAM::SetCurrentPtr(
  358. char * pCur)
  359. {
  360. if( GetStreamType() == STREAM_MEMORY )
  361. return (S.M.pCurrent = pCur);
  362. return 0;
  363. }
  364. char *
  365. STREAM::GetCurrentPtr()
  366. {
  367. if( GetStreamType() == STREAM_MEMORY )
  368. return S.M.pCurrent;
  369. return 0;
  370. }
  371. long
  372. STREAM::GetCurrentPosition()
  373. {
  374. long Position = 0;
  375. if( GetStreamType() == STREAM_FILE )
  376. Position = ftell( S.F.pHandle );
  377. return Position;
  378. }
  379. void
  380. STREAM::SetCurrentPosition( long Position)
  381. {
  382. if( GetStreamType() == STREAM_FILE )
  383. if ( 0 != fseek( S.F.pHandle, Position, SEEK_SET ) )
  384. MIDL_ASSERT(!"fseek failed");
  385. return;
  386. }
  387. char *
  388. STREAM::SetStart(
  389. char * pStart)
  390. {
  391. if( GetStreamType() == STREAM_MEMORY )
  392. return (S.M.pMem = pStart);
  393. return 0;
  394. }
  395. char *
  396. STREAM::GetStart()
  397. {
  398. if( GetStreamType() == STREAM_MEMORY )
  399. return S.M.pMem;
  400. return 0;
  401. }
  402. #define MAX_INDENT (sizeof(SpaceBuffer) - 1)
  403. static
  404. char SpaceBuffer[] = " "
  405. " "
  406. " "
  407. " ";
  408. #define MAX_NEWLINES (sizeof(NewLineBuffer) - 1)
  409. static
  410. char NewLineBuffer[] = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
  411. void
  412. ISTREAM::NewLine()
  413. {
  414. unsigned short usIndent = CurrentIndent;
  415. if (usIndent > MAX_INDENT )
  416. {
  417. usIndent = MAX_INDENT;
  418. };
  419. Write('\n');
  420. SpaceBuffer[usIndent] = '\0';
  421. Write( (char *) SpaceBuffer);
  422. SpaceBuffer[usIndent] = ' ';
  423. }
  424. void
  425. ISTREAM::NewLine( unsigned short count )
  426. {
  427. unsigned short usIndent = CurrentIndent;
  428. if (usIndent > MAX_INDENT )
  429. {
  430. usIndent = MAX_INDENT;
  431. };
  432. if ( count > MAX_NEWLINES )
  433. {
  434. count = MAX_NEWLINES;
  435. };
  436. NewLineBuffer[ count ] = '\0';
  437. Write( (char *) NewLineBuffer);
  438. NewLineBuffer[ count ] = '\n';
  439. SpaceBuffer[usIndent] = '\0';
  440. Write( (char *) SpaceBuffer);
  441. SpaceBuffer[usIndent] = ' ';
  442. }
  443. void
  444. ISTREAM::Spaces(
  445. unsigned short NoOfSpaces )
  446. {
  447. if (NoOfSpaces > MAX_INDENT )
  448. {
  449. NoOfSpaces = MAX_INDENT;
  450. };
  451. SpaceBuffer[NoOfSpaces] = '\0';
  452. Write( (char *) SpaceBuffer);
  453. SpaceBuffer[NoOfSpaces] = ' ';
  454. }