Commit 27337af6 authored by Bertho Stultiens's avatar Bertho Stultiens Committed by Alexandre Julliard

- Implemented a new preprocessor that is (nearly) ANSI-C compliant. The

old parser has been stripped from the old preprocessor-code which cleaned up both resource-scanner and -parser. - Standard defines have been introduced (see README.wrc) - Both preprocessor- and resource-scanner have been optimized slightly so that no backing up is required (one char lookahead is enough). - Filename-scanning has been cleaned up, though not perfect yet. - User-type resources are compatible now. - Line-continuation in strings is corrected so that it does not introduce a newline in the output.
parent 5b4f3e8d
#include "windef.h"
#include "winuser.h"
#include "comctl32.h"
......
......@@ -3,6 +3,7 @@
*
*/
#include "windef.h"
#include "winuser.h"
#include "winnls.h"
#include "cdlg.h"
......
......@@ -3,7 +3,7 @@
*
*/
1 "OEMBIN"
1 OEMBIN
{
0x11, /* vertical thumb height (in pixels) */
0x11, /* horizontal thumb width (in pixels) */
......
......@@ -3,6 +3,7 @@
*
*/
#include "windef.h"
#include "winuser.h"
#include "winnls.h"
#include "shlobj.h"
......
......@@ -25,10 +25,6 @@ all: check_wrc $(PROGRAMS)
@MAKE_RULES@
# Override resource compiler rules
.rc.s:
$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
clock: $(OBJS)
$(CC) -o clock $(OBJS) $(DLL_LINK) $(LIBS)
......
......@@ -26,10 +26,6 @@ all: check_wrc $(PROGRAMS)
@MAKE_RULES@
# Override resource compiler rules
.rc.s:
$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
notepad: $(OBJS)
$(CC) -o notepad $(OBJS) $(DLL_LINK) $(LIBS)
......
......@@ -28,10 +28,6 @@ all: check_wrc $(PROGRAMS)
@MAKE_RULES@
# Override resource compiler rules
.rc.s:
$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
progman: $(OBJS)
$(CC) -o progman $(OBJS) $(DLL_LINK) $(LIBS)
......
......@@ -22,10 +22,6 @@ all: check_wrc $(PROGRAMS)
@MAKE_RULES@
# Override resource compiler rules
.rc.s:
$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
winemine: $(OBJS)
$(CC) -o winemine $(OBJS) $(DLL_LINK) $(LIBS)
......
......@@ -27,10 +27,6 @@ depend: y.tab.h
@MAKE_RULES@
# Override resource compiler rules
.rc.s:
$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
winhelp: $(OBJS)
$(CC) -o winhelp $(OBJS) $(DLL_LINK) $(LIBS)
......
......@@ -3,6 +3,7 @@
*
*/
#include "windef.h"
#include "winuser.h"
#include "winnls.h"
#include "dlgs.h"
......
......@@ -19,7 +19,7 @@ EXTRASUBDIRS = \
winapi_check/win32 \
wineconf.libs
all: $(PROGRAMS)
all: $(PROGRAMS) wrc
@MAKE_RULES@
......
Makefile
lex.ppl.c
lex.yy.c
ppy.tab.c
ppy.tab.h
wrc
y.tab.c
y.tab.h
---------------------------------------------------------------------------
Version 1.1.0 (01-May-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Implemented a new preprocessor that is (nearly) ANSI-C compliant. The
old parser has been stripped from the old preprocessor-code which
cleaned up both resource-scanner and -parser.
- Standard defines have been introduced (see README.wrc)
- Both preprocessor- and resource-scanner have been optimized slightly
so that no backing up is required (one char lookahead is enough).
- Filename-scanning has been cleaned up, though not perfect yet.
- User-type resources are compatible now.
- Line-continuation in strings is corrected so that it does not
introduce a newline in the output.
---------------------------------------------------------------------------
Version 1.0.18 (28-Dec-1999)
Bertho Stultiens <bertho@akhphd.au.dk>
......
......@@ -3,6 +3,8 @@ TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
LEXOPT = -Cf #-w -b
YACCOPT = #-v
PROGRAMS = wrc@PROGEXT@
MODULE = none
......@@ -17,12 +19,12 @@ C_SRCS = \
wrc.c \
writeres.c
EXTRA_SRCS = parser.y parser.l
EXTRA_OBJS = y.tab.o lex.yy.o
EXTRA_SRCS = parser.y parser.l ppl.l ppy.y ppy.tab.c lex.ppl.c
EXTRA_OBJS = y.tab.o lex.yy.o ppy.tab.o lex.ppl.o
all: $(PROGRAMS)
depend: y.tab.h
depend: y.tab.h ppy.tab.h ppy.tab.c lex.ppl.c
@MAKE_RULES@
......@@ -30,12 +32,18 @@ wrc@PROGEXT@: $(OBJS)
$(CC) $(CFLAGS) -o wrc@PROGEXT@ $(OBJS) $(LEXLIB)
y.tab.c y.tab.h: parser.y
$(YACC) -d -t $(SRCDIR)/parser.y
$(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y
ppy.tab.c ppy.tab.h: ppy.y
$(YACC) $(YACCOPT) -bppy -ppp -d -t $(SRCDIR)/ppy.y
lex.yy.c: parser.l
$(LEX) -8 $(SRCDIR)/parser.l
$(LEX) $(LEXOPT) -d -8 $(SRCDIR)/parser.l
lex.ppl.c: ppl.l
$(LEX) $(LEXOPT) -d -Ppp -8 -olex.ppl.c $(SRCDIR)/ppl.l
clean::
$(RM) y.tab.c y.tab.h lex.yy.c
$(RM) y.tab.c y.tab.h lex.yy.c ppy.tab.c ppy.tab.h lex.ppl.c ppy.output lex.backup y.output
### Dependencies:
Release 1.0.2 of wrc (20-Jun-1998), the wine resource compiler.
Release 1.1.0 of wrc (01-May-2000), the wine resource compiler.
See the file CHANGES for differences between the version and what has been
corrected in the current version.
Wrc features:
- source preprocessing
- full source preprocessing
- 16 and 32 bit support
- LANGUAGE support (32 bit only)
- almost all resource types are supported
- most resource types are supported
- enhanced expression capabilities and resource naming
- indirect loadable resources
- NE/PE resource directory generation
......@@ -34,13 +34,15 @@ Usage: wrc [options...] [infile[.rc|.res]]
-d n Set debug level to 'n'
-D id[=val] Define preprocessor identifier id=val
-e Disable recognition of win32 keywords in 16bit compile
-E Preprocess only
-g Add symbols to the global c namespace
-h Also generate a .h file
-H file Same as -h but written to file
-I path Set include search dir to path (multiple -I allowed)
-l lan Set default language to lan (default is neutral {0})
-l lan Set default language to lan (default is neutral {0, 0})
-L Leave case of embedded filenames as is
-n Do not generate .s file
-N Do not preprocess input
-o file Output to file (default is infile.[res|s|h]
-p prefix Give a prefix for the generated names
-r Create binary .res file (compile only)
......@@ -57,6 +59,9 @@ Debug level 'n' is a bitmask with following meaning:
* 0x01 Tell which resource is parsed (verbose mode)
* 0x02 Dump internal structures
* 0x04 Create a parser trace (yydebug=1)
* 0x08 Preprocessor messages
* 0x10 Preprocessor lex messages
* 0x20 Preprocessor yacc trace
The -o option only applies to the final destination file, which is
in case of normal compile a .s file. You must use the '-H header.h'
......@@ -67,10 +72,12 @@ with -o and/or -H, then the output is written to "wrc.tab.[sh]"
Preprocessing
-------------
The build-in preprocessor is not a full implementation of the C counterpart.
Wrc does not understand function-type macros. These are discarded as they
are scanned. This will be a future project. Wrc does understand these:
#define
The preprocessor is a fully operational C preprocessor. It handles all
directives supported by ANSI-C. It also includes some additions from
gcc/egcs.
Wrc understands these directives:
#define (both simple and macro)
#undef
#if
#ifdef
#ifndef
......@@ -78,13 +85,42 @@ are scanned. This will be a future project. Wrc does understand these:
#else
#endif
#error
Also 'defined' is supported as operator (both with and without parenthesis).
'#if' expressions can be anything valid that evaluates to an integer
expression (where 0 is false and anything else is true). Others (#pragma,
#line) are ignored. A special case '#' generates an error. This is due to
the implementation to enable generation of errors on preprocessing and will
be improved in the future.
#warning
#line
#
#pragma (ignored)
#ident (ignored)
The extensions include '#'-line directives.
Not handled at the moment are variable argument macros. They are parsed,
but not expanded properly. This will be corrected in the future.
The preprocessor handles the special defines and aditionally defines an
extra set of defines:
Define | Value | Comment
-----------+-------------------+---------------
RC_INVOKED | 1 | Always defined
__FLAT__ | 1 | Only defined if win32 compile
__WIN32__ | 1 | Only defined if win32 compile
__FILE__ | "..." | Current filename as string
__LINE__ | nnn | Current linenumber as integer
__TIME__ | "23:59:59" | Timestring of compilation
__DATE__ | "May 1 2000" | Datestring of compilation
__WRC__  1 | Wrc's major version
__WRC_MINOR__ | 1 | Wrc's minor version
__WRC_MICRO__ | 0 | Wrc's minor version
__WRC_PATCH__ | 0 | Alias of __WRC_MICRO__
Include-files are not read twice if they are protected with this scheme:
#ifndef SOME_DEFINE
#define SOME_DEFINE
...
#endif
This strategy has been borrowed from gcc/egcs and results in significantly
reduced preprocessing times (20..30%). There must not be any junk before
the first #ifndef and not after the last #endif; comments and whitespace
excepted. Wrc will check the existance of the define prior to inclusion to
detect "#undef SOME_DEFINE" (notably poppack.h) and act accordingly.
16 and 32 bit support
......@@ -115,35 +151,15 @@ statement before (and evt. after) the code in the resource file.
Resource types supported
------------------------
All types are supported except for:
- FONT
- MESSAGETABLE
- extensions like TOOLBAR and the like (is this a user-type?)
- FONT (RT_FONT, RT_FONTDIR)
- MESSAGETABLE (RT_MESSAGETABLE)
- Animated cursors/icons (RT_ANIICON, RT_ANICURSOR)
- RT_VXD
- RT_PLUGPLAY
These types will be implemented as soon as I get a proper specification of
the layout.
Note: Usertype resources with character strings as types have a different
layout and do not accept expressions when a numerical type is specified. The
must be enclosed in double quotes. These are examples of valid usertype
resources:
MyName "MyType" mydata.bin
MyName 12345 mydata.bin
MyName "MyType" "mydata.bin"
MyName 12345 "mydata.bin"
MyName "MyType"
{
..., data, ...
}
or
MyName 12345
{
..., data, ...
}
Expression capabilities and resource names
------------------------------------------
......@@ -152,22 +168,19 @@ expects a number (except usertype type). Operators supported:
() parenthesis
* multiply
/ divide
+ add
+ plus/add
- minus/substract
| binary or
& binary and
~ binary not (unary operator though)
NOT ... (sigh)
Minus (-) can both be unary and binary. The NOT operator is (primarily)
used to disable window styles but I strongly suggest to refrain from using
this operator.
There is a shift/reduce conflict on the unary minus, but this is not
problematic. I was too lazy to make a new expression parser (next version or
so). Unary plus (+) would cause another confilct, so I let it out for now.
Plus (+) and minus (-) can both be unary and binary. The NOT operator is
(primarily) used to disable window styles but I strongly suggest to refrain
from using this operator.
Resource names can be both numerical (expressions) and character typed. Wrc
does supports this insane (deep sigh) construct:
does support this insane (deep sigh) construct:
MENU MENU
{
......@@ -250,9 +263,8 @@ though):
- No documentation ('wrc -?' gives command-line options though)
- grep for FIXME in the source
- Memory options are wrong under some conditions. There seems to be a
different action for win32 and win16.
- User-type resources have slightly different layout.
- Filename scanning is still hopeless.
different action for win32 and win16
- Little/big-endian
Reporting bugs and patches
--------------------------
......
......@@ -293,3 +293,4 @@ style_t *new_style(DWORD or_mask, DWORD and_mask)
st->and_mask = and_mask;
return st;
}
......@@ -9,8 +9,7 @@
/* From parser.y */
extern int yydebug;
extern int indialog; /* Set when parsing dialogs */
extern int want_rscname; /* Set when a resource's name is required */
extern int want_nl; /* Set when getting line-numers */
int yyparse(void);
void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico);
......@@ -19,15 +18,10 @@ void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur);
/* From parser.l */
extern FILE *yyin;
extern char *yytext;
extern int line_number;
extern int char_number;
extern int yy_flex_debug;
int yylex(void);
void set_yywf(void);
void set_pp_ignore(int state);
void push_to(int start);
void pop_start(void);
void strip_extern(void);
void strip_til_semicolon(void);
void strip_til_parenthesis(void);
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
......@@ -6,30 +6,193 @@
#ifndef __WRC_PREPROC_H
#define __WRC_PREPROC_H
struct pp_entry {
struct pp_entry; /* forward */
/*
* Include logic
* A stack of files which are already included and
* are protected in the #ifndef/#endif way.
*/
typedef struct includelogicentry {
struct includelogicentry *next;
struct includelogicentry *prev;
struct pp_entry *ppp; /* The define which protects the file */
char *filename; /* The filename of the include */
} includelogicentry_t;
/*
* The arguments of a macrodefinition
*/
typedef enum {
arg_single,
arg_list
} def_arg_t;
typedef struct marg {
def_arg_t type; /* Normal or ... argument */
char *arg; /* The textual argument */
int nnl; /* Number of newlines in the text to subst */
} marg_t;
/*
* The expansiontext of a macro
*/
typedef enum {
exp_text, /* Simple text substitution */
exp_concat, /* Concat (##) operator requested */
exp_stringize, /* Stringize (#) operator requested */
exp_subst /* Substitute argument */
} def_exp_t;
typedef struct mtext {
struct mtext *next;
struct mtext *prev;
def_exp_t type;
union {
char *text;
int argidx; /* For exp_subst and exp_stringize reference */
} subst;
} mtext_t;
/*
* The define descriptor
*/
typedef enum {
def_none, /* Not-a-define; used as return value */
def_define, /* Simple defines */
def_macro, /* Macro defines */
def_special /* Special expansions like __LINE__ and __FILE__ */
} def_type_t;
typedef struct pp_entry {
struct pp_entry *next;
struct pp_entry *prev;
char *ident;
char *subst;
int expanding;
};
struct if_state {
int current;
int hasbeentrue;
int nevertrue;
};
struct pp_entry *pp_lookup(char *ident);
void set_define(char *name);
def_type_t type; /* Define or macro */
char *ident; /* The key */
marg_t **margs; /* Macro arguments array or NULL if none */
int nargs;
union {
mtext_t *mtext; /* The substitution sequence or NULL if none */
char *text;
} subst;
int expanding; /* Set when feeding substitution into the input */
char *filename; /* Filename where it was defined */
int linenumber; /* Linenumber where it was defined */
includelogicentry_t *iep; /* Points to the include it protects */
} pp_entry_t;
/*
* If logic
*/
#define MAXIFSTACK 64 /* If this isn't enough you should alter the source... */
typedef enum {
if_false,
if_true,
if_elif,
if_elsefalse,
if_elsetrue,
if_ignore
} if_state_t;
/*
* I assume that 'long long' exists in the compiler when it has a size
* of 8 or bigger. If not, then we revert to a simple 'long' for now.
* This should prevent most unexpected things with other compilers than
* gcc and egcs for now.
* In the future it should be possible to use another way, like a
* structure, so that we can emulate the MS compiler.
*/
#if defined(SIZEOF_LONGLONG) && SIZEOF_LONGLONG >= 8
typedef long long wrc_sll_t;
typedef unsigned long long wrc_ull_t;
#else
typedef long wrc_sll_t;
typedef unsigned long wrc_ull_t;
#endif
#define SIZE_CHAR 1
#define SIZE_SHORT 2
#define SIZE_INT 3
#define SIZE_LONG 4
#define SIZE_LONGLONG 5
#define SIZE_MASK 0x00ff
#define FLAG_SIGNED 0x0100
typedef enum {
#if 0
cv_schar = SIZE_CHAR + FLAG_SIGNED,
cv_uchar = SIZE_CHAR,
cv_sshort = SIZE_SHORT + FLAG_SIGNED,
cv_ushort = SIZE_SHORT,
#endif
cv_sint = SIZE_INT + FLAG_SIGNED,
cv_uint = SIZE_INT,
cv_slong = SIZE_LONG + FLAG_SIGNED,
cv_ulong = SIZE_LONG,
cv_sll = SIZE_LONGLONG + FLAG_SIGNED,
cv_ull = SIZE_LONGLONG
} ctype_t;
typedef struct cval {
ctype_t type;
union {
#if 0
signed char sc; /* Explicitely signed because compilers are stupid */
unsigned char uc;
short ss;
unsigned short us;
#endif
int si;
unsigned int ui;
long sl;
unsigned long ul;
wrc_sll_t sll;
wrc_ull_t ull;
} val;
} cval_t;
pp_entry_t *pplookup(char *ident);
pp_entry_t *add_define(char *def, char *text);
pp_entry_t *add_cmdline_define(char *set);
pp_entry_t *add_special_define(char *id);
pp_entry_t *add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp);
void del_define(char *name);
void add_define(char *text);
void add_cmdline_define(char *set);
FILE *open_include(const char *name, int search);
FILE *open_include(const char *name, int search, char **newpath);
void add_include_path(char *path);
void push_if(int truecase, int wastrue, int nevertrue);
int pop_if(void);
int isnevertrue_if(void);
void push_if(if_state_t s);
void next_if_state(int);
if_state_t pop_if(void);
if_state_t if_state(void);
int get_if_depth(void);
/*
* From ppl.l
*/
extern FILE *ppin;
extern FILE *ppout;
extern char *pptext;
extern int pp_flex_debug;
int pplex(void);
void do_include(char *fname, int type);
void push_ignore_state(void);
void pop_ignore_state(void);
extern int include_state;
extern char *include_ppp;
extern char *include_filename;
extern int include_ifdepth;
extern int seen_junk;
extern includelogicentry_t *includelogiclist;
/*
* From ppy.y
*/
int ppparse(void);
extern int ppdebug;
#endif
......@@ -17,8 +17,9 @@
#include "wrc.h"
#include "utils.h"
#include "parser.h"
#include "preproc.h"
#define WANT_NEAR_INDICATION
/* #define WANT_NEAR_INDICATION */
#ifdef WANT_NEAR_INDICATION
......@@ -33,22 +34,31 @@ void make_print(char *str)
}
#endif
int yyerror(const char *s, ...)
static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Error %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
fprintf(stderr, "%s %s: %d, %d: ", t, input_name ? input_name : "stdin", line_number, char_number);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
{
char *cpy = xstrdup(yytext);
make_print(cpy);
fprintf(stderr, " near '%s'\n", cpy);
free(cpy);
char *cpy;
if(n)
{
cpy = xstrdup(n);
make_print(cpy);
fprintf(stderr, " near '%s'", cpy);
free(cpy);
}
}
#else
fprintf(stderr, "\n");
#endif
fprintf(stderr, "\n");
}
int yyerror(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Error", yytext, ap);
va_end(ap);
exit(1);
return 1;
......@@ -58,22 +68,31 @@ int yywarning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Warning %s: %d, %d: ", input_name ? input_name : "stdin", line_number, char_number);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
{
char *cpy = xstrdup(yytext);
make_print(cpy);
fprintf(stderr, " near '%s'\n", cpy);
free(cpy);
}
#else
fprintf(stderr, "\n");
#endif
generic_msg(s, "Warning", yytext, ap);
va_end(ap);
return 0;
}
int pperror(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Error", pptext, ap);
va_end(ap);
exit(1);
return 1;
}
int ppwarning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Warning", pptext, ap);
va_end(ap);
return 0;
}
void internal_error(const char *file, int line, const char *s, ...)
{
va_list ap;
......@@ -156,6 +175,11 @@ void *xmalloc(size_t size)
{
error("Virtual memory exhausted.\n");
}
/*
* We set it to 0.
* This is *paramount* because we depend on it
* just about everywhere in the rest of the code.
*/
memset(res, 0, size);
return res;
}
......@@ -177,7 +201,10 @@ void *xrealloc(void *p, size_t size)
char *xstrdup(const char *str)
{
char *s = (char *)xmalloc(strlen(str)+1);
char *s;
assert(str != NULL);
s = (char *)xmalloc(strlen(str)+1);
return strcpy(s, str);
}
......
......@@ -18,12 +18,14 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *str);
int yyerror(const char *s, ...);
int yywarning(const char *s, ...);
void internal_error(const char *file, int line, const char *s, ...);
void error(const char *s, ...);
void warning(const char *s, ...);
void chat(const char *s, ...);
int pperror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int ppwarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
void error(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *dup_basename(const char *name, const char *ext);
int string_compare(const string_t *s1, const string_t *s2);
......
......@@ -3,6 +3,7 @@
* Copyright Martin von Loewis, 1994
* Copyrignt 1998 Bertho A. Stultiens (BS)
*
* 30-Apr-2000 BS - Integrated a new preprocessor (-E and -N)
* 20-Jun-1998 BS - Added -L option to prevent case conversion
* of embedded filenames.
*
......@@ -36,9 +37,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <signal.h>
#include "wrc.h"
#include "utils.h"
......@@ -59,13 +62,15 @@ char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n"
" -d n Set debug level to 'n'\n"
" -D id[=val] Define preprocessor identifier id=val\n"
" -e Disable recognition of win32 keywords in 16bit compile\n"
" -E Preprocess only\n"
" -g Add symbols to the global c namespace\n"
" -h Also generate a .h file\n"
" -H file Same as -h but written to file\n"
" -I path Set include search dir to path (multiple -I allowed)\n"
" -l lan Set default language to lan (default is neutral {0})\n"
" -l lan Set default language to lan (default is neutral {0, 0})\n"
" -L Leave case of embedded filenames as is\n"
" -n Do not generate .s file\n"
" -N Do not preprocess input\n"
" -o file Output to file (default is infile.[res|s|h]\n"
" -p prefix Give a prefix for the generated names\n"
" -r Create binary .res file (compile only)\n"
......@@ -80,6 +85,9 @@ char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n"
" * 0x01 Tell which resource is parsed (verbose mode)\n"
" * 0x02 Dump internal structures\n"
" * 0x04 Create a parser trace (yydebug=1)\n"
" * 0x08 Preprocessor messages\n"
" * 0x10 Preprocessor lex messages\n"
" * 0x20 Preprocessor yacc trace\n"
"The -o option only applies to the final destination file, which is\n"
"in case of normal compile a .s file. You must use the '-H header.h'\n"
"option to override the header-filename.\n"
......@@ -88,7 +96,7 @@ char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n"
;
char version_string[] = "Wine Resource Compiler Version " WRC_FULLVERSION "\n"
"Copyright 1998,1999 Bertho A. Stultiens\n"
"Copyright 1998-2000 Bertho A. Stultiens\n"
" 1994 Martin von Loewis\n";
/*
......@@ -121,6 +129,9 @@ int create_res = 0;
* debuglevel & DEBUGLEVEL_CHAT Say whats done
* debuglevel & DEBUGLEVEL_DUMP Dump internal structures
* debuglevel & DEBUGLEVEL_TRACE Create parser trace
* debuglevel & DEBUGLEVEL_PPMSG Preprocessor messages
* debuglevel & DEBUGLEVEL_PPLEX Preprocessor lex trace
* debuglevel & DEBUGLEVEL_PPTRACE Preprocessor yacc trace
*/
int debuglevel = DEBUGLEVEL_NONE;
......@@ -198,15 +209,32 @@ int auto_register = 0;
*/
int leave_case = 0;
/*
* Set when _only_ to run the preprocessor (-E option)
*/
int preprocess_only = 0;
/*
* Set when _not_ to run the preprocessor (-N option)
*/
int no_preprocess = 0;
char *output_name; /* The name given by the -o option */
char *input_name; /* The name given on the command-line */
char *header_name; /* The name given by the -H option */
char *temp_name; /* Temporary file for preprocess pipe */
int line_number = 1; /* The current line */
int char_number = 1; /* The current char pos within the line */
char *cmdline; /* The entire commandline */
time_t now; /* The time of start of wrc */
resource_t *resource_top; /* The top of the parsed resources */
int getopt (int argc, char *const *argv, const char *optstring);
static void rm_tempfile(void);
static void segvhandler(int sig);
int main(int argc,char *argv[])
{
......@@ -219,6 +247,10 @@ int main(int argc,char *argv[])
int i;
int cmdlen;
signal(SIGSEGV, segvhandler);
now = time(NULL);
/* First rebuild the commandline to put in destination */
/* Could be done through env[], but not all OS-es support it */
cmdlen = 4; /* for "wrc " */
......@@ -233,7 +265,7 @@ int main(int argc,char *argv[])
strcat(cmdline, " ");
}
while((optc = getopt(argc, argv, "a:AbcC:d:D:eghH:I:l:Lno:p:rstTVw:W")) != EOF)
while((optc = getopt(argc, argv, "a:AbcC:d:D:eEghH:I:l:LnNo:p:rstTVw:W")) != EOF)
{
switch(optc)
{
......@@ -261,6 +293,9 @@ int main(int argc,char *argv[])
case 'e':
extensions = 0;
break;
case 'E':
preprocess_only = 1;
break;
case 'g':
global = 1;
break;
......@@ -286,6 +321,9 @@ int main(int argc,char *argv[])
case 'n':
create_s = 0;
break;
case 'N':
no_preprocess = 1;
break;
case 'o':
output_name = strdup(optarg);
break;
......@@ -390,6 +428,62 @@ int main(int argc,char *argv[])
}
}
if(preprocess_only)
{
if(constant)
{
warning("Option -c ignored with preprocess only\n");
constant = 0;
}
if(create_header)
{
warning("Option -[h|H] ignored with preprocess only\n");
create_header = 0;
}
if(indirect)
{
warning("Option -l ignored with preprocess only\n");
indirect = 0;
}
if(indirect_only)
{
error("Option -E and -L cannot be used together\n");
}
if(global)
{
warning("Option -g ignored with preprocess only\n");
global = 0;
}
if(create_dir)
{
warning("Option -s ignored with preprocess only\n");
create_dir = 0;
}
if(binary)
{
error("Option -E and -b cannot be used together\n");
}
if(no_preprocess)
{
error("Option -E and -N cannot be used together\n");
}
}
#if !defined(HAVE_WINE_CONSTRUCTOR)
if(auto_register)
{
warning("Autoregister code non-operable (HAVE_WINE_CONSTRUCTOR not defined)");
auto_register = 0;
}
#endif
/* Set alignment power */
a = alignment;
for(alignment_pwr = 0; alignment_pwr < 10 && a > 1; alignment_pwr++)
......@@ -413,16 +507,29 @@ int main(int argc,char *argv[])
}
yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
ppdebug = debuglevel & DEBUGLEVEL_PPTRACE ? 1 : 0;
pp_flex_debug = debuglevel & DEBUGLEVEL_PPLEX ? 1 : 0;
/* Set the default defined stuff */
add_cmdline_define("__WRC__=" WRC_STRINGIZE(WRC_MAJOR_VERSION));
add_cmdline_define("__WRC_MINOR__=" WRC_STRINGIZE(WRC_MINOR_VERSION));
add_cmdline_define("__WRC_MICRO__=" WRC_STRINGIZE(WRC_MICRO_VERSION));
add_cmdline_define("__WRC_PATCH__=" WRC_STRINGIZE(WRC_MICRO_VERSION));
add_cmdline_define("RC_INVOKED=1");
add_cmdline_define("__WRC__=1");
if(win32)
{
add_cmdline_define("__WIN32__=1");
add_cmdline_define("__FLAT__=1");
}
add_special_define("__FILE__");
add_special_define("__LINE__");
add_special_define("__DATE__");
add_special_define("__TIME__");
/* Check if the user set a language, else set default */
if(!currentlanguage)
currentlanguage = new_language(0, 0);
......@@ -431,23 +538,15 @@ int main(int argc,char *argv[])
if(optind < argc)
{
input_name = argv[optind];
yyin = fopen(input_name, "rb");
if(!yyin)
{
error("Could not open %s\n", input_name);
}
}
else
{
yyin = stdin;
}
if(binary && !input_name)
{
error("Binary mode requires .res file as input");
error("Binary mode requires .res file as input\n");
}
if(!output_name)
/* Generate appropriate outfile names */
if(!output_name && !preprocess_only)
{
output_name = dup_basename(input_name, binary ? ".res" : ".rc");
strcat(output_name, create_res ? ".res" : ".s");
......@@ -459,10 +558,75 @@ int main(int argc,char *argv[])
strcat(header_name, ".h");
}
/* Run the preprocessor on the input */
if(!no_preprocess && !binary)
{
char *real_name;
/*
* Preprocess the input to a temp-file, or stdout if
* no output was given.
*/
chat("Starting preprocess");
if(preprocess_only && !output_name)
{
ppout = stdout;
}
else if(preprocess_only && output_name)
{
if(!(ppout = fopen(output_name, "wb")))
error("Could not open %s for writing\n", output_name);
}
else
{
if(!(temp_name = tmpnam(NULL)))
error("Could nor generate a temp-name\n");
temp_name = xstrdup(temp_name);
if(!(ppout = fopen(temp_name, "wb")))
error("Could not create a temp-file\n");
atexit(rm_tempfile);
}
real_name = input_name; /* Because it gets overwritten */
if(!input_name)
ppin = stdin;
else
{
if(!(ppin = fopen(input_name, "rb")))
error("Could not open %s\n", input_name);
}
fprintf(ppout, "# 1 \"%s\" 1\n", input_name ? input_name : "");
ret = ppparse();
input_name = real_name;
if(input_name)
fclose(ppin);
fclose(ppout);
input_name = temp_name;
if(ret)
exit(1); /* Error during preprocess */
if(preprocess_only)
exit(0);
}
if(!binary)
{
/* Go from .rc to .res or .s */
chat("Starting parse");
if(!(yyin = fopen(input_name, "rb")))
error("Could not open %s for input\n", input_name);
ret = yyparse();
if(input_name)
......@@ -521,5 +685,17 @@ int main(int argc,char *argv[])
}
static void rm_tempfile(void)
{
if(temp_name)
unlink(temp_name);
}
static void segvhandler(int sig)
{
fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
fflush(stdout);
fflush(stderr);
abort();
}
......@@ -12,9 +12,17 @@
#include "wrctypes.h"
#endif
#define WRC_VERSION "1.0.18"
#define WRC_RELEASEDATE "(28-Dec-1999)"
#define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE
#include <time.h> /* For time_t */
#define WRC_MAJOR_VERSION 1
#define WRC_MINOR_VERSION 1
#define WRC_MICRO_VERSION 0
#define WRC_RELEASEDATE "(01-May-2000)"
#define WRC_STRINGIZE(a) #a
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
#define WRC_VERSION WRC_VERSIONIZE(WRC_MAJOR_VERSION, WRC_MINOR_VERSION, WRC_MICRO_VERSION)
#define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE
/* Only used in heavy debugging sessions */
#define HEAPCHECK()
......@@ -25,6 +33,9 @@ extern int debuglevel;
#define DEBUGLEVEL_CHAT 0x0001
#define DEBUGLEVEL_DUMP 0x0002
#define DEBUGLEVEL_TRACE 0x0004
#define DEBUGLEVEL_PPMSG 0x0008
#define DEBUGLEVEL_PPLEX 0x0010
#define DEBUGLEVEL_PPTRACE 0x0020
extern int win32;
extern int constant;
......@@ -43,12 +54,18 @@ extern DWORD codepage;
extern int pedantic;
extern int auto_register;
extern int leave_case;
extern int preprocess_only;
extern int no_preprocess;
extern char *prefix;
extern char *output_name;
extern char *input_name;
extern char *header_name;
extern char *cmdline;
extern time_t now;
extern int line_number;
extern int char_number;
extern resource_t *resource_top;
extern language_t *currentlanguage;
......
......@@ -11,7 +11,6 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "wrc.h"
#include "writeres.h"
......@@ -91,8 +90,6 @@ int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level ar
static int direntries; /* win32 only: Total number of unique resources */
time_t now;
/*
*****************************************************************************
* Function : write_resfile
......@@ -940,7 +937,6 @@ void write_s_file(char *outname, resource_t *top)
{
char *s, *p;
now = time(NULL);
s = ctime(&now);
p = strchr(s, '\n');
if(p) *p = '\0';
......@@ -1127,7 +1123,6 @@ void write_h_file(char *outname, resource_t *top)
error("Could not open %s\n", outname);
}
time(&now);
fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
cmdline, ctime(&now), (long)now, (long)now);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment