home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / COMPILER.PEL < prev    next >
Text File  |  1995-04-10  |  56KB  |  1,996 lines

  1. # $Header:   P:\source\wmacros\compiler.pev   1.51.1.2   10 Apr 1995 14:18:08   WALKER  $
  2. ## $Tabs:4 7$
  3.  
  4. ##############################################################################
  5. #
  6. #       Compuware Corporation
  7. #         31440 Northwestern Highway
  8. #           Farmington Hills, Michigan 48334-2564
  9. #
  10. #   This source code listing contains information that is
  11. #   proprietary to Compuware Corporation and may not be copied
  12. #   duplicated, translated, transmitted, stored, retrieved
  13. #   or in any manner or by any method conveyed or disclosed
  14. #   to a third party or parties without express written
  15. #   permission from Compuware Corporation.
  16. #
  17. #  
  18. ##############################################################################
  19.  
  20. #### $Workfile:   compiler.pel  $: dialog window interface
  21.  
  22. #  Types
  23. #  -----
  24. #  ada
  25. #  basic
  26. #  c
  27. #  cobol
  28. #  makefile
  29. #  pascal
  30. #  pel
  31. #  
  32. #  
  33. #  typedef struct compiler
  34. #  {
  35. #     str  command_line;
  36. #     str  error_format;
  37. #     bool needs_input;
  38. #     str  input_file;
  39. #     bool list_all;
  40. #     bool save_all;
  41. #     bool chdir;
  42. #     bool background;
  43. #     long flags;
  44. #     any  dos_settings;
  45. #  } Compiler;
  46. #  
  47. #  typedef struct category
  48. #  {
  49. #     str name;
  50. #     long foreground;
  51. #     long background;
  52. #  } Category;
  53. #  
  54. #  typedef long Style; // 0xllffccss : ll - column; ff - flags; cc - category; ss - style index
  55. #  
  56. #  typedef struct type
  57. #  {
  58. #     bool      modified;
  59. #     str       compiler_name;
  60. #     str       template;
  61. #     str       tab_stops;
  62. #     str       margins;
  63. #     str       matching_pairs;
  64. #     str       esc_character;
  65. #     int       buff_flags;
  66. #     str       auto_indent;
  67. #     int       syntax;
  68. #     str       stile_delimiters;
  69. #     bool      sensitive;          // case sensitive find for keywords;
  70. #     int       expand;             // word processing mode indicator;
  71. #     int       make_default;       // for "type" == CURRENT_BUFFER only
  72. #     int       apply_to_all;       // for "type" == CURRENT_BUFFER only
  73. #     Category  category[];         // indexed by number; contains category name, fg, bg color;
  74. #     Style     keyword[];          // indexed by item; contains style;
  75. #     Style     block[];            // indexed by item; contains style;
  76. #     Style     line[];             // indexed by item; contains style;
  77. #  } Type;
  78. #  
  79. #  str extensions[];        //  Indexed by extension (set to name of type for that extension);
  80. #  
  81. #  Compiler compilers[];    //  Indexed by compiler name;
  82. #  
  83. #  str templates[];         //  Indexed by type; template name for the type;
  84. #  
  85. #  Type languages[];        //  Indexed by type;
  86. #  
  87. ################################################################################
  88.  
  89. global extensions[];
  90. global compilers[];
  91. global templates[];
  92. global KEYWORD = 1;
  93. global LINE    = 2;
  94. global BLOCK   = 4;
  95.  
  96. ################################################################################
  97. #  The folllowing functions and variables were put here in order to facilitate the
  98. #  exclusion of some pel from the response file;
  99. ################################################################################
  100.  
  101. global language_compiled = FALSE;
  102. global save_languages;
  103. global global_type;
  104.  
  105. global CURRENT_BUFFER = "Current Buffer";
  106. global DEFAULT        = "Default";
  107.  
  108. global function init_types(handle, buffer_page)
  109. {
  110.    local name;
  111.  
  112.    set_dialog_item(handle, IDL_TYPE, DAC_DELETE_ITEM)
  113.    for (name in languages)
  114.    {
  115.       if((name != CURRENT_BUFFER) && (name != DEFAULT))
  116.          set_dialog_item(handle, IDL_TYPE, DAC_ADD_ITEM, name "");
  117.    }
  118. }
  119.  
  120. ################################################################################
  121. #  end of refugee section;
  122. ################################################################################
  123.  
  124. ## expand_command()
  125. #  function to substitute the components of a filename for the replacable
  126. #  characters in the compiler or vcs (or any other) command line.
  127. #
  128. #  $< = full file spec
  129. #  $r = file name without path or extension (aka, root)
  130. #  $e = extension without period
  131. #  $p = path with trailing \
  132. #  $a = full file spec of the editor's AE file.
  133. #
  134. global function expand_command(cmd, fname)
  135. {
  136.    gsub( /\$\</, fname, cmd);
  137.    gsub( /\$r/,  path_fname(fname), cmd);
  138.    gsub( /\$e/,  substr( path_ext(fname), 2 ), cmd);
  139.    gsub( /\$p/,  path_path(fname), cmd);
  140.    gsub( /\$a/,  locate_cpe_file(CPE_FILE_AE), cmd);
  141.    return cmd
  142. }
  143.  
  144. ## add_compiler()
  145. #
  146. # adds information about a compiler to the compilers array.
  147. #
  148. global function add_compiler( name, cmd_line, error_ruleset, needs_input,
  149.                               input_file, list_all, save_all, chdir,
  150.                               background, flags )
  151. {
  152. #     cvdebug("add_compiler >" name "< called from >" function_caller() "<");
  153.    # check required arguments
  154.    if ( !name )
  155.       warning( "missing compiler_name in call to add_compiler" )
  156.    else
  157.    {
  158. #     if ( !cmd_line )
  159. #        warning( "missing command_line in call to add_compiler" )
  160.  
  161.       set_command_line(name,        cmd_line);
  162.       set_error_format(name,        error_ruleset);
  163.       set_compiler_input(name,      (needs_input+0 > 0), input_file);
  164.       set_compiler_output(name,     (list_all+0 > 0));
  165.       set_compiler_save_all(name,   (save_all+0 > 0));
  166.       set_compiler_chdir(name,      chdir)
  167.       set_compiler_background(name, background)
  168.       set_compiler_flags(name,      flags)
  169.    }
  170. }
  171.  
  172. ## edit_compiler()
  173. #
  174. # edits a compiler command string in the compilers array
  175. #
  176. global function edit_compiler( name )
  177. {
  178.    local ext
  179.    local cmd
  180.  
  181.    if ( !name )
  182.    {
  183.       # default is filename extension of current buffer
  184.       ext  = path_ext( buffer_filename )
  185.       name = CompilerName(ext);
  186.    }
  187.  
  188.    # prompt for compiler command string
  189.    if(name)
  190.       cmd = CommandLine(name);
  191.  
  192.    cmd = prompt_history("COMPILE", "Enter compiler command: ", cmd, 1, 1)
  193.  
  194.    # update the compiler command array
  195.    if(cmd)
  196.       set_command_line(name, cmd);
  197.  
  198.    return cmd
  199. }
  200.  
  201. ## delete_compiler()
  202. #
  203. # deletes information about a compiler from the compilers array.
  204. #
  205. global function delete_compiler(comp_name)
  206. {
  207.    local type;
  208.  
  209.    #  TODO Delete references to the compiler in the languages array also;
  210.    #  Should it be "" or "[None]"?
  211.    delete compilers[comp_name];
  212.    for(type in languages)
  213.    {
  214.       if(CompilerName(type) == comp_name)
  215.          set_compiler_name(type, "");
  216.    }
  217. }
  218.  
  219. ################################################################################
  220. #  
  221. #  Utility functions
  222. #  
  223. ################################################################################
  224.  
  225. local function getCompiler(index)
  226. {
  227.    local compiler = 0;
  228.  
  229.    if(prefix(index, 1) == ".")
  230.    {
  231.       if(index in extensions)
  232.          compiler = languages[extensions[index]].compiler_name;
  233.       else
  234.          compiler = -1
  235.    }
  236.    else if(index in languages)
  237.       compiler = languages[index].compiler_name;
  238.    else
  239.       compiler = index
  240.  
  241.    if (!(compiler in compilers))
  242.       compiler = -2
  243.  
  244.    return compiler
  245. }
  246.  
  247. global function Type(ext)
  248. {
  249.    local result = "";
  250.  
  251.    if(ext in extensions)
  252.       result = extensions[ext];
  253.  
  254.    return result;
  255. }
  256.  
  257. global function SetType(ext, type)
  258. {
  259.    if(type)
  260.       extensions[ext] = type;
  261.    else
  262.       delete extensions[ext];
  263. }
  264.  
  265. global function CopyType(type, new_type)
  266. {
  267.    local word;
  268.  
  269.    languages[new_type].compiler_name     = languages[type].compiler_name;
  270.    languages[new_type].template          = languages[type].template;
  271.    languages[new_type].tab_stops         = languages[type].tab_stops;
  272.    languages[new_type].margins           = languages[type].margins;
  273.    languages[new_type].matching_pairs    = languages[type].matching_pairs;
  274.    languages[new_type].buff_flags        = languages[type].buff_flags;
  275.    languages[new_type].auto_indent       = languages[type].auto_indent;
  276.    languages[new_type].syntax            = languages[type].syntax;
  277.    languages[new_type].stile_delimiters  = languages[type].stile_delimiters;
  278.    languages[new_type].esc_character     = languages[type].esc_character;
  279.    languages[new_type].sensitive         = languages[type].sensitive;
  280.    languages[new_type].expand            = languages[type].expand;
  281.    for(word in languages[type].category)
  282.    {
  283.       languages[new_type].category[word].name       = languages[type].category[word].name;
  284.       languages[new_type].category[word].foreground = languages[type].category[word].foreground;
  285.       languages[new_type].category[word].background = languages[type].category[word].background;
  286.    }
  287.    for(word in languages[type].keyword)
  288.    {
  289.       languages[new_type].keyword[word] = languages[type].keyword[word];
  290.    }
  291.    for(word in languages[type].line)
  292.    {
  293.       languages[new_type].line[word] = languages[type].line[word];
  294.    }
  295.    for(word in languages[type].block)
  296.    {
  297.       languages[new_type].block[word] = languages[type].block[word];
  298.    }
  299. }
  300.  
  301. ################################################################################
  302. #  
  303. #  Type Query functions
  304. #  
  305. ################################################################################
  306.  
  307. global function Modified(index)
  308. {
  309.    local result = "";
  310.  
  311.    if(validate_index(index))
  312.       index = local_index;
  313.  
  314.    if(index in languages)
  315.       result = languages[index].modified;
  316.  
  317.    return result;
  318. }
  319.  
  320. global function CompilerName(index)
  321. {
  322.    local result = "";
  323.  
  324.    if(validate_index(index))
  325.       index = local_index;
  326.  
  327.    if(index in languages)
  328.       result = languages[index].compiler_name;
  329.  
  330.    return result;
  331. }
  332.  
  333. #  
  334. #  Return template of given type/ext.  Default is "text"
  335. #  
  336. global function Template(index)
  337. {
  338.    local result = "text";
  339.  
  340.    if(validate_index(index))
  341.       index = local_index;
  342.  
  343.    if(index in languages)
  344.       result = languages[index].template;
  345.  
  346.    return result;
  347. }
  348.  
  349.  
  350. global function Tabs(index)
  351. {
  352.    local result = "";
  353.  
  354.    if(validate_index(index))
  355.       index = local_index;
  356.  
  357.    if(index in languages)
  358.       result = languages[index].tab_stops;
  359.  
  360.    return result;
  361. }
  362.  
  363. global function Margins(index)
  364. {
  365.    local result = "";
  366.  
  367.    if(validate_index(index))
  368.       index = local_index;
  369.  
  370.    if(index in languages)
  371.       result = languages[index].margins;
  372.  
  373.    return result;
  374. }
  375.  
  376. global function LeftMargin(index)
  377. {
  378.    local arr, result = "";
  379.  
  380.    if(validate_index(index))
  381.       index = local_index;
  382.  
  383.    if(index in languages)
  384.    {
  385.       split(languages[index].margins, arr);
  386.       result = arr[1];
  387.    }
  388.  
  389.    return result;
  390. }
  391.  
  392. global function RightMargin(index)
  393. {
  394.    local arr, result = "";
  395.  
  396.    if(validate_index(index))
  397.       index = local_index;
  398.  
  399.    if(index in languages)
  400.    {
  401.       split(languages[index].margins, arr);
  402.       result = arr[2];
  403.    }
  404.  
  405.    return result;
  406. }
  407.  
  408. global function MatchingPairs(index)
  409. {
  410.    local result = "";
  411.  
  412.    if(validate_index(index))
  413.       index = local_index;
  414.  
  415.    if(index in languages)
  416.       result = languages[index].matching_pairs;
  417.  
  418.    return result;
  419. }
  420.  
  421. global function BufferFlags(index)
  422. {
  423.    local result = "";
  424.  
  425.    if(validate_index(index))
  426.       index = local_index;
  427.  
  428.    if(index in languages)
  429.       result = languages[index].buff_flags;
  430.  
  431.    return result;
  432. }
  433.  
  434. global function AutoIndent(index)
  435. {
  436.    local result = "";
  437.  
  438.    if(validate_index(index))
  439.       index = local_index;
  440.  
  441.    if(index in languages)
  442.       result = languages[index].auto_indent;
  443.  
  444.    return result;
  445. }
  446.  
  447. global function get_category_name(index, item)
  448. {
  449.    local result = "";
  450.  
  451.    if(validate_index(index))
  452.       index = local_index;
  453.  
  454.    if((index in languages) && item)
  455.    {
  456.       result = Block(index, item, CATEGORY_MASK);
  457.       if(result < 0)
  458.       {
  459.          result = Line(index, item, CATEGORY_MASK);
  460.          if(result < 0)
  461.             result = Keyword(index, item, CATEGORY_MASK);
  462.       }
  463.       if(result > -1)
  464.          result = Category(index, result);
  465.       else
  466.          result = "";
  467.    }
  468.  
  469.    return result;
  470. }
  471.  
  472. #  
  473. #  1 parameter - return category array
  474. #  1 < parameters - if word is an index return name of "word"th category
  475. #         or foreground color of category[word]
  476. #         or background color of category[word]
  477. #                 - if word is a category name, return index of category "word"
  478. #         or foreground color of category "word"
  479. #         or background color of category "word"
  480. #  
  481. global function Category(index, word, isfg)
  482. {
  483.    local result = "", ind, found = FALSE;
  484.  
  485.    if(validate_index(index))
  486.       index = local_index;
  487.  
  488.    if(index in languages)
  489.    {
  490.       if(argcount() > 1)
  491.       {
  492.          if(word in languages[index].category)
  493.          {
  494.             if(isfg == 1)
  495.                result = languages[index].category[word].foreground;
  496.             else if(isfg == 2)
  497.                result = languages[index].category[word].background;
  498.             else
  499.                result = languages[index].category[word].name;
  500.          }
  501.          else
  502.          {
  503.             #  word not in category array;
  504.             #  check to see if word is a category name and not a category index
  505.  
  506.             for(ind in languages[index].category)
  507.             {
  508.                if(languages[index].category[ind].name == word)
  509.                {
  510.                   found = TRUE;
  511.                   if(isfg == 1)
  512.                      result = languages[index].category[ind].foreground;
  513.                   else if(isfg == 2)
  514.                      result = languages[index].category[ind].background;
  515.                   else
  516.                      result = ind;
  517.                   break;
  518.                }
  519.             }
  520.             if(!found)
  521.                result = -1;
  522.          }
  523.       }
  524.       else
  525.          result = languages[index].category;
  526.    }
  527.  
  528.    return result;
  529. }
  530.  
  531. global ITEM_MASK     = 0xffffff00;
  532. global CATEGORY_MASK = 0xffff00ff;
  533. global FLAG_MASK     = 0xff00ffff;
  534. global COLUMN_MASK   = 0x00ffffff;
  535.  
  536. global function Keyword(index, word, MASK)
  537. {
  538.    local result = -1;
  539.  
  540.    if(validate_index(index))
  541.       index = local_index;
  542.  
  543.    if(index in languages)
  544.    {
  545.       if(argcount() >= 2)
  546.       {
  547.          if(word in languages[index].keyword)
  548.          {
  549.             if(MASK)
  550.             {
  551.                result = and(languages[index].keyword[word], not(MASK));
  552.                if(MASK == CATEGORY_MASK)
  553.                   result = shiftr(result, 8);
  554.                else if(MASK == FLAG_MASK)
  555.                   result = shiftr(result, 16);
  556.                else if(MASK == COLUMN_MASK)
  557.                   result = shiftr(result, 24);
  558.             }
  559.             else
  560.                result = languages[index].keyword[word];
  561.          }
  562.       }
  563.       else
  564.          result = languages[index].keyword;
  565.    }
  566.  
  567.    return result;
  568. }
  569.  
  570. global function Line(index, word, MASK)
  571. {
  572.    local result = -1;
  573.  
  574.    if(validate_index(index))
  575.       index = local_index;
  576.  
  577.    if(index in languages)
  578.    {
  579.       if(argcount() >= 2)
  580.       {
  581.          if(word in languages[index].line)
  582.          {
  583.             if(MASK)
  584.             {
  585.                result = and(languages[index].line[word], not(MASK));
  586.                if(MASK == CATEGORY_MASK)
  587.                   result = shiftr(result, 8);
  588.                else if(MASK == FLAG_MASK)
  589.                   result = shiftr(result, 16);
  590.                else if(MASK == COLUMN_MASK)
  591.                   result = shiftr(result, 24);
  592.             }
  593.             else
  594.                result = languages[index].line[word];
  595.          }
  596.       }
  597.       else
  598.          result = languages[index].line;
  599.    }
  600.  
  601.    return result;
  602. }
  603.  
  604. global function Block(index, word, MASK)
  605. {
  606.    local result = -1;
  607.  
  608.    if(validate_index(index))
  609.       index = local_index;
  610.  
  611.    if(index in languages)
  612.    {
  613.       if(argcount() >= 2)
  614.       {
  615.          if(word in languages[index].block)
  616.          {
  617.             if(MASK)
  618.             {
  619.                result = and(languages[index].block[word], not(MASK));
  620.                if(MASK == CATEGORY_MASK)
  621.                   result = shiftr(result, 8);
  622.                else if(MASK == FLAG_MASK)
  623.                   result = shiftr(result, 16);
  624.                else if(MASK == COLUMN_MASK)
  625.                   result = shiftr(result, 24);
  626.             }
  627.             else
  628.                result = languages[index].block[word];
  629.          }
  630.       }
  631.       else
  632.          result = languages[index].block;
  633.    }
  634.  
  635.    return result;
  636. }
  637.  
  638. global function Syntax(index)
  639. {
  640.    local result = "";
  641.  
  642.    if(validate_index(index))
  643.       index = local_index;
  644.  
  645.    if(index in languages)
  646.       result = languages[index].syntax;
  647.  
  648.    return result;
  649. }
  650.  
  651. global function StyleDelimiters(index)
  652. {
  653.    local result = "";
  654.  
  655.    if(validate_index(index))
  656.       index = local_index;
  657.  
  658.    if(index in languages)
  659.       result = languages[index].stile_delimiters;
  660.  
  661.    return result;
  662. }
  663.  
  664. global function get_case_sensitive(index)
  665. {
  666.    local result = 0;
  667.  
  668.    if(validate_index(index))
  669.       index = local_index;
  670.  
  671.    if(index in languages)
  672.       result = languages[index].sensitive;
  673.  
  674.    return result;
  675. }
  676.  
  677. global function get_expand_template(index)
  678. {
  679.    local result = 0;
  680.  
  681.    if(validate_index(index))
  682.       index = local_index;
  683.  
  684.    if(index in languages)
  685.       result = languages[index].expand;
  686.  
  687.    return result;
  688. }
  689.  
  690. #
  691. # wp_mode( flags )
  692. #
  693. local WRAP                 = 0x01
  694. local AUTO_FLOW            = 0x02
  695. local CARRY_DOWN_COMMENTS  = 0x04
  696. global function wp_mode( flags )
  697. {
  698.    local result = 0;
  699.  
  700.    if ( argcount() < 1 )
  701.       flags = buffer_flags
  702.   
  703.    if ( and(flags, BUFFER_WP_ENABLED) )
  704.    {
  705.       result = WRAP;
  706.  
  707.       if ( and(flags, BUFFER_WP_WRAP_CONTINUOUS) )
  708.          result = or(result, AUTO_FLOW);
  709.  
  710.  
  711.       if ( and(flags, BUFFER_WP_CARRY_COMMENTS) )
  712.          result = or(result, CARRY_DOWN_COMMENTS);
  713.    }
  714.  
  715.    return result;
  716. }
  717.  
  718. global function get_word_mode(index)
  719. {
  720.    local mode
  721.    local flags
  722.  
  723.    if ( argcount() < 1 )
  724.    {
  725.       flags = buffer_flags
  726.    }
  727.    else
  728.    {
  729.       if(validate_index(index))
  730.          index = local_index;
  731.  
  732.       flags = BufferFlags(index)
  733.    }
  734.  
  735.    mode = wp_mode( flags )
  736.  
  737.    return mode
  738. }
  739.  
  740. global function set_word_mode( mode )
  741. {
  742.    if ( argcount() )
  743.    {
  744.       if ( and(mode, WRAP) )
  745.       {
  746.          buffer_flags = or( buffer_flags, BUFFER_WP_ENABLED )
  747.         
  748.          if ( and(mode, AUTO_FLOW) )
  749.             buffer_flags = or( buffer_flags, BUFFER_WP_WRAP_CONTINUOUS )
  750.          else
  751.             buffer_flags = and( buffer_flags, not(BUFFER_WP_WRAP_CONTINUOUS) )
  752.            
  753.          if ( and(mode, CARRY_DOWN_COMMENTS) )
  754.             buffer_flags = or( buffer_flags, BUFFER_WP_CARRY_COMMENTS )
  755.          else
  756.             buffer_flags = and( buffer_flags, not(BUFFER_WP_CARRY_COMMENTS) )
  757.       }
  758.       else
  759.       {
  760.          buffer_flags = and( buffer_flags, not(BUFFER_WP_ENABLED) )
  761.          buffer_flags = and( buffer_flags, not(BUFFER_WP_WRAP_CONTINUOUS) )
  762.          buffer_flags = and( buffer_flags, not(BUFFER_WP_CARRY_COMMENTS) )
  763.       }
  764.    }
  765. }
  766.  
  767. global function EscapeCharacter(index)
  768. {
  769.    local result = "";
  770.  
  771.    if(validate_index(index))
  772.       index = local_index;
  773.  
  774.    if(index in languages)
  775.       result = languages[index].esc_character;
  776.  
  777.    return result;
  778. }
  779.  
  780. global function Style(index, item)
  781. {
  782.    local result = 0;
  783.  
  784.    if(validate_index(index))
  785.       index = local_index;
  786.  
  787.    if(index in languages)
  788.    {
  789.       if(item in languages[index].block)
  790.          result = BLOCK;
  791.       else if(item in languages[index].line)
  792.          result = LINE;
  793.       else if(item in languages[index].keyword)
  794.          result = KEYWORD;
  795.    }
  796.  
  797.    return result;
  798. }
  799.  
  800.  
  801.  
  802. ################################################################################
  803. #  
  804. #  Type Set functions
  805. #  
  806. ################################################################################
  807. local local_index;
  808.  
  809. local function validate_index(index)
  810. {
  811.    local ret_val = TRUE;
  812.  
  813.    if(prefix(index, 1) == ".")
  814.    {
  815.       if(index in extensions)
  816.          local_index = extensions[index];
  817.       else
  818.       {
  819.          local_index = DEFAULT;
  820.          #  warning("tried to use non-existent extension in %s", function_caller());
  821.          ret_val = FALSE;
  822.       }
  823.    }
  824.    else
  825.       local_index = index;
  826.  
  827.    return ret_val;
  828. }
  829.  
  830. global function set_modified(index, value)
  831. {
  832.    validate_index(index);
  833.    languages[local_index].modified = value;
  834. }
  835.  
  836. global function set_compiler_name(index, value)
  837. {
  838.    validate_index(index);
  839.    languages[local_index].compiler_name = value;
  840. }
  841.  
  842. global function set_template(index, value)
  843. {
  844.    validate_index(index);
  845.    languages[local_index].template = value;
  846. }
  847.  
  848. global function set_tabs(index, value)
  849. {
  850.    validate_index(index);
  851.    languages[local_index].tab_stops = value;
  852. }
  853.  
  854. global function set_pairs(index, value)
  855. {
  856.    validate_index(index);
  857.    languages[local_index].matching_pairs = value;
  858. }
  859.  
  860. global function set_margins(index, value)
  861. {
  862.    validate_index(index);
  863.    languages[local_index].margins = value;
  864. }
  865.  
  866. global function set_buffer_flags(index, value)
  867. {
  868.    validate_index(index);
  869.    languages[local_index].buff_flags = value;
  870. }
  871.  
  872. global function set_auto_indent(index, value)
  873. {
  874.    validate_index(index);
  875.    languages[local_index].auto_indent = value;
  876. }
  877.  
  878. global function set_category(index, value1, value2, isfg)
  879. {
  880.    local word, i = 1, done = FALSE, count = argcount();
  881.  
  882.    validate_index(index);
  883.    
  884.    if(count >= 3)
  885.    {
  886.       if(isfg == 1)
  887.          languages[local_index].category[value1].foreground = value2;
  888.       else if(isfg == 2)
  889.          languages[local_index].category[value1].background = value2;
  890.       else
  891.          languages[local_index].category[value1].name = value2;
  892.    }
  893.    else if(count == 1)
  894.       delete languages[local_index].category;
  895.    else
  896.    {
  897.       do
  898.       {
  899.          if(i in languages[local_index].category)
  900.             i++;
  901.          else
  902.          {
  903.             languages[local_index].category[i].name = value1;
  904.             done = TRUE;
  905.          }
  906.       } while(!done);
  907.    }
  908.  
  909.    return i;
  910. }
  911.  
  912. global function set_keyword(index, value1, value2, MASK)
  913. {
  914.    local word;
  915.  
  916.    validate_index(index);
  917.    
  918.    if(argcount() > 2)
  919.    {
  920.       if(MASK)
  921.       {
  922.          if(MASK == CATEGORY_MASK)
  923.             value2 = shiftl(value2, 8);
  924.          else if(MASK == FLAG_MASK)
  925.             value2 = shiftl(value2, 16);
  926.          else if(MASK == COLUMN_MASK)
  927.             value2 = shiftl(value2, 24);
  928.    
  929.          languages[local_index].keyword[value1] = and(languages[local_index].keyword[value1], MASK);
  930.          languages[local_index].keyword[value1] =  or(languages[local_index].keyword[value1], value2);
  931.       }
  932.       else
  933.          languages[local_index].keyword[value1] = value2;
  934.    }
  935.    else
  936.    {
  937.       if(value1)
  938.       {
  939.          for(word in value1)
  940.             languages[local_index].keyword[word] = value1[word];
  941.       }
  942.       else
  943.          delete languages[local_index].keyword;
  944.    }
  945.  
  946. }
  947.  
  948. global function set_line(index, value1, value2, MASK)
  949. {
  950.    local word;
  951.  
  952.    validate_index(index);
  953.  
  954.    if(argcount() > 2)
  955.    {
  956.       if(MASK)
  957.       {
  958.          if(MASK == CATEGORY_MASK)
  959.             value2 = shiftl(value2, 8);
  960.          else if(MASK == FLAG_MASK)
  961.             value2 = shiftl(value2, 16);
  962.          else if(MASK == COLUMN_MASK)
  963.             value2 = shiftl(value2, 24);
  964.    
  965.          languages[local_index].line[value1] = and(languages[local_index].line[value1], MASK);
  966.          languages[local_index].line[value1] =  or(languages[local_index].line[value1], value2);
  967.       }
  968.       else
  969.          languages[local_index].line[value1] = value2;
  970.    }
  971.    else
  972.    {
  973.       if(value1)
  974.       {
  975.          for(word in value1)
  976.             languages[local_index].line[word] = value1[word];
  977.       }
  978.       else
  979.          delete languages[local_index].line;
  980.    }
  981.  
  982. }
  983.  
  984. global function set_block(index, value1, value2, MASK)
  985. {
  986.    local word;
  987.  
  988.    validate_index(index);
  989.  
  990.    if(argcount() > 2)
  991.    {
  992.       if(MASK)
  993.       {
  994.          if(MASK == CATEGORY_MASK)
  995.             value2 = shiftl(value2, 8);
  996.          else if(MASK == FLAG_MASK)
  997.             value2 = shiftl(value2, 16);
  998.          else if(MASK == COLUMN_MASK)
  999.             value2 = shiftl(value2, 24);
  1000.    
  1001.          languages[local_index].block[value1] = and(languages[local_index].block[value1], MASK);
  1002.          languages[local_index].block[value1] =  or(languages[local_index].block[value1], value2);
  1003.       }
  1004.       else
  1005.          languages[local_index].block[value1] = value2;
  1006.    }
  1007.    else
  1008.    {
  1009.       if(value1)
  1010.       {
  1011.          for(word in value1)
  1012.             languages[local_index].block[word] = value1[word];
  1013.       }
  1014.       else
  1015.          delete languages[local_index].block;
  1016.    }
  1017.  
  1018. }
  1019.  
  1020. global function set_left_margin(index, value)
  1021. {
  1022.    local arr;
  1023.  
  1024.    validate_index(index);
  1025.    split(languages[local_index].margins, arr);
  1026.  
  1027.    languages[local_index].margins = value " " arr[2];
  1028. }
  1029.  
  1030. global function set_right_margin(index, value)
  1031. {
  1032.    local arr;
  1033.  
  1034.    validate_index(index);
  1035.    split(languages[local_index].margins, arr);
  1036.  
  1037.    languages[local_index].margins = arr[1] " " value;
  1038. }
  1039.  
  1040. global function set_syntax(index, value)
  1041. {
  1042.    validate_index(index);
  1043.    languages[local_index].syntax = value;
  1044. }
  1045.  
  1046. global function set_style_delimiters(index, value)
  1047. {
  1048.    validate_index(index);
  1049.    languages[local_index].stile_delimiters = value;
  1050. }
  1051.  
  1052. global function set_case_sensitive(index, value)
  1053. {
  1054.    validate_index(index);
  1055.    languages[local_index].sensitive = value;
  1056. }
  1057.  
  1058. global function set_escape_character(index, value)
  1059. {
  1060.    validate_index(index);
  1061.    languages[local_index].esc_character = value;
  1062. }
  1063.  
  1064. global function set_expand_template(index, value)
  1065. {
  1066.    validate_index(index);
  1067.    languages[local_index].expand = value;
  1068. }
  1069.  
  1070.  
  1071. ################################################################################
  1072. #  
  1073. #  Compiler Query Functions
  1074. #  
  1075. ################################################################################
  1076.  
  1077. global function CommandLine(index, expand, fname)
  1078. {
  1079.    local result
  1080.    local compiler = getCompiler(index)
  1081.  
  1082.    if (compiler+0 < 0)
  1083.       result = ""
  1084.    else
  1085.    {
  1086.       result = compilers[compiler].command_line;
  1087.       if(expand)
  1088.       {
  1089.          result = expand_command(result, fname)
  1090. #        gsub( /\$\</, fname, result);
  1091. #        gsub( /\$r/,  path_fname(fname), result);
  1092. #        gsub( /\$e/,  substr( path_ext(fname), 2 ), result);
  1093. #        gsub( /\$p/,  path_path(fname), result);
  1094. #        gsub( /\$a/,  locate_cpe_file(CPE_FILE_AE), result);
  1095.       }
  1096.    }
  1097.    return result
  1098. }
  1099.  
  1100. global function ErrorFormat(index)
  1101. {
  1102.    local result
  1103.    local compiler = getCompiler(index)
  1104.  
  1105.    if (compiler+0 < 0)
  1106.       result = compiler
  1107.    else
  1108.       result = compilers[compiler].error_format;
  1109.  
  1110.    return result;
  1111. }
  1112.  
  1113. global function CompilerInput(index)
  1114. {
  1115.    local file
  1116.    local state
  1117.    local compiler = getCompiler(index)
  1118.  
  1119.    if (compiler+0 < 0)
  1120.       state = compiler - 1
  1121.    else if (compilers[compiler].needs_input)
  1122.    {
  1123.       state = 1
  1124.       file  = compilers[compiler].input_file;
  1125.    }
  1126.    else
  1127.       state = -1
  1128.  
  1129.    return (state > 0) && length(file) ? file : state;
  1130. }
  1131.  
  1132. global function CompilerSaveAll(index)
  1133. {
  1134.    local result = FALSE, compiler = getCompiler(index)
  1135.  
  1136.    if(compiler+0 < 0)
  1137.       result = compiler - 1
  1138.    else
  1139.       result = compilers[compiler].save_all;
  1140.  
  1141.    return result;
  1142. }
  1143.  
  1144. global function CompilerOutput(index)
  1145. {
  1146.    local state
  1147.    local compiler = getCompiler(index)
  1148.  
  1149.    if (compiler+0 < 0)
  1150.       state = compiler
  1151.    else
  1152.       state = compilers[compiler].list_all
  1153.  
  1154.    return state;
  1155. }
  1156.  
  1157. global function CompilerChdir(index)
  1158. {
  1159.    local state
  1160.    local compiler = getCompiler(index)
  1161.  
  1162.    if (compiler+0 < 0)
  1163.       state = compiler
  1164.    else
  1165.       state = compilers[compiler].chdir
  1166.  
  1167.    return state;
  1168. }
  1169.  
  1170. global function CompilerBackground(index)
  1171. {
  1172.    local state
  1173.    local compiler = getCompiler(index)
  1174.  
  1175.    if (compiler+0 < 0)
  1176.       state = compiler
  1177.    else
  1178.       state = compilers[compiler].background
  1179.  
  1180.    return state;
  1181. }
  1182.  
  1183. global function CompilerFlags(index)
  1184. {
  1185.    local state
  1186.    local compiler = getCompiler(index)
  1187.  
  1188.    if (compiler+0 < 0)
  1189.       state = compiler
  1190.    else
  1191.       state = compilers[compiler].flags
  1192.  
  1193.    return state;
  1194. }
  1195.  
  1196. global function CompilerDOSSettingsArray(index)
  1197. {
  1198.    local result
  1199.    local compiler = getCompiler(index)
  1200.  
  1201.    if (compiler+0 < 0)
  1202.       result = compiler
  1203.    else
  1204.       result = compilers[compiler].dos_settings
  1205.  
  1206.    return result;
  1207. }
  1208.  
  1209. ################################################################################
  1210. #  
  1211. #  Compiler Set Functions
  1212. #  
  1213. ################################################################################
  1214.  
  1215. global function set_command_line(compiler, value)
  1216. {
  1217.    compilers[compiler].command_line = value;
  1218. }
  1219.  
  1220. global function set_error_format(compiler, value)
  1221. {
  1222.    compilers[compiler].error_format = value;
  1223. }
  1224.  
  1225. global function set_compiler_input(compiler, state, file)
  1226. {
  1227.    compilers[compiler].needs_input = state;
  1228.    compilers[compiler].input_file  = state ? file : "";;
  1229. }
  1230.  
  1231. global function set_compiler_save_all(compiler, save)
  1232. {
  1233.    compilers[compiler].save_all = save;
  1234. }
  1235.  
  1236. global function set_compiler_output(compiler, state)
  1237. {
  1238.    compilers[compiler].list_all = state;
  1239. }
  1240.  
  1241. global function set_compiler_chdir(compiler, state)
  1242. {
  1243.    compilers[compiler].chdir = state;
  1244. }
  1245.  
  1246. global function set_compiler_background(compiler, state)
  1247. {
  1248.    compilers[compiler].background = state;
  1249. }
  1250.  
  1251. global function set_compiler_flags(compiler, state)
  1252. {
  1253.    compilers[compiler].flags = state;
  1254. }
  1255.  
  1256. global function set_compiler_dos_settings_array(compiler, table)
  1257. {
  1258.    compilers[compiler].dos_settings = table;
  1259. }
  1260.  
  1261. global function set_compiler_dos_setting(compiler, setting, value)
  1262. {
  1263.    compilers[compiler].dos_settings[setting] = value;
  1264. }
  1265.  
  1266. global function copy_compiler(old, new)
  1267. {
  1268.    local setting;
  1269.  
  1270.    compilers[new].command_line = compilers[old].command_line;
  1271.    compilers[new].error_format = compilers[old].error_format;
  1272.    compilers[new].needs_input  = compilers[old].needs_input;
  1273.    compilers[new].input_file   = compilers[old].input_file;
  1274.    compilers[new].save_all     = compilers[old].save_all;
  1275.    compilers[new].list_all     = compilers[old].list_all;
  1276.    compilers[new].chdir        = compilers[old].chdir;
  1277.    compilers[new].background   = compilers[old].background;
  1278.    compilers[new].flags        = compilers[old].flags;
  1279.  
  1280.    delete compilers[new].dos_settings;
  1281.    for(setting in compilers[old].dos_settings)
  1282.       compilers[new].dos_settings[setting] = compilers[old].dos_settings[setting];
  1283. }
  1284.  
  1285. ################################################################################
  1286.  
  1287. global function add_extension(ext, type)
  1288. {
  1289.    extensions[ext] = type;
  1290. }
  1291.  
  1292. global function add_syntax_item(type, style, word, value, MASK)
  1293. {
  1294.    if((style != LINE) && (style != KEYWORD) && (style != BLOCK))
  1295.       style = tolower(style);
  1296.  
  1297.    if((style == LINE) || (style == "line"))
  1298.       set_line(type, word, value+0, MASK);
  1299.    else if((style == KEYWORD) || (style == "keyword"))
  1300.       set_keyword(type, word, value+0, MASK);
  1301.    else if((style == BLOCK) || (style == "block"))
  1302.       set_block(type, word, value+0, MASK);
  1303. }
  1304.  
  1305. global function add_syntax_category(type, index, name, fg, bg)
  1306. {
  1307.    if(index < 0)
  1308.    {
  1309.       #  Check to see if name is already a category name;
  1310.       index = Category(type, name) +0;
  1311.       if(index < 0)
  1312.       {
  1313.          index = set_category(type, name);   #  Add it and get its index;
  1314.       }
  1315.    }
  1316.  
  1317.    set_category(type, index, name);
  1318.    set_category(type, index, fg, 1);
  1319.    set_category(type, index, bg, 2);
  1320. }
  1321.  
  1322. global function add_type(index, comp_name, plate, stops, mrgns, matching, 
  1323.                          esc_char, flags, indent, syntx, stile_delims, no_case, expand_temp)
  1324. {
  1325.    if(argcount() > 1)
  1326.    {
  1327.       languages[index].compiler_name     = comp_name;
  1328.       languages[index].template          = plate;
  1329.       languages[index].tab_stops         = stops;
  1330.       languages[index].margins           = mrgns;
  1331.       languages[index].matching_pairs    = matching;
  1332.       languages[index].buff_flags        = flags;
  1333.       languages[index].auto_indent       = indent;
  1334.       languages[index].syntax            = syntx;
  1335.       languages[index].stile_delimiters  = stile_delims;
  1336.       languages[index].esc_character     = esc_char;
  1337.       languages[index].sensitive         = no_case;
  1338.       languages[index].expand            = expand_temp;
  1339.    }
  1340.    else if(index == CURRENT_BUFFER)
  1341.    {
  1342.       languages[index].compiler_name     = "";
  1343.       languages[index].template          = "";
  1344.       languages[index].tab_stops         = buffer_tabs;
  1345.       languages[index].margins           = wp_left_margin "  " wp_right_margin;
  1346.       languages[index].matching_pairs    = matching_pairs;
  1347.       languages[index].buff_flags        = buffer_flags;
  1348.       languages[index].auto_indent       = auto_indent_mode;
  1349.       languages[index].syntax            = syntax_highlight;
  1350.       languages[index].stile_delimiters  = style_delimiter;
  1351.       languages[index].esc_character     = escape_character;
  1352.       languages[index].sensitive         = case_insensitive;
  1353.       languages[index].expand            = electric_mode;
  1354.    }
  1355.    else
  1356.    {
  1357.       languages[index].compiler_name     = "";
  1358.       languages[index].template          = "";
  1359.       languages[index].tab_stops         = default_buffer_tabs;
  1360.       languages[index].margins           = default_wp_left_margin "  " default_wp_right_margin;
  1361.       languages[index].matching_pairs    = default_matching_pairs;
  1362.       languages[index].buff_flags        = default_buffer_flags;
  1363.       languages[index].auto_indent       = auto_indent_mode;
  1364.       languages[index].syntax            = default_syntax_highlight;
  1365.       languages[index].stile_delimiters  = style_delimiter;
  1366.       languages[index].esc_character     = escape_character;
  1367.       languages[index].sensitive         = case_insensitive;
  1368.       languages[index].expand            = 0;
  1369.    }
  1370.    set_factory_categories(index);
  1371.    #  add_syntax_category(index, 0, "All", COLOR_RED, -1);
  1372. }
  1373.  
  1374. global function delete_type(type)
  1375. {
  1376.    local ext;
  1377.  
  1378.    reset_languages(0);
  1379.    delete languages[type];
  1380.    reset_languages(1);
  1381.  
  1382.    for(ext in extensions)
  1383.       if(Type(ext) == type)
  1384.          SetType(ext, "");
  1385. }
  1386.  
  1387. global function delete_keyword(type, word)
  1388. {
  1389.    local value;
  1390.  
  1391.    validate_index(type);
  1392.  
  1393.    value = languages[local_index].keyword[word];
  1394.    delete languages[local_index].keyword[word]
  1395.  
  1396.    return value;
  1397. }
  1398.  
  1399. ################################################################################
  1400. #  
  1401. #  Load default functions
  1402. #  
  1403. ################################################################################
  1404.  
  1405. global function load_factory_default_extensions(add)
  1406. {
  1407.    if(!add)
  1408.       delete extensions;
  1409.  
  1410.    extensions[".ada"] = "ada";
  1411.    extensions[".asm"] = "assembler";
  1412.    extensions[".awk"] = "awk";
  1413.    extensions[".bas"] = "basic";
  1414.    extensions[".bat"] = "batch";
  1415.    extensions[".c"]   = "c";
  1416.    extensions[".h"]   = "c";
  1417.    extensions[".cpp"] = "c";
  1418.    extensions[".hpp"] = "c";
  1419.    extensions[".cxx"] = "c";
  1420.    extensions[".hxx"] = "c";
  1421.    extensions[".cbl"] = "cobol";
  1422.    extensions[".cob"] = "cobol";
  1423.    extensions[".f"]   = "fortran";
  1424.    extensions[".for"] = "fortran";
  1425.    extensions[".ipf"] = "helpfile";
  1426.    extensions[".mak"] = "makefile";
  1427.    extensions[".pas"] = "pascal";
  1428.    extensions[".pel"] = "pel";
  1429.    extensions[".rc"] = "rc";
  1430.    extensions[".dlg"] = "rc";
  1431.    extensions[".cmd"] = "rexx";
  1432.    extensions[".txt"] = "text";
  1433. }
  1434.  
  1435. global function load_factory_default_compilers(add)
  1436. {
  1437.    if(!add)
  1438.       delete compilers
  1439.  
  1440.    add_compiler("Advantage ADA", "ada $<", "ada");
  1441.    add_compiler("Borland C++", "bcc -c $<", "turboc");
  1442.    add_compiler("COBOL Compiler", "cobol $<", "other");
  1443.    add_compiler("Clipper 5.0", "clipper $< /s /w /m", "clipper5");
  1444.    add_compiler("Clipper Summer '87", "clipper $< -m -s", "clipper87");
  1445.    add_compiler("Clipper Summer '87 (preprocessor)", "pre $<", "clipper87");
  1446.    add_compiler("DOS Command Interpeter", "command.com /c $<", "none", 1, "", 1, 0, 0, 0, 512);
  1447.    add_compiler("FORCE dBase Compiler", "force $<", "force");
  1448.    add_compiler("IBM CSet++", "icc  $<", "generic");
  1449.    add_compiler("INTERSOLV PVCS Builder", "build -f $<", "build");
  1450.    add_compiler("INTERSOLV PolyMake", "make -f $<", "polymake");
  1451.    add_compiler("Lahey FORTRAN 77", "f77l $<", "lahey");
  1452.    add_compiler("Microsoft C", "cl -c $<", "c");
  1453.    add_compiler("Microsoft Masm", "masm $<,nul,asm.err;", "asm");
  1454.    add_compiler("Microsoft Quick BASIC", "qb $<", "bas");
  1455.    add_compiler("NMake", "nmake -f $<", "nmake");
  1456.    add_compiler("PEL Compiler", "pel -o $a -adis $<", "pel");
  1457.    add_compiler("Resource Compiler", "rc -r $<", "generic", 0, "");
  1458.    add_compiler("REXX Interpeter", "cmd.exe /c $<", "none", 1, "", 1);
  1459.    add_compiler("Thompson Tools Awk Compiler", "awkc $<", "none");
  1460.    add_compiler("Turbo C", "tcc -c -w $<", "turboc");
  1461.    add_compiler("Turbo C++", "tcc -c $<", "turboc");
  1462.    add_compiler("Turbo Pascal", "tpc $<", "pas");
  1463.    add_compiler("Watcom C++", "wcc386 -c $<", "watcom");
  1464.    add_compiler("Zortech C", "ztc -c -r $<", "zortech");
  1465.    add_compiler("Zortech C++", "ztc -c -cpp -r $<", "zortech");
  1466.    add_compiler("[None]", "$<", "none");
  1467. }
  1468.  
  1469. global function load_factory_default_types(add)
  1470. {
  1471.    local tab_stops = default_buffer_tabs;
  1472.    local margins = wp_left_margin " " wp_right_margin;
  1473.    local matching = default_matching_pairs;
  1474.    local escchar = "\\"
  1475.    local flags = default_buffer_flags;
  1476.    local indent = 0;
  1477.    local syntax = 1;
  1478.    local c_pairs = "{ } [ ] ( ) /* */ #if #endif #ifdef #endif";
  1479.    local c_tabs  = "4 7";
  1480.    local delimiter = "()[];:,='"
  1481.    local no_case = 1;
  1482.  
  1483. #      ext = ".prg"
  1484. #      extension_array[ext].tabs           = "5 9"
  1485.  
  1486. #   if(!add)
  1487. #   {
  1488. #      reset_languages(0);
  1489. #      delete languages;
  1490. #   }
  1491.  
  1492. #  Cobol should have expand tabs on;
  1493.  
  1494.    add_type("ada",       "Advantage ADA",          "c",   "5 9", margins, "begin end (* *) { }", escchar, flags, indent, syntax, delimiter, no_case);
  1495.    add_type("assembler", "Microsoft Masm",         "asm",   "5 9", margins, c_pairs, escchar, flags, indent, syntax, delimiter, no_case);
  1496.    optional_function("add_awk_type");
  1497.    add_type("batch",     "DOS Command Interpeter", "[None]", "4 7", "1  77", "{ } [ ] ( ) /* */ %if %endif #if #endif #ifdef #endif", "", 8448, 0, 1, "", 0, 0);
  1498.    add_type("basic",     "IBM Basic",              "basic", tab_stops, margins, "", escchar, flags, indent, syntax, delimiter, no_case);
  1499.    add_type("c",         "Borland C++",            "c",     c_tabs, margins, c_pairs, escchar, flags, indent, syntax, delimiter, no_case);
  1500.    optional_function("add_cobol_type");
  1501.    add_type("fortran",   "Lahey FORTRAN 77",       "text",  tab_stops, margins, "", escchar, flags, indent, syntax, delimiter, no_case);
  1502.    add_type("helpfile",  "IPFC",                   "text",  tab_stops, margins, "", escchar, flags, indent, syntax, delimiter, no_case);
  1503.    add_type("makefile",  "NMake",                  "text",  tab_stops, margins, "( ) %if %endif", escchar, flags, indent, syntax, delimiter, no_case);
  1504.    optional_function("add_pascal_type");
  1505.    optional_function("add_pel_type");
  1506.    optional_function("add_rexx_type");
  1507.    add_type("rc",        "Resource Compiler",      "", "4 7", "1  77", "{ } [ ] ( ) /* */ %if %endif #if #endif #ifdef #endif begin end", "", 8448, 0, 1, "", 0, 0);
  1508.    add_type("rexx",      "REXX Interpeter",        "rexx", "4 7", "1  77", "{ } [ ] ( ) /* */ %if %endif #if #endif #ifdef #endif", "\\", 8448, 0, 1, ".();,=':", 1, 0);
  1509.    add_type("text",      "",                       "text",  tab_stops, margins, "", escchar, flags, indent, syntax, delimiter, no_case);
  1510.    optional_function("add_vdiff_ref_type");
  1511.    optional_function("add_vdiff_target_type");
  1512.    add_type(DEFAULT);
  1513. #  add_type("[None]",  comp_name, template, tab_stops, margins, "", escchar, syntax, delimiter, no_case);
  1514.  
  1515. #  if(!add)
  1516. #     reset_languages(1);
  1517. }
  1518.  
  1519. ################################################################################
  1520. #  
  1521. #  Copy array functions
  1522. #  
  1523. ################################################################################
  1524.  
  1525. global function copy_extensions_array(input)
  1526. {
  1527.    local ext, result[];
  1528.  
  1529.    for(ext in input)
  1530.       result[ext] = input[ext];
  1531.  
  1532.    return result;
  1533. }
  1534.  
  1535. global function copy_compilers_array(input)
  1536. {
  1537.    local comp, result[], setting;
  1538.  
  1539.    for(comp in input)
  1540.    {
  1541.       result[comp].error_format = input[comp].error_format;
  1542.       result[comp].command_line = input[comp].command_line;
  1543.       result[comp].needs_input  = input[comp].needs_input;
  1544.       result[comp].inpput_file  = input[comp].input_file;
  1545.       result[comp].list_all     = input[comp].list_all;
  1546.       result[comp].save_all     = input[comp].save_all;
  1547.       result[comp].chdir        = input[comp].chdir;
  1548.       result[comp].background   = input[comp].background;
  1549.       result[comp].flags        = input[comp].flags;
  1550.  
  1551.       for(setting in input[comp].dos_settings)
  1552.          result[comp].dos_settings[setting] = input[comp].dos_settings[setting];
  1553.    }
  1554.  
  1555.    return result;
  1556. }
  1557.  
  1558. global function copy_languages_array(input)
  1559. {
  1560.    local type, result[], word;
  1561.  
  1562.    for(type in input)
  1563.    {
  1564.       result[type].compiler_name    = input[type].compiler_name;
  1565.       result[type].template         = input[type].template;
  1566.       result[type].tab_stops        = input[type].tab_stops;
  1567.       result[type].margins          = input[type].margins;
  1568.       result[type].matching_pairs   = input[type].matching_pairs;
  1569.       result[type].buff_flags       = input[type].buff_flags;
  1570.       result[type].auto_indent      = input[type].auto_indent;
  1571.       result[type].esc_character    = input[type].esc_character;
  1572.       result[type].stile_delimiters = input[type].stile_delimiters;
  1573.       result[type].syntax           = input[type].syntax;
  1574.       result[type].sensitive        = input[type].sensitive;
  1575.       result[type].expand           = input[type].expand;
  1576.  
  1577.       for(word in input[type].category)
  1578.          result[type].category[word] = input[type].category[word];
  1579.  
  1580.       for(word in input[type].keyword)
  1581.          result[type].keyword[word]  = input[type].keyword[word];
  1582.  
  1583.       for(word in input[type].line)
  1584.          result[type].line[word]     = input[type].line[word];
  1585.  
  1586.       for(word in input[type].block)
  1587.          result[type].block[word]    = input[type].block[word];
  1588.    }
  1589.    return result;
  1590. }
  1591.  
  1592. #global function copy_languages_array(input, page)
  1593. #{
  1594. #   local type, result;
  1595. #
  1596. #   for(type in input)
  1597. #   {
  1598. #      if(page && (page == "compiler"))
  1599. #         result[type].compiler_name  = input[type].compiler_name;
  1600. #      else if(page && (page == "template"))
  1601. #         result[type].template       = input[type].template;
  1602. #      else if(page && (page == "syntax"))
  1603. #         result[type].syntax         = input[type].syntax;
  1604. #      else if(page && (page == "buffer2"))
  1605. #      {
  1606. #         result[type].tab_stops      = input[type].tab_stops;
  1607. #         result[type].margins        = input[type].margins;
  1608. #         result[type].matching_pairs = input[type].matching_pairs;
  1609. #         result[type].buff_flags     = input[type].buff_flags;
  1610. #         result[type].auto_indent    = input[type].auto_indent;
  1611. #      }
  1612. #   }
  1613. #
  1614. #   return result;
  1615. #}
  1616.  
  1617. ################################################################################
  1618. #  
  1619. #  Write structure functions
  1620. #  
  1621. ################################################################################
  1622. global function write_language_data()
  1623. {
  1624.    local fname, prevEol, old_buffer = current_buffer, out_fid, outfile, status, cmd;
  1625.    local language_buffer, dlgid, response = "y", old_beep = beep_string;
  1626.    local pel_comp
  1627.    local array[]
  1628.  
  1629.    fname = source_file_name(function_id("load_user_types"));
  1630.    if(!fname)
  1631.    {
  1632.       warning("language.pel could not be found.  All notebook changes will be lost.");
  1633.       return 2;
  1634.    }
  1635.  
  1636.    prevEol = default_buffer_eol_string;
  1637.    default_buffer_eol_string = "\r\n";
  1638.    language_buffer = create_buffer( "Language File"  , fname, BUFFER_SYSTEM  + 
  1639.                                                               BUFFER_NO_UNDO + 
  1640.                                                               BUFFER_REAL_SPACE_ONLY);
  1641.    current_buffer = language_buffer;
  1642.  
  1643.    # restore the default end of line sequence
  1644.    default_buffer_eol_string = prevEol;
  1645.  
  1646.    #  TODO: do a check here to see if the arrays are changed before writing them and compiling;
  1647.    #  should only really compile if we have to;
  1648.    if(and(buffer_flags, BUFFER_READ_ONLY))
  1649.    {
  1650.       set_status_bar_flags( and(status_bar_flags, not(STB_PROMPTS)));
  1651.       response = confirm(fname " is read only.  Do you want to save settings changes anyway? (yn)", "YyNn");
  1652.       restore_status_bar();
  1653.       if(tolower(response) == "y")
  1654.          toggle_buffer_flags(BUFFER_READ_ONLY, FALSE);
  1655.    }
  1656.  
  1657.    if(response == "y")
  1658.    {
  1659.       beep_string = "";
  1660.       write_extensions();
  1661.       write_compilers();
  1662.       write_types();
  1663.       write_styles();
  1664.       write_syntax();
  1665.       write_colors();
  1666.       write_buffer();
  1667.       delete_buffer(language_buffer);
  1668.       current_buffer = old_buffer;
  1669.  
  1670.       cmd     = CommandLine(".pel", 1, fname);
  1671.       outfile = create_temp_name(0, "err", "pel_" );
  1672.  
  1673.       if ( (out_fid = fopen( outfile, 2 )) != -1 )
  1674.       {
  1675.          message("compiling %s", fname)
  1676.          status  = system(cmd, 0, out_fid, out_fid, SYS_NOSESSION)
  1677.  
  1678.          fclose( out_fid );
  1679.          if (status > 0)
  1680.          {
  1681.             if(status == 65526)
  1682.             {
  1683.                #  unlink(outfile);
  1684.                warning("Invalid PEL compiler found.  Please change compile line for the PEL type.");
  1685.             }
  1686.             else
  1687.                display_errors(fname, outfile);
  1688.          }
  1689.          else if ( status == -2 )
  1690.          {
  1691.             warning("PEL Compiler not found.  Check command line for the compiler mapped to the '.pel' extension.");
  1692.             language_compiled = TRUE; #  This is set so we don't end up here again;
  1693.          }
  1694.          else
  1695.          {
  1696.             #  unlink(outfile);
  1697.             if(status == -10)
  1698.                warning("Invalid PEL compiler found.  Please change compile line for the PEL type.");
  1699.             else if (status < 0)
  1700.                warning("Unable to compile %s, Error %s", fname, status)
  1701.             else
  1702.                message("")
  1703.          }
  1704.  
  1705.          unlink(outfile);
  1706.       }
  1707.       language_compiled = TRUE;
  1708.       beep_string       = old_beep;
  1709.    }
  1710.    else
  1711.    {
  1712.       warning("Changes made to the language structure in the notebook have not been saved.");
  1713.       delete_buffer(language_buffer);
  1714.       current_buffer = old_buffer;
  1715.    }
  1716. }
  1717.  
  1718. local function my_quote(string)
  1719. {
  1720.    local r = string;
  1721.  
  1722.    gsub( "[\"\\\\]", "\\\\&", r);
  1723.  
  1724.    return r
  1725. }
  1726.  
  1727. local function write_extensions()
  1728. {
  1729.    local outline, ext;
  1730.  
  1731.    create_header("extensions");
  1732.    for(ext in extensions)
  1733.    {
  1734.       outline = sprintf("   add_extension(\"%s\", \"%s\");\n", my_quote(ext), 
  1735.                                                                my_quote(Type(ext)) );
  1736.       insert_string(outline);
  1737.    }
  1738.    end_section("extensions");
  1739. }
  1740.  
  1741. local function write_compilers()
  1742. {
  1743.    local cname, outline, s;
  1744.  
  1745.    create_header("compilers");
  1746.  
  1747.    for(cname in compilers)
  1748.    {
  1749.       outline = sprintf("   add_compiler(\"%s\", \"%s\", \"%s\", %d, \"%s\", %d, %d, %d, %d, %d);\n",
  1750.                                          my_quote(cname), 
  1751.                                          my_quote(compilers[cname].command_line),
  1752.                                          my_quote(compilers[cname].error_format),
  1753.                                          compilers[cname].needs_input > 0,
  1754.                                          my_quote(compilers[cname].input_file),
  1755.                                          compilers[cname].list_all > 0,
  1756.                                          compilers[cname].save_all > 0,
  1757.                                          compilers[cname].chdir > 0,
  1758.                                          compilers[cname].background > 0,
  1759.                                          compilers[cname].flags > 0 ? compilers[cname].flags : 0);
  1760.       insert_string(outline);
  1761.  
  1762.       if (compilers[cname].flags > 0 && and(compilers[cname].flags, SYS_DOSSHELL))
  1763.       {
  1764.          for (s in compilers[cname].dos_settings)
  1765.          {
  1766.             if (length(s) && length(compilers[cname].dos_settings[s]))
  1767.             {
  1768.                outline = sprintf("   set_compiler_dos_setting(\"%s\", \"%s\", \"%s\");\n",
  1769.                                      my_quote(cname),  my_quote(s),
  1770.                                      my_quote(compilers[cname].dos_settings[s]));
  1771.                insert_string(outline);
  1772.             }
  1773.          }
  1774.       }
  1775.    }
  1776.  
  1777.    end_section("compilers");
  1778. }
  1779.  
  1780. local function write_types()
  1781. {
  1782.    local type, outline;
  1783.  
  1784.    create_header("types");
  1785.  
  1786.    for(type in languages)
  1787.    {
  1788. #        if((type != DEFAULT) && (type != CURRENT_BUFFER))
  1789.       if(type != CURRENT_BUFFER)
  1790.       {
  1791.          outline = sprintf("   add_type(\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", %d, %d, %d, \"%s\", %d, %d);\n", 
  1792.                           my_quote(type),           my_quote(CompilerName(type)),
  1793.                           my_quote(Template(type)), my_quote(Tabs(type)),
  1794.                           my_quote(Margins(type)),  my_quote(MatchingPairs(type)),
  1795.                           quote_regex(EscapeCharacter(type)), BufferFlags(type), 
  1796.                           AutoIndent(type),         Syntax(type), 
  1797.                           my_quote(StyleDelimiters(type)), get_case_sensitive(type),
  1798.                           get_expand_template(type) );
  1799.          insert_string(outline);
  1800.       }
  1801.    }
  1802.  
  1803.    end_section("types");
  1804. }
  1805.  
  1806. global function write_syntax()
  1807. {
  1808.    local type, outline, array, item, line_count;
  1809.    local suffix = "", MAX = 200;
  1810.  
  1811.    for(type in languages)
  1812.    {
  1813.       if((type != CURRENT_BUFFER) && (type != DEFAULT) && Modified(type))
  1814.       {
  1815.          line_count = 0;
  1816.          suffix = "";
  1817.          create_header(type "_syntax" suffix);
  1818.          insert_string("   local type = \"" my_quote(type) "\";\n\n");
  1819.          line_count++;
  1820.          array = Line(type);
  1821.          for(item in array)
  1822.          {
  1823.             outline = sprintf("   add_syntax_item(type, LINE, \"%s\", 0x%x);\n", 
  1824.                               my_quote(item), array[item]);
  1825.             insert_string(outline);
  1826.             if(line_count++ > MAX)
  1827.             {
  1828.                suffix = start_new_function(type, suffix);
  1829.                line_count = 1;
  1830.             }
  1831.          }
  1832.  
  1833.          array = Keyword(type);
  1834.          for(item in array)
  1835.          {
  1836.             outline = sprintf("   add_syntax_item(type, KEYWORD, \"%s\", 0x%x);\n", 
  1837.                                my_quote(item), array[item]);
  1838.             insert_string(outline);
  1839.             if(line_count++ > MAX)
  1840.             {
  1841.                suffix = start_new_function(type, suffix);
  1842.                line_count = 1;
  1843.             }
  1844.          }
  1845.    
  1846.          array = Block(type);
  1847.          for(item in array)
  1848.          {
  1849.             outline = sprintf("   add_syntax_item(type, BLOCK, \"%s\", 0x%x);\n", 
  1850.                               my_quote(item), array[item]);
  1851.             insert_string(outline);
  1852.             if(line_count++ > MAX)
  1853.             {
  1854.                suffix = start_new_function(type, suffix);
  1855.                line_count = 1;
  1856.             }
  1857.          }
  1858.    
  1859.          array = Category(type);
  1860.          for(item in array)
  1861.          {
  1862.             outline = sprintf("   add_syntax_category(type, %d, \"%s\", %d, %d);\n", 
  1863.                               item,       my_quote(array[item].name), 
  1864.                               array[item].foreground, array[item].background);
  1865.             insert_string(outline);
  1866.             if(line_count++ > MAX)
  1867.             {
  1868.                suffix = start_new_function(type, suffix);
  1869.                line_count = 1;
  1870.             }
  1871.          }
  1872.          end_section(type "_syntax" suffix);
  1873.       }
  1874.    }
  1875. }
  1876.  
  1877. local function start_new_function(type, suffix)
  1878. {
  1879.    local old_name = type "_syntax" suffix;
  1880.    local new_name = type "_syntax"
  1881.    local new_suffix;
  1882.  
  1883.    new_suffix = suffix + 1;
  1884.    new_name = new_name new_suffix;
  1885.  
  1886.    insert_string("\n   # Function too long, had to be split\n");
  1887.    insert_string("   load_user_" new_name "(type);\n");
  1888.    end_section(old_name);
  1889.  
  1890.    create_header(new_name, 1);
  1891.  
  1892.    return new_suffix;
  1893. }
  1894.  
  1895. local function write_styles()
  1896. {
  1897.    local n = 1, FG = 0, BG = 1, still_valid = TRUE;
  1898.    local fg, bg, BAD = 0xFF000000, outline;
  1899.    local at_least_one = FALSE;
  1900.  
  1901.    create_header("styles");
  1902.  
  1903.    while((n < 256) && still_valid)
  1904.    {
  1905.       fg = query_syntax_style(n, FG);
  1906.       bg = query_syntax_style(n, BG);
  1907.       still_valid = ((fg != BAD) && (bg != BAD));
  1908.       if(still_valid)
  1909.       {
  1910.          at_least_one = TRUE;
  1911.          outline = sprintf("   defined_styles[%d][%d] = ", fg, bg);
  1912.          insert_string(outline);
  1913.          if((fg < 0) || (bg < 0))
  1914.          {
  1915.             if((fg < 0) && (bg < 0))
  1916.                outline = sprintf("create_syntax_style(%d, %d);\n", fg, bg);
  1917.             else if(fg <0)
  1918.                outline = sprintf("create_syntax_style(%d, 0x%lx);\n", fg, bg);
  1919.             else
  1920.                outline = sprintf("create_syntax_style(0x%lx, %d);\n", fg, bg);
  1921.          }
  1922.          else
  1923.             outline = sprintf("create_syntax_style(0x%lx, 0x%lx);\n", fg, bg);
  1924.  
  1925.          insert_string(outline);
  1926.       }
  1927.       n++;
  1928.    }
  1929.    if(!at_least_one)
  1930.       insert_string("optional_function(\"load_factory_default_styles\");\n");
  1931.  
  1932.    end_section("styles");
  1933. }
  1934.  
  1935.  
  1936. local function write_colors()
  1937. {
  1938.    local color, outline;
  1939.  
  1940.    create_header("syntax_colors");
  1941.  
  1942.    insert_string("   #  Foreground colors for syntax highlighting\n");
  1943.    for(color in syntax_colors_fg)
  1944.    {
  1945.       outline = sprintf("   syntax_colors_fg[%d] = 0x%06x;\n", color, syntax_colors_fg[color]);
  1946.       insert_string(outline);
  1947.    }
  1948.  
  1949.    insert_string("\n   #  Background colors for syntax highlighting\n");
  1950.    for(color in syntax_colors_bg)
  1951.    {
  1952.       outline = sprintf("   syntax_colors_bg[%d] = 0x%06x;\n", color, syntax_colors_bg[color]);
  1953.       insert_string(outline);
  1954.    }
  1955.  
  1956.    end_section("syntax_colors");
  1957. }
  1958.  
  1959. local function create_header(type, parm)
  1960. {
  1961.    save_position();
  1962.    goto_buffer_top();
  1963.    if(!search("function load_user_" type "(", SEARCH_FORWARD))
  1964.    {
  1965.       restore_position(TRUE);
  1966.  
  1967.       if(parm)
  1968.          insert_string("\nlocal function load_user_" type "(type)\n{\n\n\n} # End " type "\n");
  1969.       else
  1970.          insert_string("\nglobal function load_user_" type "()\n{\n\n\n} # End " type "\n");
  1971.       up(5);
  1972.    }
  1973.    else
  1974.    {
  1975.       restore_position();
  1976.    }
  1977.    down(2);
  1978.    goto_bol();
  1979. }
  1980.  
  1981. local function end_section(type)
  1982. {
  1983.    begin_selection(NORMAL_SELECTION);
  1984.    if(search("} # End "type, SEARCH_FORWARD))
  1985.    {
  1986.       up();
  1987.       goto_bol();
  1988.       delete_chars();
  1989.       down(2);
  1990.    }
  1991.    else
  1992.    {
  1993.       end_selection();
  1994.    }
  1995. }
  1996.