diff -cr ../ctags-5.5.4.orig/c.c ./c.c
*** ../ctags-5.5.4.orig/c.c	Sat Feb 28 16:37:52 2004
--- ./c.c	Sun Sep 11 13:02:59 2005
***************
*** 455,460 ****
--- 455,463 ----
      { "while",		KEYWORD_WHILE,		{ 1, 1, 1, 1, 0 } }
  };
  
+ /* Added by Bram: number for nameless structs and unions. */
+ static int numberForName = 0;
+ 
  /*
  *   FUNCTION PROTOTYPES
  */
***************
*** 762,768 ****
  	initToken (st->token [i]);
  
      initToken (st->context);
!     initToken (st->blockName);
      vStringClear (st->parentClasses);
  
      /*  Init member info.
--- 765,775 ----
  	initToken (st->token [i]);
  
      initToken (st->context);
! 
!     /* Keep the block name, so that a variable following after a comma will
!      * still have the structure name. (Bram) */
!     if (! partial)
! 	initToken (st->blockName);
      vStringClear (st->parentClasses);
  
      /*  Init member info.
***************
*** 943,950 ****
      return result;
  }
  
  static void addOtherFields (tagEntryInfo* const tag, const tagType type,
! 			    const statementInfo *const st, vString *const scope)
  {
      /*  For selected tag types, append an extension flag designating the
       *  parent object in which the tag is defined.
--- 950,966 ----
      return result;
  }
  
+ static void addContextSeparator (vString *const scope)
+ {
+     if (isLanguage (Lang_c)  ||  isLanguage (Lang_cpp))
+ 	vStringCatS (scope, "::");
+     else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
+ 	vStringCatS (scope, ".");
+ }
+ 
  static void addOtherFields (tagEntryInfo* const tag, const tagType type,
! 			    const statementInfo *const st,
! 			    vString *const scope, vString *const typeName)
  {
      /*  For selected tag types, append an extension flag designating the
       *  parent object in which the tag is defined.
***************
*** 1001,1014 ****
  	    }
  	    break;
      }
- }
  
! static void addContextSeparator (vString *const scope)
! {
!     if (isLanguage (Lang_c)  ||  isLanguage (Lang_cpp))
! 	vStringCatS (scope, "::");
!     else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
! 	vStringCatS (scope, ".");
  }
  
  static void findScopeHierarchy (vString *const string,
--- 1017,1054 ----
  	    }
  	    break;
      }
  
!     /* Added by Bram: typename info, type of the tag and name of
!      * struct/union/etc. */
!     if ((type == TAG_TYPEDEF || type == TAG_VARIABLE || type == TAG_MEMBER)
! 	    && isContextualStatement(st))
!     {
! 	char *p;
! 
! 	tag->extensionFields.typeName [0] =
! 				    tagName (declToTagType (st->declaration));
! 	p = vStringValue (st->blockName->name);
! 
! 	/* If there was no {} block get the name from the token before the
! 	 * name (current token is ';' or ',', previous token is the name). */
! 	if (p == NULL || *p == '\0')
! 	{
! 	    tokenInfo *const prev2 = prevToken (st, 2);
! 
! 	    if (isType (prev2, TOKEN_NAME))
! 		p = vStringValue (prev2->name);
! 	}
! 
! 	/* Prepend the scope name if there is one. */
! 	if (vStringLength (scope) > 0)
! 	{
! 	    vStringCopy(typeName, scope);
! 	    addContextSeparator (typeName);
! 	    vStringCatS(typeName, p);
! 	    p = vStringValue (typeName);
! 	}
! 	tag->extensionFields.typeName [1] = p;
!     }
  }
  
  static void findScopeHierarchy (vString *const string,
***************
*** 1106,1111 ****
--- 1146,1154 ----
  	includeTag (type, isFileScope))
      {
  	vString *scope = vStringNew ();
+ 	/* Added "typeName" to store the typename from addOtherFields() until
+ 	 * it's used in makeTagEntry(). (Bram) */
+ 	vString *typeName = vStringNew ();
  	tagEntryInfo e;
  
  	initTagEntry (&e, vStringValue (token->name));
***************
*** 1117,1127 ****
  	e.kind		= tagLetter (type);
  
  	findScopeHierarchy (scope, st);
! 	addOtherFields (&e, type, st, scope);
  
  	makeTagEntry (&e);
  	makeExtraTagEntry (type, &e, scope);
  	vStringDelete (scope);
      }
  }
  
--- 1160,1171 ----
  	e.kind		= tagLetter (type);
  
  	findScopeHierarchy (scope, st);
! 	addOtherFields (&e, type, st, scope, typeName);
  
  	makeTagEntry (&e);
  	makeExtraTagEntry (type, &e, scope);
  	vStringDelete (scope);
+ 	vStringDelete (typeName);
      }
  }
  
***************
*** 2566,2571 ****
--- 2610,2627 ----
  	    {
  		if (isType (prev, TOKEN_NAME))
  		    copyToken (st->blockName, prev);
+ 		else
+ 		{
+ 		    char	buf[30];
+ 
+ 		    /* Added by Bram: for a nameless struct or union we use a
+ 		     * number, so that the members can be found. */
+ 		    vStringClear (st->blockName->name);
+ 		    sprintf(buf, "%d", ++numberForName);
+ 		    vStringCatS (st->blockName->name, buf);
+ 		    st->blockName->type = TOKEN_NAME;
+ 		    st->blockName->keyword = KEYWORD_NONE;
+ 		}
  		qualifyBlockTag (st, prev);
  	    }
  	    else if (isLanguage (Lang_csharp))
diff -cr ../ctags-5.5.4.orig/ctags.1 ./ctags.1
*** ../ctags-5.5.4.orig/ctags.1	Tue Mar 30 06:18:13 2004
--- ./ctags.1	Sun Sep 11 12:53:14 2005
***************
*** 453,458 ****
--- 453,461 ----
  .TP 4
  .I z
  Include the "kind:" key in kind field
+ .TP 4
+ .I t
+ Type and name of a variable or typedef as "typename:" field [enabled]
  .PD 1
  .RE
  
diff -cr ../ctags-5.5.4.orig/ctags.html ./ctags.html
*** ../ctags-5.5.4.orig/ctags.html	Tue Mar 30 06:18:20 2004
--- ./ctags.html	Sun Sep 11 12:54:26 2005
***************
*** 516,521 ****
--- 516,527 ----
  <DD>
  Include the &quot;kind:&quot; key in kind field
  
+ <DT><I>t</I>
+ 
+ <DD>
+ Include the type and name of a variable or typedef, using the "typename:" field
+ [enabled]
+ 
  </DL>
  </DL>
  
diff -cr ../ctags-5.5.4.orig/debug.c ./debug.c
*** ../ctags-5.5.4.orig/debug.c	Tue Apr  1 06:52:44 2003
--- ./debug.c	Sun Sep 11 13:05:03 2005
***************
*** 105,110 ****
--- 105,117 ----
  		tag->extensionFields.implementation != NULL)
  	    printf (" [imp:%s]", tag->extensionFields.implementation);
  
+ 	/* Added by Bram */
+ 	if (Option.extensionFields.typeName  &&
+ 		tag->extensionFields.typeName [0] != NULL  &&
+ 		tag->extensionFields.typeName [1] != NULL)
+ 	    printf (" [%s:%s]", tag->extensionFields.typeName [0],
+ 		    tag->extensionFields.typeName [1]);
+ 
  	printf ("#>");
  	fflush (stdout);
      }
diff -cr ../ctags-5.5.4.orig/entry.c ./entry.c
*** ../ctags-5.5.4.orig/entry.c	Wed Mar 24 03:28:52 2004
--- ./entry.c	Sun Sep 11 13:05:13 2005
***************
*** 729,734 ****
--- 729,742 ----
  			   tag->extensionFields.scope [0],
  			   tag->extensionFields.scope [1]);
  
+     /* Added by Bram.  TODO: use separate option? */
+     if (Option.extensionFields.typeName  &&
+ 	    tag->extensionFields.typeName [0] != NULL  &&
+ 	    tag->extensionFields.typeName [1] != NULL)
+ 	length += fprintf (TagFile.fp, "%s\ttypename:%s:%s", sep,
+ 			   tag->extensionFields.typeName [0],
+ 			   tag->extensionFields.typeName [1]);
+ 
      if (Option.extensionFields.fileScope  &&  tag->isFileScope)
  	length += fprintf (TagFile.fp, "%s\tfile:", sep);
  
diff -cr ../ctags-5.5.4.orig/entry.h ./entry.h
*** ../ctags-5.5.4.orig/entry.h	Mon Sep 30 06:30:47 2002
--- ./entry.h	Sun Sep 11 13:05:36 2005
***************
*** 72,77 ****
--- 72,82 ----
  	const char* inheritance;
  	const char* scope [2];	/* value and key */
  	const char* signature;
+ 
+ 	/* Added by Bram: type (union/struct/etc.) and name for a variable or
+ 	 * typedef. */
+ 	const char* typeName [2];	/* e.g., "struct" and struct name */
+ 
      } extensionFields;		/* list of extension fields*/
  } tagEntryInfo;
  
diff -cr ../ctags-5.5.4.orig/options.c ./options.c
*** ../ctags-5.5.4.orig/options.c	Sat Feb 28 16:19:45 2004
--- ./options.c	Sun Sep 11 12:50:56 2005
***************
*** 118,124 ****
  	FALSE,		/* -fields=l */
  	FALSE,		/* -fields=n */
  	TRUE,		/* -fields=s */
! 	FALSE		/* -fields=S */
      },
      NULL,		/* -I */
      FALSE,		/* -a */
--- 118,125 ----
  	FALSE,		/* -fields=l */
  	FALSE,		/* -fields=n */
  	TRUE,		/* -fields=s */
! 	FALSE,		/* -fields=S */
! 	TRUE		/* -fields=t */
      },
      NULL,		/* -I */
      FALSE,		/* -a */
***************
*** 207,213 ****
   {1,"  --extra=[+|-]flags"},
   {1,"      Include extra tag entries for selected information (flags: \"fq\")."},
   {1,"  --fields=[+|-]flags"},
!  {1,"      Include selected extension fields (flags: \"afmikKlnsSz\") [fks]."},
   {1,"  --file-scope=[yes|no]"},
   {1,"       Should tags scoped only for a single file (e.g. \"static\" tags"},
   {1,"       be included in the output [yes]?"},
--- 208,214 ----
   {1,"  --extra=[+|-]flags"},
   {1,"      Include extra tag entries for selected information (flags: \"fq\")."},
   {1,"  --fields=[+|-]flags"},
!  {1,"      Include selected extension fields (flags: \"afmikKlnsStz\") [fks]."},
   {1,"  --file-scope=[yes|no]"},
   {1,"       Should tags scoped only for a single file (e.g. \"static\" tags"},
   {1,"       be included in the output [yes]?"},
***************
*** 835,840 ****
--- 836,842 ----
  	field->kindLong		= FALSE;
  	field->language		= FALSE;
  	field->scope		= FALSE;
+ 	field->typeName		= FALSE;
      }
      while ((c = *p++) != '\0') switch (c)
      {
***************
*** 852,857 ****
--- 854,860 ----
  	case 's': field->scope		= mode;	break;
  	case 'S': field->signature	= mode;	break;
  	case 'z': field->kindKey	= mode;	break;
+ 	case 't': field->typeName	= mode;	break;
  
  	default: error(WARNING, "Unsupported parameter '%c' for \"%s\" option",
  		       c, option);
diff -cr ../ctags-5.5.4.orig/options.h ./options.h
*** ../ctags-5.5.4.orig/options.h	Mon Jul 21 03:09:08 2003
--- ./options.h	Sun Sep 11 12:48:29 2005
***************
*** 77,82 ****
--- 77,85 ----
      boolean lineNumber;
      boolean scope;
      boolean signature;
+ 
+     /* Added by Bram. */
+     boolean typeName;
  };
  
  /*  This stores the command line options.
