Fresh IDE . Artifact [0198fe7fcf]
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Artifact 0198fe7fcf48b3a88c0d8897844666eb1e624792:



MAX_CCITEMS = 100


uglobal
  hCCList         dd 0
  hCCPrefix       dd 0
endg

idCCList = 763


proc CreateCCList, .parent
begin
        push    ebx

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE, cFormClassName, 0, WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,   \
                                0, 0, 300, 120, 0, 0, [hInstance], 0
        mov     [hCCList], eax
        invoke  SetWindowLongA, [hCCList], GWL_HWNDPARENT, [.parent]
        stdcall SubclassWindow, [hCCList], CCParentProc

        invoke  CreateWindowExA, 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

        invoke  GetStockObject, DEFAULT_GUI_FONT
        invoke  SendMessageA, 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  SendMessageA, [hCCList], LB_GETCURSEL, 0, 0
        add     eax, 1
        jc      .err

        mov     ebx, eax

        invoke  GetWindowLongA, [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  SendMessageA, [hCCList], LB_SETCOUNT, 0, 0

        invoke  GetWindowLongA, [hCCList], GWL_USERDATA

        stdcall FreeMem, eax
        stdcall CreateArray, 4  ; dword array.

        invoke  SetWindowLongA, [hCCList], GWL_USERDATA, eax
        return
endp




proc SelectCCList, .hStr
begin
        push    ebx esi edi

        stdcall StrPtr, [.hStr]
        mov     edi, eax

        invoke  GetWindowLongA, [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

        jnc     .matchloop

        invoke  SendMessageA, [hCCList], LB_SETCURSEL, eax, 0
        clc
        return

.notfound:
        invoke  SendMessageA, [hCCList], LB_SETCURSEL, 0, 0
        stc
        return
endp






winproc CCParentProc
begin
        cmp     ebx, WM_KEYDOWN
        je      .relay

        cmp     ebx, LB_ADDSTRING
        jl      .process
        cmp     ebx, LB_ITEMFROMPOINT
        ja      .process

.relay:
        invoke  SendDlgItemMessageA, [.hwnd], idCCList, [.wmsg], [.wparam], [.lparam]
        clc
        return

.process:

ondefault
        stc
        return

onmessage AM_INITWINDOW
        stdcall CreateArray, 4  ; dword array.
        invoke  SetWindowLongA, [.hwnd], GWL_USERDATA, eax
        clc
        return


onmessage WM_SIZE
        invoke  GetDlgItem, [.hwnd], idCCList
        invoke  InvalidateRect, eax, 0, 0
        xor     eax, eax
        clc
        return


onmessage WM_CLOSE
        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        invoke  SetFocus, eax

        invoke  DestroyWindow, [.hwnd]
        xor     eax, eax
        mov     [hCCList], eax
        clc
        return


onmessage WM_DESTROY
        invoke  GetWindowLongA, [.hwnd], GWL_USERDATA
        stdcall FreeMem, eax
        stc
        return



onmessage 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


onmessage 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, 2          ; 1/4 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  GetWindowLongA, [.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]
        lea     ecx, [.rectL]
        invoke  DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS

  cNotDefined text 'undefined'
  cVirtual    text 'virtual'

; then write the value

        test    [edi+TLabel.flags], lfDefined
        jz      .notdefined

        cmp     [edi+TLabel.SIBEx], 0
        jne     .virtual

        stdcall NumToStr, [edi+TLabel.ValueLo], ntsHex or ntsSigned
        jmp     .printvalue

.notdefined:
        stdcall StrDup, cNotDefined
        jmp     .printvalue

.virtual:
        stdcall StrDup, cVirtual

.printvalue:
        push    eax
        stdcall StrPtr, eax
        lea     ecx, [.rectR]
        invoke  DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER
        stdcall StrDel ; from the stack.

.cleanup:
        invoke  DeleteObject, [.bkbrush]
        or      eax, -1
        clc
        return

endwp







winproc CCListProc
begin

ondefault
        stc
        return

; This makes CCList to never get the focus.
;onmessage WM_SETFOCUS
;        invoke GetParent, [.hwnd]
;        invoke SetFocus, eax
;        xor    eax, eax
;        clc
;        return

;-----------------------------------------------------------------------
onmessage WM_LBUTTONDBLCLK

        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        invoke  PostMessageA, eax, WM_KEYDOWN, VK_RETURN, 0
        clc
        return

;-----------------------------------------------------------------------
onmessage 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  GetWindowLongA, eax, GWL_HWNDPARENT
        invoke  PostMessageA, eax, [.wmsg], [.wparam], [.lparam]
        xor     eax, eax
        clc
        return

endwp




proc UpdateCCPosition
  .aepos    AEPOS
  .caret    AECARETXY
  .rect     RECT
  .workrect RECT
  .prefix   rb    $100
  .word     rb    $100
  .aedit    dd    ?

; benchmark variables
;  .time dd ?
;  .count dd ?
begin
        cmp     [hCCList], 0
        je      .finish

        stdcall WaitForCompiler
        jc      .finish

        invoke  GetWindowLongA, [hCCList], GWL_HWNDPARENT
        mov     [.aedit], eax

        lea     eax, [.aepos]
        invoke  SendMessageA, [.aedit], AEM_GETPOS, eax, 0

        lea     ebx, [.caret]
        invoke  SendMessageA, [.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

        lea     ebx, [.workrect]
        invoke  SystemParametersInfoA, SPI_GETWORKAREA,0,ebx,0

        mov     eax, [.workrect.right]
        sub     eax, [.rect.right]
        mov     ecx, [.caret.x0]
        cmp     eax, ecx
        jle     @f
        mov     eax, ecx
@@:
        mov     edx, [.workrect.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  SendMessageA, [.aedit], AEM_GETWORDATCARET, $100, ebx

        cmp     byte [.word], '.'
        jne     .localok

        cmp     [hCCPrefix], 0
        jne     .prefixok

        stdcall SearchForLabelPrefix, [.aedit], [.aepos.caretLine]
        mov     [hCCPrefix], eax

.prefixok:
        cmp     [hCCPrefix], 0
        je      .localok

        stdcall StrLen, [hCCPrefix]
        mov     ecx, eax
        jecxz   .localok        ; the prefix was not found or there is no prefix.

        stdcall StrPtr, [hCCPrefix]
        lea     esi, [eax+ecx]  ; the end of the string

.copy_prefix:
        dec     esi
        mov     al, [esi]
        dec     ebx
        mov     [ebx], al
        loop    .copy_prefix

; here ebx contains a pointer to the whole name including the parent label.
.localok:
        stdcall ClearCCList

        stdcall SearchTree, ebx, ptrLabels

        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  GetWindowLongA, [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
        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  SetWindowLongA, [hCCList], GWL_USERDATA, edx
        pop     ecx

        test    ecx, ecx
        jz      .destroycc

        invoke  SendMessageA, [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  PostMessageA, [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
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:
        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 SearchForLabelPrefix, .editor, .caretY
begin
        push    edx esi

        stdcall GetEditorFile, [.editor]
        stdcall SearchFileInGlobalIndex, [eax+TOpenFile.hFileName]
        jc      .not_found

        mov     esi, eax        ; pointer to TArray of strinigs for needed file.
        mov     edx, [.caretY]
        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:
        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
        mov     [.fSkip], 1
        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

        mov     eax, [esi+2]
        or      eax, $20202020

        cmp     byte [esi+1], 4
        jne     .no_file

        cmp     eax, 'file'
        jne     .no_dd

.yes_dd:
        pop     eax
        stc
        retn

.no_file:
        cmp     byte [esi+1], 2
        jne     .no_dd

        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
.file1 rb 1024
.file2 rb 1024
.name  dd ?
begin
        pushad

        lea     esi, [.file1]
        lea     edi, [.file2]

        stdcall StrPtr, [.hName1]
        lea     edx, [.name]
        invoke GetFullPathNameA, eax, 1024, esi, edx
        cmp    eax, 1023
        ja     .not_equal
        test   eax, eax
        jz     .not_equal

        mov     ebx, eax

        stdcall StrPtr, [.hName2]
        lea     edx, [.name]
        invoke GetFullPathNameA, eax, 1024, edi, edx
        cmp    eax, 1023
        ja     .not_equal
        test   eax, eax
        jz     .not_equal

        cmp     eax, ebx
        jne     .not_equal

        mov     ecx, ebx
        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