Branch: Tag:

2018-01-05

2018-01-05 10:19:47 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Cpp: Moved preprocessor state to a proper object.

Cleans up memory and error handling somewhat.

86:    ptrdiff_t len;   };    - struct cpp; + struct CPP_struct;   struct define_struct; - typedef void (*magic_define_fun)(struct cpp *, + typedef void (*magic_define_fun)(struct CPP_struct *,    struct define_struct *,    struct pike_string *,    struct string_builder *);
121:    }   }    - struct cpp + PIKECLASS CPP   { -  struct mapping *defines; -  INT_TYPE current_line; -  INT32 compile_errors; -  struct pike_string *current_file; -  struct string_builder buf; -  struct object *handler; -  struct object *compat_handler; -  INT_TYPE compat_major; -  INT_TYPE compat_minor; -  struct pike_string *data; -  struct pike_string *prefix; -  INT_TYPE picky_cpp, keep_comments, dependencies_fail; +  PIKEVAR mapping(string:object(define)) defines flags ID_PRIVATE|ID_PROTECTED; +  PIKEVAR int current_line; +  PIKEVAR int compile_errors; +  PIKEVAR string current_file; +  CVAR struct string_builder buf; +  PIKEVAR object handler; +  PIKEVAR object compat_handler; +  PIKEVAR int compat_major; +  PIKEVAR int compat_minor; +  /* NB: data is marked private to ensure that pike level code can't +  * remove its references while we hold pointers into it. +  */ +  PIKEVAR string data flags ID_PRIVATE|ID_PROTECTED; +  PIKEVAR string prefix; +  PIKEVAR int picky_cpp; +  PIKEVAR int keep_comments; +  PIKEVAR int dependencies_fail; +  +  INIT +  { +  init_string_builder(&THIS->buf, 0); +  } +  +  EXIT +  { +  /* NOTE: Most of the fields are mapped, and thus freed automatically. */ +  +  if (THIS->buf.s) { +  free_string_builder(&THIS->buf); +  } +  }   };      #define FIND_DEFINE(N) find_define(this, (N))    - static struct define_struct *find_define(struct cpp *this, struct pike_string *n) + static struct define_struct *find_define(struct CPP_struct *this, struct pike_string *n)   {    struct svalue *s;    if (!this->defines) return NULL;
148:    return (struct define_struct *)get_storage(s->u.object, define_program);   }    - static void cpp_error(struct cpp *this, const char *err) ATTRIBUTE((noinline)); - static void cpp_error_vsprintf (struct cpp *this, const char *fmt, + static void cpp_error(struct CPP_struct *this, const char *err) ATTRIBUTE((noinline)); + static void cpp_error_vsprintf (struct CPP_struct *this, const char *fmt,    va_list args) ATTRIBUTE((noinline)); - static void cpp_error_sprintf(struct cpp *this, const char *fmt, ...) ATTRIBUTE((noinline)); - static void cpp_handle_exception(struct cpp *this, + static void cpp_error_sprintf(struct CPP_struct *this, const char *fmt, ...) ATTRIBUTE((noinline)); + static void cpp_handle_exception(struct CPP_struct *this,    const char *cpp_error_fmt, ...) ATTRIBUTE((noinline)); - static void cpp_warning(struct cpp *this, const char *cpp_warn_fmt, ...) ATTRIBUTE((noinline)); + static void cpp_warning(struct CPP_struct *this, const char *cpp_warn_fmt, ...) ATTRIBUTE((noinline));   struct define_struct *defined_macro = NULL;   static struct svalue defined_macro_sval;    - static void cpp_error(struct cpp *this, const char *err) + static void cpp_error(struct CPP_struct *this, const char *err)   {    this->compile_errors++;    if(this->compile_errors > 10) return;
179:    }   }    - static void cpp_error_vsprintf (struct cpp *this, const char *fmt, + static void cpp_error_vsprintf (struct CPP_struct *this, const char *fmt,    va_list args)   {    struct string_builder s;
221:    fflush(stderr);   }    - static void cpp_error_sprintf(struct cpp *this, const char *fmt, ...) + static void cpp_error_sprintf(struct CPP_struct *this, const char *fmt, ...)   {    va_list args;    va_start(args,fmt);
229:    va_end(args);   }    - static void cpp_handle_exception(struct cpp *this, + static void cpp_handle_exception(struct CPP_struct *this,    const char *cpp_error_fmt, ...)   {    struct svalue thrown;
259:    free_svalue(&thrown);   }    - static void cpp_warning(struct cpp *this, const char *cpp_warn_fmt, ...) + static void cpp_warning(struct CPP_struct *this, const char *cpp_warn_fmt, ...)   {    struct string_builder sb;    va_list args;
490:      /* #pike handling. */    - void cpp_change_compat(struct cpp *this, int major, int minor) + void cpp_change_compat(struct CPP_struct *this, int major, int minor)   {    if(this->compat_major == major &&    this->compat_minor == minor) return;
896:    *! @seealso    *! @[#if], @[#ifdef], @[constant()]    */ - static void check_defined(struct cpp *this, + static void check_defined(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *arg,    struct string_builder *tmp)
907:    string_builder_binary_strcat(tmp, " 0 ", 3);   }    - static int do_safe_index_call(struct cpp *this, struct pike_string *s) + static int do_safe_index_call(struct CPP_struct *this, struct pike_string *s)   {    int res;    JMP_BUF recovery;
936:    *! @seealso    *! @[#if], @[defined()]    */ - static void cpp_constant(struct cpp *this, int value) + static void cpp_constant(struct CPP_struct *this, int value)   {    struct svalue *save_stack=Pike_sp;    struct array *arr;
1067:    return map;   }    - static p_wchar2 readchar( PCHARP data, ptrdiff_t *pos, struct cpp *this ) + static p_wchar2 readchar( PCHARP data, ptrdiff_t *pos, struct CPP_struct *this )   {    ptrdiff_t l;    p_wchar2 C;
1108:   }       - static ptrdiff_t readstring( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos, + static ptrdiff_t readstring( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,    struct string_builder*nf, int nl_ok)   {    while(1)
1161:    return pos;   }    - static ptrdiff_t readstring_lit( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos, + static ptrdiff_t readstring_lit( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,    struct string_builder*nf, INT32 ec)   {    INT32 ch;
1183:    return pos;   }    - static ptrdiff_t fixstring(struct cpp *this, const PCHARP data, ptrdiff_t len, + static ptrdiff_t fixstring(struct CPP_struct *this, const PCHARP data, ptrdiff_t len,    ptrdiff_t pos, struct string_builder *nf, int outp)   {    int trailing_newlines=0;
1232:    return pos;   }    - static ptrdiff_t find_end_of_line( struct cpp *this, const PCHARP data, + static ptrdiff_t find_end_of_line( struct CPP_struct *this, const PCHARP data,    ptrdiff_t len, ptrdiff_t pos, int emit )   {    while(pos < len) {
1257:   }       - static ptrdiff_t find_end_of_comment( struct cpp *this, const PCHARP data, ptrdiff_t len, + static ptrdiff_t find_end_of_comment( struct CPP_struct *this, const PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int emit)   {    pos++;
1280:    return pos + 2;   }    - static ptrdiff_t find_end_quote(struct cpp *this, const PCHARP data, + static ptrdiff_t find_end_quote(struct CPP_struct *this, const PCHARP data,    ptrdiff_t len, ptrdiff_t pos,    p_wchar2 quote, int flags)   {
1330:   }       - static ptrdiff_t find_end_brace(struct cpp *this, + static ptrdiff_t find_end_brace(struct CPP_struct *this,    PCHARP data,    ptrdiff_t len,    ptrdiff_t pos);    - static ptrdiff_t find_end_parenthesis(struct cpp *this, + static ptrdiff_t find_end_parenthesis(struct CPP_struct *this,    PCHARP data,    ptrdiff_t len,    ptrdiff_t pos)
1372:   }       - static ptrdiff_t find_end_brace(struct cpp *this, + static ptrdiff_t find_end_brace(struct CPP_struct *this,    const PCHARP data,    ptrdiff_t len,    ptrdiff_t pos)
1407:    }   }    - static struct pike_string *gobble_identifier (struct cpp *this, const PCHARP data, ptrdiff_t *pos) + static struct pike_string *gobble_identifier (struct CPP_struct *this, const PCHARP data, ptrdiff_t *pos)   {    ptrdiff_t p = *pos;    struct string_builder sb;
1528:    *! @seealso    *! @[#define], @[defined()]    */ - static void undefine(struct cpp *this, struct pike_string *name) + static void undefine(struct CPP_struct *this, struct pike_string *name)   {    ref_push_string(name);    push_int(0);
1575:    *! will be replaced with @tt{something1@} and @tt{something2@}.    */    - static struct pike_string *make_define_name(struct cpp *this, + static struct pike_string *make_define_name(struct CPP_struct *this,    const char *name)   {    if (this->prefix) {
1592:    return make_shared_string(name);   }    - static struct define_struct *do_magic_define(struct cpp *this, + static struct define_struct *do_magic_define(struct CPP_struct *this,    const char *name,    magic_define_fun fun)   {
1606:    return def;   }    - static void add_define(struct cpp *this, + static void add_define(struct CPP_struct *this,    struct pike_string *name,    struct pike_string *what)   {
1620:    pop_stack();   }    - static void simple_add_define(struct cpp *this, + static void simple_add_define(struct CPP_struct *this,    const char *name,    const char *what)   {
1632:    free_string(name_str);   }    - static struct pike_string *recode_string(struct cpp *this, struct pike_string *data) + static struct pike_string *recode_string(struct CPP_struct *this, struct pike_string *data)   {    /* Observations:    *
1967:    free_string(x);   }    - static ptrdiff_t find_eos( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos ) + static ptrdiff_t find_eos( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos )   {    while(pos < len)    {
2001:    return pos;   }    - static ptrdiff_t skipwhite(struct cpp *this, const PCHARP data, ptrdiff_t pos) + static ptrdiff_t skipwhite(struct CPP_struct *this, const PCHARP data, ptrdiff_t pos)   {    do    {
2035:    return pos;   }    - static ptrdiff_t skipspace(struct cpp *this, const PCHARP data, ptrdiff_t pos, int emit) + static ptrdiff_t skipspace(struct CPP_struct *this, const PCHARP data, ptrdiff_t pos, int emit)   {    do {    int c;
2109:    return 1;   }    - static ptrdiff_t low_cpp(struct cpp *this, + static ptrdiff_t low_cpp(struct CPP_struct *this,    PCHARP data,    ptrdiff_t len,    int flags,    int auto_convert,    struct pike_string *charset); - static void insert_callback_define(struct cpp *this, + static void insert_callback_define(struct CPP_struct *this,    struct define_struct *def,    struct pike_string *arg,    struct string_builder *tmp); - static void insert_callback_define_no_args(struct cpp *this, + static void insert_callback_define_no_args(struct CPP_struct *this,    struct define_struct *def,    struct pike_string *arg,    struct string_builder *tmp); - static void insert_pragma(struct cpp *this, + static void insert_pragma(struct CPP_struct *this,    struct define_struct *def,    struct pike_string *arg,    struct string_builder *tmp);    - static ptrdiff_t calc1(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc1(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags);    - static ptrdiff_t calcC(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calcC(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    SKIPWHITE();
2369:    return pos;   }    - static ptrdiff_t calcB(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calcB(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calcB");
2389:    return pos;   }    - static ptrdiff_t calcA(struct cpp *this,PCHARP data, ptrdiff_t len, + static ptrdiff_t calcA(struct CPP_struct *this,PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calcA");
2431:    return pos;   }    - static ptrdiff_t calc9(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc9(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc9");
2465:    return pos;   }    - static ptrdiff_t calc8(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc8(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc8");
2499:    return pos;   }    - static ptrdiff_t calc7b(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc7b(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc7b");
2549:    return pos;   }    - static ptrdiff_t calc7(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc7(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc7");
2582:    return pos;   }    - static ptrdiff_t calc6(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc6(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc6");
2602:    return pos;   }    - static ptrdiff_t calc5(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc5(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc5");
2621:    return pos;   }    - static ptrdiff_t calc4(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc4(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc4");
2640:    return pos;   }    - static ptrdiff_t calc3(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc3(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {   
2668:    return pos;   }    - static ptrdiff_t calc2(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc2(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {   
2696:    return pos;   }    - static ptrdiff_t calc1(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc1(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t pos, int flags)   {    CALC_DUMPPOS("before calc1");
2721:    return pos;   }    - static ptrdiff_t calc(struct cpp *this, PCHARP data, ptrdiff_t len, + static ptrdiff_t calc(struct CPP_struct *this, PCHARP data, ptrdiff_t len,    ptrdiff_t tmp, int flags)   {    JMP_BUF recovery;
2802:    }   }    - static void apply_define(struct cpp *this, + static void apply_define(struct CPP_struct *this,    struct define_struct *d,    struct define_argument *arguments,    short flags, short auto_convert,
2934:    *! This define contains the current line number, represented as an    *! integer, in the source file.    */ - static void insert_current_line(struct cpp *this, + static void insert_current_line(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
2946:    *!    *! This define contains the file path and name of the source file.    */ - static void insert_current_file_as_string(struct cpp *this, + static void insert_current_file_as_string(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
2959:    *!    *! This define contains the directory path of the source file.    */ - static void insert_current_dir_as_string(struct cpp *this, + static void insert_current_dir_as_string(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
2977:    *! This define contains the current time at the time of compilation,    *! e.g. "12:20:51".    */ - static void insert_current_time_as_string(struct cpp *UNUSED(this), + static void insert_current_time_as_string(struct CPP_struct *UNUSED(this),    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
2996:    *! This define contains the current date at the time of compilation,    *! e.g. "Jul 28 2001".    */ - static void insert_current_date_as_string(struct cpp *UNUSED(this), + static void insert_current_date_as_string(struct CPP_struct *UNUSED(this),    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3020:    *! @seealso    *! @[__REAL_VERSION__]    */ - static void insert_current_version(struct cpp *this, + static void insert_current_version(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3038:    *! @seealso    *! @[__REAL_MINOR__]    */ - static void insert_current_minor(struct cpp *this, + static void insert_current_minor(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3051:    *! Int.NATIVE_MAX times) represented as an integer.    *!    */ - static void insert_current_counter(struct cpp *UNUSED(this), + static void insert_current_counter(struct CPP_struct *UNUSED(this),    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3069:    *! @seealso    *! @[__REAL_MAJOR__]    */ - static void insert_current_major(struct cpp *this, + static void insert_current_major(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3089:    *! @seealso    *! @[#pragma]    */ - static void insert_pragma(struct cpp *this, + static void insert_pragma(struct CPP_struct *this,    struct define_struct *UNUSED(def),    struct pike_string *arg,    struct string_builder *tmp)
3148:    string_builder_putchar(tmp, '\n');   }    - static void insert_callback_define(struct cpp *this, + static void insert_callback_define(struct CPP_struct *this,    struct define_struct *def,    struct pike_string *arg,    struct string_builder *tmp)
3173:    }   }    - static void insert_callback_define_no_args(struct cpp *this, + static void insert_callback_define_no_args(struct CPP_struct *this,    struct define_struct *def,    struct pike_string *UNUSED(arg),    struct string_builder *tmp)
3325:    *! @[compile()]    */    - /* Doesn't free string_builder buf! */ - static void free_cpp(struct cpp *this) - { -  if(this->defines) -  free_mapping(this->defines); -  -  if(this->current_file) -  free_string(this->current_file); -  -  if(this->handler) { -  free_object(this->handler); -  this->handler = 0; -  } -  -  if(this->compat_handler) { -  free_object(this->compat_handler); -  this->compat_handler=0; -  } -  -  if(this->data) -  free_string(this->data); -  -  if(this->prefix) -  free_string(this->prefix); - } -  -  +    PIKEFUN string cpp(string data,    mapping|string|void opts_or_file,    int|string|void charset_sv,
3361:    int|void picky_cpp_sv)    efun;   { -  struct cpp this; +  struct object *cpp_obj = fast_clone_object(CPP_program); +  struct CPP_struct *this = +  (struct CPP_struct *)get_storage(cpp_obj, CPP_program);    struct svalue *save_sp = Pike_sp - args;    struct mapping *predefs = NULL;   
3376:    int compat_minor = compat_minor_sv?compat_minor_sv->u.integer:0;    int picky_cpp = picky_cpp_sv?picky_cpp_sv->u.integer:0;    -  ONERROR err; +    #ifdef PIKE_DEBUG    ONERROR tmp;   #endif /* PIKE_DEBUG */    -  this.prefix = NULL; -  this.current_line=1; -  this.compile_errors=0; -  this.defines = allocate_mapping(32); -  this.keep_comments = 0; -  this.dependencies_fail = 0; +  push_object(cpp_obj);    -  +  this->prefix = NULL; +  this->current_line=1; +  this->compile_errors=0; +  this->defines = allocate_mapping(32); +  this->keep_comments = 0; +  this->dependencies_fail = 0; +     if (opts_or_file) {    if (TYPEOF(*opts_or_file) == PIKE_T_MAPPING) {    struct svalue *tmp;
3404:    if (GET_TYPE(INT, "compat_minor")) compat_minor = tmp->u.integer;    if (GET_TYPE(INT, "picky")) picky_cpp = tmp->u.integer;    if (GET_TYPE(STRING, "prefix")) prefix = tmp->u.string; -  if (GET_TYPE(INT, "keep_comments")) this.keep_comments = tmp->u.integer; +  if (GET_TYPE(INT, "keep_comments")) this->keep_comments = tmp->u.integer;   #undef GET_TYPE    } else if (TYPEOF(*opts_or_file) == PIKE_T_STRING) {    current_file = opts_or_file->u.string;    }    }    -  this.data = data; +  this->data = data;    add_ref(data);       if(current_file)    add_ref(current_file);    else    current_file = make_shared_string("-"); -  this.current_file = current_file; +  this->current_file = current_file;    -  this.compat_major=PIKE_MAJOR_VERSION; -  this.compat_minor=PIKE_MINOR_VERSION; -  this.compat_handler = 0; -  this.handler = handler; +  this->compat_major=PIKE_MAJOR_VERSION; +  this->compat_minor=PIKE_MINOR_VERSION; +  this->compat_handler = 0; +  this->handler = handler;    if(handler)    add_ref(handler);    -  /* Don't call free_cpp before all variables are cleared or set. */ -  SET_ONERROR(err, free_cpp, &this); -  +     if (prefix) {    int i;    if (prefix->size_shift) {
3440:    Pike_error("Invalid char in prefix.\n");    }    } -  this.prefix = prefix; +  this->prefix = prefix;    add_ref(prefix);    }   
3449:    if(TYPEOF(*charset_sv) == T_STRING) {    charset = charset_sv->u.string;    push_string(data); -  this.data = data = NULL; +  this->data = data = NULL;    ref_push_string(charset); -  if (!safe_apply_handler ("decode_charset", this.handler, -  this.compat_handler, 2, BIT_STRING)) { -  cpp_handle_exception (&this, "Error decoding with charset %S", +  if (!safe_apply_handler ("decode_charset", this->handler, +  this->compat_handler, 2, BIT_STRING)) { +  cpp_handle_exception (this, "Error decoding with charset %S",    charset);    Pike_error("Unknown charset.\n");    } -  this.data = data = Pike_sp[-1].u.string; +  this->data = data = Pike_sp[-1].u.string;    Pike_sp--;    dmalloc_touch_svalue(Pike_sp);    }
3469:    }       if(compat_major) -  cpp_change_compat(&this, compat_major, compat_minor); +  cpp_change_compat(this, compat_major, compat_minor);    -  this.picky_cpp = picky_cpp; +  this->picky_cpp = picky_cpp;       if (use_initial_predefs)    /* Typically compiling the master here. */    predefs = initial_predefs_mapping();    else { -  low_unsafe_apply_handler ("get_predefines", this.handler, -  this.compat_handler, 0); +  low_unsafe_apply_handler ("get_predefines", this->handler, +  this->compat_handler, 0);    if (!UNSAFE_IS_ZERO (Pike_sp - 1)) {    struct keypair *k;    int e, sprintf_args = 0;
3523:       if (auto_convert && (!data->size_shift) && (data->len > 1)) {    /* Try to determine if we need to recode the string */ -  struct pike_string *new_data = recode_string(&this, data); +  struct pike_string *new_data = recode_string(this, data);    free_string(data); -  this.data = data = new_data; +  this->data = data = new_data;    }    if (data->size_shift) {    /* Get rid of any byte order marks (0xfeff) */    struct pike_string *new_data = filter_bom(data);    free_string(data); -  this.data = data = new_data; +  this->data = data = new_data;    }    -  init_string_builder(&this.buf, 0); -  +     /* These attempt to be compatible with the C standard. */ -  do_magic_define(&this,"__LINE__",insert_current_line); -  do_magic_define(&this,"__FILE__",insert_current_file_as_string); -  do_magic_define(&this,"__DATE__",insert_current_date_as_string); -  do_magic_define(&this,"__TIME__",insert_current_time_as_string); +  do_magic_define(this,"__LINE__",insert_current_line); +  do_magic_define(this,"__FILE__",insert_current_file_as_string); +  do_magic_define(this,"__DATE__",insert_current_date_as_string); +  do_magic_define(this,"__TIME__",insert_current_time_as_string);       /* These are from the 201x C standard. */ -  do_magic_define(&this,"_Pragma",insert_pragma)->args = 1; -  simple_add_define(&this, "static_assert", "_Static_assert"); +  do_magic_define(this,"_Pragma",insert_pragma)->args = 1; +  simple_add_define(this, "static_assert", "_Static_assert");    -  simple_add_define(&this, "__ARGS__", "__args__"); +  simple_add_define(this, "__ARGS__", "__args__");    -  do_magic_define(&this,"__COUNTER__",insert_current_counter); +  do_magic_define(this,"__COUNTER__",insert_current_counter);       /* These are Pike extensions. */ -  do_magic_define(&this,"__DIR__",insert_current_dir_as_string); -  do_magic_define(&this,"__VERSION__",insert_current_version); -  do_magic_define(&this,"__MAJOR__",insert_current_major); -  do_magic_define(&this,"__MINOR__",insert_current_minor); +  do_magic_define(this,"__DIR__",insert_current_dir_as_string); +  do_magic_define(this,"__VERSION__",insert_current_version); +  do_magic_define(this,"__MAJOR__",insert_current_major); +  do_magic_define(this,"__MINOR__",insert_current_minor);       {   #if 0
3565:    REF_MAKE_CONST_STRING(def->first, "__attribute__(\"deprecated\", ");    def->parts[0].argument = 0;    REF_MAKE_CONST_STRING(def->parts[0].postfix, ")"); -  mapping_string_insert(this.defines, def->name, Pike_sp-1); +  mapping_string_insert(this->defines, def->name, Pike_sp-1);    pop_stack();   #endif /* 0 */    -  simple_add_define(&this, "__PIKE__", " 1 "); +  simple_add_define(this, "__PIKE__", " 1 ");    -  simple_add_define(&this, "__REAL_VERSION__", +  simple_add_define(this, "__REAL_VERSION__",    " " DEFINETOSTR(PIKE_MAJOR_VERSION) "."    DEFINETOSTR(PIKE_MINOR_VERSION) " "); -  simple_add_define(&this, "__REAL_MAJOR__", +  simple_add_define(this, "__REAL_MAJOR__",    " " DEFINETOSTR(PIKE_MAJOR_VERSION) " "); -  simple_add_define(&this, "__REAL_MINOR__", +  simple_add_define(this, "__REAL_MINOR__",    " " DEFINETOSTR(PIKE_MINOR_VERSION) " "); -  simple_add_define(&this, "__BUILD__", +  simple_add_define(this, "__BUILD__",    " " DEFINETOSTR(PIKE_BUILD_VERSION) " "); -  simple_add_define(&this, "__REAL_BUILD__", +  simple_add_define(this, "__REAL_BUILD__",    " " DEFINETOSTR(PIKE_BUILD_VERSION) " "); -  simple_add_define(&this, "__AUTO_BIGNUM__", " 1 "); +  simple_add_define(this, "__AUTO_BIGNUM__", " 1 ");   #ifdef __NT__ -  simple_add_define(&this, "__NT__", " 1 "); +  simple_add_define(this, "__NT__", " 1 ");   #endif   #ifdef __amigaos__ -  simple_add_define(&this, "__amigaos__", " 1 "); +  simple_add_define(this, "__amigaos__", " 1 ");   #endif   #ifdef __OS2__ -  simple_add_define(&this, "__OS2__", " 1 "); +  simple_add_define(this, "__OS2__", " 1 ");   #endif   #ifdef __APPLE__ -  simple_add_define(&this, "__APPLE__", " 1 "); +  simple_add_define(this, "__APPLE__", " 1 ");   #endif -  simple_add_define(&this, "SIZEOF_INT", +  simple_add_define(this, "SIZEOF_INT",    " " DEFINETOSTR(SIZEOF_INT) " "); -  simple_add_define(&this, "SIZEOF_FLOAT", +  simple_add_define(this, "SIZEOF_FLOAT",    " " DEFINETOSTR(SIZEOF_FLOAT) " ");    }   
3606:    int e;    NEW_MAPPING_LOOP (predefs->data) {    if (TYPEOF(k->val) == T_STRING) -  add_define (&this, k->ind.u.string, k->val.u.string); +  add_define (this, k->ind.u.string, k->val.u.string);    else if(TYPEOF(k->val) == T_FUNCTION || TYPEOF(k->val) == T_OBJECT)    {    struct define_struct *def;
3624:    def = alloc_empty_define(k->ind.u.string);    def->magic = insert_callback_define_no_args;    } -  mapping_string_insert(this.defines, def->name, Pike_sp-1); +  mapping_string_insert(this->defines, def->name, Pike_sp-1);    pop_stack();    }    else -  add_define (&this, k->ind.u.string, empty_pike_string); +  add_define (this, k->ind.u.string, empty_pike_string);    }    free_mapping (predefs);    }    -  string_builder_binary_strcat(&this.buf, "#line 1 ", 8); -  PUSH_STRING_SHIFT(this.current_file->str, this.current_file->len, -  this.current_file->size_shift, &this.buf); -  string_builder_putchar(&this.buf, '\n'); +  string_builder_binary_strcat(&this->buf, "#line 1 ", 8); +  PUSH_STRING_SHIFT(this->current_file->str, this->current_file->len, +  this->current_file->size_shift, &this->buf); +  string_builder_putchar(&this->buf, '\n');      #ifdef PIKE_DEBUG    SET_ONERROR(tmp, fatal_on_error, "Preprocessor exited with longjump!\n");   #endif /* PIKE_DEBUG */       -  low_cpp(&this, MKPCHARP_STR(data), data->len, +  low_cpp(this, MKPCHARP_STR(data), data->len,    0, auto_convert, charset);      #ifdef PIKE_DEBUG    UNSET_ONERROR(tmp);   #endif /* PIKE_DEBUG */    -  UNSET_ONERROR(err); -  free_cpp(&this); -  -  if(this.compile_errors) +  if(this->compile_errors)    { -  free_string_builder(&this.buf); +     throw_error_object(fast_clone_object(cpp_error_program), 0, 0, 0,    "Cpp() failed\n");    } -  else if(this.dependencies_fail) +  else if(this->dependencies_fail)    { -  free_string_builder(&this.buf); -  pop_n_elems(Pike_sp - save_sp); +     push_int(0);    }    else    { -  pop_n_elems(Pike_sp - save_sp); -  push_string(finish_string_builder(&this.buf)); +  push_string(finish_string_builder(&this->buf)); +  /* NB: Make sure the buffer isn't freed twice. */ +  this->buf.s = NULL;    } -  +  stack_pop_n_elems_keep_top((Pike_sp - save_sp) - 1);   }      /*! @module Builtin