h2pout.pp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505
  1. unit h2pout;
  2. interface
  3. uses
  4. SysUtils, classes,
  5. h2poptions, h2pconst,h2plexlib,h2pyacclib, scanbase,h2ptypes;
  6. procedure OpenOutputFiles;
  7. procedure CloseTempFiles;
  8. procedure WriteFileHeader(var headerfile: Text);
  9. procedure WriteLibraryInitialization;
  10. procedure write_statement_block(var outfile:text; p : presobject);
  11. procedure write_type_specifier(var outfile:text; p : presobject);
  12. procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
  13. procedure write_ifexpr(var outfile:text; p : presobject);
  14. procedure write_funexpr(var outfile:text; p : presobject);
  15. procedure write_def_params(var outfile:text; p : presobject);
  16. procedure write_args(var outfile:text; p : presobject);
  17. procedure write_packed_fields_info(var outfile:text; p : presobject; ph : string);
  18. procedure write_expr(var outfile:text; p : presobject);
  19. procedure emitignoreconst;
  20. procedure emitignore(p : presobject);
  21. procedure emitignoredefault(p : presobject);
  22. procedure EmitAbstractIgnored;
  23. procedure EmitWriteln(S : string);
  24. procedure EmitPacked(aPack : integer);
  25. procedure EmitAndOutput(S : string; aLine : integer);
  26. procedure EmitErrorStart(S : string);
  27. procedure shift(space_number : byte);
  28. procedure popshift;
  29. procedure resetshift;
  30. function str(i : longint) : string;
  31. function hexstr(i : cardinal) : string;
  32. function uppercase(s : string) : string;
  33. function PointerName(const s:string):string;
  34. function IsACType(const s : String) : Boolean;
  35. function NeedEllipsisOverload : Boolean;
  36. function TypeName(const s:string):string;
  37. Var
  38. No_pop : boolean;
  39. implemfile : text; (* file for implementation headers extern procs *)
  40. in_args : boolean = false;
  41. old_in_args : boolean = false;
  42. must_write_packed_field : boolean;
  43. is_procvar : boolean = false;
  44. is_packed : boolean = false;
  45. if_nb : longint = 0;
  46. implementation
  47. var
  48. tempfile : text;
  49. space_array : array [0..255] of integer;
  50. space_index : integer;
  51. _NeedEllipsisOverload : boolean;
  52. typedef_level : longint = 0;
  53. procedure EmitAndOutput(S : string; aLine : integer);
  54. begin
  55. if yydebug then
  56. begin
  57. writeln(S,line_no);
  58. writeln(outfile,'(* ',S,' *)');
  59. end;
  60. end;
  61. procedure EmitErrorStart(S : string);
  62. begin
  63. writeln(outfile,'(* error ');
  64. writeln(outfile,s);
  65. end;
  66. procedure EmitWriteln(S : string);
  67. begin
  68. Writeln(outfile,S);
  69. end;
  70. procedure EmitPacked(aPack: integer);
  71. var
  72. newpacked : boolean;
  73. begin
  74. newpacked:=(aPack<>4);
  75. if (newpacked<>is_packed) and (not packrecords) then
  76. writeln(outfile,'{$PACKRECORDS ',aPack,'}');
  77. is_packed:=newpacked;
  78. end;
  79. procedure emitignoredefault(p : presobject);
  80. begin
  81. if not stripinfo then
  82. writeln(outfile,'(* Warning : default value for ',p^.p,' ignored *)');
  83. end;
  84. procedure EmitAbstractIgnored;
  85. begin
  86. if not stripinfo then
  87. writeln(outfile,'(* Const before abstract_declarator ignored *)');
  88. end;
  89. procedure emitignore(p : presobject);
  90. begin
  91. if not stripinfo then
  92. writeln(outfile,aktspace,'(* ',p^.p,' ignored *)');
  93. end;
  94. procedure emitignoreconst;
  95. begin
  96. if not stripinfo then
  97. writeln(outfile,'(* Const before declarator ignored *)');
  98. end;
  99. function NeedEllipsisOverload : Boolean;
  100. begin
  101. NeedEllipsisOverload:=_NeedEllipsisOverload
  102. end;
  103. procedure shift(space_number : byte);
  104. var
  105. i : byte;
  106. begin
  107. space_array[space_index]:=space_number;
  108. inc(space_index);
  109. for i:=1 to space_number do
  110. aktspace:=aktspace+' ';
  111. end;
  112. procedure popshift;
  113. begin
  114. dec(space_index);
  115. if space_index<0 then
  116. begin
  117. Writeln('Warning: atempt to decrease index below zero');
  118. space_index:=1;
  119. end
  120. else
  121. delete(aktspace,1,space_array[space_index]);
  122. end;
  123. procedure resetshift;
  124. begin
  125. space_index:=1;
  126. end;
  127. function str(i : longint) : string;
  128. var
  129. s : string;
  130. begin
  131. system.str(i,s);
  132. str:=s;
  133. end;
  134. function hexstr(i : cardinal) : string;
  135. const
  136. HexTbl : array[0..15] of char='0123456789ABCDEF';
  137. var
  138. str : string;
  139. begin
  140. str:='';
  141. while i<>0 do
  142. begin
  143. str:=hextbl[i and $F]+str;
  144. i:=i shr 4;
  145. end;
  146. if str='' then str:='0';
  147. hexstr:='$'+str;
  148. end;
  149. function uppercase(s : string) : string;
  150. var
  151. i : byte;
  152. begin
  153. for i:=1 to length(s) do
  154. s[i]:=UpCase(s[i]);
  155. uppercase:=s;
  156. end;
  157. { This converts pascal reserved words to
  158. the correct syntax.
  159. }
  160. function FixId(const s:string):string;
  161. const
  162. maxtokens = 16;
  163. reservedid: array[1..maxtokens] of string[14] = (
  164. 'CLASS',
  165. 'DISPOSE',
  166. 'FUNCTION',
  167. 'FALSE',
  168. 'LABEL',
  169. 'NEW',
  170. 'OUT',
  171. 'PROPERTY',
  172. 'PROCEDURE',
  173. 'RECORD',
  174. 'REPEAT',
  175. 'STRING',
  176. 'TYPE',
  177. 'TRUE',
  178. 'UNTIL',
  179. 'VAR'
  180. );
  181. var
  182. b : boolean;
  183. up : string;
  184. i: integer;
  185. begin
  186. if s='' then
  187. begin
  188. FixId:='';
  189. exit;
  190. end;
  191. b:=false;
  192. up:=Uppercase(s);
  193. for i:=1 to maxtokens do
  194. begin
  195. if up=reservedid[i] then
  196. begin
  197. b:=true;
  198. break;
  199. end;
  200. end;
  201. if b then
  202. FixId:='_'+s
  203. else
  204. FixId:=s;
  205. end;
  206. function TypeName(const s:string):string;
  207. var
  208. i : longint;
  209. begin
  210. i:=1;
  211. if RemoveUnderScore and (length(s)>1) and (s[1]='_') then
  212. i:=2;
  213. if PrependTypes then
  214. TypeName:='T'+Copy(s,i,255)
  215. else
  216. TypeName:=Copy(s,i,255);
  217. end;
  218. function IsACType(const s : String) : Boolean;
  219. var i : Integer;
  220. begin
  221. IsACType := True;
  222. for i := 0 to MAX_CTYPESARRAY do
  223. begin
  224. if s = CTypesArray[i] then
  225. Exit;
  226. end;
  227. IsACType := False;
  228. end;
  229. function PointerName(const s:string):string;
  230. var
  231. i : longint;
  232. begin
  233. if UseCTypesUnit then
  234. begin
  235. if IsACType(s) then
  236. begin
  237. PointerName := 'p'+s;
  238. exit;
  239. end;
  240. end;
  241. i:=1;
  242. if RemoveUnderScore and (length(s)>1) and (s[1]='_') then
  243. i:=2;
  244. if UsePPointers then
  245. begin
  246. PointerName:='P'+Copy(s,i,255);
  247. PTypeList.Add(PointerName);
  248. end
  249. else
  250. PointerName:=Copy(s,i,255);
  251. if PointerPrefix then
  252. PTypeList.Add('P'+s);
  253. end;
  254. Function IsVarPara(P : presobject) : Boolean;
  255. var
  256. varpara: boolean;
  257. begin
  258. varpara:=usevarparas and
  259. assigned(p^.p1^.p1) and
  260. (p^.p1^.p1^.typ in [t_addrdef,t_pointerdef]) and
  261. assigned(p^.p1^.p1^.p1) and
  262. (p^.p1^.p1^.p1^.typ<>t_procdef);
  263. (* do not do it for char pointer !! *)
  264. (* para : pchar; and var para : char; are *)
  265. (* completely different in pascal *)
  266. (* here we exclude all typename containing char *)
  267. (* is this a good method ?? *)
  268. if varpara and
  269. (p^.p1^.p1^.typ=t_pointerdef) and
  270. (((p^.p1^.p1^.p1^.typ=t_id) and
  271. (pos('CHAR',uppercase(p^.p1^.p1^.p1^.str))<>0)) or
  272. ((p^.p1^.p1^.p1^.typ=t_void))
  273. ) then
  274. varpara:=false;
  275. IsVarPara:=varpara;
  276. end;
  277. procedure write_packed_fields_info(var outfile:text; p : presobject; ph : string);
  278. var
  279. hp1,hp2,hp3 : presobject;
  280. is_sized : boolean;
  281. line : string;
  282. flag_index : longint;
  283. name : pansichar;
  284. ps : byte;
  285. begin
  286. { write out the tempfile created }
  287. close(tempfile);
  288. reset(tempfile);
  289. is_sized:=false;
  290. flag_index:=0;
  291. writeln(outfile);
  292. writeln(outfile,aktspace,'const');
  293. shift(2);
  294. while not eof(tempfile) do
  295. begin
  296. readln(tempfile,line);
  297. ps:=pos('&',line);
  298. if ps>0 then
  299. line:=copy(line,1,ps-1)+ph+'_'+copy(line,ps+1,255);
  300. writeln(outfile,aktspace,line);
  301. end;
  302. writeln(outfile);
  303. close(tempfile);
  304. rewrite(tempfile);
  305. popshift;
  306. (* walk through all members *)
  307. hp1 := p^.p1;
  308. while assigned(hp1) do
  309. begin
  310. (* hp2 is t_memberdec *)
  311. hp2:=hp1^.p1;
  312. (* hp3 is t_declist *)
  313. hp3:=hp2^.p2;
  314. while assigned(hp3) do
  315. begin
  316. if assigned(hp3^.p1^.p3) and
  317. (hp3^.p1^.p3^.typ = t_size_specifier) then
  318. begin
  319. is_sized:=true;
  320. name:=hp3^.p1^.p2^.p;
  321. { get function in interface }
  322. write(outfile,aktspace,'function ',name);
  323. write(outfile,'(var a : ',ph,') : ');
  324. shift(2);
  325. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  326. writeln(outfile,';');
  327. popshift;
  328. { get function in implementation }
  329. write(implemfile,aktspace,'function ',name);
  330. write(implemfile,'(var a : ',ph,') : ');
  331. if not compactmode then
  332. shift(2);
  333. write_p_a_def(implemfile,hp3^.p1^.p1,hp2^.p1);
  334. writeln(implemfile,';');
  335. writeln(implemfile,aktspace,'begin');
  336. shift(2);
  337. write(implemfile,aktspace,name,':=(a.flag',flag_index);
  338. writeln(implemfile,' and bm_',ph,'_',name,') shr bp_',ph,'_',name,';');
  339. popshift;
  340. writeln(implemfile,aktspace,'end;');
  341. if not compactmode then
  342. popshift;
  343. writeln(implemfile,'');
  344. { set function in interface }
  345. write(outfile,aktspace,'procedure set_',name);
  346. write(outfile,'(var a : ',ph,'; __',name,' : ');
  347. shift(2);
  348. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  349. writeln(outfile,');');
  350. popshift;
  351. { set function in implementation }
  352. write(implemfile,aktspace,'procedure set_',name);
  353. write(implemfile,'(var a : ',ph,'; __',name,' : ');
  354. if not compactmode then
  355. shift(2);
  356. write_p_a_def(implemfile,hp3^.p1^.p1,hp2^.p1);
  357. writeln(implemfile,');');
  358. writeln(implemfile,aktspace,'begin');
  359. shift(2);
  360. write(implemfile,aktspace,'a.flag',flag_index,':=');
  361. write(implemfile,'a.flag',flag_index,' or ');
  362. writeln(implemfile,'((__',name,' shl bp_',ph,'_',name,') and bm_',ph,'_',name,');');
  363. popshift;
  364. writeln(implemfile,aktspace,'end;');
  365. if not compactmode then
  366. popshift;
  367. writeln(implemfile,'');
  368. end
  369. else if is_sized then
  370. begin
  371. is_sized:=false;
  372. inc(flag_index);
  373. end;
  374. hp3:=hp3^.next;
  375. end;
  376. hp1:=hp1^.next;
  377. end;
  378. must_write_packed_field:=false;
  379. block_type:=bt_no;
  380. end;
  381. procedure write_expr(var outfile:text; p : presobject);
  382. var
  383. DoFlush:Boolean;
  384. begin
  385. if Not assigned(p) then
  386. begin
  387. writeln('Warning: attempt to write empty expression');
  388. exit;
  389. end;
  390. DoFlush:=True;
  391. case p^.typ of
  392. t_id,
  393. t_ifexpr :
  394. write(outfile,FixId(p^.p));
  395. t_funexprlist :
  396. write_funexpr(outfile,p);
  397. t_exprlist:
  398. begin
  399. if assigned(p^.p1) then
  400. write_expr(outfile,p^.p1);
  401. if assigned(p^.next) then
  402. begin
  403. write(', ');
  404. write_expr(outfile,p^.next);
  405. end;
  406. DoFlush:=False;
  407. end;
  408. t_preop:
  409. begin
  410. write(outfile,p^.p,'(');
  411. write_expr(outfile,p^.p1);
  412. write(outfile,')');
  413. end;
  414. t_typespec :
  415. begin
  416. write_type_specifier(outfile,p^.p1);
  417. write(outfile,'(');
  418. write_expr(outfile,p^.p2);
  419. write(outfile,')');
  420. end;
  421. t_bop :
  422. begin
  423. if p^.p1^.typ<>t_id then
  424. write(outfile,'(');
  425. write_expr(outfile,p^.p1);
  426. if p^.p1^.typ<>t_id then
  427. write(outfile,')');
  428. write(outfile,p^.p);
  429. if p^.p2^.typ<>t_id then
  430. write(outfile,'(');
  431. write_expr(outfile,p^.p2);
  432. if p^.p2^.typ<>t_id then
  433. write(outfile,')');
  434. end;
  435. t_arrayop :
  436. begin
  437. write_expr(outfile,p^.p1);
  438. write(outfile,p^.p,'[');
  439. write_expr(outfile,p^.p2);
  440. write(outfile,']');
  441. end;
  442. t_callop :
  443. begin
  444. write_expr(outfile,p^.p1);
  445. write(outfile,p^.p,'(');
  446. write_expr(outfile,p^.p2);
  447. write(outfile,')');
  448. end;
  449. else
  450. writeln(ord(p^.typ));
  451. internalerror(2);
  452. doFlush:=False;
  453. end;
  454. if DoFlush then
  455. Flush(OutFile);
  456. end;
  457. procedure write_ifexpr(var outfile:text; p : presobject);
  458. begin
  459. flush(outfile);
  460. write(outfile,'if ');
  461. write_expr(outfile,p^.p1);
  462. writeln(outfile,' then');
  463. write(outfile,aktspace,' ');
  464. write(outfile,p^.p);
  465. write(outfile,':=');
  466. write_expr(outfile,p^.p2);
  467. writeln(outfile);
  468. writeln(outfile,aktspace,'else');
  469. write(outfile,aktspace,' ');
  470. write(outfile,p^.p);
  471. write(outfile,':=');
  472. write_expr(outfile,p^.p3);
  473. writeln(outfile,';');
  474. write(outfile,aktspace);
  475. flush(outfile);
  476. end;
  477. procedure write_all_ifexpr(var outfile:text; p : presobject);
  478. begin
  479. if not assigned(p) then
  480. begin
  481. Writeln('Warning: writing empty ifexpr');
  482. exit;
  483. end;
  484. case p^.typ of
  485. t_id :;
  486. t_preop :
  487. write_all_ifexpr(outfile,p^.p1);
  488. t_callop,
  489. t_arrayop,
  490. t_bop :
  491. begin
  492. write_all_ifexpr(outfile,p^.p1);
  493. write_all_ifexpr(outfile,p^.p2);
  494. end;
  495. t_ifexpr :
  496. begin
  497. write_all_ifexpr(outfile,p^.p1);
  498. write_all_ifexpr(outfile,p^.p2);
  499. write_all_ifexpr(outfile,p^.p3);
  500. write_ifexpr(outfile,p);
  501. end;
  502. t_typespec :
  503. write_all_ifexpr(outfile,p^.p2);
  504. t_funexprlist,
  505. t_exprlist :
  506. begin
  507. if assigned(p^.p1) then
  508. write_all_ifexpr(outfile,p^.p1);
  509. if assigned(p^.next) then
  510. write_all_ifexpr(outfile,p^.next);
  511. end
  512. else
  513. internalerror(6);
  514. end;
  515. end;
  516. procedure write_funexpr(var outfile:text; p : presobject);
  517. var
  518. i : longint;
  519. begin
  520. if not assigned(p) then
  521. begin
  522. Writeln('Warning: attempt to write empty function expression');
  523. exit;
  524. end;
  525. case p^.typ of
  526. t_ifexpr :
  527. write(outfile,p^.p);
  528. t_exprlist :
  529. begin
  530. write_expr(outfile,p^.p1);
  531. if assigned(p^.next) then
  532. begin
  533. write(outfile,',');
  534. write_funexpr(outfile,p^.next);
  535. end
  536. end;
  537. t_funcname :
  538. begin
  539. if if_nb>0 then
  540. begin
  541. writeln(outfile,aktspace,'var');
  542. write(outfile,aktspace,' ');
  543. for i:=1 to if_nb do
  544. begin
  545. write(outfile,'if_local',i);
  546. if i<if_nb then
  547. write(outfile,', ')
  548. else
  549. writeln(outfile,' : longint;');
  550. end;
  551. writeln(outfile,aktspace,'(* result types are not known *)');
  552. if_nb:=0;
  553. end;
  554. writeln(outfile,aktspace,'begin');
  555. shift(2);
  556. write(outfile,aktspace);
  557. write_all_ifexpr(outfile,p^.p2);
  558. write_expr(outfile,p^.p1);
  559. write(outfile,':=');
  560. write_funexpr(outfile,p^.p2);
  561. writeln(outfile,';');
  562. popshift;
  563. writeln(outfile,aktspace,'end;');
  564. if not compactmode then
  565. popshift;
  566. flush(outfile);
  567. end;
  568. t_funexprlist :
  569. begin
  570. if assigned(p^.p3) then
  571. begin
  572. write_type_specifier(outfile,p^.p3);
  573. write(outfile,'(');
  574. end;
  575. if assigned(p^.p1) then
  576. write_funexpr(outfile,p^.p1);
  577. if assigned(p^.p2) then
  578. begin
  579. write(outfile,'(');
  580. write_funexpr(outfile,p^.p2);
  581. write(outfile,')');
  582. end;
  583. if assigned(p^.p3) then
  584. write(outfile,')');
  585. end
  586. else
  587. internalerror(5);
  588. end;
  589. end;
  590. procedure write_args(var outfile:text; p : presobject);
  591. var
  592. len,para : longint;
  593. old_in_args : boolean;
  594. varpara : boolean;
  595. lastp : presobject;
  596. hs : string;
  597. begin
  598. _NeedEllipsisOverload:=false;
  599. para:=1;
  600. len:=0;
  601. lastp:=nil;
  602. old_in_args:=in_args;
  603. in_args:=true;
  604. write(outfile,'(');
  605. shift(2);
  606. (* walk through all arguments *)
  607. (* p must be of type t_arglist *)
  608. while assigned(p) do
  609. begin
  610. if p^.typ<>t_arglist then
  611. internalerror(10);
  612. (* is ellipsis ? *)
  613. if not assigned(p^.p1^.p1) and not assigned(p^.p1^.next) then
  614. begin
  615. write(outfile,'args:array of const');
  616. (* if variable number of args we must allways pop *)
  617. no_pop:=false;
  618. (* Needs 2 declarations, also one without args, becuase
  619. in C you can omit the second parameter. Default parameter
  620. doesn't help as that isn't possible with array of const *)
  621. _NeedEllipsisOverload:=true;
  622. (* Remove this para *)
  623. if assigned(lastp) then
  624. lastp^.next:=nil;
  625. dispose(p,done);
  626. (* leave the loop as p isnot valid anymore *)
  627. break;
  628. end
  629. (* we need to correct this in the pp file after *)
  630. else
  631. begin
  632. (* generate a call by reference parameter ? *)
  633. // varpara:=usevarparas and
  634. // assigned(p^.p1^.p2^.p1) and
  635. // (p^.p1^.p2^.p1^.typ in [t_addrdef,t_pointerdef]) and
  636. // assigned(p^.p1^.p2^.p1^.p1) and
  637. // (p^.p1^.p2^.p1^.p1^.typ<>t_procdef);
  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^.intname 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. procedure write_statement_block(var outfile:text; p : presobject);
  1212. begin
  1213. writeln(outfile,aktspace,'begin');
  1214. while assigned(p) do
  1215. begin
  1216. shift(2);
  1217. if assigned(p^.p1) then
  1218. case p^.p1^.typ of
  1219. t_whilenode:
  1220. begin
  1221. write(outfile,aktspace,'while ');
  1222. write_expr(outfile,p^.p1^.p1);
  1223. writeln(outfile,' do');
  1224. shift(2);
  1225. write_statement_block(outfile,p^.p1^.p2);
  1226. popshift;
  1227. end;
  1228. else
  1229. write(outfile,aktspace);
  1230. write_expr(outfile,p^.p1);
  1231. writeln(outfile,';');
  1232. end; // case
  1233. p:=p^.next;
  1234. popshift;
  1235. end;
  1236. writeln(outfile,aktspace,'end;');
  1237. end;
  1238. procedure WriteFileHeader(var headerfile: Text);
  1239. var
  1240. i: integer;
  1241. originalstr: string;
  1242. begin
  1243. { write unit header }
  1244. if not includefile then
  1245. begin
  1246. if createdynlib then
  1247. writeln(headerfile,'{$mode objfpc}');
  1248. writeln(headerfile,'unit ',unitname,';');
  1249. writeln(headerfile,'interface');
  1250. writeln(headerfile);
  1251. if UseCTypesUnit then
  1252. begin
  1253. writeln(headerfile,'uses');
  1254. writeln(headerfile,' ctypes;');
  1255. writeln(headerfile);
  1256. end;
  1257. writeln(headerfile,'{');
  1258. writeln(headerfile,' Automatically converted by H2Pas ',version,' from ',inputfilename);
  1259. writeln(headerfile,' The following command line parameters were used:');
  1260. for i:=1 to paramcount do
  1261. writeln(headerfile,' ',paramstr(i));
  1262. writeln(headerfile,'}');
  1263. writeln(headerfile);
  1264. end;
  1265. if UseName then
  1266. begin
  1267. writeln(headerfile,aktspace,'const');
  1268. writeln(headerfile,aktspace,' External_library=''',libfilename,'''; {Setup as you need}');
  1269. writeln(headerfile);
  1270. end;
  1271. if UsePPointers then
  1272. begin
  1273. Writeln(headerfile,aktspace,'{ Pointers to basic pascal types, inserted by h2pas conversion program.}');
  1274. Writeln(headerfile,aktspace,'Type');
  1275. Writeln(headerfile,aktspace,' PLongint = ^Longint;');
  1276. Writeln(headerfile,aktspace,' PSmallInt = ^SmallInt;');
  1277. Writeln(headerfile,aktspace,' PByte = ^Byte;');
  1278. Writeln(headerfile,aktspace,' PWord = ^Word;');
  1279. Writeln(headerfile,aktspace,' PDWord = ^DWord;');
  1280. Writeln(headerfile,aktspace,' PDouble = ^Double;');
  1281. Writeln(headerfile);
  1282. end;
  1283. if PTypeList.count <> 0 then
  1284. Writeln(headerfile,aktspace,'Type');
  1285. for i:=0 to (PTypeList.Count-1) do
  1286. begin
  1287. originalstr:=copy(PTypelist[i],2,length(PTypeList[i]));
  1288. if PrependTypes then
  1289. originalstr:='T'+originalstr;
  1290. Writeln(headerfile,aktspace,' '+PTypeList[i],' = ^',originalstr,';');
  1291. end;
  1292. if not packrecords then
  1293. begin
  1294. writeln(headerfile,'{$IFDEF FPC}');
  1295. writeln(headerfile,'{$PACKRECORDS C}');
  1296. writeln(headerfile,'{$ENDIF}');
  1297. end;
  1298. writeln(headerfile);
  1299. end;
  1300. procedure OpenOutputFiles;
  1301. begin
  1302. { This is the intermediate output file }
  1303. assign(outfile, 'ext3.tmp');
  1304. {$I-}
  1305. rewrite(outfile);
  1306. {$I+}
  1307. if ioresult<>0 then
  1308. begin
  1309. writeln('file ext3.tmp could not be created!');
  1310. halt(1);
  1311. end;
  1312. writeln(outfile);
  1313. { Open tempfiles }
  1314. { This is where the implementation section of the unit shall be stored }
  1315. Assign(implemfile,'ext.tmp');
  1316. rewrite(implemfile);
  1317. Assign(tempfile,'ext2.tmp');
  1318. rewrite(tempfile);
  1319. end;
  1320. procedure CloseTempFiles;
  1321. begin
  1322. close(implemfile);
  1323. erase(implemfile);
  1324. close(tempfile);
  1325. erase(tempfile);
  1326. end;
  1327. procedure WriteLibraryInitialization;
  1328. var
  1329. I : Integer;
  1330. begin
  1331. writeln(outfile,' uses');
  1332. writeln(outfile,' SysUtils, dynlibs;');
  1333. writeln(outfile);
  1334. writeln(outfile,' var');
  1335. writeln(outfile,' hlib : tlibhandle;');
  1336. writeln(outfile);
  1337. writeln(outfile);
  1338. writeln(outfile,' procedure Free',unitname,';');
  1339. writeln(outfile,' begin');
  1340. writeln(outfile,' FreeLibrary(hlib);');
  1341. for i:=0 to (freedynlibproc.Count-1) do
  1342. Writeln(outfile,' ',freedynlibproc[i]);
  1343. writeln(outfile,' end;');
  1344. writeln(outfile);
  1345. writeln(outfile);
  1346. writeln(outfile,' procedure Load',unitname,'(lib : pchar);');
  1347. writeln(outfile,' begin');
  1348. writeln(outfile,' Free',unitname,';');
  1349. writeln(outfile,' hlib:=LoadLibrary(lib);');
  1350. writeln(outfile,' if hlib=0 then');
  1351. writeln(outfile,' raise Exception.Create(format(''Could not load library: %s'',[lib]));');
  1352. writeln(outfile);
  1353. for i:=0 to (loaddynlibproc.Count-1) do
  1354. Writeln(outfile,' ',loaddynlibproc[i]);
  1355. writeln(outfile,' end;');
  1356. writeln(outfile);
  1357. writeln(outfile);
  1358. writeln(outfile,'initialization');
  1359. writeln(outfile,' Load',unitname,'(''',unitname,''');');
  1360. writeln(outfile,'finalization');
  1361. writeln(outfile,' Free',unitname,';');
  1362. end;
  1363. end.