home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w048 / 2.ddi / MSSRC.ARC / MSINVOKE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-21  |  6.6 KB  |  201 lines

  1. {                           MSINVOKE.PAS
  2.                                MS 4.0
  3.                 Copyright (c) 1985, 87 by Borland International, Inc.         }
  4.  
  5. {$I msdirect.inc}
  6.  
  7. unit MsInvoke;
  8.   {-DOS shell for MicroStar}
  9.  
  10. interface
  11.  
  12. uses
  13.   Crt,                       {Basic video operations - standard unit}
  14.   Dos,                       {Basic DOS operations - standard unit}
  15.   Errors,                    {Runtime error handler}
  16.   MsVars,                    {Global types and declarations}
  17.   MsScrn1,                   {Fast screen writing routines}
  18.   MsString,                  {String primitives}
  19.   MsPtrOp,                   {Pointer primitives}
  20.   EscSeq,                    {Returns text string for extended scan codes}
  21.   MsCmds,                    {Maps keystrokes to commands}
  22.   Int24,                     {DOS critical error handler}
  23.   Message,                   {Message system}
  24.   MsUser,                    {User keyboard input, line edit, error report, help}
  25.   MsMemOp,                   {Text buffer allocation and deallocation}
  26.   MsBack,                    {Background processes}
  27.   MsScrn2,                   {Editor screen updating}
  28.   MsMenu,                    {Pulldown and custom menu system}
  29.   MsDir,                     {Popup directory picker}
  30.   MsEdit,                    {Basic editing commands}
  31.   MsFile,                    {File I/O routines}
  32.   MsSet,                     {Setup and installation}
  33.   Invoke;                    {Compress heap and run DOS shell}
  34.  
  35. procedure EdInvokeDOS;
  36.   {-Start a new DOS shell, then return to editor}
  37.  
  38.   {==========================================================================}
  39.  
  40. implementation
  41.  
  42.   procedure EdInvokeDOS;
  43.     {-Start a new DOS shell, then return to editor}
  44.   label
  45.     ExitPoint;
  46.   type
  47.     Environment = array[0..MaxInt] of Char;
  48.     EnvPtr = ^Environment;
  49.  
  50.   var
  51.     NewEptr : EnvPtr;        {Pointer to new environment with special prompt}
  52.     NewEnvLen : Word;        {Length of new environment}
  53.     NewEnvSeg : Word;        {Segment of new environment}
  54.     OldEnvSeg : Word;        {Segment of current environment}
  55.     CommandName : VarString; {DOS command to execute}
  56.     ExecStatus : Integer;    {Status returned by Exec function}
  57.     OldEgaMode : Boolean;
  58.  
  59.     function BuildNewEnvironment : Word;
  60.       {-Modify the environment for a new prompt, returning the new segment}
  61.     const
  62.       NewPrompt : string[64] = '';
  63.     var
  64.       LnewEptr, EPtr : EnvPtr;
  65.       SearchString, EStr, ThePrompt : string[127];
  66.       Done : Boolean;
  67.       I, EnvLen, Pstart, Pend : Word;
  68.  
  69.     begin                    {BuildNewEnvironment}
  70.  
  71.       {Set up}
  72.       NewPrompt := EdGetMessage(347);
  73.       EdDeleteLeadingBlanks(NewPrompt);
  74.       EPtr := Ptr(MemW[PrefixSeg:$002C], 0);
  75.       I := 0;
  76.       Done := False;
  77.       SearchString := 'PROMPT=';
  78.       EStr := '';
  79.       Pstart := $FFFF;
  80.  
  81.       {Scan the existing environment for length and the prompt string}
  82.       repeat
  83.         if EPtr^[I] = Null then begin
  84.           if EPtr^[Succ(I)] = Null then begin
  85.             Done := True;
  86.             EnvLen := Succ(I);
  87.           end;
  88.           if Copy(EStr, 1, Length(SearchString)) = SearchString then begin
  89.             Pend := I;
  90.             Pstart := I-Length(EStr)+Length(SearchString);
  91.           end;
  92.           EStr := '';
  93.         end else
  94.           EStr := EStr+EPtr^[I];
  95.         Inc(I);
  96.       until Done;
  97.  
  98.       if Pstart = $FFFF then begin
  99.         {PROMPT not found, make up a new one}
  100.         Pstart := Pred(EnvLen);
  101.         Pend := Pstart;
  102.         ThePrompt := Null+SearchString+NewPrompt+'$n$g'+Null;
  103.       end else
  104.         ThePrompt := NewPrompt;
  105.  
  106.       {Size up environment to hold new prompt}
  107.       NewEnvLen := EnvLen+Length(ThePrompt);
  108.       if not(EdMemAvail(NewEnvLen+15, FreeListTemp)) then begin
  109.         {Insufficient space for the new environment}
  110.         BuildNewEnvironment := MemW[PrefixSeg:$002C];
  111.         Exit;
  112.       end;
  113.       GetMem(NewEptr, NewEnvLen+15);
  114.       if Ofs(NewEptr^) <> 0 then
  115.         LnewEptr := Ptr(Succ(Seg(NewEptr^)), 0)
  116.       else
  117.         LnewEptr := NewEptr;
  118.       BuildNewEnvironment := Seg(LnewEptr^);
  119.  
  120.       {Insert the new prompt in the new environment}
  121.       Move(EPtr^[0], LnewEptr^[0], Pstart);
  122.       Move(ThePrompt[1], LnewEptr^[Pstart], Length(ThePrompt));
  123.       Move(EPtr^[Pstart], LnewEptr^[Pstart+Length(ThePrompt)], Succ(EnvLen-Pstart));
  124.  
  125.     end;                     {BuildNewEnvironment}
  126.  
  127.     procedure EdRestoreEditorScreen;
  128.       {-Restore the screen after the shell}
  129.  
  130.     begin                    {EdRestoreEditorScreen}
  131.       {Reinitialize video parameters in case of dual monitor switch}
  132.       EdGetScreenMode;
  133.       if Ega43lineMode <> OldEgaMode then begin
  134.         Ega43lineMode := not(Ega43lineMode);
  135.         EdToggleEga43Line;
  136.       end;
  137.  
  138.       {Redraw screen and menus if on}
  139.       if WindowCount > 0 then
  140.         EdUpdateScreen
  141.       else
  142.         ClrScr;
  143.       if EdPtrNotNil(CurrMenu) then
  144.         EdDrawMenu(RootMenu);
  145.     end;                     {EdRestoreEditorScreen}
  146.  
  147.   begin                      {EdInvokedos}
  148.  
  149.     {Get DOS Command to execute}
  150.     CommandName := LastDosCommand;
  151.     EdAskfor(EdGetMessage(333), 5, EdYcenterWindow(3), 70, CommandName);
  152.     if Abortcmd then
  153.       Exit;
  154.     LastDosCommand := CommandName;
  155.  
  156.     if EdStringEmpty(CommandName) then begin
  157.       {DOS shell, build new environment with custom prompt}
  158.       NewEnvSeg := BuildNewEnvironment;
  159.       OldEnvSeg := MemW[PrefixSeg:$2C];
  160.       MemW[PrefixSeg:$2C] := NewEnvSeg;
  161.     end else
  162.       {Pass on the existing environment}
  163.       NewEnvSeg := MemW[PrefixSeg:$2C];
  164.  
  165.     {Save current color table}
  166.     if InitRetracemode then
  167.       ColorAttr := ScreenAttr
  168.     else
  169.       MonoAttr := ScreenAttr;
  170.  
  171.     {Restore screen mode and cursor to default, and clear screen}
  172.     OldEgaMode := Ega43lineMode;
  173.     EdRestoreScreenMode;
  174.  
  175.     {Free memory and execute command}
  176.     ExecStatus := ExecShrink(CommandName);
  177.  
  178.     {Restore the screen}
  179.     EdRestoreEditorScreen;
  180.  
  181.     case ExecStatus of
  182.       0 : ;                  {Success}
  183.       -1 : EdErrormsg(126);  {Insufficient memory for free list}
  184.       -4 : EdErrormsg(125);  {Insufficient memory to run DOS}
  185.     else
  186.       {Could not execute DOS}
  187.       EdErrormsg(124);
  188.     end;
  189.  
  190. ExitPoint:
  191.     if EdStringEmpty(CommandName) then
  192.       if MemW[PrefixSeg:$002C] <> OldEnvSeg then begin
  193.         {Release the heap space for the new prompt}
  194.         FreeMem(NewEptr, NewEnvLen+15);
  195.         MemW[PrefixSeg:$2C] := OldEnvSeg;
  196.       end;
  197.  
  198.   end;                       {EdInvokedos}
  199.  
  200. end.
  201.