9506a1 | 2016-08-20 | Martin Nilsson | | /* -*- mode: c; encoding: utf-8; -*-
|
e576bb | 2002-10-11 | Martin Nilsson | | || This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "stralloc.h"
#include "module_support.h"
#include "interpret.h"
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #include "svalue.h"
#include "pike_macros.h"
#include "program.h"
|
142073 | 2017-02-08 | Henrik Grubbström (Grubba) | | #include "pike_compiler.h"
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #include "object.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #include "array.h"
#include "mapping.h"
#include "builtin_functions.h"
#include "operators.h"
#include "constants.h"
#include "time.h"
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | #include "version.h"
|
a0180b | 2003-11-14 | Martin Stjernholm | | #include "pike_types.h"
|
b964fd | 2004-04-16 | Martin Stjernholm | | #include "cpp.h"
|
bdd37a | 2004-11-02 | Martin Stjernholm | | #include "lex.h"
|
9d1f54 | 2017-01-25 | Henrik Grubbström (Grubba) | | #include "sprintf.h"
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | #include "pike_compiler.h"
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #include <ctype.h>
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | #define DEFAULT_CMOD_STORAGE
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | #define CPP_NO_OUTPUT 1 /* Inside false section of #if/#else */
#define CPP_EXPECT_ELSE 2 /* Expect #else/#elif/#elseif. */
#define CPP_EXPECT_ENDIF 4 /* Expect #endif */
#define CPP_REALLY_NO_OUTPUT 8 /* Entire preprocessor is in false section. */
#define CPP_END_AT_NEWLINE 16 /* Halt at end of line. */
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #define CPP_DO_IF 32
|
0d52dd | 1998-01-16 | Fredrik Hübinette (Hubbe) | | #define CPP_NO_EXPAND 64
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
#define OUTP() (!(flags & (CPP_NO_OUTPUT | CPP_REALLY_NO_OUTPUT)))
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | #define PUTNL() string_builder_putchar(&this->buf, '\n')
|
74966e | 2014-05-12 | Per Hedbor | | #define GOBBLE(X) (INDEX_PCHARP(data,pos)==(X)?++pos,1:0)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #define PUTC(C) do { \
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | int c_=(C); if(OUTP() || c_=='\n') string_builder_putchar(&this->buf, c_); }while(0)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
#define MAX_ARGS 255
#define DEF_ARG_STRINGIFY 0x100000
#define DEF_ARG_NOPRESPACE 0x200000
#define DEF_ARG_NOPOSTSPACE 0x400000
|
9b52e5 | 2011-10-24 | Tobias S. Josefowitz | | #define DEF_ARG_NEED_COMMA 0x800000
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #define DEF_ARG_MASK 0x0fffff
|
58efb8 | 2014-05-12 | Per Hedbor | | #ifdef __GNUC__
#pragma GCC optimize "-Os"
#endif
|
7050b7 | 2014-02-25 | Per Hedbor | |
/* Return true if compat version is equal or less than MAJOR.MINOR */
#define CPP_TEST_COMPAT(THIS,MAJOR,MINOR) \
(THIS->compat_major < (MAJOR) || \
(THIS->compat_major == (MAJOR) && \
THIS->compat_minor <= (MINOR)))
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | #if 0
#define CALC_DUMPPOS(X) DUMPPOS(X)
#else /* !0 */
#define CALC_DUMPPOS(X)
#endif /* 0 */
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
516482 | 2004-11-14 | Martin Stjernholm | | static struct pike_string *efun_str;
static struct pike_string *constant_str;
static struct pike_string *defined_str;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct pike_predef_s
{
struct pike_predef_s *next;
char *name;
char *value;
};
|
b584b1 | 2001-12-20 | Martin Stjernholm | | static int use_initial_predefs;
|
1f7c5c | 2018-07-20 | Henrik Grubbström (Grubba) | | static struct mapping *initial_predefs_mapping(void);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | static struct pike_predef_s *first_predef = NULL, *last_predef = NULL;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct define_argument {
|
2dc009 | 1999-02-27 | Henrik Grubbström (Grubba) | | PCHARP arg;
|
f49e47 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t len;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | };
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | struct CPP_struct;
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct;
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | typedef void (*magic_define_fun)(struct object *,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *,
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *,
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | struct string_builder *);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | DECLARATIONS;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
7db6bc | 2016-09-08 | Henrik Grubbström (Grubba) | | #define CPP_MACRO_DISABLED 1 /* Don't expand. */
#define CPP_MACRO_IN_USE 2 /* In use. */
|
347b10 | 2018-04-19 | Henrik Grubbström (Grubba) | | #define CPP_MACRO_VARARGS 4 /* Varargs. */
|
d5ccb9 | 2018-08-19 | Henrik Grubbström (Grubba) | | #define CPP_MACRO_KEEP_NL 8 /* Keep newlines. */
|
7db6bc | 2016-09-08 | Henrik Grubbström (Grubba) | |
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | /*! @class CompilerEnvironment
*/
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | /* Consider
*
* class Preprocessor
* {
* class Macro
* {
* }
*
* mapping(string:Macro) macros;
*
* class Context
* {
* inherit String.Buffer;
*
* string current_file;
* int current_line;
*
* string directive_*(...);
*
* void cpp(string data);
*
* Context clone();
* }
* }
*
* string cpp(...)
* {
* Preprocessor p = Preprocessor();
* p->init();
* Preprocessor.Context ctx = p->Context();
* ctx->cpp(data);
* return ctx->get();
* }
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_pragma(struct object *cpp_obj,
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | struct define_struct *def,
struct pike_string *arg,
struct string_builder *tmp);
/*! @class define
*/
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | PIKECLASS define
{
|
279a4f | 2016-09-03 | Henrik Grubbström (Grubba) | | PIKEVAR string name flags ID_PRIVATE|ID_PROTECTED;
|
7a6120 | 2016-09-04 | Henrik Grubbström (Grubba) | | PIKEVAR array(string|int) parts flags ID_PRIVATE|ID_PROTECTED;
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | CVAR magic_define_fun magic;
CVAR int args;
|
7db6bc | 2016-09-08 | Henrik Grubbström (Grubba) | | CVAR short flags; /* CPP_MACRO_* */
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | |
|
2e060f | 2018-04-04 | Henrik Grubbström (Grubba) | | CVAR struct svalue self;
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | DECLARE_STORAGE;
|
f8a633 | 2016-09-02 | Henrik Grubbström (Grubba) | | INIT
{
|
b46752 | 2017-06-25 | Martin Nilsson | | struct define_struct *def = (struct define_struct *)CURRENT_STORAGE;
|
2e060f | 2018-04-04 | Henrik Grubbström (Grubba) | | /* NB: NO reference for def->self! */
SET_SVAL(def->self, T_OBJECT,
Pike_fp->context - Pike_fp->current_program->inherits,
object, Pike_fp->current_object);
|
f8a633 | 2016-09-02 | Henrik Grubbström (Grubba) | | def->args=-1;
|
b46752 | 2017-06-25 | Martin Nilsson | | #ifdef PIKE_NULL_IS_SPECIAL
def->magic=0;
|
7db6bc | 2016-09-08 | Henrik Grubbström (Grubba) | | def->flags = 0;
|
b46752 | 2017-06-25 | Martin Nilsson | | #endif
|
f8a633 | 2016-09-02 | Henrik Grubbström (Grubba) | | }
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
PIKEFUN void create(string name, int num_args,
array(string|int|function(mixed|void...:string)) parts)
flags ID_PROTECTED;
{
if (THIS->name) free_string(THIS->name);
add_ref(THIS->name = name);
/* FIXME: Validate the arguments. */
THIS->args = num_args;
THIS->flags = 0;
if (THIS->parts) {
free_array(THIS->parts);
}
add_ref(THIS->parts = parts);
}
#ifndef tObjImpl_CPP
#define tObjImpl_CPP tObj
#endif
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | /*! @decl string `()(array(string)|void arguments, CPP|void context, @
*! int|void flags)
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | *!
*! @param arguments
*! Array of arguments to the macro. Zero if no parenthesis.
*!
*! @param context
*! CPP context we are evaluating in.
*!
*! @returns
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | *! Returns the expansion of the macro on success, and @expr{0@} (zero)
*! on failure (typically due to invalid @[arguments]).
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | */
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | | PIKEFUN string `()(array(string)|void arguments, object(CPP)|void context_obj,
int|void flags_sval)
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | flags ID_PROTECTED;
{
struct define_struct *d = THIS;
struct string_builder s;
|
dda7cc | 2018-08-15 | Henrik Grubbström (Grubba) | | struct array *arguments2 = arguments;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | struct array *parts = THIS->parts;
INT32 i;
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | | INT_TYPE flags = flags_sval?flags_sval->u.integer:0;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
d05262 | 2018-08-24 | Henrik Grubbström (Grubba) | | if (d->args >= 0) {
if (!arguments) {
ref_push_array(&empty_array);
arguments = arguments2 = &empty_array;
if ((!d->args) ||
((d->flags & CPP_MACRO_VARARGS) && (d->args == 1))) {
/* NB: In the varargs case arguments2 will get
* further adjustment below.
*/
} else {
if (context_obj) {
push_text("Expected %d arguments to macro %s, got none.");
push_int(d->args);
ref_push_string(d->name);
apply(context_obj, "cpp_error", 3);
} else {
my_yyerror("Expected %d argumnets to macro %S, got none.",
d->args, d->name);
}
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | push_int(0);
return;
|
d05262 | 2018-08-24 | Henrik Grubbström (Grubba) | | }
}
if (d->args != arguments2->size) {
if (!(d->flags & CPP_MACRO_VARARGS) ||
(d->args > arguments2->size+1)) {
/* Allow varargs to be left out. */
if (context_obj) {
push_text("Bad number of arguments to macro %s, expected %d"
", got %d.");
ref_push_string(d->name);
push_int(d->args);
push_int(arguments2->size);
apply(context_obj, "cpp_error", 4);
} else {
my_yyerror("Bad number of arguments to macro %S, expected %d"
", got %d.",
d->name, d->args, arguments2->size);
}
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | push_int(0);
return;
|
d05262 | 2018-08-24 | Henrik Grubbström (Grubba) | | }
if (d->args > arguments2->size) {
/* Grow arguments2 to at least d->args elements. */
ref_push_array(arguments2);
ref_push_string(empty_pike_string);
f_aggregate(1);
push_int(d->args - arguments2->size);
o_multiply();
f_add(2);
arguments2 = Pike_sp[-1].u.array;
} else if ((d->flags & CPP_MACRO_VARARGS) &&
(arguments2->size > d->args)) {
/* Join all the varargs with commas. */
push_array(slice_array(arguments2, 0, d->args-1));
push_array(slice_array(arguments2, d->args-1, arguments2->size));
push_text(",");
o_multiply();
f_aggregate(1);
f_add(2);
arguments2 = Pike_sp[-1].u.array;
}
}
}
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | init_string_builder(&s, 0);
if(d->magic)
{
struct pike_string *a = NULL;
|
d05262 | 2018-08-24 | Henrik Grubbström (Grubba) | | if (arguments2 && (d->args > 0)) {
a = ITEM(arguments2)[0].u.string;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | d->magic(context_obj, d, a, &s);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
bb5566 | 2018-08-22 | Henrik Grubbström (Grubba) | | goto done;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
for (i = 0; i < parts->size; i++) {
struct svalue *sval = &parts->item[i];
switch (TYPEOF(*sval)) {
case PIKE_T_STRING:
string_builder_shared_strcat(&s, sval->u.string);
break;
case PIKE_T_INT:
{
int raw_arg = sval->u.integer;
int arg = raw_arg & DEF_ARG_MASK;
struct pike_string *str;
|
dda7cc | 2018-08-15 | Henrik Grubbström (Grubba) | | if (!arguments2 || (arg >= arguments2->size)) {
|
d9432a | 2018-08-23 | Henrik Grubbström (Grubba) | | if (context_obj) {
push_text("Too few arguments to macro %s.");
ref_push_string(d->name);
safe_apply(context_obj, "cpp_error", 2);
pop_stack();
} else {
my_yyerror("Too few arguments to macro %S.", d->name);
}
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | free_string_builder(&s);
push_int(0);
return;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
|
dda7cc | 2018-08-15 | Henrik Grubbström (Grubba) | | str = arguments2->item[arg].u.string;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | if (raw_arg & DEF_ARG_NEED_COMMA) {
|
347b10 | 2018-04-19 | Henrik Grubbström (Grubba) | | if (!(d->flags & CPP_MACRO_VARARGS) ||
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | (arg != d->args-1) ||
str->len) {
/* Don't add the comma if the varargs argument and empty. */
string_builder_putchar(&s, ',');
string_builder_putchar(&s, ' ');
}
}
if (!(raw_arg & DEF_ARG_NOPRESPACE)) {
string_builder_putchar(&s, ' ');
}
if (raw_arg & DEF_ARG_STRINGIFY) {
string_builder_putchar(&s, '\"');
string_builder_quote_string(&s, str, 0, 0x7fffffff,
|
397d78 | 2018-04-09 | Henrik Grubbström (Grubba) | | QUOTE_NO_STRING_CONCAT|
QUOTE_NORMALIZE_WS|
QUOTE_TOKENIZE);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | string_builder_putchar(&s, '\"');
} else {
if (raw_arg & (DEF_ARG_NOPRESPACE|DEF_ARG_NOPOSTSPACE)) {
PCHARP a = MKPCHARP_STR(str);
ptrdiff_t len = str->len;
if (raw_arg & DEF_ARG_NOPRESPACE) {
while(len && wide_isspace(EXTRACT_PCHARP(a))) {
INC_PCHARP(a, 1);
len--;
}
}
if (raw_arg & DEF_ARG_NOPOSTSPACE) {
while(len && wide_isspace(INDEX_PCHARP(a, len-1))) {
len--;
}
}
string_builder_append(&s, a, len);
} else {
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | | /* NB: Evaluate the argument before insertion. */
int save_flags = d->flags;
|
52791d | 2018-04-15 | Henrik Grubbström (Grubba) | | d->flags |= CPP_MACRO_IN_USE;
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | |
|
750994 | 2018-08-10 | Henrik Grubbström (Grubba) | | if (context_obj) {
ref_push_string(str);
push_int(flags & ~(CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE));
safe_apply(context_obj, "cpp", 2);
string_builder_shared_strcat(&s, Pike_sp[-1].u.string);
pop_stack();
} else {
string_builder_shared_strcat(&s, str);
}
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | |
d->flags = save_flags;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
}
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | | if (!(raw_arg & DEF_ARG_NOPOSTSPACE)) {
string_builder_putchar(&s, ' ');
}
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
break;
default:
/* FIXME: Check that we have a callable. */
if (arguments) {
|
3688c9 | 2018-08-21 | Henrik Grubbström (Grubba) | | add_ref(arguments);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | push_array_items(arguments);
|
3688c9 | 2018-08-21 | Henrik Grubbström (Grubba) | | safe_apply_svalue(sval, arguments->size, 1);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | } else {
|
3688c9 | 2018-08-21 | Henrik Grubbström (Grubba) | | safe_apply_svalue(sval, 0, 1);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
if (TYPEOF(Pike_sp[-1]) != T_STRING) {
|
d9432a | 2018-08-23 | Henrik Grubbström (Grubba) | | if (context_obj) {
push_text("Invalid return value from macro %s: %s (expected string).");
ref_push_string(d->name);
push_text(get_name_of_type(TYPEOF(Pike_sp[-3])));
safe_apply(context_obj, "cpp_error", 3);
} else {
my_yyerror("Invalid return value from macro %S: %s (expected string).",
d->name, get_name_of_type(TYPEOF(Pike_sp[-1])));
}
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | free_string_builder(&s);
push_int(0);
return;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
string_builder_shared_strcat(&s, Pike_sp[-1].u.string);
pop_stack();
break;
}
}
|
bb5566 | 2018-08-22 | Henrik Grubbström (Grubba) | | done:
if (!(d->flags & CPP_MACRO_KEEP_NL)) {
/* Remove any newlines from the completed expression. */
for(i=0; i< (ptrdiff_t)s.s->len; i++)
if(index_shared_string(s.s, i) == '\n')
SET_INDEX_CHARP(s.s->str, i, s.s->size_shift, ' ');
}
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
pop_n_elems(args);
push_string(finish_string_builder(&s));
}
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | }
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | /*! @endclass define
*/
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
1f7c5c | 2018-07-20 | Henrik Grubbström (Grubba) | | PIKEFUN mapping(string:string|function|object) get_predefines()
{
if (use_initial_predefs) {
push_mapping(initial_predefs_mapping());
} else {
APPLY_MASTER("get_predefines", 0);
}
}
|
0732a5 | 2018-03-30 | Henrik Grubbström (Grubba) | | /*! @class CPP
*!
*! The state for an instance of the preprocessor.
*!
*! @seealso
*! @[predef::cpp()]
*/
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | PIKECLASS CPP
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | program_flags PROGRAM_USES_PARENT|PROGRAM_NEEDS_PARENT;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | PIKEVAR mapping(string:object(define)) defines flags ID_PRIVATE|ID_PROTECTED;
PIKEVAR int current_line;
PIKEVAR int compile_errors;
PIKEVAR string current_file;
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | PIKEVAR string charset;
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | CVAR struct string_builder buf;
PIKEVAR object handler;
PIKEVAR object compat_handler;
PIKEVAR int compat_major;
PIKEVAR int compat_minor;
PIKEVAR string prefix;
PIKEVAR int picky_cpp;
PIKEVAR int keep_comments;
PIKEVAR int dependencies_fail;
|
e19aca | 2018-01-06 | Henrik Grubbström (Grubba) | | PIKEVAR int auto_convert;
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | |
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | | PIKEVAR mapping(string:function(string:string)) directives flags ID_PROTECTED;
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | INIT
{
init_string_builder(&THIS->buf, 0);
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | THIS->current_line = 1;
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | }
EXIT
{
/* NOTE: Most of the fields are mapped, and thus freed automatically. */
if (THIS->buf.s) {
free_string_builder(&THIS->buf);
}
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
350169 | 2018-03-31 | Henrik Grubbström (Grubba) | | PIKEFUN string _sprintf(int c, mapping|void opts)
flags ID_PROTECTED;
{
struct CPP_struct *this = THIS;
ref_push_string(MK_STRING("CPP(%s:%d)"));
if (this->current_file) {
ref_push_string(this->current_file);
} else {
ref_push_string(MK_STRING("-"));
}
push_int(this->current_line);
f_sprintf(2);
}
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | #define FIND_DEFINE(N) find_define(this, (N))
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static struct define_struct *find_define(struct CPP_struct *this, struct pike_string *n)
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | {
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;
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | return (struct define_struct *)get_storage(s->u.object, define_program);
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | }
|
f6abaa | 2018-02-27 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
ptrdiff_t tmp, int flags);
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | |
/*! @decl void report(SeverityLevel severity, @
*! string filename, int(1..) linenumber, @
*! string subsystem, @
*! string message, mixed ... extra_args)
*!
*! Report a diagnostic from the preprocessor.
*!
*! @param severity
*! The severity of the diagnostic.
*!
*! @param filename
*! @param linenumber
*! Location which triggered the diagnostic.
*!
*! @param subsystem
*! Always @expr{"cpp"@}.
*!
*! @param message
|
2d9630 | 2018-08-09 | Henrik Grubbström (Grubba) | | *! String with the diagnostic message, with optional
*! @[sprintf()]-style formatting (if any @[extra_args]).
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | *!
*! @param extra_args
*! Extra arguments to @[sprintf()].
*!
|
2d9630 | 2018-08-09 | Henrik Grubbström (Grubba) | | *! The default implementation just calls
*! @[CompilerEnviroment::report()] in the parent with the
*! same arguments.
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
398ee9 | 2018-08-17 | Henrik Grubbström (Grubba) | | *! @[Reporter()->report()], @[cpp_error()]
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | */
PIKEFUN void report(int(0..3) severity,
string filename, int(1..) linenumber,
string subsystem,
string message, mixed ... extra_args)
{
|
2d9630 | 2018-08-09 | Henrik Grubbström (Grubba) | | /* Call the report() in our parent. */
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | apply_external(1, CE_REPORT_FUN_NUM, args);
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | }
static void cpp_report_vsprintf(struct CPP_struct *this, int severity,
const char *fmt, va_list args)
ATTRIBUTE((noinline));
static void cpp_report(struct CPP_struct *this, int severity,
const char *fmt, ...)
ATTRIBUTE((noinline));
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_error(struct CPP_struct *this, const char *err) ATTRIBUTE((noinline));
static void cpp_error_sprintf(struct CPP_struct *this, const char *fmt, ...) ATTRIBUTE((noinline));
static void cpp_handle_exception(struct CPP_struct *this,
|
1ebec6 | 2014-05-13 | Martin Nilsson | | const char *cpp_error_fmt, ...) ATTRIBUTE((noinline));
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_warning(struct CPP_struct *this, const char *cpp_warn_fmt, ...) ATTRIBUTE((noinline));
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *defined_macro = NULL;
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | static struct svalue defined_macro_sval;
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | |
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | static void cpp_report_vsprintf(struct CPP_struct *this, int severity,
const char *fmt, va_list args)
|
9036e8 | 2001-08-16 | Martin Stjernholm | | {
|
b20284 | 2007-10-22 | Henrik Grubbström (Grubba) | | struct string_builder s;
struct pike_string *msg;
|
32118f | 2018-06-30 | Henrik Grubbström (Grubba) | | if (severity >= REPORT_ERROR) {
/* NB: This increment is here (and not in report()), to allow
* for overloading of report() with code that doesn't always
* call the above implementation. This increment is not
* optional as there is code that depends on it to detect
* whether other code has failed (eg macro expansion).
*/
this->compile_errors++;
}
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | push_int(severity);
ref_push_string(this->current_file);
push_int(this->current_line);
push_constant_text("cpp");
|
b20284 | 2007-10-22 | Henrik Grubbström (Grubba) | |
init_string_builder(&s, 0);
string_builder_vsprintf(&s, fmt, args);
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | push_string(finish_string_builder(&s));
|
b20284 | 2007-10-22 | Henrik Grubbström (Grubba) | |
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | safe_apply_current(f_CPP_report_fun_num, 5);
pop_stack();
}
|
b20284 | 2007-10-22 | Henrik Grubbström (Grubba) | |
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | static void cpp_report(struct CPP_struct *this, int severity,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
cpp_report_vsprintf(this, severity, fmt, args);
va_end(args);
}
|
b20284 | 2007-10-22 | Henrik Grubbström (Grubba) | |
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | static void cpp_error(struct CPP_struct *this, const char *err)
{
cpp_report(this, REPORT_ERROR, "%s", err);
|
37338b | 2003-11-14 | Martin Stjernholm | | }
|
9036e8 | 2001-08-16 | Martin Stjernholm | |
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_error_sprintf(struct CPP_struct *this, const char *fmt, ...)
|
37338b | 2003-11-14 | Martin Stjernholm | | {
va_list args;
|
9036e8 | 2001-08-16 | Martin Stjernholm | | va_start(args,fmt);
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | cpp_report_vsprintf(this, REPORT_ERROR, fmt, args);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | va_end(args);
}
|
398ee9 | 2018-08-17 | Henrik Grubbström (Grubba) | | /*! @decl void cpp_error(sprintf_format msg, sprintf_args ... arguments)
*!
*! Convenience function for reporting a cpp error at
*! the current position.
*!
*! This function calls @[report()] with the same arguments,
*! but prefixed with suitable defaults.
*!
*! @seealso
*! @[report()]
*/
PIKEFUN void cpp_error(sprintf_format msg, sprintf_args ... arguments)
{
struct CPP_struct *this = THIS;
struct svalue *first_arg = Pike_sp-args;
INT32 i;
|
d62f96 | 2018-08-27 | Henrik Grubbström (Grubba) | | this->compile_errors++;
|
398ee9 | 2018-08-17 | Henrik Grubbström (Grubba) | | push_int(REPORT_ERROR);
ref_push_string(this->current_file);
push_int(this->current_line);
push_constant_text("cpp");
for (i = 0; i < args; i++) {
push_svalue(first_arg + i);
}
apply_current(f_CPP_report_fun_num, 4 + args);
}
|
0de46d | 2018-08-06 | Henrik Grubbström (Grubba) | | /*! @decl string format_exception(mixed err)
*!
*! Format an exception caught by cpp as a
*! suitable cpp error message.
*!
*! @param err
*! Caught value.
*!
*! @returns
*! Returns one of:
*! @mixed
*! @type zero
*! Generate a cpp error using the default format (ie call
*! @[master()->describe_error()], and replace any newlines
*! with spaces).
*! @type string
*! Cpp error message to @[report()]. The empty string
*! supresses the cpp error.
*! @endmixed
*!
*! The default implementation just returns @expr{0@}.
*/
PIKEFUN string format_exception(mixed err)
{
push_int(0);
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_handle_exception(struct CPP_struct *this,
|
404563 | 2004-06-29 | Martin Nilsson | | const char *cpp_error_fmt, ...)
|
9036e8 | 2001-08-16 | Martin Stjernholm | | {
|
37338b | 2003-11-14 | Martin Stjernholm | | struct svalue thrown;
|
0de46d | 2018-08-06 | Henrik Grubbström (Grubba) | | struct pike_string *msg = NULL;
|
37338b | 2003-11-14 | Martin Stjernholm | | move_svalue (&thrown, &throw_value);
|
1ab4ac | 2008-01-26 | Martin Stjernholm | | mark_free_svalue (&throw_value);
|
37338b | 2003-11-14 | Martin Stjernholm | |
if (cpp_error_fmt) {
va_list args;
va_start (args, cpp_error_fmt);
|
0de46d | 2018-08-06 | Henrik Grubbström (Grubba) | | /* NB: We assume that string_builder_vsprintf() and/or
* init_string_builder() et al don't throw.
*/
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | cpp_report_vsprintf(this, REPORT_ERROR, cpp_error_fmt, args);
|
37338b | 2003-11-14 | Martin Stjernholm | | va_end (args);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
37338b | 2003-11-14 | Martin Stjernholm | | push_svalue(&thrown);
|
0de46d | 2018-08-06 | Henrik Grubbström (Grubba) | | safe_apply_current(f_CPP_format_exception_fun_num, 1);
if (TYPEOF(Pike_sp[-1]) == PIKE_T_STRING) {
if (Pike_sp[-1].u.string->len) {
msg = Pike_sp[-1].u.string;
/* FIXME: Remove the terminating LF and replace the
* other LFs with spaces?
* cf format_exception_for_error_message().
*/
|
715e55 | 2003-11-14 | Martin Stjernholm | | }
|
0de46d | 2018-08-06 | Henrik Grubbström (Grubba) | | } else if (SAFE_IS_ZERO(Pike_sp-1)) {
pop_stack();
msg = format_exception_for_error_msg(&thrown);
if (msg) {
push_string(msg);
} else {
push_int(0);
}
}
if (msg) {
cpp_report(this, REPORT_ERROR, "%S", msg);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
37338b | 2003-11-14 | Martin Stjernholm | |
pop_stack();
free_svalue(&thrown);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_warning(struct CPP_struct *this, const char *cpp_warn_fmt, ...)
|
fb59d2 | 2004-02-07 | Martin Nilsson | | {
|
f6da7b | 2004-06-27 | Martin Nilsson | | va_list args;
va_start(args, cpp_warn_fmt);
|
96594e | 2018-06-27 | Henrik Grubbström (Grubba) | | cpp_report_vsprintf(this, REPORT_WARNING, cpp_warn_fmt, args);
|
f6da7b | 2004-06-27 | Martin Nilsson | | va_end(args);
|
fb59d2 | 2004-02-07 | Martin Nilsson | | }
|
b04e20 | 2018-07-03 | Henrik Grubbström (Grubba) | | /*! @namespace predef::
*/
/*! @decl import cpp:: */
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | /*! @class MasterObject
*/
/*! @decl inherit CompilationHandler
*!
*! The master object acts as fallback compilation handler for
*! @[compile()] and @[cpp()].
*/
/*! @decl CompilationHandler get_compilation_handler(int major, int minor)
*!
*! Get compilation handler for simulation of Pike v@[major].@[minor].
*!
*! This function is called by @[cpp()] when it encounters
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! @expr{#pike@} directives.
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! @param major
*! Major version.
*!
*! @param minor
*! Minor version.
*!
*! @returns
*! Returns a compilation handler for Pike >= @[major].@[minor].
*/
/*! @decl string decode_charset(string raw, string charset)
*!
*! Convert @[raw] from encoding @[charset] to UNICODE.
*!
*! This function is called by @[cpp()] when it encounters
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! @expr{#charset@} directives.
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! @param raw
*! String to convert.
*!
*! @param charset
*! Name of encoding that @[raw] uses.
*!
*! @returns
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! @[raw] decoded to UNICODE, or @expr{0@} (zero) if the decoding failed.
|
2ee381 | 2002-12-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! @[Charset]
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | */
/*! @endclass
*/
/*! @class CompilationHandler
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *!
*! Objects used by the compiler to handle references to global symbols,
*! modules, external files, etc.
*!
|
c0fa4e | 2006-03-25 | Henrik Grubbström (Grubba) | | *! There can be up to three compilation handlers active at the same
*! time during a compilation. They are in order of precedence:
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *!
*! @ol
|
c0fa4e | 2006-03-25 | Henrik Grubbström (Grubba) | | *! @item
*! The error handler
*!
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! This is the object passed to @[compile()] as
*! the second argument (if any). This object is returned by
*! @[get_active_error_handler()] during a compilation.
*!
|
c0fa4e | 2006-03-25 | Henrik Grubbström (Grubba) | | *! @item
*! The compatibility handler
*!
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! This is the object returned by
*! @[master()->get_compilation_handler()] (if any), which
*! the compiler calls when it sees @tt{#pike@}-directives,
*! or expressions using the version scope
*! (eg @expr{7.4::rusage@}). This object is returned by
*! @[get_active_compilation_handler()] during a compilation.
*!
|
c0fa4e | 2006-03-25 | Henrik Grubbström (Grubba) | | *! @item
*! The master object.
*!
|
e290f3 | 2006-01-27 | Henrik Grubbström (Grubba) | | *! This is returned by @[master()] at any time.
*! @endol
*!
*! Any of the objects may implement a subset of the @[CompilationHandler]
*! functions, and the first object that implements a function will be
*! used. The error handler object can thus be used to block certain
*! functionality (eg to restrict the number of available functions).
*!
*! @seealso
*! @[master()->get_compilation_handler()], @[get_active_error_handler()],
*! @[get_active_compilation_handler()], @[compile()]
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | */
|
9c1e6f | 2002-12-08 | Henrik Grubbström (Grubba) | | /*! @decl void compile_error(string filename, int line, string msg)
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! Called by @[compile()] and @[cpp()] when they encounter
*! errors in the code they compile.
*!
|
9c1e6f | 2002-12-08 | Henrik Grubbström (Grubba) | | *! @param filename
*! File where the error was detected.
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! @param line
*! Line where the error was detected.
*!
|
9c1e6f | 2002-12-08 | Henrik Grubbström (Grubba) | | *! @param msg
*! Description of error.
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[compile_warning()].
*/
/*! @decl void compile_exception(mixed exception)
*!
*! Called by @[compile()] and @[cpp()] if they trigger
*! exceptions.
*/
/*! @decl mapping(string:mixed) get_predefines()
*!
|
bd537b | 2002-12-10 | Martin Stjernholm | | *! Called by @[cpp()] to get the set of global symbols.
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! Returns a mapping from symbol name to symbol value.
*! Returns zero on failure.
*!
*! @seealso
|
bd537b | 2002-12-10 | Martin Stjernholm | | *! @[resolv()], @[get_default_module()]
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | */
/*! @decl mixed resolv(string symbol, string filename, @
*! CompilationHandler handler)
*!
*! Called by @[compile()] and @[cpp()] to resolv
*! module references.
*!
*! @returns
*! Returns the resolved value, or @[UNDEFINED] on failure.
*!
*! @seealso
*! @[get_predefines()]
*/
/*! @decl mixed handle_import(string path, string filename, @
*! CompilationHandler handler)
*!
*! Called by @[compile()] and @[cpp()] to handle import
*! directives specifying specific paths.
*!
*! @returns
*! Returns the resolved value, or @[UNDEFINED] on failure.
*/
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | /*! @decl string handle_include(string header_file, string current_file, @
*! int(0..1) is_local_ref)
*!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Called by @[cpp()] to resolv @expr{#include@} and @expr{#string@}
*! directives.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *!
*! @param header_file
*! File that was requested for inclusion.
*!
*! @param current_file
|
548652 | 2002-12-08 | Henrik Grubbström (Grubba) | | *! File where the directive was found.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *!
*! @param is_local_ref
*! Specifies reference method.
*! @int
*! @value 0
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Directive was @expr{#include <header_file>@}.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *! @value 1
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Directive was @expr{#include "header_file"@}.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *! @endint
*!
*! @returns
*! Returns the filename to pass to @[read_include()] if found,
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! and @expr{0@} (zero) on failure.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[read_include()]
*/
/*! @decl string read_include(string filename)
*!
*! Called by @[cpp()] to read included files.
*!
*! @param filename
*! Filename as returned by @[handle_include()].
*!
*! @returns
*! Returns a string with the content of the header file on success,
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! and @expr{0@} (zero) on failure.
|
915e53 | 2002-12-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[handle_include()]
*/
|
bbeddc | 2002-12-07 | Henrik Grubbström (Grubba) | | /*! @endclass
*/
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @endnamespace */
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | /* #pike handling. */
|
73945f | 2018-08-13 | Henrik Grubbström (Grubba) | | /*! @decl void change_cpp_compatibility(int major, int minor)
*!
*! Change the pike compatibility level for this preprocessor
*! to the specified version of Pike.
*!
*! @param major
*! Major version of Pike to attempt to be compatible with.
*! Specifying a major version of @expr{-1@} is a short hand
*! for specifying @[__REAL_MAJOR__] and @[__REAL_MINOR__].
*!
*! @param minor
*! Minor version of Pike to attempt to be compatible with.
*!
*! This function is called by the preprocessor to set
*! the compatibility level.
*!
*! The default implementation performs some normalization, and
*! then sets @[compat_major] and @[compat_minor] to their
*! respective values (which in turn affects symbols such as
*! @[__MAJOR__] and @[__MINOR__]).
*/
PIKEFUN void change_cpp_compatibility(int major, int minor)
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | {
|
73945f | 2018-08-13 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = THIS;
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
73945f | 2018-08-13 | Henrik Grubbström (Grubba) | | if ((major < 0) || (minor < 0)) {
major = PIKE_MAJOR_VERSION;
minor = PIKE_MINOR_VERSION;
}
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
73945f | 2018-08-13 | Henrik Grubbström (Grubba) | | if ((this->compat_major == major) &&
(this->compat_minor == minor)) return;
this->compat_major = major;
this->compat_minor = minor;
|
298baf | 2018-07-25 | Henrik Grubbström (Grubba) | | }
|
68a3f1 | 2018-07-08 | Henrik Grubbström (Grubba) | | /*! @decl mixed resolv(string sym)
*!
*! Attempt to resolve a symbol.
*!
*! The default implementation calls @[CompilerEnvironment()->resolv()]
*! in the parent object, with the remaining arguments taken from the
*! current @[CPP] context.
*!
*! @returns
*! Returns the value of @[sym] if found, and @[UNDEFINED] if not.
*/
PIKEFUN mixed resolv(string sym)
{
struct CPP_struct *this = THIS;
ref_push_string(sym);
ref_push_string(this->current_file);
if (this->handler) {
ref_push_object(this->handler);
} else {
push_undefined();
}
if (this->compat_handler) {
ref_push_object(this->compat_handler);
} else {
push_undefined();
}
apply_external(1, CE_RESOLV_FUN_NUM, 4);
}
|
d87f42 | 2018-08-02 | Henrik Grubbström (Grubba) | | PIKEFUN mapping|object|program handle_import(string module)
{
struct CPP_struct *this = THIS;
ref_push_string(module);
ref_push_string(this->current_file);
if (this->handler) {
ref_push_object(this->handler);
} else {
push_int(0);
}
low_unsafe_apply_handler("handle_import",
this->handler, this->compat_handler, 3);
}
|
9c5967 | 2018-08-01 | Henrik Grubbström (Grubba) | | PIKEFUN string handle_include(string header_file, string current_file,
int(0..1) is_local_ref)
{
struct CPP_struct *this = THIS;
low_unsafe_apply_handler("handle_include",
this->handler, this->compat_handler, args);
}
PIKEFUN string read_include(string filename)
{
struct CPP_struct *this = THIS;
low_unsafe_apply_handler("read_include",
this->handler, this->compat_handler, args);
}
|
f34838 | 2018-07-30 | Henrik Grubbström (Grubba) | | PIKEFUN string decode_charset(string data, string charset)
{
struct CPP_struct *this = THIS;
low_unsafe_apply_handler("decode_charset",
this->handler, this->compat_handler, args);
}
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | /* #if macros and functions. */
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @namespace cpp::
*!
*! Pike has a builtin C-style preprocessor. It works similar to the
*! ANSI-C preprocessor but has a few extra features. These and the
*! default set of preprocessor macros are described here.
|
bcea4b | 2018-08-04 | Henrik Grubbström (Grubba) | | *!
*! The preprocessor is usually accessed via
*! @[MasterObject->compile_file()] or @[MasterObject->compile_string()],
*! but may be accessed directly by calling @[cpp()].
*!
*! @seealso
*! @[compile()], @[cpp()], @[CompilerEnvironment.CPP]
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | */
/*! @directive #!
*!
*! All lines beginning with @[#!] will be regarded as comments,
*! to enable shell integration. It is recommended that Pike applications
*! begin with the line @tt{"#! /usr/bin/env pike"@} for maximum cross
*! platform compatibility.
*/
/*! @directive #charset
*!
|
0b8d2f | 2013-06-17 | Martin Nilsson | | *! Inform the preprocessor about which charset the file is encoded
*! with. The Charset module is called with this string to decode
*! the remainder of the file.
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | */
/*! @directive #if
*!
*! The @[#if] directive can evaluate simple expressions and, if
*! the expression is evaluates to true, "activate" the code block that
*! follows. The code block ends when an @[#endif], @[#else],
*! @[#elseif] or @[#elif] block is encountered at the same
*! nesting depth.
*!
*! The @[#if] expressions may include defines, integer, string
*! and float constants, @tt{?:@}, @tt{||@} and @tt{&&@} operations,
*! @tt{~@}, @tt{^@}, @tt{!@}, @tt{|@} and @tt{&@} operations,
*! @tt{<@}, @tt{>@}, @tt{<=@}, @tt{>=@}, @tt{==@} and @tt{!=@} operations,
*! @tt{+@}, @tt{-@}, @tt{*@}, @tt{/@}, @tt{<<@} and @tt{>>@} operations
*! and paranthesis.
*!
*! Strings may also be indexed with the @tt{[]@} index operator.
*! Finally there are three special "functions" available in @[#if]
*! expressions; @[defined()], @[efun()] and @[constant()].
*!
*! @seealso
*! @[#ifdef], @[#ifndef], @[#elif], @[#else], @[#endif],
*! @[defined()], @[constant()], @[efun()]
*/
/*! @directive #ifdef
*!
*! Check whether an identifier is a macro.
*!
*! The directive
*!
*! @tt{#ifdef @i{<identifier>@}@}
*!
|
bf2c0d | 2018-01-12 | Stephen R. van den Berg | | *! is equivalent to
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *!
*! @tt{#if @[defined](@i{<identifier>@})@}
*!
*! @seealso
*! @[#if], @[#ifndef], @[defined]
*/
/*! @directive #ifndef
*!
*! Check whether an identifier is not a macro.
*!
*! This is the inverse of @[#ifdef].
*!
*! The directive
*!
*! @tt{#ifndef @i{<identifier>@}@}
*!
|
bf2c0d | 2018-01-12 | Stephen R. van den Berg | | *! is equivalent to
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *!
*! @tt{#if !@[defined](@i{<identifier>@})@}
*!
*! @seealso
*! @[#if], @[#ifdef], @[defined]
*/
|
956513 | 2014-02-14 | Martin Nilsson | | /*! @directive #require
*!
*! If the directive evaluates to false, the source file will be
*! considered to have failed dependencies, and will not be found by
*! the resolver. In practical terms the @[cpp()] call will return
*! zero.
*!
*! @seealso
*! @[#if]
*/
|
f6abaa | 2018-02-27 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..0) directive_require(int flags, string line)
{
struct CPP_struct *this = THIS;
if (OUTP()) {
ref_push_string(line);
push_int(CPP_DO_IF);
apply_current(f_CPP_cpp_fun_num, 2);
if (TYPEOF(Pike_sp[-1]) == PIKE_T_STRING) {
calc(this, MKPCHARP_STR(Pike_sp[-1].u.string),
Pike_sp[-1].u.string->len, 0, 0);
if(SAFE_IS_ZERO(Pike_sp-1)) this->dependencies_fail=1;
} else {
this->dependencies_fail=1;
}
pop_stack();
}
push_empty_string();
}
|
956513 | 2014-02-14 | Martin Nilsson | |
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @directive #endif
*!
*! End a block opened with @[#if], @[#ifdef], @[#ifndef],
*! @[#else], @[#elseif] or @[#elif].
*!
*! @example
*! @code
*! #ifdef DEBUG
*! do_debug_stuff();
*! #endif // DEBUG
*! @endcode
*/
/*! @directive #else
*!
*! This directive is used to divide the current code block into another
*! code block with inverse activation.
*!
*! @example
*! @code
*! #ifdef FAST_ALGORITHM
*! do_fast_algorithm();
*! #elif defined(EXPERIMENTAL_ALGORITHM)
*! do_experimental_algorithm();
*! #else
*! do_default_algorithm();
*! #endif
*! @endcode
*/
/*! @directive #elif
*! @directive #elseif
*!
*! These work as a combined @[#else] and @[#if] without
*! adding an extra level of nesting.
*!
*! @example
*!
|
bf2c0d | 2018-01-12 | Stephen R. van den Berg | | *! The following two are equivalent:
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *!
*! @code
*! #ifdef A
*! // Code for A.
*! #else
*! #ifdef B
*! // Code for B.
*! #else
*! #ifdef C
*! // Code for C.
*! #else
*! // Code for D.
*! #endif
*! #endif
*! #endif
*! @endcode
*!
*! And
*!
*! @code
*! #ifdef A
*! // Code for A.
*! #elif defined(B)
*! // Code for B.
*! #elseif defined(C)
*! // Code for C.
*! #else
*! // Code for D.
*! #endif
*! @endcode
*!
*! @seealso
*! @[#if], @[#ifdef], @[#else], @[defined()], @[constant()]
*/
/*! @directive #error
*!
*! Throw an error during preprocessing.
*!
*! This directive causes a cpp error. It can be used to notify
*! the user that certain functions are missing and similar things.
*!
*! @note
*! Note that this directive will cause @[cpp()] to throw
*! an error at the end of preprocessing, which will cause
*! any compilation to fail.
*!
*! @example
*! @code
*! #if !constant(Yp)
*! #error Support for NIS not available.
*! #endif
*! @endcode
*!
*! @seealso
*! @[#warning]
*/
|
78b796 | 2018-01-15 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..0) directive_error(int flags, string line)
{
struct CPP_struct *this = THIS;
if (OUTP()) {
cpp_error_sprintf(this, "%O", Pike_sp - 1);
}
push_empty_string();
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
/*! @directive #warning
*!
*! Generate a warning during preprocessing.
*!
*! This directive causes a cpp warning, it can be used to notify
*! the user that certain functions are missing and similar things.
*!
*! @example
*! @code
*! #if !constant(Yp)
*! #warning Support for NIS not available. Some features may not work.
*! #endif
*! @endcode
*!
*! @seealso
*! @[#error]
*/
|
78b796 | 2018-01-15 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..0) directive_warning(int flags, string line)
{
struct CPP_struct *this = THIS;
if (OUTP()) {
cpp_warning(this, "%O", Pike_sp - 1);
}
push_empty_string();
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
/*! @directive #include
*!
*! @[#include] is used to insert the contents of another file into
*! the processed file at the place of the include directive.
*!
*! Files can be referenced either by absolute or relative path from the
*! source file, or searched for in the include paths.
*!
*! To include a file with absolute or relative path, use double quotes,
*! e.g. @tt{#include "constants.pike"@} or @tt{#include "../debug.h"@}.
*!
*! To include from the include paths, use less than and greater than,
*! e.g. @tt{#include <profiling.h>@}.
*!
*! It is also possible to include a file whose path is defined in a
*! preprocessor macro, e.g. @tt{#include USER_SETTINGS@}.
*/
/*! @directive #line
*! @directive #<integer>
*!
*! A hash character followed by a number or by the string
*! @tt{"line"@} and a number will make the preprocessor line counter
*! set this number as the line number for the next line and adjust the
*! following lines accordingly.
*!
*! All error messages from Pike will use these line numbers.
*!
*! Optionally the number may be followed by a file name, e.g.
*! @tt{#line 1 "/home/pike/program.pike.in"@}. Then this
*! filename will be used instead of the current file for error
*! messages.
*/
/*! @directive #pike
*!
*! Set the Pike compiler backward compatibility level.
*!
*! This tells the compiler which version of Pike it should
*! attempt to emulate from this point on in the current
*! compilation unit.
*!
*! This is typically used to "quick-fix" old code to work
*! with more recent versions of Pike.
*!
*! @example
*! @code
*! // This code was written for Pike 7.2, and depends on
|
640b82 | 2016-09-10 | Henrik Grubbström (Grubba) | | *! // the old behaviour for @expr{7.2::dirname()@}.
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *! #pike 7.2
*!
*! // ... Code that uses @[dirname()] ...
*! @endcode
*!
*! This directive is also needed for Pike modules that
*! have been installed globally, and might be used by
*! a Pike that has been started with the @tt{-V@} flag.
*!
*! @example
*! @code
*! // Pike modules that are bundled with Pike are
*! // typically written for the same version of Pike.
*! #pike __REAL_VERSION__
*! @endcode
*/
|
a361fc | 2018-02-28 | Henrik Grubbström (Grubba) | | PIKEFUN string(0..0) directive_pike(int flags, string line)
{
struct CPP_struct *this = THIS;
if (OUTP()) {
int major, minor;
ptrdiff_t tmp;
PCHARP ptr;
string_builder_strcat(&this->buf, "#pike ");
ref_push_string(line);
push_int(CPP_DO_IF);
apply_current(f_CPP_cpp_fun_num, 2);
if (TYPEOF(Pike_sp[-1]) == PIKE_T_STRING) {
line = Pike_sp[-1].u.string;
ptr = MKPCHARP_STR(line);
major = STRTOL_PCHARP(ptr, &ptr, 10);
if(INDEX_PCHARP(ptr,0) == '.')
{
INC_PCHARP(ptr, 1);
minor=STRTOL_PCHARP(ptr, &ptr, 10);
|
edcd27 | 2018-08-11 | Henrik Grubbström (Grubba) | |
push_int(major);
push_int(minor);
apply_current(f_CPP_change_cpp_compatibility_fun_num, 2);
pop_stack();
|
a361fc | 2018-02-28 | Henrik Grubbström (Grubba) | | }else{
cpp_error(this, "Missing '.' in #pike.");
this->compat_minor=0;
}
/* NB: The parsed line is already in place on the stack. */
return;
} else {
cpp_error(this, "Invalid #pike directive.");
}
}
push_empty_string();
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
/*! @directive #""
*! If a string literal is opened with @tt{#"@} newlines in the
*! string will end up in the string literal, instead of triggering a
*! @tt{"newline in string"@} error.
*!
*! @note
*! Newlines will be converted to @tt{\n@} characters in the string
*! even if the newlines in the file are something else.
*!
*! This preprocessor directive may appear anywhere a string may
*! appear.
*!
*! @seealso
*! @[#string]
*/
|
d6d2e5 | 2016-06-10 | Martin Nilsson | | /*! @directive #(#)
*! @directive #[#]
*! @directive #{#}
*! If a string literal is opened with @tt{#(@} all subsequent
*! characters until the closing @tt{#)@} will be treated as
*! literals, including newlines, @tt{\@}, @tt{"@} and @tt{'@}.
*!
*! There are three different pairs of start/end tokens for this
*! type of literals, #( and #), #[ and #], and #{ and #}.
*!
*! @example
*! @expr{#["\n\'##]@} is equivalent to @expr{"\"\\n\\'#"@}.
|
b6fef0 | 2016-06-10 | Martin Nilsson | | */
|
d6d2e5 | 2016-06-10 | Martin Nilsson | |
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @directive #string
*! The preprocessor directive @[#string] will load the file in the
*! string that follows and insert its contents as a string. This
*! preprocessor directive may appear anywhere a string may appear.
*!
*! @example
*! @code
*! do_something(#string "the_file.wks");
*! @endcode
*!
*! @seealso
*! @[#include]
*/
/*! @directive #pragma
*!
*! This is a generic directive for flags to the compiler.
*!
*! These are some of the flags that are available:
*! @string
*! @value "all_inline"
*! This is the same as adding the modifier @tt{inline@}
*! to all functions that follow.
*! @value "all_final"
*! Instructs the compiler to mark all symbols as @tt{final@}.
|
d3abb8 | 2015-02-10 | Henrik Grubbström (Grubba) | | *! @value "deprecation_warnings"
*! Enable warnings for use of deprecated symbols (default).
*! @value "no_deprecation_warnings"
*! Disable warnings for use of deprecated symbols. This is
*! typically used in code that implements the deprecated
*! symbols.
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *! @value "save_parent"
*! Cause nested classes to save a reference to their
*! surrounding class even if not strictly needed.
*! @value "dont_save_parent"
*! Inverse of @tt{"save_parent"@}. This is needed to override
*! if the global symbol @[predef::__pragma_save_parent__]
*! has been set.
*! @value "strict_types"
*! Enable warnings for all cases where the compiler
*! isn't certain that the types are correct.
|
d3abb8 | 2015-02-10 | Henrik Grubbström (Grubba) | | *! @value "disassemble"
*! Enable disassembly output for the code being compiled.
*! Note that this option essentially has a function-level
*! scope, so enabling it for just a few lines is usually
*! a noop. This is similar to @[Debug.assembler_debug()]
|
fdde6b | 2017-01-16 | Henrik Grubbström (Grubba) | | *! level @expr{3@}.
|
d3abb8 | 2015-02-10 | Henrik Grubbström (Grubba) | | *! @value "no_disassemble"
*! Disable disassembly output (default).
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *! @endstring
|
dddfca | 2018-02-22 | Henrik Grubbström (Grubba) | | */
PIKEFUN string(0..0) directive_pragma(int flags, string line)
{
struct CPP_struct *this = THIS;
if (OUTP()) {
/* FIXME: Prefix with this->prefix? */
string_builder_strcat(&this->buf, "#pragma ");
ref_push_string(line);
|
ff7085 | 2018-02-23 | Henrik Grubbström (Grubba) | | push_int(flags & ~CPP_EXPECT_ENDIF);
|
dddfca | 2018-02-22 | Henrik Grubbström (Grubba) | | apply_current(f_CPP_low_cpp_fun_num, 2);
pop_stack();
}
push_empty_string();
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
/*! @decl int(0..1) defined(mixed identifier)
*!
*! Check whether an identifier is a cpp macro or not.
*!
*! @returns
*! @[defined] returns true if the symbol given as argument
*! is defined.
*!
*! @note
|
bf2c0d | 2018-01-12 | Stephen R. van den Berg | | *! @tt{#if defined(MY_DEF)@} is equivalent to
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *! @tt{#ifdef MY_DEF@}.
*!
*! @seealso
*! @[#if], @[#ifdef], @[constant()]
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void check_defined(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *arg,
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
3d6a1d | 2016-08-21 | Martin Nilsson | | if(arg && FIND_DEFINE(arg))
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | string_builder_binary_strcat(tmp, " 1 ", 3);
|
6e5206 | 2014-05-12 | Martin Nilsson | | else
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | string_builder_binary_strcat(tmp, " 0 ", 3);
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static int do_safe_index_call(struct CPP_struct *this, struct pike_string *s)
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | {
int res;
JMP_BUF recovery;
if(!s) return 0;
if (SETJMP_SP(recovery, 1)) {
|
abe9fe | 2014-09-18 | Martin Nilsson | | if(this->picky_cpp)
|
7b2a53 | 2004-06-29 | Martin Nilsson | | cpp_warning (this, "Error indexing module with %S.", s);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | res = 0;
push_undefined();
} else {
ref_push_string(s);
f_index(2);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | res=!(UNSAFE_IS_ZERO(Pike_sp-1) && SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | }
UNSETJMP(recovery);
return res;
}
|
d2ac22 | 2014-02-15 | Martin Nilsson | | /*! @decl int(0..1) constant(mixed identifier)
*! @decl __deprecated__ int(0..1) efun(mixed identifier)
*!
*! Check whether the argument resolves to a constant or not.
*!
*! @seealso
*! @[#if], @[defined()]
*/
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void cpp_constant(struct CPP_struct *this, int value)
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *save_stack=Pike_sp;
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | struct array *arr;
|
a1640e | 2010-09-18 | Marcus Comstedt | | INT_TYPE res = 0;
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | int n;
/* FIXME: Protection against errors. */
/* Remove extra whitespace. */
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text(" ");
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | o_subtract();
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("\t");
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | o_subtract();
/* Split on . */
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text(".");
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | o_divide();
#ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) != T_ARRAY) {
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | Pike_fatal("Bad result from division in constant(): %s "
"(expected array(string)).\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
arr = Pike_sp[-1].u.array;
#ifdef PIKE_DEBUG
if (!arr->size) {
Pike_fatal("Got an empty array from division in constant().\n");
}
if ((arr->type_field & ~BIT_STRING) &&
(array_fix_type_field(arr) & ~BIT_STRING)) {
Pike_fatal("Bad result from division in constant(): type_field: 0x%08x "
"(expected array(string)).\n",
arr->type_field & ~BIT_STRING);
}
#endif /* PIKE_DEBUG */
if (arr->item[0].u.string->len) {
struct pike_string *str = arr->item[0].u.string;
struct svalue *sv;
if((sv=low_mapping_string_lookup(get_builtin_constants(), str)))
{
/* efun */
push_svalue(sv);
res=1;
} else if(get_master()) {
/* Module. */
ref_push_string(str);
|
68a3f1 | 2018-07-08 | Henrik Grubbström (Grubba) | | if (safe_apply_current(f_CPP_resolv_fun_num, 1)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(Pike_sp[-1]) == T_OBJECT &&
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | Pike_sp[-1].u.object == placeholder_object) ||
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(Pike_sp[-1]) == T_PROGRAM &&
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | Pike_sp[-1].u.program == placeholder_program)) {
|
89f543 | 2004-06-29 | Martin Nilsson | | cpp_error_sprintf (this, "Got placeholder %s (resolver problem) "
"when resolving %S.",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type(TYPEOF(Pike_sp[-1])),
|
89f543 | 2004-06-29 | Martin Nilsson | | str);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | }
else
|
19961b | 2017-04-08 | Martin Nilsson | | res = !(SAFE_IS_ZERO(Pike_sp-1) && SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | }
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | else if (TYPEOF(throw_value) == T_STRING &&
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | !throw_value.u.string->size_shift) {
cpp_error(this, throw_value.u.string->str);
free_svalue(&throw_value);
|
1ab4ac | 2008-01-26 | Martin Stjernholm | | mark_free_svalue (&throw_value);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | res = 0;
|
91a2f6 | 2004-11-05 | Martin Nilsson | | } else if(this->picky_cpp) {
|
7b2a53 | 2004-06-29 | Martin Nilsson | | cpp_warning (this, "Error resolving %S.", str);
res = 0;
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | }
}
} else {
/* Handle constant(.foo) */
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text(".");
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | |
|
d87f42 | 2018-08-02 | Henrik Grubbström (Grubba) | | if (safe_apply_current(f_CPP_handle_import_fun_num, 1) &&
((1<<TYPEOF(Pike_sp[-1])) & (BIT_MAPPING|BIT_OBJECT|BIT_PROGRAM))) {
|
19961b | 2017-04-08 | Martin Nilsson | | res = !(SAFE_IS_ZERO(Pike_sp-1) && SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED);
|
d87f42 | 2018-08-02 | Henrik Grubbström (Grubba) | | } else {
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | cpp_handle_exception (this, "Error importing '.'.");
}
}
for (n = 1; res && (n < arr->size); n++) {
res = do_safe_index_call(this, arr->item[n].u.string);
}
|
a1640e | 2010-09-18 | Marcus Comstedt | | if (value && res) {
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-1]) == T_INT)
res = Pike_sp[-1].u.integer;
|
a1640e | 2010-09-18 | Marcus Comstedt | | else
res = 0;
}
|
19961b | 2017-04-08 | Martin Nilsson | | pop_n_elems(1 + Pike_sp - save_stack);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | push_int(res);
}
|
0ca86e | 2005-04-09 | Henrik Grubbström (Grubba) | | static struct mapping *initial_predefs_mapping(void)
|
b584b1 | 2001-12-20 | Martin Stjernholm | | {
struct pike_predef_s *def;
struct mapping *map = allocate_mapping (0);
#ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!use_initial_predefs) Pike_fatal ("Initial predefs has been taken over.\n");
|
b584b1 | 2001-12-20 | Martin Stjernholm | | #endif
|
df9147 | 2016-10-21 | Henrik Grubbström (Grubba) | | for (def = first_predef; def; def = def->next) {
struct pike_string *name = make_shared_string(def->name);
struct pike_string *value = make_shared_string(def->value);
mapping_string_insert_string(map, name, value);
free_string(value);
free_string(name);
}
|
b584b1 | 2001-12-20 | Martin Stjernholm | | return map;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static p_wchar2 readchar( PCHARP data, ptrdiff_t *pos, struct CPP_struct *this )
|
1f57ef | 2014-05-10 | Per Hedbor | | {
ptrdiff_t l;
p_wchar2 C;
INC_PCHARP(data,*pos);
switch(parse_esc_seq_pcharp (data, &C, &l))
{
case 0:
*pos += l;
break;
case 1:
C = '\r';
*pos += 1;
break;
case 3:
/* The eof will get caught in the next round. */
C = 0;
*pos += 1;
break;
case 4: case 5: case 6:
cpp_error (this, "Too large character value in escape.");
C = (int) MAX_UINT32;
*pos += l;
break;
case 7:
cpp_error (this, "Too few hex digits in \\u escape.");
C = '\\';
break;
case 8:
cpp_error (this, "Too few hex digits in \\U escape.");
C = '\\';
break;
|
6e5206 | 2014-05-12 | Martin Nilsson | | #ifdef PIKE_DEBUG
case 2: Pike_fatal ("Not supposed to happen.\n");
default: Pike_fatal ("Unknown error from parse_esc_seq.\n");
#endif
|
1f57ef | 2014-05-10 | Per Hedbor | | }
return C;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t readstring( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,
|
1f57ef | 2014-05-10 | Per Hedbor | | struct string_builder*nf, int nl_ok)
{
while(1)
{
pos++;
if(pos>=len)
{
cpp_error(this,"End of file in string.");
break;
}
switch(INDEX_PCHARP(data,pos))
{
case '"': break;
case '\\':
{
pos++;
if(INDEX_PCHARP(data,pos)=='\n')
{
this->current_line++;
PUTNL();
continue;
}
if(INDEX_PCHARP(data,pos)=='\r' && INDEX_PCHARP(data,pos+1)=='\n')
{
pos++;
this->current_line++;
PUTNL();
continue;
}
string_builder_putchar(nf, readchar(data,&pos,this));
pos--;
continue;
}
case '\r':
continue; /* ignored */
case '\n':
this->current_line++;
if( nl_ok )
PUTNL();
else
cpp_error(this,"Newline in string.");
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
1f57ef | 2014-05-10 | Per Hedbor | | default:
string_builder_putchar(nf, INDEX_PCHARP(data,pos));
continue;
}
pos++;
break;
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t readstring_lit( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,
|
2028f8 | 2014-07-21 | Per Hedbor | | struct string_builder*nf, INT32 ec)
{
INT32 ch;
|
b9a2a9 | 2015-07-06 | Arne Goedeke | | while(1) {
if(++pos>=len) {
|
2028f8 | 2014-07-21 | Per Hedbor | | cpp_error(this,"End of file in string.");
|
b9a2a9 | 2015-07-06 | Arne Goedeke | | break;
}
if((ch=INDEX_PCHARP(data,pos)) == '#' && INDEX_PCHARP(data,pos+1)==ec)
|
2028f8 | 2014-07-21 | Per Hedbor | | return pos + 2;
|
b9a2a9 | 2015-07-06 | Arne Goedeke | | else {
if (ch == '\n') {
this->current_line++;
PUTNL();
}
|
2028f8 | 2014-07-21 | Per Hedbor | | string_builder_putchar(nf, ch);
|
b9a2a9 | 2015-07-06 | Arne Goedeke | | }
}
|
2028f8 | 2014-07-21 | Per Hedbor | | return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t fixstring(struct CPP_struct *this, const PCHARP data, ptrdiff_t len,
|
efd97a | 2014-05-12 | Martin Nilsson | | ptrdiff_t pos, struct string_builder *nf, int outp)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
int trailing_newlines=0;
if(outp) string_builder_putchar(nf, '"');
while(1)
{
if(pos>=len)
{
cpp_error(this,"End of file in string.");
break;
}
switch(INDEX_PCHARP(data,pos++))
{
case '\n':
cpp_error(this,"Newline in string.");
this->current_line++;
break;
case '"': break;
case '\\':
if(INDEX_PCHARP(data,pos)=='\n')
{
pos++;
trailing_newlines++;
this->current_line++;
continue;
}
if(INDEX_PCHARP(data,pos)=='\r' && INDEX_PCHARP(data,pos+1)=='\n')
{
pos+=2;
trailing_newlines++;
this->current_line++;
continue;
}
if(outp) string_builder_putchar(nf, '\\');
pos++;
/* Fall through. */
default:
if(outp) string_builder_putchar(nf, INDEX_PCHARP(data,pos-1));
continue;
}
break;
}
if(outp) string_builder_putchar(nf, '"');
while(trailing_newlines--) PUTNL();
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_of_line( struct CPP_struct *this, const PCHARP data,
|
efd97a | 2014-05-12 | Martin Nilsson | | ptrdiff_t len, ptrdiff_t pos, int emit )
|
1f57ef | 2014-05-10 | Per Hedbor | | {
while(pos < len) {
switch (INDEX_PCHARP(data,pos++)) {
case '\n':
return pos-1;
case '\\':
if (INDEX_PCHARP(data,pos) == '\n') {
pos+=2;
} else if ((INDEX_PCHARP(data,pos) == '\r') &&
(INDEX_PCHARP(data,pos+1) == '\n')) {
pos+=3;
} else {
pos++;
continue;
}
this->current_line++;
if( emit ) PUTNL();
}
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_of_comment( struct CPP_struct *this, const PCHARP data, ptrdiff_t len,
|
efd97a | 2014-05-12 | Martin Nilsson | | ptrdiff_t pos, int emit)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
pos++;
while(INDEX_PCHARP(data,pos)!='*' || INDEX_PCHARP(data,pos+1)!='/')
|
13670c | 2015-05-25 | Martin Nilsson | | {
|
1f57ef | 2014-05-10 | Per Hedbor | | if(pos+2>=len)
{
cpp_error(this,"End of file in comment.");
break;
}
if(INDEX_PCHARP(data,pos)=='\n')
{
this->current_line++;
if( emit )PUTNL();
}
pos++;
}
return pos + 2;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_quote(struct CPP_struct *this, const PCHARP data,
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | ptrdiff_t len, ptrdiff_t pos,
p_wchar2 quote, int flags)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
while(1)
{
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | p_wchar2 c;
|
1f57ef | 2014-05-10 | Per Hedbor | | if(pos>=len)
{
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | if (quote == '\'') {
cpp_error(this,"End of file in character constant.");
} else {
cpp_error(this,"End of file in string.");
}
|
1f57ef | 2014-05-10 | Per Hedbor | | break;
}
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | switch((c = INDEX_PCHARP(data,pos++)))
|
1f57ef | 2014-05-10 | Per Hedbor | | {
case '\n':
|
1238cd | 2016-09-29 | Henrik Grubbström (Grubba) | | if (flags & CPP_END_AT_NEWLINE) {
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | if (quote == '\'') {
cpp_error(this,"Newline in char.");
} else {
cpp_error(this,"Newline in string.");
}
|
1238cd | 2016-09-29 | Henrik Grubbström (Grubba) | | }
|
1f57ef | 2014-05-10 | Per Hedbor | | this->current_line++;
PUTNL();
break;
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | default:
if (c == quote) return pos;
|
1f57ef | 2014-05-10 | Per Hedbor | | break;
case '\\':
if(INDEX_PCHARP(data,pos)=='\n') {
this->current_line++;
PUTNL();
}
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | else if ((INDEX_PCHARP(data,pos) == '\r') && (INDEX_PCHARP(data,pos+1) == '\n')) {
|
1f57ef | 2014-05-10 | Per Hedbor | | this->current_line++;
pos++;
PUTNL();
}
pos++;
}
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_brace(struct CPP_struct *this,
|
1f57ef | 2014-05-10 | Per Hedbor | | PCHARP data,
ptrdiff_t len,
ptrdiff_t pos);
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_parenthesis(struct CPP_struct *this,
|
1f57ef | 2014-05-10 | Per Hedbor | | PCHARP data,
ptrdiff_t len,
ptrdiff_t pos)
/* pos is after the open paren. Returns the position after the close paren. */
{
INT_TYPE start_line = this->current_line;
while(1)
{
if(pos+1>=len)
{
INT_TYPE save_line = this->current_line;
this->current_line = start_line;
cpp_error(this, "End of file while looking for end parenthesis.");
this->current_line = save_line;
return pos;
}
switch(INDEX_PCHARP(data,pos++))
{
case '\n': PUTNL(); this->current_line++; break;
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | case '\'': pos=find_end_quote(this,data,len,pos,'\'',CPP_END_AT_NEWLINE); break;
case '"': pos=find_end_quote(this,data,len,pos,'\"',CPP_END_AT_NEWLINE); break;
|
1f57ef | 2014-05-10 | Per Hedbor | | case '(': pos=find_end_parenthesis(this, data, len, pos); break;
case '{': pos=find_end_brace(this, data, len, pos); break;
case ')': return pos;
case '/':
if (INDEX_PCHARP(data,pos) == '*') {
pos = find_end_of_comment(this,data,len,pos+1,0);
} else if (INDEX_PCHARP(data,pos) == '/') {
pos = find_end_of_line(this,data,len,pos+1,0);
}
}
}
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_end_brace(struct CPP_struct *this,
|
90e5e9 | 2014-05-13 | Martin Nilsson | | const PCHARP data,
|
1f57ef | 2014-05-10 | Per Hedbor | | ptrdiff_t len,
ptrdiff_t pos)
/* pos is after the open brace. Returns the position after the close brace. */
{
INT_TYPE start_line = this->current_line;
while(1)
{
if(pos+1>=len)
{
INT_TYPE save_line = this->current_line;
this->current_line = start_line;
cpp_error(this, "End of file while looking for end brace.");
this->current_line = save_line;
return pos;
}
switch(INDEX_PCHARP(data,pos++))
{
case '\n': PUTNL(); this->current_line++; break;
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | case '\'': pos=find_end_quote(this,data,len,pos,'\'',CPP_END_AT_NEWLINE); break;
case '"': pos=find_end_quote(this,data,len,pos,'\"',CPP_END_AT_NEWLINE); break;
|
1f57ef | 2014-05-10 | Per Hedbor | | case '{': pos=find_end_brace(this, data, len, pos); break;
case '}': return pos;
case '/':
if (INDEX_PCHARP(data,pos) == '*') {
pos=find_end_of_comment(this,data,len,pos,0);
} else if (INDEX_PCHARP(data,pos) == '/') {
pos=find_end_of_line(this,data,len,pos,0);
}
}
}
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static struct pike_string *gobble_identifier (struct CPP_struct *this, const PCHARP data, ptrdiff_t *pos)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
ptrdiff_t p = *pos;
struct string_builder sb;
|
74966e | 2014-05-12 | Per Hedbor | | p_wchar2 tmp;
if( !wide_isidchar( tmp = INDEX_PCHARP(data,*pos)) && tmp != '\\' )
return NULL;
|
1f57ef | 2014-05-10 | Per Hedbor | | init_string_builder (&sb, 0); /* in fact, 0 is more likely than data.shift */
while (1) {
ptrdiff_t start = p;
|
13670c | 2015-05-25 | Martin Nilsson | | while (wide_isidchar (INDEX_PCHARP(data,p)))
|
1f57ef | 2014-05-10 | Per Hedbor | | p++;
if (p != start)
{
PCHARP x = data;
INC_PCHARP(x,start);
string_builder_append(&sb,x, p - start);
}
if (INDEX_PCHARP(data,p) != '\\') goto past_identifier;
switch (INDEX_PCHARP(data,p + 1)) {
case '\r':
if (INDEX_PCHARP(data,p + 2) != '\n')
goto past_identifier;
p++;
/* Fall through */
case '\n':
this->current_line++;
PUTNL();
p += 2;
break;
case 'u':
case 'U': {
/* Note: Code dup in parse_esc_seq in lexer.h. */
/* Don't have to bother checking for an even number of
* preceding backslashes since they aren't valid outside
* string and char literals in the lexer input. */
unsigned INT32 c = 0;
ptrdiff_t stop, q;
if (INDEX_PCHARP(data,p + 2) == INDEX_PCHARP(data,p + 1))
/* A quoted \u escape means we got "\uxxxx" dequoted here,
* and that can't be part of an identifier. */
goto past_identifier;
if (INDEX_PCHARP(data,p + 1) == 'u')
stop = p + 6;
else
stop = p + 10;
for (q = p + 2; q < stop; q++)
{
int tmp;
switch (tmp=INDEX_PCHARP(data,q)) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c = 16 * c + tmp - '0';
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
c = 16 * c + tmp - 'a' + 10;
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
c = 16 * c + tmp - 'A' + 10;
break;
default:
cpp_error_sprintf (this, "Too few hex digits in \\%c escape.",
INDEX_PCHARP(data,p + 1));
goto past_identifier;
}
}
|
1585cf | 2014-05-10 | Per Hedbor | | if (!wide_isidchar (c)) goto past_identifier;
|
1f57ef | 2014-05-10 | Per Hedbor | | string_builder_putchar (&sb, c);
p = q;
break;
}
default:
goto past_identifier;
}
}
past_identifier:
if (p != *pos) {
*pos = p;
return finish_string_builder (&sb);
}
free_string_builder (&sb);
return NULL;
}
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | /* The reference to the define is held by the stack on return. */
|
7a6120 | 2016-09-04 | Henrik Grubbström (Grubba) | | static struct define_struct *alloc_empty_define(struct pike_string *name)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *def;
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | struct object *o;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | push_object(o = fast_clone_object(define_program));
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | def = (struct define_struct *)get_storage(o, define_program);
|
500d46 | 2016-09-06 | Henrik Grubbström (Grubba) | | add_ref(def->name = name);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | return def;
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @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
*! Note that when undefining a macro, you just give the identifer,
*! not the arguments.
*!
*! @example
*! // Strip debug
*! #define werror(X ...) 0
*! #include "/home/someone/experimental/stuff.h"
*! #undef werror
*!
*! @seealso
*! @[#define], @[defined()]
*/
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void undefine(struct CPP_struct *this, struct pike_string *name)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | ref_push_string(name);
push_int(0);
map_delete_no_free(this->defines, Pike_sp - 2, Pike_sp - 1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) == PIKE_T_OBJECT) {
struct object *o = Pike_sp[-1].u.object;
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *def = (struct define_struct *)get_storage(o, define_program);
|
7db6bc | 2016-09-08 | Henrik Grubbström (Grubba) | | if (def->flags & (CPP_MACRO_IN_USE | CPP_MACRO_DISABLED)) {
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | /* 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;
}
|
853819 | 2001-05-29 | Henrik Grubbström (Grubba) | | }
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | pop_n_elems(2);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @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>@}
*! @endcode
*!
*! which will cause all subsequent occurances of @tt{@b{@i{<identifier@}@}@}
*! to be replaced with the @tt{@i{<replacement string>@}@}.
*!
*! Define also has the capability to use arguments, thus a line like
*!
*! @code
*! #define @b{@i{<identifier>@}@}(arg1, arg2) @i{<replacement string>@}
*! @endcode
*!
*! would cause @tt{@b{@i{<identifer>@}@}@} to be a macro. All occurances of
*! '@tt{@b{@i{<identifier>@}@}(something1,something2d)@}' would be replaced
*! with the @tt{@i{<replacement string>@}@}.
*! And in the @tt{@i{<replacement string>@}@}, @tt{arg1@} and @tt{arg2@}
*! will be replaced with @tt{something1@} and @tt{something2@}.
*/
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static struct pike_string *make_define_name(struct CPP_struct *this,
|
a8e54c | 2016-09-06 | Martin Nilsson | | const char *name)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | if (this->prefix) {
struct string_builder s;
init_string_builder(&s, 0);
string_builder_append(&s, MKPCHARP_STR(this->prefix),
this->prefix->len);
string_builder_putchar(&s, '_');
|
75942b | 2018-01-12 | Martin Nilsson | | string_builder_strcat(&s, name);
|
a8e54c | 2016-09-06 | Martin Nilsson | | return finish_string_builder(&s);
}
return make_shared_string(name);
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static struct define_struct *do_magic_define(struct CPP_struct *this,
|
a8e54c | 2016-09-06 | Martin Nilsson | | const char *name,
magic_define_fun fun)
{
struct define_struct* def;
|
500d46 | 2016-09-06 | Henrik Grubbström (Grubba) | | struct pike_string *name_str = make_define_name(this, name);
def = alloc_empty_define(name_str);
free_string(name_str);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | def->magic=fun;
|
279a4f | 2016-09-03 | Henrik Grubbström (Grubba) | | mapping_string_insert(this->defines, def->name, Pike_sp-1);
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | pop_stack();
|
3c8ee5 | 2011-12-28 | Henrik Grubbström (Grubba) | | return def;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | static struct define_struct *add_define(struct CPP_struct *this,
struct pike_string *name,
struct svalue *what)
|
b584b1 | 2001-12-20 | Martin Stjernholm | | {
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | struct pike_string *orig_name = name;
struct define_struct *def;
if( (name->len > 2) &&
(index_shared_string(name, name->len-1) == ')') &&
(index_shared_string(name, name->len-2) == '(')) {
/* Function-style macro. */
push_string(name = string_slice(name, 0, name->len-2));
}
/* NB: alloc_empty_define() pushes the define object onto the stack.
*/
def = alloc_empty_define(name);
|
279a4f | 2016-09-03 | Henrik Grubbström (Grubba) | | mapping_string_insert(this->defines, def->name, Pike_sp-1);
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | pop_stack();
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | |
if (orig_name != name) {
/* Function-style macro. */
def->flags |= CPP_MACRO_VARARGS | CPP_MACRO_KEEP_NL;
def->args = 1;
pop_stack();
}
if (!what || ((TYPEOF(*what) == PIKE_T_INT) && !what->u.integer)) {
ref_push_string(empty_pike_string);
f_aggregate(1);
def->parts = Pike_sp[-1].u.array;
Pike_sp--;
} else if (TYPEOF(*what) == PIKE_T_ARRAY) {
def->parts = what->u.array;
add_ref(what->u.array);
} else {
push_svalue(what);
f_aggregate(1);
def->parts = Pike_sp[-1].u.array;
Pike_sp--;
}
return def;
|
b584b1 | 2001-12-20 | Martin Stjernholm | | }
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void simple_add_define(struct CPP_struct *this,
|
90e5e9 | 2014-05-13 | Martin Nilsson | | const char *name,
const char *what)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
500d46 | 2016-09-06 | Henrik Grubbström (Grubba) | |
struct pike_string *name_str = make_define_name(this, name);
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | push_text(what);
add_define(this, name_str, Pike_sp-1);
pop_stack();
|
500d46 | 2016-09-06 | Henrik Grubbström (Grubba) | | free_string(name_str);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static struct pike_string *recode_string(struct CPP_struct *this, struct pike_string *data)
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | {
/* 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.
*/
/* Heuristic:
*
* Index 0 | Index 1 | Interpretation
* --------+---------+------------------------------------------
* 0 | 0 | 32bit wide string.
* 0 | >0 | 16bit Unicode string.
* >0 | 0 | 16bit Unicode string reverse byte order.
* 0xfe | 0xff | 16bit Unicode string.
* 0xff | 0xfe | 16bit Unicode string reverse byte order.
* 0x7b | 0x83 | EBCDIC-US ("#c").
* 0x7b | 0x40 | EBCDIC-US ("# ").
* 0x7b | 0x09 | EBCDIC-US ("#\t").
* --------+---------+------------------------------------------
* Other | Other | 8bit standard string.
*
* Note that the tests below are more lenient than the table above.
* This shouldn't matter, since the other cases would be erroneus
* anyway.
*/
/* Add an extra reference to data, since we may return it as is. */
add_ref(data);
if ((!((unsigned char *)data->str)[0]) ||
(((unsigned char *)data->str)[0] == 0xfe) ||
(((unsigned char *)data->str)[0] == 0xff) ||
(!((unsigned char *)data->str)[1])) {
/* Unicode */
if ((!((unsigned char *)data->str)[0]) &&
(!((unsigned char *)data->str)[1])) {
/* 32bit Unicode (UCS4) */
|
bc861d | 1999-02-25 | Henrik Grubbström (Grubba) | | struct pike_string *new_str;
|
d0ad0a | 2000-08-08 | Henrik Grubbström (Grubba) | | ptrdiff_t len;
ptrdiff_t i;
ptrdiff_t j;
|
bc861d | 1999-02-25 | Henrik Grubbström (Grubba) | | p_wchar0 *orig = STR0(data);
p_wchar2 *dest;
if (data->len & 3) {
/* String len is not a multiple of 4 */
return data;
}
len = data->len/4;
new_str = begin_wide_shared_string(len, 2);
dest = STR2(new_str);
j = 0;
for(i=0; i<len; i++) {
dest[i] = (orig[j]<<24) | (orig[j+1]<<16) | (orig[j+2]<<8) | orig[j+3];
j += 4;
}
free_string(data);
return(end_shared_string(new_str));
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | } else {
|
9aa6ec | 1999-02-25 | Henrik Grubbström (Grubba) | | /* 16bit Unicode (UCS2) */
|
bc861d | 1999-02-25 | Henrik Grubbström (Grubba) | | if (data->len & 1) {
/* String len is not a multiple of 2 */
return data;
}
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | if ((!((unsigned char *)data->str)[1]) ||
(((unsigned char *)data->str)[1] == 0xfe)) {
/* Reverse Byte-order */
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | | struct pike_string *new_str = begin_shared_string(data->len);
|
9aa6ec | 1999-02-25 | Henrik Grubbström (Grubba) | | int i;
for(i=0; i<data->len; i++) {
new_str->str[i^1] = data->str[i];
}
free_string(data);
|
bc861d | 1999-02-25 | Henrik Grubbström (Grubba) | | data = end_shared_string(new_str);
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | }
|
9aa6ec | 1999-02-25 | Henrik Grubbström (Grubba) | | /* Note: We lose the extra reference to data here. */
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | push_string(data);
f_unicode_to_string(1);
|
19961b | 2017-04-08 | Martin Nilsson | | add_ref(data = Pike_sp[-1].u.string);
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | pop_stack();
|
bc861d | 1999-02-25 | Henrik Grubbström (Grubba) | | return data;
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | }
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | | } else if (data->str[0] == '{') {
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | /* EBCDIC */
/* Notes on EBCDIC:
*
* * EBCDIC conversion needs to first convert the first line
* according to EBCDIC-US, and then the rest of the string
* according to the encoding specified by the first line.
*
|
a4a172 | 2000-12-05 | Per Hedbor | | * * It's an error for a program written in EBCDIC not to
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | * start with a #charset directive.
*
* Obfuscation note:
*
* * This still allows the rest of the file to be written in
* another encoding than EBCDIC.
*/
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | |
/* First split out the first line.
*
* Note that codes 0x00 - 0x1f are the same in ASCII and EBCDIC.
*/
struct pike_string *new_str;
char *p = strchr(data->str, '\n');
char *p2;
|
d0ad0a | 2000-08-08 | Henrik Grubbström (Grubba) | | size_t len;
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | |
if (!p) {
return data;
}
len = p - data->str;
if (len < CONSTANT_STRLEN("#charset ")) {
return data;
}
new_str = begin_shared_string(len);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(new_str->str, data->str, len);
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | |
push_string(end_shared_string(new_str));
|
75367d | 2014-08-22 | Arne Goedeke | | push_static_text("ebcdic-us");
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | |
|
f34838 | 2018-07-30 | Henrik Grubbström (Grubba) | | if (safe_apply_current(f_CPP_decode_charset_fun_num, 2) &&
(TYPEOF(Pike_sp[-1]) == PIKE_T_STRING)) {
|
715e55 | 2003-11-14 | Martin Stjernholm | | /* Various consistency checks. */
|
19961b | 2017-04-08 | Martin Nilsson | | if ((Pike_sp[-1].u.string->size_shift) ||
(((size_t)Pike_sp[-1].u.string->len) < CONSTANT_STRLEN("#charset")) ||
(Pike_sp[-1].u.string->str[0] != '#')) {
|
715e55 | 2003-11-14 | Martin Stjernholm | | pop_stack();
return data;
}
}
else {
cpp_handle_exception (this, "Error decoding with charset 'ebcdic-us'");
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | | return data;
}
/* At this point the decoded first line is on the stack. */
/* Extract the charset name */
|
19961b | 2017-04-08 | Martin Nilsson | | p = Pike_sp[-1].u.string->str + 1;
|
371abe | 1999-02-26 | Henrik Grubbström (Grubba) | | while (*p && isspace(*((unsigned char *)p))) {
p++;
}
if (strncmp(p, "charset", CONSTANT_STRLEN("charset")) ||
!isspace(((unsigned char *)p)[CONSTANT_STRLEN("charset")])) {
pop_stack();
return data;
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | p += CONSTANT_STRLEN("charset") + 1;
while (*p && isspace(*((unsigned char *)p))) {
p++;
}
if (!*p) {
pop_stack();
return data;
}
/* Build a string of the trailing data
* NOTE:
* Keep the newline, so the linenumber info stays correct.
*/
new_str = begin_shared_string(data->len - len);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(new_str->str, data->str + len, data->len - len);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
push_string(end_shared_string(new_str));
stack_swap();
/* Build a string of the charset name */
p2 = p;
while(*p2 && !isspace(*((unsigned char *)p2))) {
p2++;
}
len = p2 - p;
new_str = begin_shared_string(len);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(new_str->str, p, len);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
pop_stack();
|
20c006 | 2004-06-30 | Henrik Grubbström (Grubba) | | ref_push_string(new_str = end_shared_string(new_str));
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | /* Decode the string */
|
f34838 | 2018-07-30 | Henrik Grubbström (Grubba) | | if (!safe_apply_current(f_CPP_decode_charset_fun_num, 2) ||
(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)) {
|
404563 | 2004-06-29 | Martin Nilsson | | cpp_handle_exception (this, "Error decoding with charset %S", new_str);
|
715e55 | 2003-11-14 | Martin Stjernholm | | free_string (new_str);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | return data;
}
|
715e55 | 2003-11-14 | Martin Stjernholm | | free_string (new_str);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
/* Accept the new string */
free_string(data);
|
19961b | 2017-04-08 | Martin Nilsson | | add_ref(data = Pike_sp[-1].u.string);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | pop_stack();
}
return data;
}
static struct pike_string *filter_bom(struct pike_string *data)
{
/* More notes:
*
* * Character 0xfeff (ZERO WIDTH NO-BREAK SPACE = BYTE ORDER MARK = BOM)
* needs to be filtered away before processing continues.
*/
|
7e1661 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t i;
ptrdiff_t j = 0;
ptrdiff_t len = data->len;
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | struct string_builder buf;
/* Add an extra reference to data here, since we may return it as is. */
add_ref(data);
if (!data->size_shift) {
return(data);
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | init_string_builder(&buf, data->size_shift);
if (data->size_shift == 1) {
/* 16 bit string */
p_wchar1 *ptr = STR1(data);
for(i = 0; i<len; i++) {
if (ptr[i] == 0xfeff) {
if (i != j) {
|
13d2d3 | 2004-11-14 | Martin Stjernholm | | string_builder_binary_strcat1 (&buf, ptr + j, i - j);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | j = i+1;
}
}
}
if ((j) && (i != j)) {
/* Add the trailing string */
|
13d2d3 | 2004-11-14 | Martin Stjernholm | | string_builder_binary_strcat1 (&buf, ptr + j, i - j);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | free_string(data);
data = finish_string_builder(&buf);
} else {
/* String didn't contain 0xfeff */
free_string_builder(&buf);
}
} else {
/* 32 bit string */
p_wchar2 *ptr = STR2(data);
for(i = 0; i<len; i++) {
if (ptr[i] == 0xfeff) {
if (i != j) {
|
13d2d3 | 2004-11-14 | Martin Stjernholm | | string_builder_binary_strcat2 (&buf, ptr + j, i - j);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | j = i+1;
}
}
}
if ((j) && (i != j)) {
/* Add the trailing string */
|
13d2d3 | 2004-11-14 | Martin Stjernholm | | string_builder_binary_strcat2 (&buf, ptr + j, i - j);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | free_string(data);
data = finish_string_builder(&buf);
} else {
/* String didn't contain 0xfeff */
free_string_builder(&buf);
}
}
return(data);
}
|
7b73fb | 2014-05-10 | Per Hedbor | | #define PUSH_STRING0(X,Y,Z) add_quoted_string( X,Y,0,Z)
|
1585cf | 2014-05-10 | Per Hedbor | | #define PUSH_STRING_SHIFT(X,Y,Z,A) add_quoted_string(X,Y,Z,A)
|
48c4ef | 2016-12-17 | Martin Nilsson | |
|
b7df6e | 2014-05-12 | Per Hedbor | | /*
* Generic macros
*/
|
efd97a | 2014-05-12 | Martin Nilsson | | #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)
|
fbd041 | 2016-10-01 | Henrik Grubbström (Grubba) | | #define FIND_END_OF_STRING(FLAGS) (pos=find_end_quote(this,data,len,pos,'\"',FLAGS))
#define FIND_END_OF_CHAR() (pos=find_end_quote(this,data,len,pos,'\'',CPP_END_AT_NEWLINE))
|
b7df6e | 2014-05-12 | Per Hedbor | | #define FIND_EOL_PRETEND() (pos=find_end_of_line(this,data,len,pos,0))
#define FIND_EOL() (pos=find_end_of_line(this,data,len,pos,1))
#define SKIPCOMMENT_INC_LINES() (pos=find_end_of_comment(this,data,len,pos,0))
#define SKIPCOMMENT() (pos=find_end_of_comment(this,data,len,pos,1))
#define FIND_EOS() (pos=find_eos(this,data,len,pos))
/* Skips horizontal whitespace and newlines. */
#define SKIPWHITE() (pos=skipwhite(this,data,pos))
/* Skips horizontal whitespace and escaped newlines. */
#define SKIPSPACE() (pos=skipspace(this,data,pos,1))
#define SKIPSPACE_PRETEND() (pos=skipspace(this,data,pos,0))
/* At entry pos points past the start quote.
* At exit pos points past the end quote.
*/
#define READSTRING(nf) (pos=readstring(this,data,len,pos,&nf,0))
#define READSTRING2(nf) (pos=readstring(this,data,len,pos,&nf,1))
|
2028f8 | 2014-07-21 | Per Hedbor | | #define READSTRING3(nf,ec) (pos=readstring_lit(this,data,len,pos,&nf,ec))
|
b7df6e | 2014-05-12 | Per Hedbor | | #define FIXSTRING(nf,outp) (pos=fixstring(this,data,len,pos,&nf,outp))
/* Gobble an identifier at the current position. */
#define GOBBLE_IDENTIFIER() dmalloc_touch (struct pike_string *, gobble_identifier(this,data,&pos))
#define READCHAR(C) (C=readchar(data,&pos,this))
#define DATA(X) INDEX_PCHARP(data,X)
|
efd97a | 2014-05-12 | Martin Nilsson | | #define HAS_PREFIX(X) \
|
b7df6e | 2014-05-12 | Per Hedbor | | ((begins_with(X,ADD_PCHARP(data,pos),sizeof(X),len-pos,0)) ? (pos += NELEM(X)),1 : 0)
|
1585cf | 2014-05-10 | Per Hedbor | |
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static void add_quoted_string( const void *str, ptrdiff_t len, int shift,
|
7b73fb | 2014-05-10 | Per Hedbor | | struct string_builder *dst )
{
struct pike_string *x = make_shared_binary_pcharp( MKPCHARP(str,shift), len );
string_builder_putchar( dst, '"' );
string_builder_quote_string( dst, x, 0, 0x7fffffff, 0 );
string_builder_putchar( dst, '"' );
free_string(x);
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t find_eos( struct CPP_struct *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos )
|
1585cf | 2014-05-10 | Per Hedbor | | {
while(pos < len)
{
|
b7df6e | 2014-05-12 | Per Hedbor | | switch (DATA(pos++)) {
|
1585cf | 2014-05-10 | Per Hedbor | | case '\n':
break;
case '/':
|
b7df6e | 2014-05-12 | Per Hedbor | | if (DATA(pos) == '/') {
|
1585cf | 2014-05-10 | Per Hedbor | | pos = find_end_of_line(this,data,len,pos,0);
break;
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if (DATA(pos) == '*') {
|
1585cf | 2014-05-10 | Per Hedbor | | pos = find_end_of_comment(this,data,len,pos,0);
}
continue;
case '\\':
|
b7df6e | 2014-05-12 | Per Hedbor | | if (DATA(pos) == '\n') {
|
1585cf | 2014-05-10 | Per Hedbor | | pos+=1;
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if ((DATA(pos) == '\r') &&
(DATA(pos+1) == '\n')) {
|
1585cf | 2014-05-10 | Per Hedbor | | pos+=2;
} else {
continue;
}
this->current_line++;
|
3595ea | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
1585cf | 2014-05-10 | Per Hedbor | | default:
continue;
}
this->current_line++;
break;
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t skipwhite(struct CPP_struct *this, const PCHARP data, ptrdiff_t pos)
|
1585cf | 2014-05-10 | Per Hedbor | | {
|
13670c | 2015-05-25 | Martin Nilsson | | do
|
1585cf | 2014-05-10 | Per Hedbor | | {
int c;
|
b7df6e | 2014-05-12 | Per Hedbor | | if(!wide_isspace(c=DATA(pos)))
|
1585cf | 2014-05-10 | Per Hedbor | | {
|
13670c | 2015-05-25 | Martin Nilsson | | if (c == '\\')
|
1585cf | 2014-05-10 | Per Hedbor | | {
|
13670c | 2015-05-25 | Martin Nilsson | | if (DATA(pos+1) == '\n')
|
1585cf | 2014-05-10 | Per Hedbor | | {
pos += 2;
PUTNL();
this->current_line++;
continue;
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if ((DATA(pos+1) == '\r') &&
(DATA(pos+2) == '\n')) {
|
1585cf | 2014-05-10 | Per Hedbor | | pos += 3;
PUTNL();
this->current_line++;
continue;
}
}
break;
}
|
13670c | 2015-05-25 | Martin Nilsson | | else if(c=='\n')
{
PUTNL(); this->current_line++;
|
1585cf | 2014-05-10 | Per Hedbor | | }
pos++;
} while(1);
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t skipspace(struct CPP_struct *this, const PCHARP data, ptrdiff_t pos, int emit)
|
1585cf | 2014-05-10 | Per Hedbor | | {
do {
int c;
|
b7df6e | 2014-05-12 | Per Hedbor | | while (wide_isspace(c=DATA(pos)) && c!='\n') {
|
1585cf | 2014-05-10 | Per Hedbor | | pos++;
}
if (c == '\\') {
|
b7df6e | 2014-05-12 | Per Hedbor | | if (DATA(pos+1) == '\n') {
|
1585cf | 2014-05-10 | Per Hedbor | | pos+=2;
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if ((DATA(pos+1) == '\r') &&
(DATA(pos+2) == '\n')) {
|
1585cf | 2014-05-10 | Per Hedbor | | pos+=3;
} else {
break;
}
} else {
break;
}
if( emit )
{
PUTNL();
this->current_line++;
}
} while (1);
return pos;
}
static const char eq_[] = { '=', '=' };
static const char ne_[] = { '!', '=' };
static const char land_[] = { '&', '&' };
static const char lor_[] = { '|', '|' };
static const char string_recur_[] =
{ 's', 't', 'r', 'i', 'n', 'g', '_', 'r', 'e', 'c', 'u', 'r' };
static const char include_recur_[] =
{ 'i', 'n', 'c', 'l', 'u', 'd', 'e', '_', 'r', 'e', 'c', 'u', 'r' };
static const char line_[] = { 'l', 'i', 'n', 'e' };
static const char string_[] = { 's', 't', 'r', 'i', 'n', 'g' };
static const char include_[] = { 'i', 'n', 'c', 'l', 'u', 'd', 'e' };
static const char if_[] = { 'i', 'f' };
static const char ifdef_[] = { 'i', 'f', 'd', 'e', 'f' };
static const char ifndef_[] = { 'i', 'f', 'n', 'd', 'e', 'f' };
static const char endif_[] = { 'e', 'n', 'd', 'i', 'f' };
static const char else_[] = { 'e', 'l', 's', 'e' };
static const char elseif_[] = { 'e', 'l', 's', 'e', 'i', 'f' };
static const char elif_[] = { 'e', 'l', 'i', 'f' };
static const char define_[] = { 'd', 'e', 'f', 'i', 'n', 'e' };
static const char undef_[] = { 'u', 'n', 'd', 'e', 'f' };
static const char undefine_[] = { 'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e' };
static const char charset_[] = { 'c', 'h', 'a', 'r', 's', 'e', 't' };
static const char pragma_[] = { 'p', 'r', 'a', 'g', 'm', 'a' };
static const char pike_[] = { 'p', 'i', 'k', 'e' };
static const char require_[] = { 'r', 'e', 'q', 'u', 'i', 'r', 'e' };
static const char lsh_[] = { '<', '<' };
static const char rsh_[] = { '>', '>' };
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static int begins_with( const char *prefix, const PCHARP stack, int len, int remain, int whole )
|
1585cf | 2014-05-10 | Per Hedbor | | {
int i;
|
74966e | 2014-05-12 | Per Hedbor | | if( len > remain )
return 0;
|
1585cf | 2014-05-10 | Per Hedbor | | for( i=0; i<len; i++ )
if( INDEX_PCHARP(stack,i) != prefix[i] )
return 0;
|
74966e | 2014-05-12 | Per Hedbor | |
if( whole && len != remain && wide_isidchar(INDEX_PCHARP(stack,len)) )
return 0;
|
1585cf | 2014-05-10 | Per Hedbor | | return 1;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t low_cpp(struct CPP_struct *this,
|
58efb8 | 2014-05-12 | Per Hedbor | | PCHARP data,
ptrdiff_t len,
int flags,
struct pike_string *charset);
|
7b73fb | 2014-05-10 | Per Hedbor | |
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc1(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags);
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calcC(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
SKIPWHITE();
CALC_DUMPPOS("calcC");
|
b7df6e | 2014-05-12 | Per Hedbor | | switch(DATA(pos))
|
74966e | 2014-05-12 | Per Hedbor | | {
case '(':
pos=calc1(this,data,len,pos+1,flags);
SKIPWHITE();
if(!GOBBLE(')'))
cpp_error(this, "Missing ')'");
break;
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | case '0':
|
b7df6e | 2014-05-12 | Per Hedbor | | if(DATA(pos+1)=='x' || DATA(pos+1)=='X')
|
74966e | 2014-05-12 | Per Hedbor | | {
PCHARP p = data;
INC_PCHARP(p,pos + 2);
push_int(0);
safe_wide_string_to_svalue_inumber(Pike_sp-1, p.ptr, &p.ptr, 16, 0, p.shift);
if(!OUTP()) pop_stack();
pos = SUBTRACT_PCHARP(p,data);
break;
}
|
3595ea | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
PCHARP p1,p2;
PCHARP p;
double f;
long l;
/* FIXME: Support bignums. */
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | p = ADD_PCHARP(data,pos);
f = STRTOD_PCHARP(p, &p1);
l = STRTOL_PCHARP(p, &p2, 0);
if(COMPARE_PCHARP(p1,>,p2))
{
if(OUTP())
|
bd6739 | 2015-10-14 | Martin Nilsson | | push_float((FLOAT_TYPE)f);
|
74966e | 2014-05-12 | Per Hedbor | | pos = SUBTRACT_PCHARP(p1,data);
}else{
if(OUTP())
push_int(l);
pos = SUBTRACT_PCHARP(p2,data);
}
break;
}
case '\'':
{
|
b7df6e | 2014-05-12 | Per Hedbor | | p_wchar2 tmp = DATA(++pos);
|
74966e | 2014-05-12 | Per Hedbor | | if (tmp == '\\') READCHAR(tmp);
pos++;
// FIXME: Multi char char constants here as well.
if(!GOBBLE('\''))
cpp_error(this, "Missing end quote in character constant.");
if(OUTP())
push_int(tmp);
break;
}
case '"':
{
struct string_builder s;
init_string_builder(&s, 0);
READSTRING(s);
if(OUTP())
push_string(finish_string_builder(&s));
else
free_string_builder(&s);
break;
}
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | default: {
struct pike_string *func_name = gobble_identifier(this,data,&pos);
|
b7df6e | 2014-05-12 | Per Hedbor | | if (func_name || DATA(pos) == '.') {
/* NOTE: defined() can not be handled here,
|
74966e | 2014-05-12 | Per Hedbor | | * since the argument must not be expanded.
*/
SKIPWHITE();
if ( (func_name==constant_str || func_name==efun_str) &&
|
b7df6e | 2014-05-12 | Per Hedbor | | DATA(pos) == '(')
|
74966e | 2014-05-12 | Per Hedbor | | {
int start, end;
int arg = 0;
INT_TYPE start_line;
if( func_name==efun_str && !CPP_TEST_COMPAT(this,7,9) )
cpp_warning(this, "Directive efun() deprecated.");
pos++; /* GOBBLE('(') */
start_line = this->current_line;
SKIPWHITE();
start = end = pos;
|
b7df6e | 2014-05-12 | Per Hedbor | | while (DATA(pos) != ')') {
switch(DATA(pos++)) {
|
74966e | 2014-05-12 | Per Hedbor | | case '(':
pos = find_end_parenthesis(this, data, len, pos);
break;
case ',':
push_string(make_shared_binary_pcharp(ADD_PCHARP(data,start), end-start));
arg++;
start = pos;
break;
case '/':
|
b7df6e | 2014-05-12 | Per Hedbor | | if (DATA(pos) == '*') {
|
74966e | 2014-05-12 | Per Hedbor | | pos++;
if (this->keep_comments) {
start = pos - 2;
SKIPCOMMENT_INC_LINES();
|
13670c | 2015-05-25 | Martin Nilsson | | } else
|
74966e | 2014-05-12 | Per Hedbor | | SKIPCOMMENT();
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if (DATA(pos) == '/') {
|
74966e | 2014-05-12 | Per Hedbor | | if (this->keep_comments) {
start = pos - 1;
FIND_EOL_PRETEND();
} else FIND_EOL();
}
break;
case '\0':
if (pos > len) {
INT_TYPE old_line = this->current_line;
this->current_line = start_line;
cpp_error_sprintf(this, "Missing ) in the meta function %S().",
func_name);
this->current_line = old_line;
free_string (func_name);
return pos-1;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
74966e | 2014-05-12 | Per Hedbor | | default:
|
a55090 | 2016-12-17 | Martin Nilsson | | if (wide_isspace(DATA(pos-1))) {
|
74966e | 2014-05-12 | Per Hedbor | | SKIPWHITE();
continue;
}
break;
}
end = pos;
}
|
b7df6e | 2014-05-12 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | if (start != end) {
push_string(make_shared_binary_pcharp(ADD_PCHARP(data,start), end-start));
arg++;
}
if(!GOBBLE(')')) {
INT_TYPE old_line = this->current_line;
this->current_line = start_line;
cpp_error_sprintf(this, "Missing ) in the meta function %S().",
func_name);
this->current_line = old_line;
}
/* NOTE: cpp_func MUST protect against errors. */
if(OUTP())
{
if (arg != 1) {
cpp_error_sprintf(this, "Bad number of arguments to %S().",
func_name);
pop_n_elems(arg);
push_int(0);
}
else
cpp_constant(this, 0);
}
else
pop_n_elems(arg);
|
b7df6e | 2014-05-12 | Per Hedbor | | } else if (DATA(pos) == '.') {
|
74966e | 2014-05-12 | Per Hedbor | | if (func_name == NULL)
add_ref((func_name = empty_pike_string));
while (GOBBLE('.')) {
struct pike_string *ind_name;
SKIPWHITE();
ind_name = gobble_identifier(this,data,&pos);
if (ind_name == NULL) {
cpp_error_sprintf(this, "Syntax error in #if missing identifier after '.'.");
free_string (func_name);
func_name = NULL;
break;
}
if(OUTP()) {
push_string (func_name);
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text (".");
|
74966e | 2014-05-12 | Per Hedbor | | push_string (ind_name);
f_add(3);
func_name = Pike_sp[-1].u.string;
--Pike_sp;
}
SKIPWHITE();
}
if (func_name == NULL)
break;
if(OUTP())
{
ref_push_string(func_name);
cpp_constant(this, 1);
}
} else {
if(OUTP())
push_int(0);
}
free_string (func_name);
break;
}
cpp_error_sprintf(this, "Syntax error in #if bad character %c (%d).",
|
b7df6e | 2014-05-12 | Per Hedbor | | DATA(pos), DATA(pos));
|
74966e | 2014-05-12 | Per Hedbor | | break;
}
}
SKIPWHITE();
while(GOBBLE('['))
{
CALC_DUMPPOS("inside calcC");
pos=calc1(this,data,len,pos,flags);
if(OUTP())
f_index(2);
SKIPWHITE();
if(!GOBBLE(']'))
cpp_error(this, "Missing ']'.");
}
CALC_DUMPPOS("after calcC");
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calcB(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calcB");
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | | switch(DATA(pos))
|
74966e | 2014-05-12 | Per Hedbor | | {
case '-': pos++; pos=calcB(this,data,len,pos,flags);
if(OUTP()) o_negate(); break;
case '!': pos++; pos=calcB(this,data,len,pos,flags);
if(OUTP()) o_not(); break;
case '~': pos++; pos=calcB(this,data,len,pos,flags);
if(OUTP()) o_compl(); break;
default: pos=calcC(this,data,len,pos,flags);
}
CALC_DUMPPOS("after calcB");
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calcA(struct CPP_struct *this,PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calcA");
pos=calcB(this,data,len,pos,flags);
while(1)
{
CALC_DUMPPOS("inside calcA");
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | | switch(DATA(pos))
|
74966e | 2014-05-12 | Per Hedbor | | {
case '/':
|
b7df6e | 2014-05-12 | Per Hedbor | | if(DATA(pos+1)=='/' ||
DATA(pos+1)=='*')
|
74966e | 2014-05-12 | Per Hedbor | | return pos;
pos++;
pos=calcB(this,data,len,pos,flags);
if(OUTP())
o_divide();
continue;
case '*':
pos++;
pos=calcB(this,data,len,pos,flags);
if(OUTP())
o_multiply();
continue;
case '%':
pos++;
pos=calcB(this,data,len,pos,flags);
if(OUTP())
o_mod();
continue;
}
break;
}
CALC_DUMPPOS("after calcA");
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc9(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc9");
pos=calcA(this,data,len,pos,flags);
while(1)
{
CALC_DUMPPOS("inside calc9");
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | | switch(DATA(pos))
|
74966e | 2014-05-12 | Per Hedbor | | {
case '+':
pos++;
pos=calcA(this,data,len,pos,flags);
if(OUTP())
f_add(2);
continue;
case '-':
pos++;
pos=calcA(this,data,len,pos,flags);
if(OUTP())
o_subtract();
continue;
}
break;
}
CALC_DUMPPOS("after calc9");
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc8(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc8");
pos=calc9(this,data,len,pos,flags);
while(1)
{
CALC_DUMPPOS("inside calc8");
SKIPWHITE();
|
efd97a | 2014-05-12 | Martin Nilsson | | if(HAS_PREFIX(lsh_))
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("Found <<");
pos=calc9(this,data,len,pos,flags);
if(OUTP())
o_lsh();
break;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | if(HAS_PREFIX(rsh_))
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("Found >>");
pos=calc9(this,data,len,pos,flags);
if(OUTP())
o_rsh();
break;
}
break;
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc7b(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc7b");
pos=calc8(this,data,len,pos,flags);
while(1)
{
CALC_DUMPPOS("inside calc7b");
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | |
switch(DATA(pos))
|
74966e | 2014-05-12 | Per Hedbor | | {
case '<':
|
b7df6e | 2014-05-12 | Per Hedbor | | if(DATA(pos+1) == '<') break;
|
74966e | 2014-05-12 | Per Hedbor | | pos++;
if(GOBBLE('='))
{
pos=calc8(this,data,len,pos,flags);
if(OUTP())
f_le(2);
}else{
pos=calc8(this,data,len,pos,flags);
if(OUTP())
f_lt(2);
}
continue;
case '>':
|
b7df6e | 2014-05-12 | Per Hedbor | | if(DATA(pos+1) == '>') break;
|
74966e | 2014-05-12 | Per Hedbor | | pos++;
if(GOBBLE('='))
{
pos=calc8(this,data,len,pos,flags);
if(OUTP())
f_ge(2);
}else{
pos=calc8(this,data,len,pos,flags);
if(OUTP())
f_gt(2);
}
continue;
}
break;
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc7(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc7");
pos=calc7b(this,data,len,pos,flags);
while(1)
{
CALC_DUMPPOS("inside calc7");
SKIPWHITE();
|
efd97a | 2014-05-12 | Martin Nilsson | | if(HAS_PREFIX(eq_))
|
74966e | 2014-05-12 | Per Hedbor | | {
pos=calc7b(this,data,len,pos,flags);
if(OUTP())
f_eq(2);
continue;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | if(HAS_PREFIX(ne_))
|
74966e | 2014-05-12 | Per Hedbor | | {
pos=calc7b(this,data,len,pos,flags);
if(OUTP())
f_ne(2);
continue;
}
break;
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc6(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc6");
pos=calc7(this,data,len,pos,flags);
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | | while(DATA(pos) == '&' && DATA(pos+1)!='&')
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("inside calc6");
pos++;
pos=calc7(this,data,len,pos,flags);
if(OUTP())
o_and();
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc5(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc5");
pos=calc6(this,data,len,pos,flags);
SKIPWHITE();
while(GOBBLE('^'))
{
CALC_DUMPPOS("inside calc5");
pos=calc6(this,data,len,pos,flags);
if(OUTP())
o_xor();
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc4(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc4");
pos=calc5(this,data,len,pos,flags);
SKIPWHITE();
|
b7df6e | 2014-05-12 | Per Hedbor | | while(DATA(pos) == '|' && DATA(pos+1)!='|')
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("inside calc4");
pos++;
pos=calc5(this,data,len,pos,flags);
if(OUTP())
o_or();
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc3(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc3");
pos=calc4(this,data,len,pos,flags);
SKIPWHITE();
|
efd97a | 2014-05-12 | Martin Nilsson | | while(HAS_PREFIX(land_))
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("inside calc3");
if(OUTP()) {
check_destructed(Pike_sp-1);
if(UNSAFE_IS_ZERO(Pike_sp-1))
{
pos=calc4(this,data,len,pos,flags|CPP_REALLY_NO_OUTPUT);
}else{
pop_stack();
pos=calc4(this,data,len,pos,flags);
}
} else
pos=calc4(this,data,len,pos,flags);
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc2(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc2");
pos=calc3(this,data,len,pos,flags);
SKIPWHITE();
|
efd97a | 2014-05-12 | Martin Nilsson | | while(HAS_PREFIX(lor_))
|
74966e | 2014-05-12 | Per Hedbor | | {
CALC_DUMPPOS("inside calc2");
if(OUTP()) {
check_destructed(Pike_sp-1);
if(!UNSAFE_IS_ZERO(Pike_sp-1))
{
pos=calc3(this,data,len,pos,flags|CPP_REALLY_NO_OUTPUT);
}else{
pop_stack();
pos=calc3(this,data,len,pos,flags);
}
} else
pos=calc3(this,data,len,pos,flags);
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc1(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t pos, int flags)
{
CALC_DUMPPOS("before calc1");
pos=calc2(this,data,len,pos,flags);
SKIPWHITE();
if(GOBBLE('?'))
{
int select = -1;
if(OUTP()) {
check_destructed(Pike_sp-1);
select = (UNSAFE_IS_ZERO(Pike_sp-1)?0:1);
pop_stack();
}
pos=calc1(this,data,len,pos,(select == 1? flags:(flags|CPP_REALLY_NO_OUTPUT)));
if(!GOBBLE(':'))
cpp_error(this, "Colon expected.");
pos=calc1(this,data,len,pos,(select == 0? flags:(flags|CPP_REALLY_NO_OUTPUT)));
}
return pos;
}
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static ptrdiff_t calc(struct CPP_struct *this, PCHARP data, ptrdiff_t len,
|
74966e | 2014-05-12 | Per Hedbor | | ptrdiff_t tmp, int flags)
{
JMP_BUF recovery;
ptrdiff_t pos;
CALC_DUMPPOS("Calculating");
if (SETJMP(recovery))
{
cpp_handle_exception (this, "Error evaluating expression.");
pos=tmp;
FIND_EOL();
push_int(0);
}else{
pos=calc1(this,data,len,tmp,flags);
check_destructed(Pike_sp-1);
}
UNSETJMP(recovery);
CALC_DUMPPOS("Done");
return pos;
}
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | /* NB: This function is only called from low_cpp(), which
* means that Pike_fp->current_object is an object(CPP).
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | *
* NB: The arguments (if any) are in an array at the top of the stack,
* and if none there is UNDEFINED.
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | */
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | static void apply_define(struct CPP_struct *this,
|
e0b777 | 2016-09-21 | Henrik Grubbström (Grubba) | | struct define_struct *d,
|
e19aca | 2018-01-06 | Henrik Grubbström (Grubba) | | short flags,
|
e0b777 | 2016-09-21 | Henrik Grubbström (Grubba) | | struct pike_string *charset)
{
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | struct svalue *save_sp = Pike_sp;
|
52791d | 2018-04-15 | Henrik Grubbström (Grubba) | | int save_flags;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
/* Keep d around... */
push_svalue(&d->self);
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | stack_swap();
if ((d->args == 1) && !Pike_sp[-1].u.array->size &&
!(d->flags & CPP_MACRO_VARARGS)) {
// Allow a single argument to be left out.
pop_stack();
ref_push_string(empty_pike_string);
f_aggregate(1);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | | }
ref_push_object(Pike_fp->current_object);
|
e21e1a | 2018-04-07 | Henrik Grubbström (Grubba) | | push_int(flags);
apply_lfun(d->self.u.object, LFUN_CALL, 3);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-1]) == PIKE_T_STRING) {
save_flags = d->flags;
d->flags |= CPP_MACRO_DISABLED;
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | /* NB: We're executing in the CPP context object. */
low_cpp(this, MKPCHARP_STR(Pike_sp[-1].u.string), Pike_sp[-1].u.string->len,
flags & ~(CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE),
charset);
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
d8009c | 2018-08-31 | Henrik Grubbström (Grubba) | | d->flags = save_flags;
} else {
this->compile_errors++;
}
|
42af9f | 2018-04-06 | Henrik Grubbström (Grubba) | |
|
cedd4a | 2018-08-26 | Henrik Grubbström (Grubba) | | /* NB: Pop the args array too... */
pop_n_elems(Pike_sp + 1 - save_sp);
|
e0b777 | 2016-09-21 | Henrik Grubbström (Grubba) | | }
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | /*
* Preprocessor template.
*
|
671034 | 2018-02-21 | Henrik Grubbström (Grubba) | | * NB: There are two basic cases where this function is called:
*
* * Either when switching to a new input data string
* (eg macro expansion or #include). The result of
* this is added to the current buffer.
*
* * Or parsing to the end of the line after a directive.
* The result of this is added to a temporary buffer.
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | */
static ptrdiff_t low_cpp(struct CPP_struct *this,
PCHARP data,
ptrdiff_t len,
int flags,
struct pike_string *charset)
{
ptrdiff_t pos, tmp, e;
int include_mode;
INT_TYPE first_line = this->current_line;
/* FIXME: What about this->current_file? */
for(pos=0; pos<len;)
{
ptrdiff_t old_pos = pos;
int c;
/* fprintf(stderr,"%c",DATA(pos));
fflush(stderr); */
switch(c = DATA(pos++))
{
case '\n':
if(flags & CPP_END_AT_NEWLINE) return pos-1;
/* fprintf(stderr,"CURRENT LINE: %d\n",this->current_line); */
this->current_line++;
PUTNL();
goto do_skipwhite;
case 0x1b: case 0x9b: /* ESC or CSI */
/* Assume ANSI/DEC escape sequence.
* Format supported:
* <ESC>[\040-\077]+[\100-\177]
* or
* <CSI>[\040-\077]*[\100-\177]
*/
/* FIXME: This place is far from enough to make these things
* behave as whitespace. /mast */
while ((tmp = DATA(pos)) && (tmp == ((tmp & 0x1f)|0x20))) {
pos++;
}
if (tmp == ((tmp & 0x3f)|0x40)) {
pos++;
} else {
/* FIXME: Warning here? */
}
PUTC(' ');
break;
case '\t':
case ' ':
case '\r':
PUTC(' ');
do_skipwhite:
while( wide_isspace(c=DATA(pos)) && c != '\n' && c != '\r' )
pos++;
break;
/* Minor optimization */
case '<': case '=': case '>':
if(DATA(pos)==c &&
DATA(pos+1)==c &&
DATA(pos+2)==c &&
DATA(pos+3)==c &&
DATA(pos+4)==c &&
DATA(pos+5)==c) {
cpp_error(this, "Merge conflict detected.");
PUTC(c);
do {
PUTC(c);
} while (DATA(++pos) == c);
continue;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | |
case '!': case '@': case '$': case '%': case '^': case '&':
case '*': case '(': case ')': case '-': case '+':
case '{': case '}': case ':': case '?': case '`': case ';':
case ',': case '.': case '~': case '[': case ']': case '|':
PUTC(DATA(pos-1));
break;
case '\\':
if(DATA(pos)=='\n') {
pos++;
this->current_line++;
PUTNL();
goto do_skipwhite;
}
else if ((DATA(pos) == '\r') && (DATA(pos+1) == '\n')) {
pos += 2;
this->current_line++;
PUTNL();
goto do_skipwhite;
}
/* Fall through - identifiers might begin with \uxxxx. */
default:
if(OUTP())
{
struct pike_string *s;
struct define_struct *d = NULL;
pos--;
s = GOBBLE_IDENTIFIER();
if (!s) {
PUTC (DATA(pos++));
break;
}
if(flags & CPP_DO_IF && s == defined_str)
{
/* NOTE: defined() must be handled here, since its argument
* must not be macro expanded.
*/
d = defined_macro;
}else{
d=FIND_DEFINE(s);
}
if(d && !(d->flags & CPP_MACRO_DISABLED))
{
INT_TYPE start_line = this->current_line;
struct string_builder tmp;
struct define_argument arguments[ MAX_ARGS];
if (d == defined_macro) {
free_string (s);
s = NULL;
}
if(d->args>=0)
{
SKIPWHITE();
if(!GOBBLE('('))
{
if (s) {
string_builder_shared_strcat(&this->buf,s);
free_string(s);
}
/* Restore the post-whitespace. */
string_builder_putchar(&this->buf, ' ');
break;
}
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | SKIPWHITE();
BEGIN_AGGREGATE_ARRAY(d->args) {
int arg=0;
|
556735 | 2018-08-28 | Henrik Grubbström (Grubba) | | while ((pos < len) && (DATA(pos) != ')')) {
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | PCHARP arg_start;
size_t arg_len;
if(arg) {
GOBBLE(',');
SKIPWHITE();
}
arg_start = ADD_PCHARP(data, pos);
while(1)
{
|
556735 | 2018-08-28 | Henrik Grubbström (Grubba) | | if(pos>=len)
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | {
INT_TYPE save_line = this->current_line;
this->current_line = start_line;
cpp_error(this, "End of file in macro call.");
this->current_line = save_line;
break;
}
switch(DATA(pos++))
{
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | case '\n':
this->current_line++;
PUTNL();
|
3595ea | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | default: continue;
case '"':
/* Note: Strings may contain \-escaped newlines.
* They must be removed on insertion to
* avoid being counted twice.
*/
if(DATA(pos-2)!='#') {
FIND_END_OF_STRING(CPP_END_AT_NEWLINE);
}else{
FIND_END_OF_STRING(0); /* Newlines allowed */
}
continue;
case '\'':
FIND_END_OF_CHAR();
continue;
case '/':
if (DATA(pos) == '*') {
pos++;
SKIPCOMMENT();
} else if (DATA(pos) == '/') {
FIND_EOL();
}
continue;
case '(':
pos=find_end_parenthesis(this, data, len, pos);
continue;
case '{':
pos=find_end_brace(this, data, len, pos);
continue;
case ',':
case ')':
pos--;
break;
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | }
break;
}
arg_len = SUBTRACT_PCHARP(ADD_PCHARP(data, pos), arg_start);
push_string(make_shared_binary_pcharp(arg_start, arg_len));
DO_AGGREGATE_ARRAY(120);
SKIPWHITE();
arg++;
}
} END_AGGREGATE_ARRAY;
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | if(!GOBBLE(')')) {
this->current_line = start_line;
cpp_error_sprintf(this, "Missing ) in the macro %S.", d->name);
}
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | | } else {
push_undefined();
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | }
|
bfd54a | 2018-08-25 | Henrik Grubbström (Grubba) | |
apply_define(this, d, flags, charset);
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | }else{
if (OUTP())
string_builder_shared_strcat (&this->buf, s);
}
if (s) {
free_string(s);
}
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
PUTC(DATA(pos-1));
while(DATA(pos)>='0' && DATA(pos)<='9') PUTC(DATA(pos++));
break;
case '"':
FIXSTRING(this->buf,OUTP());
break;
case '\'':
tmp=pos-1;
FIND_END_OF_CHAR();
if(OUTP())
string_builder_append( &this->buf, ADD_PCHARP(data, tmp), pos - tmp);
else
for (; tmp < pos; tmp++)
if (DATA(tmp) == '\n')
string_builder_putchar (&this->buf, '\n');
break;
case '/':
if(DATA(pos)=='/')
{
if (this->keep_comments) {
FIND_EOL_PRETEND();
goto ADD_TO_BUFFER;
}
FIND_EOL();
break;
}
if(DATA(pos)=='*')
{
if (this->keep_comments) {
SKIPCOMMENT_INC_LINES();
goto ADD_TO_BUFFER;
} else {
PUTC(' ');
SKIPCOMMENT();
}
break;
}
PUTC(DATA(pos-1));
break;
case '#':
if(GOBBLE('!'))
{
FIND_EOL();
break;
}
SKIPSPACE();
if (!CHECK_WORD(string_recur_, NELEM(string_recur_))
&& !CHECK_WORD(include_recur_, NELEM(include_recur_)))
{
if (this->prefix)
{
if( !begins_with( this->prefix->str, ADD_PCHARP(data,pos), this->prefix->len, len-pos, 0 ) ||
DATA(pos+this->prefix->len) != '_')
{
FIND_EOS();
goto ADD_TO_BUFFER;
}
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 (!wide_isidchar(DATA(i)))
break;
}
}
}
switch(DATA(pos))
{
case 'l':
{
if(GOBBLE_WORD(line_))
{
/* FIXME: Why not use SKIPSPACE()? */
/* Because SKIPSPACE skips newlines? - Hubbe */
/* Actually, no - Per */
while(DATA(pos)==' ' || DATA(pos)=='\t') pos++;
}else{
goto unknown_preprocessor_directive;
}
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
INT_TYPE new_lineno;
PCHARP foo = ADD_PCHARP(data,pos);
new_lineno=STRTOL_PCHARP(foo, &foo, 10)-1;
if(OUTP())
{
string_builder_binary_strcat(&this->buf, "#line ", 6);
string_builder_append(&this->buf, ADD_PCHARP(data,pos),
SUBTRACT_PCHARP(foo,ADD_PCHARP(data,pos)));
}
pos = SUBTRACT_PCHARP(foo,data);
SKIPSPACE();
if(DATA(pos)=='"')
{
struct string_builder nf;
init_string_builder(&nf, 0);
READSTRING(nf);
if(OUTP())
{
free_string(this->current_file);
this->current_file = finish_string_builder(&nf);
string_builder_putchar(&this->buf, ' ');
PUSH_STRING_SHIFT (this->current_file->str, this->current_file->len,
this->current_file->size_shift, &this->buf);
}else{
free_string_builder(&nf);
}
}
if (OUTP())
this->current_line = new_lineno;
FIND_EOL();
break;
}
case '"':
{
struct string_builder nf;
char end;
init_string_builder(&nf, 0);
READSTRING2(nf);
goto stringout;
case '(': end = ')'; goto litstring;
case '[': end = ']'; goto litstring;
case '{': end = '}';
litstring:
init_string_builder(&nf, 0);
READSTRING3(nf,end);
stringout:
if(OUTP())
PUSH_STRING_SHIFT(nf.s->str, nf.s->len,nf.s->size_shift, &this->buf);
free_string_builder(&nf);
break;
}
case 's':
{
if(GOBBLE_WORD(string_))
{
include_mode = 1;
goto do_include;
}
if(GOBBLE_WORD(string_recur_))
{
include_mode = 3;
goto do_include;
}
}
goto unknown_preprocessor_directive;
case 'i': /* include, if, ifdef */
{
int recur = 0;
if(GOBBLE_WORD(include_) || (recur = GOBBLE_WORD(include_recur_)))
{
if (recur) {
include_mode = 2;
} else {
include_mode = 0;
}
do_include:
{
struct svalue *save_sp=Pike_sp;
SKIPSPACE();
check_stack(3);
switch(DATA(pos++))
{
case '"':
{
struct string_builder nf;
init_string_builder(&nf, 0);
pos--;
READSTRING(nf);
push_string(finish_string_builder(&nf));
/* In Pike 7.7 and later filenames belonging to Pike
* are assumed to be encoded according to UTF-8.
*/
f_string_to_utf8(1);
ref_push_string(this->current_file);
push_int(1);
break;
}
case '<':
{
ptrdiff_t tmp = pos;
while(DATA(pos)!='>')
{
if(DATA(pos)=='\n')
{
cpp_error(this, "Expecting '>' in include.");
break;
}
pos++;
}
push_string(make_shared_binary_pcharp(ADD_PCHARP(data,tmp), pos-tmp));
/* In Pike 7.7 and later filenames belonging to Pike
* are assumed to be encoded according to UTF-8.
*/
f_string_to_utf8(1);
ref_push_string(this->current_file);
pos++;
push_int(0);
break;
}
default:
if (include_mode & 2) {
/* Macro expanding didn't help... */
cpp_error(this, "Expected file to include.");
break;
} else {
/* Try macro expanding (Bug 2440). */
struct string_builder save = this->buf, tmp;
INT_TYPE save_line = this->current_line;
init_string_builder(&this->buf, 0);
/* Prefix the buffer with the corresponding *_recur
* directive, to avoid infinite loops.
*/
if (include_mode & 1) {
string_builder_strcat(&this->buf, "#string_recur ");
} else {
string_builder_strcat(&this->buf, "#include_recur ");
}
pos--;
pos += low_cpp(this, ADD_PCHARP(data,pos), len - pos,
CPP_END_AT_NEWLINE,
charset);
string_builder_putchar(&this->buf, '\n');
tmp = this->buf;
this->buf = save;
/* We now have a #include-recur or #string-recur directive
* in tmp. Preprocess it.
*/
/* We're processing the line twice. */
this->current_line = save_line;
low_cpp(this, MKPCHARP_STR(tmp.s), tmp.s->len,
flags, charset);
free_string_builder(&tmp);
this->current_line = save_line;
string_builder_sprintf(&this->buf, "\n#line %ld ",
(long)save_line);
PUSH_STRING_SHIFT(this->current_file->str,
this->current_file->len,
this->current_file->size_shift,
&this->buf);
string_builder_putchar(&this->buf, '\n');
}
break;
}
if(Pike_sp==save_sp) {
break;
}
if(OUTP())
{
struct pike_string *new_file;
|
9c5967 | 2018-08-01 | Henrik Grubbström (Grubba) | | if (!safe_apply_current(f_CPP_handle_include_fun_num, 3) ||
(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)) {
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | cpp_handle_exception (this, "Couldn't find include file.");
pop_n_elems(Pike_sp-save_sp);
break;
}
|
9c5967 | 2018-08-01 | Henrik Grubbström (Grubba) | | new_file = Pike_sp[-1].u.string;
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | |
ref_push_string(new_file);
|
9c5967 | 2018-08-01 | Henrik Grubbström (Grubba) | | if (!safe_apply_current(f_CPP_read_include_fun_num, 1) ||
!((1<<TYPEOF(Pike_sp[-1])) & (BIT_STRING|BIT_INT))) {
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | cpp_handle_exception (this, "Couldn't read include file.");
pop_n_elems(Pike_sp-save_sp);
break;
} else if (TYPEOF(Pike_sp[-1]) == PIKE_T_INT) {
cpp_error_sprintf(this, "Couldn't read include file \"%S\".",
new_file);
pop_n_elems(Pike_sp-save_sp);
break;
}
{
struct pike_string *save_current_file;
INT_TYPE save_current_line;
save_current_file=this->current_file;
save_current_line=this->current_line;
copy_shared_string(this->current_file,new_file);
this->current_line=1;
string_builder_binary_strcat(&this->buf, "#line 1 ", 8);
PUSH_STRING_SHIFT(new_file->str, new_file->len,
new_file->size_shift, &this->buf);
string_builder_putchar(&this->buf, '\n');
if(include_mode & 1)
{
/* #string */
struct pike_string *str = Pike_sp[-1].u.string;
PUSH_STRING_SHIFT(str->str, str->len, str->size_shift,
&this->buf);
}else{
/* #include */
if (this->auto_convert) {
struct pike_string *new_str =
recode_string(this, Pike_sp[-1].u.string);
free_string(Pike_sp[-1].u.string);
Pike_sp[-1].u.string = new_str;
} else if (charset) {
ref_push_string(charset);
|
f34838 | 2018-07-30 | Henrik Grubbström (Grubba) | | if (!safe_apply_current(f_CPP_decode_charset_fun_num, 2) ||
(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)) {
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | cpp_handle_exception (this,
"Charset decoding failed for included file.");
pop_n_elems(Pike_sp - save_sp);
break;
}
}
if (Pike_sp[-1].u.string->size_shift) {
/* Get rid of any byte order marks (0xfeff) */
struct pike_string *new_str = filter_bom(Pike_sp[-1].u.string);
free_string(Pike_sp[-1].u.string);
Pike_sp[-1].u.string = new_str;
}
low_cpp(this,
MKPCHARP_STR(Pike_sp[-1].u.string),
Pike_sp[-1].u.string->len,
flags&~(CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE),
charset);
}
free_string(this->current_file);
this->current_file=save_current_file;
this->current_line=save_current_line;
|
75942b | 2018-01-12 | Martin Nilsson | | string_builder_sprintf(&this->buf, "\n#line %ld ", (long)this->current_line);
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | PUSH_STRING_SHIFT(this->current_file->str,
this->current_file->len,
this->current_file->size_shift,
&this->buf);
string_builder_putchar(&this->buf, '\n');
if ((include_mode & 2) && (pos < len)) {
/* NOTE: The rest of the current buffer has already been
* expanded once.
*/
string_builder_append(&this->buf, ADD_PCHARP(data, pos), len - pos);
pos = len;
}
}
}
pop_n_elems(Pike_sp-save_sp);
break;
}
}
if(GOBBLE_WORD(if_))
{
struct string_builder save, tmp;
INT32 nflags = 0;
if(!OUTP())
nflags = CPP_REALLY_NO_OUTPUT;
save=this->buf;
init_string_builder(&this->buf, 0);
pos += low_cpp(this, ADD_PCHARP(data,pos), len-pos,
nflags | CPP_END_AT_NEWLINE | CPP_DO_IF,
charset);
tmp=this->buf;
this->buf=save;
string_builder_putchar(&tmp, 0);
tmp.s->len--;
if (!nflags) {
calc(this,MKPCHARP_STR(tmp.s),tmp.s->len,0,0);
if(SAFE_IS_ZERO(Pike_sp-1)) nflags|=CPP_NO_OUTPUT;
pop_stack();
}
free_string_builder(&tmp);
pos += low_cpp(this, ADD_PCHARP(data,pos), len-pos,
nflags | CPP_EXPECT_ELSE | CPP_EXPECT_ENDIF,
charset);
break;
}
if(GOBBLE_WORD(ifdef_))
{
INT32 nflags;
struct pike_string *s;
SKIPSPACE();
s = GOBBLE_IDENTIFIER();
if(!s)
cpp_error(this, "#ifdef what?");
nflags = CPP_EXPECT_ELSE | CPP_EXPECT_ENDIF | CPP_NO_OUTPUT;
if(!OUTP())
nflags|=CPP_REALLY_NO_OUTPUT;
if (s) {
if(FIND_DEFINE(s))
nflags&=~CPP_NO_OUTPUT;
free_string (s);
}
pos += low_cpp(this, ADD_PCHARP(data,pos), len-pos, nflags,
charset);
break;
}
if(GOBBLE_WORD(ifndef_))
{
INT32 nflags;
struct pike_string *s;
SKIPSPACE();
s = GOBBLE_IDENTIFIER();
if(!s)
cpp_error(this, "#ifndef what?");
nflags=CPP_EXPECT_ELSE | CPP_EXPECT_ENDIF;
if(!OUTP())
nflags|=CPP_REALLY_NO_OUTPUT;
if (s) {
if(FIND_DEFINE(s))
nflags|=CPP_NO_OUTPUT;
free_string (s);
}
pos += low_cpp(this, ADD_PCHARP(data,pos), len-pos, nflags,
charset);
break;
}
goto unknown_preprocessor_directive;
}
case 'e': /* endif, else, elif, error */
{
if(GOBBLE_WORD(endif_))
{
if(!(flags & CPP_EXPECT_ENDIF))
cpp_error(this, "Unmatched #endif.");
return pos;
}
if(GOBBLE_WORD(else_))
{
if(!(flags & CPP_EXPECT_ELSE))
cpp_error(this, "Unmatched #else.");
flags&=~CPP_EXPECT_ELSE;
flags|=CPP_EXPECT_ENDIF;
|
1fc5a9 | 2018-01-17 | Henrik Grubbström (Grubba) | | flags ^= CPP_NO_OUTPUT;
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | break;
}
if(GOBBLE_WORD(elif_) || GOBBLE_WORD(elseif_))
{
if(!(flags & CPP_EXPECT_ELSE))
cpp_error(this, "Unmatched #elif.");
flags|=CPP_EXPECT_ENDIF;
if((flags & (CPP_NO_OUTPUT | CPP_REALLY_NO_OUTPUT)) == CPP_NO_OUTPUT)
{
struct string_builder save,tmp;
save=this->buf;
init_string_builder(&this->buf, 0);
pos += low_cpp(this, ADD_PCHARP(data,pos), len-pos,
CPP_END_AT_NEWLINE | CPP_DO_IF,
charset);
tmp=this->buf;
this->buf=save;
string_builder_putchar(&tmp, 0);
tmp.s->len--;
calc(this,MKPCHARP_STR(tmp.s),tmp.s->len,0,0);
free_string_builder(&tmp);
if(!SAFE_IS_ZERO(Pike_sp-1)) flags&=~CPP_NO_OUTPUT;
pop_stack();
} else {
FIND_EOL();
flags |= CPP_NO_OUTPUT | CPP_REALLY_NO_OUTPUT;
}
break;
}
}
goto unknown_preprocessor_directive;
case 'd': /* define */
{
if(GOBBLE_WORD(define_))
{
struct string_builder str;
INT32 argno=-1;
ptrdiff_t tmp3;
struct pike_string *def_name;
struct define_struct *def;
struct svalue *partbase,*argbase=Pike_sp;
int varargs=0;
SKIPSPACE();
def_name = GOBBLE_IDENTIFIER();
if(!def_name) {
cpp_error(this, "Define what?");
FIND_EOL();
break;
}
if(GOBBLE('('))
{
argno=0;
SKIPWHITE();
while(DATA(pos)!=')')
{
struct pike_string *arg_name;
if(argno)
{
if(!GOBBLE(','))
cpp_error(this,
"Expecting comma in macro definition.");
SKIPWHITE();
}
if(varargs)
cpp_error(this,"Expected ) after ...");
arg_name = GOBBLE_IDENTIFIER();
if(!arg_name)
{
cpp_error(this, "Expected argument for macro.");
break;
}
check_stack(1);
push_string(arg_name);
SKIPWHITE();
argno++;
if(argno>=MAX_ARGS)
{
cpp_error(this, "Too many arguments in macro definition.");
pop_stack();
argno--;
}
if(DATA(pos)=='.' && DATA(pos+1)=='.' && DATA(pos+2)=='.')
{
|
347b10 | 2018-04-19 | Henrik Grubbström (Grubba) | | varargs = CPP_MACRO_VARARGS;
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | pos+=3;
SKIPWHITE();
}
}
if(!GOBBLE(')'))
cpp_error(this, "Missing ) in macro definition.");
}
SKIPSPACE();
partbase=Pike_sp;
init_string_builder(&str, 0);
while(1)
{
INT32 extra=0;
ptrdiff_t old_pos = pos;
switch(DATA(pos++))
{
case '/':
if(DATA(pos)=='/')
{
if (this->keep_comments) {
FIND_EOL_PRETEND();
string_builder_append( &str, ADD_PCHARP(data, old_pos), pos-old_pos );
continue;
}
string_builder_putchar(&str, ' ');
FIND_EOL();
continue;
}
if(DATA(pos)=='*')
{
if (this->keep_comments) {
SKIPCOMMENT_INC_LINES();
string_builder_append( &str, ADD_PCHARP(data, old_pos), pos-old_pos );
continue;
}
PUTC(' ');
SKIPCOMMENT();
continue;
}
string_builder_putchar(&str, '/');
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
string_builder_putchar(&str, DATA(pos-1));
while(DATA(pos)>='0' && DATA(pos)<='9')
string_builder_putchar(&str, DATA(pos++));
continue;
case '\\':
if(GOBBLE('\n'))
{
this->current_line++;
PUTNL();
continue;
}
if (DATA(pos) == '\r' && DATA(pos+1) == '\n') {
pos += 2;
this->current_line++;
PUTNL();
continue;
}
/* Identifiers might start with \uxxxx, so try to parse
* an identifier now. */
goto gobble_identifier_in_define;
case ',':
{
int oldpos;
oldpos = pos;
SKIPSPACE_PRETEND();
if (DATA(pos) == '#' && DATA(pos+1) == '#') {
extra|= DEF_ARG_NEED_COMMA;
pos += 2;
goto concat_identifier;
} else {
pos = oldpos;
goto gobble_identifier_in_define;
}
}
case '#':
if(GOBBLE('#'))
{
extra= (extra & DEF_ARG_NEED_COMMA) | DEF_ARG_NOPRESPACE;
while(str.s->len && wide_isspace(index_shared_string(str.s,str.s->len-1)))
str.s->len--;
concat_identifier:
if(!str.s->len && Pike_sp-partbase>1)
{
#ifdef PIKE_DEBUG
if(TYPEOF(Pike_sp[-1]) != PIKE_T_INT)
Pike_fatal("Internal error in CPP\n");
#endif
Pike_sp[-1].u.integer|=DEF_ARG_NOPOSTSPACE;
}
}else{
extra=DEF_ARG_STRINGIFY;
}
SKIPSPACE();
pos++;
/* fall through */
gobble_identifier_in_define:
default: {
struct pike_string *s;
pos--;
s = GOBBLE_IDENTIFIER();
if (s)
{
tmp3=pos-1;
if(argno>0)
{
if (s->refs > 1)
{
for(e=0;e<argno;e++)
{
if(argbase[e].u.string == s)
{
check_stack(2);
push_string(finish_string_builder(&str));
init_string_builder(&str, 0);
push_int(e | extra);
extra=0;
break;
}
}
if(e!=argno) {
free_string (s);
continue;
}
}
}
string_builder_shared_strcat (&str, s);
free_string (s);
}else{
string_builder_putchar(&str, DATA(pos++));
}
extra=0;
continue;
}
case '"':
FIXSTRING(str, 1);
continue;
case '\'':
tmp3=pos-1;
FIND_END_OF_CHAR();
string_builder_append(&str, ADD_PCHARP(data, tmp3), pos - tmp3);
continue;
case '\n':
PUTNL();
this->current_line++;
/* Fallthrough */
case 0:
break;
}
push_string(finish_string_builder(&str));
break;
}
if(OUTP())
{
f_aggregate(Pike_sp - partbase);
def = alloc_empty_define(def_name);
def->args=argno;
|
347b10 | 2018-04-19 | Henrik Grubbström (Grubba) | | def->flags |= varargs;
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | |
add_ref(def->parts = Pike_sp[-2].u.array);
{
struct define_struct *d;
if ((d = FIND_DEFINE(def->name)) &&
(d->flags & (CPP_MACRO_IN_USE | CPP_MACRO_DISABLED))) {
cpp_error(this,
"Illegal to redefine a macro during its expansion.");
} else {
mapping_string_insert(this->defines, def->name, Pike_sp-1);
}
}
}
free_string (def_name);
pop_n_elems(Pike_sp-argbase);
break;
}
goto unknown_preprocessor_directive;
}
case 'u': /* undefine */
{
/* NOTE: Reuses undefine_ for undef_ */
if(GOBBLE_WORD(undefine_) || GOBBLE_WORD(undef_))
{
struct pike_string *s;
SKIPSPACE();
s = GOBBLE_IDENTIFIER();
if(!s) {
cpp_error(this, "Undefine what?");
break;
}
if(OUTP())
{
undefine(this,s);
}
free_string (s);
break;
}
goto unknown_preprocessor_directive;
}
case 'c': /* charset */
{
if (GOBBLE_WORD(charset_)) {
ptrdiff_t p;
struct pike_string *s;
if (flags & (CPP_EXPECT_ENDIF | CPP_EXPECT_ELSE)) {
/* Only allowed at the top-level */
cpp_error(this, "#charset directive inside #if/#endif.");
/* Skip to end of line */
while (DATA(pos) && DATA(pos) != '\n') {
pos++;
}
break;
}
SKIPSPACE();
p = pos;
while(DATA(pos) && !wide_isspace(DATA(pos))) {
pos++;
}
if (pos != p) {
/* The rest of the string. */
push_string( make_shared_binary_pcharp( ADD_PCHARP(data,pos), len-pos ) );
/* The charset name */
push_string( make_shared_binary_pcharp( ADD_PCHARP(data,p),pos-p));
|
f34838 | 2018-07-30 | Henrik Grubbström (Grubba) | | if (!safe_apply_current(f_CPP_decode_charset_fun_num, 2) ||
(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)) {
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | cpp_handle_exception (this, NULL);
} else {
low_cpp(this, MKPCHARP_STR(Pike_sp[-1].u.string),Pike_sp[-1].u.string->len,
flags, charset);
pop_stack();
}
/* FIXME: Is this the correct thing to return? */
return len;
} else {
cpp_error(this, "What charset?");
}
break;
}
goto unknown_preprocessor_directive;
}
default:
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | | unknown_preprocessor_directive:
{
struct pike_string *directive = GOBBLE_IDENTIFIER();
|
87fa59 | 2018-01-14 | Henrik Grubbström (Grubba) | | if (directive) {
struct svalue *fun = NULL;
struct svalue sv;
struct pike_string *directive_string =
add_shared_strings(MK_STRING("directive_"), directive);
int id = find_shared_string_identifier(directive_string,
Pike_fp->current_object->prog);
free_string(directive_string);
if (id >= 0) {
/* NB: This svalue holds no reference! */
SET_SVAL(sv, PIKE_T_FUNCTION, id, object, Pike_fp->current_object);
fun = &sv;
}
if(!fun && this->directives) {
/* Try a mapping lookup instead. */
fun = low_mapping_string_lookup(this->directives, directive);
}
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | | if (fun) {
ptrdiff_t foo;
|
8f942d | 2018-02-26 | Martin Nilsson | | free_string(directive);
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | |
|
e0c30f | 2018-02-26 | Martin Nilsson | | SKIPSPACE();
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | | foo = pos;
FIND_EOL();
push_int(flags);
push_string(make_shared_binary_pcharp(ADD_PCHARP(data,foo), pos-foo));
safe_apply_svalue(fun, 2, 1);
if ((TYPEOF(Pike_sp[-1]) == PIKE_T_STRING) &&
Pike_sp[-1].u.string->len) {
/* We need to recurse. */
low_cpp(this, MKPCHARP_STR(Pike_sp[-1].u.string),
|
9e1a9b | 2018-03-02 | Henrik Grubbström (Grubba) | | Pike_sp[-1].u.string->len,
flags & ~CPP_EXPECT_ENDIF, charset);
|
86bc4e | 2018-01-12 | Henrik Grubbström (Grubba) | | }
pop_stack();
break;
}
|
ee311a | 2018-02-26 | Martin Nilsson | | }
if(!OUTP() && !this->picky_cpp)
|
8f942d | 2018-02-26 | Martin Nilsson | | {
if(directive) free_string(directive);
|
ee311a | 2018-02-26 | Martin Nilsson | | break;
|
8f942d | 2018-02-26 | Martin Nilsson | | }
|
ee311a | 2018-02-26 | Martin Nilsson | |
if (directive) {
cpp_error_sprintf(this, "Unknown preprocessor directive %S.",
directive);
free_string(directive);
} else {
cpp_error_sprintf(this, "Invalid preprocessor directive character at %d: '%c'.",
pos, DATA(pos));
}
}
|
e7bcc5 | 2018-01-11 | Henrik Grubbström (Grubba) | | }
}
continue;
ADD_TO_BUFFER:
// keep line
string_builder_append(&this->buf, ADD_PCHARP(data,old_pos), pos-old_pos);
}
if(flags & CPP_EXPECT_ENDIF) {
INT_TYPE saved_line = this->current_line;
this->current_line = first_line;
cpp_error(this, "End of file while searching for #endif.");
this->current_line = saved_line;
}
return pos;
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
671034 | 2018-02-21 | Henrik Grubbström (Grubba) | | PIKEFUN void low_cpp(string data, int flags)
|
6ae186 | 2018-01-13 | Henrik Grubbström (Grubba) | | {
|
694b0b | 2018-07-26 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = THIS;
#ifdef PIKE_DEBUG
ONERROR tmp;
SET_ONERROR(tmp, fatal_on_error, "Preprocessor exited with longjump!\n");
#endif /* PIKE_DEBUG */
low_cpp(this, MKPCHARP_STR(data), data->len, flags, this->charset);
#ifdef PIKE_DEBUG
UNSET_ONERROR(tmp);
#endif /* PIKE_DEBUG */
|
6ae186 | 2018-01-13 | Henrik Grubbström (Grubba) | | }
|
671034 | 2018-02-21 | Henrik Grubbström (Grubba) | | PIKEFUN string cpp(string data, int flags)
{
struct CPP_struct *this = THIS;
struct string_builder save_buf = this->buf;
struct pike_string *save_file = this->current_file;
INT_TYPE save_line = this->current_line;
|
694b0b | 2018-07-26 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
ONERROR tmp;
SET_ONERROR(tmp, fatal_on_error, "Preprocessor exited with longjump!\n");
#endif /* PIKE_DEBUG */
|
671034 | 2018-02-21 | Henrik Grubbström (Grubba) | |
if (save_file) add_ref(save_file);
init_string_builder(&this->buf, 0);
low_cpp(this, MKPCHARP_STR(data), data->len, flags, THIS->charset);
push_string(finish_string_builder(&this->buf));
this->buf = save_buf;
if (this->current_file) free_string(this->current_file);
this->current_file = save_file;
this->current_line = save_line;
|
694b0b | 2018-07-26 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
UNSET_ONERROR(tmp);
#endif /* PIKE_DEBUG */
|
671034 | 2018-02-21 | Henrik Grubbström (Grubba) | | }
|
a975cb | 2018-08-08 | Henrik Grubbström (Grubba) | | PIKEFUN string high_cpp(string data)
|
0e383e | 2018-07-31 | Henrik Grubbström (Grubba) | | {
struct CPP_struct *this = THIS;
if (this->charset) {
ref_push_string(this->charset);
apply_current(f_CPP_decode_charset_fun_num, 2);
if (TYPEOF(Pike_sp[-1]) != PIKE_T_STRING) {
cpp_handle_exception (this, "Error decoding with charset %S",
THIS->charset);
Pike_error("Unknown charset.\n");
}
data = Pike_sp[-1].u.string;
}
if (this->auto_convert && (!data->size_shift) && (data->len > 1)) {
/* Try to determine if we need to recode the string */
data = recode_string(this, data);
push_string(data);
}
if (data->size_shift) {
/* Get rid of any byte order marks (0xfeff) */
data = filter_bom(data);
push_string(data);
}
push_int(0); /* flags */
apply_current(f_CPP_low_cpp_fun_num, 2);
|
a975cb | 2018-08-08 | Henrik Grubbström (Grubba) | |
if(this->compile_errors)
{
throw_error_object(fast_clone_object(cpp_error_program), 0, 0,
"Cpp() failed.\n");
}
else if(this->dependencies_fail)
{
push_int(0);
}
else
{
push_string(finish_string_builder(&this->buf));
/* NB: Make sure the buffer isn't freed twice. */
this->buf.s = NULL;
}
|
2b14ff | 2018-09-05 | Henrik Grubbström (Grubba) | |
/* Zap all macros to break any circularities via the mapping. */
if (this->defines) {
clear_mapping(this->defines);
}
|
0e383e | 2018-07-31 | Henrik Grubbström (Grubba) | | }
|
9a0a00 | 2018-07-23 | Henrik Grubbström (Grubba) | | PIKEFUN string drain()
{
struct CPP_struct *this = THIS;
push_string(finish_string_builder(&this->buf));
init_string_builder(&this->buf, 0);
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | /*** Magic defines ***/
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | /*! @decl constant __LINE__
*!
*! This define contains the current line number, represented as an
*! integer, in the source file.
*/
PIKEFUN string macro___LINE__()
{
struct CPP_struct *this = THIS;
push_text(" %d ");
push_int64(this->current_line);
f_sprintf(2);
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | /*! @decl constant __FILE__
*!
*! This define contains the file path and name of the source file.
*/
PIKEFUN string macro___FILE__()
{
struct CPP_struct *this = THIS;
push_text(" %q ");
ref_push_string(this->current_file);
f_sprintf(2);
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __DIR__
*!
*! This define contains the directory path of the source file.
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_current_dir_as_string(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *UNUSED(arg),
|
15107c | 2008-06-12 | Martin Nilsson | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
d85cc3 | 2008-06-13 | Henrik Grubbström (Grubba) | | ref_push_string(this->current_file);
|
03b990 | 2009-03-08 | Henrik Grubbström (Grubba) | | /* FIXME: This isn't safe if the master hasn't been compiled yet. */
|
89b83e | 2008-06-29 | Marcus Comstedt | | SAFE_APPLY_MASTER("dirname",1);
|
15107c | 2008-06-12 | Martin Nilsson | | PUSH_STRING_SHIFT(Pike_sp[-1].u.string->str, Pike_sp[-1].u.string->len,
Pike_sp[-1].u.string->size_shift, tmp);
pop_stack();
}
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | /*! @decl constant __TIME__
*!
*! This define contains the current time at the time of compilation,
*! e.g. "12:20:51".
*/
PIKEFUN string macro___TIME__()
{
/* FIXME: Is this code safe? */
time_t tmp2;
char *buf;
push_text(" %q ");
time(&tmp2);
/* NB: The following code assumes that ctime() has the output format::
*
* "Day Mon DD HH:MM:SS YYYY\n"
* ^ ^ ^
* 0 11 11+8
*/
buf=ctime(&tmp2);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | buf[11+8] = 0;
push_text(buf + 11);
f_sprintf(2);
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | /*! @decl constant __DATE__
*!
*! This define contains the current date at the time of compilation,
*! e.g. "Jul 28 2001".
*/
PIKEFUN string macro___DATE__()
{
/* FIXME: Is this code safe? */
time_t tmp2;
char *buf;
push_text(" %q ");
time(&tmp2);
/* NB: The following code assumes that ctime() has the output format::
*
* "Day Mon DD HH:MM:SS YYYY\n"
* ^ ^ ^ ^ ^
* 0 4 4+6 19 19+5
*/
buf=ctime(&tmp2);
memcpy(buf+4+6, buf+19, 5);
buf[4+6+5] = 0;
push_text(buf + 4);
f_sprintf(2);
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | |
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __VERSION__
*!
*! This define contains the current Pike version as a float. If
*! another Pike version is emulated, this define is updated
*! accordingly.
*!
*! @seealso
*! @[__REAL_VERSION__]
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_current_version(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *UNUSED(arg),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
c060b5 | 2004-11-14 | Henrik Grubbström (Grubba) | | string_builder_sprintf(tmp, " %d.%d ", this->compat_major,
|
ce5d48 | 2004-11-14 | Martin Nilsson | | this->compat_minor);
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | }
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __MINOR__
*! This define contains the minor part of the current Pike version,
*! represented as an integer. If another Pike version is emulated,
*! this define is updated accordingly.
*!
*! @seealso
*! @[__REAL_MINOR__]
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_current_minor(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *UNUSED(arg),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
c060b5 | 2004-11-14 | Henrik Grubbström (Grubba) | | string_builder_sprintf(tmp, " %d ", this->compat_minor);
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | }
|
ce261a | 2014-08-26 | Per Hedbor | | /*! @decl int(1..) __COUNTER__
*! This define contains a unique counter (unless it has been expanded
|
6a5998 | 2016-04-27 | Chris Angelico | | *! Int.NATIVE_MAX times) represented as an integer.
|
ce261a | 2014-08-26 | Per Hedbor | | *!
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_current_counter(struct object *UNUSED(cpp_obj),
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *UNUSED(arg),
|
ce261a | 2014-08-26 | Per Hedbor | | struct string_builder *tmp)
{
static int counter = 0;
string_builder_sprintf(tmp, " %d ", ++counter);
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __MAJOR__
*!
*! This define contains the major part of the current Pike version,
*! represented as an integer. If another Pike version is emulated,
*! this define is updated accordingly.
*!
*! @seealso
*! @[__REAL_MAJOR__]
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_current_major(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *UNUSED(arg),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
c060b5 | 2004-11-14 | Henrik Grubbström (Grubba) | | string_builder_sprintf(tmp, " %d ", this->compat_major);
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | }
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | /* _Pragma(STRING) */
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl void _Pragma(string directive)
*!
*! This macro inserts the corresponding @[#pragma] @[directive]
*! in the source.
*!
*! e.g. @expr{_Pragma("strict_types")@} is the same
*! as @expr{#pragma strict_types@} .
*!
*! @seealso
*! @[#pragma]
*/
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | static void insert_pragma(struct object *cpp_obj,
|
7962c0 | 2016-09-01 | Henrik Grubbström (Grubba) | | struct define_struct *UNUSED(def),
|
3d6a1d | 2016-08-21 | Martin Nilsson | | struct pike_string *arg,
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
|
0e14b3 | 2018-07-28 | Henrik Grubbström (Grubba) | | struct CPP_struct *this = get_storage(cpp_obj, CPP_program);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | int i;
int in_string = 0;
/* Make some reasonable amount of space. */
|
3d6a1d | 2016-08-21 | Martin Nilsson | | string_build_mkspace(tmp, arg->len + 20, arg->size_shift);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | |
string_builder_strcat(tmp, "\n#pragma ");
/* Destringize the argument. */
|
3d6a1d | 2016-08-21 | Martin Nilsson | | for (i = 0; i < arg->len; i++) {
p_wchar2 ch = index_shared_string(arg, i);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | switch(ch) {
case '\n': case '\r':
ch = ' ';
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | case ' ': case '\t':
if (in_string) {
string_builder_putchar(tmp, ch);
}
break;
case '\"':
in_string = !in_string;
break;
case '\\':
if (in_string) {
|
3d6a1d | 2016-08-21 | Martin Nilsson | | ch = (++i < arg->len) ? index_shared_string(arg, i) : '\0';
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | if ((ch != '\\') && (ch != '\"')) {
cpp_error(this, "Invalid \\-escape in _Pragma().");
break;
}
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | | /* FALLTHRU */
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | default:
if (in_string) {
string_builder_putchar(tmp, ch);
} else {
cpp_error(this, "Invalid character outside of string.");
}
break;
}
}
if (in_string) {
cpp_error(this, "Unterminated string constant.");
}
|
e82c17 | 2012-07-22 | Arne Goedeke | | string_builder_sprintf(tmp, "\n#line %ld ", (long)this->current_line);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | PUSH_STRING_SHIFT(this->current_file->str,
this->current_file->len,
this->current_file->size_shift,
tmp);
string_builder_putchar(tmp, '\n');
}
|
676e41 | 2001-07-28 | Martin Nilsson | |
/*! @decl constant __REAL_VERSION__
*!
*! This define always contains the version of the current Pike,
*! represented as a float.
*!
*! @seealso
*! @[__VERSION__]
*/
/*! @decl constant __REAL_MAJOR__
*!
*! This define always contains the major part of the version of the
*! current Pike, represented as an integer.
*!
*! @seealso
*! @[__MAJOR__]
*/
/*! @decl constant __REAL_MINOR__
*!
*! This define always contains the minor part of the version of the
*! current Pike, represented as an integer.
*!
*! @seealso
*! @[__MINOR__]
*/
/*! @decl constant __BUILD__
*! This constant contains the build number of the current Pike version,
*! represented as an integer. If another Pike version is emulated,
*! this constant remains unaltered.
*!
*! @seealso
*! @[__REAL_MINOR__]
*/
/*! @decl constant __REAL_BUILD__
*!
*! This define always contains the minor part of the version of the
*! current Pike, represented as an integer.
*!
*! @seealso
*! @[__BUILD__]
*/
|
aba09a | 2011-12-28 | Henrik Grubbström (Grubba) | | /*! @decl constant static_assert
*!
*! This define expands to the symbol @[_Static_assert].
*!
*! It is the preferred way to perform static
*! (ie compile-time) assertions.
*!
*! @note
*! The macro can also be used to check for whether static assertions
*! are supported.
*!
*! @seealso
|
2d5df6 | 2013-05-04 | Henrik Grubbström (Grubba) | | *! @[predef::_Static_assert()]
|
aba09a | 2011-12-28 | Henrik Grubbström (Grubba) | | */
|
676e41 | 2001-07-28 | Martin Nilsson | | /*! @decl constant __PIKE__
*!
*! This define is always true.
*/
/*! @decl constant __AUTO_BIGNUM__
*!
*! This define is defined when automatic bignum conversion is enabled.
*! When enabled all integers will automatically be converted to
*! bignums when they get bigger than what can be represented by
*! an integer, hampering performance slightly instead of crashing
|
d6d2e5 | 2016-06-10 | Martin Nilsson | | *! the program. This define is always set since Pike 8.0.
|
676e41 | 2001-07-28 | Martin Nilsson | | */
/*! @decl constant __NT__
*!
*! This define is defined when the Pike is running on a Microsoft Windows OS,
*! not just Microsoft Windows NT, as the name implies.
*/
|
0c9594 | 2018-01-12 | Stephen R. van den Berg | | /*! @decl constant __amigaos__
*!
*! This define is defined when the Pike is running on Amiga OS.
*/
|
522042 | 2003-04-01 | Martin Nilsson | | /*! @endnamespace */
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | /*! @decl void create(string|void current_file, @
*! int|string|void charset, object|void handler, @
*! void|int compat_major, void|int compat_minor, @
*! void|int picky_cpp)
*! @decl void create(mapping(string:mixed) options)
*!
*! Initialize the preprocessor.
*!
*! @param options
*! If the first 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 then 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.
|
13256b | 2018-09-04 | Henrik Grubbström (Grubba) | | *! @member mapping(string:mixed) "predefines"
*! Mapping of predefined macros in addition to those
*! returned by @[CPP()->get_predefines()].
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | *! @endmapping
*!
*! @param current_file
*! If the @[current_file] argument has not been specified,
*! it will default to @expr{"-"@}.
*!
*! @param charset
|
17bd99 | 2018-08-13 | Per Cederqvist | | *! Turn on automatic character set detection if @expr{1@}, otherwise
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | *! specifies the character set used by the input.
*! Defaults to @expr{"ISO-10646"@}.
*!
*! @seealso
*! @[compile()]
*/
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | 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)
flags ID_PROTECTED;
{
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;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | int add_line_directive = this->current_line != 1;
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | |
this->prefix = NULL;
this->current_line=1;
this->compile_errors=0;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->defines) {
free_mapping(this->defines);
this->defines = NULL; /* Paranoia */
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | 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) {
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,"\
"got type %s for " name ".", get_name_of_type(PIKE_T_##type), get_name_of_type(TYPEOF(*tmp))), 0)))
if (GET_TYPE(STRING, "current_file")) current_file = tmp->u.string;
|
3b1b19 | 2018-07-21 | Henrik Grubbström (Grubba) | | if ((tmp = simple_mapping_string_lookup(m, "charset"))) {
if ((TYPEOF(*tmp) == PIKE_T_STRING) ||
(TYPEOF(*tmp) == PIKE_T_INT)) {
charset_sv = tmp;
} else {
Pike_error("Expected type string|int, got type %s for charset.",
get_name_of_type(TYPEOF(*tmp)));
}
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | if (GET_TYPE(OBJECT, "handler")) handler = tmp->u.object;
if (GET_TYPE(INT, "compat_major")) compat_major = tmp->u.integer;
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;
|
13256b | 2018-09-04 | Henrik Grubbström (Grubba) | | if (GET_TYPE(MAPPING, "predefines")) {
ref_push_mapping(tmp->u.mapping);
apply_current(f_CPP_define_multiple_macros_fun_num, 1);
pop_stack();
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | #undef GET_TYPE
} else if (TYPEOF(*opts_or_file) == PIKE_T_STRING) {
current_file = opts_or_file->u.string;
}
}
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if(current_file) {
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | add_ref(current_file);
|
77a282 | 2018-07-15 | Henrik Grubbström (Grubba) | | if (!this->current_file && (current_file->len == 1) &&
!current_file->size_shift && current_file->str[0] == '-') {
/* Noop */
} else if (this->current_file != current_file) add_line_directive = 1;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | } else {
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | current_file = make_shared_string("-");
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->current_file && (this->current_file != current_file)) {
add_line_directive = 1;
}
}
if (this->current_file) {
free_string(this->current_file);
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | this->current_file = current_file;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (add_line_directive) {
string_builder_binary_strcat(&this->buf, "#line 1 ", 8);
PUSH_STRING_SHIFT(current_file->str,
current_file->len,
current_file->size_shift,
&this->buf);
string_builder_putchar(&this->buf, '\n');
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | this->compat_major=PIKE_MAJOR_VERSION;
this->compat_minor=PIKE_MINOR_VERSION;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->compat_handler) {
free_object(this->compat_handler);
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | this->compat_handler = 0;
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->handler) {
free_object(this->handler);
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | this->handler = handler;
if(handler)
add_ref(handler);
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->prefix) {
free_string(this->prefix);
this->prefix = NULL;
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | if (prefix) {
int i;
if (prefix->size_shift) {
Pike_error("No widechars allowed in cpp prefix.\n");
}
for (i = 0; i < prefix->len; i++) {
if (!wide_isidchar(prefix->str[i])) {
Pike_error("Invalid char in prefix.\n");
}
}
this->prefix = prefix;
add_ref(prefix);
}
|
f06416 | 2018-07-13 | Henrik Grubbström (Grubba) | | if (this->charset) {
free_string(this->charset);
this->charset = NULL;
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | if(charset_sv) {
if(TYPEOF(*charset_sv) == T_STRING) {
this->charset = charset_sv->u.string;
add_ref(this->charset);
}
else if(TYPEOF(*charset_sv) == T_INT)
this->auto_convert = charset_sv->u.integer;
else {
SIMPLE_ARG_TYPE_ERROR("cpp", 3, "string|int");
}
}
|
edcd27 | 2018-08-11 | Henrik Grubbström (Grubba) | | if(compat_major) {
push_int(compat_major);
push_int(compat_minor);
apply_current(f_CPP_change_cpp_compatibility_fun_num, 2);
pop_stack();
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | |
this->picky_cpp = picky_cpp;
|
3b25dd | 2018-01-12 | Martin Nilsson | | pop_n_elems(args);
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | }
|
3d7b41 | 2018-09-02 | Henrik Grubbström (Grubba) | | /*! @decl void clear_macros()
*!
*! Clear the set of macros.
*!
*! It is recomended to call this function when the @[CPP] object
*! is no longer to be used.
*!
*! @seealso
*! @[define_macro()]
*/
PIKEFUN void clear_macros()
{
struct CPP_struct *this = THIS;
if (this->defines) {
clear_mapping(this->defines);
}
}
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | /*! @decl void define_macro(string name,
*! string|object|array|function|void value)
|
72d4db | 2018-06-06 | Henrik Grubbström (Grubba) | | *!
*! Define a cpp macro.
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[define_multiple_macros()]
|
72d4db | 2018-06-06 | Henrik Grubbström (Grubba) | | */
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | PIKEFUN void define_macro(string name,
string|object|array|function|void value)
|
72d4db | 2018-06-06 | Henrik Grubbström (Grubba) | | {
struct CPP_struct *this = THIS;
add_define(this, name, value);
}
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | #cmod_define DO_MAGIC_DEFINE(SYM) do { \
push_text(#SYM); \
ref_push_function(Pike_fp->current_object, \
f_CPP_macro_ ## SYM ## _fun_num + \
Pike_fp->context->identifier_level); \
apply_current(f_CPP_define_macro_fun_num, 2); \
pop_stack(); \
} while(0)
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | /*! @decl void define_ansi_macros()
*!
*! Adds some cpp macros defined by the ANSI-C standards,
*! such as @[__FILE__], @[__LINE__], etc.
*!
*! @seealso
|
72d4db | 2018-06-06 | Henrik Grubbström (Grubba) | | *! @[define_macro()], @[define_pike_macros()]
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | */
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | | PIKEFUN void define_ansi_macros()
{
struct CPP_struct *this = THIS;
|
4bcddd | 2018-08-20 | Henrik Grubbström (Grubba) | | struct define_struct *def;
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | |
/* These attempt to be compatible with the C standard. */
|
7367a0 | 2018-09-06 | Henrik Grubbström (Grubba) | | DO_MAGIC_DEFINE(__LINE__);
DO_MAGIC_DEFINE(__FILE__);
DO_MAGIC_DEFINE(__TIME__);
DO_MAGIC_DEFINE(__DATE__);
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | |
/* These are from the 201x C standard. */
|
4bcddd | 2018-08-20 | Henrik Grubbström (Grubba) | | def = do_magic_define(this, "_Pragma", insert_pragma);
def->args = 1;
def->flags |= CPP_MACRO_KEEP_NL;
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | | simple_add_define(this, "static_assert", "_Static_assert");
}
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | /*! @decl void define_pike_macros()
*!
*! Adds some pike-specific cpp macros,
*! such as @[__DIR__], @[__VERSION__], [__PIKE__], etc.
*!
*! @seealso
|
72d4db | 2018-06-06 | Henrik Grubbström (Grubba) | | *! @[define_macro()], @[define_ansi_macros()]
|
e7af4d | 2018-06-03 | Henrik Grubbström (Grubba) | | */
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | | PIKEFUN void define_pike_macros()
{
struct CPP_struct *this = THIS;
/* 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);
simple_add_define(this, "__ARGS__", "__args__");
do_magic_define(this,"__COUNTER__",insert_current_counter);
#if 0
/* Left in place for documentation reference purposes. */
struct define_struct *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, ")");
mapping_string_insert(this->defines, def->name, 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__",
" " DEFINETOSTR(PIKE_MINOR_VERSION) " ");
simple_add_define(this, "__BUILD__",
" " DEFINETOSTR(PIKE_BUILD_VERSION) " ");
simple_add_define(this, "__REAL_BUILD__",
" " DEFINETOSTR(PIKE_BUILD_VERSION) " ");
simple_add_define(this, "__AUTO_BIGNUM__", " 1 ");
#ifdef __NT__
simple_add_define(this, "__NT__", " 1 ");
#endif
|
0c9594 | 2018-01-12 | Stephen R. van den Berg | | #ifdef __amigaos__
simple_add_define(this, "__amigaos__", " 1 ");
#endif
|
8c8da9 | 2018-01-09 | Henrik Grubbström (Grubba) | | #ifdef __APPLE__
simple_add_define(this, "__APPLE__", " 1 ");
#endif
simple_add_define(this, "SIZEOF_INT",
" " DEFINETOSTR(SIZEOF_INT) " ");
simple_add_define(this, "SIZEOF_FLOAT",
" " DEFINETOSTR(SIZEOF_FLOAT) " ");
}
|
afdac0 | 2018-07-19 | Henrik Grubbström (Grubba) | |
/*! @decl void define_multiple_macros(mapping(string: @
*! string|function|object)|void predefs)
*!
*! Define multiple macros in one operation.
*!
*! @param predefs
*! Macros to define.
*!
*! @seealso
*! @[define_macro()], @[CompilationHandler()->get_predefines()],
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | *! @[_take_over_initial_predefines()]
|
afdac0 | 2018-07-19 | Henrik Grubbström (Grubba) | | */
PIKEFUN void define_multiple_macros(mapping(string:
string|function|object)|void predefs)
{
struct CPP_struct *this = THIS;
struct keypair *k;
int e;
if (!predefs) return;
NEW_MAPPING_LOOP (predefs->data) {
if ((TYPEOF(k->ind) != T_STRING) || !k->ind.u.string->len) {
Pike_error("Expected nonempty string as predefine name, got %O.\n",
&k->ind);
}
|
6eb76c | 2018-08-29 | Henrik Grubbström (Grubba) | | add_define(this, k->ind.u.string, &k->val);
|
afdac0 | 2018-07-19 | Henrik Grubbström (Grubba) | | }
}
|
1f7c5c | 2018-07-20 | Henrik Grubbström (Grubba) | |
/*! @decl mapping(string:string|function|object) get_predefines()
*!
*! Get the predefined macros for this preprocessor.
*!
*! This function is called by @[init_pike_cpp()] to
*! retrieve the set of macros to define at initialization.
*!
*! The default implementation returns the internal set of
*! predefined macros unless @[_take_over_initial_predefines()]
*! has been called, in which case it instead calls the
*! corresponding function in the master.
*!
*! @note
*! This function does NOT return the set of currently
*! defined macros.
*!
*! @seealso
*! @[init_pike_cpp()], @[define_multiple_macros()],
*! @[_take_over_initial_predefines()]
*/
PIKEFUN mapping(string:string|function|object) get_predefines()
{
|
2e7be3 | 2018-07-27 | Henrik Grubbström (Grubba) | | #if 0
|
1f7c5c | 2018-07-20 | Henrik Grubbström (Grubba) | | apply_external(1, f_get_predefines_fun_num, args);
|
2e7be3 | 2018-07-27 | Henrik Grubbström (Grubba) | | #else
struct CPP_struct *this = THIS;
if (use_initial_predefs) {
push_mapping(initial_predefs_mapping());
} else {
low_unsafe_apply_handler("get_predefines",
this->handler, this->compat_handler, 0);
}
#endif
|
1f7c5c | 2018-07-20 | Henrik Grubbström (Grubba) | | }
/*! @decl void init_pike_cpp()
*!
*! Convenience function for initializing the preprocessor
*! to Pike defaults.
*!
*! The default implementation is essentially:
*! @code
*! {
*! define_ansi_macros();
*! define_pike_macros();
*! define_multiple_macros(get_predefines());
*! }
*! @endcode
*/
PIKEFUN void init_pike_cpp()
{
apply_current(f_CPP_define_ansi_macros_fun_num, 0);
apply_current(f_CPP_define_pike_macros_fun_num, 0);
apply_current(f_CPP_get_predefines_fun_num, 0);
apply_current(f_CPP_define_multiple_macros_fun_num, 1);
}
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | }
|
3197ac | 2018-05-19 | Arne Goedeke | | /*! @endclass CPP
|
0732a5 | 2018-03-30 | Henrik Grubbström (Grubba) | | */
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | |
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | /*! @endclass CompilerEnvironment
*/
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | /*! @decl string cpp(string data, mapping|string|void current_file, @
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! int|string|void charset, object|void handler, @
|
f6da7b | 2004-06-27 | Martin Nilsson | | *! void|int compat_major, void|int compat_minor, @
|
91a2f6 | 2004-11-05 | Martin Nilsson | | *! void|int picky_cpp)
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *!
*! 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,
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! it will default to @expr{"-"@}. @[charset] defaults to @expr{"ISO-10646"@}.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *!
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | *! 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
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member string "current_file"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Name of the current file. It is used for generating
*! #line directives and for locating include files.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member int|string "charset"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Charset to use when processing @expr{data@}.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member object "handler"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Compilation handler.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member int "compat_major"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Sets the major pike version used for compat handling.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member int "compat_minor"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Sets the minor pike version used for compat handling.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member int "picky_cpp"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! Generate more warnings.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! @member int "keep_comments"
|
edd972 | 2014-08-09 | Arne Goedeke | | *! This option keeps @[cpp()] from removing comments.
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | *! Useful in combination with the prefix feature below.
*! @member string "prefix"
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | *! 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.
|
13256b | 2018-09-04 | Henrik Grubbström (Grubba) | | *! @member mapping(string:mixed) "predefines"
*! Mapping of predefined macros in addition to those
*! returned by @[CPP()->get_predefines()].
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | *! @endmapping
*!
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[compile()]
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | | */
|
e34dcf | 2004-05-22 | Martin Nilsson | |
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | 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;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
7cb5e2 | 2018-01-07 | Henrik Grubbström (Grubba) | | struct svalue *save_sp = Pike_sp - args;
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | struct object *cpp_obj =
parent_clone_object(CPP_program,
compilation_environment, CPP_program_fun_num,
args-1);
|
e34dcf | 2004-05-22 | Martin Nilsson | |
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | push_object(cpp_obj);
|
e5fa47 | 2018-07-27 | Henrik Grubbström (Grubba) | | apply(cpp_obj, "init_pike_cpp", 0);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
0e383e | 2018-07-31 | Henrik Grubbström (Grubba) | | ref_push_string(data);
apply(cpp_obj, "high_cpp", 1);
|
57cef7 | 1999-12-28 | Henrik Grubbström (Grubba) | |
|
6e2bb5 | 2018-01-05 | Henrik Grubbström (Grubba) | | stack_pop_n_elems_keep_top((Pike_sp - save_sp) - 1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | /*! @module Builtin
*/
/*! @decl mapping(string:mixed) _take_over_initial_predefines()
|
4f395b | 2018-01-10 | Henrik Grubbström (Grubba) | | *!
*! Returns a mapping containing the set of predefined macros.
*! These are typically the macros defined via the @tt{-D@} option
*! when starting Pike.
*!
*! This function is typically called by the @[MasterObject] at
*! initialization, and may only be called once. After it has been called,
*! @[cpp()] will start calling @[CompilationHandler->get_predefines()] to
*! retrieve the set of predefined macros.
*!
*! @seealso
*! [cpp()], @[CompilationHandler->get_predefines()]
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | */
|
b584b1 | 2001-12-20 | Martin Stjernholm | | void f__take_over_initial_predefines (INT32 args)
{
pop_n_elems (args);
if (use_initial_predefs) {
struct pike_predef_s *tmp;
push_mapping (initial_predefs_mapping());
use_initial_predefs = 0;
while((tmp=first_predef))
{
free(tmp->name);
first_predef=tmp->next;
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(tmp);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | }
last_predef = 0;
}
else Pike_error ("Initial predefines already taken over.\n");
}
|
6c3a6f | 2013-11-20 | Henrik Grubbström (Grubba) | | /*! @endmodule
*/
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | void init_cpp_compilerenv_classes(void)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | /* NB: This function is called *early* (during compilation
* of the CompilerEnvironment class). This means that
* there are some limitations to what is possible to use.
*
* NB: This also means that all symbols declared above that
* aren't efuns will show up in CompilerEnvironment.
*/
|
b584b1 | 2001-12-20 | Martin Stjernholm | |
|
516482 | 2004-11-14 | Martin Stjernholm | | efun_str = make_shared_string ("efun");
constant_str = make_shared_string ("constant");
defined_str = make_shared_string ("defined");
|
b584b1 | 2001-12-20 | Martin Stjernholm | | use_initial_predefs = 1;
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | INIT;
|
b584b1 | 2001-12-20 | Martin Stjernholm | |
|
500d46 | 2016-09-06 | Henrik Grubbström (Grubba) | | defined_macro = alloc_empty_define(defined_str);
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | | defined_macro->magic=check_defined;
defined_macro->args=1;
defined_macro_sval = Pike_sp[-1];
Pike_sp--;
|
2f77c9 | 2018-07-04 | Henrik Grubbström (Grubba) | | }
void init_cpp(void)
{
struct svalue s;
|
be65c5 | 2016-09-02 | Henrik Grubbström (Grubba) | |
|
75a9f6 | 2011-12-04 | Arne Goedeke | | ADD_INT_CONSTANT("__HAVE_CPP_PREFIX_SUPPORT__", 1, 0);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | /* Somewhat tricky to add a _constant_ function in _static_modules.Builtin. */
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(s, T_FUNCTION, FUNCTION_BUILTIN, efun,
make_callable (f__take_over_initial_predefines,
"_take_over_initial_predefines",
"function(void:mapping(string:string))",
OPT_SIDE_EFFECT, NULL, NULL));
|
b584b1 | 2001-12-20 | Martin Stjernholm | | simple_add_constant ("_take_over_initial_predefines", &s, 0);
free_svalue (&s);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
b678e3 | 2014-05-15 | Martin Nilsson | | void add_predefine(const char *s)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
struct pike_predef_s *tmp=ALLOC_STRUCT(pike_predef_s);
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | | size_t len = strlen(s);
char *pos=strchr(s,'=');
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | if(pos)
{
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | | tmp->name = xalloc(len+1);
memcpy(tmp->name, s, len+1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | tmp->name[pos-s]=0;
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | | tmp->value = tmp->name + (pos-s) + 1;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }else{
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | | tmp->name = xalloc(len + 1 + 4);
memcpy(tmp->name,s,len + 1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | | tmp->value = tmp->name + len + 1;
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(tmp->value," 1 ",4);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
b584b1 | 2001-12-20 | Martin Stjernholm | | tmp->next = NULL;
|
282a8a | 2018-01-04 | Henrik Grubbström (Grubba) | |
|
b584b1 | 2001-12-20 | Martin Stjernholm | | if (first_predef) {
last_predef->next = tmp;
last_predef = tmp;
}
else first_predef = last_predef = tmp;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
ae9503 | 1999-04-07 | Fredrik Hübinette (Hubbe) | | void exit_cpp(void)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
ae9503 | 1999-04-07 | Fredrik Hübinette (Hubbe) | | #ifdef DO_PIKE_CLEANUP
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct pike_predef_s *tmp;
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | |
EXIT;
|
b584b1 | 2001-12-20 | Martin Stjernholm | | while((tmp=first_predef))
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
free(tmp->name);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | first_predef=tmp->next;
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(tmp);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | | free_svalue(&defined_macro_sval);
|
516482 | 2004-11-14 | Martin Stjernholm | |
free_string (efun_str);
free_string (constant_str);
free_string (defined_str);
|
e44282 | 2016-08-31 | Henrik Grubbström (Grubba) | |
|
ae9503 | 1999-04-07 | Fredrik Hübinette (Hubbe) | | #endif
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|