X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fresrc.c;h=73b482cd04ab6ffe8210a68bbe0ae5845327b104;hb=fe09a055181c19698ce867b3cd61a895307e20dc;hp=c633c2a0b15f565a360ee568d16ea54a78cbb697;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/resrc.c b/binutils/resrc.c index c633c2a0b1..73b482cd04 100644 --- a/binutils/resrc.c +++ b/binutils/resrc.c @@ -1,5 +1,6 @@ /* resrc.c -- read and write Windows rc files. - Copyright 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -16,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ /* This file contains functions that read and write Windows rc files. These are text files that represent resources. */ @@ -25,20 +26,60 @@ #include "bfd.h" #include "bucomm.h" #include "libiberty.h" +#include "safe-ctype.h" #include "windres.h" #include -#include +#include #include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_WAIT_H +#include +#else /* ! HAVE_SYS_WAIT_H */ +#if ! defined (_WIN32) || defined (__CYGWIN__) +#ifndef WIFEXITED +#define WIFEXITED(w) (((w)&0377) == 0) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0) +#endif +#ifndef WTERMSIG +#define WTERMSIG(w) ((w) & 0177) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(w) (((w) >> 8) & 0377) +#endif +#else /* defined (_WIN32) && ! defined (__CYGWIN__) */ +#ifndef WIFEXITED +#define WIFEXITED(w) (((w) & 0xff) == 0) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f) +#endif +#ifndef WTERMSIG +#define WTERMSIG(w) ((w) & 0x7f) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(w) (((w) & 0xff00) >> 8) +#endif +#endif /* defined (_WIN32) && ! defined (__CYGWIN__) */ +#endif /* ! HAVE_SYS_WAIT_H */ -#if defined (_WIN32) && ! defined (__CYGWIN32__) +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#if defined (_WIN32) && ! defined (__CYGWIN__) #define popen _popen #define pclose _pclose #endif /* The default preprocessor. */ -#define DEFAULT_PREPROCESSOR "gcc -E -xc-header -DRC_INVOKED" +#define DEFAULT_PREPROCESSOR "gcc -E -xc -DRC_INVOKED" /* We read the directory entries in a cursor or icon file into instances of this structure. */ @@ -86,6 +127,15 @@ int rc_lineno; static FILE *cpp_pipe; +/* The temporary file used if we're not using popen, so we can delete it + if we exit. */ + +static char *cpp_temp_file; + +/* Input stream is either a file or a pipe. */ + +static enum {ISTREAM_PIPE, ISTREAM_FILE} istream_type; + /* As we read the rc file, we attach information to this structure. */ static struct res_directory *resources; @@ -112,25 +162,176 @@ static int icons; /* Local functions. */ -static FILE *look_for_default PARAMS ((char *, const char *, int, - const char *, const char *)); -static void close_pipe PARAMS ((void)); -static void unexpected_eof PARAMS ((const char *)); -static int get_word PARAMS ((FILE *, const char *)); -static unsigned long get_long PARAMS ((FILE *, const char *)); -static void get_data - PARAMS ((FILE *, unsigned char *, unsigned long, const char *)); -static void define_fontdirs PARAMS ((void)); +static int run_cmd (char *, const char *); +static FILE *open_input_stream (char *); +static FILE *look_for_default + (char *, const char *, int, const char *, const char *); +static void close_input_stream (void); +static void unexpected_eof (const char *); +static int get_word (FILE *, const char *); +static unsigned long get_long (FILE *, const char *); +static void get_data (FILE *, unsigned char *, unsigned long, const char *); +static void define_fontdirs (void); +/* Run `cmd' and redirect the output to `redir'. */ + +static int +run_cmd (char *cmd, const char *redir) +{ + char *s; + int pid, wait_status, retcode; + int i; + const char **argv; + char *errmsg_fmt, *errmsg_arg; + char *temp_base = choose_temp_base (); + int in_quote; + char sep; + int redir_handle = -1; + int stdout_save = -1; + + /* Count the args. */ + i = 0; + + for (s = cmd; *s; s++) + if (*s == ' ') + i++; + + i++; + argv = alloca (sizeof (char *) * (i + 3)); + i = 0; + s = cmd; + + while (1) + { + while (*s == ' ' && *s != 0) + s++; + + if (*s == 0) + break; + + in_quote = (*s == '\'' || *s == '"'); + sep = (in_quote) ? *s++ : ' '; + argv[i++] = s; + + while (*s != sep && *s != 0) + s++; + + if (*s == 0) + break; + + *s++ = 0; + + if (in_quote) + s++; + } + argv[i++] = NULL; + + /* Setup the redirection. We can't use the usual fork/exec and redirect + since we may be running on non-POSIX Windows host. */ + + fflush (stdout); + fflush (stderr); + + /* Open temporary output file. */ + redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (redir_handle == -1) + fatal (_("can't open temporary file `%s': %s"), redir, + strerror (errno)); + + /* Duplicate the stdout file handle so it can be restored later. */ + stdout_save = dup (STDOUT_FILENO); + if (stdout_save == -1) + fatal (_("can't redirect stdout: `%s': %s"), redir, strerror (errno)); + + /* Redirect stdout to our output file. */ + dup2 (redir_handle, STDOUT_FILENO); + + pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, + &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); + + /* Restore stdout to its previous setting. */ + dup2 (stdout_save, STDOUT_FILENO); + + /* Close response file. */ + close (redir_handle); + + if (pid == -1) + { + fatal (_("%s %s: %s"), errmsg_fmt, errmsg_arg, strerror (errno)); + return 1; + } + + retcode = 0; + pid = pwait (pid, &wait_status, 0); + + if (pid == -1) + { + fatal (_("wait: %s"), strerror (errno)); + retcode = 1; + } + else if (WIFSIGNALED (wait_status)) + { + fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status)); + retcode = 1; + } + else if (WIFEXITED (wait_status)) + { + if (WEXITSTATUS (wait_status) != 0) + { + fatal (_("%s exited with status %d"), cmd, + WEXITSTATUS (wait_status)); + retcode = 1; + } + } + else + retcode = 1; + + return retcode; +} + +static FILE * +open_input_stream (char *cmd) +{ + if (istream_type == ISTREAM_FILE) + { + char *fileprefix; + + fileprefix = choose_temp_base (); + cpp_temp_file = (char *) xmalloc (strlen (fileprefix) + 5); + sprintf (cpp_temp_file, "%s.irc", fileprefix); + free (fileprefix); + + if (run_cmd (cmd, cpp_temp_file)) + fatal (_("can't execute `%s': %s"), cmd, strerror (errno)); + + cpp_pipe = fopen (cpp_temp_file, FOPEN_RT);; + if (cpp_pipe == NULL) + fatal (_("can't open temporary file `%s': %s"), + cpp_temp_file, strerror (errno)); + + if (verbose) + fprintf (stderr, + _("Using temporary file `%s' to read preprocessor output\n"), + cpp_temp_file); + } + else + { + cpp_pipe = popen (cmd, FOPEN_RT); + if (cpp_pipe == NULL) + fatal (_("can't popen `%s': %s"), cmd, strerror (errno)); + if (verbose) + fprintf (stderr, _("Using popen to read preprocessor output\n")); + } + + xatexit (close_input_stream); + return cpp_pipe; +} + /* look for the preprocessor program */ static FILE * -look_for_default (cmd, prefix, end_prefix, preprocargs, filename) - char *cmd; - const char *prefix; - int end_prefix; - const char *preprocargs; - const char *filename; +look_for_default (char *cmd, const char *prefix, int end_prefix, + const char *preprocargs, const char *filename) { char *space; int found; @@ -143,7 +344,11 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) if (space) *space = 0; - if (strchr (cmd, '/')) + if ( +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32) + strchr (cmd, '\\') || +#endif + strchr (cmd, '/')) { found = (stat (cmd, &s) == 0 #ifdef HAVE_EXECUTABLE_SUFFIX @@ -154,7 +359,7 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) if (! found) { if (verbose) - fprintf (stderr, "Tried `%s'\n", cmd); + fprintf (stderr, _("Tried `%s'\n"), cmd); return NULL; } } @@ -165,23 +370,22 @@ look_for_default (cmd, prefix, end_prefix, preprocargs, filename) DEFAULT_PREPROCESSOR, preprocargs, filename); if (verbose) - fprintf (stderr, "Using `%s'\n", cmd); + fprintf (stderr, _("Using `%s'\n"), cmd); - cpp_pipe = popen (cmd, FOPEN_RT); + cpp_pipe = open_input_stream (cmd); return cpp_pipe; } /* Read an rc file. */ struct res_directory * -read_rc_file (filename, preprocessor, preprocargs, language) - const char *filename; - const char *preprocessor; - const char *preprocargs; - int language; +read_rc_file (const char *filename, const char *preprocessor, + const char *preprocargs, int language, int use_temp_file) { char *cmd; + istream_type = (use_temp_file) ? ISTREAM_FILE : ISTREAM_PIPE; + if (preprocargs == NULL) preprocargs = ""; if (filename == NULL) @@ -195,7 +399,7 @@ read_rc_file (filename, preprocessor, preprocargs, language) + 10); sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename); - cpp_pipe = popen (cmd, FOPEN_RT); + cpp_pipe = open_input_stream (cmd); } else { @@ -219,7 +423,7 @@ read_rc_file (filename, preprocessor, preprocargs, language) if (*cp == '-') dash = cp; if ( -#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) +#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32) *cp == ':' || *cp == '\\' || #endif *cp == '/') @@ -257,11 +461,8 @@ read_rc_file (filename, preprocessor, preprocargs, language) } } - if (cpp_pipe == NULL) - fatal (_("can't popen `%s': %s"), cmd, strerror (errno)); - free (cmd); - xatexit (close_pipe); + free (cmd); rc_filename = xstrdup (filename); rc_lineno = 1; @@ -269,10 +470,9 @@ read_rc_file (filename, preprocessor, preprocargs, language) rcparse_set_language (language); yyin = cpp_pipe; yyparse (); + rcparse_discard_strings (); - if (pclose (cpp_pipe) != 0) - fprintf (stderr, _("%s: warning: preprocessor failed\n"), program_name); - cpp_pipe = NULL; + close_input_stream (); if (fontdirs != NULL) define_fontdirs (); @@ -283,20 +483,40 @@ read_rc_file (filename, preprocessor, preprocargs, language) return resources; } -/* Close the pipe if it is open. This is called via xatexit. */ +/* Close the input stream if it is open. */ -void -close_pipe () +static void +close_input_stream (void) { - if (cpp_pipe != NULL) - pclose (cpp_pipe); + if (istream_type == ISTREAM_FILE) + { + if (cpp_pipe != NULL) + fclose (cpp_pipe); + + if (cpp_temp_file != NULL) + { + int errno_save = errno; + + unlink (cpp_temp_file); + errno = errno_save; + free (cpp_temp_file); + } + } + else + { + if (cpp_pipe != NULL) + pclose (cpp_pipe); + } + + /* Since this is also run via xatexit, safeguard. */ + cpp_pipe = NULL; + cpp_temp_file = NULL; } /* Report an error while reading an rc file. */ void -yyerror (msg) - const char *msg; +yyerror (const char *msg) { fatal ("%s:%d: %s", rc_filename, rc_lineno, msg); } @@ -304,17 +524,15 @@ yyerror (msg) /* Issue a warning while reading an rc file. */ void -rcparse_warning (msg) - const char *msg; +rcparse_warning (const char *msg) { - fprintf (stderr, "%s:%d: %s\n", rc_filename, rc_lineno, msg); + fprintf (stderr, _("%s:%d: %s\n"), rc_filename, rc_lineno, msg); } /* Die if we get an unexpected end of file. */ static void -unexpected_eof (msg) - const char *msg; +unexpected_eof (const char *msg) { fatal (_("%s: unexpected EOF"), msg); } @@ -323,9 +541,7 @@ unexpected_eof (msg) endian. */ static int -get_word (e, msg) - FILE *e; - const char *msg; +get_word (FILE *e, const char *msg) { int b1, b2; @@ -340,9 +556,7 @@ get_word (e, msg) endian. */ static unsigned long -get_long (e, msg) - FILE *e; - const char *msg; +get_long (FILE *e, const char *msg) { int b1, b2, b3, b4; @@ -361,11 +575,7 @@ get_long (e, msg) /* Read data from a file. This is a wrapper to do error checking. */ static void -get_data (e, p, c, msg) - FILE *e; - unsigned char *p; - unsigned long c; - const char *msg; +get_data (FILE *e, unsigned char *p, unsigned long c, const char *msg) { unsigned long got; @@ -379,10 +589,8 @@ get_data (e, p, c, msg) /* Define an accelerator resource. */ void -define_accelerator (id, resinfo, data) - struct res_id id; - const struct res_res_info *resinfo; - struct accelerator *data; +define_accelerator (struct res_id id, const struct res_res_info *resinfo, + struct accelerator *data) { struct res_resource *r; @@ -400,10 +608,8 @@ define_accelerator (id, resinfo, data) #define BITMAP_SKIP (14) void -define_bitmap (id, resinfo, filename) - struct res_id id; - const struct res_res_info *resinfo; - const char *filename; +define_bitmap (struct res_id id, const struct res_res_info *resinfo, + const char *filename) { FILE *e; char *real_filename; @@ -444,10 +650,8 @@ define_bitmap (id, resinfo, filename) select one of the actual cursors. */ void -define_cursor (id, resinfo, filename) - struct res_id id; - const struct res_res_info *resinfo; - const char *filename; +define_cursor (struct res_id id, const struct res_res_info *resinfo, + const char *filename) { FILE *e; char *real_filename; @@ -564,10 +768,8 @@ define_cursor (id, resinfo, filename) /* Define a dialog resource. */ void -define_dialog (id, resinfo, dialog) - struct res_id id; - const struct res_res_info *resinfo; - const struct dialog *dialog; +define_dialog (struct res_id id, const struct res_res_info *resinfo, + const struct dialog *dialog) { struct dialog *copy; struct res_resource *r; @@ -586,16 +788,10 @@ define_dialog (id, resinfo, dialog) merely allocates and fills in a structure. */ struct dialog_control * -define_control (text, id, x, y, width, height, class, style, exstyle) - const char *text; - unsigned long id; - unsigned long x; - unsigned long y; - unsigned long width; - unsigned long height; - unsigned long class; - unsigned long style; - unsigned long exstyle; +define_control (const struct res_id iid, unsigned long id, unsigned long x, + unsigned long y, unsigned long width, unsigned long height, + unsigned long class, unsigned long style, + unsigned long exstyle) { struct dialog_control *n; @@ -610,26 +806,42 @@ define_control (text, id, x, y, width, height, class, style, exstyle) n->height = height; n->class.named = 0; n->class.u.id = class; - if (text != NULL) - res_string_to_id (&n->text, text); - else - { - n->text.named = 0; - n->text.u.id = 0; - } + n->text = iid; n->data = NULL; n->help = 0; return n; } +struct dialog_control * +define_icon_control (struct res_id iid, unsigned long id, unsigned long x, + unsigned long y, unsigned long style, + unsigned long exstyle, unsigned long help, + struct rcdata_item *data, struct dialog_ex *ex) +{ + struct dialog_control *n; + struct res_id tid; + + if (style == 0) + style = SS_ICON | WS_CHILD | WS_VISIBLE; + res_string_to_id (&tid, ""); + n = define_control (tid, id, x, y, 0, 0, CTL_STATIC, style, exstyle); + n->text = iid; + if (help && !ex) + rcparse_warning (_("help ID requires DIALOGEX")); + if (data && !ex) + rcparse_warning (_("control data requires DIALOGEX")); + n->help = help; + n->data = data; + + return n; +} + /* Define a font resource. */ void -define_font (id, resinfo, filename) - struct res_id id; - const struct res_res_info *resinfo; - const char *filename; +define_font (struct res_id id, const struct res_res_info *resinfo, + const char *filename) { FILE *e; char *real_filename; @@ -646,7 +858,7 @@ define_font (id, resinfo, filename) e = open_file_search (filename, FOPEN_RB, "font file", &real_filename); if (stat (real_filename, &s) < 0) - fatal (_("stat failed on bitmap file `%s': %s"), real_filename, + fatal (_("stat failed on font file `%s': %s"), real_filename, strerror (errno)); data = (unsigned char *) res_alloc (s.st_size); @@ -714,7 +926,7 @@ define_font (id, resinfo, filename) file has been parsed, if any font resources were seen. */ static void -define_fontdirs () +define_fontdirs (void) { struct res_resource *r; struct res_id id; @@ -736,10 +948,8 @@ define_fontdirs () select one of the actual icon bitmaps. */ void -define_icon (id, resinfo, filename) - struct res_id id; - const struct res_res_info *resinfo; - const char *filename; +define_icon (struct res_id id, const struct res_res_info *resinfo, + const char *filename) { FILE *e; char *real_filename; @@ -831,10 +1041,20 @@ define_icon (id, resinfo, filename) cg->height = icondirs[i].height; cg->colors = icondirs[i].colorcount; - cg->planes = 1; - cg->bits = 0; - while ((1 << cg->bits) < cg->colors) - ++cg->bits; + if (icondirs[i].u.icon.planes) + cg->planes = icondirs[i].u.icon.planes; + else + cg->planes = 1; + + if (icondirs[i].u.icon.bits) + cg->bits = icondirs[i].u.icon.bits; + else + { + cg->bits = 0; + + while ((1L << cg->bits) < cg->colors) + ++cg->bits; + } cg->bytes = icondirs[i].bytes; cg->index = first_icon + i + 1; @@ -855,10 +1075,8 @@ define_icon (id, resinfo, filename) /* Define a menu resource. */ void -define_menu (id, resinfo, menuitems) - struct res_id id; - const struct res_res_info *resinfo; - struct menuitem *menuitems; +define_menu (struct res_id id, const struct res_res_info *resinfo, + struct menuitem *menuitems) { struct menu *m; struct res_resource *r; @@ -877,13 +1095,9 @@ define_menu (id, resinfo, menuitems) allocates and fills in a structure. */ struct menuitem * -define_menuitem (text, menuid, type, state, help, menuitems) - const char *text; - int menuid; - unsigned long type; - unsigned long state; - unsigned long help; - struct menuitem *menuitems; +define_menuitem (const char *text, int menuid, unsigned long type, + unsigned long state, unsigned long help, + struct menuitem *menuitems) { struct menuitem *mi; @@ -904,10 +1118,8 @@ define_menuitem (text, menuid, type, state, help, menuitems) /* Define a messagetable resource. */ void -define_messagetable (id, resinfo, filename) - struct res_id id; - const struct res_res_info *resinfo; - const char *filename; +define_messagetable (struct res_id id, const struct res_res_info *resinfo, + const char *filename) { FILE *e; char *real_filename; @@ -941,10 +1153,8 @@ define_messagetable (id, resinfo, filename) /* Define an rcdata resource. */ void -define_rcdata (id, resinfo, data) - struct res_id id; - const struct res_res_info *resinfo; - struct rcdata_item *data; +define_rcdata (struct res_id id, const struct res_res_info *resinfo, + struct rcdata_item *data) { struct res_resource *r; @@ -958,9 +1168,7 @@ define_rcdata (id, resinfo, data) /* Create an rcdata item holding a string. */ struct rcdata_item * -define_rcdata_string (string, len) - const char *string; - unsigned long len; +define_rcdata_string (const char *string, unsigned long len) { struct rcdata_item *ri; char *s; @@ -979,9 +1187,7 @@ define_rcdata_string (string, len) /* Create an rcdata item holding a number. */ struct rcdata_item * -define_rcdata_number (val, dword) - unsigned long val; - int dword; +define_rcdata_number (unsigned long val, int dword) { struct rcdata_item *ri; @@ -997,10 +1203,8 @@ define_rcdata_number (val, dword) which appears in a STRINGTABLE statement. */ void -define_stringtable (resinfo, stringid, string) - const struct res_res_info *resinfo; - unsigned long stringid; - const char *string; +define_stringtable (const struct res_res_info *resinfo, + unsigned long stringid, const char *string) { struct res_id id; struct res_resource *r; @@ -1034,11 +1238,9 @@ define_stringtable (resinfo, stringid, string) /* Define a user data resource where the data is in the rc file. */ void -define_user_data (id, type, resinfo, data) - struct res_id id; - struct res_id type; - const struct res_res_info *resinfo; - struct rcdata_item *data; +define_user_data (struct res_id id, struct res_id type, + const struct res_res_info *resinfo, + struct rcdata_item *data) { struct res_id ids[3]; struct res_resource *r; @@ -1048,20 +1250,50 @@ define_user_data (id, type, resinfo, data) ids[2].named = 0; ids[2].u.id = resinfo->language; - r = define_resource (&resources, 3, ids, 0); + r = define_resource (& resources, 3, ids, 0); r->type = RES_TYPE_USERDATA; r->u.userdata = data; r->res_info = *resinfo; } +void +define_rcdata_file (struct res_id id, const struct res_res_info *resinfo, + const char *filename) +{ + struct rcdata_item *ri; + FILE *e; + char *real_filename; + struct stat s; + unsigned char *data; + + e = open_file_search (filename, FOPEN_RB, "file", &real_filename); + + + if (stat (real_filename, &s) < 0) + fatal (_("stat failed on file `%s': %s"), real_filename, + strerror (errno)); + + data = (unsigned char *) res_alloc (s.st_size); + + get_data (e, data, s.st_size, real_filename); + + fclose (e); + free (real_filename); + + ri = (struct rcdata_item *) res_alloc (sizeof *ri); + ri->next = NULL; + ri->type = RCDATA_BUFFER; + ri->u.buffer.length = s.st_size; + ri->u.buffer.data = data; + + define_rcdata (id, resinfo, ri); +} + /* Define a user data resource where the data is in a file. */ void -define_user_file (id, type, resinfo, filename) - struct res_id id; - struct res_id type; - const struct res_res_info *resinfo; - const char *filename; +define_user_file (struct res_id id, struct res_id type, + const struct res_res_info *resinfo, const char *filename) { FILE *e; char *real_filename; @@ -1070,10 +1302,10 @@ define_user_file (id, type, resinfo, filename) struct res_id ids[3]; struct res_resource *r; - e = open_file_search (filename, FOPEN_RB, "font file", &real_filename); + e = open_file_search (filename, FOPEN_RB, "file", &real_filename); if (stat (real_filename, &s) < 0) - fatal (_("stat failed on bitmap file `%s': %s"), real_filename, + fatal (_("stat failed on file `%s': %s"), real_filename, strerror (errno)); data = (unsigned char *) res_alloc (s.st_size); @@ -1102,11 +1334,9 @@ define_user_file (id, type, resinfo, filename) /* Define a versioninfo resource. */ void -define_versioninfo (id, language, fixedverinfo, verinfo) - struct res_id id; - int language; - struct fixed_versioninfo *fixedverinfo; - struct ver_info *verinfo; +define_versioninfo (struct res_id id, int language, + struct fixed_versioninfo *fixedverinfo, + struct ver_info *verinfo) { struct res_resource *r; @@ -1122,10 +1352,8 @@ define_versioninfo (id, language, fixedverinfo, verinfo) /* Add string version info to a list of version information. */ struct ver_info * -append_ver_stringfileinfo (verinfo, language, strings) - struct ver_info *verinfo; - const char *language; - struct ver_stringinfo *strings; +append_ver_stringfileinfo (struct ver_info *verinfo, const char *language, + struct ver_stringinfo *strings) { struct ver_info *vi, **pp; @@ -1145,10 +1373,8 @@ append_ver_stringfileinfo (verinfo, language, strings) /* Add variable version info to a list of version information. */ struct ver_info * -append_ver_varfileinfo (verinfo, key, var) - struct ver_info *verinfo; - const char *key; - struct ver_varinfo *var; +append_ver_varfileinfo (struct ver_info *verinfo, const char *key, + struct ver_varinfo *var) { struct ver_info *vi, **pp; @@ -1168,10 +1394,8 @@ append_ver_varfileinfo (verinfo, key, var) /* Append version string information to a list. */ struct ver_stringinfo * -append_verval (strings, key, value) - struct ver_stringinfo *strings; - const char *key; - const char *value; +append_verval (struct ver_stringinfo *strings, const char *key, + const char *value) { struct ver_stringinfo *vs, **pp; @@ -1190,10 +1414,8 @@ append_verval (strings, key, value) /* Append version variable information to a list. */ struct ver_varinfo * -append_vertrans (var, language, charset) - struct ver_varinfo *var; - unsigned long language; - unsigned long charset; +append_vertrans (struct ver_varinfo *var, unsigned long language, + unsigned long charset) { struct ver_varinfo *vv, **pp; @@ -1211,42 +1433,35 @@ append_vertrans (var, language, charset) /* Local functions used to write out an rc file. */ -static void indent PARAMS ((FILE *, int)); +static void indent (FILE *, int); static void write_rc_directory - PARAMS ((FILE *, const struct res_directory *, const struct res_id *, - const struct res_id *, int *, int)); + (FILE *, const struct res_directory *, const struct res_id *, + const struct res_id *, int *, int); static void write_rc_subdir - PARAMS ((FILE *, const struct res_entry *, const struct res_id *, - const struct res_id *, int *, int)); + (FILE *, const struct res_entry *, const struct res_id *, + const struct res_id *, int *, int); static void write_rc_resource - PARAMS ((FILE *, const struct res_id *, const struct res_id *, - const struct res_resource *, int *)); -static void write_rc_accelerators - PARAMS ((FILE *, const struct accelerator *)); -static void write_rc_cursor PARAMS ((FILE *, const struct cursor *)); -static void write_rc_group_cursor - PARAMS ((FILE *, const struct group_cursor *)); -static void write_rc_dialog PARAMS ((FILE *, const struct dialog *)); -static void write_rc_dialog_control - PARAMS ((FILE *, const struct dialog_control *)); -static void write_rc_fontdir PARAMS ((FILE *, const struct fontdir *)); -static void write_rc_group_icon PARAMS ((FILE *, const struct group_icon *)); -static void write_rc_menu PARAMS ((FILE *, const struct menu *, int)); -static void write_rc_menuitems - PARAMS ((FILE *, const struct menuitem *, int, int)); -static void write_rc_rcdata PARAMS ((FILE *, const struct rcdata_item *, int)); + (FILE *, const struct res_id *, const struct res_id *, + const struct res_resource *, int *); +static void write_rc_accelerators (FILE *, const struct accelerator *); +static void write_rc_cursor (FILE *, const struct cursor *); +static void write_rc_group_cursor (FILE *, const struct group_cursor *); +static void write_rc_dialog (FILE *, const struct dialog *); +static void write_rc_dialog_control (FILE *, const struct dialog_control *); +static void write_rc_fontdir (FILE *, const struct fontdir *); +static void write_rc_group_icon (FILE *, const struct group_icon *); +static void write_rc_menu (FILE *, const struct menu *, int); +static void write_rc_menuitems (FILE *, const struct menuitem *, int, int); +static void write_rc_rcdata (FILE *, const struct rcdata_item *, int); static void write_rc_stringtable - PARAMS ((FILE *, const struct res_id *, const struct stringtable *)); -static void write_rc_versioninfo PARAMS ((FILE *, const struct versioninfo *)); -static void write_rc_filedata - PARAMS ((FILE *, unsigned long, const unsigned char *)); + (FILE *, const struct res_id *, const struct stringtable *); +static void write_rc_versioninfo (FILE *, const struct versioninfo *); +static void write_rc_filedata (FILE *, unsigned long, const unsigned char *); /* Indent a given number of spaces. */ static void -indent (e, c) - FILE *e; - int c; +indent (FILE *e, int c) { int i; @@ -1265,9 +1480,7 @@ indent (e, c) comes, this code will have to be fixed up. */ void -write_rc_file (filename, resources) - const char *filename; - const struct res_directory *resources; +write_rc_file (const char *filename, const struct res_directory *resources) { FILE *e; int language; @@ -1293,13 +1506,9 @@ write_rc_file (filename, resources) language. LEVEL is the level in the tree. */ static void -write_rc_directory (e, rd, type, name, language, level) - FILE *e; - const struct res_directory *rd; - const struct res_id *type; - const struct res_id *name; - int *language; - int level; +write_rc_directory (FILE *e, const struct res_directory *rd, + const struct res_id *type, const struct res_id *name, + int *language, int level) { const struct res_entry *re; @@ -1326,7 +1535,7 @@ write_rc_directory (e, rd, type, name, language, level) case 2: /* If we're at level 2, the key of this resource is the name - we are going to use in the rc printout. */ + we are going to use in the rc printout. */ name = &re->id; break; @@ -1338,7 +1547,8 @@ write_rc_directory (e, rd, type, name, language, level) && (re->id.u.id & 0xffff) == re->id.u.id) { fprintf (e, "LANGUAGE %lu, %lu\n", - re->id.u.id & 0xff, (re->id.u.id >> 8) & 0xff); + re->id.u.id & ((1 << SUBLANG_SHIFT) - 1), + (re->id.u.id >> SUBLANG_SHIFT) & 0xff); *language = re->id.u.id; } break; @@ -1376,13 +1586,9 @@ write_rc_directory (e, rd, type, name, language, level) LEVEL is the level in the tree. */ static void -write_rc_subdir (e, re, type, name, language, level) - FILE *e; - const struct res_entry *re; - const struct res_id *type; - const struct res_id *name; - int *language; - int level; +write_rc_subdir (FILE *e, const struct res_entry *re, + const struct res_id *type, const struct res_id *name, + int *language, int level) { fprintf (e, "\n"); switch (level) @@ -1443,7 +1649,7 @@ write_rc_subdir (e, re, type, name, language, level) fprintf (e, "// Level %d: ", level); res_id_print (e, re->id, 1); fprintf (e, "\n"); - } + } write_rc_directory (e, re->u.dir, type, name, language, level + 1); } @@ -1455,12 +1661,9 @@ write_rc_subdir (e, re, type, name, language, level) language. */ static void -write_rc_resource (e, type, name, res, language) - FILE *e; - const struct res_id *type; - const struct res_id *name; - const struct res_resource *res; - int *language; +write_rc_resource (FILE *e, const struct res_id *type, + const struct res_id *name, const struct res_resource *res, + int *language) { const char *s; int rt; @@ -1635,8 +1838,8 @@ write_rc_resource (e, type, name, res, language) if (res->res_info.language != 0 && res->res_info.language != *language) fprintf (e, "%sLANGUAGE %d, %d\n", modifiers ? "// " : "", - res->res_info.language & 0xff, - (res->res_info.language >> 8) & 0xff); + res->res_info.language & ((1<res_info.language >> SUBLANG_SHIFT) & 0xff); if (res->res_info.characteristics != 0) fprintf (e, "%sCHARACTERISTICS %lu\n", modifiers ? "// " : "", @@ -1708,9 +1911,7 @@ write_rc_resource (e, type, name, res, language) /* Write out accelerator information. */ static void -write_rc_accelerators (e, accelerators) - FILE *e; - const struct accelerator *accelerators; +write_rc_accelerators (FILE *e, const struct accelerator *accelerators) { const struct accelerator *acc; @@ -1722,7 +1923,7 @@ write_rc_accelerators (e, accelerators) fprintf (e, " "); if ((acc->key & 0x7f) == acc->key - && isprint ((unsigned char) acc->key) + && ISPRINT (acc->key) && (acc->flags & ACC_VIRTKEY) == 0) { fprintf (e, "\"%c\"", acc->key); @@ -1761,9 +1962,7 @@ write_rc_accelerators (e, accelerators) file, which the rc file would include. */ static void -write_rc_cursor (e, cursor) - FILE *e; - const struct cursor *cursor; +write_rc_cursor (FILE *e, const struct cursor *cursor) { fprintf (e, "// Hotspot: x: %d; y: %d\n", cursor->xhotspot, cursor->yhotspot); @@ -1774,9 +1973,7 @@ write_rc_cursor (e, cursor) cursor data. */ static void -write_rc_group_cursor (e, group_cursor) - FILE *e; - const struct group_cursor *group_cursor; +write_rc_group_cursor (FILE *e, const struct group_cursor *group_cursor) { const struct group_cursor *gc; @@ -1792,29 +1989,30 @@ write_rc_group_cursor (e, group_cursor) /* Write dialog data. */ static void -write_rc_dialog (e, dialog) - FILE *e; - const struct dialog *dialog; +write_rc_dialog (FILE *e, const struct dialog *dialog) { const struct dialog_control *control; - if (dialog->style != 0) - fprintf (e, "STYLE 0x%lx\n", dialog->style); + fprintf (e, "STYLE 0x%lx\n", dialog->style); + if (dialog->exstyle != 0) fprintf (e, "EXSTYLE 0x%lx\n", dialog->exstyle); + if ((dialog->class.named && dialog->class.u.n.length > 0) || dialog->class.u.id != 0) { fprintf (e, "CLASS "); - res_id_print (e, dialog->class, 0); + res_id_print (e, dialog->class, 1); fprintf (e, "\n"); } + if (dialog->caption != NULL) { fprintf (e, "CAPTION \""); unicode_print (e, dialog->caption, -1); fprintf (e, "\"\n"); } + if ((dialog->menu.named && dialog->menu.u.n.length > 0) || dialog->menu.u.id != 0) { @@ -1822,14 +2020,18 @@ write_rc_dialog (e, dialog) res_id_print (e, dialog->menu, 0); fprintf (e, "\n"); } + if (dialog->font != NULL) { fprintf (e, "FONT %d, \"", dialog->pointsize); unicode_print (e, dialog->font, -1); fprintf (e, "\""); if (dialog->ex != NULL - && (dialog->ex->weight != 0 || dialog->ex->italic != 0)) - fprintf (e, ", %d, %d", dialog->ex->weight, dialog->ex->italic); + && (dialog->ex->weight != 0 + || dialog->ex->italic != 0 + || dialog->ex->charset != 1)) + fprintf (e, ", %d, %d, %d", + dialog->ex->weight, dialog->ex->italic, dialog->ex->charset); fprintf (e, "\n"); } @@ -1880,9 +2082,7 @@ static const struct control_info control_info[] = /* Write a dialog control. */ static void -write_rc_dialog_control (e, control) - FILE *e; - const struct dialog_control *control; +write_rc_dialog_control (FILE *e, const struct dialog_control *control) { const struct control_info *ci; @@ -1904,7 +2104,7 @@ write_rc_dialog_control (e, control) fprintf (e, "%s", ci->name); else fprintf (e, "CONTROL"); - + if (control->text.named || control->text.u.id != 0) { fprintf (e, " "); @@ -1953,9 +2153,7 @@ write_rc_dialog_control (e, control) the font data. */ static void -write_rc_fontdir (e, fontdir) - FILE *e; - const struct fontdir *fontdir; +write_rc_fontdir (FILE *e, const struct fontdir *fontdir) { const struct fontdir *fc; @@ -1970,9 +2168,7 @@ write_rc_fontdir (e, fontdir) icon data. */ static void -write_rc_group_icon (e, group_icon) - FILE *e; - const struct group_icon *group_icon; +write_rc_group_icon (FILE *e, const struct group_icon *group_icon) { const struct group_icon *gi; @@ -1988,10 +2184,7 @@ write_rc_group_icon (e, group_icon) /* Write out a menu resource. */ static void -write_rc_menu (e, menu, menuex) - FILE *e; - const struct menu *menu; - int menuex; +write_rc_menu (FILE *e, const struct menu *menu, int menuex) { if (menu->help != 0) fprintf (e, "// Help ID: %lu\n", menu->help); @@ -2001,11 +2194,8 @@ write_rc_menu (e, menu, menuex) /* Write out menuitems. */ static void -write_rc_menuitems (e, menuitems, menuex, ind) - FILE *e; - const struct menuitem *menuitems; - int menuex; - int ind; +write_rc_menuitems (FILE *e, const struct menuitem *menuitems, int menuex, + int ind) { const struct menuitem *mi; @@ -2090,10 +2280,7 @@ write_rc_menuitems (e, menuitems, menuex, ind) resources that need to print arbitrary data. */ static void -write_rc_rcdata (e, rcdata, ind) - FILE *e; - const struct rcdata_item *rcdata; - int ind; +write_rc_rcdata (FILE *e, const struct rcdata_item *rcdata, int ind) { const struct rcdata_item *ri; @@ -2129,7 +2316,7 @@ write_rc_rcdata (e, rcdata, ind) s = ri->u.string.s; for (i = 0; i < ri->u.string.length; i++) { - if (isprint ((unsigned char) *s)) + if (ISPRINT (*s)) putc (*s, e); else fprintf (e, "\\%03o", *s); @@ -2155,60 +2342,100 @@ write_rc_rcdata (e, rcdata, ind) for (i = 0; i + 3 < ri->u.buffer.length; i += 4) { unsigned long l; + int j; + if (! first) + indent (e, ind + 2); l = ((((((ri->u.buffer.data[i + 3] << 8) | ri->u.buffer.data[i + 2]) << 8) | ri->u.buffer.data[i + 1]) << 8) | ri->u.buffer.data[i]); - if (first) - first = 0; - else + fprintf (e, "%luL", l); + if (i + 4 < ri->u.buffer.length || ri->next != NULL) + fprintf (e, ","); + for (j = 0; j < 4; ++j) + if (! ISPRINT (ri->u.buffer.data[i + j]) + && ri->u.buffer.data[i + j] != 0) + break; + if (j >= 4) { - fprintf (e, ",\n"); - indent (e, ind + 2); + fprintf (e, "\t// "); + for (j = 0; j < 4; ++j) + { + if (! ISPRINT (ri->u.buffer.data[i + j])) + fprintf (e, "\\%03o", ri->u.buffer.data[i + j]); + else + { + if (ri->u.buffer.data[i + j] == '\\') + fprintf (e, "\\"); + fprintf (e, "%c", ri->u.buffer.data[i + j]); + } + } } - fprintf (e, "%luL", l); + fprintf (e, "\n"); + first = 0; } if (i + 1 < ri->u.buffer.length) { - int i; - - i = (ri->u.buffer.data[i + 1] << 8) | ri->u.buffer.data[i]; - if (first) - first = 0; - else + int s; + int j; + + if (! first) + indent (e, ind + 2); + s = (ri->u.buffer.data[i + 1] << 8) | ri->u.buffer.data[i]; + fprintf (e, "%d", s); + if (i + 2 < ri->u.buffer.length || ri->next != NULL) + fprintf (e, ","); + for (j = 0; j < 2; ++j) + if (! ISPRINT (ri->u.buffer.data[i + j]) + && ri->u.buffer.data[i + j] != 0) + break; + if (j >= 2) { - fprintf (e, ",\n"); - indent (e, ind + 2); + fprintf (e, "\t// "); + for (j = 0; j < 2; ++j) + { + if (! ISPRINT (ri->u.buffer.data[i + j])) + fprintf (e, "\\%03o", ri->u.buffer.data[i + j]); + else + { + if (ri->u.buffer.data[i + j] == '\\') + fprintf (e, "\\"); + fprintf (e, "%c", ri->u.buffer.data[i + j]); + } + } } - fprintf (e, "%d", i); + fprintf (e, "\n"); i += 2; + first = 0; } if (i < ri->u.buffer.length) { - if (first) - first = 0; - else - { - fprintf (e, ",\n"); - indent (e, ind + 2); - } + if (! first) + indent (e, ind + 2); if ((ri->u.buffer.data[i] & 0x7f) == ri->u.buffer.data[i] - && isprint (ri->u.buffer.data[i])) + && ISPRINT (ri->u.buffer.data[i])) fprintf (e, "\"%c\"", ri->u.buffer.data[i]); else - fprintf (e, "\"\%03o\"", ri->u.buffer.data[i]); + fprintf (e, "\"\\%03o\"", ri->u.buffer.data[i]); + if (ri->next != NULL) + fprintf (e, ","); + fprintf (e, "\n"); + first = 0; } break; } } - if (ri->next != NULL) - fprintf (e, ","); - fprintf (e, "\n"); + if (ri->type != RCDATA_BUFFER) + { + if (ri->next != NULL) + fprintf (e, ","); + fprintf (e, "\n"); + } } indent (e, ind); @@ -2218,10 +2445,8 @@ write_rc_rcdata (e, rcdata, ind) /* Write out a stringtable resource. */ static void -write_rc_stringtable (e, name, stringtable) - FILE *e; - const struct res_id *name; - const struct stringtable *stringtable; +write_rc_stringtable (FILE *e, const struct res_id *name, + const struct stringtable *stringtable) { unsigned long offset; int i; @@ -2254,9 +2479,7 @@ write_rc_stringtable (e, name, stringtable) /* Write out a versioninfo resource. */ static void -write_rc_versioninfo (e, versioninfo) - FILE *e; - const struct versioninfo *versioninfo; +write_rc_versioninfo (FILE *e, const struct versioninfo *versioninfo) { const struct fixed_versioninfo *f; const struct ver_info *vi; @@ -2345,10 +2568,7 @@ write_rc_versioninfo (e, versioninfo) /* Write out data which would normally be read from a file. */ static void -write_rc_filedata (e, length, data) - FILE *e; - unsigned long length; - const unsigned char *data; +write_rc_filedata (FILE *e, unsigned long length, const unsigned char *data) { unsigned long i;