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.

1070 lines
26 KiB

  1. /*
  2. * MkClnMkf - generates the makefile to cleanse the VC++ v7.0 CRTL sources
  3. * in preparation for a Microsoft-internal build of the CRTL. Those
  4. * cleansed sources will also be used for the publicly-released CRTL
  5. * source as a part of the VC++ 7.0 retail product.
  6. *
  7. * Programmed by Steve Salisbury, 1994-12-07 Wed
  8. *
  9. * This program takes 7 arguments:
  10. * prefixSrc - path to the raw VC++ 7.0 CRTL sources
  11. * prefixDst - path to the partly cleansed VC++ 7.0 CRTL sources
  12. * prefixDst2 - path to the final cleansed VC++ 7.0 CRTL sources
  13. * inputRaw - a list of raw input files
  14. * inputCln - a list of the input files that must be cleansed
  15. * output - name of the first output file (may not already exist)
  16. * outputRel - name of the second output file (may not already exist)
  17. *
  18. * Modified by Steve Salisbury, 1994-12-15 Thu
  19. * Restore the crtw32/ and fpw32/ subdirectories
  20. * Automate the generation of the directory list
  21. *
  22. * Modified 1995-01-16 Mon - take directory list from an input file, too.
  23. *
  24. * Modified 1995-01-17 Tue - many changes to make things work when removing
  25. * crtw32/ and fpw32/ directories from the target filename paths.
  26. *
  27. * Modified 1995-01-18 Wed - The 3 files cleansed with bldmkf.sed should
  28. * have that file as an explicit dependency.
  29. *
  30. * Modified 1995-01-23 Mon - Add a second output file
  31. *
  32. * Modified 1996-06-27 Thu - Fix off by 1 error in list allocation
  33. *
  34. * Modified 1997-08-14 Thu (Jamie) - Revved version strings from 4.0 => 6.0
  35. *
  36. * Modified 1999-05-16 Sun (PhilipLu) - Removed MAC support
  37. *
  38. * Modified 1999-08-02 Mon (PhilipLu) - Revved version strings from 6.0 => 7.0
  39. *
  40. * Modified 1999-08-06 Fri (PhilipLu) - Set .RC file names by cmdline switches
  41. *
  42. * Modified 1999-10-17 Sun (PhilipLu) - Add -noclean options
  43. */
  44. /*-
  45. * Build Version Options
  46. -*/
  47. /* define KEEPDIRS */
  48. /*-
  49. * Include Header Files
  50. -*/
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <time.h>
  55. /*-
  56. * Define Constants
  57. -*/
  58. #define MAXARGLEN 128
  59. #define CRTW32 "crtw32\\"
  60. #define FPW32 "fpw32\\"
  61. /*-
  62. * Define VERBOSE to get verbose output makefiles
  63. -*/
  64. #ifdef VERBOSE
  65. #define AT ""
  66. #else
  67. #define AT "@"
  68. #endif
  69. #if defined(_BUILD_IA64)
  70. #define TOOLDIR "..\\libw32\\tools\\i386"
  71. #define CPUDIR "ia64"
  72. #elif defined(_BUILD_ALPHA64)
  73. #define TOOLDIR "..\\libw32\\tools\\alpha"
  74. #define CPUDIR "alpha64"
  75. #elif defined(_M_IA64)
  76. #define TOOLDIR "..\\libw32\\tools\\ia64"
  77. #define CPUDIR "ia64"
  78. #elif defined(_M_ALPHA64)
  79. #define TOOLDIR "..\\libw32\\tools\\alpha64"
  80. #define CPUDIR "alpha64"
  81. #elif defined(_M_IX86)
  82. #define TOOLDIR "..\\libw32\\tools\\i386"
  83. #define CPUDIR "intel"
  84. #elif defined(_M_ALPHA)
  85. #define TOOLDIR "..\\libw32\\tools\\alpha"
  86. #define CPUDIR "alpha"
  87. #elif defined(_M_MRX000)
  88. #define TOOLDIR "..\\libw32\\tools\\mips"
  89. #define CPUDIR "mips"
  90. #elif defined(_M_PPC)
  91. #define TOOLDIR "..\\libw32\\tools\\ppc"
  92. #define CPUDIR "ppc"
  93. #endif
  94. #define INTEL_DIR "intel"
  95. /*-
  96. * Define Global Variables (Constants)
  97. -*/
  98. #ifndef KEEPDIRS
  99. char fmtRaw2 [ ] =
  100. "%s%s: %s%s %ssrcrel\\bldmkf.sed\n"
  101. "\t" AT "echo Copying %s from %s to %s. (using SED.EXE)\n"
  102. "\t" AT "if exist %s%s attrib -r %s%s\n"
  103. "\t" AT "sed -f %ssrcrel\\bldmkf.sed %s%s > %s%s\n"
  104. "\t" AT "attrib +r %s%s\n"
  105. "\n" ;
  106. #endif /* KEEPDIRS */
  107. char fmtRaw [ ] =
  108. "%s%s: %s%s\n"
  109. "\t" AT "echo Copying %s from %s to %s.\n"
  110. "\t" AT "if exist %s%s attrib -r %s%s\n"
  111. "\t" AT "copy /b %s%s %s%s >nul\n"
  112. "\t" AT "attrib +r %s%s\n"
  113. "\n" ;
  114. char fmtCln2 [ ] =
  115. "%s%s: %s%s %ssrcrel\\msvc40.if\n"
  116. "\t" AT "echo Cleansing %s%s\n"
  117. "\t" AT "if exist %s%s attrib -r %s%s\n"
  118. "\t" AT TOOLDIR "\\detab < %s%s | " TOOLDIR "\\trailing > %s%s\n"
  119. "\t" AT "rem *\n"
  120. "\t" AT "rem * IFSTRIP is NOT used on .INC assembler include files!\n"
  121. "\t" AT "rem *\n"
  122. "\t" AT "rem " TOOLDIR "\\ifstrip -z -c -t -x.TMP -f %ssrcrel\\msvc40.if %s%s\n"
  123. "\t" AT "rem del %s%s\n"
  124. "\t" AT "rem ren %s%s.TMP *%s\n"
  125. "\t" AT TOOLDIR "\\striphdr -r %s%s\n"
  126. "\t" AT "del %s%s\n"
  127. "\t" AT "ren %s%s.NEW *%s\n"
  128. "\t" AT "attrib +r %s%s\n"
  129. "\n" ;
  130. char fmtCln [ ] =
  131. "%s%s: %s%s %ssrcrel\\msvc40.if\n"
  132. "\t" AT "echo Cleansing %s%s\n"
  133. "\t" AT "if exist %s%s attrib -r %s%s\n"
  134. "\t" AT TOOLDIR "\\detab < %s%s | " TOOLDIR "\\trailing > %s%s\n"
  135. "\t" AT TOOLDIR "\\ifstrip -z -c -t -x.TMP -f %ssrcrel\\msvc40.if %s%s\n"
  136. "\t" AT "del %s%s\n"
  137. "\t" AT "ren %s%s.TMP *%s\n"
  138. "\t" AT TOOLDIR "\\striphdr -r %s%s\n"
  139. "\t" AT "del %s%s\n"
  140. "\t" AT "ren %s%s.NEW *%s\n"
  141. "\t" AT "attrib +r %s%s\n"
  142. "\n" ;
  143. const char prefixSrc [ ] = "$(SRC)\\" ;
  144. const char prefixDst [ ] = "$(DST)\\" ;
  145. char * * DirList ;
  146. const char * szRcFiles [ 2 ] [ 2 ] [ 3 ] =
  147. {
  148. {
  149. { "msvcirt.rc" , "msvcprt.rc" , "msvcrt.rc" } ,
  150. { "msvcirt.rc" , "msvcprt.rc" , "msvcrt.rc" }
  151. } ,
  152. {
  153. { "sysirt.rc" , "sysprt.rc" , "syscrt.rc" } ,
  154. { "sysirt64.rc" , "sysprt64.rc" , "syscrt64.rc" }
  155. }
  156. } ;
  157. /*-
  158. * Function Declarations (Prototypes)
  159. -*/
  160. int main ( int argc , char * * argv ) ;
  161. void Usage ( void ) ;
  162. char * fgetsNL ( char * lineBuf , int lineSize , FILE * fileInput ) ;
  163. void Progress ( int prefix , char * string , int suffix ) ;
  164. char * SkipFirstDir ( char * string ) ;
  165. /*-
  166. * Function Definitions (Implementations)
  167. -*/
  168. int main ( int argc , char * * argv )
  169. {
  170. FILE * inputRaw ;
  171. FILE * inputCln ;
  172. FILE * inputDir ;
  173. FILE * output ;
  174. FILE * output2 ;
  175. char lineRaw [ MAXARGLEN ] ;
  176. char lineCln [ MAXARGLEN ] ;
  177. char * rvRaw ;
  178. char * rvCln ;
  179. char * defaultSrc ;
  180. char * defaultDst ;
  181. char * defaultDst2 ;
  182. char * lineSkip ;
  183. char * * pDirs ;
  184. time_t timestamp ;
  185. struct tm localt ;
  186. char * * nextArg ;
  187. int fSysCrt = 0;
  188. int fCrt64 = 0;
  189. int fNoClean = 0;
  190. nextArg = ++ argv ;
  191. while ( * nextArg != NULL && * * nextArg == '-' )
  192. {
  193. if ( strcmp ( * nextArg , "-sys" ) == 0 )
  194. {
  195. fSysCrt = 1 ;
  196. }
  197. else if ( strcmp ( * nextArg , "-64" ) == 0 )
  198. {
  199. fCrt64 = 1 ;
  200. }
  201. else if ( strcmp ( * nextArg , "-noclean" ) == 0 )
  202. {
  203. fNoClean = 1 ;
  204. }
  205. else
  206. {
  207. Usage ( ) ;
  208. exit ( 1 ) ;
  209. }
  210. nextArg = ++ argv ;
  211. -- argc ;
  212. }
  213. if ( -- argc != 8 )
  214. {
  215. Usage ( ) ;
  216. exit ( 1 ) ;
  217. }
  218. defaultSrc = * nextArg ;
  219. ++ nextArg ;
  220. defaultDst = * nextArg ;
  221. ++ nextArg ;
  222. defaultDst2 = * nextArg ;
  223. ++ nextArg ;
  224. if ( ( inputRaw = fopen ( * nextArg , "rt" ) ) == NULL )
  225. {
  226. fprintf ( stderr , "mkclnmkf: cannot open input file \"%s\"\n" ,
  227. * nextArg ) ;
  228. exit ( 1 ) ;
  229. }
  230. ++ nextArg ;
  231. if ( ( inputCln = fopen ( * nextArg , "rt" ) ) == NULL )
  232. {
  233. fprintf ( stderr , "mkclnmkf: cannot open input file \"%s\"\n" ,
  234. * nextArg ) ;
  235. exit ( 1 ) ;
  236. }
  237. ++ nextArg ;
  238. if ( ( inputDir = fopen ( * nextArg , "rt" ) ) == NULL )
  239. {
  240. fprintf ( stderr , "mkclnmkf: cannot open input file \"%s\"\n" ,
  241. * nextArg ) ;
  242. exit ( 1 ) ;
  243. }
  244. ++ nextArg ;
  245. if ( ( output = fopen ( * nextArg , "rb" ) ) != NULL )
  246. {
  247. fprintf ( stderr , "mkclnmkf: first output file already exists: \"%s\"\n" ,
  248. * nextArg ) ;
  249. exit ( 1 ) ;
  250. }
  251. if ( ( output = fopen ( * nextArg , "wt" ) ) == NULL )
  252. {
  253. fprintf ( stderr , "mkclnmkf: cannot open first output file: \"%s\"\n" ,
  254. * nextArg ) ;
  255. exit ( 1 ) ;
  256. }
  257. ++ nextArg ;
  258. if ( ( output2 = fopen ( * nextArg , "rb" ) ) != NULL )
  259. {
  260. fprintf ( stderr , "mkclnmkf: second output file already exists: \"%s\"\n" ,
  261. * nextArg ) ;
  262. exit ( 1 ) ;
  263. }
  264. if ( ( output2 = fopen ( * nextArg , "wt" ) ) == NULL )
  265. {
  266. fprintf ( stderr , "mkclnmkf: cannot open second output file: \"%s\"\n" ,
  267. * nextArg ) ;
  268. exit ( 1 ) ;
  269. }
  270. ++ nextArg ;
  271. /*-
  272. * Read in the list of directories
  273. -*/
  274. {
  275. int numDirs = 0 ;
  276. int maxNumDirs = 0 ;
  277. char nextDir [ MAXARGLEN ] ;
  278. char * pDir ;
  279. pDir = fgetsNL ( nextDir , sizeof ( nextDir ) , inputDir ) ;
  280. while ( pDir )
  281. {
  282. if ( numDirs + 1 >= maxNumDirs )
  283. {
  284. maxNumDirs += 16 ;
  285. if ( ! ( DirList = ( char * * ) realloc ( DirList ,
  286. sizeof ( char * ) * maxNumDirs ) ) )
  287. {
  288. fprintf ( stderr ,
  289. "mkclnmkf: realloc failed (maxNumDirs=%d)\n" ,
  290. maxNumDirs ) ;
  291. exit ( 1 ) ;
  292. }
  293. }
  294. DirList [ numDirs ] = _strdup ( nextDir ) ;
  295. if ( ! DirList [ numDirs ] )
  296. {
  297. fprintf ( stderr ,
  298. "mkclnmkf: strdup failed (nextDir=\"%s\")\n" ,
  299. nextDir ) ;
  300. exit ( 1 ) ;
  301. }
  302. ++ numDirs ;
  303. pDir = fgetsNL ( nextDir , sizeof ( nextDir ) , inputDir ) ;
  304. }
  305. DirList [ numDirs ] = NULL ;
  306. {
  307. int i ;
  308. fprintf ( stderr , "Reading in directory list...\n" ) ;
  309. for ( i = 0 ; DirList [ i ] ; ++ i )
  310. Progress ( '(' , DirList [ i ] , ')' ) ;
  311. Progress ( '(' , NULL , ')' ) ;
  312. }
  313. }
  314. if ( fclose ( inputDir ) )
  315. {
  316. fprintf ( stderr ,
  317. "mkclnmkf: error closing input file \"%s\"\n" ,
  318. * nextArg ) ;
  319. }
  320. /*
  321. * Generate MAKEFILE header comment
  322. */
  323. time ( & timestamp ) ;
  324. localt = * localtime ( & timestamp ) ;
  325. fprintf ( output ,
  326. "########\n"
  327. "#\n"
  328. "# This is a program-generated Makefile, the purpose of which is to\n"
  329. "# copy Visual C++ v7.0 C Run-Time Library Source files from the raw\n"
  330. "# source tree to a directory structure suitable for end user usage\n"
  331. "# in debugging and modification. Not all of the VC++ 7.0 CRTL srcs\n"
  332. "# are provided to end users, but the ones that are 'cleansed' using\n"
  333. "# an automated process. Another makefile will copy these cleansed\n"
  334. "# files to their final directory lay-out.\n"
  335. "#\n"
  336. "# This Makefile was generated on\n"
  337. "#\t\t%.3s %2d %4d at %02d:%02d:%02d\n"
  338. "#\n"
  339. "# The program that generated this Makefile was compiled on\n"
  340. "#\t\t" __DATE__ " at " __TIME__ "\n"
  341. "\n"
  342. "!if \"$(SRC)\"==\"\"\n"
  343. "SRC=%s\n"
  344. "!endif\n"
  345. "\n"
  346. "!if \"$(DST)\"==\"\"\n"
  347. "DST=%s\n"
  348. "!endif\n"
  349. "\n"
  350. "all:\tdirs files\n"
  351. "\n"
  352. "files: \\\n" ,
  353. localt . tm_mon * 3 + "JanFebMarAprMayJunJulAugSepOctNovDec" ,
  354. localt . tm_mday , localt . tm_year + 1900 ,
  355. localt . tm_hour , localt . tm_min , localt . tm_sec ,
  356. defaultSrc , defaultDst ) ;
  357. fprintf ( output2 ,
  358. "########\n"
  359. "#\n"
  360. "# This is a program-generated Makefile, the purpose of which is to\n"
  361. "# copy the cleansed Visual C++ v7.0 C Run-Time Library Source files\n"
  362. "# to their directory lay-out which will be received by end users.\n"
  363. "#\n"
  364. "# This Makefile was generated on\n"
  365. "#\t\t%.3s %2d %4d at %02d:%02d:%02d\n"
  366. "#\n"
  367. "# The program that generated this Makefile was compiled on\n"
  368. "#\t\t" __DATE__ " at " __TIME__ "\n"
  369. "\n"
  370. "!if \"$(SRC)\"==\"\"\n"
  371. "SRC=%s\n"
  372. "!endif\n"
  373. "\n"
  374. "!if \"$(DST)\"==\"\"\n"
  375. "DST=%s\n"
  376. "!endif\n"
  377. "\n"
  378. "all:\tdirs files\n"
  379. "\n"
  380. "dirs:\n"
  381. "\t" AT "if not exist %s" CPUDIR "\\NUL mkdire %s" CPUDIR "\n"
  382. #if defined(_BUILD_IA64)
  383. "\t" AT "if not exist %s" INTEL_DIR "\\NUL mkdire %s" INTEL_DIR "\n"
  384. #endif
  385. "\t" AT "if not exist %ssys\\NUL mkdire %ssys\n"
  386. "\t" AT "if not exist %sbuild\\NUL mkdire %sbuild\n"
  387. "\t" AT "if not exist %sbuild\\" CPUDIR "\\NUL mkdire %sbuild\\" CPUDIR "\n"
  388. "\t" AT "if not exist %sbuild\\" CPUDIR "\\bbt\\NUL mkdire %sbuild\\" CPUDIR "\\bbt\n"
  389. "\n"
  390. "files: \\\n"
  391. "\t%s%s \\\n"
  392. "\t%s%s \\\n"
  393. "\t%s%s \\\n"
  394. "\t%smsvcrt40.rc \\\n"
  395. "\t%smakefile \\\n"
  396. "\t%smakefile.inc \\\n"
  397. "\t%smakefile.sub \\\n" ,
  398. localt . tm_mon * 3 + "JanFebMarAprMayJunJulAugSepOctNovDec" ,
  399. localt . tm_mday , localt . tm_year + 1900 ,
  400. localt . tm_hour , localt . tm_min , localt . tm_sec ,
  401. defaultDst , defaultDst2 ,
  402. /* if not exist ... CPUDIR */
  403. prefixDst , prefixDst ,
  404. #if defined(_BUILD_IA64)
  405. /* if not exist intel */
  406. prefixDst , prefixDst ,
  407. #endif
  408. /* if not exist sys */
  409. prefixDst , prefixDst ,
  410. /* if not exist build ... */
  411. prefixDst , prefixDst ,
  412. prefixDst , prefixDst ,
  413. prefixDst , prefixDst ,
  414. /* RC files... */
  415. prefixDst , szRcFiles [ fSysCrt ] [ fCrt64 ] [ 0 ] ,
  416. prefixDst , szRcFiles [ fSysCrt ] [ fCrt64 ] [ 1 ] ,
  417. prefixDst , szRcFiles [ fSysCrt ] [ fCrt64 ] [ 2 ] ,
  418. prefixDst ,
  419. /* makefile.{,inc,sub} */
  420. prefixDst , prefixDst , prefixDst ) ;
  421. /*
  422. * Generate default ("all") dependecy
  423. */
  424. /*-
  425. * First, files that are just copied
  426. -*/
  427. rvRaw = fgetsNL ( lineRaw , sizeof ( lineRaw ) , inputRaw ) ;
  428. while ( rvRaw )
  429. {
  430. lineSkip = lineRaw ;
  431. #ifndef KEEPDIRS
  432. if ( ! strncmp ( "crtw32\\" , lineSkip , 7 ) )
  433. lineSkip += 7 ;
  434. else if ( ! strncmp ( "fpw32\\" , lineSkip , 6 ) )
  435. lineSkip += 6 ;
  436. #endif /* KEEPDIRS */
  437. fprintf ( output , "\t%s%s \\\n" ,
  438. prefixDst , lineSkip ) ;
  439. if ( ! memcmp ( lineSkip , "stdcpp\\" , 7 )
  440. || ! memcmp ( lineSkip , "stdhpp\\" , 7 ) )
  441. {
  442. /*
  443. * Files in the stdcpp / stdhpp directories are
  444. * special cases -- they are not cleansed but are
  445. * copied to the crt/src/ directory.
  446. */
  447. fprintf ( output2 , "\t%s%s \\\n" ,
  448. prefixDst , lineSkip + 7 ) ;
  449. }
  450. if ( ! memcmp ( lineSkip , "stdcpp64\\" , 9 )
  451. || ! memcmp ( lineSkip , "stdhpp64\\" , 9 ) )
  452. {
  453. /* same goes for stdcpp64 / stdhpp64 */
  454. fprintf ( output2 , "\t%s%s \\\n" ,
  455. prefixDst , lineSkip + 9 ) ;
  456. }
  457. rvRaw = fgetsNL ( lineRaw , sizeof ( lineRaw ) , inputRaw ) ;
  458. }
  459. /*-
  460. * Second, files that have be cleansed
  461. -*/
  462. rvCln = fgetsNL ( lineCln , sizeof ( lineCln ) , inputCln ) ;
  463. while ( rvCln )
  464. {
  465. lineSkip = lineCln ;
  466. #ifndef KEEPDIRS
  467. if ( ! strncmp ( "crtw32\\" , lineSkip , 7 ) )
  468. lineSkip += 7 ;
  469. else if ( ! strncmp ( "fpw32\\" , lineSkip , 6 ) )
  470. lineSkip += 6 ;
  471. #endif /* KEEPDIRS */
  472. fprintf ( output , "\t%s%s \\\n" ,
  473. prefixDst , lineSkip ) ;
  474. fprintf ( output2 , "\t%s%s \\\n" ,
  475. prefixDst , SkipFirstDir ( lineSkip ) ) ;
  476. rvCln = fgetsNL ( lineCln , sizeof ( lineCln ) , inputCln ) ;
  477. }
  478. fprintf ( output ,
  479. "\n\n# Directory Dependencies:\n\ndirs:\n"
  480. "\t" AT "if not exist %sbuild\\NUL mkdire %sbuild\n" ,
  481. prefixDst , prefixDst ) ;
  482. #ifdef BLDROOTDIR
  483. /*
  484. * Create Root Directory Component by Component
  485. * NOTE: this code assumes prefixDst resembles:
  486. * \msdev\crt\src\
  487. */
  488. {
  489. char temp [ MAXARGLEN ] ;
  490. char * prefixSlash ;
  491. char * prefixNext ;
  492. int len ;
  493. strcpy ( temp , prefixDst ) ;
  494. len = strlen ( temp ) ;
  495. if ( temp [ len - 1 ] == '\\' )
  496. temp [ len - 1 ] = '\0' ;
  497. prefixNext = prefixDst + 1 ;
  498. while ( prefixSlash = strchr ( prefixNext , '\\' ) )
  499. {
  500. temp [ prefixSlash - prefixDst ] = '\0' ;
  501. fprintf ( output ,
  502. "\t" AT "if not exist %s\\NUL mkdire %s\n" ,
  503. temp , temp ) ;
  504. prefixNext = prefixSlash + 1 ;
  505. temp [ prefixSlash - prefixDst ] = '\\' ;
  506. }
  507. }
  508. #endif /* BLDROOTDIR */
  509. /*
  510. * Create Directories
  511. */
  512. for ( pDirs = DirList ; * pDirs ; ++ pDirs )
  513. {
  514. char * targetDir ;
  515. targetDir = * pDirs ;
  516. #ifndef KEEPDIRS
  517. if ( ! strcmp ( "crtw32" , targetDir )
  518. || ! strcmp ( "fpw32" , targetDir ) )
  519. continue ;
  520. if ( ! strncmp ( "crtw32\\" , targetDir , 7 ) )
  521. targetDir += 7 ;
  522. else if ( ! strncmp ( "fpw32\\" , targetDir , 6 ) )
  523. targetDir += 6 ;
  524. #endif /* KEEPDIRS */
  525. fprintf ( output ,
  526. "\t" AT "if not exist %s%s\\NUL mkdire %s%s\n" ,
  527. prefixDst , targetDir ,
  528. prefixDst , targetDir ,
  529. prefixDst , targetDir ) ;
  530. }
  531. fprintf ( output , "\n\n#\n# Individual Dependencies:\n#\n\n" ) ;
  532. /*
  533. * Second output makefile has some special targets
  534. */
  535. fprintf ( output2 , "\n\n#\n# Individual Dependencies:\n#\n\n" ) ;
  536. {
  537. static char * listMkf [ ] =
  538. {
  539. "makefile" , "makefile.inc" , "makefile.sub" , NULL
  540. } ;
  541. static const char * listSpc [ ] =
  542. {
  543. "msvcirt.rc" , "msvcprt.rc" , "msvcrt.rc" ,
  544. "msvcrt40.rc" , NULL
  545. } ;
  546. int i ;
  547. listSpc [ 0 ] = szRcFiles [ fSysCrt ] [ fCrt64 ] [ 0 ] ;
  548. listSpc [ 1 ] = szRcFiles [ fSysCrt ] [ fCrt64 ] [ 1 ] ;
  549. listSpc [ 2 ] = szRcFiles [ fSysCrt ] [ fCrt64 ] [ 2 ] ;
  550. for ( i = 0 ; listSpc [ i ] ; ++ i )
  551. fprintf ( output2 ,
  552. "%s%s: %slibw32\\%s\n"
  553. "\t" AT "echo Copying %s from %s to %s.\n"
  554. "\t" AT "if exist %s%s attrib -r %s%s\n"
  555. "\t" AT "copy /b $** $@ >NUL\n"
  556. "\t" AT "attrib +r %s%s\n"
  557. "\n" ,
  558. /* %s%s: %slibw32\\%s */
  559. prefixDst , listSpc [ i ] ,
  560. prefixSrc , listSpc [ i ] ,
  561. /* echo Copying %s from %s to %s. */
  562. listSpc [ i ] , prefixSrc , prefixDst ,
  563. /* if exist %s%s attrib -r %s%s */
  564. prefixDst , listSpc [ i ] ,
  565. prefixDst , listSpc [ i ] ,
  566. /* copy /b $** $@ >NUL */
  567. /* attrib +r %s%s */
  568. prefixDst , listSpc [ i ] ) ;
  569. for ( i = 0 ; listMkf [ i ] ; ++ i )
  570. fprintf ( output2 ,
  571. "%s%s: %s%s relmkf.sed\n"
  572. "\t" AT "echo Copying %s from %s to %s. (using SED)\n"
  573. "\t" AT "if exist %s%s attrib -r %s%s\n"
  574. "\t" AT "sed -f relmkf.sed %s%s > $@\n"
  575. "\t" AT "attrib +r %s%s\n"
  576. "\n" ,
  577. /* %s%s: %slibw32\\%s */
  578. prefixDst , listMkf [ i ] ,
  579. prefixSrc , listMkf [ i ] ,
  580. /* echo Copying %s from %s to %s. */
  581. listMkf [ i ] , prefixSrc , prefixDst ,
  582. /* if exist %s%s attrib -r %s%s */
  583. prefixDst , listMkf [ i ] ,
  584. prefixDst , listMkf [ i ] ,
  585. /* sed -f relmkf.sed %s%s > $@ */
  586. prefixSrc , listMkf [ i ] ,
  587. /* attrib +r %s%s */
  588. prefixDst , listMkf [ i ] ) ;
  589. }
  590. /*
  591. * Reset input files for another pass: individual dependencies
  592. */
  593. if ( fseek ( inputRaw , 0L , SEEK_SET )
  594. || fseek ( inputCln , 0L , SEEK_SET ) )
  595. {
  596. fprintf ( stderr , "mkclnmkf: cannot reset input file(s)\n" ) ;
  597. exit ( 1 ) ;
  598. }
  599. /*
  600. * Generate individual dependecies for files that are copied as-is
  601. */
  602. fprintf ( stderr , "Producing copied file dependencies...\n" ) ;
  603. fprintf ( output , "# Copied File Dependencies:\n\n" ) ;
  604. rvRaw = fgetsNL ( lineRaw , sizeof ( lineRaw ) , inputRaw ) ;
  605. while ( rvRaw )
  606. {
  607. lineSkip = lineRaw ;
  608. #ifndef KEEPDIRS
  609. /*
  610. * strip crtw32\ and fpw32\ from the input string
  611. */
  612. if ( ! strncmp ( "crtw32\\" , lineSkip , 7 ) )
  613. lineSkip += 7 ;
  614. else if ( ! strncmp ( "fpw32\\" , lineSkip , 6 ) )
  615. lineSkip += 6 ;
  616. if ( ( lineRaw [ 0 ] != 'f'
  617. || strcmp ( lineSkip + strlen ( lineSkip ) - 9 , "\\lsources" ) )
  618. && strcmp ( "makefile" , lineRaw ) )
  619. #endif /* KEEPDIRS */
  620. fprintf ( output , fmtRaw ,
  621. /* %s%s: %s%s */
  622. prefixDst , lineSkip , prefixSrc , lineRaw ,
  623. /* echo Copying %s from %s to %s */
  624. lineSkip , prefixSrc , prefixDst ,
  625. /* if exist %s%s attrib -r %s%s */
  626. prefixDst , lineSkip , prefixDst , lineSkip ,
  627. /* copy /b %s%s %s%s */
  628. prefixSrc , lineRaw , prefixDst , lineSkip ,
  629. /* attrib +r %s%s */
  630. prefixDst , lineSkip ) ;
  631. #ifndef KEEPDIRS
  632. else
  633. fprintf ( output , fmtRaw2 ,
  634. /* %s%s: %s%s %ssrcrel\\bldmkf.sed */
  635. prefixDst , lineSkip ,
  636. prefixSrc , lineRaw , prefixSrc ,
  637. /* echo Copying %s from %s to %s */
  638. lineSkip , prefixSrc , prefixDst ,
  639. /* if exist %s%s attrib -r %s%s */
  640. prefixDst , lineSkip , prefixDst , lineSkip ,
  641. /* sed -f %ssrcrel\\bldmkf.sed %s%s > %s%s */
  642. prefixSrc ,
  643. prefixSrc , lineRaw , prefixDst , lineSkip ,
  644. /* attrib +r %s%s */
  645. prefixDst , lineSkip ) ;
  646. #endif /* KEEPDIRS */
  647. if ( ! memcmp ( lineSkip , "stdcpp\\" , 7 )
  648. || ! memcmp ( lineSkip , "stdhpp\\" , 7 ) )
  649. {
  650. /*
  651. * Files in the stdcpp / stdhpp directories are
  652. * special cases -- they are not cleansed but are
  653. * copied to the crt/src/ directory.
  654. */
  655. fprintf ( output2 , "%s%s: %s%s\n"
  656. "\t" AT "echo Copying %s from %s to %s.\n"
  657. "\t" AT "if exist %s%s attrib -r %s%s\n"
  658. "\t" AT "copy /b %s%s %s%s\n"
  659. "\t" AT "attrib +r %s%s\n"
  660. "\n" ,
  661. prefixDst , lineSkip + 7 ,
  662. prefixSrc , lineSkip ,
  663. lineRaw , prefixSrc , prefixDst ,
  664. prefixDst , lineSkip + 7 ,
  665. prefixDst , lineSkip + 7 ,
  666. prefixSrc , lineSkip ,
  667. prefixDst , lineSkip + 7 ,
  668. prefixDst , lineSkip + 7 ) ;
  669. }
  670. if ( ! memcmp ( lineSkip , "stdcpp64\\" , 9 )
  671. || ! memcmp ( lineSkip , "stdhpp64\\" , 9 ) )
  672. {
  673. /* Same goes for stdcpp64 / stdhpp64 */
  674. fprintf ( output2 , "%s%s: %s%s\n"
  675. "\t" AT "echo Copying %s from %s to %s.\n"
  676. "\t" AT "if exist %s%s attrib -r %s%s\n"
  677. "\t" AT "copy /b %s%s %s%s\n"
  678. "\t" AT "attrib +r %s%s\n"
  679. "\n" ,
  680. prefixDst , lineSkip + 9 ,
  681. prefixSrc , lineSkip ,
  682. lineRaw , prefixSrc , prefixDst ,
  683. prefixDst , lineSkip + 9 ,
  684. prefixDst , lineSkip + 9 ,
  685. prefixSrc , lineSkip ,
  686. prefixDst , lineSkip + 9 ,
  687. prefixDst , lineSkip + 9 ) ;
  688. }
  689. Progress ( '[' , lineRaw , ']' ) ;
  690. rvRaw = fgetsNL ( lineRaw , sizeof ( lineRaw ) , inputRaw ) ;
  691. }
  692. Progress ( '[' , NULL , ']' ) ;
  693. /*
  694. * Generate individual dependecies for files that are cleansed
  695. */
  696. fprintf ( stderr , "Producing cleansed file dependencies...\n" ) ;
  697. fprintf ( output , "# Cleansed File Dependencies:\n\n" ) ;
  698. rvCln = fgetsNL ( lineCln , sizeof ( lineCln ) , inputCln ) ;
  699. while ( rvCln )
  700. {
  701. char * pExt ;
  702. char pNoExt [ MAXARGLEN ] ;
  703. lineSkip = lineCln ;
  704. #ifndef KEEPDIRS
  705. /*
  706. * strip crtw32\ and fpw32\ from the input string
  707. */
  708. if ( ! strncmp ( "crtw32\\" , lineSkip , 7 ) )
  709. lineSkip += 7 ;
  710. else if ( ! strncmp ( "fpw32\\" , lineSkip , 6 ) )
  711. lineSkip += 6 ;
  712. #endif /* KEEPDIRS */
  713. pExt = strrchr ( lineSkip , '.' ) ;
  714. if ( ! pExt )
  715. {
  716. fprintf ( stderr ,
  717. "Warning: filename has no extension: %s\n" ,
  718. lineCln ) ;
  719. pExt = lineSkip + strlen ( pExt ) ;
  720. }
  721. strcpy ( pNoExt , lineSkip ) ;
  722. pNoExt [ pExt - lineSkip ] = '\0' ;
  723. if ( !fNoClean )
  724. /*
  725. * .INC files do not get ifstripped - use fmtCln2 for them
  726. */
  727. fprintf ( output ,
  728. strcmp ( ".inc" , pExt ) ? fmtCln : fmtCln2 ,
  729. /* %s%s: %scrtw32\%s %ssrcrel\msvc40.if */
  730. prefixDst , lineSkip , prefixSrc , lineCln , prefixSrc ,
  731. /* echo Cleansing %scrtw32\%s */
  732. prefixDst , lineSkip ,
  733. /* if exist %s%s attrib -r %s%s */
  734. prefixDst , lineSkip , prefixDst , lineSkip ,
  735. /* detab < %scrtw32\%s | trailing > ... */
  736. prefixSrc , lineCln , prefixDst , lineSkip ,
  737. /* ifstrip %s\srcrel\msvc40.if %s%s */
  738. prefixSrc , prefixDst , lineSkip ,
  739. /* del %s%s */
  740. prefixDst , lineSkip ,
  741. /* ren %s%s.TMP *%s */
  742. prefixDst , pNoExt , pExt ,
  743. /* striphdr -r %s%s */
  744. prefixDst , lineSkip ,
  745. /* del %s%s */
  746. prefixDst , lineSkip ,
  747. /* ren %s%s.NEW *%s */
  748. prefixDst , pNoExt , pExt ,
  749. /* attrib +r %s%s */
  750. prefixDst , lineSkip ) ;
  751. else
  752. /*
  753. * -noclean: Just copy, don't cleanse, for development builds
  754. */
  755. fprintf ( output , fmtRaw ,
  756. /* %s%s: %s%s */
  757. prefixDst , lineSkip , prefixSrc , lineCln ,
  758. /* echo Copying %s from %s to %s */
  759. lineSkip , prefixSrc , prefixDst ,
  760. /* if exist %s%s attrib -r %s%s */
  761. prefixDst , lineSkip , prefixDst , lineSkip ,
  762. /* copy /b %s%s %s%s */
  763. prefixSrc , lineCln , prefixDst , lineSkip ,
  764. /* attrib +r %s%s */
  765. prefixDst , lineSkip ) ;
  766. /*
  767. * Secondary makefile
  768. */
  769. if ( memcmp ( "libw32" , lineCln , 6 ) )
  770. {
  771. char * lineSkipFirst = SkipFirstDir ( lineSkip ) ;
  772. if ( ! strcmp ( ".asm" , pExt ) &&
  773. ( ! memcmp ( "mbstring" , lineSkip , 8 )
  774. || ! strcmp ( "memmove.asm" , pExt - 7 )
  775. || ! strcmp ( "strcspn.asm" , pExt - 7 )
  776. || ! strcmp ( "strpbrk.asm" , pExt - 7 ) )
  777. || ! strcmp ( ".c" , pExt ) &&
  778. ( ! strcmp ( "mbscat.c" , pExt - 6 )
  779. || ! strcmp ( "mbsdup.c" , pExt - 6 ) ) )
  780. fprintf ( output2 ,
  781. "%s%s: %s%s asmfile.sed\n"
  782. "\t" AT "echo Copying %s from %s to %s. (using SED.EXE)\n"
  783. "\t" AT "if exist %s%s attrib -r %s%s\n"
  784. "\t" AT "sed -f asmfile.sed %s%s > $@\n"
  785. "\t" AT "attrib +r %s%s\n"
  786. "\n" ,
  787. /* %s%s: %s%s asmfile.sed */
  788. prefixDst , lineSkipFirst ,
  789. prefixSrc , lineSkip ,
  790. /* echo Copying %s from %s to %s... */
  791. lineSkip , prefixSrc , prefixDst ,
  792. /* if exist %s%s attrib -r %s%s */
  793. prefixDst , lineSkipFirst ,
  794. prefixDst , lineSkipFirst ,
  795. /* sed -f asmfile.sed %s%s > $@ */
  796. prefixSrc , lineSkip ,
  797. /* attrib +r %s%s */
  798. prefixDst , lineSkipFirst ) ;
  799. else
  800. fprintf ( output2 ,
  801. "%s%s: %s%s\n"
  802. "\t" AT "echo Copying %s from %s to %s.\n"
  803. "\t" AT "if exist %s%s attrib -r %s%s\n"
  804. "\t" AT "copy /b $** $@ >NUL\n"
  805. "\t" AT "attrib +r %s%s\n"
  806. "\n" ,
  807. /* %s%s: %s%s */
  808. prefixDst , lineSkipFirst ,
  809. prefixSrc , lineSkip ,
  810. /* Copying %s from %s to %s */
  811. lineSkip , prefixSrc , prefixDst ,
  812. /* if exist %s%s attrib -r %s%s */
  813. prefixDst , lineSkipFirst ,
  814. prefixDst , lineSkipFirst ,
  815. /* copy /b $** $@ >NUL */
  816. /* attrib +r %s%s */
  817. prefixDst , lineSkipFirst ) ;
  818. }
  819. /*
  820. * Show Progress
  821. */
  822. Progress ( '{' , lineSkip , '}' ) ;
  823. rvCln = fgetsNL ( lineCln , sizeof ( lineCln ) , inputCln ) ;
  824. }
  825. Progress ( '{' , NULL , '}' ) ;
  826. return 0 ;
  827. }
  828. /*
  829. * Usage - print message explaining the arguments to this program
  830. */
  831. void Usage ( void )
  832. {
  833. fprintf ( stderr ,
  834. "Usage: mkclnmkf [opts] prefIn prefOut prefOut2 fRaw fCln dirList mkfOut mkfOut2\n"
  835. "where\tprefIn is the input prefix (such as \"\\crt\")\n"
  836. "\tprefOut is the primary output prefix (such as \"\\msdev\\crt\\prebuild\")\n"
  837. "\tprefOut2 is the secondary output prefix (such as \"\\msdev\\crt\\src\")\n"
  838. "\tfRaw is a list of files to be copied as-is\n"
  839. "\tfCln is a list of files to be cleansed\n"
  840. "\tdirList is a list of the directories to be created\n"
  841. "\tmkfOut is the primary output makefile (it may not already exist)\n"
  842. "\tmkfOut2 is the secondary output makefile (it may not already exist)\n\n"
  843. "\tOptions:\n"
  844. "\t -sys\t\tuse system CRT filenames\n"
  845. "\t -64\t\tuse Win64 CRT filenames\n"
  846. "\t -noclean\tdon't cleanse source files\n"
  847. ) ;
  848. }
  849. /*
  850. * fgetsNL - same as fgets except final newline character is deleted
  851. * Upon EOF or error, make sure the buffer is set to the empty string.
  852. */
  853. char * fgetsNL ( char * lineBuf , int lineSize , FILE * fileInput )
  854. {
  855. char * retval = fgets ( lineBuf , lineSize , fileInput ) ;
  856. if ( retval )
  857. {
  858. size_t len = strlen ( lineBuf ) ;
  859. if ( len < 1 || lineBuf [ len - 1 ] != '\n' )
  860. {
  861. fprintf ( stderr , "mkclnmkf: malformed input line:\n\t%s\n" , lineBuf ) ;
  862. }
  863. else
  864. lineBuf [ len - 1 ] = '\0' ;
  865. }
  866. else
  867. lineBuf [ 0 ] = '\0' ;
  868. return retval ;
  869. }
  870. void Progress ( int prefix , char * string , int suffix )
  871. {
  872. static size_t prevlen = 0 ;
  873. static int counter = 0 ;
  874. if ( string == NULL )
  875. {
  876. fprintf ( stderr , "%*s\n" , prevlen + 3 , " " ) ;
  877. prevlen = 0 ;
  878. counter = 0 ;
  879. }
  880. else if ( ++ counter % 100 == 1 )
  881. {
  882. size_t length = strlen ( string ) ;
  883. fprintf ( stderr , "%c%s%c%*s\r" ,
  884. prefix , string , suffix ,
  885. prevlen > length ? prevlen - length : 1 ,
  886. " " ) ;
  887. prevlen = length ;
  888. }
  889. }
  890. char * SkipFirstDir ( char * string )
  891. {
  892. char * pFile = string ;
  893. while ( * pFile ++ != '\\' )
  894. if ( ! * pFile )
  895. {
  896. fprintf ( stderr ,
  897. "mkclnmkf: no \\ in \"%s\"\n" , string ) ;
  898. exit ( 1 ) ;
  899. }
  900. return pFile ;
  901. }