Mercurial > hg-old > index.cgi
view lwasm/struct.c @ 269:6cbc409ff09f 2.6
Added asprintf redux
author | lost |
---|---|
date | Tue, 22 Dec 2009 05:53:05 +0000 |
parents | c7a41b4c89b3 |
children |
line wrap: on
line source
/* struct.c Copyright © 2009 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/>. Contains stuff associated with structure definition. Structures have their own name space. Macros will shadow structures so it's a good idea to make sure no structures are name the same as macros. */ #include <config.h> #include <ctype.h> #include <stdlib.h> #include <string.h> #include "lwasm.h" #include "instab.h" #include "util.h" OPFUNC(pseudo_struct) { structtab_t *m; // actually define a structure if (as -> instruct) { register_error(as, l, 1, "Attempt to define a structure inside a structure"); return; } as -> instruct = 1; // don't actually do anything if not pass 1 if (as -> passnum != 1) return; if (!l -> sym) { register_error(as, l, 1, "Structure definition with no effect - no symbol"); return; } // search for macro by same name... for (m = as -> structs; m; m = m -> next) { if (!strcmp(m -> name, l -> sym)) break; } if (m) { register_error(as, l, 1, "Duplicate structure definition"); return; } m = lwasm_alloc(sizeof(structtab_t)); m -> name = lwasm_strdup(l -> sym); m -> next = as -> structs; m -> fields = NULL; m -> size = 0; as -> structs = m; as -> cstruct = m; while (**p && !isspace(**p)) (*p)++; } pseudo_endstruct_aux(asmstate_t *as, lwasm_line_t *l, struct struct_sym_e *e, const char *prefix, int *coff) { char *symname = NULL; while (e) { if (e -> name) 0 == asprintf(&symname, "%s.%s", prefix, e -> name); else 0 == asprintf(&symname, "%s.___%d", prefix, *coff); // register symbol "symname" as global at coff lwasm_register_symbol(as, l, symname, *coff, SYMBOL_NOCHECK); if (e -> substruct) { char * t; 0 == asprintf(&t, "sizeof{%s}", symname); lwasm_register_symbol(as, l, t, e -> substruct -> size, SYMBOL_NOCHECK); lwasm_free(t); pseudo_endstruct_aux(as, l, e -> substruct -> fields, symname, coff); } else { *coff += e -> size; } lwasm_free(symname); e = e -> next; } } OPFUNC(pseudo_endstruct) { int coff = 0; char *t; as -> instruct = 0; if (as -> passnum != 1) return; // now register the global symbols for the structure // this is a recursive process 0 == asprintf(&t, "sizeof{%s}", as -> cstruct -> name); lwasm_register_symbol(as, l, t, as -> cstruct -> size, SYMBOL_NOCHECK); lwasm_free(t); pseudo_endstruct_aux(as, l, as -> cstruct -> fields, as -> cstruct -> name, &coff); } int expand_struct(asmstate_t *as, lwasm_line_t *l, char **p, char *opc) { structtab_t *s; int addr; char *t; if (as -> passnum != 1) return 0; for (s = as -> structs; s; s = s -> next) { if (!strcmp(opc, s -> name)) break; } if (!s) return -1; if (!(l -> sym)) { register_error(as, l, 1, "Cannot declare a structure without a symbol name."); return; } l -> nocodelen = s -> size; addr = as -> addr; as -> addr += s -> size; // now register the global symbols for the structure // this is a recursive process 0 == asprintf(&t, "sizeof{%s}", l -> sym); lwasm_register_symbol(as, l, t, s -> size, SYMBOL_NOCHECK); lwasm_free(t); pseudo_endstruct_aux(as, l, s -> fields, l -> sym, &addr); return 0; }