]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/class.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / engine / class.cpp
1 /*
2 * Copyright Vladimir Prus 2003.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7
8 #include "class.h"
9
10 #include "constants.h"
11 #include "frames.h"
12 #include "hash.h"
13 #include "lists.h"
14 #include "object.h"
15 #include "rules.h"
16 #include "strings.h"
17 #include "variable.h"
18 #include "output.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23
24 static struct hash * classes = 0;
25
26
27 static void check_defined( LIST * class_names )
28 {
29 LISTITER iter = list_begin( class_names );
30 LISTITER const end = list_end( class_names );
31 for ( ; iter != end; iter = list_next( iter ) )
32 {
33 if ( !hash_find( classes, list_item( iter ) ) )
34 {
35 out_printf( "Class %s is not defined\n", object_str( list_item( iter ) )
36 );
37 abort();
38 }
39 }
40 }
41
42
43 static OBJECT * class_module_name( OBJECT * declared_name )
44 {
45 string name[ 1 ];
46 OBJECT * result;
47
48 string_new( name );
49 string_append( name, "class@" );
50 string_append( name, object_str( declared_name ) );
51
52 result = object_new( name->value );
53 string_free( name );
54
55 return result;
56 }
57
58
59 struct import_base_data
60 {
61 OBJECT * base_name;
62 module_t * base_module;
63 module_t * class_module;
64 };
65
66
67 static void import_base_rule( void * r_, void * d_ )
68 {
69 RULE * r = (RULE *)r_;
70 RULE * ir1;
71 RULE * ir2;
72 struct import_base_data * d = (struct import_base_data *)d_;
73 OBJECT * qname;
74
75 string qualified_name[ 1 ];
76 string_new ( qualified_name );
77 string_append ( qualified_name, object_str( d->base_name ) );
78 string_push_back( qualified_name, '.' );
79 string_append ( qualified_name, object_str( r->name ) );
80 qname = object_new( qualified_name->value );
81 string_free( qualified_name );
82
83 ir1 = import_rule( r, d->class_module, r->name );
84 ir2 = import_rule( r, d->class_module, qname );
85
86 object_free( qname );
87
88 /* Copy 'exported' flag. */
89 ir1->exported = ir2->exported = r->exported;
90
91 /* If we are importing a class method, localize it. */
92 if ( ( r->module == d->base_module ) || ( r->module->class_module &&
93 ( r->module->class_module == d->base_module ) ) )
94 {
95 rule_localize( ir1, d->class_module );
96 rule_localize( ir2, d->class_module );
97 }
98 }
99
100
101 /*
102 * For each exported rule 'n', declared in class module for base, imports that
103 * rule in 'class' as 'n' and as 'base.n'. Imported rules are localized and
104 * marked as exported.
105 */
106
107 static void import_base_rules( module_t * class_, OBJECT * base )
108 {
109 OBJECT * module_name = class_module_name( base );
110 module_t * base_module = bindmodule( module_name );
111 LIST * imported;
112 struct import_base_data d;
113 d.base_name = base;
114 d.base_module = base_module;
115 d.class_module = class_;
116 object_free( module_name );
117
118 if ( base_module->rules )
119 hashenumerate( base_module->rules, import_base_rule, &d );
120
121 imported = imported_modules( base_module );
122 import_module( imported, class_ );
123 list_free( imported );
124 }
125
126
127 OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
128 {
129 OBJECT * name = class_module_name( list_front( xname ) );
130 OBJECT * * pp;
131 module_t * class_module = 0;
132 module_t * outer_module = frame->module;
133 int found;
134
135 if ( !classes )
136 classes = hashinit( sizeof( OBJECT * ), "classes" );
137
138 pp = (OBJECT * *)hash_insert( classes, list_front( xname ), &found );
139 if ( !found )
140 {
141 *pp = object_copy( list_front( xname ) );
142 }
143 else
144 {
145 out_printf( "Class %s already defined\n", object_str( list_front( xname ) )
146 );
147 abort();
148 }
149 check_defined( bases );
150
151 class_module = bindmodule( name );
152
153 {
154 /*
155 Initialize variables that Boost.Build inserts in every object.
156 We want to avoid creating the object's hash if it isn't needed.
157 */
158 int num = class_module->num_fixed_variables;
159 module_add_fixed_var( class_module, constant_name, &num );
160 module_add_fixed_var( class_module, constant_class, &num );
161 module_set_fixed_variables( class_module, num );
162 }
163
164 var_set( class_module, constant_name, xname, VAR_SET );
165 var_set( class_module, constant_bases, bases, VAR_SET );
166
167 {
168 LISTITER iter = list_begin( bases );
169 LISTITER const end = list_end( bases );
170 for ( ; iter != end; iter = list_next( iter ) )
171 import_base_rules( class_module, list_item( iter ) );
172 }
173
174 return name;
175 }
176
177
178 static void free_class( void * xclass, void * data )
179 {
180 object_free( *(OBJECT * *)xclass );
181 }
182
183
184 void class_done( void )
185 {
186 if ( classes )
187 {
188 hashenumerate( classes, free_class, (void *)0 );
189 hashdone( classes );
190 classes = 0;
191 }
192 }