1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
|
/*-
* Copyright (c) 1998, 2002-2008 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
* All rights reserved.
*
* Some parts of this code are derived from the public domain software
* DECUS cpp (1984,1985) written by Martin Minow.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* I N T E R N A L . H
* I n t e r n a l D e f i n i t i o n s f o r M C P P
*
* In general, definitions in this file should not be changed by implementor.
*/
#ifndef SYSTEM_H
#error "system.H" must be included prior to "internal.H"
#endif
#include "mcpp_out.h"
#if MCPP_LIB
#include "mcpp_lib.h" /* External interface when used as library */
#endif
#define EOS '\0' /* End of string */
#define CHAR_EOF 0 /* Returned by get_ch() on eof */
#define VA_ARGS (UCHARMAX + 1) /* Signal of variable arguments */
#define GVA_ARGS (VA_ARGS * 2) /* GCC-specific variable args */
#define AVA_ARGS (VA_ARGS | GVA_ARGS)/* Any variable arguments */
#define DEF_PRAGMA (-1 - AVA_ARGS) /* _Pragma() pseudo-macro */
#define DEF_NOARGS (-2 - AVA_ARGS) /* #define foo vs #define foo() */
#define DEF_NOARGS_PREDEF_OLD (DEF_NOARGS - 1)
/* Compiler-predefined macro without leading '_' */
#define DEF_NOARGS_PREDEF (DEF_NOARGS - 2)/* Compiler-predefined macro */
#define DEF_NOARGS_STANDARD (DEF_NOARGS - 3)/* Standard predefined macro */
#define DEF_NOARGS_DYNAMIC (DEF_NOARGS - 4)/* Standard dynamically defined */
/*
* These magic characters must be control characters which can't be used
* in source file.
*/
/* for '#pragma MCPP debug macro_call' and -K option in STD mode. */
#define MAC_INF 0x18 /* Magic for macro informations */
/* In STD and POST_STD modes (IN_SRC and TOK_SEP are for STD mode only). */
#define DEF_MAGIC 0x19 /* Magic to prevent recursive expansion */
#define IN_SRC 0x1A /* Magic of name from source */
#define RT_END 0x1C /* Magic of macro rescan boundary */
#define ST_QUOTE 0x1D /* Magic for stringizing */
#define CAT 0x1E /* Token concatenation delim. */
#define TOK_SEP 0x1F /* Magic to wrap expanded macro */
/* In OLD_PREP mode. */
#define COM_SEP 0x1F /* Comment of 0-length */
#define MAC_PARM 0x7F /* Macro parameter signal */
/* Special character types */
#define LET 1 /* Letter (alphabet and _) */
#define DIG 2 /* Digit */
#define DOT 4 /* . might start a number */
#define PUNC 8 /* Punctuators and operators */
#define QUO 0x10 /* Both flavors of quotation ",'*/
#define SPA 0x20 /* White spaces */
#define HSP 0x40
/* Horizontal white spaces (' ', '\t', TOK_SEP) */
/*
* Codes for operators used in #if expression.
* The value of the scanned operator is stored in 'openum'.
*/
#define INV 0 /* Invalid, must be zero */
#define OP_EOE INV /* End of expression */
#define VAL 1 /* Value (operand) */
#define OP_LPA 2 /* ( */
/* The following are unary. */
#define FIRST_UNOP OP_PLU /* First unary operator */
#define OP_PLU 3 /* + */
#define OP_NEG 4 /* - */
#define OP_COM 5 /* ~ */
#define OP_NOT 6 /* ! */
#define LAST_UNOP OP_NOT /* Last unary operator */
/* The following are binary. */
#define FIRST_BINOP OP_MUL /* First binary operator */
#define OP_MUL 7 /* * */
#define OP_DIV 8 /* / */
#define OP_MOD 9 /* % */
#define OP_ADD 10 /* + */
#define OP_SUB 11 /* - */
#define OP_SL 12 /* << */
#define OP_SR 13 /* >> */
#define OP_LT 14 /* < */
#define OP_LE 15 /* <= */
#define OP_GT 16 /* > */
#define OP_GE 17 /* >= */
#define OP_EQ 18 /* == */
#define OP_NE 19 /* != */
#define OP_AND 20 /* & */
#define OP_XOR 21 /* ^ */
#define OP_OR 22 /* | */
#define OP_ANA 23 /* && */
#define OP_ORO 24 /* || */
#define OP_QUE 25 /* ? */
#define OP_COL 26 /* : */
#define LAST_BINOP OP_COL /* Last binary operator */
/* Parenthesis */
#define OP_RPA 27 /* ) */
#define OP_END 28 /* End of expression marker */
#define OP_FAIL (OP_END + 1) /* For error returns */
/*
* The following are operators used in macro definition only.
*/
/* In STD and POST_STD modes. */
#define OP_STR 30 /* # */
#define OP_CAT 31 /* ## */
#define OP_ELL 32 /* ... */
/*
* The following are C source operators or punctuators,
* not preprocessing operators.
* Note: "sizeof", "defined" are read as identifier for convenience.
*/
#define OP_1 33 /* Any other single byte ops or puncs */
/* =, ., ;, [, ], {, }, ',' */
#define OP_2 34 /* Any other two bytes operators */
/* &=, |=, ++, +=, --, -=, ->, %=, *=, /=, ^=, */
#define OP_3 35 /* Three bytes operators : <<=, >>= */
/*
* The following are operators spelled in digraphs.
*/
/* In STD and POST_STD modes. */
#define OP_LBRACE_D 0x40 /* <% i.e. { */
#define OP_RBRACE_D 0x41 /* %> i.e. } */
#define OP_LBRCK_D 0x42 /* <: i.e. [ */
#define OP_RBRCK_D 0x43 /* :> i.e. ] */
#define OP_SHARP_D 0x44 /* %: i.e. # */
#define OP_DSHARP_D 0x45 /* %:%: i.e. ## */
#define OP_DIGRAPH 0x40 /* (OP_*_D & OP_DIGRAPH) == 0x40 */
/*
* The following are for lexical scanning only.
*/
/* Token types */
#define NO_TOKEN 0
#define NAM 65 /* Identifier (name, keyword) */
#define NUM 66 /* Preprocessing number */
#define STR 67 /* Character string literal */
#define CHR 69 /* Integer character constant */
/* In STD and POST_STD modes. */
#define WSTR 68 /* Wide string literal */
#define WCHR 70 /* Wide character constant */
#define OPE 71 /* Operator or punctuator */
#define SPE 72 /* Unknown token (@ or others) */
#define SEP 73 /* Token separator or magics */
/*
* The following are values of 'mcpp_debug' variable which is set by the
* arguments of '#pragma MCPP debug' directive.
*/
#define PATH 1
#define TOKEN 2
#define EXPAND 4
#define MACRO_CALL 8
#define IF 16
#define EXPRESSION 32
#define GETC 64
#define MEMORY 128
/* MAC_* represent macro information types for -K option. */
#define MAC_CALL_START 1
#define MAC_CALL_END 2
#define MAC_ARG_START 3
#define MAC_ARG_END 4
/* MB_ERROR signals wrong multi-byte character sequence. */
#define MB_ERROR 0x8000
#if MCPP_LIB && HOST_COMPILER == GNUC \
&& (SYS_FAMILY == SYS_UNIX && SYSTEM != SYS_CYGWIN)
/* For GCC 4.* on UNIXes */
#pragma GCC visibility push( hidden) /* Hide these names from outside */
#endif
/*
* The DEFBUF structure stores information about #defined macros.
* Note that DEFBUF->parmnames is parameter names catenated with commas,
* which is saved for the check of redefinition for STD mode.
* 'parmnames' and 'repl' are allocated to the area succeding to name.
*/
typedef struct defbuf {
struct defbuf * link; /* Pointer to next def in chain */
short nargs; /* Number of parameters */
char * parmnames; /* -> Parameter names catenated by ',' */
char * repl; /* Pointer to replacement text */
const char * fname; /* Macro is defined in the source file */
long mline; /* at the line. */
char push; /* Push level indicator */
char name[1]; /* Macro name */
} DEFBUF;
/*
* The FILEINFO structure stores information about open files and macros
* being expanded.
*/
typedef struct fileinfo {
char * bptr; /* Current pointer into buffer */
long line; /* Current line number of file */
FILE * fp; /* Source file if non-null */
long pos; /* Position next to #include */
struct fileinfo * parent; /* Link to includer */
struct ifinfo * initif; /* Initial ifstack (return there on EOF)*/
int sys_header; /* System header file or not */
int include_opt; /* Specified by -include option */
const char ** dirp; /* Include directory the file resides */
char * src_dir; /* Directory of source file */
const char * real_fname; /* Real file name */
char * full_fname; /* Real full path list */
char * filename; /* File/macro name (maybe changed) */
char * buffer; /* Buffer of current input line */
#if MCPP_LIB
/* Save output functions during push/pop of #includes */
int (* last_fputc) ( int c, OUTDEST od);
int (* last_fputs) ( const char * s, OUTDEST od);
int (* last_fprintf)( OUTDEST od, const char * format, ...);
#endif
} FILEINFO;
/*
* IFINFO stores information of conditional compilation.
*/
typedef struct ifinfo {
int stat; /* State of compilation */
long ifline; /* Line #if started */
long elseline; /* Line #else started */
} IFINFO;
/*
* These bits are set in IFINFO.stat
*/
#define WAS_COMPILING 1 /* TRUE if compile set at entry */
#define ELSE_SEEN 2 /* TRUE when #else processed */
#define TRUE_SEEN 4 /* TRUE when #if TRUE processed */
#define compiling ifstack[0].stat
#define FP2DEST(fp) \
(fp == fp_out) ? OUT : \
((fp == fp_err) ? ERR : \
((fp == fp_debug) ? DBG : \
((OUTDEST) -1)))
/* VAL_SIGN structure stores information about evaluated number. */
typedef struct val_sign {
expr_t val; /* Value */
int sign; /* Signed, unsigned, error */
} VAL_SIGN;
/* Values of VAL_SIGN.sign. */
#define SIGNED 1
#define UNSIGNED 0
#define VAL_ERROR (-1)
/* LINE_COL stores information of line and column data */
typedef struct line_col {
long line;
size_t col;
} LINE_COL;
/* Value of macro_line on macro call error. */
#define MACRO_ERROR (-1L)
/*
* Values of insert_sep (flag of insertion of token separator).
* Used only in POST_STD mode.
*/
#define NO_SEP 0 /* No separator is inserted */
#define INSERT_SEP 1 /* Next get_ch() insert a separator */
#define INSERTED_SEP 2 /* Last get_ch() Inserted a separator */
#define str_eq(s1, s2) (strcmp(s1, s2) == 0)
#ifndef IO_SUCCESS
#define IO_SUCCESS 0
#endif
#ifndef IO_ERROR
#define IO_ERROR (errno ? errno : 1)
#endif
/*
* Externs
*/
/* The minimum translation limits specified by the Standards. */
extern struct std_limits_ {
long str_len; /* Least maximum of string len. */
size_t id_len; /* Least maximum of ident len. */
int n_mac_pars; /* Least maximum of num of pars.*/
int exp_nest; /* Least maximum of expr nest */
int blk_nest; /* Least maximum of block nest */
int inc_nest; /* Least maximum of include nest*/
long n_macro; /* Least maximum of num of macro*/
long line_num; /* Maximum source line number */
} std_limits;
/* The boolean flags specified by the execution options. */
extern struct option_flags_ {
int c; /* -C option (keep comments) */
int k; /* -k option (keep white spaces)*/
int z; /* -z option (no-output of included file) */
int p; /* -P option (no #line output) */
int q; /* -Q option (diag to mcpp.err) */
int v; /* -v option (verbose) */
int trig; /* -3 option (toggle trigraphs) */
int dig; /* -2 option (toggle digraphs) */
int lang_asm; /* -a option (assembler source) */
int no_source_line; /* Do not output line in diag. */
int dollar_in_name; /* Allow $ in identifiers */
} option_flags;
extern int mcpp_mode; /* Mode of preprocessing */
extern int stdc_val; /* Value of __STDC__ */
extern long stdc_ver; /* Value of __STDC_VERSION__ */
extern long cplus_val; /* Value of __cplusplus for C++ */
extern int stdc2; /* cplus_val or (stdc_ver >= 199901L) */
extern int stdc3; /* (stdc_ver or cplus_val) >= 199901L */
extern int standard; /* mcpp_mode is STD or POST_STD */
extern int std_line_prefix; /* #line in C source style */
extern int warn_level; /* Level of warning */
extern int errors; /* Error counter */
extern long src_line; /* Current source line number */
extern int wrong_line; /* Force #line to compiler */
extern int newlines; /* Count of blank lines */
extern int keep_comments; /* Don't remove comments */
extern int keep_spaces; /* Don't remove white spaces */
extern int include_nest; /* Nesting level of #include */
extern const char * null; /* "" string for convenience */
extern const char ** inc_dirp; /* Directory of #includer */
extern const char * cur_fname; /* Current source file name */
extern int no_output; /* Don't output included file */
extern int in_directive; /* In process of #directive */
extern int in_define; /* In #define line */
extern int in_getarg; /* Collecting arguments of macro*/
extern int in_include; /* In #include line */
extern int in_if; /* In #if and non-skipped expr. */
extern long macro_line; /* Line number of macro call */
extern char * macro_name; /* Currently expanding macro */
extern int openum; /* Number of operator or punct. */
extern IFINFO * ifptr; /* -> current ifstack item */
extern FILEINFO * infile; /* Current input file or macro */
extern FILE * fp_in; /* Input stream to preprocess */
extern FILE * fp_out; /* Output stream preprocessed */
extern FILE * fp_err; /* Diagnostics stream */
extern FILE * fp_debug; /* Debugging information stream */
extern int insert_sep; /* Inserted token separator flag*/
extern int mkdep; /* Output source file dependency*/
extern int mbchar; /* Encoding of multi-byte char */
extern int mbchk; /* Possible multi-byte char */
extern int bsl_in_mbchar; /* 2nd byte of mbchar has '\\' */
extern int bsl_need_escape;/* '\\' in mbchar should be escaped */
extern int mcpp_debug; /* Class of debug information */
extern long in_asm; /* In #asm - #endasm block */
extern jmp_buf error_exit; /* Exit on fatal error */
extern char * cur_fullname; /* Full name of current source */
extern short * char_type; /* Character classifier */
extern char * workp; /* Free space in work[] */
extern char * const work_end; /* End of work[] buffer */
extern char identifier[]; /* Lastly scanned name */
extern IFINFO ifstack[]; /* Information of #if nesting */
extern char work_buf[];
extern FILEINFO * sh_file;
extern int sh_line;
/* Temporary buffer for directive line and macro expansion */
/* main.c */
extern void un_predefine( int clearall);
/* Undefine predefined macros */
/* directive.c */
extern void directive( void);
/* Process #directive line */
extern DEFBUF * do_define( int ignore_redef, int predefine);
/* Do #define directive */
extern DEFBUF * look_id( const char * name);
/* Look for a #define'd thing */
extern DEFBUF ** look_prev( const char * name, int * cmp);
/* Look for place to insert def.*/
extern DEFBUF * look_and_install( const char * name, int numargs
, const char * parmnames, const char * repl);
/* Look and insert macro def. */
extern DEFBUF * install_macro( const char * name, int numargs
, const char * parmnames, const char * repl, DEFBUF ** prevp, int cmp
, int predefine);
/* Install a def to symbol table*/
extern int undefine( const char * name);
/* Delete from symbol table */
extern void dump_a_def( const char * why, const DEFBUF * dp, int newdef
, int comment, FILE * fp);
/* Dump a specific macro def */
extern void dump_def( int comment, int K_opt);
/* Dump current macro defs */
/* eval.c */
extern expr_t eval_if( void);
/* Evaluate #if expression */
extern VAL_SIGN * eval_num( const char * nump);
/* Evaluate preprocessing number*/
/* expand.c */
extern char * (* expand_macro)( DEFBUF * defp, char * out, char * out_end
, LINE_COL line_col, int * pragma_op);
/* Expand a macro completely */
extern void expand_init( int compat, int strict_ansi);
/* Initialize expand_macro() */
extern DEFBUF * is_macro( char ** cp);
/* The sequence is a macro call?*/
/* mbchar.c */
extern size_t (* mb_read)( int c1, char ** in_pp, char ** out_pp);
/* Read mbchar sequence */
extern const char * set_encoding( char * name, char * env, int pragma);
/* Multi-byte char encoding */
extern void mb_init( void);
/* Initialize mbchar variables */
extern uexpr_t mb_eval( char ** seq_pp);
/* Evaluate mbchar in #if */
extern int last_is_mbchar( const char * in, int len);
/* The line ends with MBCHAR ? */
/* support.c */
extern int get_unexpandable( int c, int diag);
/* Get next unexpandable token */
extern void skip_nl( void);
/* Skip to the end of the line */
extern int skip_ws( void);
/* Skip over white-spaces */
extern int scan_token( int c, char ** out_pp, char * out_end);
/* Get the next token */
extern char * scan_quote( int delim, char * out, char * out_end, int diag);
/* Scan a quoted literal */
extern int id_operator( const char * name);
/* Check identifier-like ops */
extern void expanding( const char * name, int to_be_freed);
/* Save macro name expanding */
extern void clear_exp_mac( void);
/* Clear expanding macro infs */
extern int get_ch( void);
/* Get the next char from input */
extern int cnv_trigraph( char * in);
/* Do trigraph replacement */
extern int cnv_digraph( char * in);
/* Convert digraphs to usual tok*/
extern void unget_ch( void);
/* Push back the char to input */
extern FILEINFO * unget_string( const char * text, const char * name);
/* Push back the string to input*/
extern char * save_string( const char * text);
/* Stuff string in malloc mem. */
extern FILEINFO * get_file( const char * name, const char * src_dir
, char * fullname, size_t bufsize, int include_opt);
/* New FILEINFO initialization */
extern char * (xmalloc)( size_t size);
/* Get memory or die */
extern char * (xrealloc)( char * ptr, size_t size);
/* Reallocate memory or die */
extern LINE_COL * get_src_location( LINE_COL * p_line_col);
/* Get location on source file */
extern void cfatal( const char * format, const char * arg1, long arg2
, const char * arg3);
/* Print a fatal error and exit */
extern void cerror( const char * format, const char * arg1, long arg2
, const char * arg3);
/* Print an error message */
extern void cwarn( const char * format, const char * arg1, long arg2
, const char * arg3);
/* Print a warning message */
extern void dump_string( const char * why, const char * text);
/* Dump text readably */
extern void dump_unget( const char * why);
/* Dump all ungotten junk */
/* Support for alternate output mechanisms (e.g. memory buffers) */
extern int (* mcpp_fputc)( int c, OUTDEST od),
(* mcpp_fputs)( const char * s, OUTDEST od),
(* mcpp_fprintf)( OUTDEST od, const char * format, ...);
/* system.c */
extern void do_options( int argc, char ** argv, char ** in_pp
, char ** out_pp);
/* Process command line args */
extern void init_sys_macro( void);
/* Define system-specific macro */
extern void at_start( void);
/* Commands prior to main input */
extern void put_depend( const char * filename);
/* Output source dependency line*/
extern int do_include( int next);
/* Process #include directive */
extern void add_file( FILE * fp, const char * src_dir
, char * filename, char * fullname, int include_opt);
/* Chain the included file */
extern void sharp( FILEINFO * sharp_file, int marker);
/* Output # line number */
extern void do_pragma( void);
/* Process #pragma directive */
extern void put_asm( void);
/* Putout an asm code line */
extern void do_old( void);
/* Process older directives */
extern void at_end( void);
/* Do the final commands */
extern void print_heap( void);
/* Print blocks of heap memory */
#if ! HOST_HAVE_STPCPY
extern char * stpcpy( char * dest, const char * src);
/* Non-Standard library function*/
#endif
#if MCPP_LIB /* Setting to use mcpp as a subroutine */
/* directive.c */
extern void clear_symtable( void);
/* Free all macro definitions */
/* system.c */
extern void clear_filelist( void);
/* Free filename and directory list */
/* The following 5 functions are to Initialize static variables. */
/* directive.c */
extern void init_directive( void);
/* eval.c */
extern void init_eval( void);
/* support.c */
extern void init_support( void);
/* system.c */
extern void init_system( void);
#if HOST_COMPILER == GNUC && (SYS_FAMILY == SYS_UNIX && SYSTEM != SYS_CYGWIN)
#pragma GCC visibility pop
#endif
#endif
#if HOST_HAVE_STPCPY && !defined(stpcpy)
extern char * stpcpy( char * dest, const char * src);
#endif
|