fd2pascal.pp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  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. uses
  18. baseunix,
  19. Unix,
  20. unixutil;
  21. Const RevString = '$Revision: 1.5 $';
  22. NrOptions = 4;
  23. Options : Array[0..NrOptions] Of String[20] =
  24. ('v','callback','main','altformat','compensate');
  25. Type
  26. { Properties of an object }
  27. ContProps=(CPclass,CPtype,CPbox,CPBoxtype,CPColors,CPalignment,CPstyle,CPsize,
  28. CPlcol,CPlabel,CPShortcut,CPresize,CPgravity,CPname,CPCallback,
  29. CPargument,
  30. CPinvalid);
  31. { Properties of an object for which defaults must be set }
  32. AdjProps=(APClass,APBoxtype,ApColors,APAlignment,APSize,APLcol,APstyle,APgravity);
  33. { List of all object classes }
  34. ObjClasses=(FL_INVALID,FL_BUTTON, FL_LIGHTBUTTON,FL_ROUNDBUTTON, FL_ROUND3DBUTTON,
  35. FL_CHECKBUTTON, FL_BITMAPBUTTON, FL_PIXMAPBUTTON,FL_BITMAP, FL_PIXMAP,
  36. FL_BOX, FL_TEXT, FL_MENU, FL_CHART, FL_CHOICE, FL_COUNTER, FL_SLIDER, FL_VALSLIDER, FL_INPUT,
  37. FL_BROWSER,FL_DIAL,FL_TIMER,FL_CLOCK, FL_POSITIONER, FL_FREE,
  38. FL_XYPLOT,FL_FRAME, FL_LABELFRAME, FL_CANVAS, FL_GLCANVAS,
  39. FL_IMAGECANVAS, FL_FOLDER);
  40. { Properties in preamble }
  41. PreProps=(PPmagic,PPNrforms,PPUnitofMeasure,PPinvalid);
  42. { Properties of a form }
  43. FormProps=(FPName,FPWidth,FPHeight,FPnumObjs,FPinvalid);
  44. Const
  45. { Names of all object properties }
  46. ContPropNames : Array[ContProps] of string[20] =
  47. ('class','type','box','boxtype','colors','alignment','style','size',
  48. 'lcol','label','shortcut','resize','gravity','name','callback',
  49. 'argument',
  50. 'invalid');
  51. { Names of all object properties which must be checked.}
  52. AdjPropsNames : Array[AdjProps] of string[20] =
  53. ('class','boxtype','colors','alignment','size','lcol','style','gravity');
  54. { Names of all preamble properties }
  55. PrePropNames : Array[PreProps] of string[20] =
  56. ('Magic','Number of forms','Unit of measure','Invalid');
  57. { Names of all form properties }
  58. FormPropNames : Array[FormProps] of string[20] =
  59. ('Name','Width','Height','Number of Objects','Invalid');
  60. { Names of all object classes }
  61. FObjClassNames : Array[ObjClasses] of string[20]=
  62. ('FL_INVALID','BUTTON', 'LIGHTBUTTON','ROUNDBUTTON', 'ROUND3DBUTTON',
  63. 'CHECKBUTTON', 'BITMAPBUTTON', 'PIXMAPBUTTON','BITMAP', 'PIXMAP',
  64. 'BOX', 'TEXT', 'MENU', 'CHART', 'CHOICE', 'COUNTER', 'SLIDER', 'VALSLIDER', 'INPUT',
  65. 'BROWSER','DIAL','TIMER','CLOCK', 'POSITIONER', 'FREE',
  66. 'XYPLOT','FRAME', 'LABELFRAME', 'CANVAS', 'GLCANVAS',
  67. 'IMAGECANVAS', 'FOLDER');
  68. { Default properties. If empty a property is ignored.
  69. To force setting of a property, put 'FL_FORCE' as a string.
  70. Mind : Case sensitive }
  71. DefProps : array[ObjClasses,AdjProps] of string[30] =
  72. (('FL_INVALID','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  73. ('BUTTON','FL_UP_BOX','FL_COL1 FL_COL1','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  74. ('LIGHTBUTTON','FL_UP_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  75. ('ROUNDBUTTON','FL_NO_BOX','FL_MCOL FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  76. ('ROUND3DBUTTON','FL_NO_BOX','FL_COL1 FL_BLACK','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  77. ('CHECKBUTTON','FL_NO_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  78. ('BITMAPBUTTON','FL_UP_BOX','FL_COL1 FL_BLUE','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  79. ('PIXMAPBUTTON','FL_UP_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  80. ('BITMAP','FL_NO_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  81. ('PIXMAP','FL_NO_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  82. ('BOX','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  83. ('TEXT','FL_FLAT_BOX','FL_COL1 FL_MCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  84. ('MENU','FL_BORDER_BOX','FL_COL1 FL_MCOL','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  85. ('CHART','FL_BORDER_BOX','FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  86. ('CHOICE','FL_ROUNDED_BOX','FL_COL1 FL_LCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  87. ('COUNTER','FL_UP_BOX','FL_COL1 FL_BLUE','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  88. ('SLIDER','FL_DOWN_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  89. ('VALSLIDER','FL_DOWN_BOX','FL_COL1 FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  90. ('INPUT','FL_DOWN_BOX','FL_COL1 FL_MCOL','FL_ALIGN_LEFT','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  91. ('BROWSER','FL_DOWN_BOX','FL_COL1 FL_YELLOW','FL_ALIGN_BOTTOM','FL_SMALL_FONT','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  92. ('DIAL','FL_FLAT_BOX','FL_COL1 FL_RIGHT_BCOL','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  93. ('TIMER','FL_DOWN_BOX','FL_COL1 FL_RED','FL_ALIGN_CENTER','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  94. ('CLOCK','FL_UP_BOX','FL_INACTIVE_COL FL_BOTTOM_BCOL','FL_ALIGN_BOTTOM','','FL_BLACK','FL_NORMAL_STYLE','FL_FORCE'),
  95. ('POSITIONER','FL_DOWN_BOX','FL_COL1 FL_RED','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  96. ('FREE','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  97. ('XYPLOT','FL_FLAT_BOX','FL_COL1','FL_ALIGN_BOTTOM','','FL_LCOL','FL_NORMAL_STYLE','FL_FORCE'),
  98. ('FRAME','','FL_BLACK FL_COL1','','','FL_BLACK','FL_NORMAL_STYLE','FL_FORCE'),
  99. ('LABELFRAME','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  100. ('CANVAS','FL_NO_BOX','','FL_ALIGN_TOP','','','FL_NORMAL_STYLE','FL_FORCE'),
  101. ('GLCANVAS','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  102. ('IMAGECANVAS','','','','','','FL_NORMAL_STYLE','FL_FORCE'),
  103. ('FOLDER','','','','','','FL_NORMAL_STYLE','FL_FORCE'));
  104. Type
  105. { object data type }
  106. PControl = ^TControl;
  107. TControl = Record
  108. Props : array[ContProps] of string;
  109. NextControl : PControl;
  110. end;
  111. { Form data type}
  112. PFormRec = ^TFormRec;
  113. TFormRec = Record
  114. Name : String;
  115. Width,Height : String[5];
  116. Controls : PControl;
  117. NextForm : PFormRec;
  118. end;
  119. { Callback data type }
  120. PCBrec = ^TCBrec;
  121. TCBrec = record
  122. name : string;
  123. next : PCBrec;
  124. end;
  125. { Property emitting procedures }
  126. EmitProp = Procedure (Data : PControl;ObjClass : ObjClasses);
  127. Var
  128. OptionsSet : Array[1..NrOptions] Of Boolean;
  129. FileName : String;
  130. Infile,outfile : Text;
  131. LineNr : Longint;
  132. NrForms,NrControls : Longint;
  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,
  259. PPunitofmeasure: ;
  260. PPnrforms: begin
  261. val(value,NrForms,code);
  262. if code<>0 then EmitLineError('Invalid number of forms');
  263. end;
  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 : 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
  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. if fpstat(FileName,info)<>-1 Then
  428. begin
  429. { File exists, move to .bak}
  430. fplink (FileName,FileName+'.bak');
  431. fpunlink(FileName);
  432. end;
  433. assign(outfile,filename);
  434. {$i-}
  435. rewrite(outfile);
  436. {$i+}
  437. if ioresult<>0 then
  438. begin
  439. EmitError('Couldn''t open output file : '+filename);
  440. halt(1)
  441. end;
  442. end;
  443. Procedure CloseOutFile;
  444. begin
  445. Close(OutFile);
  446. end;
  447. { ------------------------------------------------------------------------
  448. Code to emit Header/variable/type declarations
  449. ------------------------------------------------------------------------ }
  450. Procedure EmitType (fp : Pformrec);
  451. var cp : PControl;
  452. begin
  453. writeln (OutFile,' TFD_',fp^.name,' = record');
  454. writeln (OutFile,' ',fp^.name,' : PFL_FORM;');
  455. writeln (OutFile,' vdata : Pointer;');
  456. writeln (OutFile,' ldata : Longint;');
  457. cp:=fp^.controls;
  458. {Skip first control, is formbackground }
  459. if cp<>nil then cp:=cp^.nextcontrol;
  460. while cp<>nil do
  461. begin
  462. if cp^.props[CPclass]<>'FL_END_GROUP' then
  463. begin
  464. write (Outfile,' ',cp^.props[CPname]);
  465. if cp^.nextcontrol<>nil then
  466. writeln (OutFile,',')
  467. else
  468. writeln (OutFile,' : PFL_OBJECT;');
  469. end;
  470. cp:=cp^.nextcontrol;
  471. end;
  472. writeln (OutFile,' end;');
  473. writeln (OutFile,' PFD_',fp^.name,' = ^TFD_',fp^.name,';');
  474. writeln (OutFile);
  475. end;
  476. Procedure EmitVar (fp : Pformrec);
  477. var cp : PControl;
  478. begin
  479. writeln (OutFile,' ',fp^.name,' : PFL_FORM;');
  480. cp:=fp^.controls;
  481. {Skip first control, is formbackground }
  482. if cp<>nil then cp:=cp^.nextcontrol;
  483. while cp<>nil do
  484. begin
  485. if cp^.props[CPclass]<>'FL_END_GROUP' then
  486. begin
  487. write (Outfile,' ',cp^.props[CPname]);
  488. if cp^.nextcontrol<>nil then
  489. writeln (OutFile,',')
  490. else
  491. writeln (OutFile,' : PFL_OBJECT;');
  492. end;
  493. cp:=cp^.nextcontrol;
  494. end;
  495. writeln (OutFile);
  496. end;
  497. Procedure EmitHeader;
  498. var fp : PFormRec;
  499. begin
  500. if OptionsSet[2] then
  501. write (OutFile,'Program ')
  502. else
  503. write (OutFile,'Unit ');
  504. writeln (OutFile,basename(filename,'.pp'),';');
  505. writeln (OutFile);
  506. writeln (OutFile,'{ Form definition file generated by fd2pascal }');
  507. writeln (Outfile);
  508. if not OptionsSet[2] then
  509. begin
  510. writeln (OutFile,'Interface');
  511. writeln (OutFile);
  512. end;
  513. writeln (OutFile,'Uses forms;');
  514. writeln (OutFile);
  515. writeln (OutFile,' { Variable / Type definitions. }');
  516. if Optionsset[3] then
  517. writeln (OutFile,'Var')
  518. else
  519. writeln (OutFile,'Type');
  520. fp:=FormRoot;
  521. While fp<>nil do
  522. begin
  523. if not optionsset[3] then
  524. EmitType(fp) { Emit Type definitions }
  525. else
  526. EmitVar(fp); { Emit Variable declaration}
  527. fp:=fp^.nextform;
  528. end;
  529. if not optionsset[2] then
  530. begin
  531. { No program, we must emit interface stuff }
  532. if not (optionsset[3]) then
  533. begin
  534. { Emit normal interface declarations
  535. -> functions }
  536. fp:=formroot;
  537. while fp<>nil do
  538. begin
  539. with fp^ do
  540. writeln (OutFile,'Function create_form_',name,' : PFD_',name,';');
  541. fp:=fp^.nextform;
  542. end;
  543. end
  544. else
  545. begin
  546. { Emit alternate interface declaration
  547. -> 1 function to create all forms.}
  548. writeln (OutFile,'Procedure Create_The_Forms;');
  549. end;
  550. writeln (OutFile);
  551. writeln (OutFile,'Implementation');
  552. end
  553. else
  554. begin
  555. { We must make a program. }
  556. if not(optionsset[3]) then
  557. begin
  558. { Normal format, so we need to emit variables for the forms.}
  559. writeln (OutFile,'Var');
  560. fp:=formroot;
  561. while fp<>nil do
  562. begin
  563. writeln (OutFile,' ',fp^.name,' : PFD_',fp^.name,';');
  564. fp:=fp^.nextform;
  565. end;
  566. writeln (OutFile);
  567. end;
  568. end;
  569. writeln (OutFile);
  570. end;
  571. { ------------------------------------------------------------------------
  572. Code to emit footer/main program
  573. ------------------------------------------------------------------------ }
  574. Procedure EmitCreateforms;
  575. var fp : PFormRec;
  576. begin
  577. writeln (OutFile,'Procedure Create_The_Forms;');
  578. writeln (OutFile);
  579. writeln (OutFile,'begin');
  580. fp:=FormRoot;
  581. while fp<>nil do
  582. begin
  583. writeln(OutFile,'create_form_',fp^.name,';');
  584. fp:=fp^.nextform;
  585. end;
  586. writeln (outFile,'End;');
  587. writeln (OutFile);
  588. end;
  589. Procedure EmitAlternateMain;
  590. begin
  591. { Alternate format, we just call creatallforms to create all forms}
  592. writeln (OutFile,'Create_The_Forms;');
  593. writeln (OutFile,' fl_show_form(',formroot^.name,
  594. ',FL_PLACE_CENTER,FL_FULLBORDER,''',
  595. FormRoot^.name,''');');
  596. end;
  597. Procedure EmitMain;
  598. var fp : PFormRec;
  599. begin
  600. { variables are emitted in the header }
  601. fp:=formroot;
  602. { Create all forms }
  603. while fp<>nil do
  604. begin
  605. writeln (OutFile,' ',fp^.name,' :=Create_Form_',fp^.name,';');
  606. fp:=fp^.nextform;
  607. end;
  608. { Show the first form }
  609. writeln (OutFile,' fl_show_form(',formroot^.name,'^.',Formroot^.name,
  610. ',FL_PLACE_CENTER,FL_FULLBORDER,''',
  611. FormRoot^.name,''');');
  612. end;
  613. Procedure EmitFooter;
  614. begin
  615. if OptionsSet[3] then {Alternate format.}
  616. EmitCreateForms;
  617. if Optionsset[2] then
  618. begin
  619. {Emit Main Program}
  620. writeln (OutFile);
  621. writeln (OutFile,'Begin');
  622. writeln (OutFile,' fl_initialize (@argc,argv,''',
  623. basename(Filename,'.pp'),''',nil,0);');
  624. if Not(OptionsSet[3]) then
  625. EmitMain
  626. else
  627. EmitAlternateMain;
  628. writeln (OutFile,' fl_do_forms;');
  629. end
  630. else
  631. writeln (OutFile,'begin');
  632. writeln (OutFile,'end.')
  633. end;
  634. { ------------------------------------------------------------------------
  635. Code to emit properties
  636. ------------------------------------------------------------------------ }
  637. Function EmitString(S : string) : String;
  638. var temp : String;
  639. i : longint;
  640. begin
  641. temp:='''';
  642. for i:=1 to length(s) do
  643. if s[i]<>'''' then temp:=temp+s[i] else temp:=temp+'''''';
  644. Temp:=temp+'''';
  645. EmitString:=temp;
  646. end;
  647. Procedure EmitBoxtype (cp : PControl;ObjClass : ObjClasses);
  648. begin
  649. {$ifdef debug}
  650. writeln ('EmitBoxType called with args:');
  651. writeln (cp^.props[cpboxtype]);
  652. writeln (defprops[objclass,APboxtype]);
  653. writeln ('for object : ',defprops[objclass,apclass]);
  654. writeln ('With object : ',cp^.props[cpclass]);
  655. {$endif}
  656. if cp^.props[cpboxtype]<>defprops[objclass,APboxtype] then
  657. writeln (OutFile,' fl_set_object_boxtype(obj,',
  658. cp^.props[cpboxtype],');')
  659. end;
  660. Procedure EmitColors (cp : PControl;ObjClass : ObjClasses);
  661. var temp : string;
  662. begin
  663. if cp^.props[cpcolors]<>defprops[objclass,APcolors] then
  664. begin
  665. temp:=cp^.props[cpcolors];
  666. if pos(' ',temp)=0 then exit;
  667. temp[pos(' ',temp)]:=',';
  668. writeln (OutFile,' fl_set_object_color(obj,',temp,');');
  669. end;
  670. end;
  671. Procedure EmitAlignment (cp : PControl;ObjClass : ObjClasses);
  672. begin
  673. if cp^.props[cpalignment]<>defprops[objclass,APalignment] then
  674. writeln (OutFile,' fl_set_object_alignment(obj,',
  675. cp^.props[cpalignment],');');
  676. end;
  677. Procedure EmitLcol (cp : PControl;ObjClass : ObjClasses);
  678. begin
  679. if cp^.props[cplcol]<>defprops[objclass,APlcol] then
  680. writeln (OutFile,' fl_set_object_lcol(obj,',
  681. cp^.props[cplcol],');');
  682. end;
  683. Procedure EmitSize (cp : PControl;ObjClass : ObjClasses);
  684. begin
  685. if cp^.props[cpsize]<>defprops[objclass,APsize] then
  686. writeln (OutFile,' fl_set_object_lsize(obj,',
  687. cp^.props[cpsize],');');
  688. end;
  689. Procedure EmitStyle (cp : PControl;ObjClass : ObjClasses);
  690. begin
  691. if cp^.props[cpstyle]<>defprops[objclass,APstyle] then
  692. writeln (OutFile,' fl_set_object_lstyle(obj,',
  693. cp^.props[cpstyle],');');
  694. end;
  695. Procedure EmitGravity (cp : PControl;ObjClass : ObjClasses);
  696. var temp: string;
  697. begin
  698. if cp^.props[cpstyle]<>'FL_NoGravity FL_NoGravity' then
  699. begin
  700. temp:=cp^.props[cpstyle];
  701. if pos(' ',temp)=0 then exit;
  702. temp[pos(' ',temp)]:=',';
  703. writeln (OutFile,' fl_set_object_gravity(obj,',
  704. temp,');');
  705. end;
  706. end;
  707. Procedure EmitProperties (Cp : PControl; Objclass : ObjClasses);
  708. Var i : AdjProps;
  709. begin
  710. for i:=APboxtype to APgravity do
  711. if DefProps[ObjClass,i]<>'' then
  712. EmitProcs[i](cp,objclass);
  713. end;
  714. { ------------------------------------------------------------------------
  715. Code to emit objects
  716. ------------------------------------------------------------------------ }
  717. Procedure EmitObject(cp : PControl);
  718. var temp : string;
  719. I : Longint;
  720. j,k : ObjClasses;
  721. begin
  722. with cp^ do
  723. begin
  724. temp:=lowercase(props[CPclass]);
  725. delete(temp,1,3);
  726. if temp='begin_group' then
  727. begin
  728. writeln (OutFile);
  729. write (OutFile,' ');
  730. if not (Optionsset[3]) then Write (OutFile,'fdui^.');
  731. writeln (OutFile,props[cpname],':=fl_bgn_group;');
  732. exit;
  733. end
  734. else if temp='end_group' then
  735. begin
  736. writeln (OutFile,' fl_end_group;');
  737. writeln (OutFile);
  738. exit;
  739. end;
  740. { Normal object. Emit creation code. }
  741. write (OutFile,' obj:=fl_add_',temp,' (FL_',props[Cptype],',');
  742. temp:=props[cpbox];
  743. for i:=1 to 3 do
  744. begin
  745. write (OutFile,copy(temp,1,pos(' ',temp)-1),',');
  746. delete (temp,1,pos(' ',temp));
  747. end;
  748. writeln (OutFile,temp,',',EmitString(props[cplabel]),');');
  749. { Emit Callback code if needed }
  750. if props[cpcallback]<>'' then
  751. begin
  752. write (OutFile,' fl_set_object_callback(obj,PFL_CALLBACKPTR(@');
  753. write (OutFile,props[CPcallback],'),');
  754. if props[CPargument]<>'' then
  755. writeln (OutFile,props[CPargument],');')
  756. else
  757. writeln (OutFile,'0);');
  758. end;
  759. { If known object, start emitting properties }
  760. temp:=props[CPclass];
  761. delete(temp,1,3);
  762. k:=FL_INVALID;
  763. for j:=FL_BUTTON to FL_FOLDER do
  764. if temp=DefProps[j,apclass] then k:=j;
  765. if k<>FL_INVALID then
  766. begin
  767. { Emit defaults }
  768. EmitProperties (cp,k);
  769. { If A class-specific emitter exists, call it.}
  770. if Assigned(ClassEmitters[k]) then
  771. ClassEmitters[k] (cp,k);
  772. end;
  773. { Assign to needed object. }
  774. if Optionsset[3] then
  775. Writeln (OutFile,' ',props[cpname],':=obj;')
  776. else
  777. Writeln (OutFile,' fdui^.',props[cpname],':=obj;');
  778. end;
  779. end;
  780. { ------------------------------------------------------------------------
  781. Code to emit forms
  782. ------------------------------------------------------------------------ }
  783. Procedure EmitForm(fp : PFormRec);
  784. Var
  785. cp : PControl;
  786. begin
  787. with fp^ do
  788. begin
  789. if Optionsset[3] then
  790. begin
  791. writeln (OutFile,'Procedure create_form_',name,';');
  792. writeln (OutFile);
  793. writeln (OutFile,'Var obj : PFL_OBJECT;');
  794. writeln (OutFile);
  795. writeln (OutFile,'Begin');
  796. writeln (OutFile,' If ',name,'<>nil then exit;');
  797. write (OutFile,' ',name);
  798. end
  799. else
  800. begin
  801. writeln (OutFile,'Function create_form_',name,' : PFD_',name,';');
  802. writeln (OutFile);
  803. writeln (OutFile,'Var obj : PFL_OBJECT;');
  804. writeln (OutFile,' fdui : PFD_',name,';');
  805. writeln (OutFile);
  806. writeln (OutFile,'Begin');
  807. writeln (OutFile,' New(fdui);');
  808. write (OutFile,' fdui^.',name);
  809. end;
  810. writeln (OutFile,':=fl_bgn_form(FL_NO_BOX,'
  811. ,width,','
  812. ,height,');');
  813. cp:=controls;
  814. writeln (OutFile,' obj:=fl_add_box(',cp^.props[CPboxtype],',0,0,',
  815. width,',',
  816. height,',',
  817. EmitString (cp^.props[CPname]),');');
  818. cp:=cp^.nextcontrol;
  819. { Emit all objects }
  820. while cp<>nil do
  821. begin
  822. EmitObject(cp);
  823. cp:=cp^.nextcontrol;
  824. end;
  825. writeln (OutFile,' fl_end_form;');
  826. if Optionsset[4] then
  827. begin
  828. { Emit Compensation code }
  829. write (OutFile,' fl_adjust_form_size(');
  830. if not(OptionsSet[3]) then write (OutFile,'fdui^.');
  831. writeln(OutFile,fp^.name,');');
  832. end;
  833. if not(OptionsSet[3]) then
  834. begin
  835. writeln (OutFile,' fdui^.',fp^.name,'^.fdui:=fdui;');
  836. writeln (OutFile,' create_form_',fp^.name,':=fdui;');
  837. end;
  838. writeln (OutFile,'end;');
  839. writeln (OutFile);
  840. end;
  841. end;
  842. Procedure EmitForms;
  843. var
  844. fp : PformRec;
  845. begin
  846. { Start emitting forms }
  847. fp:=Formroot;
  848. while fp<>nil do
  849. begin
  850. EmitForm(fp);
  851. fp:=fp^.nextform;
  852. end;
  853. end;
  854. { ------------------------------------------------------------------------
  855. Code to emit callbacks
  856. ------------------------------------------------------------------------ }
  857. Procedure CollectCallbacks;
  858. Var CurrentCb,CBwalk : PCBrec;
  859. fp : PformRec;
  860. cp : PControl;
  861. begin
  862. CbRoot:=nil;
  863. CurrentCB:=cbroot;
  864. fp:=formroot;
  865. while fp<>nil do
  866. begin
  867. cp:=fp^.controls;
  868. while cp<>nil do
  869. begin
  870. if cp^.props[CPcallback]<>'' then
  871. if cbroot<>nil then
  872. begin
  873. cbwalk:=cbroot;
  874. while cbwalk<>nil do
  875. if upcase(cbwalk^.name)=upcase(cp^.props[CPcallback]) then
  876. break
  877. else
  878. cbwalk:=cbwalk^.next;
  879. if cbwalk=nil then
  880. begin
  881. new(currentcb^.next);
  882. currentcb:=currentcb^.next;
  883. currentcb^.name:=cp^.props[CPcallback];
  884. currentcb^.next:=nil;
  885. end;
  886. end
  887. else
  888. begin
  889. new(cbroot);
  890. currentcb:=cbroot;
  891. cbroot^.name:=cp^.props[CPcallback];
  892. cbroot^.next:=nil;
  893. end;
  894. cp:=cp^.nextcontrol;
  895. end;
  896. fp:=fp^.nextform;
  897. end;
  898. end;
  899. Procedure EmitCallback (Const s : string);
  900. begin
  901. writeln (OutFile,'Procedure ',s,' (Sender: PFL_OBJECT; Data : Longint); export;');
  902. writeln (OutFile);
  903. writeln (OutFile,'begin');
  904. writeln (OutFile,' { Place your code here }');
  905. writeln (OutFile,'end;');
  906. writeln (OutFile);
  907. end;
  908. Procedure EmitCallBacks;
  909. var cb : pcbrec;
  910. begin
  911. { See if we must emit callback stubs }
  912. If Optionsset[1] then
  913. begin
  914. cb:=cbroot;
  915. while cb<>nil do
  916. begin
  917. EmitCallBack(cb^.Name);
  918. cb:=cb^.next;
  919. end;
  920. end;
  921. end;
  922. { ------------------------------------------------------------------------
  923. EmitterTable initialization Code
  924. ------------------------------------------------------------------------ }
  925. Procedure EmitDummy (cp : PControl;ObjClass : ObjClasses);
  926. begin
  927. end;
  928. Procedure InitEmitters;
  929. var i : objclasses;
  930. begin
  931. EmitProcs[APClass]:=@EmitDummy;
  932. EmitProcs[APBoxtype]:=@EmitBoxType;
  933. EmitProcs[APColors]:=@EmitColors;
  934. EmitProcs[APAlignment]:=@EmitAlignment;
  935. EmitProcs[APlcol]:=@EmitLcol;
  936. EmitProcs[APsize]:=@EmitSize;
  937. EmitProcs[APStyle]:=@EmitStyle;
  938. EmitProcs[APgravity]:=@EmitGravity;
  939. for i:=FL_INVALID to FL_FOLDER do
  940. ClassEmitters[i]:=EmitProp(Nil);
  941. end;
  942. { ------------------------------------------------------------------------
  943. Main program Code
  944. ------------------------------------------------------------------------ }
  945. begin
  946. { Process options }
  947. DoOptions;
  948. { Read input file }
  949. OpenFile;
  950. DoPreamble;
  951. DoForms;
  952. DoPostamble;
  953. CloseFile;
  954. { Write output file }
  955. OpenOutfile;
  956. InitEmitters;
  957. CollectCallbacks;
  958. EmitHeader;
  959. EmitCallbacks;
  960. EmitForms;
  961. EmitFooter;
  962. CloseOutFile;
  963. end.