home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / options.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  45.6 KB  |  1,253 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW IDE                       |
  4. // |  File:        OPTIONS.CPP                          |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Options Manager implementation       |
  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_stdio
  16. #define uses_string
  17.  
  18. #define uses_app
  19. #define uses_check
  20. #define uses_combo
  21. #define uses_editor
  22. #define uses_hist
  23. #define uses_ht
  24. #define uses_icons
  25. #define uses_input
  26. #define uses_stddlg
  27. #define uses_system
  28. #define uses_table
  29. #define uses_txt
  30.  
  31. #include "PVUSES.H"
  32. #include "W.H"
  33. #include "TLOG.H"
  34. #include "TPROJECT.H"
  35. #include "COMPILE.H"
  36.  
  37. #define _DECLARE_OPTIONS_H
  38.   #include "OPTIONS.H"
  39. #undef  _DECLARE_OPTIONS_H
  40.  
  41.  
  42. /*
  43. STATIC DATA
  44. */
  45.   static char pvo_signature[] = "\r\nPower View IDE options file.\r\n\032";
  46.  
  47.  
  48. #pragma off( unreferenced )
  49.   static Tcombo_box *of_target, *of_calls, *of_cpu, *of_debug, *of_optimize;
  50.   static void options_fast_handler( Titem *p )
  51.   {
  52.     of_optimize->set_state( isDISABLED, (compiler_options.debug_options&doOPTIMIZATIONS) && of_debug->cursor() );
  53.     of_cpu->set_enable( 0, of_target->cursor()<7 );
  54.     of_cpu->set_enable( 1, of_target->cursor()<7 );
  55.     of_cpu->set_enable( 2, of_target->cursor()<7 );
  56.     of_calls->set_enable( 0, of_target->cursor()>6 );
  57.     if( !of_cpu  ->enabled(of_cpu  ->cursor()) ) of_cpu  ->set_data( 5 );
  58.     if( !of_calls->enabled(of_calls->cursor()) ) of_calls->set_data( 1 );
  59.   }
  60. #pragma on( unreferenced )
  61.  
  62. void options_fast( void )
  63. {
  64.   uint cpu=compiler_options.cpu-1,
  65.        calls=compiler_options.calling_conventions-1,
  66.        model=compiler_options.memory_model-1,
  67.        align=compiler_options.alignment-1,
  68.        optimize=(compiler_options.options&opOPTIMIZATIONS)? compiler_options.optimize_for : 0,
  69.        debug=(compiler_options.options&opDEBUG_INFO)? compiler_options.debug_level : 0,
  70.        fp=compiler_options.fp_instructions-1,
  71.        target=linker_options.target_os? linker_options.target_os-1 : 0;
  72.   _help( htD_FAST_OPTIONS );
  73.   dialog( "Fast compiler/linker options" ); hspacing( 4 );
  74.   handler( options_fast_handler );
  75.   of_target = combo_box( "|~Target ", target, 35 );
  76.   for( uint i=1; i<TO_COUNT; i++ )
  77.     of_target->add( target_os[i].title );
  78.   push();
  79.   _combo_lines( 6 );
  80.   of_cpu = combo_box( "C|~PU    ", cpu, 7 );
  81.     of_cpu->add( "8086" );
  82.     of_cpu->add( "80186" );
  83.     of_cpu->add( "80286" );
  84.     of_cpu->add( "80386" );
  85.     of_cpu->add( "80486" );
  86.     of_cpu->add( "Pentium" );
  87.   _combo_lines( 2 );
  88.   of_calls = combo_box( "|~Calls  ", calls, 7 );
  89.     of_calls->add( "Regs" );
  90.     of_calls->add( "Stack" );
  91.   _combo_lines( 5 );
  92.   Tcombo_box *of_model = combo_box( "|~Model  ", model, 7 );
  93.     of_model->add( "Small" );
  94.     of_model->add( "Medium" );
  95.     of_model->add( "Compact" );
  96.     of_model->add( "Large" );
  97.     of_model->add( "Flat" );
  98.   _combo_lines( 4 );
  99.   Tcombo_box *of_align = combo_box( "|~Align  ", align, 7 );
  100.     of_align->add( "Byte" );
  101.     of_align->add( "Word" );
  102.     of_align->add( "Dword" );
  103.     of_align->add( "Qword" );
  104.   nc();
  105.   _combo_lines( 4 );
  106.   of_optimize = combo_box( "|~Optimize", optimize, 10 );
  107.     of_optimize->add( "OFF" );
  108.     of_optimize->add( "Speed" );
  109.     of_optimize->add( "Size" );
  110.     of_optimize->add( "Speed/Size" );
  111.   _combo_lines( 3 );
  112.   of_debug = combo_box( "De|~bug   ", debug, 10 );
  113.     of_debug->add( "OFF" );
  114.     of_debug->add( "Lines" );
  115.     of_debug->add( "Full" );
  116.   _combo_lines( 3 );
  117.   Tcombo_box *of_float = combo_box( "|~FP      ", fp, 10 );
  118.     of_float->add( "Calls" );
  119.     of_float->add( "Emulation" );
  120.     of_float->add( "Inline" );
  121.   linput( "|~Stack   ", linker_options.stack_size, 1024, 0x10000000 );
  122.   pop(); hor(); hspacing( 2 );
  123.   _history( &compiler_options.defines );
  124.   input( "|~Defines", compiler_options.defines, 127, 34 );
  125.   nl();
  126.   cinput( "|~Warnings level", compiler_options.warn_level, 0,   4 );
  127.   hspaces( 4 );
  128.   cinput( "|~Errors limit",   compiler_options.max_errors, 1, 255 );
  129.   nl();
  130.   check( "Warnings a|~re errors",  compiler_options.debug_options, doWARN_IS_ERR );
  131.   check( "Precompiled |~headers", compiler_options.options, opPRECOMPILE );
  132.   options_fast_handler( NULL );
  133.   if( bkch() )
  134.   {
  135.     options_changed = 1;
  136.     compiler_options.code_size = target>6? cs32BITS : cs16BITS;
  137.     linker_options.target_os=++target,
  138.     compiler_options.cpu=++cpu,
  139.     compiler_options.calling_conventions=++calls,
  140.     compiler_options.memory_model=++model,
  141.     compiler_options.alignment=++align,
  142.     compiler_options.fp_instructions=++fp;
  143.     switch( compiler_options.memory_model )
  144.     {
  145.       case mmSMALL:
  146.       case mmMEDIUM:
  147.       case mmFLAT_HUGE:
  148.         compiler_options.ds_segment = dsPEGGED;
  149.         compiler_options.fsgsss_segments = 0;
  150.         break;
  151.       default:
  152.         compiler_options.ds_segment = dsFLOATS;
  153.         compiler_options.fsgsss_segments = ssNEQDGROUP;
  154.         break;
  155.     }
  156.     if( !of_optimize->state( isDISABLED ) )
  157.       if( optimize )
  158.       {
  159.         compiler_options.optimize_for=optimize,
  160.         compiler_options.options|=opOPTIMIZATIONS,
  161.         compiler_options.optimizations|=opLOOP|opREORDER|opCALLRET|opRELAX|opNUMERICALLY|opPENTIUM;
  162.         if( optimize==1 )
  163.           compiler_options.optimizations|=opINLINE|opINTRINSIC;
  164.         else
  165.           compiler_options.optimizations&=~(opINLINE|opINTRINSIC|opUSER);
  166.       }
  167.       else
  168.         compiler_options.options&=~opOPTIMIZATIONS;
  169.     if( debug )
  170.       compiler_options.debug_level=debug,
  171.       compiler_options.options|=opDEBUG_INFO;
  172.     else
  173.       compiler_options.options&=~opDEBUG_INFO;
  174.   }
  175. }
  176.  
  177.  
  178. /*
  179. COMPILER
  180. */
  181.     static Tradio *r16, *r32, *r086, *r186, *r286, *r386, *calls_stack, *calls_regs, *rm_flat;
  182.     static void occg_handler( Titem *p )
  183.     {
  184.       boolean m16 = ( p == r16 );
  185.       boolean m32 = ( p == r32 );
  186.       if( !m16 && !m32 ) return;
  187.       if( m16 )
  188.       {
  189.         calls_stack->press();
  190.         rm_flat->set_prompt( "|~Huge" );
  191.       }
  192.       else
  193.       {
  194.         if( r086->pressed() || r186->pressed() || r286->pressed() ) r386->press();
  195.         rm_flat->set_prompt( "|~Flat" );
  196.       }
  197.       r086->set_state( isDISABLED, m32 );
  198.       r186->set_state( isDISABLED, m32 );
  199.       r286->set_state( isDISABLED, m32 );
  200.       calls_regs->set_state( isDISABLED, m16 );
  201.     }
  202.  
  203.   void options_compiler_code_generation( void )
  204.   {
  205.     _help( htD_CODE_GENERATION );
  206.     dialog( "Code generation" ); handler( occg_handler );
  207.     hspacing( 1 );
  208.     frame( "Memory model" );
  209.                 radio( "|~Small",      compiler_options.memory_model, mmSMALL     );
  210.                 radio( "|~Medium",     compiler_options.memory_model, mmMEDIUM    );
  211.                 radio( "|~Compact   ", compiler_options.memory_model, mmCOMPACT   );
  212.                 radio( "|~Large",      compiler_options.memory_model, mmLARGE     );
  213.       rm_flat = radio( "|~Flat",       compiler_options.memory_model, mmFLAT_HUGE );
  214.     endfr();
  215.     nc();
  216.     frame( "CPU" );
  217.       r086 = radio( "8|~086",      compiler_options.cpu, cp8086  );
  218.       r186 = radio( "80|~186",     compiler_options.cpu, cp80186 );
  219.       r286 = radio( "80|~286",     compiler_options.cpu, cp80286 );
  220.       r386 = radio( "80|~386",     compiler_options.cpu, cp80386 );
  221.              radio( "80|~486",     compiler_options.cpu, cp80486 );
  222.              radio( "|~Pentium  ", compiler_options.cpu, cp80586 );
  223.     endfr();
  224.     nc();
  225.     frame( "Code size" );
  226.       r16 = radio( "1|~6 bit   ", compiler_options.code_size, cs16BITS );
  227.       r32 = radio( "32 b|~it", compiler_options.code_size, cs32BITS );
  228.     endfr();
  229.     frame( "Calls" );
  230.       calls_stack = radio( "S|~tack    ", compiler_options.calling_conventions, ccSTACK    );
  231.       calls_regs  = radio( "|~Registers",   compiler_options.calling_conventions, ccREGISTER );
  232.     endfr();
  233.     nl(); hor();
  234.     _history( &compiler_options.defines );
  235.     _focused(); input( "|~Defines", compiler_options.defines, 127, 34 );
  236.     nl();
  237.     linput( "F|~ar data", compiler_options.far_data_threshold, 0, 0xFFFFF );
  238.     input( "|~Other", compiler_options.other, 127, 17 );
  239.     occg_handler( ( compiler_options.code_size == cs16BITS )? r16 : r32 );
  240.     if( bkch() ) options_changed = 1;
  241.   }
  242.  
  243.   void options_compiler_advanced_code_generation( void )
  244.   {
  245.     _help( htD_ADV_CODE_GENERATION );
  246.     dialog( "Advanced code generation" );
  247.     frame( "Options" );
  248.       check( "|~Use precompiled heades",                            compiler_options.options, opPRECOMPILE     );
  249.       check( "C|~hange characters default to signed  ",             compiler_options.options, opSIGNED_CHARS   );
  250.       check( "Force all |~enums to be type int",                    compiler_options.options, opENUMS_AS_INTS  );
  251.       check( "|~All functions must have unique addresses",          compiler_options.options, opUNIQUE         );
  252.       check( "|~Generate function prototypes using base types",     compiler_options.options, opBASE_TYPES     );
  253.       check( "Generate |~calls to grow the stack",                  compiler_options.options, opCALLS2GROW     );
  254.       check( "|~NULL points to valid memory",                       compiler_options.options, opNULLVALID      );
  255.       check( "|~Output function declarations to .def",              compiler_options.options, opOUTPUTDECL     );
  256.       check( "|~Promote to int all function arguments and returns", compiler_options.options, opINTARGS        );
  257.       check( "Place |~literal strings in the code segment",         compiler_options.options, opLITERALSINCODE );
  258.       check( "Place each |~function in separate segment",           compiler_options.options, opSEPARATESEG    );
  259.       check( "|~Save/restore segment registers across calls",       compiler_options.options, opSAVESEGS       );
  260.       check( "S|~yntax check only - no .OBJ output",                compiler_options.options, opSYNTAXONLY     );
  261.       check( "|~Touch stack through SS first",                      compiler_options.options, opTOUCHSTACK     );
  262.     endfr();
  263.     if( bkch() ) options_changed = 1;
  264.   }
  265.  
  266.   void options_compiler_target( void )
  267.   {
  268.     _help( htD_COMPILER_TARGET );
  269.     dialog( "Build target" );
  270.  
  271.     _combo_lines( 7 );
  272.     _acenter();
  273.     Tcombo_box *bt = combo_box( "|~Target OS", compiler_options.build_target, 10 );
  274.     for( uint i=0; i<BT_COUNT; i++ )
  275.       bt->add( build_target[i].title );
  276.     check( "|~Multi thread environment",      compiler_options.optimizations, opMULTI_THREAD );
  277.     check( "|~Dynamic link library",          compiler_options.optimizations, opDLL          );
  278.     check( "Default |~windowing application", compiler_options.optimizations, opDEFAULT_WIN  );
  279.     if( bkch() ) options_changed = 1;
  280.   }
  281.  
  282. #define cmFASTEST_CODE  cmUSER00
  283. #define cmSMALLEST_CODE cmUSER01
  284.     static Tdialog *oco_dialog;
  285.     static Tcheck *oco_checks[12];
  286.     static Tradio *oco_radios[7];
  287.     static Tiinput *oco_input1;
  288.     static Tcheck *oco_control;
  289.     boolean options_compiler_optimizations_validator( uint command )
  290.     {
  291.       if( command == cmFASTEST_CODE )
  292.       {
  293.         oco_checks[ 0]->press( 1 );
  294.         oco_checks[ 2]->press( 1 );
  295.         oco_checks[ 3]->press( 1 );
  296.         oco_checks[ 4]->press( 1 );
  297.         oco_checks[ 5]->press( 1 );
  298.         oco_checks[ 7]->press( 1 );
  299.         oco_checks[ 8]->press( 0 );
  300.         oco_checks[ 9]->press( compiler_options.cpu == cp80586 );
  301.         oco_checks[10]->press( 1 );
  302.         oco_radios[ 3]->press( 1 );
  303.         oco_radios[ 4]->press( 1 );
  304.         return 0;
  305.       }
  306.       if( command == cmSMALLEST_CODE )
  307.       {
  308.         oco_checks[ 0]->press( 1 );
  309.         oco_checks[ 1]->press( 0 );
  310.         oco_checks[ 2]->press( 1 );
  311.         oco_checks[ 3]->press( 1 );
  312.         oco_checks[ 4]->press( 1 );
  313.         oco_checks[ 5]->press( 1 );
  314.         oco_checks[ 7]->press( 0 );
  315.         oco_checks[ 8]->press( 0 );
  316.         oco_checks[ 9]->press( compiler_options.cpu == cp80586 );
  317.         oco_checks[10]->press( 0 );
  318.         oco_checks[11]->press( 0 );
  319.         oco_radios[ 0]->press( 1 );
  320.         oco_radios[ 5]->press( 1 );
  321.         return 0;
  322.       }
  323.       return 1;
  324.     }
  325.  
  326.     static void oco_handler( Titem *p )
  327.     {
  328.       if( p==oco_control )
  329.       {
  330.         boolean fl = !oco_control->pressed();
  331.         for( int i=0; i<12; i++ )
  332.           oco_checks[i]->set_state( isDISABLED, fl );
  333.         for(     i=0; i<7; i++ )
  334.           oco_radios[i]->set_state( isDISABLED, fl );
  335.         oco_input1 ->set_state( isDISABLED, fl );
  336.         oco_dialog->cstate( cmFASTEST_CODE, !fl );
  337.         oco_dialog->cstate( cmSMALLEST_CODE, !fl );
  338.       }
  339.     }
  340.  
  341.   void options_compiler_optimizations( void )
  342.   {
  343.     if( (compiler_options.options&opDEBUG_INFO) && (compiler_options.debug_options&doOPTIMIZATIONS) )
  344.     {
  345.       _palert();
  346.       ok( "Optimizations are disabled.\n\nTo enable optimizations, uncheck <Disable optimizations> check box from Debugging Information dialog." );
  347.       return;
  348.     }
  349.     _help( htD_OPTIMIZATIONS );
  350.     oco_dialog = dialog( "Optimizations" );
  351.     validator( options_compiler_optimizations_validator );
  352.     handler( oco_handler );
  353.     hspacing( 1 );
  354.     frame( "Options" );
  355.       oco_checks[ 0] = check( "|~1 Loop optimizations",                         compiler_options.optimizations, opLOOP        );
  356.       oco_checks[ 1] = check( "|~2 Loop unrolling optimizations",               compiler_options.optimizations, opLOOPUNROLL  );
  357.       oco_checks[ 2] = check( "|~3 Reorder instructions for best pipeline",     compiler_options.optimizations, opREORDER     );
  358.       oco_checks[ 3] = check( "|~4 <Call followed by ret>=<jump> optimization", compiler_options.optimizations, opCALLRET     );
  359.       oco_checks[ 4] = check( "|~5 Relax aliasing constraints",                 compiler_options.optimizations, opRELAX       );
  360.       oco_checks[ 5] = check( "|~6 Numerically unstable optimizations",         compiler_options.optimizations, opNUMERICALLY );
  361.       oco_checks[ 6] = check( "|~7 Continue compilation if low on memory",      compiler_options.optimizations, opLOWMEM      );
  362.     endfr();
  363.     nc();
  364.     frame( "Members alignment" );
  365.       ver();
  366.       oco_radios[ 0] = radio( "|~Byte",  compiler_options.alignment, alBYTE  );
  367.       oco_radios[ 1] = radio( "|~Word",  compiler_options.alignment, alWORD  );
  368.       nc();
  369.       oco_radios[ 2] = radio( "|~Dword", compiler_options.alignment, alDWORD );
  370.       oco_radios[ 3] = radio( "|~Qword", compiler_options.alignment, alQWORD );
  371.     endfr();
  372.     frame( "Optimize for" );
  373.       ver();
  374.       oco_radios[ 4] = radio( "S|~peed",          compiler_options.optimize_for, ofSPEED       );
  375.       oco_radios[ 5] = radio( "Si|~ze",           compiler_options.optimize_for, ofSIZE        );
  376.       oco_radios[ 6] = radio( "|~Effectivity   ", compiler_options.optimize_for, ofEFFECTIVITY );
  377.     endfr();
  378.     nl();
  379.     push();
  380.     frame( "Floating-point" );
  381.       oco_checks[ 7] = check( "Inline |~80x87 code for math functions ", compiler_options.optimizations, opINLINE     );
  382.       oco_checks[ 8] = check( "|~Consistent floating-point results",     compiler_options.optimizations, opCONSISTENT );
  383.       oco_checks[ 9] = check( "Opti|~mize for Pentium",                  compiler_options.optimizations, opPENTIUM    );
  384.     endfr();
  385.     _focused();
  386.     oco_control = check( "Enable |~optimizations", compiler_options.options, opOPTIMIZATIONS );
  387.     nc();
  388.     frame( "Expand inline" );
  389.       oco_checks[10] = check( "|~Intrinsic functions  ", compiler_options.optimizations, opINTRINSIC );
  390.       oco_checks[11] = check( "|~User functions",        compiler_options.optimizations, opUSER      );
  391.       vspace();
  392.       oco_input1     = iinput( "User |~threshold", compiler_options.inline_threshold, 0, 32767 );
  393.     endfr();
  394.     pop();
  395.     hor();
  396.     vspace();
  397.     _acenter(); button( "|~Fastest code",  cmFASTEST_CODE  );
  398.                 button( "|~Smallest code", cmSMALLEST_CODE );
  399.                 kbutton( "  OK  " );
  400.                 cbutton( "Cancel" );
  401.                 hbutton( " Help " );
  402.     oco_handler( oco_control );
  403.     if( run() == cmOK ) options_changed = 1;
  404.   }
  405. #undef cmFASTEST_CODE
  406. #undef cmSMALLEST_CODE
  407.  
  408.     static Titem *ocd_items[11];
  409.     static Tcheck *ocd_control;
  410.     static void ocd_handler( Titem *p )
  411.     {
  412.       if( p==ocd_control )
  413.       {
  414.         boolean fl = !ocd_control->pressed();
  415.         for( int i=0; i<11; i++ )
  416.           ocd_items[i]->set_state( isDISABLED, fl );
  417.       }
  418.     }
  419.  
  420.   void options_compiler_debugging( void )
  421.   {
  422.     _help( htD_DEBUGGING );
  423.     dialog( "Debugging Information" ); handler( ocd_handler );
  424.     hspacing( 1 );
  425.     frame( "Debug level" );
  426.       ocd_items[0] = radio( "|~Line numbers debug info",        compiler_options.debug_level, dlLINENUMS     );
  427.       ocd_items[1] = radio( "|~Full symbolic debug info",       compiler_options.debug_level, dlFULL         );
  428.       ocd_items[2] = radio( "Including |~unreferenced names  ", compiler_options.debug_level, dlUNREFERENCED );
  429.     endfr();
  430.     nc();
  431.     frame( "Debug format" );
  432.       ver();
  433.       ocd_items[3] = radio( "|~Watcom",     compiler_options.debug_format, dfWATCOM   );
  434.       ocd_items[4] = radio( "|~Dwarf",      compiler_options.debug_format, dfDWARF    );
  435.       ocd_items[5] = radio( "|~Codeview  ", compiler_options.debug_format, dfCODEVIEW );
  436.     endfr();
  437.     nl();
  438.     push();
  439.     frame( "Stack frames" );
  440.       ver();
  441.       ocd_items[6] = radio( "|~Generate as needed", compiler_options.stack_frames, sfNEED   );
  442.       ocd_items[7] = radio( "Generate |~always",    compiler_options.stack_frames, sfALWAYS );
  443.     endfr();
  444.     _focused();
  445.     ocd_control = check( "|~Enable debug info", compiler_options.options, opDEBUG_INFO );
  446.     nc();
  447.     frame( "Options" );
  448.       ver();
  449.       ocd_items[8]  = check( "|~Stack overflow checks",  compiler_options.debug_options, doSTACK         );
  450.       ocd_items[9]  = check( "Disable |~optimizations",  compiler_options.debug_options, doOPTIMIZATIONS );
  451.       ocd_items[10] = check( "Generate |~browsing info", compiler_options.debug_options, doBROWSING      );
  452.     endfr();
  453.     ocd_handler( ocd_control );
  454.     if( bkch() ) options_changed = 1;
  455.   }
  456.  
  457.   void options_compiler_floating_point( void )
  458.   {
  459.     _help( htD_FLOATING );
  460.     dialog( "Floating-point" );
  461.     frame( "Floating-point instructions" );
  462.       radio( "|~Calls to floating-point library", compiler_options.fp_instructions, fpCALLS     );
  463.       radio( "Inline |~with emulation",           compiler_options.fp_instructions, fpEMULATION );
  464.       radio( "Inline with|~out emulation",        compiler_options.fp_instructions, fpINLINE    );
  465.     endfr();
  466.     frame( "Portability" );
  467.       radio( "|~Backward compatible 80x87 code ", compiler_options.fp_portability,  fp8087  );
  468.       radio( "|~287 floating-point code",         compiler_options.fp_portability,  fp80287 );
  469.       radio( "|~387 floating-point code",         compiler_options.fp_portability,  fp80387 );
  470.     endfr();
  471.     if( bkch() ) options_changed = 1;
  472.   }
  473.  
  474.     static Titem *oceh_items[2];
  475.     static Tcheck *oceh_control;
  476.     static void oceh_handler( Titem *p )
  477.     {
  478.       if( p==oceh_control )
  479.       {
  480.         boolean fl = !oceh_control->pressed();
  481.         for( int i=0; i<2; i++ )
  482.           oceh_items[i]->set_state( isDISABLED, fl );
  483.       }
  484.     }
  485.  
  486.   void options_compiler_exceptions_handling( void )
  487.   {
  488.     _help( htD_EXCEPTIONS );
  489.     dialog( "Exception handling" ); handler( oceh_handler );
  490.     _acenter(); oceh_control = check( "|~Enable exception handling", compiler_options.exception_handling );
  491.     vspace();
  492.     frame( "Options" );
  493.       oceh_items[0] = radio( "|~Direct calls for destruction", compiler_options.destructions, xhDIRECTCALL  );
  494.       oceh_items[1] = radio( "|~Table-driven destructors",     compiler_options.destructions, xhTABLEDRIVEN );
  495.     endfr();
  496.     oceh_handler( oceh_control );
  497.     if( bkch() ) options_changed = 1;
  498.   }
  499.  
  500.   void options_compiler_segment_registers( void )
  501.   {
  502.     _help( htD_SEGMENTS );
  503.     dialog( "Segment registers" );
  504.     frame( "DS" );
  505.       radio( "Floats (|~not fixed to DGROUP)", compiler_options.ds_segment, dsFLOATS );
  506.       radio( "|~Pegged to DGROUP",             compiler_options.ds_segment, dsPEGGED );
  507.       radio( "|~Load directly from DGROUP",    compiler_options.ds_segment, dsLOAD   );
  508.     endfr();
  509.     frame( "Other" );
  510.       check( "|~FS pegged to a segment      ", compiler_options.fsgsss_segments, fsPEGGED    );
  511.       check( "|~GS pegged to a segment",       compiler_options.fsgsss_segments, gsPEGGED    );
  512.       check( "|~SS != DGROUP",                 compiler_options.fsgsss_segments, ssNEQDGROUP );
  513.     endfr();
  514.     if( bkch() ) options_changed = 1;
  515.   }
  516.  
  517.     static Titem *ocpf_items[5];
  518.     static Tcheck *ocpf_control;
  519.     static void ocpf_handler( Titem *p )
  520.     {
  521.       if( p==ocpf_control )
  522.       {
  523.         boolean fl = !ocpf_control->pressed();
  524.         for( int i=0; i<5; i++ )
  525.           ocpf_items[i]->set_state( isDISABLED, fl );
  526.       }
  527.     }
  528.  
  529.   void options_compiler_preprocess_files( void )
  530.   {
  531.     _help( htD_PREPROCESS );
  532.     dialog( "Preprocess files" ); handler( ocpf_handler );
  533.       _acenter(); ocpf_control = check( "Preprocessor |~only", compiler_options.exception_handling );
  534.       nl();
  535.       vspace(); hspaces( 3 );
  536.       frame( "Options" );
  537.         ocpf_items[0] = check( "|~Encrypt identifiers",     compiler_options.preprocess_options, pfENCRYPT  );
  538.         ocpf_items[1] = check( "|~Insert #line directives", compiler_options.preprocess_options, pfLINE     );
  539.         ocpf_items[2] = check( "|~Preserve comments",       compiler_options.preprocess_options, pfPRESERVE );
  540.       endfr();
  541.       nl();
  542.       vspace();
  543.       hor();
  544.       ocpf_items[3] = check( "|~Wrap output", compiler_options.preprocess_options, pfWRAP );
  545.       ocpf_items[4] = iinput( "|~at",  compiler_options.preprocess_wrap, 0, 300 );
  546.       stext( "columns", 9 );
  547.     ocpf_handler( ocpf_control );
  548.     if( bkch() ) options_changed = 1;
  549.   }
  550.  
  551.   void options_compiler_names( void )
  552.   {
  553.     _help( htD_NAMES );
  554.     dialog( "Names" );
  555.       input( "Code |~group name     ", compiler_options.code_group_name,   25, 25 );
  556.       input( "Code |~class name     ", compiler_options.code_class_name,   25, 25 );
  557.       input( "|~Data segment name   ", compiler_options.data_segment_name, 25, 25 );
  558.       input( "|~Module name         ", compiler_options.module_name,       25, 25 );
  559.       input( "Name of |~text segment", compiler_options.text_segment_name, 25, 25 );
  560.     if( bkch() ) options_changed = 1;
  561.   }
  562.  
  563.   void options_compiler_messages( void )
  564.   {
  565.     _help( htD_MESSAGES );
  566.     dialog( "Compiler messages" );
  567.     cinput( "|~Warnings: level number  ", compiler_options.warn_level, 0,   4 );
  568.     cinput( "|~Errors:   stop after  ",   compiler_options.max_errors, 1, 255 );
  569.     check( "|~Treat warnings as errors",  compiler_options.debug_options, doWARN_IS_ERR );
  570.     vspace();
  571.     frame( "Portability" );
  572.       radio( "Accept only ISO/|~ANSI C++", compiler_options.portability, poANSI   );
  573.       radio( "Enable e|~xtensions",        compiler_options.portability, poWATCOM );
  574.     endfr();
  575.     if( bkch() ) options_changed = 1;
  576.   }
  577.  
  578.  
  579. void options_linker( void )
  580. {
  581.   _help( htD_LINKER );
  582.   dialog( "Linker options" );
  583.   hor();
  584.   linput( "|~Stack size", linker_options.stack_size, 1024, 0x10000000 );
  585.   hspaces( 3 );
  586.   cinput( "|~Errors limit", linker_options.max_errors, 1, 255 );
  587.   nl();
  588.   ver();
  589.   Tcombo_box *os = combo_box( "|~Target", linker_options.target_os, 35 );
  590.   for( uint i=0; i<TO_COUNT; i++ )
  591.     os->add( target_os[i].title );
  592.   memo( "|~Other options", linker_options.other_options, sizeof( linker_options.other_options ), 43, 7 );
  593.   if( bkch() ) options_changed = 1;
  594. }
  595.  
  596.  
  597. #define cmCPP_SYNTAX cmUSER00
  598. #define cmASM_SYNTAX cmUSER01
  599.   static void update_editor_options( void )
  600.   {
  601.     strupr( editor_options.extension      );
  602.     strupr( editor_options.cpp_extensions );
  603.     strupr( editor_options.asm_extensions );
  604.     application->redraw();
  605.     editor_flags = editor_options.flags & ~(efSAVE_STATUS|efOPEN_INCLUDE);
  606.     tab_size = editor_options.tab_size;
  607.     for( Tfile_editor *p=open_editors; p!=NULL; p=p->next_editor )
  608.       p->text_editor->set_name( p->text_editor->file_name );
  609.   }
  610.  
  611.   static boolean oe_validator( uint command )
  612.   {
  613.     if( command==cmCPP_SYNTAX )
  614.     {
  615.       _help( htD_CPP_SYNTAX );
  616.       dialog( "C++ syntax hilighting options" );
  617.       input( "E|~xtensions    ", editor_options.cpp_extensions, sizeof(editor_options.cpp_extensions)-1, 26 );
  618.       nl();
  619.       push();
  620.       cinput( "|~Reserved words", cpp_syntax_colors[cppRESERVED_WORDS], 0, 15 )->set_state(isDISABLED,scr_bw);
  621.       cinput( "|~Identifiers   ", cpp_syntax_colors[cppIDENTIFIERS   ], 0, 15 )->set_state(isDISABLED,scr_bw);
  622.       cinput( "|~Numbers       ", cpp_syntax_colors[cppNUMBERS       ], 0, 15 )->set_state(isDISABLED,scr_bw);
  623.       cinput( "|~Strings       ", cpp_syntax_colors[cppSTRINGS       ], 0, 15 )->set_state(isDISABLED,scr_bw);
  624.       nc(); hspaces( 3 );
  625.       cinput( "S|~ymbols       ", cpp_syntax_colors[cppSYMBOLS       ], 0, 15 )->set_state(isDISABLED,scr_bw);
  626.       cinput( "|~Preprocessor  ", cpp_syntax_colors[cppPREPROCESSOR  ], 0, 15 )->set_state(isDISABLED,scr_bw);
  627.       cinput( "|~Comments      ", cpp_syntax_colors[cppCOMMENTS      ], 0, 15 )->set_state(isDISABLED,scr_bw);
  628.       cinput( "|~White space   ", cpp_syntax_colors[cppWHITE         ], 0, 15 )->set_state(isDISABLED,scr_bw);
  629.       if( bkch() )
  630.       {
  631.         options_changed = 1;
  632.         update_editor_options();
  633.       }
  634.       return 0;
  635.     }
  636.     if( command==cmASM_SYNTAX )
  637.     {
  638.       _help( htD_ASM_SYNTAX );
  639.       dialog( "Assembler syntax hilighting options" );
  640.       input( "E|~xtensions    ", editor_options.asm_extensions, sizeof(editor_options.asm_extensions)-1, 26 );
  641.       nl();
  642.       push();
  643.       cinput( "|~Reserved words", asm_syntax_colors[asmRESERVED_WORDS], 0, 15 )->set_state(isDISABLED,scr_bw);
  644.       cinput( "|~Identifiers   ", asm_syntax_colors[asmIDENTIFIERS   ], 0, 15 )->set_state(isDISABLED,scr_bw);
  645.       cinput( "|~Decimals      ", asm_syntax_colors[asmDECIMALS      ], 0, 15 )->set_state(isDISABLED,scr_bw);
  646.       cinput( "|~Hexadecimals  ", asm_syntax_colors[asmHEXADECIMALS  ], 0, 15 )->set_state(isDISABLED,scr_bw);
  647.       cinput( "|~Binaries      ", asm_syntax_colors[asmBINARIES      ], 0, 15 )->set_state(isDISABLED,scr_bw);
  648.       nc(); hspaces( 3 );
  649.       cinput( "|~Strings       ", asm_syntax_colors[asmSTRINGS       ], 0, 15 )->set_state(isDISABLED,scr_bw);
  650.       cinput( "S|~ymbols       ", asm_syntax_colors[asmSYMBOLS       ], 0, 15 )->set_state(isDISABLED,scr_bw);
  651.       cinput( "|~Comments      ", asm_syntax_colors[asmCOMMENTS      ], 0, 15 )->set_state(isDISABLED,scr_bw);
  652.       cinput( "|~White space   ", asm_syntax_colors[asmWHITE         ], 0, 15 )->set_state(isDISABLED,scr_bw);
  653.       if( bkch() )
  654.       {
  655.         options_changed = 1;
  656.         update_editor_options();
  657.       }
  658.       return 0;
  659.     }
  660.     return 1;
  661.   }
  662.  
  663. void options_editor( void )
  664. {
  665.   _help( htD_EDITOR );
  666.   dialog( "Editor options" ); validator( oe_validator );
  667.   frame( "Options" );
  668.     check( "|~Backup files",            editor_options.flags, efBACKUP_FILES );
  669.     check( "|~Save/restore status",     editor_options.flags, efSAVE_STATUS  );
  670.     check( "Auto |~indent mode",        editor_options.flags, efAUTO_INDENT  );
  671.     check( "|~Hard tabs",               editor_options.flags, efHARD_TABS    );
  672.     check( "|~Open from include dirs ", editor_options.flags, efOPEN_INCLUDE );
  673.   endfr();
  674.   nc();
  675.   hspace();
  676.   frame( "Search/Replace" );
  677.     check( "Case se|~nsitive",     editor_options.flags, efCASE_SENSITIVE    );
  678.     check( "|~Whole words only",   editor_options.flags, efWHOLE_WORDS_ONLY  );
  679.     check( "|~Prompt on replace ", editor_options.flags, efPROMPT_ON_REPLACE );
  680.     check( "|~Replace all",        editor_options.flags, efREPLACE_ALL       );
  681.   endfr();
  682.   nl();
  683.   hor();
  684.   iinput( "|~Tab size", editor_options.tab_size, 2, 32 );
  685.   hspaces( 3 );
  686.   input( "|~Default file name extension", editor_options.extension, _MAX_EXT - 1, _MAX_EXT - 1 );
  687.   nl();
  688.   vspace();
  689.   frame( "Condensed display" );
  690.     iinput( " |~Margin", editor_options.condense_column, 0, 255 );
  691.     iinput( "  Minimum |~length", editor_options.condense_length, 0, 255 );
  692.     stext( "characters", 12 );
  693.   endfr();
  694.   nl(); _acenter(); hspacing( 1 );
  695. #ifndef HGR
  696.   vspaces( !graph_flag );
  697. #endif
  698.   kbutton( "  OK  " );
  699.   button( " |~C++ ", cmCPP_SYNTAX );
  700.   button( " |~Assembler ", cmASM_SYNTAX );
  701.   cbutton( "Cancel" );
  702.   hbutton( " Help " );
  703.   if( run()==cmOK )
  704.   {
  705.     options_changed = 1;
  706.     update_editor_options();
  707.   }
  708. }
  709. #undef cmCPP_SYNTAX
  710. #undef cmASM_SYNTAX
  711.  
  712.  
  713. void options_directories( void )
  714. {
  715.   char *s;
  716.  
  717.   _help( htD_DIRS );
  718.   dialog( "Directories" );
  719.   input( "|~Include directories", default_directories.include,   _MAX_PATH-1, 25 );
  720.   input( "|~Library directories", default_directories.library,   _MAX_PATH-1, 25 );
  721.   input( "|~Target directory   ", default_directories.objects,   _MAX_PATH-1, 25 );
  722.   input( "|~Swap directory     ", default_directories.tmp_files, _MAX_PATH-1, 25 );
  723.   if( bkch() )
  724.   {
  725.     options_changed = 1;
  726.     s = strchr( default_directories.include, 0 );
  727.     if( ( s > default_directories.include ) && ( *(s-1) != '\\' ) )
  728.       strcat( fexpand( default_directories.include ), "\\" );
  729.     s = strchr( default_directories.library, 0 );
  730.     if( ( s > default_directories.library ) && ( *(s-1) != '\\' ) )
  731.       strcat( fexpand( default_directories.library ), "\\" );
  732.     s = strchr( default_directories.objects, 0 );
  733.     if( ( s > default_directories.objects ) && ( *(s-1) != '\\' ) )
  734.       strcat( fexpand( default_directories.objects ), "\\" );
  735.     s = strchr( default_directories.tmp_files, 0 );
  736.     if( ( s > default_directories.tmp_files ) && ( *(s-1) != '\\' ) )
  737.       strcat( fexpand( default_directories.tmp_files ), "\\" );
  738.   }
  739. }
  740.  
  741.  
  742. /*
  743. TOOLS
  744. */
  745.   #define cmOK_CLOSE  cmUSER00
  746.   #define cmADD_TOOL  cmUSER01
  747.   #define cmINS_TOOL  cmUSER02
  748.   #define cmEDIT_TOOL cmOK
  749.   #define cmDEL_TOOL  cmUSER03
  750.  
  751.       static Tlist_box *tools_list_box;
  752.       static Tinput *oti_title;
  753.       static Tinput *oti_path;
  754.       static Ttools_entry *oti_tool;
  755.       static boolean oti_validator( uint command )
  756.       {
  757.         char buffer[256];
  758.         int trap;
  759.  
  760.         if( command == cmUSER01 )
  761.         {
  762.           _help( htD_TOOL_OPTIONS );
  763.           dialog( "Tool options" );
  764.           frame( "Options" );
  765.             check( "|~Translator (can be used for make)",  oti_tool->options, teCOMPILER  );
  766.             check( "|~Don't swap screen",                  oti_tool->options, teDONT_SWAP );
  767.             check( "|~Prompt with command line",           oti_tool->options, tePROMPT    );
  768.             check( "Enable |~long command line (@file)",   oti_tool->options, teLONG_CMD  );
  769.             check( "|~Make project before execution",      oti_tool->options, teMAKE      );
  770.             check( "Save |~current file before execution", oti_tool->options, teSAVE_CUR  );
  771.             check( "Save |~all files before execution",    oti_tool->options, teSAVE_ALL  );
  772.           endfr();
  773.           trap = 1;
  774.           if( oti_tool->options & teTRAP_ERRORS ) trap = 2;
  775.           if( oti_tool->options & teTRAP_OUTPUT ) trap = 3;
  776.           frame( "Trap output" );
  777.             radio( "Don't trap |~output", trap, 1 );
  778.             radio( "Temp file > |~specified filter", trap, 2 );
  779.             radio( "Specified |~file", trap, 3 );
  780.             vspace();
  781.             input( "Trap/filter file |~name", oti_tool->trap_file, 12, 12 );
  782.           endfr();
  783.           hor(); hspacing( 1 ); nl(); _acenter();
  784.           kbutton( "  OK  " );
  785.           cbutton( "Cancel" );
  786.           hbutton( " Help " );
  787.           if( run() == cmOK )
  788.           {
  789.             options_changed = 1;
  790.             oti_tool->options &= ~( teTRAP_OUTPUT + teTRAP_ERRORS );
  791.             if( trap == 2 ) oti_tool->options |= teTRAP_ERRORS;
  792.             if( trap == 3 ) oti_tool->options |= teTRAP_OUTPUT;
  793.             strupr( oti_tool->trap_file );
  794.           }
  795.           return 0;
  796.         }
  797.         if( command != cmOK ) return 1;
  798.         oti_title->get_txt( buffer );
  799.         if( *buffer == 0 )
  800.         {
  801.           focus( oti_title );
  802.           return 0;
  803.         }
  804.         oti_path->get_txt( buffer );
  805.         if( *buffer == 0 )
  806.         {
  807.           focus( oti_path );
  808.           return 0;
  809.         }
  810.         return 1;
  811.       }
  812.  
  813.     static boolean options_tools_input( Ttools_entry &te )
  814.     {
  815.       uint shortcut;
  816.       uint shortcuts[] = { 0, kSHIFT_F1, kSHIFT_F2, kSHIFT_F3, kSHIFT_F4, kSHIFT_F5,
  817.                               kSHIFT_F6, kSHIFT_F7, kSHIFT_F8, kSHIFT_F9, kSHIFT_F10 };
  818.       char buf[20];
  819.       char drive[_MAX_DRIVE];
  820.       char dir[_MAX_DIR];
  821.       boolean result;
  822.       Tcombo_box *cb;
  823.       _help( htD_NEW_TOOL );
  824.       dialog( "Modify/New tool" ); validator( oti_validator );
  825.       oti_tool = &te;
  826.       oti_title = input( "|~Menu title  ", te.title, 20, 20 );
  827.       oti_path  = input( "|~Program path", te.path, _MAX_PATH-1, 20 );
  828.       input( "|~Command line", te.command_line, 127, 20 );
  829.       shortcut = 0;
  830.       for( uint i = 0; i <= 10; i++ )
  831.         if( te.shortcut == shortcuts[i] )
  832.         {
  833.           shortcut = i;
  834.           break;
  835.         }
  836.       cb = combo_box( "|~Shortcut    ", shortcut, 11 );
  837.         cb->add( "No shortcut" );
  838.         for( i = 1; i <= 10; i++ )
  839.         {
  840.           sprintf( buf, "Shift+F%d", i );
  841.           cb->add( buf );
  842.         }
  843.       hor(); hspacing( 1 ); nl(); vspace(); _acenter();
  844.       kbutton( "  OK  " );
  845.        button( "|~Options", cmUSER01 );
  846.       cbutton( "Cancel" );
  847.       hbutton( " Help " );
  848.       result = ( run() == cmOK );
  849.       if( result )
  850.       {
  851.         options_changed = 1;
  852.         te.shortcut = shortcuts[shortcut];
  853.         strupr( te.path );
  854.         _splitpath( te.path, drive, dir, NULL, NULL );
  855.         if( *dir || *drive ) fexpand( te.path );
  856.       }
  857.       return result;
  858.     }
  859.  
  860.   static void options_tools_edit( uint i )
  861.   {
  862.     Ttools_entry te;
  863.     tools_list_box->get( i, &te );
  864.     if( options_tools_input( te ) ) tools_list_box->put( i, &te );
  865.   }
  866.  
  867.   static void options_tools_new( uint i )
  868.   {
  869.     Ttools_entry te;
  870.     *te.path = 0;
  871.     *te.command_line = 0;
  872.     te.shortcut = 0;
  873.     te.options = 0;
  874.     *te.title = 0;
  875.     strcpy( te.trap_file, "TEXT2LOG" );
  876.     if( options_tools_input( te ) ) tools_list_box->ins( i, &te );
  877.   }
  878.  
  879.     static boolean options_tools_validator( uint command )
  880.     {
  881.       Ttools_entry *te;
  882.       boolean result;
  883.  
  884.       result = 0;
  885.       switch( command )
  886.       {
  887.         case cmEDIT_TOOL:
  888.           options_tools_edit( tools_list_box->vcurrent );
  889.           break;
  890.         case cmADD_TOOL:
  891.           options_tools_new( tools_list_box->vcount );
  892.           break;
  893.         case cmINS_TOOL:
  894.           options_tools_new( tools_list_box->vcurrent );
  895.           break;
  896.         case cmDEL_TOOL:
  897.           te = (Ttools_entry *) tools_list_box->getptr( tools_list_box->vcurrent );
  898.           tools_list_box->del( tools_list_box->vcurrent );
  899.           break;
  900.         default:
  901.           result = 1;
  902.       }
  903.       tools_list_box->cstate( cmADD_TOOL, tools_list_box->vcount < MAX_TOOLS );
  904.       tools_list_box->cstate( cmINS_TOOL, tools_list_box->vcount < MAX_TOOLS );
  905.       tools_list_box->cstate( cmDEL_TOOL, tools_list_box->vcount > 0 );
  906.       tools_list_box->cstate( cmEDIT_TOOL, tools_list_box->vcount > 0 );
  907.       return result;
  908.     }
  909.  
  910.   void options_tools( void )
  911.   {
  912.     uint i;
  913.     Ttools_entry te;
  914.  
  915.     _help( htD_TOOLS );
  916.     dialog( "Tools" ); validator( options_tools_validator );
  917.     _lsize( TTOOLS_ENTRY_SIZE );
  918.     i = 0;
  919.     tools_list_box = list_box( "Program titles", i, 20, 12 );
  920.     tools_list_box->set_flags( ifSTAY, 1 );
  921.     nc();
  922.      button( "  O|~K  ", cmOK_CLOSE );
  923.      button( " |~Add  ", cmADD_TOOL );
  924.      button( "|~Insert", cmINS_TOOL )->shortcut = kINS;
  925.      button( "|~Delete", cmDEL_TOOL )->shortcut = kDEL;
  926.     dbutton( " |~Edit ", cmEDIT_TOOL );
  927.     cbutton( "Cancel" );
  928.     hbutton( " Help " );
  929.     for( i = 0; i < ot_tools->vcount; i++ )
  930.     {
  931.       ot_tools->get( i, &te );
  932.       tools_list_box->add( &te );
  933.     }
  934.     tools_list_box->top();
  935.     options_tools_validator( 0 );
  936.     if( run() == cmOK_CLOSE )
  937.     {
  938.       options_changed = 1;
  939.       ot_tools->clear();
  940.       for( i = 0; i < tools_list_box->vcount; i++ )
  941.       {
  942.         tools_list_box->get( i, &te );
  943.         ot_tools->add( &te );
  944.       }
  945.       init_main_menu();
  946.       update_context();
  947.     }
  948.     DELETE( tools_list_box );
  949.   }
  950.   #undef cmOK_CLOSE
  951.   #undef cmADD_TOOL
  952.   #undef cmINS_TOOL
  953.   #undef cmEDIT_TOOL
  954.   #undef cmDEL_TOOL
  955.  
  956.   void expand_command_line( char *command_line, char *file, char *result )
  957.   {
  958.     char c;
  959.     char *s, *d, *pfile;
  960.     char drive[_MAX_DRIVE], pdrive[_MAX_DRIVE];
  961.     char dir[_MAX_DIR],     pdir[_MAX_DIR];
  962.     char name[_MAX_FNAME],  pname[_MAX_FNAME];
  963.     char ext[_MAX_EXT],     pext[_MAX_EXT];
  964.  
  965.     *result = *drive  = *dir  = *name  = *ext  =
  966.               *pdrive = *pdir = *pname = *pext = 0;
  967.     pfile = file;
  968.     _splitpath( file, drive,  dir,  name,  ext  );
  969.     _splitpath( file, pdrive, pdir, pname, pext );
  970.     if( project != NULL )
  971.     {
  972.       pfile = project->filename;
  973.       _splitpath( pfile, pdrive, pdir, pname, pext );
  974.     }
  975.     s = command_line - 1;
  976.     d = result - 1;
  977.     do
  978.     {
  979.       *++d = *++s;
  980.       if( *s == '$' )
  981.       {
  982.         switch( c = *++s )
  983.         {
  984.           case 'P':
  985.             strcpy( d, pfile );
  986.             break;
  987.           case 'F':
  988.             strcpy( d, pname );
  989.             strcat( d, pext );
  990.             break;
  991.           case 'N':
  992.             strcpy( d, pname );
  993.             break;
  994.           case 'X':
  995.             strcpy( d, pext );
  996.             break;
  997.           case 'D':
  998.             strcpy( d, pdrive );
  999.             strcat( d, pdir );
  1000.             break;
  1001.           case 'p':
  1002.             strcpy( d, file );
  1003.             break;
  1004.           case 'f':
  1005.             strcpy( d, name );
  1006.             strcat( d, ext );
  1007.             break;
  1008.           case 'n':
  1009.             strcpy( d, name );
  1010.             break;
  1011.           case 'x':
  1012.             strcpy( d, ext );
  1013.             break;
  1014.           case 'd':
  1015.             strcpy( d, drive );
  1016.             strcat( d, dir );
  1017.             break;
  1018.           case 'i':
  1019.           case 'I':
  1020.             strcpy( d, default_directories.include );
  1021.             break;
  1022.           case 't':
  1023.           case 'T':
  1024.             strcpy( d, default_directories.objects );
  1025.             break;
  1026.           case 'w':
  1027.           case 'W':
  1028.             *d = 0;
  1029.             if( current_editor == NULL ) break;
  1030.             current_editor->get_word_str( d, 50 );
  1031.             if( c == 'W' ) strupr( d );
  1032.             break;
  1033.           case 'c':
  1034.           case 'C':
  1035.             strcpy( d, program_params );
  1036.             break;
  1037.           default:
  1038.             continue;
  1039.         }
  1040.         d = strchr( d, 0 ) - 1;
  1041.       }
  1042.     }
  1043.     while( *s );
  1044.     get_local_options( result, file );
  1045.   }
  1046.  
  1047.   int exec_tool( uint tool, char *file )
  1048.   {
  1049.     Ttools_entry *te;
  1050.     char fn[_MAX_PATH];
  1051.     char buffer[256];
  1052.     int result;
  1053.  
  1054.     te = (Ttools_entry *) ot_tools->getptr( tool );
  1055.     strcpy( fn, file );
  1056.     if( *fn == 0 )
  1057.       if( current_editor!=NULL )
  1058.         strcpy( fn, ((Tfile_editor *) current_editor->editor)->text_editor->file_name );
  1059.       else
  1060.         if( project!=NULL && project->state( isFOCUSED ) )
  1061.         {
  1062.           Tproject_entry *pe = (Tproject_entry *) project->getptr( project->vcurrent );
  1063.           strcpy( fn, pe->filename );
  1064.         }
  1065.     expand_command_line( te->command_line, fn, buffer );
  1066.     if( te->options & teTRAP_ERRORS ) log->clear();
  1067.     if( ( te->options & teMAKE ) && !project_make() ) return -1;
  1068.     if( te->options & teDONT_SWAP )
  1069.       action( "\nExecuting %s", te->path );
  1070.     else
  1071.       hide_cursor();
  1072.     result = exec( te->options, te->path, buffer, te->trap_file, te );
  1073.     if( te->options & teDONT_SWAP )
  1074.       done_action();
  1075.     else
  1076.       show_cursor();
  1077.     if( te->options & teTRAP_ERRORS ) log->show_first_error();
  1078.     application->redraw();
  1079.     idle( 0 );
  1080.     return result;
  1081.   }
  1082.  
  1083.  
  1084. /*
  1085. OPTIONS I/O
  1086. */
  1087.   void options_file_changed( char *filename )
  1088.   {
  1089.     char buffer[_MAX_PATH];
  1090.  
  1091.     strcpy( options_filename, filename );
  1092.     strcpy( buffer, filename );
  1093.     min_path( buffer );
  1094.     short_path( buffer, 20 );
  1095.     strcpy( short_options_filename, buffer );
  1096.     init_main_menu();
  1097.     update_context();
  1098.     options_changed = 0;
  1099.   }
  1100.  
  1101.   boolean load_options( char *filename, boolean show_error )
  1102.   {
  1103.     FILE *f;
  1104.     Tcompiler_options    tmp_compiler_options;
  1105.     Tlinker_options      tmp_linker_options;
  1106.     Teditor_options      tmp_editor_options;
  1107.     char                 tmp_cpp_colors[sizeof(cpp_syntax_colors)];
  1108.     char                 tmp_asm_colors[sizeof(asm_syntax_colors)];
  1109.     Tdefault_directories tmp_default_directories;
  1110.     Tlb_list *           tmp_tools;
  1111.     char tmp_signature[ sizeof( pvo_signature ) ];
  1112.     Ttools_entry te;
  1113.     boolean success;
  1114.     uint count, i;
  1115.  
  1116.     if( *filename == 0 ) return 0;
  1117.     f = fopen( filename, "rb" );
  1118.     if( f == NULL )
  1119.     {
  1120.       if( show_error )
  1121.       {
  1122.         _terror();
  1123.         ok( "Unable to open options file \"%s\".", filename );
  1124.       }
  1125.       return 0;
  1126.     }
  1127.     _lsize( TTOOLS_ENTRY_SIZE ); tmp_tools = NEW( Tlb_list );
  1128.     memset( tmp_signature, 0, sizeof( tmp_signature ) );
  1129.     fread( tmp_signature, sizeof( tmp_signature ), 1, f );
  1130.     success = !memcmp( tmp_signature, pvo_signature, sizeof( tmp_signature ) );
  1131.     if( !success )
  1132.     {
  1133.       _terror();
  1134.       ok( "\"%s\" is not a Power View IDE options file.", filename );
  1135.       goto xit;
  1136.     }
  1137.     success = (
  1138.       ( fread( &tmp_compiler_options,    sizeof( Tcompiler_options    ), 1, f ) == 1 ) &&
  1139.       ( fread( &tmp_linker_options,      sizeof( Tlinker_options      ), 1, f ) == 1 ) &&
  1140.       ( fread( &tmp_editor_options,      sizeof( Teditor_options      ), 1, f ) == 1 ) &&
  1141.       ( fread( tmp_cpp_colors,           sizeof( tmp_cpp_colors       ), 1, f ) == 1 ) &&
  1142.       ( fread( tmp_asm_colors,           sizeof( tmp_asm_colors       ), 1, f ) == 1 ) &&
  1143.       ( fread( &tmp_default_directories, sizeof( Tdefault_directories ), 1, f ) == 1 ) &&
  1144.       ( fread( &count,                   sizeof( count                ), 1, f ) == 1 )
  1145.     );
  1146.     if( success )
  1147.     {
  1148.       ++count;
  1149.       while( success && --count )
  1150.       {
  1151.         success = success && ( fread( &te, sizeof( Ttools_entry ), 1, f ) == 1 );
  1152.         tmp_tools->add( &te );
  1153.       }
  1154.     }
  1155.     fclose( f );
  1156.     if( ferror( f ) || !success )
  1157.     {
  1158.       _terror();
  1159.       ok( "Error reading options file \"%s\".", filename );
  1160.     }
  1161.     else
  1162.     {
  1163.       compiler_options = tmp_compiler_options;
  1164.       linker_options = tmp_linker_options;
  1165.       editor_options = tmp_editor_options;
  1166.       if( !scr_bw )
  1167.       {
  1168.         memcpy( cpp_syntax_colors, tmp_cpp_colors, sizeof(cpp_syntax_colors) );
  1169.         memcpy( asm_syntax_colors, tmp_asm_colors, sizeof(asm_syntax_colors) );
  1170.       }
  1171.       update_editor_options();
  1172.       default_directories = tmp_default_directories;
  1173.       ot_tools->clear();
  1174.       for( i = 0; i < tmp_tools->vcount; i++ )
  1175.       {
  1176.         tmp_tools->get( i, &te );
  1177.         ot_tools->add( &te );
  1178.       }
  1179.       options_file_changed( filename );
  1180.     }
  1181.     xit: DELETE( tmp_tools );
  1182.     return success;
  1183.   }
  1184.  
  1185.   void options_save( void )
  1186.   {
  1187.     FILE *f;
  1188.     Ttools_entry te;
  1189.     uint i;
  1190.     boolean success;
  1191.  
  1192.     if( *options_filename==0 )
  1193.     {
  1194.       strcpy( options_filename, startup_path );
  1195.       strcat( options_filename, "SAVED.PVO" );
  1196.     }
  1197.     f = fopen( options_filename, "wb" );
  1198.     if( f == NULL )
  1199.     {
  1200.       _terror();
  1201.       ok( "Unable to create options file \"%s\".", options_filename );
  1202.       return;
  1203.     }
  1204.     success = (
  1205.       ( fwrite( pvo_signature,        sizeof( pvo_signature        ), 1, f ) == 1 ) &&
  1206.       ( fwrite( &compiler_options,    sizeof( Tcompiler_options    ), 1, f ) == 1 ) &&
  1207.       ( fwrite( &linker_options,      sizeof( Tlinker_options      ), 1, f ) == 1 ) &&
  1208.       ( fwrite( &editor_options,      sizeof( Teditor_options      ), 1, f ) == 1 ) &&
  1209.       ( fwrite( cpp_syntax_colors,    sizeof( cpp_syntax_colors    ), 1, f ) == 1 ) &&
  1210.       ( fwrite( asm_syntax_colors,    sizeof( asm_syntax_colors    ), 1, f ) == 1 ) &&
  1211.       ( fwrite( &default_directories, sizeof( Tdefault_directories ), 1, f ) == 1 ) &&
  1212.       ( fwrite( &ot_tools->vcount,    sizeof( ot_tools->vcount     ), 1, f ) == 1 )
  1213.     );
  1214.     if( success )
  1215.     {
  1216.       for( i = 0; success && ( i < ot_tools->vcount ); i++ )
  1217.       {
  1218.         ot_tools->get( i, &te );
  1219.         success = success && ( fwrite( &te, sizeof( Ttools_entry ), 1, f ) == 1 );
  1220.       }
  1221.     }
  1222.     fclose( f );
  1223.     if( ferror( f ) || !success )
  1224.     {
  1225.       remove( options_filename );
  1226.       _terror();
  1227.       ok( "Error writting options file \"%s\".", options_filename );
  1228.     }
  1229.     else
  1230.       options_file_changed( options_filename );
  1231.   }
  1232.  
  1233.  
  1234. /*
  1235. MENU COMMANDS SERVICE
  1236. */
  1237.   void options_open( void )
  1238.   {
  1239.     char f[_MAX_PATH];
  1240.  
  1241.     _filters( "Option files (*.pvo)" );
  1242.     if( get_file( "Open options", f ) == cmOK )
  1243.       load_options( f, 1 );
  1244.   }
  1245.  
  1246.   void options_save_as( void )
  1247.   {
  1248.     _new_file();
  1249.     _filters( "Option files (*.pvo)" );
  1250.     if( get_file( "Save options as", options_filename ) == cmOK )
  1251.       options_save();
  1252.   }
  1253.