pike.git/
src/
cpp.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2018-01-07
2018-01-07 11:11:18 by Henrik Grubbström (Grubba) <grubba@grubba.org>
7cb5e2612a43141ebf17e5f3f0c44f31746e6763 (
252
lines) (+
135
/-
117
)
[
Show
|
Annotate
]
Branch:
master
Cpp: Moved initialization of cpp state to create().
127:
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;
155:
free_string_builder(&THIS->buf); } }
-
};
+
#define FIND_DEFINE(N) find_define(this, (N))
3301:
/*! @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;
3369:
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;
3406:
} }
-
this->data = data;
-
add_ref(data);
-
+
if(current_file) add_ref(current_file); else
3439:
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 {
3464:
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();
3513:
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);
3623:
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);
3634:
low_cpp(this, MKPCHARP_STR(data), data->len,
-
0, charset);
+
0,
this->
charset);
#ifdef PIKE_DEBUG UNSET_ONERROR(tmp);