/kol/System/D2005/SysUtils.pas

https://bitbucket.org/krak/guidgenerator · Pascal · 16719 lines · 12400 code · 1484 blank · 2835 comment · 792 complexity · 7698f403b0e1da1267c4795ba961e473 MD5 · raw file

Large files are truncated click here to view the full file

  1. { *********************************************************************** }
  2. { }
  3. { Delphi / Kylix Cross-Platform Runtime Library }
  4. { System Utilities Unit }
  5. { }
  6. { Copyright (c) 1995-2004 Borland Software Corporation }
  7. { }
  8. { Copyright and license exceptions noted in source }
  9. { }
  10. { *********************************************************************** }
  11. unit SysUtils;
  12. {$H+}
  13. {$WARN SYMBOL_PLATFORM OFF}
  14. {$WARN UNSAFE_TYPE OFF}
  15. interface
  16. uses
  17. {$IFDEF MSWINDOWS}
  18. Windows, kol,
  19. {$ENDIF}
  20. {$IFDEF LINUX}
  21. Types,
  22. Libc,
  23. {$ENDIF}
  24. SysConst;
  25. const
  26. { File open modes }
  27. {$IFDEF LINUX}
  28. fmOpenRead = O_RDONLY;
  29. fmOpenWrite = O_WRONLY;
  30. fmOpenReadWrite = O_RDWR;
  31. // fmShareCompat not supported
  32. fmShareExclusive = $0010;
  33. fmShareDenyWrite = $0020;
  34. // fmShareDenyRead not supported
  35. fmShareDenyNone = $0030;
  36. {$ENDIF}
  37. {$IFDEF MSWINDOWS}
  38. fmOpenRead = $0000;
  39. fmOpenWrite = $0001;
  40. fmOpenReadWrite = $0002;
  41. fmShareCompat = $0000 platform; // DOS compatibility mode is not portable
  42. fmShareExclusive = $0010;
  43. fmShareDenyWrite = $0020;
  44. fmShareDenyRead = $0030 platform; // write-only not supported on all platforms
  45. fmShareDenyNone = $0040;
  46. {$ENDIF}
  47. { File attribute constants }
  48. faReadOnly = $00000001 platform;
  49. faHidden = $00000002 platform;
  50. faSysFile = $00000004 platform;
  51. faVolumeID = $00000008 platform deprecated; // not used in Win32
  52. faDirectory = $00000010;
  53. faArchive = $00000020 platform;
  54. faSymLink = $00000040 platform;
  55. faAnyFile = $0000003F;
  56. { Units of time }
  57. HoursPerDay = 24;
  58. MinsPerHour = 60;
  59. SecsPerMin = 60;
  60. MSecsPerSec = 1000;
  61. MinsPerDay = HoursPerDay * MinsPerHour;
  62. SecsPerDay = MinsPerDay * SecsPerMin;
  63. MSecsPerDay = SecsPerDay * MSecsPerSec;
  64. { Days between 1/1/0001 and 12/31/1899 }
  65. DateDelta = 693594;
  66. { Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) }
  67. UnixDateDelta = 25569;
  68. type
  69. { Standard Character set type }
  70. TSysCharSet = set of Char;
  71. { Set access to an integer }
  72. TIntegerSet = set of 0..SizeOf(Integer) * 8 - 1;
  73. { Type conversion records }
  74. WordRec = packed record
  75. case Integer of
  76. 0: (Lo, Hi: Byte);
  77. 1: (Bytes: array [0..1] of Byte);
  78. end;
  79. LongRec = packed record
  80. case Integer of
  81. 0: (Lo, Hi: Word);
  82. 1: (Words: array [0..1] of Word);
  83. 2: (Bytes: array [0..3] of Byte);
  84. end;
  85. Int64Rec = packed record
  86. case Integer of
  87. 0: (Lo, Hi: Cardinal);
  88. 1: (Cardinals: array [0..1] of Cardinal);
  89. 2: (Words: array [0..3] of Word);
  90. 3: (Bytes: array [0..7] of Byte);
  91. end;
  92. { General arrays }
  93. PByteArray = ^TByteArray;
  94. TByteArray = array[0..32767] of Byte;
  95. PWordArray = ^TWordArray;
  96. TWordArray = array[0..16383] of Word;
  97. { Generic procedure pointer }
  98. TProcedure = procedure;
  99. { Generic filename type }
  100. TFileName = type string;
  101. { Search record used by FindFirst, FindNext, and FindClose }
  102. TSearchRec = record
  103. Time: Integer;
  104. Size: Integer;
  105. Attr: Integer;
  106. Name: TFileName;
  107. ExcludeAttr: Integer;
  108. {$IFDEF MSWINDOWS}
  109. FindHandle: THandle platform;
  110. FindData: TWin32FindData platform;
  111. {$ENDIF}
  112. {$IFDEF LINUX}
  113. Mode: mode_t platform;
  114. FindHandle: Pointer platform;
  115. PathOnly: String platform;
  116. Pattern: String platform;
  117. {$ENDIF}
  118. end;
  119. { FloatToText, FloatToTextFmt, TextToFloat, and FloatToDecimal type codes }
  120. TFloatValue = (fvExtended, fvCurrency);
  121. { FloatToText format codes }
  122. TFloatFormat = (ffGeneral, ffExponent, ffFixed, ffNumber, ffCurrency);
  123. { FloatToDecimal result record }
  124. TFloatRec = packed record
  125. Exponent: Smallint;
  126. Negative: Boolean;
  127. Digits: array[0..20] of Char;
  128. end;
  129. { Date and time record }
  130. TTimeStamp = record
  131. Time: Integer; { Number of milliseconds since midnight }
  132. Date: Integer; { One plus number of days since 1/1/0001 }
  133. end;
  134. { MultiByte Character Set (MBCS) byte type }
  135. TMbcsByteType = (mbSingleByte, mbLeadByte, mbTrailByte);
  136. { System Locale information record }
  137. TSysLocale = packed record
  138. DefaultLCID: Integer;
  139. PriLangID: Integer;
  140. SubLangID: Integer;
  141. FarEast: Boolean;
  142. MiddleEast: Boolean;
  143. end;
  144. {$IFDEF MSWINDOWS}
  145. { This is used by TLanguages }
  146. TLangRec = packed record
  147. FName: string;
  148. FLCID: LCID;
  149. FExt: string;
  150. end;
  151. { This stores the languages that the system supports }
  152. TLanguages = class
  153. private
  154. FSysLangs: array of TLangRec;
  155. function LocalesCallback(LocaleID: PChar): Integer; stdcall;
  156. function GetExt(Index: Integer): string;
  157. function GetID(Index: Integer): string;
  158. function GetLCID(Index: Integer): LCID;
  159. function GetName(Index: Integer): string;
  160. function GetNameFromLocaleID(ID: LCID): string;
  161. function GetNameFromLCID(const ID: string): string;
  162. function GetCount: integer;
  163. public
  164. constructor Create;
  165. function IndexOf(ID: LCID): Integer;
  166. property Count: Integer read GetCount;
  167. property Name[Index: Integer]: string read GetName;
  168. property NameFromLocaleID[ID: LCID]: string read GetNameFromLocaleID;
  169. property NameFromLCID[const ID: string]: string read GetNameFromLCID;
  170. property ID[Index: Integer]: string read GetID;
  171. property LocaleID[Index: Integer]: LCID read GetLCID;
  172. property Ext[Index: Integer]: string read GetExt;
  173. end platform;
  174. {$ENDIF}
  175. {$IFDEF LINUX}
  176. TEraRange = record
  177. StartDate : Integer; // whole days since 12/31/1899 (TDateTime basis)
  178. EndDate : Integer; // whole days since 12/31/1899 (TDateTime basis)
  179. // Direction : Char;
  180. end;
  181. {$ENDIF}
  182. { Exceptions }
  183. Exception = class(TObject)
  184. private
  185. FMessage: string;
  186. FHelpContext: Integer;
  187. public
  188. constructor Create(const Msg: string);
  189. constructor CreateFmt(const Msg: string; const Args: array of const);
  190. constructor CreateRes(Ident: Integer); overload;
  191. constructor CreateRes(const ResStringRec: string); overload;
  192. constructor CreateResFmt(Ident: Integer; const Args: array of const); overload;
  193. constructor CreateResFmt(const ResStringRec: string; const Args: array of const); overload;
  194. constructor CreateHelp(const Msg: string; AHelpContext: Integer);
  195. constructor CreateFmtHelp(const Msg: string; const Args: array of const;
  196. AHelpContext: Integer);
  197. constructor CreateResHelp(Ident: Integer; AHelpContext: Integer); overload;
  198. constructor CreateResHelp(ResStringRec: PResStringRec; AHelpContext: Integer); overload;
  199. constructor CreateResFmtHelp(ResStringRec: PResStringRec; const Args: array of const;
  200. AHelpContext: Integer); overload;
  201. constructor CreateResFmtHelp(Ident: Integer; const Args: array of const;
  202. AHelpContext: Integer); overload;
  203. property HelpContext: Integer read FHelpContext write FHelpContext;
  204. property Message: string read FMessage write FMessage;
  205. end;
  206. ExceptClass = class of Exception;
  207. EAbort = class(Exception);
  208. EHeapException = class(Exception)
  209. private
  210. AllowFree: Boolean;
  211. public
  212. procedure FreeInstance; override;
  213. end;
  214. EOutOfMemory = class(EHeapException);
  215. EInOutError = class(Exception)
  216. public
  217. ErrorCode: Integer;
  218. end;
  219. {$IFDEF MSWINDOWS}
  220. PExceptionRecord = ^TExceptionRecord;
  221. TExceptionRecord = record
  222. ExceptionCode: Cardinal;
  223. ExceptionFlags: Cardinal;
  224. ExceptionRecord: PExceptionRecord;
  225. ExceptionAddress: Pointer;
  226. NumberParameters: Cardinal;
  227. ExceptionInformation: array[0..14] of Cardinal;
  228. end;
  229. {$ENDIF}
  230. EExternal = class(Exception)
  231. public
  232. {$IFDEF MSWINDOWS}
  233. ExceptionRecord: PExceptionRecord platform;
  234. {$ENDIF}
  235. {$IFDEF LINUX}
  236. ExceptionAddress: LongWord platform;
  237. AccessAddress: LongWord platform;
  238. SignalNumber: Integer platform;
  239. {$ENDIF}
  240. end;
  241. EExternalException = class(EExternal);
  242. EIntError = class(EExternal);
  243. EDivByZero = class(EIntError);
  244. ERangeError = class(EIntError);
  245. EIntOverflow = class(EIntError);
  246. EMathError = class(EExternal);
  247. EInvalidOp = class(EMathError);
  248. EZeroDivide = class(EMathError);
  249. EOverflow = class(EMathError);
  250. EUnderflow = class(EMathError);
  251. EInvalidPointer = class(EHeapException);
  252. EInvalidCast = class(Exception);
  253. EConvertError = class(Exception);
  254. EAccessViolation = class(EExternal);
  255. EPrivilege = class(EExternal);
  256. EStackOverflow = class(EExternal)
  257. end deprecated;
  258. EControlC = class(EExternal);
  259. {$IFDEF LINUX}
  260. EQuit = class(EExternal) end platform;
  261. {$ENDIF}
  262. {$IFDEF LINUX}
  263. ECodesetConversion = class(Exception) end platform;
  264. {$ENDIF}
  265. EVariantError = class(Exception);
  266. EPropReadOnly = class(Exception);
  267. EPropWriteOnly = class(Exception);
  268. EAssertionFailed = class(Exception);
  269. {$IFNDEF PC_MAPPED_EXCEPTIONS}
  270. EAbstractError = class(Exception) end platform;
  271. {$ENDIF}
  272. EIntfCastError = class(Exception);
  273. EInvalidContainer = class(Exception);
  274. EInvalidInsert = class(Exception);
  275. EPackageError = class(Exception);
  276. EOSError = class(Exception)
  277. public
  278. ErrorCode: DWORD;
  279. end;
  280. {$IFDEF MSWINDOWS}
  281. EWin32Error = class(EOSError)
  282. end deprecated;
  283. {$ENDIF}
  284. ESafecallException = class(Exception);
  285. {$IFDEF LINUX}
  286. {
  287. Signals
  288. External exceptions, or signals, are, by default, converted to language
  289. exceptions by the Delphi RTL. Under Linux, a Delphi application installs
  290. signal handlers to trap the raw signals, and convert them. Delphi libraries
  291. do not install handlers by default. So if you are implementing a standalone
  292. library, such as an Apache DSO, and you want to have signals converted to
  293. language exceptions that you can catch, you must install signal hooks
  294. manually, using the interfaces that the Delphi RTL provides.
  295. For most libraries, installing signal handlers is pretty
  296. straightforward. Call HookSignal(RTL_SIGDEFAULT) at initialization time,
  297. and UnhookSignal(RTL_SIGNALDEFAULT) at shutdown. This will install handlers
  298. for a set of signals that the RTL normally hooks for Delphi applications.
  299. There are some cases where the above initialization will not work properly:
  300. The proper behaviour for setting up signal handlers is to set
  301. a signal handler, and then later restore the signal handler to its previous
  302. state when you clean up. If you have two libraries lib1 and lib2, and lib1
  303. installs a signal handler, and then lib2 installs a signal handler, those
  304. libraries have to uninstall in the proper order if they restore signal
  305. handlers, or the signal handlers can be left in an inconsistent and
  306. potentially fatal state. Not all libraries behave well with respect to
  307. installing signal handlers. To hedge against this possibility, and allow
  308. you to manage signal handlers better in the face of whatever behaviour
  309. you may find in external libraries, we provide a set of four interfaces to
  310. allow you to tailor the Delphi signal handler hooking/unhooking in the
  311. event of an emergency. These are:
  312. InquireSignal
  313. AbandonSignalHandler
  314. HookSignal
  315. UnhookSignal
  316. InquireSignal allows you to look at the state of a signal handler, so
  317. that you can find out if someone grabbed it out from under you.
  318. AbandonSignalHandler tells the RTL never to unhook a particular
  319. signal handler. This can be used if you find a case where it would
  320. be unsafe to return to the previous state of signal handling. For
  321. example, if the previous signal handler was installed by a library
  322. which has since been unloaded.
  323. HookSignal/UnhookSignal setup signal handlers that map certain signals
  324. into language exceptions.
  325. See additional notes at InquireSignal, et al, below.
  326. }
  327. const
  328. RTL_SIGINT = 0; // User interrupt (SIGINT)
  329. RTL_SIGFPE = 1; // Floating point exception (SIGFPE)
  330. RTL_SIGSEGV = 2; // Segmentation violation (SIGSEGV)
  331. RTL_SIGILL = 3; // Illegal instruction (SIGILL)
  332. RTL_SIGBUS = 4; // Bus error (SIGBUS)
  333. RTL_SIGQUIT = 5; // User interrupt (SIGQUIT)
  334. RTL_SIGLAST = RTL_SIGQUIT; // Used internally. Don't use this.
  335. RTL_SIGDEFAULT = -1; // Means all of a set of signals that the we capture
  336. // normally. This is currently all of the preceding
  337. // signals. You cannot pass this to InquireSignal.
  338. type
  339. { TSignalState is the state of a given signal handler, as returned by
  340. InquireSignal. See InquireSignal, below.
  341. }
  342. TSignalState = (ssNotHooked, ssHooked, ssOverridden);
  343. var
  344. {
  345. If DeferUserInterrupts is set, we do not raise either SIGINT or SIGQUIT as
  346. an exception, instead, we set SIGINTIssued or SIGQUITIssued when the
  347. signal arrives, and swallow the signal where the OS issued it. This gives
  348. GUI applications the chance to defer the actual handling of the signal
  349. until a time when it is safe to do so.
  350. }
  351. DeferUserInterrupts: Boolean;
  352. SIGINTIssued: Boolean;
  353. SIGQUITIssued: Boolean;
  354. {$ENDIF}
  355. {$IFDEF LINUX}
  356. const
  357. MAX_PATH = 4095; // From /usr/include/linux/limits.h PATH_MAX
  358. {$ENDIF}
  359. var
  360. { Empty string and null string pointer. These constants are provided for
  361. backwards compatibility only. }
  362. EmptyStr: string = '';
  363. NullStr: PString = @EmptyStr;
  364. EmptyWideStr: WideString = '';
  365. NullWideStr: PWideString = @EmptyWideStr;
  366. {$IFDEF MSWINDOWS}
  367. { Win32 platform identifier. This will be one of the following values:
  368. VER_PLATFORM_WIN32s
  369. VER_PLATFORM_WIN32_WINDOWS
  370. VER_PLATFORM_WIN32_NT
  371. See WINDOWS.PAS for the numerical values. }
  372. Win32Platform: Integer = 0;
  373. { Win32 OS version information -
  374. see TOSVersionInfo.dwMajorVersion/dwMinorVersion/dwBuildNumber }
  375. Win32MajorVersion: Integer = 0;
  376. Win32MinorVersion: Integer = 0;
  377. Win32BuildNumber: Integer = 0;
  378. { Win32 OS extra version info string -
  379. see TOSVersionInfo.szCSDVersion }
  380. Win32CSDVersion: string = '';
  381. { Win32 OS version tester }
  382. function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean;
  383. { GetFileVersion returns the most significant 32 bits of a file's binary
  384. version number. Typically, this includes the major and minor version placed
  385. together in one 32-bit integer. It generally does not include the release
  386. or build numbers. It returns Cardinal(-1) if it failed. }
  387. function GetFileVersion(const AFileName: string): Cardinal;
  388. {$ENDIF}
  389. { Currency and date/time formatting options
  390. The initial values of these variables are fetched from the system registry
  391. using the GetLocaleInfo function in the Win32 API. The description of each
  392. variable specifies the LOCALE_XXXX constant used to fetch the initial
  393. value.
  394. CurrencyString - Defines the currency symbol used in floating-point to
  395. decimal conversions. The initial value is fetched from LOCALE_SCURRENCY.
  396. CurrencyFormat - Defines the currency symbol placement and separation
  397. used in floating-point to decimal conversions. Possible values are:
  398. 0 = '$1'
  399. 1 = '1$'
  400. 2 = '$ 1'
  401. 3 = '1 $'
  402. The initial value is fetched from LOCALE_ICURRENCY.
  403. NegCurrFormat - Defines the currency format for used in floating-point to
  404. decimal conversions of negative numbers. Possible values are:
  405. 0 = '($1)' 4 = '(1$)' 8 = '-1 $' 12 = '$ -1'
  406. 1 = '-$1' 5 = '-1$' 9 = '-$ 1' 13 = '1- $'
  407. 2 = '$-1' 6 = '1-$' 10 = '1 $-' 14 = '($ 1)'
  408. 3 = '$1-' 7 = '1$-' 11 = '$ 1-' 15 = '(1 $)'
  409. The initial value is fetched from LOCALE_INEGCURR.
  410. ThousandSeparator - The character used to separate thousands in numbers
  411. with more than three digits to the left of the decimal separator. The
  412. initial value is fetched from LOCALE_STHOUSAND. A value of #0 indicates
  413. no thousand separator character should be output even if the format string
  414. specifies thousand separators.
  415. DecimalSeparator - The character used to separate the integer part from
  416. the fractional part of a number. The initial value is fetched from
  417. LOCALE_SDECIMAL. DecimalSeparator must be a non-zero value.
  418. CurrencyDecimals - The number of digits to the right of the decimal point
  419. in a currency amount. The initial value is fetched from LOCALE_ICURRDIGITS.
  420. DateSeparator - The character used to separate the year, month, and day
  421. parts of a date value. The initial value is fetched from LOCATE_SDATE.
  422. ShortDateFormat - The format string used to convert a date value to a
  423. short string suitable for editing. For a complete description of date and
  424. time format strings, refer to the documentation for the FormatDate
  425. function. The short date format should only use the date separator
  426. character and the m, mm, d, dd, yy, and yyyy format specifiers. The
  427. initial value is fetched from LOCALE_SSHORTDATE.
  428. LongDateFormat - The format string used to convert a date value to a long
  429. string suitable for display but not for editing. For a complete description
  430. of date and time format strings, refer to the documentation for the
  431. FormatDate function. The initial value is fetched from LOCALE_SLONGDATE.
  432. TimeSeparator - The character used to separate the hour, minute, and
  433. second parts of a time value. The initial value is fetched from
  434. LOCALE_STIME.
  435. TimeAMString - The suffix string used for time values between 00:00 and
  436. 11:59 in 12-hour clock format. The initial value is fetched from
  437. LOCALE_S1159.
  438. TimePMString - The suffix string used for time values between 12:00 and
  439. 23:59 in 12-hour clock format. The initial value is fetched from
  440. LOCALE_S2359.
  441. ShortTimeFormat - The format string used to convert a time value to a
  442. short string with only hours and minutes. The default value is computed
  443. from LOCALE_ITIME and LOCALE_ITLZERO.
  444. LongTimeFormat - The format string used to convert a time value to a long
  445. string with hours, minutes, and seconds. The default value is computed
  446. from LOCALE_ITIME and LOCALE_ITLZERO.
  447. ShortMonthNames - Array of strings containing short month names. The mmm
  448. format specifier in a format string passed to FormatDate causes a short
  449. month name to be substituted. The default values are fecthed from the
  450. LOCALE_SABBREVMONTHNAME system locale entries.
  451. LongMonthNames - Array of strings containing long month names. The mmmm
  452. format specifier in a format string passed to FormatDate causes a long
  453. month name to be substituted. The default values are fecthed from the
  454. LOCALE_SMONTHNAME system locale entries.
  455. ShortDayNames - Array of strings containing short day names. The ddd
  456. format specifier in a format string passed to FormatDate causes a short
  457. day name to be substituted. The default values are fecthed from the
  458. LOCALE_SABBREVDAYNAME system locale entries.
  459. LongDayNames - Array of strings containing long day names. The dddd
  460. format specifier in a format string passed to FormatDate causes a long
  461. day name to be substituted. The default values are fecthed from the
  462. LOCALE_SDAYNAME system locale entries.
  463. ListSeparator - The character used to separate items in a list. The
  464. initial value is fetched from LOCALE_SLIST.
  465. TwoDigitYearCenturyWindow - Determines what century is added to two
  466. digit years when converting string dates to numeric dates. This value
  467. is subtracted from the current year before extracting the century.
  468. This can be used to extend the lifetime of existing applications that
  469. are inextricably tied to 2 digit year data entry. The best solution
  470. to Year 2000 (Y2k) issues is not to accept 2 digit years at all - require
  471. 4 digit years in data entry to eliminate century ambiguities.
  472. Examples:
  473. Current TwoDigitCenturyWindow Century StrToDate() of:
  474. Year Value Pivot '01/01/03' '01/01/68' '01/01/50'
  475. -------------------------------------------------------------------------
  476. 1998 0 1900 1903 1968 1950
  477. 2002 0 2000 2003 2068 2050
  478. 1998 50 (default) 1948 2003 1968 1950
  479. 2002 50 (default) 1952 2003 1968 2050
  480. 2020 50 (default) 1970 2003 2068 2050
  481. }
  482. var
  483. CurrencyString: string;
  484. CurrencyFormat: Byte;
  485. NegCurrFormat: Byte;
  486. ThousandSeparator: Char;
  487. DecimalSeparator: Char;
  488. CurrencyDecimals: Byte;
  489. DateSeparator: Char;
  490. ShortDateFormat: string;
  491. LongDateFormat: string;
  492. TimeSeparator: Char;
  493. TimeAMString: string;
  494. TimePMString: string;
  495. ShortTimeFormat: string;
  496. LongTimeFormat: string;
  497. ShortMonthNames: array[1..12] of string;
  498. LongMonthNames: array[1..12] of string;
  499. ShortDayNames: array[1..7] of string;
  500. LongDayNames: array[1..7] of string;
  501. SysLocale: TSysLocale;
  502. TwoDigitYearCenturyWindow: Word = 50;
  503. ListSeparator: Char;
  504. { Thread safe currency and date/time formatting
  505. The TFormatSettings record is designed to allow thread safe formatting,
  506. equivalent to the gloabal variables described above. Each of the
  507. formatting routines that use the gloabal variables have overloaded
  508. equivalents, requiring an additional parameter of type TFormatSettings.
  509. A TFormatSettings record must be populated before use. This can be done
  510. using the GetLocaleFormatSettings function, which will populate the
  511. record with values based on the given locale (using the Win32 API
  512. function GetLocaleInfo). Note that some format specifiers still require
  513. specific thread locale settings (such as period/era names).
  514. }
  515. type
  516. TFormatSettings = record
  517. CurrencyFormat: Byte;
  518. NegCurrFormat: Byte;
  519. ThousandSeparator: Char;
  520. DecimalSeparator: Char;
  521. CurrencyDecimals: Byte;
  522. DateSeparator: Char;
  523. TimeSeparator: Char;
  524. ListSeparator: Char;
  525. CurrencyString: string;
  526. ShortDateFormat: string;
  527. LongDateFormat: string;
  528. TimeAMString: string;
  529. TimePMString: string;
  530. ShortTimeFormat: string;
  531. LongTimeFormat: string;
  532. ShortMonthNames: array[1..12] of string;
  533. LongMonthNames: array[1..12] of string;
  534. ShortDayNames: array[1..7] of string;
  535. LongDayNames: array[1..7] of string;
  536. TwoDigitYearCenturyWindow: Word;
  537. end;
  538. TLocaleOptions = (loInvariantLocale, loUserLocale);
  539. const
  540. MaxEraCount = 7;
  541. var
  542. EraNames: array [1..MaxEraCount] of string;
  543. EraYearOffsets: array [1..MaxEraCount] of Integer;
  544. {$IFDEF LINUX}
  545. EraRanges : array [1..MaxEraCount] of TEraRange platform;
  546. EraYearFormats: array [1..MaxEraCount] of string platform;
  547. EraCount: Byte platform;
  548. {$ENDIF}
  549. const
  550. PathDelim = {$IFDEF MSWINDOWS} '\'; {$ELSE} '/'; {$ENDIF}
  551. DriveDelim = {$IFDEF MSWINDOWS} ':'; {$ELSE} ''; {$ENDIF}
  552. PathSep = {$IFDEF MSWINDOWS} ';'; {$ELSE} ':'; {$ENDIF}
  553. {$IFDEF MSWINDOWS}
  554. function Languages: TLanguages;
  555. {$ENDIF}
  556. { Memory management routines }
  557. { AllocMem allocates a block of the given size on the heap. Each byte in
  558. the allocated buffer is set to zero. To dispose the buffer, use the
  559. FreeMem standard procedure. }
  560. function AllocMem(Size: Cardinal): Pointer;
  561. { Exit procedure handling }
  562. { AddExitProc adds the given procedure to the run-time library's exit
  563. procedure list. When an application terminates, its exit procedures are
  564. executed in reverse order of definition, i.e. the last procedure passed
  565. to AddExitProc is the first one to get executed upon termination. }
  566. procedure AddExitProc(Proc: TProcedure);
  567. { String handling routines }
  568. { NewStr allocates a string on the heap. NewStr is provided for backwards
  569. compatibility only. }
  570. function NewStr(const S: string): PString; deprecated;
  571. { DisposeStr disposes a string pointer that was previously allocated using
  572. NewStr. DisposeStr is provided for backwards compatibility only. }
  573. procedure DisposeStr(P: PString); deprecated;
  574. { AssignStr assigns a new dynamically allocated string to the given string
  575. pointer. AssignStr is provided for backwards compatibility only. }
  576. procedure AssignStr(var P: PString; const S: string); deprecated;
  577. { AppendStr appends S to the end of Dest. AppendStr is provided for
  578. backwards compatibility only. Use "Dest := Dest + S" instead. }
  579. procedure AppendStr(var Dest: string; const S: string); deprecated;
  580. { UpperCase converts all ASCII characters in the given string to upper case.
  581. The conversion affects only 7-bit ASCII characters between 'a' and 'z'. To
  582. convert 8-bit international characters, use AnsiUpperCase. }
  583. function UpperCase(const S: string): string; overload;
  584. function UpperCase(const S: string; LocaleOptions: TLocaleOptions): string; overload; inline;
  585. { LowerCase converts all ASCII characters in the given string to lower case.
  586. The conversion affects only 7-bit ASCII characters between 'A' and 'Z'. To
  587. convert 8-bit international characters, use AnsiLowerCase. }
  588. function LowerCase(const S: string): string; overload;
  589. function LowerCase(const S: string; LocaleOptions: TLocaleOptions): string; overload; inline;
  590. { CompareStr compares S1 to S2, with case-sensitivity. The return value is
  591. less than 0 if S1 < S2, 0 if S1 = S2, or greater than 0 if S1 > S2. The
  592. compare operation is based on the 8-bit ordinal value of each character
  593. and is not affected by the current user locale. }
  594. function CompareStr(const S1, S2: string): Integer; overload;
  595. function CompareStr(const S1, S2: string; LocaleOptions: TLocaleOptions): Integer; overload;
  596. { SameStr compares S1 to S2, with case-sensitivity. Returns true if
  597. S1 and S2 are the equal, that is, if CompareStr would return 0. }
  598. function SameStr(const S1, S2: string): Boolean; overload;
  599. function SameStr(const S1, S2: string; LocaleOptions: TLocaleOptions): Boolean; overload;
  600. { CompareMem performs a binary compare of Length bytes of memory referenced
  601. by P1 to that of P2. CompareMem returns True if the memory referenced by
  602. P1 is identical to that of P2. }
  603. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
  604. { CompareText compares S1 to S2, without case-sensitivity. The return value
  605. is the same as for CompareStr. The compare operation is based on the 8-bit
  606. ordinal value of each character, after converting 'a'..'z' to 'A'..'Z',
  607. and is not affected by the current user locale. }
  608. function CompareText(const S1, S2: string): Integer; overload;
  609. function CompareText(const S1, S2: string; LocaleOptions: TLocaleOptions): Integer; overload;
  610. { SameText compares S1 to S2, without case-sensitivity. Returns true if
  611. S1 and S2 are the equal, that is, if CompareText would return 0. SameText
  612. has the same 8-bit limitations as CompareText }
  613. function SameText(const S1, S2: string): Boolean; overload;
  614. function SameText(const S1, S2: string; LocaleOptions: TLocaleOptions): Boolean; overload;
  615. { AnsiUpperCase converts all characters in the given string to upper case.
  616. The conversion uses the current user locale. }
  617. function AnsiUpperCase(const S: string): string;
  618. { AnsiLowerCase converts all characters in the given string to lower case.
  619. The conversion uses the current user locale. }
  620. function AnsiLowerCase(const S: string): string;
  621. { AnsiCompareStr compares S1 to S2, with case-sensitivity. The compare
  622. operation is controlled by the current user locale. The return value
  623. is the same as for CompareStr. }
  624. function AnsiCompareStr(const S1, S2: string): Integer; inline;
  625. { AnsiSameStr compares S1 to S2, with case-sensitivity. The compare
  626. operation is controlled by the current user locale. The return value
  627. is True if AnsiCompareStr would have returned 0. }
  628. function AnsiSameStr(const S1, S2: string): Boolean; inline;
  629. { AnsiCompareText compares S1 to S2, without case-sensitivity. The compare
  630. operation is controlled by the current user locale. The return value
  631. is the same as for CompareStr. }
  632. function AnsiCompareText(const S1, S2: string): Integer; inline;
  633. { AnsiSameText compares S1 to S2, without case-sensitivity. The compare
  634. operation is controlled by the current user locale. The return value
  635. is True if AnsiCompareText would have returned 0. }
  636. function AnsiSameText(const S1, S2: string): Boolean; inline;
  637. { AnsiStrComp compares S1 to S2, with case-sensitivity. The compare
  638. operation is controlled by the current user locale. The return value
  639. is the same as for CompareStr. }
  640. function AnsiStrComp(S1, S2: PChar): Integer; inline;
  641. { AnsiStrIComp compares S1 to S2, without case-sensitivity. The compare
  642. operation is controlled by the current user locale. The return value
  643. is the same as for CompareStr. }
  644. function AnsiStrIComp(S1, S2: PChar): Integer; inline;
  645. { AnsiStrLComp compares S1 to S2, with case-sensitivity, up to a maximum
  646. length of MaxLen bytes. The compare operation is controlled by the
  647. current user locale. The return value is the same as for CompareStr. }
  648. function AnsiStrLComp(S1, S2: PChar; MaxLen: Cardinal): Integer;
  649. { AnsiStrLIComp compares S1 to S2, without case-sensitivity, up to a maximum
  650. length of MaxLen bytes. The compare operation is controlled by the
  651. current user locale. The return value is the same as for CompareStr. }
  652. function AnsiStrLIComp(S1, S2: PChar; MaxLen: Cardinal): Integer;
  653. { AnsiStrLower converts all characters in the given string to lower case.
  654. The conversion uses the current user locale. }
  655. function AnsiStrLower(Str: PChar): PChar;
  656. { AnsiStrUpper converts all characters in the given string to upper case.
  657. The conversion uses the current user locale. }
  658. function AnsiStrUpper(Str: PChar): PChar;
  659. { AnsiLastChar returns a pointer to the last full character in the string.
  660. This function supports multibyte characters }
  661. function AnsiLastChar(const S: string): PChar;
  662. { AnsiStrLastChar returns a pointer to the last full character in the string.
  663. This function supports multibyte characters. }
  664. function AnsiStrLastChar(P: PChar): PChar;
  665. { WideUpperCase converts all characters in the given string to upper case. }
  666. function WideUpperCase(const S: WideString): WideString;
  667. { WideLowerCase converts all characters in the given string to lower case. }
  668. function WideLowerCase(const S: WideString): WideString;
  669. { WideCompareStr compares S1 to S2, with case-sensitivity. The return value
  670. is the same as for CompareStr. }
  671. function WideCompareStr(const S1, S2: WideString): Integer;
  672. { WideSameStr compares S1 to S2, with case-sensitivity. The return value
  673. is True if WideCompareStr would have returned 0. }
  674. function WideSameStr(const S1, S2: WideString): Boolean; inline;
  675. { WideCompareText compares S1 to S2, without case-sensitivity. The return value
  676. is the same as for CompareStr. }
  677. function WideCompareText(const S1, S2: WideString): Integer;
  678. { WideSameText compares S1 to S2, without case-sensitivity. The return value
  679. is True if WideCompareText would have returned 0. }
  680. function WideSameText(const S1, S2: WideString): Boolean; inline;
  681. { Trim trims leading and trailing spaces and control characters from the
  682. given string. }
  683. function Trim(const S: string): string; overload;
  684. function Trim(const S: WideString): WideString; overload;
  685. { TrimLeft trims leading spaces and control characters from the given
  686. string. }
  687. function TrimLeft(const S: string): string; overload;
  688. function TrimLeft(const S: WideString): WideString; overload;
  689. { TrimRight trims trailing spaces and control characters from the given
  690. string. }
  691. function TrimRight(const S: string): string; overload;
  692. function TrimRight(const S: WideString): WideString; overload;
  693. { QuotedStr returns the given string as a quoted string. A single quote
  694. character is inserted at the beginning and the end of the string, and
  695. for each single quote character in the string, another one is added. }
  696. function QuotedStr(const S: string): string;
  697. { AnsiQuotedStr returns the given string as a quoted string, using the
  698. provided Quote character. A Quote character is inserted at the beginning
  699. and end of the string, and each Quote character in the string is doubled.
  700. This function supports multibyte character strings (MBCS). }
  701. function AnsiQuotedStr(const S: string; Quote: Char): string;
  702. { AnsiExtractQuotedStr removes the Quote characters from the beginning and end
  703. of a quoted string, and reduces pairs of Quote characters within the quoted
  704. string to a single character. If the first character in Src is not the Quote
  705. character, the function returns an empty string. The function copies
  706. characters from the Src to the result string until the second solitary
  707. Quote character or the first null character in Src. The Src parameter is
  708. updated to point to the first character following the quoted string. If
  709. the Src string does not contain a matching end Quote character, the Src
  710. parameter is updated to point to the terminating null character in Src.
  711. This function supports multibyte character strings (MBCS). }
  712. function AnsiExtractQuotedStr(var Src: PChar; Quote: Char): string;
  713. { AnsiDequotedStr is a simplified version of AnsiExtractQuotedStr }
  714. function AnsiDequotedStr(const S: string; AQuote: Char): string;
  715. { AdjustLineBreaks adjusts all line breaks in the given string to the
  716. indicated style.
  717. When Style is tlbsCRLF, the function changes all
  718. CR characters not followed by LF and all LF characters not preceded
  719. by a CR into CR/LF pairs.
  720. When Style is tlbsLF, the function changes all CR/LF pairs and CR characters
  721. not followed by LF to LF characters. }
  722. function AdjustLineBreaks(const S: string; Style: TTextLineBreakStyle =
  723. {$IFDEF LINUX} tlbsLF {$ENDIF}
  724. {$IFDEF MSWINDOWS} tlbsCRLF {$ENDIF}): string;
  725. { IsValidIdent returns true if the given string is a valid identifier. An
  726. identifier is defined as a character from the set ['A'..'Z', 'a'..'z', '_']
  727. followed by zero or more characters from the set ['A'..'Z', 'a'..'z',
  728. '0..'9', '_']. With DotNet code we need to allow dots in the names.}
  729. function IsValidIdent(const Ident: string; AllowDots: Boolean = False): Boolean;
  730. { IntToStr converts the given value to its decimal string representation. }
  731. function IntToStr(Value: Integer): string; overload;
  732. function IntToStr(Value: Int64): string; overload;
  733. { IntToHex converts the given value to a hexadecimal string representation
  734. with the minimum number of digits specified. }
  735. function IntToHex(Value: Integer; Digits: Integer): string; overload;
  736. function IntToHex(Value: Int64; Digits: Integer): string; overload;
  737. { StrToInt converts the given string to an integer value. If the string
  738. doesn't contain a valid value, an EConvertError exception is raised. }
  739. function StrToInt(const S: string): Integer;
  740. function StrToIntDef(const S: string; Default: Integer): Integer;
  741. function TryStrToInt(const S: string; out Value: Integer): Boolean;
  742. { Similar to the above functions but for Int64 instead }
  743. function StrToInt64(const S: string): Int64;
  744. function StrToInt64Def(const S: string; const Default: Int64): Int64;
  745. function TryStrToInt64(const S: string; out Value: Int64): Boolean;
  746. { StrToBool converts the given string to a boolean value. If the string
  747. doesn't contain a valid value, an EConvertError exception is raised.
  748. BoolToStr converts boolean to a string value that in turn can be converted
  749. back into a boolean. BoolToStr will always pick the first element of
  750. the TrueStrs/FalseStrs arrays. }
  751. var
  752. TrueBoolStrs: array of String;
  753. FalseBoolStrs: array of String;
  754. const
  755. DefaultTrueBoolStr = 'True'; // DO NOT LOCALIZE
  756. DefaultFalseBoolStr = 'False'; // DO NOT LOCALIZE
  757. function StrToBool(const S: string): Boolean;
  758. function StrToBoolDef(const S: string; const Default: Boolean): Boolean;
  759. function TryStrToBool(const S: string; out Value: Boolean): Boolean;
  760. function BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string;
  761. { LoadStr loads the string resource given by Ident from the application's
  762. executable file or associated resource module. If the string resource
  763. does not exist, LoadStr returns an empty string. }
  764. function LoadStr(Ident: Integer): string;
  765. { FmtLoadStr loads the string resource given by Ident from the application's
  766. executable file or associated resource module, and uses it as the format
  767. string in a call to the Format function with the given arguments. }
  768. function FmtLoadStr(Ident: Integer; const Args: array of const): string;
  769. { File management routines }
  770. { FileOpen opens the specified file using the specified access mode. The
  771. access mode value is constructed by OR-ing one of the fmOpenXXXX constants
  772. with one of the fmShareXXXX constants. If the return value is positive,
  773. the function was successful and the value is the file handle of the opened
  774. file. A return value of -1 indicates that an error occurred. }
  775. function FileOpen(const FileName: string; Mode: LongWord): Integer;
  776. { FileCreate creates a new file by the specified name. If the return value
  777. is positive, the function was successful and the value is the file handle
  778. of the new file. A return value of -1 indicates that an error occurred.
  779. On Linux, this calls FileCreate(FileName, DEFFILEMODE) to create
  780. the file with read and write access for the current user only. }
  781. function FileCreate(const FileName: string): Integer; overload; inline;
  782. { This second version of FileCreate lets you specify the access rights to put on the newly
  783. created file. The access rights parameter is ignored on Win32 }
  784. function FileCreate(const FileName: string; Rights: Integer): Integer; overload; inline;
  785. { FileRead reads Count bytes from the file given by Handle into the buffer
  786. specified by Buffer. The return value is the number of bytes actually
  787. read; it is less than Count if the end of the file was reached. The return
  788. value is -1 if an error occurred. }
  789. function FileRead(Handle: Integer; var Buffer; Count: LongWord): Integer;
  790. { FileWrite writes Count bytes to the file given by Handle from the buffer
  791. specified by Buffer. The return value is the number of bytes actually
  792. written, or -1 if an error occurred. }
  793. function FileWrite(Handle: Integer; const Buffer; Count: LongWord): Integer;
  794. { FileSeek changes the current position of the file given by Handle to be
  795. Offset bytes relative to the point given by Origin. Origin = 0 means that
  796. Offset is relative to the beginning of the file, Origin = 1 means that
  797. Offset is relative to the current position, and Origin = 2 means that
  798. Offset is relative to the end of the file. The return value is the new
  799. current position, relative to the beginning of the file, or -1 if an error
  800. occurred. }
  801. function FileSeek(Handle, Offset, Origin: Integer): Integer; overload;
  802. function FileSeek(Handle: Integer; const Offset: Int64; Origin: Integer): Int64; overload;
  803. { FileClose closes the specified file. }
  804. procedure FileClose(Handle: Integer); inline;
  805. { FileAge returns the date-and-time stamp of the specified file. The return
  806. value can be converted to a TDateTime value using the FileDateToDateTime
  807. function. The return value is -1 if the file does not exist. }
  808. function FileAge(const FileName: string): Integer;
  809. { FileExists returns a boolean value that indicates whether the specified
  810. file exists. }
  811. function FileExists(const FileName: string): Boolean; inline;
  812. { DirectoryExists returns a boolean value that indicates whether the
  813. specified directory exists (and is actually a directory) }
  814. function DirectoryExists(const Directory: string): Boolean;
  815. { ForceDirectories ensures that all the directories in a specific path exist.
  816. Any portion that does not already exist will be created. Function result
  817. indicates success of the operation. The function can fail if the current
  818. user does not have sufficient file access rights to create directories in
  819. the given path. }
  820. function ForceDirectories(Dir: string): Boolean;
  821. { FindFirst searches the directory given by Path for the first entry that
  822. matches the filename given by Path and the attributes given by Attr. The
  823. result is returned in the search record given by SearchRec. The return
  824. value is zero if the function was successful. Otherwise the return value
  825. is a system error code. After calling FindFirst, always call FindClose.
  826. FindFirst is typically used with FindNext and FindClose as follows:
  827. Result := FindFirst(Path, Attr, SearchRec);
  828. while Result = 0 do
  829. begin
  830. ProcessSearchRec(SearchRec);
  831. Result := FindNext(SearchRec);
  832. end;
  833. FindClose(SearchRec);
  834. where ProcessSearchRec represents user-defined code that processes the
  835. information in a search record. }
  836. function FindFirst(const Path: string; Attr: Integer;
  837. var F: TSearchRec): Integer;
  838. { FindNext returs the next entry that matches the name and attributes
  839. specified in a previous call to FindFirst. The search record must be one
  840. that was passed to FindFirst. The return value is zero if the function was
  841. successful. Otherwise the return value is a system error code. }
  842. function FindNext(var F: TSearchRec): Integer;
  843. { FindClose terminates a FindFirst/FindNext sequence and frees memory and system
  844. resources allocated by FindFirst.
  845. Every FindFirst/FindNext must end with a call to FindClose. }
  846. procedure FindClose(var F: TSearchRec);
  847. { FileGetDate returns the OS date-and-time stamp of the file given by
  848. Handle. The return value is -1 if the handle is invalid. The
  849. FileDateToDateTime function can be used to convert the returned value to
  850. a TDateTime value. }
  851. function FileGetDate(Handle: Integer): Integer;
  852. { FileSetDate sets the OS date-and-time stamp of the file given by FileName
  853. to the value given by Age. The DateTimeToFileDate function can be used to
  854. convert a TDateTime value to an OS date-and-time stamp. The return value
  855. is zero if the function was successful. Otherwise the return value is a
  856. system error code. }
  857. function FileSetDate(const FileName: string; Age: Integer): Integer; overload;
  858. {$IFDEF MSWINDOWS}
  859. { FileSetDate by handle is not available on Unix platforms because there
  860. is no standard way to set a file's modification time using only a file
  861. handle, and no standard way to obtain the file name of an open
  862. file handle. }
  863. function FileSetDate(Handle: Integer; Age: Integer): Integer; overload; platform;
  864. { FileGetAttr returns the file attributes of the file given by FileName. The
  865. attributes can be examined by AND-ing with the faXXXX constants defined
  866. above. A return value of -1 indicates that an error occurred. }
  867. function FileGetAttr(const FileName: string): Integer; platform;
  868. { FileSetAttr sets the file attributes of the file given by FileName to the
  869. value given by Attr. The attribute value is formed by OR-ing the
  870. appropriate faXXXX constants. The return value is zero if the function was
  871. successful. Otherwise the return value is a system error code. }
  872. function FileSetAttr(const FileName: string; Attr: Integer): Integer; platform;
  873. {$ENDIF}
  874. { FileIsReadOnly tests whether a given file is read-only for the current
  875. process and effective user id. If the file does not exist, the
  876. function returns False. (Check FileExists before calling FileIsReadOnly)
  877. This function is platform portable. }
  878. function FileIsReadOnly(const FileName: string): Boolean; inline;
  879. { FileSetReadOnly sets the read only state of a file. The file must
  880. exist and the current effective user id must be the owner of the file.
  881. On Unix systems, FileSetReadOnly attempts to set or remove
  882. all three (user, group, and other) write permissions on the file.
  883. If you want to grant partial permissions (writeable for owner but not
  884. for others), use platform specific functions such as chmod.
  885. The function returns True if the file was successfully modified,
  886. False if there was an error. This function is platform portable. }
  887. function FileSetReadOnly(const FileName: string; ReadOnly: Boolean): Boolean;
  888. { DeleteFile deletes the file given by FileName. The return value is True if
  889. the file was successfully deleted, or False if an error occurred. }
  890. function DeleteFile(const FileName: string): Boolean; inline;
  891. { RenameFile renames the file given by OldName to the name given by NewName.
  892. The return value is True if the file was successfully renamed, or False if
  893. an error occurred. }
  894. function RenameFile(const OldName, NewName: string): Boolean; inline;
  895. { ChangeFileExt changes the extension of a filename. FileName specifies a
  896. filename with or without an extension, and Extension specifies the new
  897. extension for the filename. The new extension can be a an empty string or
  898. a period followed by up to three characters. }
  899. function ChangeFileExt(const FileName, Extension: string): string;
  900. { ExtractFilePath extracts the drive and directory parts of the given
  901. filename. The resulting string is the leftmost characters of FileName,
  902. up to and including the colon or backslash that separates the path
  903. information from the name and extension. The resulting string is empty
  904. if FileName contains no drive and directory parts. }
  905. function ExtractFilePath(const FileName: string): string;
  906. { ExtractFileDir extracts the drive and directory parts of the given
  907. filename. The resulting string is a directory name suitable for passing
  908. to SetCurrentDir, CreateDir, etc. The resulting string is empty if
  909. FileName contains no drive and directory parts. }
  910. function ExtractFileDir(const FileName: string): string;
  911. { ExtractFileDrive extracts the drive part of the given filename. For
  912. filenames with drive letters, the resulting string is '<drive>:'.
  913. For filenames with a UNC path, the resulting string is in the form
  914. '\\<servername>\<sharename>'. If the given path contains neither
  915. style of filename, the result is an empty string. }
  916. function ExtractFileDrive(const FileName: string): string;
  917. { ExtractFileName extracts the name and extension parts of the given
  918. filename. The resulting string is the leftmost characters of FileName,
  919. starting with the first character after the colon or backslash that
  920. separates the path information from the name and extension. The resulting
  921. string is equal to FileName if FileName contains no drive and directory
  922. parts. }
  923. function ExtractFileName(const FileName: string): string;
  924. { ExtractFileExt extracts the extension part of the given filename. The
  925. resulting string includes the period character that separates the name
  926. and extension parts. The resulting string is empty if the given filename
  927. has no extension. }
  928. function ExtractFileExt(const FileName: string): string;
  929. { ExpandFileName expands the given filename to a fully qualified filename.
  930. The resulting string consists of a drive letter, a colon, a root relative
  931. directory path, and a filename. Embedded '.' and '..' directory references
  932. are removed. }
  933. function ExpandFileName(const FileName: string): string;
  934. { ExpandFilenameCase returns a fully qualified filename like ExpandFilename,
  935. but performs a case-insensitive filename search looking for a close match
  936. in the actual file system, differing only in uppercase versus lowercase of
  937. the letters. This is useful to convert lazy user input into useable file
  938. names, or to convert filename data created on a case-insensitive file
  939. system (Win32) to something useable on a case-sensitive file system (Linux).
  940. The MatchFound out parameter indicates what kind of match was found in the
  941. file system, and what the function result is based upon:
  942. ( in order of increasing difficulty or complexity )
  943. mkExactMatch: Case-sensitive match. Result := ExpandFileName(FileName).
  944. mkSingleMatch: Exactly one file in the given directory path matches the
  945. given filename on a case-insensitive basis.
  946. Result := ExpandFileName(FileName as found in file system).
  947. mkAmbiguous: More than one file in the given directory path matches the
  948. given filename case-insensitively.
  949. In many cases, this should be considered an error.
  950. Result := ExpandFileName(First matching filename found).
  951. mkNone: File not found at all. Result := ExpandFileName(FileName).
  952. Note that because this function has to search the file system it may be
  953. much slower than ExpandFileName, particularly when the given filename is
  954. ambiguous or does not exist. Use ExpandFilenameCase only when you have
  955. a filename of dubious orgin - such as from user input - and you want
  956. to make a best guess before failing. }
  957. type
  958. TFilenameCaseMatch = (mkNone, mkExactMatch, mkSingleMatch, mkAmbiguous);
  959. function ExpandFileNameCase(const FileName: string;
  960. out MatchFound: TFilenameCaseMatch): string;
  961. { ExpandUNCFileName expands the given file