sysutils.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2021 by Free Pascal development team
  4. Sysutils unit for Sinclair QL
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit sysutils;
  12. interface
  13. {$MODE objfpc}
  14. {$MODESWITCH OUT}
  15. { force ansistrings }
  16. {$H+}
  17. {$modeswitch typehelpers}
  18. {$modeswitch advancedrecords}
  19. {$DEFINE OS_FILESETDATEBYNAME}
  20. {$DEFINE HAS_SLEEP}
  21. {$DEFINE HAS_OSERROR}
  22. {OS has only 1 byte version for ExecuteProcess}
  23. {$define executeprocuni}
  24. { used OS file system APIs use ansistring }
  25. {$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  26. { OS has an ansistring/single byte environment variable API }
  27. {$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
  28. { Include platform independent interface part }
  29. {$i sysutilh.inc}
  30. { Platform dependent calls }
  31. implementation
  32. uses
  33. sysconst;
  34. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  35. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  36. { Include platform independent implementation part }
  37. {$i sysutils.inc}
  38. {$i qdosfuncs.inc}
  39. {$i smsfuncs.inc}
  40. {****************************************************************************
  41. File Functions
  42. ****************************************************************************}
  43. {$I-}{ Required for correct usage of these routines }
  44. (****** non portable routines ******)
  45. function FileOpen(const FileName: rawbytestring; Mode: Integer): THandle;
  46. begin
  47. FileOpen:=-1;
  48. if FileOpen < -1 then
  49. FileOpen:=-1;
  50. end;
  51. function FileGetDate(Handle: THandle) : Int64;
  52. begin
  53. result:=-1;
  54. end;
  55. function FileSetDate(Handle: THandle; Age: Int64) : LongInt;
  56. begin
  57. result:=0;
  58. end;
  59. function FileSetDate(const FileName: RawByteString; Age: Int64) : LongInt;
  60. var
  61. f: THandle;
  62. begin
  63. result:=-1;
  64. f:=FileOpen(FileName,fmOpenReadWrite);
  65. if f < 0 then
  66. exit;
  67. result:=FileSetDate(f,Age);
  68. FileClose(f);
  69. end;
  70. function FileCreate(const FileName: RawByteString) : THandle;
  71. begin
  72. FileCreate:=-1;
  73. if FileCreate < -1 then
  74. FileCreate:=-1;
  75. end;
  76. function FileCreate(const FileName: RawByteString; Rights: integer): THandle;
  77. begin
  78. { Rights don't exist on the QL, so we simply map this to FileCreate() }
  79. FileCreate:=FileCreate(FileName);
  80. end;
  81. function FileCreate(const FileName: RawByteString; ShareMode: integer; Rights : integer): THandle;
  82. begin
  83. { Rights and ShareMode don't exist on the QL so we simply map this to FileCreate() }
  84. FileCreate:=FileCreate(FileName);
  85. end;
  86. function FileRead(Handle: THandle; out Buffer; Count: LongInt): LongInt;
  87. begin
  88. FileRead:=-1;
  89. if (Count<=0) then
  90. exit;
  91. FileRead:=-1;
  92. if FileRead < -1 then
  93. FileRead:=-1;
  94. end;
  95. function FileWrite(Handle: THandle; const Buffer; Count: LongInt): LongInt;
  96. begin
  97. FileWrite:=-1;
  98. if (Count<=0) then
  99. exit;
  100. FileWrite:=-1;
  101. if FileWrite < -1 then
  102. FileWrite:=-1;
  103. end;
  104. function FileSeek(Handle: THandle; FOffset, Origin: LongInt) : LongInt;
  105. var
  106. dosResult: longint;
  107. begin
  108. FileSeek:=-1;
  109. dosResult:=-1;
  110. if dosResult < 0 then
  111. exit;
  112. FileSeek:=dosResult;
  113. end;
  114. function FileSeek(Handle: THandle; FOffset: Int64; Origin: Longint): Int64;
  115. begin
  116. FileSeek:=FileSeek(Handle,LongInt(FOffset),Origin);
  117. end;
  118. procedure FileClose(Handle: THandle);
  119. begin
  120. end;
  121. function FileTruncate(Handle: THandle; Size: Int64): Boolean;
  122. begin
  123. FileTruncate:=False;
  124. end;
  125. function DeleteFile(const FileName: RawByteString) : Boolean;
  126. begin
  127. DeleteFile:=false;
  128. end;
  129. function RenameFile(const OldName, NewName: RawByteString): Boolean;
  130. begin
  131. RenameFile:=false;
  132. end;
  133. (****** end of non portable routines ******)
  134. function FileAge (const FileName : RawByteString): Int64;
  135. var
  136. f: THandle;
  137. begin
  138. FileAge:=-1;
  139. f:=FileOpen(FileName,fmOpenRead);
  140. if f < 0 then
  141. exit;
  142. FileAge:=FileGetDate(f);
  143. FileClose(f);
  144. end;
  145. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  146. begin
  147. Result := False;
  148. end;
  149. function FileExists (const FileName : RawByteString; FollowLink : Boolean) : Boolean;
  150. var
  151. Attr: longint;
  152. begin
  153. FileExists:=false;
  154. Attr:=FileGetAttr(FileName);
  155. if Attr < 0 then
  156. exit;
  157. result:=(Attr and (faVolumeID or faDirectory)) = 0;
  158. end;
  159. type
  160. PInternalFindData = ^TInternalFindData;
  161. TInternalFindData = record
  162. dummy: pointer;
  163. end;
  164. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  165. var
  166. dosResult: longint;
  167. IFD: PInternalFindData;
  168. begin
  169. result:=-1; { We emulate Linux/Unix behaviour, and return -1 on errors. }
  170. new(IFD);
  171. IFD^.dummy:=nil;
  172. Rslt.FindHandle:=nil;
  173. dosResult:=-1; { add findfirst here }
  174. if dosResult < 0 then
  175. begin
  176. InternalFindClose(IFD);
  177. exit;
  178. end;
  179. Rslt.FindHandle:=IFD;
  180. Name:='';
  181. SetCodePage(Name,DefaultFileSystemCodePage,false);
  182. Rslt.Time:=0;
  183. Rslt.Size:=0;
  184. { "128" is Windows "NORMALFILE" attribute. Some buggy code depend on this... :( (KB) }
  185. Rslt.Attr := 128 or 0;
  186. result:=0;
  187. end;
  188. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  189. var
  190. dosResult: longint;
  191. IFD: PInternalFindData;
  192. begin
  193. result:=-1;
  194. IFD:=PInternalFindData(Rslt.FindHandle);
  195. if not assigned(IFD) then
  196. exit;
  197. dosResult:=-1;
  198. if dosResult < 0 then
  199. exit;
  200. Name:='';
  201. SetCodePage(Name,DefaultFileSystemCodePage,false);
  202. Rslt.Time:=0;
  203. Rslt.Size:=0;
  204. { "128" is Windows "NORMALFILE" attribute. Some buggy code depend on this... :( (KB) }
  205. Rslt.Attr := 128 or 0;
  206. result:=0;
  207. end;
  208. Procedure InternalFindClose(var Handle: Pointer);
  209. var
  210. IFD: PInternalFindData;
  211. begin
  212. IFD:=PInternalFindData(Handle);
  213. if not assigned(IFD) then
  214. exit;
  215. dispose(IFD);
  216. end;
  217. (****** end of non portable routines ******)
  218. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  219. begin
  220. FileGetAttr:=0;
  221. end;
  222. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  223. begin
  224. FileSetAttr:=-1;
  225. if FileSetAttr < -1 then
  226. FileSetAttr:=-1
  227. else
  228. FileSetAttr:=0;
  229. end;
  230. {****************************************************************************
  231. Disk Functions
  232. ****************************************************************************}
  233. function DiskSize(Drive: Byte): Int64;
  234. var
  235. dosResult: longint;
  236. begin
  237. DiskSize := -1;
  238. dosResult:=-1;
  239. if dosResult < 0 then
  240. exit;
  241. DiskSize:=0;
  242. end;
  243. function DiskFree(Drive: Byte): Int64;
  244. var
  245. dosResult: longint;
  246. begin
  247. DiskFree := -1;
  248. dosResult:=-1;
  249. if dosResult < 0 then
  250. exit;
  251. DiskFree:=0;
  252. end;
  253. function DirectoryExists(const Directory: RawByteString; FollowLink : Boolean): Boolean;
  254. var
  255. Attr: longint;
  256. begin
  257. DirectoryExists:=false;
  258. Attr:=FileGetAttr(Directory);
  259. if Attr < 0 then
  260. exit;
  261. result:=(Attr and faDirectory) <> 0;
  262. end;
  263. {****************************************************************************
  264. Locale Functions
  265. ****************************************************************************}
  266. Procedure GetLocalTime(var SystemTime: TSystemTime);
  267. begin
  268. DateTimeToSystemTime(FileDateToDateTime(0),SystemTime);
  269. end;
  270. Procedure InitAnsi;
  271. Var
  272. i : longint;
  273. begin
  274. { Fill table entries 0 to 127 }
  275. for i := 0 to 96 do
  276. UpperCaseTable[i] := chr(i);
  277. for i := 97 to 122 do
  278. UpperCaseTable[i] := chr(i - 32);
  279. for i := 123 to 191 do
  280. UpperCaseTable[i] := chr(i);
  281. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  282. for i := 0 to 64 do
  283. LowerCaseTable[i] := chr(i);
  284. for i := 65 to 90 do
  285. LowerCaseTable[i] := chr(i + 32);
  286. for i := 91 to 191 do
  287. LowerCaseTable[i] := chr(i);
  288. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  289. end;
  290. Procedure InitInternational;
  291. begin
  292. InitInternationalGeneric;
  293. InitAnsi;
  294. end;
  295. function SysErrorMessage(ErrorCode: Integer): String;
  296. begin
  297. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  298. end;
  299. function GetLastOSError: Integer;
  300. begin
  301. result:=-1;
  302. end;
  303. {****************************************************************************
  304. OS utility functions
  305. ****************************************************************************}
  306. function GetPathString: String;
  307. begin
  308. {writeln('Unimplemented GetPathString');}
  309. result := '';
  310. end;
  311. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  312. begin
  313. {writeln('Unimplemented GetEnvironmentVariable');}
  314. result:='';
  315. end;
  316. Function GetEnvironmentVariableCount : Integer;
  317. begin
  318. {writeln('Unimplemented GetEnvironmentVariableCount');}
  319. result:=0;
  320. end;
  321. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  322. begin
  323. {writeln('Unimplemented GetEnvironmentString');}
  324. result:='';
  325. end;
  326. function ExecuteProcess (const Path: RawByteString; const ComLine: RawByteString;Flags:TExecuteFlags=[]):
  327. integer;
  328. var
  329. tmpPath: RawByteString;
  330. pcmdline: ShortString;
  331. CommandLine: RawByteString;
  332. E: EOSError;
  333. begin
  334. tmpPath:=ToSingleByteFileSystemEncodedFileName(Path);
  335. pcmdline:=ToSingleByteFileSystemEncodedFileName(ComLine);
  336. result:=-1; { execute here }
  337. if result < 0 then begin
  338. if ComLine = '' then
  339. CommandLine := Path
  340. else
  341. CommandLine := Path + ' ' + ComLine;
  342. E := EOSError.CreateFmt (SExecuteProcessFailed, [CommandLine, result]);
  343. E.ErrorCode := result;
  344. raise E;
  345. end;
  346. end;
  347. function ExecuteProcess (const Path: RawByteString;
  348. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  349. var
  350. CommandLine: RawByteString;
  351. I: integer;
  352. begin
  353. Commandline := '';
  354. for I := 0 to High (ComLine) do
  355. if Pos (' ', ComLine [I]) <> 0 then
  356. CommandLine := CommandLine + ' ' + '"' + ToSingleByteFileSystemEncodedFileName(ComLine [I]) + '"'
  357. else
  358. CommandLine := CommandLine + ' ' + ToSingleByteFileSystemEncodedFileName(Comline [I]);
  359. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  360. end;
  361. procedure Sleep(Milliseconds: cardinal);
  362. begin
  363. {writeln('Unimplemented sleep');}
  364. end;
  365. {****************************************************************************
  366. Initialization code
  367. ****************************************************************************}
  368. Initialization
  369. InitExceptions;
  370. InitInternational; { Initialize internationalization settings }
  371. OnBeep:=Nil; { No SysBeep() on the QL for now. }
  372. Finalization
  373. FreeTerminateProcs;
  374. DoneExceptions;
  375. end.