📄 ststrl.pas
字号:
mov ah, al { Save quote start }
@@NextQ:
mov [edi], al { Store quoted character }
inc edi
inc OutLen
mov al, [esi] { Get next character }
inc esi
inc edx { Increment Ipos }
cmp edx, ecx { At end of line? }
jae @@Store { If so, exit quote loop }
cmp al, ah { Matching end quote? }
jnz @@NextQ { Nope, stay in quote loop }
cmp al, 27h { Single quote? }
jz @@Store { Exit quote loop }
cmp byte ptr [esi-2],'\' { Previous character an escape? }
jz @@NextQ { Stay in if so }
@@Store:
mov [edi], al { Store last character }
inc edi
inc OutLen
inc edx { Increment input position }
jmp @@Next { Repeat while characters left }
@@Done:
mov byte ptr [edi], 0h
pop esi
pop edi
pop ebx
end;
SetLength(Result, OutLen);
end;
function DetabL(const S : AnsiString; TabSize : Byte) : AnsiString;
{-Expand tabs in a string to blanks.}
var
NumTabs : Integer;
begin
Result := '';
if S = '' then Exit;
if TabSize = 0 then Exit;
Result := S;
NumTabs := CharCountL(S, #9);
if NumTabs = 0 then Exit;
SetLength(Result, Length(Result)+NumTabs*(Pred(TabSize)));
asm
push ebx { Save registers since we'll be changing them. }
push edi
push esi
mov edi, Result { EDI => output string. }
mov esi, S { ESI => input string. }
xor ebx, ebx
mov bl, TabSize
mov edi, [edi]
xor ecx, ecx { Default input length = 0. }
xor edx, edx { Zero EDX for output length }
xor eax, eax { Zero EAX }
mov ecx, [esi-StrOffset].LStrRec.Length { Get input length. }
or ebx, ebx { TabSize = 0? }
jnz @@DefLength
mov ecx, edx { Return zero length string if TabSize = 0. }
@@DefLength:
mov [edi-StrOffset].LStrRec.Length, ecx { Store default output length. }
or ecx, ecx
jz @@Done { Done if empty input string. }
@@Next:
mov al, [esi] { Next input character. }
inc esi
cmp al, 09h { Is it a tab? }
jz @@Tab { Yes, compute next tab stop. }
mov [edi], al { No, store to output. }
inc edi
inc edx { Increment output length. }
dec ecx { Decrement input length. }
jnz @@Next
jmp @@StoreLen { Loop termination. }
@@Tab:
push ecx { Save input length. }
push edx { Save output length. }
mov eax, edx { Get current output length in EDX:EAX. }
xor edx, edx
div ebx { Output length MOD TabSize in DX. }
mov ecx, ebx { Calc number of spaces to insert... }
sub ecx, edx { = TabSize - Mod value. }
pop edx
add edx, ecx { Add count of spaces into current output length. }
mov eax,$2020 { Blank in AH, Blank in AL. }
shr ecx, 1 { Store blanks. }
rep stosw
adc ecx, ecx
rep stosb
pop ecx { Restore input length. }
dec ecx
jnz @@Next
{jmp @@Next} { Back for next input. }
@@StoreLen:
xor ebx, ebx
mov [edi], bl { Store terminating null }
mov eax, edx
sub edi, eax
mov [edi-StrOffset].LStrRec.Length, edx { Store final length. }
@@Done:
pop esi
pop edi
pop ebx
end;
end;
function ScrambleL(const S, Key : AnsiString) : AnsiString;
{-Encrypt / Decrypt string with enhanced XOR encryption.}
var
I, J, LKey, LStr : Cardinal;
begin
Result := S;
if Key = '' then Exit;
if S = '' then Exit;
LKey := Length(Key);
LStr := Length(S);
I := 1;
J := LKey;
while I <= LStr do begin
if J = 0 then
J := LKey;
if (S[I] <> Key[J]) then
Result[I] := Char(Byte(S[I]) xor Byte(Key[J]));
Inc(I);
Dec(J);
end;
end;
function SubstituteL(const S, FromStr, ToStr : AnsiString) : AnsiString;
{-Map the characters found in FromStr to the corresponding ones in ToStr.}
var
I : Cardinal;
P : Cardinal;
begin
Result := S;
if Length(FromStr) = Length(ToStr) then
for I := 1 to Length(Result) do begin
{P := System.Pos(S[I], FromStr);}
{if P <> 0 then}
if StrChPosL(FromStr, S[I], P) then
Result[I] := ToStr[P];
end;
end;
function FilterL(const S, Filters : AnsiString) : AnsiString;
{-Remove characters from a string. The characters to remove are specified in
ChSet.}
var
I : Cardinal;
Len : Cardinal;
begin
Len := 0;
SetLength(Result, Length(S));
for I := 1 to Length(S) do
if not CharExistsL(Filters, S[I]) then begin
Inc(Len);
Result[Len] := S[I];
end;
SetLength(Result, Len);
end;
{--------------- Word / Char manipulation -------------------------}
function CharExistsL(const S : AnsiString; C : AnsiChar) : Boolean; register;
{-Count the number of a given character in a string. }
asm
push ebx
xor ecx, ecx
or eax, eax
jz @@Done
mov ebx, [eax-StrOffset].LStrRec.Length
or ebx, ebx
jz @@Done
jmp @@5
@@Loop:
cmp dl, [eax+3]
jne @@1
inc ecx
jmp @@Done
@@1:
cmp dl, [eax+2]
jne @@2
inc ecx
jmp @@Done
@@2:
cmp dl, [eax+1]
jne @@3
inc ecx
jmp @@Done
@@3:
cmp dl, [eax+0]
jne @@4
inc ecx
jmp @@Done
@@4:
add eax, 4
sub ebx, 4
@@5:
cmp ebx, 4
jge @@Loop
cmp ebx, 3
je @@1
cmp ebx, 2
je @@2
cmp ebx, 1
je @@3
@@Done:
mov eax, ecx
pop ebx
end;
function CharCountL(const S : AnsiString; C : AnsiChar) : Cardinal; register;
{-Count the number of a given character in a string. }
asm
push ebx
xor ecx, ecx
or eax, eax
jz @@Done
mov ebx, [eax-StrOffset].LStrRec.Length
or ebx, ebx
jz @@Done
jmp @@5
@@Loop:
cmp dl, [eax+3]
jne @@1
inc ecx
@@1:
cmp dl, [eax+2]
jne @@2
inc ecx
@@2:
cmp dl, [eax+1]
jne @@3
inc ecx
@@3:
cmp dl, [eax+0]
jne @@4
inc ecx
@@4:
add eax, 4
sub ebx, 4
@@5:
cmp ebx, 4
jge @@Loop
cmp ebx, 3
je @@1
cmp ebx, 2
je @@2
cmp ebx, 1
je @@3
@@Done:
mov eax, ecx
pop ebx
end;
function WordCountL(const S, WordDelims : AnsiString) : Cardinal;
{-Given an array of word delimiters, return the number of words in a string.}
var
I : Cardinal;
SLen : Cardinal;
begin
Result := 0;
I := 1;
SLen := Length(S);
while I <= SLen do begin
{skip over delimiters}
while (I <= SLen) and CharExistsL(WordDelims, S[I]) do
Inc(I);
{if we're not beyond end of S, we're at the start of a word}
if I <= SLen then
Inc(Result);
{find the end of the current word}
while (I <= SLen) and not CharExistsL(WordDelims, S[I]) do
Inc(I);
end;
end;
function WordPositionL(N : Cardinal; const S, WordDelims : AnsiString;
var Pos : Cardinal) : Boolean;
{-Given an array of word delimiters, set Pos to the start position of the
N'th word in a string. Result indicates success/failure.}
var
Count : Longint;
I : Longint;
begin
Count := 0;
I := 1;
Result := False;
while (I <= Length(S)) and (Count <> LongInt(N)) do begin
{skip over delimiters}
while (I <= Length(S)) and CharExistsL(WordDelims, S[I]) do
Inc(I);
{if we're not beyond end of S, we're at the start of a word}
if I <= Length(S) then
Inc(Count);
{if not finished, find the end of the current word}
if Count <> LongInt(N) then
while (I <= Length(S)) and not CharExistsL(WordDelims, S[I]) do
Inc(I)
else begin
Pos := I;
Result := True;
end;
end;
end;
function ExtractWordL(N : Cardinal; const S, WordDelims : AnsiString) : AnsiString;
{-Given an array of word delimiters, return the N'th word in a string.}
var
C : Cardinal;
I, J : Longint;
begin
Result := '';
if WordPositionL(N, S, WordDelims, C) then begin
I := C;
{find the end of the current word}
J := I;
while (I <= Length(S)) and not
CharExistsL(WordDelims, S[I]) do
Inc(I);
SetLength(Result, I-J);
Move(S[J], Result[1], I-J);
end;
end;
function AsciiCountL(const S, WordDelims : AnsiString; Quote : AnsiChar) : Cardinal;
{-Return the number of words in a string.}
var
I : Longint;
InQuote : Boolean;
begin
Result := 0;
I := 1;
InQuote := False;
while I <= Length(S) do begin
{skip over delimiters}
while (I <= Length(S)) and (S[I] <> Quote)
and CharExistsL(WordDelims, S[I]) do
Inc(I);
{if we're not beyond end of S, we're at the start of a word}
if I <= Length(S) then
Inc(Result);
{find the end of the current word}
while (I <= Length(S)) and
(InQuote or not CharExistsL(WordDelims, S[I])) do begin
if S[I] = Quote then
InQuote := not InQuote;
Inc(I);
end;
end;
end;
function AsciiPositionL(N : Cardinal; const S, WordDelims : AnsiString;
Quote : AnsiChar; var Pos : Cardinal) : Boolean;
{-Return the position of the N'th word in a string.}
var
Count, I : Longint;
InQuote : Boolean;
begin
Count := 0;
InQuote := False;
Result := False;
I := 1;
while (I <= Length(S)) and (Count <> LongInt(N)) do begin
{skip over delimiters}
while (I <= Length(S)) and (S[I] <> Quote) and
CharExistsL(WordDelims, S[I]) do
Inc(I);
{if we're not beyond end of S, we're at the start of a word}
if I <= Length(S) then
Inc(Count);
{if not finished, find the end of the current word}
if Count <> LongInt(N) then
while (I <= Length(S)) and (InQuote or not
CharExistsL(WordDelims, S[I])) do begin
if S[I] = Quote then
InQuote := not InQuote;
Inc(I);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -