diff --git a/src/cpp.c b/src/cpp.c index a5b4b7958bf662d4610c44e6ec6dd3a4fa28dfb5..871fc3482e62c2320498291e8d8e624a9b06f12f 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -5,7 +5,7 @@ \*/ /* - * $Id: cpp.c,v 1.84 2001/05/14 03:20:39 hubbe Exp $ + * $Id: cpp.c,v 1.85 2001/05/29 16:48:20 grubba Exp $ */ #include "global.h" #include "stralloc.h" @@ -191,6 +191,11 @@ static void undefine(struct cpp *this, if(!d) return; + if (d->inside) { + cpp_error(this, "Illegal to undefine a macro during its expansion."); + return; + } + this->defines=hash_unlink(this->defines, & d->link); for(e=0;e<d->num_parts;e++) @@ -824,6 +829,18 @@ static struct pike_string *filter_bom(struct pike_string *data) return(data); } +void free_one_define(struct hash_entry *h) +{ + int e; + struct define *d=BASEOF(h, define, link); + + for(e=0;e<d->num_parts;e++) + free_string(d->parts[e].postfix); + if(d->first) + free_string(d->first); + free((char *)d); +} + static ptrdiff_t low_cpp(struct cpp *this, void *data, ptrdiff_t len, int shift, int flags, int auto_convert, struct pike_string *charset); @@ -861,18 +878,6 @@ static ptrdiff_t low_cpp(struct cpp *this, void *data, ptrdiff_t len, return 0; } -void free_one_define(struct hash_entry *h) -{ - int e; - struct define *d=BASEOF(h, define, link); - - for(e=0;e<d->num_parts;e++) - free_string(d->parts[e].postfix); - if(d->first) - free_string(d->first); - free((char *)d); -} - /*** Magic defines ***/ static void insert_current_line(struct cpp *this, struct define *def, diff --git a/src/preprocessor.h b/src/preprocessor.h index 3d13b80a7ff25b2bc0ee4e5622632fbb49cb78fa..00e688d90389a1c3ecf8dea83aa48d08c1456994 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -1,5 +1,5 @@ /* - * $Id: preprocessor.h,v 1.39 2001/05/17 23:49:07 hubbe Exp $ + * $Id: preprocessor.h,v 1.40 2001/05/29 16:48:21 grubba Exp $ * * Preprocessor template. * Based on cpp.c 1.45 @@ -1033,9 +1033,11 @@ static ptrdiff_t lower_cpp(struct cpp *this, INT32 line=this->current_line; save=this->buf; this->buf=tmp; + d->inside = 1; lower_cpp(this, a, l, flags & ~(CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE), auto_convert, charset); + d->inside = 0; tmp=this->buf; this->buf=save; this->current_line=line; @@ -1879,9 +1881,16 @@ static ptrdiff_t lower_cpp(struct cpp *this, (def->parts[0].argument & DEF_ARG_MASK) > MAX_ARGS) fatal("Internal error in define\n"); #endif - - this->defines=hash_insert(this->defines, & def->link); - + { + struct define *d; + if ((d = find_define(def->link.s)) && (d->inside)) { + cpp_error(this, + "Illegal to redefine a macro during its expansion."); + free_one_define(&(def->link)); + } else { + this->defines=hash_insert(this->defines, & def->link); + } + } } pop_n_elems(Pike_sp-argbase); break; diff --git a/src/testsuite.in b/src/testsuite.in index 13f582ca790f35d4615c38f4a8279e4d4db86e41..0597e9e3021628f9cb3ed99ef8ab58189ed98e40 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.416 2001/05/24 22:39:01 hubbe Exp $"]]); +test_true([["$Id: testsuite.in,v 1.417 2001/05/29 16:48:21 grubba Exp $"]]); cond([[all_constants()->_verify_internals]], [[ @@ -5843,6 +5843,26 @@ do_test_cpp_string([["\\\\"]]) do_test_cpp_string([["\\\\\\"]]) do_test_cpp_string([["\""]]) +// #undef inside an evaluation of the macro. +test_compile_error([[ +#define LOCALE(X,Y) (Y) +#define DEFVAR(X, Y) ret[(X)]=my_defvar((X),(Y),vars) + + DEFVAR("cm_wa", + Sitebuilder.SBConnect()-> + ChooseWorkareaVariable(LOCALE(0, "Work area") + LOCALE(0, "Work area"), + LOCALE(0, "the")); + + DEFVAR("cr_startpage", + Variable.URLList(LOCALE(0, "Crawling behaviour") + LOCALE(0, "Start pages"), "")); + +#undef DEFVAR + +constant cif_defines = #" + <input align='&_.img-align;' type='image' name='&_.name;' value='&_.contents;' src='&var.url;' border='0' /> +</define>"; +]]) + // foop define(do_test_foop,[[ test_eq($1 (17), !($2))