home *** CD-ROM | disk | FTP | other *** search
- { MSINVOKE.PAS
- MS 4.0
- Copyright (c) 1985, 87 by Borland International, Inc. }
-
- {$I msdirect.inc}
-
- unit MsInvoke;
- {-DOS shell for MicroStar}
-
- interface
-
- uses
- Crt, {Basic video operations - standard unit}
- Dos, {Basic DOS operations - standard unit}
- Errors, {Runtime error handler}
- MsVars, {Global types and declarations}
- MsScrn1, {Fast screen writing routines}
- MsString, {String primitives}
- MsPtrOp, {Pointer primitives}
- EscSeq, {Returns text string for extended scan codes}
- MsCmds, {Maps keystrokes to commands}
- Int24, {DOS critical error handler}
- Message, {Message system}
- MsUser, {User keyboard input, line edit, error report, help}
- MsMemOp, {Text buffer allocation and deallocation}
- MsBack, {Background processes}
- MsScrn2, {Editor screen updating}
- MsMenu, {Pulldown and custom menu system}
- MsDir, {Popup directory picker}
- MsEdit, {Basic editing commands}
- MsFile, {File I/O routines}
- MsSet, {Setup and installation}
- Invoke; {Compress heap and run DOS shell}
-
- procedure EdInvokeDOS;
- {-Start a new DOS shell, then return to editor}
-
- {==========================================================================}
-
- implementation
-
- procedure EdInvokeDOS;
- {-Start a new DOS shell, then return to editor}
- label
- ExitPoint;
- type
- Environment = array[0..MaxInt] of Char;
- EnvPtr = ^Environment;
-
- var
- NewEptr : EnvPtr; {Pointer to new environment with special prompt}
- NewEnvLen : Word; {Length of new environment}
- NewEnvSeg : Word; {Segment of new environment}
- OldEnvSeg : Word; {Segment of current environment}
- CommandName : VarString; {DOS command to execute}
- ExecStatus : Integer; {Status returned by Exec function}
- OldEgaMode : Boolean;
-
- function BuildNewEnvironment : Word;
- {-Modify the environment for a new prompt, returning the new segment}
- const
- NewPrompt : string[64] = '';
- var
- LnewEptr, EPtr : EnvPtr;
- SearchString, EStr, ThePrompt : string[127];
- Done : Boolean;
- I, EnvLen, Pstart, Pend : Word;
-
- begin {BuildNewEnvironment}
-
- {Set up}
- NewPrompt := EdGetMessage(347);
- EdDeleteLeadingBlanks(NewPrompt);
- EPtr := Ptr(MemW[PrefixSeg:$002C], 0);
- I := 0;
- Done := False;
- SearchString := 'PROMPT=';
- EStr := '';
- Pstart := $FFFF;
-
- {Scan the existing environment for length and the prompt string}
- repeat
- if EPtr^[I] = Null then begin
- if EPtr^[Succ(I)] = Null then begin
- Done := True;
- EnvLen := Succ(I);
- end;
- if Copy(EStr, 1, Length(SearchString)) = SearchString then begin
- Pend := I;
- Pstart := I-Length(EStr)+Length(SearchString);
- end;
- EStr := '';
- end else
- EStr := EStr+EPtr^[I];
- Inc(I);
- until Done;
-
- if Pstart = $FFFF then begin
- {PROMPT not found, make up a new one}
- Pstart := Pred(EnvLen);
- Pend := Pstart;
- ThePrompt := Null+SearchString+NewPrompt+'$n$g'+Null;
- end else
- ThePrompt := NewPrompt;
-
- {Size up environment to hold new prompt}
- NewEnvLen := EnvLen+Length(ThePrompt);
- if not(EdMemAvail(NewEnvLen+15, FreeListTemp)) then begin
- {Insufficient space for the new environment}
- BuildNewEnvironment := MemW[PrefixSeg:$002C];
- Exit;
- end;
- GetMem(NewEptr, NewEnvLen+15);
- if Ofs(NewEptr^) <> 0 then
- LnewEptr := Ptr(Succ(Seg(NewEptr^)), 0)
- else
- LnewEptr := NewEptr;
- BuildNewEnvironment := Seg(LnewEptr^);
-
- {Insert the new prompt in the new environment}
- Move(EPtr^[0], LnewEptr^[0], Pstart);
- Move(ThePrompt[1], LnewEptr^[Pstart], Length(ThePrompt));
- Move(EPtr^[Pstart], LnewEptr^[Pstart+Length(ThePrompt)], Succ(EnvLen-Pstart));
-
- end; {BuildNewEnvironment}
-
- procedure EdRestoreEditorScreen;
- {-Restore the screen after the shell}
-
- begin {EdRestoreEditorScreen}
- {Reinitialize video parameters in case of dual monitor switch}
- EdGetScreenMode;
- if Ega43lineMode <> OldEgaMode then begin
- Ega43lineMode := not(Ega43lineMode);
- EdToggleEga43Line;
- end;
-
- {Redraw screen and menus if on}
- if WindowCount > 0 then
- EdUpdateScreen
- else
- ClrScr;
- if EdPtrNotNil(CurrMenu) then
- EdDrawMenu(RootMenu);
- end; {EdRestoreEditorScreen}
-
- begin {EdInvokedos}
-
- {Get DOS Command to execute}
- CommandName := LastDosCommand;
- EdAskfor(EdGetMessage(333), 5, EdYcenterWindow(3), 70, CommandName);
- if Abortcmd then
- Exit;
- LastDosCommand := CommandName;
-
- if EdStringEmpty(CommandName) then begin
- {DOS shell, build new environment with custom prompt}
- NewEnvSeg := BuildNewEnvironment;
- OldEnvSeg := MemW[PrefixSeg:$2C];
- MemW[PrefixSeg:$2C] := NewEnvSeg;
- end else
- {Pass on the existing environment}
- NewEnvSeg := MemW[PrefixSeg:$2C];
-
- {Save current color table}
- if InitRetracemode then
- ColorAttr := ScreenAttr
- else
- MonoAttr := ScreenAttr;
-
- {Restore screen mode and cursor to default, and clear screen}
- OldEgaMode := Ega43lineMode;
- EdRestoreScreenMode;
-
- {Free memory and execute command}
- ExecStatus := ExecShrink(CommandName);
-
- {Restore the screen}
- EdRestoreEditorScreen;
-
- case ExecStatus of
- 0 : ; {Success}
- -1 : EdErrormsg(126); {Insufficient memory for free list}
- -4 : EdErrormsg(125); {Insufficient memory to run DOS}
- else
- {Could not execute DOS}
- EdErrormsg(124);
- end;
-
- ExitPoint:
- if EdStringEmpty(CommandName) then
- if MemW[PrefixSeg:$002C] <> OldEnvSeg then begin
- {Release the heap space for the new prompt}
- FreeMem(NewEptr, NewEnvLen+15);
- MemW[PrefixSeg:$2C] := OldEnvSeg;
- end;
-
- end; {EdInvokedos}
-
- end.