fd2pascal.pp 30 KB

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