h2pbase.pp 35 KB

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