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"
#include "svalue.h"
#include "pike_macros.h"
#include "hashtable.h"
#include "program.h"
#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"
|
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
|
6ad237 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
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
|
7050b7 | 2014-02-25 | Per Hedbor | | struct define_part;
struct define_argument;
struct define;
struct cpp;
|
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;
static struct pike_predef_s *first_predef = NULL, *last_predef = NULL;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct define_part
{
int argument;
struct pike_string *postfix;
};
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) | | };
struct cpp;
struct define;
typedef void (*magic_define_fun)(struct cpp *,
struct define *,
struct define_argument *,
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | struct string_builder *);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
struct define
{
struct hash_entry link; /* must be first */
magic_define_fun magic;
int args;
|
170b86 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t num_parts;
|
821bb9 | 2001-05-29 | Henrik Grubbström (Grubba) | | short inside; /* 1 - Don't expand. 2 - In use. */
|
39dc6c | 2000-06-13 | Fredrik Hübinette (Hubbe) | | short varargs;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct pike_string *first;
struct define_part parts[1];
};
|
efd97a | 2014-05-12 | Martin Nilsson | | #define FIND_DEFINE(N) \
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | (this->defines?BASEOF(hash_lookup(this->defines, N), define, link):0)
struct cpp
{
struct hash_table *defines;
|
6fc2e7 | 2012-01-12 | Henrik Grubbström (Grubba) | | INT_TYPE current_line;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | INT32 compile_errors;
struct pike_string *current_file;
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | struct string_builder buf;
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | | struct object *handler;
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | struct object *compat_handler;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | INT_TYPE compat_major;
INT_TYPE compat_minor;
|
e34dcf | 2004-05-22 | Martin Nilsson | | struct pike_string *data;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | struct pike_string *prefix;
|
956513 | 2014-02-14 | Martin Nilsson | | INT_TYPE picky_cpp, keep_comments, dependencies_fail;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | };
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | DECLARE_STORAGE;
|
1ebec6 | 2014-05-13 | Martin Nilsson | | static void cpp_error(struct cpp *this, const char *err) ATTRIBUTE((noinline));
|
7050b7 | 2014-02-25 | Per Hedbor | | static void cpp_error_vsprintf (struct cpp *this, const char *fmt,
|
1ebec6 | 2014-05-13 | Martin Nilsson | | va_list args) ATTRIBUTE((noinline));
static void cpp_error_sprintf(struct cpp *this, const char *fmt, ...) ATTRIBUTE((noinline));
|
7050b7 | 2014-02-25 | Per Hedbor | | static void cpp_handle_exception(struct cpp *this,
|
1ebec6 | 2014-05-13 | Martin Nilsson | | const char *cpp_error_fmt, ...) ATTRIBUTE((noinline));
static void cpp_warning(struct cpp *this, const char *cpp_warn_fmt, ...) ATTRIBUTE((noinline));
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | struct define *defined_macro =0;
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | |
|
404563 | 2004-06-29 | Martin Nilsson | | static void cpp_error(struct cpp *this, const char *err)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
this->compile_errors++;
if(this->compile_errors > 10) return;
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | | if((this->handler && this->handler->prog) || get_master())
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
ref_push_string(this->current_file);
push_int(this->current_line);
push_text(err);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | low_safe_apply_handler("compile_error", this->handler,
this->compat_handler, 3);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | pop_stack();
}else{
|
1154dc | 1998-05-05 | Fredrik Hübinette (Hubbe) | | (void)fprintf(stderr, "%s:%ld: %s\n",
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | this->current_file->str,
(long)this->current_line,
err);
fflush(stderr);
}
}
|
404563 | 2004-06-29 | Martin Nilsson | | static void cpp_error_vsprintf (struct cpp *this, 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;
this->compile_errors++;
if (this->compile_errors > 10) return;
init_string_builder(&s, 0);
string_builder_vsprintf(&s, fmt, args);
msg = finish_string_builder(&s);
if((this->handler && this->handler->prog) || get_master())
{
ref_push_string(this->current_file);
push_int(this->current_line);
push_string(msg);
low_safe_apply_handler("compile_error", this->handler,
this->compat_handler, 3);
pop_stack();
return;
}
if (this->current_file->size_shift) {
fprintf(stderr, "WIDE:%ld: ", (long)this->current_line);
} else {
fprintf(stderr, "%s:%ld: ",
this->current_file->str, (long)this->current_line);
}
if (!msg->size_shift) {
fprintf(stderr, "%s\n", msg->str);
} else {
fprintf(stderr, "WIDE (fmt: %s)\n", fmt);
}
free_string(msg);
fflush(stderr);
|
37338b | 2003-11-14 | Martin Stjernholm | | }
|
9036e8 | 2001-08-16 | Martin Stjernholm | |
|
404563 | 2004-06-29 | Martin Nilsson | | static void cpp_error_sprintf(struct cpp *this, const char *fmt, ...)
|
37338b | 2003-11-14 | Martin Stjernholm | | {
va_list args;
|
9036e8 | 2001-08-16 | Martin Stjernholm | | va_start(args,fmt);
|
37338b | 2003-11-14 | Martin Stjernholm | | cpp_error_vsprintf (this, fmt, args);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | va_end(args);
}
|
404563 | 2004-06-29 | Martin Nilsson | | static void cpp_handle_exception(struct cpp *this,
const char *cpp_error_fmt, ...)
|
9036e8 | 2001-08-16 | Martin Stjernholm | | {
|
37338b | 2003-11-14 | Martin Stjernholm | | struct svalue thrown;
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);
cpp_error_vsprintf (this, cpp_error_fmt, args);
va_end (args);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
37338b | 2003-11-14 | Martin Stjernholm | | push_svalue(&thrown);
|
38dfa0 | 2008-04-12 | Henrik Grubbström (Grubba) | | low_safe_apply_handler("compile_exception",
this->handler, this->compat_handler, 1);
|
37338b | 2003-11-14 | Martin Stjernholm | |
if (SAFE_IS_ZERO(sp-1)) {
struct pike_string *s = format_exception_for_error_msg (&thrown);
|
715e55 | 2003-11-14 | Martin Stjernholm | | if (s) {
|
404563 | 2004-06-29 | Martin Nilsson | | cpp_error_sprintf(this, "%S", s);
|
715e55 | 2003-11-14 | Martin Stjernholm | | free_string (s);
}
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
37338b | 2003-11-14 | Martin Stjernholm | |
pop_stack();
free_svalue(&thrown);
|
9036e8 | 2001-08-16 | Martin Stjernholm | | }
|
f6da7b | 2004-06-27 | Martin Nilsson | | static void cpp_warning(struct cpp *this, const char *cpp_warn_fmt, ...)
|
fb59d2 | 2004-02-07 | Martin Nilsson | | {
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | struct string_builder sb;
|
f6da7b | 2004-06-27 | Martin Nilsson | | va_list args;
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | init_string_builder (&sb, 0);
|
f6da7b | 2004-06-27 | Martin Nilsson | | va_start(args, cpp_warn_fmt);
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | string_builder_vsprintf (&sb, cpp_warn_fmt, args);
|
f6da7b | 2004-06-27 | Martin Nilsson | | va_end(args);
|
fb59d2 | 2004-02-07 | Martin Nilsson | | if((this->handler && this->handler->prog) || get_master())
{
ref_push_string(this->current_file);
push_int(this->current_line);
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | push_string (finish_string_builder (&sb));
|
fb59d2 | 2004-02-07 | Martin Nilsson | | low_safe_apply_handler("compile_warning", this->handler,
this->compat_handler, 3);
pop_stack();
}else{
(void)fprintf(stderr, "%s:%ld: %s\n",
this->current_file->str,
(long)this->current_line,
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | sb.s->str);
|
fb59d2 | 2004-02-07 | Martin Nilsson | | fflush(stderr);
|
0a5cb7 | 2011-03-19 | Martin Stjernholm | | free_string_builder (&sb);
|
fb59d2 | 2004-02-07 | Martin Nilsson | | }
}
|
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) | | /*! @namespace predef:: */
/*! @decl import cpp:: */
/*! @endnamespace */
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | /* #pike handling. */
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | void cpp_change_compat(struct cpp *this, int major, int minor)
{
if(this->compat_major == major &&
this->compat_minor == minor) return;
if(this->compat_handler)
{
free_object(this->compat_handler);
this->compat_handler=0;
}
if((major == PIKE_MAJOR_VERSION &&
minor == PIKE_MINOR_VERSION) || major < 0)
{
this->compat_major=PIKE_MAJOR_VERSION;
this->compat_minor=PIKE_MINOR_VERSION;
return; /* Our work here is done */
}
push_int(major);
push_int(minor);
SAFE_APPLY_MASTER("get_compilation_handler",2);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-1]) == T_OBJECT)
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (SUBTYPEOF(sp[-1])) {
|
f54c78 | 2004-12-22 | Henrik Grubbström (Grubba) | | cpp_error(this,
"#pike: Subtyped compilation handlers are not supported yet.");
}
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | this->compat_handler=sp[-1].u.object;
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | | sp--;
}
this->compat_major=major;
this->compat_minor=minor;
}
|
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.
*/
/*! @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>@}@}
*!
*! is equvivalent to
*!
*! @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>@}@}
*!
*! is equvivalent to
*!
*! @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]
*/
|
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
*!
*! The following two are equvivalent:
*!
*! @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]
*/
/*! @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]
*/
/*! @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
*! // the old behaviour for @[7.2::dirname()].
*! #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
*/
/*! @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()]
*! level @expr{3@}. Note that this @tt{#pragma@} is a noop
*! if Pike hasn't been compiled @tt{--with-debug@}.
*! @value "no_disassemble"
*! Disable disassembly output (default).
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | *! @endstring
*/
/*! @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
*! @tt{#if defined(MY_DEF)@} is equvivalent to
*! @tt{#ifdef MY_DEF@}.
*!
*! @seealso
*! @[#if], @[#ifdef], @[constant()]
*/
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | static void check_defined(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | struct define_argument *args,
struct string_builder *tmp)
{
|
9506a1 | 2016-08-20 | Martin Nilsson | | struct pike_string *s = binary_findstring_wide( args[0].arg.ptr,
args[0].arg.shift,
args[0].len );
|
6e5206 | 2014-05-12 | Martin Nilsson | |
|
efd97a | 2014-05-12 | Martin Nilsson | | if(s && FIND_DEFINE(s))
|
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);
}
static int do_safe_index_call(struct cpp *this, struct pike_string *s)
{
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 | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | res=!(UNSAFE_IS_ZERO(sp-1) && SUBTYPEOF(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()]
*/
static void cpp_constant(struct cpp *this, int value)
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | {
struct svalue *save_stack=sp;
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);
ref_push_string(this->current_file);
if (this->handler) {
ref_push_object(this->handler);
} else {
push_int(0);
}
if (safe_apply_handler("resolv", this->handler,
this->compat_handler, 3, 0)) {
|
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
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | res = !(SAFE_IS_ZERO(sp-1) && SUBTYPEOF(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) | | ref_push_string(this->current_file);
if (this->handler) {
ref_push_object(this->handler);
} else {
push_int(0);
}
if (safe_apply_handler("handle_import", this->handler,
this->compat_handler, 3,
BIT_MAPPING|BIT_OBJECT|BIT_PROGRAM))
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | res = !(SAFE_IS_ZERO(sp-1) && SUBTYPEOF(sp[-1]) == NUMBER_UNDEFINED);
|
fbf6c9 | 2004-06-29 | Henrik Grubbström (Grubba) | | else {
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) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(sp[-1]) == T_INT)
|
a1640e | 2010-09-18 | Marcus Comstedt | | res = sp[-1].u.integer;
else
res = 0;
}
pop_n_elems(1 + 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
for (def = first_predef; def; def = def->next) {
|
2d1a3e | 2003-12-06 | Martin Nilsson | | push_text (def->name);
push_text (def->value);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | mapping_insert (map, sp - 2, sp - 1);
pop_n_elems (2);
}
return map;
}
|
1f57ef | 2014-05-10 | Per Hedbor | | static p_wchar2 readchar( PCHARP data, ptrdiff_t *pos, struct cpp *this )
{
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;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t readstring( struct cpp *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.");
|
a22fe1 | 2015-04-23 | Henrik Grubbström (Grubba) | | /* FALL_THROUGH */
|
1f57ef | 2014-05-10 | Per Hedbor | | default:
string_builder_putchar(nf, INDEX_PCHARP(data,pos));
continue;
}
pos++;
break;
}
return pos;
}
|
2028f8 | 2014-07-21 | Per Hedbor | | static ptrdiff_t readstring_lit( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos,
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;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t fixstring(struct cpp *this, const PCHARP data, ptrdiff_t len,
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;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t find_end_of_line( struct cpp *this, const PCHARP data,
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;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t find_end_of_comment( struct cpp *this, const PCHARP data, ptrdiff_t len,
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;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t find_end_of_string2( struct cpp *this, const PCHARP data,
ptrdiff_t len, ptrdiff_t pos)
|
1585cf | 2014-05-10 | Per Hedbor | | {
while(1)
{
if(pos>=len)
{
cpp_error(this,"End of file in string.");
break;
}
switch(INDEX_PCHARP(data,pos++))
{
case '\n':
this->current_line++;
PUTNL();
continue;
case '"': return pos;
case '\\':
if(INDEX_PCHARP(data,pos)=='\n') {
this->current_line++;
PUTNL();
}
else if ((INDEX_PCHARP(data,pos) == '\r') && (INDEX_PCHARP(data,pos+1) == '\n')) {
this->current_line++;
pos++;
PUTNL();
}
pos++;
}
}
return pos;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t find_end_of_string( struct cpp *this, const PCHARP data,
ptrdiff_t len, ptrdiff_t pos)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
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++;
PUTNL();
break;
case '"': return pos;
case '\\':
if(INDEX_PCHARP(data,pos)=='\n') {
this->current_line++;
PUTNL();
}
else if ((INDEX_PCHARP(data,pos) == '\r') && (INDEX_PCHARP(data,pos+1) == '\n')) {
this->current_line++;
pos++;
PUTNL();
}
pos++;
}
|
13670c | 2015-05-25 | Martin Nilsson | | }
|
1f57ef | 2014-05-10 | Per Hedbor | | return pos;
}
|
efd97a | 2014-05-12 | Martin Nilsson | | static ptrdiff_t find_end_of_char( struct cpp *this, const PCHARP data, ptrdiff_t len, ptrdiff_t pos)
|
1f57ef | 2014-05-10 | Per Hedbor | | {
int e=0;
while(1)
{
if(pos>=len)
{
cpp_error(this,"End of file in character constant.");
break;
}
switch(INDEX_PCHARP(data,pos++))
{
case '\n':
cpp_error(this,"Newline in char.");
this->current_line++;
PUTNL();
break;
|
13670c | 2015-05-25 | Martin Nilsson | | case '\'':
|
1f57ef | 2014-05-10 | Per Hedbor | | return pos;
case '\\':
if(INDEX_PCHARP(data,pos)=='\n') {
this->current_line++;
PUTNL();
}
else if ((INDEX_PCHARP(data,pos) == '\r') && (INDEX_PCHARP(data,pos+1) == '\n'))
{
this->current_line++;
pos++;
PUTNL();
}
pos++;
}
}
return pos;
}
static ptrdiff_t find_end_brace(struct cpp *this,
PCHARP data,
ptrdiff_t len,
ptrdiff_t pos);
static ptrdiff_t find_end_parenthesis(struct cpp *this,
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;
case '\'': pos=find_end_of_char(this,data,len,pos); break;
case '"': pos=find_end_of_string(this,data,len,pos); break;
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);
}
}
}
}
static ptrdiff_t find_end_brace(struct cpp *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;
case '\'': pos=find_end_of_char(this,data,len,pos); break;
case '"': pos=find_end_of_string(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,0);
} else if (INDEX_PCHARP(data,pos) == '/') {
pos=find_end_of_line(this,data,len,pos,0);
}
}
}
}
|
1585cf | 2014-05-10 | Per Hedbor | |
static inline int wide_isspace( int c ) {
return WIDE_ISSPACE(c);
}
static inline int wide_isidchar( int c ) {
return WIDE_ISIDCHAR(c);
}
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static struct pike_string *gobble_identifier (struct cpp *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;
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | /* devours one reference to 'name'! */
|
170b86 | 2000-08-10 | Henrik Grubbström (Grubba) | | static struct define *alloc_empty_define(struct pike_string *name,
ptrdiff_t parts)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
struct define *def;
|
dc8d02 | 2014-04-27 | Martin Nilsson | | def=xalloc(sizeof(struct define)+
sizeof(struct define_part) * (parts -1));
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | def->magic=0;
def->args=-1;
def->inside=0;
|
39dc6c | 2000-06-13 | Fredrik Hübinette (Hubbe) | | def->varargs=0;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | def->num_parts=parts;
def->first=0;
def->link.s=name;
|
bef867 | 2001-05-13 | Fredrik Hübinette (Hubbe) | | debug_malloc_touch(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()]
*/
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | static void undefine(struct cpp *this,
|
90e5e9 | 2014-05-13 | Martin Nilsson | | const struct pike_string *name)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
INT32 e;
struct define *d;
|
efd97a | 2014-05-12 | Martin Nilsson | | d=FIND_DEFINE(name);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
if(!d) return;
|
853819 | 2001-05-29 | Henrik Grubbström (Grubba) | | if (d->inside) {
cpp_error(this, "Illegal to undefine a macro during its expansion.");
return;
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | this->defines=hash_unlink(this->defines, & d->link);
for(e=0;e<d->num_parts;e++)
free_string(d->parts[e].postfix);
free_string(d->link.s);
if(d->first)
free_string(d->first);
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(d);
|
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@}.
*/
|
3c8ee5 | 2011-12-28 | Henrik Grubbström (Grubba) | | static struct define *do_magic_define(struct cpp *this,
|
90e5e9 | 2014-05-13 | Martin Nilsson | | const char *name,
|
3c8ee5 | 2011-12-28 | Henrik Grubbström (Grubba) | | magic_define_fun fun)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | struct define* def;
if (this->prefix) {
struct string_builder s;
int len = strlen(name);
init_string_builder(&s, 0);
string_builder_append(&s, MKPCHARP_STR(this->prefix),
this->prefix->len);
string_builder_putchar(&s, '_');
string_builder_binary_strcat(&s, name, len);
def = alloc_empty_define(finish_string_builder(&s),0);
} else
def = alloc_empty_define(make_shared_string(name),0);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | def->magic=fun;
this->defines=hash_insert(this->defines, & def->link);
|
3c8ee5 | 2011-12-28 | Henrik Grubbström (Grubba) | |
return def;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
b584b1 | 2001-12-20 | Martin Stjernholm | | static void add_define(struct cpp *this,
struct pike_string *name,
struct pike_string *what)
{
struct define* def;
add_ref (name);
def=alloc_empty_define(name,0);
add_ref (def->first = what);
this->defines=hash_insert(this->defines, & def->link);
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | static void simple_add_define(struct cpp *this,
|
90e5e9 | 2014-05-13 | Martin Nilsson | | const char *name,
const char *what)
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | {
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | struct define* def;
if (this->prefix) {
struct string_builder s;
int len = strlen(name);
init_string_builder(&s, 0);
string_builder_append(&s, MKPCHARP_STR(this->prefix),
this->prefix->len);
string_builder_putchar(&s, '_');
string_builder_binary_strcat(&s, name, len);
def = alloc_empty_define(finish_string_builder(&s),0);
} else
def = alloc_empty_define(make_shared_string(name),0);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | def->first=make_shared_string(what);
this->defines=hash_insert(this->defines, & def->link);
}
|
715e55 | 2003-11-14 | Martin Stjernholm | | static struct pike_string *recode_string(struct cpp *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);
add_ref(data = sp[-1].u.string);
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) | |
|
715e55 | 2003-11-14 | Martin Stjernholm | | if (safe_apply_handler ("decode_charset", this->handler, this->compat_handler,
2, BIT_STRING)) {
/* Various consistency checks. */
if ((sp[-1].u.string->size_shift) ||
(((size_t)sp[-1].u.string->len) < CONSTANT_STRLEN("#charset")) ||
(sp[-1].u.string->str[0] != '#')) {
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 */
p = sp[-1].u.string->str + 1;
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 */
|
715e55 | 2003-11-14 | Martin Stjernholm | | if (!safe_apply_handler ("decode_charset", this->handler, this->compat_handler,
2, BIT_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);
add_ref(data = sp[-1].u.string);
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);
}
|
7050b7 | 2014-02-25 | Per Hedbor | | static void free_one_define(struct hash_entry *h)
|
853819 | 2001-05-29 | Henrik Grubbström (Grubba) | | {
int e;
struct define *d=BASEOF(h, define, link);
for(e=0;e<d->num_parts;e++)
free_string(d->parts[e].postfix);
if(d->first)
free_string(d->first);
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(d);
|
853819 | 2001-05-29 | Henrik Grubbström (Grubba) | | }
|
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)
#define WC_ISSPACE wide_isspace
#define WC_ISIDCHAR wide_isidchar
|
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)
|
b7df6e | 2014-05-12 | Per Hedbor | | #define FIND_END_OF_STRING() (pos=find_end_of_string(this,data,len,pos))
#define FIND_END_OF_STRING2() (pos=find_end_of_string2(this,data,len,pos))
#define FIND_END_OF_CHAR() (pos=find_end_of_char(this,data,len,pos))
#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);
}
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static ptrdiff_t find_eos( struct cpp *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++;
default:
continue;
}
this->current_line++;
break;
}
return pos;
}
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static ptrdiff_t skipwhite(struct cpp *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;
}
|
90e5e9 | 2014-05-13 | Martin Nilsson | | static ptrdiff_t skipspace(struct cpp *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 error_[] = { 'e', 'r', 'r', 'o', 'r' };
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 warning_[] = { 'w', 'a', 'r', 'n', 'i', 'n', 'g' };
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;
}
|
58efb8 | 2014-05-12 | Per Hedbor | | static ptrdiff_t low_cpp(struct cpp *this,
PCHARP data,
ptrdiff_t len,
int flags,
int auto_convert,
struct pike_string *charset);
|
75a9f6 | 2011-12-04 | Arne Goedeke | | static void insert_callback_define(struct cpp *this,
struct define *def,
struct define_argument *args,
struct string_builder *tmp);
static void insert_callback_define_no_args(struct cpp *this,
struct define *def,
struct define_argument *args,
struct string_builder *tmp);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | static void insert_pragma(struct cpp *this,
struct define *def,
struct define_argument *args,
struct string_builder *tmp);
|
7b73fb | 2014-05-10 | Per Hedbor | |
|
74966e | 2014-05-12 | Per Hedbor | | static ptrdiff_t calc1(struct cpp *this, PCHARP data, ptrdiff_t len,
ptrdiff_t pos, int flags);
static ptrdiff_t calcC(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
|
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;
}
/* FALL_THROUGH */
default:
|
b7df6e | 2014-05-12 | Per Hedbor | | if (WC_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;
}
static ptrdiff_t calcB(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calcA(struct cpp *this,PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc9(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc8(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc7b(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc7(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc6(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc5(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc4(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc3(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc2(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc1(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
static ptrdiff_t calc(struct cpp *this, PCHARP data, ptrdiff_t len,
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;
}
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | #include "preprocessor.h"
/*** Magic defines ***/
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | |
/*! @decl constant __LINE__
*!
*! This define contains the current line number, represented as an
*! integer, in the source file.
*/
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | static void insert_current_line(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
|
c060b5 | 2004-11-14 | Henrik Grubbström (Grubba) | | string_builder_sprintf(tmp, " %ld ", (long)this->current_line);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | }
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __FILE__
*!
*! This define contains the file path and name of the source file.
*/
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | static void insert_current_file_as_string(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
PUSH_STRING_SHIFT(this->current_file->str, this->current_file->len,
this->current_file->size_shift, tmp);
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __DIR__
*!
*! This define contains the directory path of the source file.
*/
|
15107c | 2008-06-12 | Martin Nilsson | | static void insert_current_dir_as_string(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
15107c | 2008-06-12 | Martin Nilsson | | struct string_builder *tmp)
{
|
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();
}
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __TIME__
*!
*! This define contains the current time at the time of compilation,
*! e.g. "12:20:51".
*/
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static void insert_current_time_as_string(struct cpp *UNUSED(this),
struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
/* FIXME: Is this code safe? */
time_t tmp2;
char *buf;
time(&tmp2);
buf=ctime(&tmp2);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | PUSH_STRING0((p_wchar0 *)buf+11, 8, tmp);
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | }
|
4fa654 | 2012-03-24 | Henrik Grubbström (Grubba) | | /*! @decl constant __DATE__
*!
*! This define contains the current date at the time of compilation,
*! e.g. "Jul 28 2001".
*/
|
74dfe8 | 2012-12-30 | Jonas Walldén | | static void insert_current_date_as_string(struct cpp *UNUSED(this),
struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
7bfa4f | 1999-03-09 | Henrik Grubbström (Grubba) | | struct string_builder *tmp)
{
/* FIXME: Is this code safe? */
time_t tmp2;
char *buf;
time(&tmp2);
buf=ctime(&tmp2);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | PUSH_STRING0((p_wchar0 *)buf+4, 6, tmp);
|
e5fac4 | 2000-03-09 | Johan Sundström | | PUSH_STRING0((p_wchar0 *)buf+19, 5, tmp);
|
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__]
*/
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | static void insert_current_version(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
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__]
*/
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | static void insert_current_minor(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
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 | | *!
*/
static void insert_current_counter(struct cpp *UNUSED(this),
struct define *UNUSED(def),
struct define_argument *UNUSED(args),
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__]
*/
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | static void insert_current_major(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
struct define_argument *UNUSED(args),
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | struct string_builder *tmp)
{
|
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]
*/
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | static void insert_pragma(struct cpp *this,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define *UNUSED(def),
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | struct define_argument *args,
struct string_builder *tmp)
{
int i;
int in_string = 0;
PCHARP arg = args->arg;
ptrdiff_t len = args->len;
/* Make some reasonable amount of space. */
string_build_mkspace(tmp, len + 20, arg.shift);
string_builder_strcat(tmp, "\n#pragma ");
/* Destringize the argument. */
for (i = 0; i < len; i++) {
p_wchar2 ch = INDEX_PCHARP(arg, i);
switch(ch) {
case '\n': case '\r':
ch = ' ';
/* FALL_THROUGH */
case ' ': case '\t':
if (in_string) {
string_builder_putchar(tmp, ch);
}
break;
case '\"':
in_string = !in_string;
break;
case '\\':
if (in_string) {
ch = (++i < len) ? INDEX_PCHARP(arg, i) : '\0';
if ((ch != '\\') && (ch != '\"')) {
cpp_error(this, "Invalid \\-escape in _Pragma().");
break;
}
}
/* FALL_THROUGH */
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');
}
|
080e3a | 2011-11-04 | Per Hedbor | | static void insert_callback_define(struct cpp *this,
struct define *def,
struct define_argument *args,
struct string_builder *tmp)
{
ref_push_string( def->link.s );
push_string( make_shared_binary_pcharp( args[0].arg, args[0].len ) );
|
819004 | 2011-12-28 | Henrik Grubbström (Grubba) | | if (safe_apply_handler( "evaluate_define",
this->handler, this->compat_handler, 2, 0 ) &&
TYPEOF(sp[-1]) == T_STRING ) {
|
6d3ae7 | 2011-11-20 | Henrik Grubbström (Grubba) | | string_builder_shared_strcat(tmp, sp[-1].u.string);
|
7e5b17 | 2014-04-10 | Per Hedbor | | if( !this->prefix ){
int min;
check_string_range( sp[-1].u.string, 0, &min, 0 );
if( min < 32 )
{
string_builder_sprintf(tmp, "\n#line %ld ", (long)this->current_line);
insert_current_file_as_string( this,def,args,tmp);
string_builder_putchar(tmp, '\n');
}
}
|
75a9f6 | 2011-12-04 | Arne Goedeke | | pop_stack();
}
|
080e3a | 2011-11-04 | Per Hedbor | | }
static void insert_callback_define_no_args(struct cpp *this,
struct define *def,
|
74dfe8 | 2012-12-30 | Jonas Walldén | | struct define_argument *UNUSED(args),
|
080e3a | 2011-11-04 | Per Hedbor | | struct string_builder *tmp)
{
|
75a9f6 | 2011-12-04 | Arne Goedeke | | struct svalue *save_sp = Pike_sp;
|
080e3a | 2011-11-04 | Per Hedbor | | ref_push_string( def->link.s );
|
819004 | 2011-12-28 | Henrik Grubbström (Grubba) | | if (safe_apply_handler( "evaluate_define",
this->handler, this->compat_handler, 1, 0 ) &&
TYPEOF(sp[-1]) == T_STRING )
|
6d3ae7 | 2011-11-20 | Henrik Grubbström (Grubba) | | string_builder_shared_strcat(tmp, sp[-1].u.string);
|
75a9f6 | 2011-12-04 | Arne Goedeke | | if (Pike_sp > save_sp) pop_n_elems(Pike_sp-save_sp);
|
080e3a | 2011-11-04 | Per Hedbor | | }
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | |
|
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.
*/
/*! @decl constant __amigaos__
*!
*! This define is defined when the Pike is running on Amiga OS.
*/
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
9ace1e | 2013-03-16 | Chris Angelico | | /*! @decl constant __OS2__
*!
*! This define is defined when the Pike is running on IBM OS/2.
*/
|
522042 | 2003-04-01 | Martin Nilsson | | /*! @endnamespace */
|
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.
*! @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 | |
/* Doesn't free string_builder buf! */
static void free_cpp(struct cpp *this)
{
if(this->defines)
free_hashtable(this->defines, free_one_define);
if(this->current_file)
free_string(this->current_file);
if(this->handler) {
free_object(this->handler);
this->handler = 0;
}
if(this->compat_handler) {
free_object(this->compat_handler);
this->compat_handler=0;
}
if(this->data)
free_string(this->data);
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | |
if(this->prefix)
free_string(this->prefix);
|
e34dcf | 2004-05-22 | Martin Nilsson | | }
|
080e3a | 2011-11-04 | Per Hedbor | |
|
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) | | {
struct cpp this;
|
e34dcf | 2004-05-22 | Martin Nilsson | | struct svalue *save_sp = sp - args;
struct mapping *predefs = NULL;
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | struct pike_string *prefix = NULL;
|
e34dcf | 2004-05-22 | Martin Nilsson | |
struct pike_string *current_file = 0;
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | | int auto_convert = 0;
|
a9a8dd | 1999-03-09 | Henrik Grubbström (Grubba) | | struct pike_string *charset = NULL;
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | 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;
|
e34dcf | 2004-05-22 | Martin Nilsson | |
ONERROR err;
|
57cef7 | 1999-12-28 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
ONERROR tmp;
#endif /* PIKE_DEBUG */
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | |
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | this.prefix = NULL;
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.current_line=1;
this.compile_errors=0;
this.defines=0;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | this.keep_comments = 0;
|
956513 | 2014-02-14 | Martin Nilsson | | this.dependencies_fail = 0;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | |
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | if (opts_or_file) {
if (TYPEOF(*opts_or_file) == PIKE_T_MAPPING) {
struct svalue *tmp;
struct mapping *m = opts_or_file->u.mapping;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | #define GET_TYPE(type, name) ((tmp = simple_mapping_string_lookup(m, name)) \
&& (TYPEOF(*(tmp)) == PIKE_T_##type || (Pike_error("Expected type %s,"\
|
b5b29e | 2016-07-27 | Henrik Grubbström (Grubba) | | "got type %s for " name ".", get_name_of_type(PIKE_T_##type), get_name_of_type(TYPEOF(*tmp))), 0)))
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | |
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | if (GET_TYPE(STRING, "current_file")) current_file = tmp->u.string;
if (GET_TYPE(STRING, "charset")) charset_sv = tmp;
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;
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | #undef GET_TYPE
|
3b8741 | 2016-07-27 | Henrik Grubbström (Grubba) | | } else if (TYPEOF(*opts_or_file) == PIKE_T_STRING) {
current_file = opts_or_file->u.string;
}
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | }
|
10ddf6 | 1999-02-27 | Henrik Grubbström (Grubba) | |
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.data = data;
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | | add_ref(data);
|
e34dcf | 2004-05-22 | Martin Nilsson | | if(current_file)
add_ref(current_file);
else
current_file = make_shared_string("-");
this.current_file = current_file;
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | |
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.compat_major=PIKE_MAJOR_VERSION;
this.compat_minor=PIKE_MINOR_VERSION;
this.compat_handler = 0;
this.handler = handler;
if(handler)
add_ref(handler);
/* Don't call free_cpp before all variables are cleared or set. */
SET_ONERROR(err, free_cpp, &this);
|
16a6f7 | 2011-11-27 | Tobias S. Josefowitz | | 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 (!isalnum(prefix->str[i])) {
Pike_error("Invalid char in prefix.\n");
}
}
this.prefix = prefix;
add_ref(prefix);
}
|
e34dcf | 2004-05-22 | Martin Nilsson | | if(charset_sv) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(*charset_sv) == T_STRING) {
|
e34dcf | 2004-05-22 | Martin Nilsson | | charset = charset_sv->u.string;
push_string(data);
|
18c0fa | 2011-12-01 | Tobias S. Josefowitz | | this.data = data = NULL;
|
e34dcf | 2004-05-22 | Martin Nilsson | | ref_push_string(charset);
if (!safe_apply_handler ("decode_charset", this.handler,
this.compat_handler, 2, BIT_STRING)) {
|
404563 | 2004-06-29 | Martin Nilsson | | cpp_handle_exception (&this, "Error decoding with charset %S",
charset);
|
e34dcf | 2004-05-22 | Martin Nilsson | | Pike_error("Unknown charset.\n");
|
739f9d | 1999-11-04 | Henrik Grubbström (Grubba) | | }
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.data = data = sp[-1].u.string;
sp--;
dmalloc_touch_svalue(sp);
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | else if(TYPEOF(*charset_sv) == T_INT)
|
e34dcf | 2004-05-22 | Martin Nilsson | | auto_convert = charset_sv->u.integer;
else {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("cpp", 3, "string|int");
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | | }
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|
55eb58 | 1999-02-22 | Henrik Grubbström (Grubba) | |
|
ddc1a3 | 2010-07-27 | Martin Stjernholm | | if(compat_major)
|
e34dcf | 2004-05-22 | Martin Nilsson | | cpp_change_compat(&this, compat_major, compat_minor);
|
569e07 | 2004-07-01 | Martin Nilsson | |
|
ddc1a3 | 2010-07-27 | Martin Stjernholm | | this.picky_cpp = picky_cpp;
|
b584b1 | 2001-12-20 | Martin Stjernholm | |
if (use_initial_predefs)
/* Typically compiling the master here. */
predefs = initial_predefs_mapping();
else {
|
e34dcf | 2004-05-22 | Martin Nilsson | | low_unsafe_apply_handler ("get_predefines", this.handler,
this.compat_handler, 0);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | if (!UNSAFE_IS_ZERO (sp - 1)) {
struct keypair *k;
int e, sprintf_args = 0;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(sp[-1]) != T_MAPPING) {
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text ("Invalid return value from get_predefines, got %O\n");
|
b584b1 | 2001-12-20 | Martin Stjernholm | | push_svalue (sp - 3);
sprintf_args = 2;
}
else {
predefs = copy_mapping (sp[-1].u.mapping);
NEW_MAPPING_LOOP (predefs->data) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(k->ind) != T_STRING || !k->ind.u.string->len) {
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text ("Expected nonempty string as predefine name, got %O\n");
|
b584b1 | 2001-12-20 | Martin Stjernholm | | push_svalue (&k->ind);
sprintf_args = 2;
free_mapping (predefs);
predefs = NULL;
goto predef_map_error;
|
75a9f6 | 2011-12-04 | Arne Goedeke | | } else if (!(TYPEOF(k->val) == T_INT && !k->val.u.integer)
&& TYPEOF(k->val) != T_STRING
&& TYPEOF(k->val) != T_FUNCTION
&& TYPEOF(k->val) != T_OBJECT) {
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text ("expected zero, string or function value for"
|
75a9f6 | 2011-12-04 | Arne Goedeke | | " predefine %O\n");
push_svalue (&k->ind);
sprintf_args = 2;
free_mapping (predefs);
predefs = NULL;
goto predef_map_error;
|
b584b1 | 2001-12-20 | Martin Stjernholm | | }
}
}
if (!predefs) {
predef_map_error:
f_sprintf (sprintf_args);
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | Pike_error("%S", sp[-1].u.string);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | }
}
pop_stack();
}
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | | if (auto_convert && (!data->size_shift) && (data->len > 1)) {
|
55eb58 | 1999-02-22 | Henrik Grubbström (Grubba) | | /* Try to determine if we need to recode the string */
|
715e55 | 2003-11-14 | Martin Stjernholm | | struct pike_string *new_data = recode_string(&this, data);
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | free_string(data);
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.data = data = new_data;
|
55eb58 | 1999-02-22 | Henrik Grubbström (Grubba) | | }
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | | if (data->size_shift) {
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | | /* Get rid of any byte order marks (0xfeff) */
struct pike_string *new_data = filter_bom(data);
free_string(data);
|
e34dcf | 2004-05-22 | Martin Nilsson | | this.data = data = new_data;
|
e7d390 | 1999-02-23 | Henrik Grubbström (Grubba) | | }
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | |
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | init_string_builder(&this.buf, 0);
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | /* These attempt to be compatible with the C standard. */
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | do_magic_define(&this,"__LINE__",insert_current_line);
do_magic_define(&this,"__FILE__",insert_current_file_as_string);
do_magic_define(&this,"__DATE__",insert_current_date_as_string);
do_magic_define(&this,"__TIME__",insert_current_time_as_string);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | |
|
aba09a | 2011-12-28 | Henrik Grubbström (Grubba) | | /* These are from the 201x C standard. */
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | do_magic_define(&this,"_Pragma",insert_pragma)->args = 1;
|
aba09a | 2011-12-28 | Henrik Grubbström (Grubba) | | simple_add_define(&this, "static_assert", "_Static_assert");
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | |
|
ce261a | 2014-08-26 | Per Hedbor | | do_magic_define(&this,"__COUNTER__",insert_current_counter);
|
51d3f3 | 2011-12-28 | Henrik Grubbström (Grubba) | | /* These are Pike extensions. */
do_magic_define(&this,"__DIR__",insert_current_dir_as_string);
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | do_magic_define(&this,"__VERSION__",insert_current_version);
do_magic_define(&this,"__MAJOR__",insert_current_major);
|
0d36ca | 2001-02-09 | Henrik Grubbström (Grubba) | | do_magic_define(&this,"__MINOR__",insert_current_minor);
|
b3cc13 | 1998-01-15 | Fredrik Hübinette (Hubbe) | |
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | {
|
82c660 | 2008-04-04 | Henrik Grubbström (Grubba) | | #if 0
/* Left in place for documentation reference purposes. */
|
ef56c1 | 2008-03-27 | Henrik Grubbström (Grubba) | | struct define *def =
alloc_empty_define(make_shared_string("__deprecated__"), 1);
def->args = 1;
REF_MAKE_CONST_STRING(def->first, "__attribute__(\"deprecated\", ");
def->parts[0].argument = 0;
REF_MAKE_CONST_STRING(def->parts[0].postfix, ")");
this.defines = hash_insert(this.defines, &def->link);
|
82c660 | 2008-04-04 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
ef56c1 | 2008-03-27 | Henrik Grubbström (Grubba) | |
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | simple_add_define(&this, "__PIKE__", " 1 ");
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | simple_add_define(&this, "__REAL_VERSION__",
|
659825 | 1999-12-08 | Henrik Grubbström (Grubba) | | " " DEFINETOSTR(PIKE_MAJOR_VERSION) "."
DEFINETOSTR(PIKE_MINOR_VERSION) " ");
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | simple_add_define(&this, "__REAL_MAJOR__",
|
659825 | 1999-12-08 | Henrik Grubbström (Grubba) | | " " DEFINETOSTR(PIKE_MAJOR_VERSION) " ");
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | simple_add_define(&this, "__REAL_MINOR__",
|
659825 | 1999-12-08 | Henrik Grubbström (Grubba) | | " " DEFINETOSTR(PIKE_MINOR_VERSION) " ");
simple_add_define(&this, "__BUILD__",
" " DEFINETOSTR(PIKE_BUILD_VERSION) " ");
|
a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | simple_add_define(&this, "__REAL_BUILD__",
" " DEFINETOSTR(PIKE_BUILD_VERSION) " ");
|
599715 | 1999-10-16 | Fredrik Noring | | simple_add_define(&this, "__AUTO_BIGNUM__", " 1 ");
|
b3cc13 | 1998-01-15 | Fredrik Hübinette (Hubbe) | | #ifdef __NT__
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | simple_add_define(&this, "__NT__", " 1 ");
|
b3cc13 | 1998-01-15 | Fredrik Hübinette (Hubbe) | | #endif
|
bf2b45 | 1998-11-23 | Marcus Comstedt | | #ifdef __amigaos__
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | simple_add_define(&this, "__amigaos__", " 1 ");
|
74bf1a | 2006-04-22 | Henrik Grubbström (Grubba) | | #endif
|
9ace1e | 2013-03-16 | Chris Angelico | | #ifdef __OS2__
simple_add_define(&this, "__OS2__", " 1 ");
#endif
|
74bf1a | 2006-04-22 | Henrik Grubbström (Grubba) | | #ifdef __APPLE__
simple_add_define(&this, "__APPLE__", " 1 ");
|
bf2b45 | 1998-11-23 | Marcus Comstedt | | #endif
|
665950 | 2003-09-20 | Martin Nilsson | | simple_add_define(&this, "SIZEOF_INT",
" " DEFINETOSTR(SIZEOF_INT) " ");
simple_add_define(&this, "SIZEOF_FLOAT",
" " DEFINETOSTR(SIZEOF_FLOAT) " ");
|
f0950a | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
b584b1 | 2001-12-20 | Martin Stjernholm | | if (predefs) {
struct keypair *k;
int e;
NEW_MAPPING_LOOP (predefs->data) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(k->val) == T_STRING)
|
b584b1 | 2001-12-20 | Martin Stjernholm | | add_define (&this, k->ind.u.string, k->val.u.string);
|
75a9f6 | 2011-12-04 | Arne Goedeke | | else if(TYPEOF(k->val) == T_FUNCTION || TYPEOF(k->val) == T_OBJECT)
|
080e3a | 2011-11-04 | Per Hedbor | | {
struct define *def;
if( index_shared_string( k->ind.u.string, k->ind.u.string->len-1) == ')' )
{
struct pike_string *s = string_slice( k->ind.u.string, 0, k->ind.u.string->len-2);
def = alloc_empty_define( s, 0 );
def->magic = insert_callback_define;
def->varargs=1;
def->args=1;
}
else
{
def = alloc_empty_define( k->ind.u.string, 0 );
k->ind.u.string->refs++;
def->magic = insert_callback_define_no_args;
}
this.defines = hash_insert( this.defines, &def->link );
}
|
b584b1 | 2001-12-20 | Martin Stjernholm | | else
|
4edb1a | 2002-09-11 | David Hedbor | | add_define (&this, k->ind.u.string, empty_pike_string);
|
b584b1 | 2001-12-20 | Martin Stjernholm | | }
free_mapping (predefs);
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
38e296 | 2012-07-22 | Arne Goedeke | | string_builder_binary_strcat(&this.buf, "#line 1 ", 8);
|
2dc009 | 1999-02-27 | Henrik Grubbström (Grubba) | | PUSH_STRING_SHIFT(this.current_file->str, this.current_file->len,
this.current_file->size_shift, &this.buf);
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | string_builder_putchar(&this.buf, '\n');
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
57cef7 | 1999-12-28 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
SET_ONERROR(tmp, fatal_on_error, "Preprocessor exited with longjump!\n");
#endif /* PIKE_DEBUG */
|
ac8715 | 2000-09-25 | Fredrik Hübinette (Hubbe) | |
|
58efb8 | 2014-05-12 | Per Hedbor | | low_cpp(&this, MKPCHARP_STR(data), data->len,
|
a9a8dd | 1999-03-09 | Henrik Grubbström (Grubba) | | 0, auto_convert, charset);
|
57cef7 | 1999-12-28 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
UNSET_ONERROR(tmp);
#endif /* PIKE_DEBUG */
|
e34dcf | 2004-05-22 | Martin Nilsson | | UNSET_ONERROR(err);
free_cpp(&this);
|
1c8da5 | 1999-02-24 | Henrik Grubbström (Grubba) | |
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | if(this.compile_errors)
{
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | free_string_builder(&this.buf);
|
db1450 | 2008-05-27 | Henrik Grubbström (Grubba) | | throw_error_object(fast_clone_object(cpp_error_program), 0, 0, 0,
|
010dc6 | 2001-08-16 | Martin Stjernholm | | "Cpp() failed\n");
|
956513 | 2014-02-14 | Martin Nilsson | | }
else if(this.dependencies_fail)
{
free_string_builder(&this.buf);
|
19e516 | 2014-02-21 | Martin Nilsson | | pop_n_elems(sp - save_sp);
|
956513 | 2014-02-14 | Martin Nilsson | | push_int(0);
}
else
{
|
770b6d | 1999-02-23 | Henrik Grubbström (Grubba) | | pop_n_elems(sp - save_sp);
|
d9ac33 | 1999-02-22 | Henrik Grubbström (Grubba) | | push_string(finish_string_builder(&this.buf));
|
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()
*/
|
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);
free(tmp->value);
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
*/
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | void init_cpp()
{
|
b584b1 | 2001-12-20 | Martin Stjernholm | | struct svalue s;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | defined_macro=alloc_empty_define(make_shared_string("defined"),0);
defined_macro->magic=check_defined;
defined_macro->args=1;
|
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 | |
|
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);
|
5aa54c | 2014-09-03 | Martin Nilsson | | char * pos=strchr(s,'=');
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | if(pos)
{
|
dc8d02 | 2014-04-27 | Martin Nilsson | | tmp->name=xalloc(pos-s+1);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(tmp->name,s,pos-s);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | tmp->name[pos-s]=0;
|
dc8d02 | 2014-04-27 | Martin Nilsson | | tmp->value=xalloc(s+strlen(s)-pos);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(tmp->value,pos+1,s+strlen(s)-pos);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }else{
|
dc8d02 | 2014-04-27 | Martin Nilsson | | tmp->name=xalloc(strlen(s)+1);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(tmp->name,s,strlen(s)+1);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
|
dc8d02 | 2014-04-27 | Martin Nilsson | | tmp->value=xalloc(4);
|
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;
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);
free(tmp->value);
|
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) | | }
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | free_string(defined_macro->link.s);
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(defined_macro);
|
516482 | 2004-11-14 | Martin Stjernholm | |
free_string (efun_str);
free_string (constant_str);
free_string (defined_str);
|
ae9503 | 1999-04-07 | Fredrik Hübinette (Hubbe) | | #endif
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | }
|