tphc.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. {
  2. !!! Someone please fix DRIVERS.PAS, so it doesn't clears the screen on exit
  3. when we didn't use any of it's functions, just had it in 'uses'
  4. Then we can delete GetDosTicks() from WHelp...
  5. }
  6. uses Objects,WUtils,WHelp,WTPHWriter;
  7. const
  8. SrcExt = '.txt';
  9. HelpExt = '.fph';
  10. TokenPrefix = '.';
  11. CommentPrefix = ';';
  12. TokenIndex = 'INDEX';
  13. TokenTopic = 'TOPIC';
  14. TokenCode = 'CODE';
  15. FirstTempTopic = 1000000;
  16. CR = #$0D;
  17. LF = #$0A;
  18. type
  19. THCIndexEntry = record
  20. Tag : PString;
  21. TopicName: PString;
  22. end;
  23. THCTopic = record
  24. Name : PString;
  25. Topic : PTopic;
  26. end;
  27. PHCIndexEntryCollection = ^THCIndexEntryCollection;
  28. THCIndexEntryCollection = object(T
  29. var SrcName, DestName: string;
  30. HelpFile : THelpFileWriter;
  31. procedure Print(const S: string);
  32. begin
  33. writeln(S);
  34. end;
  35. procedure Abort; forward;
  36. procedure Help;
  37. begin
  38. Print('Syntax : TPHC <helpsource>[.TXT] <helpfile>[.FPH]');
  39. Abort;
  40. end;
  41. procedure Fatal(const S: string);
  42. begin
  43. Print('Fatal: '+S);
  44. Abort;
  45. end;
  46. procedure Warning(const S: string);
  47. begin
  48. Print('Warning: '+S);
  49. end;
  50. procedure ProcessParams;
  51. begin
  52. if (ParamCount<1) or (ParamCount>2) then Help;
  53. SrcName:=ParamStr(1);
  54. if ExtOf(SrcName)='' then SrcName:=SrcName+SrcExt;
  55. if ParamCount=1 then
  56. DestName:=DirAndNameOf(SrcName)+HelpExt
  57. else
  58. begin
  59. DestName:=ParamStr(2);
  60. if ExtOf(DestName)='' then DestName:=DestName+HelpExt;
  61. end;
  62. end;
  63. procedure Compile(SrcS, DestS: PStream);
  64. var CurLine: string;
  65. CurLineNo: longint;
  66. CurTopic : PTopic;
  67. HelpFile: PHelpFileWriter;
  68. InCode: boolean;
  69. NextTempTopic: longint;
  70. procedure AddLine(const S: string);
  71. begin
  72. if CurTopic<>nil then
  73. HelpFile^.AddLineToTopic(CurTopic,S);
  74. end;
  75. procedure ProcessToken(S: string);
  76. var P: byte;
  77. Token: string;
  78. TopicName: string;
  79. TopicContext: THelpCtx;
  80. Text: string;
  81. begin
  82. S:=Trim(S);
  83. P:=Pos(' ',S); if P=0 then P:=length(S)+1;
  84. Token:=UpcaseStr(copy(S,1,P-1)); Delete(S,1,P); S:=Trim(S);
  85. if Token=TokenIndex then
  86. begin
  87. if InCode then AddLine(hscCode);
  88. if copy(S,1,1)<>'{' then
  89. Fatal('"{" expected at line '+IntToStr(CurLineNo));
  90. if copy(S,length(S),1)<>'}' then
  91. Fatal('"}" expected at line '+IntToStr(CurLineNo));
  92. S:=copy(S,2,length(S)-2);
  93. P:=Pos(':',S); if P=0 then P:=length(S)+1;
  94. Text:=copy(S,1,!!
  95. end else
  96. if Token=TokenTopic then
  97. begin
  98. if InCode then AddLine(hscCode);
  99. P:=Pos(' ',S); if P=0 then P:=length(S)+1;
  100. TopicName:=UpcaseStr(copy(S,1,P-1)); Delete(S,1,P); S:=Trim(S);
  101. if TopicName='' then
  102. Fatal('Topic name missing at line '+IntToStr(CurLineNo));
  103. if S='' then
  104. TopicContext:=0
  105. else
  106. if copy(S,1,1)<>'=' then
  107. begin
  108. Fatal('"=" expected at line '+IntToStr(CurLineNo));
  109. TopicContext:=0;
  110. end
  111. else
  112. begin
  113. S:=Trim(copy(S,2,255));
  114. TopicContext:=StrToInt(S);
  115. if LastStrToIntResult<>0 then
  116. Fatal('Error interpreting context number at line '+IntToStr(CurLineNo));
  117. end;
  118. if TopicContext=0 then
  119. begin
  120. TopicContext:=NextTempTopic;
  121. Inc(NextTempTopic);
  122. end;
  123. CurTopic:=HelpFile^.CreateTopic(TopicContext);
  124. end else
  125. if Token=TokenCode then
  126. begin
  127. AddLine(hscCode);
  128. InCode:=not InCode;
  129. end else
  130. Warning('Uknown token "'+Token+'" encountered at line '+IntToStr(CurLineNo));
  131. end;
  132. procedure ProcessLine(const S: string);
  133. begin
  134. AddLine(S);
  135. end;
  136. function ReadNextLine: boolean;
  137. var C: char;
  138. begin
  139. Inc(CurLineNo);
  140. CurLine:='';
  141. repeat
  142. SrcS^.Read(C,1);
  143. if (C in[CR,LF])=false then
  144. CurLine:=CurLine+C;
  145. until (C=LF) or (SrcS^.Status<>stOK);
  146. ReadNextLine:=(SrcS^.Status=stOK);
  147. end;
  148. var OK: boolean;
  149. begin
  150. New(HelpFile, InitStream(DestS,0));
  151. CurTopic:=nil; CurLineNo:=0;
  152. NextTempTopic:=FirstTempTopic;
  153. InCode:=false;
  154. repeat
  155. OK:=ReadNextLine;
  156. if OK then
  157. if copy(CurLine,1,length(CommentPrefix))=CommentPrefix then
  158. { comment }
  159. else
  160. if copy(CurLine,1,length(TokenPrefix))=TokenPrefix then
  161. ProcessToken(copy(CurLine,2,255))
  162. else
  163. { normal help-text }
  164. begin
  165. ProcessLine(CurLine);
  166. end;
  167. until OK=false;
  168. if HelpFile^.WriteFile=false then
  169. Fatal('Error writing help file.');
  170. Dispose(HelpFile, Done);
  171. end;
  172. const SrcS : PBufStream = nil;
  173. DestS : PBufStream = nil;
  174. procedure Abort;
  175. begin
  176. if SrcS<>nil then Dispose(SrcS, Done); SrcS:=nil;
  177. if DestS<>nil then Dispose(DestS, Done); DestS:=nil;
  178. end;
  179. BEGIN
  180. Print('þ Help Compiler Version 0.9 Copyright (c) 1999 by B‚rczi G bor');
  181. ProcessParams;
  182. New(SrcS, Init(SrcName, stOpenRead, 4096));
  183. if (SrcS=nil) or (SrcS^.Status<>stOK) then
  184. Fatal('Error opening source file.');
  185. New(DestS, Init(DestName, stCreate, 4096));
  186. if (DestS=nil) or (DestS^.Status<>stOK) then
  187. Fatal('Error creating destination file.');
  188. Compile(SrcS,DestS);
  189. END.