[Back to MISC SWAG index] [Back to Main SWAG index] [Original]
{
Here is a VERY simple source-code mangler that I just made. It simply:
1) Removes whitespace,
2) Removes comments (but not Compiler-directives!),
3) Makes everything upper-Case.
4) Make lines max. 127 Chars wide (max. For Turbo Pascal),
5) Doesn't mess up literal Strings :-)
I don't imagine that this is anything Near perfect - but it's better than
nothing...
}
Program Mangler;
Const
Alpha : Set of Char = ['a'..'z', 'A'..'Z', '0'..'9'];
Var
F, F2 : Text;
R, S : String;
X : Byte;
InString : Boolean;
Function NumChar(C : Char; S : String; Max : Byte) : Byte;
Var
N, Y : Byte;
begin
N := 0;
For Y := 1 to Max do
if S[Y] = C then Inc(N);
NumChar := N;
end;
Function TrimF(T : String) : String;
Var
T2 : String;
begin
T2 := T;
While (Length(T2) > 0) and (T2[1] = ' ') do
Delete(T2, 1, 1);
TrimF := T2;
end;
Function Trim(T : String) : String;
Var
T2 : String;
begin
T2 := TrimF(T);
While (Length(T2) > 0) and (T2[Length(T2)] = ' ') do
Delete(T2, Length(T2), 1);
Trim := T2;
end;
Procedure StripComments(Var T : String);
Var
Y : Byte;
Rem : Boolean;
begin
Rem := True;
if Pos('(*', T) > 0 then
begin
For Y := Pos('(*', T) to Pos('*)', T) do
if (T[Y] = '$') or (T[Y] = '''') then
Rem := False;
if (Rem) and (not Odd(NumChar('''', T, Pos('(*', T)))) then
Delete(T, Pos('(*', T), Pos('*)', T)+2-Pos('(*', T));
end;
if Pos('{', T) > 0 then
begin
For Y := Pos('{', T) to Pos('}', T) do
if (T[Y] = '$') or (T[Y] = '''') then
Rem := False;
if (Rem) and (not Odd(NumChar('''', T, Pos('(*', T)))) then
Delete(T, Pos('{', T), Pos('}', T)+1-Pos('{', T));
end;
end;
begin
ReadLn(S);
Assign(F, S);
Reset(F);
ReadLn(S);
Assign(F2, S);
ReWrite(F2);
R := '';
S := '';
While not EoF(F) do
begin
ReadLn(F, R);
StripComments(R);
R := Trim(R);
X := 1;
While X <= Length(R) do
begin
InString := (R[X] = '''') xor InString;
if not InString then
begin
if R[X] = #9 then
R[X] := ' ';
if ((R[X] = ' ') and (R[X+1] = ' ')) then
begin
Delete(R, X, 1);
if X > 1 then
Dec(X);
end;
if ((R[X] = ' ') and not(R[X+1] in Alpha)) then
Delete(R, X, 1);
if ((R[X+1] = ' ') and not(R[X] in Alpha)) then
Delete(R, X+1, 1);
R[X] := UpCase(R[X]);
end;
Inc(X);
end;
if (Length(R) > 0) and (R[Length(R)] <> ';') then
R := R+' ';
if Length(R)+Length(S) <= 127 then
S := TrimF(S+R)
else
begin
WriteLn(F2, Trim(S));
S := TrimF(R);
end;
end;
WriteLn(F2, S);
Close(F);
Close(F2);
end.
{
> 1) Remove whitespace.
Just removes indentation now.
> 2) Put lines together (max. length approx. 120 Chars).
This is going to be one of the harder parts.
> 3) Make everything lower-Case (or upper-Case).
No need.. see 4.
4. Convert all Types, Consts, and VarS to an encypted name, like so:
IIl0lll1O0lI1
5. Convert all Procedures, and Functions like #4
6. On Objects, Convert all "data" fields. Leave alone all others except For
the "ConstRUCtoR" and on that, only check to see if any Types are being used.
Constructors are the only ones that can change from the ancestor.
7. on Records, When Typed like this:
aRec.Name:='Rob Green'; check to see if arec is in the list, if not, skip.
if like this:
With arec do
name:='Rob Green'; do the same as above, but check For begin and end.
8. Leave externals alone.
9. Also mangle the Includes.
10. Leave Any Interface part alone, and only work With the Implementation.
This is what my mangler currently does.(all except For #7 and #10, havent got
that Far yet.) Any ways it works pretty good. im happy With the results i
am getting With it. It makes it "VERY" hard to read. The only thing i see
having trouble With down the line, is the "Compressing" of mulitiple lines.
Anyways, heres a small Program, and then what PAM(Pascal automatic mangler)
did to it:
}
Program test;
Type
pstr30 = ^str30;
str30 = String[30];
Var
b : Byte;
s : pstr30;
Function hex(b : Byte) : String;
Const
Digits : Array [0..15] of Char = '0123456789ABCDEF';
Var
s:String;
begin
s:='';
s[0] := #2;
s[1] := Digits [b shr 4];
s[2] := Digits [b and $F];
hex:=s;
end;
begin
new(s);
s^:='Hello world';
Writeln(s^);
Writeln('Enter a Byte to convert to hex:');
readln(b);
s^:=hex(b);
Writeln('Byte :',b,' = $',s^);
dispose(s);
end.
Program test;
Type
IO1II0IO00O = ^II0lOl1011I;
II0lOl1011I = String[30];
Var
III0O1ll10l:Byte;
I11110I11Il0:IO1II0IO00O;
Function Il00O011IO0I(III0O1ll10l:Byte):String;
Const
Illl1OOOO0I : Array [0..15] of Char = '0123456789ABCDEF';
Var
I11110I11Il0:String;
begin
I11110I11Il0:='';
I11110I11Il0[0] := #2;
I11110I11Il0[1] := Illl1OOOO0I [III0O1ll10l shr 4];
I11110I11Il0[2] := Illl1OOOO0I [III0O1ll10l and $F];
Il00O011IO0I:=I11110I11Il0;
end;
begin
new(I11110I11Il0);
I11110I11Il0^:='Hello world';
Writeln(I11110I11Il0^);
Writeln('Enter a Byte to convert to hex:');
readln(III0O1ll10l);
I11110I11Il0^:=Il00O011IO0I(III0O1ll10l);
Writeln('Byte :',III0O1ll10l,' = $',I11110I11Il0^);
dispose(I11110I11Il0);
end.
[Back to MISC SWAG index] [Back to Main SWAG index] [Original]