uHSFParser.pas 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. unit uHSFParser;
  2. interface
  3. uses Classes, uEditor;
  4. type
  5. TOnGetLine = function(const Symbol: string): Integer of object;
  6. procedure ImportFile(const FileName: string; F: TCEditorForm; GetLine: TOnGetLine);
  7. procedure ImportDir(Dir: string; F: TCEditorForm; GetLine: TOnGetLine);
  8. function SimplifyType(T: string): string;
  9. function SimplifyLeft(T: string; out Right: string): string;
  10. function FilterComment(const Comment: string): string;
  11. function FilterDesc(const Def: string): string;
  12. var
  13. DoEnum: Boolean;
  14. implementation
  15. uses SysUtils, StrUtils, UtilsDos;
  16. function SimplifyType(T: string): string;
  17. begin
  18. T := Trim(T);
  19. if T = 'Type' then
  20. Result := '<c:Olive>type'
  21. else if T = 'Function' then
  22. Result := '<c:Teal>func'
  23. else if T = 'Constant' then
  24. Result := '<c:Green>const'
  25. else if T = 'Variable' then
  26. Result := '<c:Maroon>var'
  27. else if T = 'Enum' then
  28. Result := '<c:Olive>enum'
  29. else
  30. Result := T;
  31. end;
  32. function SimplifyLeft(T: string; out Right: string): string;
  33. begin
  34. T := Trim(T);
  35. if AnsiStartsText('typedef', T) then
  36. begin
  37. Right := Copy(T, 9, MaxInt);
  38. Result := '';
  39. end
  40. else if AnsiStartsText('CALLBACK', T) then
  41. begin
  42. Result := '<i>callback';
  43. Right := Trim(Copy(T, 10, MaxInt)) + ' | ';
  44. end
  45. else if T = 'unknown_retval' then
  46. Result := '?'
  47. else if T = '#define' then
  48. Result := ''
  49. else
  50. Result := T;
  51. end;
  52. function FilterComment(const Comment: string): string;
  53. var
  54. i, j: Integer;
  55. begin
  56. Result := '';
  57. i := Pos('/*', Comment);
  58. j := -1;
  59. while i <> 0 do
  60. begin
  61. Result := Result + Copy(Comment, j + 2, i - j - 1);
  62. j := PosEx('*/', Comment, i);
  63. if j = 0 then
  64. begin
  65. j := MaxInt;
  66. Break;
  67. end;
  68. i := PosEx('/*', Comment, j);
  69. end;
  70. Result := Result + Copy(Comment, j + 2, MaxInt);
  71. end;
  72. function FilterDesc(const Def: string): string;
  73. var
  74. i, j: Integer;
  75. begin
  76. Result := '';
  77. i := Pos('<', Def);
  78. j := 0;
  79. while i <> 0 do
  80. begin
  81. Result := Result + Copy(Def, j + 1, i - j - 1);
  82. j := PosEx('>', Def, i);
  83. if j = 0 then
  84. begin
  85. j := MaxInt;
  86. Break;
  87. end;
  88. i := PosEx('<', Def, j);
  89. end;
  90. Result := Result + Copy(Def, j + 1, MaxInt);
  91. end;
  92. procedure FilterEnum(const Definition, Description: string; F: TCEditorForm; Line: Integer);
  93. var
  94. Items: TStringList;
  95. i, p: Integer;
  96. L, R, S: string;
  97. begin
  98. Items := TStringList.Create;
  99. p := Pos('{', Definition);
  100. if p <> 0 then
  101. begin
  102. Inc(p);
  103. Items.CommaText := Copy(Definition, p, PosEx('}', Definition, p) - p);
  104. L := '<c:Olive>' + Trim(Copy(Definition, 1, p - 2));
  105. for i := 0 to Items.Count - 1 do
  106. begin
  107. S := Trim(Items[i]);
  108. p := Pos('=', S);
  109. if P <> 0 then
  110. begin
  111. R := Trim(Copy(S, p + 1, MaxInt));
  112. S := Trim(Copy(S, 1, p - 1));
  113. end
  114. else
  115. R := '';
  116. F.SetItem(S, L, R, Description, Line);
  117. end;
  118. end;
  119. Items.Free;
  120. end;
  121. procedure ImportFile(const FileName: string; F: TCEditorForm; GetLine: TOnGetLine);
  122. var
  123. Lst: TStringList;
  124. Name, Left, Right, Description, Definition, Tmp: string;
  125. i, Line: Integer;
  126. begin
  127. Lst := TStringList.Create;
  128. Lst.LoadFromFile(FileName);
  129. Name := Lst.Values['Name'];
  130. Definition := Lst.Values['Definition'];
  131. Left := FilterComment(SimplifyType(Lst.Values['Type']) + ' <c:Blue>' + SimplifyLeft(Copy(Definition, 1, Pos(Name, Definition) - 1), Tmp));
  132. Right := Tmp + Trim(Copy(Definition, Pos(Name, Definition) + Length(Name), MaxInt));
  133. i := Lst.IndexOf('[Description]');
  134. if i <> -1 then
  135. Description := FilterDesc(Lst[i + 1])
  136. else
  137. Description := '';
  138. if Assigned(GetLine) then
  139. Line := GetLine(Name)
  140. else
  141. Line := 0;
  142. F.SetItem(Name, Left, Right, Description, Line);
  143. if DoEnum and (Lst.Values['SubType'] = 'Enumeration') then
  144. FilterEnum(Definition, Description, F, Line);
  145. Lst.Free;
  146. end;
  147. procedure ImportDir(Dir: string; F: TCEditorForm; GetLine: TOnGetLine);
  148. var
  149. SR: TSearchRec;
  150. begin
  151. Dir := IncludeTrailingPathDelimiter(Dir);
  152. if FindFirst(Dir + '*.*', faAnyFile, SR) = 0 then
  153. begin
  154. repeat
  155. if SR.Name[1] <> '.' then
  156. begin
  157. if SR.Attr and faDirectory = faDirectory then
  158. ImportDir(Dir + SR.Name, F, GetLine)
  159. else if UpperCase(ExtractFileExt(SR.Name)) = '.HSF' then
  160. ImportFile(Dir + SR.Name, F, GetLine);
  161. end;
  162. until FindNext(SR) <> 0;
  163. FindClose(SR);
  164. end;
  165. end;
  166. end.