Windows NT 4.0 source code leak
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.

1049 lines
25 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. hsplit.c
  5. Abstract:
  6. This is the main module for a header the file splitter. It will look
  7. for various blocks marked with begin/end tags and treat them specially
  8. based on the tag. Also, it looks for tags that are line based. The
  9. list is show below. Public indicates is appears in the public header file
  10. private in the private header file. Chicago only has one header file,
  11. but private lines are marked as internal.
  12. Author:
  13. Sanford Staab (sanfords) 22-Apr-1992
  14. Revision History:
  15. sankar 05-Dec-1995 Make it work for Nashville.
  16. stevefir 14-Dec-1995 Make it work for SUR & WINVER 4.1
  17. --*/
  18. #include <assert.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. typedef int boolean;
  24. #define TRUE 1
  25. #define FALSE 0
  26. char *szIFDEF[7][2] = {
  27. {
  28. "#if(WINVER >= 0x0400)\n",
  29. "#endif /* WINVER >= 0x0400 */\n"
  30. },
  31. {
  32. "#if(WINVER < 0x0400)\n",
  33. "#endif /* WINVER < 0x0400 */\n"
  34. },
  35. {
  36. "#if(WINVER >= 0x040a)\n",
  37. "#endif /* WINVER >= 0x040a */\n"
  38. },
  39. {
  40. "#if(WINVER < 0x040a)\n",
  41. "#endif /* WINVER < 0x040a */\n"
  42. },
  43. {
  44. "#if(_WIN32_WINNT >= 0x0400)\n",
  45. "#endif /* _WIN32_WINNT >= 0x0400 */\n"
  46. },
  47. {
  48. "#if(_WIN32_WINNT < 0x0400)\n",
  49. "#endif /* _WIN32_WINNT < 0x0400 */\n"
  50. },
  51. {
  52. "#if(_WIN32_WINDOWS >= 0x040a)\n",
  53. "#endif /* _WIN32_WINDOWS >= 0x040a */\n"
  54. },
  55. //
  56. // we don't need _WIN32_WINDOWS < 0x040a
  57. // since Chicago has no private *p.h headers.
  58. //
  59. };
  60. //
  61. // Global Data
  62. //
  63. boolean NT = TRUE; // says if nt flag is on command line
  64. boolean Chicago = FALSE; // says if chicago flag is on command line
  65. boolean Cairo = FALSE; // says if cairo flag is on command line
  66. boolean SURPlus = FALSE; // says if SURPlus flag is on command line
  67. boolean SplitOnly = FALSE; // says only do both and internal
  68. #define MODE_PUBLICNT 0x01
  69. #define MODE_PUBLICCHICAGO 0x02
  70. #define MODE_PUBLICCAIRO 0x04
  71. #define MODE_PUBLICSURPLUS 0x08
  72. #define MODE_PUBLICALL 0x0F
  73. #define MODE_PRIVATENT 0x10
  74. #define MODE_PRIVATECHICAGO 0x20 // goes to public header and marked ;internal.
  75. #define MODE_PRIVATECAIRO 0x40
  76. #define MODE_PRIVATESURPLUS 0x80
  77. #define MODE_PRIVATEALL 0xF0
  78. #define MODE_BOTH 0xFF
  79. #define MODE_NOWHERE 0
  80. #define MODE_IFDEF_WV400 0x100
  81. #define MODE_IFDEF_WV40a 0x200
  82. #define MODE_IFDEF_W32WIN 0x400
  83. #define MODE_IFDEF_W32WNT 0x800
  84. #define MODE_IFDEFALL 0xf00
  85. #define C_BLOCKDEFS 21
  86. #define BLOCKDEF_BOTH 0
  87. #define BLOCKDEF_INTERNAL 1
  88. typedef struct tagBLOCKDEF {
  89. char *pszLineMark;
  90. char * pszBlockStart;
  91. char * pszBlockEnd;
  92. int dwFlags;
  93. } BLOCKDEF, *PBLOCKDEF;
  94. BLOCKDEF aBlockDef[C_BLOCKDEFS] = {
  95. {
  96. "both",
  97. "begin_both",
  98. "end_both",
  99. MODE_BOTH
  100. },
  101. {
  102. "internal",
  103. "begin_internal",
  104. "end_internal",
  105. MODE_PRIVATEALL
  106. },
  107. {
  108. "internal_NT",
  109. "begin_internal_NT",
  110. "end_internal_NT",
  111. MODE_PRIVATENT | MODE_PRIVATECAIRO | MODE_PRIVATESURPLUS
  112. },
  113. {
  114. "internal_win40",
  115. "begin_internal_win40",
  116. "end_internal_win40",
  117. MODE_PRIVATECHICAGO | MODE_PRIVATECAIRO | MODE_PRIVATESURPLUS
  118. },
  119. {
  120. "internal_win40a",
  121. "begin_internal_win40a",
  122. "end_internal_win40a",
  123. MODE_PRIVATECHICAGO | MODE_PRIVATESURPLUS
  124. },
  125. {
  126. "internal_chicago",
  127. "begin_internal_chicago",
  128. "end_internal_chicago",
  129. MODE_PRIVATECHICAGO
  130. },
  131. {
  132. "internal_NT_35",
  133. "begin_internal_NT_35",
  134. "end_internal_NT_35",
  135. MODE_PRIVATENT
  136. },
  137. {
  138. "internal_cairo",
  139. "begin_internal_cairo",
  140. "end_internal_cairo",
  141. MODE_PRIVATECAIRO | MODE_PRIVATESURPLUS
  142. },
  143. {
  144. "internal_surplus",
  145. "begin_internal_surplus",
  146. "end_internal_surplus",
  147. MODE_PRIVATESURPLUS
  148. },
  149. {
  150. "public_winver_400",
  151. "begin_winver_400",
  152. "end_winver_400",
  153. MODE_PRIVATENT | MODE_PUBLICALL | MODE_IFDEF_WV400
  154. },
  155. {
  156. "public_win40",
  157. "begin_public_win40",
  158. "end_public_win40",
  159. MODE_PUBLICCAIRO | MODE_PUBLICCHICAGO
  160. },
  161. {
  162. "public_win40a",
  163. "begin_public_win40a",
  164. "end_public_win40a",
  165. MODE_PUBLICSURPLUS | MODE_PUBLICCHICAGO
  166. },
  167. {
  168. "public_cairo",
  169. "begin_public_cairo",
  170. "end_public_cairo",
  171. MODE_PUBLICCAIRO
  172. },
  173. {
  174. "public_NT",
  175. "begin_public_NT",
  176. "end_public_NT",
  177. MODE_PUBLICNT | MODE_PUBLICCAIRO
  178. },
  179. {
  180. "public_NT_35",
  181. "begin_public_NT_35",
  182. "end_public_NT_35",
  183. MODE_PUBLICNT
  184. },
  185. {
  186. "public_chicago",
  187. "begin_public_chicago",
  188. "end_public_chicago",
  189. MODE_PUBLICCHICAGO
  190. },
  191. {
  192. "public_sur",
  193. "begin_sur",
  194. "end_sur",
  195. MODE_PUBLICCAIRO | MODE_IFDEF_W32WNT
  196. },
  197. {
  198. "public_surplus",
  199. "begin_surplus",
  200. "end_surplus",
  201. MODE_PUBLICSURPLUS | MODE_IFDEF_W32WNT
  202. },
  203. {
  204. "public_nashville",
  205. "begin_nashville",
  206. "end_nashville",
  207. MODE_PUBLICCHICAGO | MODE_IFDEF_W32WIN
  208. },
  209. {
  210. "public_winver_40a",
  211. "begin_winver_40a",
  212. "end_winver_40a",
  213. MODE_PUBLICSURPLUS | MODE_PRIVATECAIRO | MODE_PUBLICCHICAGO | MODE_IFDEF_WV40a
  214. },
  215. {
  216. "$",
  217. "begin_$",
  218. "end_$",
  219. MODE_NOWHERE
  220. }
  221. };
  222. char *CommentDelimiter = ";";
  223. char *OutputFileName1;
  224. char *OutputFileName2;
  225. char *SourceFileName;
  226. char **SourceFileList;
  227. int SourceFileCount;
  228. FILE *SourceFile, *OutputFile1, *OutputFile2;
  229. #define STRING_BUFFER_SIZE 1024
  230. char StringBuffer[STRING_BUFFER_SIZE];
  231. #define BUILD_VER_COMMENT "/*++ BUILD Version: "
  232. #define BUILD_VER_COMMENT_LENGTH (sizeof (BUILD_VER_COMMENT)-1)
  233. int OutputVersion = 0;
  234. #define DONE 1
  235. #define NOT_DONE 0
  236. //
  237. // Function declarations
  238. //
  239. int
  240. ProcessParameters(
  241. int argc,
  242. char *argv[]
  243. );
  244. void
  245. ProcessSourceFile( void );
  246. boolean
  247. ExactMatch (
  248. char *,
  249. char *
  250. );
  251. char *laststrstr (
  252. const char *,
  253. const char *
  254. );
  255. boolean
  256. CheckForSingleLine (
  257. char *
  258. );
  259. int
  260. ProcessLine (
  261. char *Input,
  262. char *LineTag,
  263. int mode
  264. );
  265. void
  266. AddString (
  267. int mode,
  268. char *string
  269. );
  270. void
  271. AddIfDef (
  272. int mode,
  273. int fBegin
  274. );
  275. int
  276. ProcessBlock (
  277. char **s,
  278. char *BlockTagStart,
  279. char *BlockTagEnd,
  280. int mode
  281. );
  282. void
  283. DoOutput (
  284. int mode,
  285. char *string
  286. );
  287. int
  288. _CRTAPI1 main( argc, argv )
  289. int argc;
  290. char *argv[];
  291. {
  292. if (!ProcessParameters( argc, argv )) {
  293. fprintf( stderr, "usage: HSPLIT\n" );
  294. fprintf( stderr, " [-?]\n" );
  295. fprintf( stderr, " display this message\n" );
  296. fprintf( stderr, "\n" );
  297. fprintf( stderr, " <-o fname1 fname2>\n" );
  298. fprintf( stderr, " supplies output file names\n" );
  299. fprintf( stderr, "\n" );
  300. fprintf( stderr, " [-lt2 string]\n" );
  301. fprintf( stderr, " one line tag for output to second file only\n" );
  302. fprintf( stderr, " default=\"%s\"\n",
  303. aBlockDef[BLOCKDEF_INTERNAL].pszLineMark );
  304. fprintf( stderr, "\n" );
  305. fprintf( stderr, " [-bt2 string1 string2]\n" );
  306. fprintf( stderr, " block tags for output to second file only\n" );
  307. fprintf( stderr, " default=\"%s\",\"%s\"\n",
  308. aBlockDef[BLOCKDEF_INTERNAL].pszBlockStart,
  309. aBlockDef[BLOCKDEF_INTERNAL].pszBlockEnd );
  310. fprintf( stderr, "\n" );
  311. fprintf( stderr, " [-ltb string]\n" );
  312. fprintf( stderr, " one line tag for output to both files\n" );
  313. fprintf( stderr, " default=\"%s\"\n",
  314. aBlockDef[BLOCKDEF_BOTH].pszLineMark );
  315. fprintf( stderr, "\n" );
  316. fprintf( stderr, " [-btb string1 string2]\n" );
  317. fprintf( stderr, " block tags for output to both files\n" );
  318. fprintf( stderr, " default=\"%s\",\"%s\"\n",
  319. aBlockDef[BLOCKDEF_BOTH].pszBlockStart,
  320. aBlockDef[BLOCKDEF_BOTH].pszBlockEnd );
  321. fprintf( stderr, "\n" );
  322. fprintf( stderr, " [-c comment delimiter]\n" );
  323. fprintf( stderr, " default=\"%s\"\n", CommentDelimiter);
  324. fprintf( stderr, "\n" );
  325. fprintf( stderr, " [-n]\n" );
  326. fprintf( stderr, " generate NT header (default)\n");
  327. fprintf( stderr, "\n" );
  328. fprintf( stderr, " [-4]\n" );
  329. fprintf( stderr, " generate Chicago/Nashville header\n");
  330. fprintf( stderr, "\n" );
  331. fprintf( stderr, " [-e]\n" );
  332. fprintf( stderr, " generate NT (SUR) header\n");
  333. fprintf( stderr, "\n" );
  334. fprintf( stderr, " [-p]\n" );
  335. fprintf( stderr, " generate NT (SURPlus) header\n");
  336. fprintf( stderr, "\n" );
  337. fprintf( stderr, " [-s]\n" );
  338. fprintf( stderr, " process only the ;both and ;internal\n");
  339. fprintf( stderr, " tags, or those tags specified by the\n");
  340. fprintf( stderr, " -lt* and -bt* options. All other tags\n");
  341. fprintf( stderr, " are left intact.\n");
  342. fprintf( stderr, "\n" );
  343. fprintf( stderr, " filename1 filename2 ...\n" );
  344. fprintf( stderr, " files to concat and split\n" );
  345. fprintf( stderr, "\n" );
  346. fprintf( stderr, " Untagged lines output to the first file only.\n" );
  347. fprintf( stderr, " All tags must follow a comment delimiter.\n" );
  348. fprintf( stderr, " Comments are not propagated to either output file.\n" );
  349. fprintf( stderr, " Tag nesting is not supported.\n" );
  350. return TRUE;
  351. }
  352. if ( (OutputFile1 = fopen(OutputFileName1,"w")) == 0) {
  353. fprintf(stderr,"HSPLIT: Unable to open output file %s\n",
  354. OutputFileName1);
  355. return TRUE;
  356. }
  357. //
  358. // Chicago doesn't ever have a second output file
  359. //
  360. if (!Chicago) {
  361. if ( (OutputFile2 = fopen(OutputFileName2,"w")) == 0) {
  362. fprintf(stderr,"HSPLIT: Unable to open output file %s\n",
  363. OutputFileName2);
  364. return TRUE;
  365. }
  366. }
  367. while ( SourceFileCount-- ) {
  368. SourceFileName = *SourceFileList++;
  369. if ( (SourceFile = fopen(SourceFileName,"r")) == 0) {
  370. fprintf(stderr,
  371. "HSPLIT: Unable to open source file %s for read access\n",
  372. SourceFileName);
  373. return TRUE;
  374. }
  375. ProcessSourceFile();
  376. fclose(SourceFile);
  377. }
  378. return( FALSE );
  379. }
  380. int
  381. ProcessParameters(
  382. int argc,
  383. char *argv[]
  384. )
  385. {
  386. char c, *p;
  387. while (--argc) {
  388. p = *++argv;
  389. //
  390. // if we have a delimiter for a parameter, case through the valid
  391. // parameter. Otherwise, the rest of the parameters are the list of
  392. // input files.
  393. //
  394. if (*p == '/' || *p == '-') {
  395. //
  396. // Switch on all the valid delimiters. If we don't get a valid
  397. // one, return with an error.
  398. //
  399. c = *++p;
  400. switch (toupper( c )) {
  401. case 'C':
  402. argc--, argv++;
  403. CommentDelimiter = *argv;
  404. break;
  405. case 'O':
  406. argc--, argv++;
  407. OutputFileName1 = *argv;
  408. argc--, argv++;
  409. OutputFileName2 = *argv;
  410. break;
  411. case 'L':
  412. c = *++p;
  413. if ( (toupper ( c )) != 'T')
  414. return FALSE;
  415. c = *++p;
  416. switch (toupper ( c )) {
  417. case '2':
  418. argc--, argv++;
  419. aBlockDef[BLOCKDEF_INTERNAL].pszLineMark = *argv;
  420. break;
  421. case 'B':
  422. argc--, argv++;
  423. aBlockDef[BLOCKDEF_BOTH].pszLineMark = *argv;
  424. break;
  425. default:
  426. return(FALSE);
  427. }
  428. break;
  429. case 'B':
  430. c = *++p;
  431. if ( (toupper ( c )) != 'T')
  432. return FALSE;
  433. c = *++p;
  434. switch (toupper ( c )) {
  435. case '2':
  436. argc--, argv++;
  437. aBlockDef[BLOCKDEF_INTERNAL].pszBlockStart = *argv;
  438. argc--, argv++;
  439. aBlockDef[BLOCKDEF_INTERNAL].pszBlockEnd = *argv;
  440. break;
  441. case 'B':
  442. argc--, argv++;
  443. aBlockDef[BLOCKDEF_BOTH].pszBlockStart = *argv;
  444. argc--, argv++;
  445. aBlockDef[BLOCKDEF_BOTH].pszBlockEnd = *argv;
  446. break;
  447. default:
  448. return(FALSE);
  449. }
  450. break;
  451. case '4':
  452. Chicago = TRUE;
  453. NT = FALSE;
  454. Cairo = FALSE;
  455. SURPlus = FALSE;
  456. SplitOnly = FALSE;
  457. break;
  458. case 'N':
  459. NT = TRUE;
  460. Chicago = FALSE;
  461. SURPlus = FALSE;
  462. Cairo = FALSE;
  463. SplitOnly = FALSE;
  464. break;
  465. case 'S':
  466. Cairo = FALSE;
  467. NT = FALSE;
  468. SURPlus = FALSE;
  469. Chicago = FALSE;
  470. SplitOnly = TRUE;
  471. break;
  472. case 'E':
  473. Cairo = TRUE;
  474. NT = FALSE;
  475. SURPlus = FALSE;
  476. SplitOnly = FALSE;
  477. Chicago = FALSE;
  478. break;
  479. case 'P':
  480. Cairo = FALSE;
  481. NT = FALSE;
  482. SURPlus = TRUE;
  483. SplitOnly = FALSE;
  484. Chicago = FALSE;
  485. break;
  486. default:
  487. return FALSE;
  488. }
  489. } else {
  490. //
  491. // Make the assumption that we have a valid command line if and
  492. // only if we have a list of filenames.
  493. //
  494. SourceFileList = argv;
  495. SourceFileCount = argc;
  496. return TRUE;
  497. }
  498. }
  499. return FALSE;
  500. }
  501. void
  502. ProcessSourceFile(
  503. void
  504. )
  505. {
  506. char *s;
  507. int i;
  508. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  509. if (!strncmp( s, BUILD_VER_COMMENT, BUILD_VER_COMMENT_LENGTH )) {
  510. OutputVersion += atoi( s + BUILD_VER_COMMENT_LENGTH );
  511. }
  512. while ( s ) {
  513. for (i = 0; i < (SplitOnly ? (BLOCKDEF_INTERNAL + 1) : C_BLOCKDEFS); i++) {
  514. if (ProcessBlock (&s,
  515. aBlockDef[i].pszBlockStart,
  516. aBlockDef[i].pszBlockEnd,
  517. aBlockDef[i].dwFlags) == DONE) {
  518. goto bottom;
  519. }
  520. }
  521. if(!CheckForSingleLine(s)) {
  522. // fprintf (stderr, "ProcessSouceFile: output by default\n");
  523. fputs(s, OutputFile1);
  524. }
  525. bottom:
  526. s = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  527. }
  528. }
  529. //
  530. // CheckForSingleLine - processes a line looking for a line tag.
  531. //
  532. // RETURNS: TRUE if a line tag was found and the line was dealt with.
  533. //
  534. // FALSE if no line tag was found.
  535. //
  536. boolean
  537. CheckForSingleLine(
  538. char *s
  539. )
  540. {
  541. int i;
  542. for (i = 0; i < (SplitOnly ? (BLOCKDEF_INTERNAL + 1) : C_BLOCKDEFS); i++) {
  543. if (ProcessLine (s,
  544. aBlockDef[i].pszLineMark,
  545. aBlockDef[i].dwFlags) == DONE) {
  546. return TRUE;
  547. }
  548. }
  549. return(FALSE);
  550. }
  551. //
  552. // ProcessLine - looks for a line tag in an input string and does the
  553. // correct output corresponding to the bits passed in the
  554. // mode parameter. If there is no line tag, there is no
  555. // output generated.
  556. //
  557. // Input -
  558. // LineTag -
  559. // mode - MODE_PUBLICALL:
  560. // MODE_PRIVATEALL:
  561. // NTONLY:
  562. // WIN4ONLY:
  563. //
  564. // RETURNS - DONE if found the LineTag in Input.
  565. //
  566. // NOTDONE if LineTag was not found in Input string.
  567. int
  568. ProcessLine (
  569. char *Input,
  570. char *LineTag,
  571. int mode
  572. )
  573. {
  574. char *comment;
  575. char *tag;
  576. // fprintf (stderr, "ProcessLine: Input=%s, LineTag=%s, mode=0x%x\n",
  577. // Input, LineTag, mode);
  578. //
  579. // Check for a single line to output.
  580. //
  581. comment = laststrstr(Input,CommentDelimiter);
  582. if ( comment ) {
  583. // get past the comment delimiter and white space
  584. tag = comment + strlen (CommentDelimiter);
  585. while (isspace (*tag)) tag++;
  586. if ( tag && ExactMatch (tag, LineTag)) {
  587. char *p;
  588. p = laststrstr(comment + 1, CommentDelimiter);
  589. while (p != NULL && p < tag) {
  590. comment = p;
  591. p = laststrstr(comment + 1, CommentDelimiter);
  592. }
  593. if (NT || Cairo || SURPlus || (mode & MODE_PUBLICCHICAGO)) {
  594. // lop off the line tag.
  595. while (isspace(*(--comment)));
  596. comment++;
  597. *comment++ = '\n';
  598. *comment = '\0';
  599. } else {
  600. // put the // before the CommentDelimter
  601. char temp [STRING_BUFFER_SIZE];
  602. strcpy (temp, comment);
  603. *comment++ = '/';
  604. *comment++ = '/';
  605. *comment++ = ' ';
  606. strcpy (comment, temp);
  607. }
  608. if (mode & MODE_IFDEFALL) {
  609. AddIfDef (mode, TRUE);
  610. }
  611. AddString(mode, Input);
  612. if (mode & MODE_IFDEFALL) {
  613. AddIfDef (mode, FALSE);
  614. }
  615. return(DONE);
  616. }
  617. }
  618. return (NOT_DONE);
  619. }
  620. //
  621. // ExactMatch - performs an exact, case insensitive string compare between
  622. // LookingFor and the first token in Input.
  623. //
  624. // RETURNS: TRUE if exact match, else FALSE
  625. //
  626. boolean
  627. ExactMatch (char *Input, char *LookingFor)
  628. {
  629. char Save;
  630. int Length;
  631. boolean TheSame;
  632. // if (*Input == '\0' || *LookingFor == '\0')
  633. // fprintf (stderr, "\n\n\nExactMatch: Input='%s' and LookingFor='%s'\n",
  634. // Input, LookingFor);
  635. //
  636. // Place a '\0' at the first space in the string, then compare, and restore
  637. //
  638. Length = 0;
  639. while (Input [Length] != '\0' && !isspace (Input[Length])) {
  640. // fprintf (stderr, "Input[%d]='0x%x', isspace=%s\n",
  641. // Length,
  642. // Input [Length],
  643. // isspace (Input[Length])?"T":"F");
  644. Length++;
  645. }
  646. Save = Input [Length];
  647. Input [Length] = '\0';
  648. TheSame = !_stricmp (Input, LookingFor);
  649. // fprintf (stderr, "Comparing Input='%s' and LookingFor='%s', ret=%d\n",
  650. // Input, LookingFor, TheSame);
  651. Input [Length] = Save;
  652. return (TheSame);
  653. }
  654. //
  655. // laststrstr
  656. //
  657. // Finds the last occurence of string2 in string1
  658. //
  659. char *
  660. laststrstr( const char *str1, const char *str2 )
  661. {
  662. const char *cp = str1 + strlen(str1) - strlen(str2);
  663. const char *s1, *s2;
  664. while(cp > str1) {
  665. s1 = cp;
  666. s2 = str2;
  667. while( *s1 && *s2 && (*s1 == *s2) ) {
  668. s1++, s2++;
  669. }
  670. //
  671. // If the chars matched until s2 reached '\0', then we've
  672. // found our substring.
  673. //
  674. if(*s2 == '\0') {
  675. // fprintf (stderr, "laststrstr: found '%s' in '%s'\n",
  676. // str2, str1);
  677. return((char *) cp);
  678. }
  679. cp--;
  680. }
  681. // fprintf (stderr, "laststrstr: did not find '%s' in '%s'\n",
  682. // str2, str1);
  683. return(NULL);
  684. }
  685. int
  686. ProcessBlock (
  687. char **pInput,
  688. char *BlockTagStart,
  689. char *BlockTagEnd,
  690. int mode
  691. )
  692. {
  693. char *comment;
  694. char *tag;
  695. char *Input = *pInput;
  696. // fprintf (stderr, "ProcessBlock: *pINput=%s, BlockTagStart=%s, BlockTagEnd=%s\n", *pInput, BlockTagStart, BlockTagEnd);
  697. comment = strstr(Input,CommentDelimiter);
  698. if ( comment ) {
  699. // get past the comment delimiter and white space
  700. tag = comment + strlen (CommentDelimiter);
  701. while (isspace (*tag)) tag++;
  702. //
  703. // If we found a substring and the tag is identical to
  704. // what we are looking for...
  705. //
  706. if ( tag && ExactMatch (tag, BlockTagStart)) {
  707. //
  708. // Now that we have found an opening tag, check each
  709. // following line for the closing tag, and then include it
  710. // in the output.
  711. //
  712. //
  713. // For NT we set the string to be WINVER < 0x0400 so we
  714. // don't interfere with the Cairo stuff
  715. //
  716. if(mode & MODE_IFDEFALL) {
  717. AddIfDef (mode, TRUE);
  718. }
  719. Input = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  720. while ( Input ) {
  721. comment = strstr(Input,CommentDelimiter);
  722. if ( comment ) {
  723. tag = strstr(comment,BlockTagEnd);
  724. if ( tag ) {
  725. if(mode & MODE_IFDEFALL) {
  726. AddIfDef (mode, FALSE);
  727. }
  728. return DONE;
  729. }
  730. }
  731. DoOutput (mode, Input);
  732. Input = fgets(StringBuffer,STRING_BUFFER_SIZE,SourceFile);
  733. }
  734. }
  735. }
  736. *pInput = Input;
  737. return NOT_DONE;
  738. }
  739. //
  740. // DoOuput - called to output a line during block processsing. Since
  741. // some lines for Chicago's header files contain line tags,
  742. // we need to do line processing on the line to see if
  743. // it needs to be treated specially.
  744. //
  745. void
  746. DoOutput (
  747. int mode,
  748. char *string
  749. )
  750. {
  751. char *comment;
  752. //
  753. // When we do line processing on it, we will return if this
  754. // line processing actually did the output already. Otherwise,
  755. // drop into the output processing for lines within a block.
  756. //
  757. // fprintf (stderr, "DoOutput (%d,%s)\n", mode, string);
  758. if (CheckForSingleLine (string)) {
  759. // fprintf (stderr, "DoOutput: Called CheckForSingleLine and returning\n");
  760. return;
  761. }
  762. if ((mode & MODE_PRIVATECHICAGO) && Chicago && !(mode & MODE_PUBLICCHICAGO)) {
  763. //
  764. // If this is for Chicago, outfile2 is not relavant
  765. // but we have to add the internal comment
  766. //
  767. comment = string + strlen(string);
  768. while(*(--comment) != '\n');
  769. if(comment != string) {
  770. *comment='\0';
  771. strcat(string, "\t// ;internal\n");
  772. }
  773. }
  774. AddString(mode, string);
  775. }
  776. void
  777. AddString (
  778. int mode,
  779. char *string
  780. )
  781. {
  782. if ((NT && (mode & MODE_PUBLICNT)) ||
  783. (Chicago && ((mode & MODE_PUBLICCHICAGO) || (mode & MODE_PRIVATECHICAGO))) ||
  784. (Cairo && (mode & MODE_PUBLICCAIRO)) ||
  785. (SURPlus && (mode & MODE_PUBLICSURPLUS)) ||
  786. (SplitOnly && (mode & MODE_PUBLICALL)))
  787. fputs(string, OutputFile1);
  788. if ((NT && (mode & MODE_PRIVATENT)) ||
  789. (Cairo && (mode & MODE_PRIVATECAIRO)) ||
  790. (SURPlus&& (mode & MODE_PRIVATESURPLUS)) ||
  791. (SplitOnly && (mode & MODE_PRIVATEALL)))
  792. fputs(string, OutputFile2);
  793. }
  794. void
  795. AddIfDef (
  796. int mode,
  797. int fBegin
  798. )
  799. {
  800. int iVerIndex = 0;
  801. int iBeginEnd = 0;
  802. //
  803. // Chose index of the ifdef string
  804. //
  805. iBeginEnd = fBegin ? 0 : 1;
  806. if (mode & MODE_IFDEF_WV400 ) iVerIndex = 0;
  807. else if (mode & MODE_IFDEF_WV40a ) iVerIndex = 2;
  808. else if (mode & MODE_IFDEF_W32WNT) iVerIndex = 4;
  809. else if (mode & MODE_IFDEF_W32WIN) iVerIndex = 6;
  810. else
  811. fprintf (stderr, "AddIfDef: bad mode parameter\n");
  812. //
  813. // Write ifdef line to the correct files.
  814. //
  815. if ((NT && (mode & MODE_PUBLICNT)) ||
  816. (Chicago && ((mode & MODE_PUBLICCHICAGO) || (mode & MODE_PRIVATECHICAGO))) ||
  817. (Cairo && (mode & MODE_PUBLICCAIRO)) ||
  818. (SURPlus && (mode & MODE_PUBLICSURPLUS)))
  819. fputs(szIFDEF[iVerIndex][iBeginEnd], OutputFile1);
  820. //
  821. // Private NT material also goes into public, so reverse sense of #if check
  822. // to avoid multiple defines.
  823. //
  824. if (NT && (mode & MODE_PRIVATENT))
  825. fputs(szIFDEF[iVerIndex+1][iBeginEnd], OutputFile2);
  826. //
  827. // Not a problem for private cairo material, since it is not in public.
  828. //
  829. if (Cairo && (mode & MODE_PRIVATECAIRO))
  830. fputs(szIFDEF[iVerIndex][iBeginEnd], OutputFile2);
  831. //
  832. // Not a problem for private SURPlus material, since it is not in public.
  833. //
  834. if (SURPlus && (mode & MODE_PRIVATESURPLUS))
  835. fputs(szIFDEF[iVerIndex][iBeginEnd], OutputFile2);
  836. }