From 94aed463d5da584157e03885646f40b08a774ab2 Mon Sep 17 00:00:00 2001 From: "Mihail Semenyako (mike.dld)" Date: Wed, 6 Aug 2008 02:13:01 +0000 Subject: [PATCH] libs_dev: refactoring, comments git-svn-id: svn://kolibrios.org@845 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../libraries/libs-dev/libini/libini.asm | 697 +++--------------- .../libraries/libs-dev/libini/libini_p.asm | 575 +++++++++++++++ .../libraries/libs-dev/libio/libio.asm | 343 ++------- .../libraries/libs-dev/libio/libio_p.asm | 282 +++++++ 4 files changed, 987 insertions(+), 910 deletions(-) create mode 100644 programs/develop/libraries/libs-dev/libini/libini_p.asm create mode 100644 programs/develop/libraries/libs-dev/libio/libio_p.asm diff --git a/programs/develop/libraries/libs-dev/libini/libini.asm b/programs/develop/libraries/libs-dev/libini/libini.asm index 01fc91e4f6..5963debaf2 100644 --- a/programs/develop/libraries/libs-dev/libini/libini.asm +++ b/programs/develop/libraries/libs-dev/libini/libini.asm @@ -17,6 +17,9 @@ ;; ;; ;;================================================================================================;; ;; ;; +;; 2008-08-06 (mike.dld) ;; +;; changes: ;; +;; - split private procs into libini_p.asm, added comments ;; ;; 2008-02-07 (mike.dld) ;; ;; changes: ;; ;; - renamed all *.aux.* to *._.* to match overall libraries design ;; @@ -52,575 +55,23 @@ include '../../../../macros.inc' include '../libio/libio.inc' purge section ; mov,add,sub -section '.flat' code readable align 16 - include 'libini_p.inc' -mem.alloc dd ? -mem.free dd ? -mem.realloc dd ? -dll.load dd ? +section '.flat' code readable align 16 -;;================================================================================================;; -proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Library entry point (called after library load) ;; -;;------------------------------------------------------------------------------------------------;; -;> eax = pointer to memory allocation routine ;; -;> ebx = pointer to memory freeing routine ;; -;> ecx = pointer to memory reallocation routine ;; -;> edx = pointer to library loading routine ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 1 (fail) / 0 (ok) (library initialization result) ;; -;;================================================================================================;; - mov [mem.alloc], eax - mov [mem.free], ebx - mov [mem.realloc], ecx - mov [dll.load], edx - - invoke dll.load, @IMPORT - or eax, eax - jz .ok - - xor eax, eax - inc eax - ret - - .ok: xor eax,eax - ret -endp - -;;================================================================================================;; -proc ini._.unget_char _f ;////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - ;push ecx - ;mov ecx,[f] - ;inc [ecx+INIFILE.cnt] - ;dec esi - ;pop ecx - ;ret - push eax ecx - mov ecx, [_f] - inc [ecx + IniFile.cnt] - dec esi - mov eax, [ecx + IniFile.bsize] - cmp [ecx + IniFile.cnt], eax - jle @f - stdcall ini._.unload_block, [_f] - @@: ;mov al,[esi-1] - pop ecx eax - ret -endp - -;;================================================================================================;; -proc ini._.get_char _f ;//////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - mov ecx, [_f] - dec [ecx + IniFile.cnt] - jns @f - stdcall ini._.preload_block, [_f] - dec [ecx + IniFile.cnt] - @@: lodsb - ret -endp - -;;================================================================================================;; -proc ini._.skip_nonblanks _f ;////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - mov ecx, [_f] - @@: stdcall ini._.get_char, [_f] - cmp al, 32 - je @b - cmp al, 13 - je @b - cmp al, 10 - je @b - cmp al, 9 - je @b - @@: stdcall ini._.unget_char, [_f] - ;inc [ecx+INIFILE.cnt] - ret -endp - -;;================================================================================================;; -proc ini._.skip_spaces _f ;///////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - mov ecx, [_f] - @@: stdcall ini._.get_char, [_f] - cmp al, 32 - je @b - cmp al, 9 - je @b - @@: stdcall ini._.unget_char, [_f] - ;inc [ecx+INIFILE.cnt] - ret -endp - -;;================================================================================================;; -proc ini._.skip_line _f ;/////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - mov ecx, [_f] - @@: stdcall ini._.get_char, [_f] - or al, al - jz @f - cmp al, 13 - je @f - cmp al, 10 - jne @b - @@: stdcall ini._.unget_char, [_f] - ;inc [ecx+INIFILE.cnt] - ret -endp - -;;================================================================================================;; -proc ini._.unload_block _f ;//////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push eax ebx ecx - mov ebx, [_f] - mov eax, [ebx + IniFile.pos] - add eax, -ini.BLOCK_SIZE - invoke file.seek, [ebx + IniFile.fh], SEEK_SET, eax - stdcall ini._.preload_block, ebx - add esi, eax ; ini.BLOCK_SIZE - mov [ebx + IniFile.cnt], 0 - pop ecx ebx eax - ret -endp - -;;================================================================================================;; -proc ini._.preload_block _f ;/////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push eax ebx ecx - mov ebx, [_f] - @@: mov esi, [ebx + IniFile.buf] - push edi - mov edi, esi - mov ecx, ini.BLOCK_SIZE / 4 - xor eax, eax - rep stosd - pop edi - invoke file.tell, [ebx + IniFile.fh] - mov [ebx + IniFile.pos], eax - invoke file.read, [ebx + IniFile.fh], esi, ini.BLOCK_SIZE - mov esi,[ebx + IniFile.buf] - cmp eax,ini.BLOCK_SIZE - jl @f - ;dec eax - @@: mov [ebx + IniFile.cnt], eax;ini.BLOCK_SIZE-1 - mov [ebx + IniFile.bsize], eax - pop ecx ebx eax - ret -endp - -;;================================================================================================;; -proc ini._.reload_block _f ;//////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push eax ebx ecx - mov ebx, [_f] - push [ebx + IniFile.bsize] - push esi [ebx + IniFile.cnt] - invoke file.seek, [ebx + IniFile.fh], SEEK_SET, [ebx + IniFile.pos] - stdcall ini._.preload_block, ebx - pop [ebx + IniFile.cnt] esi - pop eax - sub eax,[ebx + IniFile.bsize] - sub [ebx + IniFile.cnt], eax - pop ecx ebx eax - ret -endp - -; f_info - contains current file block number -; esi - position in block from where to shift -; ecx - number of bytes to shift by - -;;================================================================================================;; -proc ini._.shift_content _f, _delta ;/////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Shift file content starting from cursor position (~ delete) ;; -;? Content is copied by 'delta' bytes up/down ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (ok) / -1 (fail) ;; -;;================================================================================================;; -locals - buf dd ? -endl - - xor eax, eax - cmp [_delta], 0 - je .skip - - push ebx ecx - invoke mem.alloc, ini.BLOCK_SIZE - or eax, eax - jz .fail - mov [buf], eax - - cmp [_delta], 0 - jl .down - - mov ebx, [_f] - mov ecx, [ebx + IniFile.cnt] - mov ebx, [ebx + IniFile.fh] - invoke file.tell, ebx -; push eax - sub eax, ecx -; dec eax - invoke file.seek, ebx, SEEK_SET, eax - @@: invoke file.seek, ebx, SEEK_CUR, [_delta] - invoke file.eof?, ebx - or eax, eax - jnz .done - invoke file.read, ebx, [buf], ini.BLOCK_SIZE - mov ecx, eax - mov eax, [_delta] - neg eax - sub eax,ecx;ini.BLOCK_SIZE - invoke file.seek,ebx,SEEK_CUR,eax - invoke file.write,ebx,[buf],ecx;ini.BLOCK_SIZE - jmp @b - .done: - mov eax, [_delta] - neg eax - invoke file.seek, ebx, SEEK_CUR, eax - invoke file.seteof, ebx -; pop eax -; invoke file.seek, ebx, SEEK_SET;, eax - stdcall ini._.reload_block, [_f] - invoke mem.free, [buf] - pop ecx ebx - .skip: - ret - .fail: - or eax, -1 - pop ecx ebx - ret - - .down: - neg [_delta] - - mov ebx, [_f] - mov ecx, [ebx + IniFile.cnt] - mov ebx, [ebx + IniFile.fh] - invoke file.tell, ebx -; push eax - sub eax, ecx - lea edx, [eax - 1] - push edx - @@: invoke file.seek, ebx, SEEK_SET, edx - invoke file.eof?, ebx - or eax, eax - jnz @f - add edx, ini.BLOCK_SIZE - jmp @b - @@: cmp edx, [esp] - je .skip.2 - add edx, -ini.BLOCK_SIZE - cmp edx, [esp] - jl @f - invoke file.seek, ebx, SEEK_SET, edx - invoke file.read, ebx, [buf], ini.BLOCK_SIZE - mov ecx, eax - mov eax, [_delta] - sub eax, ecx - invoke file.seek, ebx, SEEK_CUR, eax - invoke file.write, ebx, [buf], ecx - jmp @b - @@: - .skip.2: - add esp, 4 -; mov eax,[delta] -; neg eax -; invoke file.seek,ebx,SEEK_CUR,eax -; pop eax -; invoke file.seek,ebx,SEEK_SET;,eax - stdcall ini._.reload_block, [_f] - invoke mem.free, [buf] - pop ecx ebx - ret -endp - -;;================================================================================================;; -proc ini._.get_value_length _f ;//////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push ebx ecx edx eax - mov ebx, [_f] - invoke file.tell, [ebx + IniFile.fh] - push esi [ebx + IniFile.cnt] [ebx + IniFile.pos] - sub eax, [ebx + IniFile.cnt] - mov edx, eax - - stdcall ini._.skip_line, [_f] - invoke file.tell, [ebx + IniFile.fh] - sub eax, [ebx + IniFile.cnt] - sub eax, edx - mov [esp + 4 * 3], eax - -; pop eax - invoke file.seek, [ebx + IniFile.fh], SEEK_SET;, eax - stdcall ini._.preload_block, [_f] - pop [ebx + IniFile.cnt] esi - pop eax edx ecx ebx - ret -endp - -;;================================================================================================;; -proc ini._.string_copy ;//////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - @@: lodsb - or al, al - jz @f - stosb - jmp @b - @@: ret -endp - -;;================================================================================================;; -proc ini._.find_next_section _f ;/////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push ebx edi - - @@: stdcall ini._.skip_nonblanks, [_f] - cmp al, '[' - je @f - or al, al - jz .exit_error - stdcall ini._.skip_line, [_f] - or al, al - jz .exit_error - jmp @b - @@: - pop edi ebx - xor eax, eax - ret - - .exit_error: - pop edi ebx - or eax, -1 - ret -endp - -;;================================================================================================;; -proc ini._.find_section _f, _sec_name ;///////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Find section in file ;; -;? Search is performed from the beginning of file ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (ok) / -1 (fail) ;; -;< [f.pos] = new cursor position (right after ']' char if eax = 0, at the end of file otherwise) ;; -;;================================================================================================;; - push ebx edi - - mov ecx, [_f] - invoke file.seek, [ecx + IniFile.fh], SEEK_SET, 0 - stdcall ini._.preload_block, [_f] - - .next_section: - stdcall ini._.find_next_section, [_f] - or eax, eax - jnz .exit_error - - stdcall ini._.get_char, [_f] -; inc esi -; dec [ecx + IniFile.cnt] - stdcall ini._.skip_spaces, [_f] - mov edi, [_sec_name] - @@: stdcall ini._.get_char, [_f] - cmp al, ']' - je @f - or al, al - jz .exit_error - cmp al, 13 - je .next_section - cmp al, 10 - je .next_section - scasb - je @b - cmp byte[edi - 1], 0 - jne .next_section - dec edi - stdcall ini._.unget_char, [_f] - stdcall ini._.skip_spaces, [_f] - stdcall ini._.get_char, [_f] - cmp al, ']' - jne .next_section - @@: - cmp byte[edi], 0 - jne .next_section - pop edi ebx - xor eax, eax - ret - - .exit_error: - pop edi ebx - or eax, -1 - ret -endp - -;;================================================================================================;; -proc ini._.find_key _f, _key_name ;///////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Find key in section ;; -;? Search is performed within current section starting from cursor position ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (ok) / -1 (fail) ;; -;< [f.pos] = new cursor position (right after '=' char if eax = 0, at the end of file or right ;; -;< before '[' char otherwise) ;; -;;================================================================================================;; - push ebx edi - - .next_value: - mov edi, [_key_name] - stdcall ini._.skip_line, [_f] - stdcall ini._.skip_nonblanks, [_f] - or al, al - jz .exit_error - cmp al, '[' - je .exit_error - @@: stdcall ini._.get_char, [_f] - or al, al - jz .exit_error - cmp al, '=' - je @f - scasb - je @b - cmp byte[edi - 1], 0 - jne .next_value - dec edi - stdcall ini._.unget_char, [_f] - stdcall ini._.skip_spaces, [_f] - stdcall ini._.get_char, [_f] - cmp al, '=' - je @f - jmp .next_value - @@: - cmp byte[edi], 0 - jne .next_value - - pop edi ebx - xor eax, eax - ret - - .exit_error: - pop edi ebx - or eax, -1 - ret -endp - -;;================================================================================================;; -proc ini._.low.read_value _f_addr, _buffer, _buf_len ;////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; -;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; -;;================================================================================================;; - push edi eax - mov edi, [_buffer] - stdcall ini._.skip_spaces, [_f_addr] - @@: dec [_buf_len] - jz @f - stdcall ini._.get_char, [_f_addr] - cmp al, 13 - je @f - cmp al, 10 - je @f - stosb - or al, al - jnz @b - @@: stdcall ini._.unget_char, [_f_addr] - mov byte[edi], 0 - dec edi - @@: cmp byte[edi], 32 - ja @f - mov byte[edi], 0 - dec edi - cmp edi, [_buffer] - jae @b - @@: pop eax edi - ret -endp +include 'libini_p.asm' ;;================================================================================================;; proc ini.enum_sections _f_name, _callback ;///////////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Enumerate sections, calling callback function for each of them ;; ;;------------------------------------------------------------------------------------------------;; -;> _callback = callback function address: func(f_name, sec_name) ;; +;> _f_name = ini filename ;; +;> _callback = callback function address: func(f_name, sec_name), where ;; +;> f_name = ini filename (as passed to the function) ;; +;> sec_name = section name found ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = -1 (error) / 0 ;; ;;================================================================================================;; locals f IniFile @@ -652,19 +103,19 @@ endl mov [f_addr], ebx invoke file.seek, [f.fh], SEEK_SET, 0 - stdcall ini._.preload_block, [f_addr] + stdcall libini._.preload_block, [f_addr] .next_section: - stdcall ini._.find_next_section, [f_addr] + stdcall libini._.find_next_section, [f_addr] or eax, eax jnz .exit_error - stdcall ini._.get_char, [f_addr] - stdcall ini._.skip_spaces, [f_addr] + stdcall libini._.get_char, [f_addr] + stdcall libini._.skip_spaces, [f_addr] ; inc esi ; dec [f.cnt] mov edi, [sec_buf] - @@: stdcall ini._.get_char, [f_addr] + @@: stdcall libini._.get_char, [f_addr] cmp al, ']' je @f or al, al @@ -712,11 +163,17 @@ endp ;;================================================================================================;; proc ini.enum_keys _f_name, _sec_name, _callback ;////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Enumerate keys within a section, calling callback function for each of them ;; ;;------------------------------------------------------------------------------------------------;; -;> _callback = callback function address: func(f_name, sec_name, key_name, key_value) ;; +;> _f_name = ini filename ;; +;> _sec_name = section name ;; +;> _callback = callback function address: func(f_name, sec_name, key_name, key_value), where ;; +;> f_name = ini filename (as passed to the function) ;; +;> sec_name = section name (as passed to the function) ;; +;> key_name = key name found ;; +;> key_value = value of key found ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = -1 (error) / 0 ;; ;;================================================================================================;; locals f IniFile @@ -751,19 +208,19 @@ endl mov [f.buf], eax lea ebx, [f] mov [f_addr], ebx - stdcall ini._.find_section, ebx, [_sec_name] + stdcall libini._.find_section, ebx, [_sec_name] or eax, eax jnz .exit_error .next_key: - stdcall ini._.skip_line, [f_addr] - stdcall ini._.skip_nonblanks, [f_addr] + stdcall libini._.skip_line, [f_addr] + stdcall libini._.skip_nonblanks, [f_addr] or al, al jz .exit_error cmp al, '[' je .exit_error mov edi, [key_buf] - @@: stdcall ini._.get_char, [f_addr] + @@: stdcall libini._.get_char, [f_addr] or al, al jz .exit_error cmp al, '=' @@ -779,7 +236,7 @@ endl mov byte[edi], 0 dec edi jmp @b - @@: stdcall ini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN + @@: stdcall libini._.low.read_value, [f_addr], [val_buf], ini.MAX_VALUE_LEN pushad stdcall [_callback], [_f_name], [_sec_name], [key_buf], [val_buf] or eax, eax @@ -808,11 +265,17 @@ endp ;;================================================================================================;; proc ini.get_str _f_name, _sec_name, _key_name, _buffer, _buf_len, _def_val ;/////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Read string ;; ;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; +;> _f_name = ini filename ;; +;> _sec_name = section name ;; +;> _key_name = key name ;; +;> _buffer = destination buffer address ;; +;> _buf_len = buffer size (maximum bytes to read) ;; +;> _def_val = default value to return if no key, section or file found ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = -1 (error) / 0 ;; +;< [_buffer] = [_def_val] (error) / found key value ;; ;;================================================================================================;; locals f IniFile @@ -834,15 +297,15 @@ endl mov [f.buf], eax lea ebx, [f] mov [f_addr], ebx - stdcall ini._.find_section, ebx, [_sec_name] + stdcall libini._.find_section, ebx, [_sec_name] or eax, eax jnz .exit_error - stdcall ini._.find_key, ebx, [_key_name] + stdcall libini._.find_key, ebx, [_key_name] or eax, eax jnz .exit_error - stdcall ini._.low.read_value, [f_addr], [_buffer], [_buf_len] + stdcall libini._.low.read_value, [f_addr], [_buffer], [_buf_len] ; mov edi, [_buffer] ; @@: dec [_buf_len] ; jz @f @@ -879,11 +342,15 @@ endp ;;================================================================================================;; proc ini.set_str _f_name, _sec_name, _key_name, _buffer, _buf_len ;///////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Write string ;; ;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; +;> _f_name = ini filename ;; +;> _sec_name = section name ;; +;> _key_name = key name ;; +;> _buffer = source buffer address ;; +;> _buf_len = buffer size (bytes to write) ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = -1 (error) / 0 ;; ;;================================================================================================;; locals f IniFile @@ -906,19 +373,19 @@ endl lea ebx, [f] mov [f_addr], ebx - stdcall ini._.find_section, ebx, [_sec_name] + stdcall libini._.find_section, ebx, [_sec_name] or eax, eax jnz .create_section - stdcall ini._.find_key, ebx, [_key_name] + stdcall libini._.find_key, ebx, [_key_name] or eax, eax jnz .create_key .modify_key: - stdcall ini._.get_value_length, [f_addr] + stdcall libini._.get_value_length, [f_addr] sub eax, [_buf_len] - stdcall ini._.shift_content, [f_addr], eax + stdcall libini._.shift_content, [f_addr], eax .modify_key.ex: invoke file.tell, [f.fh] @@ -940,7 +407,7 @@ endl ; mov word[edi], 0x0A0D ; add edi,2 mov esi, [_key_name] - call ini._.string_copy + call libini._.string_copy mov byte[edi], '=' inc edi mov esi, [_buffer] @@ -955,7 +422,7 @@ endl mov [_buffer], edi mov [_buf_len], eax neg eax - stdcall ini._.shift_content, [f_addr], eax + stdcall libini._.shift_content, [f_addr], eax jmp .modify_key.ex @@ -969,7 +436,7 @@ endl ; add edi, 3 mov byte[edi], '[' inc edi - call ini._.string_copy + call libini._.string_copy ; mov byte[edi], ']' ; inc edi mov dword[edi], ']' + (0x0A0D shl 8) @@ -986,11 +453,14 @@ endp ;;================================================================================================;; proc ini.get_int _f_name, _sec_name, _key_name, _def_val ;////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Read integer ;; ;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; +;> _f_name = ini filename ;; +;> _sec_name = section name ;; +;> _key_name = key name ;; +;> _def_val = default value to return if no key, section or file found ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = [_def_val] (error) / found key value ;; ;;================================================================================================;; locals f IniFile @@ -1012,23 +482,23 @@ endl mov [f.buf], eax lea ebx, [f] mov [f_addr], ebx - stdcall ini._.find_section, ebx, [_sec_name] + stdcall libini._.find_section, ebx, [_sec_name] or eax, eax jnz .exit_error - stdcall ini._.find_key, ebx, [_key_name] + stdcall libini._.find_key, ebx, [_key_name] or eax, eax jnz .exit_error - stdcall ini._.skip_nonblanks, [f_addr] + stdcall libini._.skip_nonblanks, [f_addr] xor eax, eax xor ebx, ebx xor edx, edx - stdcall ini._.get_char, [f_addr] + stdcall libini._.get_char, [f_addr] cmp al, '-' jne .lp1 inc bh - @@: stdcall ini._.get_char, [f_addr] + @@: stdcall libini._.get_char, [f_addr] .lp1: cmp al, '0' jb @f cmp al, '9' @@ -1061,11 +531,14 @@ endp ;;================================================================================================;; proc ini.set_int _f_name, _sec_name, _key_name, _val ;////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; -;? --- TBD --- ;; +;? Write integer ;; ;;------------------------------------------------------------------------------------------------;; -;> --- TBD --- ;; +;> _f_name = ini filename ;; +;> _sec_name = section name ;; +;> _key_name = key name ;; +;> _val = value ;; ;;------------------------------------------------------------------------------------------------;; -;< --- TBD --- ;; +;< eax = -1 (error) / 0 ;; ;;================================================================================================;; locals buf rb 16 @@ -1114,18 +587,18 @@ align 16 @IMPORT: library \ - libfile , 'libio.obj' + libio , 'libio.obj' -import libfile , \ - file.size , 'file.size' , \ ; f_name - file.open , 'file.open' , \ ; f_name f_mode - file.read , 'file.read' , \ ; f_descr buffer buf_len - file.write , 'file.write' , \ ; f_descr buffer buf_len - file.seek , 'file.seek' , \ ; f_descr f_origin f_where - file.eof? , 'file.eof?' , \ ; f_descr - file.seteof , 'file.seteof' , \ ; f_descr - file.tell , 'file.tell' , \ ; f_descr - file.close , 'file.close' ; f_descr +import libio , \ + file.size , 'file.size' , \ + file.open , 'file.open' , \ + file.read , 'file.read' , \ + file.write , 'file.write' , \ + file.seek , 'file.seek' , \ + file.eof? , 'file.eof?' , \ + file.seteof , 'file.seteof' , \ + file.tell , 'file.tell' , \ + file.close , 'file.close' ;;================================================================================================;; @@ -1141,7 +614,7 @@ align 16 @EXPORT: export \ - lib_init , 'lib_init' , \ + libini._.init , 'lib_init' , \ 0x00040005 , 'version' , \ ini.enum_sections , 'ini.enum_sections' , \ ini.enum_keys , 'ini.enum_keys' , \ diff --git a/programs/develop/libraries/libs-dev/libini/libini_p.asm b/programs/develop/libraries/libs-dev/libini/libini_p.asm new file mode 100644 index 0000000000..19d295bd7b --- /dev/null +++ b/programs/develop/libraries/libs-dev/libini/libini_p.asm @@ -0,0 +1,575 @@ +;;================================================================================================;; +;;//// libini_p.asm //// (c) mike.dld, 2006-2008 /////////////////////////////////////////////////;; +;;================================================================================================;; +;; ;; +;; This file is part of Common development libraries (Libs-Dev). ;; +;; ;; +;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; +;; General Public License as published by the Free Software Foundation, either version 3 of the ;; +;; License, or (at your option) any later version. ;; +;; ;; +;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; +;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; +;; General Public License for more details. ;; +;; ;; +;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;; +;; see . ;; +;; ;; +;;================================================================================================;; + +mem.alloc dd ? +mem.free dd ? +mem.realloc dd ? +dll.load dd ? + +;;================================================================================================;; +proc libini._.init ;//////////////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Library entry point (called after library load) ;; +;;------------------------------------------------------------------------------------------------;; +;> eax = memory allocation routine ;; +;> ebx = memory freeing routine ;; +;> ecx = memory reallocation routine ;; +;> edx = library loading routine ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 1 (fail) / 0 (ok) (library initialization result) ;; +;;================================================================================================;; + mov [mem.alloc], eax + mov [mem.free], ebx + mov [mem.realloc], ecx + mov [dll.load], edx + + invoke dll.load, @IMPORT + or eax, eax + jz .ok + + xor eax, eax + inc eax + ret + + .ok: xor eax,eax + ret +endp + +;;================================================================================================;; +proc libini._.unget_char _f ;/////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + ;push ecx + ;mov ecx,[f] + ;inc [ecx+INIFILE.cnt] + ;dec esi + ;pop ecx + ;ret + push eax ecx + mov ecx, [_f] + inc [ecx + IniFile.cnt] + dec esi + mov eax, [ecx + IniFile.bsize] + cmp [ecx + IniFile.cnt], eax + jle @f + stdcall libini._.unload_block, [_f] + @@: ;mov al,[esi-1] + pop ecx eax + ret +endp + +;;================================================================================================;; +proc libini._.get_char _f ;///////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + mov ecx, [_f] + dec [ecx + IniFile.cnt] + jns @f + stdcall libini._.preload_block, [_f] + dec [ecx + IniFile.cnt] + @@: lodsb + ret +endp + +;;================================================================================================;; +proc libini._.skip_nonblanks _f ;/////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + mov ecx, [_f] + @@: stdcall libini._.get_char, [_f] + cmp al, 32 + je @b + cmp al, 13 + je @b + cmp al, 10 + je @b + cmp al, 9 + je @b + @@: stdcall libini._.unget_char, [_f] + ;inc [ecx+INIFILE.cnt] + ret +endp + +;;================================================================================================;; +proc libini._.skip_spaces _f ;////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + mov ecx, [_f] + @@: stdcall libini._.get_char, [_f] + cmp al, 32 + je @b + cmp al, 9 + je @b + @@: stdcall libini._.unget_char, [_f] + ;inc [ecx+INIFILE.cnt] + ret +endp + +;;================================================================================================;; +proc libini._.skip_line _f ;//////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + mov ecx, [_f] + @@: stdcall libini._.get_char, [_f] + or al, al + jz @f + cmp al, 13 + je @f + cmp al, 10 + jne @b + @@: stdcall libini._.unget_char, [_f] + ;inc [ecx+INIFILE.cnt] + ret +endp + +;;================================================================================================;; +proc libini._.unload_block _f ;///////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push eax ebx ecx + mov ebx, [_f] + mov eax, [ebx + IniFile.pos] + add eax, -ini.BLOCK_SIZE + invoke file.seek, [ebx + IniFile.fh], SEEK_SET, eax + stdcall libini._.preload_block, ebx + add esi, eax ; ini.BLOCK_SIZE + mov [ebx + IniFile.cnt], 0 + pop ecx ebx eax + ret +endp + +;;================================================================================================;; +proc libini._.preload_block _f ;//////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push eax ebx ecx + mov ebx, [_f] + @@: mov esi, [ebx + IniFile.buf] + push edi + mov edi, esi + mov ecx, ini.BLOCK_SIZE / 4 + xor eax, eax + rep stosd + pop edi + invoke file.tell, [ebx + IniFile.fh] + mov [ebx + IniFile.pos], eax + invoke file.read, [ebx + IniFile.fh], esi, ini.BLOCK_SIZE + mov esi,[ebx + IniFile.buf] + cmp eax,ini.BLOCK_SIZE + jl @f + ;dec eax + @@: mov [ebx + IniFile.cnt], eax;ini.BLOCK_SIZE-1 + mov [ebx + IniFile.bsize], eax + pop ecx ebx eax + ret +endp + +;;================================================================================================;; +proc libini._.reload_block _f ;///////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push eax ebx ecx + mov ebx, [_f] + push [ebx + IniFile.bsize] + push esi [ebx + IniFile.cnt] + invoke file.seek, [ebx + IniFile.fh], SEEK_SET, [ebx + IniFile.pos] + stdcall libini._.preload_block, ebx + pop [ebx + IniFile.cnt] esi + pop eax + sub eax,[ebx + IniFile.bsize] + sub [ebx + IniFile.cnt], eax + pop ecx ebx eax + ret +endp + +; f_info - contains current file block number +; esi - position in block from where to shift +; ecx - number of bytes to shift by + +;;================================================================================================;; +proc libini._.shift_content _f, _delta ;//////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Shift file content starting from cursor position (~ delete) ;; +;? Content is copied by 'delta' bytes up/down ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = -1 (fail) / 0 (ok) ;; +;;================================================================================================;; +locals + buf dd ? +endl + + xor eax, eax + cmp [_delta], 0 + je .skip + + push ebx ecx + invoke mem.alloc, ini.BLOCK_SIZE + or eax, eax + jz .fail + mov [buf], eax + + cmp [_delta], 0 + jl .down + + mov ebx, [_f] + mov ecx, [ebx + IniFile.cnt] + mov ebx, [ebx + IniFile.fh] + invoke file.tell, ebx +; push eax + sub eax, ecx +; dec eax + invoke file.seek, ebx, SEEK_SET, eax + @@: invoke file.seek, ebx, SEEK_CUR, [_delta] + invoke file.eof?, ebx + or eax, eax + jnz .done + invoke file.read, ebx, [buf], ini.BLOCK_SIZE + mov ecx, eax + mov eax, [_delta] + neg eax + sub eax,ecx;ini.BLOCK_SIZE + invoke file.seek,ebx,SEEK_CUR,eax + invoke file.write,ebx,[buf],ecx;ini.BLOCK_SIZE + jmp @b + .done: + mov eax, [_delta] + neg eax + invoke file.seek, ebx, SEEK_CUR, eax + invoke file.seteof, ebx +; pop eax +; invoke file.seek, ebx, SEEK_SET;, eax + stdcall libini._.reload_block, [_f] + invoke mem.free, [buf] + pop ecx ebx + .skip: + ret + .fail: + or eax, -1 + pop ecx ebx + ret + + .down: + neg [_delta] + + mov ebx, [_f] + mov ecx, [ebx + IniFile.cnt] + mov ebx, [ebx + IniFile.fh] + invoke file.tell, ebx +; push eax + sub eax, ecx + lea edx, [eax - 1] + push edx + @@: invoke file.seek, ebx, SEEK_SET, edx + invoke file.eof?, ebx + or eax, eax + jnz @f + add edx, ini.BLOCK_SIZE + jmp @b + @@: cmp edx, [esp] + je .skip.2 + add edx, -ini.BLOCK_SIZE + cmp edx, [esp] + jl @f + invoke file.seek, ebx, SEEK_SET, edx + invoke file.read, ebx, [buf], ini.BLOCK_SIZE + mov ecx, eax + mov eax, [_delta] + sub eax, ecx + invoke file.seek, ebx, SEEK_CUR, eax + invoke file.write, ebx, [buf], ecx + jmp @b + @@: + .skip.2: + add esp, 4 +; mov eax,[delta] +; neg eax +; invoke file.seek,ebx,SEEK_CUR,eax +; pop eax +; invoke file.seek,ebx,SEEK_SET;,eax + stdcall libini._.reload_block, [_f] + invoke mem.free, [buf] + pop ecx ebx + ret +endp + +;;================================================================================================;; +proc libini._.get_value_length _f ;///////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push ebx ecx edx eax + mov ebx, [_f] + invoke file.tell, [ebx + IniFile.fh] + push esi [ebx + IniFile.cnt] [ebx + IniFile.pos] + sub eax, [ebx + IniFile.cnt] + mov edx, eax + + stdcall libini._.skip_line, [_f] + invoke file.tell, [ebx + IniFile.fh] + sub eax, [ebx + IniFile.cnt] + sub eax, edx + mov [esp + 4 * 3], eax + +; pop eax + invoke file.seek, [ebx + IniFile.fh], SEEK_SET;, eax + stdcall libini._.preload_block, [_f] + pop [ebx + IniFile.cnt] esi + pop eax edx ecx ebx + ret +endp + +;;================================================================================================;; +proc libini._.string_copy ;///////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + @@: lodsb + or al, al + jz @f + stosb + jmp @b + @@: ret +endp + +;;================================================================================================;; +proc libini._.find_next_section _f ;//////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push ebx edi + + @@: stdcall libini._.skip_nonblanks, [_f] + cmp al, '[' + je @f + or al, al + jz .exit_error + stdcall libini._.skip_line, [_f] + or al, al + jz .exit_error + jmp @b + @@: + pop edi ebx + xor eax, eax + ret + + .exit_error: + pop edi ebx + or eax, -1 + ret +endp + +;;================================================================================================;; +proc libini._.find_section _f, _sec_name ;////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Find section in file ;; +;? Search is performed from the beginning of file ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = -1 (fail) / 0 (ok) ;; +;< [_f.pos] = new cursor position (right after ']' char if eax = 0, at the end of file otherwise) ;; +;;================================================================================================;; + push ebx edi + + mov ecx, [_f] + invoke file.seek, [ecx + IniFile.fh], SEEK_SET, 0 + stdcall libini._.preload_block, [_f] + + .next_section: + stdcall libini._.find_next_section, [_f] + or eax, eax + jnz .exit_error + + stdcall libini._.get_char, [_f] +; inc esi +; dec [ecx + IniFile.cnt] + stdcall libini._.skip_spaces, [_f] + mov edi, [_sec_name] + @@: stdcall libini._.get_char, [_f] + cmp al, ']' + je @f + or al, al + jz .exit_error + cmp al, 13 + je .next_section + cmp al, 10 + je .next_section + scasb + je @b + cmp byte[edi - 1], 0 + jne .next_section + dec edi + stdcall libini._.unget_char, [_f] + stdcall libini._.skip_spaces, [_f] + stdcall libini._.get_char, [_f] + cmp al, ']' + jne .next_section + @@: + cmp byte[edi], 0 + jne .next_section + pop edi ebx + xor eax, eax + ret + + .exit_error: + pop edi ebx + or eax, -1 + ret +endp + +;;================================================================================================;; +proc libini._.find_key _f, _key_name ;////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Find key in section ;; +;? Search is performed within current section starting from cursor position ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = -1 (fail) / 0 (ok) ;; +;< [_f.pos] = new cursor position (right after '=' char if eax = 0, at the end of file or right ;; +;< before '[' char otherwise) ;; +;;================================================================================================;; + push ebx edi + + .next_value: + mov edi, [_key_name] + stdcall libini._.skip_line, [_f] + stdcall libini._.skip_nonblanks, [_f] + or al, al + jz .exit_error + cmp al, '[' + je .exit_error + @@: stdcall libini._.get_char, [_f] + or al, al + jz .exit_error + cmp al, '=' + je @f + scasb + je @b + cmp byte[edi - 1], 0 + jne .next_value + dec edi + stdcall libini._.unget_char, [_f] + stdcall libini._.skip_spaces, [_f] + stdcall libini._.get_char, [_f] + cmp al, '=' + je @f + jmp .next_value + @@: + cmp byte[edi], 0 + jne .next_value + + pop edi ebx + xor eax, eax + ret + + .exit_error: + pop edi ebx + or eax, -1 + ret +endp + +;;================================================================================================;; +proc libini._.low.read_value _f_addr, _buffer, _buf_len ;/////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;> --- TBD --- ;; +;;------------------------------------------------------------------------------------------------;; +;< --- TBD --- ;; +;;================================================================================================;; + push edi eax + mov edi, [_buffer] + stdcall libini._.skip_spaces, [_f_addr] + @@: dec [_buf_len] + jz @f + stdcall libini._.get_char, [_f_addr] + cmp al, 13 + je @f + cmp al, 10 + je @f + stosb + or al, al + jnz @b + @@: stdcall libini._.unget_char, [_f_addr] + mov byte[edi], 0 + dec edi + @@: cmp byte[edi], 32 + ja @f + mov byte[edi], 0 + dec edi + cmp edi, [_buffer] + jae @b + @@: pop eax edi + ret +endp diff --git a/programs/develop/libraries/libs-dev/libio/libio.asm b/programs/develop/libraries/libs-dev/libio/libio.asm index 71762d672e..ba69a7278f 100644 --- a/programs/develop/libraries/libs-dev/libio/libio.asm +++ b/programs/develop/libraries/libs-dev/libio/libio.asm @@ -17,6 +17,9 @@ ;; ;; ;;================================================================================================;; ;; ;; +;; 2008-08-06 (mike.dld) ;; +;; changes: ;; +;; - split private procs into libio_p.asm, added comments ;; ;; 2007-12-10 (mike.dld) ;; ;; changes: ;; ;; - almost fully incompatible with previous version since return values were changed. ;; @@ -47,280 +50,18 @@ include 'libio_p.inc' section '.flat' code readable align 16 -mem.alloc dd ? -mem.free dd ? -mem.realloc dd ? -dll.load dd ? - -;;================================================================================================;; -proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Library entry point (called after library load) ;; -;;------------------------------------------------------------------------------------------------;; -;> eax = pointer to memory allocation routine ;; -;> ebx = pointer to memory freeing routine ;; -;> ecx = pointer to memory reallocation routine ;; -;> edx = pointer to library loading routine ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 1 (fail) / 0 (ok) (library initialization result) ;; -;;================================================================================================;; - mov [mem.alloc], eax - mov [mem.free], ebx - mov [mem.realloc], ecx - mov [dll.load], edx - xor eax, eax - ret -endp - -;;================================================================================================;; -proc file.aux.match_wildcard _str, _wcard ;///////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Match string against wildcard ;; -;? Based on http://user.cs.tu-berlin.de/~schintke/references/wildcards/ ;; -;? 1997-2001 (c) Florian Schintke ;; -;;------------------------------------------------------------------------------------------------;; -;> _str = pointer to string (filename in most cases) ;; -;> _wcard = pointer to string (mask expressed using wilcards (?, *, [..])) ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = false / true (match result) ;; -;;================================================================================================;; - push ecx edx esi edi - mov dl, 1 ; fit - mov esi, [_wcard] - mov edi, [_str] - .loop_wildcard: - mov al, [esi] - or al, al - jz .loop_wildcard_exit - or dl, dl - jz .loop_wildcard_exit - cmp byte[edi], 0 - je .loop_wildcard_exit - - cmp al, '[' - je .process_set - cmp al, '?' - je .process_question - cmp al, '*' - je .process_asterisk - - xor dl, dl - cmp [edi], al - jne @f - inc dl - @@: inc edi - - .loop_wildcard_next: - inc esi - jmp .loop_wildcard - - - .process_set: - inc esi - xor dl, dl ; fit - xor dh, dh ; negation - mov cl, 1 ; at_beginning - cmp byte[esi], '^' - jne .loop_set_wildcard - inc dh - inc esi - - .loop_set_wildcard: - mov al, [esi] - cmp al, ']' - jne @f - or cl, cl - jz .loop_set_wildcard_exit - @@: or dl, dl - jnz .loop_set_wildcard_fit - cmp al, '-' - jne .loop_set_wildcard_not_range - mov ch, [esi - 1] - cmp [esi + 1], ch - jbe .loop_set_wildcard_not_range - cmp byte[esi + 1], ']' - je .loop_set_wildcard_not_range - or cl, cl - jnz .loop_set_wildcard_not_range - cmp [edi], ch - jb .loop_set_wildcard_fit - mov ch, [esi + 1] - cmp [edi], ch - ja .loop_set_wildcard_fit - mov dl, 1 - inc esi - jmp .loop_set_wildcard_fit - - .loop_set_wildcard_not_range: - cmp [edi], al - jne .loop_set_wildcard_fit - mov dl, 1 - - .loop_set_wildcard_fit: - inc esi - xor cl, cl - jmp .loop_set_wildcard - - .loop_set_wildcard_exit: - or dh, dh - jz @f - xor dl, 1 - @@: or dl, dl - jz @f - inc edi - @@: - jmp .loop_wildcard_next - - .process_question: - inc edi - jmp .loop_wildcard_next - - .process_asterisk: - mov dl, 1 - inc esi - - .loop_asterisk_del_shit: - lodsb - cmp byte[edi], 0 - je .loop_asterisk_del_shit_exit - cmp al, '?' - jne @f - inc edi - jmp .loop_asterisk_del_shit - @@: cmp al, '*' - je .loop_asterisk_del_shit - - .loop_asterisk_del_shit_exit: - - @@: cmp al, '*' - jne @f - lodsb - jmp @b - @@: - dec esi - cmp byte[edi], 0 - jne .process_asterisk_skip_exit - xor dl, dl - or al, al - jnz @f - inc dl - @@: dec esi - jmp .loop_wildcard_next - - .process_asterisk_skip_exit: - stdcall file.aux.match_wildcard, edi, esi - or eax, eax - jnz .process_asterisk_not_match - - .loop_asterisk_match: - inc edi - - .loop_asterisk_char_match: - mov al, [esi] - cmp [edi], al - je .loop_asterisk_char_match_exit - cmp byte[esi], '[' - je .loop_asterisk_char_match_exit - cmp byte[edi], 0 - je .loop_asterisk_char_match_exit - inc edi - jmp .loop_asterisk_char_match - - .loop_asterisk_char_match_exit: - cmp byte[edi], 0 - je @f - stdcall file.aux.match_wildcard, edi, esi - or eax, eax - jnz .loop_asterisk_match_exit - jmp .loop_asterisk_match - @@: - xor dl, dl - - .loop_asterisk_match_exit: - - .process_asterisk_not_match: - cmp byte[esi], 0 - jne @f - cmp byte[edi], 0 - jne @f - mov dl, 1 - @@: - dec esi - jmp .loop_wildcard_next - - .loop_wildcard_exit: - or dl, dl - jz .exit - @@: cmp byte[esi], '*' - jne .exit - inc esi - jmp @b - - .exit: - cmp byte[esi], 0 - je @f - xor dl, dl - @@: cmp byte[edi], 0 - je @f - xor dl, dl - @@: - movzx eax, dl - - pop edi esi edx ecx - ret -endp - -;;================================================================================================;; -proc file.aux.find_matching_file _ffb ;///////////////////////////////////////////////////////////;; -;;------------------------------------------------------------------------------------------------;; -;? Find file with matching attributes (`FindFileBlock.Options.Attributes`) and mask ;; -;? (`FindFileBlock.Options.Mask`) starting from Nth (`FindFileBlock.InfoBlock.Position`) file in ;; -;? directory (`FindFileBlock.InfoBlock.FileName`) ;; -;;------------------------------------------------------------------------------------------------;; -;> _ffb = pointer to FindFileBlock ;; -;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (error) / pointer to `FileInfo` with matched file data ;; -;;================================================================================================;; - push ebx edx - mov edx, [_ffb] - .loop_find: - lea ebx, [edx + FindFileBlock.InfoBlock] - mcall 70 - or eax, eax - jnz .loop_find_error - mov eax, [edx + FindFileBlock.Info.Attributes] - and eax, [edx + FindFileBlock.Options.Attributes] - jz .loop_find_next - lea eax, [edx + FindFileBlock.Info.FileName] - stdcall file.aux.match_wildcard, eax, [edx + FindFileBlock.Options.Mask] - or eax, eax - jnz .loop_find_exit - - .loop_find_next: - inc [edx + FindFileBlock.InfoBlock.Position] - jmp .loop_find - - .loop_find_error: - xor eax, eax - pop edx ebx - ret - - .loop_find_exit: - lea eax, [edx + FindFileBlock.Info] - pop edx ebx - ret -endp +include 'libio_p.asm' ;;================================================================================================;; proc file.find_first _dir, _mask, _attr ;/////////////////////////////////////////////////////////;; ;;------------------------------------------------------------------------------------------------;; ;? Find first file with matching attributes and mask in specified directory ;; ;;------------------------------------------------------------------------------------------------;; -;> _dir = pointer to string (directory path to search in) ;; -;> _mask = pointer to string (file mask, with use of wildcards) ;; -;> _attr = file attributes mask (combination of FA_* constants) ;; +;> _dir = directory path to search in ;; +;> _mask = file mask, with use of wildcards ;; +;> _attr = file attributes mask (combination of FA_* constants) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (error) / pointer to `FileInfo` with matched file data (acts as find descriptor) ;; +;< eax = 0 (error) / matched file data pointer (acts as find descriptor) ;; ;;================================================================================================;; push ebx edx @@ -341,7 +82,7 @@ proc file.find_first _dir, _mask, _attr ;/////////////////////////////////////// mov eax, [_dir] mov [ebx + FileInfoBlock.FileName], eax - stdcall file.aux.find_matching_file, edx + stdcall libio._.find_matching_file, edx pop edx ebx ret @@ -356,14 +97,14 @@ proc file.find_next _findd ;//////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Find next file matching criteria ;; ;;------------------------------------------------------------------------------------------------;; -;> _findd = find descriptor (see `file.find_first`) ;; +;> _findd = find descriptor (see `file.find_first`) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (error) / pointer to `FileInfo` with matched file data (acts as find descriptor) ;; +;< eax = 0 (error) / matched file data pointer (acts as find descriptor) ;; ;;================================================================================================;; mov eax, [_findd] add eax, -sizeof.FileInfoHeader inc [eax + FindFileBlock.InfoBlock.Position] - stdcall file.aux.find_matching_file, eax + stdcall libio._.find_matching_file, eax ret endp @@ -372,7 +113,7 @@ proc file.find_close _findd ;/////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Close find descriptor and free memory ;; ;;------------------------------------------------------------------------------------------------;; -;> _findd = find descriptor (see `file.find_first`) ;; +;> _findd = find descriptor (see `file.find_first`) ;; ;;------------------------------------------------------------------------------------------------;; ;< eax = result of memory freeing routine ;; ;;================================================================================================;; @@ -387,9 +128,9 @@ proc file.size _name ;////////////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Get file size ;; ;;------------------------------------------------------------------------------------------------;; -;> _name = path to file (full or relative) ;; +;> _name = path to file (full or relative) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / file size (in bytes, up to 2G) ;; +;< eax = -1 (error) / file size (in bytes, up to 2G) ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -420,10 +161,16 @@ proc file.open _name, _mode ;/////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Open file ;; ;;------------------------------------------------------------------------------------------------;; -;> _name = path to file (full or relative) ;; -;> _mode = mode to open file in (combination of O_* constants) ;; +;> _name = path to file (full or relative) ;; +;> _mode = mode to open file in (combination of O_* constants) ;; +;> O_BINARY - don't change read/written data in any way (default) ;; +;> O_READ - open file for reading ;; +;> O_WRITE - open file for writing ;; +;> O_CREATE - create file if it doesn't exist, open otherwise ;; +;> O_SHARE - allow simultaneous access by using different file descriptors (not implemented) ;; +;> O_TEXT - replace newline chars with LF (overrides O_BINARY, not implemented) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = 0 (error) / file descriptor ;; +;< eax = 0 (error) / file descriptor ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -495,11 +242,11 @@ proc file.read _filed, _buf, _buflen ;////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Read data from file ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; -;> _buf = pointer to buffer to put read data to ;; -;> _buflen = buffer size (number of bytes to be read from file) ;; +;> _filed = file descriptor (see `file.open`) ;; +;> _buf = buffer to put read data to ;; +;> _buflen = buffer size (number of bytes to be read from file) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / number of bytes read ;; +;< eax = -1 (error) / number of bytes read ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -545,11 +292,11 @@ proc file.write _filed, _buf, _buflen ;///////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Write data to file ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; -;> _buf = pointer to buffer to get write data from ;; -;> _buflen = buffer size (number of bytes to be written to file) ;; +;> _filed = file descriptor (see `file.open`) ;; +;> _buf = buffer to get write data from ;; +;> _buflen = buffer size (number of bytes to be written to file) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / number of bytes written ;; +;< eax = -1 (error) / number of bytes written ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -599,14 +346,14 @@ proc file.seek _filed, _where, _origin ;//////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Set file pointer position ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; -;> _where = position in file (in bytes) counted from specified origin ;; -;> _origin = origin from where to set the position (one of SEEK_* constants) ;; +;> _filed = file descriptor (see `file.open`) ;; +;> _where = position in file (in bytes) counted from specified origin ;; +;> _origin = origin from where to set the position (one of SEEK_* constants) ;; ;> SEEK_SET - from beginning of file ;; ;> SEEK_CUR - from current pointer position ;; ;> SEEK_END - from end of file ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / 0 ;; +;< eax = -1 (error) / 0 ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -661,9 +408,9 @@ proc file.eof? _filed ;///////////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Determine if file pointer is at the end of file ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; +;> _filed = file descriptor (see `file.open`) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = false / true ;; +;< eax = false / true ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -693,9 +440,9 @@ proc file.truncate _filed ;///////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Truncate file size to current file pointer position ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; +;> _filed = file descriptor (see `file.open`) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / 0 ;; +;< eax = -1 (error) / 0 ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -742,9 +489,9 @@ proc file.tell _filed ;///////////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Get current file pointer position ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; +;> _filed = file descriptor (see `file.open`) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / file pointer position ;; +;< eax = -1 (error) / file pointer position ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -758,9 +505,9 @@ proc file.close _filed ;//////////////////////////////////////////////////////// ;;------------------------------------------------------------------------------------------------;; ;? Close file ;; ;;------------------------------------------------------------------------------------------------;; -;> _filed = file descriptor (see `file.open`) ;; +;> _filed = file descriptor (see `file.open`) ;; ;;------------------------------------------------------------------------------------------------;; -;< eax = -1 (error) / file pointer position ;; +;< eax = -1 (error) / file pointer position ;; ;;------------------------------------------------------------------------------------------------;; ;# call `file.err` to obtain extended error information ;; ;;================================================================================================;; @@ -786,7 +533,7 @@ align 16 @EXPORT: export \ - lib_init , 'lib_init' , \ + libio._.init , 'lib_init' , \ 0x00030003 , 'version' , \ file.find_first , 'file.find_first' , \ file.find_next , 'file.find_next' , \ diff --git a/programs/develop/libraries/libs-dev/libio/libio_p.asm b/programs/develop/libraries/libs-dev/libio/libio_p.asm new file mode 100644 index 0000000000..c0d35c4db4 --- /dev/null +++ b/programs/develop/libraries/libs-dev/libio/libio_p.asm @@ -0,0 +1,282 @@ +;;================================================================================================;; +;;//// libio_p.asm //// (c) mike.dld, 2006-2008 //////////////////////////////////////////////////;; +;;================================================================================================;; +;; ;; +;; This file is part of Common development libraries (Libs-Dev). ;; +;; ;; +;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; +;; General Public License as published by the Free Software Foundation, either version 3 of the ;; +;; License, or (at your option) any later version. ;; +;; ;; +;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; +;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; +;; General Public License for more details. ;; +;; ;; +;; You should have received a copy of the GNU General Public License along with Libs-Dev. If not, ;; +;; see . ;; +;; ;; +;;================================================================================================;; + +mem.alloc dd ? +mem.free dd ? +mem.realloc dd ? +dll.load dd ? + +;;================================================================================================;; +proc libio._.init ;///////////////////////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Library entry point (called after library load) ;; +;;------------------------------------------------------------------------------------------------;; +;> eax = memory allocation routine ;; +;> ebx = memory freeing routine ;; +;> ecx = memory reallocation routine ;; +;> edx = library loading routine ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 1 (fail) / 0 (ok) (library initialization result) ;; +;;================================================================================================;; + mov [mem.alloc], eax + mov [mem.free], ebx + mov [mem.realloc], ecx + mov [dll.load], edx + xor eax, eax + ret +endp + +;;================================================================================================;; +proc libio._.match_wildcard _str, _wcard ;////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Match string against wildcard ;; +;? Based on http://user.cs.tu-berlin.de/~schintke/references/wildcards/ ;; +;? 1997-2001 (c) Florian Schintke ;; +;;------------------------------------------------------------------------------------------------;; +;> _str = string (filename in most cases) ;; +;> _wcard = mask expressed using wilcards (?, *, [..]) ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = false / true (match result) ;; +;;================================================================================================;; + push ecx edx esi edi + mov dl, 1 ; fit + mov esi, [_wcard] + mov edi, [_str] + .loop_wildcard: + mov al, [esi] + or al, al + jz .loop_wildcard_exit + or dl, dl + jz .loop_wildcard_exit + cmp byte[edi], 0 + je .loop_wildcard_exit + + cmp al, '[' + je .process_set + cmp al, '?' + je .process_question + cmp al, '*' + je .process_asterisk + + xor dl, dl + cmp [edi], al + jne @f + inc dl + @@: inc edi + + .loop_wildcard_next: + inc esi + jmp .loop_wildcard + + + .process_set: + inc esi + xor dl, dl ; fit + xor dh, dh ; negation + mov cl, 1 ; at_beginning + cmp byte[esi], '^' + jne .loop_set_wildcard + inc dh + inc esi + + .loop_set_wildcard: + mov al, [esi] + cmp al, ']' + jne @f + or cl, cl + jz .loop_set_wildcard_exit + @@: or dl, dl + jnz .loop_set_wildcard_fit + cmp al, '-' + jne .loop_set_wildcard_not_range + mov ch, [esi - 1] + cmp [esi + 1], ch + jbe .loop_set_wildcard_not_range + cmp byte[esi + 1], ']' + je .loop_set_wildcard_not_range + or cl, cl + jnz .loop_set_wildcard_not_range + cmp [edi], ch + jb .loop_set_wildcard_fit + mov ch, [esi + 1] + cmp [edi], ch + ja .loop_set_wildcard_fit + mov dl, 1 + inc esi + jmp .loop_set_wildcard_fit + + .loop_set_wildcard_not_range: + cmp [edi], al + jne .loop_set_wildcard_fit + mov dl, 1 + + .loop_set_wildcard_fit: + inc esi + xor cl, cl + jmp .loop_set_wildcard + + .loop_set_wildcard_exit: + or dh, dh + jz @f + xor dl, 1 + @@: or dl, dl + jz @f + inc edi + @@: + jmp .loop_wildcard_next + + .process_question: + inc edi + jmp .loop_wildcard_next + + .process_asterisk: + mov dl, 1 + inc esi + + .loop_asterisk_del_shit: + lodsb + cmp byte[edi], 0 + je .loop_asterisk_del_shit_exit + cmp al, '?' + jne @f + inc edi + jmp .loop_asterisk_del_shit + @@: cmp al, '*' + je .loop_asterisk_del_shit + + .loop_asterisk_del_shit_exit: + + @@: cmp al, '*' + jne @f + lodsb + jmp @b + @@: + dec esi + cmp byte[edi], 0 + jne .process_asterisk_skip_exit + xor dl, dl + or al, al + jnz @f + inc dl + @@: dec esi + jmp .loop_wildcard_next + + .process_asterisk_skip_exit: + stdcall libio._.match_wildcard, edi, esi + or eax, eax + jnz .process_asterisk_not_match + + .loop_asterisk_match: + inc edi + + .loop_asterisk_char_match: + mov al, [esi] + cmp [edi], al + je .loop_asterisk_char_match_exit + cmp byte[esi], '[' + je .loop_asterisk_char_match_exit + cmp byte[edi], 0 + je .loop_asterisk_char_match_exit + inc edi + jmp .loop_asterisk_char_match + + .loop_asterisk_char_match_exit: + cmp byte[edi], 0 + je @f + stdcall libio._.match_wildcard, edi, esi + or eax, eax + jnz .loop_asterisk_match_exit + jmp .loop_asterisk_match + @@: + xor dl, dl + + .loop_asterisk_match_exit: + + .process_asterisk_not_match: + cmp byte[esi], 0 + jne @f + cmp byte[edi], 0 + jne @f + mov dl, 1 + @@: + dec esi + jmp .loop_wildcard_next + + .loop_wildcard_exit: + or dl, dl + jz .exit + @@: cmp byte[esi], '*' + jne .exit + inc esi + jmp @b + + .exit: + cmp byte[esi], 0 + je @f + xor dl, dl + @@: cmp byte[edi], 0 + je @f + xor dl, dl + @@: + movzx eax, dl + + pop edi esi edx ecx + ret +endp + +;;================================================================================================;; +proc libio._.find_matching_file _ffb ;////////////////////////////////////////////////////////////;; +;;------------------------------------------------------------------------------------------------;; +;? Find file with matching attributes (`FindFileBlock.Options.Attributes`) and mask ;; +;? (`FindFileBlock.Options.Mask`) starting from Nth (`FindFileBlock.InfoBlock.Position`) file in ;; +;? directory (`FindFileBlock.InfoBlock.FileName`) ;; +;;------------------------------------------------------------------------------------------------;; +;> _ffb = find file block ;; +;;------------------------------------------------------------------------------------------------;; +;< eax = 0 (error) / matched file info pointer ;; +;;================================================================================================;; + push ebx edx + mov edx, [_ffb] + .loop_find: + lea ebx, [edx + FindFileBlock.InfoBlock] + mcall 70 + or eax, eax + jnz .loop_find_error + mov eax, [edx + FindFileBlock.Info.Attributes] + and eax, [edx + FindFileBlock.Options.Attributes] + jz .loop_find_next + lea eax, [edx + FindFileBlock.Info.FileName] + stdcall libio._.match_wildcard, eax, [edx + FindFileBlock.Options.Mask] + or eax, eax + jnz .loop_find_exit + + .loop_find_next: + inc [edx + FindFileBlock.InfoBlock.Position] + jmp .loop_find + + .loop_find_error: + xor eax, eax + pop edx ebx + ret + + .loop_find_exit: + lea eax, [edx + FindFileBlock.Info] + pop edx ebx + ret +endp