mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-02 02:10:46 -08:00
Fix file name encodings in diagnostics
Also, close some minor races when opening image files, by opening them once instead of multiple times. * src/gtkutil.c (xg_get_image_for_pixmap): * src/image.c (xpm_load, tiff_load, gif_load, imagemagick_load) (svg_load): * src/nsimage.m (allocInitFromFile:): * src/xfns.c (xg_set_icon): Encode file name, since x_find_image_file no longer does that. * src/image.c (x_find_image_fd): New function. (x_find_image_file): Use it. Do not encode resulting file name, since callers sometimes need it decoded. (slurp_file): File arg is now a fd, not a file name. All callers changed. This saves us having to open the file twice. (xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body) (svg_load): Use x_find_image_fd and fdopen to save a file-open. Report file name that failed. * src/lread.c (openp): If PREDICATE is t, open the file in binary mode.
This commit is contained in:
parent
345284f5e9
commit
6367368616
5 changed files with 84 additions and 70 deletions
|
|
@ -382,10 +382,11 @@ xg_get_image_for_pixmap (struct frame *f,
|
|||
if (STRINGP (specified_file)
|
||||
&& STRINGP (file = x_find_image_file (specified_file)))
|
||||
{
|
||||
char *encoded_file = SSDATA (ENCODE_FILE (file));
|
||||
if (! old_widget)
|
||||
old_widget = GTK_IMAGE (gtk_image_new_from_file (SSDATA (file)));
|
||||
old_widget = GTK_IMAGE (gtk_image_new_from_file (encoded_file));
|
||||
else
|
||||
gtk_image_set_from_file (old_widget, SSDATA (file));
|
||||
gtk_image_set_from_file (old_widget, encoded_file);
|
||||
|
||||
return GTK_WIDGET (old_widget);
|
||||
}
|
||||
|
|
|
|||
133
src/image.c
133
src/image.c
|
|
@ -2270,11 +2270,13 @@ image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
|
|||
***********************************************************************/
|
||||
|
||||
/* Find image file FILE. Look in data-directory/images, then
|
||||
x-bitmap-file-path. Value is the encoded full name of the file
|
||||
found, or nil if not found. */
|
||||
x-bitmap-file-path. Value is the full name of the file
|
||||
found, or nil if not found. If PFD is nonnull store into *PFD a
|
||||
readable file descriptor for the file, opened in binary mode. If
|
||||
PFD is null, do not open the file. */
|
||||
|
||||
Lisp_Object
|
||||
x_find_image_file (Lisp_Object file)
|
||||
static Lisp_Object
|
||||
x_find_image_fd (Lisp_Object file, int *pfd)
|
||||
{
|
||||
Lisp_Object file_found, search_path;
|
||||
int fd;
|
||||
|
|
@ -2286,29 +2288,35 @@ x_find_image_file (Lisp_Object file)
|
|||
Vx_bitmap_file_path);
|
||||
|
||||
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
|
||||
fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
|
||||
|
||||
if (fd == -1)
|
||||
file_found = Qnil;
|
||||
else
|
||||
{
|
||||
file_found = ENCODE_FILE (file_found);
|
||||
if (fd != -2)
|
||||
emacs_close (fd);
|
||||
}
|
||||
|
||||
fd = openp (search_path, file, Qnil, &file_found,
|
||||
pfd ? Qt : make_number (R_OK), false);
|
||||
if (fd < 0)
|
||||
return Qnil;
|
||||
if (pfd)
|
||||
*pfd = fd;
|
||||
return file_found;
|
||||
}
|
||||
|
||||
/* Find image file FILE. Look in data-directory/images, then
|
||||
x-bitmap-file-path. Value is the encoded full name of the file
|
||||
found, or nil if not found. */
|
||||
|
||||
Lisp_Object
|
||||
x_find_image_file (Lisp_Object file)
|
||||
{
|
||||
return x_find_image_fd (file, 0);
|
||||
}
|
||||
|
||||
/* Read FILE into memory. Value is a pointer to a buffer allocated
|
||||
with xmalloc holding FILE's contents. Value is null if an error
|
||||
occurred. *SIZE is set to the size of the file. */
|
||||
occurred. FD is a file descriptor open for reading FILE. Set
|
||||
*SIZE to the size of the file. */
|
||||
|
||||
static unsigned char *
|
||||
slurp_file (char *file, ptrdiff_t *size)
|
||||
slurp_file (int fd, ptrdiff_t *size)
|
||||
{
|
||||
FILE *fp = emacs_fopen (file, "rb");
|
||||
FILE *fp = fdopen (fd, "rb");
|
||||
|
||||
unsigned char *buf = NULL;
|
||||
struct stat st;
|
||||
|
||||
|
|
@ -2980,21 +2988,19 @@ xbm_load (struct frame *f, struct image *img)
|
|||
file_name = image_spec_value (img->spec, QCfile, NULL);
|
||||
if (STRINGP (file_name))
|
||||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (file_name, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
contents = slurp_file (SSDATA (file), &size);
|
||||
ptrdiff_t size;
|
||||
unsigned char *contents = slurp_file (fd, &size);
|
||||
if (contents == NULL)
|
||||
{
|
||||
image_error ("Error loading XBM image "uLSQM"%s"uRSQM, img->spec);
|
||||
image_error ("Error loading XBM image "uLSQM"%s"uRSQM, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3640,6 +3646,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
return 0;
|
||||
}
|
||||
|
||||
file = ENCODE_FILE (file);
|
||||
#ifdef HAVE_NTGUI
|
||||
#ifdef WINDOWSNT
|
||||
/* FILE is encoded in UTF-8, but image libraries on Windows
|
||||
|
|
@ -4290,21 +4297,19 @@ xpm_load (struct frame *f,
|
|||
file_name = image_spec_value (img->spec, QCfile, NULL);
|
||||
if (STRINGP (file_name))
|
||||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (file_name, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
contents = slurp_file (SSDATA (file), &size);
|
||||
ptrdiff_t size;
|
||||
unsigned char *contents = slurp_file (fd, &size);
|
||||
if (contents == NULL)
|
||||
{
|
||||
image_error ("Error loading XPM image "uLSQM"%s"uRSQM, img->spec);
|
||||
image_error ("Error loading XPM image "uLSQM"%s"uRSQM, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5253,11 +5258,10 @@ pbm_load (struct frame *f, struct image *img)
|
|||
bool raw_p;
|
||||
int x, y;
|
||||
int width, height, max_color_idx = 0;
|
||||
Lisp_Object file, specified_file;
|
||||
Lisp_Object specified_file;
|
||||
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
|
||||
unsigned char *contents = NULL;
|
||||
unsigned char *end, *p;
|
||||
ptrdiff_t size;
|
||||
#ifdef USE_CAIRO
|
||||
unsigned char *data = 0;
|
||||
uint32_t *dataptr;
|
||||
|
|
@ -5269,7 +5273,8 @@ pbm_load (struct frame *f, struct image *img)
|
|||
|
||||
if (STRINGP (specified_file))
|
||||
{
|
||||
file = x_find_image_file (specified_file);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (specified_file, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
|
||||
|
|
@ -5277,7 +5282,8 @@ pbm_load (struct frame *f, struct image *img)
|
|||
return 0;
|
||||
}
|
||||
|
||||
contents = slurp_file (SSDATA (file), &size);
|
||||
ptrdiff_t size;
|
||||
contents = slurp_file (fd, &size);
|
||||
if (contents == NULL)
|
||||
{
|
||||
image_error ("Error reading "uLSQM"%s"uRSQM, file);
|
||||
|
|
@ -5878,7 +5884,7 @@ struct png_load_context
|
|||
static bool
|
||||
png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
||||
{
|
||||
Lisp_Object file, specified_file;
|
||||
Lisp_Object specified_file;
|
||||
Lisp_Object specified_data;
|
||||
int x, y;
|
||||
ptrdiff_t i;
|
||||
|
|
@ -5909,7 +5915,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
|
||||
if (NILP (specified_data))
|
||||
{
|
||||
file = x_find_image_file (specified_file);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (specified_file, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
|
||||
|
|
@ -5918,7 +5925,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
|
|||
}
|
||||
|
||||
/* Open the image file. */
|
||||
fp = emacs_fopen (SSDATA (file), "rb");
|
||||
fp = fdopen (fd, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
image_error ("Cannot open image file "uLSQM"%s"uRSQM, file);
|
||||
|
|
@ -6654,7 +6661,7 @@ static bool
|
|||
jpeg_load_body (struct frame *f, struct image *img,
|
||||
struct my_jpeg_error_mgr *mgr)
|
||||
{
|
||||
Lisp_Object file, specified_file;
|
||||
Lisp_Object specified_file;
|
||||
Lisp_Object specified_data;
|
||||
/* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
|
||||
FILE * IF_LINT (volatile) fp = NULL;
|
||||
|
|
@ -6674,7 +6681,8 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
|
||||
if (NILP (specified_data))
|
||||
{
|
||||
file = x_find_image_file (specified_file);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (specified_file, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
|
||||
|
|
@ -6682,7 +6690,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
return 0;
|
||||
}
|
||||
|
||||
fp = emacs_fopen (SSDATA (file), "rb");
|
||||
fp = fdopen (fd, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
|
||||
|
|
@ -7172,7 +7180,7 @@ tiff_warning_handler (const char *title, const char *format, va_list ap)
|
|||
static bool
|
||||
tiff_load (struct frame *f, struct image *img)
|
||||
{
|
||||
Lisp_Object file, specified_file;
|
||||
Lisp_Object specified_file;
|
||||
Lisp_Object specified_data;
|
||||
TIFF *tiff;
|
||||
int width, height, x, y, count;
|
||||
|
|
@ -7191,19 +7199,21 @@ tiff_load (struct frame *f, struct image *img)
|
|||
if (NILP (specified_data))
|
||||
{
|
||||
/* Read from a file */
|
||||
file = x_find_image_file (specified_file);
|
||||
Lisp_Object file = x_find_image_file (specified_file);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
|
||||
specified_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Lisp_Object encoded_file = ENCODE_FILE (file);
|
||||
# ifdef WINDOWSNT
|
||||
file = ansi_encode_filename (file);
|
||||
encoded_file = ansi_encode_filename (encoded_file);
|
||||
# endif
|
||||
|
||||
/* Try to open the image file. */
|
||||
tiff = TIFFOpen (SSDATA (file), "r");
|
||||
tiff = TIFFOpen (SSDATA (encoded_file), "r");
|
||||
if (tiff == NULL)
|
||||
{
|
||||
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
|
||||
|
|
@ -7605,7 +7615,6 @@ static const int interlace_increment[] = {8, 8, 4, 2};
|
|||
static bool
|
||||
gif_load (struct frame *f, struct image *img)
|
||||
{
|
||||
Lisp_Object file;
|
||||
int rc, width, height, x, y, i, j;
|
||||
ColorMapObject *gif_color_map;
|
||||
unsigned long pixel_colors[256];
|
||||
|
|
@ -7626,27 +7635,29 @@ gif_load (struct frame *f, struct image *img)
|
|||
|
||||
if (NILP (specified_data))
|
||||
{
|
||||
file = x_find_image_file (specified_file);
|
||||
Lisp_Object file = x_find_image_file (specified_file);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
|
||||
specified_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Lisp_Object encoded_file = ENCODE_FILE (file);
|
||||
#ifdef WINDOWSNT
|
||||
file = ansi_encode_filename (file);
|
||||
encoded_file = ansi_encode_filename (encoded_file);
|
||||
#endif
|
||||
|
||||
/* Open the GIF file. */
|
||||
#if GIFLIB_MAJOR < 5
|
||||
gif = DGifOpenFileName (SSDATA (file));
|
||||
gif = DGifOpenFileName (SSDATA (encoded_file));
|
||||
if (gif == NULL)
|
||||
{
|
||||
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
gif = DGifOpenFileName (SSDATA (file), &gif_err);
|
||||
gif = DGifOpenFileName (SSDATA (encoded_file), &gif_err);
|
||||
if (gif == NULL)
|
||||
{
|
||||
image_error ("Cannot open "uLSQM"%s"uRSQM": %s",
|
||||
|
|
@ -8818,14 +8829,13 @@ imagemagick_load (struct frame *f, struct image *img)
|
|||
file_name = image_spec_value (img->spec, QCfile, NULL);
|
||||
if (STRINGP (file_name))
|
||||
{
|
||||
Lisp_Object file;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
Lisp_Object file = x_find_image_file (file_name);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
|
||||
return 0;
|
||||
}
|
||||
file = ENCODE_FILE (file);
|
||||
#ifdef WINDOWSNT
|
||||
file = ansi_encode_filename (file);
|
||||
#endif
|
||||
|
|
@ -9097,11 +9107,8 @@ svg_load (struct frame *f, struct image *img)
|
|||
file_name = image_spec_value (img->spec, QCfile, NULL);
|
||||
if (STRINGP (file_name))
|
||||
{
|
||||
Lisp_Object file;
|
||||
unsigned char *contents;
|
||||
ptrdiff_t size;
|
||||
|
||||
file = x_find_image_file (file_name);
|
||||
int fd;
|
||||
Lisp_Object file = x_find_image_fd (file_name, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
|
||||
|
|
@ -9109,14 +9116,16 @@ svg_load (struct frame *f, struct image *img)
|
|||
}
|
||||
|
||||
/* Read the entire file into memory. */
|
||||
contents = slurp_file (SSDATA (file), &size);
|
||||
ptrdiff_t size;
|
||||
unsigned char *contents = slurp_file (fd, &size);
|
||||
if (contents == NULL)
|
||||
{
|
||||
image_error ("Error loading SVG image "uLSQM"%s"uRSQM, img->spec);
|
||||
image_error ("Error loading SVG image "uLSQM"%s"uRSQM, file);
|
||||
return 0;
|
||||
}
|
||||
/* If the file was slurped into memory properly, parse it. */
|
||||
success_p = svg_load_image (f, img, contents, size, SSDATA (file));
|
||||
success_p = svg_load_image (f, img, contents, size,
|
||||
SSDATA (ENCODE_FILE (file)));
|
||||
xfree (contents);
|
||||
}
|
||||
/* Else its not a file, its a lisp object. Load the image from a
|
||||
|
|
|
|||
13
src/lread.c
13
src/lread.c
|
|
@ -1403,7 +1403,8 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
|
|||
SUFFIXES is a list of strings containing possible suffixes.
|
||||
The empty suffix is automatically added if the list is empty.
|
||||
|
||||
PREDICATE non-nil means don't open the files,
|
||||
PREDICATE t means the files are binary.
|
||||
PREDICATE non-nil and non-t means don't open the files,
|
||||
just look for one that satisfies the predicate. In this case,
|
||||
return 1 on success. The predicate can be a lisp function or
|
||||
an integer to pass to `access' (in which case file-name-handlers
|
||||
|
|
@ -1418,7 +1419,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
|
|||
|
||||
If NEWER is true, try all SUFFIXes and return the result for the
|
||||
newest file that exists. Does not apply to remote files,
|
||||
or if PREDICATE is specified. */
|
||||
or if a non-nil and non-t PREDICATE is specified. */
|
||||
|
||||
int
|
||||
openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
||||
|
|
@ -1520,10 +1521,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
else
|
||||
string = make_string (fn, fnlen);
|
||||
handler = Ffind_file_name_handler (string, Qfile_exists_p);
|
||||
if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
|
||||
if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
|
||||
&& !NATNUMP (predicate))
|
||||
{
|
||||
bool exists;
|
||||
if (NILP (predicate))
|
||||
if (NILP (predicate) || EQ (predicate, Qt))
|
||||
exists = !NILP (Ffile_readable_p (string));
|
||||
else
|
||||
{
|
||||
|
|
@ -1577,7 +1579,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
}
|
||||
else
|
||||
{
|
||||
fd = emacs_open (pfn, O_RDONLY, 0);
|
||||
int oflags = O_RDONLY + (NILP (predicate) ? 0 : O_BINARY);
|
||||
fd = emacs_open (pfn, oflags, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
|
|||
found = x_find_image_file (file);
|
||||
if (!STRINGP (found))
|
||||
return nil;
|
||||
found = ENCODE_FILE (found);
|
||||
|
||||
image = [[EmacsImage alloc] initByReferencingFile:
|
||||
[NSString stringWithUTF8String: SSDATA (found)]];
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ xg_set_icon (struct frame *f, Lisp_Object file)
|
|||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *err = NULL;
|
||||
char *filename = SSDATA (found);
|
||||
char *filename = SSDATA (ENCODE_FILE (found));
|
||||
block_input ();
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename, &err);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue