From 528fe1c11f9a75d6172f9027cc9866db7bad3730 Mon Sep 17 00:00:00 2001 From: Martin Nilsson <mani@lysator.liu.se> Date: Sat, 23 Oct 2004 01:26:13 +0200 Subject: [PATCH] Facets Rev: src/.cvsignore:1.37 Rev: src/Makefile.in:1.387 Rev: src/errors.h:1.27 Rev: src/facetgroup.cmod:1.1 Rev: src/interpret.c:1.357 Rev: src/interpret.h:1.155 Rev: src/language.yacc:1.344 Rev: src/lexer.h:1.50 Rev: src/main.c:1.215 Rev: src/program.c:1.572 Rev: src/program.h:1.212 --- .gitattributes | 1 + src/.cvsignore | 1 + src/.gitignore | 1 + src/Makefile.in | 6 +- src/errors.h | 4 +- src/facetgroup.cmod | 291 ++++++++++++++++++++++++++++++++++++++++++++ src/interpret.c | 16 ++- src/interpret.h | 3 +- src/language.yacc | 65 +++++++++- src/lexer.h | 5 +- src/main.c | 6 +- src/program.c | 58 ++++++++- src/program.h | 11 +- 13 files changed, 459 insertions(+), 9 deletions(-) create mode 100644 src/facetgroup.cmod diff --git a/.gitattributes b/.gitattributes index f2cb39efdd..516c273635 100644 --- a/.gitattributes +++ b/.gitattributes @@ -338,6 +338,7 @@ testfont binary /src/error.c foreign_ident /src/errors.h foreign_ident /src/export_list foreign_ident +/src/facetgroup.cmod foreign_ident /src/fd_control.c foreign_ident /src/fd_control.h foreign_ident /src/fdlib.c foreign_ident diff --git a/src/.cvsignore b/src/.cvsignore index 25fc710fc7..7113a7e3c9 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -15,6 +15,7 @@ conftest.c conftest.h dependencies dumpmodule.log +facetgroup.c hilfe hsort_template.h interpret_functions_fixed.h diff --git a/src/.gitignore b/src/.gitignore index d150510c6c..4e12d8b27d 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -15,6 +15,7 @@ /conftest.h /dependencies /dumpmodule.log +/facetgroup.c /hilfe /hsort_template.h /interpret_functions_fixed.h diff --git a/src/Makefile.in b/src/Makefile.in index ece4172688..c48496624f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.386 2004/10/20 18:59:38 grubba Exp $ +# $Id: Makefile.in,v 1.387 2004/10/22 23:22:57 nilsson Exp $ # # This line is needed on some machines. @@ -169,6 +169,7 @@ OBJ= \ queue.o \ builtin.o \ iterators.o \ + facetgroup.o \ svalue.o \ las.o \ builtin_functions.o \ @@ -983,6 +984,8 @@ builtin.o: $(SRCDIR)/builtin.c iterators.o: $(SRCDIR)/iterators.c +facetgroup.o: $(SRCDIR)/facetgroup.c + backend.o: $(SRCDIR)/backend.c # Internal testing target @@ -1142,6 +1145,7 @@ HFILES= \ version.protos \ builtin.protos \ iterators.protos \ + facetgroup.protos \ rbtree.protos $(HFILES): precompile.sh-stamp diff --git a/src/errors.h b/src/errors.h index c2467b2752..f898d08bda 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: errors.h,v 1.26 2004/04/18 02:19:38 mast Exp $ +|| $Id: errors.h,v 1.27 2004/10/22 23:22:24 nilsson Exp $ */ #ifdef ERR_DECLARE @@ -125,6 +125,8 @@ DECLARE_ERROR(cpp, Cpp, ERR_INHERIT(generic), EMPTY) DECLARE_ERROR(compilation, Compilation, ERR_INHERIT(generic), EMPTY) +DECLARE_ERROR(compile_callback, CompileCallback, ERR_INHERIT(generic), EMPTY) + DECLARE_ERROR(master_load, MasterLoad, ERR_INHERIT (generic), EMPTY) DECLARE_ERROR (module_load, ModuleLoad, diff --git a/src/facetgroup.cmod b/src/facetgroup.cmod new file mode 100644 index 0000000000..1290ae8377 --- /dev/null +++ b/src/facetgroup.cmod @@ -0,0 +1,291 @@ +/* -*- c -*- +|| This file is part of Pike. For copyright information see COPYRIGHT. +|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING +|| for more information. +|| $Id: facetgroup.cmod,v 1.1 2004/10/22 23:20:35 nilsson Exp $ +*/ + +#include "global.h" +#include "fdlib.h" +#include "main.h" +#include "object.h" +#include "mapping.h" +#include "multiset.h" +#include "svalue.h" +#include "stralloc.h" +#include "array.h" +#include "pike_macros.h" +#include "pike_error.h" +#include "pike_memory.h" +#include "dynamic_buffer.h" +#include "interpret.h" +#include "las.h" +#include "gc.h" +#include "stralloc.h" +#include "opcodes.h" +#include "pike_error.h" +#include "program.h" +#include "operators.h" +#include "builtin_functions.h" +#include "constants.h" +#include "program.h" +#include "block_alloc.h" + +DECLARATIONS + +/*! @class facetgroup + *! + *! This class is used to handle facets in the system. All facets + *! in the system have to belong to a facet group. The facet + *! group is a pike module that inherits from this class. For + *! example you can create a file MyFacetgroup.pmod with the following + *! content: + *! + *! @tt{inherit facetgroup; + *! int main() { ; } @} + *! + *! You can then use the facet group MyFacetGroup in a facet-class + *! like this: + *! + *! @tt{class A + *! { + *! facet NameOfMyFacet : .MyFacetGroup; + *! // Rest of class A + *! } @} + *! + */ + +/* Linked list of facet-classes */ +struct facet_class_struct { + int id; + struct facet_class_struct *next; +}; + +/* Linked list of facets with their facet-classes */ +struct facet_node_struct { + struct pike_string *name; + struct facet_class_struct *classes; + struct facet_node_struct *next; +}; + +/* Linked list of facets a product class is inheriting from */ +struct facet_list_struct { + int facet_index; + int facet_class; + struct facet_list_struct *next; +}; + +/* Linked list of product classes with lists of what facets they use */ +struct product_class_struct { + int id; + struct facet_list_struct *facets; + int num_used_facets; + struct product_class_struct *next; +}; + +BLOCK_ALLOC_FILL_PAGES(facet_class_struct, 2) +BLOCK_ALLOC_FILL_PAGES(facet_node_struct, 2) +BLOCK_ALLOC_FILL_PAGES(product_class_struct, 2) +BLOCK_ALLOC_FILL_PAGES(facet_list_struct, 2) + + +/* The actual facet_group class */ +PIKECLASS facet_group +{ + CVAR struct facet_node_struct *facets; + CVAR struct product_class_struct *pclasses; + CVAR int num_facets; + CVAR int checked_product_classes; + + /* Retruns 1 if product classes in this facet group have been checked, + * 0 otherwise */ + PIKEFUN int product_classes_checked() { + RETURN THIS->checked_product_classes; + } + + /* Function to check that all product-classes inherits from all facet */ + PIKEFUN void check_product_classes() { + struct facet_list_struct *fl; + struct product_class_struct *pc; + int error = 0; + for(pc=THIS->pclasses; pc; pc = pc->next) { + if (pc->num_used_facets < THIS->num_facets) { + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Product class does not inherit from all facets.\n"); + } + else if (pc->num_used_facets > THIS->num_facets) { + /* It should be impossible to get here */ + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Product class inherits more than once from some facet.\n"); + } + } + THIS->checked_product_classes = 1; + pop_n_elems(args); + } + + /* Add info that the class "class" inherits from the facet "facet_index" */ + PIKEFUN void add_product_class(int class, int facet_index, int facet_class) { + struct facet_list_struct *fl, *fltmp; + struct product_class_struct *pc, *pctmp; + /* Set checked_product_classes to 0 to indicate that not all + * product classes have been checked */ + THIS->checked_product_classes = 0; + /* Check whether the product class is allready in our list of + * product classes */ + for (pc=THIS->pclasses; pc; pc = pc->next) { + if (class == pc->id) + break; + } + + if (!pc) { /* New product class */ + pctmp = alloc_product_class_struct(); + pctmp->id = class; + pctmp->facets = NULL; + pctmp->num_used_facets = 0; + pctmp->next = THIS->pclasses; + THIS->pclasses = pctmp; + pc = pctmp; + } + + /* pc now points to the product class to modify */ + for(fl=pc->facets; fl; fl = fl->next) { + if (fl->facet_index == facet_index) + break; + } + if (!fl) { + //Add facet "facet_index" to product class "class"'s inherits + fltmp = alloc_facet_list_struct(); + fltmp->facet_index = facet_index; + fltmp->facet_class = facet_class; + pc->num_used_facets++; + fltmp->next = pc->facets; + pc->facets = fltmp; + } + else /* The product class already inherits from this facet */ + if (fl->facet_class != facet_class) + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Product class can only inherit from one class in every facet.\n"); + pop_n_elems(args); + } + + /* Add a facet class in the facet group */ + PIKEFUN int add_facet_class(string facet, int class, int product_class) { + struct facet_class_struct *c, *ctmp; + struct facet_node_struct *f, *prevf, *ftmp; + struct product_class_struct *pc, *prevpc; + struct object *o; + int facet_index = 0; + if (facet == NULL) + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Invalid facet name.\n"); + + // Check if it is a new facet or not. + prevf = NULL; + for(f=THIS->facets; f; f=f->next, facet_index++) { + if (f->name == facet) + break; + prevf=f; + } + if (product_class) { + // This occurs if the inherit statement comes before the facet + // statement in the class + for (prevpc=pc=THIS->pclasses; pc; pc = pc->next) { + if (pc->id == class) + break; + prevpc = pc; + } + if (!pc) + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Program marked as product class but not found in list of product classes.\n"); + else { + if (pc->num_used_facets > 1 || + facet_index != pc->facets->facet_index) + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Facet class can not inherit from a class in another facet."); + else { + if (prevpc->id == pc->id) + THIS->pclasses = pc->next; + else + prevpc->next = pc->next; + really_free_product_class_struct(pc); + } + } + } + if (!f) { /* A new facet */ + THIS->num_facets++; + f = alloc_facet_node_struct(); + add_ref(f->name = facet); + f->next = NULL; + if (!prevf) + THIS->facets = f; + else + prevf->next = f; + f->classes = NULL; + } + // f now points to the facet 'facet' in 'facets' + // Check whether the class 'class' is already in the facet + for (c=f->classes; c; c = c->next) { + if (class == c->id) + break; + } + if (c) { + throw_error_object(low_clone(compile_callback_error_program),0,0,0, + "Redundant facet statement.\n"); + } + else { + ctmp = alloc_facet_class_struct(); + ctmp->id = class; + ctmp->next = f->classes; + f->classes = ctmp; + } + RETURN facet_index; + } + + INIT { + THIS->facets = NULL; + THIS->pclasses = NULL; + THIS->num_facets = 0; + THIS->checked_product_classes = 0; + } + + EXIT { + struct facet_node_struct *f, *fnext; + struct facet_class_struct *fc, *fcnext; + struct product_class_struct *p, *pnext; + struct facet_list_struct *fl, *flnext; + for (fnext=f=THIS->facets; fnext; f=fnext) { + fnext = f->next; + for (fcnext=fc=f->classes; fcnext; fc=fcnext) { + fcnext = fc->next; + really_free_facet_class_struct(fc); + } + really_free_string(f->name); + really_free_facet_node_struct(f); + } + for (pnext=p=THIS->pclasses; pnext; p=pnext) { + pnext = p->next; + for (flnext=fl=p->facets; flnext; fl=flnext) { + flnext = fl->next; + really_free_facet_list_struct(fl); + } + really_free_product_class_struct(p); + } + } +}; + +void init_facetgroup(void) +{ + init_facet_class_struct_blocks(); + init_facet_node_struct_blocks(); + init_facet_list_struct_blocks(); + init_product_class_struct_blocks(); + INIT; + add_global_program("FacetGroup", facet_group_program); +} + +void exit_facetgroup(void) +{ + EXIT +} +/*! @endclass + */ diff --git a/src/interpret.c b/src/interpret.c index 3194c32f91..da837c5b56 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: interpret.c,v 1.356 2004/10/16 07:27:29 agehall Exp $ +|| $Id: interpret.c,v 1.357 2004/10/22 23:23:51 nilsson Exp $ */ #include "global.h" @@ -2216,6 +2216,20 @@ PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset) return ret; } +PMOD_EXPORT void safe_apply_low3(struct object *o,int fun,int args, char *error) +{ + JMP_BUF recovery; + free_svalue(& throw_value); + throw_value.type=T_INT; + if(SETJMP_SP(recovery, args)) + { + handle_compile_exception(error); + }else{ + apply_low(o,fun,args); + } + UNSETJMP(recovery); +} + PMOD_EXPORT void safe_apply_low2(struct object *o,int fun,int args, int handle_errors) { JMP_BUF recovery; diff --git a/src/interpret.h b/src/interpret.h index 39c4dc0c2f..8c6df91739 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: interpret.h,v 1.154 2004/09/22 13:10:30 mast Exp $ +|| $Id: interpret.h,v 1.155 2004/10/22 23:23:51 nilsson Exp $ */ #ifndef INTERPRET_H @@ -671,6 +671,7 @@ PMOD_EXPORT void call_handle_error(void); PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset); PMOD_EXPORT void safe_apply_low(struct object *o,int fun,int args); PMOD_EXPORT void safe_apply_low2(struct object *o,int fun,int args, int handle_errors); +PMOD_EXPORT void safe_apply_low3(struct object *o,int fun,int args, char *error); PMOD_EXPORT void safe_apply(struct object *o, const char *fun ,INT32 args); PMOD_EXPORT int low_unsafe_apply_handler(const char *fun, struct object *handler, diff --git a/src/language.yacc b/src/language.yacc index 975d15c124..f9157f8841 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: language.yacc,v 1.343 2004/10/22 14:42:16 grubba Exp $ +|| $Id: language.yacc,v 1.344 2004/10/22 23:23:20 nilsson Exp $ */ %pure_parser @@ -60,6 +60,7 @@ %token TOK_IF %token TOK_IMPORT %token TOK_INHERIT +%token TOK_FACET %token TOK_INLINE %token TOK_LOCAL_ID %token TOK_FINAL_ID @@ -208,6 +209,7 @@ int yylex(YYSTYPE *yylval); %type <number> TOK_DEFAULT %type <number> TOK_DO %type <number> TOK_ELSE +%type <number> TOK_FACET %type <number> TOK_FLOAT_ID %type <number> TOK_FOR %type <number> TOK_FOREACH @@ -429,6 +431,41 @@ program_ref: low_program_ref } ; +facet: TOK_FACET TOK_IDENTIFIER ':' idents ';' + { + struct object *o; + if (Pike_compiler->compiler_pass == 1) { + if (Pike_compiler->new_program->facet_class == PROGRAM_IS_FACET_CLASS) { + yyerror("A class can only belong to one facet"); + } + else { + resolv_constant($4); + if (Pike_sp[-1].type == T_OBJECT) { + o = Pike_sp[-1].u.object; + push_string($2->u.sval.u.string); + push_int(Pike_compiler->new_program->id); + push_int(Pike_compiler->new_program->facet_class); + safe_apply_low3(o, find_identifier("add_facet_class",o->prog), 3, + "Failed to add facet class to system"); + if (Pike_sp[-1].type == T_INT && + Pike_sp[-1].u.integer >= 0) { + Pike_compiler->new_program->facet_class = PROGRAM_IS_FACET_CLASS; + Pike_compiler->new_program->facet_index = Pike_sp[-1].u.integer; + add_ref(Pike_compiler->new_program->facet_group = o); + } + else + yyerror("Could not add facet class to system."); + pop_n_elems(2); + } + else + yyerror("Illegal facet group specifier."); + free_node($4); + } + } + } + ; + + inherit_ref: { SET_FORCE_RESOLVE($<number>$); @@ -451,6 +488,28 @@ inheritance: modifiers TOK_INHERIT inherit_ref optional_rename_inherit ';' if($4) s=$4->u.sval.u.string; compiler_do_inherit($3,$1,s); } + + /* If this is a product class, check that all product classes in its + * facet-group inherits from all facets */ + if($3 && Pike_compiler->compiler_pass == 2) { + if (Pike_compiler->new_program->facet_class==PROGRAM_IS_PRODUCT_CLASS){ + if (!Pike_compiler->new_program->facet_group) + yyerror("Invalid facet group."); + apply(Pike_compiler->new_program->facet_group, + "product_classes_checked", 0); + if (Pike_sp[-1].type == T_INT && + Pike_sp[-1].u.integer == 0) { + pop_stack(); + safe_apply_low3(Pike_compiler->new_program->facet_group, + find_identifier + ("check_product_classes", + Pike_compiler->new_program->facet_group->prog), + 0, + "Error in some product classes"); + } + } + } + if($4) free_node($4); pop_stack(); if ($3) free_node($3); @@ -928,6 +987,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0 } | modifiers type_or_error name_list ';' {} | inheritance {} + | facet {} | import {} | constant {} | class { free_node($1); } @@ -1081,6 +1141,7 @@ magic_identifiers3: | TOK_CONSTANT { $$ = "constant"; } | TOK_CONTINUE { $$ = "continue"; } | TOK_DEFAULT { $$ = "default"; } + | TOK_FACET { $$ = "facet"; } | TOK_IMPORT { $$ = "import"; } | TOK_INHERIT { $$ = "inherit"; } | TOK_LAMBDA { $$ = "lambda"; } @@ -3860,6 +3921,8 @@ bad_expr_ident: { yyerror("return is a reserved word."); } | TOK_IMPORT { yyerror("import is a reserved word."); } + | TOK_FACET + { yyerror("facet is a reserved word."); } | TOK_INHERIT { yyerror("inherit is a reserved word."); } | TOK_CATCH diff --git a/src/lexer.h b/src/lexer.h index 44fdb6759e..ab69c94991 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: lexer.h,v 1.49 2004/06/30 00:17:42 nilsson Exp $ +|| $Id: lexer.h,v 1.50 2004/10/22 23:24:15 nilsson Exp $ */ /* @@ -376,6 +376,9 @@ static int low_yylex(YYSTYPE *yylval) case TWO_CHAR('e','x'): if(ISWORD("extern")) return TOK_EXTERN; break; + case TWO_CHAR('f','a'): + if(ISWORD("facet")) return TOK_FACET; + break; case TWO_CHAR('f','i'): if(ISWORD("final")) return TOK_FINAL_ID; break; diff --git a/src/main.c b/src/main.c index 3f7ad22846..da488bab0e 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: main.c,v 1.214 2004/10/14 11:07:44 grubba Exp $ +|| $Id: main.c,v 1.215 2004/10/22 23:24:28 nilsson Exp $ */ #include "global.h" @@ -918,6 +918,7 @@ DECLSPEC(noreturn) void pike_do_exit(int num) ATTRIBUTE((noreturn)) void low_init_main(void) { void init_iterators(void); + void init_facetgroup(void); init_cpp(); init_backend(); @@ -933,6 +934,7 @@ void low_init_main(void) init_builtin_efuns(); init_signals(); init_dynamic_load(); + init_facetgroup(); } void exit_main(void) @@ -972,6 +974,7 @@ void low_exit_main(void) { #ifdef DO_PIKE_CLEANUP void exit_iterators(void); + void exit_facetgroup(void); /* Clear various global references. */ @@ -988,6 +991,7 @@ void low_exit_main(void) cleanup_module_support(); exit_operators(); exit_iterators(); + exit_facetgroup(); cleanup_program(); cleanup_compiler(); cleanup_error(); diff --git a/src/program.c b/src/program.c index 903332d314..89b97c4493 100644 --- a/src/program.c +++ b/src/program.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: program.c,v 1.571 2004/10/22 20:18:03 grubba Exp $ +|| $Id: program.c,v 1.572 2004/10/22 23:24:49 nilsson Exp $ */ #include "global.h" @@ -2052,6 +2052,12 @@ void low_start_new_program(struct program *p, int id=0; struct svalue tmp; + if(Pike_compiler->compiler_pass == 1 && p) { + p->facet_class = 0; + p->facet_index = -1; + p->facet_group = NULL; + } + #if 0 #ifdef SHARED_NODES if (!node_hash.table) { @@ -3587,6 +3593,53 @@ static int find_depth(struct program_state *state, } #endif +void check_for_facet_inherit(struct program *p) +{ + int fid; + /* If the inherit statement comes before the facet keyword in the + * class declaration the class will be temporarily marked as a + * product-class, but this will be taken care of when the facet + * keyword is found. */ + if (p && Pike_compiler->new_program->facet_group && + p->facet_group != Pike_compiler->new_program->facet_group) + yyerror("A class can not belong to two facet-groups\n"); + if (p && p->facet_class == PROGRAM_IS_FACET_CLASS) { + if (Pike_compiler->new_program->facet_class == PROGRAM_IS_FACET_CLASS) { + if(Pike_compiler->new_program->facet_index != p->facet_index) + yyerror("Facet class can't inherit from class in different facet."); + } + /* Otherwise this is a product class */ + else { + int line = 0; + Pike_compiler->new_program->facet_class = PROGRAM_IS_PRODUCT_CLASS; + Pike_compiler->new_program->facet_group = p->facet_group; + push_int(Pike_compiler->new_program->id); + push_int(p->facet_index); + push_int(p->id); + safe_apply_low3(p->facet_group, + find_identifier("add_product_class", + p->facet_group->prog), + 3, + "Unable to add product class"); + } + } + /* The inherited class is not a facet class */ + else if (p && p->facet_class == PROGRAM_IS_PRODUCT_CLASS) { + if (Pike_compiler->new_program->facet_class == PROGRAM_IS_FACET_CLASS) { + yyerror("Facet class can't inherit from product class."); + } + else if(Pike_compiler->new_program->facet_class==PROGRAM_IS_PRODUCT_CLASS){ + yyerror("Product class can't inherit from other prodcut class."); + } + /* A class that inherits from a product class is also a product class */ + else if(Pike_compiler->new_program->facet_class!=PROGRAM_IS_FACET_CLASS) { + Pike_compiler->new_program->facet_class = PROGRAM_IS_PRODUCT_CLASS; + Pike_compiler->new_program->facet_group = p->facet_group; + } + } +} + + /* * make this program inherit another program */ @@ -3621,6 +3674,9 @@ void low_inherit(struct program *p, return; } + /* Check if inherit is a facet inherit. */ + check_for_facet_inherit(p); + if (p == placeholder_program) { yyerror("Trying to inherit placeholder program (resolver problem)."); return; diff --git a/src/program.h b/src/program.h index 664796a3cf..5bbc7299c5 100644 --- a/src/program.h +++ b/src/program.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: program.h,v 1.211 2004/09/28 23:58:26 mast Exp $ +|| $Id: program.h,v 1.212 2004/10/22 23:24:50 nilsson Exp $ */ #ifndef PROGRAM_H @@ -472,6 +472,10 @@ struct pike_trampoline * parent object. Only set if PROGRAM_USES_PARENT is. */ #define PROGRAM_NEEDS_PARENT 0x1000 +/* Indicates that the class is a facet or product_class. */ +#define PROGRAM_IS_FACET_CLASS 0x1 +#define PROGRAM_IS_PRODUCT_CLASS 0x2 + /* Using define instead of enum allows for ifdefs - Hubbe */ #define PROG_EVENT_INIT 0 #define PROG_EVENT_EXIT 1 @@ -539,6 +543,11 @@ struct program #include "program_areas.h" INT16 lfuns[NUM_LFUNS]; + + /* Facet related stuff */ + INT16 facet_class; /* PROGRAM_IS_X_CLASS (X=FACET/PRODUCT) */ + INT32 facet_index; /* Index to the facet this facet class belongs to */ + struct object *facet_group; }; #if 0 -- GitLab