Subversion Repositories Kolibri OS

Rev

Rev 988 | Rev 995 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 ;;
  8. ;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
  9. ;; License, or (at your option) any later version.                                                ;;
  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  ;;
  13. ;; General Public License for more details.                                                       ;;
  14. ;;                                                                                                ;;
  15. ;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
  16. ;; see <http://www.gnu.org/licenses/>.                                                            ;;
  17. ;;                                                                                                ;;
  18. ;;================================================================================================;;
  19. ;;                                                                                                ;;
  20. ;; 2008-12-29 (mike.dld)                                                                          ;;
  21. ;;   bug-fixes:                                                                                   ;;
  22. ;;     - unnecessary 'stosb' in ini.get_str was causing problems                                  ;;
  23. ;; 2008-08-06 (mike.dld)                                                                          ;;
  24. ;;   changes:                                                                                     ;;
  25. ;;     - split private procs into libini_p.asm, added comments                                    ;;
  26. ;; 2008-02-07 (mike.dld)                                                                          ;;
  27. ;;   changes:                                                                                     ;;
  28. ;;     - renamed all *.aux.* to *._.* to match overall libraries design                           ;;
  29. ;; 2007-09-26 (mike.dld)                                                                          ;;
  30. ;;   bug-fixes:                                                                                   ;;
  31. ;;     - value was not correctly trimmed (reported by diamond)                                    ;;
  32. ;; 2007-08-01 (mike.dld)                                                                          ;;
  33. ;;   bug-fixes:                                                                                   ;;
  34. ;;     - serious defect in ini.set_str causing displaced write operations                         ;;
  35. ;;       (reported by diamond)                                                                    ;;
  36. ;;     - another serious defect in ini.enum_keys introduced with refactoring                      ;;
  37. ;;   changes:                                                                                     ;;
  38. ;;     - callback for enum_keys now takes additional parameter - key value                        ;;
  39. ;;     - handling trailing spaces in section/key/value                                            ;;
  40. ;; 2007-05-19 (mike.dld)                                                                          ;;
  41. ;;   bug-fixes:                                                                                   ;;
  42. ;;     - last char still wasn't read correctly                                                    ;;
  43. ;;     - digits of number were reversed when using ini.set_int                                    ;;
  44. ;;     - now using 'ini.aux.unget_char' instead of dangerous 'dec esi'                            ;;
  45. ;;   changes:                                                                                     ;;
  46. ;;     - all non-public functions now start with ini.aux.*                                        ;;
  47. ;;     - added ini.enum_sections and ini.enum_keys                                                ;;
  48. ;;     - removed ini.query_sec (use ini.enum_* instead)                                           ;;
  49. ;;                                                                                                ;;
  50. ;;================================================================================================;;
  51.  
  52. format MS COFF
  53.  
  54. public @EXPORT as 'EXPORTS'
  55.  
  56. include '../../../../proc32.inc'
  57. include '../../../../macros.inc'
  58. include '../libio/libio.inc'
  59. purge section ; mov,add,sub
  60.  
  61. include 'libini_p.inc'
  62.  
  63. section '.flat' code readable align 16
  64.  
  65. include 'libini_p.asm'
  66.  
  67. ;;================================================================================================;;
  68. proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
  69. ;;------------------------------------------------------------------------------------------------;;
  70. ;? Enumerate sections, calling callback function for each of them                                 ;;
  71. ;;------------------------------------------------------------------------------------------------;;
  72. ;> _f_name = ini filename <asciiz>                                                                ;;
  73. ;> _callback = callback function address: func(f_name, sec_name), where                           ;;
  74. ;>   f_name = ini filename (as passed to the function) <asciiz>                                   ;;
  75. ;>   sec_name = section name found <asciiz>                                                       ;;
  76. ;;------------------------------------------------------------------------------------------------;;
  77. ;< eax = -1 (error) / 0                                                                           ;;
  78. ;;================================================================================================;;
  79. locals
  80.   f       IniFile
  81.   f_addr  dd ?
  82.   sec_buf dd ?
  83. endl
  84.  
  85.         push    ebx esi edi
  86.  
  87.         cld
  88.  
  89.         invoke  mem.alloc, ini.MAX_NAME_LEN
  90.         or      eax, eax
  91.         jz      .exit_error.2
  92.         mov     [sec_buf], eax
  93.  
  94.         xor     eax, eax
  95.         mov     [f.fh], eax
  96.         mov     [f.buf], eax
  97.         invoke  file.open, [_f_name], O_READ
  98.         cmp     eax, 32
  99.         jb      .exit_error
  100.         mov     [f.fh], eax
  101.         invoke  mem.alloc, ini.MEM_SIZE
  102.         or      eax, eax
  103.         jz      .exit_error
  104.         mov     [f.buf], eax
  105.         lea     ebx, [f]
  106.         mov     [f_addr], ebx
  107.  
  108.         invoke  file.seek, [f.fh], 0, SEEK_SET
  109.         stdcall libini._.preload_block, [f_addr]
  110.  
  111.   .next_section:
  112.         stdcall libini._.find_next_section, [f_addr]
  113.         or      eax, eax
  114.         jnz     .exit_error
  115.  
  116.         stdcall libini._.get_char, [f_addr]
  117.         stdcall libini._.skip_spaces, [f_addr]
  118. ;       inc     esi
  119. ;       dec     [f.cnt]
  120.         mov     edi, [sec_buf]
  121.     @@: stdcall libini._.get_char, [f_addr]
  122.         cmp     al, ']'
  123.         je      @f
  124.         or      al, al
  125.         jz      .exit_ok
  126.         cmp     al, 13
  127.         je      .next_section
  128.         cmp     al, 10
  129.         je      .next_section
  130.         stosb
  131.         jmp     @b
  132.     @@: xor     al, al
  133.         stosb
  134.         add     edi, -2
  135.     @@: cmp     byte[edi], 32
  136.         ja      @f
  137.         mov     byte[edi], 0
  138.         dec     edi
  139.         jmp     @b
  140.     @@:
  141.         pushad
  142.         mov     eax, [f_addr]
  143.         stdcall [_callback], [_f_name], [sec_buf]
  144.         or      eax, eax
  145.         popad
  146.         jnz     .next_section
  147.  
  148.   .exit_ok:
  149.         invoke  file.close, [f.fh]
  150.         invoke  mem.free, [f.buf]
  151.         invoke  mem.free, [sec_buf]
  152.         xor     eax, eax
  153.         pop     edi esi ebx
  154.         ret
  155.  
  156.   .exit_error:
  157.         invoke  file.close, [f.fh]
  158.         invoke  mem.free, [f.buf]
  159.         invoke  mem.free, [sec_buf]
  160.   .exit_error.2:
  161.         or      eax, -1
  162.         pop     edi esi ebx
  163.         ret
  164. endp
  165.  
  166. ;;================================================================================================;;
  167. proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
  168. ;;------------------------------------------------------------------------------------------------;;
  169. ;? Enumerate keys within a section, calling callback function for each of them                    ;;
  170. ;;------------------------------------------------------------------------------------------------;;
  171. ;> _f_name = ini filename <asciiz>                                                                ;;
  172. ;> _sec_name = section name <asciiz>                                                              ;;
  173. ;> _callback = callback function address: func(f_name, sec_name, key_name, key_value), where      ;;
  174. ;>   f_name = ini filename (as passed to the function) <asciiz>                                   ;;
  175. ;>   sec_name = section name (as passed to the function) <asciiz>                                 ;;
  176. ;>   key_name = key name found <asciiz>                                                           ;;
  177. ;>   key_value = value of key found <asciiz>                                                      ;;
  178. ;;------------------------------------------------------------------------------------------------;;
  179. ;< eax = -1 (error) / 0                                                                           ;;
  180. ;;================================================================================================;;
  181. locals
  182.   f       IniFile
  183.   f_addr  dd ?
  184.   key_buf dd ?
  185.   val_buf dd ?
  186. endl
  187.  
  188.         push    ebx esi edi
  189.  
  190.         cld
  191.  
  192.         invoke  mem.alloc, ini.MAX_NAME_LEN
  193.         or      eax, eax
  194.         jz      .exit_error.3
  195.         mov     [key_buf], eax
  196.         invoke  mem.alloc, ini.MAX_VALUE_LEN
  197.         or      eax, eax
  198.         jz      .exit_error.2
  199.         mov     [val_buf], eax
  200.  
  201.         xor     eax, eax
  202.         mov     [f.fh], eax
  203.         mov     [f.buf], eax
  204.         invoke  file.open, [_f_name], O_READ
  205.         cmp     eax, 32
  206.         jb      .exit_error
  207.         mov     [f.fh], eax
  208.         invoke  mem.alloc, ini.MEM_SIZE
  209.         or      eax, eax
  210.         jz      .exit_error
  211.         mov     [f.buf], eax
  212.         lea     ebx, [f]
  213.         mov     [f_addr], ebx
  214.         stdcall libini._.find_section, ebx, [_sec_name]
  215.         or      eax, eax
  216.         jnz     .exit_error
  217.  
  218.   .next_key:
  219.         stdcall libini._.skip_line, [f_addr]
  220.         stdcall libini._.skip_nonblanks, [f_addr]
  221.         or      al, al
  222.         jz      .exit_error
  223.         cmp     al, '['
  224.         je      .exit_error
  225.         mov     edi, [key_buf]
  226.     @@: stdcall libini._.get_char, [f_addr]
  227.         or      al, al
  228.         jz      .exit_error
  229.         cmp     al, '='
  230.         je      @f
  231.         stosb
  232.         jmp     @b
  233.     @@:
  234.         xor     al, al
  235.         stosb
  236.         add     edi, -2
  237.     @@: cmp     byte[edi], 32
  238.         ja      @f
  239.         mov     byte[edi], 0
  240.         dec     edi
  241.         jmp     @b
  242.     @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
  243.         pushad
  244.         stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
  245.         or      eax, eax
  246.         popad
  247.         jnz     .next_key
  248.  
  249.     @@: invoke  file.close, [f.fh]
  250.         invoke  mem.free, [f.buf]
  251.         xor     eax, eax
  252.         stosb
  253.         pop     edi esi ebx
  254.         ret
  255.  
  256.   .exit_error:
  257.         invoke  file.close, [f.fh]
  258.         invoke  mem.free, [f.buf]
  259.         invoke  mem.free, [val_buf]
  260.   .exit_error.2:
  261.         invoke  mem.free, [key_buf]
  262.   .exit_error.3:
  263.         or      eax, -1
  264.         pop     edi esi ebx
  265.         ret
  266. endp
  267.  
  268. ;;================================================================================================;;
  269. proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
  270. ;;------------------------------------------------------------------------------------------------;;
  271. ;? Read string                                                                                    ;;
  272. ;;------------------------------------------------------------------------------------------------;;
  273. ;> _f_name = ini filename <asciiz>                                                                ;;
  274. ;> _sec_name = section name <asciiz>                                                              ;;
  275. ;> _key_name = key name <asciiz>                                                                  ;;
  276. ;> _buffer = destination buffer address <byte*>                                                   ;;
  277. ;> _buf_len = buffer size (maximum bytes to read) <dword>                                         ;;
  278. ;> _def_val = default value to return if no key, section or file found <asciiz>                   ;;
  279. ;;------------------------------------------------------------------------------------------------;;
  280. ;< eax = -1 (error) / 0                                                                           ;;
  281. ;< [_buffer] = [_def_val] (error) / found key value <asciiz>                                      ;;
  282. ;;================================================================================================;;
  283. locals
  284.   f      IniFile
  285.   f_addr dd ?
  286. endl
  287.  
  288.         push    ebx esi edi
  289.  
  290.         xor     eax, eax
  291.         mov     [f.fh], eax
  292.         mov     [f.buf], eax
  293.         invoke  file.open, [_f_name], O_READ
  294.         cmp     eax, 32
  295.         jb      .exit_error
  296.         mov     [f.fh], eax
  297.         invoke  mem.alloc, ini.MEM_SIZE
  298.         or      eax, eax
  299.         jz      .exit_error
  300.         mov     [f.buf], eax
  301.         lea     ebx, [f]
  302.         mov     [f_addr], ebx
  303.         stdcall libini._.find_section, ebx, [_sec_name]
  304.         or      eax, eax
  305.         jnz     .exit_error
  306.  
  307.         stdcall libini._.find_key, ebx, [_key_name]
  308.         or      eax, eax
  309.         jnz     .exit_error
  310.  
  311.         stdcall libini._.low.read_value, [f_addr], [_buffer], [_buf_len]
  312.     @@: invoke  file.close, [f.fh]
  313.         invoke  mem.free, [f.buf]
  314.         xor     eax, eax
  315.         pop     edi esi ebx
  316.         ret
  317.  
  318.   .exit_error:
  319.         invoke  file.close, [f.fh]
  320.         invoke  mem.free, [f.buf]
  321.         mov     edi, [_buffer]
  322.         mov     esi, [_def_val]
  323.         xor     al, al
  324.         or      esi, esi
  325.         jz      .exit_error.2
  326.     @@: lodsb
  327.   .exit_error.2:
  328.         stosb
  329.         or      al, al
  330.         jnz     @b
  331.         or      eax, -1
  332.         pop     edi esi ebx
  333.         ret
  334. endp
  335.  
  336. ;;================================================================================================;;
  337. proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
  338. ;;------------------------------------------------------------------------------------------------;;
  339. ;? Write string                                                                                   ;;
  340. ;;------------------------------------------------------------------------------------------------;;
  341. ;> _f_name = ini filename <asciiz>                                                                ;;
  342. ;> _sec_name = section name <asciiz>                                                              ;;
  343. ;> _key_name = key name <asciiz>                                                                  ;;
  344. ;> _buffer = source buffer address <byte*>                                                        ;;
  345. ;> _buf_len = buffer size (bytes to write) <dword>                                                ;;
  346. ;;------------------------------------------------------------------------------------------------;;
  347. ;< eax = -1 (error) / 0                                                                           ;;
  348. ;;================================================================================================;;
  349. locals
  350.   f      IniFile
  351.   f_addr dd ?
  352. endl
  353.  
  354.         push    ebx esi edi
  355.  
  356.         xor     eax, eax
  357.         mov     [f.fh], eax
  358.         mov     [f.buf], eax
  359.         invoke  file.open, [_f_name], O_READ + O_WRITE + O_CREATE
  360.         cmp     eax, 32
  361.         jb      .exit_error
  362.         mov     [f.fh], eax
  363.         invoke  mem.alloc, ini.MEM_SIZE
  364.         or      eax, eax
  365.         jz      .exit_error
  366.         mov     [f.buf], eax
  367.         lea     ebx, [f]
  368.         mov     [f_addr], ebx
  369.  
  370.         stdcall libini._.find_section, ebx, [_sec_name]
  371.         or      eax, eax
  372.         jnz     .create_section
  373.  
  374.         stdcall libini._.find_key, ebx, [_key_name]
  375.         or      eax, eax
  376.         jnz     .create_key
  377.  
  378.   .modify_key:
  379.         stdcall libini._.get_value_length, [f_addr]
  380.         sub     eax, [_buf_len]
  381.         stdcall libini._.shift_content, [f_addr], eax
  382.  
  383.   .modify_key.ex:
  384.         invoke  file.tell, [f.fh]
  385.         sub     eax, [f.cnt]
  386. ;       dec     eax
  387.         invoke  file.seek, [f.fh], eax, SEEK_SET
  388.         invoke  file.write, [f.fh], [_buffer], [_buf_len]
  389.  
  390.         pop     edi esi ebx
  391.         xor     eax, eax
  392.         ret
  393.  
  394.   .create_key:
  395.         mov     edi, [f.buf]
  396.         add     edi, ini.BLOCK_SIZE
  397.         push    edi
  398.  
  399.   .create_key.ex:
  400. ;       mov     word[edi], 0x0A0D
  401. ;       add     edi,2
  402.         mov     esi, [_key_name]
  403.         call    libini._.string_copy
  404.         mov     byte[edi], '='
  405.         inc     edi
  406.         mov     esi, [_buffer]
  407.         mov     ecx, [_buf_len]
  408.         rep     movsb
  409.         mov     word[edi], 0x0A0D
  410.         add     edi, 2
  411.         mov     eax, edi
  412.  
  413.         pop     edi
  414.         sub     eax, edi
  415.         mov     [_buffer], edi
  416.         mov     [_buf_len], eax
  417.         neg     eax
  418.         stdcall libini._.shift_content, [f_addr], eax
  419.  
  420.         jmp     .modify_key.ex
  421.  
  422.   .create_section:
  423.         mov     edi, [f.buf]
  424.         add     edi, ini.BLOCK_SIZE
  425.         push    edi
  426.  
  427.         mov     esi, [_sec_name]
  428. ;       mov     dword[edi], 0x0A0D + ('[' shl 16)
  429. ;       add     edi, 3
  430.         mov     byte[edi], '['
  431.         inc     edi
  432.         call    libini._.string_copy
  433. ;       mov     byte[edi], ']'
  434. ;       inc     edi
  435.         mov     dword[edi], ']' + (0x0A0D shl 8)
  436.         add     edi, 3
  437.  
  438.         jmp     .create_key.ex
  439.  
  440.   .exit_error:
  441.         pop     edi esi ebx
  442.         or      eax, -1
  443.         ret
  444. endp
  445.  
  446. ;;================================================================================================;;
  447. proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
  448. ;;------------------------------------------------------------------------------------------------;;
  449. ;? Read integer                                                                                   ;;
  450. ;;------------------------------------------------------------------------------------------------;;
  451. ;> _f_name = ini filename <asciiz>                                                                ;;
  452. ;> _sec_name = section name <asciiz>                                                              ;;
  453. ;> _key_name = key name <asciiz>                                                                  ;;
  454. ;> _def_val = default value to return if no key, section or file found <dword>                    ;;
  455. ;;------------------------------------------------------------------------------------------------;;
  456. ;< eax = [_def_val] (error) / found key value <dword>                                             ;;
  457. ;;================================================================================================;;
  458. locals
  459.   f      IniFile
  460.   f_addr dd ?
  461. endl
  462.  
  463.         push    ebx esi edi
  464.  
  465.         xor     eax, eax
  466.         mov     [f.fh], eax
  467.         mov     [f.buf], eax
  468.         invoke  file.open, [_f_name], O_READ
  469.         cmp     eax, 32
  470.         jb      .exit_error
  471.         mov     [f.fh], eax
  472.         invoke  mem.alloc, ini.MEM_SIZE
  473.         or      eax, eax
  474.         jz      .exit_error
  475.         mov     [f.buf], eax
  476.         lea     ebx, [f]
  477.         mov     [f_addr], ebx
  478.         stdcall libini._.find_section, ebx, [_sec_name]
  479.         or      eax, eax
  480.         jnz     .exit_error
  481.  
  482.         stdcall libini._.find_key, ebx, [_key_name]
  483.         or      eax, eax
  484.         jnz     .exit_error
  485.  
  486.         stdcall libini._.skip_nonblanks, [f_addr]
  487.         xor     eax, eax
  488.         xor     ebx, ebx
  489.         xor     edx, edx
  490.         stdcall libini._.get_char, [f_addr]
  491.         cmp     al, '-'
  492.         jne     .lp1
  493.         inc     bh
  494.     @@: stdcall libini._.get_char, [f_addr]
  495.   .lp1: cmp     al, '0'
  496.         jb      @f
  497.         cmp     al, '9'
  498.         ja      @f
  499.         inc     bl
  500.         add     eax, -'0'
  501.         imul    edx, 10
  502.         add     edx, eax
  503.         jmp     @b
  504.     @@:
  505.         or      bl, bl
  506.         jz      .exit_error
  507.         or      bh, bh
  508.         jz      @f
  509.         neg     edx
  510.     @@: invoke  file.close, [f.fh]
  511.         invoke  mem.free, [f.buf]
  512.         mov     eax, edx
  513.         pop     edi esi ebx
  514.         ret
  515.  
  516.   .exit_error:
  517.         invoke  file.close, [f.fh]
  518.         invoke  mem.free, [f.buf]
  519.         mov     eax, [_def_val]
  520.         pop     edi esi ebx
  521.         ret
  522. endp
  523.  
  524. ;;================================================================================================;;
  525. proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
  526. ;;------------------------------------------------------------------------------------------------;;
  527. ;? Write integer                                                                                  ;;
  528. ;;------------------------------------------------------------------------------------------------;;
  529. ;> _f_name = ini filename <asciiz>                                                                ;;
  530. ;> _sec_name = section name <asciiz>                                                              ;;
  531. ;> _key_name = key name <asciiz>                                                                  ;;
  532. ;> _val = value <dword>                                                                           ;;
  533. ;;------------------------------------------------------------------------------------------------;;
  534. ;< eax = -1 (error) / 0                                                                           ;;
  535. ;;================================================================================================;;
  536. locals
  537.   buf rb 16
  538. endl
  539.  
  540.         push    ecx edx edi
  541.  
  542.         lea     edi, [buf]
  543.         add     edi, 15
  544.         mov     eax, [_val]
  545.         or      eax, eax
  546.         jns     @f
  547.         mov     byte[edi], '-'
  548.         neg     eax
  549.         inc     edi
  550.     @@: mov     ecx, 10
  551.     @@: xor     edx, edx
  552.         idiv    ecx
  553.         add     dl, '0'
  554.         mov     [edi], dl
  555.         dec     edi
  556.         or      eax, eax
  557.         jnz     @b
  558.         lea     eax, [buf]
  559.         add     eax, 15
  560.         sub     eax, edi
  561.         inc     edi
  562.  
  563.         stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
  564.  
  565.         pop     edi edx ecx
  566.         ret
  567. endp
  568.  
  569. ;;================================================================================================;;
  570. proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
  571. ;;------------------------------------------------------------------------------------------------;;
  572. ;? Read color                                                                                     ;;
  573. ;;------------------------------------------------------------------------------------------------;;
  574. ;> _f_name = ini filename <asciiz>                                                                ;;
  575. ;> _sec_name = section name <asciiz>                                                              ;;
  576. ;> _key_name = key name <asciiz>                                                                  ;;
  577. ;> _def_val = default value to return if no key, section or file found <dword>                    ;;
  578. ;;------------------------------------------------------------------------------------------------;;
  579. ;< eax = [_def_val] (error) / found key value <dword>                                             ;;
  580. ;;================================================================================================;;
  581. locals
  582.   buf rb 14
  583. endl
  584.  
  585.         push    ebx esi edi
  586.  
  587.         lea     esi, [buf]
  588.         stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 14, 0
  589.         cmp     byte[esi],0
  590.         je      .exit_error
  591.  
  592.         xor     ebx, ebx
  593.         stdcall libini._.str_to_int
  594.         movzx   ebx, al
  595.         shl     ebx, 16
  596.         lodsb
  597.         cmp     al, ','
  598.         jne     @f
  599.         stdcall libini._.str_to_int
  600.         mov     bh, al
  601.         lodsb
  602.         cmp     al, ','
  603.         jne     @f
  604.         stdcall libini._.str_to_int
  605.         mov     bl, al
  606.  
  607.     @@: mov     eax, ebx
  608.  
  609.         pop     edi esi ebx
  610.         ret
  611.  
  612.   .exit_error:
  613.         mov     eax, [_def_val]
  614.         pop     edi esi ebx
  615.         ret
  616. endp
  617.  
  618. ;;================================================================================================;;
  619. proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
  620. ;;------------------------------------------------------------------------------------------------;;
  621. ;? Write color                                                                                    ;;
  622. ;;------------------------------------------------------------------------------------------------;;
  623. ;> _f_name = ini filename <asciiz>                                                                ;;
  624. ;> _sec_name = section name <asciiz>                                                              ;;
  625. ;> _key_name = key name <asciiz>                                                                  ;;
  626. ;> _val = value <dword>                                                                           ;;
  627. ;;------------------------------------------------------------------------------------------------;;
  628. ;< eax = -1 (error) / 0                                                                           ;;
  629. ;;================================================================================================;;
  630. locals
  631.   buf rb 16
  632. endl
  633.  
  634.         push    ecx edx edi
  635.  
  636.         lea     edi, [buf]
  637.         mov     ecx, 10
  638.         mov     ebx, [_val]
  639.         mov     eax, ebx
  640.         shr     eax, 16
  641.         and     eax, 0x0ff
  642.         stdcall libini._.int_to_str
  643.         mov     byte[edi], ','
  644.         inc     edi
  645.         movzx   eax, bh
  646.         stdcall libini._.int_to_str
  647.         mov     byte[edi], ','
  648.         inc     edi
  649.         movzx   eax, bl
  650.         stdcall libini._.int_to_str
  651.  
  652.         lea     eax, [buf]
  653.         sub     edi, eax
  654.  
  655.         stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
  656.  
  657.         pop     edi edx ecx
  658.         ret
  659. endp
  660.  
  661.  
  662. ;;================================================================================================;;
  663. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  664. ;;================================================================================================;;
  665. ;! Imported functions section                                                                     ;;
  666. ;;================================================================================================;;
  667. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  668. ;;================================================================================================;;
  669.  
  670.  
  671. align 16
  672. @IMPORT:
  673.  
  674. library \
  675.         libio , 'libio.obj'
  676.  
  677. import  libio                       , \
  678.         file.size   , 'file.size'   , \
  679.         file.open   , 'file.open'   , \
  680.         file.read   , 'file.read'   , \
  681.         file.write  , 'file.write'  , \
  682.         file.seek   , 'file.seek'   , \
  683.         file.eof?   , 'file.eof?'   , \
  684.         file.seteof , 'file.seteof' , \
  685.         file.tell   , 'file.tell'   , \
  686.         file.close  , 'file.close'
  687.  
  688.  
  689. ;;================================================================================================;;
  690. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  691. ;;================================================================================================;;
  692. ;! Exported functions section                                                                     ;;
  693. ;;================================================================================================;;
  694. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  695. ;;================================================================================================;;
  696.  
  697.  
  698. align 16
  699. @EXPORT:
  700.  
  701. export                                            \
  702.         libini._.init     , 'lib_init'          , \
  703.         0x00040006        , 'version'           , \
  704.         ini.enum_sections , 'ini.enum_sections' , \
  705.         ini.enum_keys     , 'ini.enum_keys'     , \
  706.         ini.get_str       , 'ini.get_str'       , \
  707.         ini.get_int       , 'ini.get_int'       , \
  708.         ini.get_color     , 'ini.get_color'     , \
  709.         ini.set_str       , 'ini.set_str'       , \
  710.         ini.set_int       , 'ini.set_int'       , \
  711.         ini.set_color     , 'ini.set_color'
  712.