Sometimes one might get confused when to use TAG_DONE in AmigaOS C-code, and when to use TAG_END. The answer is very simple: They're one and the same. But it turns out there might be a little bit of an unknown story to these two widely used tokens.
TAG_DONE showed up before TAG_END, in NDK1.3, along with struct
TagItem, but not as part of the system includes, and the TagItem system
wasn't used in system functions.
Or was it? This is a section of code from the file Read-Me1.3/A2024Docs/OpenA2024.c, which is part of NDK1.3.
#define NONEWINCLUDES 1 /* don't have 1.3 includes yet */
#if NONEWINCLUDES /* Some additional definitions */
/********** from intuition/screens.h ************/
#define NS_EXTENDED 0x1000 /* NewScreen.Extension is valid */
struct TagItem
{
ULONG ti_Tag; /* identifies the type of this item */
ULONG ti_Data; /* type-specific data, can be a pointer */
};
/* ---- system tag values ----------------------------- */
#define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
#define TAG_IGNORE (1L) /* ignore this item, not end of array */
#define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems
* note that this tag terminates the current array
*/
Note
the condition "#if NONEWINCLUDES". It looks as if these definitions
were part of some "new includes" that weren't part of the distribution
(yet?).
There appears to be a nice little oddity here:
NS_EXTENDED (and TagItem) can't be found in intuition/screens.h,
while other sections of the code (not shown here) can. The code
contains a copy of NewScreen structure definition, only extended with an
extra field, type TagItem pointer. It then creates an instance of that
NewScreen structure, with type NS_EXTENDED, and calls OpenScreen() with
that structure. There's no mentioning of NS_EXTENDED, or a TagItem
pointer field in the Autodocs of OpenScreen() in this version of the
NDK.
Does that mean that AmigaOS1.3 already had an (almost)
undocumented feature, that would only be made (really) public with
AmigaOS2?
TAG_END appears in NDK2.0, in new system include file utility/tagitem.h, as a clone of TAG_DONE, along with struct TagItem etc.:
NDK2.0-4/include/utility/tagitem.h
#define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
#define TAG_END TAG_DONE
This NDK's version of intuition/screens.h also defines an ExtNewScreen structure that has the extra TagItem pointer field.
Looking at the usage of TAG_DONE and TAG_END, across all files that are supplied with NDK2.0, there seems to be no preference. Maybe TAG_END was really just introduced to avoid interruptions in workflow, because many developers would intuitively think, and type, "end" instead of "done"?
Another tiny oddity is a change that appears in NDK3.1. It has a slightly different definition of TAG_END: It's still identical, but for some unexplainable reason, TAG_END isn't bound to TAG_DONE anymore. Instead, a comment explains why both use the same value.
Includes\&Libs/include_h/utility/tagitem.h
#define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
#define TAG_END (0L) /* synonym for TAG_DONE */
We'll probably never find out what happened, precisely.
But that's ok. Fortunately, TAG_DONE and TAG_END are either synonyms, or simply the same. ;-)