h2pout.pp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547
  1. unit h2pout;
  2. {$modeswitch result}
  3. interface
  4. uses
  5. SysUtils, classes,
  6. h2poptions, h2pconst,h2plexlib,h2pyacclib, scanbase,h2ptypes;
  7. procedure OpenOutputFiles;
  8. procedure CloseTempFiles;
  9. procedure WriteFileHeader(var headerfile: Text);
  10. procedure WriteLibraryInitialization;
  11. // This will write each pointer type only once.
  12. function WritePointerTypeDef(var aFile : text; const PN,TN : AnsiString) : Boolean;
  13. procedure write_statement_block(var outfile:text; p : presobject);
  14. procedure write_type_specifier(var outfile:text; p : presobject);
  15. procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
  16. procedure write_ifexpr(var outfile:text; p : presobject);
  17. procedure write_funexpr(var outfile:text; p : presobject);
  18. procedure write_def_params(var outfile:text; p : presobject);
  19. procedure write_args(var outfile:text; p : presobject);
  20. procedure write_packed_fields_info(var outfile:text; p : presobject; ph : string);
  21. procedure write_expr(var outfile:text; p : presobject);
  22. procedure emitignoreconst;
  23. procedure emitignore(p : presobject);
  24. procedure emitignoredefault(p : presobject);
  25. procedure EmitAbstractIgnored;
  26. procedure EmitWriteln(S : string);
  27. procedure EmitPacked(aPack : integer);
  28. procedure EmitAndOutput(S : string; aLine : integer);
  29. procedure EmitErrorStart(S : string);
  30. procedure shift(space_number : byte);
  31. procedure popshift;
  32. procedure resetshift;
  33. function str(i : longint) : string;
  34. function hexstr(i : cardinal) : string;
  35. function uppercase(s : string) : string;
  36. function PointerName(const s:string):string;
  37. function IsACType(const s : String) : Boolean;
  38. function NeedEllipsisOverload : Boolean;
  39. function TypeName(const s:string):string;
  40. Var
  41. No_pop : boolean;
  42. implemfile : text; (* file for implementation headers extern procs *)
  43. in_args : boolean = false;
  44. old_in_args : boolean = false;
  45. must_write_packed_field : boolean;
  46. is_procvar : boolean = false;
  47. is_packed : boolean = false;
  48. if_nb : longint = 0;
  49. implementation
  50. var
  51. WrittenPointers : TStringList;
  52. tempfile : text;
  53. space_array : array [0..255] of integer;
  54. space_index : integer;
  55. _NeedEllipsisOverload : boolean;
  56. typedef_level : longint = 0;
  57. procedure EmitAndOutput(S : string; aLine : integer);
  58. begin
  59. if yydebug then
  60. begin
  61. writeln(S,line_no);
  62. writeln(outfile,'(* ',S,' *)');
  63. end;
  64. end;
  65. procedure EmitErrorStart(S : string);
  66. begin
  67. writeln(outfile,'(* error ');
  68. writeln(outfile,s);
  69. end;
  70. procedure EmitWriteln(S : string);
  71. begin
  72. Writeln(outfile,S);
  73. end;
  74. procedure EmitPacked(aPack: integer);
  75. var
  76. newpacked : boolean;
  77. begin
  78. newpacked:=(aPack<>4);
  79. if (newpacked<>is_packed) and (not packrecords) then
  80. writeln(outfile,'{$PACKRECORDS ',aPack,'}');
  81. is_packed:=newpacked;
  82. end;
  83. procedure emitignoredefault(p : presobject);
  84. begin
  85. if not stripinfo then
  86. writeln(outfile,'(* Warning : default value for ',p^.p,' ignored *)');
  87. end;
  88. procedure EmitAbstractIgnored;
  89. begin
  90. if not stripinfo then
  91. writeln(outfile,'(* Const before abstract_declarator ignored *)');
  92. end;
  93. procedure emitignore(p : presobject);
  94. begin
  95. if not stripinfo then
  96. writeln(outfile,aktspace,'(* ',p^.p,' ignored *)');
  97. end;
  98. procedure emitignoreconst;
  99. begin
  100. if not stripinfo then
  101. writeln(outfile,'(* Const before declarator ignored *)');
  102. end;
  103. function NeedEllipsisOverload : Boolean;
  104. begin
  105. NeedEllipsisOverload:=_NeedEllipsisOverload
  106. end;
  107. procedure shift(space_number : byte);
  108. var
  109. i : byte;
  110. begin
  111. space_array[space_index]:=space_number;
  112. inc(space_index);
  113. for i:=1 to space_number do
  114. aktspace:=aktspace+' ';
  115. end;
  116. procedure popshift;
  117. begin
  118. dec(space_index);
  119. if space_index<0 then
  120. begin
  121. Writeln('Warning: atempt to decrease index below zero');
  122. space_index:=1;
  123. end
  124. else
  125. delete(aktspace,1,space_array[space_index]);
  126. end;
  127. procedure resetshift;
  128. begin
  129. space_index:=1;
  130. end;
  131. function str(i : longint) : string;
  132. var
  133. s : string;
  134. begin
  135. system.str(i,s);
  136. str:=s;
  137. end;
  138. function hexstr(i : cardinal) : string;
  139. const
  140. HexTbl : array[0..15] of char='0123456789ABCDEF';
  141. var
  142. str : string;
  143. begin
  144. str:='';
  145. while i<>0 do
  146. begin
  147. str:=hextbl[i and $F]+str;
  148. i:=i shr 4;
  149. end;
  150. if str='' then str:='0';
  151. hexstr:='$'+str;
  152. end;
  153. function uppercase(s : string) : string;
  154. var
  155. i : byte;
  156. begin
  157. for i:=1 to length(s) do
  158. s[i]:=UpCase(s[i]);
  159. uppercase:=s;
  160. end;
  161. { This converts pascal reserved words to
  162. the correct syntax.
  163. }
  164. function FixId(const s:string):string;
  165. const
  166. maxtokens = 17;
  167. reservedid: array[1..maxtokens] of string[14] = (
  168. 'CLASS',
  169. 'DISPOSE',
  170. 'FUNCTION',
  171. 'FALSE',
  172. 'LABEL',
  173. 'NEW',
  174. 'OUT',
  175. 'PROPERTY',
  176. 'PROCEDURE',
  177. 'RECORD',
  178. 'REPEAT',
  179. 'STRING',
  180. 'TYPE',
  181. 'TRUE',
  182. 'UNTIL',
  183. 'VAR',
  184. 'OBJECT'
  185. );
  186. var
  187. b : boolean;
  188. up : string;
  189. i: integer;
  190. begin
  191. if s='' then
  192. begin
  193. FixId:='';
  194. exit;
  195. end;
  196. b:=false;
  197. up:=Uppercase(s);
  198. for i:=1 to maxtokens do
  199. begin
  200. if up=reservedid[i] then
  201. begin
  202. b:=true;
  203. break;
  204. end;
  205. end;
  206. if b then
  207. FixId:='_'+s
  208. else
  209. FixId:=s;
  210. end;
  211. function TypeName(const s:string):string;
  212. var
  213. i : longint;
  214. begin
  215. i:=1;
  216. if RemoveUnderScore and (length(s)>1) and (s[1]='_') then
  217. i:=2;
  218. if PrependTypes then
  219. TypeName:='T'+Copy(s,i,255)
  220. else
  221. TypeName:=Copy(s,i,255);
  222. end;
  223. function IsACType(const s : String) : Boolean;
  224. var i : Integer;
  225. begin
  226. IsACType := True;
  227. for i := 0 to MAX_CTYPESARRAY do
  228. begin
  229. if s = CTypesArray[i] then
  230. Exit;
  231. end;
  232. IsACType := False;
  233. end;
  234. function PointerName(const s:string):string;
  235. var
  236. i : longint;
  237. begin
  238. if UseCTypesUnit then
  239. begin
  240. if IsACType(s) then
  241. begin
  242. PointerName := 'p'+s;
  243. exit;
  244. end;
  245. end;
  246. i:=1;
  247. if RemoveUnderScore and (length(s)>1) and (s[1]='_') then
  248. i:=2;
  249. if UsePPointers then
  250. begin
  251. PointerName:='P'+Copy(s,i,255);
  252. PTypeList.Add(PointerName);
  253. end
  254. else
  255. PointerName:=Copy(s,i,255);
  256. if PointerPrefix then
  257. PTypeList.Add('P'+s);
  258. end;
  259. Function IsVarPara(P : presobject) : Boolean;
  260. var
  261. varpara: boolean;
  262. begin
  263. varpara:=usevarparas and
  264. assigned(p^.p1^.p1) and
  265. (p^.p1^.p1^.typ in [t_addrdef,t_pointerdef]) and
  266. assigned(p^.p1^.p1^.p1) and
  267. (p^.p1^.p1^.p1^.typ<>t_procdef);
  268. (* do not do it for char pointer !! *)
  269. (* para : pchar; and var para : char; are *)
  270. (* completely different in pascal *)
  271. (* here we exclude all typename containing char *)
  272. (* is this a good method ?? *)
  273. if varpara and
  274. (p^.p1^.p1^.typ=t_pointerdef) and
  275. (((p^.p1^.p1^.p1^.typ=t_id) and
  276. (pos('CHAR',uppercase(p^.p1^.p1^.p1^.str))<>0)) or
  277. ((p^.p1^.p1^.p1^.typ=t_void))
  278. ) then
  279. varpara:=false;
  280. IsVarPara:=varpara;
  281. end;
  282. procedure write_packed_fields_info(var outfile:text; p : presobject; ph : string);
  283. var
  284. hp1,hp2,hp3 : presobject;
  285. is_sized : boolean;
  286. line : string;
  287. flag_index : longint;
  288. name : pansichar;
  289. ps : byte;
  290. begin
  291. { write out the tempfile created }
  292. close(tempfile);
  293. reset(tempfile);
  294. is_sized:=false;
  295. flag_index:=0;
  296. writeln(outfile);
  297. writeln(outfile,aktspace,'const');
  298. shift(2);
  299. while not eof(tempfile) do
  300. begin
  301. readln(tempfile,line);
  302. ps:=pos('&',line);
  303. if ps>0 then
  304. line:=copy(line,1,ps-1)+ph+'_'+copy(line,ps+1,255);
  305. writeln(outfile,aktspace,line);
  306. end;
  307. writeln(outfile);
  308. close(tempfile);
  309. rewrite(tempfile);
  310. popshift;
  311. (* walk through all members *)
  312. hp1 := p^.p1;
  313. while assigned(hp1) do
  314. begin
  315. (* hp2 is t_memberdec *)
  316. hp2:=hp1^.p1;
  317. (* hp3 is t_declist *)
  318. hp3:=hp2^.p2;
  319. while assigned(hp3) do
  320. begin
  321. if assigned(hp3^.p1^.p3) and
  322. (hp3^.p1^.p3^.typ = t_size_specifier) then
  323. begin
  324. is_sized:=true;
  325. name:=hp3^.p1^.p2^.p;
  326. { get function in interface }
  327. write(outfile,aktspace,'function ',name);
  328. write(outfile,'(var a : ',ph,') : ');
  329. shift(2);
  330. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  331. writeln(outfile,';');
  332. popshift;
  333. { get function in implementation }
  334. write(implemfile,aktspace,'function ',name);
  335. write(implemfile,'(var a : ',ph,') : ');
  336. if not compactmode then
  337. shift(2);
  338. write_p_a_def(implemfile,hp3^.p1^.p1,hp2^.p1);
  339. writeln(implemfile,';');
  340. writeln(implemfile,aktspace,'begin');
  341. shift(2);
  342. write(implemfile,aktspace,name,':=(a.flag',flag_index);
  343. writeln(implemfile,' and bm_',ph,'_',name,') shr bp_',ph,'_',name,';');
  344. popshift;
  345. writeln(implemfile,aktspace,'end;');
  346. if not compactmode then
  347. popshift;
  348. writeln(implemfile,'');
  349. { set function in interface }
  350. write(outfile,aktspace,'procedure set_',name);
  351. write(outfile,'(var a : ',ph,'; __',name,' : ');
  352. shift(2);
  353. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  354. writeln(outfile,');');
  355. popshift;
  356. { set function in implementation }
  357. write(implemfile,aktspace,'procedure set_',name);
  358. write(implemfile,'(var a : ',ph,'; __',name,' : ');
  359. if not compactmode then
  360. shift(2);
  361. write_p_a_def(implemfile,hp3^.p1^.p1,hp2^.p1);
  362. writeln(implemfile,');');
  363. writeln(implemfile,aktspace,'begin');
  364. shift(2);
  365. write(implemfile,aktspace,'a.flag',flag_index,':=');
  366. write(implemfile,'a.flag',flag_index,' or ');
  367. writeln(implemfile,'((__',name,' shl bp_',ph,'_',name,') and bm_',ph,'_',name,');');
  368. popshift;
  369. writeln(implemfile,aktspace,'end;');
  370. if not compactmode then
  371. popshift;
  372. writeln(implemfile,'');
  373. end
  374. else if is_sized then
  375. begin
  376. is_sized:=false;
  377. inc(flag_index);
  378. end;
  379. hp3:=hp3^.next;
  380. end;
  381. hp1:=hp1^.next;
  382. end;
  383. must_write_packed_field:=false;
  384. block_type:=bt_no;
  385. end;
  386. procedure write_expr(var outfile:text; p : presobject);
  387. var
  388. DoFlush:Boolean;
  389. begin
  390. if Not assigned(p) then
  391. begin
  392. writeln('Warning: attempt to write empty expression');
  393. exit;
  394. end;
  395. DoFlush:=True;
  396. case p^.typ of
  397. t_id,
  398. t_ifexpr :
  399. write(outfile,FixId(p^.p));
  400. t_funexprlist :
  401. write_funexpr(outfile,p);
  402. t_exprlist:
  403. begin
  404. if assigned(p^.p1) then
  405. write_expr(outfile,p^.p1);
  406. if assigned(p^.next) then
  407. begin
  408. write(', ');
  409. write_expr(outfile,p^.next);
  410. end;
  411. DoFlush:=False;
  412. end;
  413. t_preop:
  414. begin
  415. write(outfile,p^.p,'(');
  416. write_expr(outfile,p^.p1);
  417. write(outfile,')');
  418. end;
  419. t_typespec :
  420. begin
  421. write_type_specifier(outfile,p^.p1);
  422. write(outfile,'(');
  423. write_expr(outfile,p^.p2);
  424. write(outfile,')');
  425. end;
  426. t_bop :
  427. begin
  428. if p^.p1^.typ<>t_id then
  429. write(outfile,'(');
  430. write_expr(outfile,p^.p1);
  431. if p^.p1^.typ<>t_id then
  432. write(outfile,')');
  433. write(outfile,p^.p);
  434. if p^.p2^.typ<>t_id then
  435. write(outfile,'(');
  436. write_expr(outfile,p^.p2);
  437. if p^.p2^.typ<>t_id then
  438. write(outfile,')');
  439. end;
  440. t_arrayop :
  441. begin
  442. write_expr(outfile,p^.p1);
  443. write(outfile,p^.p,'[');
  444. write_expr(outfile,p^.p2);
  445. write(outfile,']');
  446. end;
  447. t_callop :
  448. begin
  449. write_expr(outfile,p^.p1);
  450. write(outfile,p^.p,'(');
  451. write_expr(outfile,p^.p2);
  452. write(outfile,')');
  453. end;
  454. else
  455. writeln(ord(p^.typ));
  456. internalerror(2);
  457. doFlush:=False;
  458. end;
  459. if DoFlush then
  460. Flush(OutFile);
  461. end;
  462. procedure write_ifexpr(var outfile:text; p : presobject);
  463. begin
  464. flush(outfile);
  465. write(outfile,'if ');
  466. write_expr(outfile,p^.p1);
  467. writeln(outfile,' then');
  468. write(outfile,aktspace,' ');
  469. write(outfile,p^.p);
  470. write(outfile,':=');
  471. write_expr(outfile,p^.p2);
  472. writeln(outfile);
  473. writeln(outfile,aktspace,'else');
  474. write(outfile,aktspace,' ');
  475. write(outfile,p^.p);
  476. write(outfile,':=');
  477. write_expr(outfile,p^.p3);
  478. writeln(outfile,';');
  479. write(outfile,aktspace);
  480. flush(outfile);
  481. end;
  482. procedure write_all_ifexpr(var outfile:text; p : presobject);
  483. begin
  484. if not assigned(p) then
  485. begin
  486. Writeln('Warning: writing empty ifexpr');
  487. exit;
  488. end;
  489. case p^.typ of
  490. t_id :;
  491. t_preop :
  492. write_all_ifexpr(outfile,p^.p1);
  493. t_callop,
  494. t_arrayop,
  495. t_bop :
  496. begin
  497. write_all_ifexpr(outfile,p^.p1);
  498. write_all_ifexpr(outfile,p^.p2);
  499. end;
  500. t_ifexpr :
  501. begin
  502. write_all_ifexpr(outfile,p^.p1);
  503. write_all_ifexpr(outfile,p^.p2);
  504. write_all_ifexpr(outfile,p^.p3);
  505. write_ifexpr(outfile,p);
  506. end;
  507. t_typespec :
  508. write_all_ifexpr(outfile,p^.p2);
  509. t_funexprlist,
  510. t_exprlist :
  511. begin
  512. if assigned(p^.p1) then
  513. write_all_ifexpr(outfile,p^.p1);
  514. if assigned(p^.next) then
  515. write_all_ifexpr(outfile,p^.next);
  516. end
  517. else
  518. internalerror(6);
  519. end;
  520. end;
  521. procedure write_funexpr(var outfile:text; p : presobject);
  522. var
  523. i : longint;
  524. begin
  525. if not assigned(p) then
  526. begin
  527. Writeln('Warning: attempt to write empty function expression');
  528. exit;
  529. end;
  530. case p^.typ of
  531. t_ifexpr :
  532. write(outfile,p^.p);
  533. t_exprlist :
  534. begin
  535. write_expr(outfile,p^.p1);
  536. if assigned(p^.next) then
  537. begin
  538. write(outfile,',');
  539. write_funexpr(outfile,p^.next);
  540. end
  541. end;
  542. t_funcname :
  543. begin
  544. if if_nb>0 then
  545. begin
  546. writeln(outfile,aktspace,'var');
  547. write(outfile,aktspace,' ');
  548. for i:=1 to if_nb do
  549. begin
  550. write(outfile,'if_local',i);
  551. if i<if_nb then
  552. write(outfile,', ')
  553. else
  554. writeln(outfile,' : longint;');
  555. end;
  556. writeln(outfile,aktspace,'(* result types are not known *)');
  557. if_nb:=0;
  558. end;
  559. writeln(outfile,aktspace,'begin');
  560. shift(2);
  561. write(outfile,aktspace);
  562. write_all_ifexpr(outfile,p^.p2);
  563. write_expr(outfile,p^.p1);
  564. write(outfile,':=');
  565. write_funexpr(outfile,p^.p2);
  566. writeln(outfile,';');
  567. popshift;
  568. writeln(outfile,aktspace,'end;');
  569. if not compactmode then
  570. popshift;
  571. flush(outfile);
  572. end;
  573. t_funexprlist :
  574. begin
  575. if assigned(p^.p3) then
  576. begin
  577. write_type_specifier(outfile,p^.p3);
  578. write(outfile,'(');
  579. end;
  580. if assigned(p^.p1) then
  581. write_funexpr(outfile,p^.p1);
  582. if assigned(p^.p2) then
  583. begin
  584. write(outfile,'(');
  585. write_funexpr(outfile,p^.p2);
  586. write(outfile,')');
  587. end;
  588. if assigned(p^.p3) then
  589. write(outfile,')');
  590. end
  591. else
  592. internalerror(5);
  593. end;
  594. end;
  595. procedure write_args(var outfile:text; p : presobject);
  596. var
  597. len,para : longint;
  598. old_in_args : boolean;
  599. varpara : boolean;
  600. lastp : presobject;
  601. hs : string;
  602. begin
  603. _NeedEllipsisOverload:=false;
  604. para:=1;
  605. len:=0;
  606. lastp:=nil;
  607. old_in_args:=in_args;
  608. in_args:=true;
  609. write(outfile,'(');
  610. shift(2);
  611. (* walk through all arguments *)
  612. (* p must be of type t_arglist *)
  613. while assigned(p) do
  614. begin
  615. if p^.typ<>t_arglist then
  616. internalerror(10);
  617. (* is ellipsis ? *)
  618. if not assigned(p^.p1^.p1) and not assigned(p^.p1^.next) then
  619. begin
  620. write(outfile,'args:array of const');
  621. (* if variable number of args we must allways pop *)
  622. no_pop:=false;
  623. (* Needs 2 declarations, also one without args, becuase
  624. in C you can omit the second parameter. Default parameter
  625. doesn't help as that isn't possible with array of const *)
  626. _NeedEllipsisOverload:=true;
  627. (* Remove this para *)
  628. if assigned(lastp) then
  629. lastp^.next:=nil;
  630. dispose(p,done);
  631. (* leave the loop as p isnot valid anymore *)
  632. break;
  633. end
  634. (* we need to correct this in the pp file after *)
  635. else
  636. begin
  637. (* generate a call by reference parameter ? *)
  638. varpara:=IsVarPara(p);
  639. if varpara then
  640. begin
  641. write(outfile,'var ');
  642. inc(len,4);
  643. end;
  644. (* write new parameter name *)
  645. if assigned(p^.p1^.p2^.p2) then
  646. begin
  647. hs:=FixId(p^.p1^.p2^.p2^.p);
  648. write(outfile,hs);
  649. inc(len,length(hs));
  650. end
  651. else
  652. begin
  653. If removeUnderscore then
  654. begin
  655. Write (outfile,'para',para);
  656. inc(Len,5);
  657. end
  658. else
  659. begin
  660. write(outfile,'_para',para);
  661. inc(Len,6);
  662. end;
  663. end;
  664. write(outfile,':');
  665. if varpara then
  666. begin
  667. write_p_a_def(outfile,p^.p1^.p2^.p1,p^.p1^.p1^.p1);
  668. end
  669. else
  670. write_p_a_def(outfile,p^.p1^.p2^.p1,p^.p1^.p1);
  671. end;
  672. lastp:=p;
  673. p:=p^.next;
  674. if assigned(p) then
  675. begin
  676. write(outfile,'; ');
  677. { if len>40 then : too complicated to compute }
  678. if (para mod 5) = 0 then
  679. begin
  680. writeln(outfile);
  681. write(outfile,aktspace);
  682. end;
  683. end;
  684. inc(para);
  685. end;
  686. write(outfile,')');
  687. flush(outfile);
  688. in_args:=old_in_args;
  689. popshift;
  690. end;
  691. Procedure write_pointerdef(var outfile:text; p,simple_type : presobject);
  692. var
  693. pointerwritten : Boolean;
  694. begin
  695. (* procedure variable ? *)
  696. if assigned(p^.p1) and (p^.p1^.typ=t_procdef) then
  697. begin
  698. is_procvar:=true;
  699. (* distinguish between procedure and function *)
  700. if (simple_type^.typ=t_void) and (p^.p1^.p1=nil) then
  701. begin
  702. write(outfile,'procedure ');
  703. shift(10);
  704. (* write arguments *)
  705. if assigned(p^.p1^.p2) then
  706. write_args(outfile,p^.p1^.p2);
  707. flush(outfile);
  708. popshift;
  709. end
  710. else
  711. begin
  712. write(outfile,'function ');
  713. shift(9);
  714. (* write arguments *)
  715. if assigned(p^.p1^.p2) then
  716. write_args(outfile,p^.p1^.p2);
  717. write(outfile,':');
  718. flush(outfile);
  719. old_in_args:=in_args;
  720. (* write pointers as P.... instead of ^.... *)
  721. in_args:=true;
  722. write_p_a_def(outfile,p^.p1^.p1,simple_type);
  723. in_args:=old_in_args;
  724. popshift;
  725. end
  726. end
  727. else
  728. begin
  729. (* generate "pointer" ? *)
  730. if (simple_type^.typ=t_void) and (p^.p1=nil) then
  731. begin
  732. write(outfile,'pointer');
  733. flush(outfile);
  734. end
  735. else
  736. begin
  737. pointerwritten:=false;
  738. if (p^.p1=nil) and UsePPointers then
  739. begin
  740. if (simple_type^.typ=t_id) then
  741. begin
  742. write(outfile,PointerName(simple_type^.p));
  743. pointerwritten:=true;
  744. end
  745. { structure }
  746. else if (simple_type^.typ in [t_uniondef,t_structdef]) and
  747. (simple_type^.p1=nil) and (simple_type^.p2^.typ=t_id) then
  748. begin
  749. write(outfile,PointerName(simple_type^.p2^.p));
  750. pointerwritten:=true;
  751. end;
  752. end;
  753. if not pointerwritten then
  754. begin
  755. if in_args then
  756. begin
  757. write(outfile,'P');
  758. pointerprefix:=true;
  759. end
  760. else
  761. write(outfile,'^');
  762. write_p_a_def(outfile,p^.p1,simple_type);
  763. pointerprefix:=false;
  764. end;
  765. end;
  766. end;
  767. end;
  768. Procedure write_arraydef(var outfile:text; p,simple_type : presobject);
  769. var
  770. constant : boolean;
  771. i, error : integer;
  772. begin
  773. constant:=false;
  774. if assigned(p^.p2) then
  775. begin
  776. if p^.p2^.typ=t_id then
  777. begin
  778. val(p^.p2^.str,i,error);
  779. if error=0 then
  780. begin
  781. dec(i);
  782. constant:=true;
  783. end;
  784. end;
  785. if not constant then
  786. begin
  787. write(outfile,'array[0..(');
  788. write_expr(outfile,p^.p2);
  789. write(outfile,')-1] of ');
  790. end
  791. else
  792. write(outfile,'array[0..',i,'] of ');
  793. end
  794. else
  795. begin
  796. (* open array *)
  797. write(outfile,'array of ');
  798. end;
  799. flush(outfile);
  800. write_p_a_def(outfile,p^.p1,simple_type);
  801. end;
  802. procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
  803. begin
  804. if not(assigned(p)) then
  805. begin
  806. write_type_specifier(outfile,simple_type);
  807. exit;
  808. end;
  809. case p^.typ of
  810. t_pointerdef :
  811. Write_pointerdef(outfile,p,simple_type);
  812. t_arraydef :
  813. Write_arraydef(outfile,p,simple_type);
  814. else
  815. internalerror(1);
  816. end;
  817. end;
  818. procedure write_type_specifier_id(var outfile:text; p : presobject);
  819. begin
  820. if pointerprefix then
  821. if UseCtypesUnit then
  822. begin
  823. if not IsACType(p^.p) then
  824. begin
  825. PTypeList.Add('P'+p^.str);
  826. end;
  827. end
  828. else
  829. begin
  830. PTypeList.Add('P'+p^.str);
  831. end;
  832. if p^.skiptprefix then
  833. write(outfile,p^.p)
  834. else
  835. write(outfile,TypeName(p^.p));
  836. end;
  837. procedure write_type_specifier_pointer(var outfile:text; p : presobject);
  838. var
  839. pointerwritten : Boolean;
  840. begin
  841. pointerwritten:=false;
  842. if (p^.p1^.typ=t_void) then
  843. begin
  844. write(outfile,'pointer');
  845. pointerwritten:=true;
  846. end
  847. else if UsePPointers then
  848. begin
  849. if (p^.p1^.typ=t_id) then
  850. begin
  851. write(outfile,PointerName(p^.p1^.p));
  852. pointerwritten:=true;
  853. end
  854. { structure }
  855. else if (p^.p1^.typ in [t_uniondef,t_structdef]) and
  856. (p^.p1^.p1=nil) and (p^.p1^.p2^.typ=t_id) then
  857. begin
  858. write(outfile,PointerName(p^.p1^.p2^.p));
  859. pointerwritten:=true;
  860. end;
  861. end;
  862. if not pointerwritten then
  863. begin
  864. if in_args then
  865. begin
  866. if UseCTypesUnit and IsACType(p^.p1^.p) then
  867. write(outfile,'p')
  868. else
  869. write(outfile,'P');
  870. pointerprefix:=true;
  871. end
  872. else
  873. begin
  874. if UseCTypesUnit and (IsACType(p^.p1^.p)=False) then
  875. write(outfile,'^')
  876. else
  877. write(outfile,'p');
  878. end;
  879. write_type_specifier(outfile,p^.p1);
  880. pointerprefix:=false;
  881. end;
  882. end;
  883. procedure write_enum_const(var outfile:text; hp1 : presobject; var lastexpr : presobject; var l : longint);
  884. var
  885. error : integer;
  886. begin
  887. write(outfile,aktspace,hp1^.p1^.p,' = ');
  888. if assigned(hp1^.p2) then
  889. begin
  890. write_expr(outfile,hp1^.p2);
  891. writeln(outfile,';');
  892. lastexpr:=hp1^.p2;
  893. if lastexpr^.typ=t_id then
  894. begin
  895. val(lastexpr^.str,l,error);
  896. if error=0 then
  897. begin
  898. inc(l);
  899. lastexpr:=nil;
  900. end
  901. else
  902. l:=1;
  903. end
  904. else
  905. l:=1;
  906. end
  907. else
  908. begin
  909. if assigned(lastexpr) then
  910. begin
  911. write(outfile,'(');
  912. write_expr(outfile,lastexpr);
  913. writeln(outfile,')+',l,';');
  914. end
  915. else
  916. writeln (outfile,l,';');
  917. inc(l);
  918. end;
  919. end;
  920. procedure write_type_specifier_enum(var outfile:text; p : presobject);
  921. var
  922. hp1,lastexpr : presobject;
  923. l,w : longint;
  924. begin
  925. if (typedef_level>1) and (p^.p1=nil) and (p^.p2^.typ=t_id) then
  926. begin
  927. if pointerprefix then
  928. if UseCTypesUnit and (IsACType( p^.p2^.p )=False) then
  929. PTypeList.Add('P'+p^.p2^.str);
  930. write(outfile,p^.p2^.p);
  931. end
  932. else if not EnumToConst then
  933. begin
  934. write(outfile,'(');
  935. hp1:=p^.p1;
  936. w:=length(aktspace);
  937. while assigned(hp1) do
  938. begin
  939. write(outfile,hp1^.p1^.p);
  940. if assigned(hp1^.p2) then
  941. begin
  942. write(outfile,' := ');
  943. write_expr(outfile,hp1^.p2);
  944. w:=w+6;(* strlen(hp1^.p); *)
  945. end;
  946. w:=w+length(hp1^.p1^.str);
  947. hp1:=hp1^.next;
  948. if assigned(hp1) then
  949. write(outfile,',');
  950. if w>40 then
  951. begin
  952. writeln(outfile);
  953. write(outfile,aktspace);
  954. w:=length(aktspace);
  955. end;
  956. flush(outfile);
  957. end;
  958. write(outfile,')');
  959. flush(outfile);
  960. end
  961. else
  962. begin
  963. Writeln (outfile,' Longint;');
  964. hp1:=p^.p1;
  965. lastexpr:=nil;
  966. l:=0;
  967. Writeln (outfile,copy(aktspace,1,length(aktspace)-2),'Const');
  968. while assigned(hp1) do
  969. begin
  970. write_enum_const(outfile,hp1,lastexpr,l);
  971. hp1:=hp1^.next;
  972. flush(outfile);
  973. end;
  974. block_type:=bt_const;
  975. end;
  976. end;
  977. procedure write_type_specifier_struct(var outfile:text; p : presobject);
  978. var
  979. hp1,hp2,hp3 : presobject;
  980. i,l : longint;
  981. error : integer;
  982. current_power,
  983. mask : cardinal;
  984. flag_index : longint;
  985. current_level : byte;
  986. is_sized : boolean;
  987. begin
  988. inc(typedef_level);
  989. flag_index:=-1;
  990. is_sized:=false;
  991. current_level:=0;
  992. if ((in_args) or (typedef_level>1)) and (p^.p1=nil) and (p^.p2^.typ=t_id) then
  993. begin
  994. if pointerprefix then
  995. if UseCTypesUnit and (IsACType(p^.p2^.str)=false) then
  996. PTypeList.Add('P'+p^.p2^.str);
  997. write(outfile,TypeName(p^.p2^.p));
  998. end
  999. else
  1000. begin
  1001. if packrecords then
  1002. writeln(outfile,'packed record')
  1003. else
  1004. writeln(outfile,'record');
  1005. shift(2);
  1006. hp1:=p^.p1;
  1007. (* walk through all members *)
  1008. while assigned(hp1) do
  1009. begin
  1010. (* hp2 is t_memberdec *)
  1011. hp2:=hp1^.p1;
  1012. (* hp3 is t_declist *)
  1013. hp3:=hp2^.p2;
  1014. while assigned(hp3) do
  1015. begin
  1016. if assigned(hp3^.p1) and
  1017. (not assigned(hp3^.p1^.p3) or
  1018. (hp3^.p1^.p3^.typ <> t_size_specifier)) then
  1019. begin
  1020. if is_sized then
  1021. begin
  1022. if current_level <= 16 then
  1023. writeln(outfile,'word;')
  1024. else if current_level <= 32 then
  1025. writeln(outfile,'longint;')
  1026. else
  1027. internalerror(11);
  1028. is_sized:=false;
  1029. end;
  1030. write(outfile,aktspace,FixId(hp3^.p1^.p2^.p));
  1031. write(outfile,' : ');
  1032. shift(2);
  1033. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  1034. popshift;
  1035. end;
  1036. { size specifier or default value ? }
  1037. if assigned(hp3^.p1) and
  1038. assigned(hp3^.p1^.p3) then
  1039. begin
  1040. { we could use mask to implement this }
  1041. { because we need to respect the positions }
  1042. if hp3^.p1^.p3^.typ = t_size_specifier then
  1043. begin
  1044. if not is_sized then
  1045. begin
  1046. current_power:=1;
  1047. current_level:=0;
  1048. inc(flag_index);
  1049. write(outfile,aktspace,'flag',flag_index,' : ');
  1050. end;
  1051. must_write_packed_field:=true;
  1052. is_sized:=true;
  1053. { can it be something else than a constant ? }
  1054. { it can be a macro !! }
  1055. if hp3^.p1^.p3^.p1^.typ=t_id then
  1056. begin
  1057. val(hp3^.p1^.p3^.p1^.str,l,error);
  1058. if error=0 then
  1059. begin
  1060. mask:=0;
  1061. for i:=1 to l do
  1062. begin
  1063. inc(mask,current_power);
  1064. current_power:=current_power*2;
  1065. end;
  1066. write(tempfile,'bm_&',hp3^.p1^.p2^.p);
  1067. writeln(tempfile,' = ',hexstr(mask),';');
  1068. write(tempfile,'bp_&',hp3^.p1^.p2^.p);
  1069. writeln(tempfile,' = ',current_level,';');
  1070. current_level:=current_level + l;
  1071. { go to next flag if 31 }
  1072. if current_level = 32 then
  1073. begin
  1074. write(outfile,'longint');
  1075. is_sized:=false;
  1076. end;
  1077. end;
  1078. end;
  1079. end
  1080. else if hp3^.p1^.p3^.typ = t_default_value then
  1081. begin
  1082. write(outfile,'{=');
  1083. write_expr(outfile,hp3^.p1^.p3^.p1);
  1084. write(outfile,' ignored}');
  1085. end;
  1086. end;
  1087. if not is_sized then
  1088. begin
  1089. if is_procvar then
  1090. begin
  1091. if not no_pop then
  1092. write(outfile,';cdecl');
  1093. is_procvar:=false;
  1094. end;
  1095. writeln(outfile,';');
  1096. end;
  1097. hp3:=hp3^.next;
  1098. end;
  1099. hp1:=hp1^.next;
  1100. end;
  1101. if is_sized then
  1102. begin
  1103. if current_level <= 16 then
  1104. writeln(outfile,'word;')
  1105. else if current_level <= 32 then
  1106. writeln(outfile,'longint;')
  1107. else
  1108. internalerror(11);
  1109. is_sized:=false;
  1110. end;
  1111. popshift;
  1112. write(outfile,aktspace,'end');
  1113. flush(outfile);
  1114. end;
  1115. dec(typedef_level);
  1116. end;
  1117. procedure write_type_specifier_union(var outfile:text; p : presobject);
  1118. var
  1119. hp1,hp2,hp3 : presobject;
  1120. l : integer;
  1121. begin
  1122. inc(typedef_level);
  1123. if (typedef_level>1) and (p^.p1=nil) and (p^.p2^.typ=t_id) then
  1124. begin
  1125. write(outfile,p^.p2^.p);
  1126. end
  1127. else
  1128. begin
  1129. inc(typedef_level);
  1130. if packrecords then
  1131. writeln(outfile,'packed record')
  1132. else
  1133. writeln(outfile,'record');
  1134. shift(2);
  1135. writeln(outfile,aktspace,'case longint of');
  1136. shift(2);
  1137. l:=0;
  1138. hp1:=p^.p1;
  1139. (* walk through all members *)
  1140. while assigned(hp1) do
  1141. begin
  1142. (* hp2 is t_memberdec *)
  1143. hp2:=hp1^.p1;
  1144. (* hp3 is t_declist *)
  1145. hp3:=hp2^.p2;
  1146. while assigned(hp3) do
  1147. begin
  1148. write(outfile,aktspace,l,' : ( ');
  1149. write(outfile,FixId(hp3^.p1^.p2^.p),' : ');
  1150. shift(2);
  1151. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  1152. popshift;
  1153. writeln(outfile,' );');
  1154. hp3:=hp3^.next;
  1155. inc(l);
  1156. end;
  1157. hp1:=hp1^.next;
  1158. end;
  1159. popshift;
  1160. write(outfile,aktspace,'end');
  1161. popshift;
  1162. flush(outfile);
  1163. dec(typedef_level);
  1164. end;
  1165. dec(typedef_level);
  1166. end;
  1167. procedure write_type_specifier(var outfile:text; p : presobject);
  1168. begin
  1169. case p^.typ of
  1170. t_id :
  1171. write_type_specifier_id(outfile,p);
  1172. { what can we do with void defs ? }
  1173. t_void :
  1174. write(outfile,'pointer');
  1175. t_pointerdef :
  1176. Write_type_specifier_pointer(outfile,p);
  1177. t_enumdef :
  1178. Write_type_specifier_enum(outfile,p);
  1179. t_structdef :
  1180. Write_type_specifier_struct(outfile,p);
  1181. t_uniondef :
  1182. Write_type_specifier_union(outfile,p);
  1183. else
  1184. internalerror(3);
  1185. end;
  1186. end;
  1187. procedure write_def_params(var outfile:text; p : presobject);
  1188. var
  1189. hp1 : presobject;
  1190. begin
  1191. case p^.typ of
  1192. t_enumdef:
  1193. begin
  1194. hp1:=p^.p1;
  1195. while assigned(hp1) do
  1196. begin
  1197. write(outfile,FixId(hp1^.p1^.p));
  1198. hp1:=hp1^.next;
  1199. if assigned(hp1) then
  1200. write(outfile,',')
  1201. else
  1202. write(outfile);
  1203. flush(outfile);
  1204. end;
  1205. flush(outfile);
  1206. end;
  1207. else
  1208. internalerror(4);
  1209. end;
  1210. end;
  1211. function MayWritePointerTypeDef(const PN: AnsiString): Boolean;
  1212. begin
  1213. Result:=WrittenPointers.IndexOf(PN)=-1;
  1214. end;
  1215. function WritePointerTypeDef(var aFile : text; const PN, TN: AnsiString): Boolean;
  1216. begin
  1217. Result:=MayWritePointerTypeDef(PN);;
  1218. if Result then
  1219. begin
  1220. WrittenPointers.Add(PN);
  1221. Writeln(aFile,aktspace,PN,' = ^',TN,';');
  1222. end;
  1223. end;
  1224. procedure write_statement_block(var outfile:text; p : presobject);
  1225. begin
  1226. writeln(outfile,aktspace,'begin');
  1227. while assigned(p) do
  1228. begin
  1229. shift(2);
  1230. if assigned(p^.p1) then
  1231. case p^.p1^.typ of
  1232. t_whilenode:
  1233. begin
  1234. write(outfile,aktspace,'while ');
  1235. write_expr(outfile,p^.p1^.p1);
  1236. writeln(outfile,' do');
  1237. shift(2);
  1238. write_statement_block(outfile,p^.p1^.p2);
  1239. popshift;
  1240. end;
  1241. else
  1242. write(outfile,aktspace);
  1243. write_expr(outfile,p^.p1);
  1244. writeln(outfile,';');
  1245. end; // case
  1246. p:=p^.next;
  1247. popshift;
  1248. end;
  1249. writeln(outfile,aktspace,'end;');
  1250. end;
  1251. procedure WritePointerList(var headerfile: Text);
  1252. var
  1253. I : Integer;
  1254. MustWritePointers : Boolean;
  1255. originalstr : String;
  1256. begin
  1257. I:=PTypeList.count-1;
  1258. MustWritePointers:=False;
  1259. While (Not MustWritePointers) and (I>=0) do
  1260. begin
  1261. MustWritePointers:=MayWritePointerTypeDef(PTypelist[i]);
  1262. Dec(I);
  1263. end;
  1264. if not MustWritePointers then
  1265. exit;
  1266. Writeln(headerfile,'Type');
  1267. for i:=0 to (PTypeList.Count-1) do
  1268. begin
  1269. originalstr:=copy(PTypelist[i],2,length(PTypeList[i]));
  1270. if PrependTypes then
  1271. originalstr:='T'+originalstr;
  1272. WritePointerTypeDef(HeaderFile,PTypeList[i],OriginalStr);
  1273. end;
  1274. end;
  1275. procedure WriteFileHeader(var headerfile: Text);
  1276. var
  1277. i: integer;
  1278. originalstr: string;
  1279. begin
  1280. { write unit header }
  1281. if not includefile then
  1282. begin
  1283. if createdynlib then
  1284. writeln(headerfile,'{$mode objfpc}');
  1285. writeln(headerfile,'unit ',unitname,';');
  1286. writeln(headerfile,'interface');
  1287. writeln(headerfile);
  1288. if UseCTypesUnit then
  1289. begin
  1290. writeln(headerfile,'uses');
  1291. writeln(headerfile,' ctypes;');
  1292. writeln(headerfile);
  1293. end;
  1294. writeln(headerfile,'{');
  1295. writeln(headerfile,' Automatically converted by H2Pas ',version,' from ',inputfilename);
  1296. writeln(headerfile,' The following command line parameters were used:');
  1297. for i:=1 to paramcount do
  1298. writeln(headerfile,' ',paramstr(i));
  1299. writeln(headerfile,'}');
  1300. writeln(headerfile);
  1301. end;
  1302. if UseName then
  1303. begin
  1304. writeln(headerfile,'const');
  1305. writeln(headerfile,' External_library=''',libfilename,'''; {Setup as you need}');
  1306. writeln(headerfile);
  1307. end;
  1308. if PTypeList.count <> 0 then
  1309. WritePointerList(headerfile);
  1310. writeln(headerfile);
  1311. if not packrecords then
  1312. begin
  1313. writeln(headerfile,'{$IFDEF FPC}');
  1314. writeln(headerfile,'{$PACKRECORDS C}');
  1315. writeln(headerfile,'{$ENDIF}');
  1316. end;
  1317. writeln(headerfile);
  1318. end;
  1319. procedure OpenOutputFiles;
  1320. begin
  1321. { This is the intermediate output file }
  1322. assign(outfile, 'ext3.tmp');
  1323. {$I-}
  1324. rewrite(outfile);
  1325. {$I+}
  1326. if ioresult<>0 then
  1327. begin
  1328. writeln('file ext3.tmp could not be created!');
  1329. halt(1);
  1330. end;
  1331. writeln(outfile);
  1332. { Open tempfiles }
  1333. { This is where the implementation section of the unit shall be stored }
  1334. Assign(implemfile,'ext.tmp');
  1335. rewrite(implemfile);
  1336. Assign(tempfile,'ext2.tmp');
  1337. rewrite(tempfile);
  1338. end;
  1339. procedure CloseTempFiles;
  1340. begin
  1341. close(implemfile);
  1342. erase(implemfile);
  1343. close(tempfile);
  1344. erase(tempfile);
  1345. end;
  1346. procedure WriteLibraryInitialization;
  1347. var
  1348. I : Integer;
  1349. begin
  1350. writeln(outfile,' uses');
  1351. writeln(outfile,' SysUtils, dynlibs;');
  1352. writeln(outfile);
  1353. writeln(outfile,' var');
  1354. writeln(outfile,' hlib : tlibhandle;');
  1355. writeln(outfile);
  1356. writeln(outfile);
  1357. writeln(outfile,' procedure Free',unitname,';');
  1358. writeln(outfile,' begin');
  1359. writeln(outfile,' FreeLibrary(hlib);');
  1360. for i:=0 to (freedynlibproc.Count-1) do
  1361. Writeln(outfile,' ',freedynlibproc[i]);
  1362. writeln(outfile,' end;');
  1363. writeln(outfile);
  1364. writeln(outfile);
  1365. writeln(outfile,' procedure Load',unitname,'(lib : pchar);');
  1366. writeln(outfile,' begin');
  1367. writeln(outfile,' Free',unitname,';');
  1368. writeln(outfile,' hlib:=LoadLibrary(lib);');
  1369. writeln(outfile,' if hlib=0 then');
  1370. writeln(outfile,' raise Exception.Create(format(''Could not load library: %s'',[lib]));');
  1371. writeln(outfile);
  1372. for i:=0 to (loaddynlibproc.Count-1) do
  1373. Writeln(outfile,' ',loaddynlibproc[i]);
  1374. writeln(outfile,' end;');
  1375. writeln(outfile);
  1376. writeln(outfile);
  1377. writeln(outfile,'initialization');
  1378. writeln(outfile,' Load',unitname,'(''',unitname,''');');
  1379. writeln(outfile,'finalization');
  1380. writeln(outfile,' Free',unitname,';');
  1381. end;
  1382. initialization
  1383. WrittenPointers:=TStringList.Create;
  1384. WrittenPointers.Sorted:=true;
  1385. // We must never write these, they are defined in the system unit
  1386. WrittenPointers.Add('pansichar');
  1387. WrittenPointers.Add('pchar');
  1388. WrittenPointers.Add('pdouble');
  1389. WrittenPointers.Add('plongint');
  1390. WrittenPointers.Add('psmallint');
  1391. WrittenPointers.Add('pshortint');
  1392. WrittenPointers.Add('pbyte');
  1393. WrittenPointers.Add('pint64');
  1394. WrittenPointers.Add('pword');
  1395. WrittenPointers.Add('pqword');
  1396. finalization
  1397. WrittenPointers.Free;
  1398. end.