pike.git / src / cpp.cmod

version» Context lines:

pike.git/src/cpp.cmod:120:   #endif    }   }      PIKECLASS CPP   {    PIKEVAR mapping(string:object(define)) defines flags ID_PRIVATE|ID_PROTECTED;    PIKEVAR int current_line;    PIKEVAR int compile_errors;    PIKEVAR string current_file; +  PIKEVAR string charset;    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;
pike.git/src/cpp.cmod:148:    }       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_struct *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_struct *)get_storage(s->u.object, define_program);
pike.git/src/cpp.cmod:3294:    *! This define is defined when the Pike is running on Amiga OS.    */      /*! @decl constant __OS2__    *!    *! This define is defined when the Pike is running on IBM OS/2.    */      /*! @endnamespace */    - /*! @decl string cpp(string data, mapping|string|void current_file, @ -  *! int|string|void charset, object|void handler, @ -  *! void|int compat_major, void|int compat_minor, @ -  *! void|int picky_cpp) -  *! -  *! Run a string through the preprocessor. -  *! -  *! Preprocesses the string @[data] with Pike's builtin ANSI-C look-alike -  *! preprocessor. If the @[current_file] argument has not been specified, -  *! it will default to @expr{"-"@}. @[charset] defaults to @expr{"ISO-10646"@}. -  *! -  *! If the second argument is a mapping, no other arguments may follow. -  *! Instead, they have to be given as members of the mapping (if wanted). -  *! The following members are recognized: -  *! -  *! @mapping -  *! @member string "current_file" -  *! Name of the current file. It is used for generating -  *! #line directives and for locating include files. -  *! @member int|string "charset" -  *! Charset to use when processing @expr{data@}. -  *! @member object "handler" -  *! Compilation handler. -  *! @member int "compat_major" -  *! Sets the major pike version used for compat handling. -  *! @member int "compat_minor" -  *! Sets the minor pike version used for compat handling. -  *! @member int "picky_cpp" -  *! Generate more warnings. -  *! @member int "keep_comments" -  *! This option keeps @[cpp()] from removing comments. -  *! Useful in combination with the prefix feature below. -  *! @member string "prefix" -  *! If a prefix is given, only prefixed directives will be -  *! processed. For example, if the prefix is @expr{"foo"@}, then -  *! @expr{#foo_ifdef COND@} and @expr{foo___LINE__@} would be -  *! processed, @expr{#ifdef COND@} and @expr{__LINE__@} would not. -  *! @endmapping -  *! -  *! @seealso -  *! @[compile()] -  */ -  - PIKEFUN string cpp(string data, -  mapping|string|void opts_or_file, +  PIKEFUN void create(mapping|string|void opts_or_file,    int|string|void charset_sv,    object|void handler,    int|void compat_major_sv,    int|void compat_minor_sv,    int|void picky_cpp_sv) -  efun; +  flags ID_PROTECTED;    { -  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; +  struct CPP_struct *this = THIS;       struct pike_string *prefix = NULL;       struct pike_string *current_file = 0;       struct pike_string *charset = NULL;       int compat_major = compat_major_sv?compat_major_sv->u.integer:0;    int compat_minor = compat_minor_sv?compat_minor_sv->u.integer:0;    int picky_cpp = picky_cpp_sv?picky_cpp_sv->u.integer:0;    - #ifdef PIKE_DEBUG -  ONERROR tmp; - #endif /* PIKE_DEBUG */ -  -  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;    this->auto_convert = 0;       if (opts_or_file) {    if (TYPEOF(*opts_or_file) == PIKE_T_MAPPING) {
pike.git/src/cpp.cmod:3399:    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;   #undef GET_TYPE    } else if (TYPEOF(*opts_or_file) == PIKE_T_STRING) {    current_file = opts_or_file->u.string;    }    }    -  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->compat_major=PIKE_MAJOR_VERSION;    this->compat_minor=PIKE_MINOR_VERSION;    this->compat_handler = 0;    this->handler = handler;
pike.git/src/cpp.cmod:3432:    Pike_error("Invalid char in prefix.\n");    }    }    this->prefix = prefix;    add_ref(prefix);    }          if(charset_sv) {    if(TYPEOF(*charset_sv) == T_STRING) { -  charset = charset_sv->u.string; -  push_string(data); -  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", -  charset); -  Pike_error("Unknown charset.\n"); +  this->charset = charset_sv->u.string; +  add_ref(this->charset);    } -  this->data = data = Pike_sp[-1].u.string; -  Pike_sp--; -  dmalloc_touch_svalue(Pike_sp); -  } +     else if(TYPEOF(*charset_sv) == T_INT)    this->auto_convert = charset_sv->u.integer;    else {    SIMPLE_ARG_TYPE_ERROR("cpp", 3, "string|int");    }    }       if(compat_major)    cpp_change_compat(this, compat_major, compat_minor);       this->picky_cpp = picky_cpp; -  +  }    -  + } +  + /*! @decl string cpp(string data, mapping|string|void current_file, @ +  *! int|string|void charset, object|void handler, @ +  *! void|int compat_major, void|int compat_minor, @ +  *! void|int picky_cpp) +  *! +  *! Run a string through the preprocessor. +  *! +  *! Preprocesses the string @[data] with Pike's builtin ANSI-C look-alike +  *! preprocessor. If the @[current_file] argument has not been specified, +  *! it will default to @expr{"-"@}. @[charset] defaults to @expr{"ISO-10646"@}. +  *! +  *! If the second argument is a mapping, no other arguments may follow. +  *! Instead, they have to be given as members of the mapping (if wanted). +  *! The following members are recognized: +  *! +  *! @mapping +  *! @member string "current_file" +  *! Name of the current file. It is used for generating +  *! #line directives and for locating include files. +  *! @member int|string "charset" +  *! Charset to use when processing @expr{data@}. +  *! @member object "handler" +  *! Compilation handler. +  *! @member int "compat_major" +  *! Sets the major pike version used for compat handling. +  *! @member int "compat_minor" +  *! Sets the minor pike version used for compat handling. +  *! @member int "picky_cpp" +  *! Generate more warnings. +  *! @member int "keep_comments" +  *! This option keeps @[cpp()] from removing comments. +  *! Useful in combination with the prefix feature below. +  *! @member string "prefix" +  *! If a prefix is given, only prefixed directives will be +  *! processed. For example, if the prefix is @expr{"foo"@}, then +  *! @expr{#foo_ifdef COND@} and @expr{foo___LINE__@} would be +  *! processed, @expr{#ifdef COND@} and @expr{__LINE__@} would not. +  *! @endmapping +  *! +  *! @seealso +  *! @[compile()] +  */ +  + PIKEFUN string cpp(string data, +  mapping|string|void opts_or_file, +  int|string|void charset_sv, +  object|void handler, +  int|void compat_major_sv, +  int|void compat_minor_sv, +  int|void picky_cpp_sv) +  efun; + { +  struct svalue *save_sp = Pike_sp - args; +  struct object *cpp_obj = clone_object(CPP_program, args-1); +  struct CPP_struct *this = +  (struct CPP_struct *)get_storage(cpp_obj, CPP_program); +  struct mapping *predefs = NULL; +  + #ifdef PIKE_DEBUG +  ONERROR tmp; + #endif /* PIKE_DEBUG */ +  +  push_object(cpp_obj); +     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);    if (!UNSAFE_IS_ZERO (Pike_sp - 1)) {    struct keypair *k;    int e, sprintf_args = 0;    if (TYPEOF(Pike_sp[-1]) != T_MAPPING) {
pike.git/src/cpp.cmod:3506:    }    if (!predefs) {    predef_map_error:    f_sprintf (sprintf_args);    Pike_error("%S", Pike_sp[-1].u.string);    }    }    pop_stack();    }    -  if (this->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); -  free_string(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; -  } -  +     /* 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);       /* These are from the 201x C standard. */    do_magic_define(this,"_Pragma",insert_pragma)->args = 1;    simple_add_define(this, "static_assert", "_Static_assert");   
pike.git/src/cpp.cmod:3616:    }    mapping_string_insert(this->defines, def->name, Pike_sp-1);    pop_stack();    }    else    add_define (this, k->ind.u.string, empty_pike_string);    }    free_mapping (predefs);    }    +  this->data = data; +  add_ref(data); +  +  if (this->charset) { +  push_string(data); +  this->data = data = NULL; +  ref_push_string(this->charset); +  if (!safe_apply_handler ("decode_charset", this->handler, +  this->compat_handler, 2, BIT_STRING)) { +  cpp_handle_exception (this, "Error decoding with charset %S", +  THIS->charset); +  Pike_error("Unknown charset.\n"); +  } +  this->data = data = Pike_sp[-1].u.string; +  Pike_sp--; +  dmalloc_touch_svalue(Pike_sp); +  } +  +  if (this->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); +  free_string(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; +  } +     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, -  0, charset); +  0, this->charset);      #ifdef PIKE_DEBUG    UNSET_ONERROR(tmp);   #endif /* PIKE_DEBUG */       if(this->compile_errors)    {    throw_error_object(fast_clone_object(cpp_error_program), 0, 0, 0,    "Cpp() failed\n");    }