Subversion Repositories Kolibri OS

Rev

Rev 3112 | Rev 3832 | 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
544
endl
545
 
2603 hidnplayr 546
        push    ecx edx edi
717 mikedld 547
 
2603 hidnplayr 548
        lea     edi, [buf]
549
        add     edi, 15
550
        mov     eax, [_val]
551
        or      eax, eax
552
        jns     @f
553
        mov     byte[edi], '-'
554
        neg     eax
555
        inc     edi
556
    @@: mov     ecx, 10
557
    @@: xor     edx, edx
558
        idiv    ecx
559
        add     dl, '0'
560
        mov     [edi], dl
561
        dec     edi
562
        or      eax, eax
563
        jnz     @b
564
        lea     eax, [buf]
565
        add     eax, 15
566
        sub     eax, edi
567
        inc     edi
717 mikedld 568
 
2603 hidnplayr 569
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
717 mikedld 570
 
2603 hidnplayr 571
        pop     edi edx ecx
572
        ret
717 mikedld 573
endp
574
 
988 mikedld 575
;;================================================================================================;;
576
proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
577
;;------------------------------------------------------------------------------------------------;;
578
;? Read color                                                                                     ;;
579
;;------------------------------------------------------------------------------------------------;;
580
;> _f_name = ini filename                                                                 ;;
581
;> _sec_name = section name                                                               ;;
582
;> _key_name = key name                                                                   ;;
583
;> _def_val = default value to return if no key, section or file found                     ;;
584
;;------------------------------------------------------------------------------------------------;;
585
;< eax = [_def_val] (error) / found key value                                              ;;
586
;;================================================================================================;;
587
locals
588
  buf rb 14
589
endl
717 mikedld 590
 
2603 hidnplayr 591
        push    ebx esi edi
988 mikedld 592
 
2603 hidnplayr 593
        lea     esi, [buf]
594
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
595
        cmp     byte[esi],0
596
        je      .exit_error
988 mikedld 597
 
2603 hidnplayr 598
        xor     ebx, ebx
599
        stdcall libini._.str_to_int
600
        movzx   ebx, al
601
        shl     ebx, 16
602
        lodsb
603
        cmp     al, ','
604
        jne     @f
605
        stdcall libini._.str_to_int
606
        mov     bh, al
607
        lodsb
608
        cmp     al, ','
609
        jne     @f
610
        stdcall libini._.str_to_int
611
        mov     bl, al
988 mikedld 612
 
2603 hidnplayr 613
    @@: mov     eax, ebx
988 mikedld 614
 
2603 hidnplayr 615
        pop     edi esi ebx
616
        ret
988 mikedld 617
 
618
  .exit_error:
2603 hidnplayr 619
        mov     eax, [_def_val]
620
        pop     edi esi ebx
621
        ret
988 mikedld 622
endp
623
 
717 mikedld 624
;;================================================================================================;;
988 mikedld 625
proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
626
;;------------------------------------------------------------------------------------------------;;
627
;? Write color                                                                                    ;;
628
;;------------------------------------------------------------------------------------------------;;
629
;> _f_name = ini filename                                                                 ;;
630
;> _sec_name = section name                                                               ;;
631
;> _key_name = key name                                                                   ;;
632
;> _val = value                                                                            ;;
633
;;------------------------------------------------------------------------------------------------;;
634
;< eax = -1 (error) / 0                                                                           ;;
635
;;================================================================================================;;
636
locals
637
  buf rb 16
638
endl
639
 
2603 hidnplayr 640
        push    ecx edx edi
988 mikedld 641
 
2603 hidnplayr 642
        lea     edi, [buf]
643
        mov     ecx, 10
644
        mov     ebx, [_val]
645
        mov     eax, ebx
646
        shr     eax, 16
647
        and     eax, 0x0ff
648
        stdcall libini._.int_to_str
649
        mov     byte[edi], ','
650
        inc     edi
651
        movzx   eax, bh
652
        stdcall libini._.int_to_str
653
        mov     byte[edi], ','
654
        inc     edi
655
        movzx   eax, bl
656
        stdcall libini._.int_to_str
988 mikedld 657
 
2603 hidnplayr 658
        lea     eax, [buf]
659
        sub     edi, eax
988 mikedld 660
 
2603 hidnplayr 661
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
988 mikedld 662
 
2603 hidnplayr 663
        pop     edi edx ecx
664
        ret
988 mikedld 665
endp
666
 
1327 diamond 667
;;================================================================================================;;
668
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
669
;;------------------------------------------------------------------------------------------------;;
670
;? Read shortcut key                                                                              ;;
671
;;------------------------------------------------------------------------------------------------;;
672
;> _f_name = ini filename                                                                 ;;
673
;> _sec_name = section name                                                               ;;
674
;> _key_name = key name                                                                   ;;
675
;> _def_val = default value to return if no key, section or file found                     ;;
676
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4       ;;
677
;;------------------------------------------------------------------------------------------------;;
678
;< eax = [_def_val] (error) / shortcut key value as scancode                                 ;;
679
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut                    ;;
680
;;================================================================================================;;
681
locals
682
  buf rb 64
683
endl
988 mikedld 684
 
2603 hidnplayr 685
        push    ebx esi edi
1327 diamond 686
 
2603 hidnplayr 687
        lea     esi, [buf]
688
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
689
        cmp     byte[esi],0
690
        je      .exit_error
1327 diamond 691
 
2603 hidnplayr 692
        xor     ebx, ebx        ; ebx holds the value of modifiers
1327 diamond 693
.loop:
694
; test for end
2603 hidnplayr 695
        xor     eax, eax
696
        cmp     byte [esi], al
697
        jz      .exit_ok        ; exit with scancode zero
1327 diamond 698
; skip all '+'s
2603 hidnplayr 699
        cmp     byte [esi], '+'
700
        jnz     @f
701
        inc     esi
702
        jmp     .loop
1327 diamond 703
@@:
704
; test for names
2603 hidnplayr 705
        mov     edi, .names_table
706
        xor     edx, edx
1327 diamond 707
.names_loop:
2603 hidnplayr 708
        movzx   ecx, byte [edi]
709
        inc     edi
710
        push    esi
1327 diamond 711
@@:
2603 hidnplayr 712
        lodsb
713
        or      al, 20h
714
        scasb
715
        loopz   @b
716
        jz      .name_found
717
        pop     esi
718
        lea     edi, [edi+ecx+4]
719
        inc     edx
720
        cmp     byte [edi], 0
721
        jnz     .names_loop
1327 diamond 722
; special test: functional keys F
2603 hidnplayr 723
        cmp     byte [esi], 'f'
724
        jz      @f
725
        cmp     byte [esi], 'F'
726
        jnz     .no_fx
1327 diamond 727
@@:
2603 hidnplayr 728
        mov     edi, esi
729
        inc     esi
730
        call    libini._.str_to_int
731
        test    eax, eax
3112 dunkaist 732
        jnz     .fx
2603 hidnplayr 733
        mov     esi, edi
1327 diamond 734
.no_fx:
735
; name not found, that must be usual key
2603 hidnplayr 736
        movzx   eax, byte [esi]
737
        stdcall libini._.ascii_to_scan, eax
738
        test    eax, eax
739
        jz      .exit_error
1327 diamond 740
; all is ok
741
.exit_ok:
2603 hidnplayr 742
        mov     ecx, [_modifiers]
743
        test    ecx, ecx
744
        jz      @f
745
        mov     [ecx], ebx
1327 diamond 746
 
747
@@:
748
 
2603 hidnplayr 749
        pop     edi esi ebx
750
        ret
1327 diamond 751
 
752
.exit_error:
2603 hidnplayr 753
        mov     eax, [_def_val]
754
        pop     edi esi ebx
755
        ret
1327 diamond 756
; handler for Fx
757
; eax = number
758
.fx:
2603 hidnplayr 759
        cmp     eax, 10
760
        ja      @f
761
        add     eax, 3Bh-1
762
        jmp     .exit_ok
1327 diamond 763
@@:
2603 hidnplayr 764
        add     eax, 57h-11
765
        jmp     .exit_ok
1327 diamond 766
; handlers for names
767
.name_found:
2603 hidnplayr 768
        pop     eax     ; ignore saved esi
769
        call    dword [edi]
770
        cmp     edx, .num_modifiers
771
        jae     .exit_ok
772
        jmp     .loop
1327 diamond 773
; modifiers
774
; syntax of value for each modifier:
775
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
776
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
777
; generic modifier: 0->1->2->2, 3->2, 4->2
778
; left modifier: 0->3->3, 1->2->2, 4->2
779
; right modifier: 0->4->4, 1->2->2, 3->2
780
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
781
macro shortcut_handle_modifiers name,reg,shift
782
{
783
local .set2,.set3,.set4
2603 hidnplayr 784
.#name#_handler:        ; generic modifier
785
        test    reg, 0xF
786
        jnz     .set2
1327 diamond 787
if shift
2603 hidnplayr 788
        or      reg, 1 shl shift
1327 diamond 789
else
2603 hidnplayr 790
        inc     reg
1327 diamond 791
end if
2603 hidnplayr 792
        retn
1327 diamond 793
.set2:
2603 hidnplayr 794
        and     reg, not (0xF shl shift)
795
        or      reg, 2 shl shift
796
        retn
1327 diamond 797
.l#name#_handler:
2603 hidnplayr 798
        mov     al, reg
799
        and     al, 0xF shl shift
800
        jz      .set3
801
        cmp     al, 3 shl shift
802
        jnz     .set2
803
        retn
1327 diamond 804
.set3:
2603 hidnplayr 805
        add     reg, 3 shl shift
806
        retn
1327 diamond 807
.r#name#_handler:
2603 hidnplayr 808
        mov     al, reg
809
        and     al, 0xF shl shift
810
        jz      .set4
811
        cmp     al, 4 shl shift
812
        jnz     .set2
813
        retn
1327 diamond 814
.set4:
2603 hidnplayr 815
        add     reg, 4 shl shift
816
        retn
1327 diamond 817
}
818
shortcut_handle_modifiers shift,bl,0
819
shortcut_handle_modifiers ctrl,bl,4
820
shortcut_handle_modifiers alt,bh,0
821
; names of keys
822
.name_handler:
2603 hidnplayr 823
        movzx   eax, byte [.names_scancodes+edx-.num_modifiers]
824
        retn
1327 diamond 825
endp
826
 
827
; note: comparison ignores case, so this table keeps lowercase names
828
; macro does this
829
macro shortcut_name_with_handler name,handler
830
{
831
local .start, .end
2603 hidnplayr 832
        db      .end - .start
1327 diamond 833
.start:
2603 hidnplayr 834
        db      name
1327 diamond 835
.end:
836
repeat .end - .start
2603 hidnplayr 837
        load .a byte from .start + % - 1
838
        store byte .a or 0x20 at .start + % - 1
1327 diamond 839
end repeat
2603 hidnplayr 840
        dd      handler
1327 diamond 841
}
842
macro shortcut_name [name]
843
{
2603 hidnplayr 844
        shortcut_name_with_handler name, .name_handler
1327 diamond 845
}
846
; all names here must be in english
847
; ... or modify lowercasing in macro and in comparison
848
.names_table:
849
; generic modifiers
2603 hidnplayr 850
        shortcut_name_with_handler 'Ctrl', .ctrl_handler
851
        shortcut_name_with_handler 'Alt', .alt_handler
852
        shortcut_name_with_handler 'Shift', .shift_handler
1327 diamond 853
; concrete modifiers
2603 hidnplayr 854
        shortcut_name_with_handler 'LCtrl', .lctrl_handler
855
        shortcut_name_with_handler 'RCtrl', .rctrl_handler
856
        shortcut_name_with_handler 'LAlt', .lalt_handler
857
        shortcut_name_with_handler 'RAlt', .ralt_handler
858
        shortcut_name_with_handler 'LShift', .lshift_handler
859
        shortcut_name_with_handler 'RShift', .rshift_handler
1327 diamond 860
.num_modifiers = 9
861
; symbolic names of keys
2603 hidnplayr 862
        shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
863
        shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
864
        shortcut_name 'Up', 'Down'
1327 diamond 865
; end of table
2603 hidnplayr 866
        db      0
1327 diamond 867
ini.get_shortcut.names_scancodes:
868
; scancodes for 'Home' ... 'Down'
2603 hidnplayr 869
        db      47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
870
        db      0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
871
        db      48h, 50h
1327 diamond 872
 
988 mikedld 873
;;================================================================================================;;
717 mikedld 874
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
875
;;================================================================================================;;
876
;! Imported functions section                                                                     ;;
877
;;================================================================================================;;
878
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
879
;;================================================================================================;;
880
 
881
 
882
align 16
883
@IMPORT:
884
 
885
library \
2603 hidnplayr 886
        libio , 'libio.obj'
717 mikedld 887
 
2603 hidnplayr 888
import  libio                       , \
889
        file.size   , 'file_size'   , \
890
        file.open   , 'file_open'   , \
891
        file.read   , 'file_read'   , \
892
        file.write  , 'file_write'  , \
893
        file.seek   , 'file_seek'   , \
894
        file.eof?   , 'file_iseof'  , \
895
        file.seteof , 'file_seteof' , \
896
        file.tell   , 'file_tell'   , \
897
        file.close  , 'file_close'
717 mikedld 898
 
899
 
900
;;================================================================================================;;
901
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
902
;;================================================================================================;;
903
;! Exported functions section                                                                     ;;
904
;;================================================================================================;;
905
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
906
;;================================================================================================;;
907
 
908
 
909
align 16
910
@EXPORT:
911
 
2603 hidnplayr 912
export                                            \
913
        libini._.init     , 'lib_init'          , \
914
        0x00080009        , 'version'           , \
915
        ini.enum_sections , 'ini_enum_sections' , \
916
        ini.enum_keys     , 'ini_enum_keys'     , \
917
        ini.get_str       , 'ini_get_str'       , \
918
        ini.get_int       , 'ini_get_int'       , \
919
        ini.get_color     , 'ini_get_color'     , \
920
        ini.set_str       , 'ini_set_str'       , \
921
        ini.set_int       , 'ini_set_int'       , \
922
        ini.set_color     , 'ini_set_color'     , \
923
        ini.get_shortcut  , 'ini_get_shortcut'