Subversion Repositories Kolibri OS

Rev

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

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