?? symbol.c
字號:
} } } /* run the loop manually one last time */ for (sp = *hp; sp; sp = sp->g_next) { if (sp->g_value.v_type != V_NULL) { freevalue(&sp->g_value); count++; } }}/* * Free all invisible static variables */voidfreestatics(void){ GLOBAL **stp; GLOBAL *sp; long count; stp = statictable; count = staticcount; while (count-- > 0) { sp = *stp++; freevalue(&sp->g_value); }}/* * Reset the file and function scope levels back to the original values. * This is called on errors to forget any static variables which were being * defined. */voidresetscopes(void){ filescope = SCOPE_STATIC; funcscope = 0; unscope();}/* * Enter a new file scope level so that newly defined static variables * will have the appropriate scope, and so that previously defined static * variables will temporarily be unaccessible. This should only be called * when the function scope level is zero. */voidenterfilescope(void){ filescope++; funcscope = 0;}/* * Exit from a file scope level. This deletes from the global symbol table * all of the static variables that were defined within this file scope level. * The function scope level is also reset to zero. */voidexitfilescope(void){ if (filescope > SCOPE_STATIC) filescope--; funcscope = 0; unscope();}/* * Enter a new function scope level within the current file scope level. * This allows newly defined static variables to override previously defined * static variables in the same file scope level. */voidenterfuncscope(void){ funcscope++;}/* * Exit from a function scope level. This deletes static symbols which were * defined within the current function scope level, and makes previously * defined symbols with the same name within the same file scope level * accessible again. */voidexitfuncscope(void){ if (funcscope > 0) funcscope--; unscope();}/* * To end the scope of any static variable with identifier id when * id is being declared as global, or when id is declared as static and the * variable is at the same file and function level. */voidendscope(char *name, BOOL isglobal){ GLOBAL *sp; GLOBAL *prevsp; GLOBAL **hp; size_t len; len = strlen(name); prevsp = NULL; hp = &globalhash[HASHSYM(name, len)]; for (sp = *hp; sp; sp = sp->g_next) { if (sp->g_len == len && !strcmp(sp->g_name, name) && sp->g_filescope > SCOPE_GLOBAL) { if (isglobal || (sp->g_filescope == filescope && sp->g_funcscope == funcscope)) { addstatic(sp); if (prevsp) prevsp->g_next = sp->g_next; else *hp = sp->g_next; continue; } } prevsp = sp; }}/* * To store in a table a static variable whose scope is being ended */voidaddstatic(GLOBAL *sp){ GLOBAL **stp; if (staticavail <= 0) { if (staticcount <= 0) stp = (GLOBAL **) malloc(20 * sizeof(GLOBAL *)); else stp = (GLOBAL **) realloc(statictable, (20 + staticcount) * sizeof(GLOBAL *)); if (stp == NULL) { math_error("Cannot allocate static-variable table"); /*NOTREACHED*/ } statictable = stp; staticavail = 20; } statictable[staticcount++] = sp; staticavail--;}/* * To display all static variables whose scope has been ended */voidshowstatics(void){ long count; GLOBAL **stp; GLOBAL *sp; for (count = 0, stp = statictable; count < staticcount; count++) { sp = *stp++; if (count == 0) { printf("\nName Scopes Type\n"); printf( "---- ------ -----\n"); } printf("%-8s", sp->g_name); printf("%3d", sp->g_filescope); printf("%3d ", sp->g_funcscope); printtype(&sp->g_value); printf("\n"); } if (count > 0) printf("\nNumber: %ld\n", count); else printf("No unscoped static variables\n");}/* * Remove all the symbols from the global symbol table which have file or * function scopes larger than the current scope levels. Their memory * remains allocated since their values still actually exist. */static voidunscope(void){ GLOBAL **hp; /* hash table head address */ register GLOBAL *sp; /* current global symbol pointer */ GLOBAL *prevsp; /* previous kept symbol pointer */ /* * We prevent the hp pointer from walking behind globalhash * by stopping one short of the end and running the loop one * more time. * * We could stop the loop with just hp >= globalhash, but stopping * short and running the loop one last time manually helps make * code checkers such as insure happy. */ for (hp = &globalhash[HASHSIZE-1]; hp > globalhash; hp--) { prevsp = NULL; for (sp = *hp; sp; sp = sp->g_next) { if ((sp->g_filescope == SCOPE_GLOBAL) || (sp->g_filescope < filescope) || ((sp->g_filescope == filescope) && (sp->g_funcscope <= funcscope))) { prevsp = sp; continue; } /* * This symbol needs removing. */ addstatic(sp); if (prevsp) prevsp->g_next = sp->g_next; else *hp = sp->g_next; } } /* run the loop manually one last time */ prevsp = NULL; for (sp = *hp; sp; sp = sp->g_next) { if ((sp->g_filescope == SCOPE_GLOBAL) || (sp->g_filescope < filescope) || ((sp->g_filescope == filescope) && (sp->g_funcscope <= funcscope))) { prevsp = sp; continue; } /* * This symbol needs removing. */ addstatic(sp); if (prevsp) prevsp->g_next = sp->g_next; else *hp = sp->g_next; }}/* * Initialize the local and parameter symbol table information. */voidinitlocals(void){ initstr(&localnames); initstr(¶mnames); curfunc->f_localcount = 0; curfunc->f_paramcount = 0;}/* * Add a possibly new local variable definition. * Returns the index of the variable into the local symbol table. * Minus one indicates the symbol could not be added. * * given: * name name of local variable */longaddlocal(char *name){ long index; /* current symbol index */ index = findstr(&localnames, name); if (index >= 0) return index; index = localnames.h_count; (void) addstr(&localnames, name); curfunc->f_localcount++; return index;}/* * Find a local variable name and return its index. * Returns minus one if the variable name is not defined. * * given: * name name of local variable */longfindlocal(char *name){ return findstr(&localnames, name);}/* * Return the name of a local variable. */char *localname(long n){ return namestr(&localnames, n);}/* * Add a possibly new parameter variable definition. * Returns the index of the variable into the parameter symbol table. * Minus one indicates the symbol could not be added. * * given: * name name of parameter variable */longaddparam(char *name){ long index; /* current symbol index */ index = findstr(¶mnames, name); if (index >= 0) return index; index = paramnames.h_count; (void) addstr(¶mnames, name); curfunc->f_paramcount++; return index;}/* * Find a parameter variable name and return its index. * Returns minus one if the variable name is not defined. * * given: * name name of parameter variable */longfindparam(char *name){ return findstr(¶mnames, name);}/* * Return the name of a parameter variable. */char *paramname(long n){ return namestr(¶mnames, n);}/* * Return the type of a variable name. * This is either local, parameter, global, static, or undefined. * * given: * name variable name to find */intsymboltype(char *name){ GLOBAL *sp; if (findparam(name) >= 0) return SYM_PARAM; if (findlocal(name) >= 0) return SYM_LOCAL; sp = findglobal(name); if (sp) { if (sp->g_filescope == SCOPE_GLOBAL) return SYM_GLOBAL; return SYM_STATIC; } return SYM_UNDEFINED;}/* END CODE */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -