mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:09:19 +02:00
* GetEnv correction, better PM support, ...
This commit is contained in:
parent
aea2fdff0e
commit
ab27397399
@ -943,58 +943,53 @@ begin
|
|||||||
{$ASMMODE INTEL}
|
{$ASMMODE INTEL}
|
||||||
asm
|
asm
|
||||||
cld
|
cld
|
||||||
mov ecx, EnvC
|
mov edi, Environment
|
||||||
mov edi, EnvP
|
|
||||||
mov edi, [edi]
|
|
||||||
lea esi, _EnvVar
|
lea esi, _EnvVar
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
lodsb
|
lodsb
|
||||||
@NewVar:
|
@NewVar:
|
||||||
push ecx
|
cmp byte ptr [edi], 0
|
||||||
push eax
|
jz @Stop
|
||||||
push esi
|
push eax { eax contains length of searched variable name }
|
||||||
mov ecx, -1
|
push esi { esi points to the beginning of the variable name }
|
||||||
mov edx, edi
|
mov ecx, -1 { our character ('=' - see below) _must_ be found }
|
||||||
mov al, '='
|
mov edx, edi { pointer to beginning of variable name saved in edx }
|
||||||
|
mov al, '=' { searching until '=' (end of variable name) }
|
||||||
repne
|
repne
|
||||||
scasb
|
scasb { scan until '=' not found }
|
||||||
neg ecx
|
neg ecx { what was the name length? }
|
||||||
dec ecx
|
dec ecx { corrected }
|
||||||
dec ecx
|
dec ecx { exclude the '=' character }
|
||||||
pop esi
|
pop esi { restore pointer to beginning of variable name }
|
||||||
pop eax
|
pop eax { restore length of searched variable name }
|
||||||
push eax
|
push eax { and save both of them again for later use }
|
||||||
push esi
|
push esi
|
||||||
cmp ecx, eax
|
cmp ecx, eax { compare length of searched variable name with name }
|
||||||
jnz @NotEqual
|
jnz @NotEqual { ... of currently found variable, jump if different }
|
||||||
xchg edx, edi
|
xchg edx, edi { pointer to current variable name restored in edi }
|
||||||
repe
|
repe
|
||||||
cmpsb
|
cmpsb { compare till the end of variable name }
|
||||||
xchg edx, edi
|
xchg edx, edi { pointer to beginning of variable contents in edi }
|
||||||
jz @Equal
|
jz @Equal { finish if they're equal }
|
||||||
@NotEqual:
|
@NotEqual:
|
||||||
xor eax, eax
|
xor eax, eax { look for 00h }
|
||||||
mov ecx, -1
|
mov ecx, -1 { it _must_ be found }
|
||||||
repne
|
repne
|
||||||
scasb
|
scasb { scan until found }
|
||||||
pop esi
|
pop esi { restore pointer to beginning of variable name }
|
||||||
pop eax
|
pop eax { restore length of searched variable name }
|
||||||
pop ecx
|
jmp @NewVar { ... or continue with new variable otherwise }
|
||||||
dec ecx
|
|
||||||
jecxz @Stop
|
|
||||||
jmp @NewVar
|
|
||||||
@Stop:
|
@Stop:
|
||||||
mov P, ecx
|
xor eax, eax
|
||||||
|
mov P, eax { Not found - return nil }
|
||||||
jmp @End
|
jmp @End
|
||||||
@Equal:
|
@Equal:
|
||||||
pop esi
|
pop esi { restore the stack position }
|
||||||
pop eax
|
pop eax
|
||||||
pop ecx
|
mov P, edi { place pointer to variable contents in P }
|
||||||
mov P, edi
|
|
||||||
@End:
|
@End:
|
||||||
end;
|
end;
|
||||||
GetEnv := StrPas (P);
|
GetEnv := StrPas (P);
|
||||||
end;
|
|
||||||
{$ASMMODE ATT}
|
{$ASMMODE ATT}
|
||||||
|
|
||||||
procedure fsplit(path:pathstr;var dir:dirstr;var name:namestr;
|
procedure fsplit(path:pathstr;var dir:dirstr;var name:namestr;
|
||||||
@ -1218,7 +1213,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.20 2002-11-18 19:51:00 hajny
|
Revision 1.21 2002-12-07 19:17:13 hajny
|
||||||
|
* GetEnv correction, better PM support, ...
|
||||||
|
|
||||||
|
Revision 1.20 2002/11/18 19:51:00 hajny
|
||||||
* another bunch of type corrections
|
* another bunch of type corrections
|
||||||
|
|
||||||
Revision 1.19 2002/09/07 16:01:24 peter
|
Revision 1.19 2002/09/07 16:01:24 peter
|
||||||
|
@ -109,6 +109,18 @@ var
|
|||||||
argv : ppchar;external name '_argv';
|
argv : ppchar;external name '_argv';
|
||||||
envp : ppchar;external name '_environ';
|
envp : ppchar;external name '_environ';
|
||||||
|
|
||||||
|
(* Pointer to the block of environment variables - used e.g. in unit Dos. *)
|
||||||
|
Environment: PChar;
|
||||||
|
|
||||||
|
var
|
||||||
|
(* Type / run mode of the current process: *)
|
||||||
|
(* 0 .. full screen OS/2 session *)
|
||||||
|
(* 1 .. DOS session *)
|
||||||
|
(* 2 .. VIO windowable OS/2 session *)
|
||||||
|
(* 3 .. Presentation Manager OS/2 session *)
|
||||||
|
(* 4 .. detached (background) OS/2 process *)
|
||||||
|
ApplicationType: cardinal;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{$I system.inc}
|
{$I system.inc}
|
||||||
@ -117,6 +129,8 @@ var
|
|||||||
heap_base: pointer; external name '__heap_base';
|
heap_base: pointer; external name '__heap_base';
|
||||||
heap_brk: pointer; external name '__heap_brk';
|
heap_brk: pointer; external name '__heap_brk';
|
||||||
heap_end: pointer; external name '__heap_end';
|
heap_end: pointer; external name '__heap_end';
|
||||||
|
|
||||||
|
(* Maximum heap size - only used if heap is allocated as continuous block. *)
|
||||||
{$IFDEF CONTHEAP}
|
{$IFDEF CONTHEAP}
|
||||||
BrkLimit: cardinal;
|
BrkLimit: cardinal;
|
||||||
{$ENDIF CONTHEAP}
|
{$ENDIF CONTHEAP}
|
||||||
@ -125,6 +139,14 @@ procedure DosGetInfoBlocks (PATIB: PPThreadInfoBlock;
|
|||||||
PAPIB: PPProcessInfoBlock); cdecl;
|
PAPIB: PPProcessInfoBlock); cdecl;
|
||||||
external 'DOSCALLS' index 312;
|
external 'DOSCALLS' index 312;
|
||||||
|
|
||||||
|
function DosLoadModule (ObjName: PChar; ObjLen: cardinal; DLLName: PChar;
|
||||||
|
var Handle: cardinal): longint; cdecl;
|
||||||
|
external 'DOSCALLS' index 318;
|
||||||
|
|
||||||
|
function DosQueryProcAddr (Handle, Ordinal: cardinal; ProcName: PChar;
|
||||||
|
var Address: pointer): longint; cdecl;
|
||||||
|
external 'DOSCALLS' index 321;
|
||||||
|
|
||||||
function DosSetRelMaxFH (var ReqCount, CurMaxFH: longint): longint; cdecl;
|
function DosSetRelMaxFH (var ReqCount, CurMaxFH: longint): longint; cdecl;
|
||||||
external 'DOSCALLS' index 382;
|
external 'DOSCALLS' index 382;
|
||||||
|
|
||||||
@ -134,9 +156,9 @@ external 'DOSCALLS' index 255;
|
|||||||
function DosSetDefaultDisk (DiskNum:longint): longint; cdecl;
|
function DosSetDefaultDisk (DiskNum:longint): longint; cdecl;
|
||||||
external 'DOSCALLS' index 220;
|
external 'DOSCALLS' index 220;
|
||||||
|
|
||||||
{ This is not real prototype, but its close enough }
|
{ This is not real prototype, but is close enough }
|
||||||
{ for us. (The 2nd parameter is acutally a pointer) }
|
{ for us (the 2nd parameter is actually a pointer }
|
||||||
{ to a structure. }
|
{ to a structure). }
|
||||||
function DosCreateDir( Name : pchar; p : pointer): longint; cdecl;
|
function DosCreateDir( Name : pchar; p : pointer): longint; cdecl;
|
||||||
external 'DOSCALLS' index 270;
|
external 'DOSCALLS' index 270;
|
||||||
|
|
||||||
@ -883,12 +905,136 @@ end;
|
|||||||
|
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|
||||||
|
{****************************************************************************
|
||||||
|
Error Message writing using messageboxes
|
||||||
|
****************************************************************************}
|
||||||
|
|
||||||
|
type
|
||||||
|
TWinMessageBox = function (Parent, Owner: cardinal;
|
||||||
|
BoxText, BoxTitle: PChar; Identity, Style: cardinal): cardinal; cdecl;
|
||||||
|
TWinInitialize = function (Options: cardinal): cardinal; cdecl;
|
||||||
|
TWinCreateMsgQueue = function (Handle: cardinal; cmsg: longint): cardinal;
|
||||||
|
cdecl;
|
||||||
|
|
||||||
|
const
|
||||||
|
ErrorBufferLength = 1024;
|
||||||
|
mb_OK = $0000;
|
||||||
|
mb_Error = $0040;
|
||||||
|
mb_Moveable = $4000;
|
||||||
|
MBStyle = mb_OK or mb_Error or mb_Moveable;
|
||||||
|
WinInitialize: TWinInitialize = nil;
|
||||||
|
WinCreateMsgQueue: TWinCreateMsgQueue = nil;
|
||||||
|
WinMessageBox: TWinMessageBox = nil;
|
||||||
|
|
||||||
|
var
|
||||||
|
ErrorBuf: array [0..ErrorBufferLength] of char;
|
||||||
|
ErrorLen: longint;
|
||||||
|
PMWinHandle: cardinal;
|
||||||
|
|
||||||
|
function ErrorWrite (var F: TextRec): integer;
|
||||||
|
{
|
||||||
|
An error message should always end with #13#10#13#10
|
||||||
|
}
|
||||||
|
var
|
||||||
|
P: PChar;
|
||||||
|
I: longint;
|
||||||
|
begin
|
||||||
|
if F.BufPos > 0 then
|
||||||
|
begin
|
||||||
|
if F.BufPos + ErrorLen > ErrorBufferLength then
|
||||||
|
I := ErrorBufferLength - ErrorLen
|
||||||
|
else
|
||||||
|
I := F.BufPos;
|
||||||
|
Move (F.BufPtr^, ErrorBuf [ErrorLen], I);
|
||||||
|
Inc (ErrorLen, I);
|
||||||
|
ErrorBuf [ErrorLen] := #0;
|
||||||
|
end;
|
||||||
|
if ErrorLen > 3 then
|
||||||
|
begin
|
||||||
|
P := @ErrorBuf [ErrorLen];
|
||||||
|
for I := 1 to 4 do
|
||||||
|
begin
|
||||||
|
Dec (P);
|
||||||
|
if not (P^ in [#10, #13]) then
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if ErrorLen = ErrorBufferLength then
|
||||||
|
I := 4;
|
||||||
|
if (I = 4) then
|
||||||
|
begin
|
||||||
|
WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
|
||||||
|
ErrorLen := 0;
|
||||||
|
end;
|
||||||
|
F.BufPos := 0;
|
||||||
|
ErrorWrite := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ErrorClose (var F: TextRec): integer;
|
||||||
|
begin
|
||||||
|
if ErrorLen > 0 then
|
||||||
|
begin
|
||||||
|
WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
|
||||||
|
ErrorLen := 0;
|
||||||
|
end;
|
||||||
|
ErrorLen := 0;
|
||||||
|
ErrorClose := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ErrorOpen (var F: TextRec): integer;
|
||||||
|
begin
|
||||||
|
TextRec(F).InOutFunc := @ErrorWrite;
|
||||||
|
TextRec(F).FlushFunc := @ErrorWrite;
|
||||||
|
TextRec(F).CloseFunc := @ErrorClose;
|
||||||
|
ErrorOpen := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure AssignError (var T: Text);
|
||||||
|
begin
|
||||||
|
Assign (T, '');
|
||||||
|
TextRec (T).OpenFunc := @ErrorOpen;
|
||||||
|
Rewrite (T);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure SysInitStdIO;
|
procedure SysInitStdIO;
|
||||||
begin
|
begin
|
||||||
OpenStdIO(Input,fmInput,StdInputHandle);
|
{ Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
|
||||||
OpenStdIO(Output,fmOutput,StdOutputHandle);
|
displayed in a messagebox }
|
||||||
OpenStdIO(StdOut,fmOutput,StdOutputHandle);
|
(*
|
||||||
OpenStdIO(StdErr,fmOutput,StdErrorHandle);
|
StdInputHandle := longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
|
||||||
|
StdOutputHandle := longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
|
||||||
|
StdErrorHandle := longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
|
||||||
|
*)
|
||||||
|
if not IsConsole then
|
||||||
|
begin
|
||||||
|
if (DosLoadModule (nil, 0, 'PMWIN', PMWinHandle) = 0) and
|
||||||
|
(DosQueryProcAddr (PMWinHandle, 789, nil, pointer (WinMessageBox)) = 0)
|
||||||
|
and
|
||||||
|
(DosQueryProcAddr (PMWinHandle, 763, nil, pointer (WinInitialize)) = 0)
|
||||||
|
and
|
||||||
|
(DosQueryProcAddr (PMWinHandle, 716, nil, pointer (WinCreateMsgQueue))
|
||||||
|
= 0)
|
||||||
|
then
|
||||||
|
begin
|
||||||
|
WinInitialize (0);
|
||||||
|
WinCreateMsgQueue (0, 0);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
HandleError (2);
|
||||||
|
AssignError (StdErr);
|
||||||
|
AssignError (StdOut);
|
||||||
|
Assign (Output, '');
|
||||||
|
Assign (Input, '');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
OpenStdIO (Input, fmInput, StdInputHandle);
|
||||||
|
OpenStdIO (Output, fmOutput, StdOutputHandle);
|
||||||
|
OpenStdIO (StdOut, fmOutput, StdOutputHandle);
|
||||||
|
OpenStdIO (StdErr, fmOutput, StdErrorHandle);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -900,10 +1046,10 @@ begin
|
|||||||
else GetFileHandleCount := L2;
|
else GetFileHandleCount := L2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var tib:Pthreadinfoblock;
|
var TIB: PThreadInfoBlock;
|
||||||
|
PIB: PProcessInfoBlock;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
IsConsole := TRUE;
|
|
||||||
IsLibrary := FALSE;
|
IsLibrary := FALSE;
|
||||||
{Determine the operating system we are running on.}
|
{Determine the operating system we are running on.}
|
||||||
{$ASMMODE INTEL}
|
{$ASMMODE INTEL}
|
||||||
@ -971,16 +1117,31 @@ begin
|
|||||||
{At 0.9.2, case for enumeration does not work.}
|
{At 0.9.2, case for enumeration does not work.}
|
||||||
case os_mode of
|
case os_mode of
|
||||||
osDOS:
|
osDOS:
|
||||||
stackbottom:=cardinal(heap_brk); {In DOS mode, heap_brk is also the
|
begin
|
||||||
stack bottom.}
|
stackbottom:=cardinal(heap_brk); {In DOS mode, heap_brk is
|
||||||
|
also the stack bottom.}
|
||||||
|
ApplicationType := 1; (* Running under DOS. *)
|
||||||
|
IsConsole := true;
|
||||||
|
(* Currently broken!!! *)
|
||||||
|
Environment := nil;
|
||||||
|
end;
|
||||||
osOS2:
|
osOS2:
|
||||||
begin
|
begin
|
||||||
dosgetinfoblocks(@tib,nil);
|
DosGetInfoBlocks (@TIB, @PIB);
|
||||||
stackbottom:=cardinal(tib^.stack);
|
StackBottom := cardinal (TIB^.Stack);
|
||||||
|
Environment := pointer (PIB^.Env);
|
||||||
|
ApplicationType := PIB^.ProcType;
|
||||||
|
IsConsole := ApplicationType <> 3;
|
||||||
end;
|
end;
|
||||||
osDPMI:
|
osDPMI:
|
||||||
stackbottom:=0; {Not sure how to get it, but seems to be
|
begin
|
||||||
always zero.}
|
stackbottom:=0; {Not sure how to get it, but seems to be
|
||||||
|
always zero.}
|
||||||
|
ApplicationType := 1; (* Running under DOS. *)
|
||||||
|
IsConsole := true;
|
||||||
|
(* Currently broken!!! *)
|
||||||
|
Environment := nil;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
exitproc:=nil;
|
exitproc:=nil;
|
||||||
|
|
||||||
@ -1009,8 +1170,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.27 2002-11-17 22:31:02 hajny
|
Revision 1.28 2002-12-07 19:17:14 hajny
|
||||||
* type corrections (longing x cardinal)
|
* GetEnv correction, better PM support, ...
|
||||||
|
|
||||||
|
Revision 1.27 2002/11/17 22:31:02 hajny
|
||||||
|
* type corrections (longint x cardinal)
|
||||||
|
|
||||||
Revision 1.26 2002/10/27 14:29:00 hajny
|
Revision 1.26 2002/10/27 14:29:00 hajny
|
||||||
* heap management (hopefully) fixed
|
* heap management (hopefully) fixed
|
||||||
|
Loading…
Reference in New Issue
Block a user