fd2pascal.pp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. Program fd2pascal;
  2. { ---------------------------------------------------------------------------
  3. Program to convert forms fdesign file to pascal code
  4. Copyright (C) 1997 Michael Van Canneyt
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. --------------------------------------------------------------------------- }
  17. { $Id$ }
  18. Uses linux;
  19. Const RevString = '$Revision$';
  20. NrOptions = 4;
  21. Options : Array[0..NrOptions] Of String[20] =
  22. ('v','callback','main','altformat','compensate');
  23. Type
  24. { Properties of an object }
  25. ContProps=(CPclass,CPtype,CPbox,CPBoxtype,CPColors,CPalignment,CPstyle,CPsize,
  26. CPlcol,CPlabel,CPShortcut,CPresize,CPgravity,CPname,CPCallback,
  27. CPargument,
  28. CPinvalid);
  29. { Properties of an object for which defaults must be set }
  30. AdjProps=(APClass,APBoxtype,ApColors,APAlignment,APSize,APLcol,APstyle,APgravity);
  31. { List of all object classes }
  32. ObjClasses=(FL_INVALID,FL_BUTTON, FL_LIGHTBUTTON,FL_ROUNDBUTTON, FL_ROUND3DBUTTON,
  33. FL_CHECKBUTTON, FL_BITMAPBUTTON, FL_PIXMAPBUTTON,FL_BITMAP, FL_PIXMAP,
  34. FL_BOX, FL_TEXT, FL_MENU, FL_CHART, FL_CHOICE, FL_COUNTER, FL_SLIDER, FL_VALSLIDER, FL_INPUT,
  35. FL_BROWSER,FL_DIAL,FL_TIMER,FL_CLOCK, FL_POSITIONER, FL_FREE,
  36. FL_XYPLOT,FL_FRAME, FL_LABELFRAME, FL_CANVAS, FL_GLCANVAS,
  37. FL_IMAGECANVAS, FL_FOLDER);
  38. { Properties in preamble }
  39. PreProps=(PPmagic,PPNrforms,PPUnitofMeasure,PPinvalid);
  40. { Properties of a form }
  41. FormProps=(FPName,FPWidth,FPHeight,FPnumObjs,FPinvalid);
  42. Const
  43. { Names of all object properties }
  44. ContPropNames : Array[ContProps] of string[20] =
  45. ('class','type','box','boxtype','colors','alignment','style','size',
  46. 'lcol','label','shortcut','resize','gravity','name','callback',
  47. 'argument',
  48. 'invalid');
  49. { Names of all object properties which must be checked.}
  50. AdjPropsNames : Array[AdjProps] of string[20] =
  51. ('class','boxtype','colors','alignment','size','lcol','style','gravity');
  52. { Names of all preamble properties }
  53. PrePropNames : Array[PreProps] of string[20] =
  54. ('Magic','Number of forms','Unit of measure','Invalid');
  55. { Names of all form properties }
  56. FormPropNames : Array[FormProps] of string[20] =
  57. ('Name','Width','Height','Number of Objects','Invalid');
  58. { Names of all object classes }
  59. FObjClassNames : Array[ObjClasses] of string[20]=
  60. ('FL_INVALID','BUTTON', 'LIGHTBUTTON','ROUNDBUTTON', 'ROUND3DBUTTON',
  61. 'CHECKBUTTON', 'BITMAPBUTTON', 'PIXMAPBUTTON','BITMAP', 'PIXMAP',
  62. 'BOX', 'TEXT', 'MENU', 'CHART', 'CHOICE', 'COUNTER', 'SLIDER', 'VALSLIDER', 'INPUT',
  63. 'BROWSER','DIAL','TIMER','CLOCK', 'POSITIONER', 'FREE',
  64. 'XYPLOT','FRAME', 'LABELFRAME', 'CANVAS', 'GLCANVAS',
  65. 'IMAGECANVAS', 'FOLDER');
  66. { Default properties. If empty a property is ignored.
  67. To force setting of a property, put 'FL_FORCE' as a string.
  68. Mind : Case sensitive }
  69. DefProps : array[ObjClasses,AdjProps] of string[25] =
  70. (('FL_INVALID','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  71. ('BUTTON','FL_UP_BOX','FL_COL1 FL_COL1','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  72. ('LIGHTBUTTON','FL_UP_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  73. ('ROUNDBUTTON','FL_NO_BOX','FL_MCOL FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  74. ('ROUND3DBUTTON','FL_NO_BOX','FL_COL1 FL_BLACK','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  75. ('CHECKBUTTON','FL_NO_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  76. ('BITMAPBUTTON','FL_UP_BOX','FL_COL1 FL_BLUE','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  77. ('PIXMAPBUTTON','FL_UP_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  78. ('BITMAP','FL_NO_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  79. ('PIXMAP','FL_NO_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  80. ('BOX','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  81. ('TEXT','FL_FLAT_BOX','FL_COL1 FL_MCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  82. ('MENU','FL_BORDER_BOX','FL_COL1 FL_MCOL','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  83. ('CHART','FL_BORDER_BOX','FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  84. ('CHOICE','FL_ROUNDED_BOX','FL_COL1 FL_LCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  85. ('COUNTER','FL_UP_BOX','FL_COL1 FL_BLUE','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  86. ('SLIDER','FL_DOWN_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  87. ('VALSLIDER','FL_DOWN_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  88. ('INPUT','FL_DOWN_BOX','FL_COL1 FL_MCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  89. ('BROWSER','FL_DOWN_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_BOTTOM','FL_SMALL_FONT','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  90. ('DIAL','FL_FLAT_BOX','FL_COL1 FL_RIGHT_BCOL','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  91. ('TIMER','FL_DOWN_BOX','FL_COL1 FL_RED','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  92. ('CLOCK','FL_UP_BOX','FL_INACTIVE_COL FL_BOTTOM_BCOL','FL_ALIGN_BOTTOM','','FL_BLACK','FL_NORMAL_STYLE','FL_FORCE'),
  93. ('POSITIONER','FL_DOWN_BOX','FL_COL1 FL_RED','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  94. ('FREE','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  95. ('XYPLOT','FL_FLAT_BOX','FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  96. ('FRAME','','FL_BLACK FL_COL1','','','FL_BLACK','FL_NORMAL_STYLE','FL_FORCE'),
  97. ('LABELFRAME','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  98. ('CANVAS','FL_NO_BOX','','FL_ALIGN_TOP','','','FL_NORMAL_STYLE','FL_FORCE'),
  99. ('GLCANVAS','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  100. ('IMAGECANVAS','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  101. ('FOLDER','','','','','','FL_NORMAL_STYLE','FL_FORCE'));
  102. Type
  103. { object data type }
  104. PControl = ^TControl;
  105. TControl = Record
  106. Props : array[ContProps] of string;
  107. NextControl : PControl;
  108. end;
  109. { Form data type}
  110. PFormRec = ^TFormRec;
  111. TFormRec = Record
  112. Name : String;
  113. Width,Height : String[5];
  114. Controls : PControl;
  115. NextForm : PFormRec;
  116. end;
  117. { Callback data type }
  118. PCBrec = ^TCBrec;
  119. TCBrec = record
  120. name : string;
  121. next : PCBrec;
  122. end;
  123. { Property emitting procedures }
  124. EmitProp = Procedure (Data : PControl;ObjClass : ObjClasses);
  125. Var
  126. OptionsSet : Array[1..NrOptions] Of Boolean;
  127. FileName : String;
  128. Infile,outfile : Text;
  129. Magic : String[20];
  130. LineNr : Longint;
  131. NrForms,NrControls : Longint;
  132. UnitOfMeasure : string;
  133. FormRoot : PFormRec;
  134. cbroot : pcbrec;
  135. { Default properties emitters }
  136. EmitProcs : array [AdjProps] of EmitProp;
  137. { Class specific property emitters. Nil pointers are ignored.}
  138. ClassEmitters : Array[ObjClasses] of EmitProp;
  139. { ------------------------------------------------------------------------
  140. Utilities Code
  141. ------------------------------------------------------------------------ }
  142. Function IntTostr (s : Longint) : String;
  143. var temp : String;
  144. begin
  145. str(s,temp);
  146. IntToStr:=Temp;
  147. end;
  148. Procedure EmitError (Const s : String);
  149. begin
  150. writeln (stderr,'Error: ',s);
  151. flush(stderr)
  152. end;
  153. Procedure EmitLineError (Const s : string);
  154. begin
  155. EmitError('Line '+IntToStr(LineNr)+': '+s)
  156. end;
  157. { ------------------------------------------------------------------------
  158. Option handling Code
  159. ------------------------------------------------------------------------ }
  160. Procedure DoOptions;
  161. Var i,j,k : byte;
  162. os : string;
  163. Procedure ShowVersion;
  164. begin
  165. Writeln ('fd2pascal : ',RevString);
  166. Halt(0);
  167. end;
  168. Procedure ShowUsage;
  169. begin
  170. Writeln ('fd2pascal : usage :');
  171. writeln (' fd2pascal [options] filename');
  172. writeln (' Where [options] may be zero or more of :');
  173. writeln (' -compensate Emit size-compensation code.');
  174. writeln (' -altformat Emit code in alternate format.');
  175. writeln (' -main Emit program instead of unit.');
  176. writeln (' -callback Emit callback stubs.');
  177. writeln;
  178. halt(0);
  179. end;
  180. begin
  181. if paramcount=0 then
  182. ShowUsage;
  183. FileName:='';
  184. for i:=1 to paramcount do
  185. begin
  186. if paramstr(i)[1]<>'-' then
  187. If FileName<>'' then
  188. EmitError('Only one filename supported. Ignoring :'+paramstr(i))
  189. else
  190. Filename:=Paramstr(i)
  191. else
  192. begin
  193. os:=copy(paramstr(i),2,length(paramstr(i))-1);
  194. k:=NrOptions+1;
  195. for j:=0 to NrOptions do
  196. if os=options[j] then k:=j;
  197. if k=NrOptions+1 then
  198. EmitError('Option not recognised : '+paramstr(i))
  199. else
  200. if k=0 then ShowVersion else OptionsSet[k]:=True;
  201. end
  202. end; {for}
  203. if FileName='' then
  204. begin
  205. EmitError('No filename supplied. Exiting.');
  206. halt(1);
  207. end;
  208. end;
  209. { ------------------------------------------------------------------------
  210. Code for reading the input file.
  211. ------------------------------------------------------------------------ }
  212. Procedure OpenFile;
  213. begin
  214. if pos('.fd',FileName)=0 then
  215. FileName:=FileName+'.fd';
  216. assign(infile,Filename);
  217. {$i-}
  218. reset (infile);
  219. {$i+}
  220. if ioresult<>0 then
  221. begin
  222. EmitError('Can''t open : '+filename);
  223. halt(1);
  224. end;
  225. LineNr:=0;
  226. end;
  227. Procedure CloseFile;
  228. begin
  229. Close(infile);
  230. end;
  231. Procedure GetLine(Var S : String);
  232. begin
  233. inc(LineNr);
  234. Readln(infile,s);
  235. {$ifdef debug}
  236. writeln ('Reading line : ',linenr)
  237. {$endif}
  238. end;
  239. Procedure ProcessPreAmbleLine (Const s: String);
  240. var key,value : string;
  241. ppos : Longint;
  242. i,k : PreProps;
  243. code : Word;
  244. begin
  245. if s='' then exit;
  246. ppos:=pos(':',s);
  247. if ppos=0 then
  248. exit;
  249. Key:=Copy(s,1,ppos-1);
  250. Value:=Copy(s,ppos+2,length(s)-ppos-1);
  251. k:=PPinvalid;
  252. for i:=PPmagic to PPinvalid do
  253. if key=PrePropNames[i] then k:=i;
  254. if k=PPinvalid then
  255. EmitLineError('Unknown keyword : '+Key)
  256. else
  257. Case K of
  258. PPMagic : Magic:=key;
  259. PPnrforms: begin
  260. val(value,NrForms,code);
  261. if code<>0 then EmitLineError('Invalid number of forms');
  262. end;
  263. PPunitofmeasure: UnitOfMeasure:=Value;
  264. end;
  265. end;
  266. { ------------------------------------------------------------------------
  267. Code for reading preamble.
  268. ------------------------------------------------------------------------ }
  269. Procedure DoPreamble;
  270. var line : String;
  271. begin
  272. {$ifdef debug}
  273. writeln ('Starting preamble');
  274. {$endif}
  275. Getline (line);
  276. while pos('= FORM =',line)=0 do
  277. begin
  278. ProcessPreAmbleLine(line);
  279. GetLine(Line)
  280. end;
  281. end;
  282. { ------------------------------------------------------------------------
  283. Code for reading 1 object.
  284. ------------------------------------------------------------------------ }
  285. Procedure ProcessControlLine (PC : PControl; const S : String);
  286. Var Key,Value : String;
  287. i,k : ContProps;
  288. ppos,code : word;
  289. begin
  290. if s='' then exit;
  291. ppos:=pos(':',s);
  292. if ppos=0 then
  293. exit;
  294. Key:=Copy(s,1,ppos-1);
  295. Value:=Copy(s,ppos+2,length(s)-ppos-1);
  296. K:=CPInvalid;
  297. For i:=CPclass to CPInvalid do
  298. if ContPropNames[i]=Key then k:=i;
  299. if K=CPinvalid then
  300. begin
  301. EmitLineError('Unknown keyword'+key);
  302. exit
  303. end;
  304. PC^.props[k]:=value;
  305. end;
  306. Procedure ProcessControl (PC : PControl);
  307. var line : String;
  308. begin
  309. {$ifdef debug}
  310. Writeln ('Starting Control');
  311. {$endif}
  312. Getline(Line);
  313. while Line<>'' do
  314. begin
  315. ProcessControlLine (PC,line);
  316. Getline(Line);
  317. end;
  318. Getline(Line)
  319. end;
  320. { ------------------------------------------------------------------------
  321. Code for reading 1 form.
  322. ------------------------------------------------------------------------ }
  323. Procedure ProcessFormLine (PF : PFormRec; const S : String);
  324. Var Key,Value : String;
  325. i,k : FormProps;
  326. ppos,code : word;
  327. begin
  328. if s='' then exit;
  329. ppos:=pos(':',s);
  330. if ppos=0 then
  331. exit;
  332. Key:=Copy(s,1,ppos-1);
  333. Value:=Copy(s,ppos+2,length(s)-ppos-1);
  334. K:=FPInvalid;
  335. For i:=FPName to FPInvalid do
  336. if FormPropNames[i]=Key then k:=i;
  337. if K=FPinvalid then
  338. begin
  339. EmitLineError('Unknown keyword'+key);
  340. exit
  341. end;
  342. case k of
  343. FPname : PF^.name:=value;
  344. FPWidth : PF^.width:=value;
  345. FPHeight : PF^.height:=value;
  346. FPNumObjs : begin
  347. val(value,Nrcontrols,code);
  348. If Code<>0 then EmitLineError('Invalid number of objects : '+value)
  349. end;
  350. end;
  351. end;
  352. Procedure ProcessForm (PF : PFormRec);
  353. Var line : String;
  354. CurrentControl : PControl;
  355. I : Integer;
  356. begin
  357. {$ifdef debug}
  358. writeln('Starting form');
  359. {$endif}
  360. NrControls:=0;
  361. with PF^ do
  362. begin
  363. name:='';
  364. Width:='';
  365. Height:='';
  366. Controls:=nil;
  367. GetLine(Line);
  368. while line<>'' do
  369. begin
  370. ProcessFormLine(PF,Line);
  371. GetLine(Line);
  372. end;
  373. Getline(Line);
  374. If NrControls=0 then
  375. Controls:=nil
  376. else
  377. begin
  378. New (Controls);
  379. CurrentControl:=Controls;
  380. for i:=1 to nrcontrols do
  381. begin
  382. ProcessControl(CurrentControl);
  383. if i<NrControls then
  384. New(CurrentControl^.NextControl)
  385. else
  386. CurrentControl^.NextControl:=nil;
  387. CurrentControl:=CurrentControl^.NextControl
  388. end; { for }
  389. end; { Else }
  390. end; { With }
  391. end;
  392. { ------------------------------------------------------------------------
  393. Code for reading the forms.
  394. ------------------------------------------------------------------------ }
  395. Procedure DoForms;
  396. Var Line : String;
  397. i : Longint;
  398. CurrentForm: PformRec;
  399. begin
  400. FormRoot:=Nil;
  401. if NrForms=0 then exit;
  402. new(FormRoot);
  403. Currentform:=FormRoot;
  404. for i:=1 to nrforms do
  405. begin
  406. ProcessForm (CurrentForm);
  407. If i=nrforms then
  408. Currentform^.NextForm:=nil
  409. else
  410. New(CurrentForm^.NextForm);
  411. CurrentForm:=CurrentForm^.NextForm;
  412. end;
  413. end;
  414. { ------------------------------------------------------------------------
  415. Code for reading the postamble.
  416. ------------------------------------------------------------------------ }
  417. Procedure DoPostamble;
  418. begin
  419. end;
  420. { ------------------------------------------------------------------------
  421. Code for writing the output file.
  422. ------------------------------------------------------------------------ }
  423. Procedure OpenOutFile;
  424. var info : stat;
  425. begin
  426. FileName:=Copy(Filename,1,Length(Filename)-3)+'.pp';
  427. fstat(FileName,info);
  428. if linuxerror=0 then
  429. begin
  430. { File exists, move to .bak}
  431. link (FileName,FileName+'.bak');
  432. unlink (FileName);
  433. end;
  434. assign(outfile,filename);
  435. {$i-}
  436. rewrite(outfile);
  437. {$i+}
  438. if ioresult<>0 then
  439. begin
  440. EmitError('Couldn''t open output file : '+filename);
  441. halt(1)
  442. end;
  443. end;
  444. Procedure CloseOutFile;
  445. begin
  446. Close(OutFile);
  447. end;
  448. { ------------------------------------------------------------------------
  449. Code to emit Header/variable/type declarations
  450. ------------------------------------------------------------------------ }
  451. Procedure EmitType (fp : Pformrec);
  452. var cp : PControl;
  453. begin
  454. writeln (OutFile,' TFD_',fp^.name,' = record');
  455. writeln (OutFile,' ',fp^.name,' : PFL_FORM;');
  456. writeln (OutFile,' vdata : Pointer;');
  457. writeln (OutFile,' ldata : Longint;');
  458. cp:=fp^.controls;
  459. {Skip first control, is formbackground }
  460. if cp<>nil then cp:=cp^.nextcontrol;
  461. while cp<>nil do
  462. begin
  463. if cp^.props[CPclass]<>'FL_END_GROUP' then
  464. begin
  465. write (Outfile,' ',cp^.props[CPname]);
  466. if cp^.nextcontrol<>nil then
  467. writeln (OutFile,',')
  468. else
  469. writeln (OutFile,' : PFL_OBJECT;');
  470. end;
  471. cp:=cp^.nextcontrol;
  472. end;
  473. writeln (OutFile,' end;');
  474. writeln (OutFile,' PFD_',fp^.name,' = ^TFD_',fp^.name,';');
  475. writeln (OutFile);
  476. end;
  477. Procedure EmitVar (fp : Pformrec);
  478. var cp : PControl;
  479. begin
  480. writeln (OutFile,' ',fp^.name,' : PFL_FORM;');
  481. cp:=fp^.controls;
  482. {Skip first control, is formbackground }
  483. if cp<>nil then cp:=cp^.nextcontrol;
  484. while cp<>nil do
  485. begin
  486. if cp^.props[CPclass]<>'FL_END_GROUP' then
  487. begin
  488. write (Outfile,' ',cp^.props[CPname]);
  489. if cp^.nextcontrol<>nil then
  490. writeln (OutFile,',')
  491. else
  492. writeln (OutFile,' : PFL_OBJECT;');
  493. end;
  494. cp:=cp^.nextcontrol;
  495. end;
  496. writeln (OutFile);
  497. end;
  498. Procedure EmitHeader;
  499. var fp : PFormRec;
  500. cp : PControl;
  501. begin
  502. if OptionsSet[2] then
  503. write (OutFile,'Program ')
  504. else
  505. write (OutFile,'Unit ');
  506. writeln (OutFile,basename(filename,'.pp'),';');
  507. writeln (OutFile);
  508. writeln (OutFile,'{ Form definition file generated by fd2pascal }');
  509. writeln (Outfile);
  510. if not OptionsSet[2] then
  511. begin
  512. writeln (OutFile,'Interface');
  513. writeln (OutFile);
  514. end;
  515. writeln (OutFile,'Uses forms;');
  516. writeln (OutFile);
  517. writeln (OutFile,' { Variable / Type definitions. }');
  518. if Optionsset[3] then
  519. writeln (OutFile,'Var')
  520. else
  521. writeln (OutFile,'Type');
  522. fp:=FormRoot;
  523. While fp<>nil do
  524. begin
  525. if not optionsset[3] then
  526. EmitType(fp) { Emit Type definitions }
  527. else
  528. EmitVar(fp); { Emit Variable declaration}
  529. fp:=fp^.nextform;
  530. end;
  531. if not optionsset[2] then
  532. begin
  533. { No program, we must emit interface stuff }
  534. if not (optionsset[3]) then
  535. begin
  536. { Emit normal interface declarations
  537. -> functions }
  538. fp:=formroot;
  539. while fp<>nil do
  540. begin
  541. with fp^ do
  542. writeln (OutFile,'Function create_form_',name,' : PFD_',name,';');
  543. fp:=fp^.nextform;
  544. end;
  545. end
  546. else
  547. begin
  548. { Emit alternate interface declaration
  549. -> 1 function to create all forms.}
  550. writeln (OutFile,'Procedure Create_The_Forms;');
  551. end;
  552. writeln (OutFile);
  553. writeln (OutFile,'Implementation');
  554. end
  555. else
  556. begin
  557. { We must make a program. }
  558. if not(optionsset[3]) then
  559. begin
  560. { Normal format, so we need to emit variables for the forms.}
  561. writeln (OutFile,'Var');
  562. fp:=formroot;
  563. while fp<>nil do
  564. begin
  565. writeln (OutFile,' ',fp^.name,' : PFD_',fp^.name,';');
  566. fp:=fp^.nextform;
  567. end;
  568. writeln (OutFile);
  569. end;
  570. end;
  571. writeln (OutFile);
  572. end;
  573. { ------------------------------------------------------------------------
  574. Code to emit footer/main program
  575. ------------------------------------------------------------------------ }
  576. Procedure EmitCreateforms;
  577. var fp : PFormRec;
  578. begin
  579. writeln (OutFile,'Procedure Create_The_Forms;');
  580. writeln (OutFile);
  581. writeln (OutFile,'begin');
  582. fp:=FormRoot;
  583. while fp<>nil do
  584. begin
  585. writeln(OutFile,'create_form_',fp^.name,';');
  586. fp:=fp^.nextform;
  587. end;
  588. writeln (outFile,'End;');
  589. writeln (OutFile);
  590. end;
  591. Procedure EmitAlternateMain;
  592. var fp : PFormRec;
  593. begin
  594. { Alternate format, we just call creatallforms to create all forms}
  595. writeln (OutFile,'Create_The_Forms;');
  596. writeln (OutFile,' fl_show_form(',formroot^.name,
  597. ',FL_PLACE_CENTER,FL_FULLBORDER,''',
  598. FormRoot^.name,''');');
  599. end;
  600. Procedure EmitMain;
  601. var fp : PFormRec;
  602. begin
  603. { variables are emitted in the header }
  604. fp:=formroot;
  605. { Create all forms }
  606. while fp<>nil do
  607. begin
  608. writeln (OutFile,' ',fp^.name,' :=Create_Form_',fp^.name,';');
  609. fp:=fp^.nextform;
  610. end;
  611. { Show the first form }
  612. writeln (OutFile,' fl_show_form(',formroot^.name,'^.',Formroot^.name,
  613. ',FL_PLACE_CENTER,FL_FULLBORDER,''',
  614. FormRoot^.name,''');');
  615. end;
  616. Procedure EmitFooter;
  617. var fp : PFormRec;
  618. begin
  619. if OptionsSet[3] then {Alternate format.}
  620. EmitCreateForms;
  621. if Optionsset[2] then
  622. begin
  623. {Emit Main Program}
  624. writeln (OutFile);
  625. writeln (OutFile,'Begin');
  626. writeln (OutFile,' fl_initialize (@argc,argv,''',
  627. BaseName(Filename,'.pp'),''',nil,0);');
  628. if Not(OptionsSet[3]) then
  629. EmitMain
  630. else
  631. EmitAlternateMain;
  632. writeln (OutFile,' fl_do_forms;');
  633. end
  634. else
  635. writeln (OutFile,'begin');
  636. writeln (OutFile,'end.')
  637. end;
  638. { ------------------------------------------------------------------------
  639. Code to emit properties
  640. ------------------------------------------------------------------------ }
  641. Function EmitString(S : string) : String;
  642. var temp : String;
  643. i : longint;
  644. begin
  645. temp:='''';
  646. for i:=1 to length(s) do
  647. if s[i]<>'''' then temp:=temp+s[i] else temp:=temp+'''''';
  648. Temp:=temp+'''';
  649. EmitString:=temp;
  650. end;
  651. Procedure EmitBoxtype (cp : PControl;ObjClass : ObjClasses);
  652. begin
  653. {$ifdef debug}
  654. writeln ('EmitBoxType called with args:');
  655. writeln (cp^.props[cpboxtype]);
  656. writeln (defprops[objclass,APboxtype]);
  657. writeln ('for object : ',defprops[objclass,apclass]);
  658. writeln ('With object : ',cp^.props[cpclass]);
  659. {$endif}
  660. if cp^.props[cpboxtype]<>defprops[objclass,APboxtype] then
  661. writeln (OutFile,' fl_set_object_boxtype(obj,',
  662. cp^.props[cpboxtype],');')
  663. end;
  664. Procedure EmitColors (cp : PControl;ObjClass : ObjClasses);
  665. var temp : string;
  666. begin
  667. if cp^.props[cpcolors]<>defprops[objclass,APcolors] then
  668. begin
  669. temp:=cp^.props[cpcolors];
  670. if pos(' ',temp)=0 then exit;
  671. temp[pos(' ',temp)]:=',';
  672. writeln (OutFile,' fl_set_object_color(obj,',temp,');');
  673. end;
  674. end;
  675. Procedure EmitAlignment (cp : PControl;ObjClass : ObjClasses);
  676. begin
  677. if cp^.props[cpalignment]<>defprops[objclass,APalignment] then
  678. writeln (OutFile,' fl_set_object_alignment(obj,',
  679. cp^.props[cpalignment],');');
  680. end;
  681. Procedure EmitLcol (cp : PControl;ObjClass : ObjClasses);
  682. begin
  683. if cp^.props[cplcol]<>defprops[objclass,APlcol] then
  684. writeln (OutFile,' fl_set_object_lcol(obj,',
  685. cp^.props[cplcol],');');
  686. end;
  687. Procedure EmitSize (cp : PControl;ObjClass : ObjClasses);
  688. begin
  689. if cp^.props[cpsize]<>defprops[objclass,APsize] then
  690. writeln (OutFile,' fl_set_object_lsize(obj,',
  691. cp^.props[cpsize],');');
  692. end;
  693. Procedure EmitStyle (cp : PControl;ObjClass : ObjClasses);
  694. begin
  695. if cp^.props[cpstyle]<>defprops[objclass,APstyle] then
  696. writeln (OutFile,' fl_set_object_lstyle(obj,',
  697. cp^.props[cpstyle],');');
  698. end;
  699. Procedure EmitGravity (cp : PControl;ObjClass : ObjClasses);
  700. var temp: string;
  701. begin
  702. if cp^.props[cpstyle]<>'FL_NoGravity FL_NoGravity' then
  703. begin
  704. temp:=cp^.props[cpstyle];
  705. if pos(' ',temp)=0 then exit;
  706. temp[pos(' ',temp)]:=',';
  707. writeln (OutFile,' fl_set_object_gravity(obj,',
  708. temp,');');
  709. end;
  710. end;
  711. Procedure EmitProperties (Cp : PControl; Objclass : ObjClasses);
  712. Var i : AdjProps;
  713. begin
  714. for i:=APboxtype to APgravity do
  715. if DefProps[ObjClass,i]<>'' then
  716. EmitProcs[i](cp,objclass);
  717. end;
  718. { ------------------------------------------------------------------------
  719. Code to emit objects
  720. ------------------------------------------------------------------------ }
  721. Procedure EmitObject(cp : PControl);
  722. var temp : string;
  723. Corners : array[1..4] of string[5];
  724. I : Longint;
  725. j,k : ObjClasses;
  726. begin
  727. with cp^ do
  728. begin
  729. temp:=lowercase(props[CPclass]);
  730. delete(temp,1,3);
  731. if temp='begin_group' then
  732. begin
  733. writeln (OutFile);
  734. write (OutFile,' ');
  735. if not (Optionsset[3]) then Write (OutFile,'fdui^.');
  736. writeln (OutFile,props[cpname],':=fl_bgn_group;');
  737. exit;
  738. end
  739. else if temp='end_group' then
  740. begin
  741. writeln (OutFile,' fl_end_group;');
  742. writeln (OutFile);
  743. exit;
  744. end;
  745. { Normal object. Emit creation code. }
  746. write (OutFile,' obj:=fl_add_',temp,' (FL_',props[Cptype],',');
  747. temp:=props[cpbox];
  748. for i:=1 to 3 do
  749. begin
  750. write (OutFile,copy(temp,1,pos(' ',temp)-1),',');
  751. delete (temp,1,pos(' ',temp));
  752. end;
  753. writeln (OutFile,temp,',',EmitString(props[cplabel]),');');
  754. { Emit Callback code if needed }
  755. if props[cpcallback]<>'' then
  756. begin
  757. write (OutFile,' fl_set_object_callback(obj,PFL_CALLBACKPTR(@');
  758. write (OutFile,props[CPcallback],'),');
  759. if props[CPargument]<>'' then
  760. writeln (OutFile,props[CPargument],');')
  761. else
  762. writeln (OutFile,'0);');
  763. end;
  764. { If known object, start emitting properties }
  765. temp:=props[CPclass];
  766. delete(temp,1,3);
  767. k:=FL_INVALID;
  768. for j:=FL_BUTTON to FL_FOLDER do
  769. if temp=DefProps[j,apclass] then k:=j;
  770. if k<>FL_INVALID then
  771. begin
  772. { Emit defaults }
  773. EmitProperties (cp,k);
  774. { If A class-specific emitter exists, call it.}
  775. if Assigned(ClassEmitters[k]) then
  776. ClassEmitters[k] (cp,k);
  777. end;
  778. { Assign to needed object. }
  779. if Optionsset[3] then
  780. Writeln (OutFile,' ',props[cpname],':=obj;')
  781. else
  782. Writeln (OutFile,' fdui^.',props[cpname],':=obj;');
  783. end;
  784. end;
  785. { ------------------------------------------------------------------------
  786. Code to emit forms
  787. ------------------------------------------------------------------------ }
  788. Procedure EmitForm(fp : PFormRec);
  789. Var
  790. cp : PControl;
  791. begin
  792. with fp^ do
  793. begin
  794. if Optionsset[3] then
  795. begin
  796. writeln (OutFile,'Procedure create_form_',name,';');
  797. writeln (OutFile);
  798. writeln (OutFile,'Var obj : PFL_OBJECT;');
  799. writeln (OutFile);
  800. writeln (OutFile,'Begin');
  801. writeln (OutFile,' If ',name,'<>nil then exit;');
  802. write (OutFile,' ',name);
  803. end
  804. else
  805. begin
  806. writeln (OutFile,'Function create_form_',name,' : PFD_',name,';');
  807. writeln (OutFile);
  808. writeln (OutFile,'Var obj : PFL_OBJECT;');
  809. writeln (OutFile,' fdui : PFD_',name,';');
  810. writeln (OutFile);
  811. writeln (OutFile,'Begin');
  812. writeln (OutFile,' New(fdui);');
  813. write (OutFile,' fdui^.',name);
  814. end;
  815. writeln (OutFile,':=fl_bgn_form(FL_NO_BOX,'
  816. ,width,','
  817. ,height,');');
  818. cp:=controls;
  819. writeln (OutFile,' obj:=fl_add_box(',cp^.props[CPboxtype],',0,0,',
  820. width,',',
  821. height,',',
  822. EmitString (cp^.props[CPname]),');');
  823. cp:=cp^.nextcontrol;
  824. { Emit all objects }
  825. while cp<>nil do
  826. begin
  827. EmitObject(cp);
  828. cp:=cp^.nextcontrol;
  829. end;
  830. writeln (OutFile,' fl_end_form;');
  831. if Optionsset[4] then
  832. begin
  833. { Emit Compensation code }
  834. write (OutFile,' fl_adjust_form_size(');
  835. if not(OptionsSet[3]) then write (OutFile,'fdui^.');
  836. writeln(OutFile,fp^.name,');');
  837. end;
  838. if not(OptionsSet[3]) then
  839. begin
  840. writeln (OutFile,' fdui^.',fp^.name,'^.fdui:=fdui;');
  841. writeln (OutFile,' create_form_',fp^.name,':=fdui;');
  842. end;
  843. writeln (OutFile,'end;');
  844. writeln (OutFile);
  845. end;
  846. end;
  847. Procedure EmitForms;
  848. var
  849. fp : PformRec;
  850. cp : PControl;
  851. begin
  852. { Start emitting forms }
  853. fp:=Formroot;
  854. while fp<>nil do
  855. begin
  856. EmitForm(fp);
  857. fp:=fp^.nextform;
  858. end;
  859. end;
  860. { ------------------------------------------------------------------------
  861. Code to emit callbacks
  862. ------------------------------------------------------------------------ }
  863. Procedure CollectCallbacks;
  864. Var CurrentCb,CBwalk : PCBrec;
  865. fp : PformRec;
  866. cp : PControl;
  867. begin
  868. CbRoot:=nil;
  869. CurrentCB:=cbroot;
  870. fp:=formroot;
  871. while fp<>nil do
  872. begin
  873. cp:=fp^.controls;
  874. while cp<>nil do
  875. begin
  876. if cp^.props[CPcallback]<>'' then
  877. if cbroot<>nil then
  878. begin
  879. cbwalk:=cbroot;
  880. while cbwalk<>nil do
  881. if upcase(cbwalk^.name)=upcase(cp^.props[CPcallback]) then
  882. break
  883. else
  884. cbwalk:=cbwalk^.next;
  885. if cbwalk=nil then
  886. begin
  887. new(currentcb^.next);
  888. currentcb:=currentcb^.next;
  889. currentcb^.name:=cp^.props[CPcallback];
  890. currentcb^.next:=nil;
  891. end;
  892. end
  893. else
  894. begin
  895. new(cbroot);
  896. currentcb:=cbroot;
  897. cbroot^.name:=cp^.props[CPcallback];
  898. cbroot^.next:=nil;
  899. end;
  900. cp:=cp^.nextcontrol;
  901. end;
  902. fp:=fp^.nextform;
  903. end;
  904. end;
  905. Procedure EmitCallback (Const s : string);
  906. begin
  907. writeln (OutFile,'Procedure ',s,' (Sender: PFL_OBJECT; Data : Longint); export;');
  908. writeln (OutFile);
  909. writeln (OutFile,'begin');
  910. writeln (OutFile,' { Place your code here }');
  911. writeln (OutFile,'end;');
  912. writeln (OutFile);
  913. end;
  914. Procedure EmitCallBacks;
  915. var cb : pcbrec;
  916. begin
  917. { See if we must emit callback stubs }
  918. If Optionsset[1] then
  919. begin
  920. cb:=cbroot;
  921. while cb<>nil do
  922. begin
  923. EmitCallBack(cb^.Name);
  924. cb:=cb^.next;
  925. end;
  926. end;
  927. end;
  928. { ------------------------------------------------------------------------
  929. EmitterTable initialization Code
  930. ------------------------------------------------------------------------ }
  931. Procedure EmitDummy (cp : PControl;ObjClass : ObjClasses);
  932. begin
  933. end;
  934. Procedure InitEmitters;
  935. var i : objclasses;
  936. begin
  937. EmitProcs[APClass]:=@EmitDummy;
  938. EmitProcs[APBoxtype]:=@EmitBoxType;
  939. EmitProcs[APColors]:=@EmitColors;
  940. EmitProcs[APAlignment]:=@EmitAlignment;
  941. EmitProcs[APlcol]:=@EmitLcol;
  942. EmitProcs[APsize]:=@EmitSize;
  943. EmitProcs[APStyle]:=@EmitStyle;
  944. EmitProcs[APgravity]:=@EmitGravity;
  945. for i:=FL_INVALID to FL_FOLDER do
  946. ClassEmitters[i]:=EmitProp(Nil);
  947. end;
  948. { ------------------------------------------------------------------------
  949. Main program Code
  950. ------------------------------------------------------------------------ }
  951. begin
  952. { Process options }
  953. DoOptions;
  954. { Read input file }
  955. OpenFile;
  956. DoPreamble;
  957. DoForms;
  958. DoPostamble;
  959. CloseFile;
  960. { Write output file }
  961. OpenOutfile;
  962. InitEmitters;
  963. CollectCallbacks;
  964. EmitHeader;
  965. EmitCallbacks;
  966. EmitForms;
  967. EmitFooter;
  968. CloseOutFile;
  969. end.