{$M 16384,0,0}
{$I+,G+,Q-,R-}
program setini;
uses WinDos,Strings,Parser;
{Setzt in INI-Datei <arg1> in Sektion <arg2> den Schlüssel <arg3> auf <arg4>}
procedure Usage;
begin
WriteLn(
'SETINI (h#s 09/02): Analogon zu Get/WritePrivateProfileString'#13#10+
'Argumente: <dateiname> [<multikey_action>] <[sektion]> [<schlüssel> [<wert>]]'#13#10+
'<dateiname> und <[sektion]> sind Pflicht; Sektion mit [] schreiben!');
WriteLn(
'Präfix "!" vor Dateinamen steht für Windows-Verzeichnis (%windir%)'#13#10+
'Extra-Funktionen: Leere Sektion [] setzt Variable in Nicht-Windows-.INI'#13#10+
'Kein Wert: Schlüssel löschen. Kein Schlüssel: Sektion löschen.');
WriteLn(
'<wert> darf Leerzeichen enthalten, <schlüssel> und <[sektion]> nur mittels ""!'#13#10+
'<multikey_action>=ADD: Hinzufügen, <multikey_action>=DEL: Löschen'#13#10+
'<multikey_action>=GET: Nach Umgebungsvariable <wert> lesen (sonst nur stdout)');
WriteLn(
'Beispiele:'#13#10+
'Windows-Shell ändern: setini !system.ini [boot] Shell c:\vc\vc.com'#13#10+
'ein VxD hinzufügen: setini !system.ini ADD [386Enh] device myvxd.386'#13#10+
'ein anderes VxD löschen: setini !system.ini DEL [386Enh] device othervxd.386');
WriteLn(
'3.1: Dr.Watson nützlich machen: setini !win.ini "[Dr. Watson]" ShowInfo par sou'#13#10+
'DOS-CDROM-Treiber setzen: setini c:\config.sys ADD [common] device mycdrom.sys');
halt;
end;
function IsVar(Env,l:PChar):Boolean;
var
SP1: PChar;
len: Word;
begin
IsVar:=false;
SP1:=StrScan(Env,'=');
len:=StrLen(l);
if (SP1<>nil) and (SP1-Env=len) and (StrLIComp(Env,l,len)=0)
then IsVar:=true;
end;
var
EnvSize: Integer;
function GetParentEnvPtr: PChar; assembler;
asm mov es,[PrefixSeg]
mov es,es:[$16]
mov dx,es:[$2C]
dec dx
mov es,dx
mov ax,es:[3] {Länge Env-Speicher}
shl ax,4 {in Bytes}
mov [EnvSize],ax
inc dx
xor ax,ax
end;
function SetEnv(l,r:PChar): Boolean; {Arg[4] und SP1}
type
PInteger=^Integer;
PtrRec=record
ofs,seg: Word;
end;
var
SPE,SP2,SP3: PChar;
Shift,BytesFree: Integer;
begin
SetEnv:=false;
SPE:=GetParentEnvPtr;
SP2:=nil;
while SPE^<>#0 do begin
if IsVar(SPE,l) then begin
SP2:=SPE;
SP3:=StrEnd(SPE)+1; {Hier ersetzen}
end;
SPE:=StrEnd(SPE)+1;
end;
if SP2=nil then begin
SP2:=SPE; {Zuletzt einfügen}
SP3:=SPE;
end;
Inc(SPE);
if PInteger(SPE)^=1 then SPE:=StrEnd(SPE+2)+1;
Shift:=(StrLen(l)+StrLen(r)+2) {Verschiebung nach hinten}
-(PtrRec(SP3).ofs-PtrRec(SP2).ofs); {Verschiebung nach vorn}
BytesFree:=EnvSize-PtrRec(SPE).ofs-Shift;{Platz am Ende minus Schiebung}
if BytesFree<0 then begin
WriteLn('Umgebungsspeicher voll!');
exit;
end;
Move(SP3^,(SP3+Shift)^,PtrRec(SPE).ofs-PtrRec(SP3).ofs);
StrCopy(SP2,l);
StrCat(SP2,'=');
StrCat(SP2,r);
SetEnv:=true;
end;
var
Arg: array[1..4] of PChar;
I: Integer;
f,f2: Text;
FName1,FName2: array[0..127] of Char;
S,Line: array[0..255] of Char;
InSection,CopyLine,MultiKey: Boolean;
MultiKey_Add, MultiKey_Del: Boolean;
MultiKey_Get, BlankLineBefore: Boolean;
SP1: PChar;
begin
Arg[4]:=Ptr(PrefixSeg,$81);
Arg[4][Mem[PrefixSeg:$80]]:=#0; {nullterminieren}
for I:=1 to 3 do Arg[I]:=NextItem(Arg[4],Word('"'),DELIM_WhiteSpace);
if Arg[2][0]=#0 then Usage;
if Arg[2][0]<>'[' then begin
MultiKey:=true;
MultiKey_Add:=StrIComp(Arg[2],'ADD')=0;
MultiKey_Del:=StrIComp(Arg[2],'DEL')=0;
MultiKey_Get:=StrIComp(Arg[2],'GET')=0;
Arg[2]:=Arg[3]; {vorrücken}
Arg[3]:=NextItem(Arg[4],Word('"'),DELIM_WhiteSpace);
{ for I:=3 to 5 do Arg[I-1]:=Arg[I]GetArgStr(Arg[I-1],I,63);}
if MultiKey_Get then begin
StrUpper(Arg[4]); {Umgebungsvariable}
if Arg[3][0]=#0 then begin
WriteLn('FATAL: Parameter <schlüssel> muss angegeben werden!');
halt;
end;
if StrScan(Arg[4],' ')<>nil then begin
WriteLn('FATAL: Zu viele Parameter!');
halt;
end;
end else begin
if Arg[4][0]=#0 then begin
WriteLn('FATAL: Alle Parameter müssen angegeben werden!');
halt;
end;
end;
end else begin
MultiKey_Add:=Arg[4][0]<>#0;
MultiKey_Del:=not MultiKey_Add;
end;
OneItem(Arg[4],Arg[4],0,0); {links und rechts "trimmen"}
if Arg[1][0]='!' then begin {Windows-Verzeichnis (sofern Windows läuft)}
SP1:=GetEnvVar('windir'); {arbeitet zum Glück auch mit Kleinbuchstaben}
if SP1=nil then SP1:=GetEnvVar('winbootdir'); {Win9x, schon unter DOS}
if SP1=nil then begin
WriteLn('FATAL: %windir%-Verzeichnis angefordert, aber nicht vorhanden!');
halt;
end;
Arg[1][0]:='\';
if Arg[1][1] in ['\','/'] then Inc(Arg[1]);
StrCopy(StrECopy(FName1,SP1),Arg[1]);
Arg[1]:=FName1; {umsetzen auf Puffer mit Pfad}
end;
Assign(f,Arg[1]); {$I-} Reset(f); if IOResult<>0 then; {$I+}
InSection:=StrIComp(Arg[2],'[]')=0;{Sonderfall Sektion=[]: keine Sektion!}
if MultiKey_Get then begin
while (TTextRec(f).mode<>fmClosed) and not eof(f) do begin
ReadLn(f,S);
if (StrLen(S)>=2) and (S[0]='[') then begin
OneItem(S,S,0,0); {trimmen}
InSection:=StrIComp(S,Arg[2])=0;
end else begin
if InSection then begin
SP1:=OneItem(S,S,0,Word('=') or DELIM_NilWhenNone);
if (SP1<>nil) and (StrIComp(S,Arg[3])=0) then begin
OneItem(SP1,SP1,0,0); {trimmen}
break; {KEY gefunden}
end;
end;
end;
SP1:=nil;
end;
if Arg[4][0]<>#0 then begin {mit EnvVar}
if SP1<>nil
then WriteLn(Arg[4],'=',SP1)
else WriteLn('Sektion/Schlüssel nicht gefunden!');
SetEnv(Arg[4],SP1);
end else begin
WriteLn(SP1); {bei NIL macht WriteLn nur Linefeed}
end;
Close(f);
end else begin {Schreibzugriff}
FileSplit(Arg[1],FName2,nil,nil);
StrCat(FName2,'tmp.$$$');
Assign(f2,FName2); ReWrite(f2);
BlankLineBefore:=false;
while (TTextRec(f).mode<>fmClosed) and not eof(f) do begin
ReadLn(f,S); {S ist zum Zerpflücken}
StrCopy(Line,S); {Line ist zum Kopieren}
CopyLine:=true;
if (StrLen(S)>=2) and (S[0]='[') then begin
OneItem(S,S,0,0); {trimmen}
if InSection and MultiKey_Add then begin
WriteLn(f2,Arg[3],'=',Arg[4]);
BlankLineBefore:=true; {Leerzeile}
MultiKey_Add:=false;
end;
InSection:=StrIComp(S,Arg[2])=0;
if InSection and (Arg[3][0]=#0)
then CopyLine:=false; {Sektion komplett löschen}
end else begin
if InSection then begin
if MultiKey then begin
if MultiKey_Add then begin
WriteLn(f2,Arg[3],'=',Arg[4]);
MultiKey_Add:=false; {nur 1x hinzufügen!}
end;
if MultiKey_Del then begin
SP1:=OneItem(S,S,0,Word('=') or DELIM_NilWhenNone);
if (SP1<>nil) and (StrIComp(S,Arg[3])=0) then begin
OneItem(SP1,SP1,0,0);
if (StrIComp(SP1,Arg[4])=0) or (StrPos(SP1,Arg[4])<>nil) then begin
CopyLine:=false;
MultiKey_Del:=false; {nur 1x löschen!}
end;
end;
end;
end else begin
if Arg[3][0]<>#0 then begin {sonst: Sektion komplett löschen}
SP1:=OneItem(S,S,0,Word('=') or DELIM_NilWhenNone);
if (SP1<>nil) and (StrIComp(S,Arg[3])=0) then begin {KEY gefunden}
if MultiKey_Add then begin
StrCopy(SP1,Arg[4]);
MultiKey_Add:=false; {nur 1x ändern!}
end else begin
CopyLine:=false;
MultiKey_Del:=false; {Löschen OK}
end;
end;
end else begin
CopyLine:=false;
MultiKey_Del:=false; {Löschen OK}
end;
end;
end;
end;
if CopyLine then begin
if S[0]=#0 then BlankLineBefore:=true
else begin
if BlankLineBefore then begin
WriteLn(f2);
BlankLineBefore:=false;
end;
WriteLn(f2,Line);
end;
end;
end;
if MultiKey_Add then begin
if not InSection then begin
WriteLn(f2);
WriteLn(f2,Arg[2]);
InSection:=true;
end;
WriteLn(f2,Arg[3],'=',Arg[4]);
MultiKey_Add:=false;
end;
if MultiKey_Del then WriteLn('Sektion/Schlüssel nicht gefunden!');
if TTextRec(f).mode<>fmClosed then begin
close(f);
Erase(f);
end;
close(f2);
Rename(f2,Arg[1]);
end;
end.
Detected encoding: OEM (CP437) | 1
|
|