| 1 |
|
|---|
| 2 | {ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
|---|
| 3 | º º
|
|---|
| 4 | º Sibyl Portable Component Classes º
|
|---|
| 5 | º º
|
|---|
| 6 | º Copyright (C) 1995,97 SpeedSoft Germany, All rights reserved. º
|
|---|
| 7 | º º
|
|---|
| 8 | ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ}
|
|---|
| 9 |
|
|---|
| 10 | {*******************************************************}
|
|---|
| 11 | { }
|
|---|
| 12 | { System Utilities Unit (Delphi compatible) }
|
|---|
| 13 | { }
|
|---|
| 14 | { (C) 1995-96 Joerg Pleumann }
|
|---|
| 15 | { (C) 1996 SpeedSoft }
|
|---|
| 16 | { }
|
|---|
| 17 | { Please mail All bugs And suggestions To: }
|
|---|
| 18 | { }
|
|---|
| 19 | { Internet: sa021pl @ uni-duisburg.de }
|
|---|
| 20 | { FidoNet: Joerg Pleumann @ 2:2448/136.6 }
|
|---|
| 21 | { }
|
|---|
| 22 | {*******************************************************}
|
|---|
| 23 |
|
|---|
| 24 | Unit SysUtils;
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 | Interface
|
|---|
| 28 |
|
|---|
| 29 | { define Compiler symbol GUI To Include FUNCTIONs from
|
|---|
| 30 | OS/2 PM API. If you need A Version Of SysUtils that
|
|---|
| 31 | Uses only OS/2 base API FUNCTIONs (And therefore lacks
|
|---|
| 32 | Some features), comment This Line out And recompile the
|
|---|
| 33 | Unit. Change This To produce programs that Run without
|
|---|
| 34 | the OS/2 PM being Active (may also need changes In
|
|---|
| 35 | System Unit). Normally you shouldn't Change This. }
|
|---|
| 36 |
|
|---|
| 37 | {$DEFINE GUI}
|
|---|
| 38 |
|
|---|
| 39 | {$IFDEF OS2}
|
|---|
| 40 | {$IFDEF GUI}
|
|---|
| 41 | Uses
|
|---|
| 42 | Os2Def,BseDos, BseErr, PmWin, PMSHL;
|
|---|
| 43 | {$ELSE GUI}
|
|---|
| 44 | Uses
|
|---|
| 45 | Os2Def,BseDos, BseErr;
|
|---|
| 46 | {$ENDIF GUI}
|
|---|
| 47 | {$ENDIF OS2}
|
|---|
| 48 |
|
|---|
| 49 | {$IFDEF Win95}
|
|---|
| 50 | Uses
|
|---|
| 51 | WinNt, WinBase, WinUser;
|
|---|
| 52 | {$ENDIF Win95}
|
|---|
| 53 |
|
|---|
| 54 | { constants For SPCC Notification And Error Messages And Month / Day Names. }
|
|---|
| 55 | {$I SPCC.Inc}
|
|---|
| 56 |
|
|---|
| 57 | Type
|
|---|
| 58 | { Pointer To floating Point Value. }
|
|---|
| 59 | PExtended = ^Extended;
|
|---|
| 60 |
|
|---|
| 61 | Type
|
|---|
| 62 | //Override Exception definition from System To allow formatted Create...
|
|---|
| 63 | Exception=Class(SysException)
|
|---|
| 64 | Public
|
|---|
| 65 | Constructor CreateFmt(Const Msg:String;Const Args:Array Of Const);
|
|---|
| 66 | Constructor CreateRes(Ident:Word);
|
|---|
| 67 | Constructor CreateResFmt(Ident:Word;Const Args:Array Of Const);
|
|---|
| 68 | Constructor CreateResNLS(Ident:Word);
|
|---|
| 69 | Constructor CreateResNLSFmt(Ident:Word;Const Args:Array Of Const);
|
|---|
| 70 | Constructor CreateHelp(Const Msg:String;AHelpContext:LongInt);
|
|---|
| 71 | Constructor CreateFmtHelp(Const Msg:String;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 72 | Constructor CreateResHelp(Ident:Word;AHelpContext:LongInt);
|
|---|
| 73 | Constructor CreateResFmtHelp(Ident:Word;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 74 | Constructor CreateResNLSHelp(Ident:Word;AHelpContext:LongInt);
|
|---|
| 75 | Constructor CreateResNLSFmtHelp(Ident:Word;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 76 | End;
|
|---|
| 77 |
|
|---|
| 78 | ExceptClass = Class Of Exception;
|
|---|
| 79 |
|
|---|
| 80 | EConvertError = Class(Exception);
|
|---|
| 81 |
|
|---|
| 82 | Const
|
|---|
| 83 |
|
|---|
| 84 | { File Open modes - A legal File Open Mode Is A logical combination
|
|---|
| 85 | Of an Open Mode And A sharing Mode. Please note that OS/2 Normally
|
|---|
| 86 | doesn't allow fmShareCompat, but For reasons Of compatibility the
|
|---|
| 87 | File FUNCTIONs automatically replace This constant by
|
|---|
| 88 | fmShareDenyNone. }
|
|---|
| 89 |
|
|---|
| 90 | {$IFDEF OS2}
|
|---|
| 91 | fmOpenRead = $0000;
|
|---|
| 92 | fmOpenWrite = $0001;
|
|---|
| 93 | fmOpenReadWrite = $0002;
|
|---|
| 94 | fmShareCompat = $0000;
|
|---|
| 95 | fmShareExclusive = $0010;
|
|---|
| 96 | fmShareDenyWrite = $0020;
|
|---|
| 97 | fmShareDenyRead = $0030;
|
|---|
| 98 | fmShareDenyNone = $0040;
|
|---|
| 99 | {$ENDIF}
|
|---|
| 100 |
|
|---|
| 101 | {$IFDEF Win95}
|
|---|
| 102 | fmOpenRead = $80000000;
|
|---|
| 103 | fmOpenWrite = $40000000;
|
|---|
| 104 | fmOpenReadWrite = $C0000000;
|
|---|
| 105 | fmShareCompat = $00000003;
|
|---|
| 106 | fmShareExclusive = $00000000;
|
|---|
| 107 | fmShareDenyWrite = $00000001;
|
|---|
| 108 | fmShareDenyRead = $00000002;
|
|---|
| 109 | fmShareDenyNone = $00000003;
|
|---|
| 110 | {$ENDIF}
|
|---|
| 111 |
|
|---|
| 112 | { File Record}
|
|---|
| 113 | Type
|
|---|
| 114 | TFileRec=FileRec;
|
|---|
| 115 |
|
|---|
| 116 | { File attribute constants - Please note that there Is no constant
|
|---|
| 117 | faVolumeID, since OS/2 handles volume Ids In another way than Dos
|
|---|
| 118 | does. }
|
|---|
| 119 | Const
|
|---|
| 120 | faReadOnly = $0001;
|
|---|
| 121 | faHidden = $0002;
|
|---|
| 122 | faSysFile = $0004;
|
|---|
| 123 | faDirectory = $0010;
|
|---|
| 124 | faArchive = $0020;
|
|---|
| 125 |
|
|---|
| 126 | faAnyFile = faReadOnly Or faHidden Or faSysFile Or faDirectory Or faArchive;
|
|---|
| 127 |
|
|---|
| 128 | { 'Must' attribute constants - OS/2-specific File attribute constants
|
|---|
| 129 | For searching files. Use these constants In logical combination
|
|---|
| 130 | With the normal File Attributes when calling FindFirst() To restrict
|
|---|
| 131 | the Search results. }
|
|---|
| 132 |
|
|---|
| 133 | faMustReadOnly = $0100;
|
|---|
| 134 | faMustHidden = $0200;
|
|---|
| 135 | faMustSysFile = $0400;
|
|---|
| 136 | faMustDirectory = $1000;
|
|---|
| 137 | faMustArchive = $2000;
|
|---|
| 138 |
|
|---|
| 139 | Const
|
|---|
| 140 |
|
|---|
| 141 | { File Lock-TimeOut - This TimeOut Value Is used when performing File
|
|---|
| 142 | locking / unlocking operations. Value Is given In ms. }
|
|---|
| 143 |
|
|---|
| 144 | LockTimeout: LongInt = 5000;
|
|---|
| 145 |
|
|---|
| 146 | Type
|
|---|
| 147 |
|
|---|
| 148 | { support For date And Time operations - both values are stored In
|
|---|
| 149 | one floating Point Value. the Integer part Contains the days passed
|
|---|
| 150 | since 31-Dec-0000, assuming that the Gregorian calendar has always
|
|---|
| 151 | been used. the fractional part Contains the part Of the Day since
|
|---|
| 152 | 00:00:00. the Time part Is always equal To Or greater than Zero
|
|---|
| 153 | And smaller than one. }
|
|---|
| 154 |
|
|---|
| 155 | TDateTime = Extended;
|
|---|
| 156 |
|
|---|
| 157 | Const
|
|---|
| 158 |
|
|---|
| 159 | SecsPerDay = 24 * 60 * 60;
|
|---|
| 160 | MSecsPerDay = SecsPerDay * 1000;
|
|---|
| 161 |
|
|---|
| 162 | Type
|
|---|
| 163 |
|
|---|
| 164 | { Some Type conversion records. }
|
|---|
| 165 |
|
|---|
| 166 | WordRec = Record
|
|---|
| 167 | Lo, Hi: Byte;
|
|---|
| 168 | End;
|
|---|
| 169 |
|
|---|
| 170 | LongRec = Record
|
|---|
| 171 | Lo, Hi: Word;
|
|---|
| 172 | End;
|
|---|
| 173 |
|
|---|
| 174 | TMethod = Record
|
|---|
| 175 | Code, Data: Pointer;
|
|---|
| 176 | End;
|
|---|
| 177 |
|
|---|
| 178 | { Some useful arrays. }
|
|---|
| 179 |
|
|---|
| 180 | PByteArray = ^TByteArray;
|
|---|
| 181 | TByteArray = Array[0..MaxLongInt] Of Byte;
|
|---|
| 182 |
|
|---|
| 183 | PWordArray = ^TWordArray;
|
|---|
| 184 | TWordArray = Array[0..MaxLongInt Div 2] Of Word;
|
|---|
| 185 |
|
|---|
| 186 | { Generic Procedure Type. }
|
|---|
| 187 |
|
|---|
| 188 | TProcedure = Procedure;
|
|---|
| 189 |
|
|---|
| 190 | { Generic FileName Type }
|
|---|
| 191 |
|
|---|
| 192 | TFileName = String;
|
|---|
| 193 |
|
|---|
| 194 | { File Search Record - This Is the Data structure internally used
|
|---|
| 195 | by the FindFirst, FindNext, And FindClose FUNCTIONs. }
|
|---|
| 196 |
|
|---|
| 197 | TSearchRec = Record
|
|---|
| 198 | {$IFDEF Win95}
|
|---|
| 199 | InternalAttr:LongWord;
|
|---|
| 200 | SearchRecIntern:WIN32_FIND_DATA;
|
|---|
| 201 | {$ENDIF}
|
|---|
| 202 | HDir: LongWord;
|
|---|
| 203 | Attr: Byte;
|
|---|
| 204 | Time: LongInt;
|
|---|
| 205 | Size: LongInt;
|
|---|
| 206 | Name: String;
|
|---|
| 207 | End;
|
|---|
| 208 |
|
|---|
| 209 | { FloatToText codes - these codes are used To specify the basic
|
|---|
| 210 | Output format Of the various FUNCTIONs that Convert floating
|
|---|
| 211 | Point values To Strings. }
|
|---|
| 212 |
|
|---|
| 213 | TFloatFormat = (ffGeneral, ffExponent, ffFixed, ffNumber, ffCurrency);
|
|---|
| 214 |
|
|---|
| 215 | { FloatToDecimal Result Record - This Record Is used To hold the return
|
|---|
| 216 | Value Of the FloatToDecimal Function. }
|
|---|
| 217 |
|
|---|
| 218 | TFloatRec = Record
|
|---|
| 219 | Exponent: Integer;
|
|---|
| 220 | Negative: Boolean;
|
|---|
| 221 | Digits: Array[0..18] Of Char;
|
|---|
| 222 | End;
|
|---|
| 223 |
|
|---|
| 224 | Const
|
|---|
| 225 |
|
|---|
| 226 | { Empty String And Pointer To Empty String - used internally by various
|
|---|
| 227 | String FUNCTIONs. }
|
|---|
| 228 |
|
|---|
| 229 | EmptyStr: String[1] = '';
|
|---|
| 230 | NullStr: PString = @EmptyStr;
|
|---|
| 231 |
|
|---|
| 232 | Var
|
|---|
| 233 |
|
|---|
| 234 | { --- date, Time, And currency defaults ---
|
|---|
| 235 |
|
|---|
| 236 | the following global variables contain Default values For formatting
|
|---|
| 237 | date, Time, And currency values. most Of them are queried from the
|
|---|
| 238 | System At Program startup. Some others are taken from the
|
|---|
| 239 | application's resources. }
|
|---|
| 240 |
|
|---|
| 241 | { DateSeparator - the character used To separate Year, Month, And Day,
|
|---|
| 242 | when converting A TDateTime Value To Text. queried from the System
|
|---|
| 243 | At Program startup. }
|
|---|
| 244 |
|
|---|
| 245 | DateSeparator: Char;
|
|---|
| 246 |
|
|---|
| 247 | { ShortDateFormat - the Default format String used when converting a
|
|---|
| 248 | TDateTime Value To Text. This one Is used whenever A short Result
|
|---|
| 249 | Is desired. the Value Is computed At Program startup. }
|
|---|
| 250 |
|
|---|
| 251 | ShortDateFormat: String[15];
|
|---|
| 252 |
|
|---|
| 253 | { LongDateFormat - the Default format String used when converting a
|
|---|
| 254 | TDateTime Value To Text. This one Is used whenever A LONG Result
|
|---|
| 255 | Is desired. the Value Is computed At Program startup. }
|
|---|
| 256 |
|
|---|
| 257 | LongDateFormat: String[31];
|
|---|
| 258 |
|
|---|
| 259 | { ShortMonthNames - Abbreviations For Month Names used when converting
|
|---|
| 260 | A TDateTime Value To Text. the Names are taken from the program's
|
|---|
| 261 | resources. }
|
|---|
| 262 |
|
|---|
| 263 | ShortMonthNames: Array[1..12] Of String[7];
|
|---|
| 264 |
|
|---|
| 265 | { LongMonthNames - the full Month Names used when converting a
|
|---|
| 266 | TDateTime Value To Text. the Names are taken from the program's
|
|---|
| 267 | resources. }
|
|---|
| 268 |
|
|---|
| 269 | LongMonthNames: Array[1..12] Of String[15];
|
|---|
| 270 |
|
|---|
| 271 | { ShortDayNames - Abbreviations For Day Names used when converting
|
|---|
| 272 | A TDateTime Value To Text. the Names are taken from the program's
|
|---|
| 273 | resources. }
|
|---|
| 274 |
|
|---|
| 275 | ShortDayNames: Array[1..7] Of String[7];
|
|---|
| 276 |
|
|---|
| 277 | { LongDayNames - the full Day Names used when converting A TDateTime
|
|---|
| 278 | Value To Text. the Names are taken from the program's resources. }
|
|---|
| 279 |
|
|---|
| 280 | LongDayNames: Array[1..7] Of String[15];
|
|---|
| 281 |
|
|---|
| 282 | { DateOrder - the order Of Year, Month, And Day assumed when trying To
|
|---|
| 283 | extract date information from A String. queried from the System At
|
|---|
| 284 | Program startup. }
|
|---|
| 285 |
|
|---|
| 286 | DateOrder: Byte;
|
|---|
| 287 |
|
|---|
| 288 | { TimeSeparator - the character used To separate Hour, Minute, And
|
|---|
| 289 | Second, when converting A TDateTime Value To Text. queried from the
|
|---|
| 290 | System At Program startup. }
|
|---|
| 291 |
|
|---|
| 292 | TimeSeparator: Char;
|
|---|
| 293 |
|
|---|
| 294 | { TimeAMString - the String appended To Time values between 00:00 And
|
|---|
| 295 | 11:59 when converting A DateTime Value To Text. only used when
|
|---|
| 296 | 12-Hour clock format Is used. queried from the System At Program
|
|---|
| 297 | startup. }
|
|---|
| 298 |
|
|---|
| 299 | TimeAMString: String[7];
|
|---|
| 300 |
|
|---|
| 301 | { TimePMString - the String appended To Time values between 12:00 And
|
|---|
| 302 | 23:59 when converting A DateTime Value To Text. only used when
|
|---|
| 303 | 12-Hour clock format Is used. queried from the System At Program
|
|---|
| 304 | startup. }
|
|---|
| 305 |
|
|---|
| 306 | TimePMString: String[7];
|
|---|
| 307 |
|
|---|
| 308 | { ShortTimeFormat - the Default format String used when converting a
|
|---|
| 309 | TDateTime Value To Text. This one Is used whenever A shorter Result
|
|---|
| 310 | Is desired. queried from the System At Program startup. }
|
|---|
| 311 |
|
|---|
| 312 | ShortTimeFormat: String[15];
|
|---|
| 313 |
|
|---|
| 314 | { LongTimeFormat - the Default format String used when converting a
|
|---|
| 315 | TDateTime Value To Text. This one Is used whenever A longer Result
|
|---|
| 316 | Is desired. queried from the System At Program startup. }
|
|---|
| 317 |
|
|---|
| 318 | LongTimeFormat: String[31];
|
|---|
| 319 |
|
|---|
| 320 | { TwelveHours - Indicates whether 12-Hour clock format Is used when
|
|---|
| 321 | trying To extract Time information from A String. queried from
|
|---|
| 322 | the System At Program startup. }
|
|---|
| 323 |
|
|---|
| 324 | TwelveHours: Boolean;
|
|---|
| 325 |
|
|---|
| 326 | { CurrencyString - the local currency String used when converting
|
|---|
| 327 | currency values To Text. Default Value Is queried from the System
|
|---|
| 328 | At Program startup. }
|
|---|
| 329 |
|
|---|
| 330 | CurrencyString: String[7];
|
|---|
| 331 |
|
|---|
| 332 | { CurrencyFormat - the order Of currency Value, currency String, And
|
|---|
| 333 | separating space used when converting currency values To Text.
|
|---|
| 334 | Default Value Is queried from the System At Program startup.
|
|---|
| 335 |
|
|---|
| 336 | the following values four are possible, With the fifth one
|
|---|
| 337 | being an additional Value that Is only supported by OS/2:
|
|---|
| 338 |
|
|---|
| 339 | 0 = '$1' 1 = '1$' 2 = '$ 1' 3 = '1 $'
|
|---|
| 340 |
|
|---|
| 341 | 4 = currency String replaces DECIMAL indicator }
|
|---|
| 342 |
|
|---|
| 343 | CurrencyFormat: Byte;
|
|---|
| 344 |
|
|---|
| 345 | { NegCurrFormat - Corresponds To CurrencyFormat, but Is used when
|
|---|
| 346 | converting Negative currency values To Text. queried from the
|
|---|
| 347 | System At Program startup.
|
|---|
| 348 |
|
|---|
| 349 | the following values are possible:
|
|---|
| 350 |
|
|---|
| 351 | 0 = '($1)' 1 = '-$1' 2 = '$-1' 3 = '$1-'
|
|---|
| 352 | 4 = '(1$)' 5 = '-1$' 6 = '1-$' 7 = '1$-'
|
|---|
| 353 | 8 = '-1 $' 9 = '-$ 1' 10 = '$ 1-'
|
|---|
| 354 |
|
|---|
| 355 | since OS/2 doesn't support A Special format For Negative currency
|
|---|
| 356 | values, A format Is chosen that matches the CurrencyFormat With
|
|---|
| 357 | A preceding '-'. the following List shows the possible values:
|
|---|
| 358 |
|
|---|
| 359 | CurrencyFormat NegCurrFormat
|
|---|
| 360 |
|
|---|
| 361 | 0 = '$1' 1 = -$1
|
|---|
| 362 | 1 = '1$' 5 = -1$
|
|---|
| 363 | 2 = '$ 1' 9 = -$ 1
|
|---|
| 364 | 3 = '1 $' 8 = -1 $ }
|
|---|
| 365 |
|
|---|
| 366 | NegCurrFormat: Byte;
|
|---|
| 367 |
|
|---|
| 368 | { ThousandSeparator - the character used To separate blocks Of three
|
|---|
| 369 | Digits when converting floating Point values To Text. queried from
|
|---|
| 370 | the System At Program startup. }
|
|---|
| 371 |
|
|---|
| 372 | ThousandSeparator: Char;
|
|---|
| 373 |
|
|---|
| 374 | { DecimalSeparator - the character used To separate the Integer part
|
|---|
| 375 | from the fractional part when converting floating Point values To
|
|---|
| 376 | Text. queried from the System At Program startup. }
|
|---|
| 377 |
|
|---|
| 378 | DecimalSeparator: Char;
|
|---|
| 379 |
|
|---|
| 380 | { CurrencyDigits - the Number Of Digits used In the fractional part
|
|---|
| 381 | Of A currency Value when converting A currency Value To Text.
|
|---|
| 382 | queried from the System At Program startup. }
|
|---|
| 383 |
|
|---|
| 384 | CurrencyDecimals: Byte;
|
|---|
| 385 |
|
|---|
| 386 | { ListSeparator - the character To Use when separating Items In A List.
|
|---|
| 387 | Currently Not used by any Function. }
|
|---|
| 388 |
|
|---|
| 389 | ListSeparator: Char;
|
|---|
| 390 |
|
|---|
| 391 | { --- Memory management --- }
|
|---|
| 392 |
|
|---|
| 393 | { AllocMem - Allocates A Memory block Of the desired Size ON the heap.
|
|---|
| 394 | In contrast To the GetMem Standard Procedure, AllocMem fills the
|
|---|
| 395 | whole block With zeroes. }
|
|---|
| 396 |
|
|---|
| 397 | Function AllocMem(Size: Cardinal): Pointer;
|
|---|
| 398 |
|
|---|
| 399 | { ReAllocMem - re-Allocates A previously allocated Memory block And
|
|---|
| 400 | changes its Size. copies the contents Of the old block into the
|
|---|
| 401 | New one. CurSize And NewSize specify the Current And the New Size
|
|---|
| 402 | Of the block. If the New Size Is larger than the Current Size, the
|
|---|
| 403 | additional Bytes are zeroed. the old Memory block Is automatically
|
|---|
| 404 | disposed. note that the resulting Pointer will always be different
|
|---|
| 405 | from the old Pointer, even If the Size isn't changed. the Function
|
|---|
| 406 | can Handle Nil pointers And Zero blocks. }
|
|---|
| 407 |
|
|---|
| 408 | Function ReAllocMem(P: Pointer; CurSize, NewSize: Cardinal): Pointer;
|
|---|
| 409 |
|
|---|
| 410 | { --- Exit Procedure Handling --- }
|
|---|
| 411 |
|
|---|
| 412 | { AddExitProc - Adds A parameterless Procedure To the List Of
|
|---|
| 413 | procedures To be called when the Program Is Terminated. note that
|
|---|
| 414 | the Procedure that Is added Last will be called First. }
|
|---|
| 415 |
|
|---|
| 416 | Procedure AddExitProc(Proc: TProcedure);
|
|---|
| 417 |
|
|---|
| 418 | { CallExitProcs - calls All procedures that were installed by
|
|---|
| 419 | AddExitProc And deletes them from the List. note that the
|
|---|
| 420 | Procedure that was added Last will be called First. }
|
|---|
| 421 |
|
|---|
| 422 | Procedure CallExitProcs;
|
|---|
| 423 |
|
|---|
| 424 | { --- String Handling --- }
|
|---|
| 425 |
|
|---|
| 426 | { NewStr - Allocates A block Of Memory ON the heap And fills it With
|
|---|
| 427 | the given String, returns A PString To the Memory block. the Memory
|
|---|
| 428 | block's Size will be exactly one Byte more than the string's Real
|
|---|
| 429 | Length. Empty Strings don't Use any heap space, the Function returns
|
|---|
| 430 | NullStr In This Case. since NullStr Points To EmptyStr, the Function
|
|---|
| 431 | never returns Nil, So you can always de-Reference the resulting
|
|---|
| 432 | Pointer. Use DisposeStr To Free the Memory block. }
|
|---|
| 433 |
|
|---|
| 434 | Function NewStr(Const S: String): PString;
|
|---|
| 435 |
|
|---|
| 436 | { DisposeStr - Disposes A block Of Memory ON the heap that Contains
|
|---|
| 437 | A String. the block MUST have been allocated by A call To NewStr.
|
|---|
| 438 | If the given Pointer Is NullStr (And thereby references the Empty
|
|---|
| 439 | String) Or Nil, the Function does absolutely Nothing. }
|
|---|
| 440 |
|
|---|
| 441 | Procedure DisposeStr(P: PString);
|
|---|
| 442 |
|
|---|
| 443 | { AssignStr - Assigns A New Value To A String Pointer that has been
|
|---|
| 444 | previously allocated by A call To NewStr, Or Is Nil. the old String
|
|---|
| 445 | Is disposed by DisposeStr, And the New one Is allocated by NewStr. }
|
|---|
| 446 |
|
|---|
| 447 | Procedure AssignStr(Var P: PString; Const S: String);
|
|---|
| 448 |
|
|---|
| 449 | { AppendStr - Appends A String To the End Of another. }
|
|---|
| 450 |
|
|---|
| 451 | Procedure AppendStr(Var Dest: String; Const S: String);
|
|---|
| 452 |
|
|---|
| 453 | { uppercase - Converts A String To upper Case by simply Changing All
|
|---|
| 454 | occurences Of 'a'..'z' To the corresponding upper Case characters.
|
|---|
| 455 | If you want A conversion that also considers international Special
|
|---|
| 456 | characters, Use AnsiUpperCase. }
|
|---|
| 457 |
|
|---|
| 458 | Function uppercase(Const S: String): String;
|
|---|
| 459 |
|
|---|
| 460 | { lowercase - Converts A String To lower Case by simply Changing All
|
|---|
| 461 | occurences Of 'A'..'Z' To the corresponding lower Case characters.
|
|---|
| 462 | If you want A conversion that also considers international Special
|
|---|
| 463 | characters, Use AnsiLowerCase. }
|
|---|
| 464 |
|
|---|
| 465 | Function lowercase(Const S: String): String;
|
|---|
| 466 |
|
|---|
| 467 | { CompareStr - Compares two Strings And returns an Integer Value
|
|---|
| 468 | As In the following Table:
|
|---|
| 469 |
|
|---|
| 470 | s1 < s2 Result < 0
|
|---|
| 471 | s1 = s2 Result = 0
|
|---|
| 472 | s1 > s2 Result > 0
|
|---|
| 473 |
|
|---|
| 474 | CompareStr Is Case-sensitive, but does Not take international
|
|---|
| 475 | Special characters Or the Currently Selected codepage into account. }
|
|---|
| 476 |
|
|---|
| 477 | Function CompareStr(Const s1, s2: String): Integer;
|
|---|
| 478 |
|
|---|
| 479 | { CompareText - Compares two Strings And returns an Integer Value
|
|---|
| 480 | As In the following Table:
|
|---|
| 481 |
|
|---|
| 482 | s1 < s2 Result < 0
|
|---|
| 483 | s1 = s2 Result = 0
|
|---|
| 484 | s1 > s2 Result > 0
|
|---|
| 485 |
|
|---|
| 486 | CompareText Is Case-insensitive, And does Not take international
|
|---|
| 487 | Special characters Or the Currently Selected codepage into account. }
|
|---|
| 488 |
|
|---|
| 489 | Function CompareText(Const s1, s2: String): Integer;
|
|---|
| 490 |
|
|---|
| 491 | { AnsiUpperCase - Converts A String To upper Case. This Function
|
|---|
| 492 | also takes international Special characters And the Currently
|
|---|
| 493 | Selected codepage into account. If you don't want This, Use
|
|---|
| 494 | uppercase. }
|
|---|
| 495 |
|
|---|
| 496 | Function AnsiUpperCase(Const S: String): String;
|
|---|
| 497 |
|
|---|
| 498 | { AnsiLowerCase - Converts A String To lower Case. This Function
|
|---|
| 499 | also takes international Special characters And the Currently
|
|---|
| 500 | Selected codepage into account. If you don't want This, Use
|
|---|
| 501 | lowercase. note that AnsiLowerCase Is Not available under OS/2. }
|
|---|
| 502 |
|
|---|
| 503 | {$IFNDEF OS2}
|
|---|
| 504 | Function AnsiLowerCase(Const S: String): String;
|
|---|
| 505 | {$ENDIF}
|
|---|
| 506 |
|
|---|
| 507 | { AnsiCompareStr - Compares two Strings And returns an Integer Value
|
|---|
| 508 | As In the following Table:
|
|---|
| 509 |
|
|---|
| 510 | s1 < s2 Result < 0
|
|---|
| 511 | s1 = s2 Result = 0
|
|---|
| 512 | s1 > s2 Result > 0
|
|---|
| 513 |
|
|---|
| 514 | AnsiCompareStr Is Case-sensitive, And takes international Special
|
|---|
| 515 | characters And the Currently Selected codepage into account. note
|
|---|
| 516 | that the Function Is Not available under OS/2. }
|
|---|
| 517 |
|
|---|
| 518 | {$IFNDEF OS2}
|
|---|
| 519 | Function AnsiCompareStr(Const s1, s2: String): Integer;
|
|---|
| 520 | {$ENDIF}
|
|---|
| 521 |
|
|---|
| 522 | { AnsiCompareText - Compares two Strings And returns an Integer Value
|
|---|
| 523 | As In the following Table:
|
|---|
| 524 |
|
|---|
| 525 | s1 < s2 Result < 0
|
|---|
| 526 | s1 = s2 Result = 0
|
|---|
| 527 | s1 > s2 Result > 0
|
|---|
| 528 |
|
|---|
| 529 | AnsiCompareText Is Case-insensitive, And takes international Special
|
|---|
| 530 | characters And the Currently Selected codepage into account. }
|
|---|
| 531 |
|
|---|
| 532 | Function AnsiCompareText(Const s1, s2: String): Integer;
|
|---|
| 533 |
|
|---|
| 534 | { Trim - Removes leading And trailing spaces And Control characters. }
|
|---|
| 535 |
|
|---|
| 536 | Function Trim(Const S: String): String;
|
|---|
| 537 |
|
|---|
| 538 | { TrimLeft - Removes leading spaces And Control characters. }
|
|---|
| 539 |
|
|---|
| 540 | Function TrimLeft(Const S: String): String;
|
|---|
| 541 |
|
|---|
| 542 | { TrimRight - Removes trailing spaces And Control characters. }
|
|---|
| 543 |
|
|---|
| 544 | Function TrimRight(Const S: String): String;
|
|---|
| 545 |
|
|---|
| 546 | { QuotedStr - returns the given String enclosed In quotes. quotes already
|
|---|
| 547 | included In the String are returned As two quote characters. }
|
|---|
| 548 |
|
|---|
| 549 | Function QuotedStr(Const S: String): String;
|
|---|
| 550 |
|
|---|
| 551 | { IsValidIdent - Checks whether the given String Contains A legal
|
|---|
| 552 | Pascal identifier. check your Speed-Pascal manual To See what A
|
|---|
| 553 | legal identifier looks like. :-) }
|
|---|
| 554 |
|
|---|
| 555 | Function IsValidIdent(Const Ident: String): Boolean;
|
|---|
| 556 |
|
|---|
| 557 | { IntToStr - Converts an Integer Value To A String Of Digits. }
|
|---|
| 558 |
|
|---|
| 559 | Function IntToStr(Value: LongInt): String;
|
|---|
| 560 |
|
|---|
| 561 | { IntToHex - Converts an Integer Value To A String Of hexadecimal
|
|---|
| 562 | Digits. the minimum desired Number Of Digits can be specified.
|
|---|
| 563 | If the Result Contains less Digits, it Is Left-padded With zeroes. }
|
|---|
| 564 |
|
|---|
| 565 | Function IntToHex(Value: LongInt; Digits: Integer): String;
|
|---|
| 566 |
|
|---|
| 567 | { StrToInt - Extracts an Integer Value from A String. If the String
|
|---|
| 568 | doesn't contain A legal Integer Value, Exception EConvertError
|
|---|
| 569 | Is raised. }
|
|---|
| 570 |
|
|---|
| 571 | Function StrToInt(Const S: String): LongInt;
|
|---|
| 572 |
|
|---|
| 573 | { StrToIntDef - Extracts an Integer Value from A String. If the String
|
|---|
| 574 | doesn't contain A legal Integer Value, the desired Default Value
|
|---|
| 575 | Is returned instead. }
|
|---|
| 576 |
|
|---|
| 577 | {$IFDEF GUI}
|
|---|
| 578 | Function StrToIntDef(Const S: String; Default: LongInt): LongInt;
|
|---|
| 579 | {$ENDIF GUI}
|
|---|
| 580 |
|
|---|
| 581 | { LoadStr - Loads A String from the application's resources. the
|
|---|
| 582 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 583 | contain A String With the given Number, LoadStr returns an Empty
|
|---|
| 584 | String. }
|
|---|
| 585 |
|
|---|
| 586 | {$IFDEF GUI}
|
|---|
| 587 | Function LoadStr(Ident: Word): String;
|
|---|
| 588 | {$ENDIF GUI}
|
|---|
| 589 |
|
|---|
| 590 | { LoadNLSStr - Loads A String from the application's Current Language Table. the
|
|---|
| 591 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 592 | contain A String With the given Number, LoadStr returns an Empty
|
|---|
| 593 | String. }
|
|---|
| 594 |
|
|---|
| 595 | Function LoadNLSStr(Ident: Word): String;
|
|---|
| 596 |
|
|---|
| 597 | { LoadTableStr - Loads A String from the specified String Table. the
|
|---|
| 598 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 599 | contain A String With the given Number, LoadStr returns an Empty
|
|---|
| 600 | String. }
|
|---|
| 601 |
|
|---|
| 602 | Function LoadTableStr(Const Table:String;Ident: Word): String;
|
|---|
| 603 |
|
|---|
| 604 | { FmtLoadStr - Loads A String from the application's resources And
|
|---|
| 605 | replaces Some placeholders by values given In an Open-Array. the
|
|---|
| 606 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 607 | contain A String With the given Number, FmtLoadStr returns an
|
|---|
| 608 | Empty String. }
|
|---|
| 609 |
|
|---|
| 610 | {$IFDEF GUI}
|
|---|
| 611 | Function FmtLoadStr(Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 612 | {$ENDIF GUI}
|
|---|
| 613 |
|
|---|
| 614 | { FmtLoadNLSStr - Loads A String from the application's Current Language Table And
|
|---|
| 615 | replaces Some placeholders by values given In an Open-Array. the
|
|---|
| 616 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 617 | contain A String With the given Number, FmtLoadStr returns an
|
|---|
| 618 | Empty String. }
|
|---|
| 619 |
|
|---|
| 620 | Function FmtLoadNLSStr(Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 621 |
|
|---|
| 622 | { FmtLoadTableStr - Loads A String from the specified String Table And
|
|---|
| 623 | replaces Some placeholders by values given In an Open-Array. the
|
|---|
| 624 | String Is retrieved by an Integer Number. If the resources don't
|
|---|
| 625 | contain A String With the given Number, FmtLoadStr returns an
|
|---|
| 626 | Empty String. }
|
|---|
| 627 |
|
|---|
| 628 | Function FmtLoadTableStr(Const Table:String;Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 629 |
|
|---|
| 630 |
|
|---|
| 631 | { SysErrorMessage - returns A System Error Message. }
|
|---|
| 632 |
|
|---|
| 633 | {$IFDEF OS2}
|
|---|
| 634 | Function SysErrorMessage(MsgNum: LongInt): String;
|
|---|
| 635 | {$ENDIF OS2}
|
|---|
| 636 |
|
|---|
| 637 | { --- File management --- }
|
|---|
| 638 |
|
|---|
| 639 | { FileOpen - Opens an existing File With A given File Mode. the File
|
|---|
| 640 | Mode Is A logical combination Of one Of the File Open constants
|
|---|
| 641 | (fmOpenXXX) And one Of the sharing Mode constants (fmShareXXX). If
|
|---|
| 642 | the File Is successfully opended, the resulting Integer Value Is
|
|---|
| 643 | positive And Contains the File Handle. Otherwise the Result Is the
|
|---|
| 644 | Negative Value Of the Error Code returned by the operating System. }
|
|---|
| 645 |
|
|---|
| 646 | Function FileOpen(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 647 |
|
|---|
| 648 | { FileCreate - creates A New File Or overwrites an existing one. no
|
|---|
| 649 | File Mode can be specified, So the File Is always created With
|
|---|
| 650 | fmOpenWrite Or fmShareExclusive. If the File Is successfully
|
|---|
| 651 | created, the resulting Integer Value Is positive And Contains the
|
|---|
| 652 | File Handle. Otherwiese the Result Is the Negative Value Of the
|
|---|
| 653 | Error Code returned by the operating System. }
|
|---|
| 654 |
|
|---|
| 655 | Function FileCreate(Const FileName: String): LongInt;
|
|---|
| 656 |
|
|---|
| 657 | { FileOpenOrCreate - Opens Or creates A File, depending ON whether
|
|---|
| 658 | the File already exists Or Not. A File Mode can be specified. the
|
|---|
| 659 | File Mode Is A logical combination Of one Of the File Open constants
|
|---|
| 660 | (fmOpenXXX) And one Of the sharing Mode constants (fmShareXXX). If
|
|---|
| 661 | the File Is successfully opended Or created, the resulting Integer
|
|---|
| 662 | Value Is positive And Contains the File Handle. Otherwise the
|
|---|
| 663 | Result Is the Negative Value Of the Error Code returned by the
|
|---|
| 664 | operating System. }
|
|---|
| 665 |
|
|---|
| 666 | Function FileOpenOrCreate(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 667 |
|
|---|
| 668 | { FileCreateIfNew - creates A File If there's Not already A File With
|
|---|
| 669 | the same Name. A File Mode can be specified. the File Mode Is a
|
|---|
| 670 | logical combination Of one Of the File Open constants (fmOpenXXX)
|
|---|
| 671 | And one Of the sharing Mode constants (fmShareXXX). If the New File
|
|---|
| 672 | Is successfully created, the resulting Integer Value Is positive And
|
|---|
| 673 | Contains the File Handle. Otherwise the Result Is the Negative Value
|
|---|
| 674 | Of the Error Code returned by the operating System. note that This
|
|---|
| 675 | Function also fails If the File already exists. }
|
|---|
| 676 |
|
|---|
| 677 | Function FileCreateIfNew(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 678 |
|
|---|
| 679 | { FileRead - Attempts To Read up To Count Bytes from the given File
|
|---|
| 680 | Handle And returns the Number Of Bytes actually Read. If an Error
|
|---|
| 681 | occurs, the Result Is -1. }
|
|---|
| 682 |
|
|---|
| 683 | Function FileRead(Handle: LongInt; Var Buffer; Count: LongInt): LongInt;
|
|---|
| 684 |
|
|---|
| 685 | { FileWrite - Attempts To Write up To Count Bytes To the given File
|
|---|
| 686 | Handle And returns the Number Of Bytes actually written. If an Error
|
|---|
| 687 | occurs, the Result Is -1. }
|
|---|
| 688 |
|
|---|
| 689 | Function FileWrite(Handle: LongInt; Const Buffer; Count: LongInt): LongInt;
|
|---|
| 690 |
|
|---|
| 691 | { FileSeek - changes the Current Position Of A File Handle by Count
|
|---|
| 692 | Bytes. the actual Movement depends ON the Value Of Origin, according
|
|---|
| 693 | To the following Table:
|
|---|
| 694 |
|
|---|
| 695 | Origin Action
|
|---|
| 696 |
|
|---|
| 697 | 0 Move relative To the file's beginning
|
|---|
| 698 | 1 Move relative To the Current Position
|
|---|
| 699 | 2 Move relative To the file's End
|
|---|
| 700 |
|
|---|
| 701 | the Function returns the New Position, Or -1 If an Error occured. }
|
|---|
| 702 |
|
|---|
| 703 | Function FileSeek(Handle: LongInt; Offset: LongInt; Origin: Integer): LongInt;
|
|---|
| 704 |
|
|---|
| 705 | { FileClose - Closes A File And frees the Handle. }
|
|---|
| 706 |
|
|---|
| 707 | Procedure FileClose(Handle: LongInt);
|
|---|
| 708 |
|
|---|
| 709 | { FileLock - Locks A Range Of A File For exclusive access by the
|
|---|
| 710 | Application. returns A Boolean Value indicating Success Or
|
|---|
| 711 | failure. note that the Function waits up To the Time specified
|
|---|
| 712 | In the LockTimeout global variable before it fails. }
|
|---|
| 713 |
|
|---|
| 714 | Function FileLock(Handle, Offset, Range: LongInt): Boolean;
|
|---|
| 715 |
|
|---|
| 716 | { FileUnLock - Unlocks A Range Of A File that was previously locked
|
|---|
| 717 | For exclusive access by the Application. returns A Boolean Value
|
|---|
| 718 | indicating Success Or failure. }
|
|---|
| 719 |
|
|---|
| 720 | Function FileUnLock(Handle, Offset, Range: LongInt): Boolean;
|
|---|
| 721 |
|
|---|
| 722 | { FileAge - returns the date And Time Of A file's Last modification.
|
|---|
| 723 |
|
|---|
| 724 | If the File doesn't exist, -1 Is returned instead.
|
|---|
| 725 |
|
|---|
| 726 | To Use date / Time formatting FUNCTIONs For This Value, Convert it
|
|---|
| 727 | To A TDateTime by A call To FileDateToDateTime First. }
|
|---|
| 728 |
|
|---|
| 729 | Function FileAge(Const FileName: String): LongInt;
|
|---|
| 730 |
|
|---|
| 731 | { FileExists - Indicates whether A File exists Or Not. }
|
|---|
| 732 |
|
|---|
| 733 | Function FileExists(Const FileName: String): Boolean;
|
|---|
| 734 |
|
|---|
| 735 | { FindFirst - Starts A Search For files specified by A Name Pattern
|
|---|
| 736 | And File Attributes.
|
|---|
| 737 |
|
|---|
| 738 | any Pattern that Is allowed ON the Command Line Is also A legal
|
|---|
| 739 | argument For Path.
|
|---|
| 740 |
|
|---|
| 741 | Attr Is A logical combination Of File Attributes (faXXX) And
|
|---|
| 742 | File-MUST Attributes (faMustXXX), the latter being available only
|
|---|
| 743 | under OS/2.
|
|---|
| 744 |
|
|---|
| 745 | the Var SearchRec will contain Name And Attributes Of the First File
|
|---|
| 746 | that matched the given specs. In This Case the Function returns 0.
|
|---|
| 747 | If an Error occurs, the Result Is the Negative Value Of the Error
|
|---|
| 748 | Code returned by the operating System.
|
|---|
| 749 |
|
|---|
| 750 | Use FindNext To Find more files And FindClose To End the File
|
|---|
| 751 | Search. note that you MUST Use FindClose, Or you may Run out Of
|
|---|
| 752 | handles after A While. }
|
|---|
| 753 |
|
|---|
| 754 | Function FindFirst(Const Path: String; Attr: Integer; Var SearchRec: TSearchRec): LongInt;
|
|---|
| 755 |
|
|---|
| 756 | { FindNext - after A call To FindNext, the Var SearchRec Contains the
|
|---|
| 757 | Next File that matches the specs Of A File Search previously started
|
|---|
| 758 | by FindFirst.
|
|---|
| 759 |
|
|---|
| 760 | A return Value Of 0 Indicates Success. you may call FindNext Until
|
|---|
| 761 | an Error occures (With the Negative Value Of the operating system's
|
|---|
| 762 | Error Code returned), Or Until no more matching files are found
|
|---|
| 763 | (usually indicated by A return Value Of -18.) }
|
|---|
| 764 |
|
|---|
| 765 | Function FindNext(Var SearchRec: TSearchRec): LongInt;
|
|---|
| 766 |
|
|---|
| 767 | { FindClose - Ends A File Search previously started by FindFirst. note
|
|---|
| 768 | that you MUST Use FindClose, Or you may Run out Of handles after a
|
|---|
| 769 | While. }
|
|---|
| 770 |
|
|---|
| 771 | Procedure FindClose(Var SearchRec: TSearchRec);
|
|---|
| 772 |
|
|---|
| 773 | { FileGetDate - returns the date And Time Of A file's Last
|
|---|
| 774 | modification. If the given File Handle Is invalid, -1 Is returned
|
|---|
| 775 | instead.
|
|---|
| 776 |
|
|---|
| 777 | To Use date / Time formatting FUNCTIONs For the Result, Convert
|
|---|
| 778 | it To A TDateTime by A call To FileDateToDateTime First. }
|
|---|
| 779 |
|
|---|
| 780 | Function FileGetDate(Handle: LongInt): LongInt;
|
|---|
| 781 |
|
|---|
| 782 | { FileSetDate - changes the date And Time Of A file's Last
|
|---|
| 783 | modification. If the Operation fails due To an invalid Handle Or
|
|---|
| 784 | an illegal Age Parameter, the date And Time remain unchanged.
|
|---|
| 785 |
|
|---|
| 786 | This Procedure doesn't Accept TDateTime values. you have To Convert
|
|---|
| 787 | them To A LongInt by DateTimeToFileDate First. }
|
|---|
| 788 |
|
|---|
| 789 | Procedure FileSetDate(Handle: Integer; Age: LongInt);
|
|---|
| 790 |
|
|---|
| 791 | { FileGetAttr - returns A file's Attributes. the Result Value Is a
|
|---|
| 792 | logical combination Of File attribute constants (faXXX). If the
|
|---|
| 793 | Function fails due To A non-existing File Or another Error
|
|---|
| 794 | condition, the Result Is the Negative Value Of the operating
|
|---|
| 795 | system's Error Code. }
|
|---|
| 796 |
|
|---|
| 797 | Function FileGetAttr(Const FileName: String): LongInt;
|
|---|
| 798 |
|
|---|
| 799 | { FileSetAttr - changes A file's Attributes. the Attr Parameter may
|
|---|
| 800 | contain any logical combination Of File attribute constants
|
|---|
| 801 | (faXXX). A Result Value Of 0 Indicates Success. If the Function
|
|---|
| 802 | fails due To A non-existing File Or another Error condition, the
|
|---|
| 803 | Result Is the Negative Value Of the operating system's Error Code. }
|
|---|
| 804 |
|
|---|
| 805 | Function FileSetAttr(Const FileName: String; Attr: Integer): Integer;
|
|---|
| 806 |
|
|---|
| 807 | { CopyFile - copies A File. Result Is A Boolean indicating Success Or
|
|---|
| 808 | failure. }
|
|---|
| 809 |
|
|---|
| 810 | Function CopyFile(Const SourceName, DestName: String): Boolean;
|
|---|
| 811 |
|
|---|
| 812 | { DeleteFile - deletes A File. Result Is A Boolean indicating Success
|
|---|
| 813 | Or failure. }
|
|---|
| 814 |
|
|---|
| 815 | Function DeleteFile(Const FileName: String): Boolean;
|
|---|
| 816 |
|
|---|
| 817 | { RenameFile - Renames A File. Result Is A Boolean indicating Success
|
|---|
| 818 | Or failure. you may Use RenameFile To Move A File To A New location,
|
|---|
| 819 | but only If the Drive stays the same. }
|
|---|
| 820 |
|
|---|
| 821 | Function RenameFile(Const OldName, NewName: String): Boolean;
|
|---|
| 822 |
|
|---|
| 823 | { ChangeFileExt - changes the extension Of A given FileName. the
|
|---|
| 824 | extension Is the part from the rightmost dot To the End Of the
|
|---|
| 825 | FileName. If the old FileName doesn't contain an extension, it
|
|---|
| 826 | Is simply added. the extension MUST Start With A dot.
|
|---|
| 827 |
|
|---|
| 828 | note that the Function only handles A String, but does Not Perform
|
|---|
| 829 | any Physical changes To files. }
|
|---|
| 830 |
|
|---|
| 831 | Function ChangeFileExt(Const FileName, extension: String): String;
|
|---|
| 832 |
|
|---|
| 833 | { ExtractFilePath - returns the Drive And Directory parts Of a
|
|---|
| 834 | FileName, that Is, everything from the Start To the rightmost colon
|
|---|
| 835 | Or backslash In the String. If the FileName doesn't contain Drive Or
|
|---|
| 836 | Directory information, an Empty String Is returned. }
|
|---|
| 837 |
|
|---|
| 838 | Function ExtractFilePath(Const FileName: String): String;
|
|---|
| 839 |
|
|---|
| 840 | { ExtractFileName - returns the Name And extension parts Of A
|
|---|
| 841 | FileName, that Is, everything from rightmost colon Or backslash To
|
|---|
| 842 | the End Of the String. If the FileName doesn't contain A Name Or
|
|---|
| 843 | extension, an Empty String Is returned. }
|
|---|
| 844 |
|
|---|
| 845 | Function ExtractFileName(Const FileName: String): String;
|
|---|
| 846 |
|
|---|
| 847 | { ExtractFileExt - returns the extension part Of A FileName, that Is,
|
|---|
| 848 | everything from rightmost dot To the End Of the String. If the
|
|---|
| 849 | FileName doesn't contain A dot, an Empty String Is returned. }
|
|---|
| 850 |
|
|---|
| 851 | Function ExtractFileExt(Const FileName: String): String;
|
|---|
| 852 |
|
|---|
| 853 | { ConcatFileName - Concatenates two filenames, assuming the First
|
|---|
| 854 | one specifies Some Kind Of Directory information, And the Second
|
|---|
| 855 | one A FileName. the Result Is A Complete legal pathname. the
|
|---|
| 856 | Function automatically inserts A backslash, If necessary. }
|
|---|
| 857 |
|
|---|
| 858 | Function ConcatFileName(Const pathname, FileName: String): String;
|
|---|
| 859 |
|
|---|
| 860 | { ExpandFileName - Expands A FileName To an Absolute FileName, that
|
|---|
| 861 | Is, A FileName containing A Drive letter, Directory information
|
|---|
| 862 | relative To the root Of the Drive, And the FileName. Embedded '..'
|
|---|
| 863 | are removed. }
|
|---|
| 864 |
|
|---|
| 865 | Function ExpandFileName(FileName: String): String;
|
|---|
| 866 |
|
|---|
| 867 | { EditFileName - changes A FileName using A Pattern possibly
|
|---|
| 868 | containing the wildcards '*' And '?'. everything that would
|
|---|
| 869 | be Accepted by the Copy Command should be legal For Name And
|
|---|
| 870 | edit. }
|
|---|
| 871 |
|
|---|
| 872 | Function EditFileName(Const Name, edit: String): String;
|
|---|
| 873 |
|
|---|
| 874 | { FileSearch - Searches For A File Name In A List Of directories
|
|---|
| 875 | given by DirList. the Directory entries MUST be separated by
|
|---|
| 876 | semicolons, just like the system's Path. the working Directory
|
|---|
| 877 | Is implicitly prepended To the List Of directories. the Result
|
|---|
| 878 | String Is either the First occurence Of the File Complete With
|
|---|
| 879 | the Directory it was found In, Or the Empty String, If the File
|
|---|
| 880 | could Not be found. }
|
|---|
| 881 |
|
|---|
| 882 | Function FileSearch(Const Name, DirList: String): String;
|
|---|
| 883 |
|
|---|
| 884 | { DiskFree - returns the Free space Of the given disk Drive. Drive 0
|
|---|
| 885 | Is the Current Drive, Drive 1 Is 'A:', And So ON. If the given Drive
|
|---|
| 886 | Is invalid Or cannot be Read, -1 Is returned, Otherwise the Result
|
|---|
| 887 | Contains the Number Of Bytes Free. }
|
|---|
| 888 |
|
|---|
| 889 | Function DiskFree(Drive: Byte): LongInt;
|
|---|
| 890 |
|
|---|
| 891 | { DiskSize - returns the disk Size Of the given disk Drive. Drive 0
|
|---|
| 892 | Is the Current Drive, Drive 1 Is 'A:', And So ON. If the given Drive
|
|---|
| 893 | Is invalid Or cannot be Read, -1 Is returned, Otherwise the Result
|
|---|
| 894 | Contains the Number Of Bytes that can be potentially used For File
|
|---|
| 895 | storage. }
|
|---|
| 896 |
|
|---|
| 897 | Function DiskSize(Drive: Byte): LongInt;
|
|---|
| 898 |
|
|---|
| 899 | { FileDateToDateTime - Converts A File date / Time Value To a
|
|---|
| 900 | TDateTime that can be used within formatting operations. }
|
|---|
| 901 |
|
|---|
| 902 | Function FileDateToDateTime(FileDate: LongInt): TDateTime;
|
|---|
| 903 |
|
|---|
| 904 | { FileDateToDateTime - Converts A TDateTime To A File date / Time
|
|---|
| 905 | Value that can be used within File FUNCTIONs. }
|
|---|
| 906 |
|
|---|
| 907 | Function DateTimeToFileDate(DateTime: TDateTime): LongInt;
|
|---|
| 908 |
|
|---|
| 909 | { --- 'C'-like String Handling --- }
|
|---|
| 910 |
|
|---|
| 911 | { StrLen - returns the Length Of Str, ignoring the terminating Zero. }
|
|---|
| 912 |
|
|---|
| 913 | Function StrLen(Str: PChar): Cardinal;
|
|---|
| 914 |
|
|---|
| 915 | { StrEnd - returns A Pointer To the terminating Zero Of Str. }
|
|---|
| 916 |
|
|---|
| 917 | Function StrEnd(Str: PChar): PChar;
|
|---|
| 918 |
|
|---|
| 919 | { StrMove - copies exactly Count characters from Source To Dest. It's
|
|---|
| 920 | okay when Source And Dest overlap, StrMove can Handle This. }
|
|---|
| 921 |
|
|---|
| 922 | Function StrMove(Dest, Source: PChar; Count: Cardinal): PChar;
|
|---|
| 923 |
|
|---|
| 924 | { StrCopy - copies Source To Dest And returns Dest. }
|
|---|
| 925 |
|
|---|
| 926 | Function StrCopy(Dest, Source: PChar): PChar;
|
|---|
| 927 |
|
|---|
| 928 | { StrECopy - copies Source To Dest And returns A Pointer To the
|
|---|
| 929 | terminating Zero Of the resulting String. }
|
|---|
| 930 |
|
|---|
| 931 | Function StrECopy(Dest, Source: PChar): PChar;
|
|---|
| 932 |
|
|---|
| 933 | { StrLCopy - copies A maximum Of MaxLen characters from Source To Dest
|
|---|
| 934 | And returns Dest. }
|
|---|
| 935 |
|
|---|
| 936 | Function StrLCopy(Dest, Source: PChar; MaxLen: Cardinal): PChar;
|
|---|
| 937 |
|
|---|
| 938 | { StrPCopy - copies A Pascal String Source To A PChar Dest And returns
|
|---|
| 939 | Dest. }
|
|---|
| 940 |
|
|---|
| 941 | Function StrPCopy(Dest: PChar; Const Source: String): PChar;
|
|---|
| 942 |
|
|---|
| 943 | { StrPLCopy - copies A maximum Of MaxLen characters from A Pascal
|
|---|
| 944 | String Source To A PChar Dest. returns Dest. }
|
|---|
| 945 |
|
|---|
| 946 | Function StrPLCopy(Dest: PChar; Const Source: String; MaxLen: Cardinal): PChar;
|
|---|
| 947 |
|
|---|
| 948 | { StrCat - Concatenates Dest And Source, that Is, Appends Source To
|
|---|
| 949 | the End Of Dest, And returns Dest. }
|
|---|
| 950 |
|
|---|
| 951 | Function StrCat(Dest, Source: PChar): PChar;
|
|---|
| 952 |
|
|---|
| 953 | { StrLCat - Concatenates Dest And Source, that Is, Appends Source To
|
|---|
| 954 | the End Of Dest, but copies only So many characters that the
|
|---|
| 955 | resulting String does Not exceed MaxLen characters. returns Dest. }
|
|---|
| 956 |
|
|---|
| 957 | Function StrLCat(Dest, Source: PChar; MaxLen: Cardinal): PChar;
|
|---|
| 958 |
|
|---|
| 959 | { StrComp - Compares two Strings And returns an Integer Value
|
|---|
| 960 | As In the following Table:
|
|---|
| 961 |
|
|---|
| 962 | Str1 < Str2 Result < 0
|
|---|
| 963 | Str1 = Str2 Result = 0
|
|---|
| 964 | Str1 > Str2 Result > 0
|
|---|
| 965 |
|
|---|
| 966 | StrComp Is Case-sensitive, but does Not take international Special
|
|---|
| 967 | characters Or the Currently Selected codepage into account. }
|
|---|
| 968 |
|
|---|
| 969 | Function StrComp(Str1, Str2: PChar): Integer;
|
|---|
| 970 |
|
|---|
| 971 | { StrIComp - Compares two Strings And returns an Integer Value
|
|---|
| 972 | As In the following Table:
|
|---|
| 973 |
|
|---|
| 974 | Str1 < Str2 Result < 0
|
|---|
| 975 | Str1 = Str2 Result = 0
|
|---|
| 976 | Str1 > Str2 Result > 0
|
|---|
| 977 |
|
|---|
| 978 | StrComp Is Case-insensitive, And does Not take international
|
|---|
| 979 | Special characters Or the Currently Selected codepage into account. }
|
|---|
| 980 |
|
|---|
| 981 | Function StrIComp(Str1, Str2: PChar): Integer;
|
|---|
| 982 |
|
|---|
| 983 | { StrLComp - Compares up To MaxLen characters Of two Strings And
|
|---|
| 984 | returns an Integer Value As In the following Table:
|
|---|
| 985 |
|
|---|
| 986 | Str1 < Str2 Result < 0
|
|---|
| 987 | Str1 = Str2 Result = 0
|
|---|
| 988 | Str1 > Str2 Result > 0
|
|---|
| 989 |
|
|---|
| 990 | StrLComp Is Case-sensitive, but does Not take international Special
|
|---|
| 991 | characters Or the Currently Selected codepage into account. }
|
|---|
| 992 |
|
|---|
| 993 | Function StrLComp(Str1, Str2: PChar; MaxLen: Cardinal): Integer;
|
|---|
| 994 |
|
|---|
| 995 | { StrLIComp - Compares up To MaxLen characters Of two Strings And
|
|---|
| 996 | returns an Integer Value As In the following Table:
|
|---|
| 997 |
|
|---|
| 998 | Str1 < Str2 Result < 0
|
|---|
| 999 | Str1 = Str2 Result = 0
|
|---|
| 1000 | Str1 > Str2 Result > 0
|
|---|
| 1001 |
|
|---|
| 1002 | StrLComp Is Case-insensitive, And does Not take international
|
|---|
| 1003 | Special characters Or the Currently Selected codepage into account. }
|
|---|
| 1004 |
|
|---|
| 1005 | Function StrLIComp(Str1, Str2: PChar; MaxLen: Cardinal): Integer;
|
|---|
| 1006 |
|
|---|
| 1007 | { StrScan - Searches For the First occurence Of A character In A
|
|---|
| 1008 | String. returns the Pointer To the occurence, Or Nil, If the
|
|---|
| 1009 | character cannot be found. }
|
|---|
| 1010 |
|
|---|
| 1011 | Function StrScan(Str: PChar; Chr: Char): PChar;
|
|---|
| 1012 |
|
|---|
| 1013 | { StrRScan - Searches For the Last occurence Of A character In A
|
|---|
| 1014 | String. returns the Pointer To the occurence, Or Nil, If the
|
|---|
| 1015 | character cannot be found. }
|
|---|
| 1016 |
|
|---|
| 1017 | Function StrRScan(Str: PChar; Chr: Char): PChar;
|
|---|
| 1018 |
|
|---|
| 1019 | { StrScan - Searches For the First occurence Of A SubStr In A given
|
|---|
| 1020 | String Str. returns the Pointer To the occurence, Or Nil, If the
|
|---|
| 1021 | SubStr cannot be found. }
|
|---|
| 1022 |
|
|---|
| 1023 | Function StrPos(Str, SubStr: PChar): PChar;
|
|---|
| 1024 |
|
|---|
| 1025 | { StrUpper - Converts A String To upper Case by simply Changing All
|
|---|
| 1026 | occurences Of 'a'..'z' To the corresponding upper Case characters.
|
|---|
| 1027 | returns A Pointer To the String. changes the Source String, does
|
|---|
| 1028 | Not Create A New String. does also Not take international Special
|
|---|
| 1029 | characters Or the Currently Selected codepage into account. }
|
|---|
| 1030 |
|
|---|
| 1031 | Function StrUpper(Str: PChar): PChar;
|
|---|
| 1032 |
|
|---|
| 1033 | { StrLower - Converts A String To lower Case by simply Changing All
|
|---|
| 1034 | occurences Of 'A'..'Z' To the corresponding lower Case characters.
|
|---|
| 1035 | returns A Pointer To the String. changes the Source String, does
|
|---|
| 1036 | Not Create A New String. does also Not take international Special
|
|---|
| 1037 | characters Or the Currently Selected codepage into account. }
|
|---|
| 1038 |
|
|---|
| 1039 | Function StrLower(Str: PChar): PChar;
|
|---|
| 1040 |
|
|---|
| 1041 | { StrPas - Converts A PChar Str To A Pascal String. }
|
|---|
| 1042 |
|
|---|
| 1043 | Function StrPas(Str: PChar): String;
|
|---|
| 1044 |
|
|---|
| 1045 | { StrAlloc - Allocates A block Of Memory For storing PChars. the Size
|
|---|
| 1046 | Is specified And stored In A Double Word that preceeds the Buffer.
|
|---|
| 1047 | Use StrDispose To Free the Buffer. }
|
|---|
| 1048 |
|
|---|
| 1049 | Function StrAlloc(Size: Cardinal): PChar;
|
|---|
| 1050 |
|
|---|
| 1051 | { StrBufSize - returns the Size Of A PChar Buffer that has been
|
|---|
| 1052 | previously allocated by StrAlloc. }
|
|---|
| 1053 |
|
|---|
| 1054 | Function StrBufSize(Str: PChar): Cardinal;
|
|---|
| 1055 |
|
|---|
| 1056 | { StrNew - creates A Copy Of A given String. In contrast To StrCopy,
|
|---|
| 1057 | StrNew Allocates A Memory block that can hold the String, by a
|
|---|
| 1058 | call To StrAlloc. Then it copies the Source String. the New
|
|---|
| 1059 | String can be disposed by A call To StrDispose. }
|
|---|
| 1060 |
|
|---|
| 1061 | Function StrNew(Str: PChar): PChar;
|
|---|
| 1062 |
|
|---|
| 1063 | { StrDispose - Disposes A PChar Buffer that has been previously
|
|---|
| 1064 | allocated by A call To StrAlloc. }
|
|---|
| 1065 |
|
|---|
| 1066 | Procedure StrDispose(Str: PChar);
|
|---|
| 1067 |
|
|---|
| 1068 | { --- String formatting --- }
|
|---|
| 1069 |
|
|---|
| 1070 | { format - formats A String And replaces placeholders by arguments.
|
|---|
| 1071 |
|
|---|
| 1072 | the format String can contain arbitrary Text. This Text Is simply
|
|---|
| 1073 | copied into the Result. everything that Starts With A '%' Is
|
|---|
| 1074 | considered A placeholder. placeholders are replaced by the
|
|---|
| 1075 | Parameters given In the variant-Type Open-Array Args. the First
|
|---|
| 1076 | placeholder Is replaced by the First argument, the Second one
|
|---|
| 1077 | by the Second argument, And So ON. you MUST specify At least As many
|
|---|
| 1078 | Parameters As there are placeholders, Otherwise an Exception
|
|---|
| 1079 | EConvertError will be raised.
|
|---|
| 1080 |
|
|---|
| 1081 | the way A placeholder / argument pair will be Handled Is controlled
|
|---|
| 1082 | by Some optional specifiers. the Line below shows the possibilities.
|
|---|
| 1083 |
|
|---|
| 1084 | Text In " " MUST appear literally, 'index', 'width' And 'precision'
|
|---|
| 1085 | MUST be replaced by Integer numbers, And 'type' MUST be replaced by
|
|---|
| 1086 | A character that specifies the argument Type.
|
|---|
| 1087 |
|
|---|
| 1088 | parts enclosed In angular brackets are optional, the angular
|
|---|
| 1089 | brackets MUST Not appear In the format specifier, they are only used
|
|---|
| 1090 | To Show the syntax.
|
|---|
| 1091 |
|
|---|
| 1092 | "%" [Index ":"] ["-"] [Width] ["." Precision] Type
|
|---|
| 1093 |
|
|---|
| 1094 | the different parts Of the format specifier MUST appear In the
|
|---|
| 1095 | given order, And they have the following meaning:
|
|---|
| 1096 |
|
|---|
| 1097 | "%" Begins the format specifier
|
|---|
| 1098 |
|
|---|
| 1099 | Index ":" takes the Next argument from the Array entry
|
|---|
| 1100 | given by Integer Value Index. Normally the
|
|---|
| 1101 | arguments are used one after the other. This
|
|---|
| 1102 | part Of the format specifier allows To Change
|
|---|
| 1103 | This behaviour.
|
|---|
| 1104 |
|
|---|
| 1105 | "-" Left-Justifies the Text inserted For the format
|
|---|
| 1106 | specifier. Normally the Text Is justified To
|
|---|
| 1107 | the Right. only applies If the String Is Left-
|
|---|
| 1108 | padded With spaces by the Width-specifier.
|
|---|
| 1109 |
|
|---|
| 1110 | Width Integer Value that specifies the Width being
|
|---|
| 1111 | reserved For the argument. If the String
|
|---|
| 1112 | resulting from the conversion Of the argument
|
|---|
| 1113 | Contains less than Width characters, it Is
|
|---|
| 1114 | Left padded With spaces To achieve This minimum
|
|---|
| 1115 | Length. If "-" Is used To Activate Left-
|
|---|
| 1116 | justification, the String Is padded To the
|
|---|
| 1117 | Right rather than To the Left. If the String
|
|---|
| 1118 | already has A Length equal To Or greater than
|
|---|
| 1119 | Width, no padding Is Needed.
|
|---|
| 1120 |
|
|---|
| 1121 | "." Precision Integer Value that specifies the Precision
|
|---|
| 1122 | used when converting the argument. the actual
|
|---|
| 1123 | consequences Of Precision depend ON the
|
|---|
| 1124 | argument Type. See descriptions below For
|
|---|
| 1125 | Details.
|
|---|
| 1126 |
|
|---|
| 1127 | the Index, Width, And Precision specifiers can also contain an
|
|---|
| 1128 | asterisk ('*'). In This Case, the Real Value Is taken from the
|
|---|
| 1129 | Next argument Array entry, which has To be an Integer Value, Or
|
|---|
| 1130 | EConvertError will be raised.
|
|---|
| 1131 |
|
|---|
| 1132 | following are the characters allowed To specify the argument Type.
|
|---|
| 1133 | note that 'decimal point' And 'thousand separator' mean that the
|
|---|
| 1134 | characters contained In the global variables DecimalSeparator And
|
|---|
| 1135 | ThousandSeparator will be inserted.
|
|---|
| 1136 |
|
|---|
| 1137 | D DECIMAL format. the corresponding argument MUST
|
|---|
| 1138 | be an Integer Value, Otherwise EConvertError Is
|
|---|
| 1139 | raised. the argument Is converted To A DECIMAL
|
|---|
| 1140 | String. If A Precision Is specified, the String
|
|---|
| 1141 | Is guaranteed To have At least A Number Of
|
|---|
| 1142 | Digits equal To Precision. If the String Is
|
|---|
| 1143 | shorter, it Is padded With zeroes.
|
|---|
| 1144 |
|
|---|
| 1145 | E Scientific (exponential) format. the
|
|---|
| 1146 | corresponding argument MUST be A floating Point
|
|---|
| 1147 | Value, Otherwise EConvertError Is raised. the
|
|---|
| 1148 | argument Is converted To A DECIMAL String using
|
|---|
| 1149 | Scientific notation. the String Starts With a
|
|---|
| 1150 | minus sign, If the argument Is Negative. one
|
|---|
| 1151 | digit always precedes the DECIMAL Point. the
|
|---|
| 1152 | Number Of Digits following the DECIMAL Point Is
|
|---|
| 1153 | controlled by the optional Precision specifier.
|
|---|
| 1154 | the total Number Of Digits Is always equal To
|
|---|
| 1155 | Precision. If Precision Is Not specified, a
|
|---|
| 1156 | Default Of 15 Is assumed, resulting In 1 digit
|
|---|
| 1157 | before And 14 after the DECIMAL Point.
|
|---|
| 1158 | following Is the exponential 'E' With A plus Or
|
|---|
| 1159 | A minus sign And up To 3 Digits indicating the
|
|---|
| 1160 | Exponent.
|
|---|
| 1161 |
|
|---|
| 1162 | F FIXED Point format. the corresponding argument
|
|---|
| 1163 | MUST be A floating Point Value, Otherwise
|
|---|
| 1164 | EConvertError Is raised. the argument Is
|
|---|
| 1165 | converted To A String using FIXED notation. it
|
|---|
| 1166 | Starts With A minus sign, If the argument Is
|
|---|
| 1167 | Negative. All Digits Of the argument's Integer
|
|---|
| 1168 | part appear In the Result. following Is a
|
|---|
| 1169 | DECIMAL separator And A Number Of Digits equal
|
|---|
| 1170 | To Precision. If no Precision Is specified, a
|
|---|
| 1171 | Default Of 2 DECIMAL places Is assumed.
|
|---|
| 1172 |
|
|---|
| 1173 | G General Number format. the argument MUST be a
|
|---|
| 1174 | floating Point Value, Otherwise EConvertError
|
|---|
| 1175 | Is raised. the argument Is converted To a
|
|---|
| 1176 | String using either FIXED Or Scientific format,
|
|---|
| 1177 | depending ON which results In A shorter String.
|
|---|
| 1178 | the optional Precision specifier Controls the
|
|---|
| 1179 | Number Of significant Digits (used For
|
|---|
| 1180 | rounding) With A Default Of 15. the Result will
|
|---|
| 1181 | contain neither unnecessary zeroes nor an
|
|---|
| 1182 | unnecessary DECIMAL Point. If the argument
|
|---|
| 1183 | Value Is greater than Or equal To 0.00001, And
|
|---|
| 1184 | If the Number Of Digits To the Left Of the
|
|---|
| 1185 | DECIMAL Point Is less than Or equal To the
|
|---|
| 1186 | Precision, FIXED format Is used. Otherwise the
|
|---|
| 1187 | Result Uses Scientific format.
|
|---|
| 1188 |
|
|---|
| 1189 | M currency (money) format. the corresponding
|
|---|
| 1190 | argument MUST be A floating Point Value,
|
|---|
| 1191 | Otherwise EConvertError Is raised. the argument
|
|---|
| 1192 | Is converted To A String using the following
|
|---|
| 1193 | global variables:
|
|---|
| 1194 |
|
|---|
| 1195 | CurrencyString
|
|---|
| 1196 | CurrencyFormat
|
|---|
| 1197 | NegCurrFormat
|
|---|
| 1198 | CurrencyDecimals
|
|---|
| 1199 |
|
|---|
| 1200 | If A Precision Is specified, it overrides the
|
|---|
| 1201 | Default Value Of CurrencyDecimals.
|
|---|
| 1202 |
|
|---|
| 1203 | N Number format. equal To FIXED, but the Result
|
|---|
| 1204 | String will contain thousand separators.
|
|---|
| 1205 |
|
|---|
| 1206 | P Pointer format. the corresponding argument MUST
|
|---|
| 1207 | be A Pointer Value, Otherwise EConvertError Is
|
|---|
| 1208 | raised. the Value Is converted To A String
|
|---|
| 1209 | containing the hexadecimal representation Of
|
|---|
| 1210 | the Pointer, With an additional ':' In the
|
|---|
| 1211 | middle. the resulting String has always a
|
|---|
| 1212 | Length Of 9 characters. since we are dealing
|
|---|
| 1213 | With flat Memory model, we have A full 32-bit
|
|---|
| 1214 | Pointer With no segment part, only Offset.
|
|---|
| 1215 |
|
|---|
| 1216 | S String format. the corresponding argument MUST
|
|---|
| 1217 | be A Single character, A String Or A PChar Value,
|
|---|
| 1218 | Otherwise EConvertError Is raised. the argument
|
|---|
| 1219 | Is simply copied To the destination String. If
|
|---|
| 1220 | A Precision Is specified, it Is considered the
|
|---|
| 1221 | maximum Length Of the argument String. longer
|
|---|
| 1222 | Strings will be truncated.
|
|---|
| 1223 |
|
|---|
| 1224 | X hexadecimal format. the corresponding argument
|
|---|
| 1225 | MUST be an Integer Value, Otherwise EConvertError
|
|---|
| 1226 | Is raised. the argument Is converted To a
|
|---|
| 1227 | hexadecimal String. If A Precision Is specified,
|
|---|
| 1228 | the String Is guaranteed To have At least a
|
|---|
| 1229 | Number Of Digits equal To Precision. If the
|
|---|
| 1230 | String Is shorter, it Is padded With zeroes. }
|
|---|
| 1231 |
|
|---|
| 1232 | Function format(Const format: String; Const Args: Array Of Const): String;
|
|---|
| 1233 |
|
|---|
| 1234 | { FmtStr - formats A String And replaces placeholders by arguments.
|
|---|
| 1235 | See format For A detailed description Of the format String And the
|
|---|
| 1236 | argument Array. }
|
|---|
| 1237 |
|
|---|
| 1238 | Procedure FmtStr(Var Result: String; Const format: String;
|
|---|
| 1239 | Const Args: Array Of Const);
|
|---|
| 1240 |
|
|---|
| 1241 | { StrFmt - formats A String And replaces placeholders by arguments.
|
|---|
| 1242 | note that the Buffer MUST be large enough To hold the Complete
|
|---|
| 1243 | Result, Otherwise A protection fault (EGPFault) may occur. See
|
|---|
| 1244 | format For A detailed description Of the format String And the
|
|---|
| 1245 | argument Array. }
|
|---|
| 1246 |
|
|---|
| 1247 | Function StrFmt(Buffer, format: PChar; Const Args: Array Of Const): PChar;
|
|---|
| 1248 |
|
|---|
| 1249 | { StrLFmt - formats A String And replaces placeholders by arguments.
|
|---|
| 1250 | the Function ensures that the Size Of the Output String written into
|
|---|
| 1251 | Buffer won't exceed MaxLen characters. the function's Result Is also
|
|---|
| 1252 | A Pointer To Buffer. See format For A detailed description Of the
|
|---|
| 1253 | format String And the argument Array. }
|
|---|
| 1254 |
|
|---|
| 1255 | Function StrLFmt(Buffer: PChar; MaxLen: Cardinal; format: PChar;
|
|---|
| 1256 | Const Args: Array Of Const): PChar;
|
|---|
| 1257 |
|
|---|
| 1258 | { FormatBuf - formats A String And replaces placeholders by arguments.
|
|---|
| 1259 | format And Buffer Strings are given As untyped Var / Const
|
|---|
| 1260 | Parameters. their sizes are given In BufLen And FmtLen. the Function
|
|---|
| 1261 | ensures that the Size Of the Output String written into Buffer won't
|
|---|
| 1262 | exceed BufLen characters. the Result Value Is the Number Of
|
|---|
| 1263 | characters actually written into Buffer. See format For A detailed
|
|---|
| 1264 | description Of the format String And the argument Array. }
|
|---|
| 1265 |
|
|---|
| 1266 | Function FormatBuf(Var Buffer; BufLen: Cardinal; Const format;
|
|---|
| 1267 | FmtLen: Cardinal; Const Args: Array Of Const): Cardinal;
|
|---|
| 1268 |
|
|---|
| 1269 | { --- floating Point conversion --- }
|
|---|
| 1270 |
|
|---|
| 1271 | { FloatToStrF - Converts A floating Point Number To A String. the
|
|---|
| 1272 | appearance Of the Result String can be controlled by specifying
|
|---|
| 1273 | A basic format To apply, A Precision, And A Number Of Digits.
|
|---|
| 1274 | the Precision Parameter should be less than Or equal To 18. the
|
|---|
| 1275 | meaning Of the Digits Parameter depends ON the format chosen.
|
|---|
| 1276 |
|
|---|
| 1277 | following Is A detailed description Of the possible formats:
|
|---|
| 1278 |
|
|---|
| 1279 | ffCurrency money (currency) format. the argument Is converted
|
|---|
| 1280 | To A String using the following global variables:
|
|---|
| 1281 |
|
|---|
| 1282 | CurrencyString
|
|---|
| 1283 | CurrencyFormat
|
|---|
| 1284 | NegCurrFormat
|
|---|
| 1285 |
|
|---|
| 1286 | the Digits Parameter specifies the Number Of Digits
|
|---|
| 1287 | following the DECIMAL Point (0 To 18 being legal
|
|---|
| 1288 | values).
|
|---|
| 1289 |
|
|---|
| 1290 | ffExponent Scientific (exponential) format. the argument Is
|
|---|
| 1291 | converted To A DECIMAL String using Scientific
|
|---|
| 1292 | notation. the String Starts With A minus sign, If
|
|---|
| 1293 | the argument Is Negative. one digit precedes the
|
|---|
| 1294 | DECIMAL Point. the Number Of Digits following the
|
|---|
| 1295 | DECIMAL Point Is controlled by Precision. the total
|
|---|
| 1296 | Number Of Digits Is always equal To Precision.
|
|---|
| 1297 | following Is the exponential 'E' With A plus Or a
|
|---|
| 1298 | minus sign And the Exponent With A minimum Length
|
|---|
| 1299 | Of Digits characters (0 To 4 being legal values).
|
|---|
| 1300 |
|
|---|
| 1301 | ffFixed FIXED Point format. the argument Is converted To a
|
|---|
| 1302 | String using FIXED Point notation. it Starts With a
|
|---|
| 1303 | minus sign, If the argument Is Negative. All Digits
|
|---|
| 1304 | Of the argument's Integer part appear In the Result.
|
|---|
| 1305 | following Is A comma And A Number Of DECIMAL Digits
|
|---|
| 1306 | equal To Digits (0 To 18 being legal values). If
|
|---|
| 1307 | the Number Of Digits To the Left Of the DECIMAL
|
|---|
| 1308 | Point Is greater than Precision, the Output will be
|
|---|
| 1309 | In Scientific format.
|
|---|
| 1310 |
|
|---|
| 1311 | ffGeneral General Number format. the argument Is converted
|
|---|
| 1312 | To A String using either FIXED Or Scientific
|
|---|
| 1313 | format, depending ON which results In A shorter
|
|---|
| 1314 | String. the Result will contain neither trailing
|
|---|
| 1315 | zeroes nor an unnecessary DECIMAL Point. If the
|
|---|
| 1316 | argument Value Is greater than Or equal To 0.00001,
|
|---|
| 1317 | And If the Number Of Digits To the Left Of the
|
|---|
| 1318 | DECIMAL Point Is less than Or equal To Precision,
|
|---|
| 1319 | FIXED format Is used. Otherwise the Result Is
|
|---|
| 1320 | formatted In Scientific format With Digits
|
|---|
| 1321 | specifying the minimum Number Of Digits In the
|
|---|
| 1322 | Exponent (0 To 4 being legal values).
|
|---|
| 1323 |
|
|---|
| 1324 | ffNumber Number format. equal To FIXED, but the Result
|
|---|
| 1325 | String will contain thousand separators.
|
|---|
| 1326 |
|
|---|
| 1327 | If the Value Is Not-A-Number, positive infinity, Or Negative
|
|---|
| 1328 | infinity, Then the Output String will also be NAN, INF, Or -INF. }
|
|---|
| 1329 |
|
|---|
| 1330 | Function FloatToStrF(Value: Extended; format: TFloatFormat;
|
|---|
| 1331 | Precision, Digits: Integer): String;
|
|---|
| 1332 |
|
|---|
| 1333 | { FloatToStr - Converts A floating Point Value To A String using
|
|---|
| 1334 | General Number format And 15 significant Digits. See FloatToStrF
|
|---|
| 1335 | For more Details. }
|
|---|
| 1336 |
|
|---|
| 1337 | Function FloatToStr(Value: Extended): String;
|
|---|
| 1338 |
|
|---|
| 1339 | { FloatToText - Converts A floating Point Number To A String. the
|
|---|
| 1340 | Result Is written To Buffer without A Zero teminator being
|
|---|
| 1341 | appended. the caller has To ensure that the Buffer Is large
|
|---|
| 1342 | enough To hold the Result. the Result can be controlled using
|
|---|
| 1343 | format, Precision And Digits Parameters. See FloatToStrF For
|
|---|
| 1344 | A detailed description Of these Parameters. }
|
|---|
| 1345 |
|
|---|
| 1346 | Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat;
|
|---|
| 1347 | Precision, Digits: Integer): Integer;
|
|---|
| 1348 |
|
|---|
| 1349 | { FormatFloat - Converts A floating Point Value To A String using a
|
|---|
| 1350 | specified format.
|
|---|
| 1351 |
|
|---|
| 1352 | the Parameter format Controls the appearance Of the Result String.
|
|---|
| 1353 |
|
|---|
| 1354 | format can contain up To three Sections, separated from each other
|
|---|
| 1355 | by semicolons. the First section holds the format String used For
|
|---|
| 1356 | positive values, the Second one holds the format For Negative
|
|---|
| 1357 | values, And the third one Is applied To Zero values. If one Of
|
|---|
| 1358 | the Sections Is missing Or Empty, the First section Is used
|
|---|
| 1359 | instead. If All Sections are missing Or Empty, General Number
|
|---|
| 1360 | format Is used With A Precision Of 15. See FloatToStrF For more
|
|---|
| 1361 | Details about General Number format.
|
|---|
| 1362 |
|
|---|
| 1363 | each Of the three Sections can contain arbitrary Text, which Is
|
|---|
| 1364 | simply copied To the Result String. Some characters have A Special
|
|---|
| 1365 | meaning, they serve As placeholders For inserting Data from the
|
|---|
| 1366 | Value Parameter.
|
|---|
| 1367 |
|
|---|
| 1368 | the following List shows All placeholders And their meaning:
|
|---|
| 1369 |
|
|---|
| 1370 | 0 Mandatory digit. If the Value has A digit At This
|
|---|
| 1371 | Position, it Is copied To the Result. Otherwise a
|
|---|
| 1372 | 0 Is inserted.
|
|---|
| 1373 |
|
|---|
| 1374 | # optional digit. If the Value has A digit At This
|
|---|
| 1375 | Position, it Is copied To the Result. Otherwise
|
|---|
| 1376 | This Position Of the format String will be ignored.
|
|---|
| 1377 |
|
|---|
| 1378 | . DECIMAL separator. the First occurence Of '.' In the
|
|---|
| 1379 | format String determines the Position At which A DECIMAL
|
|---|
| 1380 | separator will be inserted. the DECIMAL separator Is
|
|---|
| 1381 | taken from the global variable DecimalSeparator. further
|
|---|
| 1382 | occurences Of '.' will be ignored.
|
|---|
| 1383 |
|
|---|
| 1384 | , thousand separator. any occurence Of ',' activates the
|
|---|
| 1385 | insertion Of thousand separators into the Result, where
|
|---|
| 1386 | necessary. the thousand separator Is taken from the
|
|---|
| 1387 | global variable DecimalSeparator.
|
|---|
| 1388 |
|
|---|
| 1389 | E+ E- Scientific (exponential) format. If any Of the four
|
|---|
| 1390 | E+ E- Strings To the Left occur In the format String, the
|
|---|
| 1391 | Result will be formatted using Scientific notation.
|
|---|
| 1392 | the exponential E will have the same Case As In the
|
|---|
| 1393 | format String. the Exponent itself will always be
|
|---|
| 1394 | preceded by its sign, If E+ Or E+ are used. E- And E-
|
|---|
| 1395 | contain A sign only If the Exponent Value Is Negative.
|
|---|
| 1396 | up To four digit placeholders can be used To specify the
|
|---|
| 1397 | minimum Number Of Digits used For the Exponent.
|
|---|
| 1398 |
|
|---|
| 1399 | '...' characters enclosed In Single Or Double quotes will
|
|---|
| 1400 | "..." simply be copied To the Result (without quotes).
|
|---|
| 1401 |
|
|---|
| 1402 | the floating Point Value Is rounded With A Precision equal To the
|
|---|
| 1403 | total Number Of digit placeholders In the format String. optional
|
|---|
| 1404 | digit placeholders between the leftmost And rightmost Mandatory
|
|---|
| 1405 | digit placeholders will be taken As Mandatory Digits, So it makes
|
|---|
| 1406 | no sense To specify one ore more '#' between zeroes. If the rounded
|
|---|
| 1407 | Value Contains more Digits In the Integer part than there are
|
|---|
| 1408 | placeholders Left Of the DECIMAL separator, the additional Digits
|
|---|
| 1409 | will be inserted before the First placeholder. }
|
|---|
| 1410 |
|
|---|
| 1411 | Function FormatFloat(Const format: String; Value: Extended): String;
|
|---|
| 1412 |
|
|---|
| 1413 | { FloatToTextFmt - Converts A floating Point Value To A String using a
|
|---|
| 1414 | specified format. the Result Is written To Buffer without a
|
|---|
| 1415 | terminating Zero. the caller has To ensure that the Buffer Is large
|
|---|
| 1416 | enough To hold the Result. the Number Of characters actually written
|
|---|
| 1417 | To Buffer Is returned. See FormatFloat For A description Of the
|
|---|
| 1418 | format Parameter. }
|
|---|
| 1419 |
|
|---|
| 1420 | Function FloatToTextFmt(Buffer: PChar; Value: Extended;
|
|---|
| 1421 | format: PChar): Integer;
|
|---|
| 1422 |
|
|---|
| 1423 | { StrToFloat - Converts A String To A floating Point Value. the String
|
|---|
| 1424 | MUST contain A legal floating Point Value, With the DECIMAL Point
|
|---|
| 1425 | being the same character As In the global variable DecimalSeparator.
|
|---|
| 1426 | it MUST Not contain thousand separators Or currency symbols. leading
|
|---|
| 1427 | And trailing spaces are allowed. If the String does Not conform
|
|---|
| 1428 | these restrictions, EConvertError Is raised. }
|
|---|
| 1429 |
|
|---|
| 1430 | Function StrToFloat(Const S: String): Extended;
|
|---|
| 1431 |
|
|---|
| 1432 | { TextToFloat - Converts A Zero-Terminated String To A floating Point
|
|---|
| 1433 | Value. the String MUST contain A legal floating Point Value, With
|
|---|
| 1434 | the DECIMAL Point being the same character As In the global variable
|
|---|
| 1435 | DecimalSeparator. it MUST Not contain thousand separators Or
|
|---|
| 1436 | currency symbols. leading And trailing spaces are allowed. If the
|
|---|
| 1437 | String does Not conform these restrictions, EConvertError Is raised. }
|
|---|
| 1438 |
|
|---|
| 1439 | Function TextToFloat(Buffer: PChar; Var Value: Extended): Boolean;
|
|---|
| 1440 |
|
|---|
| 1441 | { FloatToDecimal - Converts A floating Point Value To A TFloatRec
|
|---|
| 1442 | Record which separates Digits, sign, And Exponent. the Precision
|
|---|
| 1443 | Parameter specifies the Number Of significant Digits (With 1..18
|
|---|
| 1444 | being legal values), the Decimals Parameter specifies the desired
|
|---|
| 1445 | minimum Number Of Digits In the fractional part. rounding Is
|
|---|
| 1446 | controlled by Precision As well As by Decimals. To force A Number
|
|---|
| 1447 | Of significant Digits even With large values, specify 9999 For
|
|---|
| 1448 | Decimals.
|
|---|
| 1449 |
|
|---|
| 1450 | the resulting TFloatRec will contain the following information:
|
|---|
| 1451 |
|
|---|
| 1452 | Exponent - the result's Exponent. an Exponent Value Of -32768
|
|---|
| 1453 | Indicates that the Value Is Not-A-Number (NAN). positive Or
|
|---|
| 1454 | Negative infinity (INF / -INF) Is indicated by an Exponent
|
|---|
| 1455 | Value Of 32767.
|
|---|
| 1456 |
|
|---|
| 1457 | Negative - Indicates whether the Value Is Negative Or Not. Use
|
|---|
| 1458 | This To distinguish positive from Negative infinity, too. Zero
|
|---|
| 1459 | Is assumed To be non-Negative.
|
|---|
| 1460 |
|
|---|
| 1461 | Digits - Contains the significant Digits With A terminating
|
|---|
| 1462 | Zero (Chr(0)). does Not contain the DECIMAL separator. Empty,
|
|---|
| 1463 | If the Value Is Not-A-Number, Or positive, Or Negative infinity. }
|
|---|
| 1464 |
|
|---|
| 1465 | Procedure FloatToDecimal(Var Result: TFloatRec; Value: Extended;
|
|---|
| 1466 | Precision, Decimals: Integer);
|
|---|
| 1467 |
|
|---|
| 1468 | { --- date / Time Handling --- }
|
|---|
| 1469 |
|
|---|
| 1470 | { EncodeDate - Encodes the given Year, Month, And Day into A Single
|
|---|
| 1471 | TDateTime Value. the Result Contains the Number Of days passed since
|
|---|
| 1472 | the 31-Dec-0000 And the given date, assuming Gregorian calendar has
|
|---|
| 1473 | always been used. If any Parameter Contains an illegal Value,
|
|---|
| 1474 | EConvertError Is raised. }
|
|---|
| 1475 |
|
|---|
| 1476 | Function EncodeDate(Year, Month, Day: Word): TDateTime;
|
|---|
| 1477 |
|
|---|
| 1478 | { EncodeTime - Encodes the given Hour, Minute, Second And millisecond
|
|---|
| 1479 | into A Single TDateTime Value. the Result Contains the fractional
|
|---|
| 1480 | part Of the Day passed since 00:00:00. it Is always A Value equal To
|
|---|
| 1481 | Or greater than Zero And And smaller that one. If any Parameter
|
|---|
| 1482 | Contains an illegal Value, EConvertError Is raised. }
|
|---|
| 1483 |
|
|---|
| 1484 | Function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
|
|---|
| 1485 |
|
|---|
| 1486 | { DecodeDate - Extracts Year, Month, And Day from A given TDateTime
|
|---|
| 1487 | Value. }
|
|---|
| 1488 |
|
|---|
| 1489 | Procedure DecodeDate(date: TDateTime; Var Year, Month, Day: Word);
|
|---|
| 1490 |
|
|---|
| 1491 | { DecodeTime - Extracts Hour, Minute, Second, And millisecond from a
|
|---|
| 1492 | given TDateTime Value. }
|
|---|
| 1493 |
|
|---|
| 1494 | Procedure DecodeTime(Time: TDateTime; Var Hour, Min, Sec, MSec: Word);
|
|---|
| 1495 |
|
|---|
| 1496 | { DayOfWeek - Extracts the Day Of the week from A given TDateTime
|
|---|
| 1497 | Value. the days are numbered from 1 To 7 In the following order:
|
|---|
| 1498 |
|
|---|
| 1499 | Sun / Mon / Tue / Wed / Thu / Fri / Sat }
|
|---|
| 1500 |
|
|---|
| 1501 | Function DayOfWeek(date: TDateTime): Integer;
|
|---|
| 1502 |
|
|---|
| 1503 | { date - Queries the Current System date. }
|
|---|
| 1504 |
|
|---|
| 1505 | Function date: TDateTime;
|
|---|
| 1506 |
|
|---|
| 1507 | { Time - Queries the Current System Time. }
|
|---|
| 1508 |
|
|---|
| 1509 | Function Time: TDateTime;
|
|---|
| 1510 |
|
|---|
| 1511 | { now - Queries the Current System date And Time. }
|
|---|
| 1512 |
|
|---|
| 1513 | Function now: TDateTime;
|
|---|
| 1514 |
|
|---|
| 1515 | { DateToStr - Converts the date part Of the given TDateTime Value
|
|---|
| 1516 | To A String, using the format specified In the global variable
|
|---|
| 1517 | ShortDateFormat. }
|
|---|
| 1518 |
|
|---|
| 1519 | Function DateToStr(date: TDateTime): String;
|
|---|
| 1520 |
|
|---|
| 1521 | { TimeToStr - Converts the Time part ao the given TDateTime Value
|
|---|
| 1522 | To A String, using the format specified In the global variable
|
|---|
| 1523 | LongTimeFormat. }
|
|---|
| 1524 |
|
|---|
| 1525 | Function TimeToStr(Time: TDateTime): String;
|
|---|
| 1526 |
|
|---|
| 1527 | { DateTimeToStr - Converts the given TDateTime Value To A String
|
|---|
| 1528 | using the formats specified In the global variables ShortDateFormat
|
|---|
| 1529 | And LongTimeFormat. the Time Is only appended, If the TDateTime
|
|---|
| 1530 | Value Contains A (fractional) Time part different from 00:00:00. }
|
|---|
| 1531 |
|
|---|
| 1532 | Function DateTimeToStr(DateTime: TDateTime): String;
|
|---|
| 1533 |
|
|---|
| 1534 | { StrToDate - Tries To exctract date information from A String.
|
|---|
| 1535 | the FUNCTIONs expects the String To contain two Or three numbers
|
|---|
| 1536 | separated by the character given In the global variable
|
|---|
| 1537 | DateSeparator. the order In which Day, Month, And Year are
|
|---|
| 1538 | expected Is determined by the global variable DateOrder.
|
|---|
| 1539 | If only two numbers are found, they are assumed To specify
|
|---|
| 1540 | A Month And Day Of the Current Year. If the Year Is smaller
|
|---|
| 1541 | than 100, it Is assumed To be A Year Of the Current century.
|
|---|
| 1542 | If no legal date can be extracted from the String,
|
|---|
| 1543 | EConvertError Is raised. }
|
|---|
| 1544 |
|
|---|
| 1545 | Function StrToDate(Const S: String): TDateTime;
|
|---|
| 1546 |
|
|---|
| 1547 | { StrToTime - Tries To exctract Time information from A String.
|
|---|
| 1548 | the FUNCTIONs expects the String To contain two Or three numbers
|
|---|
| 1549 | separated by the character given In the global variable
|
|---|
| 1550 | TimeSeparator, optionally followed by 'AM' Or 'PM' To indicate
|
|---|
| 1551 | 12-Hour format. the First two numbers are taken As Hour And
|
|---|
| 1552 | Minute, the optional third one As Second. If no indicator For
|
|---|
| 1553 | 12-Hour format Is found, the Time Is assumed To be In 24-Hour
|
|---|
| 1554 | format. If no legal Time can be extracted from the String,
|
|---|
| 1555 | EConvertError Is raised. }
|
|---|
| 1556 |
|
|---|
| 1557 | Function StrToTime(Const S: String): TDateTime;
|
|---|
| 1558 |
|
|---|
| 1559 | { StrToDateTime - Tries To extract date And Time information from A
|
|---|
| 1560 | String. the Function expects the String To contain A date optionally
|
|---|
| 1561 | followed by A Time. See StrToDate And StrToTime For more Details
|
|---|
| 1562 | about the string's contents. If no legal date And Time can be
|
|---|
| 1563 | extracted from the String, EConvertError Is raised. }
|
|---|
| 1564 |
|
|---|
| 1565 | Function StrToDateTime(Const S: String): TDateTime;
|
|---|
| 1566 |
|
|---|
| 1567 | { FormatDateTime - Converts A TDateTime Value To A String using a
|
|---|
| 1568 | format specified by the Parameter format.
|
|---|
| 1569 |
|
|---|
| 1570 | the format String may contain arbitrary Text, which Is simply
|
|---|
| 1571 | copies To the Result String. Some characters Or character
|
|---|
| 1572 | sequences have A Special meaning, they serve As placeholders And
|
|---|
| 1573 | are replaced by values extracted from DateTime.
|
|---|
| 1574 |
|
|---|
| 1575 | the following placeholders are allowed In the format String. their
|
|---|
| 1576 | Case doesn't matter. If the format String Is Empty, 'c' Is assumed
|
|---|
| 1577 | the Default format.
|
|---|
| 1578 |
|
|---|
| 1579 | C replaced by the date formatted As specified In the
|
|---|
| 1580 | global variable ShortDateFormat. If the (fractional)
|
|---|
| 1581 | Time part Is different from 00:00:00, the Time Is
|
|---|
| 1582 | appended using the format specified In the global
|
|---|
| 1583 | variable LongTimeFormat.
|
|---|
| 1584 |
|
|---|
| 1585 | D replaced by A Number indicating the Day Of the Month,
|
|---|
| 1586 | With no leading Zero.
|
|---|
| 1587 |
|
|---|
| 1588 | dd replaced by A Number indicating the Day Of the Month,
|
|---|
| 1589 | With leading Zero.
|
|---|
| 1590 |
|
|---|
| 1591 | ddd replaced by the Day Of the week's Name taken from the
|
|---|
| 1592 | global Array ShortDayNames, resulting In an abbreviation
|
|---|
| 1593 | Of the day's Name.
|
|---|
| 1594 |
|
|---|
| 1595 | dddd replaced by the Day Of the week's Name taken from the
|
|---|
| 1596 | global Array LongDayNames, resulting In the day's full
|
|---|
| 1597 | Name.
|
|---|
| 1598 |
|
|---|
| 1599 | ddddd replaced by the date formatted As specified In the
|
|---|
| 1600 | global variable ShortDateFormat.
|
|---|
| 1601 |
|
|---|
| 1602 | dddddd replaced by the date formatted As specified In the
|
|---|
| 1603 | global variable LongDateFormat.
|
|---|
| 1604 |
|
|---|
| 1605 | M when used immediately after an Hour placeholder,
|
|---|
| 1606 | replaced by the Minute. Otherwise replaced by A
|
|---|
| 1607 | Number indicating the Month. no leading zeroes.
|
|---|
| 1608 |
|
|---|
| 1609 | mm when used immediately after an Hour placeholder,
|
|---|
| 1610 | replaced by the Minute. Otherwise replaced by A
|
|---|
| 1611 | Number indicating the Month. leading zeroes.
|
|---|
| 1612 |
|
|---|
| 1613 | mmm replaced by the month's Name taken from the global Array
|
|---|
| 1614 | ShortMonthNames, resulting In an abbreviation Of the
|
|---|
| 1615 | month's Name.
|
|---|
| 1616 |
|
|---|
| 1617 | mmmm replaced by the month's Name taken from the global Array
|
|---|
| 1618 | LongMonthNames, resulting In the month's full Name.
|
|---|
| 1619 |
|
|---|
| 1620 | yy replaced by two Digits indicating the Year. leading
|
|---|
| 1621 | zeroes.
|
|---|
| 1622 |
|
|---|
| 1623 | yyyy replaced by four Digits indicating the Year. leading
|
|---|
| 1624 | zeroes.
|
|---|
| 1625 |
|
|---|
| 1626 | H replaced by the Hour without leading Zero.
|
|---|
| 1627 |
|
|---|
| 1628 | hh replaced by the Hour With leading Zero.
|
|---|
| 1629 |
|
|---|
| 1630 | N replaced by the Minute without leading Zero.
|
|---|
| 1631 |
|
|---|
| 1632 | nn replaced by the Minute With leading Zero.
|
|---|
| 1633 |
|
|---|
| 1634 | S replaced by the Second without leading Zero.
|
|---|
| 1635 |
|
|---|
| 1636 | SS replaced by the Second With leading Zero.
|
|---|
| 1637 |
|
|---|
| 1638 | T replaced by the Time formatted As specified In the
|
|---|
| 1639 | global variable ShortTimeFormat.
|
|---|
| 1640 |
|
|---|
| 1641 | tt replaced by the Time formatted As specified In the
|
|---|
| 1642 | global variable LongTimeFormat.
|
|---|
| 1643 |
|
|---|
| 1644 | am/PM Indicates that 12-Hour format should be used For the
|
|---|
| 1645 | preceding Hour placeholder. replaced by 'am' Or 'pm',
|
|---|
| 1646 | depending ON the Time, With the same Case As specified.
|
|---|
| 1647 |
|
|---|
| 1648 | A/P Indicates that 12-Hour format should be used For the
|
|---|
| 1649 | preceding Hour placeholder. replaced by 'a' Or 'p',
|
|---|
| 1650 | depending ON the Time, With the same Case As specified.
|
|---|
| 1651 |
|
|---|
| 1652 | ampm Indicates that 12-Hour format should be used For the
|
|---|
| 1653 | preceding Hour placeholder. replaced by A String taken
|
|---|
| 1654 | from the global variables TimeAMString Or TimePMString,
|
|---|
| 1655 | depending ON the Time.
|
|---|
| 1656 |
|
|---|
| 1657 | / replaced by the date separator As specified In the global
|
|---|
| 1658 | variable DateSeparator.
|
|---|
| 1659 |
|
|---|
| 1660 | : replaced by the Time separator As specified In the global
|
|---|
| 1661 | variable TimeSeparator.
|
|---|
| 1662 |
|
|---|
| 1663 | '...' characters enclosed In Single Or Double quotes will
|
|---|
| 1664 | "..." simply be copied To the Result (without quotes). }
|
|---|
| 1665 |
|
|---|
| 1666 | Function FormatDateTime(Const format: String; DateTime: TDateTime): String;
|
|---|
| 1667 |
|
|---|
| 1668 | { DateTimeToString - Converts A TDateTime Value To A String using A
|
|---|
| 1669 | format specified by the format Parameter . See FormatDateTime For
|
|---|
| 1670 | A detailed description Of the format String. }
|
|---|
| 1671 |
|
|---|
| 1672 | Procedure DateTimeToString(Var Result: String; Const format: String;
|
|---|
| 1673 | DateTime: TDateTime);
|
|---|
| 1674 |
|
|---|
| 1675 | { --- System profile support --- }
|
|---|
| 1676 |
|
|---|
| 1677 | {$IFDEF GUI}
|
|---|
| 1678 |
|
|---|
| 1679 | { GetProfileStr - Reads A String from the operating system's user
|
|---|
| 1680 | profile. If section Or entry don't exist, A Default Value Is
|
|---|
| 1681 | returned instead. }
|
|---|
| 1682 |
|
|---|
| 1683 | Function GetProfileStr(Const Section, Entry, Default: String): String;
|
|---|
| 1684 |
|
|---|
| 1685 | { GetProfileChar - Reads A character from the operating system's user
|
|---|
| 1686 | profile. If section Or entry don't exist, A Default Value Is
|
|---|
| 1687 | returned instead. }
|
|---|
| 1688 |
|
|---|
| 1689 | Function GetProfileChar(Const Section, Entry: String; Default: Char): Char;
|
|---|
| 1690 |
|
|---|
| 1691 | { GetProfileInt - Reads an Integer from the operating system's user
|
|---|
| 1692 | profile. If section Or entry don't exist, A Default Value Is
|
|---|
| 1693 | returned instead. }
|
|---|
| 1694 |
|
|---|
| 1695 | Function GetProfileInt(Const Section, Entry: string; Default: Integer): Integer;
|
|---|
| 1696 |
|
|---|
| 1697 | { GetFormatSettings - Queries A lot Of Default values used For
|
|---|
| 1698 | formatting FUNCTIONs from the Operation System. called automatically
|
|---|
| 1699 | In the SysUtils startup Code, So an Application that Uses SysUtils
|
|---|
| 1700 | can always access these values immediately after Program startup. }
|
|---|
| 1701 |
|
|---|
| 1702 | {$ENDIF GUI}
|
|---|
| 1703 |
|
|---|
| 1704 | Procedure GetFormatSettings;
|
|---|
| 1705 |
|
|---|
| 1706 | { ConvertError - Raises EConvertError With the given Error Message. }
|
|---|
| 1707 |
|
|---|
| 1708 | Procedure ConvertError(Const Msg: String);
|
|---|
| 1709 |
|
|---|
| 1710 | { --- Some routines that belong into System.PAS --- }
|
|---|
| 1711 |
|
|---|
| 1712 | { SetLength - changes the Length Of A String. Please Use This
|
|---|
| 1713 | Procedure instead Of writing S[0] := NewLength To maintain
|
|---|
| 1714 | compatibility With the forthcoming LONG Strings that won't contain
|
|---|
| 1715 | A Length-Byte any more. }
|
|---|
| 1716 |
|
|---|
| 1717 | { Procedure SetLength(Var S: String; NewLength: Byte); }
|
|---|
| 1718 |
|
|---|
| 1719 | { StringOfChars - returns A String that consists Of
|
|---|
| 1720 | Count occurences Of the given character CH. }
|
|---|
| 1721 |
|
|---|
| 1722 | Function StringOfChars(CH: Char; Count: Integer): String;
|
|---|
| 1723 |
|
|---|
| 1724 | { SetCurrentLanguageTable - sets the Language Table Name To the specified Language.
|
|---|
| 1725 | the Name MUST Start With "SIBYL_NLS_". A Table With the Name MUST exist. If the Table
|
|---|
| 1726 | cannot be found Or Some other Error occurs This Function returns False, otherise True.
|
|---|
| 1727 | by convention the Table MUST Include All Sibyl Default Language identifiers
|
|---|
| 1728 | (See /Language Directory For examples).}
|
|---|
| 1729 |
|
|---|
| 1730 | Function SetCurrentLanguageTable(Const Table:String):Boolean;
|
|---|
| 1731 |
|
|---|
| 1732 | { GetCurrentLanguageTable - gets the Current Language Table Name. }
|
|---|
| 1733 |
|
|---|
| 1734 | Function GetCurrentLanguageTable:String;
|
|---|
| 1735 |
|
|---|
| 1736 | { GetCurrentLanguage - returns the Currently Set Language. the Language String Is
|
|---|
| 1737 | retrieved from the Current Language Table With the "SLanguage" Index. This Function
|
|---|
| 1738 | returns an Empty String ON Error. }
|
|---|
| 1739 |
|
|---|
| 1740 | Function GetCurrentLanguage:String;
|
|---|
| 1741 |
|
|---|
| 1742 | {GetPhysicalDrives - returns information about logical drives connected
|
|---|
| 1743 | to the system. The drives are encoded bitwise starting with bit 0 for
|
|---|
| 1744 | drive A. A enabled bit indicates that the appropriate drive is present}
|
|---|
| 1745 | Function GetPhysicalDrives:LongWord;
|
|---|
| 1746 |
|
|---|
| 1747 | {$IFDEF WIN32}
|
|---|
| 1748 | Procedure StrOemToAnsi(Var s:String);
|
|---|
| 1749 | {$ENDIF}
|
|---|
| 1750 |
|
|---|
| 1751 | Implementation
|
|---|
| 1752 |
|
|---|
| 1753 | {$IFDEF WIN32}
|
|---|
| 1754 | Procedure StrOemToAnsi(Var s:String);
|
|---|
| 1755 | Var Found:Boolean;
|
|---|
| 1756 | c:CString;
|
|---|
| 1757 | Begin
|
|---|
| 1758 | Found:=True;
|
|---|
| 1759 | Asm
|
|---|
| 1760 | MOV EDI,s
|
|---|
| 1761 | MOVZXB ECX,[EDI]
|
|---|
| 1762 | INC EDI
|
|---|
| 1763 | CMP ECX,0
|
|---|
| 1764 | JE !End1
|
|---|
| 1765 | !Lo1:
|
|---|
| 1766 | //Check for ä,ö,ü,Ä,Ö,Ü,ß
|
|---|
| 1767 | CMPB [EDI],132
|
|---|
| 1768 | JE !End2
|
|---|
| 1769 | CMPB [EDI],142
|
|---|
| 1770 | JE !End2
|
|---|
| 1771 | CMPB [EDI],148
|
|---|
| 1772 | JE !End2
|
|---|
| 1773 | CMPB [EDI],153
|
|---|
| 1774 | JE !End2
|
|---|
| 1775 | CMPB [EDI],129
|
|---|
| 1776 | JE !End2
|
|---|
| 1777 | CMPB [EDI],154
|
|---|
| 1778 | JE !End2
|
|---|
| 1779 | CMPB [EDI],225
|
|---|
| 1780 | JE !End2
|
|---|
| 1781 |
|
|---|
| 1782 | INC EDI
|
|---|
| 1783 | LOOP !Lo1
|
|---|
| 1784 | !End1:
|
|---|
| 1785 | MOVB Found,0
|
|---|
| 1786 | !End2:
|
|---|
| 1787 | End;
|
|---|
| 1788 |
|
|---|
| 1789 | If Found Then
|
|---|
| 1790 | Begin
|
|---|
| 1791 | c:=s;
|
|---|
| 1792 | OemToAnsi(c,c);
|
|---|
| 1793 | s:=c;
|
|---|
| 1794 | End;
|
|---|
| 1795 | End;
|
|---|
| 1796 | {$ENDIF}
|
|---|
| 1797 |
|
|---|
| 1798 | Uses
|
|---|
| 1799 | Language;
|
|---|
| 1800 |
|
|---|
| 1801 |
|
|---|
| 1802 | Function GetPhysicalDrives:LongWord;
|
|---|
| 1803 | {$IFDEF OS2}
|
|---|
| 1804 | Var
|
|---|
| 1805 | ActualDrive:LongWord;
|
|---|
| 1806 | {$ENDIF}
|
|---|
| 1807 | Begin
|
|---|
| 1808 | {$IFDEF OS2}
|
|---|
| 1809 | DosQueryCurrentDisk(ActualDrive,Result);
|
|---|
| 1810 | {$ENDIF}
|
|---|
| 1811 | {$IFDEF Win95}
|
|---|
| 1812 | result := GetLogicalDrives;
|
|---|
| 1813 | {$ENDIF}
|
|---|
| 1814 | End;
|
|---|
| 1815 |
|
|---|
| 1816 | { Current Language String Table identifier. Name has preceding SIBYL_NLS_ String !}
|
|---|
| 1817 | Var
|
|---|
| 1818 | CurrentLanguageTable:String;
|
|---|
| 1819 |
|
|---|
| 1820 | Function SetCurrentLanguageTable(Const Table:String):Boolean;
|
|---|
| 1821 | Var P:Pointer;
|
|---|
| 1822 | len:LongWord;
|
|---|
| 1823 | Begin
|
|---|
| 1824 | P:=FindStringTableRes(Table,len);
|
|---|
| 1825 | Result:=P<>Nil;
|
|---|
| 1826 | If Result Then CurrentLanguageTable:=Table;
|
|---|
| 1827 | End;
|
|---|
| 1828 |
|
|---|
| 1829 | Function GetCurrentLanguageTable:String;
|
|---|
| 1830 | Begin
|
|---|
| 1831 | Result:=CurrentLanguageTable;
|
|---|
| 1832 | End;
|
|---|
| 1833 |
|
|---|
| 1834 | Function GetCurrentLanguage:String;
|
|---|
| 1835 | Begin
|
|---|
| 1836 | Result:=LoadNLSStr(SLanguage);
|
|---|
| 1837 | End;
|
|---|
| 1838 |
|
|---|
| 1839 | Const
|
|---|
| 1840 |
|
|---|
| 1841 | { Array With Number Of days passed since beginning Of the Year
|
|---|
| 1842 | Until the 1st Of Every Month. used For date/Time conversions. }
|
|---|
| 1843 |
|
|---|
| 1844 | DaysPassed: Array[False..True, 1..13] Of Integer =
|
|---|
| 1845 | ((0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365),
|
|---|
| 1846 | (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366));
|
|---|
| 1847 |
|
|---|
| 1848 | ShareModes = fmShareExclusive
|
|---|
| 1849 | Or fmShareDenyRead
|
|---|
| 1850 | Or fmShareDenyWrite
|
|---|
| 1851 | Or fmShareDenyNone;
|
|---|
| 1852 |
|
|---|
| 1853 | Var
|
|---|
| 1854 |
|
|---|
| 1855 | { Collating sequence. Needed For sorting when OS/2 base API FUNCTIONs are used. }
|
|---|
| 1856 |
|
|---|
| 1857 | CollatingSequence: Array[#0..#255] Of Byte;
|
|---|
| 1858 |
|
|---|
| 1859 | Const
|
|---|
| 1860 |
|
|---|
| 1861 | { Array For creation Of hexadecimal numbers }
|
|---|
| 1862 |
|
|---|
| 1863 | Hexadecimals: Array[0..15] Of Char = '0123456789ABCDEF';
|
|---|
| 1864 |
|
|---|
| 1865 | Procedure ConvertError(Const Msg: String);
|
|---|
| 1866 | Begin
|
|---|
| 1867 | Raise EConvertError.Create(Msg);
|
|---|
| 1868 | End;
|
|---|
| 1869 |
|
|---|
| 1870 | Procedure FmtLoadConvertError(Ident: Integer; Args: Array Of Const);
|
|---|
| 1871 | Var
|
|---|
| 1872 | Msg: String;
|
|---|
| 1873 | Begin
|
|---|
| 1874 | {$IFDEF GUI}
|
|---|
| 1875 | Try
|
|---|
| 1876 | Msg := FmtLoadNLSStr(Ident, Args);
|
|---|
| 1877 | Except
|
|---|
| 1878 | Msg := LoadNLSStr(Ident) + ' [!]';
|
|---|
| 1879 | End;
|
|---|
| 1880 | {$ELSE GUI}
|
|---|
| 1881 | Msg := 'SysUtils conversion error #' + IntToStr(Ident);
|
|---|
| 1882 | {$ENDIF GUI}
|
|---|
| 1883 | ConvertError(Msg);
|
|---|
| 1884 | End;
|
|---|
| 1885 |
|
|---|
| 1886 | { --- String / PChar Utility FUNCTIONs --- }
|
|---|
| 1887 |
|
|---|
| 1888 | Assembler
|
|---|
| 1889 |
|
|---|
| 1890 | { This Function returns the Length Of A String And A Pointer To the
|
|---|
| 1891 | Zero terminator.
|
|---|
| 1892 |
|
|---|
| 1893 | Input: EDI holds Pointer String
|
|---|
| 1894 | Output: EDI hols Pointer To Zero terminator, EAX holds String Length
|
|---|
| 1895 | changes: EAX, EBX, ECX, EDI }
|
|---|
| 1896 |
|
|---|
| 1897 | SysUtils.!StringLength Proc NEAR32
|
|---|
| 1898 |
|
|---|
| 1899 | MOV EBX, EDI
|
|---|
| 1900 | Xor EAX, EAX
|
|---|
| 1901 | CMP EDI, 0
|
|---|
| 1902 | JE !Out!StringLength
|
|---|
| 1903 | MOV ECX, $FFFFFFFF
|
|---|
| 1904 | CLD
|
|---|
| 1905 | REPNE SCASB
|
|---|
| 1906 | Not ECX
|
|---|
| 1907 | MOV EAX, ECX
|
|---|
| 1908 | Dec EAX
|
|---|
| 1909 | Dec EDI
|
|---|
| 1910 |
|
|---|
| 1911 | !Out!StringLength:
|
|---|
| 1912 | RETN32
|
|---|
| 1913 |
|
|---|
| 1914 | SysUtils.!StringLength ENDP
|
|---|
| 1915 |
|
|---|
| 1916 | { This FUNCTIONs copies A maximum Number Of characters from one String
|
|---|
| 1917 | To another.
|
|---|
| 1918 |
|
|---|
| 1919 | Input: ESI holds Source, EDI holds destination, ECX hold maximum
|
|---|
| 1920 | Number Of characters
|
|---|
| 1921 | Output: EDI holds End Of destination String
|
|---|
| 1922 | changes: EAX, EBX, ECX, EDX, ESI, EDI }
|
|---|
| 1923 |
|
|---|
| 1924 | SysUtils.!StringCopy Proc NEAR32
|
|---|
| 1925 |
|
|---|
| 1926 | MOV EBX, ECX // EBX now contains max chars
|
|---|
| 1927 | MOV EDX, EDI // edx now contains destination
|
|---|
| 1928 | Xor EAX, EAX // set eax=0
|
|---|
| 1929 |
|
|---|
| 1930 | // Check parameters
|
|---|
| 1931 | CMP EDI, 0 // if destination is null, exit
|
|---|
| 1932 | JE !Out!StringCopy
|
|---|
| 1933 | CMP ESI, 0 // if destination is null, exit
|
|---|
| 1934 | JE !Out!StringCopy
|
|---|
| 1935 |
|
|---|
| 1936 | MOV EDI, ESI // load source into EDI
|
|---|
| 1937 | CLD
|
|---|
| 1938 |
|
|---|
| 1939 | // look for 0 terminator, starting from EDI
|
|---|
| 1940 | // or stop at max chars, when ECX = 0
|
|---|
| 1941 | REPNE SCASB
|
|---|
| 1942 | // ECX is now (max chars - length) or 0 if limit reached
|
|---|
| 1943 |
|
|---|
| 1944 | SUB EBX, ECX // (max - ( max - length ) ) = length to copy
|
|---|
| 1945 |
|
|---|
| 1946 | // BX now contains number of chars
|
|---|
| 1947 | // to copy INCLUDING null terminator
|
|---|
| 1948 |
|
|---|
| 1949 | // if reached max chars then
|
|---|
| 1950 | // count will not include zero terminator
|
|---|
| 1951 | CMP ECX, 0
|
|---|
| 1952 | JE !ReachedMaxChars
|
|---|
| 1953 | DEC EBX // Don't want to copy null teriminator
|
|---|
| 1954 | !ReachedMaxChars:
|
|---|
| 1955 |
|
|---|
| 1956 | MOV ECX, EBX // Load count into ecx
|
|---|
| 1957 | Shr ECX, 2 // divide by 4 to find number of dwords to copy
|
|---|
| 1958 | MOV EDI, EDX // load destination into EDI
|
|---|
| 1959 |
|
|---|
| 1960 | REP MOVSD // copy (ECX * 4 bytes) from ESI to EDI
|
|---|
| 1961 | MOV ECX, EBX // get num chars to copy, again
|
|---|
| 1962 | And ECX, 3 // AND with 3 to get remaining bytes to copy
|
|---|
| 1963 | REP MOVSB // Copy remaining bytes
|
|---|
| 1964 |
|
|---|
| 1965 | STOSB // zero terminate result
|
|---|
| 1966 | Dec EDI
|
|---|
| 1967 |
|
|---|
| 1968 | !Out!StringCopy:
|
|---|
| 1969 | RETN32
|
|---|
| 1970 |
|
|---|
| 1971 | SysUtils.!StringCopy ENDP
|
|---|
| 1972 |
|
|---|
| 1973 | // This Function Compares A maximum Number Of characters
|
|---|
| 1974 | // this IS case SENSITIVE.
|
|---|
| 1975 |
|
|---|
| 1976 | SysUtils.!StringCompare Proc NEAR32
|
|---|
| 1977 |
|
|---|
| 1978 | REPE CMPSB
|
|---|
| 1979 | Xor EAX, EAX
|
|---|
| 1980 | MOV AL, [ESI - 1]
|
|---|
| 1981 | MOV BL, [EDI - 1]
|
|---|
| 1982 | SUB EAX, EBX
|
|---|
| 1983 | RETN32
|
|---|
| 1984 |
|
|---|
| 1985 | SysUtils.!StringCompare ENDP
|
|---|
| 1986 |
|
|---|
| 1987 | // Compare a maximum number of characters,
|
|---|
| 1988 | // ignoring case
|
|---|
| 1989 | SysUtils.!StringICompare Proc NEAR32
|
|---|
| 1990 |
|
|---|
| 1991 | Xor EAX, EAX;
|
|---|
| 1992 |
|
|---|
| 1993 | !Loop!StringICompare:
|
|---|
| 1994 |
|
|---|
| 1995 | REPE CMPSB
|
|---|
| 1996 | JE !Out!StringICompare
|
|---|
| 1997 |
|
|---|
| 1998 | Xor EBX, EBX
|
|---|
| 1999 | MOV BL, [ESI - 1]
|
|---|
| 2000 | CMP BL, 'A'
|
|---|
| 2001 | JL !UpcaseSecondChar!StringICompare
|
|---|
| 2002 | CMP BL, 'Z'
|
|---|
| 2003 | JG !UpcaseSecondChar!StringICompare
|
|---|
| 2004 | Or BL, 32
|
|---|
| 2005 |
|
|---|
| 2006 | !UpcaseSecondChar!StringICompare:
|
|---|
| 2007 |
|
|---|
| 2008 | Xor EDX, EDX
|
|---|
| 2009 | MOV DL, [EDI - 1]
|
|---|
| 2010 | CMP DL, 'A'
|
|---|
| 2011 | JL !CompareSingleChar!StringICompare
|
|---|
| 2012 | CMP DL, 'Z'
|
|---|
| 2013 | JG !CompareSingleChar!StringICompare
|
|---|
| 2014 | Or DL, 32
|
|---|
| 2015 |
|
|---|
| 2016 | !CompareSingleChar!StringICompare:
|
|---|
| 2017 |
|
|---|
| 2018 | SUB EBX, EDX
|
|---|
| 2019 | JE !Loop!StringICompare
|
|---|
| 2020 | MOV EAX, EBX
|
|---|
| 2021 |
|
|---|
| 2022 | !Out!StringICompare:
|
|---|
| 2023 |
|
|---|
| 2024 | RETN32
|
|---|
| 2025 |
|
|---|
| 2026 | SysUtils.!StringICompare ENDP
|
|---|
| 2027 |
|
|---|
| 2028 | // Compares two zero terminated strings, case insensitively
|
|---|
| 2029 | // ESI : Str1
|
|---|
| 2030 | // EDI : Str2
|
|---|
| 2031 | // Returns in EAX: 0 : strings equal
|
|---|
| 2032 | // <0 : str1 > str2
|
|---|
| 2033 | // >0 : str2 > str1
|
|---|
| 2034 |
|
|---|
| 2035 | SysUtils.!ZeroTerminatedStringICompare Proc NEAR32
|
|---|
| 2036 |
|
|---|
| 2037 | Xor EAX, EAX; // set result (EAX) to 0 i.e. match
|
|---|
| 2038 |
|
|---|
| 2039 | !Loop!StringICompare:
|
|---|
| 2040 |
|
|---|
| 2041 | Xor EBX, EBX // Set EBX to 0
|
|---|
| 2042 | MOV BL, [ESI] // load char out of str1 into BL
|
|---|
| 2043 |
|
|---|
| 2044 | Xor EDX, EDX // set EDX to 0
|
|---|
| 2045 | MOV DL, [EDI] // load char out of str2 into DL
|
|---|
| 2046 | CMP EDX, 0
|
|---|
| 2047 | jne !Str2NotTerminated!StringICompare // str2 not ended
|
|---|
| 2048 | // str2 has ended.
|
|---|
| 2049 | CMP EBX, 0 // Has str1 also ended?
|
|---|
| 2050 | je !Out!StringICompare // Yes, strings are equal
|
|---|
| 2051 | // no, str1 is continuing,
|
|---|
| 2052 | // so it's "greater"
|
|---|
| 2053 | MOV EAX, $ffffffff // set result = -1
|
|---|
| 2054 | RETN32 // exit
|
|---|
| 2055 |
|
|---|
| 2056 | !Str2NotTerminated!StringICompare: // str2 continues
|
|---|
| 2057 | CMP EBX, 0 // has str2 ended?
|
|---|
| 2058 | jne !Str1NotTerminated!StringICompare
|
|---|
| 2059 | MOV EAX, 1 // set result = 1
|
|---|
| 2060 | RETN32 // exit
|
|---|
| 2061 |
|
|---|
| 2062 | !Str1NotTerminated!StringICompare:
|
|---|
| 2063 | // Neither string has ended
|
|---|
| 2064 | INC esi // increment str1 and str2 pointers
|
|---|
| 2065 | INC edi
|
|---|
| 2066 |
|
|---|
| 2067 | CMP EBX, EDX // char1 = char2?
|
|---|
| 2068 | JE !Loop!StringICompare // yes, continue loop
|
|---|
| 2069 | // no, check case insensitive
|
|---|
| 2070 | // Convert char1 to lowercase, if needed
|
|---|
| 2071 | CMP BL, 'A'
|
|---|
| 2072 | JL !Char1Converted!StringICompare
|
|---|
| 2073 | CMP BL, 'Z'
|
|---|
| 2074 | JG !Char1Converted!StringICompare
|
|---|
| 2075 | Or BL, 32 // change to lower case
|
|---|
| 2076 | !Char1Converted!StringICompare:
|
|---|
| 2077 |
|
|---|
| 2078 | // Convert char2 to lowercase, if needed
|
|---|
| 2079 | CMP DL, 'A'
|
|---|
| 2080 | JL !Char2Converted!StringICompare
|
|---|
| 2081 | CMP DL, 'Z'
|
|---|
| 2082 | JG !Char2Converted!StringICompare
|
|---|
| 2083 | Or DL, 32 // change to lowercase
|
|---|
| 2084 | !Char2Converted!StringICompare:
|
|---|
| 2085 |
|
|---|
| 2086 | SUB EBX, EDX // Subtract char2 from char1
|
|---|
| 2087 | JE !Loop!StringICompare // if chars same, continue loop
|
|---|
| 2088 | MOV EAX, EBX // load difference into EAX
|
|---|
| 2089 |
|
|---|
| 2090 | !Out!StringICompare:
|
|---|
| 2091 |
|
|---|
| 2092 | RETN32
|
|---|
| 2093 |
|
|---|
| 2094 | SysUtils.!ZeroTerminatedStringICompare ENDP
|
|---|
| 2095 |
|
|---|
| 2096 | End;
|
|---|
| 2097 |
|
|---|
| 2098 | { --- Memory management --- }
|
|---|
| 2099 |
|
|---|
| 2100 | Function AllocMem(Size: Cardinal): Pointer;
|
|---|
| 2101 | Begin
|
|---|
| 2102 | GetMem(Result, Size);
|
|---|
| 2103 | FillChar(Result^, Size, 0);
|
|---|
| 2104 | End;
|
|---|
| 2105 |
|
|---|
| 2106 | Function ReAllocMem(P: Pointer; CurSize, NewSize: Cardinal): Pointer;
|
|---|
| 2107 | Var
|
|---|
| 2108 | Q: PByteArray;
|
|---|
| 2109 | Begin
|
|---|
| 2110 | If NewSize <> 0 Then GetMem(Q, NewSize) Else Q := Nil;
|
|---|
| 2111 |
|
|---|
| 2112 | If NewSize > 0 Then
|
|---|
| 2113 | Begin
|
|---|
| 2114 | If NewSize > CurSize Then
|
|---|
| 2115 | Begin
|
|---|
| 2116 | FillChar(Q^[CurSize], NewSize - CurSize, 0);
|
|---|
| 2117 | NewSize := CurSize;
|
|---|
| 2118 | End;
|
|---|
| 2119 | If NewSize <> 0 Then Move(P^, Q^, NewSize);
|
|---|
| 2120 | End;
|
|---|
| 2121 | If CurSize <> 0 Then FreeMem(P, CurSize);
|
|---|
| 2122 | Result := Q;
|
|---|
| 2123 | End;
|
|---|
| 2124 |
|
|---|
| 2125 | { Exit Procedure Handling }
|
|---|
| 2126 |
|
|---|
| 2127 | Type
|
|---|
| 2128 | PExitNode = ^TExitNode;
|
|---|
| 2129 | TExitNode = Record
|
|---|
| 2130 | Next: PExitNode;
|
|---|
| 2131 | Proc: TProcedure;
|
|---|
| 2132 | End;
|
|---|
| 2133 |
|
|---|
| 2134 | Const
|
|---|
| 2135 | ExitChain: PExitNode = Nil;
|
|---|
| 2136 |
|
|---|
| 2137 | Var
|
|---|
| 2138 | SaveExitProc: Pointer;
|
|---|
| 2139 |
|
|---|
| 2140 | Procedure CallExitProcs;
|
|---|
| 2141 | Var
|
|---|
| 2142 | First: PExitNode;
|
|---|
| 2143 | Proc: TProcedure;
|
|---|
| 2144 | Begin
|
|---|
| 2145 | While ExitChain <> Nil Do
|
|---|
| 2146 | Begin
|
|---|
| 2147 | First := ExitChain;
|
|---|
| 2148 | Proc := First^.Proc;
|
|---|
| 2149 | ExitChain := First^.Next;
|
|---|
| 2150 | ExitProc := Nil; { Avoids recursion! }
|
|---|
| 2151 | Dispose(First);
|
|---|
| 2152 | Proc;
|
|---|
| 2153 | End;
|
|---|
| 2154 | ExitProc := SaveExitProc;
|
|---|
| 2155 | End;
|
|---|
| 2156 |
|
|---|
| 2157 | Procedure AddExitProc(Proc: TProcedure);
|
|---|
| 2158 | Var
|
|---|
| 2159 | NewNode: PExitNode;
|
|---|
| 2160 | Begin
|
|---|
| 2161 | If ExitChain = Nil Then SaveExitProc := ExitProc;
|
|---|
| 2162 | New(NewNode);
|
|---|
| 2163 | NewNode^.Next := ExitChain;
|
|---|
| 2164 | NewNode^.Proc := Proc;
|
|---|
| 2165 | ExitChain := NewNode;
|
|---|
| 2166 | ExitProc := @CallExitProcs;
|
|---|
| 2167 | End;
|
|---|
| 2168 |
|
|---|
| 2169 | { --- Pascal String Handling --- }
|
|---|
| 2170 |
|
|---|
| 2171 | Function NewStr(Const S: String): PString;
|
|---|
| 2172 | Begin
|
|---|
| 2173 | If Length(S) = 0 Then Result := NullStr
|
|---|
| 2174 | Else
|
|---|
| 2175 | Begin
|
|---|
| 2176 | GetMem(Result, Length(S) + 1);
|
|---|
| 2177 | Result^ := S;
|
|---|
| 2178 | End;
|
|---|
| 2179 | End;
|
|---|
| 2180 |
|
|---|
| 2181 | Procedure DisposeStr(P: PString);
|
|---|
| 2182 | Begin
|
|---|
| 2183 | If (P <> NullStr) And (P <> Nil) Then FreeMem(P, Length(P^) + 1);
|
|---|
| 2184 | End;
|
|---|
| 2185 |
|
|---|
| 2186 | Procedure AssignStr(Var P: PString; Const S: String);
|
|---|
| 2187 | Begin
|
|---|
| 2188 | DisposeStr(P);
|
|---|
| 2189 | P := NewStr(S);
|
|---|
| 2190 | End;
|
|---|
| 2191 |
|
|---|
| 2192 | Procedure AppendStr(Var Dest: String; Const S: String);
|
|---|
| 2193 | Begin
|
|---|
| 2194 | Insert(S, Dest, Length(Dest) + 1);
|
|---|
| 2195 | End;
|
|---|
| 2196 |
|
|---|
| 2197 | Function uppercase(Const S: String): String;
|
|---|
| 2198 | Var
|
|---|
| 2199 | N, C: Integer;
|
|---|
| 2200 | Begin
|
|---|
| 2201 | Result := S;
|
|---|
| 2202 | For N := 1 To Length(Result) Do
|
|---|
| 2203 | Begin
|
|---|
| 2204 | C := Ord(Result[N]);
|
|---|
| 2205 | If (C >= Ord('a')) And (C <= Ord('z')) Then Result[N] := Chr(C And Not 32);
|
|---|
| 2206 | End;
|
|---|
| 2207 | End;
|
|---|
| 2208 |
|
|---|
| 2209 | Function lowercase(Const S: String): String;
|
|---|
| 2210 | Var
|
|---|
| 2211 | N, C: Integer;
|
|---|
| 2212 | Begin
|
|---|
| 2213 | Result := S;
|
|---|
| 2214 | For N := 1 To Length(Result) Do
|
|---|
| 2215 | Begin
|
|---|
| 2216 | C := Ord(Result[N]);
|
|---|
| 2217 | If (C >= Ord('A')) And (C <= Ord('Z')) Then Result[N] := Chr(C Or 32);
|
|---|
| 2218 | End;
|
|---|
| 2219 | End;
|
|---|
| 2220 |
|
|---|
| 2221 | Function CompareStr(Const s1, s2: String): Integer;
|
|---|
| 2222 | Begin
|
|---|
| 2223 | If s1 <= s2 Then
|
|---|
| 2224 | Begin
|
|---|
| 2225 | If s1 = s2 Then Result := 0 Else Result := -1;
|
|---|
| 2226 | End
|
|---|
| 2227 | Else Result := +1
|
|---|
| 2228 | End;
|
|---|
| 2229 |
|
|---|
| 2230 | Function CompareText(Const s1, s2: String): Integer;
|
|---|
| 2231 | Var
|
|---|
| 2232 | l1, l2, L: Integer;
|
|---|
| 2233 | Begin
|
|---|
| 2234 | l1 := Length(s1);
|
|---|
| 2235 | l2 := Length(s2);
|
|---|
| 2236 | If l1 <= l2 Then L := l1 Else L := l2;
|
|---|
| 2237 | Result := StrLIComp(@s1[1], @s2[1], L);
|
|---|
| 2238 | If Result = 0 Then
|
|---|
| 2239 | Begin
|
|---|
| 2240 | If l1 < l2 Then Result := -1 Else If l1 > l2 Then Result := 1;
|
|---|
| 2241 | End;
|
|---|
| 2242 | End;
|
|---|
| 2243 |
|
|---|
| 2244 | {$IFDEF OS2}
|
|---|
| 2245 | {$IFDEF GUI}
|
|---|
| 2246 | Function AnsiUpperCase(Const S: String): String;
|
|---|
| 2247 | Var
|
|---|
| 2248 | Temp: cstring;
|
|---|
| 2249 | Begin
|
|---|
| 2250 | Temp := S;
|
|---|
| 2251 | WinUpper(AppHandle, 0, 0, Temp);
|
|---|
| 2252 | Result := Temp;
|
|---|
| 2253 | End;
|
|---|
| 2254 | {$ELSE GUI}
|
|---|
| 2255 | Function AnsiUpperCase(Const S: String): String;
|
|---|
| 2256 | Var
|
|---|
| 2257 | cc: COUNTRYCODE;
|
|---|
| 2258 | Begin
|
|---|
| 2259 | Result := S;
|
|---|
| 2260 | cc.country := 0;
|
|---|
| 2261 | cc.codepage := 0;
|
|---|
| 2262 | DosMapCase(Length(Result), cc, Result[1]);
|
|---|
| 2263 | End;
|
|---|
| 2264 | {$ENDIF GUI}
|
|---|
| 2265 | {$ENDIF OS2}
|
|---|
| 2266 |
|
|---|
| 2267 | {$IFDEF Win95}
|
|---|
| 2268 | Function AnsiUpperCase(Const S: String): String;
|
|---|
| 2269 | Var
|
|---|
| 2270 | s1: cstring;
|
|---|
| 2271 | Begin
|
|---|
| 2272 | s1 := S;
|
|---|
| 2273 | AnsiUpperBuff(s1, Length(s));
|
|---|
| 2274 | AnsiUpperCase:=s1;
|
|---|
| 2275 | End;
|
|---|
| 2276 | {$ENDIF Win95}
|
|---|
| 2277 |
|
|---|
| 2278 | {$IFDEF Win95}
|
|---|
| 2279 | Function AnsiLowerCase(Const S: String): String;
|
|---|
| 2280 | Var
|
|---|
| 2281 | s1: cstring;
|
|---|
| 2282 | Begin
|
|---|
| 2283 | s1 := S;
|
|---|
| 2284 | AnsiLowerBuff(s1, Length(s));
|
|---|
| 2285 | Result := s1;
|
|---|
| 2286 | End;
|
|---|
| 2287 | {$ENDIF Win95}
|
|---|
| 2288 |
|
|---|
| 2289 | {$IFDEF OS2}
|
|---|
| 2290 | {$IFDEF GUI}
|
|---|
| 2291 | Function AnsiCompareText(Const s1, s2: String): Integer;
|
|---|
| 2292 | Var
|
|---|
| 2293 | Temp1, Temp2: cstring[256];
|
|---|
| 2294 | Begin
|
|---|
| 2295 | Temp1 := s1;
|
|---|
| 2296 | Temp2 := s2;
|
|---|
| 2297 | Case WinCompareStrings(AppHandle, 0, 0, Temp1, Temp2, 0) Of
|
|---|
| 2298 | WCS_LT: Result := -1;
|
|---|
| 2299 | WCS_EQ: Result := 0;
|
|---|
| 2300 | WCS_GT: Result := 1;
|
|---|
| 2301 | End;
|
|---|
| 2302 | End;
|
|---|
| 2303 | {$ELSE GUI}
|
|---|
| 2304 | Function AnsiCompareText(Const s1, s2: String): Integer;
|
|---|
| 2305 | Var
|
|---|
| 2306 | N, l1, l2: Integer;
|
|---|
| 2307 | Begin
|
|---|
| 2308 | N := 1;
|
|---|
| 2309 | l1 := Length(s1);
|
|---|
| 2310 | l2 := Length(s2);
|
|---|
| 2311 | While (N <= l1) And (N <= l2)
|
|---|
| 2312 | And (CollatingSequence[s1[N]] = CollatingSequence[s2[N]]) Do Inc(N);
|
|---|
| 2313 |
|
|---|
| 2314 | If (N <= l1) And (N <= l2) Then
|
|---|
| 2315 | Begin
|
|---|
| 2316 | If CollatingSequence[s1[N]] < CollatingSequence[s2[N]] Then Result := -1
|
|---|
| 2317 | Else If CollatingSequence[s1[N]] > CollatingSequence[s2[N]] Then Result := 1
|
|---|
| 2318 | Else Result := 0;
|
|---|
| 2319 | End
|
|---|
| 2320 | Else
|
|---|
| 2321 | Begin
|
|---|
| 2322 | If l1 < l2 Then Result := -1
|
|---|
| 2323 | Else If l1 > l2 Then Result := 1
|
|---|
| 2324 | Else Result := 0;
|
|---|
| 2325 | End;
|
|---|
| 2326 | End;
|
|---|
| 2327 | {$ENDIF GUI}
|
|---|
| 2328 | {$ENDIF OS2}
|
|---|
| 2329 |
|
|---|
| 2330 | {$IFDEF Win95}
|
|---|
| 2331 | Function AnsiCompareText(Const s1, s2: String): Integer;
|
|---|
| 2332 | Var
|
|---|
| 2333 | Temp1, Temp2: Array[0..255] Of Char;
|
|---|
| 2334 | Begin
|
|---|
| 2335 | AnsiCompareText:=lstrcmpi(StrPCopy(Temp1,s1)^,
|
|---|
| 2336 | StrPCopy(Temp2,s2)^);
|
|---|
| 2337 | End;
|
|---|
| 2338 | {$ENDIF Win95}
|
|---|
| 2339 |
|
|---|
| 2340 | {$IFDEF Win95}
|
|---|
| 2341 | Function AnsiCompareStr(Const s1, s2: String): Integer;
|
|---|
| 2342 | Var
|
|---|
| 2343 | Temp1, Temp2: Array[0..255] Of Char;
|
|---|
| 2344 | Begin
|
|---|
| 2345 | Result := lstrcmp(StrPCopy(Temp1,s1)^, StrPCopy(Temp2,s2)^);
|
|---|
| 2346 | End;
|
|---|
| 2347 | {$ENDIF Win95}
|
|---|
| 2348 |
|
|---|
| 2349 | Function IsValidIdent(Const Ident: String): Boolean;
|
|---|
| 2350 | Var
|
|---|
| 2351 | L, N: Integer;
|
|---|
| 2352 | Begin
|
|---|
| 2353 | L := Length(Ident);
|
|---|
| 2354 | If L = 0 Then IsValidIdent := False
|
|---|
| 2355 | Else
|
|---|
| 2356 | Begin
|
|---|
| 2357 | If Ident[1] In ['a'..'z', 'A'..'Z', '_'] Then
|
|---|
| 2358 | Begin
|
|---|
| 2359 | N := 2;
|
|---|
| 2360 | While (N <= L) And (Ident[N] In ['a'..'z', 'A'..'Z', '_', '0'..'9']) Do Inc(N);
|
|---|
| 2361 | If N > L Then IsValidIdent := True
|
|---|
| 2362 | Else IsValidIdent := False;
|
|---|
| 2363 | End
|
|---|
| 2364 | Else IsValidIdent := False;
|
|---|
| 2365 | End;
|
|---|
| 2366 | End;
|
|---|
| 2367 |
|
|---|
| 2368 | Function IntToStr(Value: LongInt): String;
|
|---|
| 2369 | Begin
|
|---|
| 2370 | Str(Value, Result);
|
|---|
| 2371 | End;
|
|---|
| 2372 |
|
|---|
| 2373 | Function IntToHex(Value: LongInt; Digits: Integer): String;
|
|---|
| 2374 | Begin
|
|---|
| 2375 | Result := '';
|
|---|
| 2376 | Repeat
|
|---|
| 2377 | Dec(Digits);
|
|---|
| 2378 | Result := Hexadecimals[Value And $0F] + Result;
|
|---|
| 2379 | Value := Value Shr 4;
|
|---|
| 2380 | Until Value = 0;
|
|---|
| 2381 | If Digits > 0 Then
|
|---|
| 2382 | Begin
|
|---|
| 2383 | Move(Result[1], Result[1 + Digits], Byte(Result[0]));
|
|---|
| 2384 | FillChar(Result[1], Digits, '0');
|
|---|
| 2385 | Inc(Byte(Result[0]), Digits);
|
|---|
| 2386 | End;
|
|---|
| 2387 | End;
|
|---|
| 2388 |
|
|---|
| 2389 | Function StrToInt(Const S: String): LongInt;
|
|---|
| 2390 | Var
|
|---|
| 2391 | err: Integer;
|
|---|
| 2392 | Begin
|
|---|
| 2393 | Val(S, Result, err);
|
|---|
| 2394 | If err <> 0 Then FmtLoadConvertError(SInvalidInteger, [S]);
|
|---|
| 2395 | End;
|
|---|
| 2396 |
|
|---|
| 2397 | Function StrToIntDef(Const S: String; Default: LongInt): LongInt;
|
|---|
| 2398 | Var
|
|---|
| 2399 | err: Integer;
|
|---|
| 2400 | Begin
|
|---|
| 2401 | Val(S, Result, err);
|
|---|
| 2402 | If err <> 0 Then Result := Default;
|
|---|
| 2403 | End;
|
|---|
| 2404 |
|
|---|
| 2405 | {$IFDEF OS2}
|
|---|
| 2406 | Function LoadStr(Ident: Word): String;
|
|---|
| 2407 | Var
|
|---|
| 2408 | Buffer: cstring;
|
|---|
| 2409 | Begin
|
|---|
| 2410 | {$IFDEF GUI}
|
|---|
| 2411 | WinLoadString(AppHandle, 0, Ident, 256, Buffer);
|
|---|
| 2412 | Result := Buffer;
|
|---|
| 2413 | {$ELSE}
|
|---|
| 2414 | Result := 'SysUtils Msg #' + IntToStr(Ident);
|
|---|
| 2415 | {$ENDIF GUI}
|
|---|
| 2416 | End;
|
|---|
| 2417 |
|
|---|
| 2418 | Function FmtLoadStr(Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 2419 | Begin
|
|---|
| 2420 | FmtStr(Result, LoadStr(Ident), Args);
|
|---|
| 2421 | End;
|
|---|
| 2422 | {$ENDIF OS2}
|
|---|
| 2423 |
|
|---|
| 2424 | Function LoadTableStr(Const Table:String;Ident: Word): String;
|
|---|
| 2425 | Begin
|
|---|
| 2426 | Result:=GetStringTableEntry(Table,Ident);
|
|---|
| 2427 | End;
|
|---|
| 2428 |
|
|---|
| 2429 | Function LoadNLSStr(Ident: Word): String;
|
|---|
| 2430 | Begin
|
|---|
| 2431 | Result:=GetStringTableEntry(CurrentLanguageTable,Ident);
|
|---|
| 2432 | //If the above failed, Try To Load from Default Table...
|
|---|
| 2433 | If Result='' Then Result:=GetStringTableEntry('SIBYL_NLS_Default',Ident);
|
|---|
| 2434 | End;
|
|---|
| 2435 |
|
|---|
| 2436 | Function FmtLoadTableStr(Const Table:String;Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 2437 | Begin
|
|---|
| 2438 | FmtStr(Result, LoadTableStr(Table,Ident), Args);
|
|---|
| 2439 | End;
|
|---|
| 2440 |
|
|---|
| 2441 | Function FmtLoadNLSStr(Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 2442 | Begin
|
|---|
| 2443 | FmtStr(Result, LoadNLSStr(Ident), Args);
|
|---|
| 2444 | End;
|
|---|
| 2445 |
|
|---|
| 2446 | {$IFDEF Win95}
|
|---|
| 2447 | Function LoadStr(Ident: Word): String;
|
|---|
| 2448 | Begin
|
|---|
| 2449 | Result[0] := Char(LoadString(DllModule,Ident,cstring(Result[1]),254));
|
|---|
| 2450 | End;
|
|---|
| 2451 |
|
|---|
| 2452 | Function FmtLoadStr(Ident: Word; Const Args: Array Of Const): String;
|
|---|
| 2453 | Begin
|
|---|
| 2454 | FmtStr(Result, LoadStr(Ident), Args);
|
|---|
| 2455 | End;
|
|---|
| 2456 | {$ENDIF}
|
|---|
| 2457 |
|
|---|
| 2458 | {$IFDEF OS2}
|
|---|
| 2459 | Function SysErrorMessage(MsgNum: LongInt): String;
|
|---|
| 2460 | Begin
|
|---|
| 2461 | Result := System.SysErrorMessage( MsgNum );
|
|---|
| 2462 | End;
|
|---|
| 2463 | {$ENDIF}
|
|---|
| 2464 |
|
|---|
| 2465 | {
|
|---|
| 2466 | Procedure SetLength(Var S: String; NewLength: Byte);
|
|---|
| 2467 | Begin
|
|---|
| 2468 | Byte(S[0]) := NewLength;
|
|---|
| 2469 | End;
|
|---|
| 2470 | }
|
|---|
| 2471 |
|
|---|
| 2472 | Function Trim(Const S: String): String;
|
|---|
| 2473 | Var
|
|---|
| 2474 | L, R: Integer;
|
|---|
| 2475 | Begin
|
|---|
| 2476 | R := Length(S);
|
|---|
| 2477 | While (R > 0) And (S[R] <= ' ') Do Dec(R);
|
|---|
| 2478 | L := 1;
|
|---|
| 2479 | While (L <= R) And (S[L] <= ' ') Do Inc(L);
|
|---|
| 2480 | Result := Copy(S, L, R - L + 1);
|
|---|
| 2481 | End;
|
|---|
| 2482 |
|
|---|
| 2483 | Function TrimLeft(Const S: String): String;
|
|---|
| 2484 | Var
|
|---|
| 2485 | L, R: Integer;
|
|---|
| 2486 | Begin
|
|---|
| 2487 | R := Length(S);
|
|---|
| 2488 | L := 1;
|
|---|
| 2489 | While (L <= R) And (S[L] <= ' ') Do Inc(L);
|
|---|
| 2490 | Result := Copy(S, L, R - L + 1);
|
|---|
| 2491 | End;
|
|---|
| 2492 |
|
|---|
| 2493 | Function TrimRight(Const S: String): String;
|
|---|
| 2494 | Var
|
|---|
| 2495 | R: Integer;
|
|---|
| 2496 | Begin
|
|---|
| 2497 | R := Length(S);
|
|---|
| 2498 | While (R > 0) And (S[R] <= ' ') Do Dec(R);
|
|---|
| 2499 | Result := Copy(S, 1, R);
|
|---|
| 2500 | End;
|
|---|
| 2501 |
|
|---|
| 2502 | Function QuotedStr(Const S: String): String;
|
|---|
| 2503 | Var
|
|---|
| 2504 | N: Integer;
|
|---|
| 2505 | Begin
|
|---|
| 2506 | Result := #39;
|
|---|
| 2507 | For N := 1 To Length(S) Do
|
|---|
| 2508 | Begin
|
|---|
| 2509 | Result := Result + S[N];
|
|---|
| 2510 | If S[N] = #39 Then Result := Result + #39;
|
|---|
| 2511 | End;
|
|---|
| 2512 | Result := Result + #39;
|
|---|
| 2513 | End;
|
|---|
| 2514 |
|
|---|
| 2515 | { --- File management --- }
|
|---|
| 2516 |
|
|---|
| 2517 | Function FileOpen(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 2518 | {$IFDEF OS2}
|
|---|
| 2519 | Const
|
|---|
| 2520 | Action = OPEN_ACTION_OPEN_IF_EXISTS Or OPEN_ACTION_FAIL_IF_NEW;
|
|---|
| 2521 | Var
|
|---|
| 2522 | ActionTaken, Handle: LongWord;
|
|---|
| 2523 | {$ENDIF}
|
|---|
| 2524 | {$IFDEF Win95}
|
|---|
| 2525 | Const
|
|---|
| 2526 | Action = OPEN_EXISTING;
|
|---|
| 2527 | VAR SA:SECURITY_ATTRIBUTES;
|
|---|
| 2528 | {$ENDIF}
|
|---|
| 2529 | Var
|
|---|
| 2530 | FileNameZ: cstring[256];
|
|---|
| 2531 | Begin
|
|---|
| 2532 | FileNameZ := FileName;
|
|---|
| 2533 | If Mode And ShareModes = 0 Then Mode := Mode Or fmShareDenyNone;
|
|---|
| 2534 | {$IFDEF OS2}
|
|---|
| 2535 | Result := - DosOpen(FileNameZ, Handle, ActionTaken, 0, 0, Action, Mode, Nil);
|
|---|
| 2536 | If Result = NO_ERROR Then Result := Handle;
|
|---|
| 2537 | {$ENDIF}
|
|---|
| 2538 | {$IFDEF Win95}
|
|---|
| 2539 | SA.nLength:=sizeof(SA);
|
|---|
| 2540 | SA.lpSecurityDescriptor:=Nil;
|
|---|
| 2541 | SA.bInheritHandle:=True;
|
|---|
| 2542 | Result:=CreateFile(FileNameZ,Mode And Not 3,Mode And 3,SA,Action,
|
|---|
| 2543 | FILE_ATTRIBUTE_NORMAL,0);
|
|---|
| 2544 | {$ENDIF}
|
|---|
| 2545 | End;
|
|---|
| 2546 |
|
|---|
| 2547 | Function FileOpenOrCreate(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 2548 | {$IFDEF OS2}
|
|---|
| 2549 | Const
|
|---|
| 2550 | Action = OPEN_ACTION_OPEN_IF_EXISTS Or OPEN_ACTION_CREATE_IF_NEW;
|
|---|
| 2551 | Var
|
|---|
| 2552 | ActionTaken, Handle: LongWord;
|
|---|
| 2553 | {$ENDIF}
|
|---|
| 2554 | {$IFDEF Win95}
|
|---|
| 2555 | Const
|
|---|
| 2556 | Action = OPEN_ALWAYS;
|
|---|
| 2557 | Var SA:SECURITY_ATTRIBUTES;
|
|---|
| 2558 | {$ENDIF}
|
|---|
| 2559 | Var
|
|---|
| 2560 | FileNameZ: cstring[256];
|
|---|
| 2561 | Begin
|
|---|
| 2562 | FileNameZ := FileName;
|
|---|
| 2563 | If Mode And ShareModes = 0 Then Mode := Mode Or fmShareDenyNone;
|
|---|
| 2564 | {$IFDEF OS2}
|
|---|
| 2565 | Result := - DosOpen(FileNameZ, Handle, ActionTaken, 0, 0, Action, Mode, Nil);
|
|---|
| 2566 | If Result = NO_ERROR Then Result := Handle;
|
|---|
| 2567 | {$ENDIF}
|
|---|
| 2568 | {$IFDEF Win95}
|
|---|
| 2569 | SA.nLength:=sizeof(SA);
|
|---|
| 2570 | SA.lpSecurityDescriptor:=Nil;
|
|---|
| 2571 | SA.bInheritHandle:=True;
|
|---|
| 2572 | Result:=CreateFile(FileNameZ,Mode And Not 3,Mode And 3,SA,Action,
|
|---|
| 2573 | FILE_ATTRIBUTE_NORMAL,0);
|
|---|
| 2574 | {$ENDIF}
|
|---|
| 2575 | End;
|
|---|
| 2576 |
|
|---|
| 2577 | Function FileCreateIfNew(Const FileName: String; Mode: Word): LongInt;
|
|---|
| 2578 | {$IFDEF OS2}
|
|---|
| 2579 | Const
|
|---|
| 2580 | Action = OPEN_ACTION_FAIL_IF_EXISTS Or OPEN_ACTION_CREATE_IF_NEW;
|
|---|
| 2581 | Var
|
|---|
| 2582 | ActionTaken, Handle: LongWord;
|
|---|
| 2583 | {$ENDIF}
|
|---|
| 2584 | {$IFDEF Win95}
|
|---|
| 2585 | Const
|
|---|
| 2586 | Action = CREATE_NEW;
|
|---|
| 2587 | Var SA:SECURITY_ATTRIBUTES;
|
|---|
| 2588 | {$ENDIF}
|
|---|
| 2589 | Var
|
|---|
| 2590 | FileNameZ: cstring[256];
|
|---|
| 2591 | Begin
|
|---|
| 2592 | FileNameZ := FileName;
|
|---|
| 2593 | If Mode And ShareModes = 0 Then Mode := Mode Or fmShareDenyNone;
|
|---|
| 2594 | {$IFDEF OS2}
|
|---|
| 2595 | Result := - DosOpen(FileNameZ, Handle, ActionTaken, 0, 0, Action, Mode, Nil);
|
|---|
| 2596 | If Result = NO_ERROR Then Result := Handle;
|
|---|
| 2597 | {$ENDIF}
|
|---|
| 2598 | {$IFDEF Win95}
|
|---|
| 2599 | SA.nLength:=sizeof(SA);
|
|---|
| 2600 | SA.lpSecurityDescriptor:=Nil;
|
|---|
| 2601 | SA.bInheritHandle:=True;
|
|---|
| 2602 | Result:=CreateFile(FileNameZ,Mode And Not 3,Mode And 3,SA,Action,
|
|---|
| 2603 | FILE_ATTRIBUTE_NORMAL,0);
|
|---|
| 2604 | {$ENDIF}
|
|---|
| 2605 | End;
|
|---|
| 2606 |
|
|---|
| 2607 | Function FileCreate(Const FileName: String): LongInt;
|
|---|
| 2608 | {$IFDEF OS2}
|
|---|
| 2609 | Const
|
|---|
| 2610 | Action = OPEN_ACTION_REPLACE_IF_EXISTS Or OPEN_ACTION_CREATE_IF_NEW;
|
|---|
| 2611 | Var
|
|---|
| 2612 | ActionTaken, Handle: LongWord;
|
|---|
| 2613 | {$ENDIF}
|
|---|
| 2614 | {$IFDEF Win95}
|
|---|
| 2615 | Const
|
|---|
| 2616 | Action = CREATE_ALWAYS;
|
|---|
| 2617 | Var SA:SECURITY_ATTRIBUTES;
|
|---|
| 2618 | {$ENDIF}
|
|---|
| 2619 | Const
|
|---|
| 2620 | Mode = fmOpenReadWrite Or fmShareExclusive;
|
|---|
| 2621 | Var
|
|---|
| 2622 | FileNameZ: cstring[256];
|
|---|
| 2623 | Begin
|
|---|
| 2624 | FileNameZ := FileName;
|
|---|
| 2625 | {$IFDEF OS2}
|
|---|
| 2626 | Result := - DosOpen(FileNameZ, Handle, ActionTaken, 0, 0, Action, Mode, Nil);
|
|---|
| 2627 | If Result = NO_ERROR Then Result := Handle;
|
|---|
| 2628 | {$ENDIF}
|
|---|
| 2629 | {$IFDEF Win95}
|
|---|
| 2630 | SA.nLength:=sizeof(SA);
|
|---|
| 2631 | SA.lpSecurityDescriptor:=Nil;
|
|---|
| 2632 | SA.bInheritHandle:=True;
|
|---|
| 2633 | Result:=CreateFile(FileNameZ,Mode And Not 3,Mode And 3,SA,Action,
|
|---|
| 2634 | FILE_ATTRIBUTE_NORMAL,0);
|
|---|
| 2635 | {$ENDIF}
|
|---|
| 2636 | End;
|
|---|
| 2637 |
|
|---|
| 2638 | Function FileRead(Handle: LongInt; Var Buffer; Count: LongInt): LongInt;
|
|---|
| 2639 | Var
|
|---|
| 2640 | Result: LongWord;
|
|---|
| 2641 | Begin
|
|---|
| 2642 | {$IFDEF OS2}
|
|---|
| 2643 | If DosRead(Handle, Buffer, Count, Result) = NO_ERROR Then FileRead := Result
|
|---|
| 2644 | Else FileRead := -1;
|
|---|
| 2645 | {$ENDIF}
|
|---|
| 2646 | {$IFDEF Win95}
|
|---|
| 2647 | If ReadFile(Handle,Buffer,Count,Result,Nil) Then FileRead := Result
|
|---|
| 2648 | Else FileRead := -1;
|
|---|
| 2649 | {$ENDIF}
|
|---|
| 2650 | End;
|
|---|
| 2651 |
|
|---|
| 2652 | Function FileWrite(Handle: LongInt; Const Buffer; Count: LongInt): LongInt;
|
|---|
| 2653 | Var
|
|---|
| 2654 | Result:LongWord;
|
|---|
| 2655 | Begin
|
|---|
| 2656 | {$IFDEF OS2}
|
|---|
| 2657 | If DosWrite(Handle, Buffer, Count, Result) = NO_ERROR Then FileWrite := Result
|
|---|
| 2658 | Else FileWrite := -1;
|
|---|
| 2659 | {$ENDIF}
|
|---|
| 2660 | {$IFDEF Win95}
|
|---|
| 2661 | If Not WriteFile(Handle,Buffer,Count,Result,Nil) Then Result := -1
|
|---|
| 2662 | Else FileWrite := Result;
|
|---|
| 2663 | {$ENDIF}
|
|---|
| 2664 | End;
|
|---|
| 2665 |
|
|---|
| 2666 | Function FileSeek(Handle: LongInt; Offset: LongInt; Origin: Integer): LongInt;
|
|---|
| 2667 | {$IFDEF OS2}
|
|---|
| 2668 | Var
|
|---|
| 2669 | NewPos: LongWord;
|
|---|
| 2670 | {$ENDIF}
|
|---|
| 2671 | Begin
|
|---|
| 2672 | {$IFDEF OS2}
|
|---|
| 2673 | If DosSetFilePtr(Handle, Offset, Origin, NewPos) = NO_ERROR Then FileSeek := NewPos
|
|---|
| 2674 | Else FileSeek := -1;
|
|---|
| 2675 | {$ENDIF}
|
|---|
| 2676 | {$IFDEF Win95}
|
|---|
| 2677 | Result:=SetFilePointer(Handle,Offset,Nil,Origin);
|
|---|
| 2678 | {$ENDIF}
|
|---|
| 2679 | End;
|
|---|
| 2680 |
|
|---|
| 2681 | Procedure FileClose(Handle: LongInt);
|
|---|
| 2682 | Begin
|
|---|
| 2683 | {$IFDEF OS2}
|
|---|
| 2684 | DosClose(Handle);
|
|---|
| 2685 | {$ENDIF}
|
|---|
| 2686 | {$IFDEF Win95}
|
|---|
| 2687 | CloseHandle(Handle);
|
|---|
| 2688 | {$ENDIF}
|
|---|
| 2689 | End;
|
|---|
| 2690 |
|
|---|
| 2691 | Function FileLock(Handle, Offset, Range: LongInt): Boolean;
|
|---|
| 2692 | {$IFDEF OS2}
|
|---|
| 2693 | Var
|
|---|
| 2694 | Lock, UnLock: BseDos.FileLock;
|
|---|
| 2695 | {$ENDIF}
|
|---|
| 2696 | Begin
|
|---|
| 2697 | {$IFDEF OS2}
|
|---|
| 2698 | Lock.LOffset := Offset;
|
|---|
| 2699 | Lock.LRange := Range;
|
|---|
| 2700 | UnLock.LOffset := 0;
|
|---|
| 2701 | UnLock.LRange := 0;
|
|---|
| 2702 | Result := (DosSetFileLocks(Handle, UnLock, Lock, LockTimeout, 0) = NO_ERROR);
|
|---|
| 2703 | {$ENDIF}
|
|---|
| 2704 | {$IFDEF Win95}
|
|---|
| 2705 | Result := LockFile(Handle,Offset,0,Range,0);
|
|---|
| 2706 | {$ENDIF}
|
|---|
| 2707 | End;
|
|---|
| 2708 |
|
|---|
| 2709 | Function FileUnLock(Handle, Offset, Range: LongInt): Boolean;
|
|---|
| 2710 | {$IFDEF OS2}
|
|---|
| 2711 | Var
|
|---|
| 2712 | Lock, UnLock: BseDos.FileLock;
|
|---|
| 2713 | {$ENDIF}
|
|---|
| 2714 | Begin
|
|---|
| 2715 | {$IFDEF OS2}
|
|---|
| 2716 | UnLock.LOffset := Offset;
|
|---|
| 2717 | UnLock.LRange := Range;
|
|---|
| 2718 | Lock.LOffset := 0;
|
|---|
| 2719 | Lock.LRange := 0;
|
|---|
| 2720 | Result := (DosSetFileLocks(Handle, UnLock, Lock, LockTimeout, 0) = NO_ERROR);
|
|---|
| 2721 | {$ENDIF}
|
|---|
| 2722 | {$IFDEF Win95}
|
|---|
| 2723 | Result := UnlockFile(Handle,Offset,0,Range,0);
|
|---|
| 2724 | {$ENDIF}
|
|---|
| 2725 | End;
|
|---|
| 2726 |
|
|---|
| 2727 | Function FileAge(Const FileName: String): LongInt;
|
|---|
| 2728 | Var
|
|---|
| 2729 | FileNameZ: cstring;
|
|---|
| 2730 | {$IFDEF OS2}
|
|---|
| 2731 | Buffer: FILESTATUS3;
|
|---|
| 2732 | {$ENDIF}
|
|---|
| 2733 | {$IFDEF Win95}
|
|---|
| 2734 | Handle:LongWord;
|
|---|
| 2735 | LastAccess,creation,LastWrite,actual:FILETIME;
|
|---|
| 2736 | date,Time:Word;
|
|---|
| 2737 | {$ENDIF}
|
|---|
| 2738 | Begin
|
|---|
| 2739 | FileNameZ := FileName;
|
|---|
| 2740 | {$IFDEF OS2}
|
|---|
| 2741 | If DosQueryPathInfo(FileNameZ, FIL_STANDARD, Buffer, SizeOf(Buffer)) = NO_ERROR Then
|
|---|
| 2742 | FileAge := (Buffer.fdateLastWrite Shl 16) Or Buffer.ftimeLastWrite
|
|---|
| 2743 | Else FileAge := -1;
|
|---|
| 2744 | {$ENDIF}
|
|---|
| 2745 | {$IFDEF Win95}
|
|---|
| 2746 | Handle:=CreateFile(FileNameZ,GENERIC_READ,0,Nil,OPEN_EXISTING,
|
|---|
| 2747 | FILE_ATTRIBUTE_NORMAL,0);
|
|---|
| 2748 | If Handle=-1 Then
|
|---|
| 2749 | Begin
|
|---|
| 2750 | FileAge:=-1;
|
|---|
| 2751 | Exit;
|
|---|
| 2752 | End;
|
|---|
| 2753 | If Not GetFileTime(Handle,creation,LastAccess,LastWrite) Then
|
|---|
| 2754 | Begin
|
|---|
| 2755 | CloseHandle(Handle);
|
|---|
| 2756 | FileAge:=-1;
|
|---|
| 2757 | Exit;
|
|---|
| 2758 | End;
|
|---|
| 2759 | CloseHandle(Handle);
|
|---|
| 2760 | FileTimeToLocalFileTime(LastWrite,actual);
|
|---|
| 2761 | FileTimeToDosDateTime(actual,date,Time);
|
|---|
| 2762 | FileAge := (date Shl 16) Or Time;
|
|---|
| 2763 | {$ENDIF}
|
|---|
| 2764 | End;
|
|---|
| 2765 |
|
|---|
| 2766 | Function FileExists(Const FileName: String): Boolean;
|
|---|
| 2767 | Var
|
|---|
| 2768 | SearchRec: TSearchRec;
|
|---|
| 2769 | Begin
|
|---|
| 2770 | If FindFirst(FileName, faAnyFile, SearchRec) = 0 Then
|
|---|
| 2771 | Begin
|
|---|
| 2772 | FileExists := True;
|
|---|
| 2773 | FindClose(SearchRec);
|
|---|
| 2774 | End
|
|---|
| 2775 | Else FileExists := False;
|
|---|
| 2776 | End;
|
|---|
| 2777 |
|
|---|
| 2778 | Function FindFirst(Const Path: String; Attr: Integer; Var SearchRec: TSearchRec): LongInt;
|
|---|
| 2779 | {$IFDEF OS2}
|
|---|
| 2780 | Var
|
|---|
| 2781 | OS2SearchRec: FILEFINDBUF3;
|
|---|
| 2782 | Result, Count: LongWord;
|
|---|
| 2783 | Const
|
|---|
| 2784 | Size = SizeOf(OS2SearchRec);
|
|---|
| 2785 | {$ENDIF}
|
|---|
| 2786 | {$IFDEF WIN32}
|
|---|
| 2787 | Var Actual:FILETIME;
|
|---|
| 2788 | date,time:word;
|
|---|
| 2789 | {$ENDIF}
|
|---|
| 2790 | Var
|
|---|
| 2791 | PathZ: cstring;
|
|---|
| 2792 | Begin
|
|---|
| 2793 | PathZ := Path;
|
|---|
| 2794 | {$IFDEF OS2}
|
|---|
| 2795 | SearchRec.HDir := HDIR_CREATE;
|
|---|
| 2796 | Count := 1;
|
|---|
| 2797 | Result := DosFindFirst(PathZ, SearchRec.HDir, Attr, OS2SearchRec, Size, Count, FIL_STANDARD);
|
|---|
| 2798 | If Result = NO_ERROR Then
|
|---|
| 2799 | Begin
|
|---|
| 2800 | With OS2SearchRec Do
|
|---|
| 2801 | Begin
|
|---|
| 2802 | SearchRec.Name := achName;
|
|---|
| 2803 | SearchRec.Size := cbFile;
|
|---|
| 2804 | SearchRec.Attr := attrFile;
|
|---|
| 2805 | SearchRec.Time := fdateLastWrite;
|
|---|
| 2806 | SearchRec.Time := SearchRec.Time Shl 16 + ftimeLastWrite;
|
|---|
| 2807 | End;
|
|---|
| 2808 | FindFirst := 0;
|
|---|
| 2809 | End
|
|---|
| 2810 | Else FindFirst := -Result;
|
|---|
| 2811 | {$ENDIF}
|
|---|
| 2812 | {$IFDEF Win95}
|
|---|
| 2813 | SearchRec.InternalAttr:=Attr;
|
|---|
| 2814 | SearchRec.HDir:=FindFirstFile(PathZ,SearchRec.SearchRecIntern);
|
|---|
| 2815 | If SearchRec.HDir=INVALID_HANDLE_VALUE Then
|
|---|
| 2816 | Begin
|
|---|
| 2817 | FindFirst:=-GetLastError;
|
|---|
| 2818 | Exit;
|
|---|
| 2819 | End;
|
|---|
| 2820 | While SearchRec.SearchRecIntern.dwFileAttributes And SearchRec.InternalAttr=0 Do
|
|---|
| 2821 | Begin
|
|---|
| 2822 | If FindNextFile(SearchRec.HDir,SearchRec.SearchRecIntern)=False Then
|
|---|
| 2823 | Begin
|
|---|
| 2824 | Result:=-GetLastError;
|
|---|
| 2825 | WinBase.FindClose(SearchRec.HDir);
|
|---|
| 2826 | Exit;
|
|---|
| 2827 | End;
|
|---|
| 2828 | End;
|
|---|
| 2829 |
|
|---|
| 2830 | FileTimeToLocalFileTime(SearchRec.SearchRecIntern.ftLastWriteTime,Actual);
|
|---|
| 2831 | FileTimeToDosDateTime(Actual,date,time);
|
|---|
| 2832 | SearchRec.Time:=(date Shl 16) Or Time;
|
|---|
| 2833 | SearchRec.Size:=SearchRec.SearchRecIntern.nFileSizeLow;
|
|---|
| 2834 | SearchRec.Attr:=SearchRec.SearchRecIntern.dwFileAttributes;
|
|---|
| 2835 | SearchRec.Name:=cstring(SearchRec.SearchRecIntern.cFileName);
|
|---|
| 2836 | Result := 0;
|
|---|
| 2837 | {$ENDIF}
|
|---|
| 2838 | End;
|
|---|
| 2839 |
|
|---|
| 2840 | Function FindNext(Var SearchRec: TSearchRec): LongInt;
|
|---|
| 2841 | {$IFDEF OS2}
|
|---|
| 2842 | Var
|
|---|
| 2843 | OS2SearchRec: FILEFINDBUF3;
|
|---|
| 2844 | Result: Integer;
|
|---|
| 2845 | Count: LongWord;
|
|---|
| 2846 | Const
|
|---|
| 2847 | Size = SizeOf(OS2SearchRec);
|
|---|
| 2848 | {$ENDIF}
|
|---|
| 2849 | {$IFDEF WIN32}
|
|---|
| 2850 | Var Actual:FILETIME;
|
|---|
| 2851 | date,time:word;
|
|---|
| 2852 | {$ENDIF}
|
|---|
| 2853 | Begin
|
|---|
| 2854 | {$IFDEF OS2}
|
|---|
| 2855 | Count := 1;
|
|---|
| 2856 | Result := DosFindNext (SearchRec.HDir, OS2SearchRec, Size, Count);
|
|---|
| 2857 | If Result = NO_ERROR Then
|
|---|
| 2858 | Begin
|
|---|
| 2859 | With OS2SearchRec Do
|
|---|
| 2860 | Begin
|
|---|
| 2861 | SearchRec.Name := achName;
|
|---|
| 2862 | SearchRec.Size := cbFile;
|
|---|
| 2863 | SearchRec.Attr := attrFile;
|
|---|
| 2864 | SearchRec.Time := fdateLastWrite;
|
|---|
| 2865 | SearchRec.Time := SearchRec.Time Shl 16 + ftimeLastWrite;
|
|---|
| 2866 | End;
|
|---|
| 2867 | FindNext := 0;
|
|---|
| 2868 | End
|
|---|
| 2869 | Else FindNext := -Result;
|
|---|
| 2870 | {$ENDIF}
|
|---|
| 2871 | {$IFDEF Win95}
|
|---|
| 2872 | If FindNextFile(SearchRec.HDir,SearchRec.SearchRecIntern)=False Then
|
|---|
| 2873 | Begin
|
|---|
| 2874 | Result:=-GetLastError;
|
|---|
| 2875 | WinBase.FindClose(SearchRec.HDir);
|
|---|
| 2876 | Exit;
|
|---|
| 2877 | End;
|
|---|
| 2878 | While SearchRec.SearchRecIntern.dwFileAttributes And SearchRec.InternalAttr=0 Do
|
|---|
| 2879 | Begin
|
|---|
| 2880 | If FindNextFile(SearchRec.HDir,SearchRec.SearchRecIntern)=False Then
|
|---|
| 2881 | Begin
|
|---|
| 2882 | Result:=-GetLastError;
|
|---|
| 2883 | WinBase.FindClose(SearchRec.HDir);
|
|---|
| 2884 | Exit;
|
|---|
| 2885 | End;
|
|---|
| 2886 | End;
|
|---|
| 2887 |
|
|---|
| 2888 | FileTimeToLocalFileTime(SearchRec.SearchRecIntern.ftLastWriteTime,Actual);
|
|---|
| 2889 | FileTimeToDosDateTime(Actual,date,time);
|
|---|
| 2890 | SearchRec.Time:=(date Shl 16) Or Time;
|
|---|
| 2891 | SearchRec.Size:=SearchRec.SearchRecIntern.nFileSizeLow;
|
|---|
| 2892 | SearchRec.Attr:=SearchRec.SearchRecIntern.dwFileAttributes;
|
|---|
| 2893 | SearchRec.Name:=cstring(SearchRec.SearchRecIntern.cFileName);
|
|---|
| 2894 | Result := 0;
|
|---|
| 2895 | {$ENDIF}
|
|---|
| 2896 | End;
|
|---|
| 2897 |
|
|---|
| 2898 | Procedure FindClose(Var SearchRec: TSearchRec);
|
|---|
| 2899 | Begin
|
|---|
| 2900 | {$IFDEF OS2}
|
|---|
| 2901 | DosFindClose(SearchRec.HDir);
|
|---|
| 2902 | {$ENDIF}
|
|---|
| 2903 | {$IFDEF Win95}
|
|---|
| 2904 | WinBase.FindClose(SearchRec.HDir);
|
|---|
| 2905 | {$ENDIF}
|
|---|
| 2906 | End;
|
|---|
| 2907 |
|
|---|
| 2908 | Function FileGetDate(Handle: LongInt): LongInt;
|
|---|
| 2909 | {$IFDEF OS2}
|
|---|
| 2910 | Var
|
|---|
| 2911 | Buffer: FILESTATUS3;
|
|---|
| 2912 | {$ENDIF}
|
|---|
| 2913 | {$IFDEF Win95}
|
|---|
| 2914 | Var
|
|---|
| 2915 | LastAccess,creation,LastWrite,actual:FILETIME;
|
|---|
| 2916 | date,Time:Word;
|
|---|
| 2917 | {$ENDIF}
|
|---|
| 2918 | Begin
|
|---|
| 2919 | {$IFDEF OS2}
|
|---|
| 2920 | If DosQueryFileInfo(Handle, FIL_STANDARD, Buffer, SizeOf(Buffer)) = NO_ERROR Then
|
|---|
| 2921 | FileGetDate := (Buffer.fdateLastWrite Shl 16) Or Buffer.ftimeLastWrite
|
|---|
| 2922 | Else FileGetDate := -1;
|
|---|
| 2923 | {$ENDIF}
|
|---|
| 2924 | {$IFDEF Win95}
|
|---|
| 2925 | If Not GetFileTime(Handle,creation,LastAccess,LastWrite) Then
|
|---|
| 2926 | Begin
|
|---|
| 2927 | CloseHandle(Handle);
|
|---|
| 2928 | FileGetDate:=-1;
|
|---|
| 2929 | Exit;
|
|---|
| 2930 | End;
|
|---|
| 2931 | CloseHandle(Handle);
|
|---|
| 2932 | FileTimeToLocalFileTime(LastWrite,actual);
|
|---|
| 2933 | FileTimeToDosDateTime(actual,date,Time);
|
|---|
| 2934 | FileGetDate := (date Shl 16) Or Time;
|
|---|
| 2935 | {$ENDIF}
|
|---|
| 2936 | End;
|
|---|
| 2937 |
|
|---|
| 2938 | Procedure FileSetDate(Handle: Integer; Age: LongInt);
|
|---|
| 2939 | {$IFDEF OS2}
|
|---|
| 2940 | Var
|
|---|
| 2941 | Buffer: FILESTATUS3;
|
|---|
| 2942 | {$ENDIF}
|
|---|
| 2943 | {$IFDEF Win95}
|
|---|
| 2944 | Var
|
|---|
| 2945 | date,Time:Word;
|
|---|
| 2946 | LastWrite:FILETIME;
|
|---|
| 2947 | {$ENDIF}
|
|---|
| 2948 | Begin
|
|---|
| 2949 | {$IFDEF OS2}
|
|---|
| 2950 | FillChar(Buffer, SizeOf(Buffer), 0);
|
|---|
| 2951 | Buffer.ftimeLastWrite := Age And $FFFF;
|
|---|
| 2952 | Buffer.fdateLastWrite := Age Shr 16;
|
|---|
| 2953 | DosSetFileInfo(Handle, FIL_STANDARD, Buffer, SizeOf(Buffer));
|
|---|
| 2954 | {$ENDIF}
|
|---|
| 2955 | {$IFDEF Win95}
|
|---|
| 2956 | date:= Age Shr 16;
|
|---|
| 2957 | Time:= Age And $FFFF;
|
|---|
| 2958 | DosDateTimeToFileTime(date,Time,LastWrite);
|
|---|
| 2959 |
|
|---|
| 2960 | WinBase.SetFileTime(Handle,Nil,Nil,LastWrite);
|
|---|
| 2961 | {$ENDIF}
|
|---|
| 2962 | End;
|
|---|
| 2963 |
|
|---|
| 2964 | Function FileGetAttr(Const FileName: String): LongInt;
|
|---|
| 2965 | {$IFDEF OS2}
|
|---|
| 2966 | Var
|
|---|
| 2967 | Buffer: FILESTATUS3;
|
|---|
| 2968 | {$ENDIF}
|
|---|
| 2969 | Var
|
|---|
| 2970 | FileNameZ: cstring;
|
|---|
| 2971 | Begin
|
|---|
| 2972 | FileNameZ := FileName;
|
|---|
| 2973 | {$IFDEF OS2}
|
|---|
| 2974 | Result := - DosQueryPathInfo(FileNameZ, FIL_STANDARD, Buffer, SizeOf(Buffer));
|
|---|
| 2975 | If Result = 0 Then Result := Buffer.attrFile;
|
|---|
| 2976 | {$ENDIF}
|
|---|
| 2977 | {$IFDEF Win95}
|
|---|
| 2978 | Result := GetFileAttributes(FileNameZ);
|
|---|
| 2979 | {$ENDIF}
|
|---|
| 2980 | End;
|
|---|
| 2981 |
|
|---|
| 2982 | Function FileSetAttr(Const FileName: String; Attr: Integer): Integer;
|
|---|
| 2983 | {$IFDEF OS2}
|
|---|
| 2984 | Var
|
|---|
| 2985 | Buffer: FILESTATUS3;
|
|---|
| 2986 | {$ENDIF}
|
|---|
| 2987 | Var
|
|---|
| 2988 | FileNameZ: cstring;
|
|---|
| 2989 | Begin
|
|---|
| 2990 | FileNameZ := FileName;
|
|---|
| 2991 | {$IFDEF OS2}
|
|---|
| 2992 | FillChar(Buffer, SizeOf(Buffer), 0);
|
|---|
| 2993 | Buffer.attrFile := Attr;
|
|---|
| 2994 | Result := - DosSetPathInfo(FileNameZ, FIL_STANDARD, Buffer, SizeOf(Buffer), 0);
|
|---|
| 2995 | {$ENDIF}
|
|---|
| 2996 | {$IFDEF Win95}
|
|---|
| 2997 | If SetFileAttributes(FileNameZ,Attr) Then Result:=0
|
|---|
| 2998 | Else Result := -GetLastError;
|
|---|
| 2999 | {$ENDIF}
|
|---|
| 3000 | End;
|
|---|
| 3001 |
|
|---|
| 3002 | Function CopyFile(Const SourceName, DestName: String): Boolean;
|
|---|
| 3003 | Var
|
|---|
| 3004 | SourceZ, DestZ: cstring;
|
|---|
| 3005 | Begin
|
|---|
| 3006 | SourceZ := SourceName;
|
|---|
| 3007 | DestZ := DestName;
|
|---|
| 3008 | {$IFDEF OS2}
|
|---|
| 3009 | Result := (DosCopy(SourceZ, DestZ, DCPY_EXISTING) = NO_ERROR);
|
|---|
| 3010 | {$ENDIF}
|
|---|
| 3011 | {$IFDEF Win95}
|
|---|
| 3012 | Result := WinBase.CopyFile(SourceZ, DestZ, True);
|
|---|
| 3013 | {$ENDIF}
|
|---|
| 3014 | End;
|
|---|
| 3015 |
|
|---|
| 3016 | Function DeleteFile(Const FileName: String): Boolean;
|
|---|
| 3017 | Var
|
|---|
| 3018 | FileNameZ: cstring;
|
|---|
| 3019 | Begin
|
|---|
| 3020 | FileNameZ := FileName;
|
|---|
| 3021 | {$IFDEF OS2}
|
|---|
| 3022 | Result := (DosDelete(FileNameZ) = NO_ERROR);
|
|---|
| 3023 | {$ENDIF}
|
|---|
| 3024 | {$IFDEF Win95}
|
|---|
| 3025 | Result := WinBase.DeleteFile(FileNameZ);
|
|---|
| 3026 | {$ENDIF}
|
|---|
| 3027 | End;
|
|---|
| 3028 |
|
|---|
| 3029 | Function RenameFile(Const OldName, NewName: String): Boolean;
|
|---|
| 3030 | Var
|
|---|
| 3031 | OldNameZ, NewNameZ: cstring;
|
|---|
| 3032 | Begin
|
|---|
| 3033 | OldNameZ := OldName;
|
|---|
| 3034 | NewNameZ := NewName;
|
|---|
| 3035 | {$IFDEF OS2}
|
|---|
| 3036 | Result := (DosMove(OldNameZ, NewNameZ) = NO_ERROR);
|
|---|
| 3037 | {$ENDIF}
|
|---|
| 3038 | {$IFDEF Win95}
|
|---|
| 3039 | Result := MoveFile(OldNameZ, NewNameZ);
|
|---|
| 3040 | {$ENDIF}
|
|---|
| 3041 | End;
|
|---|
| 3042 |
|
|---|
| 3043 | Function ChangeFileExt(Const FileName, extension: String): String;
|
|---|
| 3044 | Var
|
|---|
| 3045 | P: Integer;
|
|---|
| 3046 | Begin
|
|---|
| 3047 | P := Length(FileName);
|
|---|
| 3048 | While (P > 0) And (FileName[P] <> '.') Do Dec(P);
|
|---|
| 3049 | If P = 0 Then Result := FileName + extension
|
|---|
| 3050 | Else Result := Copy(FileName, 1, P - 1) + extension;
|
|---|
| 3051 | End;
|
|---|
| 3052 |
|
|---|
| 3053 | Function ExtractFilePath(Const FileName: String): String;
|
|---|
| 3054 | Var
|
|---|
| 3055 | P: Integer;
|
|---|
| 3056 | Begin
|
|---|
| 3057 | P := Length(FileName);
|
|---|
| 3058 | While (P > 0) And (FileName[P] <> ':') And (FileName[P] <> '\') Do Dec(P);
|
|---|
| 3059 | Result := Copy(FileName, 1, P);
|
|---|
| 3060 | End;
|
|---|
| 3061 |
|
|---|
| 3062 | Function ExtractFileName(Const FileName: String): String;
|
|---|
| 3063 | Var
|
|---|
| 3064 | P: Integer;
|
|---|
| 3065 | Begin
|
|---|
| 3066 | P := Length(FileName);
|
|---|
| 3067 | While (P > 0) And (FileName[P] <> ':') And (FileName[P] <> '\') Do Dec(P);
|
|---|
| 3068 | Result := Copy(FileName, P + 1, 255);
|
|---|
| 3069 | End;
|
|---|
| 3070 |
|
|---|
| 3071 | Function ExtractFileExt(Const FileName: String): String;
|
|---|
| 3072 | Var
|
|---|
| 3073 | P: Integer;
|
|---|
| 3074 | Begin
|
|---|
| 3075 | P := Length(FileName);
|
|---|
| 3076 | While (P > 0) And (FileName[P] <> '.') Do Dec(P);
|
|---|
| 3077 | If P = 0 Then Result := ''
|
|---|
| 3078 | Else Result := Copy(FileName, P, 255);
|
|---|
| 3079 | End;
|
|---|
| 3080 |
|
|---|
| 3081 | Function ConcatFileName(Const pathname, FileName: String): String;
|
|---|
| 3082 | Begin
|
|---|
| 3083 | If (pathname = '') Or (FileName = '') Or
|
|---|
| 3084 | (pathname[Length(pathname)] In ['\', ':']) Then
|
|---|
| 3085 | Result := pathname + FileName
|
|---|
| 3086 | Else Result := pathname + '\' + FileName;
|
|---|
| 3087 | End;
|
|---|
| 3088 |
|
|---|
| 3089 | Function ExpandFileName(FileName: String): String;
|
|---|
| 3090 | {$IFDEF OS2}
|
|---|
| 3091 | Const
|
|---|
| 3092 | Level = FIL_QUERYFULLNAME;
|
|---|
| 3093 | Var
|
|---|
| 3094 | Buffer:CString;
|
|---|
| 3095 | {$ENDIF}
|
|---|
| 3096 | {$IFDEF Win95}
|
|---|
| 3097 | Var
|
|---|
| 3098 | TempName : PChar;
|
|---|
| 3099 | {$ENDIF}
|
|---|
| 3100 | Var
|
|---|
| 3101 | FileNameZ: cstring;
|
|---|
| 3102 | Begin
|
|---|
| 3103 | FileNameZ := FileName;
|
|---|
| 3104 | {$IFDEF OS2}
|
|---|
| 3105 | If DosQueryPathInfo(FileNameZ, Level, Buffer, SizeOf(Buffer)) = NO_ERROR Then Result := Buffer
|
|---|
| 3106 | Else
|
|---|
| 3107 | Begin
|
|---|
| 3108 | If ((length(FileName)=2)And(FileName[2]=':')) Then
|
|---|
| 3109 | Begin
|
|---|
| 3110 | {$I-}
|
|---|
| 3111 | GetDir(ord(Upcase(FileName[1]))-64,Result);
|
|---|
| 3112 | {$I+}
|
|---|
| 3113 | If IoResult<>0 Then Result:='';
|
|---|
| 3114 | End
|
|---|
| 3115 | Else Result:='';
|
|---|
| 3116 | End;
|
|---|
| 3117 | {$ENDIF}
|
|---|
| 3118 | {$IFDEF Win95}
|
|---|
| 3119 | Result[0]:=Chr(GetFullPathName(FileNameZ,256,cstring(Result[1]),TempName));
|
|---|
| 3120 | {$ENDIF}
|
|---|
| 3121 | End;
|
|---|
| 3122 |
|
|---|
| 3123 | Function EditFileName(Const Name, edit: String): String;
|
|---|
| 3124 | {$IFDEF OS2}
|
|---|
| 3125 | Var
|
|---|
| 3126 | Buffer: cstring;
|
|---|
| 3127 | {$ENDIF}
|
|---|
| 3128 | Var
|
|---|
| 3129 | NameZ, EditZ: cstring;
|
|---|
| 3130 | Begin
|
|---|
| 3131 | NameZ := Name;
|
|---|
| 3132 | EditZ := edit;
|
|---|
| 3133 | {$IFDEF OS2}
|
|---|
| 3134 | If DosEditName(1, NameZ, EditZ, Buffer, 256) = 0 Then Result := Buffer
|
|---|
| 3135 | Else Result := '';
|
|---|
| 3136 | {$ENDIF}
|
|---|
| 3137 | {$IFDEF Win95}
|
|---|
| 3138 | Result := ''; //Not supported
|
|---|
| 3139 | {$ENDIF}
|
|---|
| 3140 | End;
|
|---|
| 3141 |
|
|---|
| 3142 | Function FileSearch(Const Name, DirList: String): String;
|
|---|
| 3143 | {$IFDEF OS2}
|
|---|
| 3144 | Const
|
|---|
| 3145 | Flags = SEARCH_IGNORENETERRS;
|
|---|
| 3146 | {$ENDIF}
|
|---|
| 3147 | {$IFDEF Win95}
|
|---|
| 3148 | Var
|
|---|
| 3149 | Temp : PChar;
|
|---|
| 3150 | {$ENDIF}
|
|---|
| 3151 | Var
|
|---|
| 3152 | NameZ, DirListZ, Buffer: cstring;
|
|---|
| 3153 | Begin
|
|---|
| 3154 | NameZ := Name;
|
|---|
| 3155 | DirListZ := DirList;
|
|---|
| 3156 | {$IFDEF OS2}
|
|---|
| 3157 | If DosSearchPath(Flags, DirListZ, NameZ, Buffer, SizeOf(Buffer)) = NO_ERROR Then
|
|---|
| 3158 | Result := Buffer
|
|---|
| 3159 | Else Result := '';
|
|---|
| 3160 | {$ENDIF}
|
|---|
| 3161 | {$IFDEF Win95}
|
|---|
| 3162 | If SearchPath(DirListZ,Name,Nil,256,Buffer,Temp)=0 Then Result:=''
|
|---|
| 3163 | Else Result:=Buffer;
|
|---|
| 3164 | {$ENDIF}
|
|---|
| 3165 | End;
|
|---|
| 3166 |
|
|---|
| 3167 | Function DiskFree(Drive: Byte): LongInt;
|
|---|
| 3168 | {$IFDEF OS2}
|
|---|
| 3169 | Var
|
|---|
| 3170 | Buffer: FSALLOCATE;
|
|---|
| 3171 | {$ENDIF}
|
|---|
| 3172 | {$IFDEF Win95}
|
|---|
| 3173 | Var
|
|---|
| 3174 | C : cstring;
|
|---|
| 3175 | S:LongWord;
|
|---|
| 3176 | Sec,clust,freeclust:LongWord;
|
|---|
| 3177 | {$ENDIF}
|
|---|
| 3178 | Begin
|
|---|
| 3179 | {$IFDEF OS2}
|
|---|
| 3180 | If DosQueryFSInfo(Drive, FSIL_ALLOC, Buffer, SizeOf(Buffer)) = NO_ERROR Then
|
|---|
| 3181 | With Buffer Do Result := cUnitAvail * cSectorUnit * cbSector
|
|---|
| 3182 | Else Result := -1;
|
|---|
| 3183 | {$ENDIF}
|
|---|
| 3184 | {$IFDEF Win95}
|
|---|
| 3185 | If Drive=0 Then
|
|---|
| 3186 | Begin
|
|---|
| 3187 | If Not GetDiskFreeSpace(Nil,S,Sec,freeclust,clust) Then
|
|---|
| 3188 | Begin
|
|---|
| 3189 | Result:=-1;
|
|---|
| 3190 | Exit;
|
|---|
| 3191 | End;
|
|---|
| 3192 | End
|
|---|
| 3193 | Else
|
|---|
| 3194 | Begin
|
|---|
| 3195 | C:=Chr(Ord('A')+(Drive-1))+':\';
|
|---|
| 3196 | If Not GetDiskFreeSpace(C,S,Sec,freeclust,clust) Then
|
|---|
| 3197 | Begin
|
|---|
| 3198 | Result:=-1;
|
|---|
| 3199 | Exit;
|
|---|
| 3200 | End;
|
|---|
| 3201 | End;
|
|---|
| 3202 | Result:=S*Sec*freeclust;
|
|---|
| 3203 | {$ENDIF}
|
|---|
| 3204 | End;
|
|---|
| 3205 |
|
|---|
| 3206 | Function DiskSize(Drive: Byte): LongInt;
|
|---|
| 3207 | {$IFDEF OS2}
|
|---|
| 3208 | Var
|
|---|
| 3209 | Buffer: FSALLOCATE;
|
|---|
| 3210 | {$ENDIF}
|
|---|
| 3211 | {$IFDEF Win95}
|
|---|
| 3212 | Var
|
|---|
| 3213 | C : cstring;
|
|---|
| 3214 | S:LongWord;
|
|---|
| 3215 | Sec,clust,freeclust:LongWord;
|
|---|
| 3216 | {$ENDIF}
|
|---|
| 3217 | Begin
|
|---|
| 3218 | {$IFDEF OS2}
|
|---|
| 3219 | If DosQueryFSInfo(Drive, FSIL_ALLOC, Buffer, SizeOf(Buffer)) = NO_ERROR Then
|
|---|
| 3220 | With Buffer Do Result := cUnit * cSectorUnit * cbSector
|
|---|
| 3221 | Else Result := -1;
|
|---|
| 3222 | {$ENDIF}
|
|---|
| 3223 | {$IFDEF Win95}
|
|---|
| 3224 | If Drive=0 Then
|
|---|
| 3225 | Begin
|
|---|
| 3226 | If Not GetDiskFreeSpace(Nil,S,Sec,freeclust,clust) Then
|
|---|
| 3227 | Begin
|
|---|
| 3228 | Result:=-1;
|
|---|
| 3229 | Exit;
|
|---|
| 3230 | End;
|
|---|
| 3231 | End
|
|---|
| 3232 | Else
|
|---|
| 3233 | Begin
|
|---|
| 3234 | C:=Chr(Ord('A')+(Drive-1))+':\';
|
|---|
| 3235 | If Not GetDiskFreeSpace(C,S,Sec,freeclust,clust) Then
|
|---|
| 3236 | Begin
|
|---|
| 3237 | Result:=-1;
|
|---|
| 3238 | Exit;
|
|---|
| 3239 | End;
|
|---|
| 3240 | End;
|
|---|
| 3241 | Result:=S*Sec*clust;
|
|---|
| 3242 | {$ENDIF}
|
|---|
| 3243 | End;
|
|---|
| 3244 |
|
|---|
| 3245 | Function FileDateToDateTime(FileDate: LongInt): TDateTime;
|
|---|
| 3246 | Var
|
|---|
| 3247 | Day, Month, Year, Hour, Min, Sec: Word;
|
|---|
| 3248 | Begin
|
|---|
| 3249 | Sec := (FileDate And 31) Shl 1;
|
|---|
| 3250 | FileDate := FileDate Shr 5;
|
|---|
| 3251 | Min := FileDate And 63;
|
|---|
| 3252 | FileDate := FileDate Shr 6;
|
|---|
| 3253 | Hour := FileDate And 31;
|
|---|
| 3254 | FileDate := FileDate Shr 5;
|
|---|
| 3255 |
|
|---|
| 3256 | Day := FileDate And 31;
|
|---|
| 3257 | FileDate := FileDate Shr 5;
|
|---|
| 3258 | Month := FileDate And 15;
|
|---|
| 3259 | FileDate := FileDate Shr 4;
|
|---|
| 3260 | Year := 1980 + (FileDate And 127);
|
|---|
| 3261 |
|
|---|
| 3262 | Result := EncodeDate(Year, Month, Day) + EncodeTime(Hour, Min, Sec, 0);
|
|---|
| 3263 | End;
|
|---|
| 3264 |
|
|---|
| 3265 | Function DateTimeToFileDate(DateTime: TDateTime): LongInt;
|
|---|
| 3266 | Var
|
|---|
| 3267 | Day, Month, Year, Hour, Min, Sec, MSec: Word;
|
|---|
| 3268 | FileDate, FILETIME: LongInt;
|
|---|
| 3269 | Begin
|
|---|
| 3270 | DecodeDate(DateTime, Year, Month, Day);
|
|---|
| 3271 | DecodeTime(DateTime, Hour, Min, Sec, MSec);
|
|---|
| 3272 |
|
|---|
| 3273 | FileDate := Year - 1980;
|
|---|
| 3274 | FileDate := (FileDate Shl 4) Or Month;
|
|---|
| 3275 | FileDate := (FileDate Shl 5) Or Day;
|
|---|
| 3276 |
|
|---|
| 3277 | FILETIME := Hour;
|
|---|
| 3278 | FILETIME := (FILETIME Shl 6) Or Min;
|
|---|
| 3279 | FILETIME := (FILETIME Shl 5) Or (Sec Div 2);
|
|---|
| 3280 |
|
|---|
| 3281 | Result := (FileDate Shl 16) Or FILETIME;
|
|---|
| 3282 | End;
|
|---|
| 3283 |
|
|---|
| 3284 | /* Alte Implementierung, macht Probleme mit neuem Compiler
|
|---|
| 3285 |
|
|---|
| 3286 | Function DateTimeToFileDate(DateTime: TDateTime): LongInt;
|
|---|
| 3287 | Var
|
|---|
| 3288 | Day, Month, Year, Hour, Min, Sec, MSec: Word;
|
|---|
| 3289 | FileDate: LongInt;
|
|---|
| 3290 | Begin
|
|---|
| 3291 | DecodeDate(DateTime, Year, Month, Day);
|
|---|
| 3292 | DecodeTime(DateTime, Hour, Min, Sec, MSec);
|
|---|
| 3293 |
|
|---|
| 3294 | FileDate := Year - 1980;
|
|---|
| 3295 | FileDate := (FileDate Shl 4) Or Month;
|
|---|
| 3296 | FileDate := (FileDate Shl 5) Or Day;
|
|---|
| 3297 | FileDate := Hour;
|
|---|
| 3298 | FileDate := (FileDate Shl 6) Or Min;
|
|---|
| 3299 | FileDate := (FileDate Shl 5) Or (Sec Div 2);
|
|---|
| 3300 |
|
|---|
| 3301 | Result := FileDate;
|
|---|
| 3302 | End;
|
|---|
| 3303 |
|
|---|
| 3304 | */
|
|---|
| 3305 |
|
|---|
| 3306 | { --- PChar Handling --- }
|
|---|
| 3307 |
|
|---|
| 3308 | Function StrLen(Str:PChar): Cardinal;
|
|---|
| 3309 | Begin
|
|---|
| 3310 | Asm
|
|---|
| 3311 | MOV EDI, Str
|
|---|
| 3312 | CALLN32 !StringLength
|
|---|
| 3313 | MOV Result, EAX
|
|---|
| 3314 | End;
|
|---|
| 3315 | End;
|
|---|
| 3316 |
|
|---|
| 3317 | Function StrEnd(Str:PChar):PChar;
|
|---|
| 3318 | Begin
|
|---|
| 3319 | Asm
|
|---|
| 3320 | MOV EDI, Str
|
|---|
| 3321 | CALLN32 !StringLength
|
|---|
| 3322 | MOV Result, EDI
|
|---|
| 3323 | End;
|
|---|
| 3324 | End;
|
|---|
| 3325 |
|
|---|
| 3326 | Function StrMove(Dest, Source: PChar; Count: Cardinal): PChar;
|
|---|
| 3327 | Begin
|
|---|
| 3328 | If (Source = Nil) Or (Dest = Nil) Or (Count = 0) Then Result := Nil
|
|---|
| 3329 | Else
|
|---|
| 3330 | Begin
|
|---|
| 3331 | Move(Source^, Dest^, Count);
|
|---|
| 3332 | Result := Dest;
|
|---|
| 3333 | End;
|
|---|
| 3334 | End;
|
|---|
| 3335 |
|
|---|
| 3336 | Function StrCopy(Dest, Source:PChar):PChar;
|
|---|
| 3337 | Begin
|
|---|
| 3338 | Asm
|
|---|
| 3339 | MOV ESI, Source
|
|---|
| 3340 | MOV EDI, Dest
|
|---|
| 3341 | MOV ECX, $FFFFFFFF
|
|---|
| 3342 | CALLN32 !StringCopy
|
|---|
| 3343 | MOV EAX, Dest
|
|---|
| 3344 | MOV Result, EAX
|
|---|
| 3345 | End;
|
|---|
| 3346 | End;
|
|---|
| 3347 |
|
|---|
| 3348 | Function StrECopy(Dest, Source:PChar):PChar;
|
|---|
| 3349 | Begin
|
|---|
| 3350 | Asm
|
|---|
| 3351 | MOV ESI, Source
|
|---|
| 3352 | MOV EDI, Dest
|
|---|
| 3353 | MOV ECX, $FFFFFFFF
|
|---|
| 3354 | CALLN32 !StringCopy
|
|---|
| 3355 | MOV Result, EDI
|
|---|
| 3356 | End;
|
|---|
| 3357 | End;
|
|---|
| 3358 |
|
|---|
| 3359 | Function StrLCopy(Dest, Source:PChar; MaxLen: Cardinal):PChar;
|
|---|
| 3360 | Begin
|
|---|
| 3361 | Asm
|
|---|
| 3362 | MOV ESI, Source
|
|---|
| 3363 | MOV EDI, Dest
|
|---|
| 3364 | MOV ECX, MaxLen
|
|---|
| 3365 | CALLN32 !StringCopy
|
|---|
| 3366 | MOV EAX, Dest
|
|---|
| 3367 | MOV Result, EAX
|
|---|
| 3368 | End;
|
|---|
| 3369 | End;
|
|---|
| 3370 |
|
|---|
| 3371 | Function StrPCopy(Dest: PChar; Const Source: String): PChar;
|
|---|
| 3372 | Begin
|
|---|
| 3373 | Asm
|
|---|
| 3374 | MOV EDI, Dest
|
|---|
| 3375 | MOV ESI, Source
|
|---|
| 3376 | Xor ECX, ECX
|
|---|
| 3377 | MOV CL, [ESI]
|
|---|
| 3378 | Inc ESI
|
|---|
| 3379 | CALLN32 !StringCopy
|
|---|
| 3380 | MOV EAX, Dest
|
|---|
| 3381 | MOV Result, EAX
|
|---|
| 3382 | End;
|
|---|
| 3383 | End;
|
|---|
| 3384 |
|
|---|
| 3385 | Function StrPLCopy(Dest: PChar; Const Source: String; MaxLen: Cardinal): PChar;
|
|---|
| 3386 | Begin
|
|---|
| 3387 | Asm
|
|---|
| 3388 | MOV EDI, Dest
|
|---|
| 3389 | MOV ESI, Source
|
|---|
| 3390 | Xor ECX, ECX
|
|---|
| 3391 | MOV CL, [ESI]
|
|---|
| 3392 | Inc ESI
|
|---|
| 3393 | CMP ECX, MaxLen
|
|---|
| 3394 | JLE StrPLCopy_1
|
|---|
| 3395 | MOV ECX, MaxLen
|
|---|
| 3396 |
|
|---|
| 3397 | StrPLCopy_1:
|
|---|
| 3398 |
|
|---|
| 3399 | CALLN32 !StringCopy
|
|---|
| 3400 | MOV EAX, Dest
|
|---|
| 3401 | MOV Result, EAX
|
|---|
| 3402 | End;
|
|---|
| 3403 | End;
|
|---|
| 3404 |
|
|---|
| 3405 | Function StrCat(Dest, Source: PChar): PChar;
|
|---|
| 3406 | Begin
|
|---|
| 3407 | Asm
|
|---|
| 3408 | MOV EDI, Dest
|
|---|
| 3409 | MOV ESI, Source
|
|---|
| 3410 | CALLN32 !StringLength
|
|---|
| 3411 | MOV ECX, $FFFFFFFF
|
|---|
| 3412 | CALLN32 !StringCopy
|
|---|
| 3413 | MOV EAX, Dest
|
|---|
| 3414 | MOV Result, EAX
|
|---|
| 3415 | End;
|
|---|
| 3416 | End;
|
|---|
| 3417 |
|
|---|
| 3418 | Function StrLCat(Dest, Source: PChar; MaxLen: Cardinal): PChar;
|
|---|
| 3419 | Begin
|
|---|
| 3420 | Asm
|
|---|
| 3421 | MOV EDI, Dest
|
|---|
| 3422 | MOV ESI, Source
|
|---|
| 3423 | CALLN32 !StringLength
|
|---|
| 3424 | MOV ECX, MaxLen
|
|---|
| 3425 | SUB ECX, EAX
|
|---|
| 3426 | JLE StrLCat_1
|
|---|
| 3427 | CALLN32 !StringCopy
|
|---|
| 3428 |
|
|---|
| 3429 | StrLCat_1:
|
|---|
| 3430 |
|
|---|
| 3431 | MOV EAX, Dest
|
|---|
| 3432 | MOV Result, EAX
|
|---|
| 3433 | End;
|
|---|
| 3434 | End;
|
|---|
| 3435 |
|
|---|
| 3436 | Function StrComp(Str1, Str2: PChar): Integer;
|
|---|
| 3437 | Begin
|
|---|
| 3438 | Asm
|
|---|
| 3439 | MOV EDI, Str1
|
|---|
| 3440 | CALLN32 !StringLength
|
|---|
| 3441 | MOV ECX, EAX
|
|---|
| 3442 | MOV ESI, Str1
|
|---|
| 3443 | MOV EDI, Str2
|
|---|
| 3444 | CALLN32 !StringCompare
|
|---|
| 3445 | MOV Result, EAX
|
|---|
| 3446 | End;
|
|---|
| 3447 | End;
|
|---|
| 3448 |
|
|---|
| 3449 | Function StrLComp(Str1, Str2: PChar; MaxLen: Cardinal): Integer;
|
|---|
| 3450 | Begin
|
|---|
| 3451 | Asm
|
|---|
| 3452 | MOV EDI, Str1
|
|---|
| 3453 | MOV ECX, MaxLen
|
|---|
| 3454 | MOV EBX, ECX
|
|---|
| 3455 | Xor EAX, EAX
|
|---|
| 3456 | REPNZ SCASB
|
|---|
| 3457 | SUB EBX, ECX
|
|---|
| 3458 | MOV ECX, EBX
|
|---|
| 3459 | MOV ESI, Str1
|
|---|
| 3460 | MOV EDI, Str2
|
|---|
| 3461 | CALLN32 !StringCompare
|
|---|
| 3462 | MOV Result, EAX
|
|---|
| 3463 | End;
|
|---|
| 3464 | End;
|
|---|
| 3465 |
|
|---|
| 3466 | Function StrIComp(Str1, Str2: PChar): Integer;
|
|---|
| 3467 | Begin
|
|---|
| 3468 | Asm
|
|---|
| 3469 | // Set MaxLen (ECX) to Maxint
|
|---|
| 3470 | MOV ECX, $ffffffff
|
|---|
| 3471 | MOV ESI, Str1 // Set ESI to Str1
|
|---|
| 3472 | MOV EDI, Str2 // Set EDI to Str2
|
|---|
| 3473 | CALLN32 !ZeroTerminatedStringICompare
|
|---|
| 3474 | MOV Result, EAX // Set result
|
|---|
| 3475 | End;
|
|---|
| 3476 | End;
|
|---|
| 3477 |
|
|---|
| 3478 | Function StrLIComp(Str1, Str2: PChar; MaxLen: Cardinal): Integer;
|
|---|
| 3479 | Begin
|
|---|
| 3480 | Asm
|
|---|
| 3481 | MOV ECX, MaxLen // put MaxLen into ECX
|
|---|
| 3482 | MOV ESI, Str1
|
|---|
| 3483 | MOV EDI, Str2
|
|---|
| 3484 | CALLN32 !StringICompare
|
|---|
| 3485 | MOV Result, EAX
|
|---|
| 3486 | End;
|
|---|
| 3487 | End;
|
|---|
| 3488 |
|
|---|
| 3489 | Function StrScan(Str: PChar; Chr: Char): PChar;
|
|---|
| 3490 | Begin
|
|---|
| 3491 | Asm
|
|---|
| 3492 | MOV EDI, Str
|
|---|
| 3493 | CALLN32 !StringLength
|
|---|
| 3494 | Inc EAX
|
|---|
| 3495 | MOV ECX, EAX
|
|---|
| 3496 | Xor EBX, EBX
|
|---|
| 3497 | MOV AL, Chr
|
|---|
| 3498 | MOV EDI, Str
|
|---|
| 3499 | REPNZ SCASB
|
|---|
| 3500 | Dec EDI
|
|---|
| 3501 | CMP AL, [EDI]
|
|---|
| 3502 | JNE !StrScan_1
|
|---|
| 3503 | MOV EBX, EDI
|
|---|
| 3504 |
|
|---|
| 3505 | !StrScan_1:
|
|---|
| 3506 |
|
|---|
| 3507 | MOV Result, EBX
|
|---|
| 3508 | End;
|
|---|
| 3509 | End;
|
|---|
| 3510 |
|
|---|
| 3511 | Function StrRScan(Str: PChar; Chr: Char): PChar;
|
|---|
| 3512 | Begin
|
|---|
| 3513 | Asm
|
|---|
| 3514 | MOV EDI, Str
|
|---|
| 3515 | CALLN32 !StringLength
|
|---|
| 3516 | Inc EAX
|
|---|
| 3517 | MOV ECX, EAX
|
|---|
| 3518 | Xor EBX, EBX
|
|---|
| 3519 | MOV AL, Chr
|
|---|
| 3520 | STD
|
|---|
| 3521 | REPNZ SCASB
|
|---|
| 3522 | Inc EDI
|
|---|
| 3523 | CMP AL, [EDI]
|
|---|
| 3524 | JNE !StrRScan_1
|
|---|
| 3525 | MOV EBX, EDI
|
|---|
| 3526 |
|
|---|
| 3527 | !StrRScan_1:
|
|---|
| 3528 |
|
|---|
| 3529 | CLD
|
|---|
| 3530 | MOV Result, EBX
|
|---|
| 3531 | End;
|
|---|
| 3532 | End;
|
|---|
| 3533 |
|
|---|
| 3534 | Function StrPos(Str, SubStr: PChar): PChar;
|
|---|
| 3535 | Begin
|
|---|
| 3536 | Asm
|
|---|
| 3537 | MOV EDI, SubStr
|
|---|
| 3538 | CALLN32 !StringLength
|
|---|
| 3539 | CMP EAX, 0
|
|---|
| 3540 | JE !ErrOutStrPos
|
|---|
| 3541 |
|
|---|
| 3542 | MOV EDX, EAX
|
|---|
| 3543 | MOV EDI, Str
|
|---|
| 3544 | CALLN32 !StringLength
|
|---|
| 3545 | CMP EAX, 0
|
|---|
| 3546 | JE !ErrOutStrPos
|
|---|
| 3547 | SUB EAX, EDX
|
|---|
| 3548 | JB !ErrOutStrPos
|
|---|
| 3549 | MOV EDI, Str
|
|---|
| 3550 |
|
|---|
| 3551 | !1:
|
|---|
| 3552 |
|
|---|
| 3553 | MOV ESI, SubStr
|
|---|
| 3554 | LODSB
|
|---|
| 3555 | REPNE SCASB
|
|---|
| 3556 | JNE !ErrOutStrPos;
|
|---|
| 3557 | MOV EAX, ECX
|
|---|
| 3558 | PUSH EDI
|
|---|
| 3559 | MOV ECX, EDX
|
|---|
| 3560 | Dec ECX
|
|---|
| 3561 | REPE CMPSB
|
|---|
| 3562 | MOV ECX, EAX
|
|---|
| 3563 | POP EDI
|
|---|
| 3564 | JNE !1
|
|---|
| 3565 | MOV EAX, EDI
|
|---|
| 3566 | Dec EAX
|
|---|
| 3567 | JMP !out
|
|---|
| 3568 |
|
|---|
| 3569 | !ErrOutStrPos:
|
|---|
| 3570 |
|
|---|
| 3571 | Xor EAX,EAX
|
|---|
| 3572 |
|
|---|
| 3573 | !out:
|
|---|
| 3574 |
|
|---|
| 3575 | MOV Result, EAX
|
|---|
| 3576 | End;
|
|---|
| 3577 | End;
|
|---|
| 3578 |
|
|---|
| 3579 | Function StrLower(Str: PChar): PChar;
|
|---|
| 3580 | Begin
|
|---|
| 3581 | Asm
|
|---|
| 3582 | CLD
|
|---|
| 3583 | MOV ESI, Str
|
|---|
| 3584 |
|
|---|
| 3585 | !StringLower1:
|
|---|
| 3586 |
|
|---|
| 3587 | LODSB
|
|---|
| 3588 | Or AL, AL
|
|---|
| 3589 | JE !OutStrLower
|
|---|
| 3590 |
|
|---|
| 3591 | CMP AL, 'A'
|
|---|
| 3592 | JB !StringLower1
|
|---|
| 3593 | CMP AL, 'Z'
|
|---|
| 3594 | JA !StringLower1
|
|---|
| 3595 | Or AL, 32
|
|---|
| 3596 | MOV [ESI-1], AL
|
|---|
| 3597 | JMP !StringLower1
|
|---|
| 3598 |
|
|---|
| 3599 | !OutStrLower:
|
|---|
| 3600 |
|
|---|
| 3601 | MOV EAX, Str
|
|---|
| 3602 | MOV Result, EAX
|
|---|
| 3603 | End;
|
|---|
| 3604 | End;
|
|---|
| 3605 |
|
|---|
| 3606 | Function StrUpper(Str: PChar): PChar;
|
|---|
| 3607 | Begin
|
|---|
| 3608 | Asm
|
|---|
| 3609 | CLD
|
|---|
| 3610 | MOV ESI, Str
|
|---|
| 3611 |
|
|---|
| 3612 | !StringUpper_Loop:
|
|---|
| 3613 |
|
|---|
| 3614 | LODSB
|
|---|
| 3615 | Or AL, AL
|
|---|
| 3616 | JE !OutStrUpper
|
|---|
| 3617 |
|
|---|
| 3618 | CMP AL, 'a'
|
|---|
| 3619 | JB !StringUpper_Loop
|
|---|
| 3620 | CMP AL, 'z'
|
|---|
| 3621 | JA !StringUpper_Loop
|
|---|
| 3622 | And AL, $DF
|
|---|
| 3623 | MOV [ESI-1], AL
|
|---|
| 3624 | JMP !StringUpper_Loop
|
|---|
| 3625 |
|
|---|
| 3626 | !OutStrUpper:
|
|---|
| 3627 |
|
|---|
| 3628 | MOV EAX, Str
|
|---|
| 3629 | MOV Result, EAX
|
|---|
| 3630 | End;
|
|---|
| 3631 | End;
|
|---|
| 3632 |
|
|---|
| 3633 | Function StrPas(Str: PChar): String;
|
|---|
| 3634 | Begin
|
|---|
| 3635 | Result := Str^;
|
|---|
| 3636 | End;
|
|---|
| 3637 |
|
|---|
| 3638 | Function StrAlloc(Size: Cardinal): PChar;
|
|---|
| 3639 | Type
|
|---|
| 3640 | PLong = ^LongInt;
|
|---|
| 3641 | Var
|
|---|
| 3642 | P: PChar;
|
|---|
| 3643 | Begin
|
|---|
| 3644 | GetMem(P, Size + 4);
|
|---|
| 3645 | PLong(P)^ := Size + 4;
|
|---|
| 3646 | Inc(P, 4);
|
|---|
| 3647 | StrAlloc := P;
|
|---|
| 3648 | End;
|
|---|
| 3649 |
|
|---|
| 3650 | Function StrBufSize(Str: PChar): Cardinal;
|
|---|
| 3651 | Type
|
|---|
| 3652 | PLong = ^LongInt;
|
|---|
| 3653 | Begin
|
|---|
| 3654 | Dec(Str, 4);
|
|---|
| 3655 | StrBufSize := PLong(Str)^ - 4;
|
|---|
| 3656 | End;
|
|---|
| 3657 |
|
|---|
| 3658 | Function StrNew(Str: PChar): PChar;
|
|---|
| 3659 | Var
|
|---|
| 3660 | Size: LongInt;
|
|---|
| 3661 | Begin
|
|---|
| 3662 | If Str = Nil Then StrNew := Nil
|
|---|
| 3663 | Else
|
|---|
| 3664 | Begin
|
|---|
| 3665 | Size := StrLen(Str) + 1;
|
|---|
| 3666 | StrNew := StrMove(StrAlloc(Size), Str, Size);
|
|---|
| 3667 | End;
|
|---|
| 3668 | End;
|
|---|
| 3669 |
|
|---|
| 3670 | Procedure StrDispose(Str: PChar);
|
|---|
| 3671 | Type
|
|---|
| 3672 | PLong = ^LongInt;
|
|---|
| 3673 | Begin
|
|---|
| 3674 | If Str <> Nil Then
|
|---|
| 3675 | If Str <> NullStr Then
|
|---|
| 3676 | Begin
|
|---|
| 3677 | Dec(Str, 4);
|
|---|
| 3678 | FreeMem(Str, PLong(Str)^);
|
|---|
| 3679 | End;
|
|---|
| 3680 | End;
|
|---|
| 3681 |
|
|---|
| 3682 | { --- String formatting --- }
|
|---|
| 3683 |
|
|---|
| 3684 | {$HINTS OFF}
|
|---|
| 3685 | Function FormatBuf(Var Buffer; BufLen: Cardinal; Const format; FmtLen: Cardinal; Const Args: Array Of Const): Cardinal;
|
|---|
| 3686 | Var
|
|---|
| 3687 | { format And Result buffers }
|
|---|
| 3688 |
|
|---|
| 3689 | FmtPos, OldFmtPos, BufPos, ArgPos: LongInt;
|
|---|
| 3690 | Buf: cstring Absolute Buffer;
|
|---|
| 3691 | Fmt: cstring Absolute format;
|
|---|
| 3692 |
|
|---|
| 3693 | { argument Buffer }
|
|---|
| 3694 |
|
|---|
| 3695 | VArgs: Array[0..1023] Of TVarRec Absolute Args;
|
|---|
| 3696 |
|
|---|
| 3697 | { Workaround For High() problem }
|
|---|
| 3698 |
|
|---|
| 3699 | High_Args: LongInt;
|
|---|
| 3700 |
|
|---|
| 3701 | { format Details }
|
|---|
| 3702 |
|
|---|
| 3703 | Index, Width, Precision: LongInt;
|
|---|
| 3704 | LeftAlign: Boolean;
|
|---|
| 3705 | ArgType: Char;
|
|---|
| 3706 |
|
|---|
| 3707 | { temporary variables }
|
|---|
| 3708 |
|
|---|
| 3709 | C: Char;
|
|---|
| 3710 | P: Pointer;
|
|---|
| 3711 | E: Extended;
|
|---|
| 3712 | Pnt,M:LongInt;
|
|---|
| 3713 | L: LongInt;
|
|---|
| 3714 | S: String[80];
|
|---|
| 3715 |
|
|---|
| 3716 | { Raise Exception: format And argument don't match }
|
|---|
| 3717 |
|
|---|
| 3718 | Procedure IllegalArg;
|
|---|
| 3719 | Begin
|
|---|
| 3720 | FmtLoadConvertError(SInvalidFormat, [ArgType]);
|
|---|
| 3721 | End;
|
|---|
| 3722 |
|
|---|
| 3723 | { Raise Exception: out Of arguments }
|
|---|
| 3724 |
|
|---|
| 3725 | Procedure OutOfArgs;
|
|---|
| 3726 | Begin
|
|---|
| 3727 | FmtLoadConvertError(SArgumentMissing, [ArgType]);
|
|---|
| 3728 | End;
|
|---|
| 3729 |
|
|---|
| 3730 | { Get an argument from the Open Array. If the
|
|---|
| 3731 | Type Is unexpected, Raise an Exception. }
|
|---|
| 3732 |
|
|---|
| 3733 | Function GetIntegerArg: LongInt;
|
|---|
| 3734 | Begin
|
|---|
| 3735 | If ArgPos > High_Args Then OutOfArgs;
|
|---|
| 3736 | If VArgs[ArgPos].VType <> vtInteger Then IllegalArg;
|
|---|
| 3737 | Result := VArgs[ArgPos].VInteger;
|
|---|
| 3738 | Inc(ArgPos);
|
|---|
| 3739 | End;
|
|---|
| 3740 |
|
|---|
| 3741 | Function GetExtendedArg: Extended;
|
|---|
| 3742 | Begin
|
|---|
| 3743 | If ArgPos > High_Args Then OutOfArgs;
|
|---|
| 3744 | If VArgs[ArgPos].VType <> vtExtended Then IllegalArg;
|
|---|
| 3745 | Result := VArgs[ArgPos].VExtended^;
|
|---|
| 3746 | Inc(ArgPos);
|
|---|
| 3747 | End;
|
|---|
| 3748 |
|
|---|
| 3749 | Function GetPointerArg: Pointer;
|
|---|
| 3750 | Begin
|
|---|
| 3751 | If ArgPos > High_Args Then OutOfArgs;
|
|---|
| 3752 | If VArgs[ArgPos].VType <> vtPointer Then IllegalArg;
|
|---|
| 3753 | Result := VArgs[ArgPos].VPointer;
|
|---|
| 3754 | Inc(ArgPos);
|
|---|
| 3755 | End;
|
|---|
| 3756 |
|
|---|
| 3757 | Procedure GetStringArg(Var FirstChar: Pointer; Var len: LongInt);
|
|---|
| 3758 | Begin
|
|---|
| 3759 | If ArgPos > High_Args Then OutOfArgs;
|
|---|
| 3760 | Case VArgs[ArgPos].VType Of
|
|---|
| 3761 | vtChar:
|
|---|
| 3762 | Begin
|
|---|
| 3763 | FirstChar := @VArgs[ArgPos].VChar;
|
|---|
| 3764 | len := 1;
|
|---|
| 3765 | End;
|
|---|
| 3766 |
|
|---|
| 3767 | vtString:
|
|---|
| 3768 | Begin
|
|---|
| 3769 | FirstChar := VArgs[ArgPos].VString;
|
|---|
| 3770 | len := Byte(FirstChar^);
|
|---|
| 3771 | Inc(FirstChar);
|
|---|
| 3772 | End;
|
|---|
| 3773 |
|
|---|
| 3774 | vtPointer,
|
|---|
| 3775 | vtPChar:
|
|---|
| 3776 | Begin
|
|---|
| 3777 | FirstChar := VArgs[ArgPos].VPChar;
|
|---|
| 3778 | len := StrLen(FirstChar);
|
|---|
| 3779 | End;
|
|---|
| 3780 |
|
|---|
| 3781 | vtAnsiString:
|
|---|
| 3782 | Begin
|
|---|
| 3783 | FirstChar := VArgs[ArgPos].VPChar;
|
|---|
| 3784 | len := Length(AnsiString(VArgs[ArgPos].VAnsiString));
|
|---|
| 3785 | End;
|
|---|
| 3786 | Else
|
|---|
| 3787 | IllegalArg;
|
|---|
| 3788 | End;
|
|---|
| 3789 | Inc(ArgPos);
|
|---|
| 3790 | End;
|
|---|
| 3791 |
|
|---|
| 3792 | { Parse A Number from the format String. A '*' means:
|
|---|
| 3793 | Get the Next Integer argument from the Open Array. }
|
|---|
| 3794 |
|
|---|
| 3795 | Function ParseNum: LongInt;
|
|---|
| 3796 | Begin
|
|---|
| 3797 | If Fmt[FmtPos] = '*' Then Result := GetIntegerArg
|
|---|
| 3798 | Else
|
|---|
| 3799 | Begin
|
|---|
| 3800 | Result := 0;
|
|---|
| 3801 | While (Fmt[FmtPos] In ['0'..'9']) And (FmtPos < FmtLen) Do
|
|---|
| 3802 | Begin
|
|---|
| 3803 | Result := Result * 10 + Ord(Fmt[FmtPos]) - 48;
|
|---|
| 3804 | Inc(FmtPos);
|
|---|
| 3805 | End;
|
|---|
| 3806 | End;
|
|---|
| 3807 | End;
|
|---|
| 3808 |
|
|---|
| 3809 | { Parse A whole format specifier. }
|
|---|
| 3810 |
|
|---|
| 3811 | Function ParseFmtSpec: Char;
|
|---|
| 3812 | Label
|
|---|
| 3813 | LIndex, LColon, LMinus, LWidth, LPoint, LType;
|
|---|
| 3814 | Begin
|
|---|
| 3815 | Width := -1;
|
|---|
| 3816 | Index := -1;
|
|---|
| 3817 | Precision := -1;
|
|---|
| 3818 | LeftAlign := False;
|
|---|
| 3819 | ArgType := #0;
|
|---|
| 3820 | C := Fmt[FmtPos];
|
|---|
| 3821 |
|
|---|
| 3822 | LIndex:
|
|---|
| 3823 |
|
|---|
| 3824 | If Not (C In ['0'..'9']) Then Goto LMinus;
|
|---|
| 3825 | Width := ParseNum;
|
|---|
| 3826 | If FmtPos >= FmtLen Then Exit;
|
|---|
| 3827 | C := Fmt[FmtPos];
|
|---|
| 3828 |
|
|---|
| 3829 | LColon:
|
|---|
| 3830 |
|
|---|
| 3831 | If C <> ':' Then Goto LPoint;
|
|---|
| 3832 | Index := Width;
|
|---|
| 3833 | Width := -1;
|
|---|
| 3834 | Inc(FmtPos);
|
|---|
| 3835 | If FmtPos >= FmtLen Then Exit;
|
|---|
| 3836 | C := Fmt[FmtPos];
|
|---|
| 3837 |
|
|---|
| 3838 | LMinus:
|
|---|
| 3839 |
|
|---|
| 3840 | If C <> '-' Then Goto LWidth;
|
|---|
| 3841 | LeftAlign := True;
|
|---|
| 3842 | Inc(FmtPos);
|
|---|
| 3843 | If FmtPos >= FmtLen Then Exit;
|
|---|
| 3844 | C := Fmt[FmtPos];
|
|---|
| 3845 |
|
|---|
| 3846 | LWidth:
|
|---|
| 3847 |
|
|---|
| 3848 | If Not (C In ['0'..'9']) Then Goto LPoint;
|
|---|
| 3849 | Width := ParseNum;
|
|---|
| 3850 | If FmtPos >= FmtLen Then Exit;
|
|---|
| 3851 | C := Fmt[FmtPos];
|
|---|
| 3852 |
|
|---|
| 3853 | LPoint:
|
|---|
| 3854 |
|
|---|
| 3855 | If C <> '.' Then Goto LType;
|
|---|
| 3856 | Inc(FmtPos);
|
|---|
| 3857 | Precision := ParseNum;
|
|---|
| 3858 | If FmtPos >= FmtLen Then Exit;
|
|---|
| 3859 | C := Fmt[FmtPos];
|
|---|
| 3860 |
|
|---|
| 3861 | LType:
|
|---|
| 3862 |
|
|---|
| 3863 | Result := UpCase(C);
|
|---|
| 3864 | ArgType := Result;
|
|---|
| 3865 |
|
|---|
| 3866 | {WriteLn;
|
|---|
| 3867 | WriteLn('Index:', Index, ' Align:', LeftAlign, ' Width:', Width, ' Prec: ', Precision, ' Type:', Result);
|
|---|
| 3868 | WriteLn;}
|
|---|
| 3869 |
|
|---|
| 3870 | Inc(FmtPos);
|
|---|
| 3871 | End;
|
|---|
| 3872 |
|
|---|
| 3873 | { Append something To the Result Buffer }
|
|---|
| 3874 |
|
|---|
| 3875 | Procedure AppendStr(P: Pointer; Count: LongInt);
|
|---|
| 3876 | Begin
|
|---|
| 3877 | If BufLen - BufPos < Count Then Count := BufLen - BufPos;
|
|---|
| 3878 | Move(P^, Buf[BufPos], Count);
|
|---|
| 3879 | Inc(BufPos, Count);
|
|---|
| 3880 | End;
|
|---|
| 3881 |
|
|---|
| 3882 | Procedure AppendChar(C: Char; Count: LongInt);
|
|---|
| 3883 | Begin
|
|---|
| 3884 | If BufLen - BufPos < Count Then Count := BufLen - BufPos;
|
|---|
| 3885 | FillChar(Buf[BufPos], Count, C);
|
|---|
| 3886 | Inc(BufPos, Count);
|
|---|
| 3887 | End;
|
|---|
| 3888 |
|
|---|
| 3889 | Begin
|
|---|
| 3890 | FmtPos := 0;
|
|---|
| 3891 | OldFmtPos := 0;
|
|---|
| 3892 | BufPos := 0;
|
|---|
| 3893 | ArgPos := 0;
|
|---|
| 3894 |
|
|---|
| 3895 | High_Args := High(Args);
|
|---|
| 3896 |
|
|---|
| 3897 | While (FmtPos < FmtLen) And (BufPos < BufLen) Do
|
|---|
| 3898 | Begin
|
|---|
| 3899 | C := Fmt[FmtPos];
|
|---|
| 3900 | Inc(FmtPos);
|
|---|
| 3901 | If C = '%' Then
|
|---|
| 3902 | Begin
|
|---|
| 3903 | C := ParseFmtSpec;
|
|---|
| 3904 | If C = 'S' Then
|
|---|
| 3905 | Begin
|
|---|
| 3906 | GetStringArg(P, L);
|
|---|
| 3907 | If (Precision > -1) And (Precision < L) Then L := Precision;
|
|---|
| 3908 | End
|
|---|
| 3909 | Else
|
|---|
| 3910 | Begin
|
|---|
| 3911 | Case C Of
|
|---|
| 3912 | 'D': Begin
|
|---|
| 3913 | Str(GetIntegerArg, S);
|
|---|
| 3914 | L := Length(S);
|
|---|
| 3915 | If (Precision <> -1) And (L < Precision) Then
|
|---|
| 3916 | Begin
|
|---|
| 3917 | SetLength(S, Precision);
|
|---|
| 3918 | Move(S[1], S[1 + Precision - L], L);
|
|---|
| 3919 | FillChar(S[1], Precision - L, '0');
|
|---|
| 3920 | End;
|
|---|
| 3921 | End;
|
|---|
| 3922 | 'E': S := FloatToStrF(GetExtendedArg, ffExponent, Precision, 3);
|
|---|
| 3923 | 'F': S := FloatToStrF(GetExtendedArg, ffFixed, 9999, Precision);
|
|---|
| 3924 | 'G': S := FloatToStrF(GetExtendedArg, ffGeneral, Precision, 3);
|
|---|
| 3925 | 'N': S := FloatToStrF(GetExtendedArg, ffFixed, 9999, Precision);
|
|---|
| 3926 | 'M': S := FloatToStrF(GetExtendedArg, ffCurrency, 9999, Precision);
|
|---|
| 3927 | 'P': Begin
|
|---|
| 3928 | L := LongInt(GetPointerArg);
|
|---|
| 3929 | S := IntToHex(L Shr 16, 4) + ':' + IntToHex(L And $FFFF, 4);
|
|---|
| 3930 | End;
|
|---|
| 3931 | 'X': Begin
|
|---|
| 3932 | If Precision <> -1 Then S := IntToHex(GetIntegerArg, Precision)
|
|---|
| 3933 | Else S := IntToHex(GetIntegerArg, 0);
|
|---|
| 3934 | End;
|
|---|
| 3935 | Else FmtLoadConvertError(SInvalidFormat, [C]);
|
|---|
| 3936 | End;
|
|---|
| 3937 | P := @S[1];
|
|---|
| 3938 | L := Length(S);
|
|---|
| 3939 | End;
|
|---|
| 3940 |
|
|---|
| 3941 | { now P Points To the First Char To Append To our Result, L holds the
|
|---|
| 3942 | Length Of the Text To Insert. If Width > L Then we have To pad our
|
|---|
| 3943 | Text With spaces. }
|
|---|
| 3944 |
|
|---|
| 3945 | If LeftAlign Then
|
|---|
| 3946 | Begin
|
|---|
| 3947 | AppendStr(P, L);
|
|---|
| 3948 | If (Width > -1) And (L < Width) Then AppendChar(' ', Width - L );
|
|---|
| 3949 | End
|
|---|
| 3950 | Else
|
|---|
| 3951 | Begin
|
|---|
| 3952 | If (Width > -1) And (L < Width) Then AppendChar(' ', Width - L );
|
|---|
| 3953 | AppendStr(P, L);
|
|---|
| 3954 | End;
|
|---|
| 3955 | End
|
|---|
| 3956 | Else
|
|---|
| 3957 | Begin
|
|---|
| 3958 | { Ordinary character }
|
|---|
| 3959 | Buf[BufPos] := C;
|
|---|
| 3960 | Inc(BufPos);
|
|---|
| 3961 | End;
|
|---|
| 3962 | OldFmtPos := FmtPos;
|
|---|
| 3963 | End;
|
|---|
| 3964 | Result := BufPos;
|
|---|
| 3965 | End;
|
|---|
| 3966 | {$HINTS ON}
|
|---|
| 3967 |
|
|---|
| 3968 |
|
|---|
| 3969 | Function format(Const format: String; Const Args: Array Of Const): String;
|
|---|
| 3970 | Begin
|
|---|
| 3971 | SetLength(Result, FormatBuf(Result[1], 255, format[1], Length(format), Args));
|
|---|
| 3972 | End;
|
|---|
| 3973 |
|
|---|
| 3974 | Procedure FmtStr(Var Result: String; Const format: String; Const Args: Array Of Const);
|
|---|
| 3975 | Begin
|
|---|
| 3976 | SetLength(Result, FormatBuf(Result[1], 255, format[1], Length(format), Args));
|
|---|
| 3977 | End;
|
|---|
| 3978 |
|
|---|
| 3979 | Function StrFmt(Buffer, format: PChar; Const Args: Array Of Const): PChar;
|
|---|
| 3980 | Begin
|
|---|
| 3981 | FormatBuf(Buffer, MaxLongInt, format, StrLen(format), Args);
|
|---|
| 3982 | Result := Buffer;
|
|---|
| 3983 | End;
|
|---|
| 3984 |
|
|---|
| 3985 | Function StrLFmt(Buffer: PChar; MaxLen: Cardinal; format: PChar; Const Args: Array Of Const): PChar;
|
|---|
| 3986 | Begin
|
|---|
| 3987 | FormatBuf(Buffer, MaxLen, format, StrLen(format), Args);
|
|---|
| 3988 | Result := Buffer;
|
|---|
| 3989 | End;
|
|---|
| 3990 |
|
|---|
| 3991 | { --- floating Point conversion --- }
|
|---|
| 3992 |
|
|---|
| 3993 | Function FloatToStr(Value: Extended): String;
|
|---|
| 3994 | Begin
|
|---|
| 3995 | Result := FloatToStrF(Value, ffGeneral, 15, 0);
|
|---|
| 3996 | End;
|
|---|
| 3997 |
|
|---|
| 3998 | Function FloatToStrF(Value: Extended; format: TFloatFormat; Precision, Digits: Integer): String;
|
|---|
| 3999 | Var
|
|---|
| 4000 | P: Integer;
|
|---|
| 4001 | Negative, TooSmall, TooLarge: Boolean;
|
|---|
| 4002 | Begin
|
|---|
| 4003 | Case format Of
|
|---|
| 4004 |
|
|---|
| 4005 | ffGeneral:
|
|---|
| 4006 |
|
|---|
| 4007 | Begin
|
|---|
| 4008 | If (Precision = -1) Or (Precision > 15) Then Precision := 15;
|
|---|
| 4009 | TooSmall := Abs(Value) < 0.00001;
|
|---|
| 4010 | If Not TooSmall Then
|
|---|
| 4011 | Begin
|
|---|
| 4012 | Str(Value:0:999, Result);
|
|---|
| 4013 | P := Pos('.', Result);
|
|---|
| 4014 | Result[P] := DecimalSeparator;
|
|---|
| 4015 | TooLarge := P > Precision + 1;
|
|---|
| 4016 | End;
|
|---|
| 4017 |
|
|---|
| 4018 | If TooSmall Or TooLarge Then
|
|---|
| 4019 | Result := FloatToStrF(Value, ffExponent, Precision, Digits);
|
|---|
| 4020 |
|
|---|
| 4021 | P := Length(Result);
|
|---|
| 4022 | While Result[P] = '0' Do Dec(P);
|
|---|
| 4023 | If Result[P] = DecimalSeparator Then Dec(P);
|
|---|
| 4024 | SetLength(Result, P);
|
|---|
| 4025 | End;
|
|---|
| 4026 |
|
|---|
| 4027 | ffExponent:
|
|---|
| 4028 |
|
|---|
| 4029 | Begin
|
|---|
| 4030 | If (Precision = -1) Or (Precision > 15) Then Precision := 15;
|
|---|
| 4031 | Str(Value:Precision + 8, Result);
|
|---|
| 4032 | Result[3] := DecimalSeparator;
|
|---|
| 4033 | If (Digits < 4) And (Result[Precision + 5] = '0') Then
|
|---|
| 4034 | Begin
|
|---|
| 4035 | Delete(Result, Precision + 5, 1);
|
|---|
| 4036 | If (Digits < 3) And (Result[Precision + 5] = '0') Then
|
|---|
| 4037 | Begin
|
|---|
| 4038 | Delete(Result, Precision + 5, 1);
|
|---|
| 4039 | If (Digits < 2) And (Result[Precision + 5] = '0') Then
|
|---|
| 4040 | Begin
|
|---|
| 4041 | Delete(Result, Precision + 5, 1);
|
|---|
| 4042 | If (Digits < 1) And (Result[Precision + 5] = '0') Then Delete(Result, Precision + 3, 3);
|
|---|
| 4043 | End;
|
|---|
| 4044 | End;
|
|---|
| 4045 | End;
|
|---|
| 4046 | If Result[1] = ' ' Then Delete(Result, 1, 1);
|
|---|
| 4047 | End;
|
|---|
| 4048 |
|
|---|
| 4049 | ffFixed:
|
|---|
| 4050 |
|
|---|
| 4051 | Begin
|
|---|
| 4052 | If Digits = -1 Then Digits := 2
|
|---|
| 4053 | Else If Digits > 15 Then Digits := 15;
|
|---|
| 4054 | Str(Value:0:Digits, Result);
|
|---|
| 4055 | If Result[1] = ' ' Then Delete(Result, 1, 1);
|
|---|
| 4056 | P := Pos('.', Result);
|
|---|
| 4057 | If P <> 0 Then Result[P] := DecimalSeparator;
|
|---|
| 4058 | End;
|
|---|
| 4059 |
|
|---|
| 4060 | ffNumber:
|
|---|
| 4061 |
|
|---|
| 4062 | Begin
|
|---|
| 4063 | If Digits = -1 Then Digits := 2
|
|---|
| 4064 | Else If Digits > 15 Then Digits := 15;
|
|---|
| 4065 | Str(Value:0:Digits, Result);
|
|---|
| 4066 | If Result[1] = ' ' Then Delete(Result, 1, 1);
|
|---|
| 4067 | P := Pos('.', Result);
|
|---|
| 4068 | If P <> 0 Then Result[P] := DecimalSeparator;
|
|---|
| 4069 | Dec(P, 3);
|
|---|
| 4070 | While (P > 1) Do
|
|---|
| 4071 | Begin
|
|---|
| 4072 | If Result[P - 1] <> '-' Then Insert(ThousandSeparator, Result, P);
|
|---|
| 4073 | Dec(P, 3);
|
|---|
| 4074 | End;
|
|---|
| 4075 | End;
|
|---|
| 4076 |
|
|---|
| 4077 | ffCurrency:
|
|---|
| 4078 |
|
|---|
| 4079 | Begin
|
|---|
| 4080 | If Value < 0 Then
|
|---|
| 4081 | Begin
|
|---|
| 4082 | Negative := True;
|
|---|
| 4083 | Value := -Value;
|
|---|
| 4084 | End
|
|---|
| 4085 | Else Negative := False;
|
|---|
| 4086 |
|
|---|
| 4087 | If Digits = -1 Then Digits := CurrencyDecimals
|
|---|
| 4088 | Else If Digits > 15 Then Digits := 15;
|
|---|
| 4089 | Str(Value:0:Digits, Result);
|
|---|
| 4090 | If Result[1] = ' ' Then Delete(Result, 1, 1);
|
|---|
| 4091 | P := Pos('.', Result);
|
|---|
| 4092 | If P <> 0 Then Result[P] := DecimalSeparator;
|
|---|
| 4093 | Dec(P, 3);
|
|---|
| 4094 | While (P > 1) Do
|
|---|
| 4095 | Begin
|
|---|
| 4096 | Insert(ThousandSeparator, Result, P);
|
|---|
| 4097 | Dec(P, 3);
|
|---|
| 4098 | End;
|
|---|
| 4099 |
|
|---|
| 4100 | If Not Negative Then
|
|---|
| 4101 | Begin
|
|---|
| 4102 | Case CurrencyFormat Of
|
|---|
| 4103 | 0: Result := CurrencyString + Result;
|
|---|
| 4104 | 1: Result := Result + CurrencyString;
|
|---|
| 4105 | 2: Result := CurrencyString + ' ' + Result;
|
|---|
| 4106 | 3: Result := Result + ' ' + CurrencyString;
|
|---|
| 4107 | End
|
|---|
| 4108 | End
|
|---|
| 4109 | Else
|
|---|
| 4110 | Begin
|
|---|
| 4111 | Case NegCurrFormat Of
|
|---|
| 4112 | 0: Result := '(' + CurrencyString + Result + ')';
|
|---|
| 4113 | 1: Result := '-' + CurrencyString + Result;
|
|---|
| 4114 | 2: Result := CurrencyString + '-' + Result;
|
|---|
| 4115 | 3: Result := CurrencyString + Result + '-';
|
|---|
| 4116 | 4: Result := '(' + Result + CurrencyString + ')';
|
|---|
| 4117 | 5: Result := '-' + Result + CurrencyString;
|
|---|
| 4118 | 6: Result := Result + '-' + CurrencyString;
|
|---|
| 4119 | 7: Result := Result + CurrencyString + '-';
|
|---|
| 4120 | 8: Result := '-' + Result + ' ' + CurrencyString;
|
|---|
| 4121 | 9: Result := '-' + CurrencyString + ' ' + Result;
|
|---|
| 4122 | 10: Result := CurrencyString + ' ' + Result + '-';
|
|---|
| 4123 | End;
|
|---|
| 4124 | End;
|
|---|
| 4125 | End;
|
|---|
| 4126 | End;
|
|---|
| 4127 | End;
|
|---|
| 4128 |
|
|---|
| 4129 | Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat; Precision, Digits: Integer): Integer;
|
|---|
| 4130 | Var
|
|---|
| 4131 | Tmp: String[40];
|
|---|
| 4132 | Begin
|
|---|
| 4133 | Tmp := FloatToStrF(Value, format, Precision, Digits);
|
|---|
| 4134 | Result := Length(Tmp);
|
|---|
| 4135 | Move(Tmp[1], Buffer[0], Result);
|
|---|
| 4136 | End;
|
|---|
| 4137 |
|
|---|
| 4138 | Function StrToFloat(Const S: String): Extended;
|
|---|
| 4139 | Var
|
|---|
| 4140 | Error: Integer;
|
|---|
| 4141 | Tmp: String;
|
|---|
| 4142 | P: Integer;
|
|---|
| 4143 | Begin
|
|---|
| 4144 | Tmp := S;
|
|---|
| 4145 | P := Pos(DecimalSeparator, Tmp);
|
|---|
| 4146 | If P <> 0 Then Tmp[P] := '.';
|
|---|
| 4147 | Val(Tmp, Result, Error);
|
|---|
| 4148 | If Error <> 0 Then FmtLoadConvertError(SInvalidFloat, [S]);
|
|---|
| 4149 | End;
|
|---|
| 4150 |
|
|---|
| 4151 | Function TextToFloat(Buffer: PChar; Var Value: Extended): Boolean;
|
|---|
| 4152 | Var
|
|---|
| 4153 | Error: Integer;
|
|---|
| 4154 | Tmp: String;
|
|---|
| 4155 | P: Integer;
|
|---|
| 4156 | Begin
|
|---|
| 4157 | Tmp := StrPas(Buffer);
|
|---|
| 4158 | P := Pos(DecimalSeparator, Tmp);
|
|---|
| 4159 | If P <> 0 Then Tmp[P] := '.';
|
|---|
| 4160 | Val(Tmp, Value, Error);
|
|---|
| 4161 | Result := (Error = 0);
|
|---|
| 4162 | End;
|
|---|
| 4163 |
|
|---|
| 4164 | Function FloatToTextFmt(Buffer: PChar; Value: Extended; format: PChar): Integer;
|
|---|
| 4165 | Var
|
|---|
| 4166 | Digits: String[40]; { String Of Digits }
|
|---|
| 4167 | Exponent: String[8]; { Exponent strin }
|
|---|
| 4168 | FmtStart, FmtStop: PChar; { Start And End Of relevant part }
|
|---|
| 4169 | { Of format String }
|
|---|
| 4170 | ExpFmt, ExpSize: Integer; { Type And Length Of }
|
|---|
| 4171 | { exponential format chosen }
|
|---|
| 4172 | Placehold: Array[1..4] Of Integer; { Number Of placeholders In All }
|
|---|
| 4173 | { four Sections }
|
|---|
| 4174 | thousand: Boolean; { thousand separators? }
|
|---|
| 4175 | UnexpectedDigits: Integer; { Number Of unexpected Digits that }
|
|---|
| 4176 | { have To be inserted before the }
|
|---|
| 4177 | { First placeholder. }
|
|---|
| 4178 | DigitExponent: Integer; { Exponent Of First digit In }
|
|---|
| 4179 | { Digits Array. }
|
|---|
| 4180 |
|
|---|
| 4181 | { Find end of format section starting at P. False, if empty }
|
|---|
| 4182 |
|
|---|
| 4183 | Function GetSectionEnd(Var P: PChar): Boolean;
|
|---|
| 4184 | Var
|
|---|
| 4185 | C: Char;
|
|---|
| 4186 | SQ, DQ: Boolean;
|
|---|
| 4187 | Begin
|
|---|
| 4188 | Result := False;
|
|---|
| 4189 | SQ := False;
|
|---|
| 4190 | DQ := False;
|
|---|
| 4191 | C := P[0];
|
|---|
| 4192 | While (C <> #0) And ((C <> ';') Or SQ Or DQ) Do
|
|---|
| 4193 | Begin
|
|---|
| 4194 | Result := True;
|
|---|
| 4195 | Case C Of
|
|---|
| 4196 | #34: If Not SQ Then DQ := Not DQ;
|
|---|
| 4197 | #39: If Not DQ Then SQ := Not SQ;
|
|---|
| 4198 | End;
|
|---|
| 4199 | Inc(P);
|
|---|
| 4200 | C := P[0];
|
|---|
| 4201 | End;
|
|---|
| 4202 | End;
|
|---|
| 4203 |
|
|---|
| 4204 | { Find start and end of format section to apply. If section doesn't exist,
|
|---|
| 4205 | use section 1. If section 2 is used, the sign of value is ignored. }
|
|---|
| 4206 |
|
|---|
| 4207 | Procedure GetSectionRange(section: Integer);
|
|---|
| 4208 | Var
|
|---|
| 4209 | Sec: Array[1..3] Of PChar;
|
|---|
| 4210 | SecOk: Array[1..3] Of Boolean;
|
|---|
| 4211 | Begin
|
|---|
| 4212 | Sec[1] := format;
|
|---|
| 4213 | SecOk[1] := GetSectionEnd(Sec[1]);
|
|---|
| 4214 | If section > 1 Then
|
|---|
| 4215 | Begin
|
|---|
| 4216 | Sec[2] := Sec[1];
|
|---|
| 4217 | If Sec[2][0] <> #0 Then Inc(Sec[2]);
|
|---|
| 4218 | SecOk[2] := GetSectionEnd(Sec[2]);
|
|---|
| 4219 | If section > 2 Then
|
|---|
| 4220 | Begin
|
|---|
| 4221 | Sec[3] := Sec[2];
|
|---|
| 4222 | If Sec[3][0] <> #0 Then Inc(Sec[3]);
|
|---|
| 4223 | SecOk[3] := GetSectionEnd(Sec[3]);
|
|---|
| 4224 | End;
|
|---|
| 4225 | End;
|
|---|
| 4226 | If Not SecOk[1] Then FmtStart := Nil
|
|---|
| 4227 | Else
|
|---|
| 4228 | Begin
|
|---|
| 4229 | If Not SecOk[section] Then section := 1
|
|---|
| 4230 | Else If section = 2 Then Value := -Value; { Remove sign }
|
|---|
| 4231 | If section = 1 Then FmtStart := format Else
|
|---|
| 4232 | Begin
|
|---|
| 4233 | FmtStart := Sec[section - 1];
|
|---|
| 4234 | Inc(FmtStart);
|
|---|
| 4235 | End;
|
|---|
| 4236 | FmtStop := Sec[section];
|
|---|
| 4237 | End;
|
|---|
| 4238 | End;
|
|---|
| 4239 |
|
|---|
| 4240 | { Find format section ranging from FmtStart to FmtStop. }
|
|---|
| 4241 |
|
|---|
| 4242 | Procedure GetFormatOptions;
|
|---|
| 4243 | Var
|
|---|
| 4244 | Fmt: PChar;
|
|---|
| 4245 | SQ, DQ: Boolean;
|
|---|
| 4246 | area: Integer;
|
|---|
| 4247 | Begin
|
|---|
| 4248 | SQ := False;
|
|---|
| 4249 | DQ := False;
|
|---|
| 4250 | Fmt := FmtStart;
|
|---|
| 4251 | ExpFmt := 0;
|
|---|
| 4252 | area := 1;
|
|---|
| 4253 | thousand := False;
|
|---|
| 4254 | Placehold[1] := 0;
|
|---|
| 4255 | Placehold[2] := 0;
|
|---|
| 4256 | Placehold[3] := 0;
|
|---|
| 4257 | Placehold[4] := 0;
|
|---|
| 4258 |
|
|---|
| 4259 | While Fmt < FmtStop Do
|
|---|
| 4260 | Begin
|
|---|
| 4261 | Case Fmt[0] Of
|
|---|
| 4262 | #34:
|
|---|
| 4263 | Begin
|
|---|
| 4264 | If Not SQ Then DQ := Not DQ;
|
|---|
| 4265 | Inc(Fmt);
|
|---|
| 4266 | End;
|
|---|
| 4267 |
|
|---|
| 4268 | #39:
|
|---|
| 4269 | Begin
|
|---|
| 4270 | If Not DQ Then SQ := Not SQ;
|
|---|
| 4271 | Inc(Fmt);
|
|---|
| 4272 | End;
|
|---|
| 4273 |
|
|---|
| 4274 | Else
|
|---|
| 4275 | { This was 'if not SQ or DQ'. Looked wrong... }
|
|---|
| 4276 | If Not SQ Or DQ Then
|
|---|
| 4277 | Begin
|
|---|
| 4278 | Case Fmt[0] Of
|
|---|
| 4279 | '0':
|
|---|
| 4280 | Begin
|
|---|
| 4281 | Case area Of
|
|---|
| 4282 | 1:
|
|---|
| 4283 | area := 2;
|
|---|
| 4284 | 4:
|
|---|
| 4285 | Begin
|
|---|
| 4286 | area := 3;
|
|---|
| 4287 | Inc(Placehold[3], Placehold[4]);
|
|---|
| 4288 | Placehold[4] := 0;
|
|---|
| 4289 | End;
|
|---|
| 4290 | End;
|
|---|
| 4291 | Inc(Placehold[area]);
|
|---|
| 4292 | Inc(Fmt);
|
|---|
| 4293 | End;
|
|---|
| 4294 |
|
|---|
| 4295 | '#':
|
|---|
| 4296 | Begin
|
|---|
| 4297 | If area = 3 Then area := 4;
|
|---|
| 4298 | Inc(Placehold[area]);
|
|---|
| 4299 | Inc(Fmt);
|
|---|
| 4300 | End;
|
|---|
| 4301 |
|
|---|
| 4302 | '.':
|
|---|
| 4303 | Begin
|
|---|
| 4304 | If area < 3 Then area := 3;
|
|---|
| 4305 | Inc(Fmt);
|
|---|
| 4306 | End;
|
|---|
| 4307 |
|
|---|
| 4308 | ',':
|
|---|
| 4309 | Begin
|
|---|
| 4310 | thousand := True;
|
|---|
| 4311 | Inc(Fmt);
|
|---|
| 4312 | End;
|
|---|
| 4313 |
|
|---|
| 4314 | 'e', 'E':
|
|---|
| 4315 | If ExpFmt = 0 Then
|
|---|
| 4316 | Begin
|
|---|
| 4317 | If Fmt[0] = 'E' Then ExpFmt := 1 Else ExpFmt := 3;
|
|---|
| 4318 | Inc(Fmt);
|
|---|
| 4319 | If Fmt < FmtStop Then
|
|---|
| 4320 | Begin
|
|---|
| 4321 | Case Fmt[0] Of
|
|---|
| 4322 | '+':
|
|---|
| 4323 | Begin
|
|---|
| 4324 | End;
|
|---|
| 4325 |
|
|---|
| 4326 | '-':
|
|---|
| 4327 | Inc(ExpFmt);
|
|---|
| 4328 |
|
|---|
| 4329 | Else
|
|---|
| 4330 | ExpFmt := 0;
|
|---|
| 4331 | End;
|
|---|
| 4332 |
|
|---|
| 4333 | If ExpFmt <> 0 Then
|
|---|
| 4334 | Begin
|
|---|
| 4335 | Inc(Fmt);
|
|---|
| 4336 | ExpSize := 0;
|
|---|
| 4337 | While (Fmt < FmtStop) And (ExpSize < 4) And (Fmt[0] In ['0'..'9']) Do
|
|---|
| 4338 | Begin
|
|---|
| 4339 | Inc(ExpSize);
|
|---|
| 4340 | Inc(Fmt);
|
|---|
| 4341 | End;
|
|---|
| 4342 | End;
|
|---|
| 4343 | End;
|
|---|
| 4344 | End
|
|---|
| 4345 | Else Inc(Fmt);
|
|---|
| 4346 |
|
|---|
| 4347 | Else { Case }
|
|---|
| 4348 | Inc(Fmt);
|
|---|
| 4349 | End; { Case }
|
|---|
| 4350 | End; { Begin }
|
|---|
| 4351 | End; { Case }
|
|---|
| 4352 | End; { While .. Begin }
|
|---|
| 4353 | End;
|
|---|
| 4354 |
|
|---|
| 4355 | Procedure FloatToStr;
|
|---|
| 4356 | Var
|
|---|
| 4357 | I, J, Exp, Width, Decimals, DecimalPoint, len: Integer;
|
|---|
| 4358 | Begin
|
|---|
| 4359 | If ExpFmt = 0 Then
|
|---|
| 4360 | Begin
|
|---|
| 4361 | { Fixpoint }
|
|---|
| 4362 | Decimals := Placehold[3] + Placehold[4];
|
|---|
| 4363 | Width := Placehold[1] + Placehold[2] + Decimals;
|
|---|
| 4364 |
|
|---|
| 4365 | If Decimals = 0 Then Str(Value: Width: 0, Digits)
|
|---|
| 4366 | Else Str(Value: Width + 1: Decimals, Digits);
|
|---|
| 4367 |
|
|---|
| 4368 | len := Length(Digits);
|
|---|
| 4369 |
|
|---|
| 4370 | { Find the decimal point }
|
|---|
| 4371 | If Decimals = 0 Then DecimalPoint := len + 1 Else DecimalPoint := len - Decimals;
|
|---|
| 4372 |
|
|---|
| 4373 | { If value is very small, and no decimal places
|
|---|
| 4374 | are desired, remove the leading 0. }
|
|---|
| 4375 | If (Abs(Value) < 1) And (Placehold[2] = 0) Then
|
|---|
| 4376 | Begin
|
|---|
| 4377 | If Placehold[1] = 0 Then Delete(Digits, DecimalPoint - 1, 1)
|
|---|
| 4378 | Else Digits[DecimalPoint - 1] := ' ';
|
|---|
| 4379 | End;
|
|---|
| 4380 |
|
|---|
| 4381 | { Convert optional zeroes to spaces. }
|
|---|
| 4382 | I := len;
|
|---|
| 4383 | J := DecimalPoint + Placehold[3];
|
|---|
| 4384 | While (I > J) And (Digits[I] = '0') Do
|
|---|
| 4385 | Begin
|
|---|
| 4386 | Digits[I] := ' ';
|
|---|
| 4387 | Dec(I);
|
|---|
| 4388 | End;
|
|---|
| 4389 |
|
|---|
| 4390 | { If integer value and no obligatory decimal
|
|---|
| 4391 | places, remove decimal point. }
|
|---|
| 4392 |
|
|---|
| 4393 | If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then
|
|---|
| 4394 | Digits[DecimalPoint] := ' ';
|
|---|
| 4395 |
|
|---|
| 4396 | { Convert spaces left from obligatory decimal point to zeroes. }
|
|---|
| 4397 |
|
|---|
| 4398 | I := DecimalPoint - Placehold[2];
|
|---|
| 4399 | While (I < DecimalPoint) And (Digits[I] = ' ') Do
|
|---|
| 4400 | Begin
|
|---|
| 4401 | Digits[I] := '0';
|
|---|
| 4402 | Inc(I);
|
|---|
| 4403 | End;
|
|---|
| 4404 |
|
|---|
| 4405 | Exp := 0;
|
|---|
| 4406 | End
|
|---|
| 4407 | Else
|
|---|
| 4408 | Begin
|
|---|
| 4409 | { Scientific: exactly <Width> Digits With <Precision> Decimals
|
|---|
| 4410 | And adjusted Exponent. }
|
|---|
| 4411 | If Placehold[1] + Placehold[2] = 0 Then Placehold[1] := 1;
|
|---|
| 4412 |
|
|---|
| 4413 | Decimals := Placehold[3] + Placehold[4];
|
|---|
| 4414 | Width := Placehold[1] + Placehold[2] + Decimals;
|
|---|
| 4415 |
|
|---|
| 4416 | Str(Value: Width + 8, Digits);
|
|---|
| 4417 |
|
|---|
| 4418 | //WriteLn('Digits: ', Digits);
|
|---|
| 4419 |
|
|---|
| 4420 | { Find and cut out exponent. Always the
|
|---|
| 4421 | last 6 characters in the string.
|
|---|
| 4422 | -> 0000E+0000 }
|
|---|
| 4423 |
|
|---|
| 4424 | I := Length(Digits) - 5;
|
|---|
| 4425 |
|
|---|
| 4426 | Val(Copy(Digits, I + 1, 5), Exp, J);
|
|---|
| 4427 |
|
|---|
| 4428 | //WriteLn('Exp: ', Exp);
|
|---|
| 4429 |
|
|---|
| 4430 | Exp := Exp + 1 - (Placehold[1] + Placehold[2]);
|
|---|
| 4431 | Delete(Digits, I, 6);
|
|---|
| 4432 |
|
|---|
| 4433 | //WriteLn('Exp: ', Exp);
|
|---|
| 4434 |
|
|---|
| 4435 | { Str() always returns at least one digit after the decimal point.
|
|---|
| 4436 | If we don't want it, we have to remove it. }
|
|---|
| 4437 | If (Decimals = 0) And (Placehold[1] + Placehold[2] <= 1) Then
|
|---|
| 4438 | Begin
|
|---|
| 4439 | If Digits[4] >= '5' Then
|
|---|
| 4440 | Begin
|
|---|
| 4441 | Inc(Digits[2]);
|
|---|
| 4442 | If Digits[2] > '9' Then
|
|---|
| 4443 | Begin
|
|---|
| 4444 | Digits[2] := '1';
|
|---|
| 4445 | Inc(Exp);
|
|---|
| 4446 | End;
|
|---|
| 4447 | End;
|
|---|
| 4448 | Delete(Digits, 3, 2);
|
|---|
| 4449 | DecimalPoint := Length(Digits) + 1;
|
|---|
| 4450 | End
|
|---|
| 4451 | Else
|
|---|
| 4452 | Begin
|
|---|
| 4453 | //WriteLn(Digits);
|
|---|
| 4454 |
|
|---|
| 4455 | { Move decimal point at the desired position }
|
|---|
| 4456 | Delete(Digits, 3, 1);
|
|---|
| 4457 | DecimalPoint := 2 + Placehold[1] + Placehold[2];
|
|---|
| 4458 | If Decimals <> 0 Then Insert('.', Digits, DecimalPoint);
|
|---|
| 4459 | End;
|
|---|
| 4460 |
|
|---|
| 4461 | //WriteLn(Digits);
|
|---|
| 4462 |
|
|---|
| 4463 | { Convert optional zeroes to spaces. }
|
|---|
| 4464 | I := Length(Digits);
|
|---|
| 4465 | J := DecimalPoint + Placehold[3];
|
|---|
| 4466 | While (I > J) And (Digits[I] = '0') Do
|
|---|
| 4467 | Begin
|
|---|
| 4468 | Digits[I] := ' ';
|
|---|
| 4469 | Dec(I);
|
|---|
| 4470 | End;
|
|---|
| 4471 |
|
|---|
| 4472 | { If integer number and no obligatory decimal paces, remove decimal point }
|
|---|
| 4473 |
|
|---|
| 4474 | If (DecimalPoint < Length(Digits)) And (Digits[DecimalPoint + 1] = ' ') Then
|
|---|
| 4475 | Digits[DecimalPoint] := ' ';
|
|---|
| 4476 |
|
|---|
| 4477 | If Digits[1] = ' ' Then
|
|---|
| 4478 | Begin
|
|---|
| 4479 | Delete(Digits, 1, 1);
|
|---|
| 4480 | Dec(DecimalPoint);
|
|---|
| 4481 | End;
|
|---|
| 4482 |
|
|---|
| 4483 | { Calculate exponent string }
|
|---|
| 4484 | Str(Abs(Exp), Exponent);
|
|---|
| 4485 | While Length(Exponent) < ExpSize Do Insert('0', Exponent, 1);
|
|---|
| 4486 | If Exp >= 0 Then
|
|---|
| 4487 | Begin
|
|---|
| 4488 | If ExpFmt In [1, 3] Then Insert('+', Exponent, 1);
|
|---|
| 4489 | End
|
|---|
| 4490 | Else Insert('-', Exponent, 1);
|
|---|
| 4491 | If ExpFmt < 3 Then Insert('E', Exponent, 1) Else Insert('e', Exponent, 1);
|
|---|
| 4492 | End;
|
|---|
| 4493 |
|
|---|
| 4494 | DigitExponent := DecimalPoint - 2;
|
|---|
| 4495 | If Digits[1] = '-' Then Dec(DigitExponent);
|
|---|
| 4496 |
|
|---|
| 4497 | UnexpectedDigits := DecimalPoint - 1 - (Placehold[1] + Placehold[2]);
|
|---|
| 4498 | End;
|
|---|
| 4499 |
|
|---|
| 4500 | Function PutResult: LongInt;
|
|---|
| 4501 | Var
|
|---|
| 4502 | SQ, DQ: Boolean;
|
|---|
| 4503 | Fmt, Buf: PChar;
|
|---|
| 4504 | Dig, N: Integer;
|
|---|
| 4505 | Begin
|
|---|
| 4506 | SQ := False;
|
|---|
| 4507 | DQ := False;
|
|---|
| 4508 | Fmt := FmtStart;
|
|---|
| 4509 | Buf := Buffer;
|
|---|
| 4510 | Dig := 1;
|
|---|
| 4511 |
|
|---|
| 4512 | //WriteLn('Putting result: ');
|
|---|
| 4513 |
|
|---|
| 4514 | While Fmt < FmtStop Do
|
|---|
| 4515 | Begin
|
|---|
| 4516 | //Write(Fmt[0]);
|
|---|
| 4517 |
|
|---|
| 4518 | Case Fmt[0] Of
|
|---|
| 4519 | #34:
|
|---|
| 4520 | Begin
|
|---|
| 4521 | If Not SQ Then DQ := Not DQ;
|
|---|
| 4522 | Inc(Fmt);
|
|---|
| 4523 | End;
|
|---|
| 4524 |
|
|---|
| 4525 | #39:
|
|---|
| 4526 | Begin
|
|---|
| 4527 | If Not DQ Then SQ := Not SQ;
|
|---|
| 4528 | Inc(Fmt);
|
|---|
| 4529 | End;
|
|---|
| 4530 |
|
|---|
| 4531 | Else
|
|---|
| 4532 |
|
|---|
| 4533 | If Not (SQ Or DQ) Then
|
|---|
| 4534 | Begin
|
|---|
| 4535 | Case Fmt[0] Of
|
|---|
| 4536 | '0', '#', '.':
|
|---|
| 4537 | Begin
|
|---|
| 4538 | If (Dig = 1) And (UnexpectedDigits > 0) Then
|
|---|
| 4539 | Begin
|
|---|
| 4540 | { Everything unexpected is written before the first digit }
|
|---|
| 4541 | For N := 1 To UnexpectedDigits Do
|
|---|
| 4542 | Begin
|
|---|
| 4543 | Buf[0] := Digits[N];
|
|---|
| 4544 | Inc(Buf);
|
|---|
| 4545 | If thousand And (Digits[N] <> '-') Then
|
|---|
| 4546 | Begin
|
|---|
| 4547 | If (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then
|
|---|
| 4548 | Begin
|
|---|
| 4549 | Buf[0] := ThousandSeparator;
|
|---|
| 4550 | Inc(Buf);
|
|---|
| 4551 | End;
|
|---|
| 4552 | Dec(DigitExponent);
|
|---|
| 4553 | End;
|
|---|
| 4554 | End;
|
|---|
| 4555 | Inc(Dig, UnexpectedDigits);
|
|---|
| 4556 | End;
|
|---|
| 4557 |
|
|---|
| 4558 | If Digits[Dig] <> ' ' Then
|
|---|
| 4559 | Begin
|
|---|
| 4560 | If Digits[Dig] = '.' Then Buf[0] := DecimalSeparator
|
|---|
| 4561 | Else Buf[0] := Digits[Dig];
|
|---|
| 4562 | Inc(Buf);
|
|---|
| 4563 | If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then
|
|---|
| 4564 | Begin
|
|---|
| 4565 | Buf[0] := ThousandSeparator;
|
|---|
| 4566 | Inc(Buf);
|
|---|
| 4567 | End;
|
|---|
| 4568 | End;
|
|---|
| 4569 | Inc(Dig);
|
|---|
| 4570 | Dec(DigitExponent);
|
|---|
| 4571 | Inc(Fmt);
|
|---|
| 4572 | End;
|
|---|
| 4573 |
|
|---|
| 4574 | 'e', 'E':
|
|---|
| 4575 | Begin
|
|---|
| 4576 | If ExpFmt <> 0 Then
|
|---|
| 4577 | Begin
|
|---|
| 4578 | Inc(Fmt);
|
|---|
| 4579 | If Fmt < FmtStop Then
|
|---|
| 4580 | Begin
|
|---|
| 4581 | If Fmt[0] In ['+', '-'] Then
|
|---|
| 4582 | Begin
|
|---|
| 4583 | Inc(Fmt, ExpSize);
|
|---|
| 4584 |
|
|---|
| 4585 | //WriteLn('Exponent: ', Exponent);
|
|---|
| 4586 |
|
|---|
| 4587 | For N := 1 To Length(Exponent) Do Buf[N - 1] := Exponent[N];
|
|---|
| 4588 | Inc(Buf, Length(Exponent));
|
|---|
| 4589 | ExpFmt := 0;
|
|---|
| 4590 | End;
|
|---|
| 4591 | Inc(Fmt);
|
|---|
| 4592 | End;
|
|---|
| 4593 | End
|
|---|
| 4594 | Else
|
|---|
| 4595 | Begin
|
|---|
| 4596 | { No legal exponential format. Simply write
|
|---|
| 4597 | the 'E' to the reult. }
|
|---|
| 4598 | Buf[0] := Fmt[0];
|
|---|
| 4599 | Inc(Buf);
|
|---|
| 4600 | Inc(Fmt);
|
|---|
| 4601 | End;
|
|---|
| 4602 | End;
|
|---|
| 4603 |
|
|---|
| 4604 | Else
|
|---|
| 4605 | { Usual character }
|
|---|
| 4606 | If Fmt[0] <> ',' Then
|
|---|
| 4607 | Begin
|
|---|
| 4608 | Buf[0] := Fmt[0];
|
|---|
| 4609 | Inc(Buf);
|
|---|
| 4610 | End;
|
|---|
| 4611 | Inc(Fmt);
|
|---|
| 4612 | End; { Case }
|
|---|
| 4613 | End
|
|---|
| 4614 |
|
|---|
| 4615 | Else { IF }
|
|---|
| 4616 |
|
|---|
| 4617 | Begin
|
|---|
| 4618 | { Character inside single or double quotes }
|
|---|
| 4619 | Buf[0] := Fmt[0];
|
|---|
| 4620 | Inc(Buf);
|
|---|
| 4621 | Inc(Fmt);
|
|---|
| 4622 | End;
|
|---|
| 4623 | End; { Case }
|
|---|
| 4624 | End; { While .. Begin }
|
|---|
| 4625 |
|
|---|
| 4626 | //WriteLn;
|
|---|
| 4627 |
|
|---|
| 4628 | Result := LongInt(Buf) - LongInt(Buffer);
|
|---|
| 4629 | End;
|
|---|
| 4630 |
|
|---|
| 4631 | Begin
|
|---|
| 4632 | If Value > 0 Then GetSectionRange(1)
|
|---|
| 4633 | Else If Value < 0 Then GetSectionRange(2)
|
|---|
| 4634 | Else GetSectionRange(3);
|
|---|
| 4635 |
|
|---|
| 4636 | If FmtStart = Nil Then
|
|---|
| 4637 | Begin
|
|---|
| 4638 | //WriteLn('No format sections available.');
|
|---|
| 4639 | Result := FloatToText(Buffer, Value, ffGeneral, 15, 4);
|
|---|
| 4640 | End
|
|---|
| 4641 | Else
|
|---|
| 4642 | Begin
|
|---|
| 4643 | GetFormatOptions;
|
|---|
| 4644 | //WriteLn('Parsing complete');
|
|---|
| 4645 | If (ExpFmt = 0) And (Abs(Value) >= 1E18) Then Result := FloatToText(Buffer, Value, ffGeneral, 15, 4)
|
|---|
| 4646 | Else
|
|---|
| 4647 | Begin
|
|---|
| 4648 | FloatToStr;
|
|---|
| 4649 | //WriteLn('FloatToStr() complete: "', Digits, '" / ', Exponent);
|
|---|
| 4650 | //WriteLn('Unexpected digits: ', UnexpectedDigits);
|
|---|
| 4651 | //WriteLn('DigitExponent: ', DigitExponent);
|
|---|
| 4652 | Result := PutResult;
|
|---|
| 4653 | //WriteLn('PutResult() complete');
|
|---|
| 4654 | End;
|
|---|
| 4655 | End;
|
|---|
| 4656 | End;
|
|---|
| 4657 |
|
|---|
| 4658 |
|
|---|
| 4659 | Function FormatFloat(Const format: String; Value: Extended): String;
|
|---|
| 4660 | Var
|
|---|
| 4661 | Temp: cstring[128];
|
|---|
| 4662 | Begin
|
|---|
| 4663 | Temp := format;
|
|---|
| 4664 | SetLength(Result, FloatToTextFmt(@Result[1], Value, @Temp));
|
|---|
| 4665 | End;
|
|---|
| 4666 |
|
|---|
| 4667 |
|
|---|
| 4668 | Procedure FloatToDecimal(Var Result: TFloatRec; Value: Extended; Precision, Decimals: Integer);
|
|---|
| 4669 | Var
|
|---|
| 4670 | Buffer: String[24];
|
|---|
| 4671 | Error, N: Integer;
|
|---|
| 4672 | Begin
|
|---|
| 4673 | { If Precision > 15 Then Precision := 15;
|
|---|
| 4674 | If Decimals > 15 Then Decimals := 15; }
|
|---|
| 4675 |
|
|---|
| 4676 | Str(Value:23, Buffer);
|
|---|
| 4677 | {WriteLn('Buffer is: ', Buffer);}
|
|---|
| 4678 |
|
|---|
| 4679 | Result.Negative := (Buffer[1] = '-');
|
|---|
| 4680 | Val(Copy(Buffer, 19, 5), Result.Exponent, Error);
|
|---|
| 4681 | Inc(Result. Exponent);
|
|---|
| 4682 | {WriteLn('Exponent is: ', Result.Exponent);}
|
|---|
| 4683 |
|
|---|
| 4684 | Result.Digits[0] := Buffer[2];
|
|---|
| 4685 | Move(Buffer[4], Result.Digits[1], 14);
|
|---|
| 4686 |
|
|---|
| 4687 | If Decimals + Result.Exponent < Precision Then N := Decimals + Result.Exponent
|
|---|
| 4688 | Else N := Precision;
|
|---|
| 4689 |
|
|---|
| 4690 | {WriteLn('Cut point is ', N);}
|
|---|
| 4691 |
|
|---|
| 4692 | If N > 15 Then N := 15;
|
|---|
| 4693 |
|
|---|
| 4694 | {WriteLn('That makes ', N, ' with our precision.');}
|
|---|
| 4695 |
|
|---|
| 4696 | {WriteLn;}
|
|---|
| 4697 |
|
|---|
| 4698 | If N = 0 Then
|
|---|
| 4699 | Begin
|
|---|
| 4700 | If Result.Digits[0] >= '5' Then
|
|---|
| 4701 | Begin
|
|---|
| 4702 | Result.Digits[0] := '1';
|
|---|
| 4703 | Result.Digits[1] := #0;
|
|---|
| 4704 | Inc(Result.Exponent);
|
|---|
| 4705 | End
|
|---|
| 4706 | Else Result.Digits[0] := #0;
|
|---|
| 4707 | End
|
|---|
| 4708 | Else If N > 0 Then
|
|---|
| 4709 | Begin
|
|---|
| 4710 | If Result.Digits[N] >= '5' Then
|
|---|
| 4711 | Begin
|
|---|
| 4712 | { Round up }
|
|---|
| 4713 | Repeat
|
|---|
| 4714 | Result.Digits[N] := #0;
|
|---|
| 4715 | Dec(N);
|
|---|
| 4716 | Inc(Result.Digits[N]);
|
|---|
| 4717 | Until (N = 0) Or (Result.Digits[N] < ':');
|
|---|
| 4718 | If Result.Digits[0] = ':' Then
|
|---|
| 4719 | Begin
|
|---|
| 4720 | Result.Digits[0] := '1';
|
|---|
| 4721 | Inc(Result.Exponent);
|
|---|
| 4722 | End;
|
|---|
| 4723 | End
|
|---|
| 4724 | Else
|
|---|
| 4725 | Begin
|
|---|
| 4726 | { Cut zeros }
|
|---|
| 4727 | Result.Digits[N] := '0';
|
|---|
| 4728 | While (Result.Digits[N] = '0') And (N > -1) Do
|
|---|
| 4729 | Begin
|
|---|
| 4730 | Result.Digits[N] := #0;
|
|---|
| 4731 | Dec(N);
|
|---|
| 4732 | End;
|
|---|
| 4733 | End;
|
|---|
| 4734 | End
|
|---|
| 4735 | Else Result.Digits[0] := #0;
|
|---|
| 4736 |
|
|---|
| 4737 | If Result.Digits[0] = #0 Then
|
|---|
| 4738 | Begin
|
|---|
| 4739 | { Zero has neither Exponent nor signum }
|
|---|
| 4740 | Result.Exponent := 0;
|
|---|
| 4741 | Result.Negative := False;
|
|---|
| 4742 | End;
|
|---|
| 4743 | End;
|
|---|
| 4744 |
|
|---|
| 4745 | { Time encoding And decoding }
|
|---|
| 4746 |
|
|---|
| 4747 | Procedure FastDiv(P, Q: LongWord; Var X, Y: LongInt); Assembler;
|
|---|
| 4748 | Asm
|
|---|
| 4749 | MOV EAX, P;
|
|---|
| 4750 | Xor EDX, EDX;
|
|---|
| 4751 | Div DWord Ptr Q;
|
|---|
| 4752 | MOV EBX, X;
|
|---|
| 4753 | MOV [EBX], EAX;
|
|---|
| 4754 | MOV EBX, Y;
|
|---|
| 4755 | MOV [EBX], EDX;
|
|---|
| 4756 | End;
|
|---|
| 4757 |
|
|---|
| 4758 | Function _EncodeDate(Var date: TDateTime; Year, Month, Day: LongInt): Boolean;
|
|---|
| 4759 | Begin
|
|---|
| 4760 | If (Year <= 9999) And (Month In [1..12]) And (Day In [1..31]) Then
|
|---|
| 4761 | Begin
|
|---|
| 4762 | If Month > 2 Then Dec (Month, 3)
|
|---|
| 4763 | Else
|
|---|
| 4764 | Begin
|
|---|
| 4765 | Inc (Month, 9);
|
|---|
| 4766 | Dec (Year);
|
|---|
| 4767 | End;
|
|---|
| 4768 | date:= (146097 * (Year Div 100)) Shr 2
|
|---|
| 4769 | + (1461 * (Year Mod 100)) Shr 2
|
|---|
| 4770 | + (153 * Month + 2) Div 5 + Day - 306;
|
|---|
| 4771 | Result := True;
|
|---|
| 4772 | End
|
|---|
| 4773 | Else Result := False;
|
|---|
| 4774 | End;
|
|---|
| 4775 |
|
|---|
| 4776 | /*
|
|---|
| 4777 | Function _EncodeDate(Var date: TDateTime; Year, Month, Day: LongWord): Boolean;
|
|---|
| 4778 | Var
|
|---|
| 4779 | LeapYear: Boolean;
|
|---|
| 4780 | Begin
|
|---|
| 4781 | If (Year <= 9999) And (Month In [1..12]) And (Day In [1..31]) Then
|
|---|
| 4782 | Begin
|
|---|
| 4783 | LeapYear := (Year Mod 4 = 0) And Not (Year Mod 100 = 0) Or (Year Mod 400 = 0);
|
|---|
| 4784 | Dec(Year);
|
|---|
| 4785 | date := Year * 365 + Year Div 4 - Year Div 100 + Year Div 400
|
|---|
| 4786 | + 1 + DaysPassed[LeapYear, Month] + Day - 1;
|
|---|
| 4787 | Result := True;
|
|---|
| 4788 | End
|
|---|
| 4789 | Else Result := False;
|
|---|
| 4790 | End;
|
|---|
| 4791 | */
|
|---|
| 4792 |
|
|---|
| 4793 | Function _EncodeTime(Var Time: TDateTime; Hour, Min, Sec, MSec: LongInt): Boolean;
|
|---|
| 4794 | Begin
|
|---|
| 4795 | If (Hour < 24) And (Min < 60) And (Sec < 60) And (MSec < 1000) Then
|
|---|
| 4796 | Begin
|
|---|
| 4797 | Time := (((Hour * 60 + Min) * 60 + Sec) * 1000 + MSec) / MSecsPerDay;
|
|---|
| 4798 | Result := True
|
|---|
| 4799 | End
|
|---|
| 4800 | Else Result := False;
|
|---|
| 4801 | End;
|
|---|
| 4802 |
|
|---|
| 4803 | Function EncodeDate(Year, Month, Day: Word): TDateTime;
|
|---|
| 4804 | Begin
|
|---|
| 4805 | If Not _EncodeDate(Result, Year, Month, Day) Then
|
|---|
| 4806 | FmtLoadConvertError(SDateEncodeError, [Year, Month, Day]);
|
|---|
| 4807 | End;
|
|---|
| 4808 |
|
|---|
| 4809 | Function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
|
|---|
| 4810 | Begin
|
|---|
| 4811 | If Not _EncodeTime(Result, Hour, Min, Sec, MSec) Then
|
|---|
| 4812 | FmtLoadConvertError(STimeEncodeError, [Hour, Min, Sec, MSec]);
|
|---|
| 4813 | End;
|
|---|
| 4814 |
|
|---|
| 4815 | Procedure DecodeDate(date: TDateTime; Var Year, Month, Day: Word);
|
|---|
| 4816 | Const
|
|---|
| 4817 | Days400 = 146097;
|
|---|
| 4818 | Days4 = 1461;
|
|---|
| 4819 | Var
|
|---|
| 4820 | Y, M, D, Tmp1, Tmp2, Tmp3, Tmp4: LongInt;
|
|---|
| 4821 | Begin
|
|---|
| 4822 | Tmp1 := Trunc (date) + 306;
|
|---|
| 4823 | Tmp2 := 4 * Tmp1 - 1;
|
|---|
| 4824 |
|
|---|
| 4825 | FastDiv(Tmp2, Days400, Tmp3, Tmp1);
|
|---|
| 4826 |
|
|---|
| 4827 | Tmp2 := Tmp1 Shr 2;
|
|---|
| 4828 | Tmp4 := 4 * Tmp2 + 3;
|
|---|
| 4829 |
|
|---|
| 4830 | FastDiv(Tmp4, Days4, Tmp1, Tmp2);
|
|---|
| 4831 |
|
|---|
| 4832 | Tmp2 := (Tmp2 + 4) Shr 2;
|
|---|
| 4833 |
|
|---|
| 4834 | Y := 100 * Tmp3 + Tmp1;
|
|---|
| 4835 | Tmp3 := 5 * Tmp2 - 3;
|
|---|
| 4836 |
|
|---|
| 4837 | FastDiv(Tmp3, 153, M, Tmp2);
|
|---|
| 4838 |
|
|---|
| 4839 | D := (Tmp2 + 5) Div 5;
|
|---|
| 4840 | If M < 10 Then Inc (M, 3)
|
|---|
| 4841 | Else
|
|---|
| 4842 | Begin
|
|---|
| 4843 | Dec (M, 9);
|
|---|
| 4844 | Inc (Y);
|
|---|
| 4845 | End;
|
|---|
| 4846 |
|
|---|
| 4847 | Year := Y;
|
|---|
| 4848 | Month := M;
|
|---|
| 4849 | Day := D;
|
|---|
| 4850 | End;
|
|---|
| 4851 |
|
|---|
| 4852 | /*
|
|---|
| 4853 | Procedure DecodeDate(date: TDateTime; Var Year, Month, Day: Word);
|
|---|
| 4854 | Const
|
|---|
| 4855 | Days400 = 146097;
|
|---|
| 4856 | Days100 = 36524;
|
|---|
| 4857 | Days4 = 1461;
|
|---|
| 4858 | Var
|
|---|
| 4859 | cnt, DayNum: LongInt;
|
|---|
| 4860 | LeapYear: Boolean;
|
|---|
| 4861 | Begin
|
|---|
| 4862 | DayNum := Trunc(date);
|
|---|
| 4863 |
|
|---|
| 4864 | Year := 1;
|
|---|
| 4865 |
|
|---|
| 4866 | While DayNum > Days400 Do
|
|---|
| 4867 | Begin
|
|---|
| 4868 | Inc(Year, 400);
|
|---|
| 4869 | Dec(DayNum, Days400);
|
|---|
| 4870 | End;
|
|---|
| 4871 |
|
|---|
| 4872 | cnt := 0;
|
|---|
| 4873 | While (DayNum > Days100) And (cnt < 3) Do
|
|---|
| 4874 | Begin
|
|---|
| 4875 | Inc(Year, 100);
|
|---|
| 4876 | Dec(DayNum, Days100);
|
|---|
| 4877 | Inc(cnt);
|
|---|
| 4878 | End;
|
|---|
| 4879 |
|
|---|
| 4880 | While DayNum > Days4 Do
|
|---|
| 4881 | Begin
|
|---|
| 4882 | Inc(Year, 4);
|
|---|
| 4883 | Dec(DayNum, Days4);
|
|---|
| 4884 | End;
|
|---|
| 4885 |
|
|---|
| 4886 | cnt := 0;
|
|---|
| 4887 | While (DayNum > 365) And (cnt < 3) Do
|
|---|
| 4888 | Begin
|
|---|
| 4889 | Inc(Year);
|
|---|
| 4890 | Dec(DayNum, 365);
|
|---|
| 4891 | Inc(cnt);
|
|---|
| 4892 | End;
|
|---|
| 4893 |
|
|---|
| 4894 | LeapYear := (Year Mod 4 = 0) And Not (Year Mod 100 = 0) Or (Year Mod 400 = 0);
|
|---|
| 4895 |
|
|---|
| 4896 | Month := 0;
|
|---|
| 4897 | While DaysPassed[LeapYear, Month + 1] < DayNum Do
|
|---|
| 4898 | Inc(Month);
|
|---|
| 4899 |
|
|---|
| 4900 | Day := DayNum - DaysPassed[LeapYear, Month];
|
|---|
| 4901 | End;
|
|---|
| 4902 | */
|
|---|
| 4903 |
|
|---|
| 4904 | Procedure DecodeTime(Time: TDateTime; Var Hour, Min, Sec, MSec: Word);
|
|---|
| 4905 | Begin
|
|---|
| 4906 | Time := Frac(Time) * 24;
|
|---|
| 4907 | Hour := Trunc(Time);
|
|---|
| 4908 | Time := Frac(Time) * 60;
|
|---|
| 4909 | Min := Trunc(Time);
|
|---|
| 4910 | Time := Frac(Time) * 60;
|
|---|
| 4911 | Sec := Trunc(Time);
|
|---|
| 4912 | MSec := Trunc(Frac(Time) * 1000);
|
|---|
| 4913 | End;
|
|---|
| 4914 |
|
|---|
| 4915 | Function DayOfWeek(date: TDateTime): Integer;
|
|---|
| 4916 | Begin
|
|---|
| 4917 | Result := (1 + Trunc(date)) Mod 7;
|
|---|
| 4918 | If Result = 0 Then Result := 7;
|
|---|
| 4919 | End;
|
|---|
| 4920 |
|
|---|
| 4921 | Function date: TDateTime;
|
|---|
| 4922 | {$IFDEF OS2}
|
|---|
| 4923 | Var
|
|---|
| 4924 | dt: DateTime;
|
|---|
| 4925 | {$ENDIF}
|
|---|
| 4926 | {$IFDEF Win95}
|
|---|
| 4927 | Var
|
|---|
| 4928 | dt: SYSTEMTIME;
|
|---|
| 4929 | {$ENDIF}
|
|---|
| 4930 | Begin
|
|---|
| 4931 | {$IFDEF OS2}
|
|---|
| 4932 | DosGetDateTime (dt);
|
|---|
| 4933 | date := EncodeDate(dt.Year, dt.Month, dt.Day);
|
|---|
| 4934 | {$ENDIF}
|
|---|
| 4935 | {$IFDEF Win95}
|
|---|
| 4936 | GetLocalTime(dt);
|
|---|
| 4937 | date := EncodeDate(dt.wYear, dt.wMonth, dt.wDay);
|
|---|
| 4938 | {$ENDIF}
|
|---|
| 4939 | End;
|
|---|
| 4940 |
|
|---|
| 4941 | Function Time: TDateTime;
|
|---|
| 4942 | {$IFDEF OS2}
|
|---|
| 4943 | Var
|
|---|
| 4944 | dt: DateTime;
|
|---|
| 4945 | {$ENDIF}
|
|---|
| 4946 | {$IFDEF Win95}
|
|---|
| 4947 | Var
|
|---|
| 4948 | dt: SYSTEMTIME;
|
|---|
| 4949 | {$ENDIF}
|
|---|
| 4950 | Begin
|
|---|
| 4951 | {$IFDEF OS2}
|
|---|
| 4952 | DosGetDateTime (dt);
|
|---|
| 4953 | Time := EncodeTime(dt.Hour, dt.Min, dt.Sec, dt.Hundredths * 10);
|
|---|
| 4954 | {$ENDIF}
|
|---|
| 4955 | {$IFDEF Win95}
|
|---|
| 4956 | GetLocalTime(dt);
|
|---|
| 4957 | Time := EncodeTime(dt.wHour, dt.wMinute, dt.wSecond, dt.wMilliSeconds * 10);
|
|---|
| 4958 | {$ENDIF}
|
|---|
| 4959 | End;
|
|---|
| 4960 |
|
|---|
| 4961 | Function now: TDateTime;
|
|---|
| 4962 | {$IFDEF OS2}
|
|---|
| 4963 | Var
|
|---|
| 4964 | dt: DateTime;
|
|---|
| 4965 | {$ENDIF}
|
|---|
| 4966 | {$IFDEF Win95}
|
|---|
| 4967 | Var
|
|---|
| 4968 | dt: SYSTEMTIME;
|
|---|
| 4969 | {$ENDIF}
|
|---|
| 4970 | Begin
|
|---|
| 4971 | {$IFDEF OS2}
|
|---|
| 4972 | DosGetDateTime (dt);
|
|---|
| 4973 | now := EncodeDate(dt.Year, dt.Month, dt.Day) + EncodeTime(dt.Hour, dt.Min, dt.Sec, dt.Hundredths * 10);
|
|---|
| 4974 | {$ENDIF}
|
|---|
| 4975 | {$IFDEF Win95}
|
|---|
| 4976 | GetLocalTime(dt);
|
|---|
| 4977 | now := EncodeDate(dt.wYear, dt.wMonth, dt.wDay) + EncodeTime(dt.wHour, dt.wMinute, dt.wSecond, dt.wMilliSeconds * 10);
|
|---|
| 4978 | {$ENDIF}
|
|---|
| 4979 | End;
|
|---|
| 4980 |
|
|---|
| 4981 | { --- date/Time To String conversion --- }
|
|---|
| 4982 |
|
|---|
| 4983 | Procedure DateTimeToString(Var Result: String; Const format: String; DateTime: TDateTime);
|
|---|
| 4984 | Var
|
|---|
| 4985 | Year, Month, Day, Hour, Min, Sec, MSec, Hour12: Word;
|
|---|
| 4986 | BeforeNoon: Boolean;
|
|---|
| 4987 |
|
|---|
| 4988 | Procedure _DateTimeToString(Var Result: String; Const format: String; recursive: Boolean);
|
|---|
| 4989 | { internal Function To Control recursion In format specifiers. Avoids
|
|---|
| 4990 | stack overflow when format Strings contain Macros For other format
|
|---|
| 4991 | Strings. }
|
|---|
| 4992 |
|
|---|
| 4993 | Var
|
|---|
| 4994 | Start, Count, Pos, len, LastHourPos, LastHourSize, Tmp: Integer;
|
|---|
| 4995 | Token: Char;
|
|---|
| 4996 | UseMinutes: Boolean;
|
|---|
| 4997 |
|
|---|
| 4998 | Procedure AppendInt(I, Digits: Integer);
|
|---|
| 4999 | Var
|
|---|
| 5000 | S: String[5];
|
|---|
| 5001 | P: Integer;
|
|---|
| 5002 | Begin
|
|---|
| 5003 | Str(I:Digits, S);
|
|---|
| 5004 | P := 1;
|
|---|
| 5005 | While S[P] = ' ' Do
|
|---|
| 5006 | Begin
|
|---|
| 5007 | S[P] := '0';
|
|---|
| 5008 | Inc(P);
|
|---|
| 5009 | End;
|
|---|
| 5010 | AppendStr(Result, S);
|
|---|
| 5011 | End;
|
|---|
| 5012 |
|
|---|
| 5013 | Procedure AppendStr(Const S: String);
|
|---|
| 5014 | Begin
|
|---|
| 5015 | Insert(S, Result, Length(Result) + 1);
|
|---|
| 5016 | End;
|
|---|
| 5017 |
|
|---|
| 5018 | Function CountChar(C: Char; Max: Integer): Integer;
|
|---|
| 5019 | Var
|
|---|
| 5020 | Result: Integer;
|
|---|
| 5021 | Begin
|
|---|
| 5022 | Result := 1;
|
|---|
| 5023 | While (Pos <= len) And (UpCase(format[Pos]) = C) And (Result < Max) Do
|
|---|
| 5024 | Begin
|
|---|
| 5025 | Inc(Pos);
|
|---|
| 5026 | Inc(Result);
|
|---|
| 5027 | End;
|
|---|
| 5028 | CountChar := Result;
|
|---|
| 5029 | End;
|
|---|
| 5030 |
|
|---|
| 5031 | Function IsSubStr(Const S: String): Boolean;
|
|---|
| 5032 | Begin
|
|---|
| 5033 | IsSubStr := (uppercase(Copy(format, Pos, Length(S))) = S);
|
|---|
| 5034 | End;
|
|---|
| 5035 |
|
|---|
| 5036 | Procedure GetNextToken(BeforeNoon: Boolean);
|
|---|
| 5037 | Begin
|
|---|
| 5038 | Start := Pos;
|
|---|
| 5039 | Token := UpCase(format[Pos]);
|
|---|
| 5040 | Inc(Pos);
|
|---|
| 5041 | Case Token Of
|
|---|
| 5042 | #34,
|
|---|
| 5043 | #39: Begin
|
|---|
| 5044 | Inc(Start);
|
|---|
| 5045 | While (Pos <= len) And (format[Pos] <> Token) Do Inc(Pos);
|
|---|
| 5046 | Count := Pos - Start;
|
|---|
| 5047 | If Pos < len Then Inc(Pos);
|
|---|
| 5048 | Token := '$';
|
|---|
| 5049 | End;
|
|---|
| 5050 | 'D': Count := CountChar('D', 6);
|
|---|
| 5051 | 'M': Count := CountChar('M', 4);
|
|---|
| 5052 | 'Y': Count := CountChar('Y', 4);
|
|---|
| 5053 | 'H',
|
|---|
| 5054 | 'N',
|
|---|
| 5055 | 'S',
|
|---|
| 5056 | 'T': Count := CountChar(Token, 2);
|
|---|
| 5057 | 'A': Begin
|
|---|
| 5058 | If IsSubStr('MPM') Then
|
|---|
| 5059 | Begin
|
|---|
| 5060 | Inc(Pos, 3);
|
|---|
| 5061 | Count := 0;
|
|---|
| 5062 | End
|
|---|
| 5063 | Else If IsSubStr('/P') Then
|
|---|
| 5064 | Begin
|
|---|
| 5065 | Inc(Pos, 2);
|
|---|
| 5066 | If Not BeforeNoon Then Inc(Start, 2);
|
|---|
| 5067 | Count := 1;
|
|---|
| 5068 | End
|
|---|
| 5069 | Else If IsSubStr('M/PM') Then
|
|---|
| 5070 | Begin
|
|---|
| 5071 | Inc(Pos, 4);
|
|---|
| 5072 | If Not BeforeNoon Then Inc(Start, 3);
|
|---|
| 5073 | Count := 2;
|
|---|
| 5074 | End
|
|---|
| 5075 | Else
|
|---|
| 5076 | Begin
|
|---|
| 5077 | Token := '$';
|
|---|
| 5078 | Count := 1;
|
|---|
| 5079 | End;
|
|---|
| 5080 | End;
|
|---|
| 5081 | 'C',
|
|---|
| 5082 | '/',
|
|---|
| 5083 | ':': Begin
|
|---|
| 5084 | { Nope }
|
|---|
| 5085 | End;
|
|---|
| 5086 | Else Begin
|
|---|
| 5087 | Token := '$';
|
|---|
| 5088 | Count := 1;
|
|---|
| 5089 | While (Pos <= len) And Not (UpCase(format[Pos]) In
|
|---|
| 5090 | [#34, #39, 'A', 'C', 'D', 'H', 'M', 'N', 'S', 'T', 'Y', ':', '/']) Do
|
|---|
| 5091 | Begin
|
|---|
| 5092 | Inc(Pos);
|
|---|
| 5093 | Inc(Count);
|
|---|
| 5094 | End;
|
|---|
| 5095 | End;
|
|---|
| 5096 | End;
|
|---|
| 5097 |
|
|---|
| 5098 | If (Token = 'M') And UseMinutes Then Token := 'N';
|
|---|
| 5099 |
|
|---|
| 5100 | Case Token Of
|
|---|
| 5101 | 'H': UseMinutes := True;
|
|---|
| 5102 | 'A', 'C', 'D', 'M', 'N', 'S', 'T', 'Y': UseMinutes := False;
|
|---|
| 5103 | End;
|
|---|
| 5104 | End;
|
|---|
| 5105 |
|
|---|
| 5106 | Begin
|
|---|
| 5107 | Pos := 1;
|
|---|
| 5108 | len := Length(format);
|
|---|
| 5109 | LastHourPos := 0;
|
|---|
| 5110 | UseMinutes := False;
|
|---|
| 5111 |
|
|---|
| 5112 | If len = 0 Then _DateTimeToString(Result, 'C', True)
|
|---|
| 5113 | Else While (Pos <= len) Do
|
|---|
| 5114 | Begin
|
|---|
| 5115 | GetNextToken(BeforeNoon);
|
|---|
| 5116 | // WriteLn('Token=', Token, ' Start=', Start, ' Count=', Count);
|
|---|
| 5117 | Case Token Of
|
|---|
| 5118 | 'C': If recursive Then
|
|---|
| 5119 | Begin
|
|---|
| 5120 | _DateTimeToString(Result, ShortDateFormat, False);
|
|---|
| 5121 | If (Hour + Min + Sec) > 0 Then
|
|---|
| 5122 | Begin
|
|---|
| 5123 | AppendStr(' ');
|
|---|
| 5124 | _DateTimeToString(Result, LongTimeFormat, False);
|
|---|
| 5125 | End;
|
|---|
| 5126 | End
|
|---|
| 5127 | Else AppendStr('C');
|
|---|
| 5128 | 'D': Case Count Of
|
|---|
| 5129 | 1: AppendInt(Day, 1);
|
|---|
| 5130 | 2: AppendInt(Day, 2);
|
|---|
| 5131 | 3: AppendStr(ShortDayNames[DayOfWeek(DateTime)]);
|
|---|
| 5132 | 4: AppendStr(LongDayNames[DayOfWeek(DateTime)]);
|
|---|
| 5133 | 5: If recursive Then _DateTimeToString(Result, ShortDateFormat, False)
|
|---|
| 5134 | Else AppendStr('DDDDD');
|
|---|
| 5135 | 6: If recursive Then _DateTimeToString(Result, LongDateFormat, False)
|
|---|
| 5136 | Else AppendStr('DDDDDD');
|
|---|
| 5137 | End;
|
|---|
| 5138 | 'M': Case Count Of
|
|---|
| 5139 | 1: AppendInt(Month, 1);
|
|---|
| 5140 | 2: AppendInt(Month, 2);
|
|---|
| 5141 | 3: AppendStr(ShortMonthNames[Month]);
|
|---|
| 5142 | 4: AppendStr(LongMonthNames[Month]);
|
|---|
| 5143 | End;
|
|---|
| 5144 | 'Y': Case Count Of
|
|---|
| 5145 | 1, 2: AppendInt(Year Mod 100, 2);
|
|---|
| 5146 | 3, 4: AppendInt(Year, 4);
|
|---|
| 5147 | End;
|
|---|
| 5148 | 'H': Begin
|
|---|
| 5149 | LastHourPos := Length(Result) + 1;
|
|---|
| 5150 | LastHourSize := Count;
|
|---|
| 5151 | AppendInt(Hour, Count);
|
|---|
| 5152 | End;
|
|---|
| 5153 | 'N': AppendInt(Min, Count);
|
|---|
| 5154 | 'S': AppendInt(Sec, Count);
|
|---|
| 5155 | 'T': Case Count Of
|
|---|
| 5156 | 1: If recursive Then _DateTimeToString(Result, ShortTimeFormat, False)
|
|---|
| 5157 | Else AppendStr('T');
|
|---|
| 5158 | 2: If recursive Then _DateTimeToString(Result, LongTimeFormat, False)
|
|---|
| 5159 | Else AppendStr('TT');
|
|---|
| 5160 | End;
|
|---|
| 5161 | 'A': Begin
|
|---|
| 5162 | If LastHourPos <> 0 Then
|
|---|
| 5163 | Begin
|
|---|
| 5164 | If (LastHourSize = 1) And (Hour < 10) Then Tmp := 1
|
|---|
| 5165 | Else Tmp := 2;
|
|---|
| 5166 | Delete(Result, LastHourPos, Tmp);
|
|---|
| 5167 | If (LastHourSize = 2) And (Hour12 < 10) Then
|
|---|
| 5168 | Insert('0' + IntToStr(Hour12), Result, LastHourPos)
|
|---|
| 5169 | Else Insert(IntToStr(Hour12), Result, LastHourPos);
|
|---|
| 5170 | LastHourPos := 0;
|
|---|
| 5171 | End;
|
|---|
| 5172 | Case Count Of
|
|---|
| 5173 | 0: If BeforeNoon Then AppendStr(TimeAMString)
|
|---|
| 5174 | Else AppendStr(TimePMString);
|
|---|
| 5175 | 1: AppendStr(format[Start]);
|
|---|
| 5176 | 2: AppendStr(format[Start] + format[Start + 1]);
|
|---|
| 5177 | End
|
|---|
| 5178 | End;
|
|---|
| 5179 | '/': AppendStr(DateSeparator);
|
|---|
| 5180 | ':': AppendStr(TimeSeparator);
|
|---|
| 5181 | '$': AppendStr(Copy(format, Start, Count));
|
|---|
| 5182 | End;
|
|---|
| 5183 | End;
|
|---|
| 5184 | End;
|
|---|
| 5185 |
|
|---|
| 5186 | Begin
|
|---|
| 5187 | DateTime := DateTime + 5.79e-6; // avoid rounding problems
|
|---|
| 5188 |
|
|---|
| 5189 | DecodeDate(DateTime, Year, Month, Day);
|
|---|
| 5190 | DecodeTime(DateTime, Hour, Min, Sec, MSec);
|
|---|
| 5191 |
|
|---|
| 5192 | If (Hour = 0) Or (Hour > 12) Then
|
|---|
| 5193 | Begin
|
|---|
| 5194 | If Hour = 0 Then Hour12 := 12
|
|---|
| 5195 | Else Hour12 := Hour - 12;
|
|---|
| 5196 | BeforeNoon := False;
|
|---|
| 5197 | End
|
|---|
| 5198 | Else
|
|---|
| 5199 | Begin
|
|---|
| 5200 | BeforeNoon := True;
|
|---|
| 5201 | Hour12 := Hour;
|
|---|
| 5202 | End;
|
|---|
| 5203 | Result := '';
|
|---|
| 5204 |
|
|---|
| 5205 | If Length(format) <> 0 Then _DateTimeToString(Result, format, True)
|
|---|
| 5206 | Else _DateTimeToString(Result, 'C', True)
|
|---|
| 5207 | End;
|
|---|
| 5208 |
|
|---|
| 5209 | Function DateToStr(date: TDateTime): String;
|
|---|
| 5210 | Begin
|
|---|
| 5211 | DateTimeToString(Result, ShortDateFormat, date);
|
|---|
| 5212 | End;
|
|---|
| 5213 |
|
|---|
| 5214 | Function TimeToStr(Time: TDateTime): String;
|
|---|
| 5215 | Begin
|
|---|
| 5216 | DateTimeToString(Result, LongTimeFormat, Time);
|
|---|
| 5217 | End;
|
|---|
| 5218 |
|
|---|
| 5219 | Function DateTimeToStr(DateTime: TDateTime): String;
|
|---|
| 5220 | Begin
|
|---|
| 5221 | DateTimeToString(Result, ShortDateFormat + ' ' + LongTimeFormat, DateTime);
|
|---|
| 5222 | End;
|
|---|
| 5223 |
|
|---|
| 5224 | Function FormatDateTime(Const format: String; DateTime: TDateTime): String;
|
|---|
| 5225 | Begin
|
|---|
| 5226 | DateTimeToString(Result, format, DateTime);
|
|---|
| 5227 | End;
|
|---|
| 5228 |
|
|---|
| 5229 | { --- String To date/Time conversions --- }
|
|---|
| 5230 |
|
|---|
| 5231 | Procedure IgnoreSpaces(Const S: String; Var Pos: Integer; len: Integer);
|
|---|
| 5232 | Begin
|
|---|
| 5233 | While (Pos <= len) And (S[Pos] = ' ') Do Inc(Pos);
|
|---|
| 5234 | End;
|
|---|
| 5235 |
|
|---|
| 5236 | Function GetNumber(Var Num: Integer; Const S: String; Var Pos: Integer; len: Integer): Boolean;
|
|---|
| 5237 | Begin
|
|---|
| 5238 | Result := False;
|
|---|
| 5239 | Num := 0;
|
|---|
| 5240 | IgnoreSpaces(S, Pos, len);
|
|---|
| 5241 | While (Pos <= len) And (S[Pos] In ['0'..'9']) Do
|
|---|
| 5242 | Begin
|
|---|
| 5243 | Result := True;
|
|---|
| 5244 | Num := Num * 10 + Ord(S[Pos]) - 48;
|
|---|
| 5245 | Inc(Pos);
|
|---|
| 5246 | End;
|
|---|
| 5247 | End;
|
|---|
| 5248 |
|
|---|
| 5249 | {$HINTS OFF}
|
|---|
| 5250 | Function CompareString(Const SubStr, S: String; Var Pos: Integer; len: Integer): Boolean;
|
|---|
| 5251 | Begin
|
|---|
| 5252 | If CompareText(SubStr, Copy(S, 1, Length(SubStr))) = 0 Then
|
|---|
| 5253 | Begin
|
|---|
| 5254 | Result := True;
|
|---|
| 5255 | Inc(Pos, Length(SubStr));
|
|---|
| 5256 | End
|
|---|
| 5257 | Else Result := False;
|
|---|
| 5258 | End;
|
|---|
| 5259 | {$HINTS ON}
|
|---|
| 5260 |
|
|---|
| 5261 | Function CompareChar(C: Char; S: String; Var Pos: Integer; len: Integer): Boolean;
|
|---|
| 5262 | Begin
|
|---|
| 5263 | If (Pos <= len) And (UpCase(C) = UpCase(S[Pos])) Then
|
|---|
| 5264 | Begin
|
|---|
| 5265 | Result := True;
|
|---|
| 5266 | Inc(Pos);
|
|---|
| 5267 | End
|
|---|
| 5268 | Else Result := False;
|
|---|
| 5269 | End;
|
|---|
| 5270 |
|
|---|
| 5271 | Function CutString(Var S: String; separator: Char): String;
|
|---|
| 5272 | Var
|
|---|
| 5273 | P: Integer;
|
|---|
| 5274 | Begin
|
|---|
| 5275 | P := Pos(separator, S);
|
|---|
| 5276 | If P = 0 Then P := Length(S) + 1;
|
|---|
| 5277 | Result := Copy(S, 1, P - 1);
|
|---|
| 5278 | Delete(S, 1, P);
|
|---|
| 5279 | End;
|
|---|
| 5280 |
|
|---|
| 5281 | Function ParseDate(Var date: TDateTime; Const S: String; Var Pos: Integer; len: Integer): Boolean;
|
|---|
| 5282 | Var
|
|---|
| 5283 | Head, Temp: String[15];
|
|---|
| 5284 | N, Year, Month, Day: Integer;
|
|---|
| 5285 | Number: Array[1..3] Of Integer;
|
|---|
| 5286 | order: String[3];
|
|---|
| 5287 |
|
|---|
| 5288 | Function GetCurrentYear: Integer;
|
|---|
| 5289 | Var
|
|---|
| 5290 | Y, M, D: Word;
|
|---|
| 5291 | Begin
|
|---|
| 5292 | DecodeDate(now, Y, M, D);
|
|---|
| 5293 | Result := Y;
|
|---|
| 5294 | End;
|
|---|
| 5295 |
|
|---|
| 5296 | Begin
|
|---|
| 5297 | order := 'XXX';
|
|---|
| 5298 |
|
|---|
| 5299 | Result := False;
|
|---|
| 5300 |
|
|---|
| 5301 | If Not GetNumber(Number[1], S, Pos, len) Then Exit;
|
|---|
| 5302 | If Not CompareChar(DateSeparator, S, Pos, len) Then Exit;
|
|---|
| 5303 | If Not GetNumber(Number[2], S, Pos, len) Then Exit;
|
|---|
| 5304 | If Not CompareChar(DateSeparator, S, Pos, len) Then Exit;
|
|---|
| 5305 | If Not GetNumber(Number[3], S, Pos, len) Then Number[3] := -1;
|
|---|
| 5306 |
|
|---|
| 5307 | { For N := 1 To 3 Do WriteLn(Number[N]); }
|
|---|
| 5308 |
|
|---|
| 5309 | Temp := ShortDateFormat;
|
|---|
| 5310 |
|
|---|
| 5311 | For N := 1 To 3 Do
|
|---|
| 5312 | Begin
|
|---|
| 5313 | Head := CutString(Temp, '/');
|
|---|
| 5314 | If Length(Head) <> 0 Then order[N] := UpCase(Head[1]);
|
|---|
| 5315 | End;
|
|---|
| 5316 |
|
|---|
| 5317 | If order = 'MDY' Then
|
|---|
| 5318 | Begin
|
|---|
| 5319 | Month := Number[1];
|
|---|
| 5320 | Day := Number[2];
|
|---|
| 5321 | Year := Number[3];
|
|---|
| 5322 | End
|
|---|
| 5323 | Else If order = 'DMY' Then
|
|---|
| 5324 | Begin
|
|---|
| 5325 | { WriteLn('DMY'); }
|
|---|
| 5326 | Day := Number[1];
|
|---|
| 5327 | Month := Number[2];
|
|---|
| 5328 | Year := Number[3];
|
|---|
| 5329 | End
|
|---|
| 5330 | Else If order = 'YMD' Then
|
|---|
| 5331 | Begin
|
|---|
| 5332 | If Number[3] = -1 Then
|
|---|
| 5333 | Begin
|
|---|
| 5334 | Year := -1;
|
|---|
| 5335 | Month := Number[1];
|
|---|
| 5336 | Day := Number[2];
|
|---|
| 5337 | End
|
|---|
| 5338 | Else
|
|---|
| 5339 | Begin
|
|---|
| 5340 | Year := Number[1];
|
|---|
| 5341 | Month := Number[2];
|
|---|
| 5342 | Day := Number[3];
|
|---|
| 5343 | End;
|
|---|
| 5344 | End;
|
|---|
| 5345 |
|
|---|
| 5346 | If Year = -1 Then Year := GetCurrentYear
|
|---|
| 5347 | Else If Year < 100 Then Inc(Year, 1900);
|
|---|
| 5348 |
|
|---|
| 5349 | Result := True;
|
|---|
| 5350 | Result := _EncodeDate(date, Year, Month, Day);
|
|---|
| 5351 | End;
|
|---|
| 5352 |
|
|---|
| 5353 | Function ParseTime(Var Time: TDateTime; Const S: String; Var Pos: Integer; len: Integer): Boolean;
|
|---|
| 5354 | Var
|
|---|
| 5355 | Hour, Min, Sec: Integer;
|
|---|
| 5356 | Begin
|
|---|
| 5357 | Result := False;
|
|---|
| 5358 |
|
|---|
| 5359 | If Not GetNumber(Hour, S, Pos, len) Then Exit;
|
|---|
| 5360 | If Not CompareChar(TimeSeparator, S, Pos, len) Then Exit;
|
|---|
| 5361 | If Not GetNumber(Min, S, Pos, len) Then Exit;
|
|---|
| 5362 | If CompareChar(TimeSeparator, S, Pos, len) And Not GetNumber(Sec, S, Pos, len) Then Exit;
|
|---|
| 5363 |
|
|---|
| 5364 | IgnoreSpaces(S, Pos, len);
|
|---|
| 5365 | If CompareChar('A', S, Pos, len) Then
|
|---|
| 5366 | Begin
|
|---|
| 5367 | CompareChar('M', S, Pos, len);
|
|---|
| 5368 | If Hour = 12 Then Hour := 0;
|
|---|
| 5369 | End
|
|---|
| 5370 | Else If CompareChar('P', S, Pos, len) Then
|
|---|
| 5371 | Begin
|
|---|
| 5372 | CompareChar('M', S, Pos, len);
|
|---|
| 5373 | If (Hour >= 1) And (Hour <= 11) Then Inc(Hour, 12);
|
|---|
| 5374 | End;
|
|---|
| 5375 |
|
|---|
| 5376 | Result := _EncodeTime(Time, Hour, Min, Sec, 0);
|
|---|
| 5377 | End;
|
|---|
| 5378 |
|
|---|
| 5379 | Function StrToDate(Const S: String): TDateTime;
|
|---|
| 5380 | Var
|
|---|
| 5381 | Pos, len: Integer;
|
|---|
| 5382 | Begin
|
|---|
| 5383 | Pos := 1;
|
|---|
| 5384 | len := Length(S);
|
|---|
| 5385 | If Not ParseDate(Result, S, Pos, len) Then FmtLoadConvertError(SInvalidDate, [S]);
|
|---|
| 5386 | End;
|
|---|
| 5387 |
|
|---|
| 5388 | Function StrToTime(Const S: String): TDateTime;
|
|---|
| 5389 | Var
|
|---|
| 5390 | Pos, len: Integer;
|
|---|
| 5391 | Begin
|
|---|
| 5392 | Pos := 1;
|
|---|
| 5393 | len := Length(S);
|
|---|
| 5394 | If Not ParseTime(Result, S, Pos, len) Then FmtLoadConvertError(SInvalidTime, [S]);
|
|---|
| 5395 | End;
|
|---|
| 5396 |
|
|---|
| 5397 | Function StrToDateTime(Const S: String): TDateTime;
|
|---|
| 5398 | Var
|
|---|
| 5399 | Time: TDateTime;
|
|---|
| 5400 | Pos, len: Integer;
|
|---|
| 5401 | Begin
|
|---|
| 5402 | Pos := 1;
|
|---|
| 5403 | len := Length(S);
|
|---|
| 5404 | If Not ParseDate(Result, S, Pos, len) Then FmtLoadConvertError(SInvalidDateTime, [S]);
|
|---|
| 5405 | If ParseTime(Time, S, Pos, len) Then Result := Result + Time;
|
|---|
| 5406 | End;
|
|---|
| 5407 |
|
|---|
| 5408 | { --- Initialization File support --- }
|
|---|
| 5409 |
|
|---|
| 5410 | {$IFDEF GUI}
|
|---|
| 5411 |
|
|---|
| 5412 | Function GetProfileStr(Const Section, Entry, Default: String): String;
|
|---|
| 5413 | Var
|
|---|
| 5414 | CDefault,OutBuf: cstring;
|
|---|
| 5415 | Begin
|
|---|
| 5416 | CDefault := Default;
|
|---|
| 5417 | {$IFDEF OS2}
|
|---|
| 5418 | Fillchar(OutBuf, 255, 0); {sometimes the #0 character is not copied (cdp.ini)}
|
|---|
| 5419 | PrfQueryProfileString(HINI_UserProfile, Section, Entry, Default, OutBuf, 255);
|
|---|
| 5420 | Result := OutBuf;
|
|---|
| 5421 | {$ENDIF}
|
|---|
| 5422 | {$IFDEF Win95}
|
|---|
| 5423 | If entry='' Then GetProfileString('USER',section,Default,CDefault,255)
|
|---|
| 5424 | Else GetProfileString('USER',section,entry,CDefault,255);
|
|---|
| 5425 | result:=CDefault;
|
|---|
| 5426 | {$ENDIF}
|
|---|
| 5427 | End;
|
|---|
| 5428 |
|
|---|
| 5429 | {$HINTS OFF}
|
|---|
| 5430 | Function GetProfileChar(Const Section, Entry: String; Default: Char): Char;
|
|---|
| 5431 | Var
|
|---|
| 5432 | InBuf, OutBuf: cstring[2];
|
|---|
| 5433 | Begin
|
|---|
| 5434 | InBuf[0] := Default;
|
|---|
| 5435 | InBuf[1] := #0;
|
|---|
| 5436 | {$IFDEF OS2}
|
|---|
| 5437 | PrfQueryProfileString(HINI_UserProfile,
|
|---|
| 5438 | Section, Entry,
|
|---|
| 5439 | InBuf, OutBuf, 2);
|
|---|
| 5440 | Result := OutBuf[0];
|
|---|
| 5441 | {$ENDIF}
|
|---|
| 5442 | {$IFDEF Win95}
|
|---|
| 5443 | GetProfileString('USER',section,InBuf,OutBuf,255);
|
|---|
| 5444 | Result:= OutBuf[0];
|
|---|
| 5445 | {$ENDIF}
|
|---|
| 5446 | End;
|
|---|
| 5447 | {$HINTS ON}
|
|---|
| 5448 |
|
|---|
| 5449 | Function GetProfileInt(Const Section, Entry: string; Default: Integer): Integer;
|
|---|
| 5450 | {$IFDEF Win95}
|
|---|
| 5451 | Var
|
|---|
| 5452 | S: String;
|
|---|
| 5453 | C: Integer;
|
|---|
| 5454 | {$ENDIF}
|
|---|
| 5455 | Begin
|
|---|
| 5456 | {$IFDEF OS2}
|
|---|
| 5457 | Result := PrfQueryProfileInt(HINI_UserProfile,Section, Entry,Default);
|
|---|
| 5458 | {$ENDIF}
|
|---|
| 5459 | {$IFDEF Win95}
|
|---|
| 5460 | S:=GetProfileStr(section,entry,'');
|
|---|
| 5461 | Val(S,Result,C);
|
|---|
| 5462 | If C<>0 Then Result:=Default;
|
|---|
| 5463 | {$ENDIF}
|
|---|
| 5464 | End;
|
|---|
| 5465 |
|
|---|
| 5466 | Procedure GetFormatSettings;
|
|---|
| 5467 | Const
|
|---|
| 5468 | key = 'PM_National';
|
|---|
| 5469 | Var
|
|---|
| 5470 | N: Integer;
|
|---|
| 5471 | Begin
|
|---|
| 5472 | TimeAMString := GetProfileStr(key, 's1159', 'am');
|
|---|
| 5473 | TimePMString := GetProfileStr(key, 's2359', 'pm');
|
|---|
| 5474 | CurrencyString := GetProfileStr(key, 'sCurrency', '$');
|
|---|
| 5475 | ThousandSeparator := GetProfileChar(key, 'sThousand', ',');
|
|---|
| 5476 | DecimalSeparator := GetProfileChar(key, 'sDecimal', '.');
|
|---|
| 5477 | DateSeparator := GetProfileChar(key, 'sDate', '/');
|
|---|
| 5478 | TimeSeparator := GetProfileChar(key, 'sTime', ':');
|
|---|
| 5479 | ListSeparator := GetProfileChar(key, 'sList', ';');
|
|---|
| 5480 |
|
|---|
| 5481 | DateOrder := GetProfileInt(key, 'iDate', 0);
|
|---|
| 5482 | Case DateOrder Of
|
|---|
| 5483 | 0: Begin
|
|---|
| 5484 | ShortDateFormat := 'mm/dd/yyyy';
|
|---|
| 5485 | LongDateFormat := 'dddd, mmmm d. yyyy';
|
|---|
| 5486 | End;
|
|---|
| 5487 | 1: Begin
|
|---|
| 5488 | ShortDateFormat := 'dd/mm/yyyy';
|
|---|
| 5489 | LongDateFormat := 'dddd, d. mmmm yyyy';
|
|---|
| 5490 | End;
|
|---|
| 5491 | 2: Begin
|
|---|
| 5492 | ShortDateFormat := 'yyyy/mm/dd';
|
|---|
| 5493 | LongDateFormat := 'dddd, yyyy mmmm d.';
|
|---|
| 5494 | End;
|
|---|
| 5495 | End;
|
|---|
| 5496 |
|
|---|
| 5497 | CurrencyFormat := GetProfileInt(key, 'iCurrency', 0);
|
|---|
| 5498 |
|
|---|
| 5499 | Case CurrencyFormat Of
|
|---|
| 5500 | 0: NegCurrFormat := 1;
|
|---|
| 5501 | 1: NegCurrFormat := 5;
|
|---|
| 5502 | 2: NegCurrFormat := 9;
|
|---|
| 5503 | 3: NegCurrFormat := 8;
|
|---|
| 5504 | End;
|
|---|
| 5505 |
|
|---|
| 5506 | CurrencyDecimals := GetProfileInt(key, 'iDigits', 2);
|
|---|
| 5507 |
|
|---|
| 5508 | Case GetProfileInt(key, 'iLzero', 0) Of
|
|---|
| 5509 | 0: Begin
|
|---|
| 5510 | ShortTimeFormat := 'h:mm';
|
|---|
| 5511 | LongTimeFormat := 'h:mm:ss';
|
|---|
| 5512 | End;
|
|---|
| 5513 | 1: Begin
|
|---|
| 5514 | ShortTimeFormat := 'hh:mm';
|
|---|
| 5515 | LongTimeFormat := 'hh:mm:ss';
|
|---|
| 5516 | End;
|
|---|
| 5517 | End;
|
|---|
| 5518 |
|
|---|
| 5519 | If GetProfileInt(key, 'iTime', 0) = 0 Then
|
|---|
| 5520 | Begin
|
|---|
| 5521 | ShortTimeFormat := ShortTimeFormat + ' ampm';
|
|---|
| 5522 | LongTimeFormat := LongTimeFormat + ' ampm';
|
|---|
| 5523 | TwelveHours := True;
|
|---|
| 5524 | End
|
|---|
| 5525 | Else TwelveHours := False;
|
|---|
| 5526 |
|
|---|
| 5527 | For N := 1 To 12 Do
|
|---|
| 5528 | Begin
|
|---|
| 5529 | ShortMonthNames[N] := LoadNLSStr(SShortMonthNames + N - 1);
|
|---|
| 5530 | LongMonthNames[N] := LoadNLSStr(SLongMonthNames + N - 1);
|
|---|
| 5531 | End;
|
|---|
| 5532 |
|
|---|
| 5533 | For N := 1 To 7 Do
|
|---|
| 5534 | Begin
|
|---|
| 5535 | ShortDayNames[N] := LoadNLSStr(SShortDayNames + N - 1);
|
|---|
| 5536 | LongDayNames[N] := LoadNLSStr(SLongDayNames + N - 1);
|
|---|
| 5537 | End;
|
|---|
| 5538 | End;
|
|---|
| 5539 |
|
|---|
| 5540 | {$ELSE}
|
|---|
| 5541 |
|
|---|
| 5542 | Procedure GetFormatSettings; { VIO-only! }
|
|---|
| 5543 | Var
|
|---|
| 5544 | cc: COUNTRYCODE;
|
|---|
| 5545 | CI: COUNTRYINFO;
|
|---|
| 5546 | L: LongInt;
|
|---|
| 5547 | Begin
|
|---|
| 5548 | cc.country := 0;
|
|---|
| 5549 | cc.codepage := 0;
|
|---|
| 5550 | If DosQueryCtryInfo(SizeOf(CI), cc, CI, L) <> NO_ERROR Then Halt(255);
|
|---|
| 5551 |
|
|---|
| 5552 | CurrencyString := CI.szCurrency;
|
|---|
| 5553 | CurrencyFormat := CI.fsCurrencyFmt;
|
|---|
| 5554 |
|
|---|
| 5555 | ThousandSeparator := CI.szThousandsSeparator[0];
|
|---|
| 5556 | DecimalSeparator := CI.szDecimal[0];
|
|---|
| 5557 | DateSeparator := CI.szDateSeparator[0];
|
|---|
| 5558 | TimeSeparator := CI.szTimeSeparator[0];
|
|---|
| 5559 | ListSeparator := CI.szDataSeparator[0];
|
|---|
| 5560 | CurrencyDecimals := CI.cDecimalPlace;
|
|---|
| 5561 |
|
|---|
| 5562 | Case CurrencyFormat Of
|
|---|
| 5563 | 0: NegCurrFormat := 1;
|
|---|
| 5564 | 1: NegCurrFormat := 5;
|
|---|
| 5565 | 2: NegCurrFormat := 9;
|
|---|
| 5566 | 3: NegCurrFormat := 8;
|
|---|
| 5567 | End;
|
|---|
| 5568 |
|
|---|
| 5569 | DateOrder := CI.fsDateFmt;
|
|---|
| 5570 | Case DateOrder Of
|
|---|
| 5571 | 0: Begin
|
|---|
| 5572 | ShortDateFormat := 'mm/dd/yyyy';
|
|---|
| 5573 | LongDateFormat := 'dddd, mmmm d. yyyy';
|
|---|
| 5574 | End;
|
|---|
| 5575 | 1: Begin
|
|---|
| 5576 | ShortDateFormat := 'dd/mm/yyyy';
|
|---|
| 5577 | LongDateFormat := 'dddd, d. mmmm yyyy';
|
|---|
| 5578 | End;
|
|---|
| 5579 | 2: Begin
|
|---|
| 5580 | ShortDateFormat := 'yyyy/mm/dd';
|
|---|
| 5581 | LongDateFormat := 'dddd, yyyy mmmm d.';
|
|---|
| 5582 | End;
|
|---|
| 5583 | End;
|
|---|
| 5584 |
|
|---|
| 5585 | Case CI.fsTimeFmt Of
|
|---|
| 5586 | 0: Begin
|
|---|
| 5587 | ShortTimeFormat := 'hh:mm ampm';
|
|---|
| 5588 | LongTimeFormat := 'hh:mm:ss ampm';
|
|---|
| 5589 | TwelveHours := True;
|
|---|
| 5590 | End;
|
|---|
| 5591 | 1: Begin
|
|---|
| 5592 | ShortTimeFormat := 'hh:mm';
|
|---|
| 5593 | LongTimeFormat := 'hh:mm:ss';
|
|---|
| 5594 | TwelveHours := False;
|
|---|
| 5595 | End;
|
|---|
| 5596 | End;
|
|---|
| 5597 |
|
|---|
| 5598 | DosQueryCollate(256, cc, CollatingSequence, L);
|
|---|
| 5599 | End;
|
|---|
| 5600 |
|
|---|
| 5601 | {$ENDIF}
|
|---|
| 5602 |
|
|---|
| 5603 | Function StringOfChars(CH: Char; Count: Integer): String;
|
|---|
| 5604 | Begin
|
|---|
| 5605 | SetLength(Result, Count);
|
|---|
| 5606 | FillChar(Result[1], Count, CH);
|
|---|
| 5607 | End;
|
|---|
| 5608 |
|
|---|
| 5609 | {Exception management}
|
|---|
| 5610 | Constructor Exception.CreateFmt(Const Msg:String;Const Args:Array Of Const);
|
|---|
| 5611 | Begin
|
|---|
| 5612 | Inherited Create(format(Msg,Args));
|
|---|
| 5613 | End;
|
|---|
| 5614 |
|
|---|
| 5615 | Constructor Exception.CreateRes(Ident:Word);
|
|---|
| 5616 | Begin
|
|---|
| 5617 | Inherited Create(LoadStr(Ident));
|
|---|
| 5618 | End;
|
|---|
| 5619 |
|
|---|
| 5620 | Constructor Exception.CreateResFmt(Ident:Word;Const Args:Array Of Const);
|
|---|
| 5621 | Begin
|
|---|
| 5622 | Inherited Create(format(LoadStr(Ident),Args));
|
|---|
| 5623 | End;
|
|---|
| 5624 |
|
|---|
| 5625 | Constructor Exception.CreateResNLS(Ident:Word);
|
|---|
| 5626 | Begin
|
|---|
| 5627 | Inherited Create(LoadNLSStr(Ident));
|
|---|
| 5628 | End;
|
|---|
| 5629 |
|
|---|
| 5630 | Constructor Exception.CreateResNLSFmt(Ident:Word;Const Args:Array Of Const);
|
|---|
| 5631 | Begin
|
|---|
| 5632 | Inherited Create(format(LoadNLSStr(Ident),Args));
|
|---|
| 5633 | End;
|
|---|
| 5634 |
|
|---|
| 5635 | Constructor Exception.CreateHelp(Const Msg:String;AHelpContext:LongInt);
|
|---|
| 5636 | Begin
|
|---|
| 5637 | Inherited Create(Msg);
|
|---|
| 5638 | HelpContext:=AHelpContext;
|
|---|
| 5639 | End;
|
|---|
| 5640 |
|
|---|
| 5641 | Constructor Exception.CreateFmtHelp(Const Msg:String;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 5642 | Begin
|
|---|
| 5643 | Inherited Create(format(Msg,Args));
|
|---|
| 5644 | HelpContext:=AHelpContext;
|
|---|
| 5645 | End;
|
|---|
| 5646 |
|
|---|
| 5647 | Constructor Exception.CreateResHelp(Ident:Word;AHelpContext:LongInt);
|
|---|
| 5648 | Begin
|
|---|
| 5649 | Inherited Create(LoadStr(Ident));
|
|---|
| 5650 | HelpContext:=AHelpContext;
|
|---|
| 5651 | End;
|
|---|
| 5652 |
|
|---|
| 5653 | Constructor Exception.CreateResFmtHelp(Ident:Word;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 5654 | Begin
|
|---|
| 5655 | Inherited Create(format(LoadStr(Ident),Args));
|
|---|
| 5656 | HelpContext:=AHelpContext;
|
|---|
| 5657 | End;
|
|---|
| 5658 |
|
|---|
| 5659 | Constructor Exception.CreateResNLSHelp(Ident:Word;AHelpContext:LongInt);
|
|---|
| 5660 | Begin
|
|---|
| 5661 | Inherited Create(LoadNLSStr(Ident));
|
|---|
| 5662 | HelpContext:=AHelpContext;
|
|---|
| 5663 | End;
|
|---|
| 5664 |
|
|---|
| 5665 | Constructor Exception.CreateResNLSFmtHelp(Ident:Word;Const Args:Array Of Const;AHelpContext:LongInt);
|
|---|
| 5666 | Begin
|
|---|
| 5667 | Inherited Create(format(LoadNLSStr(Ident),Args));
|
|---|
| 5668 | HelpContext:=AHelpContext;
|
|---|
| 5669 | End;
|
|---|
| 5670 |
|
|---|
| 5671 | Var AH,AQ:LongWord;
|
|---|
| 5672 |
|
|---|
| 5673 | Begin
|
|---|
| 5674 | {$IFDEF OS2}
|
|---|
| 5675 | InitPM;
|
|---|
| 5676 | {$ENDIF}
|
|---|
| 5677 | SetCurrentLanguageTable('SIBYL_NLS_Default');
|
|---|
| 5678 | GetFormatSettings;
|
|---|
| 5679 | End.
|
|---|
| 5680 |
|
|---|
| 5681 | { -- date -- -- changes ----------------------------------------------
|
|---|
| 5682 |
|
|---|
| 5683 | 28-Feb-96 assume fmShareDenyNone, If no sharing Mode Is specified.
|
|---|
| 5684 | added support For File locking.
|
|---|
| 5685 | 08-Mar-96 added lots Of comments. added resources And loading Of
|
|---|
| 5686 | Error Messages And Month / Day Names.
|
|---|
| 5687 | FIXED A bug In FormatStr.
|
|---|
| 5688 | 14-Apr-96 removed Some forgotten debugging Code.
|
|---|
| 5689 | 18-Apr-96 added windows-only AnsiLowerCase And AnsiCompareStr.
|
|---|
| 5690 | FIXED A bug In DayOfWeek.
|
|---|
| 5691 | Faster EncodeDate / DecodeDate.
|
|---|
| 5692 | 12-may-96 Error codes returned by File Open FUNCTIONs were always -1.
|
|---|
| 5693 | 24-may-96 added Trim, TrimLeft, TrimRight, And QuotedStr FUNCTIONs As
|
|---|
| 5694 | In Delphi 2.0.
|
|---|
| 5695 | 11-Jun-96 bug In FloatToStrF, ffGeneral With values < 0.001 always used
|
|---|
| 5696 | FIXED Point.
|
|---|
| 5697 | 27-Jul-96 removed SetLength, already declared In System Unit.
|
|---|
| 5698 | 27-Aug-96 added SysErrorMessage.
|
|---|
| 5699 | 26-Dec-96 FIXED Error In date encoding. changed numerous Parameters In
|
|---|
| 5700 | API calls from LongInt To LongWord where ULONG was expected.
|
|---|
| 5701 | 27-Dec-96 added support For AnsiStrings As Open Array Parameters In
|
|---|
| 5702 | String formatting FUNCTIONs.
|
|---|
| 5703 | 02-Feb-97 FIXED Some bugs:
|
|---|
| 5704 | - FileWrite returned -1 ON Success instead Of ON failure.
|
|---|
| 5705 | - DateTimeToFileDate didn't work With New Compiler.
|
|---|
| 5706 | changed File access Mode For FileCreate To RD/WR/exclusive.
|
|---|
| 5707 |
|
|---|
| 5708 |
|
|---|
| 5709 | ---------------------------
|
|---|
| 5710 | Bemerkungen fr Jrg: (nur der Form halber)
|
|---|
| 5711 | -
|
|---|
| 5712 | Function FileCreate
|
|---|
| 5713 | fmOpenReadWrite Or fmShareExclusive
|
|---|
| 5714 | -
|
|---|
| 5715 | Function DateTimeToFileDate
|
|---|
| 5716 | Result := (FileDate Shl 16) Or FILETIME;
|
|---|
| 5717 |
|
|---|