MAX_CCITEMS = 100
uglobal
hCCList dd 0
hCCPrefix dd 0
endg
idCCList = 763
proc CreateCCList, .parent
begin
push ebx
invoke CreateWindowExW, WS_EX_CLIENTEDGE, cFormClassName, 0, WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN, \
0, 0, 300, 120, [.parent], 0, [hInstance], 0
mov [hCCList], eax
invoke SetPropW, eax, [propOwnerAsmEdit], [.parent]
; invoke SetWindowLongA, [hCCList], GWL_HWNDPARENT, [.parent]
stdcall SubclassWindow, [hCCList], CCParentProc
invoke CreateWindowExW, 0, cListboxClassName, 0, \
WS_CHILD or WS_VSCROLL or WS_VISIBLE or LBS_NOINTEGRALHEIGHT or LBS_OWNERDRAWFIXED or LBS_NODATA, \
0, 0, 300, 120, [hCCList], idCCList, [hInstance], 0
mov ebx, eax
stdcall SubclassWindow, ebx, CCListProc
stdcall SetAlign, ebx, waClient
stdcall GetDefaultFont, gdfMessage
invoke SendMessageW, ebx, WM_SETFONT, eax, TRUE
mov [hCCPrefix], 0
pop ebx
return
endp
; returns pointer to the string in ebx
proc GetCCListSelected
begin
push eax ecx edx
invoke SendMessageW, [hCCList], LB_GETCURSEL, 0, 0
add eax, 1
jc .err
mov ebx, eax
invoke GetWindowLongW, [hCCList], GWL_USERDATA
cmp [eax+TArray.count], ebx
jb .err
mov ebx, [eax+TArray.array+4*ebx-4]
mov ebx, [ebx+TLabel.iName]
add ebx, [ptrNames]
clc
.err:
pop edx ecx eax
return
endp
proc ClearCCList
begin
invoke SendMessageW, [hCCList], LB_SETCOUNT, 0, 0
invoke GetWindowLongW, [hCCList], GWL_USERDATA
stdcall FreeMem, eax
stdcall CreateArray, 4 ; dword array.
invoke SetWindowLongW, [hCCList], GWL_USERDATA, eax
return
endp
proc SelectCCList, .hStr
begin
push ebx esi edi
stdcall StrPtr, [.hStr]
mov edi, eax
invoke GetWindowLongW, [hCCList], GWL_USERDATA
mov ebx, [eax+TArray.count]
lea esi, [eax+TArray.array]
or eax, -1
.matchloop:
inc eax
cmp eax, ebx
je .notfound
mov ecx, [esi]
lea esi, [esi+4]
mov ecx, [ecx+TLabel.iName]
add ecx, [ptrNames]
stdcall StringMatch, ecx, edi, FALSE
jnc .matchloop
invoke SendMessageW, [hCCList], LB_SETCURSEL, eax, 0
clc
return
.notfound:
invoke SendMessageW, [hCCList], LB_SETCURSEL, -1, 0
stc
return
endp
proc CCParentProc, .hwnd, .wmsg, .wparam, .lparam
begin
cmp ebx, WM_KEYDOWN
je .relay
cmp ebx, LB_ADDSTRING
jl .process
cmp ebx, LB_ITEMFROMPOINT
ja .process
.relay:
invoke SendDlgItemMessageW, [.hwnd], idCCList, [.wmsg], [.wparam], [.lparam]
clc
return
.process:
dispatch ebx
.ondefault:
stc
return
oncase WM_SETFOCUS
xor eax, eax
clc
return
oncase AM_INITWINDOW
stdcall CreateArray, 4 ; dword array.
invoke SetWindowLongW, [.hwnd], GWL_USERDATA, eax
clc
return
oncase WM_SIZE
invoke GetDlgItem, [.hwnd], idCCList
invoke InvalidateRect, eax, 0, 0
xor eax, eax
clc
return
oncase WM_CLOSE
invoke DestroyWindow, [.hwnd]
xor eax, eax
mov [hCCList], eax
clc
return
oncase WM_DESTROY
invoke GetWindowLongW, [.hwnd], GWL_USERDATA
stdcall FreeMem, eax
stc
return
oncase WM_MEASUREITEM
locals
.ccrect RECT
endl
mov esi, [.lparam]
cmp [esi+MEASUREITEMSTRUCT.CtlType], ODT_LISTBOX
jne .ondefault
cmp [esi+MEASUREITEMSTRUCT.CtlID], idCCList
jne .ondefault
invoke GetDlgItem, [.hwnd], idCCList
mov ebx, eax
lea ecx, [.ccrect]
invoke GetClientRect, ebx, ecx
push [.ccrect.right]
pop [esi+MEASUREITEMSTRUCT.itemWidth]
or eax, -1
clc
return
oncase WM_DRAWITEM
locals
.rectL RECT
.rectR RECT
.bkbrush dd ?
.buffer rb 32
endl
cmp [.wparam], idCCList
jne .ondefault
mov esi, [.lparam]
mov eax, [esi+DRAWITEMSTRUCT.hwndItem]
mov eax, COLOR_HIGHLIGHT
mov ebx, COLOR_HIGHLIGHTTEXT
test [esi+DRAWITEMSTRUCT.itemState], ODS_SELECTED or ODS_FOCUS
jnz @f
mov eax, COLOR_WINDOW
mov ebx, COLOR_WINDOWTEXT
@@:
invoke GetSysColor, eax
invoke CreateSolidBrush, eax
mov [.bkbrush], eax
invoke GetSysColor, ebx
invoke SetTextColor, [esi+DRAWITEMSTRUCT.hDC], eax
invoke SetBkMode, [esi+DRAWITEMSTRUCT.hDC], TRANSPARENT
; First fill the background
lea eax, [esi+DRAWITEMSTRUCT.rcItem]
invoke FillRect, [esi+DRAWITEMSTRUCT.hDC], eax, [.bkbrush]
; then compute the rectangles
mov eax, [esi+DRAWITEMSTRUCT.rcItem.left]
mov ecx, [esi+DRAWITEMSTRUCT.rcItem.right]
mov [.rectL.left], eax
mov [.rectL.right], ecx
mov [.rectR.left], ecx
mov [.rectR.right], ecx
sub ecx, eax
shr ecx, 1 ; 1/2 of the field for the value.
sub [.rectL.right], ecx
sub [.rectR.left], ecx
mov eax, [esi+DRAWITEMSTRUCT.rcItem.top]
mov ecx, [esi+DRAWITEMSTRUCT.rcItem.bottom]
mov [.rectL.top], eax
mov [.rectL.bottom], ecx
mov [.rectR.top], eax
mov [.rectR.bottom], ecx
add [.rectL.left], 4
add [.rectR.left], 4
invoke GetSysColor, COLOR_BTNFACE
invoke CreatePen, PS_SOLID, 0, eax
invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC], eax
push eax
invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.top], NULL
invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.bottom]
mov edi, [.rectL.bottom]
dec edi
invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [esi+DRAWITEMSTRUCT.rcItem.left], edi, NULL
invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectR.right], edi
invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC] ; from the stack
invoke DeleteObject, eax
; then write the text
mov edi, [esi+DRAWITEMSTRUCT.itemID]
cmp edi, -1
je .cleanup
invoke GetWindowLongW, [.hwnd], GWL_USERDATA
cmp edi, [eax+TArray.count]
jae .cleanup
mov edi, [eax+TArray.array + 4*edi]
mov eax, [edi+TLabel.iName]
add eax, [ptrNames]
stdcall utf8ToWideChar, eax
push eax
lea ecx, [.rectL]
invoke DrawTextW, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS
stdcall FreeMem ; from the stack
; then write the value
stdcall SymbolToStr, edi
push eax
stdcall utf8ToWideChar, eax
stdcall StrDel ; from the stack
push eax
lea ecx, [.rectR]
invoke DrawTextW, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER
stdcall FreeMem ; from the stack.
.cleanup:
invoke DeleteObject, [.bkbrush]
or eax, -1
clc
return
enddispatch
endp
cVirtual text 'virtual'
proc SymbolToStr, .ptrLabel
begin
pushad
mov edi, [.ptrLabel]
test [edi+TLabel.flags], lfDefined
jz .notdefined
stdcall StrNew
mov ebx, eax
mov cl, [edi+TLabel.DataSize]
mov eax, 'b '
cmp cl, 1
je .sz_ok
mov eax, 'w '
cmp cl, 2
je .sz_ok
mov eax, 'dw '
cmp cl, 4
je .sz_ok
mov eax, 'pw '
cmp cl, 6
je .sz_ok
mov eax, 'qw '
cmp cl, 8
je .sz_ok
mov eax, 'tw '
cmp cl, 10
jne .prefix_ok
.sz_ok:
stdcall StrCharCat, ebx, eax
.prefix_ok:
; type:
cmp [edi+TLabel.type], ltAbsolute
je .type_ok
stdcall StrCharCat, ebx, 'r '
.type_ok:
; registers
xor edx, edx
cmp [edi+TLabel.SIBEx], 0
je .reg_ok2
or edx, 1 ; close the bracket
stdcall StrCharCat, ebx, '['
movzx eax, byte [edi+TLabel.SIBEx+2]
cmp eax, 1
je .mul_ok1
test eax, eax
jz .reg_ok1
add eax, '0'
stdcall StrCharCat, ebx, eax
stdcall StrCharCat, ebx, '*'
or edx, 2 ; at lease one register
.mul_ok1:
movzx eax, byte [edi+TLabel.SIBEx]
test eax, eax
jz .reg_ok1
stdcall GetRegisterName, eax
stdcall StrCharCat, ebx, eax
or edx, 2 ; at lease one register
.reg_ok1:
movzx eax, byte [edi+TLabel.SIBEx+3]
cmp eax, 1
je .mul_ok2
test eax, eax
jz .reg_ok2
add eax, '0'
test edx, 2
jz @f
stdcall StrCharCat, ebx, '+'
@@:
stdcall StrCharCat, ebx, eax
stdcall StrCharCat, ebx, '*'
.mul_ok2:
movzx eax, byte [edi+TLabel.SIBEx+1]
test eax, eax
jz .reg_ok2
stdcall GetRegisterName, eax
stdcall StrCharCat, ebx, eax
.reg_ok2:
mov ecx, ntsHex or ntsUnsigned
test edx, 2 ; is there at least one register?
jz .add_number
mov eax, [edi+TLabel.ValueHi]
test eax, eax
jns .add_sign
mov ecx, ntsHex or ntsSigned
jmp .add_number
.add_sign:
stdcall StrCharCat, ebx, '+'
.add_number:
stdcall NumToStr64, [edi+TLabel.ValueLo], [edi+TLabel.ValueHi], ecx
stdcall StrCharCat, eax, 'h'
stdcall StrCat, ebx, eax
stdcall StrDel, eax
test edx, 1
jz .value_ok
stdcall StrCharCat, ebx, ']'
.value_ok:
mov eax, ebx
jmp .finish
.notdefined:
stdcall StrDup, 'undefined'
jmp .finish
.finish:
mov [esp+4*regEAX], eax
popad
return
endp
proc GetRegisterName, .index
begin
push ecx
mov ecx, [.index]
cmp ecx, $f4
je .eip
cmp ecx, $f8
je .rip
and ecx, $0f
mov eax, [cSIBStrings+4*ecx]
mov ecx, [.index]
shr ecx, 4 ; 2, 4 or 8
mov ch, byte [.index]
and ch, $0f
cmp cl, 2
je .finish
cmp cl, 4
jne .qword
;dword
cmp ch, 8
jb .e_prefix
mov ecx, 'd' shl 16
cmp ch, 10
jb @f
shl ecx, 8
@@:
or eax, ecx
jmp .finish
.e_prefix:
shl eax, 8
mov al, 'e'
jmp .finish
.qword:
cmp ch, 8
jae .finish
shl eax, 8
mov al, 'r'
.finish:
pop ecx
return
.eip:
mov eax, 'eip'
jmp .finish
.rip:
mov eax, 'rip'
jmp .finish
endp
iglobal
cSIBStrings dd 'ax', 'cx', 'dx', 'bx'
dd 'sp', 'bp', 'si', 'di'
dd 'r8', 'r9', 'r10', 'r11'
dd 'r12', 'r13', 'r14', 'r15'
endg
proc CCListProc, .hwnd, .wmsg, .wparam, .lparam
begin
mov ebx, [.wmsg]
dispatch ebx
.ondefault:
stc
return
;-----------------------------------------------------------------------
oncase WM_LBUTTONDBLCLK
invoke GetParent, [.hwnd]
invoke GetPropW, eax, [propOwnerAsmEdit]
invoke PostMessageW, eax, WM_KEYDOWN, VK_RETURN, 0
clc
return
;-----------------------------------------------------------------------
oncase WM_KEYDOWN
mov ebx, [.wparam]
call JumpTo
MessageList \
VK_DOWN, .ondefault, \
VK_UP, .ondefault, \
VK_PRIOR, .ondefault, \
VK_NEXT, .ondefault, \
VK_HOME, .ondefault, \
VK_END, .ondefault
; invoke SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
invoke GetParent, [.hwnd]
invoke GetPropW, eax, [propOwnerAsmEdit]
invoke PostMessageW, eax, [.wmsg], [.wparam], [.lparam]
xor eax, eax
clc
return
enddispatch
endp
proc UpdateCCPosition
.aepos AEPOS
.caret AECARETXY
.rect RECT
; .workrect RECT
.word rw $100
.aedit dd ?
.info MONITORINFO
; benchmark variables
; .time dd ?
; .count dd ?
begin
cmp [hCCList], 0
je .finish
stdcall WaitForCompiler
jc .finish
invoke GetPropW, [hCCList], [propOwnerAsmEdit]
mov [.aedit], eax
lea eax, [.aepos]
invoke SendMessageW, [.aedit], AEM_GETPOS, eax, 0
lea ebx, [.caret]
invoke SendMessageW, [.aedit], AEM_GETCARETXY, ebx, 0
invoke ClientToScreen, [.aedit], ebx
add ebx, 8
invoke ClientToScreen, [.aedit], ebx
sub ebx, 8
lea eax, [.rect]
invoke GetWindowRect, [hCCList], eax
mov eax, [.rect.right]
mov ecx, [.rect.bottom]
sub eax, [.rect.left]
sub ecx, [.rect.top]
mov [.rect.right], eax
mov [.rect.bottom], ecx
invoke MonitorFromWindow, [.aedit], 2
mov [.info.cbSize], sizeof.MONITORINFO
lea ecx, [.info]
invoke GetMonitorInfoW, eax, ecx
mov eax, [.info.rcWork.right]
sub eax, [.rect.right]
mov ecx, [.caret.x0]
cmp eax, ecx
jle @f
mov eax, ecx
@@:
mov edx, [.info.rcWork.bottom]
sub edx, [.rect.bottom]
mov ecx, [.caret.y1]
add ecx, 1
cmp edx, ecx
jg @f
mov ecx, [.caret.y0]
sub ecx, [.rect.bottom]
sub ecx, 2
@@:
invoke SetWindowPos, [hCCList], NULL, eax, ecx, 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOCOPYBITS
lea ebx, [.word]
invoke SendMessageW, [.aedit], AEM_GETWORDATCARET, $100, ebx
stdcall WideCharToUtf8, ebx
mov ebx, eax
cmp word [.word], '.'
jne .localok
cmp [hCCPrefix], 0
jne .prefixok
stdcall SearchForLabelPrefixInEditor, [.aedit], [.aepos.caretLine]
mov [hCCPrefix], eax
.prefixok:
cmp [hCCPrefix], 0
je .localok
stdcall StrInsert, ebx, [hCCPrefix], 0
; here ebx contains a pointer to the whole name including the parent label.
.localok:
stdcall ClearCCList
stdcall SearchTree, ebx, ptrLabels
stdcall StrDel, ebx
test eax, eax
jz .destroycc
mov esi, [eax]
test esi, esi
jz .destroycc
mov ebx, [esi+TArray.count]
lea esi, [esi+TArray.array]
test ebx, ebx
jz .destroycc
mov edi, edx ; The last word
invoke GetWindowLongW, [hCCList], GWL_USERDATA
mov edx, eax
test edx, edx
jz .destroycc
xor ecx, ecx
; benchmark code.
; mov [.count], ecx
; stdcall GetTimestamp
; mov [.time], eax
.fill_loop:
; inc [.count] ; benchmark
mov eax, [esi+TLabel.iName]
test eax, eax
jz .next
add eax, [ptrNames]
stdcall StringMatch, eax, edi, TRUE
jnc .next
stdcall AddArrayItems, edx, 1
mov [eax], esi
inc ecx
cmp ecx, MAX_CCITEMS
jae .end_fill_loop
.next:
add esi, sizeof.TLabel
dec ebx
jnz .fill_loop
.end_fill_loop:
; benchmark code...
; pushad
; stdcall GetTimestamp
; sub eax, [.time]
; stdcall Output, 'Fill loop time:'
; stdcall OutputNumber, eax, 10, 8
; stdcall Output, <' ms ', 13, 10>
;
; stdcall Output, 'Total processed:'
; stdcall OutputNumber, [.count], 10, 8
; stdcall Output, <' records ', 13, 10>
;
; popad
push ecx
invoke SetWindowLongW, [hCCList], GWL_USERDATA, edx
pop ecx
test ecx, ecx
jz .destroycc
invoke SendMessageW, [hCCList], LB_SETCOUNT, ecx
stdcall SelectCCList, edi
stdcall StrDel, edi
invoke SetWindowPos, [hCCList], NULL, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_SHOWWINDOW or SWP_NOACTIVATE
.finish:
return
.destroycc:
invoke PostMessageW, [hCCList], WM_CLOSE, 0, 0
return
endp
; If str1 begins with str2 then returns CF=1
; else CF=0
; preserves all registers.
proc StringMatch, .str1, .str2, .empty
begin
push esi edi eax
mov esi, [.str1]
mov edi, [.str2]
.loop:
mov al, [edi]
lea edi, [edi+1]
test al,al
jz .match
mov ah, [esi]
lea esi, [esi+1]
test ah,ah
jz .notmatch
or eax, $2020
cmp al,ah
je .loop
.notmatch:
clc
pop eax edi esi
return
.match:
cmp byte [.empty], al ; al is always 0 here
jne .yesmatch
cmp esi, [.str1]
je .notmatch
.yesmatch:
stc
pop eax edi esi
return
endp
; searches the preprocessed source for the last global label definition before the
; specified line in the file. Returns the name of this label as a string in eax.
; If such label is not found, returns eax=0
proc SearchForLabelPrefixInEditor, .editor, .caretY
begin
push ecx edx
stdcall GetEditorFile, [.editor]
test eax, eax
jz @f
stdcall SearchForLabelPrefix, [eax+TOpenFile.hFileName], [.caretY]
@@:
pop edx ecx
return
endp
; searches the preprocessed source for the last global label definition before the
; specified line in the file. Returns the name of this label as a string in eax.
; If such label is not found, returns eax=0
proc SearchForLabelPrefix, .hFilename, .line
begin
push edx esi
stdcall SearchFileInGlobalIndex, [.hFilename]
jc .not_found
mov esi, eax ; pointer to TArray of strinigs for needed file.
mov edx, [.line]
dec edx
cmp edx, [esi+TArray.count]
jb .lineok
mov edx, [esi+TArray.count]
dec edx
.lineok:
mov eax, [esi+TArray.array+4*edx] ; handle to the global label name
test eax, eax
jz .not_found
pop esi edx
clc
return
.not_found:
pop esi edx
stc
return
endp
struct TGlobalIndexItem
.iFilename dd ?
.ptrLines dd ?
ends
proc FreeGlobalIndex
begin
push eax ecx esi
mov esi, [ptrGlobalsList]
test esi, esi
jz .finish
mov ecx, [esi+TArray.count]
.loop:
dec ecx
js .end_free
mov eax, [esi+TArray.array + sizeof.TGlobalIndexItem * ecx + TGlobalIndexItem.ptrLines]
test eax, eax
jz .loop
stdcall FreeMem, eax
jmp .loop
.end_free:
stdcall ListFree, [esi+TArray.lparam], StrDel
stdcall FreeMem, esi
mov [ptrGlobalsList], 0
.finish:
pop esi ecx eax
return
endp
proc CreateGlobalIndex
.end dd ?
.current dd ? ; handle of string with the current root label.
.fLabel dd ?
.fSkip dd ?
begin
pushad
stdcall FreeGlobalIndex
mov [.current], 0
stdcall CreateArray, sizeof.TGlobalIndexItem
mov [ptrGlobalsList], eax
mov esi, eax
stdcall CreateArray, 4
mov [esi+TArray.lparam], eax ; array with all defined strings for later free.
mov esi, [ptrPreprocessed]
mov eax, [lenPreprocessed]
add eax, esi
mov [.end], eax
test esi, esi
jz .finish
; start of a preprocessor line...
.line_loop:
cmp esi, [.end]
jae .end_of_file
test [esi+TIntLine.LineNumber], $80000000
jnz .process_line ; this line is generated by macro and thus is nor in the source.
stdcall SearchInGIndex, [ptrGlobalsList], [esi+TIntLine.ofsGenerator]
jnc .fileok
stdcall AddArrayItems, [ptrGlobalsList], 1
mov [ptrGlobalsList], edx
.fileok:
mov edi, eax
mov eax, [esi+TIntLine.ofsGenerator]
mov [edi+TGlobalIndexItem.iFilename], eax
mov eax,[edi+TGlobalIndexItem.ptrLines]
test eax, eax
jnz .linesok
stdcall CreateArray, 4
mov [edi+TGlobalIndexItem.ptrLines], eax
.linesok:
mov edx, eax
mov eax, [esi+TIntLine.LineNumber]
sub eax, [edx+TArray.count]
jb .this_line_ok
stdcall AddArrayItems, edx, eax
mov [edi+TGlobalIndexItem.ptrLines], edx
.this_line_ok:
mov eax, [esi+TIntLine.LineNumber]
dec eax
lea edi, [edx+TArray.array+4*eax] ; pointer to the memory for the global label string.
.process_line:
add esi, sizeof.TIntLine
mov [.fLabel], 0
mov [.fSkip], 0
.pre_loop:
lodsb
cmp al, $1a
je .symbol
cmp al, $22
je .string
cmp al, $3b
je .preprocessor
test al, al
jnz .pre_loop
; line end...
mov eax, [.current]
mov [edi], eax
jmp .line_loop
.preprocessor:
mov [.fSkip], 1
.symbol:
movzx eax, byte [esi]
lea esi, [esi+1]
mov ebx, esi
add esi, eax
cmp [.fSkip], 0
jne .pre_loop
cmp [.fLabel], 0
jne .label_name
cmp byte [esi], ':' ; this symbol is label, so check it.
je .label_name
call .check_for_dd
jc .label_name
cmp eax, 5
jne .pre_loop
mov eax, [ebx]
or eax, $20202020
cmp eax, 'labe'
jne .pre_loop
mov al, [ebx+4]
or al, $20
cmp al, 'l'
jne .pre_loop
mov [.fLabel], 1
jmp .pre_loop
.label_name:
mov [.fSkip], 1 ; after processing the label name, skip to the end of the line.
cmp byte [ebx], '.' ; it is local label
je .pre_loop
cmp word [ebx], '@@'
je .pre_loop
mov ecx, eax
stdcall StrNew
mov [.current], eax
stdcall StrCopyPart, eax, ebx, 0, ecx
; save the string in one place for later free.
push eax
mov ecx, [ptrGlobalsList]
stdcall AddArrayItems, [ecx+TArray.lparam], 1
mov [ecx+TArray.lparam], edx
pop dword [eax]
mov [.fLabel], 0
jmp .pre_loop
.string:
lodsd
add esi, eax
jmp .pre_loop
; check for data definition directive
.check_for_dd:
push eax
cmp byte [esi], $1a
jne .no_dd
cmp byte [esi+1], 4
jne .no_file
mov eax, [esi+2]
or eax, $20202020
cmp eax, 'file'
jne .no_dd
.yes_dd:
pop eax
stc
retn
.no_file:
cmp byte [esi+1], 2
jne .no_dd
mov ax, [esi+2]
or ax, $2020
cmp ax, 'rb'
je .yes_dd
cmp ax, 'rw'
je .yes_dd
cmp ax, 'rd'
je .yes_dd
cmp ax, 'rp'
je .yes_dd
cmp ax, 'rf'
je .yes_dd
cmp ax, 'rq'
je .yes_dd
cmp ax, 'rt'
je .yes_dd
cmp ax, 'db'
je .yes_dd
cmp ax, 'dw'
je .yes_dd
cmp ax, 'du'
je .yes_dd
cmp ax, 'dd'
je .yes_dd
cmp ax, 'dp'
je .yes_dd
cmp ax, 'df'
je .yes_dd
cmp ax, 'dq'
je .yes_dd
cmp ax, 'dt'
je .yes_dd
.no_dd:
pop eax
clc
retn
.end_of_file:
.finish:
popad
return
endp
proc SearchInGIndex, .ptrGIndex, .value
begin
push ecx esi
mov esi, [.ptrGIndex]
mov ecx, [esi+TArray.count]
.loop:
dec ecx
js .not_found
mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.iFilename]
cmp eax, [.value]
jne .loop
.found:
lea eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx]
pop esi ecx
return
.not_found:
stc
pop esi ecx
return
endp
proc SearchFileInGlobalIndex, .hFilename
begin
push ecx esi
mov esi, [ptrGlobalsList]
test esi, esi
jz .not_found
mov ecx, [esi+TArray.count]
.loop:
dec ecx
js .not_found
mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.iFilename]
test eax, eax
jnz .fileok
mov eax, [ptrMainFilename]
jmp .compare
.fileok:
add eax, [ptrPreprocessed]
.compare:
stdcall StrCompFilename, eax, [.hFilename]
jnc .loop
; equal files
mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.ptrLines]
test eax, eax
jz .not_found
clc
pop esi ecx
return
.not_found:
xor eax, eax
stc
pop esi ecx
return
endp
proc StrCompFilename, .hName1, .hName2
begin
pushad
stdcall GetFullPathNameUtf8, [.hName1]
mov [.hName1], eax
stdcall StrPtr, eax
mov esi, eax
mov ecx, [esi+string.len]
stdcall GetFullPathNameUtf8, [.hName2]
mov [.hName2], eax
stdcall StrPtr, eax
mov edi, eax
cmp ecx, [edi+string.len]
jne .not_equal
jecxz .equal
.loop:
mov al, [esi]
mov ah, [edi]
lea esi, [esi+1]
lea edi, [edi+1]
; cmp al, '\'
; jne @f
; mov al, '/'
;
;@@:
; cmp ah, '\'
; jne @f
; mov ah, '/'
;@@:
cmp al, $41
jb @f
cmp al, $5f
ja @f
add al, $20
@@:
cmp ah, $41
jb @f
cmp ah, $5f
ja @f
add ah, $20
@@:
cmp al, ah
jne .not_equal
loop .loop
.equal:
stc
popad
return
.not_equal:
clc
popad
return
endp