Using Tags for our own functions

14 posts / 0 new
Last post
YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Using Tags for our own functions

Hello,
I am testing the TagItem structure in my function
Here is some parts of the code inspired by the AmigaOSWiki.

  1. void Test(uint32 n, ...) {
  2.  
  3. uint item = 1;
  4. struct TagItem *tags = (struct TagItem *) &n; // Here may be the problem. How does gcc read the stack?
  5. struct TagItem *ctags=IUtility->CloneTagItems (tags); //not useful, just for testing the function, at least I think.
  6. struct TagItem *ltags=ctags;
  7. struct TagItem *tag;
  8.  
  9. while (tag = IUtility->NextTagItem (&ltags)) {
  10.  
  11. uint32 titag = tag->ti_Tag;
  12. uint32 tidata = tag->ti_Data;
  13. cout <<"Element "<<item<<": First="<<titag<<", Second="<<tidata<<endl;
  14. ++item;
  15. }
  16. IUtility->FreeTagItems (ctags);
  17. }
  18.  
  19. int main(int argc, char *argv[]) {
  20.  
  21. Test(1,4,2,46,3,31,4,65,5,86, TAG_END);
  22.  
  23. return 0;
  24.  
  25. <cpp-qt>
  26.  
  27. Here the output :
  28. Element 1: First=1297767648, Second=1866413944
  29. Element 2: First=1297767680, Second=1866413840
  30. Element 3: First=5, Second=86
  31.  
  32. As you can read, I only obtain 5 and 86. I think that it prints the address and not the values but I don't know why.
  33. I would want to undersand better how the methods and TagItem work.
  34. I mean, how the parameters of Test() are converted into TagItem and vice-versa when they are not only int but float, pointers, strings...?
  35.  
  36. The purpose of all this is of course to use Test() with a variety of parameters.
  37.  
  38. Thanks for reading.
thomas
thomas's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2011-05-16 14:23
Re: Using Tags for our own functions

On a PPC OS you cannot use just &n to get a tag list.

Read section 5.2 of SDK:Documentation/Developer Info/General/Migration Guide.pdf

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 1 week ago
Joined: 2011-05-26 03:58
Re: Using Tags for our own functions

Also, the choice of tag values has restrictions, especially if you're using utility tag management functions.
You can read more in
SDK:Include/include_h/utility/tagitem.h

LyleHaze

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Thomas, thanks to remind me of this pdf.
My first version of my test function uses va_list and co. That works well without trick.
I would want the AmigaOS Wiki to verify his code. I though that the source published in this site was 'OS4 proof'.

Lyle, I had already read the include file. I didn't see what you wanted to point to except may be that the TagItem structure contains two ints.
My interest about Tags was the possibility to use as variables int and strings (pointers). I wanted to obtain something like a lot if OS4 functions like OpenwindowTags (Tag1=2, Tag2="My window"...

I am a little disappointed about this.
Thanks for your replies.

thomas
thomas's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2011-05-16 14:23
Re: Using Tags for our own functions

I had already read the include file. I didn't see what you wanted to point to

The values you use for ti_Tag are already used by the system and have special meanings:

1 is TAG_IGNORE
2 is TAG_MORE
3 is TAG_SKIP

Especially TAG_MORE is dangerous if ti_Data does not point to another tag list.

You should always set the TAG_USER bit on your own tags.

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Thanks.
You are right about TAG_USER.
Finally after some tests, I don't really see the interest usings tagitem.h.
I consider simpler using own tags and va_list so I can use whatever types.

If some reader thinks that I am wrong, feel free to give an example.

thomas
thomas's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2011-05-16 14:23
Re: Using Tags for our own functions

If you only use it in your own programs, it is up to you. But if you want to publish the interface, you should use utility.library functions to examine the tag list and thus use linear varargs.

Here is an example which demonstrates the difference:

  1. #include <stdarg.h>
  2. #include <proto/dos.h>
  3. #include <proto/utility.h>
  4.  
  5.  
  6. void func1 (ULONG dummy, ...)
  7. {
  8. va_list args;
  9. ULONG tag,data;
  10.  
  11. va_start (args,dummy);
  12.  
  13. Printf ("\nfunc1: begin of tag list\n");
  14. while ((tag = va_arg(args,ULONG)))
  15. {
  16. data = va_arg(args,ULONG);
  17. Printf ("%-4lu = %lu\n",tag,data);
  18. }
  19. Printf ("func1: end of tag list\n");
  20.  
  21. va_end (args);
  22. }
  23.  
  24.  
  25. VARARGS68K
  26. void func2 (ULONG dummy, ...)
  27. {
  28. va_list args;
  29. struct TagItem *taglist,*ti;
  30.  
  31. va_startlinear (args,dummy);
  32.  
  33. taglist = va_getlinearva(args,struct TagItem *);
  34.  
  35. Printf ("\nfunc2: begin of tag list\n");
  36. while ((ti = NextTagItem (&taglist)))
  37. {
  38. Printf ("%-4lu = %lu\n",ti->ti_Tag,ti->ti_Data);
  39. }
  40. Printf ("func2: end of tag list\n");
  41.  
  42. va_end (args);
  43. }
  44.  
  45.  
  46.  
  47. int main (void)
  48.  
  49. {
  50. ULONG taglist[] = {1004, 5, TAG_END};
  51.  
  52. func1 (0,
  53. 1001, 2,
  54. 1002, 3,
  55. 1003, 4,
  56. TAG_END);
  57.  
  58. func2 (0,
  59. 1001, 2,
  60. 1002, 3,
  61. 1003, 4,
  62. TAG_END);
  63.  
  64. func2 (0,
  65. 1001, 2,
  66. TAG_IGNORE, 6,
  67. 1002, 3,
  68. TAG_SKIP, 2,
  69. 1005, 5,
  70. 1006, 6,
  71. 1003, 4,
  72. TAG_MORE, taglist);
  73.  
  74. return (0);
  75. }

As you can see by the second call to func2, a real tag list can be rather complicated and NextTagItem handles it all.

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Thanks Thomas.
I read and compile your example. I learned something, I didn't know VARARGS68K.
Could you tell me if you know what is the interest to write some tags in the call and ignore them in fact?

thomas
thomas's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2011-05-16 14:23
Re: Using Tags for our own functions

You can programmatically decide whether some tags should be used or not

for example

  1. window = OpenWindowTags (NULL,
  2. width > 0 ? WA_Width : TAG_IGNORE, width,
  3. height > 0 ? WA_Height : TAG_IGNORE, height,
  4. TAG_END);

or

  1. window = OpenWindowTags (NULL,
  2. no_size ? TAG_SKIP : TAG_IGNORE, 2,
  3. WA_Width, width,
  4. WA_Height, height,
  5. TAG_END);

TAG_MORE can be used for example to forward a given taglist to a subroutine with some tags added:

  1. subroutine (dummy,
  2. my_tag1, my_value1,
  3. my_tag2, my_value2,
  4. TAG_MORE, given_taglist);
YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Ok.
Thanks for your answers.

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Thomas,
I have one more question. I played with tags and int, strings and floats.
I must convert float to fixpoint in the call and I can use it next converting back.
Is there any way to not convert values in the call to the function?
And I didn't succeed with negative values.

Here is the example to illustrate.
Func1(tag1, "text", tag2, COMP-float-to-fix(2.3), tag3, -1)

I would wish to remove the comp-float from the call and use negative values.

thomas
thomas's picture
Offline
Last seen: 3 months 6 days ago
Joined: 2011-05-16 14:23
Re: Using Tags for our own functions

The problem is that the compiler converts float (32 bits) into double (64 bits) before it pushes them on the stack. But the ti_Data field is only 32 bits wide. So you have to assure that the 32 bit floats are stored (and later read) as-is and not converted.

This trick could work:

float x = 2.3;
Func1(tag1, "text", tag2, *((ULONG *)&x), tag3, -1, TAG_END);

and reading by the opposite:

x = *((float *)&ti->ti_Data);

YesCop
YesCop's picture
Offline
Last seen: 4 years 3 months ago
Joined: 2011-05-17 15:07
Re: Using Tags for our own functions

Thank for the explanation. I hadn't imagined the 64 bit stack.
Your trick worked.
Thanks.

hypex
hypex's picture
Offline
Last seen: 3 months 2 weeks ago
Joined: 2011-09-09 16:20
Re: Using Tags for our own functions

They had this problem when porting OS4 to PPC. The tags weren't designed to be dynamic and support variable sized data. And this presented a problem for 64-bit data like a float. One solution is to simply use a pointer instead. Then you don't have to worry about the size. Just specifying the correct datatype.

Log in or register to post comments