forked from KolibriOS/kolibrios
Added CWD command to FTP daemon (net branch)
git-svn-id: svn://kolibrios.org@2563 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
0833e5c02d
commit
d277a579f2
@ -49,7 +49,7 @@ commands: ; all commands must be in uppercase
|
|||||||
dd cmdPASS
|
dd cmdPASS
|
||||||
db 'PASV'
|
db 'PASV'
|
||||||
dd cmdPASV
|
dd cmdPASV
|
||||||
db 'PWD', 0 ; Print Working Directory
|
db 'PWD', 0
|
||||||
dd cmdPWD
|
dd cmdPWD
|
||||||
db 'PORT'
|
db 'PORT'
|
||||||
dd cmdPORT
|
dd cmdPORT
|
||||||
@ -76,7 +76,39 @@ cmdABOR:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
cmdCWD:
|
cmdCWD: ; Change Working Directory
|
||||||
|
|
||||||
|
sub ecx, 4
|
||||||
|
jb .err
|
||||||
|
add esi, 4
|
||||||
|
mov edi, work_dir + 1
|
||||||
|
|
||||||
|
cmp byte [esi], '/'
|
||||||
|
jne @f
|
||||||
|
inc esi
|
||||||
|
dec ecx
|
||||||
|
jz .done
|
||||||
|
@@:
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
lodsb
|
||||||
|
cmp al, 0x20
|
||||||
|
jb .done
|
||||||
|
stosb
|
||||||
|
loop .loop
|
||||||
|
.done:
|
||||||
|
cmp byte [edi-1], '/'
|
||||||
|
je @f
|
||||||
|
mov byte [edi], '/'
|
||||||
|
inc edi
|
||||||
|
@@:
|
||||||
|
mov byte [edi], 0
|
||||||
|
|
||||||
|
mcall send, [socketnum2], str250, str250.length, 0
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.err:
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -88,6 +120,7 @@ cmdDELE:
|
|||||||
align 4
|
align 4
|
||||||
cmdLIST:
|
cmdLIST:
|
||||||
|
|
||||||
|
; If we are in active mode, it's time to open a data socket..
|
||||||
cmp [mode], MODE_ACTIVE
|
cmp [mode], MODE_ACTIVE
|
||||||
jne @f
|
jne @f
|
||||||
mcall connect, [datasocketnum], datasock, datasock.length
|
mcall connect, [datasocketnum], datasock, datasock.length
|
||||||
@ -95,31 +128,30 @@ cmdLIST:
|
|||||||
je .err
|
je .err
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
|
; Warn the client we're about to send the data
|
||||||
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
|
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
|
||||||
|
|
||||||
|
; Create fpath from home_dir and work_dir
|
||||||
|
call create_path
|
||||||
|
|
||||||
|
; Start the search
|
||||||
push FA_READONLY + FA_FOLDER
|
push FA_READONLY + FA_FOLDER
|
||||||
push str_mask
|
push str_mask
|
||||||
push home_dir
|
push fpath
|
||||||
call [file.find.first]
|
call [file.find.first]
|
||||||
|
|
||||||
mov edi, buffer
|
mov edi, buffer
|
||||||
jmp .parse_file
|
|
||||||
|
|
||||||
.checknextfile:
|
|
||||||
push edx
|
|
||||||
call [file.find.next]
|
|
||||||
|
|
||||||
.parse_file:
|
.parse_file:
|
||||||
test eax, eax
|
test eax, eax ; did we find a file?
|
||||||
jz .done
|
jz .done
|
||||||
|
|
||||||
mov edx, eax
|
mov edx, eax ; yes, save the descripter
|
||||||
|
|
||||||
; first, convert the attributes
|
; first, convert the attributes
|
||||||
test [eax + FileInfoA.Attributes], FA_FOLDER
|
test [edx + FileInfoA.Attributes], FA_FOLDER
|
||||||
jnz .folder
|
jnz .folder
|
||||||
|
|
||||||
test [eax + FileInfoA.Attributes], FA_READONLY
|
test [edx + FileInfoA.Attributes], FA_READONLY
|
||||||
jnz .readonly
|
jnz .readonly
|
||||||
|
|
||||||
mov eax, '-rw-'
|
mov eax, '-rw-'
|
||||||
@ -128,7 +160,7 @@ cmdLIST:
|
|||||||
|
|
||||||
.folder:
|
.folder:
|
||||||
mov eax, 'drwx'
|
mov eax, 'drwx'
|
||||||
stosb
|
stosd
|
||||||
jmp .attr
|
jmp .attr
|
||||||
|
|
||||||
.readonly:
|
.readonly:
|
||||||
@ -153,7 +185,7 @@ cmdLIST:
|
|||||||
stosd
|
stosd
|
||||||
|
|
||||||
; now the filesize in ascii
|
; now the filesize in ascii
|
||||||
mov ebx, dword [edx + FileInfoA.FileSize]
|
mov ebx, [edx + FileInfoA.FileSizeLow]
|
||||||
call dword_to_ascii
|
call dword_to_ascii
|
||||||
|
|
||||||
mov al, ' '
|
mov al, ' '
|
||||||
@ -186,24 +218,34 @@ cmdLIST:
|
|||||||
stosb
|
stosb
|
||||||
loop .nameloop
|
loop .nameloop
|
||||||
|
|
||||||
|
; insert a cr lf
|
||||||
.namedone:
|
.namedone:
|
||||||
mov ax, 0x0d0a
|
mov ax, 0x0d0a
|
||||||
stosw
|
stosw
|
||||||
jmp .checknextfile
|
|
||||||
|
|
||||||
|
; check next file
|
||||||
|
push edx
|
||||||
|
call [file.find.next]
|
||||||
|
jmp .parse_file
|
||||||
|
|
||||||
|
; close file desc
|
||||||
.done:
|
.done:
|
||||||
push edx
|
push edx
|
||||||
call [file.find.close]
|
call [file.find.close]
|
||||||
|
|
||||||
|
; append the string with a 0
|
||||||
xor al, al
|
xor al, al
|
||||||
stosb
|
stosb
|
||||||
|
|
||||||
|
; print everything on the console
|
||||||
push buffer
|
push buffer
|
||||||
call [con_write_asciiz]
|
call [con_write_asciiz]
|
||||||
|
|
||||||
|
; and send it to the client
|
||||||
lea esi, [edi - buffer]
|
lea esi, [edi - buffer]
|
||||||
mcall send, [datasocketnum], buffer, , 0
|
mcall send, [datasocketnum], buffer, , 0
|
||||||
|
|
||||||
|
; close the data socket..
|
||||||
mcall close, [datasocketnum]
|
mcall close, [datasocketnum]
|
||||||
|
|
||||||
cmp [mode], MODE_PASSIVE_OK
|
cmp [mode], MODE_PASSIVE_OK
|
||||||
@ -211,7 +253,8 @@ cmdLIST:
|
|||||||
mov [mode], MODE_PASSIVE_WAIT
|
mov [mode], MODE_PASSIVE_WAIT
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok
|
; And send "transfer ok" on the base connection
|
||||||
|
mcall send, [socketnum2], str226, str226.length, 0
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -296,7 +339,7 @@ cmdPASV:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
cmdPWD:
|
cmdPWD: ; Print Working Directory
|
||||||
|
|
||||||
mov dword[buffer], '257 '
|
mov dword[buffer], '257 '
|
||||||
mov byte[buffer+4], '"'
|
mov byte[buffer+4], '"'
|
||||||
@ -383,22 +426,51 @@ cmdQUIT:
|
|||||||
align 4
|
align 4
|
||||||
cmdRETR:
|
cmdRETR:
|
||||||
|
|
||||||
; mcall connect, [datasocketnum], datasock, datasock.length
|
cmp [mode], MODE_ACTIVE
|
||||||
|
jne @f
|
||||||
|
mcall connect, [datasocketnum], datasock, datasock.length
|
||||||
; cmp eax, -1
|
; cmp eax, -1
|
||||||
; je .err
|
; je .err
|
||||||
|
@@:
|
||||||
|
|
||||||
; push O_READ
|
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
|
||||||
; push home_dir
|
|
||||||
; call [file.open]
|
push O_READ
|
||||||
|
push home_dir
|
||||||
|
call [file.open]
|
||||||
; test eax, eax
|
; test eax, eax
|
||||||
; jz .cannot_open
|
; jz .cannot_open
|
||||||
;
|
|
||||||
; push BUFFERSIZE
|
mov ebx, eax
|
||||||
; push buffer
|
|
||||||
; push eax
|
.read_more:
|
||||||
; call [file.read]
|
push BUFFERSIZE
|
||||||
|
push buffer
|
||||||
|
push ebx
|
||||||
|
call [file.read]
|
||||||
; cmp eax, -1
|
; cmp eax, -1
|
||||||
; jz .cannot_open
|
; je .cannot_open
|
||||||
|
|
||||||
|
push eax
|
||||||
|
push ebx
|
||||||
|
mov esi, eax
|
||||||
|
mcall send, [datasocketnum], buffer, , 0
|
||||||
|
pop ebx
|
||||||
|
pop ecx
|
||||||
|
; cmp eax, -1
|
||||||
|
; je .socketerr
|
||||||
|
|
||||||
|
cmp ecx, BUFFERSIZE
|
||||||
|
je .read_more
|
||||||
|
|
||||||
|
mcall close, [datasocketnum]
|
||||||
|
|
||||||
|
cmp [mode], MODE_PASSIVE_OK
|
||||||
|
jne @f
|
||||||
|
mov [mode], MODE_PASSIVE_WAIT
|
||||||
|
@@:
|
||||||
|
|
||||||
|
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -542,6 +614,41 @@ dword_to_ascii: ; edi = ptr where to write, ebx is number
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
align 4
|
||||||
|
create_path: ; combine home_dir and work_dir strings into fpath
|
||||||
|
mov edi, fpath
|
||||||
|
mov esi, home_dir
|
||||||
|
mov ecx, 1024
|
||||||
|
|
||||||
|
.loop1:
|
||||||
|
lodsb
|
||||||
|
or al, al
|
||||||
|
jz .next
|
||||||
|
stosb
|
||||||
|
loop .loop1
|
||||||
|
.next:
|
||||||
|
|
||||||
|
cmp byte[edi-1], '/'
|
||||||
|
jne @f
|
||||||
|
dec edi
|
||||||
|
@@:
|
||||||
|
|
||||||
|
mov esi, work_dir
|
||||||
|
mov ecx, 1024
|
||||||
|
|
||||||
|
.loop2:
|
||||||
|
lodsb
|
||||||
|
or al, al
|
||||||
|
jz .done
|
||||||
|
stosb
|
||||||
|
loop .loop2
|
||||||
|
|
||||||
|
.done:
|
||||||
|
stosb
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -563,10 +670,7 @@ str226 db '226 Transfer OK, Closing connection', 13, 10
|
|||||||
str230 db '230 You are now logged in.', 13, 10
|
str230 db '230 You are now logged in.', 13, 10
|
||||||
.length = $ - str230
|
.length = $ - str230
|
||||||
str250 db '250 command successful', 13, 10
|
str250 db '250 command successful', 13, 10
|
||||||
;str257 db '257 "'
|
.length = $ - str250
|
||||||
;.length = $ - str257
|
|
||||||
;str257b db '"', 13, 10
|
|
||||||
;.length = $ - str257b
|
|
||||||
str331 db '331 Please specify the password.', 13, 10
|
str331 db '331 Please specify the password.', 13, 10
|
||||||
.length = $ - str331
|
.length = $ - str331
|
||||||
str421 db '421 Timeout!', 13, 10
|
str421 db '421 Timeout!', 13, 10
|
||||||
@ -576,3 +680,4 @@ str425 db '425 Cant open data connection.', 13, 10
|
|||||||
str500 db '500 Unsupported command', 13, 10
|
str500 db '500 Unsupported command', 13, 10
|
||||||
.length = $ - str500
|
.length = $ - str500
|
||||||
str550 db '550 No such file', 13, 10
|
str550 db '550 No such file', 13, 10
|
||||||
|
.length = $ - str550
|
@ -157,10 +157,8 @@ start:
|
|||||||
|
|
||||||
pushd 0x0a
|
pushd 0x0a
|
||||||
call [con_set_flags]
|
call [con_set_flags]
|
||||||
|
|
||||||
push buffer
|
push buffer
|
||||||
call [con_write_asciiz]
|
call [con_write_asciiz]
|
||||||
|
|
||||||
pushd 0x07
|
pushd 0x07
|
||||||
call [con_set_flags]
|
call [con_set_flags]
|
||||||
|
|
||||||
@ -297,8 +295,11 @@ socketnum dd ?
|
|||||||
; thread specific data
|
; thread specific data
|
||||||
socketnum2 dd ?
|
socketnum2 dd ?
|
||||||
state dd ?
|
state dd ?
|
||||||
home_dir db '/rd/1/',0
|
home_dir db '/rd/1/', 0
|
||||||
|
rb 1024
|
||||||
work_dir rb 1024
|
work_dir rb 1024
|
||||||
|
fpath rb 2048
|
||||||
|
|
||||||
type db ?
|
type db ?
|
||||||
mode db ? ; active/passive
|
mode db ? ; active/passive
|
||||||
|
|
||||||
|
@ -2,53 +2,79 @@
|
|||||||
; Macroinstructions for defining data structures
|
; Macroinstructions for defining data structures
|
||||||
|
|
||||||
macro struct name
|
macro struct name
|
||||||
{ fields@struct equ name
|
{ virtual at 0
|
||||||
|
fields@struct equ name
|
||||||
match child parent, name \{ fields@struct equ child,fields@\#parent \}
|
match child parent, name \{ fields@struct equ child,fields@\#parent \}
|
||||||
sub@struct equ
|
sub@struct equ
|
||||||
struc db [val] \{ \common fields@struct equ fields@struct,.,db,<val> \}
|
struc db [val] \{ \common define field@struct .,db,<val>
|
||||||
struc dw [val] \{ \common fields@struct equ fields@struct,.,dw,<val> \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc du [val] \{ \common fields@struct equ fields@struct,.,du,<val> \}
|
struc dw [val] \{ \common define field@struct .,dw,<val>
|
||||||
struc dd [val] \{ \common fields@struct equ fields@struct,.,dd,<val> \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc dp [val] \{ \common fields@struct equ fields@struct,.,dp,<val> \}
|
struc du [val] \{ \common define field@struct .,du,<val>
|
||||||
struc dq [val] \{ \common fields@struct equ fields@struct,.,dq,<val> \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc dt [val] \{ \common fields@struct equ fields@struct,.,dt,<val> \}
|
struc dd [val] \{ \common define field@struct .,dd,<val>
|
||||||
struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \}
|
struc dp [val] \{ \common define field@struct .,dp,<val>
|
||||||
struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \}
|
struc dq [val] \{ \common define field@struct .,dq,<val>
|
||||||
struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \}
|
fields@struct equ fields@struct,field@struct \}
|
||||||
struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \}
|
struc dt [val] \{ \common define field@struct .,dt,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rb count \{ define field@struct .,db,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rw count \{ define field@struct .,dw,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rd count \{ define field@struct .,dd,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rp count \{ define field@struct .,dp,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rq count \{ define field@struct .,dq,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
|
struc rt count \{ define field@struct .,dt,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro db [val] \{ \common \local anonymous
|
macro db [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,db,<val> \}
|
define field@struct anonymous,db,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro dw [val] \{ \common \local anonymous
|
macro dw [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dw,<val> \}
|
define field@struct anonymous,dw,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro du [val] \{ \common \local anonymous
|
macro du [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,du,<val> \}
|
define field@struct anonymous,du,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro dd [val] \{ \common \local anonymous
|
macro dd [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dd,<val> \}
|
define field@struct anonymous,dd,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro dp [val] \{ \common \local anonymous
|
macro dp [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dp,<val> \}
|
define field@struct anonymous,dp,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro dq [val] \{ \common \local anonymous
|
macro dq [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dq,<val> \}
|
define field@struct anonymous,dq,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro dt [val] \{ \common \local anonymous
|
macro dt [val] \{ \common \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dt,<val> \}
|
define field@struct anonymous,dt,<val>
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rb count \{ \local anonymous
|
macro rb count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,db,count dup (?) \}
|
define field@struct anonymous,db,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rw count \{ \local anonymous
|
macro rw count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dw,count dup (?) \}
|
define field@struct anonymous,dw,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rd count \{ \local anonymous
|
macro rd count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dd,count dup (?) \}
|
define field@struct anonymous,dd,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rp count \{ \local anonymous
|
macro rp count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dp,count dup (?) \}
|
define field@struct anonymous,dp,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rq count \{ \local anonymous
|
macro rq count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dq,count dup (?) \}
|
define field@struct anonymous,dq,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro rt count \{ \local anonymous
|
macro rt count \{ \local anonymous
|
||||||
fields@struct equ fields@struct,anonymous,dt,count dup (?) \}
|
define field@struct anonymous,dt,count dup (?)
|
||||||
|
fields@struct equ fields@struct,field@struct \}
|
||||||
macro union \{ fields@struct equ fields@struct,,union,<
|
macro union \{ fields@struct equ fields@struct,,union,<
|
||||||
sub@struct equ union \}
|
sub@struct equ union \}
|
||||||
macro struct \{ fields@struct equ fields@struct,,substruct,<
|
macro struct \{ fields@struct equ fields@struct,,substruct,<
|
||||||
sub@struct equ substruct \}
|
sub@struct equ substruct \} }
|
||||||
virtual at 0 }
|
|
||||||
|
|
||||||
macro ends
|
macro ends
|
||||||
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
|
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
|
||||||
@ -56,19 +82,19 @@ macro ends
|
|||||||
purge db,dw,du,dd,dp,dq,dt
|
purge db,dw,du,dd,dp,dq,dt
|
||||||
purge rb,rw,rd,rp,rq,rt
|
purge rb,rw,rd,rp,rq,rt
|
||||||
purge union,struct
|
purge union,struct
|
||||||
|
match name tail,fields@struct, \\{ if $
|
||||||
|
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
|
||||||
|
err
|
||||||
|
end if \\}
|
||||||
match name=,fields,fields@struct \\{ fields@struct equ
|
match name=,fields,fields@struct \\{ fields@struct equ
|
||||||
make@struct name,fields
|
make@struct name,fields
|
||||||
fields@\\#name equ fields \\}
|
define fields@\\#name fields \\}
|
||||||
end virtual \}
|
end virtual \}
|
||||||
match any, sub@struct \{ fields@struct equ fields@struct> \}
|
match any, sub@struct \{ fields@struct equ fields@struct> \}
|
||||||
restore sub@struct }
|
restore sub@struct }
|
||||||
|
|
||||||
macro make@struct name,[field,type,def]
|
macro make@struct name,[field,type,def]
|
||||||
{ common
|
{ common
|
||||||
if $
|
|
||||||
display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah
|
|
||||||
err
|
|
||||||
end if
|
|
||||||
local define
|
local define
|
||||||
define equ name
|
define equ name
|
||||||
forward
|
forward
|
||||||
@ -81,6 +107,14 @@ macro make@struct name,[field,type,def]
|
|||||||
|
|
||||||
macro define@struct name,[field,type,def]
|
macro define@struct name,[field,type,def]
|
||||||
{ common
|
{ common
|
||||||
|
virtual
|
||||||
|
db `name
|
||||||
|
load initial@struct byte from 0
|
||||||
|
if initial@struct = '.'
|
||||||
|
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
|
||||||
|
err
|
||||||
|
end if
|
||||||
|
end virtual
|
||||||
local list
|
local list
|
||||||
list equ
|
list equ
|
||||||
forward
|
forward
|
||||||
@ -88,6 +122,7 @@ macro define@struct name,[field,type,def]
|
|||||||
name#field type def
|
name#field type def
|
||||||
sizeof.#name#field = $ - name#field
|
sizeof.#name#field = $ - name#field
|
||||||
else
|
else
|
||||||
|
label name#.#type
|
||||||
rb sizeof.#type
|
rb sizeof.#type
|
||||||
end if
|
end if
|
||||||
local value
|
local value
|
||||||
@ -97,15 +132,29 @@ macro define@struct name,[field,type,def]
|
|||||||
sizeof.#name = $
|
sizeof.#name = $
|
||||||
restruc name
|
restruc name
|
||||||
match values, list \{
|
match values, list \{
|
||||||
struc name value \\{
|
struc name value \\{ \\local \\..base
|
||||||
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
|
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
|
||||||
match , fields@struct \\\{ label .
|
match , fields@struct \\\{ label \\..base
|
||||||
forward
|
forward
|
||||||
match , value \\\\{ field type def \\\\}
|
match , value \\\\{ field type def \\\\}
|
||||||
match any, value \\\\{ field type value
|
match any, value \\\\{ field type value
|
||||||
if ~ field eq .
|
if ~ field eq .
|
||||||
rb sizeof.#name#field - ($-field)
|
rb sizeof.#name#field - ($-field)
|
||||||
end if \\\\}
|
end if \\\\}
|
||||||
|
common label . at \\..base \\\}
|
||||||
|
\\}
|
||||||
|
macro name value \\{
|
||||||
|
match any, fields@struct \\\{ \\\local anonymous
|
||||||
|
fields@struct equ fields@struct,anonymous,name,<values> \\\}
|
||||||
|
match , fields@struct \\\{
|
||||||
|
forward
|
||||||
|
match , value \\\\{ type def \\\\}
|
||||||
|
match any, value \\\\{ \\\\local ..field
|
||||||
|
..field = $
|
||||||
|
type value
|
||||||
|
if ~ field eq .
|
||||||
|
rb sizeof.#name#field - ($-..field)
|
||||||
|
end if \\\\}
|
||||||
common \\\} \\} \} }
|
common \\\} \\} \} }
|
||||||
|
|
||||||
macro enable@substruct
|
macro enable@substruct
|
||||||
@ -116,7 +165,7 @@ macro enable@substruct
|
|||||||
\forward
|
\forward
|
||||||
\local sub
|
\local sub
|
||||||
match , field \\{ match any, type \\\{ enable@substruct
|
match , field \\{ match any, type \\\{ enable@substruct
|
||||||
make@substruct type,name,sub def
|
make@substruct type,parent,sub def
|
||||||
purge make@substruct
|
purge make@substruct
|
||||||
define equ define,.,sub, \\\} \\}
|
define equ define,.,sub, \\\} \\}
|
||||||
match any, field \\{ define equ define,.\#field,type,<def> \\}
|
match any, field \\{ define equ define,.\#field,type,<def> \\}
|
||||||
@ -127,21 +176,28 @@ enable@substruct
|
|||||||
|
|
||||||
macro define@union parent,name,[field,type,def]
|
macro define@union parent,name,[field,type,def]
|
||||||
{ common
|
{ common
|
||||||
virtual at 0
|
virtual at parent#.#name
|
||||||
forward
|
forward
|
||||||
if ~ field eq .
|
if ~ field eq .
|
||||||
virtual at 0
|
virtual at parent#.#name
|
||||||
parent#field type def
|
parent#field type def
|
||||||
sizeof.#parent#field = $ - parent#field
|
sizeof.#parent#field = $ - parent#field
|
||||||
end virtual
|
end virtual
|
||||||
if sizeof.#parent#field > $
|
if sizeof.#parent#field > $ - parent#.#name
|
||||||
rb sizeof.#parent#field - $
|
rb sizeof.#parent#field - ($ - parent#.#name)
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
virtual at parent#.#name
|
||||||
|
label parent#.#type
|
||||||
|
type def
|
||||||
|
end virtual
|
||||||
|
label name#.#type at parent#.#name
|
||||||
|
if sizeof.#type > $ - parent#.#name
|
||||||
|
rb sizeof.#type - ($ - parent#.#name)
|
||||||
end if
|
end if
|
||||||
else if sizeof.#type > $
|
|
||||||
rb sizeof.#type - $
|
|
||||||
end if
|
end if
|
||||||
common
|
common
|
||||||
sizeof.#name = $
|
sizeof.#name = $ - parent#.#name
|
||||||
end virtual
|
end virtual
|
||||||
struc name [value] \{ \common
|
struc name [value] \{ \common
|
||||||
label .\#name
|
label .\#name
|
||||||
@ -153,21 +209,23 @@ macro define@union parent,name,[field,type,def]
|
|||||||
match , last@union \\{ match , value \\\{ field type def \\\}
|
match , last@union \\{ match , value \\\{ field type def \\\}
|
||||||
match any, value \\\{ field type value \\\} \\}
|
match any, value \\\{ field type value \\\} \\}
|
||||||
last@union equ field
|
last@union equ field
|
||||||
common rb sizeof.#name - ($ - .\#name) \} }
|
common rb sizeof.#name - ($ - .\#name) \}
|
||||||
|
macro name [value] \{ \common \local ..anonymous
|
||||||
|
..anonymous name value \} }
|
||||||
|
|
||||||
macro define@substruct parent,name,[field,type,def]
|
macro define@substruct parent,name,[field,type,def]
|
||||||
{ common
|
{ common
|
||||||
virtual at 0
|
virtual at parent#.#name
|
||||||
forward
|
forward
|
||||||
if ~ field eq .
|
if ~ field eq .
|
||||||
parent#field type def
|
parent#field type def
|
||||||
sizeof.#parent#field = $ - parent#field
|
sizeof.#parent#field = $ - parent#field
|
||||||
else
|
else
|
||||||
|
label parent#.#type
|
||||||
rb sizeof.#type
|
rb sizeof.#type
|
||||||
end if
|
end if
|
||||||
local value
|
|
||||||
common
|
common
|
||||||
sizeof.#name = $
|
sizeof.#name = $ - parent#.#name
|
||||||
end virtual
|
end virtual
|
||||||
struc name value \{
|
struc name value \{
|
||||||
label .\#name
|
label .\#name
|
||||||
@ -177,4 +235,6 @@ macro define@substruct parent,name,[field,type,def]
|
|||||||
if ~ field eq .
|
if ~ field eq .
|
||||||
rb sizeof.#parent#field - ($-field)
|
rb sizeof.#parent#field - ($-field)
|
||||||
end if \\}
|
end if \\}
|
||||||
common \} }
|
common \}
|
||||||
|
macro name value \{ \local ..anonymous
|
||||||
|
..anonymous name \} }
|
||||||
|
Loading…
Reference in New Issue
Block a user