Need help on converting C code

General FreeBASIC programming questions.
Post Reply
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Need help on converting C code

Post by marpon »

Hi
I'm converting a c decompression code to freebasic, whith plenty of macros
after preprocessing result, i've got many parts of code i do not understant , as the following

Code: Select all

if (!((bits=bits&0x7fffffff? (resbits=bits,bits+bits) :  (src+=4,resbits=*((Ulong *)(src-4)),(resbits<<1)+1)),resbits>>31))
        {
            goto uselastofs;
        }
all the var are unsigned 32 bits int
what i don't understand is (resbits=bits,bits+bits) and the (src+=4,resbits=*((Ulong *)(src-4)),(resbits<<1)+1)),resbits>>31
all the parenthesis and the , in between...

some of you can help ?
Thanks in advance
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Need help on converting C code

Post by counting_pine »

What horrible code!
Unfortunately it won't translate directly to a single FB expression.

Maybe the first thing to do would be to translate it several separate lines of C, which can then be ported..

- (b=c) is an expression that assigns c to b, then returns b.
- (a,b) evaluates a, then evaluates b, then returns b.
- (a?b:c) evaluates a, then evaluates and returns either b (if a is nonzero) or c (if a is zero). (The other one is not evaluated.)

This last one is equivalent to FB's iif(a,b,c), so you don't technically need to change this in the C, but it could stand to be rewritten so that it's clearer. e.g. 'if (a) tmp = b; else tmp = c'.

Sorry, I had a quick look, but don't have enough time to try and translate it properly now. You may be able to work through it if you can split it up enough.
It's hard to tell how likely you are to run into operator precedence issues, the code is that horrible...
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Need help on converting C code

Post by paul doe »

Had a quick shot at it:

Code: Select all

'if ( _
'  !( _
'    ( bits = bits & 0x7fffffff ? _
'      ( resbits = bits, bits + bits ) : _
'      ( src +=4 , resbits = *( ( Ulong * ) ( src - 4 ) ), ( resbits << 1 ) + 1 ) ), _
'      resbits >> 31 ) )
'        {
'            goto uselastofs;
'        }
dim as ulong _
  result, _
  bits, _
  resbits, _
  src

if( bits = bits and &h7fffffff ) then
  resbits => bits
  result => bits + bits
else
  src +=> 4
  resbits => *cptr( ulong ptr, src - 4 )
  resbits => ( resbits shl 1 ) + 1
end if

resbits => resbits shr 31

if( not result ) then
  goto uselastofus
end if

uselastofus:
Be aware that it may contain errors. I can't check the equivalence of both codes now, but I may later (or you can test them to see if they give the same results for yourself).

Sadly, as awful as that code is, C actually encourages you to write such crap, since the compiler emits quite efficient code for them... ='(
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

SOLVED - Re: Need help on converting C code

Post by marpon »

Thank's both of you for your answer,

on the mean time i think i got a good replacement code in c

Code: Select all

sub_macro( Ulong *presbits, Ulong *pbits , Ubyte **ppsrc0 )
{
	(*pbits) = (*pbits) & 0x7fffffff;
	if(*pbits)
	{
		*presbits = (*pbits);
		(*pbits) = (*pbits) + (*pbits);	
	}
	else
	{
		(*ppsrc0) += 4;
		(*presbits) = *((Ulong *)((*ppsrc0) - 4));
		(*pbits) = (((*presbits) << 1) + 1);
	}	
}

//and use like that
sub_macro( &resbits, &bits , &src );
if (!(resbits>>31))
{
       goto uselastofs;
}
use a sub because it will be 6 times in the code, now i can easily convert to freebasic...

similar as you proposed Paul, seems ok , i 've made a comparative test on the previous and the expended one, same results
done.

always difficulties when converting from c complex macros

Marc
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: SOLVED - Re: Need help on converting C code

Post by paul doe »

marpon wrote:...
always difficulties when converting from c complex macros

Marc
Yeah, the 'everything is an expression' mantra from C does indeed have its rough edges. Good luck ;)
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Need help on converting C code

Post by badidea »

Could have been worse, see: Obfuscated C Code :-)
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Need help on converting C code

Post by paul doe »

badidea wrote:Could have been worse, see: Obfuscated C Code :-)
Indeed XD
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Need help on converting C code

Post by counting_pine »

I had another go at translating. Here is the code with indentation:

Code: Select all

if (!
	(
		(
			bits=
			bits&0x7fffffff? (
				resbits=bits,
				bits+bits
			) : (
				src+=4,
				resbits=*((Ulong *)(src-4)),
				(resbits<<1)+1
			)
		),
		resbits>>31
	)
)
{
	goto uselastofs;
}
That means it can be translated to something like:

Code: Select all

if (bits & 0x7fffffff) {
	resbits=bits;
	bits = bits+bits;
} else {
	src+=4;
	resbits=*((Ulong *)(src-4));
	bits = (resbits<<1)+1;
}
if (!(resbits>>31)) {
	goto uselastofs;
}
It looks like you've reached pretty much the same conclusion. In your translation you seem to infer a different operator precedence, and assign (bits&0x7ffffff) to bits. This assignment doesn't actually happen, but it works either way because its high bit is discarded anyway. (Perhaps you realised that though.)

Be careful with your macro parentheses. You'll need to use e.g. *(pres) instead of (*pres), otherwise you'll just have the illusion of safety.
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

SOLVED REALLY : Need help on converting C code

Post by marpon »

@counting_pine
thanks for your very good answer,

on the mean time i've concluded as you , see here the macro :

Code: Select all

#macro sub_macro(m_resbits, m_bits , m_src)
	if (m_bits and &h7fffffff) <> 0 then
        m_resbits = m_bits
        m_bits = m_bits + m_bits
    else
        m_src += 4
        m_resbits = *(cptr(Ulong ptr ,(m_src - 4)))
        m_bits = (m_resbits shl 1) + 1
    end if
#endmacro
assign (bits&0x7ffffff) to bits
yes, was wrong!
use a macro in place of function,
thanks again for the support
Last edited by marpon on Apr 03, 2019 14:37, edited 1 time in total.
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Conclusion : Need help on converting C code

Post by marpon »

In fact for the ones who want convert c to freebasic, some interresting advice

clean as much as you can on the c side,
choose to preprocess the code or not ( you can replace defines by macros in fb)
replace all the for loops , by while or do loops
replace i++ by i +=1 in all part of your code
try to decompose the code steps ex :

Code: Select all

*str++ = *dest++ 
better like that
 ( str=dest ; dest+=1; str+=1;)
and if the code is refactored like that
put it on fbfrog , most of the c code will be converted

you will have after to review the todo elements

but you will save lot of time

thanks to fbfrog creator that have done a quite complete c code parser!
nirmitpatel
Posts: 1
Joined: Apr 04, 2019 10:17
Contact:

Re: Need help on converting C code

Post by nirmitpatel »

Really thankful for sharing this great post.Helpful
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Conclusion : Need help on converting C code

Post by counting_pine »

You have dkl from the FB development team to thank for fbfrog.
marpon wrote:

Code: Select all

*str++ = *dest++ 
better like that
 ( str=dest ; dest+=1; str+=1;)
Don't forget to dereference: '*str = *dst'

A couple more thoughts occur to me:
- (a,b) can be translated to FB (if you really have to!) as 'iif(a,b,b)', as long as 'a' returns a value whose truth can be evaluated.
- the expression (a=b) can be replaced by a function call 'assign(a,b)', e.g.

Code: Select all

function assign overload(byref lhs as T, byval rhs as T) byref as T
  lhs = rhs
  return lhs
end function
But you have to write an assign() overload for every type you want to use. Order of evaluation may also be different.
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Need help on converting C code

Post by marpon »

THANK YOU DLK, for your very good fbfrog.

just finished convert a compress /decompress code from c, can see the post on Tips & Tricks

After some cleaning on the c code as explained before,
the for ... loop do not convert easily with fbfrog
the --, ++ , multi steps expended...

used fbfrog and only the break statement gave todo.



@counting_pine
< Don't forget to dereference: '*str = *dst' > sure was just a typo. :)
Post Reply