flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
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 |
|||||||||||||||||||||
![]() |
|
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 ... |
|||
![]() |
|
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. |
|||
![]() |
|
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 |
|||
![]() |
|
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.
|
|||
![]() |
|
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 |
|||
![]() |
|
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? |
|||
![]() |
|
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 |
|||
![]() |
|
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 |
|||
![]() |
|
revolution 15 Dec 2015, 14:19
l_inc wrote: revolution Code: include 'c:\code\uberstuff.inc' ;<--- Linux can open this? |
|||
![]() |
|
idle 15 Dec 2015, 14:24
Forum page wrap, reposting...
http://board.flatassembler.net/topic.php?t=12725&start=19 |
|||
![]() |
|
l_inc 15 Dec 2015, 14:30
revolution
I didn't say, one should use full paths, but your suggestion is to introduce many more limitations. Say there's a library that includes its files using relative paths (similar to win32a.inc). Some files can be included as a part of the library or individually. The relative paths would be different. How restrictive should be your rules to avoid this? That's not mentioning that soft and hard links are possible in both Windows and Linux. Taking that into account shows that C-style inclusion duplication prevention is the only correct way. Just consider what you'd do to compile a project making use of soft links on a system that has no support for them. _________________ Faith is a superposition of knowledge and fallacy |
|||
![]() |
|
revolution 15 Dec 2015, 16:41
l_inc wrote: That's not mentioning that soft and hard links are possible in both Windows and Linux. Taking that into account shows that C-style inclusion duplication prevention is the only correct way. Just consider what you'd do to compile a project making use of soft links on a system that has no support for them. |
|||
![]() |
|
l_inc 15 Dec 2015, 19:16
revolution
I have nothing against some rules of project organization. I'm just saying that the only reason to implement "include once" natively is the ability to unambiguously identify files, and if even this advantage is ignored, then it's just useless. _________________ Faith is a superposition of knowledge and fallacy |
|||
![]() |
|
idle 16 Dec 2015, 06:25
Again, once is a user-typed hint to overcome standard behaviour of fasm.
It does nothing to fasm structures, keeping inclusion order as described in official manual. What it really does: when fasm is just about including a file, once checks for its presence and does its job. |
|||
![]() |
|
idle 21 Nov 2017, 16:55
hi, just updated to 1.72
esp tnx to TG for keeping include logics same |
|||
![]() |
|
idle 23 Feb 2021, 18:38
Damn!..
I'm glad to see you again! According the topic, i solved to automate patching process. The only condition - the Author not to change inclusion logics. Right now it is 2/3 complete. There it is. And the stumble: how to analize preproce.inc guys? Do we need to read&trim lines, or tokenize(that is heavy), extract lexems, how to mind the style (e.g. was movsb, became movs byte [etc]), or should we detect inclusion code and replace it all. I donot know. Tnx! |
|||
![]() |
|
idle 24 Feb 2021, 23:30
|
|||
![]() |
|
edfed 28 Feb 2021, 19:21
include once useless now.
test_it.asm: Code: include 'file_to_include_once.inc' include 'file_that_includes_the_file_to_include_once.inc' call something_from_this_once_file call something_from_the_second_file file_to_include_once.inc: Code: if ~ definite FileToIncludeOnceStillIncluded ... end if FileToIncludeOnceStillIncluded=0 file_that_includes_the_file_to_include_once.inc: Code:
include 'file_that_includes_the_file_to_include_once.inc'
call something_from_the_once_file
definite keyword is a new feature and i like it. |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.