Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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