Welcome, Guest. Please login or register.

Author Topic: varargs compatibility probs with PPC Oses./Passing to 2nd function  (Read 3916 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
varargs compatibility probs with PPC Oses./Passing to 2nd function
« on: September 11, 2005, 11:15:13 AM »
Hi. Suppose I have a function that has a variable number of arguments. How do I call a second function passign it those arguments in the very same way they were passed to the 1st one.

For example..

Code: [Select]
void SomeFunction (int a, ...);
void SecondFunc (int nr, ...);


How do I call the 2nd function from the 1st one passing it the first's varargs...?

I have an idea of making va_list global and initializing it in the first function. The second one would then only have to call va_arg. I could also pass a pointer to va_arg I guess.
Would this work or it's not very safe (calling a 2nd function will mess with the stack..) ?
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #1 on: September 11, 2005, 11:29:03 AM »
Er...I meant I could also pass a pointer to va_list not va_arg...
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #2 on: September 11, 2005, 12:12:00 PM »
Hmm... where do you get these:

va_startlinear
va_getlinearva

Can't find them anywhere..
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #3 on: September 11, 2005, 12:17:49 PM »
Ahh, it's in the headers...
Why not just use va_start anyway ?
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #4 on: September 11, 2005, 01:18:28 PM »
When you use:

Code: [Select]
return (SecondFunc (a,va_getlinearva (ap,int *)));

Wouldn't this be the same as:
Code: [Select]
return (SecondFunc (a,va_arg (ap,int *)));


And will SecondFunc (actually I think you meant SecondFuncA), supposing it was declared as
Code: [Select]
void SecondFuncA (int a,int *b,...), be able to get other subsequent values, like:
Code: [Select]
va_list ap;
int d;
int e;

va_start (ap,b);
d = va_arg (ap, int)
e = va_arg (ap, int)
;

I think you're just calling SomeFuncA and SecondFuncA with the first argument in the variable argument list but I want them to be able to get any subsequent value...
That or I'm just getting all this wrong...
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #5 on: September 13, 2005, 04:34:53 PM »
Hi. I'd have no problems with that except in this particular function I'm dealing with, actually all my functions that accept an array accept a pointer to it.

I want to be able to allocate the exact needed memory to the concatenation of various strings, using one of them as template like printf does. How I'm doing this is having sprintf or one of the other similar exec functions accept various created substrings from the format string (actually it's the same one wich is temporarily NULL terminated before it's end), each one with the successive % format commands. Then I check the size of the substring or number (%d, %ld, etc. ) and continue till the end adding to the total till I get the total memory needed to hold the whole resulting string. After that I just need to allocate the needed memory and call sprintf or one alike function to produce the wanted final string using the template string. And this is where the problem lies, sprintf is a varargs function.
I'm not at home and can't check from here, but maybe there's some exec function that accepts an pointer to a format string, that would be perfect... :-)

:pint:
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #6 on: September 13, 2005, 04:59:53 PM »
@Piru
Yes! :-D The a) option sounds perfect. I had forgot that RawDoFmt outputs one char at a time so I can just count the size of the final string... Dynamically expanding buffer would probably involve a linked list type of thing, not really needed for what I want to do.
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #7 on: September 15, 2005, 05:44:57 PM »
Hi. If I don't use varargs and use a pointer to an array I'd have to dynamically allocate an array everytime I wanted to create a string using other strings (for example a list of errors) and variables.
I read this is a big problem for OS4 compatibility, is there a way around this still using varargs?
What about MOS, doesn it have the same problem ?

The bellow code is some example I made last night. Using Piru's suggestion the code size more than halved (was almost 200 lines).

However the bloody thing doesn't work. I couldn't find the bug, so since the code size is small and it's probably a stack related problem that I wouldn't find anyway I decided to post it here in hope some benevolent soul finds it :roll:


Code: [Select]
#include <exec/memory.h>
#include <exec/types.h>
#include <stdio.h>

BOOL AllocAndCpyStr (char *CtrlStr, char **dest, ...);
void CountChrs (char ch, LONG *StringSize);
void CpyChr (char ch, char *dest);

int main (int argc, char **argv)
{
 char *a = &quot;Error a&quot;;
 char *b = &quot;Error b&quot;;
 char *c = 0;

 /* .. Other function code...*/

 /* Make information strings without having to allocate an array everytime for each */
 /* Suppose both error a and b happened. Allocate string with info without having make */
 /* an array with pointers a and b plus other data we want to put into final string */
 /* Also serves to test AllocAndCpyStr */
 if (AllocAndCpyStr (&quot;%s %c %s \n Test number is %d&quot;, &c, a, ' ', b, 44))
   printf (&quot;Sucess, concatenation and allocation result is:\n %s\n&quot;,c);
 else
   printf (&quot;Failed\n&quot;);
 if (c)
   FreeMem (c, strlen (c) + 1);
 exit (0);
}


/* printf() like, except it copies resulting string to it's own allocated chunk, whose ptr is put in *dest */
/* uses StrToRawDF */
BOOL AllocAndCpyStr (char *CtrlStr, char **dest, ...)
{
 LONG StringSize = 0;
 BOOL Result = FALSE;

 /* Check total size */
 RawDoFmt (CtrlStr, &dest + 1, (void (*)())CountChrs, &StringSize);

 /* Allocate space 4 strings */
 if (!(*dest = (char *)AllocMem (StringSize, MEMF_ANY | MEMF_CLEAR)))
   { printf (&quot;Out of memory in report!\n&quot;);
     goto END;
   }
 printf (&quot;Allocated space (resulting string size) was %ld bytes\n\n&quot;, StringSize);
 Result = TRUE;

 /* Copy over strings */
 RawDoFmt (CtrlStr, &dest + 1, (void (*)())CpyChr, *dest);

 END:
 return (Result);
}


/* Count nr. of times it's called (= string size) */
void CountChrs (char ch, LONG *StringSize)
{ ++*StringSize;
}


void CpyChr (char ch, char *dest)
{ *dest++ = ch;
}
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #8 on: September 16, 2005, 04:21:32 PM »
@Thomas

 :lol: I knew you were gonna say something...
That's just a scratch to try it out. I'll read that varargs chapter in the OS4 docs later..
I don't even have the OS4 docs though, but I want my code to run on OS4 and MOS so sooner or later I'll have to deal with it.

@Piru
Wow! I'll have a look at it this evening, thanks.
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #9 on: September 16, 2005, 04:40:35 PM »
@Piru
"Basically your CountChrs and CpyChr didn't use correct registers."

Why? I took care to have them receive the arguments as described in the RawDoFmt docs.
 :-? I'm on 68K so &dest+1 shouldn't be a problem here.
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show all replies
Re: Passing a function's variable arguments to a 2nd one...?
« Reply #10 on: September 19, 2005, 06:08:44 PM »
Got it! And IIRC VBCC uses yet another syntax for registers...
\\"We made Amiga, they {bleep}ed it up\\"