/* TODO: obey static to declare a function to the file level */ symbol *define_function(char *name, YYLTYPE loc, data_type_t return_type, symbol* param_list) { symbol *s; MALLOC(s, symbol, 1); s->type = FUNCTION; s->loc = loc; strcpy(s->name, name); //s->u.func.arity = size; s->u.func.return_type = return_type; s->u.func.defined = TRUE; s->u.func.plist = param_list; print_fn_signature(s); if ( check_duplicate(GLOBAL_LEVEL, s) ) { /* if a prototype exists, replace it by the definition */ symbol *sym; if ( (sym = find_symbol(GLOBAL_LEVEL, s->name)) ) { delete_symbol(GLOBAL_LEVEL, sym); } add_symbol(GLOBAL_LEVEL, s); // add all params as vars to the current function symtable for ( sym = param_list; sym; sym = sym->u.param.next ) if ( !declare_symbol(VARIABLE, sym->name, sym->loc, FUNCTION_LEVEL, sym->u.param.data_type, sym->u.param.size) ) return NULL; return s; } else { nberrs++; printf("errrrrr\n"); return NULL; } }
user_datum_t *declare_user(void) { char *id = queue_remove(id_queue), *dest_id = NULL; user_datum_t *user = NULL, *dest_user = NULL; int retval; uint32_t value = 0; if (id == NULL) { yyerror("no user name"); return NULL; } if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) { yyerror("Out of memory!"); free(id); return NULL; } user_datum_init(user); retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, &value); if (retval == 0) { user->s.value = value; if ((dest_id = strdup(id)) == NULL) { yyerror("Out of memory!"); return NULL; } } else { /* this user was already declared in this module, or error */ dest_id = id; user_datum_destroy(user); free(user); } if (retval == 0 || retval == 1) { /* create a new user_datum_t for this decl, if necessary */ hashtab_t users_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in parent, so use global symbol table */ users_tab = policydbp->p_users.table; } else { users_tab = stack_top->decl->p_users.table; } dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id); if (dest_user == NULL) { if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) { yyerror("Out of memory!"); free(dest_id); return NULL; } user_datum_init(dest_user); dest_user->s.value = value; if (user_implicit_bounds(users_tab, dest_id, dest_user)) { free(dest_id); user_datum_destroy(dest_user); free(dest_user); return NULL; } if (hashtab_insert(users_tab, dest_id, dest_user)) { yyerror("Out of memory!"); free(dest_id); user_datum_destroy(dest_user); free(dest_user); return NULL; } } else { free(dest_id); } } else { free(dest_id); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror("duplicate declaration of user"); return NULL; } case -1:{ yyerror("could not declare user here"); return NULL; } case 0:{ return dest_user; } case 1:{ return dest_user; /* user already declared for this block */ } default:{ assert(0); /* should never get here */ } } }
type_datum_t *declare_type(unsigned char primary, unsigned char isattr) { char *id; type_datum_t *typdatum; int retval; uint32_t value = 0; id = (char *)queue_remove(id_queue); if (!id) { yyerror("no type/attribute name?"); return NULL; } if (strcmp(id, "self") == 0) { yyerror("'self' is a reserved type name and may not be declared."); free(id); return NULL; } typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); if (!typdatum) { yyerror("Out of memory!"); free(id); return NULL; } type_datum_init(typdatum); typdatum->primary = primary; typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value); if (retval == 0 || retval == 1) { if (typdatum->primary) { typdatum->s.value = value; } } else { /* error occurred (can't have duplicate type declarations) */ free(id); type_datum_destroy(typdatum); free(typdatum); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror2("duplicate declaration of type/attribute"); return NULL; } case -1:{ yyerror("could not declare type/attribute here"); return NULL; } case 0: case 1:{ return typdatum; } default:{ assert(0); /* should never get here */ } } }
role_datum_t *declare_role(void) { char *id = queue_remove(id_queue), *dest_id = NULL; role_datum_t *role = NULL, *dest_role = NULL; int retval; uint32_t value; if (id == NULL) { yyerror("no role name"); return NULL; } if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { yyerror("Out of memory!"); free(id); return NULL; } role_datum_init(role); retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, &value); if (retval == 0) { role->s.value = value; if ((dest_id = strdup(id)) == NULL) { yyerror("Out of memory!"); return NULL; } } else { /* this role was already declared in this module, or error */ dest_id = id; role_datum_destroy(role); free(role); } if (retval == 0 || retval == 1) { /* create a new role_datum_t for this decl, if necessary */ hashtab_t roles_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in parent, so use global symbol table */ roles_tab = policydbp->p_roles.table; } else { roles_tab = stack_top->decl->p_roles.table; } dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); if (dest_role == NULL) { if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) { yyerror("Out of memory!"); free(dest_id); return NULL; } role_datum_init(dest_role); dest_role->s.value = value; if (role_implicit_bounds(roles_tab, dest_id, dest_role)) { free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } if (hashtab_insert(roles_tab, dest_id, dest_role)) { yyerror("Out of memory!"); free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } } else { free(dest_id); } } else { free(dest_id); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror("duplicate declaration of role"); return NULL; } case -1:{ yyerror("could not declare role here"); return NULL; } case 0:{ if (ebitmap_set_bit(&dest_role->dominates, role->s.value - 1, 1)) { yyerror("out of memory"); return NULL; } return dest_role; } case 1:{ return dest_role; /* role already declared for this block */ } default:{ assert(0); /* should never get here */ } } }