h2paspp.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. {
  2. Copyright (c) 2000 by Peter Vreman
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. ****************************************************************************}
  15. program h2paspp;
  16. type
  17. PSymbol=^TSymbol;
  18. TSymbol=record
  19. name : string[32];
  20. next : PSymbol;
  21. end;
  22. var
  23. Symbols : PSymbol;
  24. OutFile : string;
  25. procedure def_symbol(const s:string);
  26. var
  27. p : PSymbol;
  28. begin
  29. new(p);
  30. p^.name:=s;
  31. p^.next:=Symbols;
  32. Symbols:=p;
  33. end;
  34. procedure undef_symbol(const s:string);
  35. var
  36. p,plast : PSymbol;
  37. begin
  38. p:=Symbols;
  39. plast:=nil;
  40. while assigned(p) do
  41. begin
  42. if p^.name=s then
  43. begin
  44. if assigned(plast) then
  45. plast^.next:=p^.next
  46. else
  47. Symbols:=p^.next;
  48. dispose(p);
  49. exit;
  50. end;
  51. p:=p^.next;
  52. end;
  53. end;
  54. function check_symbol(const s:string):boolean;
  55. var
  56. p : PSymbol;
  57. begin
  58. check_symbol:=false;
  59. p:=Symbols;
  60. while assigned(p) do
  61. begin
  62. if p^.name=s then
  63. begin
  64. check_symbol:=true;
  65. exit;
  66. end;
  67. p:=p^.next;
  68. end;
  69. end;
  70. procedure clear_symbols;
  71. var
  72. hp : PSymbol;
  73. begin
  74. while assigned(Symbols) do
  75. begin
  76. hp:=Symbols;
  77. Symbols:=Symbols^.next;
  78. dispose(hp);
  79. end;
  80. end;
  81. function dofile(const filename : string):boolean;
  82. procedure RemoveSpace(var fn:string);
  83. var
  84. i : longint;
  85. begin
  86. i:=0;
  87. while (i<length(fn)) and (fn[i+1] in [' ',#9]) do
  88. inc(i);
  89. Delete(fn,1,i);
  90. i:=length(fn);
  91. while (i>0) and (fn[i] in [' ',#9]) do
  92. dec(i);
  93. fn:=copy(fn,1,i);
  94. end;
  95. function GetName(var fn:string):string;
  96. var
  97. i : longint;
  98. begin
  99. i:=0;
  100. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  101. inc(i);
  102. GetName:=Copy(fn,1,i);
  103. Delete(fn,1,i);
  104. end;
  105. const
  106. maxlevel=16;
  107. var
  108. f,g : text;
  109. s,orgs,
  110. opts : string;
  111. skip : array[0..maxlevel-1] of boolean;
  112. level : longint;
  113. begin
  114. dofile:=false;
  115. { open file }
  116. assign(f,filename);
  117. {$I-}
  118. reset(f);
  119. {$I+}
  120. if ioresult<>0 then
  121. begin
  122. Writeln('Unable to open file ',filename);
  123. exit;
  124. end;
  125. if outfile='' then
  126. assign(g,'h2paspp.tmp')
  127. else
  128. assign(g,outfile);
  129. {$I-}
  130. rewrite(g);
  131. {$I+}
  132. if ioresult<>0 then
  133. begin
  134. Writeln('Unable to create file tmp');
  135. Close(f);
  136. exit;
  137. end;
  138. fillchar(skip,sizeof(skip),0);
  139. level:=0;
  140. while not eof(f) do
  141. begin
  142. readln(f,orgs);
  143. opts:=orgs;
  144. if (opts<>'') and (opts[1]='#') then
  145. begin
  146. Delete(opts,1,1);
  147. RemoveSpace(opts);
  148. s:=GetName(opts);
  149. if (s='ifdef') then
  150. begin
  151. RemoveSpace(opts);
  152. if Level>=maxlevel then
  153. begin
  154. Writeln('Too many ifdef levels');
  155. exit;
  156. end;
  157. inc(Level);
  158. skip[level]:=(skip[level-1] or (not check_symbol(GetName(opts))));
  159. end
  160. else
  161. if (s='if') then
  162. begin
  163. RemoveSpace(opts);
  164. if Level>=maxlevel then
  165. begin
  166. Writeln('Too many ifdef levels');
  167. exit;
  168. end;
  169. inc(Level);
  170. skip[level]:=(skip[level-1] or (not check_symbol(GetName(opts))));
  171. end
  172. else
  173. if (s='ifndef') then
  174. begin
  175. RemoveSpace(opts);
  176. if Level>=maxlevel then
  177. begin
  178. Writeln('Too many ifdef levels');
  179. exit;
  180. end;
  181. inc(Level);
  182. skip[level]:=(skip[level-1] or (check_symbol(GetName(opts))));
  183. end
  184. else
  185. if (s='else') then
  186. skip[level]:=skip[level-1] or (not skip[level])
  187. else
  188. if (s='endif') then
  189. begin
  190. skip[level]:=false;
  191. if Level=0 then
  192. begin
  193. Writeln('Too many endif found');
  194. exit;
  195. end;
  196. dec(level);
  197. end
  198. else
  199. if (not skip[level]) then
  200. begin
  201. if (s='define') then
  202. begin
  203. RemoveSpace(opts);
  204. def_symbol(GetName(opts));
  205. end
  206. else
  207. if (s='undef') then
  208. begin
  209. RemoveSpace(opts);
  210. undef_symbol(GetName(opts));
  211. end
  212. else
  213. if (s='include') then
  214. begin
  215. RemoveSpace(opts);
  216. Writeln('Uses include: ',opts);
  217. opts:='';
  218. end;
  219. { Add defines also to the output }
  220. if opts<>'' then
  221. writeln(g,orgs);
  222. end;
  223. end
  224. else
  225. begin
  226. if (not skip[level]) then
  227. writeln(g,orgs);
  228. end;
  229. end;
  230. if Level>0 then
  231. Writeln('Error: too less endif found');
  232. Close(f);
  233. Close(g);
  234. if outfile='' then
  235. begin
  236. Erase(f);
  237. Rename(g,filename);
  238. end;
  239. DoFile:=true;
  240. end;
  241. procedure Usage;
  242. begin
  243. writeln('h2paspp [options] <file(s)>');
  244. writeln('options:');
  245. writeln(' -d<symbol> define symbol');
  246. writeln(' -o<outfile> output file');
  247. writeln(' -i include also includes (default is to remove)');
  248. writeln(' -h or -? this helpscreen');
  249. halt(0);
  250. end;
  251. var
  252. i,j : longint;
  253. s : string;
  254. begin
  255. { process options }
  256. j:=0;
  257. for i:=1to paramcount do
  258. begin
  259. s:=paramstr(i);
  260. if s[1]='-' then
  261. begin
  262. case s[2] of
  263. 'd' :
  264. def_symbol(Copy(s,3,255));
  265. 'o' :
  266. outfile:=Copy(s,3,255);
  267. 'h','?' :
  268. Usage;
  269. end;
  270. end
  271. else
  272. inc(j);
  273. end;
  274. { no files? }
  275. if j=0 then
  276. Usage;
  277. { process files }
  278. for i:=1to paramcount do
  279. begin
  280. s:=paramstr(i);
  281. if s[1]<>'-' then
  282. dofile(s);
  283. end;
  284. end.