Subversion Repositories Kolibri OS

Rev

Rev 3131 | Rev 3859 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
717 mikedld 1
;;================================================================================================;;
2
;;//// libini.asm //// (c) mike.dld, 2006-2008 ///////////////////////////////////////////////////;;
3
;;================================================================================================;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
1001 diamond 8
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
9
;; of the License, or (at your option) any later version.                                         ;;
717 mikedld 10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
1001 diamond 13
;; Lesser General Public License for more details.                                                ;;
717 mikedld 14
;;                                                                                                ;;
1001 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
717 mikedld 17
;;                                                                                                ;;
18
;;================================================================================================;;
19
;;                                                                                                ;;
1048 mikedld 20
;; 2009-03-08 (mike.dld)                                                                          ;;
21
;;   bug-fixes:                                                                                   ;;
22
;;     - moved buffer bound check in libini._.low.read_value up (reported by Insolor)             ;;
23
;;   new features:                                                                                ;;
24
;;     - comments support (char is ini.COMMENT_CHAR, defaults to ';')                             ;;
25
;;       inline comments are not supported                                                        ;;
988 mikedld 26
;; 2008-12-29 (mike.dld)                                                                          ;;
27
;;   bug-fixes:                                                                                   ;;
28
;;     - unnecessary 'stosb' in ini.get_str was causing problems                                  ;;
995 mikedld 29
;;   new features:                                                                                ;;
30
;;     - new functions: ini.get_color and ini.set_color                                           ;;
845 mikedld 31
;; 2008-08-06 (mike.dld)                                                                          ;;
32
;;   changes:                                                                                     ;;
33
;;     - split private procs into libini_p.asm, added comments                                    ;;
717 mikedld 34
;; 2008-02-07 (mike.dld)                                                                          ;;
35
;;   changes:                                                                                     ;;
36
;;     - renamed all *.aux.* to *._.* to match overall libraries design                           ;;
37
;; 2007-09-26 (mike.dld)                                                                          ;;
38
;;   bug-fixes:                                                                                   ;;
39
;;     - value was not correctly trimmed (reported by diamond)                                    ;;
40
;; 2007-08-01 (mike.dld)                                                                          ;;
41
;;   bug-fixes:                                                                                   ;;
42
;;     - serious defect in ini.set_str causing displaced write operations                         ;;
43
;;       (reported by diamond)                                                                    ;;
44
;;     - another serious defect in ini.enum_keys introduced with refactoring                      ;;
45
;;   changes:                                                                                     ;;
46
;;     - callback for enum_keys now takes additional parameter - key value                        ;;
47
;;     - handling trailing spaces in section/key/value                                            ;;
48
;; 2007-05-19 (mike.dld)                                                                          ;;
49
;;   bug-fixes:                                                                                   ;;
50
;;     - last char still wasn't read correctly                                                    ;;
51
;;     - digits of number were reversed when using ini.set_int                                    ;;
52
;;     - now using 'ini.aux.unget_char' instead of dangerous 'dec esi'                            ;;
53
;;   changes:                                                                                     ;;
54
;;     - all non-public functions now start with ini.aux.*                                        ;;
55
;;     - added ini.enum_sections and ini.enum_keys                                                ;;
56
;;     - removed ini.query_sec (use ini.enum_* instead)                                           ;;
57
;;                                                                                                ;;
58
;;================================================================================================;;
59
 
60
format MS COFF
61
 
62
public @EXPORT as 'EXPORTS'
63
 
64
include '../../../../proc32.inc'
65
include '../../../../macros.inc'
66
include '../libio/libio.inc'
1327 diamond 67
purge section,mov,add,sub
717 mikedld 68
 
69
include 'libini_p.inc'
70
 
845 mikedld 71
section '.flat' code readable align 16
717 mikedld 72
 
845 mikedld 73
include 'libini_p.asm'
717 mikedld 74
 
75
;;================================================================================================;;
76
proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
77
;;------------------------------------------------------------------------------------------------;;
845 mikedld 78
;? Enumerate sections, calling callback function for each of them                                 ;;
717 mikedld 79
;;------------------------------------------------------------------------------------------------;;
845 mikedld 80
;> _f_name = ini filename                                                                 ;;
81
;> _callback = callback function address: func(f_name, sec_name), where                           ;;
82
;>   f_name = ini filename (as passed to the function)                                    ;;
83
;>   sec_name = section name found                                                        ;;
717 mikedld 84
;;------------------------------------------------------------------------------------------------;;
845 mikedld 85
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 86
;;================================================================================================;;
87
locals
2603 hidnplayr 88
  f       IniFile
717 mikedld 89
  f_addr  dd ?
90
  sec_buf dd ?
91
endl
92
 
2603 hidnplayr 93
        push    ebx esi edi
717 mikedld 94
 
2603 hidnplayr 95
        cld
717 mikedld 96
 
2603 hidnplayr 97
        invoke  mem.alloc, ini.MAX_NAME_LEN
98
        or      eax, eax
99
        jz      .exit_error.2
100
        mov     [sec_buf], eax
717 mikedld 101
 
2603 hidnplayr 102
        xor     eax, eax
103
        mov     [f.fh], eax
104
        mov     [f.buf], eax
105
        invoke  file.open, [_f_name], O_READ
106
        cmp     eax, 32
3131 clevermous 107
        jb      .exit_file_error
2603 hidnplayr 108
        mov     [f.fh], eax
109
        invoke  mem.alloc, ini.MEM_SIZE
110
        or      eax, eax
111
        jz      .exit_error
112
        mov     [f.buf], eax
113
        lea     ebx, [f]
114
        mov     [f_addr], ebx
717 mikedld 115
 
2603 hidnplayr 116
        invoke  file.seek, [f.fh], 0, SEEK_SET
117
        stdcall libini._.preload_block, [f_addr]
717 mikedld 118
 
119
  .next_section:
2603 hidnplayr 120
        stdcall libini._.find_next_section, [f_addr]
121
        or      eax, eax
122
        jnz     .exit_error
717 mikedld 123
 
2603 hidnplayr 124
        stdcall libini._.get_char, [f_addr]
125
        stdcall libini._.skip_spaces, [f_addr]
126
        mov     edi, [sec_buf]
845 mikedld 127
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 128
        cmp     al, ']'
129
        je      @f
130
        or      al, al
131
        jz      .exit_ok
132
        cmp     al, 13
133
        je      .next_section
134
        cmp     al, 10
135
        je      .next_section
136
        stosb
137
        jmp     @b
138
    @@: xor     al, al
139
        stosb
140
        add     edi, -2
141
    @@: cmp     byte[edi], 32
142
        ja      @f
143
        mov     byte[edi], 0
144
        dec     edi
145
        jmp     @b
717 mikedld 146
    @@:
2603 hidnplayr 147
        pushad
148
        mov     eax, [f_addr]
149
        stdcall [_callback], [_f_name], [sec_buf]
150
        or      eax, eax
151
        popad
152
        jnz     .next_section
717 mikedld 153
 
154
  .exit_ok:
2603 hidnplayr 155
        invoke  file.close, [f.fh]
156
        invoke  mem.free, [f.buf]
157
        invoke  mem.free, [sec_buf]
158
        xor     eax, eax
159
        pop     edi esi ebx
160
        ret
717 mikedld 161
 
162
  .exit_error:
2603 hidnplayr 163
        invoke  file.close, [f.fh]
164
        invoke  mem.free, [f.buf]
3131 clevermous 165
  .exit_file_error:
2603 hidnplayr 166
        invoke  mem.free, [sec_buf]
717 mikedld 167
  .exit_error.2:
2603 hidnplayr 168
        or      eax, -1
169
        pop     edi esi ebx
170
        ret
717 mikedld 171
endp
172
 
173
;;================================================================================================;;
174
proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
175
;;------------------------------------------------------------------------------------------------;;
845 mikedld 176
;? Enumerate keys within a section, calling callback function for each of them                    ;;
717 mikedld 177
;;------------------------------------------------------------------------------------------------;;
845 mikedld 178
;> _f_name = ini filename                                                                 ;;
179
;> _sec_name = section name                                                               ;;
180
;> _callback = callback function address: func(f_name, sec_name, key_name, key_value), where      ;;
181
;>   f_name = ini filename (as passed to the function)                                    ;;
182
;>   sec_name = section name (as passed to the function)                                  ;;
183
;>   key_name = key name found                                                            ;;
184
;>   key_value = value of key found                                                       ;;
717 mikedld 185
;;------------------------------------------------------------------------------------------------;;
845 mikedld 186
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 187
;;================================================================================================;;
188
locals
2603 hidnplayr 189
  f       IniFile
717 mikedld 190
  f_addr  dd ?
191
  key_buf dd ?
192
  val_buf dd ?
193
endl
194
 
2603 hidnplayr 195
        push    ebx esi edi
717 mikedld 196
 
2603 hidnplayr 197
        cld
717 mikedld 198
 
2603 hidnplayr 199
        invoke  mem.alloc, ini.MAX_NAME_LEN
200
        or      eax, eax
201
        jz      .exit_error.3
202
        mov     [key_buf], eax
203
        invoke  mem.alloc, ini.MAX_VALUE_LEN
204
        or      eax, eax
205
        jz      .exit_error.2
206
        mov     [val_buf], eax
717 mikedld 207
 
2603 hidnplayr 208
        xor     eax, eax
209
        mov     [f.fh], eax
210
        mov     [f.buf], eax
211
        invoke  file.open, [_f_name], O_READ
212
        cmp     eax, 32
3131 clevermous 213
        jb      .exit_file_error
2603 hidnplayr 214
        mov     [f.fh], eax
215
        invoke  mem.alloc, ini.MEM_SIZE
216
        or      eax, eax
217
        jz      .exit_error
218
        mov     [f.buf], eax
219
        lea     ebx, [f]
220
        mov     [f_addr], ebx
221
        stdcall libini._.find_section, ebx, [_sec_name]
222
        or      eax, eax
223
        jnz     .exit_error
717 mikedld 224
 
225
  .next_key:
2603 hidnplayr 226
        stdcall libini._.skip_line, [f_addr]
227
        stdcall libini._.skip_nonblanks, [f_addr]
228
        or      al, al
229
        jz      .exit_error
230
        cmp     al, '['
231
        je      .exit_error
232
        mov     edi, [key_buf]
845 mikedld 233
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 234
        or      al, al
235
        jz      .exit_error
236
        cmp     al, '='
237
        je      @f
238
        stosb
239
        jmp     @b
717 mikedld 240
    @@:
2603 hidnplayr 241
        xor     al, al
242
        stosb
243
        add     edi, -2
244
    @@: cmp     byte[edi], 32
245
        ja      @f
246
        mov     byte[edi], 0
247
        dec     edi
248
        jmp     @b
845 mikedld 249
    @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
2603 hidnplayr 250
        pushad
251
        stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
252
        or      eax, eax
253
        popad
254
        jnz     .next_key
717 mikedld 255
 
2603 hidnplayr 256
    @@: invoke  file.close, [f.fh]
257
        invoke  mem.free, [f.buf]
258
        xor     eax, eax
259
        stosb
260
        pop     edi esi ebx
261
        ret
717 mikedld 262
 
263
  .exit_error:
2603 hidnplayr 264
        invoke  file.close, [f.fh]
265
        invoke  mem.free, [f.buf]
3131 clevermous 266
  .exit_file_error:
2603 hidnplayr 267
        invoke  mem.free, [val_buf]
717 mikedld 268
  .exit_error.2:
2603 hidnplayr 269
        invoke  mem.free, [key_buf]
717 mikedld 270
  .exit_error.3:
2603 hidnplayr 271
        or      eax, -1
272
        pop     edi esi ebx
273
        ret
717 mikedld 274
endp
275
 
276
;;================================================================================================;;
277
proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
278
;;------------------------------------------------------------------------------------------------;;
845 mikedld 279
;? Read string                                                                                    ;;
717 mikedld 280
;;------------------------------------------------------------------------------------------------;;
845 mikedld 281
;> _f_name = ini filename                                                                 ;;
282
;> _sec_name = section name                                                               ;;
283
;> _key_name = key name                                                                   ;;
284
;> _buffer = destination buffer address                                                    ;;
285
;> _buf_len = buffer size (maximum bytes to read)                                          ;;
286
;> _def_val = default value to return if no key, section or file found                    ;;
717 mikedld 287
;;------------------------------------------------------------------------------------------------;;
845 mikedld 288
;< eax = -1 (error) / 0                                                                           ;;
289
;< [_buffer] = [_def_val] (error) / found key value                                       ;;
717 mikedld 290
;;================================================================================================;;
291
locals
2603 hidnplayr 292
  f      IniFile
717 mikedld 293
  f_addr dd ?
294
endl
295
 
2603 hidnplayr 296
        push    ebx esi edi
717 mikedld 297
 
2603 hidnplayr 298
        xor     eax, eax
299
        mov     [f.fh], eax
300
        mov     [f.buf], eax
301
        invoke  file.open, [_f_name], O_READ
302
        cmp     eax, 32
3131 clevermous 303
        jb      .exit_file_error
2603 hidnplayr 304
        mov     [f.fh], eax
305
        invoke  mem.alloc, ini.MEM_SIZE
306
        or      eax, eax
307
        jz      .exit_error
308
        mov     [f.buf], eax
309
        lea     ebx, [f]
310
        mov     [f_addr], ebx
311
        stdcall libini._.find_section, ebx, [_sec_name]
312
        or      eax, eax
313
        jnz     .exit_error
717 mikedld 314
 
2603 hidnplayr 315
        stdcall libini._.find_key, ebx, [_key_name]
316
        or      eax, eax
317
        jnz     .exit_error
717 mikedld 318
 
2603 hidnplayr 319
        stdcall libini._.low.read_value, [f_addr], [_buffer], [_buf_len]
320
    @@: invoke  file.close, [f.fh]
321
        invoke  mem.free, [f.buf]
322
        xor     eax, eax
323
        pop     edi esi ebx
324
        ret
717 mikedld 325
 
326
  .exit_error:
2603 hidnplayr 327
        invoke  file.close, [f.fh]
328
        invoke  mem.free, [f.buf]
3131 clevermous 329
  .exit_file_error:
2603 hidnplayr 330
        mov     edi, [_buffer]
331
        mov     esi, [_def_val]
332
        xor     al, al
333
        or      esi, esi
334
        jz      .exit_error.2
717 mikedld 335
    @@: lodsb
988 mikedld 336
  .exit_error.2:
2603 hidnplayr 337
        stosb
338
        or      al, al
339
        jnz     @b
340
        or      eax, -1
341
        pop     edi esi ebx
342
        ret
717 mikedld 343
endp
344
 
345
;;================================================================================================;;
346
proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
347
;;------------------------------------------------------------------------------------------------;;
845 mikedld 348
;? Write string                                                                                   ;;
717 mikedld 349
;;------------------------------------------------------------------------------------------------;;
845 mikedld 350
;> _f_name = ini filename                                                                 ;;
351
;> _sec_name = section name                                                               ;;
352
;> _key_name = key name                                                                   ;;
353
;> _buffer = source buffer address                                                         ;;
354
;> _buf_len = buffer size (bytes to write)                                                 ;;
717 mikedld 355
;;------------------------------------------------------------------------------------------------;;
845 mikedld 356
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 357
;;================================================================================================;;
358
locals
2603 hidnplayr 359
  f      IniFile
717 mikedld 360
  f_addr dd ?
361
endl
362
 
2603 hidnplayr 363
        push    ebx esi edi
717 mikedld 364
 
2603 hidnplayr 365
        xor     eax, eax
366
        mov     [f.fh], eax
367
        mov     [f.buf], eax
368
        invoke  file.open, [_f_name], O_READ + O_WRITE + O_CREATE
369
        cmp     eax, 32
3131 clevermous 370
        jb      .exit_file_error
2603 hidnplayr 371
        mov     [f.fh], eax
372
        invoke  mem.alloc, ini.MEM_SIZE
373
        or      eax, eax
374
        jz      .exit_error
375
        mov     [f.buf], eax
376
        lea     ebx, [f]
377
        mov     [f_addr], ebx
717 mikedld 378
 
2603 hidnplayr 379
        stdcall libini._.find_section, ebx, [_sec_name]
380
        or      eax, eax
381
        jnz     .create_section
717 mikedld 382
 
2603 hidnplayr 383
        stdcall libini._.find_key, ebx, [_key_name]
384
        or      eax, eax
385
        jnz     .create_key
717 mikedld 386
 
387
  .modify_key:
2603 hidnplayr 388
        stdcall libini._.get_value_length, [f_addr]
389
        sub     eax, [_buf_len]
390
        stdcall libini._.shift_content, [f_addr], eax
717 mikedld 391
 
392
  .modify_key.ex:
2603 hidnplayr 393
        invoke  file.tell, [f.fh]
394
        sub     eax, [f.cnt]
395
        invoke  file.seek, [f.fh], eax, SEEK_SET
396
        invoke  file.write, [f.fh], [_buffer], [_buf_len]
717 mikedld 397
 
3131 clevermous 398
        invoke  file.close, [f.fh]
2603 hidnplayr 399
        pop     edi esi ebx
400
        xor     eax, eax
401
        ret
717 mikedld 402
 
403
  .create_key:
2603 hidnplayr 404
        mov     edi, [f.buf]
405
        add     edi, ini.BLOCK_SIZE
406
        push    edi
717 mikedld 407
 
408
  .create_key.ex:
2603 hidnplayr 409
        mov     esi, [_key_name]
410
        call    libini._.string_copy
411
        mov     byte[edi], '='
412
        inc     edi
413
        mov     esi, [_buffer]
414
        mov     ecx, [_buf_len]
415
        rep     movsb
416
        mov     word[edi], 0x0A0D
417
        add     edi, 2
418
        mov     eax, edi
717 mikedld 419
 
2603 hidnplayr 420
        pop     edi
421
        sub     eax, edi
422
        mov     [_buffer], edi
423
        mov     [_buf_len], eax
424
        neg     eax
425
        stdcall libini._.shift_content, [f_addr], eax
717 mikedld 426
 
2603 hidnplayr 427
        jmp     .modify_key.ex
717 mikedld 428
 
429
  .create_section:
2603 hidnplayr 430
        mov     edi, [f.buf]
431
        add     edi, ini.BLOCK_SIZE
432
        push    edi
717 mikedld 433
 
2603 hidnplayr 434
        mov     esi, [_sec_name]
435
        mov     byte[edi], '['
436
        inc     edi
437
        call    libini._.string_copy
438
        mov     dword[edi], ']' + (0x0A0D shl 8)
439
        add     edi, 3
717 mikedld 440
 
2603 hidnplayr 441
        jmp     .create_key.ex
717 mikedld 442
 
443
  .exit_error:
3131 clevermous 444
        invoke  file.close, [f.fh]
445
  .exit_file_error:
2603 hidnplayr 446
        pop     edi esi ebx
447
        or      eax, -1
448
        ret
717 mikedld 449
endp
450
 
451
;;================================================================================================;;
452
proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
453
;;------------------------------------------------------------------------------------------------;;
845 mikedld 454
;? Read integer                                                                                   ;;
717 mikedld 455
;;------------------------------------------------------------------------------------------------;;
845 mikedld 456
;> _f_name = ini filename                                                                 ;;
457
;> _sec_name = section name                                                               ;;
458
;> _key_name = key name                                                                   ;;
459
;> _def_val = default value to return if no key, section or file found                     ;;
717 mikedld 460
;;------------------------------------------------------------------------------------------------;;
845 mikedld 461
;< eax = [_def_val] (error) / found key value                                              ;;
717 mikedld 462
;;================================================================================================;;
463
locals
2603 hidnplayr 464
  f      IniFile
717 mikedld 465
  f_addr dd ?
466
endl
467
 
2603 hidnplayr 468
        push    edx ebx esi edi
717 mikedld 469
 
2603 hidnplayr 470
        xor     eax, eax
471
        mov     [f.fh], eax
472
        mov     [f.buf], eax
473
        invoke  file.open, [_f_name], O_READ
474
        cmp     eax, 32
3131 clevermous 475
        jb      .exit_file_error
2603 hidnplayr 476
        mov     [f.fh], eax
477
        invoke  mem.alloc, ini.MEM_SIZE
478
        or      eax, eax
479
        jz      .exit_error
480
        mov     [f.buf], eax
481
        lea     ebx, [f]
482
        mov     [f_addr], ebx
483
        stdcall libini._.find_section, ebx, [_sec_name]
484
        or      eax, eax
485
        jnz     .exit_error
717 mikedld 486
 
2603 hidnplayr 487
        stdcall libini._.find_key, ebx, [_key_name]
488
        or      eax, eax
489
        jnz     .exit_error
717 mikedld 490
 
2603 hidnplayr 491
        stdcall libini._.skip_spaces, [f_addr]
492
        xor     eax, eax
493
        xor     ebx, ebx
494
        xor     edx, edx
495
        stdcall libini._.get_char, [f_addr]
496
        cmp     al, '-'
497
        jne     .lp1
498
        inc     bh
845 mikedld 499
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 500
  .lp1: cmp     al, '0'
501
        jb      @f
502
        cmp     al, '9'
503
        ja      @f
504
        inc     bl
505
        add     eax, -'0'
506
        imul    edx, 10
507
        add     edx, eax
508
        jmp     @b
717 mikedld 509
    @@:
2603 hidnplayr 510
        or      bl, bl
511
        jz      .exit_error
512
        or      bh, bh
513
        jz      @f
514
        neg     edx
515
    @@: invoke  file.close, [f.fh]
516
        invoke  mem.free, [f.buf]
517
        mov     eax, edx
518
        pop     edi esi ebx edx
519
        ret
717 mikedld 520
 
521
  .exit_error:
2603 hidnplayr 522
        invoke  file.close, [f.fh]
3131 clevermous 523
  .exit_file_error:
2603 hidnplayr 524
        invoke  mem.free, [f.buf]
525
        mov     eax, [_def_val]
526
        pop     edi esi ebx edx
527
        ret
717 mikedld 528
endp
529
 
530
;;================================================================================================;;
531
proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
532
;;------------------------------------------------------------------------------------------------;;
845 mikedld 533
;? Write integer                                                                                  ;;
717 mikedld 534
;;------------------------------------------------------------------------------------------------;;
845 mikedld 535
;> _f_name = ini filename                                                                 ;;
536
;> _sec_name = section name                                                               ;;
537
;> _key_name = key name                                                                   ;;
538
;> _val = value                                                                            ;;
717 mikedld 539
;;------------------------------------------------------------------------------------------------;;
845 mikedld 540
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 541
;;================================================================================================;;
542
locals
543
  buf rb 16
3832 GerdtR 544
  bNeg rd 1
717 mikedld 545
endl
546
 
2603 hidnplayr 547
        push    ecx edx edi
717 mikedld 548
 
2603 hidnplayr 549
        lea     edi, [buf]
550
        add     edi, 15
3832 GerdtR 551
 
2603 hidnplayr 552
        mov     eax, [_val]
3832 GerdtR 553
        mov     [bNeg],0
2603 hidnplayr 554
        or      eax, eax
555
        jns     @f
3832 GerdtR 556
        mov     [bNeg],1
2603 hidnplayr 557
        neg     eax
3832 GerdtR 558
 
2603 hidnplayr 559
    @@: mov     ecx, 10
560
    @@: xor     edx, edx
561
        idiv    ecx
562
        add     dl, '0'
563
        mov     [edi], dl
564
        dec     edi
565
        or      eax, eax
566
        jnz     @b
3832 GerdtR 567
 
568
        cmp     [bNeg],0
569
        je      @f
570
        mov     byte[edi], '-'
571
        dec     edi
572
     @@:
2603 hidnplayr 573
        lea     eax, [buf]
574
        add     eax, 15
575
        sub     eax, edi
576
        inc     edi
717 mikedld 577
 
3832 GerdtR 578
 
579
 
2603 hidnplayr 580
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
717 mikedld 581
 
2603 hidnplayr 582
        pop     edi edx ecx
583
        ret
717 mikedld 584
endp
585
 
988 mikedld 586
;;================================================================================================;;
587
proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
588
;;------------------------------------------------------------------------------------------------;;
589
;? Read color                                                                                     ;;
590
;;------------------------------------------------------------------------------------------------;;
591
;> _f_name = ini filename                                                                 ;;
592
;> _sec_name = section name                                                               ;;
593
;> _key_name = key name                                                                   ;;
594
;> _def_val = default value to return if no key, section or file found                     ;;
595
;;------------------------------------------------------------------------------------------------;;
596
;< eax = [_def_val] (error) / found key value                                              ;;
597
;;================================================================================================;;
598
locals
599
  buf rb 14
600
endl
717 mikedld 601
 
2603 hidnplayr 602
        push    ebx esi edi
988 mikedld 603
 
2603 hidnplayr 604
        lea     esi, [buf]
605
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
606
        cmp     byte[esi],0
607
        je      .exit_error
988 mikedld 608
 
2603 hidnplayr 609
        xor     ebx, ebx
610
        stdcall libini._.str_to_int
611
        movzx   ebx, al
612
        shl     ebx, 16
613
        lodsb
614
        cmp     al, ','
615
        jne     @f
616
        stdcall libini._.str_to_int
617
        mov     bh, al
618
        lodsb
619
        cmp     al, ','
620
        jne     @f
621
        stdcall libini._.str_to_int
622
        mov     bl, al
988 mikedld 623
 
2603 hidnplayr 624
    @@: mov     eax, ebx
988 mikedld 625
 
2603 hidnplayr 626
        pop     edi esi ebx
627
        ret
988 mikedld 628
 
629
  .exit_error:
2603 hidnplayr 630
        mov     eax, [_def_val]
631
        pop     edi esi ebx
632
        ret
988 mikedld 633
endp
634
 
717 mikedld 635
;;================================================================================================;;
988 mikedld 636
proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
637
;;------------------------------------------------------------------------------------------------;;
638
;? Write color                                                                                    ;;
639
;;------------------------------------------------------------------------------------------------;;
640
;> _f_name = ini filename                                                                 ;;
641
;> _sec_name = section name                                                               ;;
642
;> _key_name = key name                                                                   ;;
643
;> _val = value                                                                            ;;
644
;;------------------------------------------------------------------------------------------------;;
645
;< eax = -1 (error) / 0                                                                           ;;
646
;;================================================================================================;;
647
locals
648
  buf rb 16
649
endl
650
 
2603 hidnplayr 651
        push    ecx edx edi
988 mikedld 652
 
2603 hidnplayr 653
        lea     edi, [buf]
654
        mov     ecx, 10
655
        mov     ebx, [_val]
656
        mov     eax, ebx
657
        shr     eax, 16
658
        and     eax, 0x0ff
659
        stdcall libini._.int_to_str
660
        mov     byte[edi], ','
661
        inc     edi
662
        movzx   eax, bh
663
        stdcall libini._.int_to_str
664
        mov     byte[edi], ','
665
        inc     edi
666
        movzx   eax, bl
667
        stdcall libini._.int_to_str
988 mikedld 668
 
2603 hidnplayr 669
        lea     eax, [buf]
670
        sub     edi, eax
988 mikedld 671
 
2603 hidnplayr 672
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
988 mikedld 673
 
2603 hidnplayr 674
        pop     edi edx ecx
675
        ret
988 mikedld 676
endp
677
 
3832 GerdtR 678
 
1327 diamond 679
;;================================================================================================;;
3832 GerdtR 680
proc ini.del_section _f_name, _sec_name ;/////////////////////////////////////////////////////////;;
681
;;------------------------------------------------------------------------------------------------;;
682
;? Delete section and all key in this section                                                     ;;
683
;;------------------------------------------------------------------------------------------------;;
684
;> _f_name = ini filename                                                                 ;;
685
;> _sec_name = section name                                                               ;;
686
;;------------------------------------------------------------------------------------------------;;
687
;< eax = 0 - success                                                                              ;;
688
;<      -1 - file not found                                                                       ;;
689
;<       1 - section not found                                                                    ;;
690
;;================================================================================================;;
691
locals
692
   funcFile     rb 25
693
   fileInfo     rb 40
694
   begMem       rd 1
695
   endMem       rd 1
696
   begDel       rd 1
697
   endDel       rd 1
698
endl
699
        push    ebx ecx edi esi
700
        mov     dword[funcFile],5               ;get file info
701
        mov     dword[funcFile+4],0
702
        mov     dword[funcFile+8],0
703
        mov     dword[funcFile+12],0
704
        lea     eax,[fileInfo]
705
        mov     dword[funcFile+16],eax
706
        mov     byte[funcFile+20],0
707
        m2m     dword[funcFile+21],[_f_name]
708
        lea     ebx,[funcFile]
709
        mcall   70
710
        test    eax,eax
711
        jz      @f
712
 
713
        or      eax,-1
714
        pop     esi edi ecx ebx
715
        ret
716
      @@:
717
 
718
        mov     ecx,dword[fileInfo+32]          ;allocation mem for all file
719
        mcall   68,12
720
 
721
        mov     [begMem],eax
722
        mov     [endMem],eax
723
        add     [endMem],ecx
724
 
725
        mov     dword[funcFile],0               ;read file to buffer
726
        mov     dword[funcFile+12],ecx
727
        mov     dword[funcFile+16],eax
728
        lea     ebx,[funcFile]
729
        mcall   70
730
 
731
        mov     edi,[begMem]                    ;search begin section
732
    .searchSect:
733
        mov     al,'['
734
        repne   scasb
735
        test    ecx,ecx
736
        jnz     @f
737
 
738
        pop     esi edi ecx ebx
739
        mov     eax,1
740
        ret
741
      @@:
742
        mov     [begDel],edi
743
        mov     esi,[_sec_name]
744
      @@:
745
        lodsb
746
        test    al,al
747
        jz      @f
748
        scasb
749
        jne     .searchSect
750
        jmp     @b
751
      @@:
752
        cmp     byte[edi],']'
753
        jne     .searchSect
754
 
755
        dec     [begDel]
756
 
757
        mov     edi,[begDel]                    ;search end section
758
        inc     edi
759
    .searchEndSect:
760
        mov     al,'['
761
        repne   scasb
762
 
763
        dec     edi
764
        mov     [endDel],edi
765
 
766
        test    ecx,ecx
767
        jnz     @f
768
        jmp     .SaveToFile
769
      @@:
770
 
771
 
772
        mov     esi,[endDel]
773
        mov     edi,[begDel]
774
   @@:  lodsb
775
        stosb
776
        cmp     esi,[endMem]
777
        jb      @b
778
 
779
   .SaveToFile:
780
        mov     eax,dword[funcFile+12]
781
        sub     eax,[endDel]
782
        add     eax,[begDel]
783
 
784
        mov     dword[funcFile],2               ;write buffer to file
785
        mov     dword[funcFile+12],eax
786
        m2m     dword[funcFile+16],[begMem]
787
        lea     ebx,[funcFile]
788
        mcall   70
789
 
790
        xor     eax,eax
791
        pop     esi edi ecx ebx
792
        ret
793
endp
794
 
795
 
796
 
797
 
798
;;================================================================================================;;
1327 diamond 799
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
800
;;------------------------------------------------------------------------------------------------;;
801
;? Read shortcut key                                                                              ;;
802
;;------------------------------------------------------------------------------------------------;;
803
;> _f_name = ini filename                                                                 ;;
804
;> _sec_name = section name                                                               ;;
805
;> _key_name = key name                                                                   ;;
806
;> _def_val = default value to return if no key, section or file found                     ;;
807
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4       ;;
808
;;------------------------------------------------------------------------------------------------;;
809
;< eax = [_def_val] (error) / shortcut key value as scancode                                 ;;
810
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut                    ;;
811
;;================================================================================================;;
812
locals
813
  buf rb 64
814
endl
988 mikedld 815
 
2603 hidnplayr 816
        push    ebx esi edi
1327 diamond 817
 
2603 hidnplayr 818
        lea     esi, [buf]
819
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
820
        cmp     byte[esi],0
821
        je      .exit_error
1327 diamond 822
 
2603 hidnplayr 823
        xor     ebx, ebx        ; ebx holds the value of modifiers
1327 diamond 824
.loop:
825
; test for end
2603 hidnplayr 826
        xor     eax, eax
827
        cmp     byte [esi], al
828
        jz      .exit_ok        ; exit with scancode zero
1327 diamond 829
; skip all '+'s
2603 hidnplayr 830
        cmp     byte [esi], '+'
831
        jnz     @f
832
        inc     esi
833
        jmp     .loop
1327 diamond 834
@@:
835
; test for names
2603 hidnplayr 836
        mov     edi, .names_table
837
        xor     edx, edx
1327 diamond 838
.names_loop:
2603 hidnplayr 839
        movzx   ecx, byte [edi]
840
        inc     edi
841
        push    esi
1327 diamond 842
@@:
2603 hidnplayr 843
        lodsb
844
        or      al, 20h
845
        scasb
846
        loopz   @b
847
        jz      .name_found
848
        pop     esi
849
        lea     edi, [edi+ecx+4]
850
        inc     edx
851
        cmp     byte [edi], 0
852
        jnz     .names_loop
1327 diamond 853
; special test: functional keys F
2603 hidnplayr 854
        cmp     byte [esi], 'f'
855
        jz      @f
856
        cmp     byte [esi], 'F'
857
        jnz     .no_fx
1327 diamond 858
@@:
2603 hidnplayr 859
        mov     edi, esi
860
        inc     esi
861
        call    libini._.str_to_int
862
        test    eax, eax
3112 dunkaist 863
        jnz     .fx
2603 hidnplayr 864
        mov     esi, edi
1327 diamond 865
.no_fx:
866
; name not found, that must be usual key
2603 hidnplayr 867
        movzx   eax, byte [esi]
868
        stdcall libini._.ascii_to_scan, eax
869
        test    eax, eax
870
        jz      .exit_error
1327 diamond 871
; all is ok
872
.exit_ok:
2603 hidnplayr 873
        mov     ecx, [_modifiers]
874
        test    ecx, ecx
875
        jz      @f
876
        mov     [ecx], ebx
1327 diamond 877
 
878
@@:
879
 
2603 hidnplayr 880
        pop     edi esi ebx
881
        ret
1327 diamond 882
 
883
.exit_error:
2603 hidnplayr 884
        mov     eax, [_def_val]
885
        pop     edi esi ebx
886
        ret
1327 diamond 887
; handler for Fx
888
; eax = number
889
.fx:
2603 hidnplayr 890
        cmp     eax, 10
891
        ja      @f
892
        add     eax, 3Bh-1
893
        jmp     .exit_ok
1327 diamond 894
@@:
2603 hidnplayr 895
        add     eax, 57h-11
896
        jmp     .exit_ok
1327 diamond 897
; handlers for names
898
.name_found:
2603 hidnplayr 899
        pop     eax     ; ignore saved esi
900
        call    dword [edi]
901
        cmp     edx, .num_modifiers
902
        jae     .exit_ok
903
        jmp     .loop
1327 diamond 904
; modifiers
905
; syntax of value for each modifier:
906
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
907
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
908
; generic modifier: 0->1->2->2, 3->2, 4->2
909
; left modifier: 0->3->3, 1->2->2, 4->2
910
; right modifier: 0->4->4, 1->2->2, 3->2
911
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
912
macro shortcut_handle_modifiers name,reg,shift
913
{
914
local .set2,.set3,.set4
2603 hidnplayr 915
.#name#_handler:        ; generic modifier
916
        test    reg, 0xF
917
        jnz     .set2
1327 diamond 918
if shift
2603 hidnplayr 919
        or      reg, 1 shl shift
1327 diamond 920
else
2603 hidnplayr 921
        inc     reg
1327 diamond 922
end if
2603 hidnplayr 923
        retn
1327 diamond 924
.set2:
2603 hidnplayr 925
        and     reg, not (0xF shl shift)
926
        or      reg, 2 shl shift
927
        retn
1327 diamond 928
.l#name#_handler:
2603 hidnplayr 929
        mov     al, reg
930
        and     al, 0xF shl shift
931
        jz      .set3
932
        cmp     al, 3 shl shift
933
        jnz     .set2
934
        retn
1327 diamond 935
.set3:
2603 hidnplayr 936
        add     reg, 3 shl shift
937
        retn
1327 diamond 938
.r#name#_handler:
2603 hidnplayr 939
        mov     al, reg
940
        and     al, 0xF shl shift
941
        jz      .set4
942
        cmp     al, 4 shl shift
943
        jnz     .set2
944
        retn
1327 diamond 945
.set4:
2603 hidnplayr 946
        add     reg, 4 shl shift
947
        retn
1327 diamond 948
}
949
shortcut_handle_modifiers shift,bl,0
950
shortcut_handle_modifiers ctrl,bl,4
951
shortcut_handle_modifiers alt,bh,0
952
; names of keys
953
.name_handler:
2603 hidnplayr 954
        movzx   eax, byte [.names_scancodes+edx-.num_modifiers]
955
        retn
1327 diamond 956
endp
957
 
958
; note: comparison ignores case, so this table keeps lowercase names
959
; macro does this
960
macro shortcut_name_with_handler name,handler
961
{
962
local .start, .end
2603 hidnplayr 963
        db      .end - .start
1327 diamond 964
.start:
2603 hidnplayr 965
        db      name
1327 diamond 966
.end:
967
repeat .end - .start
2603 hidnplayr 968
        load .a byte from .start + % - 1
969
        store byte .a or 0x20 at .start + % - 1
1327 diamond 970
end repeat
2603 hidnplayr 971
        dd      handler
1327 diamond 972
}
973
macro shortcut_name [name]
974
{
2603 hidnplayr 975
        shortcut_name_with_handler name, .name_handler
1327 diamond 976
}
3832 GerdtR 977
 
1327 diamond 978
; all names here must be in english
979
; ... or modify lowercasing in macro and in comparison
980
.names_table:
981
; generic modifiers
2603 hidnplayr 982
        shortcut_name_with_handler 'Ctrl', .ctrl_handler
983
        shortcut_name_with_handler 'Alt', .alt_handler
984
        shortcut_name_with_handler 'Shift', .shift_handler
1327 diamond 985
; concrete modifiers
2603 hidnplayr 986
        shortcut_name_with_handler 'LCtrl', .lctrl_handler
987
        shortcut_name_with_handler 'RCtrl', .rctrl_handler
988
        shortcut_name_with_handler 'LAlt', .lalt_handler
989
        shortcut_name_with_handler 'RAlt', .ralt_handler
990
        shortcut_name_with_handler 'LShift', .lshift_handler
991
        shortcut_name_with_handler 'RShift', .rshift_handler
1327 diamond 992
.num_modifiers = 9
993
; symbolic names of keys
2603 hidnplayr 994
        shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
995
        shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
996
        shortcut_name 'Up', 'Down'
1327 diamond 997
; end of table
2603 hidnplayr 998
        db      0
1327 diamond 999
ini.get_shortcut.names_scancodes:
1000
; scancodes for 'Home' ... 'Down'
2603 hidnplayr 1001
        db      47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
1002
        db      0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
1003
        db      48h, 50h
1327 diamond 1004
 
988 mikedld 1005
;;================================================================================================;;
717 mikedld 1006
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1007
;;================================================================================================;;
1008
;! Imported functions section                                                                     ;;
1009
;;================================================================================================;;
1010
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1011
;;================================================================================================;;
1012
 
1013
 
1014
align 16
1015
@IMPORT:
1016
 
1017
library \
2603 hidnplayr 1018
        libio , 'libio.obj'
717 mikedld 1019
 
2603 hidnplayr 1020
import  libio                       , \
1021
        file.size   , 'file_size'   , \
1022
        file.open   , 'file_open'   , \
1023
        file.read   , 'file_read'   , \
1024
        file.write  , 'file_write'  , \
1025
        file.seek   , 'file_seek'   , \
1026
        file.eof?   , 'file_iseof'  , \
1027
        file.seteof , 'file_seteof' , \
1028
        file.tell   , 'file_tell'   , \
1029
        file.close  , 'file_close'
717 mikedld 1030
 
1031
 
1032
;;================================================================================================;;
1033
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1034
;;================================================================================================;;
1035
;! Exported functions section                                                                     ;;
1036
;;================================================================================================;;
1037
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1038
;;================================================================================================;;
1039
 
1040
 
1041
align 16
1042
@EXPORT:
1043
 
2603 hidnplayr 1044
export                                            \
1045
        libini._.init     , 'lib_init'          , \
1046
        0x00080009        , 'version'           , \
1047
        ini.enum_sections , 'ini_enum_sections' , \
1048
        ini.enum_keys     , 'ini_enum_keys'     , \
1049
        ini.get_str       , 'ini_get_str'       , \
1050
        ini.get_int       , 'ini_get_int'       , \
1051
        ini.get_color     , 'ini_get_color'     , \
1052
        ini.set_str       , 'ini_set_str'       , \
1053
        ini.set_int       , 'ini_set_int'       , \
1054
        ini.set_color     , 'ini_set_color'     , \
3832 GerdtR 1055
        ini.get_shortcut  , 'ini_get_shortcut'  , \
1056
        ini.del_section   , 'ini_del_section'
1057