Subversion Repositories Kolibri OS

Rev

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

  1. ;;================================================================================================;;
  2. ;;//// libini.asm //// (c) mike.dld, 2006-2008 ///////////////////////////////////////////////////;;
  3. ;;================================================================================================;;
  4. ;;                                                                                                ;;
  5. ;; This file is part of Common development libraries (Libs-Dev).                                  ;;
  6. ;;                                                                                                ;;
  7. ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
  8. ;; General Public License as published by the Free Software Foundation, either version 3 of the   ;;
  9. ;; License, or (at your option) any later version.                                                ;;
  10. ;;                                                                                                ;;
  11. ;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
  12. ;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
  13. ;; General Public License for more details.                                                       ;;
  14. ;;                                                                                                ;;
  15. ;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;;
  16. ;; see <http://www.gnu.org/licenses/>.                                                            ;;
  17. ;;                                                                                                ;;
  18. ;;================================================================================================;;
  19. ;;                                                                                                ;;
  20. ;; 2008-02-07 (mike.dld)                                                                          ;;
  21. ;;   changes:                                                                                     ;;
  22. ;;     - renamed all *.aux.* to *._.* to match overall libraries design                           ;;
  23. ;; 2007-09-26 (mike.dld)                                                                          ;;
  24. ;;   bug-fixes:                                                                                   ;;
  25. ;;     - value was not correctly trimmed (reported by diamond)                                    ;;
  26. ;; 2007-08-01 (mike.dld)                                                                          ;;
  27. ;;   bug-fixes:                                                                                   ;;
  28. ;;     - serious defect in ini.set_str causing displaced write operations                         ;;
  29. ;;       (reported by diamond)                                                                    ;;
  30. ;;     - another serious defect in ini.enum_keys introduced with refactoring                      ;;
  31. ;;   changes:                                                                                     ;;
  32. ;;     - callback for enum_keys now takes additional parameter - key value                        ;;
  33. ;;     - handling trailing spaces in section/key/value                                            ;;
  34. ;; 2007-05-19 (mike.dld)                                                                          ;;
  35. ;;   bug-fixes:                                                                                   ;;
  36. ;;     - last char still wasn't read correctly                                                    ;;
  37. ;;     - digits of number were reversed when using ini.set_int                                    ;;
  38. ;;     - now using 'ini.aux.unget_char' instead of dangerous 'dec esi'                            ;;
  39. ;;   changes:                                                                                     ;;
  40. ;;     - all non-public functions now start with ini.aux.*                                        ;;
  41. ;;     - added ini.enum_sections and ini.enum_keys                                                ;;
  42. ;;     - removed ini.query_sec (use ini.enum_* instead)                                           ;;
  43. ;;                                                                                                ;;
  44. ;;================================================================================================;;
  45.  
  46. format MS COFF
  47.  
  48. public @EXPORT as 'EXPORTS'
  49.  
  50. include '../../../../proc32.inc'
  51. include '../../../../macros.inc'
  52. include '../libio/libio.inc'
  53. purge section ; mov,add,sub
  54.  
  55. section '.flat' code readable align 16
  56.  
  57. include 'libini_p.inc'
  58.  
  59. mem.alloc   dd ?
  60. mem.free    dd ?
  61. mem.realloc dd ?
  62. dll.load    dd ?
  63.  
  64. ;;================================================================================================;;
  65. proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
  66. ;;------------------------------------------------------------------------------------------------;;
  67. ;? Library entry point (called after library load)                                                ;;
  68. ;;------------------------------------------------------------------------------------------------;;
  69. ;> eax = pointer to memory allocation routine                                                     ;;
  70. ;> ebx = pointer to memory freeing routine                                                        ;;
  71. ;> ecx = pointer to memory reallocation routine                                                   ;;
  72. ;> edx = pointer to library loading routine                                                       ;;
  73. ;;------------------------------------------------------------------------------------------------;;
  74. ;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
  75. ;;================================================================================================;;
  76.         mov     [mem.alloc], eax
  77.         mov     [mem.free], ebx
  78.         mov     [mem.realloc], ecx
  79.         mov     [dll.load], edx
  80.  
  81.         invoke  dll.load, @IMPORT
  82.         or      eax, eax
  83.         jz      .ok
  84.  
  85.         xor     eax, eax
  86.         inc     eax
  87.         ret
  88.  
  89.   .ok:  xor     eax,eax
  90.         ret
  91. endp
  92.  
  93. ;;================================================================================================;;
  94. proc ini._.unget_char _f ;////////////////////////////////////////////////////////////////////////;;
  95. ;;------------------------------------------------------------------------------------------------;;
  96. ;? --- TBD ---                                                                                    ;;
  97. ;;------------------------------------------------------------------------------------------------;;
  98. ;> --- TBD ---                                                                                    ;;
  99. ;;------------------------------------------------------------------------------------------------;;
  100. ;< --- TBD ---                                                                                    ;;
  101. ;;================================================================================================;;
  102.         ;push    ecx
  103.         ;mov     ecx,[f]
  104.         ;inc     [ecx+INIFILE.cnt]
  105.         ;dec     esi
  106.         ;pop     ecx
  107.         ;ret
  108.         push    eax ecx
  109.         mov     ecx, [_f]
  110.         inc     [ecx + IniFile.cnt]
  111.         dec     esi
  112.         mov     eax, [ecx + IniFile.bsize]
  113.         cmp     [ecx + IniFile.cnt], eax
  114.         jle     @f
  115.         stdcall ini._.unload_block, [_f]
  116.     @@: ;mov     al,[esi-1]
  117.         pop     ecx eax
  118.         ret
  119. endp
  120.  
  121. ;;================================================================================================;;
  122. proc ini._.get_char _f ;//////////////////////////////////////////////////////////////////////////;;
  123. ;;------------------------------------------------------------------------------------------------;;
  124. ;? --- TBD ---                                                                                    ;;
  125. ;;------------------------------------------------------------------------------------------------;;
  126. ;> --- TBD ---                                                                                    ;;
  127. ;;------------------------------------------------------------------------------------------------;;
  128. ;< --- TBD ---                                                                                    ;;
  129. ;;================================================================================================;;
  130.         mov     ecx, [_f]
  131.         dec     [ecx + IniFile.cnt]
  132.         jns     @f
  133.         stdcall ini._.preload_block, [_f]
  134.         dec     [ecx + IniFile.cnt]
  135.     @@: lodsb
  136.         ret
  137. endp
  138.  
  139. ;;================================================================================================;;
  140. proc ini._.skip_nonblanks _f ;////////////////////////////////////////////////////////////////////;;
  141. ;;------------------------------------------------------------------------------------------------;;
  142. ;? --- TBD ---                                                                                    ;;
  143. ;;------------------------------------------------------------------------------------------------;;
  144. ;> --- TBD ---                                                                                    ;;
  145. ;;------------------------------------------------------------------------------------------------;;
  146. ;< --- TBD ---                                                                                    ;;
  147. ;;================================================================================================;;
  148.         mov     ecx, [_f]
  149.     @@: stdcall ini._.get_char, [_f]
  150.         cmp     al, 32
  151.         je      @b
  152.         cmp     al, 13
  153.         je      @b
  154.         cmp     al, 10
  155.         je      @b
  156.         cmp     al, 9
  157.         je      @b
  158.     @@: stdcall ini._.unget_char, [_f]
  159.         ;inc     [ecx+INIFILE.cnt]
  160.         ret
  161. endp
  162.  
  163. ;;================================================================================================;;
  164. proc ini._.skip_spaces _f ;///////////////////////////////////////////////////////////////////////;;
  165. ;;------------------------------------------------------------------------------------------------;;
  166. ;? --- TBD ---                                                                                    ;;
  167. ;;------------------------------------------------------------------------------------------------;;
  168. ;> --- TBD ---                                                                                    ;;
  169. ;;------------------------------------------------------------------------------------------------;;
  170. ;< --- TBD ---                                                                                    ;;
  171. ;;================================================================================================;;
  172.         mov     ecx, [_f]
  173.     @@: stdcall ini._.get_char, [_f]
  174.         cmp     al, 32
  175.         je      @b
  176.         cmp     al, 9
  177.         je      @b
  178.     @@: stdcall ini._.unget_char, [_f]
  179.         ;inc     [ecx+INIFILE.cnt]
  180.         ret
  181. endp
  182.  
  183. ;;================================================================================================;;
  184. proc ini._.skip_line _f ;/////////////////////////////////////////////////////////////////////////;;
  185. ;;------------------------------------------------------------------------------------------------;;
  186. ;? --- TBD ---                                                                                    ;;
  187. ;;------------------------------------------------------------------------------------------------;;
  188. ;> --- TBD ---                                                                                    ;;
  189. ;;------------------------------------------------------------------------------------------------;;
  190. ;< --- TBD ---                                                                                    ;;
  191. ;;================================================================================================;;
  192.         mov     ecx, [_f]
  193.     @@: stdcall ini._.get_char, [_f]
  194.         or      al, al
  195.         jz      @f
  196.         cmp     al, 13
  197.         je      @f
  198.         cmp     al, 10
  199.         jne     @b
  200.     @@: stdcall ini._.unget_char, [_f]
  201.         ;inc     [ecx+INIFILE.cnt]
  202.         ret
  203. endp
  204.  
  205. ;;================================================================================================;;
  206. proc ini._.unload_block _f ;//////////////////////////////////////////////////////////////////////;;
  207. ;;------------------------------------------------------------------------------------------------;;
  208. ;? --- TBD ---                                                                                    ;;
  209. ;;------------------------------------------------------------------------------------------------;;
  210. ;> --- TBD ---                                                                                    ;;
  211. ;;------------------------------------------------------------------------------------------------;;
  212. ;< --- TBD ---                                                                                    ;;
  213. ;;================================================================================================;;
  214.         push    eax ebx ecx
  215.         mov     ebx, [_f]
  216.         mov     eax, [ebx + IniFile.pos]
  217.         add     eax, -ini.BLOCK_SIZE
  218.         invoke  file.seek, [ebx + IniFile.fh], SEEK_SET, eax
  219.         stdcall ini._.preload_block, ebx
  220.         add     esi, eax ; ini.BLOCK_SIZE
  221.         mov     [ebx + IniFile.cnt], 0
  222.         pop     ecx ebx eax
  223.         ret
  224. endp
  225.  
  226. ;;================================================================================================;;
  227. proc ini._.preload_block _f ;/////////////////////////////////////////////////////////////////////;;
  228. ;;------------------------------------------------------------------------------------------------;;
  229. ;? --- TBD ---                                                                                    ;;
  230. ;;------------------------------------------------------------------------------------------------;;
  231. ;> --- TBD ---                                                                                    ;;
  232. ;;------------------------------------------------------------------------------------------------;;
  233. ;< --- TBD ---                                                                                    ;;
  234. ;;================================================================================================;;
  235.         push    eax ebx ecx
  236.         mov     ebx, [_f]
  237.     @@: mov     esi, [ebx + IniFile.buf]
  238.         push    edi
  239.         mov     edi, esi
  240.         mov     ecx, ini.BLOCK_SIZE / 4
  241.         xor     eax, eax
  242.         rep     stosd
  243.         pop     edi
  244.         invoke  file.tell, [ebx + IniFile.fh]
  245.         mov     [ebx + IniFile.pos], eax
  246.         invoke  file.read, [ebx + IniFile.fh], esi, ini.BLOCK_SIZE
  247.         mov     esi,[ebx + IniFile.buf]
  248.         cmp     eax,ini.BLOCK_SIZE
  249.         jl      @f
  250.         ;dec     eax
  251.     @@: mov     [ebx + IniFile.cnt], eax;ini.BLOCK_SIZE-1
  252.         mov     [ebx + IniFile.bsize], eax
  253.         pop     ecx ebx eax
  254.         ret
  255. endp
  256.  
  257. ;;================================================================================================;;
  258. proc ini._.reload_block _f ;//////////////////////////////////////////////////////////////////////;;
  259. ;;------------------------------------------------------------------------------------------------;;
  260. ;? --- TBD ---                                                                                    ;;
  261. ;;------------------------------------------------------------------------------------------------;;
  262. ;> --- TBD ---                                                                                    ;;
  263. ;;------------------------------------------------------------------------------------------------;;
  264. ;< --- TBD ---                                                                                    ;;
  265. ;;================================================================================================;;
  266.         push    eax ebx ecx
  267.         mov     ebx, [_f]
  268.         push    [ebx + IniFile.bsize]
  269.         push    esi [ebx + IniFile.cnt]
  270.         invoke  file.seek, [ebx + IniFile.fh], SEEK_SET, [ebx + IniFile.pos]
  271.         stdcall ini._.preload_block, ebx
  272.         pop     [ebx + IniFile.cnt] esi
  273.         pop     eax
  274.         sub     eax,[ebx + IniFile.bsize]
  275.         sub     [ebx + IniFile.cnt], eax
  276.         pop     ecx ebx eax
  277.         ret
  278. endp
  279.  
  280. ; f_info - contains current file block number
  281. ; esi    - position in block from where to shift
  282. ; ecx    - number of bytes to shift by
  283.  
  284. ;;================================================================================================;;
  285. proc ini._.shift_content _f, _delta ;/////////////////////////////////////////////////////////////;;
  286. ;;------------------------------------------------------------------------------------------------;;
  287. ;? Shift file content starting from cursor position (~ delete)                                    ;;
  288. ;? Content is copied by 'delta' bytes up/down                                                     ;;
  289. ;;------------------------------------------------------------------------------------------------;;
  290. ;> --- TBD ---                                                                                    ;;
  291. ;;------------------------------------------------------------------------------------------------;;
  292. ;< eax = 0 (ok) / -1 (fail)                                                                       ;;
  293. ;;================================================================================================;;
  294. locals
  295.   buf dd ?
  296. endl
  297.  
  298.         xor     eax, eax
  299.         cmp     [_delta], 0
  300.         je      .skip
  301.  
  302.         push    ebx ecx
  303.         invoke  mem.alloc, ini.BLOCK_SIZE
  304.         or      eax, eax
  305.         jz      .fail
  306.         mov     [buf], eax
  307.  
  308.         cmp     [_delta], 0
  309.         jl      .down
  310.  
  311.         mov     ebx, [_f]
  312.         mov     ecx, [ebx + IniFile.cnt]
  313.         mov     ebx, [ebx + IniFile.fh]
  314.         invoke  file.tell, ebx
  315. ;       push    eax
  316.         sub     eax, ecx
  317. ;       dec     eax
  318.         invoke  file.seek, ebx, SEEK_SET, eax
  319.     @@: invoke  file.seek, ebx, SEEK_CUR, [_delta]
  320.         invoke  file.eof?, ebx
  321.         or      eax, eax
  322.         jnz     .done
  323.         invoke  file.read, ebx, [buf], ini.BLOCK_SIZE
  324.         mov     ecx, eax
  325.         mov     eax, [_delta]
  326.         neg     eax
  327.         sub     eax,ecx;ini.BLOCK_SIZE
  328.         invoke  file.seek,ebx,SEEK_CUR,eax
  329.         invoke  file.write,ebx,[buf],ecx;ini.BLOCK_SIZE
  330.         jmp     @b
  331.   .done:
  332.         mov     eax, [_delta]
  333.         neg     eax
  334.         invoke  file.seek, ebx, SEEK_CUR, eax
  335.         invoke  file.seteof, ebx
  336. ;       pop     eax
  337. ;       invoke  file.seek, ebx, SEEK_SET;, eax
  338.         stdcall ini._.reload_block, [_f]
  339.         invoke  mem.free, [buf]
  340.         pop     ecx ebx
  341.   .skip:
  342.         ret
  343.   .fail:
  344.         or      eax, -1
  345.         pop     ecx ebx
  346.         ret
  347.  
  348.   .down:
  349.         neg     [_delta]
  350.  
  351.         mov     ebx, [_f]
  352.         mov     ecx, [ebx + IniFile.cnt]
  353.         mov     ebx, [ebx + IniFile.fh]
  354.         invoke  file.tell, ebx
  355. ;       push    eax
  356.         sub     eax, ecx
  357.         lea     edx, [eax - 1]
  358.         push    edx
  359.     @@: invoke  file.seek, ebx, SEEK_SET, edx
  360.         invoke  file.eof?, ebx
  361.         or      eax, eax
  362.         jnz     @f
  363.         add     edx, ini.BLOCK_SIZE
  364.         jmp     @b
  365.     @@: cmp     edx, [esp]
  366.         je      .skip.2
  367.         add     edx, -ini.BLOCK_SIZE
  368.         cmp     edx, [esp]
  369.         jl      @f
  370.         invoke  file.seek, ebx, SEEK_SET, edx
  371.         invoke  file.read, ebx, [buf], ini.BLOCK_SIZE
  372.         mov     ecx, eax
  373.         mov     eax, [_delta]
  374.         sub     eax, ecx
  375.         invoke  file.seek, ebx, SEEK_CUR, eax
  376.         invoke  file.write, ebx, [buf], ecx
  377.         jmp     @b
  378.     @@:
  379.   .skip.2:
  380.         add     esp, 4
  381. ;       mov     eax,[delta]
  382. ;       neg     eax
  383. ;       invoke  file.seek,ebx,SEEK_CUR,eax
  384. ;       pop     eax
  385. ;       invoke  file.seek,ebx,SEEK_SET;,eax
  386.         stdcall ini._.reload_block, [_f]
  387.         invoke  mem.free, [buf]
  388.         pop     ecx ebx
  389.         ret
  390. endp
  391.  
  392. ;;================================================================================================;;
  393. proc ini._.get_value_length _f ;//////////////////////////////////////////////////////////////////;;
  394. ;;------------------------------------------------------------------------------------------------;;
  395. ;? --- TBD ---                                                                                    ;;
  396. ;;------------------------------------------------------------------------------------------------;;
  397. ;> --- TBD ---                                                                                    ;;
  398. ;;------------------------------------------------------------------------------------------------;;
  399. ;< --- TBD ---                                                                                    ;;
  400. ;;================================================================================================;;
  401.         push    ebx ecx edx eax
  402.         mov     ebx, [_f]
  403.         invoke  file.tell, [ebx + IniFile.fh]
  404.         push    esi [ebx + IniFile.cnt] [ebx + IniFile.pos]
  405.         sub     eax, [ebx + IniFile.cnt]
  406.         mov     edx, eax
  407.  
  408.         stdcall ini._.skip_line, [_f]
  409.         invoke  file.tell, [ebx + IniFile.fh]
  410.         sub     eax, [ebx + IniFile.cnt]
  411.         sub     eax, edx
  412.         mov     [esp + 4 * 3], eax
  413.  
  414. ;       pop     eax
  415.         invoke  file.seek, [ebx + IniFile.fh], SEEK_SET;, eax
  416.         stdcall ini._.preload_block, [_f]
  417.         pop     [ebx + IniFile.cnt] esi
  418.         pop     eax edx ecx ebx
  419.         ret
  420. endp
  421.  
  422. ;;================================================================================================;;
  423. proc ini._.string_copy ;//////////////////////////////////////////////////////////////////////////;;
  424. ;;------------------------------------------------------------------------------------------------;;
  425. ;? --- TBD ---                                                                                    ;;
  426. ;;------------------------------------------------------------------------------------------------;;
  427. ;> --- TBD ---                                                                                    ;;
  428. ;;------------------------------------------------------------------------------------------------;;
  429. ;< --- TBD ---                                                                                    ;;
  430. ;;================================================================================================;;
  431.     @@: lodsb
  432.         or      al, al
  433.         jz      @f
  434.         stosb
  435.         jmp     @b
  436.     @@: ret
  437. endp
  438.  
  439. ;;================================================================================================;;
  440. proc ini._.find_next_section _f ;/////////////////////////////////////////////////////////////////;;
  441. ;;------------------------------------------------------------------------------------------------;;
  442. ;? --- TBD ---                                                                                    ;;
  443. ;;------------------------------------------------------------------------------------------------;;
  444. ;> --- TBD ---                                                                                    ;;
  445. ;;------------------------------------------------------------------------------------------------;;
  446. ;< --- TBD ---                                                                                    ;;
  447. ;;================================================================================================;;
  448.         push    ebx edi
  449.  
  450.     @@: stdcall ini._.skip_nonblanks, [_f]
  451.         cmp     al, '['
  452.         je      @f
  453.         or      al, al
  454.         jz      .exit_error
  455.         stdcall ini._.skip_line, [_f]
  456.         or      al, al
  457.         jz      .exit_error
  458.         jmp     @b
  459.     @@:
  460.         pop     edi ebx
  461.         xor     eax, eax
  462.         ret
  463.  
  464.   .exit_error:
  465.         pop     edi ebx
  466.         or      eax, -1
  467.         ret
  468. endp
  469.  
  470. ;;================================================================================================;;
  471. proc ini._.find_section _f, _sec_name ;///////////////////////////////////////////////////////////;;
  472. ;;------------------------------------------------------------------------------------------------;;
  473. ;? Find section in file                                                                           ;;
  474. ;? Search is performed from the beginning of file                                                 ;;
  475. ;;------------------------------------------------------------------------------------------------;;
  476. ;> --- TBD ---                                                                                    ;;
  477. ;;------------------------------------------------------------------------------------------------;;
  478. ;< eax = 0 (ok) / -1 (fail)                                                                       ;;
  479. ;< [f.pos] = new cursor position (right after ']' char if eax = 0, at the end of file otherwise)  ;;
  480. ;;================================================================================================;;
  481.         push    ebx edi
  482.  
  483.         mov     ecx, [_f]
  484.         invoke  file.seek, [ecx + IniFile.fh], SEEK_SET, 0
  485.         stdcall ini._.preload_block, [_f]
  486.  
  487.   .next_section:
  488.         stdcall ini._.find_next_section, [_f]
  489.         or      eax, eax
  490.         jnz     .exit_error
  491.  
  492.         stdcall ini._.get_char, [_f]
  493. ;       inc     esi
  494. ;       dec     [ecx + IniFile.cnt]
  495.         stdcall ini._.skip_spaces, [_f]
  496.         mov     edi, [_sec_name]
  497.     @@: stdcall ini._.get_char, [_f]
  498.         cmp     al, ']'
  499.         je      @f
  500.         or      al, al
  501.         jz      .exit_error
  502.         cmp     al, 13
  503.         je      .next_section
  504.         cmp     al, 10
  505.         je      .next_section
  506.         scasb
  507.         je      @b
  508.         cmp     byte[edi - 1], 0
  509.         jne     .next_section
  510.         dec     edi
  511.         stdcall ini._.unget_char, [_f]
  512.         stdcall ini._.skip_spaces, [_f]
  513.         stdcall ini._.get_char, [_f]
  514.         cmp     al, ']'
  515.         jne     .next_section
  516.     @@:
  517.         cmp     byte[edi], 0
  518.         jne     .next_section
  519.         pop     edi ebx
  520.         xor     eax, eax
  521.         ret
  522.  
  523.   .exit_error:
  524.         pop     edi ebx
  525.         or      eax, -1
  526.         ret
  527. endp
  528.  
  529. ;;================================================================================================;;
  530. proc ini._.find_key _f, _key_name ;///////////////////////////////////////////////////////////////;;
  531. ;;------------------------------------------------------------------------------------------------;;
  532. ;? Find key in section                                                                            ;;
  533. ;? Search is performed within current section starting from cursor position                       ;;
  534. ;;------------------------------------------------------------------------------------------------;;
  535. ;> --- TBD ---                                                                                    ;;
  536. ;;------------------------------------------------------------------------------------------------;;
  537. ;< eax = 0 (ok) / -1 (fail)                                                                       ;;
  538. ;< [f.pos] = new cursor position (right after '=' char if eax = 0, at the end of file or right    ;;
  539. ;<           before '[' char otherwise)                                                           ;;
  540. ;;================================================================================================;;
  541.         push    ebx edi
  542.  
  543.   .next_value:
  544.         mov     edi, [_key_name]
  545.         stdcall ini._.skip_line, [_f]
  546.         stdcall ini._.skip_nonblanks, [_f]
  547.         or      al, al
  548.         jz      .exit_error
  549.         cmp     al, '['
  550.         je      .exit_error
  551.     @@: stdcall ini._.get_char, [_f]
  552.         or      al, al
  553.         jz      .exit_error
  554.         cmp     al, '='
  555.         je      @f
  556.         scasb
  557.         je      @b
  558.         cmp     byte[edi - 1], 0
  559.         jne     .next_value
  560.         dec     edi
  561.         stdcall ini._.unget_char, [_f]
  562.         stdcall ini._.skip_spaces, [_f]
  563.         stdcall ini._.get_char, [_f]
  564.         cmp     al, '='
  565.         je      @f
  566.         jmp     .next_value
  567.     @@:
  568.         cmp     byte[edi], 0
  569.         jne     .next_value
  570.  
  571.         pop     edi ebx
  572.         xor     eax, eax
  573.         ret
  574.  
  575.   .exit_error:
  576.         pop     edi ebx
  577.         or      eax, -1
  578.         ret
  579. endp
  580.  
  581. ;;================================================================================================;;
  582. proc ini._.low.read_value _f_addr, _buffer, _buf_len ;////////////////////////////////////////////;;
  583. ;;------------------------------------------------------------------------------------------------;;
  584. ;? --- TBD ---                                                                                    ;;
  585. ;;------------------------------------------------------------------------------------------------;;
  586. ;> --- TBD ---                                                                                    ;;
  587. ;;------------------------------------------------------------------------------------------------;;
  588. ;< --- TBD ---                                                                                    ;;
  589. ;;================================================================================================;;
  590.         push    edi eax
  591.         mov     edi, [_buffer]
  592.         stdcall ini._.skip_spaces, [_f_addr]
  593.     @@: dec     [_buf_len]
  594.         jz      @f
  595.         stdcall ini._.get_char, [_f_addr]
  596.         cmp     al, 13
  597.         je      @f
  598.         cmp     al, 10
  599.         je      @f
  600.         stosb
  601.         or      al, al
  602.         jnz     @b
  603.     @@: stdcall ini._.unget_char, [_f_addr]
  604.         mov     byte[edi], 0
  605.         dec     edi
  606.     @@: cmp     byte[edi], 32
  607.         ja      @f
  608.         mov     byte[edi], 0
  609.         dec     edi
  610.         cmp     edi, [_buffer]
  611.         jae     @b
  612.     @@: pop     eax edi
  613.         ret
  614. endp
  615.  
  616. ;;================================================================================================;;
  617. proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;;
  618. ;;------------------------------------------------------------------------------------------------;;
  619. ;? --- TBD ---                                                                                    ;;
  620. ;;------------------------------------------------------------------------------------------------;;
  621. ;> _callback = callback function address: func(f_name, sec_name)                                  ;;
  622. ;;------------------------------------------------------------------------------------------------;;
  623. ;< --- TBD ---                                                                                    ;;
  624. ;;================================================================================================;;
  625. locals
  626.   f       IniFile
  627.   f_addr  dd ?
  628.   sec_buf dd ?
  629. endl
  630.  
  631.         push    ebx esi edi
  632.  
  633.         cld
  634.  
  635.         invoke  mem.alloc, ini.MAX_NAME_LEN
  636.         or      eax, eax
  637.         jz      .exit_error.2
  638.         mov     [sec_buf], eax
  639.  
  640.         xor     eax, eax
  641.         mov     [f.fh], eax
  642.         mov     [f.buf], eax
  643.         invoke  file.open, [_f_name], O_READ
  644.         cmp     eax, 32
  645.         jb      .exit_error
  646.         mov     [f.fh], eax
  647.         invoke  mem.alloc, ini.MEM_SIZE
  648.         or      eax, eax
  649.         jz      .exit_error
  650.         mov     [f.buf], eax
  651.         lea     ebx, [f]
  652.         mov     [f_addr], ebx
  653.  
  654.         invoke  file.seek, [f.fh], SEEK_SET, 0
  655.         stdcall ini._.preload_block, [f_addr]
  656.  
  657.   .next_section:
  658.         stdcall ini._.find_next_section, [f_addr]
  659.         or      eax, eax
  660.         jnz     .exit_error
  661.  
  662.         stdcall ini._.get_char, [f_addr]
  663.         stdcall ini._.skip_spaces, [f_addr]
  664. ;       inc     esi
  665. ;       dec     [f.cnt]
  666.         mov     edi, [sec_buf]
  667.     @@: stdcall ini._.get_char, [f_addr]
  668.         cmp     al, ']'
  669.         je      @f
  670.         or      al, al
  671.         jz      .exit_ok
  672.         cmp     al, 13
  673.         je      .next_section
  674.         cmp     al, 10
  675.         je      .next_section
  676.         stosb
  677.         jmp     @b
  678.     @@: xor     al, al
  679.         stosb
  680.         add     edi, -2
  681.     @@: cmp     byte[edi], 32
  682.         ja      @f
  683.         mov     byte[edi], 0
  684.         dec     edi
  685.         jmp     @b
  686.     @@:
  687.         pushad
  688.         mov     eax, [f_addr]
  689.         stdcall [_callback], [_f_name], [sec_buf]
  690.         or      eax, eax
  691.         popad
  692.         jnz     .next_section
  693.  
  694.   .exit_ok:
  695.         invoke  file.close, [f.fh]
  696.         invoke  mem.free, [f.buf]
  697.         invoke  mem.free, [sec_buf]
  698.         xor     eax, eax
  699.         pop     edi esi ebx
  700.         ret
  701.  
  702.   .exit_error:
  703.         invoke  file.close, [f.fh]
  704.         invoke  mem.free, [f.buf]
  705.         invoke  mem.free, [sec_buf]
  706.   .exit_error.2:
  707.         or      eax, -1
  708.         pop     edi esi ebx
  709.         ret
  710. endp
  711.  
  712. ;;================================================================================================;;
  713. proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;;
  714. ;;------------------------------------------------------------------------------------------------;;
  715. ;? --- TBD ---                                                                                    ;;
  716. ;;------------------------------------------------------------------------------------------------;;
  717. ;> _callback = callback function address: func(f_name, sec_name, key_name, key_value)             ;;
  718. ;;------------------------------------------------------------------------------------------------;;
  719. ;< --- TBD ---                                                                                    ;;
  720. ;;================================================================================================;;
  721. locals
  722.   f       IniFile
  723.   f_addr  dd ?
  724.   key_buf dd ?
  725.   val_buf dd ?
  726. endl
  727.  
  728.         push    ebx esi edi
  729.  
  730.         cld
  731.  
  732.         invoke  mem.alloc, ini.MAX_NAME_LEN
  733.         or      eax, eax
  734.         jz      .exit_error.3
  735.         mov     [key_buf], eax
  736.         invoke  mem.alloc, ini.MAX_VALUE_LEN
  737.         or      eax, eax
  738.         jz      .exit_error.2
  739.         mov     [val_buf], eax
  740.  
  741.         xor     eax, eax
  742.         mov     [f.fh], eax
  743.         mov     [f.buf], eax
  744.         invoke  file.open, [_f_name], O_READ
  745.         cmp     eax, 32
  746.         jb      .exit_error
  747.         mov     [f.fh], eax
  748.         invoke  mem.alloc, ini.MEM_SIZE
  749.         or      eax, eax
  750.         jz      .exit_error
  751.         mov     [f.buf], eax
  752.         lea     ebx, [f]
  753.         mov     [f_addr], ebx
  754.         stdcall ini._.find_section, ebx, [_sec_name]
  755.         or      eax, eax
  756.         jnz     .exit_error
  757.  
  758.   .next_key:
  759.         stdcall ini._.skip_line, [f_addr]
  760.         stdcall ini._.skip_nonblanks, [f_addr]
  761.         or      al, al
  762.         jz      .exit_error
  763.         cmp     al, '['
  764.         je      .exit_error
  765.         mov     edi, [key_buf]
  766.     @@: stdcall ini._.get_char, [f_addr]
  767.         or      al, al
  768.         jz      .exit_error
  769.         cmp     al, '='
  770.         je      @f
  771.         stosb
  772.         jmp     @b
  773.     @@:
  774.         xor     al, al
  775.         stosb
  776.         add     edi, -2
  777.     @@: cmp     byte[edi], 32
  778.         ja      @f
  779.         mov     byte[edi], 0
  780.         dec     edi
  781.         jmp     @b
  782.     @@: stdcall ini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN
  783.         pushad
  784.         stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf]
  785.         or      eax, eax
  786.         popad
  787.         jnz     .next_key
  788.  
  789.     @@: invoke  file.close, [f.fh]
  790.         invoke  mem.free, [f.buf]
  791.         xor     eax, eax
  792.         stosb
  793.         pop     edi esi ebx
  794.         ret
  795.  
  796.   .exit_error:
  797.         invoke  file.close, [f.fh]
  798.         invoke  mem.free, [f.buf]
  799.         invoke  mem.free, [val_buf]
  800.   .exit_error.2:
  801.         invoke  mem.free, [key_buf]
  802.   .exit_error.3:
  803.         or      eax, -1
  804.         pop     edi esi ebx
  805.         ret
  806. endp
  807.  
  808. ;;================================================================================================;;
  809. proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;;
  810. ;;------------------------------------------------------------------------------------------------;;
  811. ;? --- TBD ---                                                                                    ;;
  812. ;;------------------------------------------------------------------------------------------------;;
  813. ;> --- TBD ---                                                                                    ;;
  814. ;;------------------------------------------------------------------------------------------------;;
  815. ;< --- TBD ---                                                                                    ;;
  816. ;;================================================================================================;;
  817. locals
  818.   f      IniFile
  819.   f_addr dd ?
  820. endl
  821.  
  822.         push    ebx esi edi
  823.  
  824.         xor     eax, eax
  825.         mov     [f.fh], eax
  826.         mov     [f.buf], eax
  827.         invoke  file.open, [_f_name], O_READ
  828.         cmp     eax, 32
  829.         jb      .exit_error
  830.         mov     [f.fh], eax
  831.         invoke  mem.alloc, ini.MEM_SIZE
  832.         or      eax, eax
  833.         jz      .exit_error
  834.         mov     [f.buf], eax
  835.         lea     ebx, [f]
  836.         mov     [f_addr], ebx
  837.         stdcall ini._.find_section, ebx, [_sec_name]
  838.         or      eax, eax
  839.         jnz     .exit_error
  840.  
  841.         stdcall ini._.find_key, ebx, [_key_name]
  842.         or      eax, eax
  843.         jnz     .exit_error
  844.  
  845.         stdcall ini._.low.read_value, [f_addr], [_buffer], [_buf_len]
  846. ;       mov     edi, [_buffer]
  847. ;   @@: dec     [_buf_len]
  848. ;       jz      @f
  849. ;       stdcall ini.aux.get_char, [f_addr]
  850. ;       or      al, al
  851. ;       jz      @f
  852. ;       cmp     al, 13
  853. ;       je      @f
  854. ;       cmp     al, 10
  855. ;       je      @f
  856. ;       stosb
  857. ;       jmp     @b
  858.     @@: invoke  file.close, [f.fh]
  859.         invoke  mem.free, [f.buf]
  860.         xor     eax, eax
  861.         stosb
  862.         pop     edi esi ebx
  863.         ret
  864.  
  865.   .exit_error:
  866.         invoke  file.close, [f.fh]
  867.         invoke  mem.free, [f.buf]
  868.         mov     esi, [_def_val]
  869.         mov     edi, [_buffer]
  870.     @@: lodsb
  871.         stosb
  872.         or      al, al
  873.         jnz     @b
  874.         or      eax, -1
  875.         pop     edi esi ebx
  876.         ret
  877. endp
  878.  
  879. ;;================================================================================================;;
  880. proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;;
  881. ;;------------------------------------------------------------------------------------------------;;
  882. ;? --- TBD ---                                                                                    ;;
  883. ;;------------------------------------------------------------------------------------------------;;
  884. ;> --- TBD ---                                                                                    ;;
  885. ;;------------------------------------------------------------------------------------------------;;
  886. ;< --- TBD ---                                                                                    ;;
  887. ;;================================================================================================;;
  888. locals
  889.   f      IniFile
  890.   f_addr dd ?
  891. endl
  892.  
  893.         push    ebx esi edi
  894.  
  895.         xor     eax, eax
  896.         mov     [f.fh], eax
  897.         mov     [f.buf], eax
  898.         invoke  file.open, [_f_name], O_READ + O_WRITE + O_CREATE
  899.         cmp     eax, 32
  900.         jb      .exit_error
  901.         mov     [f.fh], eax
  902.         invoke  mem.alloc, ini.MEM_SIZE
  903.         or      eax, eax
  904.         jz      .exit_error
  905.         mov     [f.buf], eax
  906.         lea     ebx, [f]
  907.         mov     [f_addr], ebx
  908.  
  909.         stdcall ini._.find_section, ebx, [_sec_name]
  910.         or      eax, eax
  911.         jnz     .create_section
  912.  
  913.         stdcall ini._.find_key, ebx, [_key_name]
  914.         or      eax, eax
  915.         jnz     .create_key
  916.  
  917.   .modify_key:
  918.  
  919.         stdcall ini._.get_value_length, [f_addr]
  920.         sub     eax, [_buf_len]
  921.         stdcall ini._.shift_content, [f_addr], eax
  922.  
  923.   .modify_key.ex:
  924.         invoke  file.tell, [f.fh]
  925.         sub     eax, [f.cnt]
  926. ;       dec     eax
  927.         invoke  file.seek, [f.fh], SEEK_SET, eax
  928.         invoke  file.write, [f.fh], [_buffer], [_buf_len]
  929.  
  930.         pop     edi esi ebx
  931.         xor     eax, eax
  932.         ret
  933.  
  934.   .create_key:
  935.         mov     edi, [f.buf]
  936.         add     edi, ini.BLOCK_SIZE
  937.         push    edi
  938.  
  939.   .create_key.ex:
  940. ;       mov     word[edi], 0x0A0D
  941. ;       add     edi,2
  942.         mov     esi, [_key_name]
  943.         call    ini._.string_copy
  944.         mov     byte[edi], '='
  945.         inc     edi
  946.         mov     esi, [_buffer]
  947.         mov     ecx, [_buf_len]
  948.         rep     movsb
  949.         mov     word[edi], 0x0A0D
  950.         add     edi, 2
  951.         mov     eax, edi
  952.  
  953.         pop     edi
  954.         sub     eax, edi
  955.         mov     [_buffer], edi
  956.         mov     [_buf_len], eax
  957.         neg     eax
  958.         stdcall ini._.shift_content, [f_addr], eax
  959.  
  960.         jmp     .modify_key.ex
  961.  
  962.   .create_section:
  963.         mov     edi, [f.buf]
  964.         add     edi, ini.BLOCK_SIZE
  965.         push    edi
  966.  
  967.         mov     esi, [_sec_name]
  968. ;       mov     dword[edi], 0x0A0D + ('[' shl 16)
  969. ;       add     edi, 3
  970.         mov     byte[edi], '['
  971.         inc     edi
  972.         call    ini._.string_copy
  973. ;       mov     byte[edi], ']'
  974. ;       inc     edi
  975.         mov     dword[edi], ']' + (0x0A0D shl 8)
  976.         add     edi, 3
  977.  
  978.         jmp     .create_key.ex
  979.  
  980.   .exit_error:
  981.         pop     edi esi ebx
  982.         or      eax, -1
  983.         ret
  984. endp
  985.  
  986. ;;================================================================================================;;
  987. proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;;
  988. ;;------------------------------------------------------------------------------------------------;;
  989. ;? --- TBD ---                                                                                    ;;
  990. ;;------------------------------------------------------------------------------------------------;;
  991. ;> --- TBD ---                                                                                    ;;
  992. ;;------------------------------------------------------------------------------------------------;;
  993. ;< --- TBD ---                                                                                    ;;
  994. ;;================================================================================================;;
  995. locals
  996.   f      IniFile
  997.   f_addr dd ?
  998. endl
  999.  
  1000.         push    ebx esi edi
  1001.  
  1002.         xor     eax, eax
  1003.         mov     [f.fh], eax
  1004.         mov     [f.buf], eax
  1005.         invoke  file.open, [_f_name], O_READ
  1006.         cmp     eax, 32
  1007.         jb      .exit_error
  1008.         mov     [f.fh], eax
  1009.         invoke  mem.alloc, ini.MEM_SIZE
  1010.         or      eax, eax
  1011.         jz      .exit_error
  1012.         mov     [f.buf], eax
  1013.         lea     ebx, [f]
  1014.         mov     [f_addr], ebx
  1015.         stdcall ini._.find_section, ebx, [_sec_name]
  1016.         or      eax, eax
  1017.         jnz     .exit_error
  1018.  
  1019.         stdcall ini._.find_key, ebx, [_key_name]
  1020.         or      eax, eax
  1021.         jnz     .exit_error
  1022.  
  1023.         stdcall ini._.skip_nonblanks, [f_addr]
  1024.         xor     eax, eax
  1025.         xor     ebx, ebx
  1026.         xor     edx, edx
  1027.         stdcall ini._.get_char, [f_addr]
  1028.         cmp     al, '-'
  1029.         jne     .lp1
  1030.         inc     bh
  1031.     @@: stdcall ini._.get_char, [f_addr]
  1032.   .lp1: cmp     al, '0'
  1033.         jb      @f
  1034.         cmp     al, '9'
  1035.         ja      @f
  1036.         inc     bl
  1037.         add     eax, -'0'
  1038.         imul    edx, 10
  1039.         add     edx, eax
  1040.         jmp     @b
  1041.     @@:
  1042.         or      bl, bl
  1043.         jz      .exit_error
  1044.         or      bh, bh
  1045.         jz      @f
  1046.         neg     edx
  1047.     @@: invoke  file.close, [f.fh]
  1048.         invoke  mem.free, [f.buf]
  1049.         mov     eax, edx
  1050.         pop     edi esi ebx
  1051.         ret
  1052.  
  1053.   .exit_error:
  1054.         invoke  file.close, [f.fh]
  1055.         invoke  mem.free, [f.buf]
  1056.         mov     eax, [_def_val]
  1057.         pop     edi esi ebx
  1058.         ret
  1059. endp
  1060.  
  1061. ;;================================================================================================;;
  1062. proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;;
  1063. ;;------------------------------------------------------------------------------------------------;;
  1064. ;? --- TBD ---                                                                                    ;;
  1065. ;;------------------------------------------------------------------------------------------------;;
  1066. ;> --- TBD ---                                                                                    ;;
  1067. ;;------------------------------------------------------------------------------------------------;;
  1068. ;< --- TBD ---                                                                                    ;;
  1069. ;;================================================================================================;;
  1070. locals
  1071.   buf rb 16
  1072. endl
  1073.  
  1074.         push    ecx edx edi
  1075.  
  1076.         lea     edi, [buf]
  1077.         add     edi, 15
  1078.         mov     eax, [_val]
  1079.         or      eax, eax
  1080.         jns     @f
  1081.         mov     byte[edi], '-'
  1082.         neg     eax
  1083.         inc     edi
  1084.     @@: mov     ecx, 10
  1085.     @@: xor     edx, edx
  1086.         idiv    ecx
  1087.         add     dl, '0'
  1088.         mov     [edi], dl
  1089.         dec     edi
  1090.         or      eax, eax
  1091.         jnz     @b
  1092.         lea     eax, [buf]
  1093.         add     eax, 15
  1094.         sub     eax, edi
  1095.         inc     edi
  1096.  
  1097.         stdcall ini.set_str, [_f_name], [_sec_name], [_key_name], edi, eax
  1098.  
  1099.         pop     edi edx ecx
  1100.         ret
  1101. endp
  1102.  
  1103.  
  1104. ;;================================================================================================;;
  1105. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1106. ;;================================================================================================;;
  1107. ;! Imported functions section                                                                     ;;
  1108. ;;================================================================================================;;
  1109. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1110. ;;================================================================================================;;
  1111.  
  1112.  
  1113. align 16
  1114. @IMPORT:
  1115.  
  1116. library \
  1117.         libfile , 'libio.obj'
  1118.  
  1119. import  libfile                     , \
  1120.         file.size   , 'file.size'   , \ ; f_name
  1121.         file.open   , 'file.open'   , \ ; f_name  f_mode
  1122.         file.read   , 'file.read'   , \ ; f_descr buffer   buf_len
  1123.         file.write  , 'file.write'  , \ ; f_descr buffer   buf_len
  1124.         file.seek   , 'file.seek'   , \ ; f_descr f_origin f_where
  1125.         file.eof?   , 'file.eof?'   , \ ; f_descr
  1126.         file.seteof , 'file.seteof' , \ ; f_descr
  1127.         file.tell   , 'file.tell'   , \ ; f_descr
  1128.         file.close  , 'file.close'      ; f_descr
  1129.  
  1130.  
  1131. ;;================================================================================================;;
  1132. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1133. ;;================================================================================================;;
  1134. ;! Exported functions section                                                                     ;;
  1135. ;;================================================================================================;;
  1136. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1137. ;;================================================================================================;;
  1138.  
  1139.  
  1140. align 16
  1141. @EXPORT:
  1142.  
  1143. export                                            \
  1144.         lib_init          , 'lib_init'          , \
  1145.         0x00040005        , 'version'           , \
  1146.         ini.enum_sections , 'ini.enum_sections' , \
  1147.         ini.enum_keys     , 'ini.enum_keys'     , \
  1148.         ini.get_str       , 'ini.get_str'       , \
  1149.         ini.get_int       , 'ini.get_int'       , \
  1150.         ini.set_str       , 'ini.set_str'       , \
  1151.         ini.set_int       , 'ini.set_int'
  1152.