home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR36 / KEXX.ZIP / RUNCMD.KEX < prev    next >
Text File  |  1992-12-29  |  13KB  |  361 lines

  1. ************************************************
  2. * RUNCMD.KEX
  3. *
  4. * Function: Run programs and locate the lines that are indicated
  5. *           in messages in the output listings.
  6. *           More concisely, this is the logic that is common to macros
  7. *           like CC and BROWSE.
  8. *
  9. * Requires: KEDIT 5.0
  10. * Version:  1.1 (December, 1992)
  11. *
  12. * Internal EDITV variables:
  13. *       Current.xx              current line
  14. *       Total.xx                number of lines
  15. *       Line.1.xx ... Line.n.xx complete message text for a given line
  16. *
  17. * Parameters:
  18. *  /Text/      - Text of message to display at each location.
  19. *                "%m" is replaced by the output from the external program.
  20. *  EditvSuffix - Tail value for EDITV variables used by RUNCMD.
  21. *                Unique values allow things like BROWSE and CC to coexist
  22. *                 during the same editing session.
  23. *  TempFileid  - Fileid to redirect the output of the external command to.
  24. *  TypeOfLine  - Label for each located line.
  25. *  NextKey     - Key to use for "next location" function.
  26. *  PrevKey     - Key to use for "previous location" function.
  27. *  CurrKey     - Key to use to redisplay the current location.
  28. *  ShellCmd    - KEDIT command used to execute the external function.
  29. *                E.g., DOSNOWAIT, or DOSQUIET
  30. *  Parms       - The commandline used to execute the external command.
  31. *                "%s" is replaced by the fileid of the current file.
  32. *                "%n" is replaced by the filename of the current file.
  33. *                "-" means skip the execution of the command and use the
  34. *                 current file as the output file.
  35. *
  36. ************************************************
  37.  
  38. TRUE  = 1
  39. FALSE = 0
  40.  
  41. * Obtain parameters from command line
  42. Parse Arg "/" MessageText "/" EditvSuffix TempFileid TypeOfLine NextKey PrevKey CurrKey ShellCmd Parms
  43.  
  44. * Make sure we got the parameters needed before continuing!
  45. If EditvSuffix = "" | TempFileid = "" | TypeOfLine = "" | NextKey = "" | PrevKey = "" | CurrKey = "" Then
  46.    Call FatalErr 4 'Missing parameters in RUNCMD.KEX'
  47.  
  48. * We depend on KEDIT messages to convey info to user
  49. MsgMode = MsgMode.1()
  50. If MsgMode = "OFF" Then "Set MsgMode ON"
  51.  
  52. UseGetCommand = FALSE;
  53.  
  54. * Process user's command
  55. If Parms \= '+find' & Parms \= '-find' & Parms \= '-+find' Then Do
  56.    SourceFid = Fileid.1()
  57.    * An argument of "-" means skip the command step and use current
  58.    *  file as if it were command output
  59.    If Parms \= '-' Then Do
  60.  
  61.       * Get rid of any old error logs on disk or in memory
  62.       Call ErrorCheck 'Kedit .:.\'TempFileid '(New NoProf'
  63.       If (Ring.0() > 1) & (SourceFid \= Fileid.1()) Then
  64.          'QQuit'
  65.       Else Do
  66.          UseGetCommand = TRUE
  67.          'NoMsg Delete All'
  68.       End
  69.  
  70.       'NoMsg Erase .:.\'TempFileid
  71.       If Upper(TestFid) \= Upper(TempFileid) Then
  72.          Call ErrorCheck 'Kedit' SourceFid
  73.  
  74.       * Process any placeholders in the command string
  75.       P = Pos("%s", Parms)
  76.       If P \= 0 Then
  77.          Parms = Substr(Parms, 1, P - 1)Fileid.1()Substr(Parms, P + 2)
  78.       P = Pos("%n", Parms)
  79.       If P \= 0 Then
  80.          Parms = Substr(Parms, 1, P - 1)FName.1()Substr(Parms, P + 2)
  81.  
  82.       * Remember current directory, in case the command changes it
  83.       SaveDir = Directory.1()
  84.  
  85.       * Execute the command
  86.  
  87.       If ShellCmd = "DOSNOWAIT" | ShellCmd = "DOS" Then
  88.          ShellCmd "/c" TempFileid Parms
  89.       Else
  90.          ShellCmd Parms ">"TempFileid
  91.  
  92.       * Restore current directory
  93.       'NoMsg ChDrive' Substr(SaveDir, 1, 1)
  94.       'NoMsg ChDir' SaveDir
  95.  
  96.    End
  97.    * Edit the error log (abort if impossible or empty)
  98.    If UseGetCommand = FALSE Then
  99.       Call ErrorCheck 'Kedit .:.\'TempFileid '(NoProf'
  100.    Else Do
  101.       Call ErrorCheck 'Get .:.\'TempFileid
  102.       'NoMsg Top'
  103.    End
  104.  
  105.    If Size.1() = 0 Then Do
  106.       If Ring.0() > 1 Then 'QQuit'
  107.       Call FatalErr 1 'No output from' Parms
  108.    End
  109.  
  110.    * Insert command into error log
  111.    If Parms \= '-' Then Do
  112.       'I' Parms
  113.       'Set Alt 0 0'
  114.    End
  115.  
  116.    * Remember number of editv variables from previous run
  117.    Call ErrorCheck 'Editv Get Total.'EditvSuffix
  118.    OldErrors = Total.EditvSuffix
  119.  
  120.    * These 2 lines inserted for OPTASM, which starts error logs with a linefeed
  121.    Call ErrorCheck 'Locate :1'
  122.    If Substr(CurLine.3(), 1, 1) = 'a'x Then Call ErrorCheck 'Shift Left'
  123.  
  124.    * Process all message lines in error listing
  125.    * First, ignore any lines that can't have error messages
  126.    'NoMsg All /:/'
  127.  
  128.    If RC \= 0 Then Do
  129.       'NoMsg All'
  130.       Call ErrorCheck 'Set CurLine On 3'
  131.       'NoMsg Locate :1'
  132.       'SOS Beep'
  133.       'Dialog' Delimit("No recognizable" TypeOfLine"s encountered") 'OK'
  134.       If MsgMode = "OFF" Then "Set MsgMode OFF"
  135.       Exit 1
  136.    End
  137.  
  138.    * RC output can cause problems
  139.    'Extract /Zone/'
  140.    * Troublesome RC output will have  "#line" starting in column one
  141.    'NoMsg Set Zone 1 5'
  142.    'NoMsg Less /#line/'
  143.    'NoMsg Set Zone' Zone.1 Zone.2
  144.  
  145.    'NoMsg Top'
  146.    Total.EditvSuffix = 0
  147.    Do Forever
  148.       Call ErrorCheck 'Kedit' TempFileid
  149.       'NoMsg Next'
  150.       If RC \= 0 Then Leave
  151.  
  152.       * Process error messages in one of the following formats:
  153.       *   filename(row):message
  154.       *   filename(row,column): message
  155.       *   filename(row:column): message
  156.       *   filename row column: message
  157.       *   "filename", row column:message
  158.       *   Error filename row: message
  159.  
  160.       Line = CurLine.3()
  161.       Parse Var Line Prefix ":" Message
  162.       If (SubStr(Message, 1, 1) = "\" | Substr(Message, 1, 1) = "/") & Length(Strip(Prefix)) = 1 Then Do
  163.          * Probably picked up a colon in the fileid
  164.          Parse Var Message MorePrefix ":" Message
  165.          Prefix = Prefix":"MorePrefix
  166.       End
  167.  
  168.       If (Pos('(', Prefix) \= 0) & (Pos(')', Prefix) = 0) & (Pos(')', Message) \= 0) Then Do
  169.          * Picked up a colon inside the parenthesis
  170.          Parse Var Message MorePrefix ":" Message
  171.          Prefix = Prefix":"MorePrefix
  172.       End
  173.  
  174.       Open = Pos('(', Prefix)
  175.       If Open > 0 Then Do
  176.          Close = Pos(')', Substr(Prefix, Open + 1))
  177.          If Close = 0 Then Iterate
  178.          Parse Var Prefix Fid "(" LineNO "," . ")"
  179.          Parse Var LineNO LineNO ":"
  180.          Parse Var LineNO LineNO ")"
  181.       End
  182.       Else Do
  183.          If Substr(Prefix, 1, 1) = '"' Then Do
  184.             CloseQuote = Pos('",', Substr(Prefix, 2))
  185.             If CloseQuote = 0 Then Iterate
  186.             Parse Var Prefix '"' Fid '"' LineNO .
  187.          End
  188.          Else Do
  189.             BorlandCheck = Word(Prefix, 1)
  190.             If BorlandCheck = "Error" | BorlandCheck = "Warning"
  191.                Then
  192.                   Parse Var Prefix . Fid LineNO .
  193.                Else
  194.                   Parse Var Prefix Fid LineNO .
  195.          End
  196.       End
  197.  
  198.       If \DataType(LineNO, 'N') | Message = '' | Length(Fid) = 0 Then Iterate
  199.       If Upper(Fid) = "<UNKNOWN>" Then Iterate
  200.  
  201.       * Ignore any troublesome macro messages from MASM 6.0
  202.       If Upper(Strip(Message)) = "MACRO CALLED FROM" Then Do
  203.          'NoMsg Next'
  204.          Iterate
  205.       End
  206.  
  207.       * Change any /s in the fileid to \s
  208.       Fid = Translate(Fid, '\', '/')
  209.       Total.EditvSuffix = Total.EditvSuffix + 1
  210.       Call ErrorCheck 'Editv SetL Line.'Total.EditvSuffix'.'EditvSuffix Fid Message
  211.       Call ErrorCheck 'Kedit' Fid '(NoDefExt'
  212.       'NoMsg Locate :'LineNO
  213.       If RC > 1 Then Iterate
  214.       Call ErrorCheck 'Set Point .'EditvSuffix'.'Total.EditvSuffix
  215.    End
  216.  
  217.    Call ErrorCheck 'All'
  218.  
  219.    * Clear out any extra editv variables from the last run
  220.    If DataType(OldErrors, 'N') Then
  221.       Do I = Total.EditvSuffix + 1 To OldErrors
  222.          Call ErrorCheck 'Editv Set Line.'I'.'EditvSuffix
  223.       End
  224.  
  225.    * Set global variable indicating number of lines
  226.    Call ErrorCheck 'Editv Put Total.'EditvSuffix
  227.  
  228.    * If no lines, issue a message and exit
  229.    if Total.EditvSuffix = 0 Then Do
  230.       Call ErrorCheck 'Set CurLine On 3'
  231.       'NoMsg Locate :1'
  232.       'SOS Beep'
  233.       'Dialog' Delimit("No recognizable" TypeOfLine"s encountered") 'OK'
  234.       If MsgMode = "OFF" Then "Set MsgMode OFF"
  235.       Exit 1
  236.    End
  237.  
  238.    * Define keys to find next, previous, and current lines
  239.    'NoMsg Define' NextKey '"Macro RUNCMD /' || MessageText || '/' EditvSuffix TempFileid TypeOfLine NextKey PrevKey CurrKey ShellCmd '+find"'
  240.    If RC \= 0 Then
  241.       Call FatalErr RC "Unable to define key" NextKey
  242.    'NoMsg Define' PrevKey '"Macro RUNCMD /' || MessageText || '/' EditvSuffix TempFileid TypeOfLine NextKey PrevKey CurrKey ShellCmd '-find"'
  243.    If RC \= 0 Then
  244.       Call FatalErr RC "Unable to define key" PrevKey
  245.    * Define key to recall current message
  246.    'NoMsg Define' CurrKey '"Macro RUNCMD /' || MessageText || '/' EditvSuffix TempFileid TypeOfLine NextKey PrevKey CurrKey ShellCmd '-+find"'
  247.    If RC \= 0 Then
  248.       Call FatalErr RC "Unable to define key" CurrKey
  249.  
  250.    * Setup to locate the first error
  251.    If NBFile.1() > 1 Then 'QQuit'
  252.    Current.EditvSuffix = 0
  253.    Call ErrorCheck 'Editv Put Current.'EditvSuffix
  254.    Parms = '+find'
  255.    'SOS Beep'
  256. End
  257.  
  258. Call ErrorCheck 'Editv Get Total.'EditvSuffix
  259. Call ErrorCheck 'Editv Get Current.'EditvSuffix
  260.  
  261. * Find next or previous lines (+find and -find)
  262. If \DataType(Total.EditvSuffix, 'N') | \DataType(Current.EditvSuffix, 'N') Then
  263.    Call FatalErr 99 'RUNCMD.KEX setup error'
  264.  
  265. If Total.EditvSuffix = 0 Then
  266.    Call FatalErr 1 'No' TypeOfLine's found'
  267.  
  268. If Parms \= '-+find' Then Do
  269.    If Parms = '+find' Then
  270.       Current.EditvSuffix = Min(Current.EditvSuffix + 1, Total.EditvSuffix + 1)
  271.    Else If Parms = '-find' Then
  272.       Current.EditvSuffix = Max(Current.EditvSuffix - 1, 0)
  273.    Else
  274.       Call FatalErr 99 "Unrecognized parameter: '"Parms"'"
  275.  
  276.    If 1 > Current.EditvSuffix Then Do
  277.       Current.EditvSuffix = 1
  278.       'Editv Put Current.'EditvSuffix
  279.       'Msg No previous' TypeOfLine's'
  280.       exit
  281.    End
  282.  
  283.    If Current.EditvSuffix > Total.EditvSuffix Then Do
  284.       Current.EditvSuffix = Total.EditvSuffix
  285.       'Editv Put Current.'EditvSuffix
  286.       'Msg No more' TypeOfLine's'
  287.       exit
  288.    End
  289.  
  290.    'Editv Put Current.'EditvSuffix
  291. End
  292.  
  293. CurrentLine = Current.EditvSuffix
  294.  
  295. Call ErrorCheck 'Editv Get Line.'CurrentLine'.'EditvSuffix
  296.  
  297. Parse Var Line.CurrentLine.EditvSuffix Fid Message
  298.  
  299. Call ErrorCheck 'Kedit' Fid '(NoDefExt'
  300. If Size.1() = 0 Then Do
  301.    'QQuit'
  302.    Call FatalErr 99 'File' Upper(Fid) 'not found.'
  303. End
  304. Else Do
  305.    'NoMsg Locate .'EditvSuffix'.'CurrentLine
  306.    If RC > 1 Then Do
  307.       'Msg' CurrentLine 'of' Total.EditvSuffix '- Use' NextKey'/'PrevKey'/'CurrKey 'to find the next/previous/current' TypeOfLine
  308.       'Msg Cannot locate the line.  It was probably deleted from the file.'
  309.       If MsgMode = "OFF" Then "Set MsgMode OFF"
  310.       Return 1
  311.    End
  312. End
  313.  
  314. MessageOut = Strip(MessageText)
  315. P = Pos("%m", MessageOut)
  316. If P \= 0 Then
  317.    MessageOut = Substr(MessageOut, 1, P - 1) || Strip(Message) || Substr(MessageOut, P + 2)
  318.  
  319. 'Msg' CurrentLine 'of' Total.EditvSuffix '- Use' NextKey'/'PrevKey'/'CurrKey 'to find the next/previous/current' TypeOfLine
  320.  
  321. WindowWidth = LScreen.2()
  322. 'Extract /SCROLLBAR/'
  323. If ScrollBar.1 = "ON" & (ScrollBar.2 = "VERTICAL" | ScrollBar.2 = "BOTH") Then
  324.    WindowWidth = WindowWidth - 1
  325.  
  326. Do While MessageOut \= ''
  327.    'Msg' Substr(MessageOut, 1, WindowWidth)
  328.    MessageOut = Substr(MessageOut, WindowWidth + 1)
  329. End
  330.  
  331. 'SOS Current Firstch'
  332.  
  333. If MsgMode = "OFF" Then "Set MsgMode OFF"
  334. Return 0
  335.  
  336. ************************************************
  337. * Subroutine to bail out with error message in alert box
  338. *  Note: This subroutine never returns to it's caller
  339. ************************************************
  340. FatalErr:
  341.    Parse Arg ReturnCode ErrorMessage
  342.    If ErrorMessage \= "" Then 'Alert' Delimit(ErrorMessage)
  343.    If MsgMode = "OFF" Then "Set MsgMode OFF"
  344.    Exit ReturnCode
  345.  
  346. ************************************************
  347. * Execute command and check for zero return code
  348. *  If RC is not 0, then bail out with FatalErr
  349. ************************************************
  350. ErrorCheck:
  351.    Parse Arg CmdString
  352.    NoMsgCmd = "NOMSG"
  353.    * NOMSG KEDIT and REPROFILE OFF can result in undesirable
  354.    * ... MSGMODE OFF situations
  355.    If Upper(Word(CmdString, 1)) = "KEDIT" Then NoMsgCmd = ""
  356.    NoMsgCmd CmdString
  357.    If RC \= 0 & NoMsgCmd \= "" Then
  358.       Call FatalErr RC "From <"Word(CmdString, 1)">" LastMsg.1()
  359.    Else If RC \= 0 Then Call FatalErr RC
  360.    Return
  361.