Subversion Repositories Kolibri OS

Rev

Rev 2603 | Rev 3131 | 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
107
        jb      .exit_error
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]
165
        invoke  mem.free, [sec_buf]
717 mikedld 166
  .exit_error.2:
2603 hidnplayr 167
        or      eax, -1
168
        pop     edi esi ebx
169
        ret
717 mikedld 170
endp
171
 
172
;;================================================================================================;;
173
proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
174
;;------------------------------------------------------------------------------------------------;;
845 mikedld 175
;? Enumerate keys within a section, calling callback function for each of them                    ;;
717 mikedld 176
;;------------------------------------------------------------------------------------------------;;
845 mikedld 177
;> _f_name = ini filename                                                                 ;;
178
;> _sec_name = section name                                                               ;;
179
;> _callback = callback function address: func(f_name, sec_name, key_name, key_value), where      ;;
180
;>   f_name = ini filename (as passed to the function)                                    ;;
181
;>   sec_name = section name (as passed to the function)                                  ;;
182
;>   key_name = key name found                                                            ;;
183
;>   key_value = value of key found                                                       ;;
717 mikedld 184
;;------------------------------------------------------------------------------------------------;;
845 mikedld 185
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 186
;;================================================================================================;;
187
locals
2603 hidnplayr 188
  f       IniFile
717 mikedld 189
  f_addr  dd ?
190
  key_buf dd ?
191
  val_buf dd ?
192
endl
193
 
2603 hidnplayr 194
        push    ebx esi edi
717 mikedld 195
 
2603 hidnplayr 196
        cld
717 mikedld 197
 
2603 hidnplayr 198
        invoke  mem.alloc, ini.MAX_NAME_LEN
199
        or      eax, eax
200
        jz      .exit_error.3
201
        mov     [key_buf], eax
202
        invoke  mem.alloc, ini.MAX_VALUE_LEN
203
        or      eax, eax
204
        jz      .exit_error.2
205
        mov     [val_buf], eax
717 mikedld 206
 
2603 hidnplayr 207
        xor     eax, eax
208
        mov     [f.fh], eax
209
        mov     [f.buf], eax
210
        invoke  file.open, [_f_name], O_READ
211
        cmp     eax, 32
212
        jb      .exit_error
213
        mov     [f.fh], eax
214
        invoke  mem.alloc, ini.MEM_SIZE
215
        or      eax, eax
216
        jz      .exit_error
217
        mov     [f.buf], eax
218
        lea     ebx, [f]
219
        mov     [f_addr], ebx
220
        stdcall libini._.find_section, ebx, [_sec_name]
221
        or      eax, eax
222
        jnz     .exit_error
717 mikedld 223
 
224
  .next_key:
2603 hidnplayr 225
        stdcall libini._.skip_line, [f_addr]
226
        stdcall libini._.skip_nonblanks, [f_addr]
227
        or      al, al
228
        jz      .exit_error
229
        cmp     al, '['
230
        je      .exit_error
231
        mov     edi, [key_buf]
845 mikedld 232
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 233
        or      al, al
234
        jz      .exit_error
235
        cmp     al, '='
236
        je      @f
237
        stosb
238
        jmp     @b
717 mikedld 239
    @@:
2603 hidnplayr 240
        xor     al, al
241
        stosb
242
        add     edi, -2
243
    @@: cmp     byte[edi], 32
244
        ja      @f
245
        mov     byte[edi], 0
246
        dec     edi
247
        jmp     @b
845 mikedld 248
    @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
2603 hidnplayr 249
        pushad
250
        stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
251
        or      eax, eax
252
        popad
253
        jnz     .next_key
717 mikedld 254
 
2603 hidnplayr 255
    @@: invoke  file.close, [f.fh]
256
        invoke  mem.free, [f.buf]
257
        xor     eax, eax
258
        stosb
259
        pop     edi esi ebx
260
        ret
717 mikedld 261
 
262
  .exit_error:
2603 hidnplayr 263
        invoke  file.close, [f.fh]
264
        invoke  mem.free, [f.buf]
265
        invoke  mem.free, [val_buf]
717 mikedld 266
  .exit_error.2:
2603 hidnplayr 267
        invoke  mem.free, [key_buf]
717 mikedld 268
  .exit_error.3:
2603 hidnplayr 269
        or      eax, -1
270
        pop     edi esi ebx
271
        ret
717 mikedld 272
endp
273
 
274
;;================================================================================================;;
275
proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
276
;;------------------------------------------------------------------------------------------------;;
845 mikedld 277
;? Read string                                                                                    ;;
717 mikedld 278
;;------------------------------------------------------------------------------------------------;;
845 mikedld 279
;> _f_name = ini filename                                                                 ;;
280
;> _sec_name = section name                                                               ;;
281
;> _key_name = key name                                                                   ;;
282
;> _buffer = destination buffer address                                                    ;;
283
;> _buf_len = buffer size (maximum bytes to read)                                          ;;
284
;> _def_val = default value to return if no key, section or file found                    ;;
717 mikedld 285
;;------------------------------------------------------------------------------------------------;;
845 mikedld 286
;< eax = -1 (error) / 0                                                                           ;;
287
;< [_buffer] = [_def_val] (error) / found key value                                       ;;
717 mikedld 288
;;================================================================================================;;
289
locals
2603 hidnplayr 290
  f      IniFile
717 mikedld 291
  f_addr dd ?
292
endl
293
 
2603 hidnplayr 294
        push    ebx esi edi
717 mikedld 295
 
2603 hidnplayr 296
        xor     eax, eax
297
        mov     [f.fh], eax
298
        mov     [f.buf], eax
299
        invoke  file.open, [_f_name], O_READ
300
        cmp     eax, 32
301
        jb      .exit_error
302
        mov     [f.fh], eax
303
        invoke  mem.alloc, ini.MEM_SIZE
304
        or      eax, eax
305
        jz      .exit_error
306
        mov     [f.buf], eax
307
        lea     ebx, [f]
308
        mov     [f_addr], ebx
309
        stdcall libini._.find_section, ebx, [_sec_name]
310
        or      eax, eax
311
        jnz     .exit_error
717 mikedld 312
 
2603 hidnplayr 313
        stdcall libini._.find_key, ebx, [_key_name]
314
        or      eax, eax
315
        jnz     .exit_error
717 mikedld 316
 
2603 hidnplayr 317
        stdcall libini._.low.read_value, [f_addr], [_buffer], [_buf_len]
318
    @@: invoke  file.close, [f.fh]
319
        invoke  mem.free, [f.buf]
320
        xor     eax, eax
321
        pop     edi esi ebx
322
        ret
717 mikedld 323
 
324
  .exit_error:
2603 hidnplayr 325
        invoke  file.close, [f.fh]
326
        invoke  mem.free, [f.buf]
327
        mov     edi, [_buffer]
328
        mov     esi, [_def_val]
329
        xor     al, al
330
        or      esi, esi
331
        jz      .exit_error.2
717 mikedld 332
    @@: lodsb
988 mikedld 333
  .exit_error.2:
2603 hidnplayr 334
        stosb
335
        or      al, al
336
        jnz     @b
337
        or      eax, -1
338
        pop     edi esi ebx
339
        ret
717 mikedld 340
endp
341
 
342
;;================================================================================================;;
343
proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
344
;;------------------------------------------------------------------------------------------------;;
845 mikedld 345
;? Write string                                                                                   ;;
717 mikedld 346
;;------------------------------------------------------------------------------------------------;;
845 mikedld 347
;> _f_name = ini filename                                                                 ;;
348
;> _sec_name = section name                                                               ;;
349
;> _key_name = key name                                                                   ;;
350
;> _buffer = source buffer address                                                         ;;
351
;> _buf_len = buffer size (bytes to write)                                                 ;;
717 mikedld 352
;;------------------------------------------------------------------------------------------------;;
845 mikedld 353
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 354
;;================================================================================================;;
355
locals
2603 hidnplayr 356
  f      IniFile
717 mikedld 357
  f_addr dd ?
358
endl
359
 
2603 hidnplayr 360
        push    ebx esi edi
717 mikedld 361
 
2603 hidnplayr 362
        xor     eax, eax
363
        mov     [f.fh], eax
364
        mov     [f.buf], eax
365
        invoke  file.open, [_f_name], O_READ + O_WRITE + O_CREATE
366
        cmp     eax, 32
367
        jb      .exit_error
368
        mov     [f.fh], eax
369
        invoke  mem.alloc, ini.MEM_SIZE
370
        or      eax, eax
371
        jz      .exit_error
372
        mov     [f.buf], eax
373
        lea     ebx, [f]
374
        mov     [f_addr], ebx
717 mikedld 375
 
2603 hidnplayr 376
        stdcall libini._.find_section, ebx, [_sec_name]
377
        or      eax, eax
378
        jnz     .create_section
717 mikedld 379
 
2603 hidnplayr 380
        stdcall libini._.find_key, ebx, [_key_name]
381
        or      eax, eax
382
        jnz     .create_key
717 mikedld 383
 
384
  .modify_key:
2603 hidnplayr 385
        stdcall libini._.get_value_length, [f_addr]
386
        sub     eax, [_buf_len]
387
        stdcall libini._.shift_content, [f_addr], eax
717 mikedld 388
 
389
  .modify_key.ex:
2603 hidnplayr 390
        invoke  file.tell, [f.fh]
391
        sub     eax, [f.cnt]
392
        invoke  file.seek, [f.fh], eax, SEEK_SET
393
        invoke  file.write, [f.fh], [_buffer], [_buf_len]
717 mikedld 394
 
2603 hidnplayr 395
        pop     edi esi ebx
396
        xor     eax, eax
397
        ret
717 mikedld 398
 
399
  .create_key:
2603 hidnplayr 400
        mov     edi, [f.buf]
401
        add     edi, ini.BLOCK_SIZE
402
        push    edi
717 mikedld 403
 
404
  .create_key.ex:
2603 hidnplayr 405
        mov     esi, [_key_name]
406
        call    libini._.string_copy
407
        mov     byte[edi], '='
408
        inc     edi
409
        mov     esi, [_buffer]
410
        mov     ecx, [_buf_len]
411
        rep     movsb
412
        mov     word[edi], 0x0A0D
413
        add     edi, 2
414
        mov     eax, edi
717 mikedld 415
 
2603 hidnplayr 416
        pop     edi
417
        sub     eax, edi
418
        mov     [_buffer], edi
419
        mov     [_buf_len], eax
420
        neg     eax
421
        stdcall libini._.shift_content, [f_addr], eax
717 mikedld 422
 
2603 hidnplayr 423
        jmp     .modify_key.ex
717 mikedld 424
 
425
  .create_section:
2603 hidnplayr 426
        mov     edi, [f.buf]
427
        add     edi, ini.BLOCK_SIZE
428
        push    edi
717 mikedld 429
 
2603 hidnplayr 430
        mov     esi, [_sec_name]
431
        mov     byte[edi], '['
432
        inc     edi
433
        call    libini._.string_copy
434
        mov     dword[edi], ']' + (0x0A0D shl 8)
435
        add     edi, 3
717 mikedld 436
 
2603 hidnplayr 437
        jmp     .create_key.ex
717 mikedld 438
 
439
  .exit_error:
2603 hidnplayr 440
        pop     edi esi ebx
441
        or      eax, -1
442
        ret
717 mikedld 443
endp
444
 
445
;;================================================================================================;;
446
proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
447
;;------------------------------------------------------------------------------------------------;;
845 mikedld 448
;? Read integer                                                                                   ;;
717 mikedld 449
;;------------------------------------------------------------------------------------------------;;
845 mikedld 450
;> _f_name = ini filename                                                                 ;;
451
;> _sec_name = section name                                                               ;;
452
;> _key_name = key name                                                                   ;;
453
;> _def_val = default value to return if no key, section or file found                     ;;
717 mikedld 454
;;------------------------------------------------------------------------------------------------;;
845 mikedld 455
;< eax = [_def_val] (error) / found key value                                              ;;
717 mikedld 456
;;================================================================================================;;
457
locals
2603 hidnplayr 458
  f      IniFile
717 mikedld 459
  f_addr dd ?
460
endl
461
 
2603 hidnplayr 462
        push    edx ebx esi edi
717 mikedld 463
 
2603 hidnplayr 464
        xor     eax, eax
465
        mov     [f.fh], eax
466
        mov     [f.buf], eax
467
        invoke  file.open, [_f_name], O_READ
468
        cmp     eax, 32
469
        jb      .exit_error
470
        mov     [f.fh], eax
471
        invoke  mem.alloc, ini.MEM_SIZE
472
        or      eax, eax
473
        jz      .exit_error
474
        mov     [f.buf], eax
475
        lea     ebx, [f]
476
        mov     [f_addr], ebx
477
        stdcall libini._.find_section, ebx, [_sec_name]
478
        or      eax, eax
479
        jnz     .exit_error
717 mikedld 480
 
2603 hidnplayr 481
        stdcall libini._.find_key, ebx, [_key_name]
482
        or      eax, eax
483
        jnz     .exit_error
717 mikedld 484
 
2603 hidnplayr 485
        stdcall libini._.skip_spaces, [f_addr]
486
        xor     eax, eax
487
        xor     ebx, ebx
488
        xor     edx, edx
489
        stdcall libini._.get_char, [f_addr]
490
        cmp     al, '-'
491
        jne     .lp1
492
        inc     bh
845 mikedld 493
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 494
  .lp1: cmp     al, '0'
495
        jb      @f
496
        cmp     al, '9'
497
        ja      @f
498
        inc     bl
499
        add     eax, -'0'
500
        imul    edx, 10
501
        add     edx, eax
502
        jmp     @b
717 mikedld 503
    @@:
2603 hidnplayr 504
        or      bl, bl
505
        jz      .exit_error
506
        or      bh, bh
507
        jz      @f
508
        neg     edx
509
    @@: invoke  file.close, [f.fh]
510
        invoke  mem.free, [f.buf]
511
        mov     eax, edx
512
        pop     edi esi ebx edx
513
        ret
717 mikedld 514
 
515
  .exit_error:
2603 hidnplayr 516
        invoke  file.close, [f.fh]
517
        invoke  mem.free, [f.buf]
518
        mov     eax, [_def_val]
519
        pop     edi esi ebx edx
520
        ret
717 mikedld 521
endp
522
 
523
;;================================================================================================;;
524
proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
525
;;------------------------------------------------------------------------------------------------;;
845 mikedld 526
;? Write integer                                                                                  ;;
717 mikedld 527
;;------------------------------------------------------------------------------------------------;;
845 mikedld 528
;> _f_name = ini filename                                                                 ;;
529
;> _sec_name = section name                                                               ;;
530
;> _key_name = key name                                                                   ;;
531
;> _val = value                                                                            ;;
717 mikedld 532
;;------------------------------------------------------------------------------------------------;;
845 mikedld 533
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 534
;;================================================================================================;;
535
locals
536
  buf rb 16
537
endl
538
 
2603 hidnplayr 539
        push    ecx edx edi
717 mikedld 540
 
2603 hidnplayr 541
        lea     edi, [buf]
542
        add     edi, 15
543
        mov     eax, [_val]
544
        or      eax, eax
545
        jns     @f
546
        mov     byte[edi], '-'
547
        neg     eax
548
        inc     edi
549
    @@: mov     ecx, 10
550
    @@: xor     edx, edx
551
        idiv    ecx
552
        add     dl, '0'
553
        mov     [edi], dl
554
        dec     edi
555
        or      eax, eax
556
        jnz     @b
557
        lea     eax, [buf]
558
        add     eax, 15
559
        sub     eax, edi
560
        inc     edi
717 mikedld 561
 
2603 hidnplayr 562
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
717 mikedld 563
 
2603 hidnplayr 564
        pop     edi edx ecx
565
        ret
717 mikedld 566
endp
567
 
988 mikedld 568
;;================================================================================================;;
569
proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
570
;;------------------------------------------------------------------------------------------------;;
571
;? Read color                                                                                     ;;
572
;;------------------------------------------------------------------------------------------------;;
573
;> _f_name = ini filename                                                                 ;;
574
;> _sec_name = section name                                                               ;;
575
;> _key_name = key name                                                                   ;;
576
;> _def_val = default value to return if no key, section or file found                     ;;
577
;;------------------------------------------------------------------------------------------------;;
578
;< eax = [_def_val] (error) / found key value                                              ;;
579
;;================================================================================================;;
580
locals
581
  buf rb 14
582
endl
717 mikedld 583
 
2603 hidnplayr 584
        push    ebx esi edi
988 mikedld 585
 
2603 hidnplayr 586
        lea     esi, [buf]
587
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
588
        cmp     byte[esi],0
589
        je      .exit_error
988 mikedld 590
 
2603 hidnplayr 591
        xor     ebx, ebx
592
        stdcall libini._.str_to_int
593
        movzx   ebx, al
594
        shl     ebx, 16
595
        lodsb
596
        cmp     al, ','
597
        jne     @f
598
        stdcall libini._.str_to_int
599
        mov     bh, al
600
        lodsb
601
        cmp     al, ','
602
        jne     @f
603
        stdcall libini._.str_to_int
604
        mov     bl, al
988 mikedld 605
 
2603 hidnplayr 606
    @@: mov     eax, ebx
988 mikedld 607
 
2603 hidnplayr 608
        pop     edi esi ebx
609
        ret
988 mikedld 610
 
611
  .exit_error:
2603 hidnplayr 612
        mov     eax, [_def_val]
613
        pop     edi esi ebx
614
        ret
988 mikedld 615
endp
616
 
717 mikedld 617
;;================================================================================================;;
988 mikedld 618
proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
619
;;------------------------------------------------------------------------------------------------;;
620
;? Write color                                                                                    ;;
621
;;------------------------------------------------------------------------------------------------;;
622
;> _f_name = ini filename                                                                 ;;
623
;> _sec_name = section name                                                               ;;
624
;> _key_name = key name                                                                   ;;
625
;> _val = value                                                                            ;;
626
;;------------------------------------------------------------------------------------------------;;
627
;< eax = -1 (error) / 0                                                                           ;;
628
;;================================================================================================;;
629
locals
630
  buf rb 16
631
endl
632
 
2603 hidnplayr 633
        push    ecx edx edi
988 mikedld 634
 
2603 hidnplayr 635
        lea     edi, [buf]
636
        mov     ecx, 10
637
        mov     ebx, [_val]
638
        mov     eax, ebx
639
        shr     eax, 16
640
        and     eax, 0x0ff
641
        stdcall libini._.int_to_str
642
        mov     byte[edi], ','
643
        inc     edi
644
        movzx   eax, bh
645
        stdcall libini._.int_to_str
646
        mov     byte[edi], ','
647
        inc     edi
648
        movzx   eax, bl
649
        stdcall libini._.int_to_str
988 mikedld 650
 
2603 hidnplayr 651
        lea     eax, [buf]
652
        sub     edi, eax
988 mikedld 653
 
2603 hidnplayr 654
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
988 mikedld 655
 
2603 hidnplayr 656
        pop     edi edx ecx
657
        ret
988 mikedld 658
endp
659
 
1327 diamond 660
;;================================================================================================;;
661
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
662
;;------------------------------------------------------------------------------------------------;;
663
;? Read shortcut key                                                                              ;;
664
;;------------------------------------------------------------------------------------------------;;
665
;> _f_name = ini filename                                                                 ;;
666
;> _sec_name = section name                                                               ;;
667
;> _key_name = key name                                                                   ;;
668
;> _def_val = default value to return if no key, section or file found                     ;;
669
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4       ;;
670
;;------------------------------------------------------------------------------------------------;;
671
;< eax = [_def_val] (error) / shortcut key value as scancode                                 ;;
672
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut                    ;;
673
;;================================================================================================;;
674
locals
675
  buf rb 64
676
endl
988 mikedld 677
 
2603 hidnplayr 678
        push    ebx esi edi
1327 diamond 679
 
2603 hidnplayr 680
        lea     esi, [buf]
681
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
682
        cmp     byte[esi],0
683
        je      .exit_error
1327 diamond 684
 
2603 hidnplayr 685
        xor     ebx, ebx        ; ebx holds the value of modifiers
1327 diamond 686
.loop:
687
; test for end
2603 hidnplayr 688
        xor     eax, eax
689
        cmp     byte [esi], al
690
        jz      .exit_ok        ; exit with scancode zero
1327 diamond 691
; skip all '+'s
2603 hidnplayr 692
        cmp     byte [esi], '+'
693
        jnz     @f
694
        inc     esi
695
        jmp     .loop
1327 diamond 696
@@:
697
; test for names
2603 hidnplayr 698
        mov     edi, .names_table
699
        xor     edx, edx
1327 diamond 700
.names_loop:
2603 hidnplayr 701
        movzx   ecx, byte [edi]
702
        inc     edi
703
        push    esi
1327 diamond 704
@@:
2603 hidnplayr 705
        lodsb
706
        or      al, 20h
707
        scasb
708
        loopz   @b
709
        jz      .name_found
710
        pop     esi
711
        lea     edi, [edi+ecx+4]
712
        inc     edx
713
        cmp     byte [edi], 0
714
        jnz     .names_loop
1327 diamond 715
; special test: functional keys F
2603 hidnplayr 716
        cmp     byte [esi], 'f'
717
        jz      @f
718
        cmp     byte [esi], 'F'
719
        jnz     .no_fx
1327 diamond 720
@@:
2603 hidnplayr 721
        mov     edi, esi
722
        inc     esi
723
        call    libini._.str_to_int
724
        test    eax, eax
3112 dunkaist 725
        jnz     .fx
2603 hidnplayr 726
        mov     esi, edi
1327 diamond 727
.no_fx:
728
; name not found, that must be usual key
2603 hidnplayr 729
        movzx   eax, byte [esi]
730
        stdcall libini._.ascii_to_scan, eax
731
        test    eax, eax
732
        jz      .exit_error
1327 diamond 733
; all is ok
734
.exit_ok:
2603 hidnplayr 735
        mov     ecx, [_modifiers]
736
        test    ecx, ecx
737
        jz      @f
738
        mov     [ecx], ebx
1327 diamond 739
 
740
@@:
741
 
2603 hidnplayr 742
        pop     edi esi ebx
743
        ret
1327 diamond 744
 
745
.exit_error:
2603 hidnplayr 746
        mov     eax, [_def_val]
747
        pop     edi esi ebx
748
        ret
1327 diamond 749
; handler for Fx
750
; eax = number
751
.fx:
2603 hidnplayr 752
        cmp     eax, 10
753
        ja      @f
754
        add     eax, 3Bh-1
755
        jmp     .exit_ok
1327 diamond 756
@@:
2603 hidnplayr 757
        add     eax, 57h-11
758
        jmp     .exit_ok
1327 diamond 759
; handlers for names
760
.name_found:
2603 hidnplayr 761
        pop     eax     ; ignore saved esi
762
        call    dword [edi]
763
        cmp     edx, .num_modifiers
764
        jae     .exit_ok
765
        jmp     .loop
1327 diamond 766
; modifiers
767
; syntax of value for each modifier:
768
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
769
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
770
; generic modifier: 0->1->2->2, 3->2, 4->2
771
; left modifier: 0->3->3, 1->2->2, 4->2
772
; right modifier: 0->4->4, 1->2->2, 3->2
773
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
774
macro shortcut_handle_modifiers name,reg,shift
775
{
776
local .set2,.set3,.set4
2603 hidnplayr 777
.#name#_handler:        ; generic modifier
778
        test    reg, 0xF
779
        jnz     .set2
1327 diamond 780
if shift
2603 hidnplayr 781
        or      reg, 1 shl shift
1327 diamond 782
else
2603 hidnplayr 783
        inc     reg
1327 diamond 784
end if
2603 hidnplayr 785
        retn
1327 diamond 786
.set2:
2603 hidnplayr 787
        and     reg, not (0xF shl shift)
788
        or      reg, 2 shl shift
789
        retn
1327 diamond 790
.l#name#_handler:
2603 hidnplayr 791
        mov     al, reg
792
        and     al, 0xF shl shift
793
        jz      .set3
794
        cmp     al, 3 shl shift
795
        jnz     .set2
796
        retn
1327 diamond 797
.set3:
2603 hidnplayr 798
        add     reg, 3 shl shift
799
        retn
1327 diamond 800
.r#name#_handler:
2603 hidnplayr 801
        mov     al, reg
802
        and     al, 0xF shl shift
803
        jz      .set4
804
        cmp     al, 4 shl shift
805
        jnz     .set2
806
        retn
1327 diamond 807
.set4:
2603 hidnplayr 808
        add     reg, 4 shl shift
809
        retn
1327 diamond 810
}
811
shortcut_handle_modifiers shift,bl,0
812
shortcut_handle_modifiers ctrl,bl,4
813
shortcut_handle_modifiers alt,bh,0
814
; names of keys
815
.name_handler:
2603 hidnplayr 816
        movzx   eax, byte [.names_scancodes+edx-.num_modifiers]
817
        retn
1327 diamond 818
endp
819
 
820
; note: comparison ignores case, so this table keeps lowercase names
821
; macro does this
822
macro shortcut_name_with_handler name,handler
823
{
824
local .start, .end
2603 hidnplayr 825
        db      .end - .start
1327 diamond 826
.start:
2603 hidnplayr 827
        db      name
1327 diamond 828
.end:
829
repeat .end - .start
2603 hidnplayr 830
        load .a byte from .start + % - 1
831
        store byte .a or 0x20 at .start + % - 1
1327 diamond 832
end repeat
2603 hidnplayr 833
        dd      handler
1327 diamond 834
}
835
macro shortcut_name [name]
836
{
2603 hidnplayr 837
        shortcut_name_with_handler name, .name_handler
1327 diamond 838
}
839
; all names here must be in english
840
; ... or modify lowercasing in macro and in comparison
841
.names_table:
842
; generic modifiers
2603 hidnplayr 843
        shortcut_name_with_handler 'Ctrl', .ctrl_handler
844
        shortcut_name_with_handler 'Alt', .alt_handler
845
        shortcut_name_with_handler 'Shift', .shift_handler
1327 diamond 846
; concrete modifiers
2603 hidnplayr 847
        shortcut_name_with_handler 'LCtrl', .lctrl_handler
848
        shortcut_name_with_handler 'RCtrl', .rctrl_handler
849
        shortcut_name_with_handler 'LAlt', .lalt_handler
850
        shortcut_name_with_handler 'RAlt', .ralt_handler
851
        shortcut_name_with_handler 'LShift', .lshift_handler
852
        shortcut_name_with_handler 'RShift', .rshift_handler
1327 diamond 853
.num_modifiers = 9
854
; symbolic names of keys
2603 hidnplayr 855
        shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
856
        shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
857
        shortcut_name 'Up', 'Down'
1327 diamond 858
; end of table
2603 hidnplayr 859
        db      0
1327 diamond 860
ini.get_shortcut.names_scancodes:
861
; scancodes for 'Home' ... 'Down'
2603 hidnplayr 862
        db      47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
863
        db      0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
864
        db      48h, 50h
1327 diamond 865
 
988 mikedld 866
;;================================================================================================;;
717 mikedld 867
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
868
;;================================================================================================;;
869
;! Imported functions section                                                                     ;;
870
;;================================================================================================;;
871
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
872
;;================================================================================================;;
873
 
874
 
875
align 16
876
@IMPORT:
877
 
878
library \
2603 hidnplayr 879
        libio , 'libio.obj'
717 mikedld 880
 
2603 hidnplayr 881
import  libio                       , \
882
        file.size   , 'file_size'   , \
883
        file.open   , 'file_open'   , \
884
        file.read   , 'file_read'   , \
885
        file.write  , 'file_write'  , \
886
        file.seek   , 'file_seek'   , \
887
        file.eof?   , 'file_iseof'  , \
888
        file.seteof , 'file_seteof' , \
889
        file.tell   , 'file_tell'   , \
890
        file.close  , 'file_close'
717 mikedld 891
 
892
 
893
;;================================================================================================;;
894
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
895
;;================================================================================================;;
896
;! Exported functions section                                                                     ;;
897
;;================================================================================================;;
898
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
899
;;================================================================================================;;
900
 
901
 
902
align 16
903
@EXPORT:
904
 
2603 hidnplayr 905
export                                            \
906
        libini._.init     , 'lib_init'          , \
907
        0x00080009        , 'version'           , \
908
        ini.enum_sections , 'ini_enum_sections' , \
909
        ini.enum_keys     , 'ini_enum_keys'     , \
910
        ini.get_str       , 'ini_get_str'       , \
911
        ini.get_int       , 'ini_get_int'       , \
912
        ini.get_color     , 'ini_get_color'     , \
913
        ini.set_str       , 'ini_set_str'       , \
914
        ini.set_int       , 'ini_set_int'       , \
915
        ini.set_color     , 'ini_set_color'     , \
916
        ini.get_shortcut  , 'ini_get_shortcut'