sysutils.pp 11 KB

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