proc OnUnrollLine, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .not_in_editor

        mov     ebx, eax

        stdcall GetEditorCaretPos, ebx  ; returns edx=caret line.

        stdcall GetEditorFile, ebx
        test    eax, eax
        jz      .not_in_editor

        stdcall UnrollMacro, [eax+TOpenFile.hFileName], edx
        jc      .error

        stdcall SetListerText, eax
        stdcall StrDel, eax
        return

.not_in_editor:
        stdcall ErrorMessage, errSourceEditor
        return

.error:
        test    eax, eax
        jz      @f
        stdcall ErrorMessage, errNotCompiled
@@:
        return
endp

; Searches the preprocessed lines of the last compilation for
; line iLine of the source file hFilename and returns a pointer
; to this line or CF=1 if not found.
; returns the end address of the preprocessed source in ECX
; if the source is not compiled, returns EAX=-1
; if the line was not found EAX=0

proc FindPreprocessedLine, .hFilename, .iLine
begin
        push    esi

        mov     esi, [ptrPreprocessed]  ; pointer to the preprocessed file.

        test    esi, esi
        jz      .not_compiled

        mov     ecx, [lenPreprocessed]
        add     ecx, esi

.search_loop:
        cmp     esi, ecx
        jae     .not_found

        mov     eax, [esi+TIntLine.LineNumber]
        cmp     eax, [.iLine]
        jne     .skip_line

        mov     eax, [esi+TIntLine.ofsGenerator]
        test    eax, eax
        jnz     .cmp_filename

        mov     eax, [ptrMainFilename]
        sub     eax, [ptrPreprocessed]

.cmp_filename:
        add     eax, [ptrPreprocessed]

        stdcall StrDupMem, eax
        push    eax
        stdcall StrNormalizePath, eax, '\/'
        stdcall StrPtr, eax

        stdcall StrCompNoCase, eax, [.hFilename]
        stdcall StrDel ; from the stack
        jc      .name_match

.skip_line:
        lea     esi, [esi+TIntLine.PreprocessedLine]

.skip_loop:
        lodsb
        test    al, al
        jz      .search_loop

        cmp     al, $1a
        je      .token
        cmp     al, $3b
        je      .token
        cmp     al, $22
        jne     .skip_loop

        lodsd
        add     esi, eax
        jmp     .skip_loop

.token:
        lodsb
        movzx   eax, al
        add     esi, eax
        jmp     .skip_loop

.name_match:
        mov     eax, esi
        clc
        pop     esi
        return


.not_compiled:
        or      eax, -1
        jmp     .error

.not_found:
        xor     eax, eax

.error:
        stc
        pop     esi
        return


endp




proc UnrollMacro, .hFilename, .iLine
.file dd ?
.line dd ?
begin
        pushad

        stdcall FindPreprocessedLine, [.hFilename], [.iLine]
        jc      .error

        mov     esi, eax

        mov     eax, [esi+TIntLine.ofsGenerator]
        mov     edx, [esi+TIntLine.LineNumber]
        mov     [.file], eax
        mov     [.line], edx

        stdcall StrNew
        mov     edi, eax

.unroll_loop:
        cmp     esi, ecx                ; the end of the preprocessed source.
        jae     .end_unroll

        stdcall RestoreSourceLine, esi, '+'
        mov     ebx, eax

        stdcall StrLen, ebx
        test    eax, eax
        jz      .line_ok

        stdcall ___IndentLine, edi, esi
        stdcall StrCat, edi, ebx
        stdcall StrCat, edi, cCRLF

.line_ok:
        mov     esi, edx
        stdcall StrDel, ebx

        test    [esi+TIntLine.LineNumber], $80000000    ; is it macro generated?
        jnz     .unroll_loop

        mov     eax, [.file]
        cmp     eax, [esi+TIntLine.ofsGenerator]
        jne     .end_unroll

        mov     eax, [.line]
        cmp     eax, [esi+TIntLine.LineNumber]
        je      .unroll_loop

.end_unroll:
        mov     [esp+4*regEAX], edi
        popad
        clc
        return

.error:
        mov     [esp+4*regEAX], eax
        popad
        stc
        return
endp



proc ___IndentLine, .hString, .ptrPreprocessed
begin
        pushad

        mov     esi, [.ptrPreprocessed]
        mov     edx, $2020

.indent_loop:
        test    [esi+TIntLine.LineNumber], $80000000
        jz      .end_indent

        stdcall StrCharCat, [.hString], edx

        mov     esi, [esi+TIntLine.ofsSourceLine]
        add     esi, [ptrPreprocessed]
        jmp     .indent_loop

.end_indent:
        popad
        return
endp





; Not used - for debug purposses only.


proc OnDumpPreprocessed
begin
        pushad

        mov     esi, [ptrPreprocessed]
        mov     ebx, [lenPreprocessed]
        add     ebx, esi

        stdcall StrNew
        mov     edi, eax

.dump_pre:
        cmp     esi, ebx
        jae     .finalize

        mov     eax, esi
        sub     eax, [ptrPreprocessed]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth or ntsUnsigned + 8
        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, ': '
        stdcall StrDel, eax

        stdcall NumToStr, [esi+TIntLine.ofsGenerator], ntsHex or ntsFixedWidth or ntsUnsigned + 8
        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, ', '
        stdcall StrDel, eax

        stdcall NumToStr, [esi+TIntLine.LineNumber], ntsHex or ntsFixedWidth or ntsUnsigned + 8
        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, ', '
        stdcall StrDel, eax

        stdcall NumToStr, [esi+TIntLine.ofsSourceLine], ntsHex or ntsFixedWidth or ntsUnsigned + 8
        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, ', '
        stdcall StrDel, eax

        stdcall NumToStr, [esi+TIntLine.ofsMacroLine], ntsHex or ntsFixedWidth or ntsUnsigned + 8
        stdcall StrCat, edi, eax
        stdcall StrCharCat, edi, '>'
        stdcall StrDel, eax

        stdcall RestoreSourceLine, esi, 0
        stdcall StrCat, edi, eax
        stdcall StrDel, eax

        stdcall StrCharCat, edi, $0a0d

        mov     esi, edx        ; next preprocessed line, returned by RestoreSourceLine
        jmp     .dump_pre

.finalize:
        stdcall StrPtr, edi
        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, eax

.finish:
        popad
        return

        stdcall UnrollMacro, 0, 0
        return
endp


