flat assembler
Message board for the users of flat assembler.
Index
> Main > Macro: string comparison and sort |
Author |
|
comrade 18 Feb 2004, 04:52
Possible? Would be nice for PE export macro to automatically sort exports alphabetically.
|
|||
18 Feb 2004, 04:52 |
|
comrade 18 Feb 2004, 14:54
Code: macro strcmp str1, str2 { local ..count,..x,..char1,..char2 strcmpr = 0 virtual at 0 db str1 ..count = $ end virtual virtual at 0 db str1 ..x = $ db str2 repeat ..count load ..char1 from %-1 load ..char2 from ..x+%-1 if strcmpr = 0 strcmpr = ..char1 - ..char2 end if end repeat end virtual } macro doshit str1, str2 { strcmp str1, str2 if strcmpr > 0 db "str1 > str2" else if strcmpr < 0 db "str1 < str2" else db "str1 = str2" end if } input: doshit "abc","def" db 0 input will contain "str1 < str2" now second part - to sort |
|||
18 Feb 2004, 14:54 |
|
Tommy 18 Feb 2004, 15:05
Cool!
|
|||
18 Feb 2004, 15:05 |
|
Joshua 18 Feb 2004, 17:49
these macros i use for named resource sections. They must be sorted so you can extract the sorting mechanism (it's a bubble sort). It is limited to 7 byte strings!
Code: macro directory [type,label] { common local ..c,..i,..j,..l,..m,..s,..t,..idcount,..namecount,..names,..offset macro TEMP_RESOURCE_GET c,i,s,l m^ i = ..Temp_ResourceId $$ c s = ..Temp_ResourceSize $$ c l = ..Temp_ResourceLabel $$ c ^m macro TEMP_RESOURCE_SET c,i,s,l m^ ..Temp_ResourceId $$ c = i ..Temp_ResourceSize $$ c = s ..Temp_ResourceLabel $$ c = l ^m ..c fix 1 ..namecount = 0 ..idcount = 0 if ~<type><label> eq <><> forward if type eqtype "" virtual at 0 db type ..s = $ times 8 db 0 ..i = -1 repeat 7 load ..j byte from %-1 ..i = (..i shl 8)+(..j and not 32) end repeat end virtual ..namecount = ..namecount+1 TEMP_RESOURCE_SET ..c,..i,..s,label TEMP_RESOURCE_GET ..c,..i,..s,..l else if type eqtype 0 ..idcount = ..idcount+1 TEMP_RESOURCE_SET ..c,type,0,label end if ..c fix ..c#1 common TEMP_RESOURCE_SET ..c,100000000h,..idcount+..namecount+1,0 repeat ..namecount+..idcount-1 ..c fix 1 forward TEMP_RESOURCE_GET ..c,..i,..s,..l TEMP_RESOURCE_GET ..c#1,..j,..t,..m if ..i > ..j TEMP_RESOURCE_SET ..c,..j,..t,..m TEMP_RESOURCE_SET ..c#1,..i,..s,..l end if ..c fix ..c#1 common end repeat ..ResourceRoot dd 0,%t,0,(..idcount shl 16)+..namecount ..names = ..offset-..ResourceRoot ..c fix 1 forward TEMP_RESOURCE_GET ..c,..i,..s,..l if ..i < 0 dd 80000000h+..names,80000000h+..l-..ResourceRoot ..names = ..names+..s*2+2 else dd ..i,80000000h+..l-..ResourceRoot end if ..c fix ..c#1 common ..offset: ..c fix 1 forward TEMP_RESOURCE_GET ..c,..i,..s,..l if ..i < 0 dw ..s ..i = ..i shr ((7-..s)*8) repeat ..s db ..i shr ((..s-%)*8) and 0FFh db 0 end repeat end if ..c fix ..c#1 common align 4 end if } macro resource dir,[id,lang,label] { common dir: forward resource_min = id resource_max = id common resource_count = 0 forward local resource_label resource_count = resource_count + 1 if id < resource_min resource_min = id else if id > resource_max resource_max = id end if common dd 0,%t,0,resource_count shl 16 repeat resource_max-resource_min+1 forward if resource_min+%-1 = id dd id,80000000h+resource_label-..ResourceRoot end if common end repeat forward label#.resid = id resource_label dd 0,%t,0,10000h,lang,label-..ResourceRoot } m^ fix { ^m fix } _common fix common _forward fix forward _reverse fix reverse _local fix local $$ fix ^_^ ^_^ fix # |
|||
18 Feb 2004, 17:49 |
|
comrade 18 Feb 2004, 20:47
Thanks. Why do you have all these fixes for common and reverse, etc at the end?
|
|||
18 Feb 2004, 20:47 |
|
Joshua 18 Feb 2004, 21:21
_common, _forward, _reverse and _local are unneeded, the others are. (it was just a copy and paste job)
|
|||
18 Feb 2004, 21:21 |
|
comrade 19 Feb 2004, 06:29
Finally, working version:
Code: macro sort [val] { common virtual at 0 definetokens val len = $ end virtual repeat len virtual at 0 definetokens val shit = % - 1 pos2idx shit end virtual if outpos > 0 virtual at 0 vsort outidx,outpos,val load char from outpos end virtual db char end if end repeat } macro vsort needidx,needpos,[val] { common definetokens val prev = 0 min = 0 i = 0 repeat tokcount i = i + 1 min = 0 k = 0 repeat tokcount k = k + 1 if prev = 0 strcmpr = 1 else strcmpidx k,prev end if if strcmpr > 0 if min = 0 min = k end if strcmpidx k,min if strcmpr < 0 min = k end if end if end repeat prev = min if % = needidx curpos = 0 k = 0 repeat tokcount k = k + 1 load curlen from curpos if k = min outpos = curpos + needpos end if curpos = curpos + curlen + 1 end repeat end if end repeat } macro definetokens [val] { tokcount = 0 forward tokcount = tokcount + 1 strlen val db strlenr db val common } macro pos2idx pos { k = 0 tokpos = 0 outpos = 0 outidx = 0 repeat tokcount k = k + 1 load toklen from tokpos if pos >= tokpos if pos <= (tokpos+toklen) outpos = pos - tokpos outidx = k end if end if tokpos = tokpos + toklen + 1 end repeat } macro strcmpidx str1,str2 { local ..count,..x,..char1,..char2,..pos strcmpr = 0 ..x = 0 ..pos = 0 repeat tokcount load len from ..pos ..x = ..x + 1 if ..x = str1 str1pos = ..pos+1 str1len = len end if if ..x = str2 str2pos = ..pos+1 str2len = len end if ..pos = ..pos + len + 1 end repeat ..count = str1len if ..count > str2len ..count = str2len end if repeat ..count load ..char1 from str1pos+%-1 load ..char2 from str2pos+%-1 if strcmpr = 0 strcmpr = ..char1 - ..char2 end if end repeat } macro strlen val { virtual at 0 db val strlenr = $ end virtual } input: sort "abc","def","bbb","zzz","yyy" db 0 input will contain "abcbbbdefyyyzzz" |
|||
19 Feb 2004, 06:29 |
|
comrade 19 Feb 2004, 06:36
Almost works, needs some change to work with variable length strings. But too late now, I must sleep.
|
|||
19 Feb 2004, 06:36 |
|
comrade 20 Feb 2004, 04:45
Here final version:
Code: macro sort [val] { common virtual at 0 definetokens val len = $ end virtual gotlen = 0 repeat len virtual at 0 needpos = %-1 vsort needpos,val load char from outpos end virtual if gotlen > 0 db char gotlen = gotlen - 1 else if gotlen = 0 gotlen = char if % > 1 db "," end if end if end repeat } macro vsort inpos,[val] { common definetokens val prev = 0 min = 0 i = 0 abspos = 0 abslen = 0 repeat tokcount i = i + 1 min = 0 k = 0 repeat tokcount k = k + 1 if prev = 0 strcmpr = 1 else strcmpidx k,prev end if if strcmpr > 0 if min = 0 min = k end if strcmpidx k,min if strcmpr < 0 min = k end if end if end repeat prev = min k = 0 display "min: ",min+30h,13,10 curpos = 0 repeat tokcount k = k + 1 load curlen from curpos if k = min repeat curlen+1 if inpos = abspos outpos = curpos + % - 1 end if abspos = abspos + 1 end repeat abslen = curlen end if curpos = curpos + curlen + 1 end repeat end repeat } macro definetokens [val] { tokcount = 0 forward tokcount = tokcount + 1 strlen val db strlenr db val common } macro pos2idx pos { k = 0 tokpos = 0 outpos = 0 outidx = 0 repeat tokcount k = k + 1 load toklen from tokpos if pos >= tokpos if pos <= (tokpos+toklen) outpos = pos - tokpos outidx = k end if end if tokpos = tokpos + toklen + 1 end repeat } macro strcmpidx str1,str2 { local ..count,..x,..char1,..char2,..pos strcmpr = 0 ..x = 0 ..pos = 0 repeat tokcount load len from ..pos ..x = ..x + 1 if ..x = str1 str1pos = ..pos+1 str1len = len end if if ..x = str2 str2pos = ..pos+1 str2len = len end if ..pos = ..pos + len + 1 end repeat ..count = str1len if ..count > str2len ..count = str2len end if repeat ..count load ..char1 from str1pos+%-1 load ..char2 from str2pos+%-1 if strcmpr = 0 strcmpr = ..char1 - ..char2 end if end repeat } macro strlen val { virtual at 0 db val strlenr = $ end virtual } input: sort "grapefruit","apple","grenade","tangerine","orange","peach" db 0 input contain "apple,grapefruit,grenade,orange,peach,tangerine" after compilation |
|||
20 Feb 2004, 04:45 |
|
comrade 20 Feb 2004, 15:58
Slightly modified version:
Code: macro sort [val] { tokcount = 0 forward tokcount = tokcount + 1 common local i, needidx,char,tokpos repeat tokcount virtual at 0 definetokens val needidx = % vsort needidx,val end virtual i = 0 tokpos = 0 repeat tokcount i = i + 1 virtual at 0 definetokens val load toklen from tokpos end virtual if i = outidx repeat toklen virtual at 0 definetokens val load char from tokpos+% end virtual db char end repeat db "," end if tokpos = tokpos + toklen + 1 end repeat end repeat } macro vsort inidx,[val] { common local prev,min,i,k prev = 0 min = 0 i = 0 repeat tokcount i = i + 1 min = 0 k = 0 repeat tokcount k = k + 1 if prev = 0 strcmpr = 1 else strcmpidx k,prev end if if strcmpr > 0 if min = 0 min = k end if strcmpidx k,min if strcmpr < 0 min = k end if end if end repeat prev = min if i = inidx outidx = min end if end repeat } macro definetokens [val] { tokcount = 0 forward tokcount = tokcount + 1 strlen val db strlenr db val common } macro strcmpidx str1,str2 { local ..count,..x,..char1,..char2,..pos strcmpr = 0 ..x = 0 ..pos = 0 repeat tokcount load len from ..pos ..x = ..x + 1 if ..x = str1 str1pos = ..pos+1 str1len = len end if if ..x = str2 str2pos = ..pos+1 str2len = len end if ..pos = ..pos + len + 1 end repeat ..count = str1len if ..count > str2len ..count = str2len end if repeat ..count load ..char1 from str1pos+%-1 load ..char2 from str2pos+%-1 if strcmpr = 0 strcmpr = ..char1 - ..char2 end if end repeat } macro strlen val { virtual at 0 db val strlenr = $ end virtual } |
|||
20 Feb 2004, 15:58 |
|
vid 21 Feb 2004, 11:29
privalov: another thread to pinpoint on fasm site
|
|||
21 Feb 2004, 11:29 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.