Subversion Repositories Kolibri OS

Rev

Rev 3859 | Rev 4422 | 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
3920 mario79 400
        mcall   68,13,[f.buf]
2603 hidnplayr 401
        xor     eax, eax
402
        ret
717 mikedld 403
 
404
  .create_key:
2603 hidnplayr 405
        mov     edi, [f.buf]
406
        add     edi, ini.BLOCK_SIZE
407
        push    edi
717 mikedld 408
 
409
  .create_key.ex:
2603 hidnplayr 410
        mov     esi, [_key_name]
411
        call    libini._.string_copy
412
        mov     byte[edi], '='
413
        inc     edi
414
        mov     esi, [_buffer]
415
        mov     ecx, [_buf_len]
416
        rep     movsb
417
        mov     word[edi], 0x0A0D
418
        add     edi, 2
419
        mov     eax, edi
717 mikedld 420
 
2603 hidnplayr 421
        pop     edi
422
        sub     eax, edi
423
        mov     [_buffer], edi
424
        mov     [_buf_len], eax
425
        neg     eax
426
        stdcall libini._.shift_content, [f_addr], eax
717 mikedld 427
 
2603 hidnplayr 428
        jmp     .modify_key.ex
717 mikedld 429
 
430
  .create_section:
2603 hidnplayr 431
        mov     edi, [f.buf]
432
        add     edi, ini.BLOCK_SIZE
433
        push    edi
717 mikedld 434
 
2603 hidnplayr 435
        mov     esi, [_sec_name]
436
        mov     byte[edi], '['
437
        inc     edi
438
        call    libini._.string_copy
439
        mov     dword[edi], ']' + (0x0A0D shl 8)
440
        add     edi, 3
717 mikedld 441
 
2603 hidnplayr 442
        jmp     .create_key.ex
717 mikedld 443
 
444
  .exit_error:
3131 clevermous 445
        invoke  file.close, [f.fh]
446
  .exit_file_error:
2603 hidnplayr 447
        pop     edi esi ebx
448
        or      eax, -1
449
        ret
717 mikedld 450
endp
451
 
452
;;================================================================================================;;
453
proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
454
;;------------------------------------------------------------------------------------------------;;
845 mikedld 455
;? Read integer                                                                                   ;;
717 mikedld 456
;;------------------------------------------------------------------------------------------------;;
845 mikedld 457
;> _f_name = ini filename                                                                 ;;
458
;> _sec_name = section name                                                               ;;
459
;> _key_name = key name                                                                   ;;
460
;> _def_val = default value to return if no key, section or file found                     ;;
717 mikedld 461
;;------------------------------------------------------------------------------------------------;;
845 mikedld 462
;< eax = [_def_val] (error) / found key value                                              ;;
717 mikedld 463
;;================================================================================================;;
464
locals
2603 hidnplayr 465
  f      IniFile
717 mikedld 466
  f_addr dd ?
467
endl
468
 
2603 hidnplayr 469
        push    edx ebx esi edi
717 mikedld 470
 
2603 hidnplayr 471
        xor     eax, eax
472
        mov     [f.fh], eax
473
        mov     [f.buf], eax
474
        invoke  file.open, [_f_name], O_READ
475
        cmp     eax, 32
3131 clevermous 476
        jb      .exit_file_error
2603 hidnplayr 477
        mov     [f.fh], eax
478
        invoke  mem.alloc, ini.MEM_SIZE
479
        or      eax, eax
480
        jz      .exit_error
481
        mov     [f.buf], eax
482
        lea     ebx, [f]
483
        mov     [f_addr], ebx
484
        stdcall libini._.find_section, ebx, [_sec_name]
485
        or      eax, eax
486
        jnz     .exit_error
717 mikedld 487
 
2603 hidnplayr 488
        stdcall libini._.find_key, ebx, [_key_name]
489
        or      eax, eax
490
        jnz     .exit_error
717 mikedld 491
 
2603 hidnplayr 492
        stdcall libini._.skip_spaces, [f_addr]
493
        xor     eax, eax
494
        xor     ebx, ebx
495
        xor     edx, edx
496
        stdcall libini._.get_char, [f_addr]
497
        cmp     al, '-'
498
        jne     .lp1
499
        inc     bh
845 mikedld 500
    @@: stdcall libini._.get_char, [f_addr]
2603 hidnplayr 501
  .lp1: cmp     al, '0'
502
        jb      @f
503
        cmp     al, '9'
504
        ja      @f
505
        inc     bl
506
        add     eax, -'0'
507
        imul    edx, 10
508
        add     edx, eax
509
        jmp     @b
717 mikedld 510
    @@:
2603 hidnplayr 511
        or      bl, bl
512
        jz      .exit_error
513
        or      bh, bh
514
        jz      @f
515
        neg     edx
516
    @@: invoke  file.close, [f.fh]
517
        invoke  mem.free, [f.buf]
518
        mov     eax, edx
519
        pop     edi esi ebx edx
520
        ret
717 mikedld 521
 
522
  .exit_error:
2603 hidnplayr 523
        invoke  file.close, [f.fh]
3131 clevermous 524
  .exit_file_error:
2603 hidnplayr 525
        invoke  mem.free, [f.buf]
526
        mov     eax, [_def_val]
527
        pop     edi esi ebx edx
528
        ret
717 mikedld 529
endp
530
 
531
;;================================================================================================;;
532
proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
533
;;------------------------------------------------------------------------------------------------;;
845 mikedld 534
;? Write integer                                                                                  ;;
717 mikedld 535
;;------------------------------------------------------------------------------------------------;;
845 mikedld 536
;> _f_name = ini filename                                                                 ;;
537
;> _sec_name = section name                                                               ;;
538
;> _key_name = key name                                                                   ;;
539
;> _val = value                                                                            ;;
717 mikedld 540
;;------------------------------------------------------------------------------------------------;;
845 mikedld 541
;< eax = -1 (error) / 0                                                                           ;;
717 mikedld 542
;;================================================================================================;;
543
locals
544
  buf rb 16
3832 GerdtR 545
  bNeg rd 1
717 mikedld 546
endl
547
 
2603 hidnplayr 548
        push    ecx edx edi
717 mikedld 549
 
2603 hidnplayr 550
        lea     edi, [buf]
551
        add     edi, 15
3832 GerdtR 552
 
2603 hidnplayr 553
        mov     eax, [_val]
3832 GerdtR 554
        mov     [bNeg],0
2603 hidnplayr 555
        or      eax, eax
556
        jns     @f
3832 GerdtR 557
        mov     [bNeg],1
2603 hidnplayr 558
        neg     eax
3832 GerdtR 559
 
2603 hidnplayr 560
    @@: mov     ecx, 10
561
    @@: xor     edx, edx
562
        idiv    ecx
563
        add     dl, '0'
564
        mov     [edi], dl
565
        dec     edi
566
        or      eax, eax
567
        jnz     @b
3832 GerdtR 568
 
569
        cmp     [bNeg],0
570
        je      @f
571
        mov     byte[edi], '-'
572
        dec     edi
573
     @@:
2603 hidnplayr 574
        lea     eax, [buf]
575
        add     eax, 15
576
        sub     eax, edi
577
        inc     edi
717 mikedld 578
 
3832 GerdtR 579
 
580
 
2603 hidnplayr 581
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
717 mikedld 582
 
2603 hidnplayr 583
        pop     edi edx ecx
584
        ret
717 mikedld 585
endp
586
 
988 mikedld 587
;;================================================================================================;;
588
proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
589
;;------------------------------------------------------------------------------------------------;;
590
;? Read color                                                                                     ;;
591
;;------------------------------------------------------------------------------------------------;;
592
;> _f_name = ini filename                                                                 ;;
593
;> _sec_name = section name                                                               ;;
594
;> _key_name = key name                                                                   ;;
595
;> _def_val = default value to return if no key, section or file found                     ;;
596
;;------------------------------------------------------------------------------------------------;;
597
;< eax = [_def_val] (error) / found key value                                              ;;
598
;;================================================================================================;;
599
locals
600
  buf rb 14
601
endl
717 mikedld 602
 
2603 hidnplayr 603
        push    ebx esi edi
988 mikedld 604
 
2603 hidnplayr 605
        lea     esi, [buf]
606
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
607
        cmp     byte[esi],0
608
        je      .exit_error
988 mikedld 609
 
2603 hidnplayr 610
        xor     ebx, ebx
611
        stdcall libini._.str_to_int
612
        movzx   ebx, al
613
        shl     ebx, 16
614
        lodsb
615
        cmp     al, ','
616
        jne     @f
617
        stdcall libini._.str_to_int
618
        mov     bh, al
619
        lodsb
620
        cmp     al, ','
621
        jne     @f
622
        stdcall libini._.str_to_int
623
        mov     bl, al
988 mikedld 624
 
2603 hidnplayr 625
    @@: mov     eax, ebx
988 mikedld 626
 
2603 hidnplayr 627
        pop     edi esi ebx
628
        ret
988 mikedld 629
 
630
  .exit_error:
2603 hidnplayr 631
        mov     eax, [_def_val]
632
        pop     edi esi ebx
633
        ret
988 mikedld 634
endp
635
 
717 mikedld 636
;;================================================================================================;;
988 mikedld 637
proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
638
;;------------------------------------------------------------------------------------------------;;
639
;? Write color                                                                                    ;;
640
;;------------------------------------------------------------------------------------------------;;
641
;> _f_name = ini filename                                                                 ;;
642
;> _sec_name = section name                                                               ;;
643
;> _key_name = key name                                                                   ;;
644
;> _val = value                                                                            ;;
645
;;------------------------------------------------------------------------------------------------;;
646
;< eax = -1 (error) / 0                                                                           ;;
647
;;================================================================================================;;
648
locals
649
  buf rb 16
650
endl
651
 
2603 hidnplayr 652
        push    ecx edx edi
988 mikedld 653
 
2603 hidnplayr 654
        lea     edi, [buf]
655
        mov     ecx, 10
656
        mov     ebx, [_val]
657
        mov     eax, ebx
658
        shr     eax, 16
659
        and     eax, 0x0ff
660
        stdcall libini._.int_to_str
661
        mov     byte[edi], ','
662
        inc     edi
663
        movzx   eax, bh
664
        stdcall libini._.int_to_str
665
        mov     byte[edi], ','
666
        inc     edi
667
        movzx   eax, bl
668
        stdcall libini._.int_to_str
988 mikedld 669
 
2603 hidnplayr 670
        lea     eax, [buf]
671
        sub     edi, eax
988 mikedld 672
 
2603 hidnplayr 673
        stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
988 mikedld 674
 
2603 hidnplayr 675
        pop     edi edx ecx
676
        ret
988 mikedld 677
endp
678
 
3832 GerdtR 679
 
1327 diamond 680
;;================================================================================================;;
3832 GerdtR 681
proc ini.del_section _f_name, _sec_name ;/////////////////////////////////////////////////////////;;
682
;;------------------------------------------------------------------------------------------------;;
683
;? Delete section and all key in this section                                                     ;;
684
;;------------------------------------------------------------------------------------------------;;
685
;> _f_name = ini filename                                                                 ;;
686
;> _sec_name = section name                                                               ;;
687
;;------------------------------------------------------------------------------------------------;;
688
;< eax = 0 - success                                                                              ;;
689
;<      -1 - file not found                                                                       ;;
690
;<       1 - section not found                                                                    ;;
691
;;================================================================================================;;
692
locals
693
   funcFile     rb 25
694
   fileInfo     rb 40
695
   begMem       rd 1
696
   endMem       rd 1
697
   begDel       rd 1
698
   endDel       rd 1
699
endl
700
        push    ebx ecx edi esi
701
        mov     dword[funcFile],5               ;get file info
702
        mov     dword[funcFile+4],0
703
        mov     dword[funcFile+8],0
704
        mov     dword[funcFile+12],0
705
        lea     eax,[fileInfo]
706
        mov     dword[funcFile+16],eax
707
        mov     byte[funcFile+20],0
708
        m2m     dword[funcFile+21],[_f_name]
709
        lea     ebx,[funcFile]
710
        mcall   70
711
        test    eax,eax
712
        jz      @f
713
 
714
        or      eax,-1
715
        pop     esi edi ecx ebx
716
        ret
717
      @@:
718
 
719
        mov     ecx,dword[fileInfo+32]          ;allocation mem for all file
720
        mcall   68,12
721
 
722
        mov     [begMem],eax
723
        mov     [endMem],eax
724
        add     [endMem],ecx
725
 
726
        mov     dword[funcFile],0               ;read file to buffer
727
        mov     dword[funcFile+12],ecx
728
        mov     dword[funcFile+16],eax
729
        lea     ebx,[funcFile]
730
        mcall   70
731
 
732
        mov     edi,[begMem]                    ;search begin section
3859 GerdtR 733
        jmp     .searchSect
734
    .NoFindSect:
735
        mov     edi,[begDel]
3832 GerdtR 736
    .searchSect:
737
        mov     al,'['
738
        repne   scasb
739
        test    ecx,ecx
740
        jnz     @f
3859 GerdtR 741
 
3832 GerdtR 742
        pop     esi edi ecx ebx
743
        mov     eax,1
744
        ret
745
      @@:
746
        mov     [begDel],edi
747
        mov     esi,[_sec_name]
748
      @@:
749
        lodsb
750
        test    al,al
751
        jz      @f
752
        scasb
3859 GerdtR 753
        jne     .NoFindSect
3832 GerdtR 754
        jmp     @b
755
      @@:
756
        cmp     byte[edi],']'
3859 GerdtR 757
        jne     .NoFindSect
3832 GerdtR 758
 
3859 GerdtR 759
        mov     edi,[begDel]
3832 GerdtR 760
        dec     [begDel]
3859 GerdtR 761
                                       ;search end section
3832 GerdtR 762
    .searchEndSect:
763
        mov     al,'['
764
        repne   scasb
765
 
766
        dec     edi
767
        mov     [endDel],edi
768
 
769
        test    ecx,ecx
770
        jnz     @f
771
        jmp     .SaveToFile
772
      @@:
773
 
774
 
775
        mov     esi,[endDel]
776
        mov     edi,[begDel]
777
   @@:  lodsb
778
        stosb
779
        cmp     esi,[endMem]
780
        jb      @b
781
 
782
   .SaveToFile:
783
        mov     eax,dword[funcFile+12]
784
        sub     eax,[endDel]
785
        add     eax,[begDel]
3859 GerdtR 786
        dec     eax
3832 GerdtR 787
 
788
        mov     dword[funcFile],2               ;write buffer to file
789
        mov     dword[funcFile+12],eax
790
        m2m     dword[funcFile+16],[begMem]
791
        lea     ebx,[funcFile]
792
        mcall   70
793
 
3920 mario79 794
        mcall   68,13,[begMem]
795
 
3832 GerdtR 796
        xor     eax,eax
797
        pop     esi edi ecx ebx
798
        ret
799
endp
800
 
801
 
802
 
803
 
804
;;================================================================================================;;
1327 diamond 805
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
806
;;------------------------------------------------------------------------------------------------;;
807
;? Read shortcut key                                                                              ;;
808
;;------------------------------------------------------------------------------------------------;;
809
;> _f_name = ini filename                                                                 ;;
810
;> _sec_name = section name                                                               ;;
811
;> _key_name = key name                                                                   ;;
812
;> _def_val = default value to return if no key, section or file found                     ;;
813
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4       ;;
814
;;------------------------------------------------------------------------------------------------;;
815
;< eax = [_def_val] (error) / shortcut key value as scancode                                 ;;
816
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut                    ;;
817
;;================================================================================================;;
818
locals
819
  buf rb 64
820
endl
988 mikedld 821
 
2603 hidnplayr 822
        push    ebx esi edi
1327 diamond 823
 
2603 hidnplayr 824
        lea     esi, [buf]
825
        stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
826
        cmp     byte[esi],0
827
        je      .exit_error
1327 diamond 828
 
2603 hidnplayr 829
        xor     ebx, ebx        ; ebx holds the value of modifiers
1327 diamond 830
.loop:
831
; test for end
2603 hidnplayr 832
        xor     eax, eax
833
        cmp     byte [esi], al
834
        jz      .exit_ok        ; exit with scancode zero
1327 diamond 835
; skip all '+'s
2603 hidnplayr 836
        cmp     byte [esi], '+'
837
        jnz     @f
838
        inc     esi
839
        jmp     .loop
1327 diamond 840
@@:
841
; test for names
2603 hidnplayr 842
        mov     edi, .names_table
843
        xor     edx, edx
1327 diamond 844
.names_loop:
2603 hidnplayr 845
        movzx   ecx, byte [edi]
846
        inc     edi
847
        push    esi
1327 diamond 848
@@:
2603 hidnplayr 849
        lodsb
850
        or      al, 20h
851
        scasb
852
        loopz   @b
853
        jz      .name_found
854
        pop     esi
855
        lea     edi, [edi+ecx+4]
856
        inc     edx
857
        cmp     byte [edi], 0
858
        jnz     .names_loop
1327 diamond 859
; special test: functional keys F
2603 hidnplayr 860
        cmp     byte [esi], 'f'
861
        jz      @f
862
        cmp     byte [esi], 'F'
863
        jnz     .no_fx
1327 diamond 864
@@:
2603 hidnplayr 865
        mov     edi, esi
866
        inc     esi
867
        call    libini._.str_to_int
868
        test    eax, eax
3112 dunkaist 869
        jnz     .fx
2603 hidnplayr 870
        mov     esi, edi
1327 diamond 871
.no_fx:
872
; name not found, that must be usual key
2603 hidnplayr 873
        movzx   eax, byte [esi]
874
        stdcall libini._.ascii_to_scan, eax
875
        test    eax, eax
876
        jz      .exit_error
1327 diamond 877
; all is ok
878
.exit_ok:
2603 hidnplayr 879
        mov     ecx, [_modifiers]
880
        test    ecx, ecx
881
        jz      @f
882
        mov     [ecx], ebx
1327 diamond 883
 
884
@@:
885
 
2603 hidnplayr 886
        pop     edi esi ebx
887
        ret
1327 diamond 888
 
889
.exit_error:
2603 hidnplayr 890
        mov     eax, [_def_val]
891
        pop     edi esi ebx
892
        ret
1327 diamond 893
; handler for Fx
894
; eax = number
895
.fx:
2603 hidnplayr 896
        cmp     eax, 10
897
        ja      @f
898
        add     eax, 3Bh-1
899
        jmp     .exit_ok
1327 diamond 900
@@:
2603 hidnplayr 901
        add     eax, 57h-11
902
        jmp     .exit_ok
1327 diamond 903
; handlers for names
904
.name_found:
2603 hidnplayr 905
        pop     eax     ; ignore saved esi
906
        call    dword [edi]
907
        cmp     edx, .num_modifiers
908
        jae     .exit_ok
909
        jmp     .loop
1327 diamond 910
; modifiers
911
; syntax of value for each modifier:
912
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
913
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
914
; generic modifier: 0->1->2->2, 3->2, 4->2
915
; left modifier: 0->3->3, 1->2->2, 4->2
916
; right modifier: 0->4->4, 1->2->2, 3->2
917
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
918
macro shortcut_handle_modifiers name,reg,shift
919
{
920
local .set2,.set3,.set4
2603 hidnplayr 921
.#name#_handler:        ; generic modifier
922
        test    reg, 0xF
923
        jnz     .set2
1327 diamond 924
if shift
2603 hidnplayr 925
        or      reg, 1 shl shift
1327 diamond 926
else
2603 hidnplayr 927
        inc     reg
1327 diamond 928
end if
2603 hidnplayr 929
        retn
1327 diamond 930
.set2:
2603 hidnplayr 931
        and     reg, not (0xF shl shift)
932
        or      reg, 2 shl shift
933
        retn
1327 diamond 934
.l#name#_handler:
2603 hidnplayr 935
        mov     al, reg
936
        and     al, 0xF shl shift
937
        jz      .set3
938
        cmp     al, 3 shl shift
939
        jnz     .set2
940
        retn
1327 diamond 941
.set3:
2603 hidnplayr 942
        add     reg, 3 shl shift
943
        retn
1327 diamond 944
.r#name#_handler:
2603 hidnplayr 945
        mov     al, reg
946
        and     al, 0xF shl shift
947
        jz      .set4
948
        cmp     al, 4 shl shift
949
        jnz     .set2
950
        retn
1327 diamond 951
.set4:
2603 hidnplayr 952
        add     reg, 4 shl shift
953
        retn
1327 diamond 954
}
955
shortcut_handle_modifiers shift,bl,0
956
shortcut_handle_modifiers ctrl,bl,4
957
shortcut_handle_modifiers alt,bh,0
958
; names of keys
959
.name_handler:
2603 hidnplayr 960
        movzx   eax, byte [.names_scancodes+edx-.num_modifiers]
961
        retn
1327 diamond 962
endp
963
 
964
; note: comparison ignores case, so this table keeps lowercase names
965
; macro does this
966
macro shortcut_name_with_handler name,handler
967
{
968
local .start, .end
2603 hidnplayr 969
        db      .end - .start
1327 diamond 970
.start:
2603 hidnplayr 971
        db      name
1327 diamond 972
.end:
973
repeat .end - .start
2603 hidnplayr 974
        load .a byte from .start + % - 1
975
        store byte .a or 0x20 at .start + % - 1
1327 diamond 976
end repeat
2603 hidnplayr 977
        dd      handler
1327 diamond 978
}
979
macro shortcut_name [name]
980
{
2603 hidnplayr 981
        shortcut_name_with_handler name, .name_handler
1327 diamond 982
}
3832 GerdtR 983
 
1327 diamond 984
; all names here must be in english
985
; ... or modify lowercasing in macro and in comparison
986
.names_table:
987
; generic modifiers
2603 hidnplayr 988
        shortcut_name_with_handler 'Ctrl', .ctrl_handler
989
        shortcut_name_with_handler 'Alt', .alt_handler
990
        shortcut_name_with_handler 'Shift', .shift_handler
1327 diamond 991
; concrete modifiers
2603 hidnplayr 992
        shortcut_name_with_handler 'LCtrl', .lctrl_handler
993
        shortcut_name_with_handler 'RCtrl', .rctrl_handler
994
        shortcut_name_with_handler 'LAlt', .lalt_handler
995
        shortcut_name_with_handler 'RAlt', .ralt_handler
996
        shortcut_name_with_handler 'LShift', .lshift_handler
997
        shortcut_name_with_handler 'RShift', .rshift_handler
1327 diamond 998
.num_modifiers = 9
999
; symbolic names of keys
2603 hidnplayr 1000
        shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
1001
        shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
1002
        shortcut_name 'Up', 'Down'
1327 diamond 1003
; end of table
2603 hidnplayr 1004
        db      0
1327 diamond 1005
ini.get_shortcut.names_scancodes:
1006
; scancodes for 'Home' ... 'Down'
2603 hidnplayr 1007
        db      47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
1008
        db      0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
1009
        db      48h, 50h
1327 diamond 1010
 
988 mikedld 1011
;;================================================================================================;;
717 mikedld 1012
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1013
;;================================================================================================;;
1014
;! Imported functions section                                                                     ;;
1015
;;================================================================================================;;
1016
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1017
;;================================================================================================;;
1018
 
1019
 
1020
align 16
1021
@IMPORT:
1022
 
1023
library \
2603 hidnplayr 1024
        libio , 'libio.obj'
717 mikedld 1025
 
2603 hidnplayr 1026
import  libio                       , \
1027
        file.size   , 'file_size'   , \
1028
        file.open   , 'file_open'   , \
1029
        file.read   , 'file_read'   , \
1030
        file.write  , 'file_write'  , \
1031
        file.seek   , 'file_seek'   , \
1032
        file.eof?   , 'file_iseof'  , \
1033
        file.seteof , 'file_seteof' , \
1034
        file.tell   , 'file_tell'   , \
1035
        file.close  , 'file_close'
717 mikedld 1036
 
1037
 
1038
;;================================================================================================;;
1039
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1040
;;================================================================================================;;
1041
;! Exported functions section                                                                     ;;
1042
;;================================================================================================;;
1043
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1044
;;================================================================================================;;
1045
 
1046
 
1047
align 16
1048
@EXPORT:
1049
 
2603 hidnplayr 1050
export                                            \
1051
        libini._.init     , 'lib_init'          , \
1052
        0x00080009        , 'version'           , \
1053
        ini.enum_sections , 'ini_enum_sections' , \
1054
        ini.enum_keys     , 'ini_enum_keys'     , \
1055
        ini.get_str       , 'ini_get_str'       , \
1056
        ini.get_int       , 'ini_get_int'       , \
1057
        ini.get_color     , 'ini_get_color'     , \
1058
        ini.set_str       , 'ini_set_str'       , \
1059
        ini.set_int       , 'ini_set_int'       , \
1060
        ini.set_color     , 'ini_set_color'     , \
3832 GerdtR 1061
        ini.get_shortcut  , 'ini_get_shortcut'  , \
1062
        ini.del_section   , 'ini_del_section'