/*
$Id: compile.the,v 1.1 2001/01/04 09:40:25 mark Exp $
*/
/***********************************************************************/
/* Description: REXX macro to simulate an Integrated Development       */
/*              Environment (IDE) for a C program.                     */
/* Syntax:      COMPILE compiler                                       */
/* Notes:       This macro is a very simple attempt at development of  */
/*              and IDE using THE as the engine.                       */
/*              The current C program is compiled (syntax of compile   */
/*              command dependant on supplied parameter); the output   */
/*              of the compiler is redirected to a temporary file, the */
/*              macro reads this file and parses each line to determine*/
/*              the line number and error message. Each line is then   */
/*              given a name associated with the error message.        */
/*              The macro then goes into an infinite loop reading      */
/*              keystrokes from the user via READV KEY until the exit  */
/*              key is hit. The macro will position the focus line     */
/*              associated with each error message vi the next and     */
/*              previous error keys (defined below).                   */
/*              Normal editing is possible while in this macro,        */
/*              although the user will notice significant response     */
/*              delays.                                                */
/***********************************************************************/
Trace o
Parse Arg comp .
If comp = '' Then
  Do
    'emsg No compiler supplied'
    Return
  End
'EXTRACT /CURLINE/FNAME/FPATH/VERSION/ALT/'       /* get various stuff */
If rc \= 0 Then
   Do
     Say 'Error in EXTRACT:' rc
     Exit 1
   End
If alt.1 > 0 Then
   Do
     'save'                            /* save any changes to the file */
     If rc \= 0 Then Exit 0
   End
/*---------------------------------------------------------------------*/
/* The default settings in the following block can be tailored to your */
/* own preferences.                                                    */
/*---------------------------------------------------------------------*/
key_exit = 'F3'                                   /* key to exit macro */
key_prev = 'F7'                       /* key to move to previous error */
key_next = 'F8'                           /* key to move to next error */
/*rsrvd_line = curline.1+1*/    /* line on which to display error messages */
rsrvd_line = 3
tmpfile = 'tmp.tmp'                          /* name of temporary file */
/*---------------------------------------------------------------------*/
filename = fpath.1||fname.1
idx = 0
err. = ''
'osredir' tmpfile comp filename
Do While(Lines(tmpfile) > 0)
   line = Linein(tmpfile)
   Select
     When comp = 'cc' Then 
          Do
            Parse Var line '"' fn '"' 'line ' line ':'  message
            If Datatype(line) = 'NUM' Then Call setline
          End
     When comp = 'c89' Then
          Do
            Parse Var line '"' fn '"' 'line ' line '.' . ': ' message
            If Datatype(line) = 'NUM' Then Call setline
          End
     When comp = 'icc' Then 
          Do
            Parse Var line fn '(' line ':' col ')' . message
            If Datatype(line) = 'NUM' & Datatype(col) = 'NUM' Then Call setline
          End
     When comp = 'gcc' Then
          Do
            Parse Var line first 3 fn ':' line ': ' message
            fn = first||fn
            If Datatype(line) = 'NUM' Then Call setline
          End
   End
End
rc = Lineout(tmpfile)

If version.3 = 'UNIX' | version.3 = 'X11' Then 'osq rm -f' tmpfile
Else 'osq del' tmpfile

num_errs = idx
idx = 1
If num_errs = 0 Then
   Do
     'msg No errors'
     'nomsg reserved * off'
     Return
   End
'msg' num_errs 'errors encountered'
Call show_err err.1

Do Forever
   'readv key'
   Select
     When readv.1 = key_exit Then Leave
     When readv.1 = key_prev Then
          Do
            If idx \= 1 Then idx = idx - 1
            Call show_err err.idx
          End
     When readv.1 = key_next Then
          Do
            If idx \= num_errs Then idx = idx + 1
            Call show_err err.idx
          End
     Otherwise 
          Do
            'hit' readv.1
            If rc \= 0 Then Leave
          End
  End
End
'nomsg reserved' rsrvd_line 'off'
Return

show_err: Procedure Expose rsrvd_line
Parse Arg err
fn = Word(err,1)
lineno = Word(err,2)
message = Subword(err,3)
'nomsg reserved * off'
'x' fn
'nomsg locate .l'||lineno
If rc < 2 Then 'reserved' rsrvd_line message
Else 'msg Original line:' lineno 'no longer exists'
Return

setline:
'x' fn
':'||line
'set point .l'||line
idx = idx + 1
err.idx = fn line message
Return
