diff --git a/v2/engine/builtins.c b/v2/engine/builtins.c index 073b0a4ef..67c90077c 100644 --- a/v2/engine/builtins.c +++ b/v2/engine/builtins.c @@ -1070,10 +1070,18 @@ LIST * builtin_delete_module( FRAME * frame, int flags ) } -static void unknown_rule( FRAME * frame, const char * key, OBJECT * module_name, OBJECT * rule_name ) +static void unknown_rule( FRAME * frame, const char * key, module_t * module, OBJECT * rule_name ) { + const char * module_name = module->name ? object_str( module->name ) : ""; backtrace_line( frame->prev ); - printf( "%s error: rule \"%s\" unknown in module \"%s\"\n", key, object_str( rule_name ), object_str( module_name ) ); + if ( module->name ) + { + printf( "%s error: rule \"%s\" unknown in module \"%s.\"\n", key, object_str( rule_name ), object_str( module->name ) ); + } + else + { + printf( "%s error: rule \"%s\" unknown in module \"\"\n", key, object_str( rule_name ) ); + } backtrace( frame->prev ); exit( 1 ); } @@ -1128,7 +1136,7 @@ LIST * builtin_import( FRAME * frame, int flags ) if ( !source_module->rules || !hashcheck( source_module->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "IMPORT", source_module->name, r_.name ); + unknown_rule( frame, "IMPORT", source_module, r_.name ); imported = import_rule( r, target_module, target_name->value ); if ( localize ) @@ -1177,7 +1185,7 @@ LIST * builtin_export( FRAME * frame, int flags ) r_.name = rules->value; if ( !m->rules || !hashcheck( m->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "EXPORT", m->name, r_.name ); + unknown_rule( frame, "EXPORT", m, r_.name ); r->exported = 1; } @@ -1275,12 +1283,20 @@ LIST * builtin_backtrace( FRAME * frame, int flags ) const char * file; int line; char buf[32]; + string module_name[1]; get_source_line( frame, &file, &line ); sprintf( buf, "%d", line ); + string_new( module_name ); + if ( frame->module->name ) + { + string_append( module_name, object_str( frame->module->name ) ); + string_append( module_name, "." ); + } result = list_new( result, object_new( file ) ); result = list_new( result, object_new( buf ) ); - result = list_new( result, object_copy( frame->module->name ) ); + result = list_new( result, object_new( module_name->value ) ); result = list_new( result, object_new( frame->rulename ) ); + string_free( module_name ); } return result; } @@ -1309,16 +1325,8 @@ LIST * builtin_caller_module( FRAME * frame, int flags ) if ( frame->module == root_module() ) return L0; - - { - LIST * result; - string name; - string_copy( &name, object_str( frame->module->name ) ); - string_pop_back( &name ); - result = list_new( L0, object_new(name.value) ); - string_free( &name ); - return result; - } + else + return list_new( L0, object_copy( frame->module->name ) ); } @@ -1621,7 +1629,7 @@ LIST * builtin_native_rule( FRAME * frame, int flags ) else { backtrace_line( frame->prev ); - printf( "error: no native rule \"%s\" defined in module \"%s\"\n", + printf( "error: no native rule \"%s\" defined in module \"%s.\"\n", object_str( n.name ), object_str( module->name ) ); backtrace( frame->prev ); exit( 1 ); @@ -2162,16 +2170,25 @@ PyObject * bjam_backtrace( PyObject * self, PyObject * args ) const char * file; int line; char buf[ 32 ]; + string module_name[1]; get_source_line( f, &file, &line ); sprintf( buf, "%d", line ); + string_new( module_name ); + if ( f->module->name ) + { + string_append( module_name, object_str( f->module->name ) ); + string_append( module_name, "." ); + } /* PyTuple_SetItem steals reference. */ PyTuple_SetItem( tuple, 0, PyString_FromString( file ) ); PyTuple_SetItem( tuple, 1, PyString_FromString( buf ) ); - PyTuple_SetItem( tuple, 2, PyString_FromString( object_str( f->module->name ) ) ); + PyTuple_SetItem( tuple, 2, PyString_FromString( module_name->value ) ); PyTuple_SetItem( tuple, 3, PyString_FromString( f->rulename ) ); + string_free( module_name ); + PyList_Append( result, tuple ); Py_DECREF( tuple ); } @@ -2180,11 +2197,10 @@ PyObject * bjam_backtrace( PyObject * self, PyObject * args ) PyObject * bjam_caller( PyObject * self, PyObject * args ) { - /* Module names in Jam end in dot. The CALLER builtin in jam - language strips the dot, and we do the same here to make it - easier to port Jam code to Python. */ - const char *s = object_str( frame_before_python_call->prev->module->name ); - return PyString_FromStringAndSize(s, strlen(s)-1); + const char * s = frame_before_python_call->prev->module->name ? + object_str( frame_before_python_call->prev->module->name ) : + ""; + return PyString_FromString( s ); } #endif /* #ifdef HAVE_PYTHON */ diff --git a/v2/engine/compile.c b/v2/engine/compile.c index 20eeedb83..c0fc5b0a0 100644 --- a/v2/engine/compile.c +++ b/v2/engine/compile.c @@ -554,7 +554,11 @@ evaluate_rule( && rule->procedure != 0 && !object_equal( rulename, function_rulename( rule->procedure ) ) ) { char buf[256] = ""; - strncat( buf, object_str( rule->module->name ), sizeof( buf ) - 1 ); + if ( rule->module->name ) + { + strncat( buf, object_str( rule->module->name ), sizeof( buf ) - 1 ); + strncat( buf, ".", sizeof( buf ) - 1 ); + } strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 ); debug_compile( 1, buf, frame ); } @@ -590,7 +594,14 @@ evaluate_rule( if ( !rule->actions && !rule->procedure ) { backtrace_line( frame->prev ); - printf( "rule %s unknown in module %s\n", object_str( rule->name ), object_str( frame->module->name ) ); + if ( frame->module->name ) + { + printf( "rule %s unknown in module %s\n", object_str( rule->name ), object_str( frame->module->name ) ); + } + else + { + printf( "rule %s unknown in module \n", object_str( rule->name ) ); + } backtrace( frame->prev ); exit( 1 ); } diff --git a/v2/engine/modules.c b/v2/engine/modules.c index 044e9a111..f11a50aec 100644 --- a/v2/engine/modules.c +++ b/v2/engine/modules.c @@ -18,47 +18,42 @@ #include static struct hash * module_hash = 0; - +static module_t root; module_t * bindmodule( OBJECT * 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 ) + if ( !name ) { - string_append( &s, object_str( name ) ); - string_push_back( &s, '.' ); - } - - m->name = name = object_new( s.value ); - - if ( hashenter( module_hash, (HASHDATA * *)&m ) ) - { - m->name = m->name; - m->variables = 0; - m->rules = 0; - m->imported_modules = 0; - m->class_module = 0; - m->native_rules = 0; - m->user_module = 0; + return &root; } else { - object_free( name ); + PROFILE_ENTER( BINDMODULE ); + + module_t m_; + module_t * m = &m_; + + if ( !module_hash ) + module_hash = hashinit( sizeof( module_t ), "modules" ); + + m->name = name; + + if ( hashenter( module_hash, (HASHDATA * *)&m ) ) + { + m->name = object_copy( name ); + m->variables = 0; + m->rules = 0; + m->imported_modules = 0; + m->class_module = 0; + m->native_rules = 0; + m->user_module = 0; + } + + PROFILE_EXIT( BINDMODULE ); + + return m; } - string_free( &s ); - - PROFILE_EXIT( BINDMODULE ); - - return m; } /* @@ -138,11 +133,7 @@ static void delete_module_( void * xmodule, void * data ) module_t *m = (module_t *)xmodule; delete_module( m ); - - if ( m->name ) - { - object_free( m->name ); - } + object_free( m->name ); } void modules_done() @@ -150,14 +141,12 @@ void modules_done() hashenumerate( module_hash, delete_module_, (void *)0 ); hashdone( module_hash ); module_hash = 0; + delete_module( &root ); } module_t * root_module() { - static module_t * root = 0; - if ( !root ) - root = bindmodule( 0 ); - return root; + return &root; } void enter_module( module_t * m ) diff --git a/v2/engine/rules.c b/v2/engine/rules.c index c28169453..32f819970 100644 --- a/v2/engine/rules.c +++ b/v2/engine/rules.c @@ -687,7 +687,11 @@ static OBJECT * global_rule_name( RULE * r ) { char name[4096] = ""; - strncat( name, object_str( r->module->name ), sizeof( name ) - 1 ); + if ( r->module->name ) + { + strncat( name, object_str( r->module->name ), sizeof( name ) - 1 ); + strncat( name, ".", sizeof( name ) - 1 ); + } strncat( name, object_str( r->name ), sizeof( name ) - 1 ); return object_new( name ); }