pike.git / src / cpp.cmod

version» Context lines:

pike.git/src/cpp.cmod:102:      struct define   {    struct hash_entry link; /* must be first */    magic_define_fun magic;    int args;    ptrdiff_t num_parts;    short inside; /* 1 - Don't expand. 2 - In use. */    short varargs;    struct pike_string *first; -  struct define_part parts[1]; +  struct define_part *parts;   };    - #define FIND_DEFINE(N) \ -  (this->defines?BASEOF(hash_lookup(this->defines, N), define, link):0) + static void init_define_struct(struct object *UNUSED(o)) + { +  struct define *def = (struct define *)(Pike_fp->current_storage); +  def->magic=0; +  def->args=-1; +  def->inside=0; +  def->varargs=0; +  def->parts = NULL; +  def->num_parts=0; +  def->first=0; +  def->link.s = NULL; + }    -  + static void exit_define_struct(struct object *UNUSED(o)) + { +  struct define *d = (struct define *)(Pike_fp->current_storage); +  INT32 e; +  for (e = 0; e < d->num_parts; e++) +  free_string(d->parts[e].postfix); +  if (d->parts) +  free(d->parts); +  if (d->link.s) +  free_string(d->link.s); +  if(d->first) +  free_string(d->first); + } +  + static struct program *define_program = NULL; +    struct cpp   { -  struct hash_table *defines; +  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;   };    -  + #define FIND_DEFINE(N) find_define(this, (N)) +  + static struct define *find_define(struct cpp *this, struct pike_string *n) + { +  struct svalue *s; +  if (!this->defines) return NULL; +  if (!(s = low_mapping_string_lookup(this->defines, n))) return NULL; +  if (TYPEOF(*s) != T_OBJECT) return NULL; +  return (struct define *)get_storage(s->u.object, define_program); + } +    DECLARE_STORAGE;      static void cpp_error(struct cpp *this, const char *err) ATTRIBUTE((noinline));   static void cpp_error_vsprintf (struct cpp *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,    const char *cpp_error_fmt, ...) ATTRIBUTE((noinline));   static void cpp_warning(struct cpp *this, const char *cpp_warn_fmt, ...) ATTRIBUTE((noinline));   struct define *defined_macro =0; -  + static struct svalue defined_macro_sval;      static void cpp_error(struct cpp *this, const char *err)   {    this->compile_errors++;    if(this->compile_errors > 10) return;    if((this->handler && this->handler->prog) || get_master())    {    ref_push_string(this->current_file);    push_int(this->current_line);    push_text(err);
pike.git/src/cpp.cmod:1539:   past_identifier:    if (p != *pos) {    *pos = p;    return finish_string_builder (&sb);    }    free_string_builder (&sb);    return NULL;   }      /* devours one reference to 'name'! */ + /* The reference to the define is held by the stack on return. */   static struct define *alloc_empty_define(struct pike_string *name,    ptrdiff_t parts)   {    struct define *def; -  def=xalloc(sizeof(struct define)+ -  sizeof(struct define_part) * (parts -1)); -  def->magic=0; -  def->args=-1; -  def->inside=0; -  def->varargs=0; -  def->num_parts=parts; -  def->first=0; +  struct object *o; +  +  push_object(o = clone_object(define_program, 0)); +  def = (struct define *)get_storage(o, define_program);    def->link.s=name;    debug_malloc_touch(name); -  +  if (parts) { +  def->parts = xalloc(sizeof(struct define_part) * parts); +  def->num_parts = parts; +  }    return def;   }      /*! @directive #undef    *! @directive #undefine    *!    *! This removes the effect of a @[#define], all subsequent occurances of    *! the undefined identifier will not be replaced by anything.    *!    *! @note
pike.git/src/cpp.cmod:1575:    *!    *! @example    *! // Strip debug    *! #define werror(X ...) 0    *! #include "/home/someone/experimental/stuff.h"    *! #undef werror    *!    *! @seealso    *! @[#define], @[defined()]    */ - static void undefine(struct cpp *this, -  const struct pike_string *name) + static void undefine(struct cpp *this, struct pike_string *name)   { -  INT32 e; -  struct define *d; +  ref_push_string(name); +  push_int(0); +  map_delete_no_free(this->defines, Pike_sp - 2, Pike_sp - 1);    -  d=FIND_DEFINE(name); -  -  if(!d) return; -  -  if (d->inside) { +  if (TYPEOF(Pike_sp[-1]) == PIKE_T_OBJECT) { +  struct object *o = Pike_sp[-1].u.object; +  struct define *def = (struct define *)get_storage(o, define_program); +  if (def->inside) { +  /* Restore the #define. */ +  mapping_insert(this->defines, Pike_sp - 2, Pike_sp - 1);    cpp_error(this, "Illegal to undefine a macro during its expansion."); -  +  pop_n_elems(2);    return;    } -  +  }    -  this->defines=hash_unlink(this->defines, & d->link); -  -  for(e=0;e<d->num_parts;e++) -  free_string(d->parts[e].postfix); -  free_string(d->link.s); -  if(d->first) -  free_string(d->first); -  free(d); +  pop_n_elems(2);   }      /*! @directive #define    *!    *! This directive is used to define or redefine a cpp macro.    *!    *! The simplest way to use define is to write    *!    *! @code    *! #define @b{@i{<identifier>@}@} @i{<replacement string>@}
pike.git/src/cpp.cmod:1645:       init_string_builder(&s, 0);    string_builder_append(&s, MKPCHARP_STR(this->prefix),    this->prefix->len);    string_builder_putchar(&s, '_');    string_builder_binary_strcat(&s, name, len);    def = alloc_empty_define(finish_string_builder(&s),0);    } else    def = alloc_empty_define(make_shared_string(name),0);    def->magic=fun; -  this->defines=hash_insert(this->defines, & def->link); +  mapping_string_insert(this->defines, def->link.s, Pike_sp-1); +  pop_stack();       return def;   }      static void add_define(struct cpp *this,    struct pike_string *name,    struct pike_string *what)   {    struct define* def;    add_ref (name);    def=alloc_empty_define(name,0);    add_ref (def->first = what); -  this->defines=hash_insert(this->defines, & def->link); +  mapping_string_insert(this->defines, def->link.s, Pike_sp-1); +  pop_stack();   }      static void simple_add_define(struct cpp *this,    const char *name,    const char *what)   {    struct define* def;       if (this->prefix) {    struct string_builder s;
pike.git/src/cpp.cmod:1681:    init_string_builder(&s, 0);    string_builder_append(&s, MKPCHARP_STR(this->prefix),    this->prefix->len);    string_builder_putchar(&s, '_');    string_builder_binary_strcat(&s, name, len);    def = alloc_empty_define(finish_string_builder(&s),0);    } else    def = alloc_empty_define(make_shared_string(name),0);       def->first=make_shared_string(what); -  this->defines=hash_insert(this->defines, & def->link); +  mapping_string_insert(this->defines, def->link.s, Pike_sp-1); +  pop_stack();   }      static struct pike_string *recode_string(struct cpp *this, struct pike_string *data)   {    /* Observations:    *    * * At least a prefix of two bytes need to be 7bit in a valid    * Pike program.    *    * * NUL isn't valid in a Pike program.
pike.git/src/cpp.cmod:1969:    free_string(data);    data = finish_string_builder(&buf);    } else {    /* String didn't contain 0xfeff */    free_string_builder(&buf);    }    }    return(data);   }    - static 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(d); - } -  +    #define PUSH_STRING0(X,Y,Z) add_quoted_string( X,Y,0,Z)   #define PUSH_STRING_SHIFT(X,Y,Z,A) add_quoted_string(X,Y,Z,A)   #define WC_ISSPACE wide_isspace   #define WC_ISIDCHAR wide_isidchar   /*    * Generic macros    */      #define CHECK_WORD(X,LEN) (begins_with(X,ADD_PCHARP(data,pos),(LEN),len-pos,1))   #define GOBBLE_WORD(X) (CHECK_WORD(X,NELEM(X)) ? (pos+=NELEM(X)),1 : 0)
pike.git/src/cpp.cmod:3216:    *! @endmapping    *!    *! @seealso    *! @[compile()]    */      /* Doesn't free string_builder buf! */   static void free_cpp(struct cpp *this)   {    if(this->defines) -  free_hashtable(this->defines, free_one_define); +  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) {
pike.git/src/cpp.cmod:3271:    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=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;    struct mapping *m = opts_or_file->u.mapping;      #define GET_TYPE(type, name) ((tmp = simple_mapping_string_lookup(m, name)) \    && (TYPEOF(*(tmp)) == PIKE_T_##type || (Pike_error("Expected type %s,"\
pike.git/src/cpp.cmod:3450:       {   #if 0    /* Left in place for documentation reference purposes. */    struct define *def =    alloc_empty_define(make_shared_string("__deprecated__"), 1);    def->args = 1;    REF_MAKE_CONST_STRING(def->first, "__attribute__(\"deprecated\", ");    def->parts[0].argument = 0;    REF_MAKE_CONST_STRING(def->parts[0].postfix, ")"); -  this.defines = hash_insert(this.defines, &def->link); +  mapping_string_insert(this.defines, def->link.s, Pike_sp-1); +  pop_stack();   #endif /* 0 */       simple_add_define(&this, "__PIKE__", " 1 ");       simple_add_define(&this, "__REAL_VERSION__",    " " DEFINETOSTR(PIKE_MAJOR_VERSION) "."    DEFINETOSTR(PIKE_MINOR_VERSION) " ");    simple_add_define(&this, "__REAL_MAJOR__",    " " DEFINETOSTR(PIKE_MAJOR_VERSION) " ");    simple_add_define(&this, "__REAL_MINOR__",
pike.git/src/cpp.cmod:3508:    def->magic = insert_callback_define;    def->varargs=1;    def->args=1;    }    else    {    def = alloc_empty_define( k->ind.u.string, 0 );    k->ind.u.string->refs++;    def->magic = insert_callback_define_no_args;    } -  this.defines = hash_insert( this.defines, &def->link ); +  mapping_string_insert(this.defines, def->link.s, Pike_sp-1); +  pop_stack();    }    else    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);
pike.git/src/cpp.cmod:3587:    else Pike_error ("Initial predefines already taken over.\n");   }      /*! @endmodule    */      void init_cpp()   {    struct svalue s;    +  start_new_program(); +  ADD_STORAGE(struct define); +  set_init_callback(init_define_struct); +  set_exit_callback(exit_define_struct); +  define_program = end_program(); +     defined_macro=alloc_empty_define(make_shared_string("defined"),0);    defined_macro->magic=check_defined;    defined_macro->args=1; -  +  defined_macro_sval = Pike_sp[-1]; +  Pike_sp--;       efun_str = make_shared_string ("efun");    constant_str = make_shared_string ("constant");    defined_str = make_shared_string ("defined");       use_initial_predefs = 1;       INIT;       ADD_INT_CONSTANT("__HAVE_CPP_PREFIX_SUPPORT__", 1, 0);
pike.git/src/cpp.cmod:3653:       EXIT;       while((tmp=first_predef))    {    free(tmp->name);    free(tmp->value);    first_predef=tmp->next;    free(tmp);    } -  free_string(defined_macro->link.s); -  free(defined_macro); +  free_svalue(&defined_macro_sval);       free_string (efun_str);    free_string (constant_str);    free_string (defined_str); -  +  +  free_program(define_program);   #endif   }