⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stabstring.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/*#@(#)stabstring.c	4.1	Ultrix	7/17/90*//* * String information interpretation * * The string part of a stab entry is broken up into name and type information. */static char rcsid[] = "$Header: stabstring.c,v 1.4 84/03/27 10:24:04 linton Exp $";#include "defs.h"#include "stabstring.h"#include "object.h"#include "main.h"#include "symbols.h"#include "names.h"#include "languages.h"#include <a.out.h>#include <ctype.h>#ifndef public#endif/* * Special characters in symbol table information. */#define TYPENAME 't'#define TAGNAME 'T'#define MODULEBEGIN 'm'#define EXTPROCEDURE 'P'#define PRIVPROCEDURE 'Q'#define INTPROCEDURE 'I'#define EXTFUNCTION 'F'#define PRIVFUNCTION 'f'#define INTFUNCTION 'J'#define EXTVAR 'G'#define MODULEVAR 'S'#define OWNVAR 'V'#define REGVAR 'r'#define VALUEPARAM 'p'#define VARIABLEPARAM 'v'#define LOCALVAR /* default *//* * Type information special characters. */#define T_SUBRANGE 'r'#define T_ARRAY 'a'#define T_OPENARRAY 'A'#define T_RECORD 's'#define T_UNION 'u'#define T_ENUM 'e'#define T_PTR '*'#define T_FUNCVAR 'f'#define T_PROCVAR 'p'#define T_IMPORTED 'i'#define T_SET 'S'#define T_OPAQUE 'o'/* * Table of types indexed by per-file unique identification number. */#define NTYPES 1000private Symbol typetable[NTYPES];public initTypeTable (){    bzero(typetable, sizeof(typetable));    (*language_op(curlang, L_MODINIT))(typetable);}/* * Put an nlist entry into the symbol table. * If it's already there just add the associated information. * * Type information is encoded in the name following a ":". */private Symbol constype();private Char *curchar;#define skipchar(ptr, ch) \{ \    if (*ptr != ch) { \	panic("expected char '%c', found '%s'", ch, ptr); \    } \    ++ptr; \}#define optchar(ptr, ch) \{ \    if (*ptr == ch) { \	++ptr; \    } \}#define chkcont(ptr) \{ \    if (*ptr == '?') { \	ptr = getcont(); \    } \}#define newSym(s, n) \{ \    s = insert(n); \    s->level = curblock->level + 1; \    s->language = curlang; \    s->block = curblock; \}#define makeVariable(s, n, off) \{ \    newSym(s, n); \    s->class = VAR; \    s->symvalue.offset = off; \    getType(s); \}#define makeParameter(s, n, cl, off) \{ \    newSym(s, n); \    s->class = cl; \    s->symvalue.offset = off; \    curparam->chain = s; \    curparam = s; \    getType(s); \}public entersym (name, np)String name;struct nlist *np;{    Symbol s;    char *p;    register Name n;    char c;    p = index(name, ':');    *p = '\0';    c = *(p+1);    n = identname(name, true);    chkUnnamedBlock();    curchar = p + 2;    switch (c) {	case TYPENAME:	    newSym(s, n);	    typeName(s);	    break;	case TAGNAME:	    newSym(s, n);	    tagName(s);	    break;	case MODULEBEGIN:	    newSym(s, n);	    publicRoutine(s, MODULE, np->n_value);	    curmodule = s;	    break;	case EXTPROCEDURE:	    newSym(s, n);	    publicRoutine(s, PROC, np->n_value);	    break;	case PRIVPROCEDURE:	    privateRoutine(&s, n, PROC, np->n_value);	    break;	case INTPROCEDURE:	    newSym(s, n);	    markInternal(s);	    publicRoutine(s, PROC, np->n_value);	    break;	case EXTFUNCTION:	    newSym(s, n);	    publicRoutine(s, FUNC, np->n_value);	    break;	case PRIVFUNCTION:	    privateRoutine(&s, n, FUNC, np->n_value);	    break;	case INTFUNCTION:	    newSym(s, n);	    markInternal(s);	    publicRoutine(s, FUNC, np->n_value);	    break;	case EXTVAR:	    find(s, n) where		s->level == program->level and s->class == VAR	    endfind(s);	    if (s == nil) {		makeVariable(s, n, np->n_value);		s->level = program->level;		s->block = program;		getExtRef(s);	    }	    break;	case MODULEVAR:	    if (curblock->class != MODULE) {		exitblock();	    }	    makeVariable(s, n, np->n_value);	    s->level = program->level;	    s->block = curmodule;	    getExtRef(s);	    break;	case OWNVAR:	    makeVariable(s, n, np->n_value);	    ownVariable(s, np->n_value);	    getExtRef(s);	    break;	case REGVAR:	    makeVariable(s, n, np->n_value);	    s->level = -(s->level);	    break;	case VALUEPARAM:	    makeParameter(s, n, VAR, np->n_value);	    break;	case VARIABLEPARAM:	    makeParameter(s, n, REF, np->n_value);	    break;	default:	/* local variable */	    --curchar;	    makeVariable(s, n, np->n_value);	    break;    }    if (tracesyms) {	printdecl(s);	fflush(stdout);    }}/* * Enter a type name. */private typeName (s)Symbol s;{    register integer i;    s->class = TYPE;    s->language = curlang;    s->block = curblock;    s->level = curblock->level + 1;    i = getint();    if (i == 0) {	panic("bad input on type \"%s\" at \"%s\"", symname(s), curchar);    } else if (i >= NTYPES) {	panic("too many types in file \"%s\"", curfilename());    }    /*     * A hack for C typedefs that don't create new types,     * e.g. typedef unsigned int Hashvalue;     *  or  typedef struct blah BLAH;     */    if (*curchar != '=') {	s->type = typetable[i];	if (s->type == nil) {	    s->type = symbol_alloc();	    typetable[i] = s->type;	}    } else {	if (typetable[i] != nil) {	    typetable[i]->language = curlang;	    typetable[i]->class = TYPE;	    typetable[i]->type = s;	} else {	    typetable[i] = s;	}	skipchar(curchar, '=');	getType(s);    }}/* * Enter a tag name. */private tagName (s)Symbol s;{    register integer i;    s->class = TAG;    i = getint();    if (i == 0) {	panic("bad input on tag \"%s\" at \"%s\"", symname(s), curchar);    } else if (i >= NTYPES) {	panic("too many types in file \"%s\"", curfilename());    }    if (typetable[i] != nil) {	typetable[i]->language = curlang;	typetable[i]->class = TYPE;	typetable[i]->type = s;    } else {	typetable[i] = s;    }    skipchar(curchar, '=');    getType(s);}/* * Setup a symbol entry for a public procedure or function. */private publicRoutine (s, class, addr)Symbol s;Symclass class;Address addr;{    enterRoutine(s, class);    s->level = program->level;}/* * Setup a symbol entry for a private procedure or function. */private privateRoutine (s, n, class, addr)Symbol *s;Name n;Symclass class;Address addr;{    Symbol t;    boolean isnew;    find(t, n) where	t->level == curmodule->level and t->class == class    endfind(t);    if (t == nil) {	isnew = true;	t = insert(n);    } else {	isnew = false;    }    t->language = curlang;    enterRoutine(t, class);    if (isnew) {	t->symvalue.funcv.src = false;	t->symvalue.funcv.inline = false;	t->symvalue.funcv.beginaddr = addr;	newfunc(t, codeloc(t));	findbeginning(t);    }    *s = t;}/* * Set up for beginning a new procedure, function, or module. * If it's a function, then read the type. * * If the next character is a ",", then read the name of the enclosing block. * Otherwise assume the previous function, if any, is over, and the current * routine is at the same level. */private enterRoutine (s, class)Symbol s;Symclass class;{    s->class = class;    if (class == FUNC) {	getType(s);    }    if (s->class != MODULE) {	getExtRef(s);    } else if (*curchar == ',') {	++curchar;    }    if (*curchar != '\0') {	exitblock();	enterNestedBlock(s);    } else {	if (curblock->class == FUNC or curblock->class == PROC) {	    exitblock();	}	if (class == MODULE) {	    exitblock();	}	enterblock(s);    }    curparam = s;}/* * Check to see if the stab string contains the name of the external * reference.  If so, we create a symbol with that name and class EXTREF, and * connect it to the given symbol.  This link is created so that when * we see the linker symbol we can resolve it to the given symbol. */private getExtRef (s)Symbol s;{    char *p;    Name n;    Symbol t;    if (*curchar == ',' and *(curchar + 1) != '\0') {	p = index(curchar + 1, ',');	*curchar = '\0';	if (p != nil) {	    *p = '\0';	    n = identname(curchar + 1, false);	    curchar = p + 1;	} else {	    n = identname(curchar + 1, true);	}	t = insert(n);	t->language = s->language;	t->class = EXTREF;	t->block = program;	t->level = program->level;	t->symvalue.extref = s;    }}/* * Find a block with the given identifier in the given outer block. * If not there, then create it. */private Symbol findBlock (id, m)String id;Symbol m;{    Name n;    Symbol s;    n = identname(id, true);    find(s, n) where s->block == m and isblock(s) endfind(s);    if (s == nil) {	s = insert(n);	s->block = m;	s->language = curlang;	s->class = MODULE;	s->level = m->level + 1;    }    return s;}/* * Enter a nested block. * The block within which it is nested is described * by "module{:module}[:proc]". */private enterNestedBlock (b)Symbol b;{    register char *p, *q;    Symbol m, s;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -