home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / compile.cpp next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  24.1 KB  |  734 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW IDE                       |
  4. // |  File:        COMPILE.CPP                          |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Compile & Link stuff                 |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_errno
  16. #define uses_fcntl
  17. #define uses_io
  18. #define uses_malloc
  19. #define uses_process
  20. #define uses_stdio
  21. #define uses_string
  22.  
  23. #define uses_app
  24. #define uses_ht
  25. #define uses_icons
  26. #define uses_input
  27. #define uses_stddlg
  28. #define uses_system
  29. #define uses_table
  30. #define uses_time
  31. #define uses_txt
  32.  
  33. #include "PVUSES.H"
  34. #include "W.H"
  35. #include "TLOG.H"
  36. #include "TPROJECT.H"
  37.  
  38. #define _DECLARE_COMPILE_H
  39.   #include "COMPILE.H"
  40. #undef  _DECLARE_COMPILE_H
  41.  
  42.  
  43. /*
  44. DEFINES
  45. */
  46.   #define TRAP_FNAME      "PVTRAP.TMP"
  47.   #define ERR_FNAME       "PVERR.TMP"
  48.   #define OPT_FNAME       "PVOPT.TMP"
  49.  
  50.  
  51. /*
  52. MAKE STATUS
  53. */
  54.   static int make_counter = 0;
  55.   static char *make_title = "";
  56.   void start_of_make( char *_make_title )
  57.   {
  58.     if( make_counter++ ) return;
  59.     make_title = _make_title;
  60.     log->clear();
  61.     log->redraw();
  62.   }
  63.  
  64.   void make_status( char *current_file, char *target_file, char *status )
  65.   {
  66.     char *prj;
  67.     char fname1[_MAX_FNAME], ext1[_MAX_EXT];
  68.     char fname2[_MAX_FNAME], ext2[_MAX_EXT];
  69.     char fname3[_MAX_FNAME], ext3[_MAX_EXT];
  70.  
  71.     prj = "";
  72.     if( project != NULL ) prj = project->filename;
  73.     _splitpath( prj,          NULL, NULL, fname1, ext1 );
  74.     _splitpath( current_file, NULL, NULL, fname2, ext2 );
  75.     _splitpath( target_file,  NULL, NULL, fname3, ext3 );
  76.     _title( make_title );
  77.     _taleft();
  78.     _dialog_xy( desktop_xl - 44, 2 );
  79.     action( "Project:      %s%s\n\nCurrent file: %s%s\nTarget file:  %s%s\n\n%s",
  80.             fname1, ext1, fname2, ext2, fname3, ext3, status );
  81.   }
  82.  
  83.   void end_of_make( int show_log )
  84.   {
  85.     if( --make_counter ) return;
  86.     make_title = "";
  87.     done_action();
  88.     if( log->vcount && show_log ) log->show_first_error();
  89.     log->redraw();
  90.     idle( 0 );
  91.   }
  92.  
  93.  
  94. /*
  95. VALIDITY CHECKS
  96. */
  97.   static boolean check_system_time( char *filespec, uint date1, uint time1 )
  98.   {
  99.     time_t t;
  100.     struct tm tmbuf;
  101.     uint date0, time0;
  102.     unsigned long t0, t1;
  103.  
  104.     if( time_check!=cmCOM_TIMECHECK ) return 1;
  105.     t = time( NULL ); _localtime( &t, &tmbuf );
  106.     time0 = (tmbuf.tm_hour<<11)|(tmbuf.tm_min<<5)|(tmbuf.tm_sec/2);
  107.     date0 = ((tmbuf.tm_year-80)<<9)|((tmbuf.tm_mon+1)<<5)|(tmbuf.tm_mday);
  108.     t0 = (date0<<16)|time0;
  109.     t1 = (date1<<16)|time1;
  110.     if( t1>t0 )
  111.     {
  112.       char s[256];
  113.       strcpy( s, filespec );
  114.       min_path( s );
  115.       short_path( s, 30 );
  116.       _iwarning();
  117.       ok( "File %s has future time stamp (system time not valid, eh?)", s );
  118.       return 0;
  119.     }
  120.     return 1;
  121.   }
  122.  
  123.   boolean target_valid( char *target, char *source )
  124.   //returns 1 if target based on source is valid
  125.   {
  126.     uint date1, date2, time1, time2;
  127.     unsigned long t1, t2;
  128.  
  129.     if( !get_date_time( target, date1, time1 ) ) return 0;
  130.     if( file_size( target ) <= 0 ) return 0;
  131.     if( ( source == NULL ) || !get_date_time( source, date2, time2 ) ) return 1;
  132.     t1 = (date1<<16)|time1; t2 = (date2<<16)|time2;
  133.     if( !check_system_time( target, date1, time1 ) ||
  134.         !check_system_time( source, date2, time2 ) ) return 1;
  135.     return t1>=t2;
  136.   }
  137.  
  138.   boolean need_make( char *filename )
  139.   //check validity of an WATCOM OBJ file
  140.   {
  141.     FILE *f;
  142.     char path[_MAX_PATH], dfile[_MAX_PATH];
  143.     long ofs;
  144.     uint file_date, file_time, date, time, size;
  145.     char type, l;
  146.     char _class;
  147.     boolean result, ok;
  148.  
  149.     if( file_size( filename ) <= 0 ) return 1;
  150.     get_date_time( filename, file_date, file_time );
  151.     if( !check_system_time( filename, file_date, file_time ) ) return 0;
  152.     fexpand( strcpy( path, filename ) );
  153.     f = fopen( path, "rb" );
  154.     if( f == NULL ) return 1;
  155.     result = 0;
  156.     ok = 0;
  157.     while( !feof( f ) && !ferror( f ) )
  158.     {
  159.       type = 0; size = 0; _class = 0; type = 0;
  160.       fread( &type, 1, 1, f );
  161.       fread( &size, 2, 1, f );
  162.       if( size == 0 ) break;
  163.       ofs = ftell( f );
  164.       fread( &_class, 1, 1, f );
  165.       fread( &_class, 1, 1, f );
  166.       if( ( type == 0x88 ) && ( _class == 0xE9 ) )
  167.       {
  168.         ok = 1;
  169.         fseek( f, 4, SEEK_CUR );
  170.         fread( &l, 1, 1, f );
  171.         fread( dfile, l, 1, f );
  172.         dfile[l] = 0;
  173.         if( strstr( "\\WATCOM\\H\\", dfile )==NULL && get_date_time( dfile, date, time ) )
  174.         {
  175.           if( !check_system_time( dfile, date, time ) ) return 0;
  176.           if( ( file_date < date ) ||
  177.               ( ( file_date == date ) && ( file_time < time ) ) )
  178.           {
  179.             result = 1;
  180.             break;
  181.           }
  182.         }
  183.       }
  184.       else
  185.         if( ok ) break;
  186.       fseek( f, ofs + size, SEEK_SET );
  187.     }
  188.     fclose( f );
  189.     return result;
  190.   }
  191.  
  192.  
  193. /*
  194. SPAWNING
  195. */
  196.   static int redirect_handle( int base_handle, int to_handle )
  197.   //returns a duplicate of the base handle
  198.   {
  199.     int saved;
  200.  
  201.     saved = dup( base_handle );
  202.     dup2( to_handle, base_handle );
  203.     _dos_close( to_handle );
  204.     return saved;
  205.   }
  206.  
  207.   static void reset_handle( int saved_handle, int base_handle )
  208.   {
  209.     dup2( saved_handle, base_handle );
  210.     _dos_close( saved_handle );
  211.   }
  212.  
  213.   static char pv_mode;
  214.   static char pv_char_size;
  215.   void unhook_system( void )
  216.   {
  217.     pv_mode = scr_mode;
  218.     pv_char_size = scr_char_size;
  219. #ifndef NOMOUSE
  220.     hide_mouse();
  221. #endif
  222.     restore_dos_screen();
  223. #if !defined( NOICONS ) && !defined( HGR )
  224.     restore_graph_chars();
  225. #endif
  226.     unhook_drivers();
  227.   }
  228.  
  229.   void hook_system( void )
  230.   {
  231.     hook_drivers();
  232. #if !defined( NOICONS ) && !defined( HGR )
  233.     set_graph_chars();
  234. #endif
  235.     save_dos_screen();
  236.     set_video_mode( pv_mode, pv_char_size );
  237. #ifndef HGR
  238.     set_blink( 0 );
  239. #endif
  240. #ifndef NOMOUSE
  241.     show_mouse();
  242. #endif
  243.     application->redraw();
  244.   }
  245.  
  246.   int exec( uint flags, char *program, char *params, char *redirect, void *history_id )
  247.   //execute program w/ params, redirect output as described in flags
  248.   {
  249.     const static char *prms[] = { NULL, NULL, NULL };
  250.     FILE *f;
  251.     char parameters[_MAX_PATH];
  252.     char buffer[_MAX_PATH];
  253.     char *p;
  254.     int handle1, handle2, in_svd, out_svd, n;
  255.     boolean success, fsuccess, rsuccess;
  256.  
  257.     if( ( flags & teSAVE_CUR ) &&
  258.         ( current_editor != NULL ) &&
  259.         ( current_editor->booleans & ebMODIFIED ) ) message( (Titem *) current_editor->editor, cmSAVE );
  260.  
  261.     if( flags & teSAVE_ALL ) broadcast( cmSAVE_ALL );
  262.  
  263.     if( flags & tePROMPT )
  264.     {
  265.       show_cursor();
  266.       _help( htD_EXECUTE );
  267.       dialog( "Execute" );
  268.       _tselected(); _tacenter(); stext( "Program: %s", 43, program );
  269.       vspace();
  270.       _focused();
  271.       if( flags & teLONG_CMD )
  272.         memo( "|~File params", params, MAX_FILE_PARAMS, 40, 8 );
  273.       else
  274.       {
  275.         _history( history_id );
  276.         input( "|~Command line", params, 125, 25 );
  277.       }
  278.       boolean result = bkch();
  279.       hide_cursor();
  280.       if( !result ) return -1;
  281.     }
  282.  
  283.     if( ( flags & teLONG_CMD ) && ( strlen( params ) > 125 ) )
  284.     {
  285.       *parameters = '@';
  286.       f = fopen( tmp_fname( parameters + 1, OPT_FNAME ), "wt" );
  287.       if( f == NULL )
  288.       {
  289.         _terror();
  290.         ok( "Can't create command line parameters file \"%s\".", parameters+1 );
  291.         return -1;
  292.       }
  293.       fputs( params, f );
  294.       fclose( f );
  295.       if( ferror( f ) )
  296.       {
  297.         _terror();
  298.         ok( "Can't write command line parameters file \"%s\".", parameters+1 );
  299.         return -1;
  300.       }
  301.     }
  302.     else
  303.       if( strlen( params ) <= 125 )
  304.       {
  305.         strcpy( parameters, params );
  306.         for( p = parameters; *p != 0; p++ )
  307.           if( *p < ' ' ) *p = ' ';
  308.       }
  309.       else
  310.       {
  311.         _terror();
  312.         ok( "Command line for \"%s\" exceed 125 characters and file command line support is not enabled for this tool. If it can handle \"@file\" command line please check Options / Tools / Edit / Options / Enable long command line.", program );
  313.         return -1;
  314.       }
  315.  
  316.     if( !(flags&teDONT_SWAP) ) unhook_system();
  317.  
  318.     handle1 = 0;
  319.     rsuccess = 1;
  320.  
  321.     if( flags & teTRAP )
  322.     {
  323.       if( flags & teTRAP_OUTPUT )
  324.         rsuccess = !_dos_creat( tmp_fname( buffer, redirect   ), _A_NORMAL, &handle1 );
  325.       if( flags & teTRAP_ERRORS )
  326.         rsuccess = !_dos_creat( tmp_fname( buffer, TRAP_FNAME ), _A_NORMAL, &handle1 );
  327.       if( rsuccess ) out_svd = redirect_handle( 1, handle1 );
  328.     }
  329.  
  330.     success = 1;
  331.     if( rsuccess )
  332.     {
  333.       _heapmin();
  334.       prms[0] = program;
  335.       prms[1] = parameters;
  336.       n = spawnvp( P_WAIT, program, prms );
  337.       _heapgrow();
  338.       success = ( n != -1 ) || ( ( errno != ENOENT ) && ( errno != ENOMEM ) );
  339.       fsuccess = 1;
  340.       if( flags & teTRAP ) reset_handle( out_svd, 1 );
  341.     }
  342.  
  343.     if( success && rsuccess && ( flags & teTRAP_ERRORS ) )
  344.     {
  345.       _dos_open( tmp_fname( buffer, TRAP_FNAME ), O_RDONLY, &handle1 );
  346.       _dos_creat( tmp_fname( buffer, ERR_FNAME ), _A_NORMAL, &handle2 );
  347.       in_svd = redirect_handle( 0, handle1 );
  348.       out_svd = redirect_handle( 1, handle2 );
  349.       strcpy( parameters, startup_path );
  350.       strcat( parameters, redirect );
  351.       prms[0] = parameters;
  352.       prms[1] = NULL;
  353.       fsuccess = ( spawnv( P_WAIT, parameters, prms ) == 0 );
  354.       reset_handle( out_svd, 1 );
  355.       reset_handle( in_svd, 0 );
  356.     }
  357.  
  358.     if( !(flags&teDONT_SWAP) ) hook_system();
  359.  
  360.     if( rsuccess && success && fsuccess && ( flags & teTRAP_ERRORS ) )
  361.     {
  362.       log->logout( "Output from %s:", program );
  363.       log->load( buffer );
  364.     }
  365.  
  366.     if( !success )
  367.     {
  368.       _terror();
  369.       if( errno == ENOENT )
  370.         ok( "Program not found, \"%s\".", program );
  371.       else
  372.         ok( "Not enough memory to execute \"%s\".", program );
  373.     }
  374.  
  375.     if( !fsuccess )
  376.     {
  377.       _terror();
  378.       if( errno == ENOENT )
  379.         ok( "Filter not found, \"%s\".", redirect );
  380.       else
  381.         ok( "Not enough memory to execute filter \"%s\".", redirect );
  382.     }
  383.  
  384.     if( !rsuccess )
  385.     {
  386.       _terror();
  387.       ok( "Can't create temporary trap file \"%s\".", buffer );
  388.     }
  389.  
  390.     remove( tmp_fname( buffer, TRAP_FNAME ) );
  391.     remove( tmp_fname( buffer, ERR_FNAME  ) );
  392.     remove( tmp_fname( buffer, OPT_FNAME  ) );
  393.  
  394.     broadcast( cmSTAMP_CHECK );
  395.     idle( 0 );
  396.     return n;
  397.   }
  398.  
  399.  
  400. /*
  401. WATCOM COMPILERS/LINKER INTERFACE
  402. */
  403.   char *get_local_options( char *buffer, char *file )
  404.   {
  405.     Tproject_entry *pe;
  406.     uint i;
  407.  
  408.     if( project != NULL )
  409.     {
  410.       for( i = 0; i < project->vcount; i++ )
  411.       {
  412.         pe = (Tproject_entry *) project->getptr( i );
  413.         if( strcmp( file, pe->filename ) == 0 )
  414.         {
  415.           if( !(pe->options&peEXCLUSIVE) )
  416.           {
  417.             buffer = strchr( buffer, 0 );
  418.             *buffer++ = ' ';
  419.           }
  420.           strcpy( buffer, pe->command_line );
  421.           break;
  422.         }
  423.       }
  424.     }
  425.     return buffer;
  426.   }
  427.  
  428.   void watcom_command_line( char *result, char *file )
  429.   {
  430.     char *s, *d;
  431.     *result = 0;
  432.  
  433.     if( compiler_options.memory_model == mmSMALL     ) strcat( result, "-ms " );
  434.     if( compiler_options.memory_model == mmMEDIUM    ) strcat( result, "-mm " );
  435.     if( compiler_options.memory_model == mmCOMPACT   ) strcat( result, "-mc " );
  436.     if( compiler_options.memory_model == mmLARGE     ) strcat( result, "-ml " );
  437.     if( compiler_options.memory_model == mmFLAT_HUGE ) strcat( result, compiler_options.code_size==cs16BITS? "-mh " : "-mf " );
  438.  
  439.     if( compiler_options.code_size == cs16BITS )
  440.     {
  441.       if( compiler_options.cpu == cp8086  ) strcat( result, "-0" );
  442.       if( compiler_options.cpu == cp80186 ) strcat( result, "-1" );
  443.       if( compiler_options.cpu == cp80286 ) strcat( result, "-2" );
  444.     }
  445.     if( compiler_options.cpu == cp80386 ) strcat( result, "-3" );
  446.     if( compiler_options.cpu == cp80486 ) strcat( result, "-4" );
  447.     if( compiler_options.cpu == cp80586 ) strcat( result, "-5" );
  448.  
  449.     if( compiler_options.code_size == cs32BITS )
  450.     {
  451.       if( compiler_options.calling_conventions == ccSTACK    )
  452.         strcat( result, "s" );
  453.       if( compiler_options.calling_conventions == ccREGISTER )
  454.         strcat( result, "r" );
  455.     }
  456.  
  457.     if( compiler_options.optimizations & opMULTI_THREAD )
  458.       strcat( result, " -bm" );
  459.     if( compiler_options.optimizations & opDLL          )
  460.       strcat( result, " -bd" );
  461.     if( compiler_options.optimizations & opDEFAULT_WIN  )
  462.       strcat( result, " -bw" );
  463.  
  464.     strcat( result, " " );
  465.  
  466.     if( compiler_options.build_target )
  467.     {
  468.       strcat( result, "-bt=" );
  469.       strcat( result, build_target[compiler_options.build_target].key );
  470.       strcat( result, " " );
  471.     }
  472.  
  473.     if( compiler_options.options & opPRECOMPILE )
  474.     {
  475.       char fname[_MAX_FNAME];
  476.       _splitpath( file, NULL, NULL, fname, NULL );
  477.       if( *fname )
  478.       {
  479.         strcat( result, "-fh=" );
  480.         strcat( result, default_directories.objects );
  481.         strcat( result, fname );
  482.         strcat( result, ".PCH " );
  483.       }
  484.     }
  485.     if( compiler_options.options & opSIGNED_CHARS   ) strcat( result, "-j "  );
  486.     if( compiler_options.options & opENUMS_AS_INTS  ) strcat( result, "-ei " );
  487.     if( compiler_options.options & opUNIQUE         ) strcat( result, "-u "  );
  488.     if( compiler_options.options & opBASE_TYPES     ) strcat( result, "-zg " );
  489.     if( compiler_options.options & opCALLS2GROW     ) strcat( result, "-sg " );
  490.     if( compiler_options.options & opNULLVALID      ) strcat( result, "-z "  );
  491.     if( compiler_options.options & opOUTPUTDECL     ) strcat( result, "-v "  );
  492.     if( compiler_options.options & opINTARGS        ) strcat( result, "-ri " );
  493.     if( compiler_options.options & opLITERALSINCODE ) strcat( result, "-zc " );
  494.     if( compiler_options.options & opSEPARATESEG    ) strcat( result, "-zm " );
  495.     if( compiler_options.options & opSAVESEGS       ) strcat( result, "-r "  );
  496.     if( compiler_options.options & opSYNTAXONLY     ) strcat( result, "-zs " );
  497.     if( compiler_options.options & opTOUCHSTACK     ) strcat( result, "-st " );
  498.     if( compiler_options.far_data_threshold!=32767 )
  499.       sprintf( strchr( result, 0 ), "-zt%lu ", compiler_options.far_data_threshold );
  500.  
  501.     if( compiler_options.debug_options & doWARN_IS_ERR ) strcat( result, "-we " );
  502.     if( !(compiler_options.options & opDEBUG_INFO) || !(compiler_options.debug_options & doSTACK) ) strcat( result, "-s " );
  503.     if( compiler_options.options & opDEBUG_INFO )
  504.     {
  505.       if( compiler_options.stack_frames == sfALWAYS         ) strcat( result, "-of+ " );
  506.       if( compiler_options.debug_options & doOPTIMIZATIONS  ) strcat( result, "-od "  );
  507.       if( compiler_options.debug_options & doBROWSING       ) strcat( result, "-db "  );
  508.       if( compiler_options.debug_level == dlLINENUMS        ) strcat( result, "-d1 "  );
  509.       if( compiler_options.debug_level == dlFULL            ) strcat( result, "-d2 "  );
  510.       if( compiler_options.debug_level == dlUNREFERENCED    ) strcat( result, "-d3 "  );
  511.       if( compiler_options.debug_format == dfDWARF    ) strcat( result, "-hd " );
  512.       if( compiler_options.debug_format == dfCODEVIEW ) strcat( result, "-hc " );
  513.     }
  514.  
  515.     if( ( compiler_options.options & opOPTIMIZATIONS ) &&
  516.         ( ( ( compiler_options.options & opDEBUG_INFO ) == 0 ) ||
  517.           ( ( compiler_options.debug_options & doOPTIMIZATIONS ) == 0 ) ) )
  518.     {
  519.       strcat( result,  "-o" );
  520.       if( compiler_options.optimize_for == ofSPEED       ) strcat( result, "t" );
  521.       if( compiler_options.optimize_for == ofSIZE        ) strcat( result, "s" );
  522.       if( compiler_options.optimizations & opLOOP        ) strcat( result, "l" );
  523.       if( compiler_options.optimizations & opLOOPUNROLL  ) strcat( result, "l+");
  524.       if( compiler_options.optimizations & opREORDER     ) strcat( result, "r" );
  525.       if( compiler_options.optimizations & opCALLRET ==0 ) strcat( result, "c" );
  526.       if( compiler_options.optimizations & opRELAX       ) strcat( result, "a" );
  527.       if( compiler_options.optimizations & opNUMERICALLY ) strcat( result, "n" );
  528.       if( compiler_options.optimizations & opLOWMEM      ) strcat( result, "o" );
  529.       if( compiler_options.optimizations & opINLINE      ) strcat( result, "m" );
  530.       if( compiler_options.optimizations & opCONSISTENT  ) strcat( result, "p" );
  531.       if( compiler_options.optimizations & opINTRINSIC   ) strcat( result, "i" );
  532.       if( compiler_options.optimizations & opUSER        ) sprintf( strchr( result, 0 ), "e=%d ", compiler_options.inline_threshold );
  533.       strcat( result, " " );
  534.       if( compiler_options.optimizations & opPENTIUM     ) strcat( result, "-fp5 " );
  535.     }
  536.  
  537.     strcat( result, "-zp" );
  538.     if( compiler_options.alignment == alBYTE  ) strcat( result, "1 " );
  539.     if( compiler_options.alignment == alWORD  ) strcat( result, "2 " );
  540.     if( compiler_options.alignment == alDWORD ) strcat( result, "4 " );
  541.     if( compiler_options.alignment == alQWORD ) strcat( result, "8 " );
  542.  
  543.     if( compiler_options.ds_segment == dsFLOATS ) strcat( result, "-zdf " );
  544.     if( compiler_options.ds_segment == dsLOAD   ) strcat( result, "-zdl " );
  545.     if( compiler_options.ds_segment == dsPEGGED ) strcat( result, "-zdp " );
  546.  
  547.     if( compiler_options.fsgsss_segments & fsPEGGED    ) strcat( result, "-zfp " );
  548.     if( compiler_options.fsgsss_segments & gsPEGGED    ) strcat( result, "-zgp " );
  549.     if( compiler_options.fsgsss_segments & ssNEQDGROUP ) strcat( result, "-zu "  );
  550.  
  551.     if( compiler_options.fp_instructions == fpCALLS     ) strcat( result, "-fpc "   );
  552.     if( compiler_options.fp_instructions == fpEMULATION ) strcat( result, "-fpi "   );
  553.     if( compiler_options.fp_instructions == fpINLINE    ) strcat( result, "-fpi87 " );
  554.  
  555.     if( compiler_options.fp_portability == fp8087  ) strcat( result, "-fpr " );
  556.     if( compiler_options.fp_portability == fp80287 ) strcat( result, "-fp2 " );
  557.     if( compiler_options.fp_portability == fp80387 ) strcat( result, "-fp3 " );
  558.  
  559.     if( compiler_options.exception_handling )
  560.     {
  561.       if( compiler_options.destructions == xhDIRECTCALL  ) strcat( result, "-xst " );
  562.       if( compiler_options.destructions == xhTABLEDRIVEN ) strcat( result, "-xss " );
  563.     }
  564.     else
  565.       if( compiler_options.destructions == xhTABLEDRIVEN ) strcat( result, "-xds " );
  566.  
  567.     if( compiler_options.preprocess_options & pfENABLE )
  568.     {
  569.       boolean fl = 1;
  570.       if( compiler_options.preprocess_options & pfENCRYPT  ) fl=0, strcat( result, "-pe " );
  571.       if( compiler_options.preprocess_options & pfLINE     ) fl=0, strcat( result, "-pl " );
  572.       if( compiler_options.preprocess_options & pfPRESERVE ) fl=0, strcat( result, "-pc " );
  573.       if( compiler_options.preprocess_options & pfWRAP     ) fl=0, sprintf( strchr( result, 0 ), "-pw=%d ", compiler_options.preprocess_wrap );
  574.       if( fl ) strcat( result, "-p " );
  575.     }
  576.  
  577.     if( compiler_options.portability == poANSI   ) strcat( result, "-za " );
  578.   //if( compiler_options.portability == poWATCOM ) strcat( result, "-ze " );
  579.  
  580.     sprintf( strchr(result,0), "-w%d ", compiler_options.warn_level );
  581.     sprintf( strchr(result,0), "-e%d ", compiler_options.max_errors );
  582.  
  583.     if( *compiler_options.code_group_name   != '*' ) strcat( result, "-g= "  );
  584.     if( *compiler_options.code_class_name   != '*' ) strcat( result, "-nc= " );
  585.     if( *compiler_options.data_segment_name != '*' ) strcat( result, "-gd= " );
  586.     if( *compiler_options.module_name       != '*' ) strcat( result, "-gm= " );
  587.     if( *compiler_options.text_segment_name != '*' ) strcat( result, "-gt= " );
  588.  
  589.     if( *default_directories.objects )
  590.     {
  591.       strcat( result, "-fo=" );
  592.       strcat( result, default_directories.objects );
  593.     }
  594.     if( *default_directories.include )
  595.     {
  596.       strcat( result, " -i=" );
  597.       strcat( result, default_directories.include );
  598.     }
  599.     strcat( result, " " );
  600.  
  601.     for( d = s = compiler_options.defines; *s; s++ )
  602.     {
  603.       if( *s == ' ' )
  604.       {
  605.         *s = 0;
  606.         sprintf( strchr( result, 0 ), "-d%s ", d );
  607.         *s = ' ';
  608.         d = s + 1;
  609.       }
  610.     }
  611.     if( d < s ) sprintf( strchr( result, 0 ), "-d%s ", d );
  612.     strcat( result, " " );
  613.     strcat( result, compiler_options.other );
  614.     strcat( result, " " );
  615.     strcat( result, file );
  616.     get_local_options( result, file );
  617.   }
  618.  
  619.   void watcom_link_command_line( char *result )
  620.   {
  621.     sprintf( result,"%s\r\n%s%s%s\r\noption stack=%lu%s%s",
  622.       (compiler_options.options&opDEBUG_INFO)? "\r\ndebug all" : "",
  623.       linker_options.other_options,
  624.       linker_options.target_os? "\r\nsystem " : "",
  625.       target_os[linker_options.target_os].key,
  626.       linker_options.stack_size,
  627.       *default_directories.library? "\r\nlibpath " : "",
  628.       default_directories.library
  629.     );
  630.   }
  631.  
  632.   int exec_watcom( char *file )
  633.   {
  634.     char file_to_execute[_MAX_PATH];
  635.     char target[_MAX_PATH];
  636.     char ext[_MAX_EXT];
  637.     char *buffer, *filter;
  638.     int result;
  639.     buffer = (char *) MALLOC( MAX_FILE_PARAMS );
  640.     watcom_command_line( buffer, file );
  641.     _splitpath( file, NULL, NULL, NULL, ext );
  642.     strcpy( file_to_execute, "WCC" );
  643.     filter = "WCC2LOG";
  644.     if( stricmp( ext, ".CPP" ) == 0 )
  645.     {
  646.       strcpy( file_to_execute, "WPP" );
  647.       filter = "WPP2LOG";
  648.     }
  649.     if( compiler_options.code_size == cs32BITS )
  650.       strcat( file_to_execute, "386" );
  651.     make_status( file, obj_file( target, file ), "Executing Watcom C/C++ Compiler..." );
  652.     result = exec( teCOMPILER | teTRAP_ERRORS | teDONT_SWAP | teSAVE_ALL | teLONG_CMD,
  653.                    file_to_execute, buffer, filter );
  654.     FREE( buffer );
  655.     return result;
  656.   }
  657.  
  658.   int exec_linker( char *file )
  659.   {
  660.     uint i;
  661.     Tproject_entry *pe;
  662.     char *buffer;
  663.     char exe[_MAX_PATH];
  664.     int result;
  665.  
  666.     if( file != NULL )
  667.       exe_fname( exe, file );
  668.     else
  669.       exe_fname( exe, project->filename );
  670.     buffer = (char *) MALLOC( MAX_FILE_PARAMS );
  671.     watcom_link_command_line( buffer );
  672.     strcat( buffer, " name " ); strcat( buffer, exe );
  673.     strcat( buffer, " file " );
  674.     if( file != NULL )
  675.       strcat( buffer, file );
  676.     else
  677.     {
  678.       for( i = 0; i < project->vcount; i++ )
  679.       {
  680.         pe = (Tproject_entry *) project->getptr( i );
  681.         if( pe->options & peDONT_LINK ) continue;
  682.         obj_file( strchr( buffer, 0 ), pe->filename );
  683.         strcat( buffer, ", " );
  684.       }
  685.     }
  686.     make_status( "", exe, "Executing Watcom Linker..." );
  687.     result = exec( teCOMPILER|teTRAP_ERRORS|teDONT_SWAP|teLONG_CMD,
  688.                    "WLINK", buffer, "WLNK2LOG" );
  689.     FREE( buffer );
  690.     if( project!=NULL &&
  691.         memcmp(&project->prj_linker_options,&linker_options,sizeof(Tlinker_options))!=0 )
  692.     {
  693.       project->prj_linker_options = linker_options;
  694.       project->save_project();
  695.     }
  696.     return result;
  697.   }
  698.  
  699. boolean compile( void )
  700. //compile current file if not compiled
  701. {
  702.   char *fn;
  703.   char path[_MAX_PATH];
  704.  
  705.   if( current_editor == NULL ) return 1;
  706.   if( current_editor->booleans & ebMODIFIED )
  707.     message( (Titem *) current_editor->editor, cmSAVE );
  708.   fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name;
  709.   obj_file( path, fn );
  710.   if( need_make( path ) ) exec_watcom( fn );
  711.   return !need_make( path );
  712. }
  713.  
  714. boolean link( void )
  715. //link current file/project if not linked
  716. {
  717.   char *fn;
  718.   char p1[_MAX_PATH], p2[_MAX_PATH];
  719.   boolean result;
  720.  
  721.   if( project != NULL )
  722.     result = project->link( 0 );
  723.   else
  724.     if( current_editor != NULL )
  725.     {
  726.       fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name;
  727.       exe_file( p1, fn );
  728.       obj_file( p2, fn );
  729.       result = 1;
  730.       if( !target_valid( p1, p2 ) ) result = ( exec_linker( p2 ) == 0 );
  731.     }
  732.   return result;
  733. }
  734.