aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2004-04-15 16:49:22 +0000
committerKaroly Lorentey2004-04-15 16:49:22 +0000
commitbf11e465e7de681939128d851b82689de1a54849 (patch)
treedd74933805490dc63c24f6a003ebb3aef591ef7b /src
parentd3c554a0d08581693289f0b781176d56163aa2a5 (diff)
parentd01ca4a8d2a5fc59742dd643e2351b956423ee73 (diff)
downloademacs-bf11e465e7de681939128d851b82689de1a54849.tar.gz
emacs-bf11e465e7de681939128d851b82689de1a54849.zip
Merged in changes from CVS trunk.
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-213 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-214 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-215 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-216 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-217 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-138
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog40
-rw-r--r--src/callint.c2
-rw-r--r--src/dispnew.c16
-rw-r--r--src/editfns.c4
-rw-r--r--src/fileio.c7
-rw-r--r--src/sheap.c104
-rw-r--r--src/syntax.c16
-rw-r--r--src/unexcw.c307
-rw-r--r--src/window.c1
-rw-r--r--src/xdisp.c40
10 files changed, 500 insertions, 37 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6d48aa0f6d0..c9cf12dc159 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,39 @@
12004-04-14 Luc Teirlinck <teirllm@auburn.edu>
2
3 * fileio.c (Fverify_visited_file_modtime, Fvisited_file_modtime):
4 Add hyperlink to Elisp manual to the docstring.
5
62004-04-14 Stefan Monnier <monnier@iro.umontreal.ca>
7
8 * callint.c (fix_command): Use XDCR.
9
102004-04-14 Nick Roberts <nick@nick.uklinux.net>
11
12 * window.c (Fget_lru_window): Doc fix.
13
142004-04-14 Kim F. Storm <storm@cua.dk>
15
16 * editfns.c (Fformat): Fix allocation size of precision array.
17
18 * dispnew.c (update_window): Only set changed_p if
19 scrolling_window actually did scroll.
20 (scrolling_window): Only return 1 if we actually did scroll.
21
22 * xdisp.c (get_glyph_string_clip_rect): Fix reduction of cursor
23 height to glyph height when cursor row is not fully visible.
24 (make_cursor_line_fully_visible): Add FORCE_P arg to return
25 failure in case row is higher than window. Callers changed.
26 (try_scrolling): Fix loop in scrolling if last_line_misfit (from Gerd).
27 Try to scroll partially visible, higher-than-window cursor row.
28 (redisplay_window): Always try to scroll partially visible,
29 higher-than-window cursor row - both initially and again with
30 centering_position = 0.
31 Clear desired matrix before retrying with centering_position = 0.
32
332004-04-13 Joe Buehler <jbuehler@hekimian.com>
34
35 * sheap.c, unexcw.c: New files.
36
12004-04-12 Luc Teirlinck <teirllm@auburn.edu> 372004-04-12 Luc Teirlinck <teirllm@auburn.edu>
2 38
3 * buffer.c (Fmake_indirect_buffer): Throw an error if the intended 39 * buffer.c (Fmake_indirect_buffer): Throw an error if the intended
@@ -32,6 +68,10 @@
32 * buffer.c (fix_start_end_in_overlays): Make overlays 68 * buffer.c (fix_start_end_in_overlays): Make overlays
33 empty if they are backwards. 69 empty if they are backwards.
34 70
712004-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
72
73 * xfaces.c (face_color_supported_p): Fix compilation without X11.
74
352004-04-07 Stefan Monnier <monnier@iro.umontreal.ca> 752004-04-07 Stefan Monnier <monnier@iro.umontreal.ca>
36 76
37 * doc.c (Fsnarf_documentation): Ignore new file name entries. 77 * doc.c (Fsnarf_documentation): Ignore new file name entries.
diff --git a/src/callint.c b/src/callint.c
index 1d7d6f9f89f..50090db8b28 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -209,7 +209,7 @@ fix_command (input, values)
209 Lisp_Object intail, valtail; 209 Lisp_Object intail, valtail;
210 for (intail = Fcdr (input), valtail = values; 210 for (intail = Fcdr (input), valtail = values;
211 CONSP (valtail); 211 CONSP (valtail);
212 intail = Fcdr (intail), valtail = Fcdr (valtail)) 212 intail = Fcdr (intail), valtail = XCDR (valtail))
213 { 213 {
214 Lisp_Object elt; 214 Lisp_Object elt;
215 elt = Fcar (intail); 215 elt = Fcar (intail);
diff --git a/src/dispnew.c b/src/dispnew.c
index 3b658993811..9a6b0cb65cf 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -4132,9 +4132,11 @@ update_window (w, force_p)
4132 goto set_cursor; 4132 goto set_cursor;
4133 } 4133 }
4134 else if (rc > 0) 4134 else if (rc > 0)
4135 /* We've scrolled the display. */ 4135 {
4136 force_p = 1; 4136 /* We've scrolled the display. */
4137 changed_p = 1; 4137 force_p = 1;
4138 changed_p = 1;
4139 }
4138 } 4140 }
4139 4141
4140 /* Update the rest of the lines. */ 4142 /* Update the rest of the lines. */
@@ -5056,8 +5058,8 @@ scrolling_window (w, header_line_p)
5056 for (i = 0; i < row_entry_idx; ++i) 5058 for (i = 0; i < row_entry_idx; ++i)
5057 row_table[row_entry_pool[i].bucket] = NULL; 5059 row_table[row_entry_pool[i].bucket] = NULL;
5058 5060
5059 /* Value is non-zero to indicate that we scrolled the display. */ 5061 /* Value is > 0 to indicate that we scrolled the display. */
5060 return 1; 5062 return nruns;
5061} 5063}
5062 5064
5063 5065
@@ -5919,13 +5921,13 @@ marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
5919 it's the one we were looking for. */ 5921 it's the one we were looking for. */
5920 if (area == RIGHT_MARGIN_AREA) 5922 if (area == RIGHT_MARGIN_AREA)
5921 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5923 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5922 ? WINDOW_LEFT_FRINGE_WIDTH (w) 5924 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5923 : WINDOW_TOTAL_FRINGE_WIDTH (w)) 5925 : WINDOW_TOTAL_FRINGE_WIDTH (w))
5924 + window_box_width (w, LEFT_MARGIN_AREA) 5926 + window_box_width (w, LEFT_MARGIN_AREA)
5925 + window_box_width (w, TEXT_AREA)); 5927 + window_box_width (w, TEXT_AREA));
5926 else 5928 else
5927 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5929 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5928 ? WINDOW_LEFT_FRINGE_WIDTH (w) 5930 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5929 : 0); 5931 : 0);
5930 5932
5931 glyph = row->glyphs[area]; 5933 glyph = row->glyphs[area];
diff --git a/src/editfns.c b/src/editfns.c
index ce075f2696c..a5c3aea14bc 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3220,7 +3220,7 @@ usage: (format STRING &rest OBJECTS) */)
3220 string itself, will not be used. Element NARGS, corresponding to 3220 string itself, will not be used. Element NARGS, corresponding to
3221 no argument, *will* be assigned to in the case that a `%' and `.' 3221 no argument, *will* be assigned to in the case that a `%' and `.'
3222 occur after the final format specifier. */ 3222 occur after the final format specifier. */
3223 int *precision = (int *) (alloca(nargs * sizeof (int))); 3223 int *precision = (int *) (alloca((nargs + 1) * sizeof (int)));
3224 int longest_format; 3224 int longest_format;
3225 Lisp_Object val; 3225 Lisp_Object val;
3226 int arg_intervals = 0; 3226 int arg_intervals = 0;
@@ -3274,7 +3274,7 @@ usage: (format STRING &rest OBJECTS) */)
3274 /* Make room in result for all the non-%-codes in the control string. */ 3274 /* Make room in result for all the non-%-codes in the control string. */
3275 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); 3275 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]);
3276 3276
3277 /* Allocate the info and discarded tables. */ 3277 /* Allocate the info and discarded tables. */
3278 { 3278 {
3279 int nbytes = nargs * sizeof *info; 3279 int nbytes = nargs * sizeof *info;
3280 int i; 3280 int i;
diff --git a/src/fileio.c b/src/fileio.c
index 3f17da7033d..c0195558a3c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5509,7 +5509,8 @@ e_write (desc, string, start, end, coding)
5509DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 5509DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
5510 Sverify_visited_file_modtime, 1, 1, 0, 5510 Sverify_visited_file_modtime, 1, 1, 0,
5511 doc: /* Return t if last mod time of BUF's visited file matches what BUF records. 5511 doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
5512This means that the file has not been changed since it was visited or saved. */) 5512This means that the file has not been changed since it was visited or saved.
5513See Info node `(elisp)Modification Time' for more details. */)
5513 (buf) 5514 (buf)
5514 Lisp_Object buf; 5515 Lisp_Object buf;
5515{ 5516{
@@ -5565,7 +5566,9 @@ DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5565 Svisited_file_modtime, 0, 0, 0, 5566 Svisited_file_modtime, 0, 0, 0,
5566 doc: /* Return the current buffer's recorded visited file modification time. 5567 doc: /* Return the current buffer's recorded visited file modification time.
5567The value is a list of the form (HIGH . LOW), like the time values 5568The value is a list of the form (HIGH . LOW), like the time values
5568that `file-attributes' returns. */) 5569that `file-attributes' returns. If the current buffer has no recorded
5570file modification time, this function returns 0.
5571See Info node `(elisp)Modification Time' for more details. */)
5569 () 5572 ()
5570{ 5573{
5571 return long_to_cons ((unsigned long) current_buffer->modtime); 5574 return long_to_cons ((unsigned long) current_buffer->modtime);
diff --git a/src/sheap.c b/src/sheap.c
new file mode 100644
index 00000000000..714eb9a710d
--- /dev/null
+++ b/src/sheap.c
@@ -0,0 +1,104 @@
1/* simulate sbrk() with an array in .bss, for unexec() support for Cygwin;
2 complete rewrite of xemacs Cygwin unexec() code
3
4 Copyright (C) 2004
5 Free Software Foundation, Inc.
6
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
23
24#include <config.h>
25#include <stdio.h>
26#include "lisp.h"
27
28#include <unistd.h>
29
30#ifdef HAVE_X_WINDOWS
31#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
32#else
33#define STATIC_HEAP_SIZE (7 * 1024 * 1024)
34#endif
35
36int debug_sheap = 0;
37
38#define BLOCKSIZE 4096
39
40char bss_sbrk_buffer[STATIC_HEAP_SIZE];
41char *bss_sbrk_ptr;
42int bss_sbrk_did_unexec;
43
44void *
45bss_sbrk (ptrdiff_t request_size)
46{
47 if (!bss_sbrk_ptr)
48 {
49 bss_sbrk_ptr = bss_sbrk_buffer;
50#ifdef CYGWIN
51 sbrk (BLOCKSIZE); /* force space for fork to work */
52#endif
53 }
54
55 if (!(int) request_size)
56 {
57 return (bss_sbrk_ptr);
58 }
59 else if (bss_sbrk_ptr + (int) request_size < bss_sbrk_buffer)
60 {
61 printf
62 ("attempt to free too much: avail %d used %d failed request %d\n",
63 STATIC_HEAP_SIZE, bss_sbrk_ptr - bss_sbrk_buffer,
64 (int) request_size);
65 exit (-1);
66 return 0;
67 }
68 else if (bss_sbrk_ptr + (int) request_size >
69 bss_sbrk_buffer + STATIC_HEAP_SIZE)
70 {
71 printf ("static heap exhausted: avail %d used %d failed request %d\n",
72 STATIC_HEAP_SIZE,
73 bss_sbrk_ptr - bss_sbrk_buffer, (int) request_size);
74 exit (-1);
75 return 0;
76 }
77 else if ((int) request_size < 0)
78 {
79 bss_sbrk_ptr += (int) request_size;
80 if (debug_sheap)
81 printf ("freed size %d\n", request_size);
82 return bss_sbrk_ptr;
83 }
84 else
85 {
86 char *ret = bss_sbrk_ptr;
87 if (debug_sheap)
88 printf ("allocated 0x%08x size %d\n", ret, request_size);
89 bss_sbrk_ptr += (int) request_size;
90 return ret;
91 }
92}
93
94void
95report_sheap_usage (int die_if_pure_storage_exceeded)
96{
97 char buf[200];
98 sprintf (buf, "Static heap usage: %d of %d bytes",
99 bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE);
100 message ("%s", buf);
101}
102
103/* arch-tag: 1bc386e8-71c2-4da4-b8b5-c1674a9cf926
104 (do not change this comment) */
diff --git a/src/syntax.c b/src/syntax.c
index 30fc94267cd..72f7a5c5209 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -2398,8 +2398,8 @@ scan_lists (from, count, depth, sexpflag)
2398 case Sstring_fence: 2398 case Sstring_fence:
2399 while (1) 2399 while (1)
2400 { 2400 {
2401 DEC_BOTH (from, from_byte);
2402 if (from == stop) goto lose; 2401 if (from == stop) goto lose;
2402 DEC_BOTH (from, from_byte);
2403 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2403 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2404 if (!char_quoted (from, from_byte) 2404 if (!char_quoted (from, from_byte)
2405 && (c = FETCH_CHAR (from_byte), 2405 && (c = FETCH_CHAR (from_byte),
@@ -2414,19 +2414,13 @@ scan_lists (from, count, depth, sexpflag)
2414 while (1) 2414 while (1)
2415 { 2415 {
2416 if (from == stop) goto lose; 2416 if (from == stop) goto lose;
2417 temp_pos = from_byte; 2417 DEC_BOTH (from, from_byte);
2418 if (! NILP (current_buffer->enable_multibyte_characters)) 2418 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2419 DEC_POS (temp_pos); 2419 if (!char_quoted (from, from_byte)
2420 else 2420 && stringterm == (c = FETCH_CHAR (from_byte))
2421 temp_pos--;
2422 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2423 if (!char_quoted (from - 1, temp_pos)
2424 && stringterm == (c = FETCH_CHAR (temp_pos))
2425 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) 2421 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
2426 break; 2422 break;
2427 DEC_BOTH (from, from_byte);
2428 } 2423 }
2429 DEC_BOTH (from, from_byte);
2430 if (!depth && sexpflag) goto done2; 2424 if (!depth && sexpflag) goto done2;
2431 break; 2425 break;
2432 default: 2426 default:
diff --git a/src/unexcw.c b/src/unexcw.c
new file mode 100644
index 00000000000..046c8f796ef
--- /dev/null
+++ b/src/unexcw.c
@@ -0,0 +1,307 @@
1/* unexec() support for Cygwin;
2 complete rewrite of xemacs Cygwin unexec() code
3
4 Copyright (C) 2004
5 Free Software Foundation, Inc.
6
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
23
24#include <config.h>
25#include <lisp.h>
26#include <stdio.h>
27#include <fcntl.h>
28#include <a.out.h>
29#include <unistd.h>
30#include <assert.h>
31
32#define DOTEXE ".exe"
33
34extern int bss_sbrk_did_unexec;
35
36/* emacs symbols that indicate where bss and data end for emacs internals */
37extern char my_endbss[];
38extern char my_edata[];
39
40/*
41** header for Windows executable files
42*/
43typedef struct
44{
45 FILHDR file_header;
46 PEAOUTHDR file_optional_header;
47 SCNHDR section_header[32];
48} exe_header_t;
49
50int debug_unexcw = 0;
51
52/*
53** Read the header from the executable into memory so we can more easily access it.
54*/
55static exe_header_t *
56read_exe_header (int fd, exe_header_t * exe_header_buffer)
57{
58 int i;
59 int ret;
60
61 assert (fd >= 0);
62 assert (exe_header_buffer != 0);
63
64 ret = lseek (fd, 0L, SEEK_SET);
65 assert (ret != -1);
66
67 ret =
68 read (fd, &exe_header_buffer->file_header,
69 sizeof (exe_header_buffer->file_header));
70 assert (ret == sizeof (exe_header_buffer->file_header));
71
72 assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
73 assert (exe_header_buffer->file_header.nt_signature == 0x4550);
74 assert (exe_header_buffer->file_header.f_magic == 0x014c);
75 assert (exe_header_buffer->file_header.f_nscns > 0);
76 assert (exe_header_buffer->file_header.f_nscns <=
77 sizeof (exe_header_buffer->section_header) /
78 sizeof (exe_header_buffer->section_header[0]));
79 assert (exe_header_buffer->file_header.f_opthdr > 0);
80
81 ret =
82 read (fd, &exe_header_buffer->file_optional_header,
83 sizeof (exe_header_buffer->file_optional_header));
84 assert (ret == sizeof (exe_header_buffer->file_optional_header));
85
86 assert (exe_header_buffer->file_optional_header.magic == 0x010b);
87
88 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
89 {
90 ret =
91 read (fd, &exe_header_buffer->section_header[i],
92 sizeof (exe_header_buffer->section_header[i]));
93 assert (ret == sizeof (exe_header_buffer->section_header[i]));
94 }
95
96 return (exe_header_buffer);
97}
98
99/*
100** Fix the dumped emacs executable:
101**
102** - copy .data section data of interest from running executable into
103** output .exe file
104**
105** - convert .bss section into an initialized data section (like
106** .data) and copy .bss section data of interest from running
107** executable into output .exe file
108*/
109static void
110fixup_executable (int fd)
111{
112 exe_header_t exe_header_buffer;
113 exe_header_t *exe_header;
114 int i;
115 int ret;
116 int found_data = 0;
117 int found_bss = 0;
118
119 exe_header = read_exe_header (fd, &exe_header_buffer);
120 assert (exe_header != 0);
121
122 assert (exe_header->file_header.f_nscns > 0);
123 for (i = 0; i < exe_header->file_header.f_nscns; ++i)
124 {
125 unsigned long start_address =
126 exe_header->section_header[i].s_vaddr +
127 exe_header->file_optional_header.ImageBase;
128 unsigned long end_address =
129 exe_header->section_header[i].s_vaddr +
130 exe_header->file_optional_header.ImageBase +
131 exe_header->section_header[i].s_paddr;
132 if (debug_unexcw)
133 printf ("%8s start 0x%08x end 0x%08x\n",
134 exe_header->section_header[i].s_name,
135 start_address, end_address);
136 if (my_edata >= (char *) start_address
137 && my_edata < (char *) end_address)
138 {
139 /* data section */
140 ret =
141 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
142 SEEK_SET);
143 assert (ret != -1);
144 ret =
145 write (fd, (char *) start_address,
146 my_edata - (char *) start_address);
147 assert (ret == my_edata - (char *) start_address);
148 ++found_data;
149 if (debug_unexcw)
150 printf (" .data, mem start 0x%08x mem length %d\n",
151 start_address, my_edata - (char *) start_address);
152 if (debug_unexcw)
153 printf (" .data, file start %d file length %d\n",
154 (int) exe_header->section_header[i].s_scnptr,
155 (int) exe_header->section_header[i].s_paddr);
156 }
157 else if (my_endbss >= (char *) start_address
158 && my_endbss < (char *) end_address)
159 {
160 /* bss section */
161 ++found_bss;
162 if (exe_header->section_header[i].s_flags & 0x00000080)
163 {
164 /* convert uninitialized data section to initialized data section */
165 struct stat statbuf;
166 ret = fstat (fd, &statbuf);
167 assert (ret != -1);
168
169 exe_header->section_header[i].s_flags &= ~0x00000080;
170 exe_header->section_header[i].s_flags |= 0x00000040;
171
172 exe_header->section_header[i].s_scnptr =
173 (statbuf.st_size +
174 exe_header->file_optional_header.FileAlignment) /
175 exe_header->file_optional_header.FileAlignment *
176 exe_header->file_optional_header.FileAlignment;
177
178 exe_header->section_header[i].s_size =
179 (exe_header->section_header[i].s_paddr +
180 exe_header->file_optional_header.FileAlignment) /
181 exe_header->file_optional_header.FileAlignment *
182 exe_header->file_optional_header.FileAlignment;
183
184 ret =
185 lseek (fd,
186 (long) (exe_header->section_header[i].s_scnptr +
187 exe_header->section_header[i].s_size - 1),
188 SEEK_SET);
189 assert (ret != -1);
190 ret = write (fd, "", 1);
191 assert (ret == 1);
192
193 ret =
194 lseek (fd,
195 (long) ((char *) &exe_header->section_header[i] -
196 (char *) exe_header), SEEK_SET);
197 assert (ret != -1);
198 ret =
199 write (fd, &exe_header->section_header[i],
200 sizeof (exe_header->section_header[i]));
201 assert (ret == sizeof (exe_header->section_header[i]));
202 if (debug_unexcw)
203 printf (" seek to %ld, write %d\n",
204 (long) ((char *) &exe_header->section_header[i] -
205 (char *) exe_header),
206 sizeof (exe_header->section_header[i]));
207 }
208 /* write initialized data section */
209 ret =
210 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
211 SEEK_SET);
212 assert (ret != -1);
213 ret =
214 write (fd, (char *) start_address,
215 my_endbss - (char *) start_address);
216 assert (ret == (my_endbss - (char *) start_address));
217 if (debug_unexcw)
218 printf (" .bss, mem start 0x%08x mem length %d\n",
219 start_address, my_endbss - (char *) start_address);
220 if (debug_unexcw)
221 printf (" .bss, file start %d file length %d\n",
222 (int) exe_header->section_header[i].s_scnptr,
223 (int) exe_header->section_header[i].s_paddr);
224 }
225 }
226 assert (found_bss == 1);
227 assert (found_data == 1);
228}
229
230/*
231** Windows likes .exe suffixes on executables.
232*/
233static char *
234add_exe_suffix_if_necessary (const char *name, char *modified)
235{
236 int i = strlen (name);
237 if (i <= (sizeof (DOTEXE) - 1))
238 {
239 sprintf (modified, "%s%s", name, DOTEXE);
240 }
241 else if (!strcasecmp (name + i - (sizeof (DOTEXE) - 1), DOTEXE))
242 {
243 strcpy (modified, name);
244 }
245 else
246 {
247 sprintf (modified, "%s%s", name, DOTEXE);
248 }
249 return (modified);
250}
251
252int
253unexec (char *outfile, char *infile, unsigned start_data, unsigned d1,
254 unsigned d2)
255{
256 char infile_buffer[FILENAME_MAX];
257 char outfile_buffer[FILENAME_MAX];
258 int fd_in;
259 int fd_out;
260 int ret;
261 int ret2;
262
263 if (bss_sbrk_did_unexec)
264 {
265 /* can only dump once */
266 printf ("You can only dump emacs once on this platform.\n");
267 return (1);
268 }
269
270 report_sheap_usage (1);
271
272 infile = add_exe_suffix_if_necessary (infile, infile_buffer);
273 outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer);
274
275 fd_in = open (infile, O_RDONLY | O_BINARY);
276 assert (fd_in >= 0);
277 fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755);
278 assert (fd_out >= 0);
279 for (;;)
280 {
281 char buffer[4096];
282 ret = read (fd_in, buffer, sizeof (buffer));
283 if (ret == 0)
284 {
285 /* eof */
286 break;
287 }
288 assert (ret > 0);
289 /* data */
290 ret2 = write (fd_out, buffer, ret);
291 assert (ret2 == ret);
292 }
293 ret = close (fd_in);
294 assert (ret == 0);
295
296 bss_sbrk_did_unexec = 1;
297 fixup_executable (fd_out);
298 bss_sbrk_did_unexec = 0;
299
300 ret = close (fd_out);
301 assert (ret == 0);
302
303 return (0);
304}
305
306/* arch-tag: fc44f6c3-ca0a-45e0-a5a2-58b6101b1e65
307 (do not change this comment) */
diff --git a/src/window.c b/src/window.c
index 0192aa4edf6..b6546eee698 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2080,6 +2080,7 @@ check_all_windows ()
2080 2080
2081DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, 2081DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0,
2082 doc: /* Return the window least recently selected or used for display. 2082 doc: /* Return the window least recently selected or used for display.
2083Return a full-width window if possible.
2083If optional argument FRAME is `visible', search all visible frames. 2084If optional argument FRAME is `visible', search all visible frames.
2084If FRAME is 0, search all visible and iconified frames. 2085If FRAME is 0, search all visible and iconified frames.
2085If FRAME is t, search all frames. 2086If FRAME is t, search all frames.
diff --git a/src/xdisp.c b/src/xdisp.c
index 0f5cde82cbd..b2e26d0858a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -846,7 +846,7 @@ static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
846 Lisp_Object)); 846 Lisp_Object));
847static void extend_face_to_end_of_line P_ ((struct it *)); 847static void extend_face_to_end_of_line P_ ((struct it *));
848static int append_space P_ ((struct it *, int)); 848static int append_space P_ ((struct it *, int));
849static int make_cursor_line_fully_visible P_ ((struct window *)); 849static int make_cursor_line_fully_visible P_ ((struct window *, int));
850static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int)); 850static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
851static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *)); 851static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
852static int trailing_whitespace_p P_ ((int)); 852static int trailing_whitespace_p P_ ((int));
@@ -1789,8 +1789,9 @@ get_glyph_string_clip_rect (s, nr)
1789 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent); 1789 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1790 if (height < r.height) 1790 if (height < r.height)
1791 { 1791 {
1792 r.y = s->ybase + glyph->descent - height; 1792 int max_y = r.y + r.height;
1793 r.height = height; 1793 r.y = min (max_y, s->ybase + glyph->descent - height);
1794 r.height = min (max_y - r.y, height);
1794 } 1795 }
1795 } 1796 }
1796 1797
@@ -10729,12 +10730,17 @@ run_window_scroll_functions (window, startp)
10729 A value of 1 means there is nothing to be done. 10730 A value of 1 means there is nothing to be done.
10730 (Either the line is fully visible, or it cannot be made so, 10731 (Either the line is fully visible, or it cannot be made so,
10731 or we cannot tell.) 10732 or we cannot tell.)
10733
10734 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10735 is higher than window.
10736
10732 A value of 0 means the caller should do scrolling 10737 A value of 0 means the caller should do scrolling
10733 as if point had gone off the screen. */ 10738 as if point had gone off the screen. */
10734 10739
10735static int 10740static int
10736make_cursor_line_fully_visible (w) 10741make_cursor_line_fully_visible (w, force_p)
10737 struct window *w; 10742 struct window *w;
10743 int force_p;
10738{ 10744{
10739 struct glyph_matrix *matrix; 10745 struct glyph_matrix *matrix;
10740 struct glyph_row *row; 10746 struct glyph_row *row;
@@ -10752,6 +10758,9 @@ make_cursor_line_fully_visible (w)
10752 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row)) 10758 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10753 return 1; 10759 return 1;
10754 10760
10761 if (force_p)
10762 return 0;
10763
10755 /* If the row the cursor is in is taller than the window's height, 10764 /* If the row the cursor is in is taller than the window's height,
10756 it's not clear what to do, so do nothing. */ 10765 it's not clear what to do, so do nothing. */
10757 window_height = window_box_height (w); 10766 window_height = window_box_height (w);
@@ -10848,7 +10857,7 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
10848 int amount_to_scroll = 0; 10857 int amount_to_scroll = 0;
10849 Lisp_Object aggressive; 10858 Lisp_Object aggressive;
10850 int height; 10859 int height;
10851 int end_scroll_margin; 10860 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10852 10861
10853#if GLYPH_DEBUG 10862#if GLYPH_DEBUG
10854 debug_method_add (w, "try_scrolling"); 10863 debug_method_add (w, "try_scrolling");
@@ -10891,11 +10900,13 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
10891 CHARPOS (scroll_margin_pos) = XINT (window_end); 10900 CHARPOS (scroll_margin_pos) = XINT (window_end);
10892 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos)); 10901 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10893 10902
10894 end_scroll_margin = this_scroll_margin + !!last_line_misfit; 10903 if (this_scroll_margin || extra_scroll_margin_lines)
10895 if (end_scroll_margin)
10896 { 10904 {
10897 start_display (&it, w, scroll_margin_pos); 10905 start_display (&it, w, scroll_margin_pos);
10898 move_it_vertically (&it, - end_scroll_margin); 10906 if (this_scroll_margin)
10907 move_it_vertically (&it, - this_scroll_margin);
10908 if (extra_scroll_margin_lines)
10909 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
10899 scroll_margin_pos = it.current.pos; 10910 scroll_margin_pos = it.current.pos;
10900 } 10911 }
10901 10912
@@ -11030,10 +11041,10 @@ try_scrolling (window, just_this_one_p, scroll_conservatively,
11030 11041
11031 /* If cursor ends up on a partially visible line, 11042 /* If cursor ends up on a partially visible line,
11032 treat that as being off the bottom of the screen. */ 11043 treat that as being off the bottom of the screen. */
11033 if (! make_cursor_line_fully_visible (w)) 11044 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11034 { 11045 {
11035 clear_glyph_matrix (w->desired_matrix); 11046 clear_glyph_matrix (w->desired_matrix);
11036 last_line_misfit = 1; 11047 ++extra_scroll_margin_lines;
11037 goto too_near_end; 11048 goto too_near_end;
11038 } 11049 }
11039 rc = SCROLLING_SUCCESS; 11050 rc = SCROLLING_SUCCESS;
@@ -11322,7 +11333,7 @@ try_cursor_movement (window, startp, scroll_step)
11322 else 11333 else
11323 { 11334 {
11324 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 11335 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11325 if (!make_cursor_line_fully_visible (w)) 11336 if (!make_cursor_line_fully_visible (w, 0))
11326 rc = CURSOR_MOVEMENT_MUST_SCROLL; 11337 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11327 else 11338 else
11328 rc = CURSOR_MOVEMENT_SUCCESS; 11339 rc = CURSOR_MOVEMENT_SUCCESS;
@@ -11655,7 +11666,7 @@ redisplay_window (window, just_this_one_p)
11655 new_vpos = window_box_height (w) / 2; 11666 new_vpos = window_box_height (w) / 2;
11656 } 11667 }
11657 11668
11658 if (!make_cursor_line_fully_visible (w)) 11669 if (!make_cursor_line_fully_visible (w, 0))
11659 { 11670 {
11660 /* Point does appear, but on a line partly visible at end of window. 11671 /* Point does appear, but on a line partly visible at end of window.
11661 Move it back to a fully-visible line. */ 11672 Move it back to a fully-visible line. */
@@ -11792,7 +11803,7 @@ redisplay_window (window, just_this_one_p)
11792 /* Forget any recorded base line for line number display. */ 11803 /* Forget any recorded base line for line number display. */
11793 w->base_line_number = Qnil; 11804 w->base_line_number = Qnil;
11794 11805
11795 if (!make_cursor_line_fully_visible (w)) 11806 if (!make_cursor_line_fully_visible (w, 1))
11796 { 11807 {
11797 clear_glyph_matrix (w->desired_matrix); 11808 clear_glyph_matrix (w->desired_matrix);
11798 last_line_misfit = 1; 11809 last_line_misfit = 1;
@@ -11952,7 +11963,7 @@ redisplay_window (window, just_this_one_p)
11952 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); 11963 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11953 } 11964 }
11954 11965
11955 if (!make_cursor_line_fully_visible (w)) 11966 if (!make_cursor_line_fully_visible (w, centering_position > 0))
11956 { 11967 {
11957 /* If vscroll is enabled, disable it and try again. */ 11968 /* If vscroll is enabled, disable it and try again. */
11958 if (w->vscroll) 11969 if (w->vscroll)
@@ -11965,6 +11976,7 @@ redisplay_window (window, just_this_one_p)
11965 /* If centering point failed to make the whole line visible, 11976 /* If centering point failed to make the whole line visible,
11966 put point at the top instead. That has to make the whole line 11977 put point at the top instead. That has to make the whole line
11967 visible, if it can be done. */ 11978 visible, if it can be done. */
11979 clear_glyph_matrix (w->desired_matrix);
11968 centering_position = 0; 11980 centering_position = 0;
11969 goto point_at_top; 11981 goto point_at_top;
11970 } 11982 }