home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / sprint / spturbo.arc / TURBO.SPM < prev   
Text File  |  1989-08-01  |  32KB  |  1,031 lines

  1. ;  Copyright (c) 1988, 1989 Ralf Brown.  All Rights Reserved.
  2. ;  Portions derived from code Copyright 1988 Borland International
  3. ;  Other portions from COMPILE.SPM by Chris Barker, CIS ID 72261,2312
  4. ;
  5. ;       May be freely redistributed provided no fee is charged and the above
  6. ;       copyright notice remains intact.
  7. ;---------------------------------------------------------------------
  8. ;  Turbo Languages compilation support package: Turbo Pascal, Turbo C,
  9. ;  Turbo Assembler, Turbo Debugger.  Allows setting compiler options which
  10. ;  will be passed to the command-line versions of the compilers.
  11. ;
  12. ;  To install, just load this file with the Alt-U-M-R or Alt-U-M-L command.
  13. ;  Uncomment the last line if you want the new user interface saved as the
  14. ;  default user interface.
  15. ;
  16. ;    Created:    Nov 12, 1988
  17. ;    LastEdit:    Aug 1, 1989
  18. ;    Release:    v2.3
  19. ;---------------------------------------------------------------------
  20. ; New and changed keys:
  21. ;    Alt-V    view file in read-only mode
  22. ;    Alt-F2  save all files
  23. ;    Alt-F3  run debugger
  24. ;    Alt-F4  run program, swapping out Sprint
  25. ;    Alt-F5  go to first message in error file
  26. ;    Alt-F6  go to last message in error file    
  27. ;    Alt-F7  find previous error or warning
  28. ;    Alt-F8  find next error or warning
  29. ;    Shf-F9  compile file (pops up menu if not .C, .H, .PAS, .ASM, or .SPM)
  30. ;    Alt-F9  run MAKE
  31. ;    Alt-F10 remove error list
  32. ;       ), ], }    briefly move cursor to matching opening delimiter
  33. ;    Shf-Alt-C  pop up compiler menu, allows setting compiler options
  34. ;    Shf-Alt-D  show declaration corresponding to English description
  35. ;    Shf-Alt-E  explain declaration on the current line, or marked declaration
  36. ;    Shf-Alt-F  add for(;;){} at cursor position
  37. ;    Shf-Alt-P  add printf() call at cursor position
  38. ;    Shf-Alt-W  add while(){} at cursor position
  39. ;---------------------------------------------------------------------
  40. ; Q registers used:
  41. ;    Q1    name of file containing error or warning, misc
  42. ;    Q4    path to file(s) being compiled
  43. ;    Q7    miscellaneous
  44. ;    QD    original path; file before switching to error; line number
  45. ;    QP    compiler command-line switches, other scratch storage
  46. ;---------------------------------------------------------------------
  47. ; Program History:
  48. ;    v1.0    12/12/88    first release
  49. ;    v1.1    1/8/89        fixed delimiter-matching when inside a string
  50. ;    v1.2    3/8/89        sped up delimiter-matching
  51. ;    v2.0    7/9/89        merged with COMPILE.SPM by Chris Barker
  52. ;                now parses TP and TASM error messages
  53. ;    v2.1    7/10/89        minor bug fixes
  54. ;    v2.2    7/14/89        added more TurboC and TurboPascal options
  55. ;    v2.3    8/1/89        additional TP5.5 flags
  56. ;                second release
  57. ;---------------------------------------------------------------------
  58.  
  59. ; start with default Borland user interface
  60. #include "sp"
  61.  
  62. ;---------------------------------------------------------------------
  63. ; Initialize debug code generation to false(0).  These settings will be 
  64. ; sticky - they will stay set to however you last set them.
  65.  
  66. int Pdebug    0        
  67. int Cdebug    0
  68. int Adebug      0
  69.  
  70. ; Initialize memory model
  71.  
  72. int Cmodel      1 ; 0 = -mt, 1 = -ms, 2 = -mc, 3 = -mm, 4 = -ml, 5 = -mh
  73.  
  74. ; Initialize command-line options to none
  75. ; These are also "sticky"
  76.  
  77. int Copts       0
  78. int PASopts     0
  79. int ASMopts     0
  80. int Lopts       0
  81.  
  82. ;---------------------------------------------------------------------
  83.  
  84. SaveUI : $ ovlwrite "turbo.ui" ovlwrite "sp"
  85.  
  86. ;---------------------------------------------------------------------
  87.  
  88. InsideQuotes:
  89.    0 -> int single
  90.    0 -> int double
  91.  
  92.    stopped mark {
  93.       tosol
  94.       do {
  95.          2 search "[\"\'\n]"
  96.      if (before themark)
  97.         {
  98.         if (current == '\'' && double == 0)
  99.            1 - single -> single
  100.         if (current == '"' && single == 0)
  101.            1 - double -> double
  102.         c
  103.         }
  104.      }
  105.       while (before themark)
  106.    }
  107.    single || double
  108.  
  109. ;---------------------------------------------------------------------
  110.  
  111. int MatchChar 0
  112.  
  113. ShowMatchingChar :      ; derived from MATCH.SPM, (c) Copyright Borland International
  114.    ->int ThisChar
  115.    1 -> int NestingLevel
  116.    dline -> int numlines
  117.    scrollborder -> int old_border
  118.  
  119.    0 -> scrollborder
  120.    set themark                ; remember where we were
  121.    r c                    ; skip back from the just-inserted delimiter
  122.    if (!InsideQuotes)
  123.       {
  124.       r stopped while (NestingLevel && !(r isend))
  125.          {
  126.      2 search "[(){}\\[\\]'\"\n]"
  127.          if (current == ThisChar)
  128.             ++NestingLevel
  129.          else if (current == MatchChar)
  130.             --NestingLevel
  131.      else if (current == '\'')
  132.         {
  133.         to (current == '\'' || isnl)
  134.             c ; skip quote or NL
  135.         }
  136.          else if (current == '"')
  137.         {
  138.         to (current == '"' || isnl)
  139.         c ; skip quote or NL
  140.         }
  141.      else if isnl
  142.         {
  143.         if (--numlines < 0)
  144.            break
  145.         }
  146.      else
  147.             c                ; keep moving backwards
  148.          }
  149.       if (NestingLevel == 0)        ; found?
  150.          mark
  151.             {
  152.            set themark            ; highlight the matched character for
  153.             1->select            ; 1/10 second
  154.             c
  155.             draw
  156.             100 wait
  157.             0->select
  158.         r c
  159.             draw
  160.             }
  161.       else if !isnl
  162.          {
  163.          MatchChar message "no matching '%c'"
  164.          }
  165.       }
  166.    swap themark
  167.    old_border -> scrollborder
  168.  
  169. ;---------------------------------------------------------------------
  170.  
  171. ParseCerror :
  172.    tosol
  173.    mark {
  174.       if (current == 'W')        ; is it a warning or an error?
  175.         set Q7 "W"
  176.       else
  177.      set Q7 "E"
  178.       past istoken            ; skip to filename
  179.       to istoken
  180.       copy to iswhite Q1        ; and get it
  181.       to iswhite            ; skip to line number
  182.       c
  183.       copy to (current == ':') QD    ; get line number
  184.       1 -> append 
  185.       copy to (current == ':') Q7    ; add line to output message
  186.       to (current == ':')        ; skip to error message
  187.       c
  188.       1 -> append
  189.       copy toeol Q7            ; & append it to output message
  190.       mode Q7                ; now show the parsed error message
  191.    }
  192.  
  193. ;---------------------------------------------------------------------
  194.  
  195. ParseASMerror :
  196.    tosol
  197.    mark {
  198.       c                    ; skip the "**" at the start of the line
  199.       if (current == 'W')        ; is it a warning or an error?
  200.         set Q7 "W"
  201.       else
  202.          {
  203.          c
  204.      if (current == 'F')        ; was it a Fatal error?
  205.         set Q7 "F"
  206.      else
  207.         set Q7 "E"
  208.      }
  209.       to iswhite
  210.       c
  211.       copy to (current == '(') Q1    ; and get it
  212.       to (current == '(')
  213.       c
  214.       copy to (current == ')') QD    ; get line number
  215.       1 -> append
  216.       copy to (current == ')') Q7    ; and also add it to output message
  217.       to iswhite            ; skip to error message
  218.       1 -> append
  219.       copy toeol Q7            ; and add it to the output message
  220.       mode Q7                ; now show the parsed error message
  221.    }
  222.  
  223. ;---------------------------------------------------------------------
  224.  
  225. ParsePASerror :
  226.    tosol
  227.    mark {
  228.       copy to (current == '(') Q1    ; get filename in which error occurred
  229.       to (current == '(')        ; now skip it
  230.       c
  231.       copy to (current == ')') QD    ; get line number
  232.       to isgray
  233.       c                    ; skip blank before "Error" or "Warning"
  234.       if (current == 'W')        ; was this a warning or an error?
  235.          set Q7 "W"
  236.       else
  237.      set Q7 "E"
  238.       to (current == ':')        ; skip message type
  239.       c
  240.       mark { to Q7 toend insert QD }    ; add line number to output message
  241.       1 -> append
  242.       copy toeol Q7            ; add error message to output
  243.       mode Q7                ; and now show the parsed err message
  244.    }
  245.  
  246. ;---------------------------------------------------------------------
  247. ;  Check if the current line in the current buffer is an error or
  248. ;  warning message.  Return 0 if not, 1 if TCC-style error, 2 if TASM-style
  249. ;  error, or 3 if TPas-style error
  250.  
  251. IsErrorMsg :
  252.    int type
  253.  
  254.    if (((0 match "Warning") && !(0 match "Warning messages")) ||
  255.        ((0 match "Error") && !(0 match "Error messages")))
  256.       1 -> type
  257.    else if ((0 match "**Error**") || (0 match "*Warning*") || (0 match "**Fatal**"))
  258.       2 -> type
  259.    else
  260.       mark {
  261.      to isgray
  262.      if ((0 match " Error ") || (0 match " Warning"))
  263.         3 -> type
  264.          else
  265.         0 -> type   
  266.       }
  267.    type
  268.  
  269. ;---------------------------------------------------------------------
  270.  
  271. ShowErrorMsg :
  272.     -> int type
  273.     int WasFound
  274.  
  275.     2 -> statline
  276.     set Q1 ""
  277.  
  278.     buffind "MAKE.$$$"
  279.     type case {
  280.        1  ParseCerror,        ; display parsed errror message
  281.        2  ParseASMerror,
  282.        3  ParsePASerror,
  283.        $  error "internal: unknown error message type"
  284.     }
  285.         1 AllCaps                       ; uppercase filename in Q1
  286.     if (!buffind Q1)        ; switch to file with error if loaded, 
  287.        {                ; otherwise find and load the file
  288.        set Q7 cd            ; store current directory
  289.        set cd Q4            ; switch to dir containing files
  290.        open Q1 -> WasFound        ; try to open the file
  291.        set cd Q7            ; and restore directory
  292.        if !WasFound
  293.           {
  294.           close            ; don't want the buffer just created
  295.           error "File not found"
  296.           }
  297.        }
  298.     atoi QD -> line            ; jump to line with error
  299.         draw                            ; force screen update
  300.     
  301. ;---------------------------------------------------------------------
  302.  
  303. FirstError :
  304.     int type 
  305.     0 -> int Done
  306.  
  307.     tosol
  308.     while (!(IsErrorMsg -> type) && (1->Done) && line != ++line)
  309.        0 -> Done
  310.     if Done
  311.        {
  312.        if (statline > 1)
  313.           1 -> statline
  314.            message "\nCompilation successful.  Press a key..."
  315.        key
  316.        message "\n"
  317.        }
  318.     else
  319.        { type ShowErrorMsg }
  320.        
  321. ;---------------------------------------------------------------------
  322.  
  323. FlagsHack :
  324.     ; hook to allow UI which includes this file to use flag[3456] in
  325.     ; the flags line
  326.  
  327. ;---------------------------------------------------------------------
  328.  
  329. Restart :                ; patterned after Borland's Restart
  330.     NormalMode
  331.     FlagsHack            ; hook to reset flag3, flag4, flag5, flag6
  332.     mark
  333.            {
  334.        if (exist "log.$$$")        ; for compatibility with standard UI 
  335.               {
  336.           draw pageread "log.$$$"
  337.               fdelete "log.$$$"
  338.               }
  339.            }
  340.        if (exist "MAKE.$$$")
  341.        {
  342.        open "MAKE.$$$"
  343.            fdelete "MAKE.$$$"           ; don't need error file anymore
  344.        set cd QD            ; restore our old directory
  345.            FirstError                   ; and show the first message
  346.            }
  347.         while keypressed        ; get rid of any typeahead
  348.        key
  349.  
  350. ;---------------------------------------------------------------------
  351.  
  352. FindErrorFile :
  353.    if (!buffind "MAKE.$$$")        ; switch to buffer containing messages
  354.       error "No error file"
  355.  
  356. ;---------------------------------------------------------------------
  357.  
  358. NoMoreErrors :
  359.    if (statline > 1)
  360.       1 -> statline        ; shut off separate line for messages
  361.    message "\nNo more errors or warnings.  Press a key..."
  362.    key
  363.    message "\n"
  364.    buffind QD            ; return to original file
  365.  
  366. ;---------------------------------------------------------------------
  367.  
  368. ToPrevError:
  369.     int type
  370.     0 -> int Done
  371.  
  372.         set QD fname                    ; remember where we were
  373.     FindErrorFile            ; switch to file containing errors
  374.         --line                          ; back up a line
  375.        while (!(IsErrorMsg -> type) && (1->Done) && line != --line)
  376.            0 -> Done            ; continue backing up until msg found
  377.     if Done
  378.        NoMoreErrors
  379.     else
  380.        { type ShowErrorMsg }
  381.  
  382. ;---------------------------------------------------------------------
  383.  
  384. ToNextError :
  385.     int type
  386.     0 -> int Done
  387.  
  388.         set QD fname                    ; remember where we were
  389.     FindErrorFile
  390.         ++line                          ; down a line
  391.        while (!(IsErrorMsg -> type) && (1->Done) && line != ++line)
  392.            0 -> Done                    ; continue down until message found
  393.     if Done
  394.        NoMoreErrors
  395.     else
  396.        { type ShowErrorMsg }
  397.  
  398. ;---------------------------------------------------------------------
  399.  
  400. ToFirstError:
  401.     FindErrorFile
  402.     r toend
  403.     ToNextError
  404.  
  405. ;---------------------------------------------------------------------
  406.  
  407. ToLastError:
  408.     FindErrorFile
  409.     toend
  410.     ToPrevError
  411.  
  412. ;---------------------------------------------------------------------
  413.  
  414. CloseErrorFile :
  415.    mark
  416.       {
  417.       if (buffind "MAKE.$$$")        ; get rid of buffer for error messages
  418.          close
  419.       }
  420.  
  421. ;---------------------------------------------------------------------
  422.  
  423. SaveAllFiles :
  424.         mark
  425.            {
  426.            bufnum -> int old_buf        ; remember where we were
  427.  
  428.        do {                ; for each buffer: if modified, save
  429.           if (modf == 1 && !IsUnnamed)
  430.          write fname
  431.           } while (bufswitch && bufnum != old_buf)
  432.        }
  433.     message "\nAll files saved"
  434.  
  435. ;---------------------------------------------------------------------
  436.  
  437. GetCompileDir :
  438.         set QD cd                       ; remember where we were
  439.         set Q4 fname                    ; get name of file in current buffer
  440.         mark
  441.            {
  442.            to Q4 toend r c              ; strip off last component of name
  443.        while (length Q4 && current != '/' && current != '\\' && current != ':')
  444.           {
  445.           del
  446.           r c
  447.           }
  448.        if (current == '\\' || current == '/')
  449.           del
  450.        }
  451.     CloseErrorFile
  452.         set cd Q4                       ; go to directory containing the file
  453.  
  454. ;---------------------------------------------------------------------
  455.  
  456. MakeOptionsPermanent :
  457.     if ovlmodf 
  458.        ovlwrite "sp.ovl"
  459.  
  460. ;---------------------------------------------------------------------
  461.  
  462. RunDebugger:
  463.         if length fname
  464.        set QP fchange "%.EXE" fname
  465.     else
  466.        set QP ""
  467.     message "\nProgram to debug: "
  468.     set QP
  469.     MakeOptionsPermanent    ; Sprint doesn't save overlay when swapping!
  470.     24 call "td" QP        ; load TD, swapping out Sprint
  471.  
  472. ;---------------------------------------------------------------------
  473.  
  474. RunProgram:
  475.         if length fname
  476.        set QP fchange "%.EXE" fname
  477.     else
  478.        set QP ""
  479.     message "\nProgram to run: "
  480.     set QP
  481.     MakeOptionsPermanent    ; Sprint doesn't save overlay when swapping!
  482.     25 call QP        ; run program, swapping out Sprint
  483.  
  484. ;---------------------------------------------------------------------
  485.  
  486. SelectModel: 
  487.         menu "Memory Model" {
  488.         "Tiny"        0 -> Cmodel,
  489.         "Small"       1 -> Cmodel,
  490.         "Compact"     2 -> Cmodel,
  491.         "Medium"      3 -> Cmodel,
  492.         "Large"       4 -> Cmodel,
  493.         "Huge"        5 -> Cmodel
  494.     }
  495.  
  496. ;---------------------------------------------------------------------
  497.  
  498. PASSettingsMenu:
  499.     stopped do {
  500.         menu "Pascal Settings" {
  501.                 Pdebug        "Debug Info\>%[NO%:YES%]"    !Pdebug->Pdebug,
  502. ;--comment out next two lines for TP4
  503.                 (PASopts & 3) "Map File\>%[None%;Segments%;Publics%:Detail%]"
  504.                   (PASopts & ~3)|(((PASopts&3)+1) & 3)->PASopts,
  505. ;--and use the next line instead
  506. ;            (PASopts & 3) "Map File\>%[NO%:YES%]"         PASops^1->PASopts,
  507.             ((PASopts &12)>>2) "Compile Type\>%[Compile%;Build%:Make%]"
  508.                   if (PASopts&12 == 8)
  509.                  (PASopts & ~12)->PASopts 
  510.                   else
  511.                  (PASopts & ~12)|(((PASopts&12)+4)&12)->PASopts,
  512.         (PASopts &16) "Force FAR Calls\>%[NO%:YES%]"  PASopts^16->PASopts,
  513.         (PASopts &32) "Boolean Eval\>%[SHORT%:FULL%]" PASopts^32->PASopts,
  514.         (PASopts &64) "Numerics\>%[SOFT%:HARD%]WARE"  PASopts^64->PASopts,
  515.             (PASopts&128) "Link Buffer\>%[DISK%:MEMORY%]" PASopts^128->PASopts,
  516.         "_Runtime",
  517.                 (PASopts&256) "Stack Checks\>%[NO%:YES%]"     PASopts^256->PASopts,
  518.                 (PASopts&1024)"VarString Checks\>%[ NO%:YES%]" PASopts^1024->PASopts,
  519.                 (PASopts&2048)"Range Checks\>%[NO%:YES%]"     PASopts^2048->PASopts,
  520.                 (PASopts&4096)"I/O Checks\>%[NO%:YES%]"       PASopts^4096->PASopts
  521.         }
  522.     }
  523.  
  524. ;---------------------------------------------------------------------
  525.  
  526. DecodePASsettings:
  527.         set QP "/q"
  528.         mark {
  529.            to QP
  530.            f toend
  531.            if Pdebug
  532.               "/v/$L+/$D+"  ; remove the /v/$L+ for TP4
  533. ;--use the following for TP4
  534. ;       "/$T"
  535. ;        if (PASopts & 3) "+" else "-"
  536. ;--comment out the following if using TP4
  537.        (PASopts & 3) case
  538.           {
  539.           1  "/GS"
  540.           2  "/GP"
  541.           3  "/GD"
  542.           }
  543. ;--end of block to comment out for TP4
  544.        (PASopts & 12) case
  545.           {
  546.           4  "/B"
  547.           8  "/M"
  548.           }
  549.        "/$F"
  550.        if (PASopts & 16) "+" else "-"
  551.        "/$B"
  552.        if (PASopts & 32) "+" else "-"
  553.        "/$N"
  554.        if (PASopts & 64) "+" else "-"
  555.        "/$L"
  556.        if (PASopts & 128) "+" else "-"
  557.        "/$S"
  558.            if (PASopts & 256) "+" else "-"
  559.        "/$V"
  560.            if (PASopts & 1024) "+" else "-"
  561.        "/$R"
  562.            if (PASopts & 2048) "+" else "-"
  563.        "/$I"
  564.            if (PASopts & 4096) "+" else "-"
  565.         }
  566.  
  567. ;---------------------------------------------------------------------
  568.  
  569. CSettingsMenu:
  570.         stopped do {
  571.         menu "C Settings" {
  572.                 Cmodel "Memory Model\>%[T%;S%;C%;M%;L%:H]"    SelectModel,
  573.                 (Copts & 2) "Alignment\>%[BYTE%:WORD%]"       Copts^2->Copts,
  574.                 (Copts & 4) "Generate for\>80%[%:1%]86"       Copts^4->Copts,
  575.                 (Copts & 8) "Calling Conv\>%[C%:Pascal%]"     Copts^8->Copts,
  576.                 (Copts & 1) "Strict ANSI\>%[NO%:YES%]"        Copts^1->Copts,
  577.             (Copts&2048)"Default Chars\>%[  %:UN%]SIGNED" Copts^2048->Copts,
  578.             (Copts &16) "Produce .ASM\>%[NO%:YES%]"       Copts^16->Copts,
  579.             "_Debugging",
  580.                 Cdebug      "Debug Info\>%[NO%:YES%]"         !Cdebug->Cdebug,
  581.         (Copts&512) "Std Stack Frame\>%[YES%:NO%]"    Copts^512->Copts,
  582.         (Copts&1024)"Stack Overflow\>%[NO%:YES%]"     Copts^1024->Copts,
  583.         "_Optimization",
  584.         (Copts&4096)"Optimize for\>%[SPEED%:SIZE%]"   Copts^4096->Copts,
  585.         (Copts&256) "Merge Dup Strings\>%[ NO%:YES%]" Copts^256->Copts,
  586.         "_Warnings",
  587.         (Copts &32) "No Prototype\>%[WARN%:OK%]"      Copts^32->Copts,
  588.         (Copts &64) "No Declaration\>%[WARN%:OK%]"    Copts^64->Copts,
  589.         (Copts&128) "Poss Inc Assign\>%[WARN%:OK%]"   Copts^128->Copts
  590.         }
  591.     }                        
  592.  
  593. ;---------------------------------------------------------------------
  594.  
  595. DecodeCsettings:
  596.         if Cdebug
  597.            set QP "-v "
  598.         else
  599.            set QP ""
  600.         mark {
  601.            to QP
  602.            toend
  603.            Cmodel case {
  604.               0  "-mt",
  605.               1  "-ms",
  606.               2  "-mc",
  607.               3  "-mm",
  608.               4  "-ml",
  609.               $  "-mh"
  610.            }
  611.        " -A"
  612.            if ((Copts & 1) == 0)
  613.               "-"
  614.            " -a"
  615.            if ((Copts & 2) == 0)
  616.               "-"
  617.        "-1"
  618.            if ((Copts & 4) == 0)
  619.               "-"
  620.            if (Copts & 8)
  621.               " -P"
  622.            if (Copts & 16)
  623.           " -S"   ; compile to .ASM
  624.        else
  625.           " -c"   ; compile to .OBJ
  626.        if (Copts & 32)
  627.           " -w-pro"
  628.        if (Copts & 64)
  629.           " -w-nod"
  630.        if (Copts & 128)
  631.           " -w-pia"
  632.        if (Copts & 256)
  633.           " -d"
  634.        " -k"
  635.        if (Copts & 512)
  636.           "-"
  637.        " -N"
  638.        if ((Copts & 1024) == 0)
  639.           "-"
  640.        " -K"
  641.        if ((Copts & 2048) == 0)
  642.           "-"
  643.        " -G"
  644.        if (Copts & 4096)
  645.           "-"
  646.         }
  647.  
  648. ;---------------------------------------------------------------------
  649.  
  650. TASMSettingsMenu:
  651.     stopped do {
  652.         menu "Assembler Settings" {
  653.            Adebug        "Debug Info\>%[NO%:YES%]"          !Adebug->Adebug,
  654.            (ASMopts & 8) "Case Sensitive\>%[NO%:YES%]"      ASMopts^8->ASMopts,
  655.            (ASMopts & 1) "Segment Order \>%[  Seq%:Alpha%]" ASMopts^1->ASMopts,
  656.        "_Listing",
  657.            (ASMopts & 4) "Generate Listing\>%[NO%:YES%]"    ASMopts^4->ASMopts,
  658.            (ASMopts & 2) "XReference\>%[NO%:YES%]"          ASMopts^2->ASMopts,
  659.        (ASMopts &64) "Symbol table\>%[YES%:NO%]"        ASMopts^64->ASMopts,
  660.        "_Compatibility",
  661.        (ASMopts &16) "MASM version\>5.%[0%:1%]"        ASMopts^16->ASMopts,
  662.        (ASMopts &32) "QUIRKS mode\>%[OFF%:ON%]"        ASMopts^32->ASMopts
  663.        }
  664.     }
  665.  
  666. ;---------------------------------------------------------------------
  667.  
  668. DecodeASMsettings:
  669.         set QP "/w"   ; enable warnings
  670.         mark {
  671.            to QP
  672.            toend
  673.        if Adebug
  674.           " /zi"
  675.            if (ASMopts & 1)
  676.               " /a"
  677.            else
  678.               " /s"
  679.            if (ASMopts & 2)
  680.               " /c"
  681.            if (ASMopts & 4)
  682.               " /l"
  683.            if (ASMopts & 8)
  684.               " /ml"
  685.        if (ASMopts & 16)
  686.           " /jmasm51"
  687.        if (ASMopts & 32)
  688.           " /jquirks"
  689.        if (ASMopts & 64)
  690.           " /n"
  691.         }
  692.  
  693. ;---------------------------------------------------------------------
  694.  
  695. LinkSettingsMenu:
  696.         stopped do {
  697.         menu "Linker Settings" {
  698.        (Lopts & 64) "Debug Info\>%[NO%:YES%]"           (Lopts^64)->Lopts,
  699.            (Lopts & 3)  "Map file\>%[None%;Publics%;Lines%:Detail%]"
  700.                                    (((Lopts&3)+1)&3) | (Lopts & ~3) -> Lopts,
  701.            (Lopts & 4)  "Case Sensitive\>%[NO%:YES%]"       (Lopts^4)->Lopts,
  702.            (Lopts & 8)  "Initialize Segments\>%[ NO%:YES%]" (Lopts^8)->Lopts,
  703.            (Lopts & 16) "Duplicate Symbols\>%[OK%:WARN%]"   (Lopts^16)->Lopts,
  704.            (Lopts & 32) "Generate .COM file\>%[NO%:YES%]"   (Lopts^32)->Lopts,
  705.        (Lopts &128) "Use extended dict\>%[YES%:NO%]"    (Lopts^128)->Lopts,
  706.        (Lopts &256) "L use default Libs\>%[YES%:NO%]"     (Lopts^256)->Lopts,
  707.        (Lopts &512) "32-bit processing\>%[NO%:YES%]"    (Lopts^512)->Lopts
  708.            }
  709.         }
  710.  
  711. ;---------------------------------------------------------------------
  712.  
  713. DecodeLINKsettings:
  714.         if (Lopts & 64)
  715.            set QP "/v"
  716.         else
  717.            set QP ""
  718.         mark {
  719.            to QP
  720.            toend
  721.            (Lopts & 3) case {
  722.               0  " /x",
  723.               1  " /m",
  724.               2  " /m/l",
  725.               $  " /m/s"
  726.            }
  727.            if (Lopts & 4)
  728.               " /c"
  729.            if (Lopts & 8)
  730.               " /i"
  731.            if (Lopts & 16)
  732.               " /d"
  733.            if (Lopts & 32)
  734.               " /t"
  735.        if (Lopts & 128)
  736.           " /e"
  737.        if (Lopts & 256)
  738.           " /n"
  739.        if (Lopts & 512)
  740.           " /3"
  741.         }
  742.  
  743. ;---------------------------------------------------------------------
  744.  
  745. RunPascal:
  746.         SaveAllFiles
  747.         GetCompileDir
  748.     status "\nCompiling..."
  749.         DecodePASsettings        ; QP := the selected cmd-line switches
  750.     MakeOptionsPermanent        ; SP 1.00a doesn't update overlay on "call" that swaps!
  751.         56 call "command /ctpc >MAKE.$$$" QP cdstrip fname  ; swap out SP to run compiler
  752. ; if you don't need Sprint to swap out, change the 56 above to 0, comment out
  753. ; the MakeOptionsPermanent, and uncomment the next line
  754. ;    Restart
  755.  
  756. ;---------------------------------------------------------------------
  757.  
  758. RunCCompiler:
  759.         SaveAllFiles
  760.         GetCompileDir
  761.     status "\nCompiling..."        ; clear the status line
  762.         DecodeCsettings            ; QP := the selected cmd-line switches
  763.     set Q1 cdstrip fname
  764.     if (mark (to Q1 1 search ".h")) ; if header, compile corresponding
  765.        set Q1 fchange "%.C" Q1    ; .C source file
  766.     MakeOptionsPermanent        ; SP 1.00a doesn't update overlay on "call" that swaps!
  767.         56 call "command /ctcc >MAKE.$$$" QP Q1 ; swap out SP to run compiler
  768.  
  769. ;---------------------------------------------------------------------
  770.  
  771. RunAssembler:
  772.     SaveAllFiles
  773.         GetCompileDir
  774.     status "\nAssembling...."
  775.         DecodeASMsettings    ; set QP to the selected command-line switches
  776.     MakeOptionsPermanent        ; SP 1.00a doesn't update overlay on "call" that swaps!
  777.         56 call "command /ctasm >MAKE.$$$" QP cdstrip fname
  778. ; if you don't need Sprint to swap out to run the assembler, change the 56 
  779. ; above to 0, comment out the MakeOptionsPermanent, and uncomment the next line
  780. ;    Restart
  781.  
  782. ;---------------------------------------------------------------------
  783.  
  784. RunLinker:
  785.     set Q1 fchange "%.obj" cdstrip fname
  786.         DecodeLINKsettings
  787.         1 call "tlink" QP Q1
  788.  
  789. ;---------------------------------------------------------------------
  790.  
  791. CompileMenu:
  792.     menu "Compiler Menu" {
  793.         "Pascal"       RunPascal,
  794.         "C"           RunCCompiler,
  795.         "Assembler"    RunAssembler,
  796.         "Linker"       RunLinker,
  797.     "_Settings",
  798.         "1 Pascal"     PASSettingsMenu,
  799.         "2 C"          CSettingsMenu,
  800.         "3 Assembler"  TASMSettingsMenu,
  801.         "4 Linker"     LinkSettingsMenu
  802.     }
  803.  
  804. ;---------------------------------------------------------------------
  805.  
  806. CompileFile:
  807.     set Q1 cdstrip fname
  808.     if (mark (to Q1 1 search ".pas"))
  809.        RunPascal
  810.     else if (mark (to Q1 1 search ".asm"))
  811.        RunAssembler
  812.     else if (mark (to Q1 2 search ".[cChH]"))
  813.        RunCCompiler
  814.     else if (mark (to Q1 1 search ".spm"))
  815.        {
  816.        SaveAllFiles
  817.        GetCompileDir
  818.        MacroRunFile
  819.        set cd QD
  820.        }
  821.     else
  822.        CompileMenu   ; unknown extension, so ask what to do
  823.  
  824. ;---------------------------------------------------------------------
  825.  
  826. RunMake:
  827.         SaveAllFiles
  828.         status "\nRunning MAKE..."
  829.     GetCompileDir
  830.     MakeOptionsPermanent
  831.         56 call "command /c >MAKE.$$$ make"  ; run the make, swapping out Sprint
  832.  
  833. ;---------------------------------------------------------------------
  834.  
  835. DeleteErrors:
  836.     if (statline > 1)
  837.            1 -> statline        ; shut off mode line for messages
  838.     CloseErrorFile
  839.     if (exist "MAKE.$$$")        ; in the unlikely event that the error
  840.        fdelete "MAKE.$$$"        ; file still exists, delete it
  841.  
  842. ;---------------------------------------------------------------------
  843.  
  844. CdeclDeclare:
  845.     int old_statline 
  846.  
  847.     message "\nDeclare: "
  848.     set QP ""            ; no default declaration
  849.     set QP                ; get it from user
  850. ;the following section of code is for versions of cdecl which require that all
  851. ;commands are given via standard input
  852. ;    mark
  853. ;       {
  854. ;       open ""            ; make an unnamed buffer
  855. ;       "declare "            ; insert the CDECL command
  856. ;       insert QP            ; and what we want converted
  857. ;       10 insert            ; terminate line
  858. ;       write "CDECL$IN.$$$"        ; save to disk
  859. ;       status "\nWorking...."
  860. ;          close            ; and discard buffer
  861. ;       32 call "command /c cdecl <CDECL$IN.$$$ >CDECL.$$$"
  862. ;       fdelete "CDECL$IN.$$$"    ; don't need input file anymore
  863. ;       }
  864. ; since the cdecl I have can take input from the command line, use short version
  865.     32 call "command /c >CDECL.$$$ cdecl declare" QP
  866. ; comment out prev line and uncomment prior block if cdecl requires input from
  867. ; stdin
  868.     if (exist "CDECL.$$$")        ; did CDECL actually get run?
  869.        mark {
  870.           open "CDECL.$$$"        ; load declaration into a buffer
  871.           fdelete "CDECL.$$$"    ; don't need temp file anymore
  872.           set QP ""
  873.           r toend            ; make sure we're at the beginning
  874.           copy to isnl QP        ; grab the first line
  875.           close            ; don't need temp buffer anymore
  876.        }
  877.     else
  878.        error "CDECL not available"
  879.     statline -> old_statline
  880.     if (statline == 0)
  881.        1 -> statline        ; make sure status line is on
  882.     status QP " /* press a key */"    ; show the declaration
  883.     if (key == 13)            ; wait for keystroke
  884.        insert QP            ; insert declaration if Return pressed
  885.     while keypressed        ; get rid of typeahead, function keys
  886.        key
  887.     old_statline -> statline    ; restore previous state of status line
  888.     draw                ; force screen update
  889.  
  890. ;---------------------------------------------------------------------
  891.  
  892. CdeclExplain:
  893.     int old_statline
  894.  
  895.     message "Explain: "
  896.     mark
  897.        {
  898.        if select            ; if anything is highlighted,
  899.           copy togmark QP        ; grab that
  900.        else
  901.           {
  902.           tosol            ; if nothing highlighted,
  903.           copy to isnl QP        ; grab current line
  904.           }
  905.        set QP            ; let user make any desired modifications
  906.        }
  907. ;the following section of code is for versions of cdecl which require that all
  908. ;commands are given via standard input
  909. ;    mark {
  910. ;       open ""            ; make an unnamed buffer
  911. ;       "explain "            ; put in the CDECL command
  912. ;       insert QP            ; and what we want converted
  913. ;       10 insert            ; terminate line
  914. ;       write "CDECL$IN.$$$"        ; save to disk
  915. ;       status "\nWorking..."
  916. ;       close            ; and discard buffer
  917. ;       32 call "command /c cdecl <CDECL$IN.$$$ >CDECL.$$$"
  918. ;       fdelete "CDECL$IN.$$$"    ; don't need input file anymore
  919. ;       }
  920. ; since the cdecl I have can take input from the command line, use short version
  921.     32 call "command /c >CDECL.$$$ cdecl explain" QP
  922. ; comment out prev line and uncomment prior block if cdecl requires input from
  923. ; stdin
  924.     mark 
  925.            {
  926.           if (exist "CDECL.$$$")    ; did CDECL actually get run?
  927.           {
  928.           open "CDECL.$$$"        ; load declaration into a buffer
  929.               fdelete "CDECL.$$$"    ; don't need temp file anymore
  930.           }
  931.        else
  932.           error "CDECL not available"
  933.        set QP ""
  934.        r toend            ; make sure we're at the beginning
  935.        copy to isnl QP        ; grab the first line
  936.        close            ; don't need temp buffer anymore
  937.        }
  938.     statline -> old_statline
  939.     if (statline == 0)
  940.        1 -> statline        ; make sure status line is on
  941.     status QP " [press a key]"    ; show the explanation
  942.     key                ; wait for keystroke
  943.     while keypressed        ; get rid of typeahead, function keys
  944.        key
  945.     old_statline -> statline    ; restore previous state of status line
  946.     draw                ; force screen update
  947.  
  948. ;---------------------------------------------------------------------
  949.  
  950. InsertPrintf:
  951.     "printf() ;\n"
  952.     r (c c c c)            ; position cursor between parens
  953.  
  954. ;---------------------------------------------------------------------
  955.  
  956. InsertWhile:
  957.    line -> int old_line
  958.    column -> int old_col
  959.  
  960.    "while ()\n"
  961.    while (column < old_col + 3)
  962.       " "
  963.    "{\n\n"
  964.    while (column < old_col + 3)
  965.       " "
  966.    "}"
  967.    old_line -> line            ; back to the line with the "while"
  968.    toeol                ; and position between parens
  969.    r c
  970.  
  971. ;---------------------------------------------------------------------
  972.  
  973. InsertFor:
  974.    line -> int old_line
  975.    column -> int old_col
  976.  
  977.    "for (;;)\n"
  978.    while (column < old_col + 3)
  979.       " "
  980.    "{\n\n"
  981.    while (column < old_col + 3)
  982.       " "
  983.    "}"
  984.    old_line -> line            ; back to the line with the "for"
  985.    toeol                ; and position between open paren and
  986.    r (c c c)                ; first semicolon
  987.  
  988. ;---------------------------------------------------------------------
  989.  
  990. ViewFile:
  991.     OpenFile            ; ask for file and load it
  992.     2 -> modf            ; then make it read-only
  993.  
  994. ;---------------------------------------------------------------------
  995.  
  996. F50 :   SaveAllFiles    ; Alt-F2    save all modified files
  997. F51 :    RunDebugger     ; Alt-F3    invoke Turbo Debugger
  998. F52 :    RunProgram      ; Alt-F4    run program, swapping out Sprint
  999. F53 :   ToFirstError    ; Alt-F5    goto first message in error file
  1000. F54 :   ToLastError     ; Alt-F6    goto last message in error file
  1001. F55 :   ToPrevError     ; Alt-F7    goto previous error
  1002. F56 :   ToNextError     ; Alt-F8    goto next error
  1003. F25 :   CompileFile     ; Shf-F9    compile  (replaces "Close all windows")
  1004. F57 :   RunMake         ; Alt-F9    make
  1005. F58 :   DeleteErrors    ; Alt-F10    delete error messages
  1006. ~c :    CompileMenu    ; Shf-Alt-C    pop up compiler menu
  1007. ~d :    CdeclDeclare    ; Shf-Alt-D    run CDECL to get a declaration
  1008. ~e :    CdeclExplain    ; Shf-Alt-E    run CDECL to explain a declaration
  1009. ~f :    InsertFor    ; Shf-Alt-F    add for(;;){} at cursor position
  1010. ~p :    InsertPrintf    ; Shf-Alt-P    add printf() at cursor position
  1011. ~w :    InsertWhile    ; Shf-Alt-W    add while(){} at cursor position
  1012. ~V :    ViewFile    ; Alt-V        view file, but don't allow any changes
  1013.  
  1014. ')' :
  1015.    ')' insert
  1016.    '(' -> MatchChar
  1017.    ')' ShowMatchingChar
  1018.  
  1019. ']' :
  1020.    ']' insert
  1021.    '[' -> MatchChar
  1022.    ']' ShowMatchingChar
  1023.  
  1024. '}' :
  1025.    '}' insert
  1026.    '{' -> MatchChar
  1027.    '}' ShowMatchingChar
  1028.  
  1029. ; uncomment the next line to save new user interface as default
  1030. ;:SaveUI
  1031.