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 fr 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 knnen selbst nicht mit
bergeben werden, falls beide gleich sind
Der String, auf den s zeigt, wird "zerstrend gelesen", die via
Returnwert (der immer gleich s beim Aufruf ist) Zeichenkette
ist auch nach mehrfachem Aufruf nicht kaputt.}
function OneItem(s: PChar; escap_delim:LongInt):PChar; stdcall;
{eine Modifikation, die als Rckgabewert den vorgerckten Zeiger hat}
implementation
procedure IsWS; assembler;
{testet AL auf Weiraum, 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;
function OneItem(s: PChar; escap_delim:LongInt):PChar; assembler;
asm pushad
cld
mov esi,[s]
mov edi,esi
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 fr 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 vorrcken}
@@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
stosb
test dh,2 {NoTrimRight?}
jnz @@oq3
call IsWS
jz @@outquoteloop
jmp @@oq3
@@oq2:
call IsWS
jz @@raus_sep
stosb
jmp @@oq3
@@inquoteloop:
lodsb; or al,al; jz @@raus
cmp al,ch
je @@outquoteloop
stosb
mov ebx,edi {hier jeden Weiraum mitnehmen!}
jmp @@inquoteloop
@@raus: {ohne Separator: NIL in S einspeichern lassen!}
dec esi {wieder AUF DIE NULL zurckstellen}
test dh,4
jz @@raus_sep
xor esi,esi
@@raus_sep:
{Rechts-Trimmung ausfhren, gleichzeitig terminieren}
mov byte ptr [ebx],0
{vorgercktes S zurckliefern}
@@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,escap_delim);
end;
end.
Vorgefundene Kodierung: UTF-8 | 0
|