/* * Copyright (c) 1999 The University of Utah and * the Computer Systems Laboratory at the University of Utah (CSL). * * This file is part of Flick, the Flexible IDL Compiler Kit. * * Flick 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 2 of the License, or * (at your option) any later version. * * Flick 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 Flick; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA. */ #include #include #include #include #include #include #include #include presentation_impl::presentation_impl() { this->idl_type = 0; this->pres_type = 0; this->scope_impl = 0; this->misc_impl = 0; this->pc = 0; } presentation_impl::~presentation_impl() { } void presentation_impl::set_idl_type(const char *type) { this->idl_type = type; } const char *presentation_impl::get_idl_type() { return( this->idl_type ); } void presentation_impl::set_pres_type(const char *type) { this->pres_type = type; } const char *presentation_impl::get_pres_type() { return( this->pres_type ); } void presentation_impl::set_scope_impl(void (*impl)(cast_scope *scope, tag_list *tl)) { this->scope_impl = impl; } void (*presentation_impl::get_scope_impl())(cast_scope *scope, tag_list *tl) { return( this->scope_impl ); } void presentation_impl::set_misc_impl(void (*impl)(pres_c_1 *pres, tag_list *)) { this->misc_impl = impl; } void (*presentation_impl::get_misc_impl())(pres_c_1 *pres, tag_list *) { return( this->misc_impl ); } void presentation_impl::set_collection(struct presentation_collection *the_pc) { this->pc = the_pc; } struct presentation_collection *presentation_impl::get_collection() { return( this->pc ); } void presentation_impl::write_pres_funcs(pres_c_1 *pres, struct scml_scope *pres_scope, tag_list *tl) { struct scml_cmd_definition *cmd_def; struct scml_scope *cmd_scope; struct scml_context *sc; tag_list *func_tl; cast_def *cfunc; tag_item *ti; int lpc, len; ti = find_tag(tl, "pres_func"); if( !ti ) return; len = tag_data_length(&ti->data); /* Create an execution context */ sc = new scml_context; sc->set_scope(pres_scope); sc->set_stream_pos(this->pc->get_scml_stream_pos()); /* Walk through the array of pres_funcs */ for( lpc = 0; lpc < len; lpc++ ) { func_tl = find_tag(tl, get_tag_data(&ti->data, lpc).str)-> data.tag_data_u.tl; cfunc = &pres->stubs_cast.cast_scope_val[find_tag(func_tl, "c_func")-> data.tag_data_u.i]; /* output only if they have a C decl and a definition */ cmd_def = pres_scope->find_cmd_definition( &cmd_scope, get_tag_data(&ti->data, lpc).str); if( !(pres->meta_data.channels.channels_val[cfunc->channel]. flags & DATA_CHANNEL_SQUELCHED) && cmd_def ) { /* Execute the definition */ sc->exec_cmd(get_tag_data(&ti->data, lpc).str, func_tl, NULL); } else if( !(pres->meta_data.channels. channels_val[cfunc->channel].flags & DATA_CHANNEL_SQUELCHED) && (cfunc->protection != CAST_PROT_PRIVATE) ) { fprintf(stderr, "Warning '%s' function in %s::%s " "not handled\n", get_tag_data(&ti->data, lpc).str, pres_scope->get_parent()->get_name(), pres_scope->get_name()); } } delete sc; } void presentation_impl::write_model_funcs(pres_c_1 *pres, struct scml_scope *pres_scope, tag_list *tl) { struct scml_scope *cmd_scope; struct scml_context *sc; tag_list *func_tl; cast_def *cfunc; char *kind_str; tag_item *ti; int lpc, len; ti = find_tag(tl, "model_func"); if( !ti ) return; len = tag_data_length(&ti->data); sc = new scml_context; sc->set_scope(pres_scope); sc->set_stream_pos(this->pc->get_scml_stream_pos()); for( lpc = 0; lpc < len; lpc++ ) { func_tl = get_tag_data(&ti->data, lpc).tl; cfunc = &pres->stubs_cast.cast_scope_val[find_tag(func_tl, "c_func")-> data.tag_data_u.i]; kind_str = find_tag(func_tl, "kind")->data.tag_data_u.str; if( !(pres->meta_data.channels.channels_val[cfunc->channel]. flags & DATA_CHANNEL_SQUELCHED) && pres_scope->find_cmd_definition(&cmd_scope, kind_str) ) { sc->exec_cmd(kind_str, func_tl, NULL); } else if( !(pres->meta_data.channels. channels_val[cfunc->channel].flags & DATA_CHANNEL_SQUELCHED) ) { fprintf(stderr, "Warning '%s' function model in %s::%s " "not handled\n", get_tag_data(&ti->data, lpc).str, pres_scope->get_parent()->get_name(), pres_scope->get_name()); } } } void presentation_impl::implement(pres_c_1 *pres, tag_list *tl) { if( this->scope_impl ) { cast_scoped_name scname; cast_scope *scope; cast_type ctype; tag_item *ti; int cdef; /* This is an operation on a type's scope */ if( (ti = find_tag(tl, "name")) && (ti->data.kind == TAG_CAST_SCOPED_NAME) ) { /* Find the scope */ scname = ti->data.tag_data_u.scname; scope = &pres->cast; cdef = cast_find_def(&scope, scname, CAST_TYPEDEF|CAST_TYPE); while( cdef != -1 ) { ctype = scope->cast_scope_val[cdef].u. cast_def_u_u.type; switch( ctype->kind ) { case CAST_TYPE_TEMPLATE: ctype = ctype->cast_type_u_u. template_type.def; break; default: break; } if( ctype->kind == CAST_TYPE_AGGREGATE ) { scope = &ctype->cast_type_u_u. agg_type.scope; /* Let the function add to it */ this->scope_impl(scope, tl); cdef = -1; } else { cdef = cast_find_def_pos(&scope, cdef + 1, scname, CAST_TYPEDEF| CAST_TYPE); } } } } if( this->misc_impl ) this->misc_impl(pres, tl); if( this->pc->get_scml_scope() && this->pres_type ) { struct scml_scope *idl_scope, *pres_scope; /* Find the matching IDL scope in the SCML */ if( (idl_scope = this->pc->get_scml_scope()-> find_child(find_tag(tl, "idl_type")-> data.tag_data_u.str)) ) { /* Find the matching pres scope in the SCML */ if( (pres_scope = idl_scope-> find_child(this->pres_type)) ) { this->write_pres_funcs(pres, pres_scope, tl); this->write_model_funcs(pres, pres_scope, tl); } else { fprintf(stderr, "Couldn't find pres_type '%s' in" " scope '%s'\n", this->pres_type, idl_scope->get_name()); } } else { fprintf(stderr, "Couldn't find idl_type '%s' in" " scope\n", find_tag(tl, "idl_type")-> data.tag_data_u.str); } } } presentation_collection::presentation_collection() { new_list(&this->impls); } presentation_collection::~presentation_collection() { } void presentation_collection::set_scml_scope(struct scml_scope *the_scope) { this->scope = the_scope; } struct scml_scope *presentation_collection::get_scml_scope() { return( this->scope ); } void presentation_collection::set_scml_stream_pos(struct scml_stream_pos *ssp) { this->stream_pos = ssp; } struct scml_stream_pos *presentation_collection::get_scml_stream_pos() { return( this->stream_pos ); } void presentation_collection::add_impl(struct presentation_impl *pi) { add_tail(&this->impls, &pi->link); pi->set_collection(this); } struct presentation_impl *presentation_collection::find_impl(char *idl_type, char *pres_type) { struct presentation_impl *retval = 0, *curr; curr = (struct presentation_impl *)this->impls.head; while( curr->link.succ ) { if( (!idl_type || !curr->get_idl_type() || !strcmp(idl_type, curr->get_idl_type())) && (!pres_type || !curr->get_pres_type() || !strcmp(pres_type, curr->get_pres_type())) ) { retval = curr; } curr = (struct presentation_impl *)curr->link.succ; } return( retval ); } void presentation_collection::implement(pres_c_1 *pres) { struct presentation_impl *pi; tag_list *tl, *sub_tl; int lpc, len; char *idl_type; tag_item *pres_ti, *ti; tl = pres->pres_attrs; if( !(pres_ti = find_tag(tl, "pres_type")) ) return; /* Fix the parent links of the tag_list's in tl */ relink_tag_list(tl); /* Typedefs, detected by the typedef_ref tag, need to have their parent links redirected to the pres_type tag_list specified by the numbe in the typedef_ref */ len = tag_data_length(&pres_ti->data); for( lpc = 0; lpc < len; lpc++ ) { sub_tl = get_tag_data(&pres_ti->data, lpc).tl; if( (ti = find_tag(sub_tl, "typedef_ref")) ) { sub_tl->parent = get_tag_data(&pres_ti->data, ti->data.tag_data_u.i).tl; } } /* Walk through the array of pres_types and process them through the list of pres_impls */ for( lpc = 0; lpc < len; lpc++ ) { sub_tl = get_tag_data(&pres_ti->data, lpc).tl; ti = find_tag(sub_tl, "idl_type"); if( find_tag(sub_tl, "main") && ti && !find_tag(sub_tl, "_pc_implemented") && (ti->data.kind == TAG_STRING) ) { idl_type = ti->data.tag_data_u.str; pi = (struct presentation_impl *)this->impls.head; while( pi->link.succ ) { if( (!pi->get_idl_type() || !strcmp(idl_type, pi->get_idl_type())) && (!pi->get_pres_type() || (ti = find_tag(sub_tl, pi->get_pres_type()))) ) { /* If we have a pres type than pass its tag_list down, otherwise use the type's root tag_list */ if( pi->get_pres_type() ) pi->implement(pres, ti->data. tag_data_u.tl); else pi->implement(pres, sub_tl); } pi = (struct presentation_impl *)pi->link.succ; } add_tag(sub_tl, "_pc_implemented", TAG_NONE); } } }