unit parser32;
{Parsen von Kommandozeilen u.ä. "komma-separierten" Listen}
interface
const
DELIM_NoTrimLeft=$100;
DELIM_NoTrimRight=$200;
DELIM_NilWhenNone=$400; {liefert NIL, wenn KEIN Element mehr da ist}
DELIM_Whitespace=$800;
ESCAP_SglQuote=LongInt('''') shl 16;
ESCAP_DblQuote=LongInt('"') shl 16;
DELIM_CmdLine=ESCAP_DblQuote or DELIM_WhiteSpace;
function NextItem(var s: PChar; escap_delim:LongInt):PChar;
{escap und delim teilen sich in Low-Byte und High-Byte auf:
escap.lo=einleitendes Flucht-Zeichen (üblich '"', 0 wenn keine Flucht)
escap.hi=ausleitendes Flucht-Zeichen (0 wenn gleich einleitendem)
delim.lo=Trennzeichen, 0 für keins (nur trimmen)
delim.hi=DELIM_xxx-Bits siehe oben
Entsprechend der Kommandozeilen-Zusammensetzungs-Strategie der COMMAND.COM
wird z.B. < "Lange Datei"".""xyz" > zu <Lange Datei.xyz> gewandelt,
d.h. Flucht-Zeichen schalten hin und her und können selbst nicht mit
übergeben werden, falls beide gleich sind
Der String, auf den s zeigt, wird "zerstörend gelesen", die via
Returnwert (der immer gleich s beim Aufruf ist) Zeichenkette
ist auch nach mehrfachem Aufruf nicht kaputt.}
function OneItem(d,s: PChar; escap_delim:LongInt):PChar; stdcall;
{eine Modifikation, die als Rückgabewert den vorgerückten Zeiger hat,
d ist die Zieladresse, d und s dürfen gleich sein; d darf NIL sein
zum Zählen der Felder}
implementation
procedure IsWS; assembler;
{testet AL auf Weißraum, d.h. $09, $0A, $0D, $20}
asm cmp al,09h
jz @@e
cmp al,0Ah
jz @@e
cmp al,0Dh
jz @@e
cmp al,' '
@@e: end;
procedure stosb; assembler;
{macht stosb nur wenn EDI<>NIL}
asm
or edi,edi
jz @@no
stosb
@@no:
end;
function OneItem(d,s: PChar; escap_delim:LongInt):PChar; assembler;
asm pushad
cld
mov esi,[s]
mov edi,[d]
or esi,esi
jz @@e {wenn da NIL drinsteht, immer durchreichen!}
mov cx,word ptr [escap_delim+2]
mov dx,word ptr [escap_delim]
or ch,ch
jnz @@1
or cl,cl
jz @@1
mov ch,cl {gleich machen wenn CH=0 und CL<>0}
@@1:
mov ebx,edi {Abhack-Zeiger für TrimRight}
test dh,1 {NoTrimLeft?}
jnz @@outquoteloop
@@trimleft:
lodsb; or al,al; jz @@raus
call IsWS
jz @@trimleft
jmp @@oq1
@@oq3: mov ebx,edi {Abhackposition vorrücken}
@@outquoteloop:
lodsb; or al,al; jz @@raus
@@oq1: cmp al,cl
je @@inquoteloop
test dh,8 {Whitespace als Trennzeichen?}
jnz @@oq2
cmp al,dl
je @@raus_sep
or edi,edi
jz @@no1
stosb
@@no1: test dh,2 {NoTrimRight?}
jnz @@oq3
call IsWS
jz @@outquoteloop
jmp @@oq3
@@oq2:
call IsWS
jz @@raus_sep
or edi,edi
jz @@oq3
stosb
jmp @@oq3
@@inquoteloop:
lodsb; or al,al; jz @@raus
cmp al,ch
je @@outquoteloop
or edi,edi
jz @@no3
stosb
@@no3: mov ebx,edi {hier jeden Weißraum mitnehmen!}
jmp @@inquoteloop
@@raus: {ohne Separator: NIL in S einspeichern lassen!}
dec esi {wieder AUF DIE NULL zurückstellen}
test dh,4
jz @@raus_sep
xor esi,esi
@@raus_sep:
{Rechts-Trimmung ausführen, gleichzeitig terminieren}
or ebx,ebx
jz @@e
mov byte ptr [ebx],0
{vorgerücktes S zurückliefern}
@@e: mov [esp+1Ch],esi {nach EAX}
popad
end;
function NextItem(var s: PChar; escap_delim:LongInt):PChar; assembler;
begin
NextItem:=s;
s:=OneItem(s,s,escap_delim);
end;
end.
Detected encoding: OEM (CP437) | 1
|
|