From 75a9f6813e17d411b148608a3e417630b14ef90a Mon Sep 17 00:00:00 2001 From: Arne Goedeke <el@laramies.com> Date: Sun, 4 Dec 2011 20:55:56 +0100 Subject: [PATCH] cpp: handle exception in magic define, fixed prefix handling --- lib/modules/Pike.pmod/module.pmod | 8 +++++ src/cpp.c | 42 +++++++++++++++++----- src/preprocessor.h | 58 +++++++++++++++++-------------- 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/lib/modules/Pike.pmod/module.pmod b/lib/modules/Pike.pmod/module.pmod index da139d0950..d70f3e57ad 100644 --- a/lib/modules/Pike.pmod/module.pmod +++ b/lib/modules/Pike.pmod/module.pmod @@ -80,6 +80,14 @@ constant low_check_call = predef::__low_check_call; constant get_return_type = predef::__get_return_type; constant get_first_arg_type = predef::__get_first_arg_type; +// precompile.pike checks for this +#if constant(__builtin.__HAVE_CPP_PREFIX_SUPPORT__) +//! This constant exists and has the value 1 if cpp supports +//! the prefix feature. +//! @seealso @[cpp()] +constant __HAVE_CPP_PREFIX_SUPPORT__ = __builtin.__HAVE_CPP_PREFIX_SUPPORT__; +#endif + program Encoder = [program] master()->Encoder; program Decoder = [program] master()->Decoder; program Codec = [program] master()->Codec; diff --git a/src/cpp.c b/src/cpp.c index 81b2380e3c..6f5d5b872c 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -1042,8 +1042,9 @@ static void simple_add_define(struct cpp *this, (data[pos+1] == '\n')) { \ pos+=2; \ } else { \ - break; \ + continue; \ } \ + this->current_line++; \ default: \ continue; \ } \ @@ -1601,7 +1602,14 @@ void free_one_define(struct hash_entry *h) static ptrdiff_t low_cpp(struct cpp *this, void *data, ptrdiff_t len, int shift, int flags, int auto_convert, struct pike_string *charset); - +static void insert_callback_define(struct cpp *this, + struct define *def, + struct define_argument *args, + struct string_builder *tmp); +static void insert_callback_define_no_args(struct cpp *this, + struct define *def, + struct define_argument *args, + struct string_builder *tmp); #define SHIFT 0 #include "preprocessor.h" #undef SHIFT @@ -1731,10 +1739,10 @@ static void insert_callback_define(struct cpp *this, { ref_push_string( def->link.s ); push_string( make_shared_binary_pcharp( args[0].arg, args[0].len ) ); - safe_apply_handler( "evaluate_define", this->handler, this->compat_handler, 2, 0 ); - if( TYPEOF(sp[-1]) == T_STRING ) + if (safe_apply_handler( "evaluate_define", this->handler, this->compat_handler, 2, 0 ) && TYPEOF(sp[-1]) == T_STRING ) { string_builder_shared_strcat(tmp, sp[-1].u.string); - pop_stack(); + pop_stack(); + } } static void insert_callback_define_no_args(struct cpp *this, @@ -1742,11 +1750,11 @@ static void insert_callback_define_no_args(struct cpp *this, struct define_argument *args, struct string_builder *tmp) { + struct svalue *save_sp = Pike_sp; ref_push_string( def->link.s ); - safe_apply_handler( "evaluate_define", this->handler, this->compat_handler, 1, 0 ); - if( TYPEOF(sp[-1]) == T_STRING ) + if (safe_apply_handler( "evaluate_define", this->handler, this->compat_handler, 1, 0 ) && TYPEOF(sp[-1]) == T_STRING ) string_builder_shared_strcat(tmp, sp[-1].u.string); - pop_stack(); + if (Pike_sp > save_sp) pop_n_elems(Pike_sp-save_sp); } /*! @namespace predef:: */ @@ -2099,6 +2107,20 @@ void f_cpp(INT32 args) free_mapping (predefs); predefs = NULL; goto predef_map_error; + } else if (!(TYPEOF(k->val) == T_INT && !k->val.u.integer) + && TYPEOF(k->val) != T_STRING + && TYPEOF(k->val) != T_FUNCTION + && TYPEOF(k->val) != T_OBJECT) { + + push_constant_text ("expected zero, string or function value for" + " predefine\n"); + push_constant_text ("expected zero, string or function value for" + " predefine %O\n"); + push_svalue (&k->ind); + sprintf_args = 2; + free_mapping (predefs); + predefs = NULL; + goto predef_map_error; } } } @@ -2186,7 +2208,7 @@ void f_cpp(INT32 args) NEW_MAPPING_LOOP (predefs->data) { if (TYPEOF(k->val) == T_STRING) add_define (&this, k->ind.u.string, k->val.u.string); - else if(TYPEOF(k->val) != T_INT || k->val.u.integer ) + else if(TYPEOF(k->val) == T_FUNCTION || TYPEOF(k->val) == T_OBJECT) { struct define *def; if( index_shared_string( k->ind.u.string, k->ind.u.string->len-1) == ')' ) @@ -2287,6 +2309,8 @@ void init_cpp() /* OPT_SIDE_EFFECT since we might instantiate modules etc. */ OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); + ADD_INT_CONSTANT("__HAVE_CPP_PREFIX_SUPPORT__", 1, 0); + /* Somewhat tricky to add a _constant_ function in _static_modules.Builtin. */ SET_SVAL(s, T_FUNCTION, FUNCTION_BUILTIN, efun, make_callable (f__take_over_initial_predefines, diff --git a/src/preprocessor.h b/src/preprocessor.h index fb24131c86..36f73b23db 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -1063,6 +1063,10 @@ static ptrdiff_t lower_cpp(struct cpp *this, int auto_convert, struct pike_string *charset) { + static const WCHAR string_recur_[] = + { 's', 't', 'r', 'i', 'n', 'g', '_', 'r', 'e', 'c', 'u', 'r' }; + static const WCHAR include_recur_[] = + { 'i', 'n', 'c', 'l', 'u', 'd', 'e', '_', 'r', 'e', 'c', 'u', 'r' }; ptrdiff_t pos, tmp, e; int include_mode; INT32 first_line = this->current_line; @@ -1434,7 +1438,9 @@ static ptrdiff_t lower_cpp(struct cpp *this, } /* Remove any newlines from the completed expression. */ - switch (tmp.s->size_shift) { + if (!(d->magic == insert_callback_define + || d->magic == insert_callback_define_no_args)) + switch (tmp.s->size_shift) { case 0: for(e=0; e< (ptrdiff_t)tmp.s->len; e++) if(STR0(tmp.s)[e]=='\n') @@ -1534,31 +1540,35 @@ static ptrdiff_t lower_cpp(struct cpp *this, } SKIPSPACE(); - if (this->prefix) { - int i; - if (this->prefix->len+1 >= len-pos) { - goto ADD_TO_BUFFER; - } - for (i = 0; i < this->prefix->len; i++) { - if (this->prefix->str[i] != data[pos+i]) { - FIND_EOS(); + if (!CHECKWORD2(string_recur_, NELEM(string_recur_)) + && !CHECKWORD2(include_recur_, NELEM(include_recur_))) { + if (this->prefix) { + int i; + if (this->prefix->len+1 >= len-pos) { goto ADD_TO_BUFFER; } - } - if (data[pos+i] != '_') { - FIND_EOS(); - goto ADD_TO_BUFFER; - } - - pos += this->prefix->len + 1; - } else { - int i; - for (i = pos; i < len; i++) { - if (data[i] == '_') { + for (i = 0; i < this->prefix->len; i++) { + if (this->prefix->str[i] != data[pos+i]) { + FIND_EOS(); + goto ADD_TO_BUFFER; + } + } + if (data[pos+i] != '_') { FIND_EOS(); goto ADD_TO_BUFFER; - } else if (!WC_ISIDCHAR(data[i])) - break; + } + + pos += this->prefix->len + 1; + } else { + int i; + + for (i = pos; i < len; i++) { + if (data[i] == '_') { + FIND_EOS(); + goto ADD_TO_BUFFER; + } else if (!WC_ISIDCHAR(data[i])) + break; + } } } @@ -1637,8 +1647,6 @@ static ptrdiff_t lower_cpp(struct cpp *this, case 's': { static const WCHAR string_[] = { 's', 't', 'r', 'i', 'n', 'g' }; - static const WCHAR string_recur_[] = - { 's', 't', 'r', 'i', 'n', 'g', '_', 'r', 'e', 'c', 'u', 'r' }; if(WGOBBLE2(string_)) { @@ -1656,8 +1664,6 @@ static ptrdiff_t lower_cpp(struct cpp *this, case 'i': /* include, if, ifdef */ { static const WCHAR include_[] = { 'i', 'n', 'c', 'l', 'u', 'd', 'e' }; - static const WCHAR include_recur_[] = - { 'i', 'n', 'c', 'l', 'u', 'd', 'e', '_', 'r', 'e', 'c', 'u', 'r' }; static const WCHAR if_[] = { 'i', 'f' }; static const WCHAR ifdef_[] = { 'i', 'f', 'd', 'e', 'f' }; static const WCHAR ifndef_[] = { 'i', 'f', 'n', 'd', 'e', 'f' }; -- GitLab