Hello,
I am testing the TagItem structure in my function
Here is some parts of the code inspired by the AmigaOSWiki.
void Test(uint32 n, ...) { uint item = 1; struct TagItem *tags = (struct TagItem *) &n; // Here may be the problem. How does gcc read the stack? struct TagItem *ctags=IUtility->CloneTagItems (tags); //not useful, just for testing the function, at least I think. struct TagItem *ltags=ctags; struct TagItem *tag; while (tag = IUtility->NextTagItem (<ags)) { uint32 titag = tag->ti_Tag; uint32 tidata = tag->ti_Data; cout <<"Element "<<item<<": First="<<titag<<", Second="<<tidata<<endl; ++item; } IUtility->FreeTagItems (ctags); } int main(int argc, char *argv[]) { Test(1,4,2,46,3,31,4,65,5,86, TAG_END); return 0; <cpp-qt> Here the output : Element 1: First=1297767648, Second=1866413944 Element 2: First=1297767680, Second=1866413840 Element 3: First=5, Second=86 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. I would want to undersand better how the methods and TagItem work. I mean, how the parameters of Test() are converted into TagItem and vice-versa when they are not only int but float, pointers, strings...? The purpose of all this is of course to use Test() with a variety of parameters. Thanks for reading.
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
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
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.
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.
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.
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:
As you can see by the second call to func2, a real tag list can be rather complicated and NextTagItem handles it all.
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?
You can programmatically decide whether some tags should be used or not
for example
or
TAG_MORE can be used for example to forward a given taglist to a subroutine with some tags added:
Ok.
Thanks for your answers.
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.
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);
Thank for the explanation. I hadn't imagined the 64 bit stack.
Your trick worked.
Thanks.
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.