flat assembler
Message board for the users of flat assembler.
Index
> Compiler Internals > include once Goto page 1, 2 Next |
Author |
|
idle 11 Apr 2011, 06:38
edit: download is always located here
hi tomasz, add include's modifier please: Code:
include once 'please.ok?'
Last edited by idle on 15 Dec 2015, 17:37; edited 2 times in total |
|||
11 Apr 2011, 06:38 |
|
revolution 11 Apr 2011, 06:59
|
|||
11 Apr 2011, 06:59 |
|
Tyler 11 Apr 2011, 07:15
revolution wrote: There are already some macros for that here on this board. |
|||
11 Apr 2011, 07:15 |
|
revolution 11 Apr 2011, 07:24
Tyler wrote: I think your link is broken. It doesn't take me to and example... |
|||
11 Apr 2011, 07:24 |
|
idle 11 Apr 2011, 07:25
Quote:
that's what i need |
|||
11 Apr 2011, 07:25 |
|
Tyler 11 Apr 2011, 08:06
What exactly do you want once to do?
|
|||
11 Apr 2011, 08:06 |
|
revolution 11 Apr 2011, 08:18
Tyler wrote: ... revolution's too lazy to teach you. |
|||
11 Apr 2011, 08:18 |
|
idle 11 Apr 2011, 08:52
how that's seen in my mind:
having met include, fasm fetches full path of the file then fasm inspects list of files it has included if no such file included, fasm includes it regardless once presence if a file had been included and once present, fasm does nothing |
|||
11 Apr 2011, 08:52 |
|
Tyler 11 Apr 2011, 09:25
Sounds like you're having the multiple declaration problem that C headers solve with condition preprocessor macros. Doesn't Fasm have those?
|
|||
11 Apr 2011, 09:25 |
|
idle 15 Dec 2015, 10:16
Done.
version.inc controls if the facility or its forms should be included. Scripting approach: Code: v: ub\ '2021.0323 ',10,\ 'www.flatassembler.net/download.php ',10,\ 'www.board.flatassembler.net/topic.php?t=12725',0 align 4 text: rb 1024*1024 && .szMax = $-text-1 ;0byte reserve .szNow = 0 get_fasmdir: ub 'pose to fasm sources directory plz',0 if ~(SelectDirA get_fasmdir text) &&ret&& endif cdA text text ;wanted final call version.inc call variable.inc call preproce.inc pause 'Done!'\ 'Recompile sources' ret preproce.inc: ub 'preproce.inc',0 ;read the file and 0byte terminate it in buffer text.szNow == ReadFileA text preproce.inc 0 text.szMax if text.szNow = -1 && hlt 'preproce.inc read failure' && end if ub[text+text.szNow]=0 ;find preprocessor: label and do patch0 .find0: ub 'preprocessor:',0 .pos == posz 0 0 .find0 text 1 0 if .pos=0 && hlt 'preproce.inc analisys failure' && end if nl.buffer==text && nl.szBuffer==(text.szNow+1) && nl.start==.pos && call nl ui32[opm.argptr+4]=dataseg+.patch0 && call opm.ret if (ShiftInBuffer text text.szNow text.szMax (nl.@stopper-1) opm.eax)<>'ok' && hlt 'reserve more space for text buffer' && end if memcopy (text+nl.@stopper-1) opm.buffer opm.eax text.szNow == text.szNow + opm.eax ;find include_file: label and do patch1 .find1: ub 'include_file:',0 .pos == posz strings.flagREVERSE 0 .find1 text 1 0 if .pos=0 && hlt 'preproce.inc analisys failure' && end if nl.buffer==text && nl.szBuffer==(text.szNow+1) && nl.start==.pos && call nl ui32[opm.argptr+4]=dataseg+.patch1 && call opm.ret text.szNow == nl.@stopper-1 + opm.eax if text.szNow>text.szMax && hlt 'reserve more space for text buffer' && end if memcopy (text+nl.@stopper-1) opm.buffer (opm.eax+1) ;+0byte ;write... aaaah if (WriteFileA text preproce.inc 0 text.szNow)<>text.szNow && hlt 'preproce.inc write failure' && end if ret .patch0: ub\ \'preprocessor: ',10,\ ';Tomasz, keep include_file: logics same and trailing the file plz! ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_ONCE <> 0 ',10,\ ' mov [includes.count],0 ;redundant, rather informal ',10,\ ' mov [includes.files],0 ;last include is none yet ',10,\ 'end if ',0 .patch1: ub\ \'include_file: ',10,\ ' lods byte [esi] ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_ONCE <> 0 ',10,\ ' mov byte[includes.flags],al ;remember include form ',10,\ ' cmp al,1Ah ',10,\ ' jne common_include ;no once key ',10,\ ' lodsb ',10,\ ' cmp al,4 ',10,\ ' jne invalid_argument ;length("once")=4 ',10,\ ' lodsd ',10,\ ' or eax," " ;case ignorant ',10,\ ' cmp eax,"once" ',10,\ ' jne invalid_argument ;no once key ',10,\ ' lodsb ;resume common include ',10,\ ' common_include: ',10,\ 'end if ',10,\ ' cmp al,22h ',10,\ ' jne invalid_argument ',10,\ ' lods dword [esi] ',10,\ ' cmp byte [esi+eax],0 ',10,\ ' jne extra_characters_on_line ',10,\ ' push esi ',10,\ ' push edi ',10,\ ' mov ebx,[current_line] ',10,\ ' find_current_file_path: ',10,\ ' mov esi,[ebx] ',10,\ ' test byte [ebx+7],80h ',10,\ ' jz copy_current_file_path ',10,\ ' mov ebx,[ebx+8] ',10,\ ' jmp find_current_file_path ',10,\ ' copy_current_file_path: ',10,\ ' lods byte [esi] ',10,\ ' stos byte [edi] ',10,\ ' or al,al ',10,\ ' jnz copy_current_file_path ',10,\ ' cut_current_file_name: ',10,\ ' cmp edi,[esp] ',10,\ ' je current_file_path_ok ',10,\ ' cmp byte [edi-1],"\" ',10,\ ' je current_file_path_ok ',10,\ ' cmp byte [edi-1],"/" ',10,\ ' je current_file_path_ok ',10,\ ' dec edi ',10,\ ' jmp cut_current_file_name ',10,\ ' current_file_path_ok: ',10,\ ' mov esi,[esp+4] ',10,\ ' call expand_path ',10,\ ' pop edx ',10,\ ' mov esi,edx ',10,\ ' call open ',10,\ ' jnc include_path_ok ',10,\ ' mov ebp,[include_paths] ',10,\ ' try_include_directories: ',10,\ ' mov edi,esi ',10,\ ' mov esi,ebp ',10,\ ' cmp byte [esi],0 ',10,\ ' je try_in_current_directory ',10,\ ' push ebp ',10,\ ' push edi ',10,\ ' call get_include_directory ',10,\ ' mov [esp+4],esi ',10,\ ' mov esi,[esp+8] ',10,\ ' call expand_path ',10,\ ' pop edx ',10,\ ' mov esi,edx ',10,\ ' call open ',10,\ ' pop ebp ',10,\ ' jnc include_path_ok ',10,\ ' jmp try_include_directories ',10,\ ' mov edi,esi ',10,\ ' try_in_current_directory: ',10,\ ' mov esi,[esp] ',10,\ ' push edi ',10,\ ' call expand_path ',10,\ ' pop edx ',10,\ ' mov esi,edx ',10,\ ' call open ',10,\ ' jc file_not_found ',10,\ ' include_path_ok: ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_WINAPI_FIX_FASM_BACKSEEK_BUG <> 0 ',10,\ ' sub esp,8+260 ',10,\ ' mov eax,esp ',10,\ ' invoke GetFullPathName,esi,260,eax,0 ',10,\ ' lea ecx,[eax+0] ;-->-----------\ ',10,\ ' mov esi,esp ;-->--\ ; ',10,\ ' add esp,8+260 ; ; ',10,\ 'end if ; ; ',10,\ ' mov edi,[esp] ; ; ',10,\ ' copy_preprocessed_path: ; ; ',10,\ ' lods byte [esi] ;<-/ ; ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_ONCE <> 0 ',10,\ ' movzx eax,al ; ',10,\ ' mov al,[upper_case_table+eax] ; ',10,\ 'end if ; ',10,\ ' stos byte [edi] ; ',10,\ ' or al,al ; ',10,\ ' jnz copy_preprocessed_path ; ',10,\ ' pop esi ; ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_WINAPI_FIX_FASM_BACKSEEK_BUG = 0 ',10,\ ' lea ecx,[edi-1] ; ',10,\ ' sub ecx,esi ;<-/ ',10,\ 'end if ',10,\ ' mov [esi-4],ecx ',10,\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_ONCE <> 0 ',10,\ ' mov [esp-8],edi ',10,\ ' ;[esp-4] =FullName ',10,\ ' ;[esp-8] =beyond FullName0 ',10,\ ' ;[FullName-4]=length(FullName) ',10,\ ' cmp byte[includes.flags],1Ah ',10,\ ' jne .include_file ',10,\ ' mov edx,includes.files-4 ',10,\ ' .match_next_include: ',10,\ ' add edx,4 ',10,\ ' mov edi,[edx] ',10,\ ' test edi,edi ',10,\ ' jz .include_file ',10,\ ' mov esi,[esp-4] ',10,\ ' mov ecx,[esi-4] ',10,\ ' cmp ecx,[edi-4] ',10,\ ' jne .match_next_include ',10,\ ' repe cmpsb ',10,\ ' jne .match_next_include ',10,\ ' .!include_file: ',10,\ ' call close ',10,\ ' mov edi,[current_line] ',10,\ ' mov byte[edi],0 ',10,\ ' jmp line_preprocessed ',10,\ ' .include_file: ',10,\ ' mov edi,[includes.count] ',10,\ ' lea edi,[includes.files+edi*4] ',10,\ ' cmp edi,includes.limit ',10,\ ' je out_of_memory ',10,\ ' inc [includes.count] ',10,\ ' mov esi,[esp-4] ',10,\ ' mov [edi],esi ',10,\ ' mov [edi+4],dword 0 ',10,\ ' mov edi,[esp-8] ',10,\ ' if INCLUDEONCE.DO and INCLUDEONCE.DO_WINAPI_LIST_INCLUDES = INCLUDEONCE.DO_WINAPI_LIST_INCLUDES ',10,\ ' jmp .list_includes_after_any_include_4_debug_purpose ',10,\ ' .includes_file : db "includes.txt",0 ',10,\ ' .includes_count: db "dword[includes.count] = %u",10,10,0 ',10,\ ' .list_includes_after_any_include_4_debug_purpose: ',10,\ ' pusha ',10,\ ' lea ebp,[esp+7*4] ;@eax, no matter, winapi needs ioResult pointer ',10,\ ' invoke CreateFile,.includes_file,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0',10,\ ' mov ebx,eax ',10,\ ' ',10,\ ' sub esp,260 ',10,\ ' mov esi,esp ',10,\ ' cinvoke wsprintf,esi,.includes_count,[includes.count] ',10,\ ' invoke WriteFile,ebx,esi,eax,ebp,0 ',10,\ ' add esp,260 ',10,\ ' ',10,\ ' mov edi,includes.files-4 ',10,\ ' .liaai4dp.loop: ',10,\ ' add edi,4 ',10,\ ' mov esi,[edi] ',10,\ ' test esi,esi ',10,\ ' jz .liaai4dp.loop. ',10,\ ' mov ecx,[esi-4] ',10,\ ' mov byte[esi+ecx],10 ',10,\ ' push ecx ',10,\ ' inc ecx ',10,\ ' invoke WriteFile,ebx,esi,ecx,ebp,0 ',10,\ ' pop ecx ',10,\ ' mov byte[esi+ecx],0 ',10,\ ' jmp .liaai4dp.loop ',10,\ ' .liaai4dp.loop.: ',10,\ ' ',10,\ ' invoke CloseHandle,ebx ',10,\ ' popa ',10,\ ' end if ',10,\ 'end if ',10,\ ' push dword [macro_status] ',10,\ ' and [macro_status],0Fh ',10,\ ' call preprocess_file ',10,\ ' pop eax ',10,\ ' and al,0F0h ',10,\ ' and [macro_status],0Fh ',10,\ ' or [macro_status],al ',10,\ ' jmp line_preprocessed ',0 pose_next_line: && nl: if .szBuffer=0 | .start=0 | .start>.szBuffer &&ret&& end if .@stopper == .start-1 while .@stopper < .szBuffer .stopper == ub[.buffer+.@stopper] .@stopper == .@stopper+1 if .stopper=0 | .stopper=10 | .stopper=13 &&ret&& end if end while ret ;caller inits vars .buffer = ;memory .szBuffer = ;its size including 0byte .start = ;1+ ;caller receives .@stopper = ;1+ .stopper = ;0byte|LF|CR variable.inc: ub 'variable.inc',0 text.szNow == ReadFileA text variable.inc 0 text.szMax if text.szNow = -1 hlt 'variable.inc read failure' end if ub[text+text.szNow]=0 .patch0: ub\ 'if INCLUDEONCE.DO and INCLUDEONCE.DO_ONCE <> 0 ',10,\ 'align 4 ',10,\ 'includes: ',10,\ ' .flags rd 1 ',10,\ ' .count rd 1 ',10,\ ' .files rd $ffff ',10,\ ' .limit rd 1 ',10,\ 'end if ',0 ui32[opm.argptr+4]=dataseg+.patch0 && call opm.ret if (ShiftInBuffer text text.szNow text.szMax text.szNow opm.eax)<>'ok' hlt 'reserve more space for text buffer' end if memcopy (text+text.szNow) opm.buffer opm.eax text.szNow == text.szNow + opm.eax if (WriteFileA text variable.inc 0 text.szNow) = -1 hlt 'variable.inc write failure' end if ret version.inc: ub 'version.inc',0 text.szNow == ReadFileA text version.inc 0 text.szMax if text.szNow = -1 hlt 'version.inc read failure' end if ub[text+text.szNow]=0 if (posz 0 0 opm text 1 0)<>0 hlt 'seems already patched' end if .patch0: ub\ 'virtual at 0 ',10,\ 'INCLUDEONCE: ',10,\ ' .DO_ONCE = 001b ',10,\ ' .DO_WINAPI_FIX_FASM_BACKSEEK_BUG = 010b ',10,\ ' .DO_WINAPI_LIST_INCLUDES = 100b or .DO_ONCE ',10,\ ' .DO = .DO_ONCE or .DO_WINAPI_FIX_FASM_BACKSEEK_BUG or .DO_WINAPI_LIST_INCLUDES',10,\ 'display 13,10,"INCLUDEONCE.DO=",.DO+"0" ',10,\ 'end virtual ',0 ui32[opm.argptr+4]=dataseg+.patch0 && call opm.ret if (ShiftInBuffer text text.szNow text.szMax text.szNow opm.eax)<>'ok' hlt 'reserve more space for text buffer' end if memcopy (text+text.szNow) opm.buffer opm.eax text.szNow == text.szNow + opm.eax if (WriteFileA text version.inc 0 text.szNow) = -1 hlt 'version.inc write failure' end if ret once_patch_marker: && opm: ub ';;include once (fasm patch autogen)',0 .format: ub 10,'%s',10,'%s',10,'%s',0 align 4 .buffer: rb 1'0000h && .szBuffer = $-.buffer .argptr: ui32 dataseg+opm,,dataseg+opm .ret: .eax == printfA .buffer .szBuffer .format .argptr ret
Last edited by idle on 17 Dec 2023, 19:37; edited 16 times in total |
|||||||||||||||||||||
15 Dec 2015, 10:16 |
|
revolution 15 Dec 2015, 11:18
Good job. I like to see small modifications like this.
Can you post just the differences (a patch type file) only? Also, I didn't try it, but can the first instance of a file also use the "once" syntax? That is: do users need to worry about which include statement is the first, or can they just make everything "include once"? |
|||
15 Dec 2015, 11:18 |
|
idle 15 Dec 2015, 12:06
>>Good job. I like to see small modifications like this.
:) >>Can they just make everything "include once"? They can. >>Can you post just the differences (a patch type file) only? version.inc Code: ... ;; INCLUDEONCE=1 display 13,10,'INCLUDEONCE=',INCLUDEONCE+'0' ;; ... variable.inc Code: ... if INCLUDEONCE=1 ;; change with care align 4 includes: .flags rd 1 .count rd 1 .files rd $ff .limit rd 1 ;; end if ... preproce.inc Code: ... if INCLUDEONCE=1 ;; mov [includes.count],eax mov [includes.files],eax ;last include is none yet ;; end if ... if INCLUDEONCE=1 ;; mov byte[includes.flags],al ;remember include form cmp al,1Ah jne common_include ;no once key lodsb cmp al,4 jne invalid_argument ;length('once') must be 4 :) lodsd or eax,' ' ;case ignorant cmp eax,'once' jne invalid_argument ;no once key lodsb ;resume common include :) common_include: ;; end if ... if INCLUDEONCE=1 ;; movzx eax,al mov al,[upper_case_table+eax] ;; end if ... if INCLUDEONCE=1 ;; mov [esp-8],edi ;[esp-4] =FullName ;[esp-8] =beyond FullName0 ;[FullName-4]=length(FullName) cmp byte[includes.flags],1Ah jne .include_file mov edx,includes.files-4 .match_next_include: add edx,4 mov edi,[edx] test edi,edi jz .include_file mov esi,[esp-4] ;sub esp,8 ;push edx ;invoke MessageBox,0,edi,esi,0 ;pop edx ;add esp,8 mov ecx,[esi-4] cmp ecx,[edi-4] jne .match_next_include repe cmpsb jne .match_next_include .!include_file: call close mov edi,[current_line] mov byte[edi],0 jmp line_preprocessed .include_file: mov edi,[includes.count] lea edi,[includes.files+edi*4] cmp edi,includes.limit je out_of_memory inc [includes.count] mov esi,[esp-4] mov [edi],esi mov [edi+4],dword 0 mov edi,[esp-8] ;; end if ... |
|||
15 Dec 2015, 12:06 |
|
revolution 15 Dec 2015, 12:53
Just some things I think people should be aware of before they decide to use it:
There is a limit of 254 files plus one pointer that must be kept as zero to terminate the search. Also the path and case must be specified exactly the same else it won't match. Code: include once 'abc.inc' ;... include once 'ABC.INC' ;<--- on Windows this is the same file. ;... include once '.\abc.inc' ;<--- the same file again but not matched. |
|||
15 Dec 2015, 12:53 |
|
l_inc 15 Dec 2015, 13:12
revolution wrote: Also the path and case must be specified exactly the same else it won't match. Well, then the patch is no-go. It's quite controversial by itself, whether it is a responsibility of the includer or the includee to ensure unique inclusion, or how "include once" should behave in relation to the normal include. And if it doesn't even make use of smth. like GetFileInformationByHandle, it's no better than the existing macros doing the same. In the current implementation it's actually worse. _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Dec 2015, 13:12 |
|
revolution 15 Dec 2015, 13:21
I don't see why it is worse. But anyhow, knowing the limitations should be enough. Users can then decide if it is fit for their purpose(s). Having some sort of coding standard documentation for specifying file paths could help to avoid problems in one's code.
|
|||
15 Dec 2015, 13:21 |
|
l_inc 15 Dec 2015, 13:45
revolution
Quote: I don't see why it is worse. There's at least one technical reason (you mentioned) for that: the limit of 254 files. And the conceptual reason is that macros give more flexibility. E.g., if you have a (say "legacy") project using only include, then you can use my includecheck (it can be improved using irpv) to avoid include duplication without having to refactor the project. Quote: Having some sort of coding standard documentation for specifying file paths could help to avoid problems in one's code. And why should one introduce such a limitation for a native solution, if it is (contrary to macros) possible to avoid it? _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Dec 2015, 13:45 |
|
revolution 15 Dec 2015, 13:59
l_inc wrote: And why should one introduce such a limitation for a native solution, if it is (contrary to macros) possible to avoid it? |
|||
15 Dec 2015, 13:59 |
|
l_inc 15 Dec 2015, 14:04
revolution
Quote: Because Linux, Unix and Windows would break the code in different ways due to case and path differences. Provide an example. Without it it seems you are just ignoring what I say. _________________ Faith is a superposition of knowledge and fallacy |
|||
15 Dec 2015, 14:04 |
|
idle 15 Dec 2015, 14:11
Files limit can migrate from $ff=255 -> $ffff=65535 :)
edit: look there to see how candidates are operated on https://board.flatassembler.net/topic.php?t=12725&start=10 Last edited by idle on 23 Mar 2021, 21:27; edited 1 time in total |
|||
15 Dec 2015, 14:11 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.