h2pbase.pp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. (*
  2. Copyright (c) 1998-2000 by Florian Klaempfl
  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. unit h2pbase;
  16. {$modeswitch result}
  17. {$message TODO: warning Unit types is only needed due to issue 7910}
  18. interface
  19. uses
  20. SysUtils, classes,
  21. h2poptions,scan,h2pconst,h2plexlib,h2pyacclib, scanbase,h2pout,h2ptypes;
  22. type
  23. YYSTYPE = presobject;
  24. var
  25. IsExtern : boolean;
  26. s,TN,PN : String;
  27. (* $ define yydebug
  28. compile with -dYYDEBUG to get debugging info *)
  29. procedure yymsg(const msg : string);
  30. function ellipsisarg : presobject;
  31. function HandleErrorDecl(e1,e2 : presobject) : presobject;
  32. Function HandleDeclarationStatement(decl,type_spec,modifier_spec,decllist_spec,block_spec : presobject) : presobject;
  33. Function HandleDeclarationSysTrap(decl,type_spec,modifier_spec,decllist_spec,sys_trap : presobject) : presobject;
  34. function HandleSpecialType(aType: presobject) : presobject;
  35. function HandleTypedef(type_spec,dec_modifier,declarator,arg_decl_list: presobject) : presobject;
  36. function HandleTypedefList(type_spec,dec_modifier,declarator_list: presobject) : presobject;
  37. function HandleStructDef(dname1,dname2 : presobject) : presobject;
  38. function HandleSimpleTypeDef(tname : presobject) : presobject;
  39. function HandleDeclarator(aTyp : ttyp; aright: presobject): presobject;
  40. function HandleDeclarator2(aTyp : ttyp; aleft,aright: presobject): presobject;
  41. function HandleSizedDeclarator(psym,psize : presobject) : presobject;
  42. function HandleSizedPointerDeclarator(psym,psize : presobject) : presobject;
  43. function HandleSizeOverrideDeclarator(psize,psym : presobject) : presobject;
  44. function HandleDefaultDeclarator(psym,pdefault : presobject) : presobject;
  45. function HandleArgList(aEl,aList : PResObject) : PResObject;
  46. function HandlePointerArgDeclarator(ptype, psym : presobject): presobject;
  47. function HandlePointerAbstractDeclarator(psym : presobject): presobject;
  48. function HandlePointerAbstractListDeclarator(psym,plist : presobject): presobject;
  49. function HandleDeclarationList(plist,pelem : presobject) : presobject;
  50. function handleSpecialSignedType(aType : presobject) : presobject;
  51. function handleSpecialUnSignedType(aType : presobject) : presobject;
  52. function handleArrayDecl(aType : presobject) : presobject;
  53. function handleSizedArrayDecl(aType,aSizeExpr: presobject): presobject;
  54. function handleFuncNoArg(aType: presobject): presobject;
  55. function handleFuncExpr(aType,aList: presobject): presobject;
  56. function handlePointerType(aType,aPointer,aSize : presobject): presobject;
  57. function HandleUnaryDefExpr(aExpr : presobject) : presobject;
  58. function HandleTernary(expr,colonexpr : presobject) : presobject;
  59. // Macros
  60. function HandleDefineMacro(dname,enum_list,para_def_expr: presobject) : presobject;
  61. function HandleDefineConst(dname,def_expr: presobject) : presobject;
  62. function HandleDefine(dname : presobject) : presobject;
  63. Function CheckWideString(S : String) : presobject;
  64. function CheckUnderScore(pdecl : presobject) : presobject;
  65. Function NewCType(aID,aIntID : String) : PresObject;
  66. Implementation
  67. function HandleTernary(expr,colonexpr : presobject) : presobject;
  68. begin
  69. colonexpr^.p1:=expr;
  70. Result:=colonexpr;
  71. inc(if_nb);
  72. result^.p:=strpnew('if_local'+str(if_nb));
  73. end;
  74. Function NewCType(aID,aIntID : String) : PresObject;
  75. begin
  76. if UseCTypesUnit then
  77. Result:=NewID(aID)
  78. else
  79. result:=NewIntID(aIntID);
  80. end;
  81. function HandleUnaryDefExpr(aExpr : presobject) : presobject;
  82. begin
  83. if aExpr^.typ=t_funexprlist then
  84. Result:=aExpr
  85. else
  86. Result:=NewType2(t_exprlist,aExpr,nil);
  87. (* if here is a type specifier we know the return type *)
  88. if (aExpr^.typ=t_typespec) then
  89. Result^.p3:=aExpr^.p1^.get_copy;
  90. end;
  91. function handleSpecialSignedType(aType : presobject) : presobject;
  92. var
  93. hp : presobject;
  94. tc,tp : string;
  95. begin
  96. tp:='';
  97. Result:=aType;
  98. hp:=result;
  99. if not Assigned(HP) then
  100. exit;
  101. tc:=strpas(hp^.p);
  102. if UseCTypesUnit then
  103. Case tc of
  104. cint_STR: tp:=csint_STR;
  105. cshort_STR: tp:=csshort_STR;
  106. cchar_STR: tp:=cschar_STR;
  107. clong_STR: tp:=cslong_STR;
  108. clonglong_STR: tp:=cslonglong_STR;
  109. cint8_STR: tp:=cint8_STR;
  110. cint16_STR: tp:=cint16_STR;
  111. cint32_STR: tp:=cint32_STR;
  112. cint64_STR: tp:=cint64_STR;
  113. else
  114. tp:='';
  115. end
  116. else
  117. case tc of
  118. UINT_STR: tp:=INT_STR;
  119. USHORT_STR: tp:=SHORT_STR;
  120. USMALL_STR: tp:=SMALL_STR;
  121. // UCHAR_STR: tp:=CHAR_STR; identical to USHORT_STR....
  122. QWORD_STR: tp:=INT64_STR;
  123. else
  124. tp:='';
  125. end;
  126. if tp<>'' then
  127. hp^.setstr(tp);
  128. end;
  129. function handleSpecialUnSignedType(aType : presobject) : presobject;
  130. var
  131. hp : presobject;
  132. begin
  133. hp:=aType;
  134. Result:=hp;
  135. if Not assigned(hp) then
  136. exit;
  137. s:=strpas(hp^.p);
  138. if UseCTypesUnit then
  139. begin
  140. if s=cint_STR then
  141. s:=cuint_STR
  142. else if s=cshort_STR then
  143. s:=cushort_STR
  144. else if s=cchar_STR then
  145. s:=cuchar_STR
  146. else if s=clong_STR then
  147. s:=culong_STR
  148. else if s=clonglong_STR then
  149. s:=culonglong_STR
  150. else if s=cint8_STR then
  151. s:=cuint8_STR
  152. else if s=cint16_STR then
  153. s:=cuint16_STR
  154. else if s=cint32_STR then
  155. s:=cuint32_STR
  156. else if s=cint64_STR then
  157. s:=cuint64_STR
  158. else
  159. s:='';
  160. end
  161. else
  162. begin
  163. if s=INT_STR then
  164. s:=UINT_STR
  165. else if s=SHORT_STR then
  166. s:=USHORT_STR
  167. else if s=SMALL_STR then
  168. s:=USMALL_STR
  169. else if s=CHAR_STR then
  170. s:=UCHAR_STR
  171. else if s=INT64_STR then
  172. s:=QWORD_STR
  173. else
  174. s:='';
  175. end;
  176. if s<>'' then
  177. hp^.setstr(s);
  178. end;
  179. function handleSizedArrayDecl(aType,aSizeExpr: presobject): presobject;
  180. var
  181. hp : presobject;
  182. begin
  183. hp:=aType;
  184. result:=hp;
  185. while assigned(hp^.p1) do
  186. hp:=hp^.p1;
  187. hp^.p1:=NewType2(t_arraydef,nil,aSizeExpr);
  188. end;
  189. function handleFuncNoArg(aType: presobject): presobject;
  190. var
  191. hp : presobject;
  192. begin
  193. hp:=aType;
  194. Result:=hp;
  195. while assigned(hp^.p1) do
  196. hp:=hp^.p1;
  197. hp^.p1:=NewType2(t_procdef,nil,nil);
  198. end;
  199. function handleFuncExpr(aType, aList: presobject): presobject;
  200. var
  201. hp : presobject;
  202. begin
  203. hp:=NewType1(t_exprlist,aType);
  204. Result:=NewType3(t_funexprlist,hp,aList,nil);
  205. end;
  206. function handlePointerType(aType, aPointer, aSize: presobject): presobject;
  207. var
  208. hp : presobject;
  209. begin
  210. if assigned(aSize) then
  211. begin
  212. if not stripinfo then
  213. emitignore(aSize);
  214. dispose(aSize,done);
  215. write_type_specifier(outfile,aType);
  216. emitwriteln(' ignored *)');
  217. end;
  218. hp:=NewType1(t_pointerdef,aType);
  219. Result:=NewType2(t_typespec,hp,aPointer);
  220. end;
  221. function handleArrayDecl(aType: presobject): presobject;
  222. var
  223. hp : presobject;
  224. begin
  225. (* this is translated into a pointer *)
  226. hp:=aType;
  227. Result:=hp;
  228. while assigned(hp^.p1) do
  229. hp:=hp^.p1;
  230. hp^.p1:=NewType1(t_pointerdef,nil);
  231. end;
  232. function HandlePointerAbstractDeclarator(psym: presobject): presobject;
  233. var
  234. hp : presobject;
  235. begin
  236. hp:=psym;
  237. Result:=hp;
  238. while assigned(hp^.p1) do
  239. hp:=hp^.p1;
  240. hp^.p1:=NewType1(t_pointerdef,nil);
  241. end;
  242. function HandlePointerAbstractListDeclarator(psym, plist: presobject
  243. ): presobject;
  244. var
  245. hp : presobject;
  246. begin
  247. hp:=psym;
  248. result:=hp;
  249. while assigned(hp^.p1) do
  250. hp:=hp^.p1;
  251. hp^.p1:=NewType2(t_procdef,nil,plist);
  252. end;
  253. function HandleDeclarationList(plist,pelem : presobject) : presobject;
  254. var
  255. hp : presobject;
  256. begin
  257. hp:=plist;
  258. result:=hp;
  259. while assigned(hp^.next) do
  260. hp:=hp^.next;
  261. hp^.next:=NewType1(t_declist,pelem);
  262. end;
  263. function HandleSizedDeclarator(psym,psize : presobject) : presobject;
  264. var
  265. hp : presobject;
  266. begin
  267. hp:=NewType1(t_size_specifier,psize);
  268. Result:=NewType3(t_dec,nil,psym,hp);
  269. end;
  270. function HandleDefaultDeclarator(psym,pdefault : presobject) : presobject;
  271. var
  272. hp : presobject;
  273. begin
  274. EmitIgnoreDefault(psym);
  275. hp:=NewType1(t_default_value,pdefault);
  276. HandleDefaultDeclarator:=NewType3(t_dec,nil,psym,hp);
  277. end;
  278. function HandleArgList(aEl, aList: PResObject): PResObject;
  279. begin
  280. Result:=NewType2(t_arglist,aEl,nil);
  281. Result^.next:=aList;
  282. end;
  283. function HandlePointerArgDeclarator(ptype, psym : presobject): presobject;
  284. var
  285. hp : presobject;
  286. begin
  287. (* type_specifier STAR declarator *)
  288. hp:=NewType1(t_pointerdef,ptype);
  289. Result:=NewType2(t_arg,hp,psym);
  290. end;
  291. function HandleSizedPointerDeclarator(psym, psize: presobject): presobject;
  292. var
  293. hp : presobject;
  294. begin
  295. emitignore(psize);
  296. dispose(psize,done);
  297. hp:=psym;
  298. Result:=hp;
  299. while assigned(hp^.p1) do
  300. hp:=hp^.p1;
  301. hp^.p1:=NewType1(t_pointerdef,nil);
  302. end;
  303. function HandleSizeOverrideDeclarator(psize,psym : presobject) : presobject;
  304. var
  305. hp : presobject;
  306. begin
  307. EmitIgnore(psize);
  308. dispose(psize,done);
  309. hp:=psym;
  310. HandleSizeOverrideDeclarator:=hp;
  311. while assigned(hp^.p1) do
  312. hp:=hp^.p1;
  313. hp^.p1:=NewType1(t_pointerdef,nil);
  314. end;
  315. function HandleDeclarator2(aTyp : ttyp; aleft,aright: presobject): presobject;
  316. var
  317. hp : presobject;
  318. begin
  319. hp:=aLeft;
  320. result:=hp;
  321. while assigned(hp^.p1) do
  322. hp:=hp^.p1;
  323. hp^.p1:=NewType2(aTyp,nil,aRight);
  324. end;
  325. function HandleDeclarator(aTyp : ttyp; aright: presobject): presobject;
  326. var
  327. hp : presobject;
  328. begin
  329. hp:=aright;
  330. Result:=hp;
  331. while assigned(hp^.p1) do
  332. hp:=hp^.p1;
  333. hp^.p1:=NewType1(atyp,nil);
  334. end;
  335. function CheckWideString(S: String): presobject;
  336. begin
  337. if Win32headers and (s[1]='L') then
  338. delete(s,1,1);
  339. CheckWideString:=NewID(''''+copy(s,2,length(s)-2)+'''');
  340. end;
  341. function CheckUnderScore(pdecl: presobject): presobject;
  342. var
  343. tn : string;
  344. len : integer;
  345. begin
  346. Result:=pdecl;
  347. tn:=result^.str;
  348. len:=length(tn);
  349. if removeunderscore and (len>1) and (tn[1]='_') then
  350. result^.setstr(Copy(tn,2,len-1));
  351. end;
  352. function yylex : Integer;
  353. begin
  354. yylex:=scan.yylex;
  355. line_no:=yylineno;
  356. end;
  357. (* writes an argument list, where p is t_arglist *)
  358. procedure yymsg(const msg : string);
  359. begin
  360. writeln('line ',line_no,': ',msg);
  361. end;
  362. function ellipsisarg : presobject;
  363. begin
  364. ellipsisarg:=new(presobject,init_two(t_arg,nil,nil));
  365. end;
  366. function HandleDeclarationStatement(decl, type_spec, modifier_spec,
  367. decllist_spec, block_spec: presobject): presobject;
  368. var
  369. hp : presobject;
  370. begin
  371. HandleDeclarationStatement:=Nil;
  372. IsExtern:=false;
  373. (* by default we must pop the args pushed on stack *)
  374. no_pop:=false;
  375. if (assigned(decllist_spec)and assigned(decllist_spec^.p1)and assigned(decllist_spec^.p1^.p1))
  376. and (decllist_spec^.p1^.p1^.typ=t_procdef) then
  377. begin
  378. repeat
  379. If UseLib then
  380. IsExtern:=true
  381. else
  382. IsExtern:=assigned(decl)and(decl^.str='extern');
  383. no_pop:=assigned(modifier_spec) and (modifier_spec^.str='no_pop');
  384. if (block_type<>bt_func) and not(createdynlib) then
  385. begin
  386. writeln(outfile);
  387. block_type:=bt_func;
  388. end;
  389. (* dyn. procedures must be put into a var block *)
  390. if createdynlib then
  391. begin
  392. if (block_type<>bt_var) then
  393. begin
  394. if not(compactmode) then
  395. writeln(outfile);
  396. writeln(outfile,aktspace,'var');
  397. block_type:=bt_var;
  398. end;
  399. shift(2);
  400. end;
  401. if not CompactMode then
  402. begin
  403. write(outfile,aktspace);
  404. if not IsExtern then
  405. write(implemfile,aktspace);
  406. end;
  407. (* distinguish between procedure and function *)
  408. if assigned(type_spec) then
  409. if (type_spec^.typ=t_void) and (decllist_spec^.p1^.p1^.p1=nil) then
  410. begin
  411. if createdynlib then
  412. begin
  413. write(outfile,decllist_spec^.p1^.p2^.p,' : procedure');
  414. end
  415. else
  416. begin
  417. shift(10);
  418. write(outfile,'procedure ',decllist_spec^.p1^.p2^.p);
  419. end;
  420. if assigned(decllist_spec^.p1^.p1^.p2) then
  421. write_args(outfile,decllist_spec^.p1^.p1^.p2);
  422. if createdynlib then
  423. begin
  424. loaddynlibproc.add('pointer('+decllist_spec^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+decllist_spec^.p1^.p2^.p+''');');
  425. freedynlibproc.add(decllist_spec^.p1^.p2^.p+':=nil;');
  426. end
  427. else if not IsExtern then
  428. begin
  429. write(implemfile,'procedure ',decllist_spec^.p1^.p2^.p);
  430. if assigned(decllist_spec^.p1^.p1^.p2) then
  431. write_args(implemfile,decllist_spec^.p1^.p1^.p2);
  432. end;
  433. end
  434. else
  435. begin
  436. if createdynlib then
  437. begin
  438. write(outfile,decllist_spec^.p1^.p2^.p,' : function');
  439. end
  440. else
  441. begin
  442. shift(9);
  443. write(outfile,'function ',decllist_spec^.p1^.p2^.p);
  444. end;
  445. if assigned(decllist_spec^.p1^.p1^.p2) then
  446. write_args(outfile,decllist_spec^.p1^.p1^.p2);
  447. write(outfile,':');
  448. old_in_args:=in_args;
  449. (* write pointers as P.... instead of ^.... *)
  450. in_args:=true;
  451. write_p_a_def(outfile,decllist_spec^.p1^.p1^.p1,type_spec);
  452. in_args:=old_in_args;
  453. if createdynlib then
  454. begin
  455. loaddynlibproc.add('pointer('+decllist_spec^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+decllist_spec^.p1^.p2^.p+''');');
  456. freedynlibproc.add(decllist_spec^.p1^.p2^.p+':=nil;');
  457. end
  458. else if not IsExtern then
  459. begin
  460. write(implemfile,'function ',decllist_spec^.p1^.p2^.p);
  461. if assigned(decllist_spec^.p1^.p1^.p2) then
  462. write_args(implemfile,decllist_spec^.p1^.p1^.p2);
  463. write(implemfile,':');
  464. old_in_args:=in_args;
  465. (* write pointers as P.... instead of ^.... *)
  466. in_args:=true;
  467. write_p_a_def(implemfile,decllist_spec^.p1^.p1^.p1,type_spec);
  468. in_args:=old_in_args;
  469. end;
  470. end;
  471. (* No CDECL in interface for Uselib *)
  472. if IsExtern and (not no_pop) then
  473. write(outfile,';cdecl');
  474. popshift;
  475. if createdynlib then
  476. begin
  477. writeln(outfile,';');
  478. end
  479. else if UseLib then
  480. begin
  481. if IsExtern then
  482. begin
  483. write (outfile,';external');
  484. If UseName then
  485. Write(outfile,' External_library name ''',decllist_spec^.p1^.p2^.p,'''');
  486. end;
  487. writeln(outfile,';');
  488. end
  489. else
  490. begin
  491. writeln(outfile,';');
  492. if not IsExtern then
  493. begin
  494. writeln(implemfile,';');
  495. shift(2);
  496. if block_spec^.typ=t_statement_list then
  497. write_statement_block(implemfile,block_spec);
  498. popshift;
  499. end;
  500. end;
  501. IsExtern:=false;
  502. if not(compactmode) and not(createdynlib) then
  503. writeln(outfile);
  504. until not NeedEllipsisOverload;
  505. end
  506. else (* decllist_spec^.p1^.p1^.typ=t_procdef *)
  507. if assigned(decllist_spec)and assigned(decllist_spec^.p1) then
  508. begin
  509. shift(2);
  510. if block_type<>bt_var then
  511. begin
  512. if not(compactmode) then
  513. writeln(outfile);
  514. writeln(outfile,aktspace,'var');
  515. end;
  516. block_type:=bt_var;
  517. shift(2);
  518. IsExtern:=assigned(decl)and(decl^.str='extern');
  519. (* walk through all declarations *)
  520. hp:=decllist_spec;
  521. while assigned(hp) and assigned(hp^.p1) do
  522. begin
  523. (* write new var name *)
  524. if assigned(hp^.p1^.p2) and assigned(hp^.p1^.p2^.p) then
  525. write(outfile,aktspace,hp^.p1^.p2^.p);
  526. write(outfile,' : ');
  527. shift(2);
  528. (* write its type *)
  529. write_p_a_def(outfile,hp^.p1^.p1,type_spec);
  530. if assigned(hp^.p1^.p2)and assigned(hp^.p1^.p2^.p)then
  531. begin
  532. if isExtern then
  533. write(outfile,';cvar;external')
  534. else
  535. write(outfile,';cvar;public');
  536. end;
  537. writeln(outfile,';');
  538. popshift;
  539. hp:=hp^.p2;
  540. end;
  541. popshift;
  542. popshift;
  543. end;
  544. if assigned(decl) then
  545. dispose(decl,done);
  546. if assigned(type_spec) then
  547. dispose(type_spec,done);
  548. if assigned(modifier_spec) then
  549. dispose(modifier_spec,done);
  550. if assigned(decllist_spec) then
  551. dispose(decllist_spec,done);
  552. if assigned(block_spec) then
  553. dispose(block_spec,done);
  554. end;
  555. function HandleDeclarationSysTrap(decl, type_spec, modifier_spec,
  556. decllist_spec, sys_trap: presobject): presobject;
  557. var
  558. hp : presobject;
  559. begin
  560. HandleDeclarationSysTrap:=Nil;
  561. IsExtern:=false;
  562. (* by default we must pop the args pushed on stack *)
  563. no_pop:=false;
  564. if (assigned(decllist_spec)and assigned(decllist_spec^.p1)and assigned(decllist_spec^.p1^.p1))
  565. and (decllist_spec^.p1^.p1^.typ=t_procdef) then
  566. begin
  567. repeat
  568. If UseLib then
  569. IsExtern:=true
  570. else
  571. IsExtern:=assigned(decl)and(decl^.str='extern');
  572. no_pop:=assigned(modifier_spec) and (modifier_spec^.str='no_pop');
  573. if (block_type<>bt_func) and not(createdynlib) then
  574. begin
  575. writeln(outfile);
  576. block_type:=bt_func;
  577. end;
  578. (* dyn. procedures must be put into a var block *)
  579. if createdynlib then
  580. begin
  581. if (block_type<>bt_var) then
  582. begin
  583. if not(compactmode) then
  584. writeln(outfile);
  585. writeln(outfile,aktspace,'var');
  586. block_type:=bt_var;
  587. end;
  588. shift(2);
  589. end;
  590. if not CompactMode then
  591. begin
  592. write(outfile,aktspace);
  593. if not IsExtern then
  594. write(implemfile,aktspace);
  595. end;
  596. (* distinguish between procedure and function *)
  597. if assigned(type_spec) then
  598. if (type_spec^.typ=t_void) and (decllist_spec^.p1^.p1^.p1=nil) then
  599. begin
  600. if createdynlib then
  601. begin
  602. write(outfile,decllist_spec^.p1^.p2^.p,' : procedure');
  603. end
  604. else
  605. begin
  606. shift(10);
  607. write(outfile,'procedure ',decllist_spec^.p1^.p2^.p);
  608. end;
  609. if assigned(decllist_spec^.p1^.p1^.p2) then
  610. write_args(outfile,decllist_spec^.p1^.p1^.p2);
  611. if createdynlib then
  612. begin
  613. loaddynlibproc.add('pointer('+decllist_spec^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+decllist_spec^.p1^.p2^.p+''');');
  614. freedynlibproc.add(decllist_spec^.p1^.p2^.p+':=nil;');
  615. end
  616. else if not IsExtern then
  617. begin
  618. write(implemfile,'procedure ',decllist_spec^.p1^.p2^.p);
  619. if assigned(decllist_spec^.p1^.p1^.p2) then
  620. write_args(implemfile,decllist_spec^.p1^.p1^.p2);
  621. end;
  622. end
  623. else
  624. begin
  625. if createdynlib then
  626. begin
  627. write(outfile,decllist_spec^.p1^.p2^.p,' : function');
  628. end
  629. else
  630. begin
  631. shift(9);
  632. write(outfile,'function ',decllist_spec^.p1^.p2^.p);
  633. end;
  634. if assigned(decllist_spec^.p1^.p1^.p2) then
  635. write_args(outfile,decllist_spec^.p1^.p1^.p2);
  636. write(outfile,':');
  637. write_p_a_def(outfile,decllist_spec^.p1^.p1^.p1,type_spec);
  638. if createdynlib then
  639. begin
  640. loaddynlibproc.add('pointer('+decllist_spec^.p1^.p2^.p+'):=GetProcAddress(hlib,'''+decllist_spec^.p1^.p2^.p+''');');
  641. freedynlibproc.add(decllist_spec^.p1^.p2^.p+':=nil;');
  642. end
  643. else if not IsExtern then
  644. begin
  645. write(implemfile,'function ',decllist_spec^.p1^.p2^.p);
  646. if assigned(decllist_spec^.p1^.p1^.p2) then
  647. write_args(implemfile,decllist_spec^.p1^.p1^.p2);
  648. write(implemfile,':');
  649. old_in_args:=in_args;
  650. (* write pointers as P.... instead of ^.... *)
  651. in_args:=true;
  652. write_p_a_def(implemfile,decllist_spec^.p1^.p1^.p1,type_spec);
  653. in_args:=old_in_args;
  654. end;
  655. end;
  656. if assigned(sys_trap) then
  657. write(outfile,';systrap ',sys_trap^.p);
  658. (* No CDECL in interface for Uselib *)
  659. if IsExtern and (not no_pop) then
  660. write(outfile,';cdecl');
  661. popshift;
  662. if createdynlib then
  663. begin
  664. writeln(outfile,';');
  665. end
  666. else if UseLib then
  667. begin
  668. if IsExtern then
  669. begin
  670. write (outfile,';external');
  671. If UseName then
  672. Write(outfile,' External_library name ''',decllist_spec^.p1^.p2^.p,'''');
  673. end;
  674. writeln(outfile,';');
  675. end
  676. else
  677. begin
  678. writeln(outfile,';');
  679. if not IsExtern then
  680. begin
  681. writeln(implemfile,';');
  682. writeln(implemfile,aktspace,'begin');
  683. writeln(implemfile,aktspace,' { You must implement this function }');
  684. writeln(implemfile,aktspace,'end;');
  685. end;
  686. end;
  687. IsExtern:=false;
  688. if not(compactmode) and not(createdynlib) then
  689. writeln(outfile);
  690. until not NeedEllipsisOverload;
  691. end
  692. else (* decllist_spec^.p1^.p1^.typ=t_procdef *)
  693. if assigned(decllist_spec)and assigned(decllist_spec^.p1) then
  694. begin
  695. shift(2);
  696. if block_type<>bt_var then
  697. begin
  698. if not(compactmode) then
  699. writeln(outfile);
  700. writeln(outfile,aktspace,'var');
  701. end;
  702. block_type:=bt_var;
  703. shift(2);
  704. IsExtern:=assigned(decl)and(decl^.str='extern');
  705. (* walk through all declarations *)
  706. hp:=decllist_spec;
  707. while assigned(hp) and assigned(hp^.p1) do
  708. begin
  709. (* write new var name *)
  710. if assigned(hp^.p1^.p2) and assigned(hp^.p1^.p2^.p) then
  711. write(outfile,aktspace,hp^.p1^.p2^.p);
  712. write(outfile,' : ');
  713. shift(2);
  714. (* write its type *)
  715. write_p_a_def(outfile,hp^.p1^.p1,type_spec);
  716. if assigned(hp^.p1^.p2)and assigned(hp^.p1^.p2^.p)then
  717. begin
  718. if isExtern then
  719. write(outfile,';cvar;external')
  720. else
  721. write(outfile,';cvar;public');
  722. end;
  723. writeln(outfile,';');
  724. popshift;
  725. hp:=hp^.p2;
  726. end;
  727. popshift;
  728. popshift;
  729. end;
  730. if assigned(decl)then dispose(decl,done);
  731. if assigned(type_spec)then dispose(type_spec,done);
  732. if assigned(decllist_spec)then dispose(decllist_spec,done);
  733. end;
  734. function HandleSpecialType(aType: presobject) : presobject;
  735. var
  736. hp : presobject;
  737. begin
  738. HandleSpecialType:=Nil;
  739. if block_type<>bt_type then
  740. begin
  741. if not(compactmode) then
  742. writeln(outfile);
  743. writeln(outfile,aktspace,'type');
  744. block_type:=bt_type;
  745. end;
  746. shift(2);
  747. if ( aType^.p2 <> nil ) then
  748. begin
  749. (* write new type name *)
  750. TN:=TypeName(aType^.p2^.p);
  751. PN:=PointerName(aType^.p2^.p);
  752. (* define a Pointer type also for structs *)
  753. if UsePPointers and (Uppercase(tn)<>Uppercase(pn)) and
  754. assigned(aType) and (aType^.typ in [t_uniondef,t_structdef]) then
  755. writeln(outfile,aktspace,PN,' = ^',TN,';');
  756. write(outfile,aktspace,TN,' = ');
  757. shift(2);
  758. hp:=aType;
  759. write_type_specifier(outfile,hp);
  760. popshift;
  761. (* enum_to_const can make a switch to const *)
  762. if block_type=bt_type then
  763. writeln(outfile,';');
  764. writeln(outfile);
  765. flush(outfile);
  766. popshift;
  767. if must_write_packed_field then
  768. write_packed_fields_info(outfile,hp,TN);
  769. if assigned(hp) then
  770. dispose(hp,done)
  771. end
  772. else
  773. begin
  774. TN:=TypeName(aType^.str);
  775. PN:=PointerName(aType^.str);
  776. if UsePPointers then writeln(outfile,aktspace,PN,' = ^',TN,';');
  777. if PackRecords then
  778. writeln(outfile, aktspace, TN, ' = packed record')
  779. else
  780. writeln(outfile, aktspace, TN, ' = record');
  781. writeln(outfile, aktspace, ' {undefined structure}');
  782. writeln(outfile, aktspace, ' end;');
  783. writeln(outfile);
  784. popshift;
  785. end;
  786. end;
  787. function HandleTypedef(type_spec,dec_modifier,declarator,arg_decl_list: presobject) : presobject;
  788. var
  789. hp : presobject;
  790. begin
  791. hp:=nil;
  792. HandleTypedef:=nil;
  793. (* TYPEDEF type_specifier LKLAMMER dec_modifier declarator RKLAMMER maybe_space LKLAMMER argument_declaration_list RKLAMMER SEMICOLON *)
  794. if block_type<>bt_type then
  795. begin
  796. if not(compactmode) then
  797. writeln(outfile);
  798. writeln(outfile,aktspace,'type');
  799. block_type:=bt_type;
  800. end;
  801. no_pop:=assigned(dec_modifier) and (dec_modifier^.str='no_pop');
  802. shift(2);
  803. (* walk through all declarations *)
  804. hp:=declarator;
  805. if assigned(hp) then
  806. begin
  807. hp:=declarator;
  808. while assigned(hp^.p1) do
  809. hp:=hp^.p1;
  810. hp^.p1:=new(presobject,init_two(t_procdef,nil,arg_decl_list));
  811. hp:=declarator;
  812. if assigned(hp^.p1) and assigned(hp^.p1^.p1) then
  813. begin
  814. writeln(outfile);
  815. (* write new type name *)
  816. write(outfile,aktspace,TypeName(hp^.p2^.p),' = ');
  817. shift(2);
  818. write_p_a_def(outfile,hp^.p1,type_spec);
  819. popshift;
  820. (* if no_pop it is normal fpc calling convention *)
  821. if is_procvar and
  822. (not no_pop) then
  823. write(outfile,';cdecl');
  824. writeln(outfile,';');
  825. flush(outfile);
  826. end;
  827. end;
  828. popshift;
  829. if assigned(type_spec)then
  830. dispose(type_spec,done);
  831. if assigned(dec_modifier)then
  832. dispose(dec_modifier,done);
  833. if assigned(declarator)then (* disposes also arg_decl_list *)
  834. dispose(declarator,done);
  835. end;
  836. function HandleTypedefList(type_spec,dec_modifier,declarator_list: presobject) : presobject;
  837. var
  838. hp,ph : presobject;
  839. begin
  840. HandleTypedefList:=Nil;
  841. ph:=nil;
  842. (* TYPEDEF type_specifier dec_modifier declarator_list SEMICOLON *)
  843. if block_type<>bt_type then
  844. begin
  845. if not(compactmode) then
  846. writeln(outfile);
  847. writeln(outfile,aktspace,'type');
  848. block_type:=bt_type;
  849. end
  850. else
  851. writeln(outfile);
  852. no_pop:=assigned(dec_modifier) and (dec_modifier^.str='no_pop');
  853. shift(2);
  854. (* Get the name to write the type definition for, try
  855. to use the tag name first *)
  856. if assigned(type_spec^.p2) then
  857. begin
  858. ph:=type_spec^.p2;
  859. end
  860. else
  861. begin
  862. if not assigned(declarator_list) then
  863. internalerror(5555);
  864. if not assigned(declarator_list^.p1) then
  865. internalerror(666);
  866. if not assigned(declarator_list^.p1^.p2) then
  867. internalerror(4444);
  868. ph:=declarator_list^.p1^.p2;
  869. end;
  870. (* write type definition *)
  871. is_procvar:=false;
  872. TN:=TypeName(ph^.p);
  873. PN:=PointerName(ph^.p);
  874. if UsePPointers and (Uppercase(tn)<>Uppercase(pn)) and
  875. assigned(type_spec) and (type_spec^.typ<>t_procdef) then
  876. writeln(outfile,aktspace,PN,' = ^',TN,';');
  877. (* write new type name *)
  878. write(outfile,aktspace,TN,' = ');
  879. shift(2);
  880. write_p_a_def(outfile,declarator_list^.p1^.p1,type_spec);
  881. popshift;
  882. (* if no_pop it is normal fpc calling convention *)
  883. if is_procvar and
  884. (not no_pop) then
  885. write(outfile,';cdecl');
  886. writeln(outfile,';');
  887. flush(outfile);
  888. (* write alias names, ph points to the name already used *)
  889. hp:=declarator_list;
  890. while assigned(hp) do
  891. begin
  892. if (hp<>ph) and assigned(hp^.p1^.p2) then
  893. begin
  894. PN:=TypeName(ph^.p);
  895. TN:=TypeName(hp^.p1^.p2^.p);
  896. if Uppercase(TN)<>Uppercase(PN) then
  897. begin
  898. write(outfile,aktspace,TN,' = ');
  899. write_p_a_def(outfile,hp^.p1^.p1,ph);
  900. writeln(outfile,';');
  901. PN:=PointerName(hp^.p1^.p2^.p);
  902. if UsePPointers and (Uppercase(tn)<>Uppercase(pn)) and
  903. assigned(type_spec) and (type_spec^.typ<>t_procdef) then
  904. writeln(outfile,aktspace,PN,' = ^',TN,';');
  905. end;
  906. end;
  907. hp:=hp^.next;
  908. end;
  909. popshift;
  910. if must_write_packed_field then
  911. if assigned(ph) then
  912. write_packed_fields_info(outfile,type_spec,ph^.str)
  913. else if assigned(type_spec^.p2) then
  914. write_packed_fields_info(outfile,type_spec,type_spec^.p2^.str);
  915. if assigned(type_spec)then
  916. dispose(type_spec,done);
  917. if assigned(dec_modifier)then
  918. dispose(dec_modifier,done);
  919. if assigned(declarator_list)then
  920. dispose(declarator_list,done);
  921. end;
  922. function HandleStructDef(dname1,dname2 : presobject) : presobject;
  923. begin
  924. HandleStructDef:=nil;
  925. (* TYPEDEF STRUCT dname dname SEMICOLON *)
  926. if block_type<>bt_type then
  927. begin
  928. if not(compactmode) then
  929. writeln(outfile);
  930. writeln(outfile,aktspace,'type');
  931. block_type:=bt_type;
  932. end;
  933. PN:=TypeName(dname1^.p);
  934. TN:=TypeName(dname2^.p);
  935. if Uppercase(tn)<>Uppercase(pn) then
  936. begin
  937. shift(2);
  938. writeln(outfile,aktspace,PN,' = ',TN,';');
  939. popshift;
  940. end;
  941. if assigned(dname1) then
  942. dispose(dname1,done);
  943. if assigned(dname2) then
  944. dispose(dname2,done);
  945. end;
  946. function HandleSimpleTypeDef(tname : presobject) : presobject;
  947. begin
  948. HandleSimpleTypeDef:=Nil;
  949. if block_type<>bt_type then
  950. begin
  951. if not(compactmode) then
  952. writeln(outfile);
  953. writeln(outfile,aktspace,'type');
  954. block_type:=bt_type;
  955. end
  956. else
  957. writeln(outfile);
  958. shift(2);
  959. (* write as pointer *)
  960. writeln(outfile,'(* generic typedef *)');
  961. writeln(outfile,aktspace,tname^.p,' = pointer;');
  962. flush(outfile);
  963. popshift;
  964. if assigned(tname) then
  965. dispose(tname,done);
  966. end;
  967. function HandleErrorDecl(e1,e2 : presobject) : presobject;
  968. begin
  969. HandleErrorDecl:=Nil;
  970. writeln(outfile,'in declaration at line ',line_no,' *)');
  971. aktspace:='';
  972. in_space_define:=0;
  973. in_define:=false;
  974. arglevel:=0;
  975. if_nb:=0;
  976. aktspace:=' ';
  977. resetshift;
  978. yyerrok;
  979. end;
  980. function HandleDefine(dname : presobject) : presobject;
  981. begin
  982. HandleDefine:=Nil;
  983. writeln(outfile,'{$define ',dname^.p,'}',aktspace,commentstr);
  984. flush(outfile);
  985. if assigned(dname)then
  986. dispose(dname,done);
  987. end;
  988. function HandleDefineConst(dname,def_expr: presobject) : presobject;
  989. var
  990. hp : presobject;
  991. begin
  992. HandleDefineConst:=Nil;
  993. (* DEFINE dname SPACE_DEFINE def_expr NEW_LINE *)
  994. if (def_expr^.typ=t_exprlist) and
  995. def_expr^.p1^.is_const and
  996. not assigned(def_expr^.next) then
  997. begin
  998. if block_type<>bt_const then
  999. begin
  1000. if block_type<>bt_func then
  1001. writeln(outfile);
  1002. writeln(outfile,aktspace,'const');
  1003. end;
  1004. block_type:=bt_const;
  1005. shift(2);
  1006. write(outfile,aktspace,dname^.p);
  1007. write(outfile,' = ');
  1008. flush(outfile);
  1009. write_expr(outfile,def_expr^.p1);
  1010. writeln(outfile,';',aktspace,commentstr);
  1011. popshift;
  1012. if assigned(dname) then
  1013. dispose(dname,done);
  1014. if assigned(def_expr) then
  1015. dispose(def_expr,done);
  1016. end
  1017. else
  1018. begin
  1019. if block_type<>bt_func then
  1020. writeln(outfile);
  1021. if not stripinfo then
  1022. begin
  1023. writeln (outfile,aktspace,'{ was #define dname def_expr }');
  1024. writeln (implemfile,aktspace,'{ was #define dname def_expr }');
  1025. end;
  1026. block_type:=bt_func;
  1027. write(outfile,aktspace,'function ',dname^.p);
  1028. write(implemfile,aktspace,'function ',dname^.p);
  1029. shift(2);
  1030. if not assigned(def_expr^.p3) then
  1031. begin
  1032. writeln(outfile,' : longint; { return type might be wrong }');
  1033. flush(outfile);
  1034. writeln(implemfile,' : longint; { return type might be wrong }');
  1035. end
  1036. else
  1037. begin
  1038. write(outfile,' : ');
  1039. write_type_specifier(outfile,def_expr^.p3);
  1040. writeln(outfile,';',aktspace,commentstr);
  1041. flush(outfile);
  1042. write(implemfile,' : ');
  1043. write_type_specifier(implemfile,def_expr^.p3);
  1044. writeln(implemfile,';');
  1045. end;
  1046. writeln(outfile);
  1047. flush(outfile);
  1048. hp:=new(presobject,init_two(t_funcname,dname,def_expr));
  1049. write_funexpr(implemfile,hp);
  1050. popshift;
  1051. dispose(hp,done);
  1052. writeln(implemfile);
  1053. flush(implemfile);
  1054. end;
  1055. end;
  1056. function HandleDefineMacro(dname,enum_list,para_def_expr: presobject) : presobject;
  1057. var
  1058. hp,ph : presobject;
  1059. begin
  1060. HandleDefineMacro:=Nil;
  1061. hp:=nil;
  1062. ph:=nil;
  1063. (* DEFINE dname LKLAMMER enum_list RKLAMMER para_def_expr NEW_LINE *)
  1064. if not stripinfo then
  1065. begin
  1066. writeln (outfile,aktspace,'{ was #define dname(params) para_def_expr }');
  1067. writeln (implemfile,aktspace,'{ was #define dname(params) para_def_expr }');
  1068. if assigned(enum_list) then
  1069. begin
  1070. writeln (outfile,aktspace,'{ argument types are unknown }');
  1071. writeln (implemfile,aktspace,'{ argument types are unknown }');
  1072. end;
  1073. if not assigned(para_def_expr^.p3) then
  1074. begin
  1075. writeln(outfile,aktspace,'{ return type might be wrong } ');
  1076. writeln(implemfile,aktspace,'{ return type might be wrong } ');
  1077. end;
  1078. end;
  1079. if block_type<>bt_func then
  1080. writeln(outfile);
  1081. block_type:=bt_func;
  1082. write(outfile,aktspace,'function ',dname^.p);
  1083. write(implemfile,aktspace,'function ',dname^.p);
  1084. if assigned(enum_list) then
  1085. begin
  1086. write(outfile,'(');
  1087. write(implemfile,'(');
  1088. ph:=new(presobject,init_one(t_enumdef,enum_list));
  1089. write_def_params(outfile,ph);
  1090. write_def_params(implemfile,ph);
  1091. if assigned(ph) then dispose(ph,done);
  1092. ph:=nil;
  1093. (* types are unknown *)
  1094. write(outfile,' : longint)');
  1095. write(implemfile,' : longint)');
  1096. end;
  1097. if not assigned(para_def_expr^.p3) then
  1098. begin
  1099. writeln(outfile,' : longint;',aktspace,commentstr);
  1100. writeln(implemfile,' : longint;');
  1101. flush(outfile);
  1102. end
  1103. else
  1104. begin
  1105. write(outfile,' : ');
  1106. write_type_specifier(outfile,para_def_expr^.p3);
  1107. writeln(outfile,';',aktspace,commentstr);
  1108. flush(outfile);
  1109. write(implemfile,' : ');
  1110. write_type_specifier(implemfile,para_def_expr^.p3);
  1111. writeln(implemfile,';');
  1112. end;
  1113. writeln(outfile);
  1114. flush(outfile);
  1115. hp:=new(presobject,init_two(t_funcname,dname,para_def_expr));
  1116. write_funexpr(implemfile,hp);
  1117. writeln(implemfile);
  1118. flush(implemfile);
  1119. if assigned(hp)then dispose(hp,done);
  1120. end;
  1121. end.