source: trunk/UFormMain.pas

Last change on this file was 3, checked in by chronos, 2 years ago
  • Modified: More conversions.
File size: 18.5 KB
Line 
1unit UFormMain;
2
3{$mode delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, FileUtil,
9 LazFileUtils;
10
11type
12
13 { TFormMain }
14
15 TFormMain = class(TForm)
16 ButtonProcess: TButton;
17 ButtonBrowse: TButton;
18 EditDir: TEdit;
19 MemoLog: TMemo;
20 procedure ButtonBrowseClick(Sender: TObject);
21 procedure ButtonProcessClick(Sender: TObject);
22 private
23 function StartsWith(Text, What: string): Boolean;
24 function EndsWith(Text, What: string): Boolean;
25 function IsSpecialSymbol(C: Char): Boolean;
26 function IsAlpha(C: Char): Boolean;
27 function IsNumeric(C: Char): Boolean;
28 function IsAlphaNumeric(C: Char): Boolean;
29 function IsAlphaNumericUnderscore(C: Char): Boolean;
30 function ReadIdent(Text: string): string;
31 function ReadIdentBack(Text: string): string;
32 function ReplaceSpecialSymbolNumericAfter(Text: string; OldPattern,
33 NewPattern, NewPattern2: string): string;
34 function ReplaceSpecialSymbolNumericBefore(Text: string; OldPattern,
35 NewPattern, NewPattern2: string): string;
36 function SpaceAround(Text, What: string; Left: Boolean = True; Right: Boolean = True): string;
37 function Replace(Text: string; OldPattern, NewPattern: string): string;
38 function ReplaceIdent(Text: string; OldPattern, NewPattern: string): string;
39 function ReplaceFunction(Text: string; ReturnType: string): string;
40 function ReplaceVariable(Text: string; VarType: string): string;
41 function ReplaceOperator(Text: string; OldOp, NewOp1, NewOp2: string): string;
42 function ReplaceAndClose(Text: string; OldPattern, NewPattern, Close: string;
43 Strip: string = ''): string;
44 function ReplaceSpecialSymbol(Text: string; OldPattern, NewPattern: string): string;
45 function FormatCodeCpp(Text: string): string;
46 function ReadFileContent(FileName: string): string;
47 procedure WriteFileContent(FileName: string; Content: string);
48 end;
49
50var
51 FormMain: TFormMain;
52
53implementation
54
55{$R *.lfm}
56
57type
58 TFilterMethod = function (FileName: string): Boolean of object;
59 TFileNameMethod = procedure (FileName: string) of object;
60
61{ TFormMain }
62
63procedure TFormMain.ButtonBrowseClick(Sender: TObject);
64var
65 Dir: string;
66begin
67 if SelectDirectory('Select directory', EditDir.Text, Dir) then
68 EditDir.Text := Dir;
69end;
70
71function TFormMain.IsSpecialSymbol(C: Char): Boolean;
72begin
73 Result := C in ['&', '|', '!', '<', '>', '+', '-', '=', '.', '#', '{', '}',
74 ':'];
75end;
76
77function TFormMain.IsAlpha(C: Char): Boolean;
78begin
79 Result := (C in ['a'..'z']) or (C in ['A'..'Z']);
80end;
81
82function TFormMain.IsNumeric(C: Char): Boolean;
83begin
84 Result := C in ['0'..'9'];
85end;
86
87function TFormMain.IsAlphaNumeric(C: Char): Boolean;
88begin
89 Result := IsAlpha(C) or IsNumeric(C);
90end;
91
92function TFormMain.IsAlphaNumericUnderscore(C: Char): Boolean;
93begin
94 Result := IsAlphaNumeric(C) or (C = '_');
95end;
96
97function TFormMain.ReadIdent(Text: string): string;
98var
99 I: Integer;
100begin
101 Result := '';
102 I := 1;
103 while (I <= Length(Text)) do begin
104 if Text[I] = ' ' then begin
105 end else
106 if (Result = '') and IsAlpha(Text[I]) then begin
107 Result := Result + Text[I];
108 end else
109 if (Result <> '') and IsAlphaNumericUnderscore(Text[I]) then begin
110 Result := Result + Text[I];
111 end else Break;
112 Inc(I);
113 end;
114end;
115
116function TFormMain.ReadIdentBack(Text: string): string;
117var
118 I: Integer;
119begin
120 Result := '';
121 I := Length(Text);
122 while (I > 0) do begin
123 if Text[I] = ' ' then begin
124 end else
125 if (Result = '') and IsAlpha(Text[I]) then begin
126 Result := Text[I] + Result;
127 end else
128 if (Result <> '') and IsAlphaNumericUnderscore(Text[I]) then begin
129 Result := Text[I] + Result;
130 end else Break;
131 Dec(I);
132 end;
133end;
134
135procedure SearchFiles(List: TStrings; Dir: string;
136 FilterMethod: TFilterMethod = nil; FileNameMethod: TFileNameMethod = nil);
137var
138 SR: TSearchRec;
139 FullName: string;
140begin
141 List.BeginUpdate;
142 try
143 Dir := IncludeTrailingPathDelimiter(Dir);
144 if FindFirst(Dir + '*', faAnyFile, SR) = 0 then begin
145 try
146 repeat
147 if (SR.Name = '.') or (SR.Name = '..') then Continue;
148 FullName := Dir + SR.Name;
149 if not Assigned(FilterMethod) or (Assigned(FilterMethod) and FilterMethod(FullName)) then begin;
150 if Assigned(FileNameMethod) then
151 FileNameMethod(Dir + SR.Name);
152 List.Add(FullName);
153 end;
154 if (SR.Attr and faDirectory) <> 0 then
155 SearchFiles(List, FullName, FilterMethod, FileNameMethod);
156 until FindNext(SR) <> 0;
157 finally
158 FindClose(SR);
159 end;
160 end;
161 finally
162 List.EndUpdate;
163 end;
164end;
165
166procedure TFormMain.ButtonProcessClick(Sender: TObject);
167var
168 I: Integer;
169 Files: TStringList;
170 FileNameSrc: string;
171 FileNameDst: string;
172 DirSrc: string;
173 DirDst: string;
174 FileExt: string;
175 Content: string;
176 Content2: string;
177begin
178 DirSrc := EditDir.Text;
179 DirDst := ExtractFileDir(DirSrc) + DirectorySeparator + ExtractFileName(DirSrc) + '_';
180 MemoLog.Lines.BeginUpdate;
181 try
182 MemoLog.Lines.Clear;
183 Files := TStringList.Create;
184 SearchFiles(Files, DirSrc, nil, nil);
185
186 for I := 0 to Files.Count - 1 do begin
187 MemoLog.Lines.Add(Files[I]);
188 FileNameSrc := Files[I];
189 if DirectoryExists(FileNameSrc) then continue;
190 if FileExists(FileNameSrc) then begin
191 FileNameDst := DirDst + Copy(FileNameSrc, Length(DirSrc) + 1, MaxInt);
192 ForceDirectories(ExtractFileDir(FileNameDst));
193 FileExt := ExtractFileExt(FileNameSrc);
194 if FileExt = '.cpp' then begin
195 FileNameDst := ExtractFileNameWithoutExt(FileNameDst) + '.pas';
196 DeleteFile(FileNameDst);
197 end;
198 end;
199 end;
200
201 for I := 0 to Files.Count - 1 do begin
202 MemoLog.Lines.Add(Files[I]);
203 FileNameSrc := Files[I];
204 if DirectoryExists(FileNameSrc) then continue;
205 if FileExists(FileNameSrc) then begin
206 FileNameDst := DirDst + Copy(FileNameSrc, Length(DirSrc) + 1, MaxInt);
207 ForceDirectories(ExtractFileDir(FileNameDst));
208 FileExt := ExtractFileExt(FileNameSrc);
209 if FileExt = '.cpp' then begin
210 // Skip for now
211 end else
212 if FileExt = '.h' then begin
213 FileNameDst := ExtractFileNameWithoutExt(FileNameDst) + '.pas';
214 Content := FormatCodeCpp(ReadFileContent(FileNameSrc));
215 Content := 'unit ' + ExtractFileNameOnly(FileNameDst) + ';' + LineEnding +
216 LineEnding + 'interface' + LineEnding + LineEnding + Content;
217 WriteFileContent(FileNameDst, Content);
218 end else
219 CopyFile(FileNameSrc, FileNameDst);
220 end;
221 end;
222
223 // Merge .cpp files
224 for I := 0 to Files.Count - 1 do begin
225 FileNameSrc := Files[I];
226 if DirectoryExists(FileNameSrc) then continue;
227 if FileExists(FileNameSrc) then begin
228 FileNameDst := DirDst + Copy(FileNameSrc, Length(DirSrc) + 1, MaxInt);
229 ForceDirectories(ExtractFileDir(FileNameDst));
230 FileExt := ExtractFileExt(FileNameSrc);
231 if FileExt = '.cpp' then begin
232 FileNameDst := ExtractFileNameWithoutExt(FileNameDst) + '.pas';
233 if FileExists(FileNameDst) then Content := ReadFileContent(FileNameDst)
234 else Content := 'unit ' + ExtractFileNameOnly(FileNameDst) + ';' + LineEnding +
235 LineEnding + 'interface' + LineEnding + LineEnding;
236 Content2 := FormatCodeCpp(ReadFileContent(FileNameSrc));
237 Content := Content + LineEnding + 'implementation' + LineEnding + LineEnding +
238 Content2 + LineEnding + LineEnding + 'end.' + LineEnding;
239 WriteFileContent(FileNameDst, Content);
240 end;
241 end;
242 end;
243 Files.Free;
244 finally
245 MemoLog.Lines.EndUpdate;
246 end;
247end;
248
249function TFormMain.EndsWith(Text, What: string): Boolean;
250begin
251 Result := Copy(Text, Length(Text) - Length(What) + 1, Length(What)) = What;
252end;
253
254function TFormMain.StartsWith(Text, What: string): Boolean;
255begin
256 Result := Copy(Text, 1, Length(What)) = What;
257end;
258
259function TFormMain.SpaceAround(Text, What: string; Left: Boolean = True; Right: Boolean = True): string;
260var
261 I: Integer;
262begin
263 Result := '';
264 while True do begin
265 I := Pos(What, Text);
266 if I > 0 then begin
267 Result := Result + Copy(Text, 1, I - 1);
268 Delete(Text, 1, I - 1);
269 if Left and (Length(Result) >= 1) and (Result[Length(Result)] <> ' ') then begin
270 Result := Result + ' ';
271 end;
272 Result := Result + What;
273 Delete(Text, 1, Length(What));
274 if Right and (Length(Text) >= 1) and (Text[1] <> ' ') then begin
275 Result := Result + ' ';
276 end;
277 end else Break;
278 end;
279 Result := Result + Text;
280end;
281
282function TFormMain.Replace(Text: string; OldPattern, NewPattern: string
283 ): string;
284begin
285 Result := StringReplace(Text, OldPattern, NewPattern, [rfReplaceAll]);
286end;
287
288function TFormMain.ReplaceIdent(Text: string; OldPattern, NewPattern: string
289 ): string;
290var
291 I: Integer;
292 TextBefore: string;
293 TextAfter: string;
294begin
295 Result := '';
296 while True do begin
297 I := Pos(OldPattern, Text);
298 if I > 0 then begin
299 TextBefore := Copy(Text, 1, I - 1);
300 TextAfter := Copy(Text, I + Length(OldPattern), Length(Text));
301 if ((Length(TextBefore) >= 1) and IsAlphaNumeric(TextBefore[Length(TextBefore)]) or
302 ((Length(Result) >= 1) and IsAlphaNumeric(Result[Length(Result)]) and
303 (Copy(Result, Length(Result) - Length(NewPattern) + 1, Length(NewPattern)) <> NewPattern)) or
304 ((Length(TextAfter) >= 1) and IsAlphaNumeric(TextAfter[1])))
305 then begin
306 Result := Result + TextBefore + OldPattern;
307 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
308 Continue;
309 end;
310 Result := Result + TextBefore + NewPattern;
311 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
312 end else Break;
313 end;
314 Result := Result + Text;
315end;
316
317function TFormMain.ReplaceFunction(Text: string; ReturnType: string): string;
318var
319 Strip: string;
320 I: Integer;
321begin
322 I := Pos(ReturnType + ' ', Text);
323 if (I > 0) and (Trim(Copy(Text, 1, I - 1)) = '') and (Pos('(', Text) > 0) and (Pos(')', Text) > 0) then begin
324 Strip := ';';
325 if EndsWith(Text, Strip) then
326 Delete(Text, Length(Text) - Length(Strip) + 1, Length(Strip));
327 Result := Copy(Text, 1, I - 1) + 'function' + Copy(Text, I + Length(ReturnType), Length(Text)) + ': ' + ReturnType + ';';
328 end else Result := Text;
329end;
330
331function TFormMain.ReplaceVariable(Text: string; VarType: string): string;
332var
333 I: Integer;
334 Ident: string;
335begin
336 Result := '';
337 while True do begin
338 I := Pos(VarType + ' ', Text);
339 if I > 0 then begin
340 Result := Result + Copy(Text, 1, I - 1);
341 Delete(Text, 1, I - 1 + Length(VarType + ' '));
342 Ident := ReadIdent(Text);
343 if Ident <> '' then begin
344 Result := Result + Ident + ': ' + VarType;
345 Delete(Text, 1, Length(Ident));
346 end else Result := Result + VarType + ' ';
347 end else begin
348 Result := Result + Text;
349 Break;
350 end;
351 end;
352end;
353
354function TFormMain.ReplaceOperator(Text: string; OldOp, NewOp1, NewOp2: string): string;
355var
356 I: Integer;
357 TextBefore: string;
358 TextAfter: string;
359 Ident: string;
360begin
361 I := Pos(OldOp, Text);
362 if I > 0 then begin
363 TextBefore := Copy(Text, 1, I - 1);
364 TextAfter := Copy(Text, I + Length(OldOp), Length(Text));
365 Ident := ReadIdentBack(TextBefore);
366 if Ident <> '' then begin
367 Delete(TextBefore, Length(TextBefore) - Length(Ident) + 1, Length(Ident));
368 Result := TextBefore + Ident + ' ' + NewOp1 + ' ' + Ident + ' ' + NewOp2 + ' ' + TextAfter;
369 end else Result := Text;
370 end else Result := Text;
371end;
372
373function TFormMain.ReplaceAndClose(Text: string; OldPattern, NewPattern,
374 Close: string; Strip: string = ''): string;
375var
376 Found: Boolean;
377begin
378 Found := Pos(OldPattern, Text) > 0;
379 Result := StringReplace(Text, OldPattern, NewPattern, [rfReplaceAll]);
380 if Found then begin
381 if (Strip <> '') and EndsWith(Result, Strip) then
382 Delete(Result, Length(Result) - Length(Strip) + 1, Length(Strip));
383 Result := Result + Close;
384 end;
385end;
386
387function TFormMain.ReplaceSpecialSymbol(Text: string; OldPattern, NewPattern: string): string;
388var
389 I: Integer;
390 TextBefore: string;
391 TextAfter: string;
392begin
393 Result := '';
394 while True do begin
395 I := Pos(OldPattern, Text);
396 if I > 0 then begin
397 TextBefore := Copy(Text, 1, I - 1);
398 TextAfter := Copy(Text, I + Length(OldPattern), Length(Text));
399 if ((Length(TextBefore) >= 1) and IsSpecialSymbol(TextBefore[Length(TextBefore)]) or
400 ((Length(Result) >= 1) and IsSpecialSymbol(Result[Length(Result)]) and
401 (Copy(Result, Length(Result) - Length(NewPattern) + 1, Length(NewPattern)) <> NewPattern)) or
402 ((Length(TextAfter) >= 1) and IsSpecialSymbol(TextAfter[1])))
403 then begin
404 Result := Result + TextBefore + OldPattern;
405 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
406 Continue;
407 end;
408 Result := Result + TextBefore + NewPattern;
409 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
410 end else Break;
411 end;
412 Result := Result + Text;
413end;
414
415function TFormMain.ReplaceSpecialSymbolNumericAfter(Text: string; OldPattern, NewPattern, NewPattern2: string): string;
416var
417 I: Integer;
418 TextBefore: string;
419 TextAfter: string;
420begin
421 Result := '';
422 while True do begin
423 I := Pos(OldPattern, Text);
424 if I > 0 then begin
425 TextBefore := Copy(Text, 1, I - 1);
426 TextAfter := Copy(Text, I + Length(OldPattern), Length(Text));
427 if (Length(TextAfter) >= 1) and IsNumeric(TextAfter[1]) then begin
428 Result := Result + TextBefore + NewPattern2;
429 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
430 end else begin
431 Result := Result + TextBefore + NewPattern;
432 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
433 end;
434 end else Break;
435 end;
436 Result := Result + Text;
437end;
438
439function TFormMain.ReplaceSpecialSymbolNumericBefore(Text: string; OldPattern,
440 NewPattern, NewPattern2: string): string;
441var
442 I: Integer;
443 TextBefore: string;
444begin
445 Result := '';
446 while True do begin
447 I := Pos(OldPattern, Text);
448 if I > 0 then begin
449 TextBefore := Copy(Text, 1, I - 1);
450 if (Length(TextBefore) >= 1) and IsNumeric(TextBefore[Length(TextBefore)]) then begin
451 Result := Result + TextBefore + NewPattern2;
452 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
453 end else begin
454 Result := Result + TextBefore + NewPattern;
455 Delete(Text, 1, Length(TextBefore) + Length(OldPattern));
456 end;
457 end else Break;
458 end;
459 Result := Result + Text;
460end;
461
462function TFormMain.FormatCodeCpp(Text: string): string;
463var
464 Lines: TStringList;
465 I: Integer;
466 J: Integer;
467 Line: string;
468const
469 Types: array[0..11] of string = ('Integer', 'Boolean', 'Cardinal', 'Byte',
470 'ShortInt', 'Pointer',
471 'Advances', 'TNewGameData', 'TServerCall', 'TClientCall', 'MyEVOArea',
472 'TileFunction');
473 PascalKeywords: array[0..1] of string = ('object', 'type');
474begin
475 Result := '';
476 Lines := TStringList.Create;
477 try
478 Lines.Text := Text;
479 for I := 0 to Lines.Count - 1 do begin
480 Line := Lines[I];
481 Line := ReplaceSpecialSymbol(Line, '>>', 'shr');
482 Line := ReplaceSpecialSymbol(Line, '<<', 'shl');
483 Line := ReplaceSpecialSymbol(Line, '&&', 'and');
484 Line := ReplaceSpecialSymbol(Line, '||', 'or');
485 Line := ReplaceSpecialSymbol(Line, '&', 'and');
486 Line := ReplaceSpecialSymbol(Line, '|', 'or');
487 Line := ReplaceSpecialSymbol(Line, '!', 'not');
488 Line := ReplaceSpecialSymbol(Line, '!=', '<>');
489 Line := ReplaceSpecialSymbol(Line, '->', '.');
490 Line := ReplaceSpecialSymbol(Line, '::', '.');
491 Line := Replace(Line, 'switch', 'case');
492 Line := Replace(Line, 'unsigned long ', 'Cardinal ');
493 Line := Replace(Line, 'unsigned short ', 'Byte ');
494 Line := Replace(Line, 'unsigned char ', 'Byte ');
495 Line := Replace(Line, 'unsigned int ', 'Cardinal ');
496 Line := Replace(Line, 'int ', 'Integer ');
497 Line := Replace(Line, 'short ', 'ShortInt ');
498 Line := Replace(Line, 'long ', 'Integer ');
499 Line := Replace(Line, 'bool ', 'Boolean ');
500 Line := Replace(Line, 'void *', 'Pointer ');
501 Line := Replace(Line, 'std.ofstream ', 'TStream ');
502 Line := Replace(Line, 'std.ostream ', 'TStream ');
503 Line := ReplaceOperator(Line, '+=', ':=', '+');
504 Line := ReplaceOperator(Line, '-=', ':=', '-');
505 Line := ReplaceOperator(Line, '++', ':=', '+ 1');
506 Line := ReplaceOperator(Line, '++', ':=', '- 1');
507 Line := ReplaceSpecialSymbol(Line, '=', ':=');
508 Line := ReplaceSpecialSymbol(Line, '==', '=');
509 Line := ReplaceSpecialSymbolNumericAfter(Line, '{', 'begin', '(');
510 Line := ReplaceSpecialSymbolNumericBefore(Line, '}', 'end;', ')');
511 Line := ReplaceAndClose(Line, '#include', '{$include', '}');
512 Line := ReplaceAndClose(Line, 'return', 'Exit(', ');', ';');
513 Line := Replace(Line, '0x', '$');
514 Line := Replace(Line, '"', '''');
515 Line := ReplaceAndClose(Line, '#define', '{$define', '}');
516 Line := ReplaceAndClose(Line, '#endif', '{$endif', '}');
517 Line := ReplaceAndClose(Line, '#ifdef', '{$ifdef', '}');
518 Line := ReplaceAndClose(Line, '#ifndef', '{$ifndef', '}');
519 Line := ReplaceAndClose(Line, 'void ', 'procedure ', ';');
520 Line := Replace(Line, 'struct', 'record');
521 Line := Replace(Line, '/*', '(*');
522 Line := Replace(Line, '*/', '*)');
523 Line := Replace(Line, 'const ', '');
524 Line := Replace(Line, ' const', '');
525 Line := Replace(Line, 'mutable ', '');
526 for J := 0 to Length(Types) - 1 do
527 Line := ReplaceFunction(Line, Types[J]);
528 if Pos('function', Line) > 0 then
529 Line := Replace(Line, ',', ';');
530 for J := 0 to Length(Types) - 1 do
531 Line := ReplaceVariable(Line, Types[J]);
532 Line := ReplaceAndClose(Line, 'if (', 'if (', ' then');
533 Line := Replace(Line, '()', '');
534 for J := 0 to Length(PascalKeywords) - 1 do
535 Line := ReplaceIdent(Line, PascalKeywords[J], 'K' + PascalKeywords[J]);
536 //Line := SpaceAround(Line, ':=');
537 //Line := SpaceAround(Line, '+');
538 //Line := SpaceAround(Line, ',', False, True);
539 Lines[I] := Line;
540 end;
541 Result := Lines.Text;
542 finally
543 Lines.Free;
544 end;
545end;
546
547function TFormMain.ReadFileContent(FileName: string): string;
548var
549 Lines: TStringList;
550begin
551 Lines := TStringList.Create;
552 try
553 Lines.LoadFromFile(FileName);
554 Result := Lines.Text;
555 finally
556 Lines.Free;
557 end;
558end;
559
560procedure TFormMain.WriteFileContent(FileName: string; Content: string);
561var
562 Lines: TStringList;
563begin
564 Lines := TStringList.Create;
565 try
566 Lines.Text := Content;
567 Lines.SaveToFile(FileName);
568 finally
569 Lines.Free;
570 end;
571end;
572
573
574end.
575
Note: See TracBrowser for help on using the repository browser.