2
0

fd2pascal.pp 30 KB

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