| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- IMPLEMENTATION MODULE EnvironUtils;
- (*
- * REPERTOIRE
- * Release 1.6
- * By Charles Bradford and Cole Brecheen
- * (c) Copyright 1985-1991 PMI
- * Portland, Oregon
- * All rights reserved
- * (503) 236-1788
- *
- * $Header: D:/logfiles/mods/environu.mov 1.9 17 Mar 1991 17:52:14 coleb $
- *)
- (*EntryDiag:
- IMPORT Diagnostics;
- :EntryDiag*)
- IMPORT ByteFiddler;
- IMPORT ErrorManager;
- IMPORT LowLevel;
- IMPORT M2Strings;
- IMPORT FAPI;
- IMPORT PosUtils;
- IMPORT StrConv;
- IMPORT StrEdit;
- IMPORT StringIO;
- IMPORT SYSTEM;
- IMPORT VStorage;
- VAR
- Initialized : BOOLEAN;
- PROCEDURE Init();
- BEGIN
- IF Initialized THEN
- RETURN;
- ELSE
- Initialized := TRUE;
- END;
- (*EntryDiag:
- Diagnostics.Init();
- :EntryDiag*)
- ByteFiddler.Init();
- ErrorManager.Init();
- LowLevel.Init();
- M2Strings.Init();
- PosUtils.Init();
- StrConv.Init();
- StrEdit.Init();
- StringIO.Init();
- VStorage.Init();
- END Init;
- PROCEDURE CutFirstParam(VAR TheStr : ARRAY OF CHAR);
- (* use when running under Logitech's run-time debugger *)
- VAR
- spot : CARDINAL;
- BEGIN
- StrEdit.CrunchBlanks(TheStr);
- spot := M2Strings.Pos(' ',TheStr);
- IF spot<=HIGH(TheStr) THEN
- M2Strings.Delete(TheStr, 0, spot+1);
- ELSE
- StrEdit.SetLength(TheStr, 0);
- END;
- END CutFirstParam;
- PROCEDURE GetProgParams(VAR ParamStr : ARRAY OF CHAR);
- VAR
- StrAdr : LowLevel.Address8086;
- knownLength, errcode, cnt, tmpw, CmdLineOffs : CARDINAL;
- tmpc : CHAR;
- LastWasNull: BOOLEAN;
- machineMode: CARDINAL;
- BEGIN
- machineMode := 0;
- (* Have to initialize machineMode because DOSGETMACHINEMODE is
- * actually expecting the address of a single byte; we use a
- * CARDINAL because JPI is obstinate about letting us compare
- * byte values with the constants in FAPI.DEF.
- *)
- errcode := FAPI.DOSGETMACHINEMODE(SYSTEM.ADR(machineMode));
- IF machineMode = FAPI.MODE_REAL THEN
- StrAdr.seg := GetPSP();
- StrAdr.off := 81H;
- knownLength := ORD(LowLevel.PeekByte(StrAdr.seg, StrAdr.off - 1));
- ELSE
- knownLength := 0FFFFH;
- (* In protected mode, the command line follows the
- * environment block. Not so in real mode. It's in the PSP
- * in real mode. And in real mode, you have to pay attention
- * to the length byte that precedes the command line. You
- * can't count on null termination, which is the only thing
- * that signals the end of the command line in protected
- * mode.
- *)
- IF FAPI.DOSGETENV(
- SYSTEM.ADR(StrAdr.seg),
- SYSTEM.ADR(CmdLineOffs )) # 0 THEN
- ErrorManager.WARN( "Failed to get command line." );
- END;
- StrAdr.off := CmdLineOffs;
- tmpc := LowLevel.PeekByte(StrAdr.seg,StrAdr.off );
- WHILE (tmpc # 0C) DO
- (* Now we start on the fully qualified name of the program. *)
- INC(StrAdr.off);
- tmpc := LowLevel.PeekByte(StrAdr.seg, StrAdr.off);
- END;
- INC( StrAdr.off );
- END;
- LowLevel.Fill( SYSTEM.ADR(ParamStr), HIGH(ParamStr) + 1, 0C );
- (* Fill the whole thing with nulls so we don't have to worry
- about terminating the string in the right place. *)
- cnt := 0;
- tmpc := StrAdr.b^;
- (* If there are any parameters at all, this
- will always be a space. *)
- WHILE (tmpc # 0C) AND
- (tmpc # 377C) AND
- (cnt <= HIGH(ParamStr)) AND
- ((cnt + 1) < knownLength) DO
- (* Now we are on the parameters. *)
- INC(StrAdr.off);
- tmpc := StrAdr.b^;
- ParamStr[ cnt ] := tmpc;
- INC( cnt );
- END;
- END GetProgParams;
- PROCEDURE ParsedParam( ParamNum: CARDINAL; VAR Result: ARRAY
- OF CHAR ): BOOLEAN;
- VAR
- ParamCnt, BlankSpot1, BlankSpot2: CARDINAL;
- FullLine: ARRAY [0..255] OF CHAR;
- BEGIN
- GetProgParams( FullLine );
- StrEdit.CrunchBlanks( FullLine );
- StrEdit.Append( FullLine, ' ' );
- IF M2Strings.Length( FullLine ) > 1 THEN
- IF (ParamNum = 0) THEN
- ErrorManager.WARN('Zero passed to ParsedParam');
- END;
- ParamCnt := 0;
- BlankSpot1 := 0;
- BlankSpot2 := 0;
- WHILE (ParamCnt < ParamNum) AND
- (BlankSpot2 <= HIGH(FullLine) ) DO
- BlankSpot2 := PosUtils.Positn( ' ', FullLine, BlankSpot2 );
- INC( ParamCnt );
- IF ParamCnt < ParamNum THEN
- BlankSpot1 := BlankSpot2;
- INC( BlankSpot2 );
- END;
- END;
- IF BlankSpot2 > HIGH(FullLine) THEN
- RETURN(FALSE);
- ELSE
- IF BlankSpot1 # 0 THEN
- INC(BlankSpot1);
- END;
- M2Strings.Copy( FullLine, BlankSpot1,
- BlankSpot2 - BlankSpot1, Result );
- RETURN(TRUE);
- END;
- ELSE
- RETURN(FALSE);
- END;
- END ParsedParam;
- PROCEDURE GetDosVersion(VAR major, minor : CARDINAL);
- VAR
- tmpc : CARDINAL;
- BEGIN
- tmpc := 0;
- FAPI.DOSGETVERSION( SYSTEM.ADR(tmpc ));
- major := ORD( CHAR(ByteFiddler.HighByte( tmpc )) );
- minor := ORD( CHAR(ByteFiddler.LowByte( tmpc )) );
- END GetDosVersion;
- PROCEDURE GetPSP() : CARDINAL;
- VAR
- rgstr : LowLevel.regpack;
- errcode, DosVersion, Subvers, PSPseg : CARDINAL;
- machineMode: CARDINAL;
- BEGIN
- machineMode := 0;
- (* Have to initialize machineMode because DOSGETMACHINEMODE is
- * actually expecting the address of a single byte; we use a
- * CARDINAL because JPI is obstinate about letting us compare
- * byte values with the constants in FAPI.DEF.
- *)
- errcode := FAPI.DOSGETMACHINEMODE(SYSTEM.ADR(machineMode));
- IF machineMode = FAPI.MODE_REAL THEN
- GetDosVersion(DosVersion, Subvers);
- IF DosVersion >= 3 THEN
- rgstr.a.h := 142C; (* 62H *)
- ELSE
- rgstr.a.h := 121C; (* 51H *)
- END;
- LowLevel.msdos( rgstr);
- IF LowLevel.FlaggedError(rgstr.flags) THEN
- ErrorManager.WarnNumber("DOS error getting PSP:", ORD(rgstr.a.l));
- END;
- RETURN (rgstr.b.x);
- ELSE
- ErrorManager.WARN("Attempt to GetPSP in protected mode");
- END;
- RETURN(0);
- END GetPSP;
- PROCEDURE EnvironmentSeg(): CARDINAL;
- VAR
- pspSeg, envSeg, cmdlineOffs, errcode: CARDINAL;
- machineMode: CARDINAL;
- BEGIN
- machineMode := 0;
- (* Have to initialize machineMode because DOSGETMACHINEMODE is
- * actually expecting the address of a single byte; we use a
- * CARDINAL because JPI is obstinate about letting us compare
- * byte values with the constants in FAPI.DEF.
- *)
- errcode := FAPI.DOSGETMACHINEMODE(SYSTEM.ADR(machineMode));
- IF machineMode = FAPI.MODE_REAL THEN
- (* We break out the steps to make them easier to see in CodeView. *)
- pspSeg := GetPSP();
- envSeg := LowLevel.PeekWord( pspSeg, 2CH );
- (*Get segment address of the environment from PSP.*)
- ELSE
- errcode := FAPI.DOSGETENV(SYSTEM.ADR(envSeg), SYSTEM.ADR(cmdlineOffs));
- (*Even though this is FAPI, it just doesn't seem to work
- under DOS. That's why we're doing it differently depending
- on the mode we're in. cmdlineOffs is telling us where the
- command line is in the environment segment, but we don't care
- about that now.*)
- END;
- RETURN envSeg;
- END EnvironmentSeg;
- PROCEDURE ReadEnvironment(name : ARRAY OF CHAR; VAR parameter :
- ARRAY OF CHAR);
- VAR
- bufch : CHAR;
- tmpcopy : ARRAY [0..255] OF CHAR;
- (*expanded from [0..80] on 11 Nov 86*)
- found : BOOLEAN;
- cmdlineOffs, pspSeg, errcode, EnvSeg, EnvNdx, cnt, EqSpot: CARDINAL;
- machineMode: SYSTEM.BYTE;
- BEGIN
- EnvSeg := EnvironmentSeg();
- (* We'd like to call DOSSCANENV here, but it's not FAPI. *)
- EnvNdx := 0;
- found := FALSE;
- StrEdit.SetLength(parameter, 0);
- StrEdit.CAPstr( name );
- REPEAT
- StrEdit.SetLength(tmpcopy, 0);
- bufch := LowLevel.PeekByte(EnvSeg,EnvNdx);
- WHILE bufch # 0C DO
- bufch := CAP(bufch);
- StrEdit.Append(tmpcopy, bufch);
- INC(EnvNdx);
- bufch := LowLevel.PeekByte(EnvSeg,EnvNdx);
- END;
- IF M2Strings.Pos(name,tmpcopy)=0 THEN
- EqSpot := M2Strings.Pos('=',tmpcopy);
- IF (EqSpot<HIGH(tmpcopy)) AND
- (EqSpot <= (M2Strings.Length(name)+1)) THEN
- (* Added second condition 26 Oct 88 to prevent
- ReadEnvironment from returning the value for, say,
- M2OBJLIB when what you wanted was the value for M2OBJ. *)
- M2Strings.Copy(tmpcopy, EqSpot + 1,
- M2Strings.Length(tmpcopy) - 1 - EqSpot, parameter);
- found := TRUE;
- END;
- END;
- INC(EnvNdx);
- IF LowLevel.PeekByte(EnvSeg, EnvNdx) = 0C THEN
- found := TRUE;
- END;
- UNTIL found;
- WHILE M2Strings.Pos(' ',parameter)=0 DO
- M2Strings.Delete(parameter, 0, 1);
- END;
- END ReadEnvironment;
- PROCEDURE GetExeName( VAR ExeName: ARRAY OF CHAR );
- VAR
- StrAdr: LowLevel.Address8086;
- tmpw, count, errcode: CARDINAL;
- tmpc: CHAR;
- machineMode: CARDINAL;
- BEGIN
- machineMode := 0;
- ExeName[0] := 0C;
- StrAdr.seg := EnvironmentSeg();
- StrAdr.off := 0;
- tmpw := LowLevel.PeekWord( StrAdr.seg, StrAdr.off );
- (* Don't know what we're skipping over here. *)
- WHILE (tmpw # 0) DO
- INC(StrAdr.off);
- tmpw := LowLevel.PeekWord( StrAdr.seg, StrAdr.off );
- END;
- (* Now skip the two null bytes that terminate the set of
- environment strings. *)
- StrAdr.off := StrAdr.off + 2;
- (* These things just never seem to be simple. It turns out that
- in real mode, the exe file name doesn't exactly follow the
- two null bytes that terminate the set of environment strings.
- There are an additional couple of bytes -- a one byte value
- and a null byte -- following the null pair. Rather than try
- to figure out why, we just increment past them if we know
- we're in real mode. *)
- errcode := FAPI.DOSGETMACHINEMODE(SYSTEM.ADR(machineMode));
- IF machineMode = FAPI.MODE_REAL THEN
- StrAdr.off := StrAdr.off + 2;
- END;
- count := 0;
- tmpc := LowLevel.PeekByte( StrAdr.seg, StrAdr.off );
- ExeName[count] := tmpc;
- WHILE (tmpc # 0C) DO
- (* We are now getting the path and file name of the .EXE file. *)
- INC(StrAdr.off);
- tmpc := LowLevel.PeekByte( StrAdr.seg, StrAdr.off );
- INC(count);
- ExeName[count] := tmpc;
- END;
- END GetExeName;
- PROCEDURE GetDate(VAR month, day, year : CARDINAL; VAR weekday,
- mmddyy : ARRAY OF CHAR);
- VAR
- TimeData: FAPI.DATETIME;
- ErrorReturn: CARDINAL;
- BEGIN
- ErrorReturn := FAPI.DOSGETDATETIME( SYSTEM.ADR(TimeData));
- CASE ORD(TimeData.weekday) OF
- 0 :
- StrEdit.AssignStr('Sunday', weekday);
- | 1 :
- StrEdit.AssignStr('Monday', weekday);
- | 2 :
- StrEdit.AssignStr('Tuesday', weekday);
- | 3 :
- StrEdit.AssignStr('Wednesday', weekday);
- | 4 :
- StrEdit.AssignStr('Thursday', weekday);
- | 5 :
- StrEdit.AssignStr('Friday', weekday);
- | 6 :
- StrEdit.AssignStr('Saturday', weekday);
- END;
- month := ORD(TimeData.month);
- day := ORD(TimeData.day);
- year := ORD(TimeData.year);
- StrConv.DateToStr(month, day, year, mmddyy);
- IF ErrorReturn # 0 THEN
- ErrorManager.WarnNumber("DOSGETDATETIME", ErrorReturn);
- END;
- END GetDate;
- PROCEDURE SetDate(month, day, year : CARDINAL): BOOLEAN;
- VAR
- TimeData: FAPI.DATETIME;
- BEGIN
- IF FAPI.DOSGETDATETIME( SYSTEM.ADR(TimeData )) = 0 THEN
- END;
- TimeData.month := SYSTEM.BYTE(CHR(month));
- TimeData.day := SYSTEM.BYTE(CHR(day));
- TimeData.year := year;
- RETURN FAPI.DOSSETDATETIME( SYSTEM.ADR(TimeData )) = 0;
- END SetDate;
- PROCEDURE GetTime(VAR hours, minutes, seconds, hundredths : CARDINAL;
- VAR text : ARRAY OF CHAR);
- VAR
- TimeData: FAPI.DATETIME;
- ErrorReturn:CARDINAL;
- BEGIN
- ErrorReturn := FAPI.DOSGETDATETIME( SYSTEM.ADR(TimeData));
- hours := ORD(TimeData.hours);
- minutes := ORD(TimeData.minutes);
- seconds := ORD(TimeData.seconds);
- hundredths := ORD(TimeData.hundredths);
- StrConv.TimeToStr(hours,minutes,seconds,hundredths,text);
- END GetTime;
- PROCEDURE SetTime(hours, minutes, seconds, hundredths : CARDINAL);
- VAR
- TimeData:FAPI.DATETIME;
- BEGIN
- IF FAPI.DOSGETDATETIME( SYSTEM.ADR(TimeData )) = 0 THEN
- END;
- TimeData.hours := SYSTEM.BYTE(CHR(hours));
- TimeData.minutes := SYSTEM.BYTE(CHR(minutes));
- TimeData.seconds := SYSTEM.BYTE(CHR(seconds));
- TimeData.hundredths := SYSTEM.BYTE(CHR(hundredths));
- IF FAPI.DOSSETDATETIME( SYSTEM.ADR(TimeData )) = 0 THEN
- END;
- END SetTime;
- PROCEDURE MemAvail(within: CARDINAL) : CARDINAL;
- VAR
- lasttry, lowtry, try : CARDINAL;
- BEGIN
- lasttry := 65535;
- try := 65535;
- lowtry := 0;
- LOOP
- WHILE (NOT VStorage.DosAvail(try)) AND (try>16) DO
- lasttry := try;
- try := lowtry + (try-lowtry) DIV 2;
- END;
- IF ((lasttry-try) > within) AND (try>16) THEN
- lowtry := try;
- try := try + (lasttry-try) DIV 2;
- ELSE
- EXIT;
- END;
- END;
- IF try<=16 THEN
- RETURN 0;
- ELSE
- RETURN try;
- END;
- END MemAvail;
- BEGIN
- Initialized := FALSE;
- Init();
- END EnvironUtils.
|