CL386.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:23k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.     Compile with Borland C/C++ v3.1
  3.         bcc -v- -ml cl386.c
  4.     or Compile with Watcom C/C++ v10.6
  5. wcl -y -ox -ml cl386.c
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <dos.h>
  11. #include <process.h>
  12. #ifdef __TURBOC__
  13.   #include <dir.h>
  14. //  extern unsigned _stklen = 16*1024;
  15. #else
  16.   #include <direct.h>
  17. #endif
  18. #define VERSION "4.1m"
  19. #define TO_CURR_DIR /* define, if you want put .ASM & .OBJ file to current dir */
  20. static char usage[] = /* Usage */ 
  21. "CL386 Version " VERSION " (c) Kirill Joss. Compile " __DATE__ "n"
  22. "Usage: CL386.EXE [options] filesn"
  23. "Options:                          @fname   specify response file   n"
  24. "/l[+|-]  dump listing file        /w-xxx   disable a warning       n"
  25. "/i[+|-]  dump preprocessed file   /Dxxx    define something        n"
  26. "/e[-|+]  dump errors to file      /Ennn    max number of errors    n"
  27. "/k[+|-]  keep generate files      /Ipath   specify include path    n"
  28. "/K[+|-]  keep response files      /Lpath   specify .LIB & .OBJ dir n"
  29. "/A[+|-]  disable extensions       /Cxxx    codegen parameters      n"
  30. "/v[+|-]  debug info               /Oxxx    optimzer parameters     n"
  31. "/m[+|-]  generate .MAP file       /Tp      use TLINK & PMODE       n"
  32. "/n[+|-]  no default .LIB & .OBJ   /Tl      use TLINK & PMODE(low)  n"
  33. "/a       generate .ASM file       /Tw      use WLINK & PMODE/W     n"
  34. "/c       generate .OBJ file       /Td      use WLINK & DOS/4GW     n"
  35. "/?,/h,/H this help                /Rname   specify .EXE namen";
  36. #define FALSE 0
  37. #define TRUE  1
  38. #define _ASM ".ASM"
  39. #define _OBJ ".OBJ"
  40. #define _LIB ".LIB"
  41. #define _LSA ".LSA"
  42. #define _CFG ".CFG"
  43. #define COMPILER     "CC386.EXE"   /* Name of compiler */
  44. #define COMPILER_RSP "CC386.$$$"   /* Response file   for compiler */
  45. #define COMPILER_OPT ""            /* Default options for compiler */
  46. #define ASSEMBLER     "TASM.EXE"   /* Name of assembler */
  47. #define ASSEMBLER_RSP "TASM.$$$"   /* Response file   for assembler */
  48. #define ASSEMBLER_OPT "/t/ml/m3"   /* Default options for assembler */
  49. #define TLINK "TLINK.EXE"
  50. #define WLINK "WLINK.EXE"
  51. #define LINKER_RSP  "LINK.$$$"
  52. #define DELETE_RSP  "DELETE.$$$"
  53. #define MAX_STR 256 /* Max len of string in .CFG file */
  54. /* For error() */
  55. #define ERR_NO        0  /* no error ! */
  56. #define ERR_FATAL   128  /* fatal error */
  57. #define ERR_RUNTIME 129  /* stdlib error - see 'errno' */
  58. // is param ?
  59. #define isparam(s) ( *(s) == '-' || *(s) == '/' || *(s) == '+' )
  60. // check for NOT NULL !!!
  61. #define chkNULL(exp, msg )  if ( !(exp) ) error( ERR_FATAL, msg )
  62. // empty string ?
  63. #define empty_string(s)  ( (s) == NULL || *(s) == '' )
  64. typedef struct _Item {
  65. struct _Item *next;
  66. int temp;
  67. char data[1];
  68. } Item;
  69. Item *ItemCreate( char *dat, int tmp );
  70. #define ItemDelete(item) free(item)
  71. char *FileDisk( Item *item );
  72. char *FilePath( Item *item );
  73. char *FileName( Item *item );
  74. char *FileExt ( Item *item );
  75. typedef struct _List {
  76. Item *head;
  77. Item *tail;
  78. unsigned count;
  79. } List;
  80. void ListAdd( List *list, char *data, int temp );
  81. void ListDelete( List *list );
  82. int  ListFind( List *list, char *data );
  83. void ListIter( List *list, void (*iter)( Item *) );
  84. #define FileAdd(list, file, temp) ListAdd((list),(file),(temp))
  85. #define ParamAdd(list, param) ListAdd((list),(param), FALSE);
  86. List f_cpp; // list of .CPP files
  87. List f_asm; // list of .ASM files
  88. List f_obj; // list of .OBJ files
  89. List f_lib; // list of .LIB files
  90. List l_inc;     // list of INCLUDE path
  91. List l_def;     // list of DEFINE var
  92. List l_cc386;   // list of CC386 options
  93. char _libpath[ _MAX_PATH ]; // Path of default LIB & OBJ
  94. char _exename[ _MAX_PATH ]; // Name of .EXE file
  95. int _compile  = TRUE;  // need compile
  96. int _assemble = TRUE;  // need assemble
  97. int _link     = TRUE;  // need link
  98. int _dump_cpp = FALSE; // dump preprocessed file
  99. int _dump_err =  TRUE; // dump error file
  100. int _dump_lst = FALSE; // dump listing file
  101. int _ansi     = FALSE; // ANSI
  102. int _map_file = FALSE; // map file
  103. int _nodef_lib= FALSE; // no default lib
  104. int _debug    = FALSE; // debug info
  105. int _keep_rsp = FALSE; // keep response files
  106. int _keep_gen = FALSE; // keep generate files
  107. int _output = 'p';     // Output format, same /Tx
  108. void help( void );
  109. void get_param( char *exe_name, char *env_var, int argc, char *argv[] );
  110.  int get_param_file( char *file );
  111. void get_param_str( char *str );
  112. void get_one_param( char *param );
  113. void get_option( char *param );
  114. void get_source( char *filename );
  115. void get_one_source( char *filename );
  116. void find_source( char *fpath, char *fname );
  117. void error( int exitcode, char *msg );
  118. void response( void );
  119. void compile( void );
  120. void assemble( void );
  121. void link( void );
  122. void remove_temp( void );
  123. void DeleteList( void );
  124. void DeleteAll( void ); /* for atexit() */
  125. void main( int argc, char *argv[] ) {
  126. if ( argc == 1 )
  127. help();
  128. get_param( argv[0], "CL386", argc - 1, argv + 1 );
  129. atexit( DeleteAll );
  130. if ( f_cpp.count == 0 && f_asm.count == 0 &&
  131.   f_obj.count == 0 && f_lib.count == 0 )
  132. help();
  133. if ( f_cpp.count == 0 ) _compile = FALSE;
  134. if ( f_asm.count == 0 ) _assemble = FALSE;
  135. if ( f_obj.count == 0 && f_lib.count == 0 ) _link = FALSE;
  136. response();
  137. DeleteList();
  138. compile();
  139. assemble();
  140. link();
  141. remove_temp();
  142. }
  143. void help( void ) {
  144. printf( usage ); exit( 0 );
  145. }
  146. void get_param( char *exe_name, char *env_var, int argc, char *argv[] ) {
  147. char file[ _MAX_PATH ], disk[ _MAX_DRIVE ],
  148. path[ _MAX_DIR ], name[ _MAX_FNAME ], ext [ _MAX_EXT ];
  149. char *env;
  150. int i;
  151. _splitpath( exe_name, disk, path, name, ext );
  152. _makepath( file, NULL, NULL, name, _CFG );
  153. if ( ! get_param_file( file ) ) {
  154. _makepath( file, disk, path, name, _CFG );
  155. get_param_file( file );
  156. }
  157. if ( (env = getenv( env_var ) ) != NULL )
  158. get_param_str( env );
  159. for ( i = 0; i < argc; i++ )
  160. get_one_param( argv[ i ] );
  161. }
  162. int get_param_file( char *file ) {
  163. static char s[ MAX_STR ];
  164. FILE *f = fopen( file, "rt" );
  165. if ( f == NULL )
  166. return FALSE;
  167. while( fgets( s, MAX_STR - 1, f) != NULL )
  168. get_param_str( s );
  169. fclose( f );
  170. return TRUE;
  171. }
  172. void get_param_str( char *s ) {
  173. char arg[ MAX_STR ];
  174. int  len;
  175. for ( len = 0; *s; s++ ) {
  176. if ( *s == ' ' || *s == 't' || *s == 'n' ) {
  177. if ( len > 0 ) {
  178. arg[ len ] = '';
  179. get_one_param( arg );
  180. }
  181. arg[ len = 0 ] = '';
  182. }
  183. else {
  184. arg[ len++ ] = *s;
  185. }
  186. }
  187.     if ( len > 0 ) {
  188.         arg[ len ] = '';
  189.         get_one_param( arg );
  190.     }
  191. }
  192. void get_one_param( char *arg ) {
  193.     if ( isparam( arg ) )                 // -X , +X or /X
  194.         get_option( arg );
  195.     else if ( *arg == '@' ) {               // @filename
  196.         if ( ! get_param_file( arg + 1 )  )
  197.             error( ERR_RUNTIME, arg + 1 );
  198.     }
  199.     else
  200.         get_source( arg );             // file.ext
  201. }
  202. void error( int exitcode, char *msg ) {
  203.     switch ( exitcode ) {
  204.         case ERR_NO: break;
  205.         case ERR_FATAL: fprintf( stderr, "Fatal : %sn", msg );
  206.             break;
  207.         case ERR_RUNTIME: fprintf( stderr, "%s : %s", msg, strerror( errno ) );
  208.             break;
  209.         default: fprintf( stderr, "Program error : %s !n", msg );
  210.             break;
  211.     }
  212.     exit( exitcode );
  213. }
  214. void get_option( char *param ) {
  215. switch( param[ 1 ] ) {
  216.         case 'i' : // dump preprocessed file
  217.             if ( param[2] == '-' ) {        // -i-
  218.                 _dump_cpp = FALSE; return;
  219.             }
  220.             else if ( param[2] == '+' || param[2] == '' ) { // -i or -i+ :)
  221.                 _dump_cpp = TRUE;  return;
  222.             }
  223.             break;
  224.         case 'e' : // dump errors to file
  225.             if ( param[2] == '-' ) {        // -e-
  226.                 _dump_err = FALSE; return;
  227.             }
  228.             else if ( param[2] == '+' || param[2] == '' ) { // -e or -e+ :)
  229.                 _dump_err = TRUE; return;
  230.             }
  231.             break;
  232.  case 'l' : // dump listing file
  233. if ( param[2] == '-' ) {            // -l-
  234.                 _dump_lst = FALSE; return;
  235.             }
  236.             else if ( param[2] == '+' || param[2] == '' ) { // -l or -l+ :)
  237.                 _dump_lst = TRUE; return;
  238.             }
  239.             break;
  240.         case 'A' : // disable extensions
  241.             if ( param[2] == '-' ) { // -A-
  242.                 _ansi = FALSE; return;
  243.             }
  244.             else if ( param[2] == '+' || param[2] == '' ) { // -A or -A+
  245.                 _ansi = TRUE; return;
  246.             }
  247.             break;
  248.         case 'm' : // gen map file
  249. if ( param[2] == '-' ) { // -m-
  250. _map_file = FALSE; return;
  251. }
  252.             else if ( param[2] == '+' || param[2] == '' ) { // -m or -m+
  253.                 _map_file = TRUE; return;
  254.             }
  255.             break;
  256.         case 'n' : // no default lib
  257.             if ( param[2] == '-' ) { // -n-
  258.                 _nodef_lib = FALSE; return;
  259.             }
  260.             else if ( param[2] == '+' || param[2] == '' ) { // -n or -n+
  261.                 _nodef_lib = TRUE; return;
  262.             }
  263.             break;
  264.         case 'v' : // debug info
  265.             if ( param[2] == '-' ) { // -v-
  266.                 _debug = FALSE; return;
  267. }
  268. else if ( param[2] == '+' || param[2] == '' ) { // -v or -v+
  269. _debug = TRUE; return;
  270.             }
  271.             break;
  272.         case 'K' : // keep response files
  273.             if ( param[2] == '-' ) { // -K-
  274.                 _keep_rsp = FALSE; return;
  275.             }
  276.             else if ( param[2] == '+' || param[2] == '' ) { // -K or -K+
  277.                 _keep_rsp = TRUE; return;
  278.             }
  279.             break;
  280.         case 'k' : // keep generate files
  281.             if ( param[2] == '-' ) { // -k-
  282.                 _keep_gen = FALSE; return;
  283.             }
  284.             else if ( param[2] == '+' || param[2] == '' ) { // -k or -k+
  285. _keep_gen = TRUE; return;
  286. }
  287. break;
  288.         case 'a' :
  289.             _compile = TRUE;
  290.             _assemble = _link = FALSE;
  291.             return;
  292.         case 'c' :
  293.             _compile = _assemble = TRUE;
  294.             _link = FALSE;
  295.             return;
  296.         case '?' :
  297.         case 'h' :
  298.         case 'H' :
  299.             help(); /* Not return ! */
  300.         case 'D' : // define
  301. ParamAdd( &l_def, param + 2 );
  302. return;
  303.         case 'I' : // include path
  304.             ParamAdd( &l_inc, param + 2 );
  305.             return;
  306.         case 'L' : // lib path
  307.             strupr( strncpy( _libpath, param + 2, _MAX_PATH ) );
  308. //            ParamAdd( &l_lib, param + 2 );
  309.             return;
  310.         case 'R' : // .EXE name
  311.             strupr( strncpy( _exename, param + 2, _MAX_PATH ) );
  312.             return;
  313.         case 'w' :
  314.         case 'C' :
  315.         case 'E' :
  316.         case 'O' :
  317. ParamAdd( &l_cc386, param );
  318. return;
  319.         case 'T' :
  320.             if ( param[3] == '' )
  321.                 if ( param[2] == 'p' || param[2] == 'l' || 
  322.                 param[2] == 'w' || param[2] == 'd' ) {
  323.                     _output = param[2]; return;
  324.                 }
  325.             break;
  326.     }
  327.     fprintf( stderr, "Warning! Parameter error : %sn", param );
  328. }
  329. Item *ItemCreate( char *dat, int tmp ) {
  330.     Item *item;
  331.     int len;
  332. if ( empty_string( dat ) )
  333. return NULL;
  334.     len = strlen( dat );
  335.     if ( (item = (Item *)malloc( sizeof( Item ) + len )) != NULL ) {
  336.         item->next = NULL;
  337.         item->temp = tmp;
  338.         strcpy( item->data, dat );
  339.     }
  340.     return item;
  341. }
  342. static char disk[ _MAX_DRIVE ];
  343. static char path[ _MAX_DIR   ];
  344. static char name[ _MAX_FNAME ];
  345. static char ext [ _MAX_EXT   ];
  346. char *FileDisk( Item *item ) {
  347. _splitpath( item->data, disk, path, name, ext );
  348.     return disk;
  349. }
  350. char *FilePath( Item *item ) {
  351.     _splitpath( item->data, disk, path, name, ext );
  352.     return path;
  353. }
  354. char *FileName( Item *item ) {
  355.     _splitpath( item->data, disk, path, name, ext );
  356.     return name;
  357. }
  358. char *FileExt ( Item *item ) {
  359. _splitpath( item->data, disk, path, name, ext );
  360. return ext;
  361. }
  362. void ListDelete( List *list ) {
  363. Item *p, *q;
  364. chkNULL( list, "Pointer is NULL !" );
  365. for( p = list->head; p; p = q ) {
  366. q = p->next;
  367. free(p);
  368. }
  369. list->head = list->tail = NULL;
  370. list->count = 0;
  371. }
  372. void ListAdd( List *list, char *file, int tmp ) {
  373. Item *item;
  374. chkNULL( list, "Pointer is NULL !" );
  375. item = ItemCreate( file, tmp );
  376. chkNULL( item, "Out of memory !" );
  377. if ( list->count == 0 )
  378. list->head = list->tail = item;
  379. else {
  380. (list->tail)->next = item;
  381. list->tail = item;
  382. }
  383. list->count++;
  384. }
  385. void ListIter( List *list, void (*iter)( Item *) ) {
  386. Item *p;
  387. chkNULL( list, "Pointer is NULL !" );
  388. if ( list->count && iter ) {
  389. for ( p = list->head; p; p = p->next )
  390. (*iter)(p);
  391. }
  392. }
  393. static char *need;
  394. static int found = 0;
  395. static void find( Item *item ) {
  396. if ( strcmp( item->data, need ) == 0 )
  397. found = 1;
  398. }
  399. int  ListFind( List *list, char *data ) {
  400. found = 0;
  401. need = data;
  402. ListIter( list, find );
  403. return found;
  404. }
  405. char findpath[ _MAX_PATH ];
  406. char findname[ _MAX_PATH ];
  407. void get_source( char *filename ) {
  408. _splitpath( filename, disk, path, name, ext );
  409. if ( strchr( filename, '?' ) || strchr( filename, '*' ) ) {  /* Check for '*' and '?' */
  410. _makepath( findpath, disk, path, NULL, NULL );
  411. _makepath( findname, NULL, NULL, name, ext );
  412. find_source( findpath, findname );
  413. }
  414. else
  415. get_one_source( filename );
  416. }
  417. #ifdef __TURBOC__
  418. void find_source( char *fpath, char *fname ) {
  419. int fpath_len = strlen( fpath );
  420. struct ffblk fb;
  421. if ( !findfirst( strcat( fpath, fname), &fb, FA_ARCH) )
  422. do {
  423. fpath[ fpath_len ] = '';
  424. get_one_source( strcat( fpath, fb.ff_name) );
  425. } while (! findnext(&fb) );
  426. }
  427. #else
  428. void find_source( char *fpath, char *fname ) {
  429. int fpath_len = strlen( fpath );
  430. struct find_t fb;
  431. if (!_dos_findfirst( strcat( fpath, fname), _A_NORMAL, &fb ) )
  432. do {
  433. fpath[ fpath_len ] = '';
  434. get_one_source( strcat( fpath, fb.name) );
  435. } while( ! _dos_findnext( &fb ) );
  436. }
  437. #endif
  438. void get_one_source( char *srcfile ) {
  439.     int temp = FALSE;
  440.     static char file[ _MAX_PATH ];
  441.     static char disk[ _MAX_DRIVE ];
  442.     static char path[ _MAX_DIR ];
  443.     static char name[ _MAX_FNAME ];
  444. static char ext [ _MAX_EXT ];
  445. strncpy( file, srcfile, _MAX_PATH );
  446.     _splitpath( strupr(file) , disk, path, name, ext );
  447. //  _makepath( file, disk, path, name, ext );
  448.     if ( strcmp( ext, _ASM ) != 0 && 
  449.          strcmp( ext, _OBJ ) != 0 && strcmp( ext, _LIB ) != 0 ) {
  450.         if ( ListFind( &f_cpp, file ) )
  451.             fprintf( stderr, "Warning! File already exist : %sn", file );
  452.         else
  453.             FileAdd( &f_cpp, file, temp++ );
  454. #ifdef TO_CURR_DIR
  455. _makepath( file, disk, NULL, name, strcpy( ext, _ASM ) );
  456. #else
  457.         _makepath( file, disk, path, name, strcpy( ext, _ASM ) );
  458. #endif
  459.     }
  460.     if ( strcmp( ext, _ASM ) == 0 ) {
  461. if ( ListFind( &f_asm, file ) )
  462. fprintf( stderr, "Warning! File already exist : %sn", file );
  463. else
  464.             FileAdd( &f_asm, file, temp++ );
  465.         _makepath( file, disk, path, name, strcpy( ext, _OBJ) );
  466.     }
  467.     if ( strcmp( ext, _OBJ ) == 0 ) {
  468.         if ( ListFind( &f_obj, file ) )
  469.             fprintf( stderr, "Warning! File already exist : %sn", file );
  470.         else
  471.             FileAdd( &f_obj, file, temp++ );
  472.     }
  473.     if ( strcmp( ext, _LIB ) == 0 ) {
  474.         if ( ListFind( &f_lib, file ) )
  475.             fprintf( stderr, "Warning! File already exist : %sn", file );
  476.         else
  477.             FileAdd( &f_lib, file, 0 );
  478.     }
  479. }
  480. void DeleteList( void ) {  // delete all list from memory
  481. ListDelete( &f_cpp );
  482. ListDelete( &f_asm );
  483. ListDelete( &f_obj );
  484. ListDelete( &f_lib );
  485. ListDelete( &l_def );
  486. ListDelete( &l_inc );
  487. //    ListDelete( &l_lib );
  488. ListDelete( &l_cc386 );
  489. }
  490. void DeleteAll( void ) {   // for atexit()
  491. DeleteList();
  492. if ( !_keep_rsp ) {
  493. remove( COMPILER_RSP );
  494. remove( ASSEMBLER_RSP );
  495. remove( LINKER_RSP );
  496. remove( DELETE_RSP );
  497. }
  498. }
  499. void exec( char *prg, char *rsp ) {
  500. static char *args[3];
  501. int err;
  502. args[0] = prg;
  503. args[1] = rsp;
  504. args[2] = NULL;
  505. err = spawnvp( P_WAIT, prg, args );
  506. if ( err <  0 )
  507. error( ERR_RUNTIME, prg );
  508. else if ( err > 0 )
  509. error( err, prg );
  510. }
  511. FILE *frsp;
  512. static void compile_def  ( Item *p ) { fprintf( frsp, " /D%s", p->data ); }
  513. static void compile_inc  ( Item *p ) { fprintf( frsp, "%s;", p->data ); }
  514. static void compile_opt  ( Item *p ) { fprintf( frsp, " %s", p->data ); }
  515. static void compile_files( Item *p ) { fprintf( frsp, "n%s", p->data ); }
  516. static void compile_rsp( char *file, char *def_opt ) {
  517. frsp = fopen( file, "wt" );
  518. if ( frsp == NULL )
  519. error( ERR_RUNTIME, file );
  520. fprintf( frsp, " %s", def_opt );
  521. ListIter( &l_cc386, compile_opt );
  522. fprintf( frsp, " %ci", ( _dump_cpp ? '+' : '-' ) );
  523. fprintf( frsp, " %ce", ( _dump_err ? '+' : '-' ) );
  524. fprintf( frsp, " %cl", ( _dump_lst ? '+' : '-' ) );
  525. fprintf( frsp, " %cA", (     _ansi ? '+' : '-' ) );
  526. ListIter( &l_def, compile_def );
  527. if ( l_inc.count > 0 ) {
  528. fprintf( frsp, " /I" );
  529. ListIter( &l_inc, compile_inc );
  530. }
  531. ListIter( &f_cpp, compile_files );
  532. fprintf( frsp, "n" );
  533. fclose( frsp );
  534. }
  535. void compile( void ) {
  536. if ( _compile /* && f_cpp.count > 0 */ )
  537. {
  538. // compile_rsp( COMPILER_RSP, COMPILER_OPT );
  539. exec( COMPILER, "/f" COMPILER_RSP );
  540. if ( !_keep_rsp )
  541. remove( COMPILER_RSP );
  542. // ListDelete( &f_cpp );
  543. // ListDelete( &l_cc386 );
  544. }
  545. }
  546. static void delete_temp( Item *p ) { if ( p->temp ) remove( p->data ); }
  547. static void assemble_def( Item *p ) { fprintf( frsp, " /d%s", p->data ); }
  548. static void assemble_inc( Item *p ) { fprintf( frsp, " /i%s", p->data ); }
  549. char *asm_opt;
  550. static void gen_for_asm( Item *p ) {
  551. fprintf( frsp, " %s", asm_opt );
  552. fprintf( frsp, " /z%c", ( _debug ? 'i' : 'n' ) );
  553. ListIter( &l_inc, assemble_inc );
  554. ListIter( &l_def, assemble_def );
  555. if ( _dump_lst )
  556. fprintf( frsp, " %s,%s%s%s.OBJ,%s%s%s.LSA;n", p->data,
  557. FileDisk(p), FilePath(p), FileName(p),
  558. FileDisk(p), FilePath(p), FileName(p) );
  559. else
  560. fprintf( frsp, " %s,%s%s%s.OBJ,NUL;n", p->data,
  561. FileDisk(p), FilePath(p), FileName(p) );
  562. }
  563. void assemble_rsp( char *file, char *def_opt ) {
  564. frsp = fopen( file, "wt" );
  565. if ( frsp == NULL )
  566. error( ERR_RUNTIME, file );
  567. asm_opt = def_opt;
  568. ListIter( &f_asm, gen_for_asm );
  569. fclose( frsp );
  570. }
  571. void assemble(void) {
  572. if ( _assemble /* && f_asm.count > 0 */ )
  573. {
  574. // assemble_rsp( ASSEMBLER_RSP, ASSEMBLER_OPT );
  575. exec( ASSEMBLER, "@" ASSEMBLER_RSP );
  576. if ( !_keep_rsp )
  577. remove( ASSEMBLER_RSP );
  578. // if ( !_keep_gen )
  579. // ListIter( &f_asm, delete_temp );
  580. // ListDelete( &f_asm );
  581. // ListDelete( &l_def );
  582. // ListDelete( &l_inc );
  583. }
  584. }
  585. char *first( void ) {
  586. if ( strlen( _exename ) > 0 )
  587. return _exename;
  588. else if ( f_obj.count > 0 )
  589. return FileName( f_obj.head );
  590. else if ( f_lib.count > 0 )
  591. return FileName( f_lib.head );
  592. else
  593. return NULL;
  594. }
  595. char *libpath( char *lib ) {
  596. static char library[ _MAX_PATH ];
  597. strcpy( library, _libpath );
  598. if ( library[ strlen( library) - 1 ] != '\' )
  599. strcat( library, "\" );
  600. return strcat( library, lib );
  601. }
  602. static void out_obj( Item *p ) { fprintf( frsp, " %s", p->data ); }
  603. void tlink_rsp( char *file ) {
  604. char *name = first();
  605. frsp = fopen( file, "wt" );
  606. if ( frsp == NULL )
  607. error( ERR_RUNTIME, file );
  608. fprintf( frsp, "/3/c/d" );
  609. if ( _map_file )
  610. fprintf( frsp, "/m/l/s" );
  611. else
  612. fprintf( frsp, "/x" );
  613. if ( _debug )
  614. fprintf( frsp, "/v" );
  615. if ( !_nodef_lib ) {
  616. if ( _output == 'p' )
  617. fprintf( frsp, " %s", 
  618. libpath( ( _debug ? "C0DOSD.OBJ" : "C0DOS.OBJ" ) )  );
  619. else
  620. fprintf( frsp, " %s", 
  621. libpath( ( _debug ? "C0DOSLD.OBJ" : "C0DOSL.OBJ" ) )  );
  622. }
  623. ListIter( &f_obj, out_obj );
  624. fprintf( frsp, ",%s,%s,", name, name );
  625. if ( !_nodef_lib )
  626. fprintf( frsp, " %s", libpath( "CLDOS.LIB" )  );
  627. ListIter( &f_lib, out_obj );
  628. fprintf( frsp, "n" );
  629. fclose( frsp );
  630. }
  631. void tlink(void) {
  632. // tlink_rsp( LINKER_RSP );
  633. exec( TLINK, "@" LINKER_RSP );
  634. }
  635. static void wout_obj( Item *p) { fprintf( frsp, "file %sn", p->data ); }
  636. static void wout_lib( Item *p) { fprintf( frsp, "library %sn", p->data ); }
  637. void wlink_rsp( char *file ) {
  638. char *name = first();
  639. frsp = fopen( file, "wt" );
  640. if ( frsp == NULL )
  641. error( ERR_RUNTIME, file );
  642. fprintf( frsp, "# Generate from CL386.EXEn" );
  643. fprintf( frsp, "format os2 len" );
  644. fprintf( frsp, "option nodn" );
  645. if ( _map_file )
  646. fprintf( frsp, "option mapn" );
  647. if ( _debug )
  648. fprintf( frsp, "option symfn" );
  649. if ( _output == 'w' )
  650. fprintf( frsp, "option osname='CC386+PMODE/W'n"
  651.    "option stub=%sn", libpath( "PMODEW.EXE" ) );
  652. else
  653. fprintf( frsp, "option osname='CC386+DOS/4GW'n"
  654.    "option stub=%sn", libpath( "D4GWSTUB.EXE" ) );
  655. fprintf( frsp, "name %sn", name );
  656. if ( !_nodef_lib )
  657. fprintf( frsp, "file %sn",
  658. libpath( ( _debug ? "C0DOSWD.OBJ" : "C0DOSW.OBJ" ) )  );
  659. ListIter( &f_obj, wout_obj );
  660. if ( !_nodef_lib )
  661. fprintf( frsp, "library %s", libpath( "CLDOS.LIB" )  );
  662. ListIter( &f_lib, wout_lib );
  663. fclose( frsp );
  664. }
  665. void wlink(void) {
  666. // wlink_rsp( LINKER_RSP );
  667. exec( WLINK, "@" LINKER_RSP );
  668. }
  669. void link(void) {
  670. if ( _link /* && ( f_obj.count > 0 || f_lib.count > 0 ) */ )
  671. {
  672. if ( _output == 'p' || _output == 'l' )
  673. tlink();
  674. else if ( _output == 'w' || _output == 'd' )
  675. wlink();
  676. else
  677. printf( "Unknow link!n" );
  678. if ( !_keep_rsp )
  679. remove( LINKER_RSP );
  680. // if ( !_keep_gen )
  681. // ListIter( &f_obj, delete_temp );
  682. // ListDelete( &f_obj );
  683. // ListDelete( &f_lib );
  684. }
  685. }
  686. static void delete_file(Item *p) {
  687. if (p->temp)
  688. fprintf( frsp, "%sn", p->data );
  689. }
  690. void delete_rsp( char *file ) {
  691. frsp = fopen( file, "wt" );
  692. if ( frsp == NULL )
  693. error( ERR_RUNTIME, file );
  694. ListIter( &f_asm, delete_file );
  695. ListIter( &f_obj, delete_file );
  696. fclose( frsp );
  697. }
  698. void response( void ) {
  699. if ( _compile && f_cpp.count > 0 ) {
  700. compile_rsp( COMPILER_RSP, COMPILER_OPT );
  701. }
  702. if ( _assemble && f_asm.count > 0 ) {
  703. assemble_rsp( ASSEMBLER_RSP, ASSEMBLER_OPT );
  704. }
  705. if ( _link && ( f_obj.count > 0 || f_lib.count > 0 ) ) {
  706. if ( _output == 'p' || _output == 'l' )
  707. tlink_rsp( LINKER_RSP );
  708. else if ( _output == 'w' || _output == 'd' )
  709. wlink_rsp( LINKER_RSP );
  710. }
  711. delete_rsp( DELETE_RSP );
  712. }
  713. void remove_temp( void ) {
  714. int len;
  715. char s[ _MAX_PATH ];
  716. if ( !_keep_gen ) {
  717. frsp = fopen( DELETE_RSP, "rt" );
  718. if ( frsp == NULL )
  719. error( ERR_RUNTIME, DELETE_RSP );
  720. while( fgets( s, _MAX_PATH, frsp ) != NULL ) {
  721. len = strlen( s );
  722. if ( len > 0 && s[ len - 1] == 'n' )
  723. s[ len - 1 ] = '';
  724. remove( s );
  725. }
  726. fclose( frsp );
  727. }
  728. if ( !_keep_rsp )
  729. remove( DELETE_RSP );
  730. }