/* * Copyright 2001-2004 David Abrahams. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) */ #include "jam.h" #include "modules.h" #include "string.h" #include "hash.h" #include "newstr.h" #include "lists.h" #include "parse.h" #include "rules.h" #include "variable.h" #include "strings.h" #include static struct hash * module_hash = 0; static char * new_module_str( module_t * m, char * suffix ) { char * result; string s; string_copy( &s, m->name ); string_append( &s, suffix ); result = newstr( s.value ); string_free( &s ); return result; } module_t * bindmodule( char * name ) { PROFILE_ENTER( BINDMODULE ); string s; module_t m_; module_t * m = &m_; if ( !module_hash ) module_hash = hashinit( sizeof( module_t ), "modules" ); string_new( &s ); if ( name ) { string_append( &s, name ); string_push_back( &s, '.' ); } m->name = s.value; if ( hashenter( module_hash, (HASHDATA * *)&m ) ) { m->name = newstr( m->name ); m->variables = 0; m->rules = 0; m->imported_modules = 0; m->class_module = 0; m->native_rules = 0; m->user_module = 0; } string_free( &s ); PROFILE_EXIT( BINDMODULE ); return m; } /* * demand_rules() - Get the module's "rules" hash on demand. */ struct hash * demand_rules( module_t * m ) { if ( !m->rules ) m->rules = hashinit( sizeof( RULE ), new_module_str( m, "rules" ) ); return m->rules; } /* * delete_module() - wipe out the module's rules and variables. */ static void delete_rule_( void * xrule, void * data ) { rule_free( (RULE *)xrule ); } void delete_module( module_t * m ) { /* Clear out all the rules. */ if ( m->rules ) { hashenumerate( m->rules, delete_rule_, (void *)0 ); hashdone( m->rules ); m->rules = 0; } if ( m->variables ) { var_hash_swap( &m->variables ); var_done(); var_hash_swap( &m->variables ); m->variables = 0; } } module_t * root_module() { static module_t * root = 0; if ( !root ) root = bindmodule( 0 ); return root; } void enter_module( module_t * m ) { var_hash_swap( &m->variables ); } void exit_module( module_t * m ) { var_hash_swap( &m->variables ); } void import_module( LIST * module_names, module_t * target_module ) { PROFILE_ENTER( IMPORT_MODULE ); struct hash * h; if ( !target_module->imported_modules ) target_module->imported_modules = hashinit( sizeof( char * ), "imported" ); h = target_module->imported_modules; for ( ; module_names; module_names = module_names->next ) { char * s = module_names->string; char * * ss = &s; hashenter( h, (HASHDATA * *)&ss ); } PROFILE_EXIT( IMPORT_MODULE ); } static void add_module_name( void * r_, void * result_ ) { char * * r = (char * *)r_; LIST * * result = (LIST * *)result_; *result = list_new( *result, copystr( *r ) ); } LIST * imported_modules( module_t * module ) { LIST * result = L0; if ( module->imported_modules ) hashenumerate( module->imported_modules, add_module_name, &result ); return result; }