resrc.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,671 行 · 第 1/5 页

C
2,671
字号
/* resrc.c -- read and write Windows rc files.   Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.   Written by Ian Lance Taylor, Cygnus Support.   This file is part of GNU Binutils.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   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.  *//* This file contains functions that read and write Windows rc files.   These are text files that represent resources.  */#include "bfd.h"#include "bucomm.h"#include "libiberty.h"#include "windres.h"#include <assert.h>#include <ctype.h>#include <errno.h>#include <sys/stat.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#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 */#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 -DRC_INVOKED"/* We read the directory entries in a cursor or icon file into   instances of this structure.  */struct icondir{  /* Width of image.  */  unsigned char width;  /* Height of image.  */  unsigned char height;  /* Number of colors in image.  */  unsigned char colorcount;  union  {    struct    {      /* Color planes.  */      unsigned short planes;      /* Bits per pixel.  */      unsigned short bits;    } icon;    struct    {      /* X coordinate of hotspot.  */      unsigned short xhotspot;      /* Y coordinate of hotspot.  */      unsigned short yhotspot;    } cursor;  } u;  /* Bytes in image.  */  unsigned long bytes;  /* File offset of image.  */  unsigned long offset;};/* The name of the rc file we are reading.  */char *rc_filename;/* The line number in the rc file.  */int rc_lineno;/* The pipe we are reading from, so that we can close it if we exit.  */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;/* The number of cursor resources we have written out.  */static int cursors;/* The number of font resources we have written out.  */static int fonts;/* Font directory information.  */struct fontdir *fontdirs;/* Resource info to use for fontdirs.  */struct res_res_info fontdirs_resinfo;/* The number of icon resources we have written out.  */static int icons;/* Local functions.  */static int run_cmd PARAMS ((char *, const char *));static FILE *open_input_stream PARAMS ((char *));static FILE *look_for_default PARAMS ((char *, const char *, int,				       const char *, const char *));static void close_input_stream 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));/* Run `cmd' and redirect the output to `redir'. */static intrun_cmd (cmd, redir)     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 reponse 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 (cmd)     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;{  char *space;  int found;  struct stat s;  strcpy (cmd, prefix);  sprintf (cmd + end_prefix, "%s", DEFAULT_PREPROCESSOR);  space = strchr (cmd + end_prefix, ' ');  if (space)    *space = 0;  if (#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32)      strchr (cmd, '\\') ||#endif      strchr (cmd, '/'))    {      found = (stat (cmd, &s) == 0#ifdef HAVE_EXECUTABLE_SUFFIX	       || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0#endif	       );      if (! found)	{	  if (verbose)	    fprintf (stderr, _("Tried `%s'\n"), cmd);	  return NULL;	}    }  strcpy (cmd, prefix);  sprintf (cmd + end_prefix, "%s %s %s",	   DEFAULT_PREPROCESSOR, preprocargs, filename);  if (verbose)    fprintf (stderr, _("Using `%s'\n"), cmd);  cpp_pipe = open_input_stream (cmd);  return cpp_pipe;}/* Read an rc file.  */struct res_directory *read_rc_file (filename, preprocessor, preprocargs, language, use_temp_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)    filename = "-";  if (preprocessor)    {      cmd = xmalloc (strlen (preprocessor)		     + strlen (preprocargs)		     + strlen (filename)		     + 10);      sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename);      cpp_pipe = open_input_stream (cmd);    }  else    {      char *dash, *slash, *cp;      preprocessor = DEFAULT_PREPROCESSOR;      cmd = xmalloc (strlen (program_name)		     + strlen (preprocessor)		     + strlen (preprocargs)		     + strlen (filename)#ifdef HAVE_EXECUTABLE_SUFFIX		     + strlen (EXECUTABLE_SUFFIX)#endif		     + 10);      dash = slash = 0;      for (cp = program_name; *cp; cp++)	{	  if (*cp == '-')	    dash = cp;	  if (#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32)	      *cp == ':' || *cp == '\\' ||#endif	      *cp == '/')	    {	      slash = cp;	      dash = 0;	    }	}      cpp_pipe = 0;      if (dash)	{	  /* First, try looking for a prefixed gcc in the windres	     directory, with the same prefix as windres */	  cpp_pipe = look_for_default (cmd, program_name, dash-program_name+1,				       preprocargs, filename);	}      if (slash && !cpp_pipe)	{	  /* Next, try looking for a gcc in the same directory as             that windres */	  cpp_pipe = look_for_default (cmd, program_name, slash-program_name+1,				       preprocargs, filename);	}      if (!cpp_pipe)	{	  /* Sigh, try the default */	  cpp_pipe = look_for_default (cmd, "", 0, preprocargs, filename);	}    }    free (cmd);  rc_filename = xstrdup (filename);  rc_lineno = 1;  if (language != -1)    rcparse_set_language (language);  yyin = cpp_pipe;  yyparse ();  close_input_stream ();    if (fontdirs != NULL)    define_fontdirs ();  free (rc_filename);  rc_filename = NULL;  return resources;}/* Close the input stream if it is open.  */static voidclose_input_stream (){  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.  */voidyyerror (msg)     const char *msg;{  fatal ("%s:%d: %s", rc_filename, rc_lineno, msg);}/* Issue a warning while reading an rc file.  */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?