fd2pascal.pp 31 KB

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