void dump() const {
     QTextStream outs(stderr, QIODevice::WriteOnly);
     QList<Line> lines;
     foreach (const char *func, counters.keys()) {
         const Counters &fCount = counters[func];
         for (int i = 0, ei = fCount.size(); i != ei; ++i) {
             quint64 count = fCount[i];
             if (!count)
                 continue;
             Line line;
             line.func = func;
             unmangle(i, line.tag1, line.tag2);
             line.count = count;
             lines.append(line);
         }
     }
     qSort(lines.begin(), lines.end(), Line::less);
     outs << lines.size() << " counters:" << endl;
     foreach (const Line &line, lines)
         outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
              << " | " << line.func
              << " | " << pretty(line.tag1)
              << " | " << pretty(line.tag2)
              << endl;
 }
Ejemplo n.º 2
0
static int
display_summary(void)
{
	FILE *swaps;
	char line[1024] ;

	if ((swaps = fopen(_PATH_PROC_SWAPS, "r")) == NULL) {
		warn(_("%s: open failed"), _PATH_PROC_SWAPS);
		return -1;
	}

	while (fgets(line, sizeof(line), swaps)) {
		char *p, *dev, *cn;
		if (!strncmp(line, "Filename\t", 9)) {
			printf("%s", line);
			continue;
		}
		for (p = line; *p && *p != ' '; p++);
		*p = '\0';
		for (++p; *p && isblank((unsigned int) *p); p++);

		dev = unmangle(line, NULL);
		if (!dev)
			continue;
		cn = canonicalize_path(dev);
		if (cn)
			printf("%-39s %s", cn, p);
		free(dev);
		free(cn);
	}

	fclose(swaps);
	return 0 ;
}
Ejemplo n.º 3
0
static void
read_proc_swaps(void) {
	FILE *swaps;
	char line[1024];
	char *p, **q;
	size_t sz;

	numSwaps = 0;
	swapFiles = NULL;

	swaps = fopen(_PATH_PROC_SWAPS, "r");
	if (swaps == NULL)
		return;		/* nothing wrong */

	/* skip the first line */
	if (!fgets(line, sizeof(line), swaps)) {
		/* do not whine about an empty file */
		if (ferror(swaps))
			warn(_("%s: unexpected file format"), _PATH_PROC_SWAPS);
		fclose(swaps);
		return;
	}
	/* make sure the first line is the header */
	if (line[0] != '\0' && strncmp(line, "Filename\t", 9))
		goto valid_first_line;

	while (fgets(line, sizeof(line), swaps)) {
 valid_first_line:
		/*
		 * Cut the line "swap_device  ... more info" after device.
		 * This will fail with names with embedded spaces.
		 */
		for (p = line; *p && *p != ' '; p++);
		*p = '\0';

		/* the kernel can use " (deleted)" suffix for paths
		 * in /proc/swaps, we have to remove this junk.
		 */
		sz = strlen(line);
		if (sz > PATH_DELETED_SUFFIX_SZ) {
		       p = line + (sz - PATH_DELETED_SUFFIX_SZ);
		       if (strcmp(p, PATH_DELETED_SUFFIX) == 0)
			       *p = '\0';
		}

		q = realloc(swapFiles, (numSwaps+1) * sizeof(*swapFiles));
		if (q == NULL)
			break;
		swapFiles = q;

		if ((p = unmangle(line, NULL)) == NULL)
			break;

		swapFiles[numSwaps++] = canonicalize_path(p);
		free(p);
	}
	fclose(swaps);
}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
    char    buff[512];
    int i;

    if  (argc == 1)
    {
        argc    = 2;
        argv[1] = "@foo@bar@$bctr$q";
    }

    for (i = 1; i < argc; i++)
    {
        printf("%-40s ", argv[i]);

        switch  (unmangle(argv[i], buff, 512, 0, 0, 1))
        {
        case    UM_NOT_MANGLED:
            printf("not mangled '%s'\n", buff);
            break;

        case    UM_MEMBER_FN:
            printf("Member fn   '%s'\n", buff);
            break;

        case    UM_CONSTRUCTOR:
            printf("Constructor '%s'\n", buff);
            break;

        case    UM_DESTRUCTOR:
            printf("Destructor  '%s'\n", buff);
            break;

        case    UM_OPERATOR:
            printf("Operator    '%s'\n", buff);
            break;

        case    UM_CONVERSION:
            printf("Conversion  '%s'\n", buff);
            break;

        case    UM_STATIC_DM:
            printf("Static d.m. '%s'\n", buff);
            break;

        case    UM_THUNK:
            printf("Thunk       '%s'\n", buff);
            break;

        case    UM_OTHER:
            printf("??????????? '%s'\n", buff);
            break;

        }
    }
    return  0;
}
Ejemplo n.º 5
0
 void GetArgData(char *proto, struct _ProtoData *arg)
 {
     sprintf(proto, "%s", arg->fieldType);
     if (arg->fieldName[0] != '{' && strcmp(arg->fieldName, " ")) // unnamed...
     {
         strcat(proto, " ");
         unmangle(proto + strlen(proto), arg->fieldName);
     }
 }
void FormatProcName( uchar *buf, uint addr, SCOPE scope, DEBFILE *pdf,  /*824*/
                       uchar FrameAtr, int MaxSymLen)                   /*824*/
{                                                                       /*824*/
 uchar *cp;                                                             /*824*/
 ushort Sel;                                                            /*824*/
 ushort Off;                                                            /*824*/
                                                                        /*824*/
 /****************************************************************************/
 /* Stuff a z-string name in the buf.                                     824*/
 /* - If there is scope, then get the name from symbols.                  824*/
 /* - else get the name from publics.                                     824*/
 /* - else format as 32 address if 32 bit frame.                          824*/
 /* - else format as 16 address if 16 bit frame.                          824*/
 /****************************************************************************/
 if( scope != NULL)
  CopyProcName( scope, buf, MaxSymLen );
 else
 {
  cp = DBFindProcName(addr , pdf);
  if ( cp )
  {
   int  NameLen;
   BOOL IsMangled;
   char buffer[256];

   memset(buffer, 0, sizeof(buffer));

   IsMangled = FALSE;
   IsMangled = unmangle( buffer, cp + 2 );
   if( IsMangled == FALSE )
   {
    NameLen =  *(USHORT *)cp;
    if( NameLen > MaxSymLen )
     NameLen = MaxSymLen;
    memcpy(buf, cp+2, NameLen);
    buf[NameLen] = '\0';
   }
   else
   {
    NameLen =  strlen(buffer);
    if( NameLen > MaxSymLen )
     NameLen = MaxSymLen;
    memcpy(buf, buffer, NameLen);
    buf[NameLen] = '\0';
   }
  }
  else if ( FrameAtr == ATR32 )
  {
   sprintf(buf, "%08X", addr);
  }
  else /* FrameAtr == ATR16 */
  {
   Code_Flat2SelOff(addr,&Sel,&Off);
   sprintf( buf, "%04X:%04X",Sel,Off);
  }
 }
}
Ejemplo n.º 7
0
/*
 * Parses one line from utab file
 */
static int mnt_parse_utab_line(struct libmnt_fs *fs, const char *s)
{
	const char *p = s;

	assert(fs);
	assert(s);
	assert(!fs->source);
	assert(!fs->target);

	while (p && *p) {
		char *end = NULL;

		while (*p == ' ') p++;
		if (!*p)
			break;

		if (!fs->source && !strncmp(p, "SRC=", 4)) {
			char *v = unmangle(p + 4, &end);
			if (!v)
				goto enomem;
			__mnt_fs_set_source_ptr(fs, v);

		} else if (!fs->target && !strncmp(p, "TARGET=", 7)) {
			fs->target = unmangle(p + 7, &end);
			if (!fs->target)
				goto enomem;

		} else if (!fs->root && !strncmp(p, "ROOT=", 5)) {
			fs->root = unmangle(p + 5, &end);
			if (!fs->root)
				goto enomem;

		} else if (!fs->bindsrc && !strncmp(p, "BINDSRC=", 8)) {
			fs->bindsrc = unmangle(p + 8, &end);
			if (!fs->bindsrc)
				goto enomem;

		} else if (!fs->user_optstr && !strncmp(p, "OPTS=", 5)) {
			fs->user_optstr = unmangle(p + 5, &end);
			if (!fs->user_optstr)
				goto enomem;

		} else if (!fs->attrs && !strncmp(p, "ATTRS=", 6)) {
			fs->attrs = unmangle(p + 6, &end);
			if (!fs->attrs)
				goto enomem;

		} else {
			/* unknown variable */
			while (*p && *p != ' ') p++;
		}
		if (end)
			p = end;
	}

	return 0;
enomem:
	DBG(TAB, mnt_debug("utab parse error: ENOMEM"));
	return -ENOMEM;
}
Ejemplo n.º 8
0
static void InsertUsage(char *name, char *file, int line, BOOL definition, BOOL declaration)
{
    char unmangled[2048];
    BROWSEWNDDATA *newData = calloc(1, sizeof(BROWSEWNDDATA));
    unmangle(unmangled, name);
    newData->declaration = declaration;
    newData->definition = definition;
    strcpy(newData->file,file);
    newData->line = line;
    strcpy(newData->name, unmangled);
    if (browsecount >= browsemax)
    {
        if (!browsecount)
            browsemax = 10;
        else
            browsemax = 2 * browsemax;
       browselist = realloc(browselist, browsemax * sizeof(BROWSEWNDDATA *));
    }
    browselist[browsecount++] = newData;
}
Ejemplo n.º 9
0
/**
 * mnt_unmangle:
 * @str: string
 *
 * Decode @str from fstab/mtab
 *
 * Returns: new allocated string or NULL in case of error.
 */
char *mnt_unmangle(const char *str)
{
	return unmangle(str, NULL);
}
Ejemplo n.º 10
0
void PE_Debug::DumpSymbolInfo(std::ostream& dumpBuffer, DWORD relativeAddress )
{
    // Variables to keep track of function symbols
    PIMAGE_SYMBOL currentSym = COFFSymbolTable ;
    PIMAGE_SYMBOL fnSymbol = NULL ;
    DWORD maxFnAddress = 0 ;

#ifdef DUMPRAM
    InitSymbols();
#endif

    // Variables to keep track of file symbols
    PIMAGE_SYMBOL fileSymbol = NULL ;
    PIMAGE_SYMBOL latestFileSymbol = NULL ;
    for ( int i = 0; i < COFFSymbolCount; i++ )	{

        // Look for .text section where relativeAddress belongs to.
        // Keep track of the filename the .text section belongs to.
        if ( currentSym->StorageClass == IMAGE_SYM_CLASS_FILE )	{
            latestFileSymbol = currentSym;
        }

        // Borland uses "CODE" instead of the standard ".text" entry
        // Microsoft uses sections that only _begin_ with .text
        const char* symName = GetSymbolName( currentSym ) ;

        if ( strnicmp( symName, ".text", 5 ) == 0 || strcmpi( symName, "CODE" ) == 0 )	{
            if ( currentSym->Value <= relativeAddress )	{
                PIMAGE_AUX_SYMBOL auxSym = (PIMAGE_AUX_SYMBOL)(currentSym + 1) ;
                if ( currentSym->Value + auxSym->Section.Length >= relativeAddress )	{
                    fileSymbol = latestFileSymbol ;
                }
            }
        }


        // Look for the function with biggest address <= relativeAddress
        BOOL isFunction = ISFCN( currentSym->Type ); // Type == 0x20, See WINNT.H
        if ( isFunction && ( currentSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL || currentSym->StorageClass == IMAGE_SYM_CLASS_STATIC ) )	{

            if ( currentSym->Value <= relativeAddress && currentSym->Value > maxFnAddress )	{
                maxFnAddress = currentSym->Value ;
                fnSymbol = currentSym ;
            }
        }

#ifdef DUMPRAM
        if ( !isFunction && (currentSym->SectionNumber >= 0) )	{
            if ( (symName[0]=='_' && symName[1]!='$') || (symName[0]=='?') ) {

                char pretty_module[1024];

                if ( fileSymbol )	{
                    const char* auxSym = (const char*)(latestFileSymbol + 1) ;
                    char tmpFile[ VA_MAX_FILENAME_LEN ] ;
                    strcpy_s( tmpFile, auxSym ) ;
                    strcpy_s( pretty_module, tmpFile );
                    char *p = pretty_module+strlen(pretty_module)-1;
                    // Move p to point to first letter of EXE filename
                    while( (*p!='\\') && (*p!='/') && (*p!=':') )
                        p--;
                    p++;
                    if ( strlen(p) < 1 ) {
                        strcpy_s( pretty_module, "<unknown>" );
                    } else {
                        memmove( pretty_module, p, strlen(p)+1 );
                    }
                } else {
                    strcpy_s( pretty_module, "" );
                }

                Add_Symbol( currentSym->SectionNumber, currentSym->Value, symName, pretty_module );
            }
        }
#endif

        // Advance counters, skip aux symbols
        i += currentSym->NumberOfAuxSymbols ;
        currentSym += currentSym->NumberOfAuxSymbols ;
        currentSym++ ;
    }

#ifdef DUMPRAM
    DumpSymbols();
#endif

    // dump symbolic info if found
    if ( fileSymbol )	{
        const char* auxSym = (const char*)(fileSymbol + 1) ;

        if( strcmpi( latestFile, auxSym ) )	{
            strcpy_s( latestFile, auxSym ) ;
            //JAS      dumpBuffer.Printf( "  file: %s\r\n", auxSym ) ;
        }
    } else {
        latestFile[ 0 ] = 0 ;
        //JAS    dumpBuffer.Printf( "  file: unknown\r\n" ) ;
    }

    if ( fnSymbol )	{
        char tmp_name[1024];
        unmangle(tmp_name, GetSymbolName( fnSymbol ) );
        dumpBuffer << "    " << tmp_name << "()";
    } else {
        dumpBuffer << "    <unknown>";
    }
}
Ejemplo n.º 11
0
TYPE *typenum(char *buf, TYPE *tp)
{
    SYMBOL *sp;
    HASHREC *hr;
    char name[100];
    if (tp == NULL)
    {
        diag("typenum - NULL type");
        return &stdvoid;
    }
    tp = enumConst(buf, tp);
    buf += strlen(buf);
    switch (tp->type)
    {
        case bt_typedef:
            strcpy(buf, tp->sp->name);
            break;
        case bt_aggregate:
            hr = tp->syms->table[0];
            sp = (SYMBOL *)hr->p;
            if (hr->next || !strcmp(sp->name, tp->sp->name)) // the tail is to prevent a problem when there are a lot of errors
            {
                strcpy(buf," (*)(???)");
                break;
            }
            tp = sp->tp;
            /* fall through */
        case bt_func:
        case bt_ifunc:
            typenum(buf, tp->btp);
            buf = buf + strlen(buf);
            strcat(buf," (*)(");
            buf += strlen(buf);
            if (tp->syms)
            {
                hr = tp->syms->table[0];
                while (hr)
                {
                    sp = (SYMBOL *)hr->p;
                    *buf = 0;
                    typenum(buf, sp->tp);
                    buf = buf + strlen(buf);
                    hr = hr->next;
                    if (hr)
                        *buf++ = ',';
                }
            }
            *buf++ = ')';
            *buf = 0;
            break;
        case bt_float_complex:
            strcpy(buf, tn_floatcomplex);
            break;
        case bt_double_complex:
            strcpy(buf, tn_doublecomplex);
            break;
        case bt_long_double_complex:
            strcpy(buf, tn_longdoublecomplex);
            break;
        case bt_float_imaginary:
            strcpy(buf, tn_floatimaginary);
            break;
        case bt_double_imaginary:
            strcpy(buf, tn_doubleimaginary);
            break;
        case bt_long_double_imaginary:
            strcpy(buf, tn_longdoubleimaginary);
            break;
        case bt_float:
            strcpy(buf, tn_float);
            break;
        case bt_double:
            strcpy(buf, tn_double);
            break;
        case bt_long_double:
            strcpy(buf, tn_longdouble);
            break;
        case bt_unsigned:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_int:
            strcpy(buf, tn_int);
            break;
        case bt_char16_t:
            strcpy(buf, tn_char16_t);
            break;
        case bt_char32_t:
            strcpy(buf, tn_char32_t);
            break;
        case bt_unsigned_long_long:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_long_long:
            strcpy(buf, tn_longlong);
            break;
        case bt_unsigned_long:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_long:
            strcpy(buf, tn_long);
            break;
        case bt_wchar_t:
            strcpy(buf, tn_wchar_t);
            break;
        case bt_unsigned_short:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_short:
            strcpy(buf, tn_short);
            break;
        case bt_unsigned_char:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_char:
            strcpy(buf, tn_char);
            break;
        case bt_bool:
            strcpy(buf, "bool");
            break;
        case bt_bit:
            strcpy(buf, "bit");
            break;
        case bt_void:
            strcpy(buf, tn_void);
            break;
        case bt_pointer:
            typenumptr(buf, tp);
            break;
        case bt_memberptr:
            getcls(buf, tp->sp);
            buf += strlen(buf);
            strcpy(buf, "::*");
            break;
        case bt_seg:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            strcpy(buf, " _seg *");
            break;
        case bt_lref:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            *buf++ = ' ';
            *buf++ = '&';
            *buf = 0;
            break;
        case bt_rref:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            *buf++ = ' ';
            *buf++ = '&';
            *buf++ = '&';
            *buf = 0;
            break;
        case bt_ellipse:
            strcpy(buf, tn_ellipse);
            break;
        case bt_any:
            strcpy(buf, "???");
            break;
        case bt_class:
/*                strcpy(buf, tn_class); */
            unmangle(name, tp->sp->errname);
            strcpy(buf, name);
            break;
        case bt_struct:
/*                strcpy(buf, tn_struct); */
            unmangle(name, tp->sp->errname);
            strcpy(buf, name);
            break;
        case bt_union:
/*                strcpy(buf, tn_union); */
            unmangle(name, tp->sp->errname);
            strcpy(buf, name);
            break;
        case bt_enum:
/*                strcpy(buf, tn_enum);  */
            unmangle(name, tp->sp->errname);
            strcpy(buf, name);
            break;
    }
    return 0;
}
Ejemplo n.º 12
0
 static BOOL GetFragments(CCFUNCDATA *funcs, int funcpos, int curarg, char **fragments)
 {
     char buf[2048], *last= funcs->fullname,*p;
     int n = GetFuncCount(funcs);
     int i, nesting = 0;
     for (i=0; i < funcpos && funcs; i++)
         funcs = funcs->next;
     if (!funcs)
         return FALSE;
     p = funcs->fullname;
     while (*p)
     {
         switch(*p)
         {
             case '@':
                 if (!nesting)
                     last = p;
                 break;
             case '#':
                 nesting++;
                 break;
             case '~':
                 if (nesting)
                     nesting--;
                 break;
         }
         p++;
     }
     if (last != p)
     {
         while (*last && *last != '$')
             last ++;
         * last = 0;
     }
     sprintf(buf, "%d of %d", funcpos+1, n);
     fragments[0] = strdup(buf);
     unmangle(buf, funcs->fullname);
     if (last != p)
         *last = '$';
     strcat(buf, "(");
     for (i=0; i < curarg && i < funcs->args->argCount; i++)
     {
         GetArgData(buf + strlen(buf), &funcs->args->data[i]);
         if (i < funcs->args->argCount-1)
             strcat(buf, ", ");
             
     }
     fragments[1] = strdup(buf);
     fragments[2] = NULL;
     if (i < funcs->args->argCount)
     {
         GetArgData(buf, &funcs->args->data[i]);
         if (i < funcs->args->argCount-1)
             strcat(buf, ", ");
         i++;
         fragments[2] = strdup(buf);
     }
     fragments[3] = NULL;
     buf[0] = 0;
     for (;i < funcs->args->argCount; i++)
     {
         GetArgData(buf + strlen(buf), &funcs->args->data[i]);
         if (i < funcs->args->argCount-1)
             strcat(buf, ", ");
             
     }
     strcat(buf, ")");
     fragments[3] = strdup(buf);
     return TRUE;
 }
Ejemplo n.º 13
0
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
struct my_mntent *
my_getmntent (mntFILE *mfp) {
	static char buf[4096];
	static struct my_mntent me;
	char *s;

 again:
	if (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX)
		return NULL;

	/* read the next non-blank non-comment line */
	do {
		if (fgets (buf, sizeof(buf), mfp->mntent_fp) == NULL)
			return NULL;

		mfp->mntent_lineno++;
		s = strchr (buf, '\n');
		if (s == NULL) {
			/* Missing final newline?  Otherwise extremely */
			/* long line - assume file was corrupted */
			if (feof(mfp->mntent_fp)) {
				fprintf(stderr, _("[mntent]: warning: no final "
					"newline at the end of %s\n"),
					mfp->mntent_file);
				s = strchr (buf, 0);
			} else {
				mfp->mntent_errs = 1;
				goto err;
			}
		}
		*s = 0;
		if (--s >= buf && *s == '\r')
			*s = 0;
		s = skip_spaces(buf);
	} while (*s == '\0' || *s == '#');

	me.mnt_fsname = unmangle(s, &s);
	s = skip_spaces(s);
	me.mnt_dir = unmangle(s, &s);
	s = skip_spaces(s);
	me.mnt_type = unmangle(s, &s);
	s = skip_spaces(s);
	me.mnt_opts = unmangle(s, &s);
	s = skip_spaces(s);

	if (!me.mnt_fsname || !me.mnt_dir || !me.mnt_type)
		goto err;

	if (isdigit(*s)) {
		me.mnt_freq = atoi(s);
		while(isdigit(*s)) s++;
	} else
		me.mnt_freq = 0;
	if(*s && !is_space_or_tab(*s))
		goto err;

	s = skip_spaces(s);
	if(isdigit(*s)) {
		me.mnt_passno = atoi(s);
		while(isdigit(*s)) s++;
	} else
		me.mnt_passno = 0;
	if(*s && !is_space_or_tab(*s))
		goto err;

	/* allow more stuff, e.g. comments, on this line */

	return &me;

 err:
	mfp->mntent_softerrs++;
	fprintf(stderr, _("[mntent]: line %d in %s is bad%s\n"),
		mfp->mntent_lineno, mfp->mntent_file,
		(mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) ?
		_("; rest of file ignored") : "");
	goto again;
}
Ejemplo n.º 14
0
static char *unmangledname(char *str)
{
    static char name[256];
    unmangle(name, str);
    return name;
}
Ejemplo n.º 15
0
TYPE *typenum(char *buf, TYPE *tp)
{
    SYMBOL *sp;
    HASHREC *hr;
    char name[4096];
    if (tp == NULL)
    {
        diag("typenum - NULL type");
        return &stdvoid;
    }
    if (tp->type == bt_derivedfromtemplate)
        tp = tp->btp;
    tp = enumConst(buf, tp);
    if (!tp)
        return NULL;
    buf += strlen(buf);
    switch (tp->type)
    {
        case bt_typedef:
            strcpy(buf, tp->sp->name);
            break;
        case bt_aggregate:
            if (!tp->syms)
                break;
            hr = tp->syms->table[0];
            sp = (SYMBOL *)hr->p;
            if (hr->next || !strcmp(sp->name, tp->sp->name)) // the tail is to prevent a problem when there are a lot of errors
            {
                strcpy(buf," (*)(\?\?\?)");
                break;
            }
            tp = sp->tp;
            /* fall through */
        case bt_func:
        case bt_ifunc:
            typenum(buf, tp->btp);
            buf = buf + strlen(buf);
            if (tp->syms)
            {
                hr = tp->syms->table[0];
                if (hr && hr->p)
                {
                    if (((SYMBOL *)hr->p)->thisPtr)
                    {
                        SYMBOL *thisptr = (SYMBOL *)hr->p;
                        *buf++ = ' ';
                        *buf++='(';
                        getcls(buf, basetype (basetype(thisptr->tp)->btp)->sp);
                        strcat(buf, "::*)(");
                        buf += strlen(buf);
                        hr = hr->next;
                    }
                    else
                    {
                       strcat(buf," (*)(");
                        buf += strlen(buf);
                    }
                }
                else
                {
                    strcat(buf," (*)(");
                    buf += strlen(buf);
                }
                while (hr)
                {
                    sp = (SYMBOL *)hr->p;
                    *buf = 0;
                    typenum(buf, sp->tp);
                    buf = buf + strlen(buf);
                    hr = hr->next;
                    if (hr)
                        *buf++ = ',';
                }
            }
            else
            {
                strcat(buf," (*)(");
                buf += strlen(buf);
            }
            *buf++ = ')';
            *buf = 0;
            break;
        case bt_float_complex:
            strcpy(buf, tn_floatcomplex);
            break;
        case bt_double_complex:
            strcpy(buf, tn_doublecomplex);
            break;
        case bt_long_double_complex:
            strcpy(buf, tn_longdoublecomplex);
            break;
        case bt_float_imaginary:
            strcpy(buf, tn_floatimaginary);
            break;
        case bt_double_imaginary:
            strcpy(buf, tn_doubleimaginary);
            break;
        case bt_long_double_imaginary:
            strcpy(buf, tn_longdoubleimaginary);
            break;
        case bt_float:
            strcpy(buf, tn_float);
            break;
        case bt_double:
            strcpy(buf, tn_double);
            break;
        case bt_long_double:
            strcpy(buf, tn_longdouble);
            break;
        case bt_unsigned:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_int:
            strcpy(buf, tn_int);
            break;
        case bt_char16_t:
            strcpy(buf, tn_char16_t);
            break;
        case bt_char32_t:
            strcpy(buf, tn_char32_t);
            break;
        case bt_unsigned_long_long:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_long_long:
            strcpy(buf, tn_longlong);
            break;
        case bt_unsigned_long:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_long:
            strcpy(buf, tn_long);
            break;
        case bt_wchar_t:
            strcpy(buf, tn_wchar_t);
            break;
        case bt_unsigned_short:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_short:
            strcpy(buf, tn_short);
            break;
        case bt_signed_char:
            strcpy(buf, tn_signed);
            buf = buf + strlen(buf);
            strcpy(buf, tn_char);
            break;
        case bt_unsigned_char:
            strcpy(buf, tn_unsigned);
            buf = buf + strlen(buf);
        case bt_char:
            strcpy(buf, tn_char);
            break;
        case bt_bool:
            strcpy(buf, tn_bool);
            break;
        case bt_bit:
            strcpy(buf, "bit");
            break;
        case bt_void:
            strcpy(buf, tn_void);
            break;
        case bt_pointer:
            if (tp->nullptrType)
            {
                strcpy(buf, "nullptr_t");
            }
            else
            {
                typenumptr(buf, tp);
            }
            break;
        case bt_memberptr:
            if (isfunction(basetype(tp)->btp))
            {
                TYPE *func = basetype(tp)->btp;
                typenum(buf, basetype(func)->btp);
                strcat(buf, " (");
                buf += strlen(buf);
                getcls(buf, tp->sp);
                buf += strlen(buf);
                strcpy(buf, "::*)(");
                buf += strlen(buf);
                if (basetype(func)->syms)
                {
                    hr = basetype(func)->syms->table[0];
                    while (hr)
                    {
                        sp = (SYMBOL *)hr->p;
                        *buf = 0;
                        typenum(buf, sp->tp);
                        buf = buf + strlen(buf);
                        hr = hr->next;
                        if (hr)
                            *buf++ = ',';
                    }
                }
                *buf++ = ')';
                *buf = 0;
            }
            else
            {
                typenum(buf, tp->btp);
                strcat(buf, " ");
                buf += strlen(buf);
                getcls(buf, tp->sp);
                buf += strlen(buf);
                strcpy(buf, "::*");
            }
            break;
        case bt_seg:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            strcpy(buf, " _seg *");
            break;
        case bt_lref:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            *buf++ = ' ';
            *buf++ = '&';
            *buf = 0;
            break;
        case bt_rref:
            typenum(buf, tp->btp);
            buf += strlen(buf);
            *buf++ = ' ';
            *buf++ = '&';
            *buf++ = '&';
            *buf = 0;
            break;
        case bt_ellipse:
            strcpy(buf, tn_ellipse);
            break;
        case bt_any:
            strcpy(buf, "???");
            break;
        case bt_class:
/*                strcpy(buf, tn_class); */
            unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name);
            strcpy(buf, name);
            break;
        case bt_struct:
/*                strcpy(buf, tn_struct); */
            unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name);
            strcpy(buf, name);
            break;
        case bt_union:
/*                strcpy(buf, tn_union); */
            unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name);
            strcpy(buf, name);
            break;
        case bt_enum:
/*                strcpy(buf, tn_enum);  */
            unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name);
            strcpy(buf, name);
            break;
        case bt_templateselector:
        {
            TEMPLATESELECTOR *ts = tp->sp->templateSelector->next;
            if (ts->sym)
            {
                strcpy(buf, ts->sym->name);
                ts = ts->next;
                while (ts)
                {
                    strcat(buf, "::");
                    strcat(buf, ts->name);
                    ts = ts->next;
                }
            }
            break;
        }
        case bt_templatedecltype:
            RenderExpr(buf, tp->templateDeclType);
            break;
        case bt_auto:
            strcpy(buf, "auto ");
            break;
        default:
            strcpy(buf, "\?\?\?");
    }
    return 0;
}