Subversion Repositories Kolibri OS

Rev

Rev 1048 | Rev 1295 | 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. ;; 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.                                         ;;
  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. ;; Lesser General Public License for more details.                                                ;;
  14. ;;                                                                                                ;;
  15. ;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
  16. ;; If not, see <http://www.gnu.org/licenses/>.                                                    ;;
  17. ;;                                                                                                ;;
  18. ;;================================================================================================;;
  19. ;;                                                                                                ;;
  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                                                        ;;
  26. ;; 2008-12-29 (mike.dld)                                                                          ;;
  27. ;;   bug-fixes:                                                                                   ;;
  28. ;;     - unnecessary 'stosb' in ini.get_str was causing problems                                  ;;
  29. ;;   new features:                                                                                ;;
  30. ;;     - new functions: ini.get_color and ini.set_color                                           ;;
  31. ;; 2008-08-06 (mike.dld)                                                                          ;;
  32. ;;   changes:                                                                                     ;;
  33. ;;     - split private procs into libini_p.asm, added comments                                    ;;
  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'
  67. purge section ; mov,add,sub
  68.  
  69. include 'libini_p.inc'
  70.  
  71. section '.flat' code readable align 16
  72.  
  73. include 'libini_p.asm'
  74.  
  75. ;;================================================================================================;;
  76. proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
  77. ;;------------------------------------------------------------------------------------------------;;
  78. ;? Enumerate sections, calling callback function for each of them                                 ;;
  79. ;;------------------------------------------------------------------------------------------------;;
  80. ;> _f_name = ini filename <asciiz>                                                                ;;
  81. ;> _callback = callback function address: func(f_name, sec_name), where                           ;;
  82. ;>   f_name = ini filename (as passed to the function) <asciiz>                                   ;;
  83. ;>   sec_name = section name found <asciiz>                                                       ;;
  84. ;;------------------------------------------------------------------------------------------------;;
  85. ;< eax = -1 (error) / 0                                                                           ;;
  86. ;;================================================================================================;;
  87. locals
  88.   f       IniFile
  89.   f_addr  dd ?
  90.   sec_buf dd ?
  91. endl
  92.  
  93.         push    ebx esi edi
  94.  
  95.         cld
  96.  
  97.         invoke  mem.alloc, ini.MAX_NAME_LEN
  98.         or      eax, eax
  99.         jz      .exit_error.2
  100.         mov     [sec_buf], eax
  101.  
  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
  115.  
  116.         invoke  file.seek, [f.fh], 0, SEEK_SET
  117.         stdcall libini._.preload_block, [f_addr]
  118.  
  119.   .next_section:
  120.         stdcall libini._.find_next_section, [f_addr]
  121.         or      eax, eax
  122.         jnz     .exit_error
  123.  
  124.         stdcall libini._.get_char, [f_addr]
  125.         stdcall libini._.skip_spaces, [f_addr]
  126.         mov     edi, [sec_buf]
  127.     @@: stdcall libini._.get_char, [f_addr]
  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
  146.     @@:
  147.         pushad
  148.         mov     eax, [f_addr]
  149.         stdcall [_callback], [_f_name], [sec_buf]
  150.         or      eax, eax
  151.         popad
  152.         jnz     .next_section
  153.  
  154.   .exit_ok:
  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
  161.  
  162.   .exit_error:
  163.         invoke  file.close, [f.fh]
  164.         invoke  mem.free, [f.buf]
  165.         invoke  mem.free, [sec_buf]
  166.   .exit_error.2:
  167.         or      eax, -1
  168.         pop     edi esi ebx
  169.         ret
  170. endp
  171.  
  172. ;;================================================================================================;;
  173. proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
  174. ;;------------------------------------------------------------------------------------------------;;
  175. ;? Enumerate keys within a section, calling callback function for each of them                    ;;
  176. ;;------------------------------------------------------------------------------------------------;;
  177. ;> _f_name = ini filename <asciiz>                                                                ;;
  178. ;> _sec_name = section name <asciiz>                                                              ;;
  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) <asciiz>                                   ;;
  181. ;>   sec_name = section name (as passed to the function) <asciiz>                                 ;;
  182. ;>   key_name = key name found <asciiz>                                                           ;;
  183. ;>   key_value = value of key found <asciiz>                                                      ;;
  184. ;;------------------------------------------------------------------------------------------------;;
  185. ;< eax = -1 (error) / 0                                                                           ;;
  186. ;;================================================================================================;;
  187. locals
  188.   f       IniFile
  189.   f_addr  dd ?
  190.   key_buf dd ?
  191.   val_buf dd ?
  192. endl
  193.  
  194.         push    ebx esi edi
  195.  
  196.         cld
  197.  
  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
  206.  
  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
  223.  
  224.   .next_key:
  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]
  232.     @@: stdcall libini._.get_char, [f_addr]
  233.         or      al, al
  234.         jz      .exit_error
  235.         cmp     al, '='
  236.         je      @f
  237.         stosb
  238.         jmp     @b
  239.     @@:
  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
  248.     @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
  249.         pushad
  250.         stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
  251.         or      eax, eax
  252.         popad
  253.         jnz     .next_key
  254.  
  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
  261.  
  262.   .exit_error:
  263.         invoke  file.close, [f.fh]
  264.         invoke  mem.free, [f.buf]
  265.         invoke  mem.free, [val_buf]
  266.   .exit_error.2:
  267.         invoke  mem.free, [key_buf]
  268.   .exit_error.3:
  269.         or      eax, -1
  270.         pop     edi esi ebx
  271.         ret
  272. endp
  273.  
  274. ;;================================================================================================;;
  275. proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
  276. ;;------------------------------------------------------------------------------------------------;;
  277. ;? Read string                                                                                    ;;
  278. ;;------------------------------------------------------------------------------------------------;;
  279. ;> _f_name = ini filename <asciiz>                                                                ;;
  280. ;> _sec_name = section name <asciiz>                                                              ;;
  281. ;> _key_name = key name <asciiz>                                                                  ;;
  282. ;> _buffer = destination buffer address <byte*>                                                   ;;
  283. ;> _buf_len = buffer size (maximum bytes to read) <dword>                                         ;;
  284. ;> _def_val = default value to return if no key, section or file found <asciiz>                   ;;
  285. ;;------------------------------------------------------------------------------------------------;;
  286. ;< eax = -1 (error) / 0                                                                           ;;
  287. ;< [_buffer] = [_def_val] (error) / found key value <asciiz>                                      ;;
  288. ;;================================================================================================;;
  289. locals
  290.   f      IniFile
  291.   f_addr dd ?
  292. endl
  293.  
  294.         push    ebx esi edi
  295.  
  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
  312.  
  313.         stdcall libini._.find_key, ebx, [_key_name]
  314.         or      eax, eax
  315.         jnz     .exit_error
  316.  
  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
  323.  
  324.   .exit_error:
  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
  332.     @@: lodsb
  333.   .exit_error.2:
  334.         stosb
  335.         or      al, al
  336.         jnz     @b
  337.         or      eax, -1
  338.         pop     edi esi ebx
  339.         ret
  340. endp
  341.  
  342. ;;================================================================================================;;
  343. proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
  344. ;;------------------------------------------------------------------------------------------------;;
  345. ;? Write string                                                                                   ;;
  346. ;;------------------------------------------------------------------------------------------------;;
  347. ;> _f_name = ini filename <asciiz>                                                                ;;
  348. ;> _sec_name = section name <asciiz>                                                              ;;
  349. ;> _key_name = key name <asciiz>                                                                  ;;
  350. ;> _buffer = source buffer address <byte*>                                                        ;;
  351. ;> _buf_len = buffer size (bytes to write) <dword>                                                ;;
  352. ;;------------------------------------------------------------------------------------------------;;
  353. ;< eax = -1 (error) / 0                                                                           ;;
  354. ;;================================================================================================;;
  355. locals
  356.   f      IniFile
  357.   f_addr dd ?
  358. endl
  359.  
  360.         push    ebx esi edi
  361.  
  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
  375.  
  376.         stdcall libini._.find_section, ebx, [_sec_name]
  377.         or      eax, eax
  378.         jnz     .create_section
  379.  
  380.         stdcall libini._.find_key, ebx, [_key_name]
  381.         or      eax, eax
  382.         jnz     .create_key
  383.  
  384.   .modify_key:
  385.         stdcall libini._.get_value_length, [f_addr]
  386.         sub     eax, [_buf_len]
  387.         stdcall libini._.shift_content, [f_addr], eax
  388.  
  389.   .modify_key.ex:
  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]
  394.  
  395.         pop     edi esi ebx
  396.         xor     eax, eax
  397.         ret
  398.  
  399.   .create_key:
  400.         mov     edi, [f.buf]
  401.         add     edi, ini.BLOCK_SIZE
  402.         push    edi
  403.  
  404.   .create_key.ex:
  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
  415.  
  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
  422.  
  423.         jmp     .modify_key.ex
  424.  
  425.   .create_section:
  426.         mov     edi, [f.buf]
  427.         add     edi, ini.BLOCK_SIZE
  428.         push    edi
  429.  
  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
  436.  
  437.         jmp     .create_key.ex
  438.  
  439.   .exit_error:
  440.         pop     edi esi ebx
  441.         or      eax, -1
  442.         ret
  443. endp
  444.  
  445. ;;================================================================================================;;
  446. proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
  447. ;;------------------------------------------------------------------------------------------------;;
  448. ;? Read integer                                                                                   ;;
  449. ;;------------------------------------------------------------------------------------------------;;
  450. ;> _f_name = ini filename <asciiz>                                                                ;;
  451. ;> _sec_name = section name <asciiz>                                                              ;;
  452. ;> _key_name = key name <asciiz>                                                                  ;;
  453. ;> _def_val = default value to return if no key, section or file found <dword>                    ;;
  454. ;;------------------------------------------------------------------------------------------------;;
  455. ;< eax = [_def_val] (error) / found key value <dword>                                             ;;
  456. ;;================================================================================================;;
  457. locals
  458.   f      IniFile
  459.   f_addr dd ?
  460. endl
  461.  
  462.         push    ebx esi edi
  463.  
  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
  480.  
  481.         stdcall libini._.find_key, ebx, [_key_name]
  482.         or      eax, eax
  483.         jnz     .exit_error
  484.  
  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
  493.     @@: stdcall libini._.get_char, [f_addr]
  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
  503.     @@:
  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
  513.         ret
  514.  
  515.   .exit_error:
  516.         invoke  file.close, [f.fh]
  517.         invoke  mem.free, [f.buf]
  518.         mov     eax, [_def_val]
  519.         pop     edi esi ebx
  520.         ret
  521. endp
  522.  
  523. ;;================================================================================================;;
  524. proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
  525. ;;------------------------------------------------------------------------------------------------;;
  526. ;? Write integer                                                                                  ;;
  527. ;;------------------------------------------------------------------------------------------------;;
  528. ;> _f_name = ini filename <asciiz>                                                                ;;
  529. ;> _sec_name = section name <asciiz>                                                              ;;
  530. ;> _key_name = key name <asciiz>                                                                  ;;
  531. ;> _val = value <dword>                                                                           ;;
  532. ;;------------------------------------------------------------------------------------------------;;
  533. ;< eax = -1 (error) / 0                                                                           ;;
  534. ;;================================================================================================;;
  535. locals
  536.   buf rb 16
  537. endl
  538.  
  539.         push    ecx edx edi
  540.  
  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
  561.  
  562.         stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
  563.  
  564.         pop     edi edx ecx
  565.         ret
  566. endp
  567.  
  568. ;;================================================================================================;;
  569. proc ini.get_color _f_name, _sec_name, _key_name, _def_val ;//////////////////////////////////////;;
  570. ;;------------------------------------------------------------------------------------------------;;
  571. ;? Read color                                                                                     ;;
  572. ;;------------------------------------------------------------------------------------------------;;
  573. ;> _f_name = ini filename <asciiz>                                                                ;;
  574. ;> _sec_name = section name <asciiz>                                                              ;;
  575. ;> _key_name = key name <asciiz>                                                                  ;;
  576. ;> _def_val = default value to return if no key, section or file found <dword>                    ;;
  577. ;;------------------------------------------------------------------------------------------------;;
  578. ;< eax = [_def_val] (error) / found key value <dword>                                             ;;
  579. ;;================================================================================================;;
  580. locals
  581.   buf rb 14
  582. endl
  583.  
  584.         push    ebx esi edi
  585.  
  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
  590.  
  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
  605.  
  606.     @@: mov     eax, ebx
  607.  
  608.         pop     edi esi ebx
  609.         ret
  610.  
  611.   .exit_error:
  612.         mov     eax, [_def_val]
  613.         pop     edi esi ebx
  614.         ret
  615. endp
  616.  
  617. ;;================================================================================================;;
  618. proc ini.set_color _f_name, _sec_name, _key_name, _val ;//////////////////////////////////////////;;
  619. ;;------------------------------------------------------------------------------------------------;;
  620. ;? Write color                                                                                    ;;
  621. ;;------------------------------------------------------------------------------------------------;;
  622. ;> _f_name = ini filename <asciiz>                                                                ;;
  623. ;> _sec_name = section name <asciiz>                                                              ;;
  624. ;> _key_name = key name <asciiz>                                                                  ;;
  625. ;> _val = value <dword>                                                                           ;;
  626. ;;------------------------------------------------------------------------------------------------;;
  627. ;< eax = -1 (error) / 0                                                                           ;;
  628. ;;================================================================================================;;
  629. locals
  630.   buf rb 16
  631. endl
  632.  
  633.         push    ecx edx edi
  634.  
  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
  650.  
  651.         lea     eax, [buf]
  652.         sub     edi, eax
  653.  
  654.         stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], eax, edi
  655.  
  656.         pop     edi edx ecx
  657.         ret
  658. endp
  659.  
  660.  
  661. ;;================================================================================================;;
  662. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  663. ;;================================================================================================;;
  664. ;! Imported functions section                                                                     ;;
  665. ;;================================================================================================;;
  666. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  667. ;;================================================================================================;;
  668.  
  669.  
  670. align 16
  671. @IMPORT:
  672.  
  673. library \
  674.         libio , 'libio.obj'
  675.  
  676. import  libio                       , \
  677.         file.size   , 'file_size'   , \
  678.         file.open   , 'file_open'   , \
  679.         file.read   , 'file_read'   , \
  680.         file.write  , 'file_write'  , \
  681.         file.seek   , 'file_seek'   , \
  682.         file.eof?   , 'file_iseof'  , \
  683.         file.seteof , 'file_seteof' , \
  684.         file.tell   , 'file_tell'   , \
  685.         file.close  , 'file_close'
  686.  
  687.  
  688. ;;================================================================================================;;
  689. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  690. ;;================================================================================================;;
  691. ;! Exported functions section                                                                     ;;
  692. ;;================================================================================================;;
  693. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  694. ;;================================================================================================;;
  695.  
  696.  
  697. align 16
  698. @EXPORT:
  699.  
  700. export                                            \
  701.         libini._.init     , 'lib_init'          , \
  702.         0x00080008        , 'version'           , \
  703.         ini.enum_sections , 'ini_enum_sections' , \
  704.         ini.enum_keys     , 'ini_enum_keys'     , \
  705.         ini.get_str       , 'ini_get_str'       , \
  706.         ini.get_int       , 'ini_get_int'       , \
  707.         ini.get_color     , 'ini_get_color'     , \
  708.         ini.set_str       , 'ini_set_str'       , \
  709.         ini.set_int       , 'ini_set_int'       , \
  710.         ini.set_color     , 'ini_set_color'
  711.