/* * 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 "debug.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_, *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; }