📄 args.c
字号:
/*ident "@(#)cls4:tools/demangler/osrc/args.c 1.1" *//******************************************************************************* C++ source for the C++ Language System, Release 3.0. This productis a new release of the original cfront developed in the computerscience research center of AT&T Bell Laboratories.Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved.THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX SystemLaboratories, Inc. The copyright notice above does not evidenceany actual or intended publication of such source code.*******************************************************************************//* * C++ Demangler Source Code * @(#)master 1.5 * 7/27/88 13:54:37 */#include <ctype.h>#if __STDC__ == 1# include <stdlib.h>#else extern long strtol();#endif#include "elf_dem.h"#include "String.h"/* This structure is used to keep * track of pointers to argument * descriptions in the mangled string. * This is needed for N and T encodings * to work. */typedef struct { char *list[10]; int pos;} Place;static Place here;/* Strings and flags needed by the argument demangles. The declarator * is built up in ptr. Type modifiers are held in the flag fields. * The type itself is passed in separately. */typedef struct { String *ptr; int Sign,Uns,Cons,Vol,Ptr,Ref;} Arg_Remem;/* initialize Arg_Remem */static voidmkar(r)Arg_Remem *r;{ r->ptr = mk_String((String *)0); r->Sign = r->Uns = r->Cons = r->Vol = r->Ptr = r->Ref = 0;}/* free data for Arg_Remem */static voiddelar(r)Arg_Remem *r;{ free_String(&r->ptr);}/* This routine formats a single argument * on the buffer sptr. * c is the type or class name, n is its length. */static voidnsetarg(sptr,r,c,n)String **sptr;Arg_Remem *r;char *c;{ r->ptr = nprep_String(c, -1, r->ptr, n); if(r->Cons) r->ptr = prep_String("const ",6,r->ptr); if(r->Vol) r->ptr = prep_String("volatile ",9,r->ptr); if(r->Uns) r->ptr = prep_String("unsigned ",9,r->ptr); else if(r->Sign) r->ptr = prep_String("signed ",7,r->ptr); *sptr = app_String(*sptr,PTR(r->ptr),-1); delar(r);}/* This routine formats a single argument * on the buffer sptr. * c is the null terminated type or class name. */static voidsetarg(sptr,r,c)String **sptr;Arg_Remem *r;char *c;{ nsetarg(sptr,r,c,NAME_MAX);}/* Demangle a single function argument. * Returns the number of characters processed from c. */intdoarg(sptr,c)String **sptr;char *c;{ register int i; Arg_Remem ar; mkar(&ar); if(here.pos < 10 && here.pos >= 0) here.list[here.pos++] = c; for(i=0;c[i];i++) { /* Loop until you find a type. Then call setarg and return. */ switch(c[i]) { case 'T': { Place tmp; tmp = here; here.pos = c[1] - '1'; if(here.pos < 0 || here.pos >= tmp.pos-1) { delar(&ar); return -1; } doarg(sptr,here.list[here.pos]); here = tmp; delar(&ar); return 2; } case 'N': { Place tmp; int cycles,pos; cycles = c[1] - '0'; pos = c[2] - '1'; here.pos += cycles - 1; tmp = here; if(cycles <= 1 || cycles > 9 || pos < 0 || pos >= tmp.pos-1) { delar(&ar); return -1; } while(cycles--) { here = tmp; here.pos = pos; doarg(sptr,here.list[here.pos]); (*sptr) = app_String(*sptr,",",1); } *sptr = trunc_String(*sptr, 1); here = tmp; delar(&ar); return 3; } /* Qualifiers to type names */ case 'S': ar.Sign = 1; break; case 'U': ar.Uns = 1; break; case 'C': ar.Cons = 1; break; case 'V': ar.Vol = 1; break; /* Pointers, references, and Member Pointers */ case 'P': case 'R': case 'M': if(ar.Cons) { ar.ptr = prep_String(" const",6,ar.ptr); ar.Cons = 0; } if(ar.Vol) { ar.ptr = prep_String(" volatile",9,ar.ptr); ar.Vol = 0; } if(c[i] == 'P') { ar.ptr = prep_String("*",1,ar.ptr); ar.Ptr = 1; /* hmm, should i set this to zero somewhere, like Cons above? */ } else if(c[i] == 'R') { ar.ptr = prep_String("&",1,ar.ptr); ar.Ref = 1; /* same hmm */ } else { int cnt = 0; char *s; ar.ptr = prep_String("::*",3,ar.ptr); /* Skip over the 'M' */ i++; cnt = strtol(c+i, &s, 10); i = s - c; ar.ptr = nprep_String(c+i, -1, ar.ptr, cnt); ar.ptr = prep_String(" ",1,ar.ptr); i += cnt; /* The loop increments i */ i--; } break; /* Demangle for basic built-in types */ case 'i': setarg(sptr,&ar,"int"); return i + 1; case 'c': setarg(sptr,&ar,"char"); return i + 1; case 's': setarg(sptr,&ar,"short"); return i + 1; case 'l': setarg(sptr,&ar,"long"); return i + 1; case 'f': setarg(sptr,&ar,"float"); return i + 1; case 'd': setarg(sptr,&ar,"double"); return i + 1; case 'r': setarg(sptr,&ar,"long double"); return i + 1; /* Class encodings */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int cnt = 0; char *s; cnt = strtol(c+i, &s, 10); i = s - c; if(strlen(c+i) < cnt) { delar(&ar); return -1; } nsetarg(sptr,&ar,c+i,cnt); return i+cnt; } /* Ellipsis and void */ case 'e': if(ar.Cons || ar.Vol || ar.Uns || ar.Sign || *PTR(ar.ptr) != '\0') return -1; /* remove previous comma */ (*sptr) = trunc_String(*sptr,1); (*sptr) = app_String(*sptr," ...",4); delar(&ar); return ++i; case 'v': if(ar.Vol || ar.Uns || ar.Sign || *PTR(ar.ptr) == '\0') return -1; if(ar.Cons) { if (ar.Ptr) (*sptr) = app_String(*sptr,"const ",6); else return -1; } (*sptr) = app_String(*sptr,"void",4); (*sptr) = app_String(*sptr,PTR(ar.ptr),-1); delar(&ar); return ++i; /* Arrays */ case 'A': if(*PTR(ar.ptr)) { ar.ptr = prep_String("(",1,ar.ptr); ar.ptr = app_String(ar.ptr,")",1); } ar.ptr = app_String(ar.ptr,"[",1); { int cnt = 0; i++; while(isdigit(c[i+cnt])) cnt++; ar.ptr = napp_String(ar.ptr,c+i,-1,cnt); i += cnt; if(c[i] != '_') { delar(&ar); return -1; } } ar.ptr = app_String(ar.ptr,"]",1); break; /* Functions * This will always be called as a pointer * to a function. */ case 'F': ar.ptr = prep_String("(",1,ar.ptr); ar.ptr = app_String(ar.ptr,")",1); { Place tmp; tmp = here; i++; i += doargs(&ar.ptr,c+i); if(c[i] != '_') { delar(&ar); return -1; } here = tmp; } break; /* Qualified type name */ case 'Q': { String *tmp; int numquals = 0; char *s; int j; tmp = mk_String((String *) 0); numquals = strtol(c+i+1, &s, 10); if (*s != '_') { delar(&ar); return -1; } s++; for (j = 0; j < numquals; j++) { int cnt = strtol(s, &s, 10); if (cnt <= 0 || strlen(s) < cnt) { delar(&ar); return -1; } if (j > 0) { tmp = app_String(tmp,"::",2); } tmp = app_String(tmp,s,cnt); s += cnt; } i = s - c; setarg(sptr,&ar,PTR(tmp)); free_String(&tmp); return i; } break; /* Needed when this is called to demangle * an argument of a pointer to a function. */ case '_': delar(&ar); return 0; default: delar(&ar); return -1; } } /* Did the argument list terminate properly? */ { int rc = 0; if(*PTR(ar.ptr) || ar.Uns || ar.Sign || ar.Cons || ar.Vol) rc = -1; delar(&ar); return rc; }}/* This function is called to demangle * an argument list. * Returns the number of characters processed from c. */intdoargs(sptr,c)String **sptr;char *c;{ int i,n = 0; here.pos = 0; *sptr = app_String(*sptr,"(",1); while(*c && (i = doarg(sptr,c)) > 0) { c += i; n += i; (*sptr) = app_String(*sptr,",",1); } if(i < 0) return -1; *sptr = app_String(trunc_String(*sptr, 1),")",1); return n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -