Mercurial > hg-old > index.cgi
view src/symtab.c @ 8:f1df096aa76f 1.1
Tagged 1.1 bugfix release
author | lost |
---|---|
date | Sun, 04 Jan 2009 05:46:07 +0000 |
parents | 34568fab6058 |
children |
line wrap: on
line source
/* symtab.c Copyright © 2008 William Astle This file is part of LWASM. LWASM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Implements code for handling the symbol table. */ #include <ctype.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define __symtab_c_seen__ #include "lwasm.h" void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags) { symtab_t *st; symtab_t *prev; int cv = -2; for (prev = NULL, st = as -> symbol_table; st; st = st -> next) { cv = strcasecmp(st -> symbol, symstr); if (cv == 0) { cv = strcmp(st -> symbol, symstr); } if (cv >= 0) break; prev = st; } // cv is 0 if we found the symbol, > 0 if we didn't and found one // later in order, or -2 if we never did a comparison // if st is NULL, the value of cv is irrelevant as it means // we fell off the end of the list // if st is NULL and prev is not, then prev is the tail of the list // if both are NULL, the list is empty // handle adding the symbol if needed if (!st || cv != 0) { symtab_t *st2; // register the symbol st2 = malloc(sizeof(symtab_t)); st2 -> symbol = strdup(symstr); st2 -> addr = val; st2 -> flags = 0; if (flags & SYMFLAG_SET) st2 -> flags |= SYMFLAG_SET; if (prev) prev -> next = st2; else as -> symbol_table = st2; st2 -> next = st; return; } // st is NOT NULL here and cv IS 0 if ((flags & SYMFLAG_SET) && ((st -> flags) & SYMFLAG_SET)) { // symbol already exists but it is a "SET" symbol so reset the value st -> addr = val; return; } if (st && as -> passnum == 1) { // duplicate symbol, flag error errorp1(ERR_DUPSYM); } if (st -> addr != val) errorp2(ERR_PHASE); } int lookup_symbol(asmstate_t *as, char *symstr) { symtab_t *st; for (st = as -> symbol_table; st; st = st -> next) { if (!strcmp(symstr, st -> symbol)) break; } if (st) return st -> addr; return -1; } void list_symbols(asmstate_t *as, FILE *f) { symtab_t *st; for (st = as -> symbol_table; st; st = st -> next) { fprintf(f, "%04X %s%s\n", st -> addr, st -> symbol, (st -> flags & SYMFLAG_SET) ? "(S)" : ""); } }