install.pas 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. This is the install program for the DOS and OS/2 versions of Free Pascal
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  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.
  12. **********************************************************************}
  13. program install;
  14. { $DEFINE DLL} (* TH - if defined, UNZIP32.DLL library is used to unpack. *)
  15. { $DEFINE DOSSTUB} (* TH - should _not_ be defined unless creating a bound DOS and OS/2 installer!!! *)
  16. (* Defining DOSSTUB causes adding a small piece of code *)
  17. (* for starting the OS/2 part from the DOS part of a bound *)
  18. (* application if running in OS/2 VDM (DOS) window. Used *)
  19. (* only if compiling with TP/BP (see conditionals below). *)
  20. {$IFDEF OS2}
  21. {$DEFINE DLL}
  22. {$ENDIF DLL}
  23. {$IFDEF VER60}
  24. {$DEFINE TP}
  25. {$ENDIF}
  26. {$IFDEF VER70}
  27. {$DEFINE TP}
  28. {$ENDIF}
  29. {$IFNDEF TP}
  30. {$UNDEF DOSSTUB}
  31. {$ELSE}
  32. {$IFDEF OS2}
  33. {$UNDEF DOSSTUB}
  34. {$ENDIF}
  35. {$ENDIF}
  36. {$IFDEF DPMI}
  37. {$UNDEF DOSSTUB}
  38. {$ENDIF}
  39. {$ifdef go32v2}
  40. {$define MAYBE_LFN}
  41. {$endif}
  42. {$ifdef debug}
  43. {$ifdef win32}
  44. {$define MAYBE_LFN}
  45. {$endif win32}
  46. {$endif debug}
  47. {$ifdef TP}
  48. {$define MAYBE_LFN}
  49. {$endif}
  50. uses
  51. {$IFDEF OS2}
  52. {$IFDEF FPC}
  53. DosCalls,
  54. {$ELSE FPC}
  55. {$IFDEF VirtualPascal}
  56. OS2Base,
  57. {$ELSE VirtualPascal}
  58. BseDos,
  59. {$ENDIF VirtualPascal}
  60. {$ENDIF FPC}
  61. {$ENDIF OS2}
  62. {$IFDEF GO32V2}
  63. emu387,
  64. {$ENDIF}
  65. {$ifdef HEAPTRC}
  66. heaptrc,
  67. {$endif HEAPTRC}
  68. strings,dos,objects,drivers,
  69. {$IFNDEF FVISION}
  70. commands,
  71. HelpCtx,
  72. {$ENDIF}
  73. unzip,ziptypes,
  74. {$IFDEF DLL}
  75. unzipdll,
  76. {$ENDIF}
  77. app,dialogs,views,menus,msgbox,colortxt,tabs,scroll,
  78. WHTMLScn;
  79. const
  80. installerversion='1.0.8';
  81. installercopyright='Copyright (c) 1993-2004 Florian Klaempfl';
  82. maxpacks=30;
  83. maxpackages=20;
  84. maxdefcfgs=1024;
  85. HTMLIndexExt = '.htx';
  86. CfgExt = '.dat';
  87. MaxStatusPos = 4;
  88. StatusChars: string [MaxStatusPos] = '/-\|';
  89. StatusPos: byte = 1;
  90. { this variable is set to true if an ide is installed }
  91. haside : boolean = false;
  92. hashtmlhelp : boolean = false;
  93. {$ifdef Unix}
  94. DirSep='/';
  95. {$else}
  96. DirSep='\';
  97. {$endif}
  98. type
  99. tpackage=record
  100. name : string[60];
  101. zip : string[40]; { default zipname }
  102. zipshort : string[12]; { 8.3 zipname }
  103. diskspace : int64; { diskspace required }
  104. end;
  105. tpack=record
  106. name : string[12];
  107. binsub : string[40];
  108. ppc386 : string[20];
  109. targetname : string[40];
  110. defidecfgfile,
  111. defideinifile,
  112. defcfgfile,
  113. setpathfile : string[12];
  114. include : boolean;
  115. { filechk : string[40]; Obsolete }
  116. packages : longint;
  117. package : array[1..maxpackages] of tpackage;
  118. end;
  119. tcfgarray = array[1..maxdefcfgs] of pstring;
  120. cfgrec=record
  121. title : string[80];
  122. version : string[20];
  123. helpidx,
  124. docsub,
  125. basepath : DirStr;
  126. packs : word;
  127. pack : array[1..maxpacks] of tpack;
  128. defideinis,
  129. defidecfgs,
  130. defcfgs,
  131. defsetpaths : longint;
  132. defideini,
  133. defidecfg,
  134. defcfg,
  135. defsetpath : tcfgarray;
  136. end;
  137. datarec=record
  138. basepath : DirStr;
  139. cfgval : word;
  140. packmask : array[1..maxpacks] of sw_word;
  141. end;
  142. punzipdialog=^tunzipdialog;
  143. tunzipdialog=object(tdialog)
  144. filetext : pstatictext;
  145. extractfiletext : pstatictext;
  146. currentfile : string;
  147. constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  148. procedure do_unzip(s,topath:string);
  149. end;
  150. penddialog = ^tenddialog;
  151. tenddialog = object(tdialog)
  152. constructor init;
  153. end;
  154. pinstalldialog = ^tinstalldialog;
  155. tinstalldialog = object(tdialog)
  156. constructor init;
  157. procedure handleevent(var event : tevent);virtual;
  158. end;
  159. PFPHTMLFileLinkScanner = ^TFPHTMLFileLinkScanner;
  160. TFPHTMLFileLinkScanner = object(THTMLFileLinkScanner)
  161. function CheckURL(const URL: string): boolean; virtual;
  162. function CheckText(const Text: string): boolean; virtual;
  163. procedure ProcessDoc(Doc: PHTMLLinkScanFile); virtual;
  164. end;
  165. phtmlindexdialog = ^thtmlindexdialog;
  166. thtmlindexdialog = object(tdialog)
  167. text : pstatictext;
  168. constructor init(var Bounds: TRect; ATitle: TTitleStr);
  169. end;
  170. tapp = object(tapplication)
  171. procedure initmenubar;virtual;
  172. procedure handleevent(var event : tevent);virtual;
  173. procedure do_installdialog;
  174. procedure readcfg(const fn:string);
  175. procedure checkavailpack;
  176. end;
  177. PSpecialInputLine= ^TSpecialInputLine;
  178. TSpecialInputLine = object (TInputLine)
  179. procedure GetData(var Rec); virtual;
  180. end;
  181. {$IFDEF DOSSTUB}
  182. PByte = ^byte;
  183. PRunBlock = ^TRunBlock;
  184. TRunBlock = record
  185. Length: word;
  186. Dependent: word;
  187. Background: word;
  188. TraceLevel: word;
  189. PrgTitle: PChar;
  190. PrgName: PChar;
  191. Args: PChar;
  192. TermQ: longint;
  193. Environment: pointer;
  194. Inheritance: word;
  195. SesType: word;
  196. Icon: pointer;
  197. PgmHandle: longint;
  198. PgmControl: word;
  199. Column: word;
  200. Row: word;
  201. Width: word;
  202. Height: word;
  203. end;
  204. {$ENDIF}
  205. var
  206. installapp : tapp;
  207. startpath : string;
  208. successfull : boolean;
  209. cfg : cfgrec;
  210. data : datarec;
  211. CfgName: NameStr;
  212. DStr: DirStr;
  213. EStr: ExtStr;
  214. UnzDlg : punzipdialog;
  215. log : text;
  216. createlog : boolean;
  217. {$IFNDEF DLL}
  218. const
  219. UnzipErr: longint = 0;
  220. {$ENDIF}
  221. {$ifdef MAYBE_LFN}
  222. const
  223. locallfnsupport : boolean = false;
  224. {$endif MAYBE_LFN}
  225. {*****************************************************************************
  226. Helpers
  227. *****************************************************************************}
  228. procedure errorhalt;
  229. begin
  230. installapp.done;
  231. if CreateLog then
  232. begin
  233. WriteLn (Log, 'Installation hasn''t been completed.');
  234. Close (Log);
  235. end;
  236. halt(1);
  237. end;
  238. function packagemask(i:longint):longint;
  239. begin
  240. packagemask:=1 shl (i-1);
  241. end;
  242. function upper(const s : string):string;
  243. var
  244. i : integer;
  245. begin
  246. for i:=1 to length(s) do
  247. if s[i] in ['a'..'z'] then
  248. upper[i]:=chr(ord(s[i])-32)
  249. else
  250. upper[i]:=s[i];
  251. upper[0]:=s[0];
  252. end;
  253. procedure Replace(var s:string;const s1,s2:string);
  254. var
  255. i : longint;
  256. begin
  257. repeat
  258. i:=pos(s1,s);
  259. if i>0 then
  260. begin
  261. Delete(s,i,length(s1));
  262. Insert(s2,s,i);
  263. end;
  264. until i=0;
  265. end;
  266. function DotStr(l:longint):string;
  267. var
  268. TmpStr : string[32];
  269. i : longint;
  270. begin
  271. Str(l,TmpStr);
  272. i:=Length(TmpStr);
  273. while (i>3) do
  274. begin
  275. i:=i-3;
  276. if TmpStr[i]<>'-' then
  277. Insert('.',TmpStr,i+1);
  278. end;
  279. DotStr:=TmpStr;
  280. end;
  281. function file_exists(const f : string;const path : string) : boolean;
  282. begin
  283. file_exists:=fsearch(f,path)<>'';
  284. end;
  285. function createdir(s:string):boolean;
  286. var
  287. s1,start : string;
  288. err : boolean;
  289. i : longint;
  290. begin
  291. err:=false;
  292. {$I-}
  293. getdir(0,start);
  294. {$ifndef Unix}
  295. if (s[2]=':') and (s[3]=DirSep) then
  296. begin
  297. chdir(Copy(s,1,3));
  298. Delete(S,1,3);
  299. end;
  300. {$endif}
  301. repeat
  302. i:=Pos(DirSep,s);
  303. if i=0 then
  304. i:=255;
  305. s1:=Copy(s,1,i-1);
  306. Delete(s,1,i);
  307. ChDir(s1);
  308. if ioresult<>0 then
  309. begin
  310. mkdir(s1);
  311. chdir(s1);
  312. if ioresult<>0 then
  313. begin
  314. err:=true;
  315. break;
  316. end;
  317. end;
  318. until s='';
  319. chdir(start);
  320. {$I+}
  321. createdir:=err;
  322. end;
  323. function DiskSpaceN(const zipfile : string) : longint;
  324. var
  325. compressed,uncompressed : longint;
  326. s : string;
  327. begin
  328. s:=zipfile+#0;
  329. if not (IsZip (@S [1])) then
  330. DiskSpaceN := -1
  331. else
  332. begin
  333. Uncompressed:=UnzipSize(@s[1],compressed);
  334. DiskSpaceN:=uncompressed shr 10;
  335. end;
  336. end;
  337. function diskspacestr(uncompressed : longint) : string;
  338. begin
  339. if Uncompressed = -1 then
  340. DiskSpacestr := ' [INVALID]'
  341. else
  342. diskspacestr:=' ('+DotStr(uncompressed)+' KB)';
  343. end;
  344. function createinstalldir(s : string) : boolean;
  345. var
  346. err : boolean;
  347. dir : searchrec;
  348. params : array[0..0] of pointer;
  349. begin
  350. if s[length(s)]=DirSep then
  351. dec(s[0]);
  352. FindFirst(s,AnyFile,dir);
  353. if doserror=0 then
  354. begin
  355. if Dir.Attr and Directory = 0 then
  356. begin
  357. messagebox('A file with the name chosen as the installation '+
  358. 'directory exists already. Cannot create this directory!',nil,
  359. mferror+mfokbutton);
  360. createinstalldir:=false;
  361. end else
  362. createinstalldir:=messagebox('The installation directory exists already. '+
  363. 'Do you want to continue ?',nil,
  364. mferror+mfyesbutton+mfnobutton)=cmYes;
  365. exit;
  366. end;
  367. err:=Createdir(s);
  368. if err then
  369. begin
  370. params[0]:=@s;
  371. messagebox('The installation directory %s couldn''t be created',
  372. @params,mferror+mfokbutton);
  373. createinstalldir:=false;
  374. exit;
  375. end;
  376. {$ifndef TP}
  377. {$IFNDEF OS2}
  378. FindClose (dir);
  379. {$ENDIF}
  380. {$endif}
  381. createinstalldir:=true;
  382. end;
  383. function GetProgDir: DirStr;
  384. var
  385. D: DirStr;
  386. N: NameStr;
  387. E: ExtStr;
  388. begin
  389. FSplit (FExpand (ParamStr (0)), D, N, E);
  390. if (D [0] <> #0) and (D [byte (D [0])] = '\') then Dec (D [0]);
  391. GetProgDir := D;
  392. end;
  393. function RTrim(const S: string): string;
  394. var
  395. i : longint;
  396. begin
  397. i:=length(s);
  398. while (i>0) and (s[i]=' ') do
  399. dec(i);
  400. RTrim:=Copy(s,1,i);
  401. end;
  402. function LTrim(const S: string): string;
  403. var
  404. i : longint;
  405. begin
  406. i:=1;
  407. while (i<length(s)) and (s[i]=' ') do
  408. inc(i);
  409. LTrim:=Copy(s,i,255);
  410. end;
  411. function Trim(const S: string): string;
  412. begin
  413. Trim:=RTrim(LTrim(S));
  414. end;
  415. function CompareText(S1, S2: string): integer;
  416. var R: integer;
  417. begin
  418. S1:=Upcase(S1);
  419. S2:=Upcase(S2);
  420. if S1<S2 then R:=-1 else
  421. if S1>S2 then R:= 1 else
  422. R:=0;
  423. CompareText:=R;
  424. end;
  425. function ExtOf(const S: string): string;
  426. var D: DirStr; E: ExtStr; N: NameStr;
  427. begin
  428. FSplit(S,D,N,E);
  429. ExtOf:=E;
  430. end;
  431. function DirAndNameOf(const S: string): string;
  432. var D: DirStr; E: ExtStr; N: NameStr;
  433. begin
  434. FSplit(S,D,N,E);
  435. DirAndNameOf:=D+N;
  436. end;
  437. function DirOf(const S: string): string;
  438. var D: DirStr; E: ExtStr; N: NameStr;
  439. begin
  440. FSplit(S,D,N,E);
  441. DirOf:=D;
  442. end;
  443. function GetZipErrorInfo(error : longint) : string;
  444. var
  445. ErrorStr : string;
  446. begin
  447. case error of
  448. unzip_CRCErr : GetZipErrorInfo:='CRC error';
  449. unzip_WriteErr : GetZipErrorInfo:='Write error';
  450. unzip_ReadErr : GetZipErrorInfo:='Read error';
  451. unzip_ZipFileErr : GetZipErrorInfo:='ZipFile erroe';
  452. unzip_UserAbort : GetZipErrorInfo:='User abort';
  453. unzip_NotSupported : GetZipErrorInfo:='Not supported';
  454. unzip_Encrypted : GetZipErrorInfo:='File is encrypted';
  455. unzip_InUse : GetZipErrorInfo:='Fie is in use';
  456. unzip_InternalError : GetZipErrorInfo:='Internal error'; {Error in zip format}
  457. unzip_NoMoreItems : GetZipErrorInfo:='No more items';
  458. unzip_FileError : GetZipErrorInfo:='File error'; {Error Accessing file}
  459. unzip_NotZipfile : GetZipErrorInfo:='Not a zipfile'; {not a zip file}
  460. unzip_SeriousError : GetZipErrorInfo:='Serious error'; {serious error}
  461. unzip_MissingParameter : GetZipErrorInfo:='Missing parameter'; {missing parameter}
  462. else
  463. begin
  464. Str(Error,ErrorStr);
  465. GetZipErrorInfo:='Unknown error '+errorstr;
  466. end;
  467. end;
  468. end;
  469. {*****************************************************************************
  470. HTML-Index Generation
  471. *****************************************************************************}
  472. var
  473. indexdlg : phtmlindexdialog;
  474. constructor thtmlindexdialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  475. var
  476. r : trect;
  477. begin
  478. inherited init(bounds,atitle);
  479. Options:=Options or ofCentered;
  480. R.Assign (4, 2,bounds.B.X-Bounds.A.X-2, 4);
  481. text:=new(pstatictext,init(r,'Please wait ...'));
  482. insert(text);
  483. end;
  484. procedure TFPHTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  485. var
  486. oldtext : pstring;
  487. begin
  488. oldtext:=indexdlg^.text^.text;
  489. indexdlg^.text^.text:=newstr('Processing '+Doc^.GetDocumentURL);
  490. indexdlg^.text^.drawview;
  491. inherited ProcessDoc(Doc);
  492. disposestr(indexdlg^.text^.text);
  493. indexdlg^.text^.text:=oldtext;
  494. indexdlg^.text^.drawview;
  495. end;
  496. function TFPHTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  497. var OK: boolean;
  498. const HTTPPrefix = 'http:';
  499. FTPPrefix = 'ftp:';
  500. begin
  501. OK:=inherited CheckURL(URL);
  502. if OK then OK:=DirAndNameOf(URL)<>'';
  503. if OK then OK:=CompareText(copy(ExtOf(URL),1,4),'.HTM')=0;
  504. if OK then OK:=CompareText(copy(URL,1,length(HTTPPrefix)),HTTPPrefix)<>0;
  505. if OK then OK:=CompareText(copy(URL,1,length(FTPPrefix)),FTPPrefix)<>0;
  506. CheckURL:=OK;
  507. end;
  508. function TFPHTMLFileLinkScanner.CheckText(const Text: string): boolean;
  509. var OK: boolean;
  510. S: string;
  511. begin
  512. S:=Trim(Text);
  513. OK:=(S<>'') and (copy(S,1,1)<>'[');
  514. CheckText:=OK;
  515. end;
  516. procedure writehlpindex(filename : string);
  517. var
  518. LS : PFPHTMLFileLinkScanner;
  519. BS : PBufStream;
  520. Re : Word;
  521. params : array[0..0] of pointer;
  522. dir : searchrec;
  523. r : trect;
  524. begin
  525. r.assign(10,10,70,15);
  526. indexdlg:=new(phtmlindexdialog,init(r,'Creating HTML index file, please wait ...'));
  527. desktop^.insert(indexdlg);
  528. { warning FIXME !!!!, don't know what is to fix here ... PM }
  529. New(LS, Init(DirOf(FileName)));
  530. LS^.ProcessDocument(FileName,[soSubDocsOnly]);
  531. if LS^.GetDocumentCount=0 then
  532. begin
  533. params[0]:=@filename;
  534. MessageBox('Problem creating help index %1, aborting',@params,
  535. mferror+mfokbutton);
  536. end
  537. else
  538. begin
  539. FileName:=DirAndNameOf(FileName)+HTMLIndexExt;
  540. findfirst(filename,AnyFile,dir);
  541. if doserror=0 then
  542. begin
  543. params[0]:=@filename;
  544. Re:=MessageBox('Help index %s already exists, overwrite it?',@params,
  545. mfinformation+mfyesbutton+mfnobutton);
  546. end
  547. else
  548. Re:=cmYes;
  549. if Re<>cmNo then
  550. begin
  551. New(BS, Init(FileName, stCreate, 4096));
  552. if Assigned(BS)=false then
  553. begin
  554. MessageBox('Error while writing help index! '+
  555. 'No help index is created',@params,
  556. mferror+mfokbutton);
  557. Re:=cmCancel;
  558. end
  559. else
  560. begin
  561. LS^.StoreDocuments(BS^);
  562. if BS^.Status<>stOK then
  563. begin
  564. MessageBox('Error while writing help index!'#13+
  565. 'No help index is created',@params,
  566. mferror+mfokbutton);
  567. Re:=cmCancel;
  568. end;
  569. Dispose(BS, Done);
  570. end;
  571. end;
  572. end;
  573. Dispose(LS, Done);
  574. desktop^.delete(indexdlg);
  575. dispose(indexdlg,done);
  576. end;
  577. {*****************************************************************************
  578. Writing of fpc.cfg
  579. *****************************************************************************}
  580. procedure writedefcfg(const fn:string;const cfgdata : tcfgarray;count : longint;const targetname : string);
  581. var
  582. t : text;
  583. i : longint;
  584. s : string;
  585. dir : searchrec;
  586. params : array[0..0] of pointer;
  587. d : dirstr;
  588. n : namestr;
  589. e : extstr;
  590. begin
  591. { already exists }
  592. findfirst(fn,AnyFile,dir);
  593. if doserror=0 then
  594. begin
  595. params[0]:=@fn;
  596. if MessageBox('Config %s already exists, continue writing default config?',@params,
  597. mfinformation+mfyesbutton+mfnobutton)=cmNo then
  598. exit;
  599. end;
  600. { create directory }
  601. fsplit(fn,d,n,e);
  602. createdir(d);
  603. { create the fpc.cfg }
  604. assign(t,fn);
  605. {$I-}
  606. rewrite(t);
  607. {$I+}
  608. if ioresult<>0 then
  609. begin
  610. params[0]:=@fn;
  611. MessageBox(#3'A config not written.'#13#3'%s'#13#3'couldn''t be created',@params,mfinformation+mfokbutton);
  612. exit;
  613. end;
  614. for i:=1 to count do
  615. if assigned(cfgdata[i]) then
  616. begin
  617. s:=cfgdata[i]^;
  618. Replace(s,'%basepath%',data.basepath);
  619. Replace(s,'%targetname%',targetname);
  620. if pos('-',targetname)=0 then
  621. begin
  622. Replace(s,'%targetos%',targetname);
  623. Replace(s,'%fpctargetmacro%','$FPCOS')
  624. end
  625. else
  626. begin
  627. Replace(s,'%targetos%',Copy(targetname,pos('-',targetname)+1,255));
  628. Replace(s,'%fpctargetmacro%','$FPCTARGET');
  629. end;
  630. writeln(t,s);
  631. end
  632. else
  633. writeln(t,'');
  634. close(t);
  635. end;
  636. {*****************************************************************************
  637. TUnZipDialog
  638. *****************************************************************************}
  639. constructor tunzipdialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  640. var
  641. r : trect;
  642. begin
  643. inherited init(bounds,atitle);
  644. Options:=Options or ofCentered;
  645. (* R.Assign (11, 4, 38, 6);*)
  646. R.Assign (1, 4,bounds.B.X-Bounds.A.X-2, 6);
  647. filetext:=new(pstatictext,init(r,#3'File: '));
  648. insert(filetext);
  649. R.Assign (1, 7,bounds.B.X-Bounds.A.X-2, 9);
  650. extractfiletext:=new(pstatictext,init(r,#3' '));
  651. insert(extractfiletext);
  652. end;
  653. {$IFNDEF DLL}
  654. procedure UnzipCheckFn (Retcode: longint; Rec: pReportRec );{$ifdef Delphi32}STDCALL;{$endif}
  655. {$ifndef fpc}{$IFNDEF BIT32} FAR;{$ENDIF BIT32}{$endif}
  656. var
  657. name : string;
  658. begin
  659. case Rec^.Status of
  660. unzip_starting:
  661. UnzipErr := 0;
  662. file_starting:
  663. begin
  664. with UnzDlg^.extractfiletext^ do
  665. begin
  666. Disposestr(text);
  667. name:=Strpas(Rec^.FileName);
  668. UnzDlg^.currentfile:=name;
  669. Text:=NewStr(#3+name);
  670. DrawView;
  671. end;
  672. end;
  673. file_failure:
  674. UnzipErr := RetCode;
  675. file_unzipping:
  676. begin
  677. with UnzDlg^.FileText^ do
  678. begin
  679. Inc (StatusPos);
  680. if StatusPos > MaxStatusPos then StatusPos := 1;
  681. Text^ [Length (Text^)] := StatusChars [StatusPos];
  682. DrawView;
  683. end;
  684. end;
  685. end;
  686. end;
  687. {$ENDIF}
  688. procedure tunzipdialog.do_unzip(s,topath : string);
  689. var
  690. {$ifdef MAYBE_LFN}
  691. p : pathstr;
  692. n : namestr;
  693. e : extstr;
  694. islfn : boolean;
  695. {$endif MAYBE_LFN}
  696. again : boolean;
  697. st2,fn,dir,wild : string;
  698. begin
  699. Disposestr(filetext^.text);
  700. filetext^.Text:=NewStr(#3'File: '+s + #13#3' ');
  701. filetext^.drawview;
  702. if not(file_exists(s,startpath)) then
  703. begin
  704. messagebox('File "'+s+'" missing for the selected installation. '+
  705. 'Installation hasn''t been completed.',nil,mferror+mfokbutton);
  706. if CreateLog then
  707. WriteLn (Log, 'File "' + S +
  708. '" missing for the selected installation!');
  709. errorhalt;
  710. end;
  711. {$IFNDEF DLL}
  712. {$IFDEF FPC}
  713. SetUnzipReportProc (@UnzipCheckFn);
  714. {$ELSE FPC}
  715. SetUnzipReportProc (UnzipCheckFn);
  716. {$ENDIF FPC}
  717. {$ENDIF DLL}
  718. if CreateLog then
  719. WriteLn (Log, 'Unpacking ' + AllFiles + ' from '
  720. + StartPath + DirSep + S + ' to ' + ToPath);
  721. repeat
  722. fn:=startpath+DirSep+s+#0;
  723. dir:=topath+#0;
  724. wild:=AllFiles + #0;
  725. again:=false;
  726. FileUnzipEx(@fn[1],@dir[1],@wild[1]);
  727. if (UnzipErr <> 0) and (UnzipErr <> 1) then
  728. begin
  729. if CreateLog then
  730. WriteLn (Log, 'Error ', UnzipErr, ' while unpacking!');
  731. s:=GetZipErrorInfo(UnzipErr);
  732. { Str(UnzipErr,s);}
  733. st2:='';
  734. if UnzipErr=unzip_WriteErr then
  735. begin
  736. {$ifdef MAYBE_LFN}
  737. if not(locallfnsupport) then
  738. begin
  739. islfn:=false;
  740. fsplit(currentfile,p,n,e);
  741. if (length(n)>8) or (length(e)>4) or
  742. (pos('.',n)>0) or (upper(p+n+e)<>upper(currentfile)) then
  743. islfn:=true;
  744. if islfn then
  745. begin
  746. if CreateLog then
  747. begin
  748. WriteLn (Log, 'Error while extracting ' +
  749. CurrentFile + ' because of missing LFN support,');
  750. WriteLn (Log, ' skipping rest of ZIP file.');
  751. end;
  752. messagebox('Error while extracting '+currentfile+
  753. #13#3'because of missing lfn support'+
  754. #13#3'skipping rest of zipfile '+s
  755. ,nil,mferror+mfOkButton);
  756. again:=false;
  757. exit;
  758. end;
  759. end
  760. else
  761. {$endif MAYBE_LFN}
  762. st2:=' Disk full?';
  763. end;
  764. if CreateLog then
  765. WriteLn (Log, 'Error (' + S + ') while extracting.' + ST2);
  766. if messagebox('Error (' + S + ') while extracting.'+st2+#13+
  767. #13#3'Try again?',nil,mferror+mfyesbutton+mfnobutton)=cmYes then
  768. again:=true
  769. else
  770. errorhalt;
  771. end;
  772. until not again;
  773. end;
  774. {*****************************************************************************
  775. TEndDialog
  776. *****************************************************************************}
  777. constructor tenddialog.init;
  778. var
  779. R : TRect;
  780. P : PStaticText;
  781. Control : PButton;
  782. YB: word;
  783. {$IFNDEF UNIX}
  784. i : longint;
  785. S: string;
  786. WPath: boolean;
  787. MixedCasePath: boolean;
  788. {$ENDIF}
  789. {$IFDEF OS2}
  790. ErrPath: array [0..259] of char;
  791. Handle: longint;
  792. WLibPath: boolean;
  793. const
  794. EMXName: array [1..4] of char = 'EMX'#0;
  795. {$ENDIF}
  796. begin
  797. if haside then
  798. YB := 15
  799. else
  800. YB := 14;
  801. {$IFNDEF UNIX}
  802. s:='';
  803. for i:=1 to cfg.packs do
  804. if cfg.pack[i].binsub<>'' then
  805. begin
  806. if s<>'' then
  807. s:=s+';';
  808. S := s+Data.BasePath + Cfg.pack[i].BinSub;
  809. end;
  810. if Pos (Upper (S), Upper (GetEnv ('PATH'))) = 0 then
  811. begin
  812. WPath := true;
  813. Inc (YB, 3);
  814. end
  815. else
  816. WPath := false;
  817. { look if path is set as Path,
  818. this leads to problems for mingw32 make PM }
  819. MixedCasePath:=false;
  820. for i:=1 to EnvCount do
  821. begin
  822. if Pos('PATH=',Upper(EnvStr(i)))=1 then
  823. if Pos('PATH=',EnvStr(i))<>1 then
  824. Begin
  825. MixedCasePath:=true;
  826. Inc(YB, 2);
  827. End;
  828. end;
  829. {$IFDEF OS2}
  830. if DosLoadModule (@ErrPath, SizeOf (ErrPath), @EMXName, Handle) = 0 then
  831. begin
  832. WLibPath := false;
  833. DosFreeModule (Handle);
  834. end
  835. else
  836. begin
  837. WLibPath := true;
  838. Inc (YB, 2);
  839. end;
  840. {$ENDIF}
  841. {$ENDIF}
  842. R.Assign(6, 6, 74, YB);
  843. inherited init(r,'Installation Successful.');
  844. Options:=Options or ofCentered;
  845. {$IFNDEF UNIX}
  846. if WPath then
  847. begin
  848. R.Assign(2, 3, 64, 5);
  849. P:=new(pstatictext,init(r,'Extend your PATH variable with '''+S+''''));
  850. insert(P);
  851. end;
  852. if MixedCasePath then
  853. begin
  854. R.Assign(2, 5, 64, 6);
  855. P:=new(pstatictext,init(r,'You need to use setpath.bat file if you want to use Makefiles'));
  856. insert(P);
  857. end;
  858. {$IFDEF OS2}
  859. if WLibPath then
  860. begin
  861. if WPath then
  862. S := 'and your LIBPATH with ''' + S + '\dll'''
  863. else
  864. S := 'Extend your LIBPATH with ''' + S + '\dll''';
  865. R.Assign (2, YB - 14, 64, YB - 12);
  866. P := New (PStaticText, Init (R, S));
  867. Insert (P);
  868. end;
  869. {$ENDIF}
  870. {$ENDIF}
  871. R.Assign(2, YB - 13, 64, YB - 12);
  872. P:=new(pstatictext,init(r,'To compile files enter fpc [file]'''));
  873. insert(P);
  874. if haside then
  875. begin
  876. R.Assign(2, YB - 12, 64, YB - 10);
  877. P:=new(pstatictext,init(r,'To start the IDE (Integrated Development Environment) type ''fp'' at a command line prompt'));
  878. insert(P);
  879. end;
  880. R.Assign (29, YB - 9, 39, YB - 7);
  881. Control := New (PButton, Init (R,'~O~k', cmOK, bfDefault));
  882. Insert (Control);
  883. end;
  884. {*****************************************************************************
  885. TInstallDialog
  886. *****************************************************************************}
  887. {$ifdef MAYBE_LFN}
  888. var
  889. islfn : boolean;
  890. procedure lfnreport( Retcode : longint;Rec : pReportRec );
  891. var
  892. p : pathstr;
  893. n : namestr;
  894. e : extstr;
  895. begin
  896. fsplit(strpas(rec^.Filename),p,n,e);
  897. if (length(n)>8) or (length(e)>4) or
  898. (pos('.',n)>0) or (upper(p+n+e)<>upper(strpas(rec^.Filename))) then
  899. islfn:=true;
  900. end;
  901. function haslfn(const zipfile : string) : boolean;
  902. var
  903. buf : array[0..255] of char;
  904. begin
  905. strpcopy(buf,zipfile);
  906. islfn:=false;
  907. {$ifdef FPC}
  908. ViewZip(buf,AllFiles,@lfnreport);
  909. {$else FPC}
  910. ViewZip(buf,AllFiles,lfnreport);
  911. {$endif FPC}
  912. haslfn:=islfn;
  913. end;
  914. {$endif MAYBE_LFN}
  915. var
  916. AllFilesPresent : boolean;
  917. procedure presentreport( Retcode : longint;Rec : pReportRec );
  918. var
  919. st : string;
  920. f : file;
  921. size,time : longint;
  922. p : pathstr;
  923. n : namestr;
  924. e : extstr;
  925. begin
  926. if not ALLFilesPresent then
  927. exit;
  928. st:=Data.BasePath+strpas(rec^.Filename);
  929. fsplit(st,p,n,e);
  930. if not file_exists(n+e,p) then
  931. AllFilesPresent:=false
  932. else
  933. begin
  934. Assign(f,st);
  935. Reset(f,1);
  936. if IOresult<>0 then
  937. begin
  938. ALLfilesPresent:=false;
  939. exit;
  940. end;
  941. GetFtime(f,time);
  942. size:=FileSize(f);
  943. if (rec^.Time<>time) or (rec^.size<>size) then
  944. ALLFilesPresent:=false;
  945. close(f);
  946. end;
  947. end;
  948. function AreAllFilesPresent(const zipfile : string) : boolean;
  949. var
  950. buf : array[0..255] of char;
  951. begin
  952. strpcopy(buf,zipfile);
  953. AllFilesPresent:=true;
  954. {$ifdef FPC}
  955. ViewZip(buf,AllFiles,@presentreport);
  956. {$else FPC}
  957. ViewZip(buf,AllFiles,presentreport);
  958. {$endif FPC}
  959. AreAllFilesPresent:=AllFilesPresent;
  960. end;
  961. constructor tinstalldialog.init;
  962. const
  963. width = 76;
  964. height = 20;
  965. x1 = (79-width) div 2;
  966. y1 = (23-height) div 2;
  967. x2 = x1+width;
  968. y2 = y1+height;
  969. var
  970. tabr,tabir,r : trect;
  971. packmask : array[1..maxpacks] of longint;
  972. enabmask : array[1..maxpacks] of longint;
  973. i,line,j : integer;
  974. items : array[1..maxpacks] of psitem;
  975. f : pview;
  976. found : boolean;
  977. okbut,cancelbut : pbutton;
  978. firstitem : array[1..maxpacks] of integer;
  979. packcbs : array[1..maxpacks] of pcheckboxes;
  980. packtd : ptabdef;
  981. labpath : plabel;
  982. ilpath : pspecialinputline;
  983. tab : ptab;
  984. titletext : pcoloredtext;
  985. labcfg : plabel;
  986. cfgcb : pcheckboxes;
  987. scrollbox: pscrollbox;
  988. sbr,sbsbr: trect;
  989. sbsb: pscrollbar;
  990. zipfile : string;
  991. begin
  992. f:=nil;
  993. { walk packages reverse and insert a newsitem for each, and set the mask }
  994. for j:=1 to cfg.packs do
  995. with cfg.pack[j] do
  996. begin
  997. firstitem[j]:=0;
  998. items[j]:=nil;
  999. packmask[j]:=0;
  1000. enabmask[j]:=0;
  1001. for i:=packages downto 1 do
  1002. begin
  1003. zipfile:='';
  1004. if file_exists(package[i].zip,startpath) then
  1005. zipfile:=startpath+DirSep+package[i].zip
  1006. else if file_exists(package[i].zipshort,startpath) then
  1007. begin
  1008. zipfile:=startpath+DirSep+package[i].zipshort;
  1009. { update package to replace the full zipname with the short name }
  1010. package[i].zip:=package[i].zipshort;
  1011. end;
  1012. if zipfile<>'' then
  1013. begin
  1014. { get diskspace required }
  1015. package[i].diskspace:=diskspaceN(zipfile);
  1016. {$ifdef MAYBE_LFN}
  1017. if not(locallfnsupport) then
  1018. begin
  1019. if not(haslfn(zipfile)) then
  1020. begin
  1021. items[j]:=newsitem(package[i].name+diskspacestr(package[i].diskspace),items[j]);
  1022. packmask[j]:=packmask[j] or packagemask(i);
  1023. enabmask[j]:=enabmask[j] or packagemask(i);
  1024. firstitem[j]:=i-1;
  1025. if createlog then
  1026. writeln(log,'Checking lfn usage for ',zipfile,' ... no lfn');
  1027. end
  1028. else
  1029. begin
  1030. items[j]:=newsitem(package[i].name+' (requires LFN support)',items[j]);
  1031. enabmask[j]:=enabmask[j] or packagemask(i);
  1032. firstitem[j]:=i-1;
  1033. if createlog then
  1034. writeln(log,'Checking lfn usage for ',zipfile,' ... uses lfn');
  1035. end;
  1036. end
  1037. else
  1038. {$endif MAYBE_LFN}
  1039. begin
  1040. items[j]:=newsitem(package[i].name+diskspacestr(package[i].diskspace),items[j]);
  1041. packmask[j]:=packmask[j] or packagemask(i);
  1042. enabmask[j]:=enabmask[j] or packagemask(i);
  1043. firstitem[j]:=i-1;
  1044. end;
  1045. end
  1046. else
  1047. items[j]:=newsitem(package[i].name,items[j]);
  1048. end;
  1049. end;
  1050. { If no component found abort }
  1051. found:=false;
  1052. for j:=1 to cfg.packs do
  1053. if packmask[j]<>0 then
  1054. found:=true;
  1055. if not found then
  1056. begin
  1057. messagebox('No components found to install, aborting.',nil,mferror+mfokbutton);
  1058. if CreateLog then
  1059. WriteLn (Log, 'No components found to install, aborting.');
  1060. errorhalt;
  1061. end;
  1062. r.assign(x1,y1,x2,y2);
  1063. inherited init(r,'');
  1064. Options:=Options or ofCentered;
  1065. GetExtent(R);
  1066. R.Grow(-2,-1);
  1067. Dec(R.B.Y,2);
  1068. TabR.Copy(R);
  1069. TabIR.Copy(R);
  1070. TabIR.Grow(-2,-2);
  1071. TabIR.Move(-2,0);
  1072. {-------- General Sheets ----------}
  1073. R.Copy(TabIR);
  1074. r.move(0,1);
  1075. r.b.x:=r.a.x+40;
  1076. r.b.y:=r.a.y+1;
  1077. new(titletext,init(r,cfg.title,$71));
  1078. r.move(0,2);
  1079. r.b.x:=r.a.x+40;
  1080. new(labpath,init(r,'~B~ase path',f));
  1081. r.move(0,1);
  1082. r.b.x:=r.a.x+40;
  1083. r.b.y:=r.a.y+1;
  1084. new(ilpath,init(r,high(DirStr)));
  1085. r.move(0,2);
  1086. r.b.x:=r.a.x+40;
  1087. new(labcfg,init(r,'Con~f~ig',f));
  1088. r.move(0,1);
  1089. r.b.x:=r.a.x+40;
  1090. r.b.y:=r.a.y+1;
  1091. new(cfgcb,init(r,newsitem('create fpc.cfg',nil)));
  1092. data.cfgval:=1;
  1093. {-------- Pack Sheets ----------}
  1094. for j:=1 to cfg.packs do
  1095. begin
  1096. R.Copy(TabIR);
  1097. if R.A.Y+cfg.pack[j].packages>R.B.Y then
  1098. R.B.Y:=R.A.Y+cfg.pack[j].packages;
  1099. new(packcbs[j],init(r,items[j]));
  1100. if data.packmask[j]=high(sw_word) then
  1101. data.packmask[j]:=packmask[j];
  1102. packcbs[j]^.enablemask:={$ifdef DEV}$7fffffff{$else}enabmask[j]{$endif};
  1103. packcbs[j]^.sel:=firstitem[j];
  1104. end;
  1105. {--------- Main ---------}
  1106. packtd:=nil;
  1107. sbr.assign(1,3,tabr.b.x-tabr.a.x-3,tabr.b.y-tabr.a.y-1);
  1108. for j:=cfg.packs downto 1 do
  1109. begin
  1110. if (sbr.b.y-sbr.a.y)<cfg.pack[j].packages then
  1111. begin
  1112. sbsbr.assign(sbr.b.x,sbr.a.y,sbr.b.x+1,sbr.b.y);
  1113. New(sbsb, init(sbsbr));
  1114. end
  1115. else
  1116. sbsb:=nil;
  1117. New(ScrollBox, Init(sbr, nil, sbsb));
  1118. PackCbs[j]^.MoveTo(0,0);
  1119. ScrollBox^.Insert(PackCbs[j]);
  1120. packtd:=NewTabDef(
  1121. cfg.pack[j].name,ScrollBox,
  1122. NewTabItem(sbsb,
  1123. NewTabItem(ScrollBox,
  1124. nil)),
  1125. packtd);
  1126. end;
  1127. New(Tab, Init(TabR,
  1128. NewTabDef('~G~eneral',IlPath,
  1129. NewTabItem(TitleText,
  1130. NewTabItem(LabPath,
  1131. NewTabItem(ILPath,
  1132. NewTabItem(LabCfg,
  1133. NewTabItem(CfgCB,
  1134. nil))))),
  1135. packtd)
  1136. ));
  1137. Tab^.GrowMode:=0;
  1138. Insert(Tab);
  1139. line:=tabr.b.y;
  1140. r.assign((width div 2)-18,line,(width div 2)-4,line+2);
  1141. new(okbut,init(r,'~C~ontinue',cmok,bfdefault));
  1142. Insert(OkBut);
  1143. r.assign((width div 2)+4,line,(width div 2)+14,line+2);
  1144. new(cancelbut,init(r,'~Q~uit',cmcancel,bfnormal));
  1145. Insert(CancelBut);
  1146. Tab^.Select;
  1147. end;
  1148. procedure tinstalldialog.handleevent(var event : tevent);
  1149. begin
  1150. if event.what=evcommand then
  1151. if event.command=cmquit then
  1152. begin
  1153. putevent(event);
  1154. event.command:=cmCancel;
  1155. end;
  1156. inherited handleevent(event);
  1157. end;
  1158. {*****************************************************************************
  1159. TSpecialInputLine
  1160. *****************************************************************************}
  1161. { this should use AreAllFilesPresent if the base dir is changed...
  1162. but what if the installer has already choosen which files he wants ... }
  1163. procedure TSpecialInputLine.GetData(var Rec);
  1164. begin
  1165. inherited GetData(Rec);
  1166. end;
  1167. {*****************************************************************************
  1168. TApp
  1169. *****************************************************************************}
  1170. const
  1171. cmstart = 1000;
  1172. procedure tapp.do_installdialog;
  1173. var
  1174. p : pinstalldialog;
  1175. p3 : penddialog;
  1176. r : trect;
  1177. result,
  1178. c : word;
  1179. i,j : longint;
  1180. found : boolean;
  1181. {$ifndef Unix}
  1182. DSize,Space,ASpace : int64;
  1183. S: DirStr;
  1184. {$endif}
  1185. procedure doconfigwrite;
  1186. var
  1187. i : longint;
  1188. begin
  1189. for i:=1 to cfg.packs do
  1190. begin
  1191. if cfg.pack[i].defcfgfile<>'' then
  1192. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defcfgfile,cfg.defcfg,cfg.defcfgs,cfg.pack[i].targetname);
  1193. if cfg.pack[i].setpathfile<>'' then
  1194. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].setpathfile,cfg.defsetpath,cfg.defsetpaths,cfg.pack[i].targetname);
  1195. end;
  1196. if haside then
  1197. begin
  1198. for i:=1 to cfg.packs do
  1199. if cfg.pack[i].defidecfgfile<>'' then
  1200. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defidecfgfile,cfg.defidecfg,cfg.defidecfgs,cfg.pack[i].targetname);
  1201. for i:=1 to cfg.packs do
  1202. if cfg.pack[i].defideinifile<>'' then
  1203. writedefcfg(data.basepath+cfg.pack[i].binsub+DirSep+cfg.pack[i].defideinifile,cfg.defideini,cfg.defideinis,cfg.pack[i].targetname);
  1204. if hashtmlhelp then
  1205. writehlpindex(data.basepath+DirSep+cfg.DocSub+DirSep+cfg.helpidx);
  1206. end;
  1207. end;
  1208. begin
  1209. data.basepath:=cfg.basepath;
  1210. data.cfgval:=0;
  1211. for j:=1 to cfg.packs do
  1212. data.packmask[j]:=high(sw_word);
  1213. repeat
  1214. { select components }
  1215. p:=new(pinstalldialog,init);
  1216. c:=executedialog(p,@data);
  1217. if (c=cmok) then
  1218. begin
  1219. if Data.BasePath = '' then
  1220. messagebox('Please, choose the directory for installation first.',nil,mferror+mfokbutton)
  1221. else
  1222. begin
  1223. found:=false;
  1224. for j:=1 to cfg.packs do
  1225. if data.packmask[j]>0 then
  1226. found:=true;
  1227. if found then
  1228. begin
  1229. {$IFNDEF UNIX}
  1230. { TH - check the available disk space here }
  1231. DSize := 0;
  1232. for j:=1 to cfg.packs do
  1233. with cfg.pack[j] do
  1234. begin
  1235. for i:=1 to packages do
  1236. begin
  1237. if data.packmask[j] and packagemask(i)<>0 then
  1238. begin
  1239. ASpace := package[i].diskspace;
  1240. if ASpace = -1 then
  1241. MessageBox ('File ' + package[i].zip +
  1242. ' is probably corrupted!', nil,
  1243. mferror + mfokbutton)
  1244. else Inc (DSize, ASpace);
  1245. end;
  1246. end;
  1247. end;
  1248. if CreateLog then
  1249. WriteLn (Log, 'Diskspace needed: ',DotStr(DSize),' Kb');
  1250. S := FExpand (Data.BasePath);
  1251. if S [Length (S)] = DirSep then
  1252. Dec (S [0]);
  1253. Space := DiskFree (byte (Upcase(S [1])) - 64);
  1254. { -1 means that the drive is invalid }
  1255. if Space=-1 then
  1256. begin
  1257. if CreateLog then
  1258. WriteLn (Log, 'The drive '+S[1]+': is not valid');
  1259. if messagebox('The drive '+S[1]+': is not valid. Do you ' +
  1260. 'want to change the installation path?',nil,
  1261. mferror+mfyesbutton+mfnobutton) = cmYes then
  1262. Continue;
  1263. Space:=0;
  1264. end;
  1265. Space := Space shr 10;
  1266. if CreateLog then
  1267. WriteLn (Log, 'Free space on drive '+S[1]+': ',DotStr(Space),' Kb');
  1268. if Space < DSize then
  1269. S := 'is not '
  1270. else
  1271. S := '';
  1272. if (Space < DSize + 500) then
  1273. begin
  1274. if S = '' then
  1275. S := 'might not be ';
  1276. if messagebox('There ' + S + 'enough space on the target ' +
  1277. 'drive for all the selected components. Do you ' +
  1278. 'want to change the installation path?',nil,
  1279. mferror+mfyesbutton+mfnobutton) = cmYes then
  1280. Continue;
  1281. end;
  1282. {$ENDIF}
  1283. if createinstalldir(data.basepath) then
  1284. break;
  1285. end
  1286. else
  1287. begin
  1288. { maybe only config }
  1289. if (data.cfgval and 1)<>0 then
  1290. begin
  1291. result:=messagebox('No components selected.'#13#13'Create a configfile ?',nil,
  1292. mfinformation+mfyesbutton+mfnobutton);
  1293. if (result=cmYes) and createinstalldir(data.basepath) then
  1294. doconfigwrite;
  1295. exit;
  1296. end
  1297. else
  1298. begin
  1299. result:=messagebox('No components selected.'#13#13'Abort installation?',nil,
  1300. mferror+mfyesbutton+mfnobutton);
  1301. if result=cmYes then
  1302. exit;
  1303. end;
  1304. end;
  1305. end;
  1306. end
  1307. else
  1308. exit;
  1309. until false;
  1310. { extract packages }
  1311. for j:=1 to cfg.packs do
  1312. with cfg.pack[j] do
  1313. begin
  1314. r.assign(10,7,70,18);
  1315. UnzDlg:=new(punzipdialog,init(r,'Extracting Packages'));
  1316. desktop^.insert(UnzDlg);
  1317. for i:=1 to packages do
  1318. begin
  1319. if data.packmask[j] and packagemask(i)<>0 then
  1320. begin
  1321. UnzDlg^.do_unzip(package[i].zip,data.basepath);
  1322. { gather some information about the installed files }
  1323. if copy(package[i].zip,1,3)='ide' then
  1324. haside:=true;
  1325. if copy(package[i].zip,1,7)='doc-htm' then
  1326. begin
  1327. hashtmlhelp:=true;
  1328. { correct the fpctoc file name if .html files are used }
  1329. if package[i].zip='doc-html.zip' then
  1330. if copy(cfg.helpidx,length(cfg.helpidx)-3,4)='.htm' then
  1331. cfg.helpidx:=cfg.helpidx+'l';
  1332. end;
  1333. end;
  1334. end;
  1335. desktop^.delete(UnzDlg);
  1336. dispose(UnzDlg,done);
  1337. end;
  1338. { write config }
  1339. if (data.cfgval and 1)<>0 then
  1340. doconfigwrite;
  1341. { show end message }
  1342. p3:=new(penddialog,init);
  1343. executedialog(p3,nil);
  1344. end;
  1345. procedure tapp.readcfg(const fn:string);
  1346. var
  1347. t : text;
  1348. i,j,k,
  1349. line : longint;
  1350. item,
  1351. s,hs : string;
  1352. params : array[0..0] of pointer;
  1353. {$ifndef FPC}
  1354. procedure readln(var t:text;var s:string);
  1355. var
  1356. c : char;
  1357. i : longint;
  1358. begin
  1359. c:=#0;
  1360. i:=0;
  1361. while (not eof(t)) and (c<>#10) do
  1362. begin
  1363. read(t,c);
  1364. if c<>#10 then
  1365. begin
  1366. inc(i);
  1367. s[i]:=c;
  1368. end;
  1369. end;
  1370. if (i>0) and (s[i]=#13) then
  1371. dec(i);
  1372. s[0]:=chr(i);
  1373. end;
  1374. {$endif}
  1375. begin
  1376. assign(t,StartPath + DirSep + fn);
  1377. {$I-}
  1378. reset(t);
  1379. {$I+}
  1380. if ioresult<>0 then
  1381. begin
  1382. StartPath := GetProgDir;
  1383. assign(t,StartPath + DirSep + fn);
  1384. {$I-}
  1385. reset(t);
  1386. {$I+}
  1387. if ioresult<>0 then
  1388. begin
  1389. params[0]:=@fn;
  1390. messagebox('File %s not found!',@params,mferror+mfokbutton);
  1391. if CreateLog then
  1392. WriteLn (Log, 'File "' + fn + '" not found!');
  1393. errorhalt;
  1394. end;
  1395. end;
  1396. line:=0;
  1397. while not eof(t) do
  1398. begin
  1399. readln(t,s);
  1400. inc(line);
  1401. if (s<>'') and not(s[1] in ['#',';']) then
  1402. begin
  1403. i:=pos('=',s);
  1404. if i>0 then
  1405. begin
  1406. item:=upper(Copy(s,1,i-1));
  1407. system.delete(s,1,i);
  1408. if item='VERSION' then
  1409. cfg.version:=s
  1410. else
  1411. if item='TITLE' then
  1412. cfg.title:=s
  1413. else
  1414. if item='BASEPATH' then
  1415. cfg.basepath:=s
  1416. else
  1417. if item='HELPIDX' then
  1418. cfg.helpidx:=s
  1419. else
  1420. if item='DOCSUB' then
  1421. cfg.docsub:=s
  1422. else
  1423. if item='DEFAULTCFG' then
  1424. begin
  1425. repeat
  1426. readln(t,s);
  1427. if upper(s)='ENDCFG' then
  1428. break;
  1429. if cfg.defcfgs<maxdefcfgs then
  1430. begin
  1431. inc(cfg.defcfgs);
  1432. cfg.defcfg[cfg.defcfgs]:=newstr(s);
  1433. end;
  1434. until false;
  1435. end
  1436. else
  1437. if item='DEFAULTIDECFG' then
  1438. begin
  1439. repeat
  1440. readln(t,s);
  1441. if upper(s)='ENDCFG' then
  1442. break;
  1443. if cfg.defidecfgs<maxdefcfgs then
  1444. begin
  1445. inc(cfg.defidecfgs);
  1446. cfg.defidecfg[cfg.defidecfgs]:=newstr(s);
  1447. end;
  1448. until false;
  1449. end
  1450. else
  1451. if item='DEFAULTSETPATH' then
  1452. begin
  1453. repeat
  1454. readln(t,s);
  1455. if upper(s)='ENDCFG' then
  1456. break;
  1457. if cfg.defsetpaths<maxdefcfgs then
  1458. begin
  1459. inc(cfg.defsetpaths);
  1460. cfg.defsetpath[cfg.defsetpaths]:=newstr(s);
  1461. end;
  1462. until false;
  1463. end
  1464. else
  1465. if item='DEFAULTIDEINI' then
  1466. begin
  1467. repeat
  1468. readln(t,s);
  1469. if upper(s)='ENDCFG' then
  1470. break;
  1471. if cfg.defideinis<maxdefcfgs then
  1472. begin
  1473. inc(cfg.defideinis);
  1474. cfg.defideini[cfg.defideinis]:=newstr(s);
  1475. end;
  1476. until false;
  1477. end
  1478. else
  1479. if item='PACK' then
  1480. begin
  1481. inc(cfg.packs);
  1482. if cfg.packs>maxpacks then
  1483. begin
  1484. MessageBox ('Too many packs!', nil,
  1485. mfError + mfOkButton);
  1486. if CreateLog then
  1487. begin
  1488. WriteLn (Log, 'Too many packs');
  1489. close(log);
  1490. end;
  1491. halt(1);
  1492. end;
  1493. cfg.pack[cfg.packs].name:=s;
  1494. end
  1495. else
  1496. if item='CFGFILE' then
  1497. begin
  1498. if cfg.packs=0 then
  1499. begin
  1500. MessageBox ('No pack set found!', nil,
  1501. mfError + mfOkButton);
  1502. if CreateLog then
  1503. begin
  1504. WriteLn (Log, 'No pack set');
  1505. close(Log);
  1506. end;
  1507. halt(1);
  1508. end;
  1509. cfg.pack[cfg.packs].defcfgfile:=s
  1510. end
  1511. else
  1512. if item='IDECFGFILE' then
  1513. begin
  1514. if cfg.packs=0 then
  1515. begin
  1516. MessageBox ('No pack set found!', nil,
  1517. mfError + mfOkButton);
  1518. if CreateLog then
  1519. begin
  1520. WriteLn (Log, 'No pack set');
  1521. Close(Log);
  1522. end;
  1523. halt(1);
  1524. end;
  1525. cfg.pack[cfg.packs].defidecfgfile:=s
  1526. end
  1527. else
  1528. if item='SETPATHFILE' then
  1529. begin
  1530. if cfg.packs=0 then
  1531. begin
  1532. MessageBox ('No pack set found!', nil,
  1533. mfError + mfOkButton);
  1534. if CreateLog then
  1535. begin
  1536. WriteLn (Log, 'No pack set');
  1537. close(Log);
  1538. end;
  1539. halt(1);
  1540. end;
  1541. cfg.pack[cfg.packs].setpathfile:=s
  1542. end
  1543. else
  1544. if item='IDEINIFILE' then
  1545. begin
  1546. if cfg.packs=0 then
  1547. begin
  1548. MessageBox ('No pack set found!', nil,
  1549. mfError + mfOkButton);
  1550. if CreateLog then
  1551. begin
  1552. WriteLn (Log, 'No pack set');
  1553. Close(Log);
  1554. end;
  1555. halt(1);
  1556. end;
  1557. cfg.pack[cfg.packs].defideinifile:=s
  1558. end
  1559. else
  1560. if item='PPC386' then
  1561. begin
  1562. if cfg.packs=0 then
  1563. begin
  1564. MessageBox ('No pack set found!', nil,
  1565. mfError + mfOkButton);
  1566. if CreateLog then
  1567. begin
  1568. WriteLn (Log, 'No pack set');
  1569. Close(Log);
  1570. end;
  1571. halt(1);
  1572. end;
  1573. cfg.pack[cfg.packs].ppc386:=s;
  1574. end
  1575. else
  1576. if item='BINSUB' then
  1577. begin
  1578. if cfg.packs=0 then
  1579. begin
  1580. MessageBox ('No pack set found!', nil,
  1581. mfError + mfOkButton);
  1582. if CreateLog then
  1583. begin
  1584. WriteLn (Log, 'No pack set');
  1585. Close(Log);
  1586. end;
  1587. halt(1);
  1588. end;
  1589. cfg.pack[cfg.packs].binsub:=s;
  1590. end
  1591. {else: Obsolete PM }
  1592. { if item='FILECHECK' then
  1593. begin
  1594. if cfg.packs=0 then
  1595. begin
  1596. MessageBox ('No pack set found!', nil,
  1597. mfError + mfOkButton);
  1598. if CreateLog then
  1599. WriteLn (Log, 'No pack set');
  1600. halt(1);
  1601. end;
  1602. cfg.pack[cfg.packs].filechk:=s;
  1603. end }
  1604. else
  1605. if item='TARGETNAME' then
  1606. begin
  1607. if cfg.packs=0 then
  1608. begin
  1609. MessageBox ('No pack set found!', nil,
  1610. mfError + mfOkButton);
  1611. if CreateLog then
  1612. begin
  1613. WriteLn (Log, 'No pack set');
  1614. Close(Log);
  1615. end;
  1616. halt(1);
  1617. end;
  1618. cfg.pack[cfg.packs].targetname:=s;
  1619. end
  1620. else
  1621. if item='PACKAGE' then
  1622. begin
  1623. if cfg.packs=0 then
  1624. begin
  1625. MessageBox ('No pack set found!', nil,
  1626. mfError + mfOkButton);
  1627. if CreateLog then
  1628. begin
  1629. WriteLn (Log, 'No pack set');
  1630. Close(Log);
  1631. end;
  1632. halt(1);
  1633. end;
  1634. with cfg.pack[cfg.packs] do
  1635. begin
  1636. j:=pos(',',s);
  1637. if (j>0) and (packages<maxpackages) then
  1638. begin
  1639. inc(packages);
  1640. hs:=copy(s,1,j-1);
  1641. k:=pos('[',hs);
  1642. if (k>0) then
  1643. begin
  1644. package[packages].zip:=Copy(hs,1,k-1);
  1645. package[packages].zipshort:=Copy(hs,k+1,length(hs)-k-1);
  1646. end
  1647. else
  1648. package[packages].zip:=hs;
  1649. package[packages].name:=copy(s,j+1,255);
  1650. end;
  1651. package[packages].diskspace:=-1;
  1652. end;
  1653. end
  1654. end;
  1655. end;
  1656. end;
  1657. close(t);
  1658. end;
  1659. procedure tapp.checkavailpack;
  1660. var
  1661. i, j : longint;
  1662. one_found : boolean;
  1663. begin
  1664. { check the packages }
  1665. j:=0;
  1666. while (j<cfg.packs) do
  1667. begin
  1668. inc(j);
  1669. one_found:=false;
  1670. {if cfg.pack[j].filechk<>'' then}
  1671. for i:=1 to cfg.pack[j].packages do
  1672. begin
  1673. if file_exists(cfg.pack[j].package[i].zip,startpath) or
  1674. file_exists(cfg.pack[j].package[i].zipshort,startpath) then
  1675. begin
  1676. one_found:=true;
  1677. break;
  1678. end;
  1679. end;
  1680. if not one_found then
  1681. begin
  1682. { remove the package }
  1683. move(cfg.pack[j+1],cfg.pack[j],sizeof(tpack)*(cfg.packs-j));
  1684. dec(cfg.packs);
  1685. dec(j);
  1686. end;
  1687. end;
  1688. end;
  1689. procedure tapp.initmenubar;
  1690. var
  1691. r : trect;
  1692. begin
  1693. getextent(r);
  1694. r.b.y:=r.a.y+1;
  1695. menubar:=new(pmenubar,init(r,newmenu(
  1696. newsubmenu('Free Pascal Installer',hcnocontext,newmenu(nil
  1697. ),
  1698. nil))));
  1699. end;
  1700. procedure tapp.handleevent(var event : tevent);
  1701. begin
  1702. inherited handleevent(event);
  1703. if event.what=evcommand then
  1704. if event.command=cmstart then
  1705. begin
  1706. clearevent(event);
  1707. do_installdialog;
  1708. if successfull then
  1709. begin
  1710. event.what:=evcommand;
  1711. event.command:=cmquit;
  1712. handleevent(event);
  1713. end;
  1714. end;
  1715. end;
  1716. {$IFDEF DOSSTUB}
  1717. function CheckOS2: boolean;
  1718. var
  1719. OwnName: PathStr;
  1720. OwnDir: DirStr;
  1721. Name: NameStr;
  1722. Ext: ExtStr;
  1723. DosV, W: word;
  1724. P: PChar;
  1725. const
  1726. Title: string [15] = 'FPC Installer'#0;
  1727. RunBlock: TRunBlock = (Length: $32;
  1728. Dependent: 0;
  1729. Background: 0;
  1730. TraceLevel: 0;
  1731. PrgTitle: @Title [1];
  1732. PrgName: nil;
  1733. Args: nil;
  1734. TermQ: 0;
  1735. Environment: nil;
  1736. Inheritance: 0;
  1737. SesType: 2;
  1738. Icon: nil;
  1739. PgmHandle: 0;
  1740. PgmControl: 2;
  1741. Column: 0;
  1742. Row: 0;
  1743. Width: 80;
  1744. Height: 25);
  1745. begin
  1746. CheckOS2 := false;
  1747. asm
  1748. mov ah, 30h
  1749. int 21h
  1750. xchg ah, al
  1751. mov DosV, ax
  1752. mov ax, 4010h
  1753. int 2Fh
  1754. cmp ax, 4010h
  1755. jnz @0
  1756. xor bx, bx
  1757. @0:
  1758. mov W, bx
  1759. end;
  1760. if DosV > 3 shl 8 then
  1761. begin
  1762. OwnName := FExpand (ParamStr (0));
  1763. FSplit (OwnName, OwnDir, Name, Ext);
  1764. if (DosV >= 20 shl 8 + 10) and (W >= 20 shl 8 + 10) then
  1765. (* OS/2 version 2.1 or later running (double-checked) *)
  1766. begin
  1767. OwnName [Succ (byte (OwnName [0]))] := #0;
  1768. RunBlock.PrgName := @OwnName [1];
  1769. P := Ptr (PrefixSeg, $80);
  1770. if PByte (P)^ <> 0 then
  1771. begin
  1772. Inc (P);
  1773. RunBlock.Args := Ptr (PrefixSeg, $81);
  1774. end;
  1775. asm
  1776. mov ax, 6400h
  1777. mov bx, 0025h
  1778. mov cx, 636Ch
  1779. mov si, offset RunBlock
  1780. int 21h
  1781. jc @0
  1782. mov DosV, 0
  1783. @0:
  1784. end;
  1785. CheckOS2 := DosV = 0;
  1786. end;
  1787. end;
  1788. end;
  1789. {$ENDIF}
  1790. procedure usagescreen;
  1791. begin
  1792. writeln('FPC Installer ',installerversion,' ',installercopyright);
  1793. writeln('Command line options:');
  1794. writeln(' -l create log file');
  1795. {$ifdef MAYBE_LFN}
  1796. writeln(' --nolfn force installation with short file names');
  1797. {$endif MAYBE_LFN}
  1798. writeln;
  1799. writeln(' -h displays this help');
  1800. end;
  1801. var
  1802. i : longint;
  1803. vm : tvideomode;
  1804. begin
  1805. { register objects for help streaming }
  1806. RegisterWHTMLScan;
  1807. {$IFDEF OS2}
  1808. { TH - no error boxes if checking an inaccessible disk etc. }
  1809. {$IFDEF FPC}
  1810. DosCalls.DosError (0);
  1811. {$ELSE FPC}
  1812. {$IFDEF VirtualPascal}
  1813. OS2Base.DosError (ferr_DisableHardErr);
  1814. {$ELSE VirtualPascal}
  1815. BseDos.DosError (0);
  1816. {$ENDIF VirtualPascal}
  1817. {$ENDIF FPC}
  1818. {$ENDIF}
  1819. {$IFDEF DOSSTUB}
  1820. if CheckOS2 then Halt;
  1821. {$ENDIF}
  1822. createlog:=false;
  1823. {$ifdef MAYBE_LFN}
  1824. locallfnsupport:=system.lfnsupport;
  1825. {$endif MAYBE_LFN}
  1826. for i:=1 to paramcount do
  1827. begin
  1828. if paramstr(i)='-l' then
  1829. createlog:=true
  1830. {$ifdef MAYBE_LFN}
  1831. else if paramstr(i)='--nolfn' then
  1832. begin
  1833. locallfnsupport:=false;
  1834. {$ifdef GO32V2}
  1835. { lfnsupport is a const in win32 RTL }
  1836. system.lfnsupport:=locallfnsupport;
  1837. {$endif GO32V2}
  1838. end
  1839. {$endif MAYBE_LFN}
  1840. else if paramstr(i)='-h' then
  1841. begin
  1842. usagescreen;
  1843. halt(0);
  1844. end
  1845. else
  1846. begin
  1847. usagescreen;
  1848. halt(1);
  1849. end;
  1850. end;
  1851. if createlog then
  1852. begin
  1853. assign(log,'install.log');
  1854. rewrite(log);
  1855. {$ifdef MAYBE_LFN}
  1856. if not(locallfnsupport) then
  1857. writeln(log,'OS doesn''t have LFN support');
  1858. {$endif}
  1859. end;
  1860. getdir(0,startpath);
  1861. successfull:=false;
  1862. fillchar(cfg, SizeOf(cfg), 0);
  1863. fillchar(data, SizeOf(data), 0);
  1864. installapp.init;
  1865. vm.col:=80;
  1866. vm.row:=25;
  1867. vm.color:=true;
  1868. installapp.SetScreenVideoMode(vm);
  1869. FSplit (FExpand (ParamStr (0)), DStr, CfgName, EStr);
  1870. installapp.readcfg(CfgName + CfgExt);
  1871. installapp.checkavailpack;
  1872. { installapp.readcfg(startpath+dirsep+cfgfile);}
  1873. {$ifdef GO32V2}
  1874. if not(lfnsupport) then
  1875. MessageBox('The operating system doesn''t support LFN (long file names),'+
  1876. ' so some packages will get shorten filenames when installed',nil,mfinformation or mfokbutton);
  1877. {$endif}
  1878. installapp.do_installdialog;
  1879. installapp.done;
  1880. if createlog then
  1881. close(log);
  1882. end.
  1883. {
  1884. $Log$
  1885. Revision 1.28 2005-01-07 16:48:14 peter
  1886. * fix writing of -T<targetos>
  1887. Revision 1.27 2005/01/05 21:27:55 hajny
  1888. * error message boxes instead of writeln
  1889. Revision 1.26 2005/01/05 17:43:44 armin
  1890. * maxpacks increased tp 30, close logfile before halt
  1891. Revision 1.25 2004/12/31 18:36:44 florian
  1892. * spelling fixed
  1893. * compiler is fpc instead ppc386
  1894. Revision 1.24 2004/12/23 17:36:53 peter
  1895. use %token% macros instead of $1 and $2
  1896. Revision 1.23 2004/12/22 15:28:48 peter
  1897. * more fixes for win32 installer
  1898. Revision 1.22 2004/12/21 18:52:31 peter
  1899. checkbox mask works, scrollbox still not
  1900. Revision 1.21 2004/12/20 18:27:00 peter
  1901. * win32 fixes
  1902. Revision 1.20 2004/12/18 16:19:57 peter
  1903. win32 fixes
  1904. Revision 1.19 2003/04/06 15:56:25 carl
  1905. * Use FPC user screen for Win32 target
  1906. Revision 1.18 2003/03/05 21:12:32 hajny
  1907. * missing quotes in GO32v2-specific part
  1908. Revision 1.17 2003/03/01 16:15:42 hajny
  1909. + logging enhanced
  1910. Revision 1.16 2003/02/08 21:49:59 carl
  1911. * DOS : fix user screen problem
  1912. DOS: emu386 reinstated
  1913. Revision 1.15 2003/01/22 14:15:13 pierre
  1914. * center all dialogs
  1915. Revision 1.14 2003/01/22 13:42:35 pierre
  1916. * fix problem with Alt-X (webbug 1959)
  1917. + use fpusrscr unit to restore console at exit.
  1918. Revision 1.13 2002/09/07 15:40:59 peter
  1919. * old logs removed and tabs fixed
  1920. Revision 1.12 2002/07/06 11:51:04 carl
  1921. + Unzip DLL fixes for warnings
  1922. Revision 1.11 2002/06/02 17:24:27 marco
  1923. * Renamefest
  1924. Revision 1.10 2002/06/01 19:43:07 marco
  1925. * Renamefest
  1926. Revision 1.9 2002/04/11 13:20:27 pierre
  1927. + several go32v2 related fixes
  1928. Revision 1.8 2002/04/10 21:18:42 pierre
  1929. * explicitly check if one of the files from the list of each package exists
  1930. Revision 1.7 2002/04/03 12:46:02 pierre
  1931. + create setpath.bat file if Path is mixed
  1932. Revision 1.6 2002/03/19 09:14:56 pierre
  1933. * fix fpctoc.html problem
  1934. Revision 1.5 2002/03/13 22:27:36 pierre
  1935. * fix problem if invalid drive is given
  1936. Revision 1.4 2002/02/28 21:30:34 peter
  1937. * regenated
  1938. Revision 1.3 2002/02/28 17:02:08 pierre
  1939. * fix win32 compilation if DEBUG cond is set
  1940. Revision 1.2 2002/01/29 22:01:17 peter
  1941. * support fvision
  1942. Revision 1.1 2002/01/29 17:59:15 peter
  1943. * moved installer
  1944. }