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

  1. # $Header:   P:\source\wmacros\errorfix.pev   1.123.1.0   11 Apr 1995 14:44:26   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:   errorfix.pel  $: Compiling and Error locating utilities
  21.  
  22. ## Overview of compile/errorfix language support
  23. ##
  24. ## The two most essential global functions defined here are 
  25. ## "compile_buffer()" and "goto_next_error()".  Compile_buffer uses the 
  26. ## name of the current buffer to determine what language is being used, 
  27. ## and then issues a command line to the shell invoking the appropriate 
  28. ## compiler.  Upon completion of the shell process, the captured error 
  29. ## output is passed on to the goto_next_error() function.  
  30. ## goto_next_error() knows the syntax of the error messages produced by 
  31. ## each compiler, and uses that information to find the name of the 
  32. ## source file where the error occurred, and the location within that 
  33. ## file.  The goto_next_error() function may also be invoked again 
  34. ## independently from the keyboard, where it will scan forward in the 
  35. ## error listing for the next error encountered.
  36. ##
  37. ## To add support for a new compiler, the arrays "compiler_cmd_array" 
  38. ## and "compiler_err_array" must be augmented and, depending on the 
  39. ## error message syntax of the new compiler, a new compiler-specific 
  40. ## error message parsing function may have to be added.  The function 
  41. ## add_compiler() can be used to update the compiler arrays.  It may be 
  42. ## called from within the user's local_setup() function, or from within 
  43. ## the cpe.cfg file.  For more information on adding a new error 
  44. ## message function, see the comments in function errorInfo() near the 
  45. ## end of this file.
  46. ##
  47. ## ---------------------------------------------------------------------
  48.  
  49. ## Clipper & FORCE compiler support enhancements provided by
  50. ## Pedro P. Polakoff III of 3P Software, Inc.
  51.  
  52. global compile_flags      = 0 # Flags to pass to system for the compile.
  53. global background_compile = 1 # TRUE = compile in the background.
  54. global list_all_output    = 0 # TRUE = add all compiler output to error list.
  55. global compile_input      = 0 # TRUE = force input box on all compiles.
  56. global compile_chdir      = 1 # TRUE = change to directory that contains the
  57.                               #        file to be compiled before compiling.
  58. local  errorSrcName
  59. local  errorLine
  60. local  errorColumn
  61. local  errorLength
  62. local  errorText
  63. local  errorCompleteText
  64. local  errorsFound
  65. local  errorInfoPrefix
  66.  
  67. #  typedef struct compiles
  68. #  {
  69. #     string name;
  70. #     string dlgid;
  71. #     bool   input;
  72. #     bool   output;
  73. #     string filename;
  74. #  }   current_compiles[];
  75. local  current_compiles[]
  76. local  compile_pipes[]
  77.  
  78. ## compile_buffer()
  79. #
  80. # compile the current buffer
  81. #
  82. global function compile_buffer(list_all, background, disable_dialog,
  83.                                input_file, source_file)
  84. {
  85.    local ch
  86.    local fh
  87.    local num
  88.    local cmd
  89.    local ext
  90.    local cwd
  91.    local fid2
  92.    local name
  93.    local file
  94.    local data
  95.    local fileid
  96.    local pipeid
  97.    local outfile
  98.  
  99.    local flags                = compile_flags
  100.    local in_background        = background_compile
  101.    local all_output           = list_all_output
  102.    local needs_input          = compile_input
  103.    local source_filename      = length(source_file) ? source_file : buffer_filename
  104.    local temp_file            = ""
  105.    local status               = -1
  106.    local dlgid                = 0
  107.    local fid                  = -1
  108.  
  109.    #  reset microfocus global variables incase this is not the first time through
  110.    reset_mf_globs();
  111.  
  112.    ## use the filename extension to decide which compiler to use
  113.  
  114.    ext = path_ext( source_filename );
  115.    if ( !ext )
  116.    {
  117.       # treat the name "makefile" with no extension as if it has
  118.       # a ".mak" extension
  119.       if ( path_fname( source_filename ) == "makefile" )
  120.          ext = ".mak"
  121.       else
  122.          ext = "NULL_ext"
  123.    }
  124.  
  125.    cmd = CommandLine(ext, 1, source_filename);
  126.    num = cmd+0
  127.    if (num == -1)
  128.    {
  129.       warning( "Don't know how to compile %s files.", ext );
  130.       return status;
  131.    }
  132.    else if (num == -2)
  133.    {
  134.       warning( "Don't know how to compile with the %s compiler.", name);
  135.       return status;
  136.    }
  137.    else
  138.    {
  139.       name = CompilerName(ext)
  140.       if (length(input_file))
  141.          needs_input = TRUE
  142.       else
  143.       {
  144.          file = CompilerInput(name)
  145.          num  = file+0
  146.          if (num >= 0)
  147.          {
  148.             needs_input = TRUE
  149.             if (num != 1)
  150.                input_file = file
  151.          }
  152.       }
  153.    }
  154.  
  155.    if (length(input_file))
  156.    {
  157.       if (cindex("><=+", prefix(input_file, 1)))
  158.       {
  159.          data       = substr(input_file, 2)
  160.          input_file = temp_file = create_temp_name()
  161.          fh         = fopen(input_file, 1)
  162.          fprintf(fh, "%s\n", data)
  163.          fclose(fh)
  164.       }
  165.    }
  166.  
  167.    if (!disable_dialog)
  168.    {
  169.       cmd = prompt_history( "COMPILE", "Compile command: ", cmd, 1, 1, "compile_dialog" )
  170.    }
  171.  
  172.    if ( cmd )
  173.    {
  174.       flags = or(flags, CompilerFlags(name))
  175.  
  176.       if (compile_chdir || CompilerChdir(name))
  177.       {
  178.          cwd = getcwd()
  179.          chdir(path_path(source_filename))
  180.       }
  181.  
  182.       if (argcount())
  183.       {
  184.          if (!all_output)
  185.             all_output = or(list_all, needs_input)
  186.  
  187.          if (argcount() >= 2)
  188.          {
  189.             if (!(in_background = background))
  190.                flags = and(flags, not(or(SYS_ASYNC, SYS_DETACHED)))
  191.          }
  192.          else
  193.             in_background = CompilerBackground(name)
  194.       }
  195.       else if (!all_output)
  196.          all_output = CompilerOutput(name) > 0
  197.  
  198.       if(CompilerSaveAll(name))
  199.       {
  200.          # write all modified buffers to disk;
  201.          write_all_buffers();
  202.       }
  203.       else
  204.       {
  205.          # write current buffer to disk if modified;
  206.          if (and(buffer_flags, BUFFER_MODIFIED))
  207.             write_buffer_key()
  208.       }
  209.  
  210.       # Do not compile PEL in the background as this causes problems!
  211.       if (ext != ".pel" && (ErrorFormat(ext) != "microfocus") && !and(flags, SYS_DOSSHELL) && \
  212.           (in_background || and(flags, or(SYS_ASYNC, SYS_DETACHED))))
  213.       {
  214.          pipeid = create_pipes()
  215.       }
  216.       else
  217.          pipeid = 0
  218.  
  219.       errorsFound = 0
  220.  
  221.       if (!disable_dialog)
  222.       {
  223.          dlgid = create_compile_dialog(source_filename, needs_input && pipeid)
  224.          set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  225.                            "Compiling " source_filename "...")
  226.       }
  227.       else
  228.          message("Compiling %s...", source_filename)
  229.  
  230.       if (pipeid)
  231.       {
  232.          status = system( cmd, pipeid, pipeid, pipeid, or(flags, SYS_ASYNC) )
  233.          if ( status > 0 )
  234.          {
  235.             attach_event_handler(EVENT.PROCESS_COMPLETE, function_id("check_compile"))
  236.             attach_event_handler(EVENT.PIPE_DATA, function_id("pipedata") )
  237.  
  238.             if (dlgid)
  239.             {
  240.                set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_ENABLE )
  241.                compile_pipes[dlgid] = pipeid
  242.             }
  243.  
  244.             current_compiles[pipeid].name      = name
  245.             current_compiles[pipeid].dlgid     = dlgid
  246.             current_compiles[pipeid].input     = needs_input
  247.             current_compiles[pipeid].output    = all_output
  248.             current_compiles[pipeid].filename  = source_filename
  249.  
  250.             process_pipes( pipeid, 1, 0 )
  251.  
  252.             if (dlgid && needs_input)
  253.                set_dialog_item(dlgid, DI_INPUT, DAC_SETFOCUS)
  254.  
  255.             # stuff the input data down the pipe.
  256.             if (length(input_file))
  257.             {
  258.                fid = fopen(input_file, 0)
  259.                if (fid > -1)
  260.                {
  261.                   while ((data = fgets(fid)))
  262.                      pputs(data "\n", pipeid)
  263.  
  264.                   fclose(fid)
  265.                }
  266.                else
  267.                   warning("unable to open %s for input", input_file)
  268.             }
  269.          }
  270.          else if ( pipeid )
  271.             close_pipes(pipeid)
  272.       }
  273.       else
  274.       {
  275.          idle(TRUE)
  276.          outfile = create_temp_name(0, "err", ltrim(ext, ".") "_" )
  277.  
  278.          if (and(flags, SYS_DOSSHELL))
  279.          {
  280.             status  = system( cmd, input_file, outfile, outfile, 
  281.                               and(flags, not(or(SYS_ASYNC, SYS_DETACHED))),
  282.                               CompilerDOSSettingsArray(name))
  283.          }
  284.          else if ( (fid = fopen( outfile, 2 )) != -1 )
  285.          {
  286.             status  = system( cmd, input_file, fid, fid, 
  287.                               and(flags, not(or(SYS_ASYNC, SYS_DETACHED))))
  288.             fclose( fid )
  289.          }
  290.          else
  291.          {
  292.             warning( "could not create temp file %s", outfile )
  293.             status = -1
  294.          }
  295.  
  296.          if ( status >= 0 )
  297.          {
  298.             if( ErrorFormat(ext) == "microfocus")
  299.             {
  300.                unlink(outfile);
  301.                outfile = path_path(buffer_filename) path_fname(buffer_filename) ".lst";
  302.                display_errors(source_filename, outfile, name, all_output,
  303.                            dlgid, TRUE)
  304.             }
  305.             else
  306.                display_errors(source_filename, outfile, name, all_output,
  307.                            dlgid, FALSE)
  308.          }
  309.  
  310.          if ( !errorsFound && status > 0)
  311.          {
  312.             if (dlgid)
  313.             {
  314.                set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  315.                                  "Compile returned error code " status ".")
  316.             }
  317.             else
  318.                warning("Compile returned error code " status ".")
  319.          }
  320.       }
  321.  
  322.       if ( status < 0 )
  323.       {
  324.          if (dlgid)
  325.          {
  326.             set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  327.                               "Unable to execute compile command, Error code = " status ".")
  328.          }
  329.          else
  330.             warning("Unable to execute compile command, Error code = " status ".")
  331.       }
  332.  
  333.       if (length(temp_file))
  334.          unlink(temp_file)
  335.  
  336.       if (compile_chdir)
  337.          chdir(cwd)
  338.    }
  339.    return status
  340. }
  341.  
  342. # called to create the compile dialog
  343. local function create_compile_dialog(source_filename, needs_input)
  344. {
  345.    local dlgid = create_list_dialog("Compile - " source_filename,             \
  346.                                     editor_helpfile, "compile_list_callback", \
  347.                                     needs_input);
  348.  
  349.    set_dialog_item(dlgid, DI_GOTO_BUTTON, DAC_DISABLE )
  350.    set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_DISABLE )
  351.    set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_DISABLE )
  352.    set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_DISABLE )
  353.    begin_list_dialog(dlgid)
  354.    return dlgid
  355. }
  356.  
  357. # called to query whether the dialog has an input box.
  358. global function compile_has_input( dlghand )
  359. {
  360.    if ( dlghand in compile_pipes )
  361.       return current_compiles[compile_pipes[dlghand]].needs_input > 0
  362.    else
  363.       return 0
  364. }
  365.  
  366. # called when the stop button on the compile dialog box is pressed
  367. global function stop_button_pressed( dlghand )
  368. {
  369.    if ( argcount() < 1 )
  370.       dlghand = callback_dialog_handle 
  371.  
  372.     if ( dlghand in compile_pipes )
  373.        close_pipes( compile_pipes[dlghand] )
  374.  
  375.    process_background(STOP_BACKGROUND)
  376.  
  377.    if ( fileid != -1 )
  378.    {
  379.       fclose(fileid)
  380.       fileid = -1
  381.    }
  382. }
  383.  
  384. # called when the compile dialog box is closed
  385. global function close_dialog_box( dlghand )
  386. {
  387.    if ( argcount() < 1 )
  388.       dlghand = callback_dialog_handle 
  389.  
  390.     if ( dlghand in compile_pipes )
  391.        close_pipes( compile_pipes[dlghand] )
  392. }
  393.  
  394. # called when the enter button is pressed.
  395. global function send_compile_data( dlghand, data )
  396. {
  397.    if ( dlghand in compile_pipes )
  398.    {
  399.       set_dialog_item(dlghand, IDL_LIST, DAC_SELECT_INDEX, 
  400.                       add_item_to_list(dlghand, data, "", 0, 0, 0))
  401.       pputs(data "\n", compile_pipes[dlghand])
  402.       set_dialog_item(dlghand, DI_INPUT, DAC_SETFOCUS)
  403.    }
  404. }
  405.  
  406. # ---------------------------------------------------------------------------
  407. ## check_compile()
  408. #
  409. # Event handler for EVENT.PROCESS_COMPLETE gets called when a process
  410. # has completed. process_id is set to the process that has just
  411. # finished.
  412. #
  413. global function check_compile()
  414. {
  415.    if ( process_pipe in current_compiles )
  416.       compile_done( process_pipe )
  417. }
  418.  
  419. local function compile_done(pid)
  420. {
  421.    local dlgid = current_compiles[pid].dlgid
  422.  
  423.    if (current_compiles[pid].input)
  424.    {
  425.       if (query_dialog_item(dlgid, DI_INPUT, DAC_SETFOCUS))
  426.          set_dialog_item(dlgid, IDL_LIST, DAC_SETFOCUS)
  427.  
  428.       set_dialog_item(dlgid, DI_INPUT,        DAC_DISABLE )
  429.       set_dialog_item(dlgid, DI_ENTER_BUTTON, DAC_DISABLE )
  430.    }
  431.    set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_DISABLE )
  432.  
  433.    if (dlgid)
  434.    {
  435.       if ( errorsFound > 0 )
  436.          set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  437.                            "Compile complete, " errorsFound " errors/warnings found." )
  438.       else if ( process_rc > 0)
  439.          set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  440.                            "Command returned error code " process_rc ".")
  441.       else
  442.          set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  443.                            "Compile complete, No errors found." )
  444.    }
  445.    else
  446.    {
  447.       if ( errorsFound > 0 )
  448.          message("Compile complete, " errorsFound " errors/warnings found." )
  449.       else if ( process_rc > 0)
  450.          message("Command returned error code " process_rc ".")
  451.       else
  452.          message("Compile complete, No errors found." )
  453.    }
  454.  
  455.    delete_event(EVENT.PIPE_DATA, function_id("pipedata"))
  456.    delete_event(EVENT.PROCESS_COMPLETE, function_id("check_compile"))
  457.  
  458.    delete current_compiles [ pid ]
  459.    delete compile_pipes [ dlgid ]
  460. }
  461.  
  462. # ---------------------------------------------------------------------------
  463. ## pipedata()
  464. #
  465. # Event handler for EVENT.PIPE_DATA to retrieve the error messages from the
  466. # pipe and place them into the error dialog.
  467. #
  468. global function pipedata()
  469. {
  470.    local name
  471.    local level
  472.    local dlgid
  473.    local input
  474.    local output
  475.    local filename
  476.    local errorOutputText
  477.    local index    = -1
  478.  
  479.    if ( process_pipe in current_compiles )
  480.    {
  481.       errorCompleteText = pipe_data
  482.  
  483.       if (length(errorCompleteText))
  484.       {
  485.          name            = current_compiles[process_pipe].name
  486.          dlgid           = current_compiles[process_pipe].dlgid
  487.          input           = current_compiles[process_pipe].input
  488.          output          = current_compiles[process_pipe].output
  489.          filename        = current_compiles[process_pipe].filename
  490.  
  491.          errorInfoPrefix = ErrorFormat(name);
  492.          level           = errorInfo()
  493.          if ( level > 0 )
  494.          {
  495.             if (!dlgid)
  496.             {
  497.                dlgid = create_compile_dialog(filename, input)
  498.                current_compiles[process_pipe].dlgid = dlgid
  499.             }
  500.  
  501.             if (!errorsFound)
  502.             {
  503.                set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_ENABLE )
  504.                set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_ENABLE )
  505.             }
  506.             errorsFound++
  507. #            if (list_all_output || (length(errorText) == 0) )
  508.             if (output || (length(errorText) == 0) )
  509.                errorOutputText = errorCompleteText
  510.             else
  511.                errorOutputText = errorText
  512.             index = add_item_to_list(dlgid, errorOutputText,
  513.                                      errorSrcName, errorLine, errorColumn,
  514.                                      errorLength ? errorLength : errorColumn > 1 ? -2 : -1)
  515.          }
  516.          else if (dlgid)
  517.          {
  518.             if (output || level < 0)
  519.                index = add_item_to_list(dlgid, errorCompleteText, "", 0, 0, 0)
  520.             else
  521.             {
  522.                errorCompleteText = ltrim(errorCompleteText)
  523.                if (length(errorCompleteText))
  524.                   set_dialog_window(dlgid, DWC_STATUSBARTEXT, errorCompleteText)
  525.             }
  526.          }
  527.          if (dlgid && input && index >= 0)
  528.             set_dialog_item(dlgid, IDL_LIST, DAC_SELECT_INDEX, index)
  529.       }
  530.    }
  531. }
  532.  
  533. # ---------------------------------------------------------------------------
  534. ## display_errors()
  535. #
  536. # Parse the error message file and put the error messages into the
  537. # error dialog.
  538. #
  539.  
  540. # needs to be global to this module because if the stop button is
  541. # pressed we need to close the file.
  542. local fileid = -1
  543.  
  544. global function display_errors(sourceFileName, errorFileName, errorCompiler,
  545.                                list_all, dlgid, saveFile)
  546. {
  547.    local data
  548.    local level
  549.    local line = 1
  550.    local errorOutputText
  551.  
  552.    process_background(ENABLE_FOREGROUND)
  553.  
  554.    if (!argcount())
  555.       sourceFileName = buffer_filename
  556.  
  557.    if (argcount() < 2 || !length(errorFileName))
  558.       errorFileName = bld_fnam(sourceFileName, sourceFileName, "err")
  559.  
  560.    if (argcount() < 3 || !length(errorCompiler))
  561.       errorCompiler = CompilerName(path_ext(sourceFileName))
  562.  
  563.    if (argcount() < 5)
  564.       list_all = list_all_output
  565.  
  566.    fileid = fopen(errorFileName, 0)
  567.  
  568.    if ( fileid == -1 )
  569.    {
  570.       if (dlgid)
  571.       {
  572.          set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  573.                            "Unable to open file " errorFileName)
  574.       }
  575.       else
  576.          warning("Unable to open file " errorFileName)
  577.    }
  578.    else
  579.    {
  580.       if (dlgid)
  581.          set_dialog_window(dlgid, DWC_STATUSBARTEXT, "Parsing errors...")
  582.  
  583.       errorInfoPrefix = ErrorFormat(errorCompiler);
  584.  
  585.       while (( errorCompleteText = fgets(fileid) ))
  586.       {
  587.          line++
  588.          level = errorInfo() 
  589.          if ( level > 0 )
  590.          {
  591.             if (!dlgid)
  592.                dlgid = create_compile_dialog(sourceFileName)
  593.  
  594.             if (!errorsFound)
  595.             {
  596.                set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_ENABLE )
  597.                set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_ENABLE )
  598.             }
  599.             errorsFound++ 
  600.  
  601.             #  If the file name is not specified in the error file,
  602.             #  default to the error file itself.
  603.             #  I put this here because of Microfocus list files.
  604.             if(!errorSrcName)
  605.                errorSrcName = errorFileName;
  606.  
  607. #            if (list_all_output || (length(errorText) == 0) )
  608.             if (list_all || (length(errorText) == 0) )
  609.                errorOutputText = errorCompleteText
  610.             else
  611.                errorOutputText = errorText
  612.             add_item_to_list(dlgid,
  613.                              errorOutputText,
  614.                              errorSrcName, errorLine, errorColumn,
  615.                              errorLength ? errorLength : errorColumn > 1 ? -2 : -1)
  616.          }
  617.          else if (dlgid)
  618.          {
  619.             if (list_all || level < 0)
  620.                add_item_to_list(dlgid, errorCompleteText, "", 0, 0, 0)
  621.             else
  622.             {
  623.                errorCompleteText = ltrim(errorCompleteText)
  624.                if (length(errorCompleteText))
  625.                   set_dialog_window(dlgid, DWC_STATUSBARTEXT, errorCompleteText)
  626.             }
  627.          }
  628.  
  629.          if ( dlgid && and(status_bar_flags, STB_MESSAGES) && line % 20 == 0 )
  630.             set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  631.                               "Parsing error file line " line)
  632.       }
  633.  
  634.       fclose(fileid)
  635.       fileid = -1
  636.  
  637.       # saveFile is set if we have loaded from an error file on disk
  638.       # which means we haven't done a compile_buffer command
  639.       if ( !saveFile )
  640.          unlink(errorFileName)
  641.  
  642.       if (dlgid)
  643.       {
  644.          if ( errorsFound > 0 )
  645.             set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  646.                               "Compile complete, " errorsFound " errors/warnings found." )
  647.          else
  648.             set_dialog_window(dlgid, DWC_STATUSBARTEXT,
  649.                               "Compile complete, No errors found." )
  650.       }
  651.       else if ( errorsFound > 0 )
  652.          message("Compile complete, " errorsFound " errors/warnings found." )
  653.       else
  654.          message("Compile complete, No errors found." )
  655.    }
  656.  
  657.    process_background(END_BACKGROUND)
  658. }
  659.  
  660. global function goto_prev_error()
  661. {
  662.    goto_prev_item()
  663. }
  664.  
  665. ## goto_next_error()                #PUBLIC
  666. #
  667. # display an individual error message
  668. #
  669. global function goto_next_error( errorFileId, suppressDisplayErrors )
  670. {
  671.    goto_next_item()
  672. }
  673.  
  674. ## errorInfo()
  675. #
  676. # Calls the appropriate compiler specific xxxErrorInfo function to find
  677. # error and warning messages in the error file and extract salient
  678. # information.  Additional functions may be added here, if desired, to
  679. # support different compilers.  Each new function should have a name which
  680. # consists of the compiler type, as defined in the init_compilers() function,
  681. # followed by "ErrorInfo".  Each new ErrorInfo function should set
  682. # the following variables:
  683. #
  684. #
  685. #  errorSrcName - the name of the source filename appearing in the
  686. #        error message
  687. #
  688. #  errorLine - the line number in the current source file where the
  689. #        error occurred.
  690. #
  691. #  errorColumn -  the column where the error occurred (or 0 if unknown)
  692. #
  693. #  errorLength -  the length of the error (to hilight) or 0 to hilight line.
  694. #
  695. #  errorText - the text of the message to be displayed in the
  696. #        dialog window.
  697. #
  698. #
  699. # In addition, the variable errorCompleteText will be displayed if the file
  700. # named in errorSrcName cannot be located.
  701. #
  702. #
  703. # The function return value should be as follows:
  704. #  0 - if no more error or warning messages could be found,
  705. #  1 - if the message is for a non-fatal error or warning,
  706. #  2 - if the message is for a severe error.
  707. #
  708. local function errorInfo()
  709. {
  710.    local pos
  711.    local functionId
  712.    local functionName
  713.    local functionParm
  714.  
  715.    # initialize
  716.    errorSrcName = ""
  717.    errorText    = ""
  718.    errorLine    = 0
  719.    errorColumn  = 0
  720.    errorLength  = 0
  721.  
  722.    # Determine which xxxErrorInfo function to use.  Known compiler
  723.    # types and source file extensions are listed in the function
  724.    # "init_compilers()".
  725.  
  726.    if ( errorInfoPrefix == "none" || errorInfoPrefix == "[None]" )
  727.       return -1 # no errorInfo function exists for this compiler
  728.  
  729.    # Append the name "ErrorInfo" to the compiler type and
  730.    # use it if a function by that name exists.
  731.  
  732.    if ((pos = cindex(errorInfoPrefix, ",")))
  733.    {
  734.       functionParm = substr(errorInfoPrefix, pos+1)
  735.       functionName = prefix(prefix(errorInfoPrefix, pos-1), 8 ) "ErrorInfo";
  736.    }
  737.    else
  738.       functionName = prefix( errorInfoPrefix, 8 ) "ErrorInfo";
  739.  
  740.    if (functionParm)
  741.       functionId   = function_id( functionName, functionParm )
  742.    else
  743.       functionId   = function_id( functionName )
  744.  
  745.    if ( functionId )
  746.       return execute_function( functionId )
  747.    else
  748.       return genericErrorInfo() # otherwise use the default errorfix routine
  749. }
  750.  
  751. # ------------------- Generic ErrorInfo function ----------------------------
  752.  
  753. global function genericErrorInfo()
  754. {
  755.    #====================================================================
  756.    # This function is invoked whenever no explicit xxxErrorInfo()
  757.    # function has been defined for the current compiler.  It supports
  758.    # the error message syntax for several compilers, for example:
  759.    #
  760.    # Microsoft C and MASM:
  761.    # <sourcefile>(<line number>): "error"|"warning" <errno>: <message>
  762.    #
  763.    # Microsoft FORTRAN:
  764.    # <sourcefile>(<line number>) : "error"|"warning" <errno> : <message>
  765.    #
  766.    # Lattice C:
  767.    # <sourcefile> <line number> "Error"|"Warning" <errno>: <message>
  768.    #
  769.    # Borland Turbo Pascal:
  770.    # <sourcefile>(<line number>): "Error"|"Warning" <errno>: <message>
  771.    #
  772.    # FORCE:
  773.    # <sourcefile>(<line number>) : "Error"(<errno>) : <message>
  774.    #
  775.    # IBM CSet/2 & IBM CSet++:
  776.    # <sourcefile>(<line>:<column>) : "error"|"warning" <errno>: <message>
  777.    #
  778.    #====================================================================
  779.  
  780.    local errorLevel
  781.    local searchFor = "(^fatal )|[ \t(]+\\c[0-9].*(<[eE]rror|<[wW]arning)[ \t(].*:"
  782.    local tempText
  783.    local colon, paren
  784.  
  785.    # scan the error file for the next appropriate message
  786.    if ( !match( errorCompleteText, searchFor ) )
  787.       return 0 # no more applicable messages
  788.  
  789.    # handle fatal errors and other messages with no source filename
  790.    tempText = substr(errorCompleteText, 0, 6)
  791.    if ((tolower(tempText) == "fatal "  ) || \
  792.        (!match( errorCompleteText, /^[( \t]*[^( \t]+\./ )))
  793.    {
  794.       errorSrcName = ""
  795.       errorLine    = 0
  796.       errorColumn  = 0
  797.       errorLevel   = 2
  798.    }
  799.    else
  800.    {
  801.       # get the source filename
  802.       match( errorCompleteText, /[^( \t]+/ )
  803.       errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
  804.  
  805.       # get the line position of the error
  806.       tempText    = substr(errorCompleteText, RSTART + RLENGTH + 1, 20)
  807.       errorLine   = atoi( tempText )
  808.  
  809.       # get the column position of the error
  810.       colon       = cindex(tempText, ":")
  811.       paren       = cindex(tempText, ")")
  812.       if (colon && paren && colon < paren)
  813.          errorColumn = atoi(substr(tempText, colon+1))
  814.       else
  815.          errorColumn = 0
  816.  
  817.       # determine the severity of the error
  818.       match( errorCompleteText, "<error>|<warning>" )
  819.       tempText   = substr(errorCompleteText, RSTART, RLENGTH)
  820.       tempText   = substr(tempText, 0, 5)
  821.       errorLevel = (tolower(tempText) == "error") ? 2 : 1
  822.    }
  823.  
  824.    # get the text of the message
  825.    match( errorCompleteText, ":\\c" )
  826.    tempText = substr(tempText, RSTART, RLENGTH)
  827.    match( tempText, "<" )
  828.    tempText  = substr(tempText, RSTART, RLENGTH)
  829.    errorText = substr(tempText, RSTART)
  830.  
  831.    return errorLevel
  832. }
  833.  
  834. # ------------------- ErrorInfo function for PEL ----------------------------
  835.  
  836. global function pelErrorInfo()
  837. {
  838.    #====================================================================
  839.    #
  840.    # error message syntax for INTERSOLV Pel compiler:
  841.    #
  842.    # <sourcefile>(<line number>):"[fatal] error"|"warning":
  843.    # <space>|<newline> <message>
  844.    #
  845.    #====================================================================
  846.  
  847.    local errorLevel
  848.    local searchFor = ":.*(error|warning).*:\\c"
  849.    local delimit
  850.  
  851.    # scan the error string for an appropriate message
  852.    if ( !match( errorCompleteText, searchFor ) )
  853.       return 0 # not a valid error message
  854.  
  855.    # get the source filename
  856.    match( errorCompleteText, /[^( ]+/ )
  857.    errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
  858.  
  859.    # get the line and column position of the error
  860.    if ( substr( errorCompleteText, RSTART+RLENGTH, 1 ) == "(" )
  861.       errorLine = atoi( substr( errorCompleteText, RSTART+RLENGTH+1 ))
  862.  
  863.    # determine the severity of the error
  864.    errorLevel        = (errorCompleteText ~ /warning:/) ? 1 : 2
  865.    errorText         = ltrim(errorCompleteText, errorSrcName)
  866. # Removed by WGN since this line just duplicates errorText in errorCompleteText
  867. #   errorCompleteText = errorCompleteText errorText
  868.  
  869.    # get the text of the message
  870.     match( errorText, ": ")
  871.     errorText = substr( errorText, RSTART+1 )
  872.  
  873.    return errorLevel
  874. }
  875.  
  876. # ------------------- ErrorInfo function for Microfocus COBOL ---------------
  877.  
  878. local function reset_mf_globs()
  879. {
  880.    mfFirstFound  = FALSE;
  881.    mfErrorNum = "";
  882.    mfErrorLine = 0;
  883.    mfSrcName = "";
  884. }
  885.  
  886. local mfFirstFound  = FALSE;
  887. local mfErrorNum;
  888. local mfErrorLine;
  889. local mfSrcName = "";
  890.  
  891. global function microfocErrorInfo(linenum)
  892. {
  893.    #====================================================================
  894.    #
  895.    # error message syntax for Microfocus COBOL compiler:
  896.    #
  897.    # *<err number>-<E|S|I|F><more than one *>\n
  898.    # **<error message>\n
  899.    # <white space><line number><code>\n
  900.    #
  901.    #====================================================================
  902.  
  903.    local errorLevel = 0;
  904.    local arr;
  905.    local firstsearchFor  = "^\\*[ ]*[0-9]+-[EFISUW][\\*]+";
  906.    local secondsearchFor = "^\\*\\* .*";
  907.    local thirdsearchFor  = "first used on line [0-9]+";
  908.  
  909.    if((prefix(errorCompleteText, 13) == "* Micro Focus") && !mfSrcName)
  910.    {
  911.       mfSrcName = "23";
  912.       #  warning("found first line of name >" errorCompleteText "<");
  913.    }
  914.    else if(mfSrcName == "23")
  915.    {
  916.       split(errorCompleteText, arr);
  917.       mfSrcName = arr[2];
  918.       #  warning("mfsrcname set to <" mfSrcName ">");
  919.    }
  920.  
  921.    if(!mfFirstFound && match(errorCompleteText, firstsearchFor) )
  922.    {
  923.       #  found the first line of a message, rip out error number and save;
  924.       mfErrorNum = prefix(errorCompleteText, 7);
  925.       mfFirstFound = TRUE;
  926.    }
  927.    else if(mfFirstFound && match(errorCompleteText, secondsearchFor) )
  928.    {
  929.       #  found a matching second line after a matching first line;
  930.       #  get the rest of the error info;
  931.  
  932.       if(match(errorCompleteText, thirdsearchFor))
  933.          errorLine = atoi(substr(errorCompleteText, RSTART + 19));
  934.  
  935.       else
  936.          errorLine = mfErrorLine;
  937.  
  938.       errorText = mfErrorNum ": " ltrim(substr(errorCompleteText, 3));
  939.       errorSrcName = mfSrcName;
  940.       mfFirstFound = FALSE;
  941.       errorLevel = 1;
  942.    }
  943.    else
  944.    {
  945.       #  no matching firstline, no matching second after first;
  946.       split(errorCompleteText, arr);
  947.       mfErrorLine = atoi(arr[1]);
  948.       mfFirstFound = FALSE;
  949.    }
  950.  
  951.    return errorLevel;
  952. }
  953.  
  954.  
  955. # ------------------- ErrorInfo function for Realia COBOL ---------------
  956.  
  957. global function realiaErrorInfo()
  958. {
  959.    #====================================================================
  960.    #
  961.    # error message syntax for Realia COBOL compiler:
  962.    #
  963.    # <line number> <err number> <E|S|I|F> <error message>
  964.    #
  965.    #====================================================================
  966.  
  967.    local errorLevel = 0;
  968.    local arr;
  969.    local searchFor  = "^*[0-9]+ [0-9]+ [EFISUW] ";
  970.  
  971.    if(!mfSrcName && match(errorCompleteText, "CA-Realia COBOL"))
  972.    {
  973.       split(errorCompleteText, arr);
  974.       mfSrcName = arr[7];
  975.    }
  976.    else if(match(errorCompleteText, searchFor) )
  977.    {
  978.       split(errorCompleteText, arr);
  979.       errorLine = atoi(arr[1]);
  980.       errorText = ltrim(errorCompleteText);
  981.       errorSrcName = mfSrcName;
  982.       errorLevel = (arr[3] == "W") ? 1 : 2;
  983.    }
  984.  
  985.    return errorLevel;
  986. }
  987.  
  988. # ------------------- ErrorInfo function for Turbo C ------------------------
  989.  
  990.  
  991. global function turbocErrorInfo()
  992. {
  993.    #====================================================================
  994.    #
  995.    # error message syntax for Borland Turbo C (Version 2.0):
  996.    #
  997.    # "Error"|"Warning" <sourcefile> <line number>: <message>
  998.    #
  999.    #====================================================================
  1000.  
  1001.    local errorLevel
  1002.    local searchFor = "^(Error|Warning).* \\c[0-9]+:"
  1003.  
  1004.    # scan the error file for the next appropriate message
  1005.    if ( !match( errorCompleteText, searchFor ) )
  1006.       return 0 # not a valid error message
  1007.  
  1008.    # determine the severity of the error
  1009.    errorLevel = (errorCompleteText ~ /^Error/) ? 2 : 1
  1010.    
  1011.    # strip off the Warning|Error string
  1012.    strtok( errorCompleteText, "[ \t]+" )
  1013.  
  1014.    # get the source filename
  1015.    errorSrcName = strtok()
  1016.  
  1017.    # get the line and column position of the error
  1018.    errorLine = atoi( strtok("", "[ :\t]+") )
  1019.    errorColumn = 0
  1020.  
  1021.    # get the text of the message
  1022.    errorText = get_tokstring()
  1023.    
  1024.    return errorLevel
  1025. }
  1026.  
  1027. # ------------------- ErrorInfo function for Zortech C and C++ --------------
  1028.  
  1029. global function watcomErrorInfo()
  1030. {
  1031.    #====================================================================
  1032.    #
  1033.    # error message syntax for Watcom C and C++
  1034.    #
  1035.    # Watcom C and C++:
  1036.    # "<sourcefile>" line <line number>: "warning"|"syntax error"|
  1037.    #  "preprocessor error"|"fatal error"|"lexical error": <message>
  1038.    #
  1039.    #====================================================================
  1040.  
  1041.    return otherErrorInfo( "%f(\\()%1(\\)):.*(col )%c(\\) )%t" )
  1042. }
  1043.  
  1044. # ------------------- ErrorInfo function for Zortech C and C++ --------------
  1045.  
  1046. global function zortechErrorInfo()
  1047. {
  1048.    #====================================================================
  1049.    #
  1050.    # error message syntax for Zortech C and C++
  1051.    #
  1052.    # Zortech C and C++:
  1053.    # "<sourcefile>" line <line number>: "warning"|"syntax error"|
  1054.    #  "preprocessor error"|"fatal error"|"lexical error": <message>
  1055.    #
  1056.    #====================================================================
  1057.  
  1058.    local errorLevel
  1059.    local searchFor = "(^\".*\",? line \\c[0-9]*[ :]*(warning|(syntax|preprocessor|fatal|lexical) error):?)" \
  1060.          "|\\c(Global Optimizer|Intermediate file|Fatal|Syntax|Preprocessor|lexical) error:+"
  1061.    local fnameline
  1062.    local tempText
  1063.  
  1064.    # scan the error file for the next appropriate message
  1065.    if ( !match( errorCompleteText, searchFor))
  1066.       return 0 # no more applicable messages
  1067.  
  1068.    # get the source filename
  1069.    errorSrcName = substr( errorCompleteText, 2,
  1070.                           cindex( substr( errorCompleteText, 2 ), "\"" ) - 1)
  1071.  
  1072.    # determine the severity of the error
  1073.    errorLevel = (errorCompleteText ~ /warning:/) ? 1 : 2
  1074.  
  1075.    # get the line and column position of the error
  1076.    tempText    = substr(errorCompleteText, 0, 10)
  1077.    errorLine   = atoi( tempText )
  1078.    errorColumn = 0
  1079.  
  1080.    # get the text of the message
  1081.    match( errorCompleteText, "(warning|error):\\c" )
  1082.    tempText  = substr(errorCompleteText, RSTART, RLENGTH)
  1083.    errorText = ltrim(tempText)
  1084.  
  1085.    return errorLevel
  1086. }
  1087.  
  1088. # ------------------- ErrorInfo function for Lahey FORTRAN ------------------
  1089.  
  1090. global laheyLine
  1091. global laheyText
  1092. global function laheyErrorInfo()
  1093. {
  1094.    #====================================================================
  1095.    #
  1096.    # error message syntax for Lahey FORTRAN 77
  1097.    #
  1098.    # Lahey FORTRAN 77:
  1099.    # "Compiling line : <line num>"    This is only shown one time
  1100.    # "File <source file name>, line    <line num>: <copy of program line>
  1101.    #        <'^' pointer to Column position of Error>
  1102.    # "(FATAL|WARNING) - <message>
  1103.    #
  1104.    #====================================================================
  1105.  
  1106.    local errorLevel
  1107.    local searchFor = "^(FATAL|WARNING)[ \t]* -\\c"
  1108.    local fnameline
  1109.  
  1110.    if (laheyText)
  1111.    {
  1112.       # the error message could span a couple of lines
  1113.       if (errorCompleteText !~ /\.$/)
  1114.       {
  1115.          laheyText = laheyText errorCompleteText
  1116.          return 0 # Error Message Not Complete
  1117.       }
  1118.    }
  1119.    else
  1120.    {
  1121.       # scan the error file for the next appropriate message
  1122.       if ( match( errorCompleteText, searchFor))
  1123.       {
  1124.          laheyText = errorCompleteText
  1125.          return 0 # Error Message Not Complete
  1126.       }
  1127.       else
  1128.          return 0 # no more applicable messages
  1129.    }
  1130.  
  1131.    errorCompleteText = laheyText
  1132.    laheyText         = ""
  1133.    delete laheyText
  1134.  
  1135.    # get the source filename
  1136.    if (match( errorCompleteText, "File .*, line[ \t]+[0-9]+\\."))
  1137.    {
  1138.       # The line number and file name are on the same line.
  1139.       fnameline = substr( errorCompleteText, RSTART+5 );
  1140.       errorSrcName = trim(ltrim(substr( fnameline, 1,
  1141.                                         cindex( fnameline, "," ) - 1 )))
  1142.       
  1143.       # get the line and column position of the error
  1144.       match( fnameline, "line[ \t]+[0-9]" )
  1145.       fnameline = ltrim(substr( fnameline, RSTART + 4 ));
  1146.       errorLine = atoi( fnameline )
  1147.       errorColumn = 0
  1148.    }
  1149.    else if (match( errorCompleteText, "^File[ \t]+.* line +\\c[0-9]*"))
  1150.    {
  1151.       # The line number and file name are on a different line.
  1152.       fnameline = substr( errorCompleteText, RSTART+5 );
  1153.       match( fnameline, "," )
  1154.       errorSrcName = substr( fnameline, 1, RSTART - 1 )
  1155.    
  1156.       # get the line and column position of the error
  1157.       match( fnameline, "line[ \t]+[0-9]" )
  1158.       fnameline = ltrim(substr( fnameline, RSTART + 4 ));
  1159.       errorLine = atoi( fnameline )
  1160.       errorColumn = 0
  1161.    }
  1162.    else
  1163.    {
  1164.       return 0;
  1165.    }
  1166.  
  1167.    # determine the severity of the error
  1168.    errorLevel = (errorCompleteText ~ /WARNING/) ? 1 : 2
  1169.  
  1170.    # get the text of the message
  1171.    if (match(errorCompleteText, "(FATAL|WARNING)[ \t]*-"))
  1172.       errorText = ltrim(substr(errorCompleteText , RSTART + RLENGTH ));
  1173.  
  1174.    return errorLevel
  1175. }
  1176.  
  1177. # ------------------- ErrorInfo function for Advantage ADA ------------------
  1178.  
  1179. global function adaErrorInfo()
  1180. {
  1181.    #====================================================================
  1182.    #
  1183.    # error message syntax for Advantage ADA
  1184.    #
  1185.    # "<filename>", <line num>: <message>
  1186.    #
  1187.    #====================================================================
  1188.  
  1189.    local errorLevel
  1190.    local searchFor = "^\".*\", \\c[0-9]*:"
  1191.    local tempText
  1192.  
  1193.    # scan the error file for the next appropriate message
  1194.    if ( !match( errorCompleteText, searchFor) )
  1195.       return 0 # no more applicable messages
  1196.  
  1197.    # get the source filename
  1198.    errorSrcName = substr( errorCompleteText, 2,
  1199.                           cindex( substr( errorCompleteText, 2 ), "\"" ) - 1)
  1200.  
  1201.    # determine the severity of the error
  1202.    errorLevel = (errorCompleteText ~ /error/) ? 2 : 1
  1203.  
  1204.    # get the line and column position of the error
  1205.    tempText    = substr(errorCompleteText, 0, 10)
  1206.    errorLine   = atoi( tempText )
  1207.    errorColumn = 0
  1208.  
  1209.    # get the text of the message
  1210.    match( errorCompleteText, ":\\c" )
  1211.    tempText  = substr(errorCompleteText, RSTART, RLENGTH)
  1212.    errorText = ltrim(errorCompleteText, tempText)
  1213.  
  1214.    return errorLevel
  1215. }
  1216.  
  1217. # ------------------- ErrorInfo functions for Clipper -----------------------
  1218.  
  1219. global clipperPos
  1220. global clipperLine
  1221. global clipperText
  1222. global clipperSrcName
  1223. global function clipper8ErrorInfo()
  1224. {
  1225.    #====================================================================
  1226.    #
  1227.    # error message syntax for Nantucket Clipper Summer87
  1228.    #
  1229.    # "Compiling <file>" (This is only shown one time)
  1230.    # "line <line>:  <message>"
  1231.    # <copy of program line>
  1232.    #        <'^' pointer to Column position of Error>
  1233.    #
  1234.    #
  1235.    # Clipper Support added by P. Polakoff III, 3P Software, Inc.
  1236.    #
  1237.    #====================================================================
  1238.  
  1239.    local errorLevel
  1240.    local searchFor = "^line \\c[0-9]+:"
  1241.    local fnameline
  1242.  
  1243.    if (substr(errorCompleteText, 1, 9) == "Compiling")
  1244.       clipperSrcName = ltrim( trim( substr(errorCompleteText, 10 )))
  1245.  
  1246.    # scan the error file for the next appropriate message
  1247.    else if ( match( errorCompleteText, searchFor) )
  1248.    {
  1249.       # get the line of the error
  1250.       errorLine   = atoi(substr(errorCompleteText, RSTART, 10))
  1251.  
  1252.       # get the text of the message
  1253.       errorText = trim( substr( errorCompleteText, \
  1254.                                 match( errorCompleteText, ":" ) + 1 ))
  1255.  
  1256.       clipperPos = 1 # Re-set the Position Counter.
  1257.    }
  1258.    else if (clipperPos)
  1259.    {
  1260.       if (++clipperPos == 3)
  1261.       {
  1262.          # get the column position of the error
  1263.          errorColumn  = match(errorCompleteText , "\\^" )
  1264.          errorLine    = clipperLine
  1265.          errorText    = clipperText
  1266.          errorLevel   = 2
  1267.          errorSrcName = clipperSrcName
  1268.          return errorLevel # Ah-Ha - This is indeed the last line of the error
  1269.       }
  1270.    }
  1271.    return 0 # Not the last line of an error message.
  1272. }
  1273.  
  1274. global function clipper5ErrorInfo()
  1275. {
  1276.    #====================================================================
  1277.    #
  1278.    # error message syntax for Nantucket Clipper 5.0 (B93)
  1279.    #
  1280.    # <sourcefile>(<line number>) "Error"|"Warning" <errno>  <message>
  1281.    #
  1282.    #====================================================================
  1283.  
  1284.    local errorLevel
  1285.    local searchFor = "\\(\\c[0-9]+\\) +(Error|Warning)"
  1286.    local tempText
  1287.  
  1288.    # scan the error file for the next appropriate message
  1289.    if ( !match( errorCompleteText, searchFor) )
  1290.       return 0 # no more applicable messages
  1291.  
  1292.    # get the source filename
  1293.    match( errorCompleteText, /[^( \t]+/ )
  1294.    errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
  1295.  
  1296.    # get the line and column position of the error
  1297.    tempText  = substr(errorCompleteText, 0, 10)
  1298.    errorLine = atoi( tempText )
  1299.  
  1300.    # determine the severity of the error
  1301.    match( errorCompleteText, "<error>|<warning>")
  1302.    tempText   = substr(errorCompleteText, RSTART, RLENGTH)
  1303.    tempText   = substr(errorCompleteText, 0, 5)
  1304.    errorLevel = (tolower(tempText) == "error") ? 2 : 1
  1305.  
  1306.    # get the text of the message
  1307.    tempText  = substr(errorCompleteText, RSTART, RLENGTH)
  1308.    errorText = ltrim(errorCompleteText, tempText)
  1309.  
  1310.    return errorLevel
  1311. }
  1312.  
  1313. global function otherErrorInfo(searchPattern)
  1314. {
  1315.    #====================================================================
  1316.    # This function is invoked when a user-defined pattern is supplied
  1317.    # for error message parsing.
  1318.    #
  1319.    # The pattern is a regular expression the contains the following
  1320.    # special codes to indicate where the relevant information is.
  1321.    #
  1322.    #     %f =  Source Filename.
  1323.    #     %l =  Error Line.
  1324.    #     %c =  Error Column.
  1325.    #     %t =  Error Message Text.
  1326.    #     %h =  Hilight length.
  1327.    #     %v =  Error Level.
  1328.    #
  1329.    #====================================================================
  1330.    local errorLevel
  1331.    local pattern
  1332.    local before
  1333.    local value
  1334.    local after
  1335.    local text
  1336.    local what
  1337.    local pos
  1338.  
  1339.    errorSrcName = ""
  1340.    errorText    = ""
  1341.    errorLine    = 0
  1342.    errorLevel   = 0
  1343.    errorColumn  = 0
  1344.    errorLength  = 0
  1345.  
  1346.    pattern = searchPattern
  1347.    text    = errorCompleteText
  1348.    pos     = cindex(pattern, "%")
  1349.  
  1350.    while (pos)
  1351.    {
  1352.       if (pos == 1)
  1353.          before = ""
  1354.       else
  1355.          before = prefix(pattern, pos - 1)
  1356.  
  1357.       what    = toupper(substr(pattern, pos+1, 1))
  1358.       pattern = substr(pattern, pos+2)
  1359.       pos     = cindex(pattern, "%")
  1360.  
  1361.       if (pos == 0)
  1362.          after = pattern
  1363.       else
  1364.          after = prefix(pattern, pos - 1)
  1365.  
  1366.       if (match(text, before ".*" after))
  1367.       {
  1368.          match(text, before)
  1369.          text = substr(text, RSTART + RLENGTH)
  1370.          if (length(after))
  1371.          {
  1372.             match(text, after)
  1373.             value = prefix(text, RSTART - 1)
  1374.          }
  1375.          else
  1376.             value = text
  1377.  
  1378.          if (what == "F")
  1379.             errorSrcName = value
  1380.          else if (what == "T")
  1381.             errorText    = value
  1382.          else if (what == "L")
  1383.             errorLine    = atoi(value)
  1384.          else if (what == "C")
  1385.             errorColumn  = atoi(value)
  1386.          else if (what == "H")
  1387.             errorLength  = atoi(value)
  1388.          else if (what == "V")
  1389.             errorLevel   = atoi(value)
  1390.       }
  1391.    }
  1392.    return errorLevel ? errorLevel : length(errorText) > 0 && errorLine
  1393. }
  1394.  
  1395. # ---------------------------------------------------------------------------
  1396. ## display_error_file_key()
  1397. #
  1398. # Presents a dialog box from which to select an error message file to be
  1399. # parsed into the error dialog.
  1400. #
  1401.  
  1402. local IDD_DISPLAY_ERRORS  = 1450
  1403. local IDE_COMPILER_LIST   = 1451
  1404. local IDE_ERROR_FILE_NAME = 1452
  1405.  
  1406. local error_filename
  1407. local dialog_return_value
  1408.  
  1409. global function display_error_file_key( sourceFileName, errorFileName )
  1410. {
  1411.    local dlgid
  1412.    local name
  1413.    local bufid
  1414.  
  1415.    #  reset microfocus global variables in case this is not the first time through
  1416.    reset_mf_globs();
  1417.    error_filename = length(sourceFileName) ? sourceFileName : buffer_filename
  1418.    dlgid = create_dialog(function_id("display_error_callback"), 0, IDD_DISPLAY_ERRORS )
  1419.    attach_help( editor_helpfile, dlgid )
  1420.    add_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DCTRL_EDIT_KEY)
  1421.    add_dialog_item(dlgid, IDE_COMPILER_LIST,   DCTRL_COMBO_BOX)
  1422.  
  1423.    if ( !errorFileName ) 
  1424.       errorFileName = bld_fnam(error_filename, error_filename, "err")
  1425.  
  1426.    set_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DAC_SET_TEXT_LEN, 512 )
  1427.    set_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DAC_EDIT_TEXT, errorFileName, 1 )
  1428.  
  1429.    begin_dialog(dlgid, TRUE)
  1430.    if ( dialog_return_value.FileName == "" )
  1431.       return
  1432.  
  1433.    bufid = next_buffer( path_fname(dialog_return_value.FileName) path_ext(dialog_return_value.FileName))
  1434.    if ( bufid )
  1435.    {
  1436.       if ( buffer_filename == dialog_return_value.FileName )
  1437.       {
  1438.          warning(dialog_return_value.FileName " currently loaded in a buffer")
  1439.          return
  1440.       }
  1441.    }
  1442.  
  1443.    errorsFound = 0;
  1444.    dlgid = create_compile_dialog(error_filename)
  1445.    display_errors(error_filename, dialog_return_value.FileName,
  1446.                   dialog_return_value.CompilerName, list_all_output, dlgid,
  1447.                   TRUE)
  1448. }
  1449.  
  1450. global function display_error_callback()
  1451. {
  1452.    local dlgid
  1453.    local i, index, found_ext
  1454.    local old_prompt_response 
  1455.    local call_hand = callback_dialog_handle
  1456.  
  1457.    if ( ( callback_msg == DM_CLICK && callback_index == DI_HELP ) ||
  1458.       ( callback_msg == DM_HELPREQUESTED ) ) 
  1459.    {
  1460.       if(isWindows())
  1461.          display_help("Error file", callback_dialog_handle);
  1462.       else
  1463.          display_help("errorfile", call_hand)
  1464.       return DRC_MSG_PROCESSED
  1465.    } # end DI_HELP
  1466.    # fill in combo box
  1467.    else if ( callback_msg == DM_INIT )
  1468.    {
  1469.       found_ext = 0
  1470.       index     = -1
  1471.       for(i in compilers)
  1472.       {
  1473.          if (i != "[None]")
  1474.          {
  1475.             index = set_dialog_item(call_hand, IDE_COMPILER_LIST,
  1476.                                      DAC_ADD_ITEM, i)
  1477.  
  1478.             if (index != -1 && CompilerName(path_ext(error_filename)) == i)
  1479.             {
  1480.                found_ext = 1
  1481.                set_dialog_item(call_hand, IDE_COMPILER_LIST,
  1482.                                DAC_SELECT_INDEX, index )
  1483.             }
  1484.          }
  1485.       }
  1486.  
  1487.       if ( found_ext == 0 && index != -1 )
  1488.          set_dialog_item(call_hand, IDE_COMPILER_LIST, DAC_SELECT_INDEX, 0 )
  1489.    }
  1490.    else if ( callback_msg == DM_OK )
  1491.    {
  1492.       cleanup_prompt_history("EDITFILE")
  1493.       dialog_return_value.FileName = query_dialog_item(call_hand, IDE_ERROR_FILE_NAME, DAC_EDIT_TEXT)
  1494.       dialog_return_value.CompilerName = query_dialog_item(call_hand, IDE_COMPILER_LIST, DAC_SELECT_ITEM)
  1495.    }
  1496.    else if ( callback_msg == DM_CLOSE || callback_index == DI_CANCEL)
  1497.    {
  1498.       cleanup_prompt_history("EDITFILE")
  1499.       dialog_return_value.FileName     = ""
  1500.       dialog_return_value.CompilerName = ""
  1501.       return DRC_EXIT
  1502.    }
  1503.    else if ( callback_msg == DM_INVALID_PCHAR && callback_index == IDE_ERROR_FILE_NAME )
  1504.    {
  1505.       dialog_history( call_hand, callback_index, "EDITFILE")
  1506.          #  This is here while we fix the prompt focus problem
  1507.       set_dialog_window(call_hand, DWC_TO_TOP)
  1508.       set_dialog_item(call_hand, IDE_ERROR_FILE_NAME,  DAC_EDIT_TEXT, prompt_response)
  1509.       return DRC_MSG_PROCESSED
  1510.    }
  1511.  
  1512.    return DRC_CONTINUE
  1513. }
  1514.